1 /* Image processing functions
2 Copyright (C) 1998 Jareth Hein
4 This file is part of SXEmacs
6 SXEmacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 SXEmacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* Synched up with: Not in FSF. */
22 /* Original author: Jareth Hein */
24 /* Parts of this file are based on code from Sam Leffler's tiff library,
25 with the original copyright displayed here:
27 Copyright (c) 1988-1997 Sam Leffler
28 Copyright (c) 1991-1997 Silicon Graphics, Inc.
30 Permission to use, copy, modify, distribute, and sell this software and
31 its documentation for any purpose is hereby granted without fee, provided
32 that (i) the above copyright notices and this permission notice appear in
33 all copies of the software and related documentation, and (ii) the names of
34 Sam Leffler and Silicon Graphics may not be used in any advertising or
35 publicity relating to the software without the specific, prior written
36 permission of Sam Leffler and Silicon Graphics. */
38 /* Quantizing code based off of the paper
39 Color Image Quantization for Frame Buffer Display, Paul Heckbert,
40 Siggraph '82 proceedings, pp. 297-307 */
47 get_histogram(quant_table * qt, unsigned char *pic,
48 int width, int height, Colorbox * box)
50 register unsigned char *inptr;
51 register int red, green, blue;
54 box->rmin = box->gmin = box->bmin = 999;
55 box->rmax = box->gmax = box->bmax = -1;
56 box->total = width * height;
59 for (i = 0; i < height; i++) {
60 for (j = width; j-- > 0;) {
61 red = (*inptr++ >> COLOR_SHIFT) & COLOR_MASK;
62 green = (*inptr++ >> COLOR_SHIFT) & COLOR_MASK;
63 blue = (*inptr++ >> COLOR_SHIFT) & COLOR_MASK;
68 if (green < box->gmin)
70 if (green > box->gmax)
76 #if defined(DEBUG_SXEMACS) && DEBUG_SXEMACS
77 if( red < 0 || green < 0 || blue < 0 ||
78 ! (red < B_LEN && green < B_LEN && blue < B_LEN) ) {
82 qt->histogram[red][green][blue]++;
87 static Colorbox *largest_box(quant_table * qt)
89 register Colorbox *p, *b;
94 for (p = qt->usedboxes; p != NULL; p = p->next)
95 if ((p->rmax > p->rmin || p->gmax > p->gmin ||
96 p->bmax > p->bmin) && p->total > size)
97 size = (b = p)->total;
101 static void shrinkbox(quant_table * qt, Colorbox * box)
103 register int *histp, ir, ig, ib;
105 if (box->rmax > box->rmin) {
106 for (ir = box->rmin; ir <= box->rmax; ++ir)
107 for (ig = box->gmin; ig <= box->gmax; ++ig) {
108 histp = &(qt->histogram[ir][ig][box->bmin]);
109 for (ib = box->bmin; ib <= box->bmax; ++ib)
116 if (box->rmax > box->rmin)
117 for (ir = box->rmax; ir >= box->rmin; --ir)
118 for (ig = box->gmin; ig <= box->gmax; ++ig) {
120 &(qt->histogram[ir][ig][box->bmin]);
122 for (; ib <= box->bmax; ++ib)
130 if (box->gmax > box->gmin) {
131 for (ig = box->gmin; ig <= box->gmax; ++ig)
132 for (ir = box->rmin; ir <= box->rmax; ++ir) {
133 histp = &(qt->histogram[ir][ig][box->bmin]);
134 for (ib = box->bmin; ib <= box->bmax; ++ib)
141 if (box->gmax > box->gmin)
142 for (ig = box->gmax; ig >= box->gmin; --ig)
143 for (ir = box->rmin; ir <= box->rmax; ++ir) {
145 &(qt->histogram[ir][ig][box->bmin]);
147 for (; ib <= box->bmax; ++ib)
155 if (box->bmax > box->bmin) {
156 for (ib = box->bmin; ib <= box->bmax; ++ib)
157 for (ir = box->rmin; ir <= box->rmax; ++ir) {
158 histp = &(qt->histogram[ir][box->gmin][ib]);
159 for (ig = box->gmin; ig <= box->gmax; ++ig) {
168 if (box->bmax > box->bmin)
169 for (ib = box->bmax; ib >= box->bmin; --ib)
170 for (ir = box->rmin; ir <= box->rmax; ++ir) {
172 &(qt->histogram[ir][box->gmin][ib]);
174 for (; ig <= box->gmax; ++ig) {
187 static void splitbox(quant_table * qt, Colorbox * ptr)
190 int first = 0, last = 0;
191 register Colorbox *new;
192 register int *iptr, *histp;
194 register int ir, ig, ib;
195 register int sum, sum1, sum2;
196 enum { RED, GREEN, BLUE } axis;
199 * See which axis is the largest, do a histogram along that
200 * axis. Split at median point. Contract both new boxes to
201 * fit points and return
203 i = ptr->rmax - ptr->rmin;
204 if (i >= ptr->gmax - ptr->gmin && i >= ptr->bmax - ptr->bmin)
206 else if (ptr->gmax - ptr->gmin >= ptr->bmax - ptr->bmin)
210 /* get histogram along longest axis */
213 histp = &hist2[ptr->rmin];
214 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {
216 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {
217 iptr = &(qt->histogram[ir][ig][ptr->bmin]);
218 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)
227 histp = &hist2[ptr->gmin];
228 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {
230 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {
231 iptr = &(qt->histogram[ir][ig][ptr->bmin]);
232 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)
241 histp = &hist2[ptr->bmin];
242 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) {
244 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {
245 iptr = &(qt->histogram[ir][ptr->gmin][ib]);
246 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {
261 /* find median point */
262 sum2 = ptr->total / 2;
263 histp = &hist2[first];
265 for (i = first; i <= last && (sum += *histp++) < sum2; ++i) ;
269 /* Create new box, re-allocate points */
271 qt->freeboxes = new->next;
273 qt->freeboxes->prev = NULL;
275 qt->usedboxes->prev = new;
276 new->next = qt->usedboxes;
279 histp = &hist2[first];
280 for (sum1 = 0, j = first; j < i; j++)
282 for (sum2 = 0, j = i; j <= last; j++)
287 new->rmin = ptr->rmin;
288 new->rmax = ptr->rmax;
289 new->gmin = ptr->gmin;
290 new->gmax = ptr->gmax;
291 new->bmin = ptr->bmin;
292 new->bmax = ptr->bmax;
315 static C_cell *create_colorcell(quant_table * qt, int num_colors, int red,
318 register int ir, ig, ib, i;
319 register C_cell *ptr;
321 register int tmp, dist, n;
323 ir = red >> (COLOR_DEPTH - C_DEPTH);
324 ig = green >> (COLOR_DEPTH - C_DEPTH);
325 ib = blue >> (COLOR_DEPTH - C_DEPTH);
326 ptr = (C_cell *)xmalloc_atomic(sizeof(C_cell));
327 *(qt->ColorCells + ir * C_LEN * C_LEN + ig * C_LEN + ib) = ptr;
331 * Step 1: find all colors inside this cell, while we're at