]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/tiffmedian.c
4 * Apply median cut on an image.
6 * tiffmedian [-c n] [-f] input output
7 * -C n - set colortable size. Default is 256.
8 * -f - use Floyd-Steinberg dithering.
9 * -c lzw - compress output with LZW
10 * -c none - use no compression on output
11 * -c packbits - use packbits compression on output
12 * -r n - create output with n rows/strip of data
13 * (by default the compression scheme and rows/strip are taken
14 * from the input file)
18 * [1] Floyd-Steinberg dither:
19 * I should point out that the actual fractions we used were, assuming
20 * you are at X, moving left to right:
25 * Note that the error goes to four neighbors, not three. I think this
26 * will probably do better (at least for black and white) than the
27 * 3/8-3/8-1/4 distribution, at the cost of greater processing. I have
28 * seen the 3/8-3/8-1/4 distribution described as "our" algorithm before,
29 * but I have no idea who the credit really belongs to.
31 * Also, I should add that if you do zig-zag scanning (see my immediately
32 * previous message), it is sufficient (but not quite as good) to send
33 * half the error one pixel ahead (e.g. to the right on lines you scan
34 * left to right), and half one pixel straight down. Again, this is for
35 * black and white; I've not tried it with color.
39 * [2] Color Image Quantization for Frame Buffer Display, Paul Heckbert,
40 * Siggraph '82 proceedings, pp. 297-307
43 #include "tif_config.h"
55 #define MAX_CMAP_SIZE 256
57 #define streq(a,b) (strcmp(a,b) == 0)
58 #define strneq(a,b,n) (strncmp(a,b,n) == 0)
63 #define B_DEPTH 5 /* # bits/pixel to use */
64 #define B_LEN (1L<<B_DEPTH)
67 #define C_LEN (1L<<C_DEPTH) /* # cells/color to use */
69 #define COLOR_SHIFT (COLOR_DEPTH-B_DEPTH)
71 typedef struct colorbox
{
72 struct colorbox
*next
, *prev
;
81 int entries
[MAX_CMAP_SIZE
][2];
84 uint16 rm
[MAX_CMAP_SIZE
], gm
[MAX_CMAP_SIZE
], bm
[MAX_CMAP_SIZE
];
86 uint32 histogram
[B_LEN
][B_LEN
][B_LEN
];
91 uint32 rowsperstrip
= (uint32
) -1;
92 uint16 compression
= (uint16
) -1;
93 uint16 bitspersample
= 1;
94 uint16 samplesperpixel
;
99 static void get_histogram(TIFF
*, Colorbox
*);
100 static void splitbox(Colorbox
*);
101 static void shrinkbox(Colorbox
*);
102 static void map_colortable(void);
103 static void quant(TIFF
*, TIFF
*);
104 static void quant_fsdither(TIFF
*, TIFF
*);
105 static Colorbox
* largest_box(void);
107 static void usage(void);
108 static int processCompressOptions(char*);
110 #define CopyField(tag, v) \
111 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
114 main(int argc
, char* argv
[])
117 uint16 shortv
, config
, photometric
;
118 Colorbox
*box_list
, *ptr
;
125 num_colors
= MAX_CMAP_SIZE
;
126 while ((c
= getopt(argc
, argv
, "c:C:r:f")) != -1)
128 case 'c': /* compression scheme */
129 if (!processCompressOptions(optarg
))
132 case 'C': /* set colormap size */
133 num_colors
= atoi(optarg
);
134 if (num_colors
> MAX_CMAP_SIZE
) {
136 "-c: colormap too big, max %d\n",
141 case 'f': /* dither */
144 case 'r': /* rows/strip */
145 rowsperstrip
= atoi(optarg
);
151 if (argc
- optind
!= 2)
153 in
= TIFFOpen(argv
[optind
], "r");
156 TIFFGetField(in
, TIFFTAG_IMAGEWIDTH
, &imagewidth
);
157 TIFFGetField(in
, TIFFTAG_IMAGELENGTH
, &imagelength
);
158 TIFFGetField(in
, TIFFTAG_BITSPERSAMPLE
, &bitspersample
);
159 TIFFGetField(in
, TIFFTAG_SAMPLESPERPIXEL
, &samplesperpixel
);
160 if (bitspersample
!= 8 && bitspersample
!= 16) {
161 fprintf(stderr
, "%s: Image must have at least 8-bits/sample\n",
165 if (!TIFFGetField(in
, TIFFTAG_PHOTOMETRIC
, &photometric
) ||
166 photometric
!= PHOTOMETRIC_RGB
|| samplesperpixel
< 3) {
167 fprintf(stderr
, "%s: Image must have RGB data\n", argv
[optind
]);
170 TIFFGetField(in
, TIFFTAG_PLANARCONFIG
, &config
);
171 if (config
!= PLANARCONFIG_CONTIG
) {
172 fprintf(stderr
, "%s: Can only handle contiguous data packing\n",
178 * STEP 1: create empty boxes
181 box_list
= freeboxes
= (Colorbox
*)_TIFFmalloc(num_colors
*sizeof (Colorbox
));
182 freeboxes
[0].next
= &freeboxes
[1];
183 freeboxes
[0].prev
= NULL
;
184 for (i
= 1; i
< num_colors
-1; ++i
) {
185 freeboxes
[i
].next
= &freeboxes
[i
+1];
186 freeboxes
[i
].prev
= &freeboxes
[i
-1];
188 freeboxes
[num_colors
-1].next
= NULL
;
189 freeboxes
[num_colors
-1].prev
= &freeboxes
[num_colors
-2];
192 * STEP 2: get histogram, initialize first box
195 freeboxes
= ptr
->next
;
197 freeboxes
->prev
= NULL
;
198 ptr
->next
= usedboxes
;
201 ptr
->next
->prev
= ptr
;
202 get_histogram(in
, ptr
);
205 * STEP 3: continually subdivide boxes until no more free
206 * boxes remain or until all colors assigned.
208 while (freeboxes
!= NULL
) {
217 * STEP 4: assign colors to all boxes
219 for (i
= 0, ptr
= usedboxes
; ptr
!= NULL
; ++i
, ptr
= ptr
->next
) {
220 rm
[i
] = ((ptr
->rmin
+ ptr
->rmax
) << COLOR_SHIFT
) / 2;
221 gm
[i
] = ((ptr
->gmin
+ ptr
->gmax
) << COLOR_SHIFT
) / 2;
222 bm
[i
] = ((ptr
->bmin
+ ptr
->bmax
) << COLOR_SHIFT
) / 2;
225 /* We're done with the boxes now */
227 freeboxes
= usedboxes
= NULL
;
230 * STEP 5: scan histogram and map all values to closest color
232 /* 5a: create cell list as described in Heckbert[2] */
233 ColorCells
= (C_cell
**)_TIFFmalloc(C_LEN
*C_LEN
*C_LEN
*sizeof (C_cell
*));
234 _TIFFmemset(ColorCells
, 0, C_LEN
*C_LEN
*C_LEN
*sizeof (C_cell
*));
235 /* 5b: create mapping from truncated pixel space to color
240 * STEP 6: scan image, match input values to table entries
242 out
= TIFFOpen(argv
[optind
+1], "w");
246 CopyField(TIFFTAG_SUBFILETYPE
, longv
);
247 CopyField(TIFFTAG_IMAGEWIDTH
, longv
);
248 TIFFSetField(out
, TIFFTAG_BITSPERSAMPLE
, (short)COLOR_DEPTH
);
249 if (compression
!= (uint16
)-1) {
250 TIFFSetField(out
, TIFFTAG_COMPRESSION
, compression
);
251 switch (compression
) {
252 case COMPRESSION_LZW
:
253 case COMPRESSION_DEFLATE
:
255 TIFFSetField(out
, TIFFTAG_PREDICTOR
, predictor
);
259 CopyField(TIFFTAG_COMPRESSION
, compression
);
260 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, (short)PHOTOMETRIC_PALETTE
);
261 CopyField(TIFFTAG_ORIENTATION
, shortv
);
262 TIFFSetField(out
, TIFFTAG_SAMPLESPERPIXEL
, (short)1);
263 CopyField(TIFFTAG_PLANARCONFIG
, shortv
);
264 TIFFSetField(out
, TIFFTAG_ROWSPERSTRIP
,
265 TIFFDefaultStripSize(out
, rowsperstrip
));
266 CopyField(TIFFTAG_MINSAMPLEVALUE
, shortv
);
267 CopyField(TIFFTAG_MAXSAMPLEVALUE
, shortv
);
268 CopyField(TIFFTAG_RESOLUTIONUNIT
, shortv
);
269 CopyField(TIFFTAG_XRESOLUTION
, floatv
);
270 CopyField(TIFFTAG_YRESOLUTION
, floatv
);
271 CopyField(TIFFTAG_XPOSITION
, floatv
);
272 CopyField(TIFFTAG_YPOSITION
, floatv
);
275 quant_fsdither(in
, out
);
279 * Scale colormap to TIFF-required 16-bit values.
281 #define SCALE(x) (((x)*((1L<<16)-1))/255)
282 for (i
= 0; i
< MAX_CMAP_SIZE
; ++i
) {
283 rm
[i
] = SCALE(rm
[i
]);
284 gm
[i
] = SCALE(gm
[i
]);
285 bm
[i
] = SCALE(bm
[i
]);
287 TIFFSetField(out
, TIFFTAG_COLORMAP
, rm
, gm
, bm
);
288 (void) TIFFClose(out
);
293 processCompressOptions(char* opt
)
295 if (streq(opt
, "none"))
296 compression
= COMPRESSION_NONE
;
297 else if (streq(opt
, "packbits"))
298 compression
= COMPRESSION_PACKBITS
;
299 else if (strneq(opt
, "lzw", 3)) {
300 char* cp
= strchr(opt
, ':');
302 predictor
= atoi(cp
+1);
303 compression
= COMPRESSION_LZW
;
304 } else if (strneq(opt
, "zip", 3)) {
305 char* cp
= strchr(opt
, ':');
307 predictor
= atoi(cp
+1);
308 compression
= COMPRESSION_DEFLATE
;
315 "usage: tiffmedian [options] input.tif output.tif",
316 "where options are:",
317 " -r # make each strip have no more than # rows",
318 " -C # create a colormap with # entries",
319 " -f use Floyd-Steinberg dithering",
320 " -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
321 " -c zip[:opts] compress output with deflate encoding",
322 " -c packbits compress output with packbits encoding",
323 " -c none use no compression algorithm on output",
325 "LZW and deflate options:",
326 " # set predictor value",
327 "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
338 fprintf(stderr
, "%s\n\n", TIFFGetVersion());
339 for (i
= 0; stuff
[i
] != NULL
; i
++)
340 fprintf(stderr
, "%s\n", stuff
[i
]);
345 get_histogram(TIFF
* in
, Colorbox
* box
)
347 register unsigned char *inptr
;
348 register int red
, green
, blue
;
349 register uint32 j
, i
;
350 unsigned char *inputline
;
352 inputline
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in
));
353 if (inputline
== NULL
) {
354 fprintf(stderr
, "No space for scanline buffer\n");
357 box
->rmin
= box
->gmin
= box
->bmin
= 999;
358 box
->rmax
= box
->gmax
= box
->bmax
= -1;
359 box
->total
= imagewidth
* imagelength
;
361 { register uint32
*ptr
= &histogram
[0][0][0];
362 for (i
= B_LEN
*B_LEN
*B_LEN
; i
-- > 0;)
365 for (i
= 0; i
< imagelength
; i
++) {
366 if (TIFFReadScanline(in
, inputline
, i
, 0) <= 0)
369 for (j
= imagewidth
; j
-- > 0;) {
370 red
= *inptr
++ >> COLOR_SHIFT
;
371 green
= *inptr
++ >> COLOR_SHIFT
;
372 blue
= *inptr
++ >> COLOR_SHIFT
;
377 if (green
< box
->gmin
)
379 if (green
> box
->gmax
)
381 if (blue
< box
->bmin
)
383 if (blue
> box
->bmax
)
385 histogram
[red
][green
][blue
]++;
388 _TIFFfree(inputline
);
394 register Colorbox
*p
, *b
;
395 register uint32 size
;
399 for (p
= usedboxes
; p
!= NULL
; p
= p
->next
)
400 if ((p
->rmax
> p
->rmin
|| p
->gmax
> p
->gmin
||
401 p
->bmax
> p
->bmin
) && p
->total
> size
)
402 size
= (b
= p
)->total
;
407 splitbox(Colorbox
* ptr
)
411 register Colorbox
*new;
412 register uint32
*iptr
, *histp
;
414 register int ir
,ig
,ib
;
415 register uint32 sum
, sum1
, sum2
;
416 enum { RED
, GREEN
, BLUE
} axis
;
419 * See which axis is the largest, do a histogram along that
420 * axis. Split at median point. Contract both new boxes to
421 * fit points and return
423 i
= ptr
->rmax
- ptr
->rmin
;
424 if (i
>= ptr
->gmax
- ptr
->gmin
&& i
>= ptr
->bmax
- ptr
->bmin
)
426 else if (ptr
->gmax
- ptr
->gmin
>= ptr
->bmax
- ptr
->bmin
)
430 /* get histogram along longest axis */
433 histp
= &hist2
[ptr
->rmin
];
434 for (ir
= ptr
->rmin
; ir
<= ptr
->rmax
; ++ir
) {
436 for (ig
= ptr
->gmin
; ig
<= ptr
->gmax
; ++ig
) {
437 iptr
= &histogram
[ir
][ig
][ptr
->bmin
];
438 for (ib
= ptr
->bmin
; ib
<= ptr
->bmax
; ++ib
)
447 histp
= &hist2
[ptr
->gmin
];
448 for (ig
= ptr
->gmin
; ig
<= ptr
->gmax
; ++ig
) {
450 for (ir
= ptr
->rmin
; ir
<= ptr
->rmax
; ++ir
) {
451 iptr
= &histogram
[ir
][ig
][ptr
->bmin
];
452 for (ib
= ptr
->bmin
; ib
<= ptr
->bmax
; ++ib
)
461 histp
= &hist2
[ptr
->bmin
];
462 for (ib
= ptr
->bmin
; ib
<= ptr
->bmax
; ++ib
) {
464 for (ir
= ptr
->rmin
; ir
<= ptr
->rmax
; ++ir
) {
465 iptr
= &histogram
[ir
][ptr
->gmin
][ib
];
466 for (ig
= ptr
->gmin
; ig
<= ptr
->gmax
; ++ig
) {
477 /* find median point */
478 sum2
= ptr
->total
/ 2;
479 histp
= &hist2
[first
];
481 for (i
= first
; i
<= last
&& (sum
+= *histp
++) < sum2
; ++i
)
486 /* Create new box, re-allocate points */
488 freeboxes
= new->next
;
490 freeboxes
->prev
= NULL
;
492 usedboxes
->prev
= new;
493 new->next
= usedboxes
;
496 histp
= &hist2
[first
];
497 for (sum1
= 0, j
= first
; j
< i
; j
++)
499 for (sum2
= 0, j
= i
; j
<= last
; j
++)
504 new->rmin
= ptr
->rmin
;
505 new->rmax
= ptr
->rmax
;
506 new->gmin
= ptr
->gmin
;
507 new->gmax
= ptr
->gmax
;
508 new->bmin
= ptr
->bmin
;
509 new->bmax
= ptr
->bmax
;
529 shrinkbox(Colorbox
* box
)
531 register uint32
*histp
;
532 register int ir
, ig
, ib
;
534 if (box
->rmax
> box
->rmin
) {
535 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
)
536 for (ig
= box
->gmin
; ig
<= box
->gmax
; ++ig
) {
537 histp
= &histogram
[ir
][ig
][box
->bmin
];
538 for (ib
= box
->bmin
; ib
<= box
->bmax
; ++ib
)
545 if (box
->rmax
> box
->rmin
)
546 for (ir
= box
->rmax
; ir
>= box
->rmin
; --ir
)
547 for (ig
= box
->gmin
; ig
<= box
->gmax
; ++ig
) {
548 histp
= &histogram
[ir
][ig
][box
->bmin
];
550 for (; ib
<= box
->bmax
; ++ib
)
558 if (box
->gmax
> box
->gmin
) {
559 for (ig
= box
->gmin
; ig
<= box
->gmax
; ++ig
)
560 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
) {
561 histp
= &histogram
[ir
][ig
][box
->bmin
];
562 for (ib
= box
->bmin
; ib
<= box
->bmax
; ++ib
)
569 if (box
->gmax
> box
->gmin
)
570 for (ig
= box
->gmax
; ig
>= box
->gmin
; --ig
)
571 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
) {
572 histp
= &histogram
[ir
][ig
][box
->bmin
];
574 for (; ib
<= box
->bmax
; ++ib
)
582 if (box
->bmax
> box
->bmin
) {
583 for (ib
= box
->bmin
; ib
<= box
->bmax
; ++ib
)
584 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
) {
585 histp
= &histogram
[ir
][box
->gmin
][ib
];
586 for (ig
= box
->gmin
; ig
<= box
->gmax
; ++ig
) {
595 if (box
->bmax
> box
->bmin
)
596 for (ib
= box
->bmax
; ib
>= box
->bmin
; --ib
)
597 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
) {
598 histp
= &histogram
[ir
][box
->gmin
][ib
];
600 for (; ig
<= box
->gmax
; ++ig
) {
614 create_colorcell(int red
, int green
, int blue
)
616 register int ir
, ig
, ib
, i
;
617 register C_cell
*ptr
;
619 register int tmp
, dist
, n
;
621 ir
= red
>> (COLOR_DEPTH
-C_DEPTH
);
622 ig
= green
>> (COLOR_DEPTH
-C_DEPTH
);
623 ib
= blue
>> (COLOR_DEPTH
-C_DEPTH
);
624 ptr
= (C_cell
*)_TIFFmalloc(sizeof (C_cell
));
625 *(ColorCells
+ ir
*C_LEN
*C_LEN
+ ig
*C_LEN
+ ib
) = ptr
;
629 * Step 1: find all colors inside this cell, while we're at
630 * it, find distance of centermost point to furthest corner
633 for (i
= 0; i
< num_colors
; ++i
) {
634 if (rm
[i
]>>(COLOR_DEPTH
-C_DEPTH
) != ir
||
635 gm
[i
]>>(COLOR_DEPTH
-C_DEPTH
) != ig
||
636 bm
[i
]>>(COLOR_DEPTH
-C_DEPTH
) != ib
)
638 ptr
->entries
[ptr
->num_ents
][0] = i
;
639 ptr
->entries
[ptr
->num_ents
][1] = 0;
642 if (tmp
< (MAX_COLOR
/C_LEN
/2))
643 tmp
= MAX_COLOR
/C_LEN
-1 - tmp
;
646 if (tmp
< (MAX_COLOR
/C_LEN
/2))
647 tmp
= MAX_COLOR
/C_LEN
-1 - tmp
;
650 if (tmp
< (MAX_COLOR
/C_LEN
/2))
651 tmp
= MAX_COLOR
/C_LEN
-1 - tmp
;
658 * Step 3: find all points within that distance to cell.
660 for (i
= 0; i
< num_colors
; ++i
) {
661 if (rm
[i
] >> (COLOR_DEPTH
-C_DEPTH
) == ir
&&
662 gm
[i
] >> (COLOR_DEPTH
-C_DEPTH
) == ig
&&
663 bm
[i
] >> (COLOR_DEPTH
-C_DEPTH
) == ib
)
666 if ((tmp
= red
- rm
[i
]) > 0 ||
667 (tmp
= rm
[i
] - (red
+ MAX_COLOR
/C_LEN
-1)) > 0 )
669 if ((tmp
= green
- gm
[i
]) > 0 ||
670 (tmp
= gm
[i
] - (green
+ MAX_COLOR
/C_LEN
-1)) > 0 )
672 if ((tmp
= blue
- bm
[i
]) > 0 ||
673 (tmp
= bm
[i
] - (blue
+ MAX_COLOR
/C_LEN
-1)) > 0 )
675 if (dist
< mindist
) {
676 ptr
->entries
[ptr
->num_ents
][0] = i
;
677 ptr
->entries
[ptr
->num_ents
][1] = dist
;
683 * Sort color cells by distance, use cheap exchange sort
685 for (n
= ptr
->num_ents
- 1; n
> 0; n
= next_n
) {
687 for (i
= 0; i
< n
; ++i
)
688 if (ptr
->entries
[i
][1] > ptr
->entries
[i
+1][1]) {
689 tmp
= ptr
->entries
[i
][0];
690 ptr
->entries
[i
][0] = ptr
->entries
[i
+1][0];
691 ptr
->entries
[i
+1][0] = tmp
;
692 tmp
= ptr
->entries
[i
][1];
693 ptr
->entries
[i
][1] = ptr
->entries
[i
+1][1];
694 ptr
->entries
[i
+1][1] = tmp
;
704 register uint32
*histp
= &histogram
[0][0][0];
705 register C_cell
*cell
;
706 register int j
, tmp
, d2
, dist
;
709 for (ir
= 0; ir
< B_LEN
; ++ir
)
710 for (ig
= 0; ig
< B_LEN
; ++ig
)
711 for (ib
= 0; ib
< B_LEN
; ++ib
, histp
++) {
716 cell
= *(ColorCells
+
717 (((ir
>>(B_DEPTH
-C_DEPTH
)) << C_DEPTH
*2) +
718 ((ig
>>(B_DEPTH
-C_DEPTH
)) << C_DEPTH
) +
719 (ib
>>(B_DEPTH
-C_DEPTH
))));
721 cell
= create_colorcell(
726 for (i
= 0; i
< cell
->num_ents
&&
727 dist
> cell
->entries
[i
][1]; ++i
) {
728 j
= cell
->entries
[i
][0];
729 d2
= rm
[j
] - (ir
<< COLOR_SHIFT
);
731 tmp
= gm
[j
] - (ig
<< COLOR_SHIFT
);
733 tmp
= bm
[j
] - (ib
<< COLOR_SHIFT
);
744 * straight quantization. Each pixel is mapped to the colors
745 * closest to it. Color values are rounded to the nearest color
749 quant(TIFF
* in
, TIFF
* out
)
751 unsigned char *outline
, *inputline
;
752 register unsigned char *outptr
, *inptr
;
753 register uint32 i
, j
;
754 register int red
, green
, blue
;
756 inputline
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in
));
757 outline
= (unsigned char *)_TIFFmalloc(imagewidth
);
758 for (i
= 0; i
< imagelength
; i
++) {
759 if (TIFFReadScanline(in
, inputline
, i
, 0) <= 0)
763 for (j
= 0; j
< imagewidth
; j
++) {
764 red
= *inptr
++ >> COLOR_SHIFT
;
765 green
= *inptr
++ >> COLOR_SHIFT
;
766 blue
= *inptr
++ >> COLOR_SHIFT
;
767 *outptr
++ = (unsigned char)histogram
[red
][green
][blue
];
769 if (TIFFWriteScanline(out
, outline
, i
, 0) < 0)
772 _TIFFfree(inputline
);
776 #define SWAP(type,a,b) { type p; p = a; a = b; b = p; }
778 #define GetInputLine(tif, row, bad) \
779 if (TIFFReadScanline(tif, inputline, row, 0) <= 0) \
782 nextptr = nextline; \
783 for (j = 0; j < imagewidth; ++j) { \
784 *nextptr++ = *inptr++; \
785 *nextptr++ = *inptr++; \
786 *nextptr++ = *inptr++; \
788 #define GetComponent(raw, cshift, c) \
792 else if (cshift >= MAX_COLOR) \
793 cshift = MAX_COLOR-1; \
795 cshift >>= COLOR_SHIFT;
798 quant_fsdither(TIFF
* in
, TIFF
* out
)
800 unsigned char *outline
, *inputline
, *inptr
;
801 short *thisline
, *nextline
;
802 register unsigned char *outptr
;
803 register short *thisptr
, *nextptr
;
804 register uint32 i
, j
;
806 int lastline
, lastpixel
;
808 imax
= imagelength
- 1;
809 jmax
= imagewidth
- 1;
810 inputline
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in
));
811 thisline
= (short *)_TIFFmalloc(imagewidth
* 3 * sizeof (short));
812 nextline
= (short *)_TIFFmalloc(imagewidth
* 3 * sizeof (short));
813 outline
= (unsigned char *) _TIFFmalloc(TIFFScanlineSize(out
));
815 GetInputLine(in
, 0, goto bad
); /* get first line */
816 for (i
= 1; i
<= imagelength
; ++i
) {
817 SWAP(short *, thisline
, nextline
);
818 lastline
= (i
>= imax
);
820 GetInputLine(in
, i
, break);
824 for (j
= 0; j
< imagewidth
; ++j
) {
825 int red
, green
, blue
;
826 register int oval
, r2
, g2
, b2
;
828 lastpixel
= (j
== jmax
);
829 GetComponent(*thisptr
++, r2
, red
);
830 GetComponent(*thisptr
++, g2
, green
);
831 GetComponent(*thisptr
++, b2
, blue
);
832 oval
= histogram
[r2
][g2
][b2
];
835 register int cj
, tmp
, d2
, dist
;
836 register C_cell
*cell
;
838 cell
= *(ColorCells
+
839 (((r2
>>(B_DEPTH
-C_DEPTH
)) << C_DEPTH
*2) +
840 ((g2
>>(B_DEPTH
-C_DEPTH
)) << C_DEPTH
) +
841 (b2
>>(B_DEPTH
-C_DEPTH
))));
843 cell
= create_colorcell(red
,
846 for (ci
= 0; ci
< cell
->num_ents
&& dist
> cell
->entries
[ci
][1]; ++ci
) {
847 cj
= cell
->entries
[ci
][0];
848 d2
= (rm
[cj
] >> COLOR_SHIFT
) - r2
;
850 tmp
= (gm
[cj
] >> COLOR_SHIFT
) - g2
;
852 tmp
= (bm
[cj
] >> COLOR_SHIFT
) - b2
;
859 histogram
[r2
][g2
][b2
] = oval
;
866 thisptr
[0] += blue
* 7 / 16;
867 thisptr
[1] += green
* 7 / 16;
868 thisptr
[2] += red
* 7 / 16;
872 nextptr
[-3] += blue
* 3 / 16;
873 nextptr
[-2] += green
* 3 / 16;
874 nextptr
[-1] += red
* 3 / 16;
876 nextptr
[0] += blue
* 5 / 16;
877 nextptr
[1] += green
* 5 / 16;
878 nextptr
[2] += red
* 5 / 16;
880 nextptr
[3] += blue
/ 16;
881 nextptr
[4] += green
/ 16;
882 nextptr
[5] += red
/ 16;
887 if (TIFFWriteScanline(out
, outline
, i
-1, 0) < 0)
891 _TIFFfree(inputline
);