blob: 546af68afdceec83634ba97f5e87b0fbd2aca626 [file] [log] [blame]
Guido van Rossume4bddea1991-10-30 11:52:48 +00001#include <stdio.h>
2
3long *bm;
4long *nbm;
5long h, w;
6int nh, nw;
7long factor;
8
9#define OC(x,xi) ((x)*factor+(xi))
10#define BM(x,xi,y,yi) bm[OC(y,yi)*w+OC(x,xi)]
11
12#define COMP(r,g,b) ((r) | ((g)<<8) | ((b) << 16))
13
14#define R(comp) ((comp) & 0xff)
15#define G(comp) (((comp)>>8) & 0xff)
16#define B(comp) (((comp)>>16) & 0xff)
17
18#define CHOICEFUNC(np1, np2) ( random() & 1 )
19
20int inlevels = 3*255;
21int outlevels = 1;
22
23main(argc, argv)
24 char **argv;
25{
26 char lbuf[100];
27 int x, y, xi, yi;
28 int num;
29 int r, g, b;
30 long data;
31 int i;
32 double greyness;
33 int inpixels, outpixels;
34 int resid;
35
36 setvbuf(stdout, 0, _IOFBF, 1024*128);
37 if( argc != 2) {
38 fprintf(stderr, "Usage: tomono factor\n");
39 exit(1);
40 }
41 factor = atoi(argv[1]);
42 gets(lbuf);
43 if ( sscanf(lbuf, "(%d,%d)", &w, &h) != 2) {
44 fprintf(stderr, "%s: bad size spec: %s\n", argv[0], lbuf);
45 exit(1);
46 }
47 nh = h / factor;
48 nw = w / factor;
49 printf("(%d,%d)\n", nw, nh);
50 if ( (bm = (long *)malloc(h*w*sizeof(long))) == 0) {
51 fprintf(stderr, "%s: No memory\n", argv[0]);
52 exit(1);
53 }
54 if ( (nbm = (long *)malloc(nh*nw*sizeof(long))) == 0) {
55 fprintf(stderr, "%s: No memory\n", argv[0]);
56 exit(1);
57 }
58 while( !feof(stdin) ) {
59 gets(lbuf);
60 if ( feof(stdin) ) break;
61 puts(lbuf);
62 fprintf(stderr, "Reading %d\n", h*w*sizeof(long));
63 if ( (i=fread(bm, 1, h*w*sizeof(long), stdin)) != h*w*sizeof(long)) {
64 fprintf(stderr, "%s: short read, %d wanted %d\n", argv[0],
65 i, h*w*sizeof(long));
66 exit(1);
67 }
68 /*
69 ** Compute picture blackness.
70 */
71 inpixels = 0;
72 inpixels = countpixels(0,0,w,h);
73 greyness = (double)inpixels/(h*w*inlevels);
74 fprintf(stderr, "%3.1f%% grey\n", 100.0*greyness);
75 outpixels = (int)(greyness*outlevels*nh*nw);
76 fprintf(stderr, "Inpixels: %d (%d) Outpixels %d\n", inpixels, inpixels/inlevels, outpixels);
77 resid = fillpixels(0,0,nw,nh,0,0,w,h,outpixels);
78 if ( resid > 1 ) fprintf(stderr, "Residue: %d pixels\n", resid);
79 fprintf(stderr, "Writing %d\n", (nh*nw)*sizeof(long));
80 fwrite(nbm, 1, (nh*nw)*sizeof(long), stdout);
81 }
82 exit(0);
83}
84
85countpixels(x0,y0,x1,y1)
86{
87 int x, y, tot, data;
88
89 tot = 0;
90 for( y=y0; y<y1; y++)
91 for(x=x0; x<x1; x++) {
92 data = bm[y*w+x];
93 tot += R(data);
94 tot += G(data);
95 tot += B(data);
96 }
97 return tot;
98}
99
100fillpixels(x0,y0,x1,y1,ox0,oy0,ox1,oy1,npixels)
101{
102 int m, om, p1, p2, np1, np2, rp, resid;
103
104 if ( npixels == 0 ) return 0;
105 if ( x0+1 >= x1 && y0+1 >= y1 ) {
106 if ( npixels ) {
107 nbm[y0*nw+x0] = 0xffffff;
108/* fprintf(stderr, "->%d,%d\n", x0,y0); */
109 return npixels - 1;
110 }
111 return 0;
112 }
113 if ( x1-x0 < y1-y0 ) {
114 if ( y1 - y0 <= 2 )
115 m = y0 + 1;
116 else
117 m = y0+1+(random()%(y1-y0-1));
118/* fprintf(stderr,"%d,%d %d,%d Y %d\n", x0, x1, y0, y1, m); */
119 /* om = (oy0+oy1)/2; */ om = m;
120 p1 = countpixels(ox0,oy0,ox1,om);
121 p2 = countpixels(ox0,om,ox1,oy1);
122 np1 = (int)(((float)p1/(p1+p2))*npixels);
123 np2 = (int)(((float)p2/(p1+p2))*npixels);
124 rp = npixels - np1 - np2;
125 if ( rp ) {
126 np1 += rp/2;
127 rp = rp - rp/2;
128 np2 += rp;
129 }
130 resid = 0;
131 if ( CHOICEFUNC(np1, np2) ) {
132 resid = fillpixels(x0,y0,x1,m,ox0,oy0,ox1,om,np1+resid);
133 resid = fillpixels(x0,m,x1,y1,ox0,om,ox1,oy1,np2+resid);
134 } else {
135 resid = fillpixels(x0,m,x1,y1,ox0,om,ox1,oy1,np2+resid);
136 resid = fillpixels(x0,y0,x1,m,ox0,oy0,ox1,om,np1+resid);
137 }
138 } else {
139 if ( x1 - x0 <= 2 )
140 m = x0 + 1;
141 else
142 m = x0+1+(random()%(x1-x0-1));
143/* fprintf(stderr,"%d,%d %d,%d X %d\n", x0, x1, y0, y1, m); */
144 /* om = (ox0+ox1)/2; */ om = m;
145 p1 = countpixels(ox0,oy0,om,oy1);
146 p2 = countpixels(om,oy0,ox1,oy1);
147 np1 = (int)(((float)p1/(p1+p2))*npixels);
148 np2 = (int)(((float)p2/(p1+p2))*npixels);
149 rp = npixels - np1 - np2;
150 if ( rp ) {
151 np1 += rp/2;
152 rp = rp - rp/2;
153 np2 += rp;
154 }
155 resid = 0;
156 if ( CHOICEFUNC(np1, np2) ) {
157 resid = fillpixels(x0,y0,m,y1,ox0,oy0,om,oy1,np1+resid);
158 resid = fillpixels(m,y0,x1,y1,om,oy0,ox1,oy1,np2+resid);
159 } else {
160 resid = fillpixels(m,y0,x1,y1,om,oy0,ox1,oy1,np2+resid);
161 resid = fillpixels(x0,y0,m,y1,ox0,oy0,om,oy1,np1+resid);
162 }
163 }
164 return resid;
165}