ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ciq.c
Revision: 1.3
Committed: Fri Apr 7 13:30:09 1989 UTC (35 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +3 -0 lines
Log Message:
initialize histogram in makehist()

File Contents

# User Rev Content
1 greg 1.2 /* Copyright 1988 Regents of the University of California */
2 greg 1.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6 greg 1.2
7     /*
8 greg 1.1 CIQ - main program for color image quantization
9     options for Floyd-Steinberg dithering by minimization of accumulated error
10     or undithered quantization
11    
12     Paul Heckbert 16 April 82, cleaned up 8 June 86
13     Greg Ward 1 March 88, modified for arbitrary picture sizes
14     */
15    
16     #include "ciq.h"
17    
18     #define table(m,r,g,b) hist[m[0][r]|m[1][g]|m[2][b]] /* histogram/pvtable */
19    
20     int hist[len]; /* list of frequencies or pixelvalues for coded color */
21    
22     colormap color; /* quantization colormap */
23     int n; /* number of colors in it */
24    
25     /*----------------------------------------------------------------------*/
26    
27     ciq(dith,nw,synth,cm)
28     int dith; /* is dithering desired? 0=no, 1=yes */
29     int nw; /* number of colors wanted in output image */
30     int synth; /* synthesize colormap? 0=no, 1=yes */
31     colormap cm; /* quantization colormap */
32     /* read if synth=0; always written */
33     {
34     int na,i;
35     colormap ocm;
36    
37     picreadcm(ocm); /* read original picture's colormap (usually identity)*/
38     sample(ocm); /* find histogram */
39    
40     if (synth)
41     n = makecm(nw,&na); /* analyze histogram and synthesize colormap */
42     else {
43     bcopy(cm,color,sizeof color);
44     n = nw;
45     na = 0;
46     for (i=0; i<len; i++) if (hist[i]) na++;
47     /*printf("from %d to %d colors\n",na,n);*/
48     }
49     picwritecm(color);
50    
51     if (dith)
52     draw_dith(ocm);
53     else {
54     for (i=0; i<len; i++)
55     if (hist[i]) hist[i] = closest(red(i),gre(i),blu(i));
56     draw_nodith(ocm);
57     }
58    
59     bcopy(color,cm,sizeof color);
60     /*endclosest();*/
61     }
62    
63     /*----------------------------------------------------------------------*/
64    
65     sample(ocm) /* make color frequency table (histogram) */
66     colormap ocm;
67     {
68     register int x,y;
69     register rgbpixel *lp;
70     rgbpixel *line;
71     colormap map;
72    
73 greg 1.3 for (x = 0; x < len; x++) /* clear histogram */
74     hist[x] = 0;
75    
76 greg 1.1 line = line3alloc(xmax);
77     convertmap(ocm,map);
78    
79     for (y=0; y<ymax; y++) {
80     picreadline3(y,line);
81     for (lp=line, x=0; x<xmax; x++, lp++)
82     table(map,lp->r,lp->g,lp->b)++;
83     }
84     free((char *)line);
85     }
86    
87     convertmap(in,out) /* convert to shifted color map */
88     register colormap in,out;
89     {
90     register int j;
91    
92     for (j=0; j<256; j++) {
93     out[0][j] = (in[0][j]&0xf8)<<7;
94     out[1][j] = (in[1][j]&0xf8)<<2;
95     out[2][j] = (in[2][j]&0xf8)>>3;
96     }
97     }
98    
99     draw_nodith(ocm) /* quantize without dithering */
100     colormap ocm; /* colormap for orig */
101     {
102     register int x,y;
103     register rgbpixel *lp;
104     rgbpixel *iline;
105     pixel *oline;
106     colormap map;
107    
108     iline = line3alloc(xmax);
109     oline = linealloc(xmax);
110     convertmap(ocm,map);
111    
112     for (y=0; y<ymax; y++) {
113     picreadline3(y,iline);
114     for (lp=iline, x=0; x<xmax; x++, lp++)
115     oline[x] = table(map,lp->r,lp->g,lp->b);
116     picwriteline(y,oline);
117     }
118     free((char *)iline);
119     free((char *)oline);
120     }
121    
122     draw_dith(ocm) /* quantize with dithering */
123     colormap ocm; /* colormap for orig */
124     {
125     register int *p,*q,rr,gg,bb,v,x,y,*P,*Q,*R;
126     int *buf;
127     rgbpixel *iline; /* input scanline */
128     pixel *oline; /* output scanline */
129    
130     buf = (int *)ecalloc(2,3*sizeof(int)*(xmax+1));
131     iline = line3alloc(xmax);
132     oline = linealloc(xmax);
133     /* reuse hist array as quantization table */
134     for (v=0; v<len; v++) hist[v] = -1;
135    
136     P = &buf[0];
137     Q = &buf[3*(xmax+1)];
138     for (y=0; y<ymax; y++, R=P, P=Q, Q=R) {
139     Q[0] = Q[1] = Q[2] = 0;
140     picreadline3(y,iline);
141     for (p=P, q=Q, x=0; x<xmax; x++, p+=3, q+=3) {
142     rr = ocm[0][iline[x].r]+p[0];
143     gg = ocm[1][iline[x].g]+p[1]; /* ideal */
144     bb = ocm[2][iline[x].b]+p[2];
145     if (rr<0) rr = 0; else if (rr>255) rr = 255;
146     if (gg<0) gg = 0; else if (gg>255) gg = 255;
147     if (bb<0) bb = 0; else if (bb>255) bb = 255;
148     v = (rr&0xf8)<<7 | (gg&0xf8)<<2 | (bb&0xf8)>>3;
149     if (hist[v]<0)
150     hist[v] = closest(rr,gg,bb); /* nearest to ideal */
151     oline[x] = v = hist[v];
152     rr -= color[0][v];
153     gg -= color[1][v]; /* error */
154     bb -= color[2][v];
155     v = rr*3>>3; p[3] += v; q[0] += v; q[3] = rr-(v<<1);
156     v = gg*3>>3; p[4] += v; q[1] += v; q[4] = gg-(v<<1);
157     v = bb*3>>3; p[5] += v; q[2] += v; q[5] = bb-(v<<1);
158     }
159     picwriteline(y,oline);
160     }
161     free((char *)iline);
162     free((char *)oline);
163     free((char *)buf);
164     }