1 /*********************************************************************/
2 /* ppmspread - randomly displace a PPM's pixels by a certain amount */
3 /* Frank Neumann, October 1993 */
4 /* V1.1 16.11.1993 */
5 /* */
6 /* version history: */
7 /* V1.0 12.10.1993 first version */
8 /* V1.1 16.11.1993 Rewritten to be NetPBM.programming conforming */
9 /*********************************************************************/
10
11 #include <string.h>
12
13 #include "ppm.h"
14
15
16
17 int
main(int argc,char * argv[])18 main(int argc,
19 char * argv[]) {
20
21 FILE * ifP;
22 int argn, rows, cols;
23 unsigned int row;
24 pixel ** destarray, ** srcarray;
25 pixel * pP;
26 pixel * pP2;
27 pixval maxval;
28 pixval r1, g1, b1;
29 int amount;
30 const char * const usage = "amount [ppmfile]\n amount: # of pixels to displace a pixel by at most\n";
31
32 /* parse in 'default' parameters */
33 ppm_init(&argc, argv);
34
35 argn = 1;
36
37 /* parse in amount & seed */
38 if (argn == argc)
39 pm_usage(usage);
40 if (sscanf(argv[argn], "%d", &amount) != 1)
41 pm_usage(usage);
42 if (amount < 0)
43 pm_error("amount should be a positive number");
44 ++argn;
45
46 /* parse in filename (if present, stdin otherwise) */
47 if (argn != argc)
48 {
49 ifP = pm_openr(argv[argn]);
50 ++argn;
51 }
52 else
53 ifP = stdin;
54
55 if (argn != argc)
56 pm_usage(usage);
57
58 srcarray = ppm_readppm(ifP, &cols, &rows, &maxval);
59
60 destarray = ppm_allocarray(cols, rows);
61
62 /* clear out the buffer */
63 for (row = 0; row < rows; ++row)
64 memset(destarray[row], 0, cols * sizeof(pixel));
65
66 srand(pm_randseed());
67
68 /* start displacing pixels */
69 for (row = 0; row < rows; ++row) {
70 unsigned int col;
71 pP = &srcarray[row][0];
72
73 for (col = 0; col < cols; ++col) {
74 int const xdis = (rand() % (amount+1)) - ((amount+1) / 2);
75 int const ydis = (rand() % (amount+1)) - ((amount+1) / 2);
76
77 int const xnew = col + xdis;
78 int const ynew = row + ydis;
79
80 /* only set the displaced pixel if it's within the bounds
81 of the image
82 */
83 if (xnew >= 0 && xnew < cols && ynew >= 0 && ynew < rows) {
84 /* displacing a pixel is accomplished by swapping it
85 with another pixel in its vicinity - so, first
86 store other pixel's RGB
87 */
88 pP2 = &srcarray[ynew][xnew];
89 r1 = PPM_GETR(*pP2);
90 g1 = PPM_GETG(*pP2);
91 b1 = PPM_GETB(*pP2);
92 /* set second pixel to new value */
93 pP2 = &destarray[ynew][xnew];
94 PPM_ASSIGN(*pP2, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP));
95
96 /* now, set first pixel to (old) value of second */
97 pP2 = &destarray[row][col];
98 PPM_ASSIGN(*pP2, r1, g1, b1);
99 } else {
100 /* displaced pixel is out of bounds; leave the old
101 pixel there
102 */
103 pP2 = &destarray[row][col];
104 PPM_ASSIGN(*pP2, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP));
105 }
106 ++pP;
107 }
108 }
109
110 ppm_writeppm(stdout, destarray, cols, rows, maxval, 0);
111
112 pm_close(ifP);
113 ppm_freearray(srcarray, rows);
114 ppm_freearray(destarray, rows);
115
116 return 0;
117 }
118