]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/tiffmedian.c
3 * Apply median cut on an image.
5 * tiffmedian [-c n] [-f] input output
6 * -C n - set colortable size. Default is 256.
7 * -f - use Floyd-Steinberg dithering.
8 * -c lzw - compress output with LZW
9 * -c none - use no compression on output
10 * -c packbits - use packbits compression on output
11 * -r n - create output with n rows/strip of data
12 * (by default the compression scheme and rows/strip are taken
13 * from the input file)
17 * [1] Floyd-Steinberg dither:
18 * I should point out that the actual fractions we used were, assuming
19 * you are at X, moving left to right:
24 * Note that the error goes to four neighbors, not three. I think this
25 * will probably do better (at least for black and white) than the
26 * 3/8-3/8-1/4 distribution, at the cost of greater processing. I have
27 * seen the 3/8-3/8-1/4 distribution described as "our" algorithm before,
28 * but I have no idea who the credit really belongs to.
30 * Also, I should add that if you do zig-zag scanning (see my immediately
31 * previous message), it is sufficient (but not quite as good) to send
32 * half the error one pixel ahead (e.g. to the right on lines you scan
33 * left to right), and half one pixel straight down. Again, this is for
34 * black and white; I've not tried it with color.
38 * [2] Color Image Quantization for Frame Buffer Display, Paul Heckbert,
39 * Siggraph '82 proceedings, pp. 297-307
42 #include "tif_config.h"
58 #define MAX_CMAP_SIZE 256
60 #define streq(a,b) (strcmp(a,b) == 0)
61 #define strneq(a,b,n) (strncmp(a,b,n) == 0)
66 #define B_DEPTH 5 /* # bits/pixel to use */
67 #define B_LEN (1L<<B_DEPTH)
70 #define C_LEN (1L<<C_DEPTH) /* # cells/color to use */
72 #define COLOR_SHIFT (COLOR_DEPTH-B_DEPTH)
74 typedef struct colorbox
{
75 struct colorbox
*next
, *prev
;
84 int entries
[MAX_CMAP_SIZE
][2];
87 uint16 rm
[MAX_CMAP_SIZE
], gm
[MAX_CMAP_SIZE
], bm
[MAX_CMAP_SIZE
];
89 uint32 histogram
[B_LEN
][B_LEN
][B_LEN
];
94 uint32 rowsperstrip
= (uint32
) -1;
95 uint16 compression
= (uint16
) -1;
96 uint16 bitspersample
= 1;
97 uint16 samplesperpixel
;
100 uint16 predictor
= 0;
102 static void get_histogram(TIFF
*, Colorbox
*);
103 static void splitbox(Colorbox
*);
104 static void shrinkbox(Colorbox
*);
105 static void map_colortable(void);
106 static void quant(TIFF
*, TIFF
*);
107 static void quant_fsdither(TIFF
*, TIFF
*);
108 static Colorbox
* largest_box(void);
110 static void usage(void);
111 static int processCompressOptions(char*);
113 #define CopyField(tag, v) \
114 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
117 main(int argc
, char* argv
[])
120 uint16 shortv
, config
, photometric
;
121 Colorbox
*box_list
, *ptr
;
128 num_colors
= MAX_CMAP_SIZE
;
129 while ((c
= getopt(argc
, argv
, "c:C:r:f")) != -1)
131 case 'c': /* compression scheme */
132 if (!processCompressOptions(optarg
))
135 case 'C': /* set colormap size */
136 num_colors
= atoi(optarg
);
137 if (num_colors
> MAX_CMAP_SIZE
) {
139 "-c: colormap too big, max %d\n",
144 case 'f': /* dither */
147 case 'r': /* rows/strip */
148 rowsperstrip
= atoi(optarg
);
154 if (argc
- optind
!= 2)
156 in
= TIFFOpen(argv
[optind
], "r");
159 TIFFGetField(in
, TIFFTAG_IMAGEWIDTH
, &imagewidth
);
160 TIFFGetField(in
, TIFFTAG_IMAGELENGTH
, &imagelength
);
161 TIFFGetField(in
, TIFFTAG_BITSPERSAMPLE
, &bitspersample
);
162 TIFFGetField(in
, TIFFTAG_SAMPLESPERPIXEL
, &samplesperpixel
);
163 if (bitspersample
!= 8 && bitspersample
!= 16) {
164 fprintf(stderr
, "%s: Image must have at least 8-bits/sample\n",
168 if (!TIFFGetField(in
, TIFFTAG_PHOTOMETRIC
, &photometric
) ||
169 photometric
!= PHOTOMETRIC_RGB
|| samplesperpixel
< 3) {
170 fprintf(stderr
, "%s: Image must have RGB data\n", argv
[optind
]);
173 TIFFGetField(in
, TIFFTAG_PLANARCONFIG
, &config
);
174 if (config
!= PLANARCONFIG_CONTIG
) {
175 fprintf(stderr
, "%s: Can only handle contiguous data packing\n",
181 * STEP 1: create empty boxes
184 box_list
= freeboxes
= (Colorbox
*)_TIFFmalloc(num_colors
*sizeof (Colorbox
));
185 freeboxes
[0].next
= &freeboxes
[1];
186 freeboxes
[0].prev
= NULL
;
187 for (i
= 1; i
< num_colors
-1; ++i
) {
188 freeboxes
[i
].next
= &freeboxes
[i
+1];
189 freeboxes
[i
].prev
= &freeboxes
[i
-1];
191 freeboxes
[num_colors
-1].next
= NULL
;
192 freeboxes
[num_colors
-1].prev
= &freeboxes
[num_colors
-2];
195 * STEP 2: get histogram, initialize first box
198 freeboxes
= ptr
->next
;
200 freeboxes
->prev
= NULL
;
201 ptr
->next
= usedboxes
;
204 ptr
->next
->prev
= ptr
;
205 get_histogram(in
, ptr
);
208 * STEP 3: continually subdivide boxes until no more free
209 * boxes remain or until all colors assigned.
211 while (freeboxes
!= NULL
) {
220 * STEP 4: assign colors to all boxes
222 for (i
= 0, ptr
= usedboxes
; ptr
!= NULL
; ++i
, ptr
= ptr
->next
) {
223 rm
[i
] = ((ptr
->rmin
+ ptr
->rmax
) << COLOR_SHIFT
) / 2;
224 gm
[i
] = ((ptr
->gmin
+ ptr
->gmax
) << COLOR_SHIFT
) / 2;
225 bm
[i
] = ((ptr
->bmin
+ ptr
->bmax
) << COLOR_SHIFT
) / 2;
228 /* We're done with the boxes now */
230 freeboxes
= usedboxes
= NULL
;
233 * STEP 5: scan histogram and map all values to closest color
235 /* 5a: create cell list as described in Heckbert[2] */
236 ColorCells
= (C_cell
**)_TIFFmalloc(C_LEN
*C_LEN
*C_LEN
*sizeof (C_cell
*));
237 _TIFFmemset(ColorCells
, 0, C_LEN
*C_LEN
*C_LEN
*sizeof (C_cell
*));
238 /* 5b: create mapping from truncated pixel space to color
243 * STEP 6: scan image, match input values to table entries
245 out
= TIFFOpen(argv
[optind
+1], "w");
249 CopyField(TIFFTAG_SUBFILETYPE
, longv
);
250 CopyField(TIFFTAG_IMAGEWIDTH
, longv
);
251 TIFFSetField(out
, TIFFTAG_BITSPERSAMPLE
, (short)COLOR_DEPTH
);
252 if (compression
!= (uint16
)-1) {
253 TIFFSetField(out
, TIFFTAG_COMPRESSION
, compression
);
254 switch (compression
) {
255 case COMPRESSION_LZW
:
256 case COMPRESSION_DEFLATE
:
258 TIFFSetField(out
, TIFFTAG_PREDICTOR
, predictor
);
262 CopyField(TIFFTAG_COMPRESSION
, compression
);
263 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, (short)PHOTOMETRIC_PALETTE
);
264 CopyField(TIFFTAG_ORIENTATION
, shortv
);
265 TIFFSetField(out
, TIFFTAG_SAMPLESPERPIXEL
, (short)1);
266 CopyField(TIFFTAG_PLANARCONFIG
, shortv
);
267 TIFFSetField(out
, TIFFTAG_ROWSPERSTRIP
,
268 TIFFDefaultStripSize(out
, rowsperstrip
));
269 CopyField(TIFFTAG_MINSAMPLEVALUE
, shortv
);
270 CopyField(TIFFTAG_MAXSAMPLEVALUE
, shortv
);
271 CopyField(TIFFTAG_RESOLUTIONUNIT
, shortv
);
272 CopyField(TIFFTAG_XRESOLUTION
, floatv
);
273 CopyField(TIFFTAG_YRESOLUTION
, floatv
);
274 CopyField(TIFFTAG_XPOSITION
, floatv
);
275 CopyField(TIFFTAG_YPOSITION
, floatv
);
278 quant_fsdither(in
, out
);
282 * Scale colormap to TIFF-required 16-bit values.
284 #define SCALE(x) (((x)*((1L<<16)-1))/255)
285 for (i
= 0; i
< MAX_CMAP_SIZE
; ++i
) {
286 rm
[i
] = SCALE(rm
[i
]);
287 gm
[i
] = SCALE(gm
[i
]);
288 bm
[i
] = SCALE(bm
[i
]);
290 TIFFSetField(out
, TIFFTAG_COLORMAP
, rm
, gm
, bm
);
291 (void) TIFFClose(out
);
296 processCompressOptions(char* opt
)
298 if (streq(opt
, "none"))
299 compression
= COMPRESSION_NONE
;
300 else if (streq(opt
, "packbits"))
301 compression
= COMPRESSION_PACKBITS
;
302 else if (strneq(opt
, "lzw", 3)) {
303 char* cp
= strchr(opt
, ':');
305 predictor
= atoi(cp
+1);
306 compression
= COMPRESSION_LZW
;
307 } else if (strneq(opt
, "zip", 3)) {
308 char* cp
= strchr(opt
, ':');
310 predictor
= atoi(cp
+1);
311 compression
= COMPRESSION_DEFLATE
;
318 "usage: tiffmedian [options] input.tif output.tif",
319 "where options are:",
320 " -r # make each strip have no more than # rows",
321 " -C # create a colormap with # entries",
322 " -f use Floyd-Steinberg dithering",
323 " -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
324 " -c zip[:opts] compress output with deflate encoding",
325 " -c packbits compress output with packbits encoding",
326 " -c none use no compression algorithm on output",
328 "LZW and deflate options:",
329 " # set predictor value",
330 "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
341 fprintf(stderr
, "%s\n\n", TIFFGetVersion());
342 for (i
= 0; stuff
[i
] != NULL
; i
++)
343 fprintf(stderr
, "%s\n", stuff
[i
]);
348 get_histogram(TIFF
* in
, Colorbox
* box
)
350 register unsigned char *inptr
;
351 register int red
, green
, blue
;
352 register uint32 j
, i
;
353 unsigned char *inputline
;
355 inputline
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in
));
356 if (inputline
== NULL
) {
357 fprintf(stderr
, "No space for scanline buffer\n");
360 box
->rmin
= box
->gmin
= box
->bmin
= 999;
361 box
->rmax
= box
->gmax
= box
->bmax
= -1;
362 box
->total
= imagewidth
* imagelength
;
364 { register uint32
*ptr
= &histogram
[0][0][0];
365 for (i
= B_LEN
*B_LEN
*B_LEN
; i
-- > 0;)
368 for (i
= 0; i
< imagelength
; i
++) {
369 if (TIFFReadScanline(in
, inputline
, i
, 0) <= 0)
372 for (j
= imagewidth
; j
-- > 0;) {
373 red
= *inptr
++ >> COLOR_SHIFT
;
374 green
= *inptr
++ >> COLOR_SHIFT
;
375 blue
= *inptr
++ >> COLOR_SHIFT
;
380 if (green
< box
->gmin
)
382 if (green
> box
->gmax
)
384 if (blue
< box
->bmin
)
386 if (blue
> box
->bmax
)
388 histogram
[red
][green
][blue
]++;
391 _TIFFfree(inputline
);
397 register Colorbox
*p
, *b
;
398 register uint32 size
;
402 for (p
= usedboxes
; p
!= NULL
; p
= p
->next
)
403 if ((p
->rmax
> p
->rmin
|| p
->gmax
> p
->gmin
||
404 p
->bmax
> p
->bmin
) && p
->total
> size
)
405 size
= (b
= p
)->total
;
410 splitbox(Colorbox
* ptr
)
414 register Colorbox
*new;
415 register uint32
*iptr
, *histp
;
417 register int ir
,ig
,ib
;
418 register uint32 sum
, sum1
, sum2
;
419 enum { RED
, GREEN
, BLUE
} axis
;
422 * See which axis is the largest, do a histogram along that
423 * axis. Split at median point. Contract both new boxes to
424 * fit points and return
426 i
= ptr
->rmax
- ptr
->rmin
;
427 if (i
>= ptr
->gmax
- ptr
->gmin
&& i
>= ptr
->bmax
- ptr
->bmin
)
429 else if (ptr
->gmax
- ptr
->gmin
>= ptr
->bmax
- ptr
->bmin
)
433 /* get histogram along longest axis */
436 histp
= &hist2
[ptr
->rmin
];
437 for (ir
= ptr
->rmin
; ir
<= ptr
->rmax
; ++ir
) {
439 for (ig
= ptr
->gmin
; ig
<= ptr
->gmax
; ++ig
) {
440 iptr
= &histogram
[ir
][ig
][ptr
->bmin
];
441 for (ib
= ptr
->bmin
; ib
<= ptr
->bmax
; ++ib
)
450 histp
= &hist2
[ptr
->gmin
];
451 for (ig
= ptr
->gmin
; ig
<= ptr
->gmax
; ++ig
) {
453 for (ir
= ptr
->rmin
; ir
<= ptr
->rmax
; ++ir
) {
454 iptr
= &histogram
[ir
][ig
][ptr
->bmin
];
455 for (ib
= ptr
->bmin
; ib
<= ptr
->bmax
; ++ib
)
464 histp
= &hist2
[ptr
->bmin
];
465 for (ib
= ptr
->bmin
; ib
<= ptr
->bmax
; ++ib
) {
467 for (ir
= ptr
->rmin
; ir
<= ptr
->rmax
; ++ir
) {
468 iptr
= &histogram
[ir
][ptr
->gmin
][ib
];
469 for (ig
= ptr
->gmin
; ig
<= ptr
->gmax
; ++ig
) {
480 /* find median point */
481 sum2
= ptr
->total
/ 2;
482 histp
= &hist2
[first
];
484 for (i
= first
; i
<= last
&& (sum
+= *histp
++) < sum2
; ++i
)
489 /* Create new box, re-allocate points */
491 freeboxes
= new->next
;
493 freeboxes
->prev
= NULL
;
495 usedboxes
->prev
= new;
496 new->next
= usedboxes
;
499 histp
= &hist2
[first
];
500 for (sum1
= 0, j
= first
; j
< i
; j
++)
502 for (sum2
= 0, j
= i
; j
<= last
; j
++)
507 new->rmin
= ptr
->rmin
;
508 new->rmax
= ptr
->rmax
;
509 new->gmin
= ptr
->gmin
;
510 new->gmax
= ptr
->gmax
;
511 new->bmin
= ptr
->bmin
;
512 new->bmax
= ptr
->bmax
;
532 shrinkbox(Colorbox
* box
)
534 register uint32
*histp
;
535 register int ir
, ig
, ib
;
537 if (box
->rmax
> box
->rmin
) {
538 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
)
539 for (ig
= box
->gmin
; ig
<= box
->gmax
; ++ig
) {
540 histp
= &histogram
[ir
][ig
][box
->bmin
];
541 for (ib
= box
->bmin
; ib
<= box
->bmax
; ++ib
)
548 if (box
->rmax
> box
->rmin
)
549 for (ir
= box
->rmax
; ir
>= box
->rmin
; --ir
)
550 for (ig
= box
->gmin
; ig
<= box
->gmax
; ++ig
) {
551 histp
= &histogram
[ir
][ig
][box
->bmin
];
553 for (; ib
<= box
->bmax
; ++ib
)
561 if (box
->gmax
> box
->gmin
) {
562 for (ig
= box
->gmin
; ig
<= box
->gmax
; ++ig
)
563 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
) {
564 histp
= &histogram
[ir
][ig
][box
->bmin
];
565 for (ib
= box
->bmin
; ib
<= box
->bmax
; ++ib
)
572 if (box
->gmax
> box
->gmin
)
573 for (ig
= box
->gmax
; ig
>= box
->gmin
; --ig
)
574 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
) {
575 histp
= &histogram
[ir
][ig
][box
->bmin
];
577 for (; ib
<= box
->bmax
; ++ib
)
585 if (box
->bmax
> box
->bmin
) {
586 for (ib
= box
->bmin
; ib
<= box
->bmax
; ++ib
)
587 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
) {
588 histp
= &histogram
[ir
][box
->gmin
][ib
];
589 for (ig
= box
->gmin
; ig
<= box
->gmax
; ++ig
) {
598 if (box
->bmax
> box
->bmin
)
599 for (ib
= box
->bmax
; ib
>= box
->bmin
; --ib
)
600 for (ir
= box
->rmin
; ir
<= box
->rmax
; ++ir
) {
601 histp
= &histogram
[ir
][box
->gmin
][ib
];
603 for (; ig
<= box
->gmax
; ++ig
) {
617 create_colorcell(int red
, int green
, int blue
)
619 register int ir
, ig
, ib
, i
;
620 register C_cell
*ptr
;
622 register int tmp
, dist
, n
;
624 ir
= red
>> (COLOR_DEPTH
-C_DEPTH
);
625 ig
= green
>> (COLOR_DEPTH
-C_DEPTH
);
626 ib
= blue
>> (COLOR_DEPTH
-C_DEPTH
);
627 ptr
= (C_cell
*)_TIFFmalloc(sizeof (C_cell
));
628 *(ColorCells
+ ir
*C_LEN
*C_LEN
+ ig
*C_LEN
+ ib
) = ptr
;
632 * Step 1: find all colors inside this cell, while we're at
633 * it, find distance of centermost point to furthest corner
636 for (i
= 0; i
< num_colors
; ++i
) {
637 if (rm
[i
]>>(COLOR_DEPTH
-C_DEPTH
) != ir
||
638 gm
[i
]>>(COLOR_DEPTH
-C_DEPTH
) != ig
||
639 bm
[i
]>>(COLOR_DEPTH
-C_DEPTH
) != ib
)
641 ptr
->entries
[ptr
->num_ents
][0] = i
;
642 ptr
->entries
[ptr
->num_ents
][1] = 0;
645 if (tmp
< (MAX_COLOR
/C_LEN
/2))
646 tmp
= MAX_COLOR
/C_LEN
-1 - tmp
;
649 if (tmp
< (MAX_COLOR
/C_LEN
/2))
650 tmp
= MAX_COLOR
/C_LEN
-1 - tmp
;
653 if (tmp
< (MAX_COLOR
/C_LEN
/2))
654 tmp
= MAX_COLOR
/C_LEN
-1 - tmp
;
661 * Step 3: find all points within that distance to cell.
663 for (i
= 0; i
< num_colors
; ++i
) {
664 if (rm
[i
] >> (COLOR_DEPTH
-C_DEPTH
) == ir
&&
665 gm
[i
] >> (COLOR_DEPTH
-C_DEPTH
) == ig
&&
666 bm
[i
] >> (COLOR_DEPTH
-C_DEPTH
) == ib
)
669 if ((tmp
= red
- rm
[i
]) > 0 ||
670 (tmp
= rm
[i
] - (red
+ MAX_COLOR
/C_LEN
-1)) > 0 )
672 if ((tmp
= green
- gm
[i
]) > 0 ||
673 (tmp
= gm
[i
] - (green
+ MAX_COLOR
/C_LEN
-1)) > 0 )
675 if ((tmp
= blue
- bm
[i
]) > 0 ||
676 (tmp
= bm
[i
] - (blue
+ MAX_COLOR
/C_LEN
-1)) > 0 )
678 if (dist
< mindist
) {
679 ptr
->entries
[ptr
->num_ents
][0] = i
;
680 ptr
->entries
[ptr
->num_ents
][1] = dist
;
686 * Sort color cells by distance, use cheap exchange sort
688 for (n
= ptr
->num_ents
- 1; n
> 0; n
= next_n
) {
690 for (i
= 0; i
< n
; ++i
)
691 if (ptr
->entries
[i
][1] > ptr
->entries
[i
+1][1]) {
692 tmp
= ptr
->entries
[i
][0];
693 ptr
->entries
[i
][0] = ptr
->entries
[i
+1][0];
694 ptr
->entries
[i
+1][0] = tmp
;
695 tmp
= ptr
->entries
[i
][1];
696 ptr
->entries
[i
][1] = ptr
->entries
[i
+1][1];
697 ptr
->entries
[i
+1][1] = tmp
;
707 register uint32
*histp
= &histogram
[0][0][0];
708 register C_cell
*cell
;
709 register int j
, tmp
, d2
, dist
;
712 for (ir
= 0; ir
< B_LEN
; ++ir
)
713 for (ig
= 0; ig
< B_LEN
; ++ig
)
714 for (ib
= 0; ib
< B_LEN
; ++ib
, histp
++) {
719 cell
= *(ColorCells
+
720 (((ir
>>(B_DEPTH
-C_DEPTH
)) << C_DEPTH
*2) +
721 ((ig
>>(B_DEPTH
-C_DEPTH
)) << C_DEPTH
) +
722 (ib
>>(B_DEPTH
-C_DEPTH
))));
724 cell
= create_colorcell(
729 for (i
= 0; i
< cell
->num_ents
&&
730 dist
> cell
->entries
[i
][1]; ++i
) {
731 j
= cell
->entries
[i
][0];
732 d2
= rm
[j
] - (ir
<< COLOR_SHIFT
);
734 tmp
= gm
[j
] - (ig
<< COLOR_SHIFT
);
736 tmp
= bm
[j
] - (ib
<< COLOR_SHIFT
);
747 * straight quantization. Each pixel is mapped to the colors
748 * closest to it. Color values are rounded to the nearest color
752 quant(TIFF
* in
, TIFF
* out
)
754 unsigned char *outline
, *inputline
;
755 register unsigned char *outptr
, *inptr
;
756 register uint32 i
, j
;
757 register int red
, green
, blue
;
759 inputline
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in
));
760 outline
= (unsigned char *)_TIFFmalloc(imagewidth
);
761 for (i
= 0; i
< imagelength
; i
++) {
762 if (TIFFReadScanline(in
, inputline
, i
, 0) <= 0)
766 for (j
= 0; j
< imagewidth
; j
++) {
767 red
= *inptr
++ >> COLOR_SHIFT
;
768 green
= *inptr
++ >> COLOR_SHIFT
;
769 blue
= *inptr
++ >> COLOR_SHIFT
;
770 *outptr
++ = (unsigned char)histogram
[red
][green
][blue
];
772 if (TIFFWriteScanline(out
, outline
, i
, 0) < 0)
775 _TIFFfree(inputline
);
779 #define SWAP(type,a,b) { type p; p = a; a = b; b = p; }
781 #define GetInputLine(tif, row, bad) \
782 if (TIFFReadScanline(tif, inputline, row, 0) <= 0) \
785 nextptr = nextline; \
786 for (j = 0; j < imagewidth; ++j) { \
787 *nextptr++ = *inptr++; \
788 *nextptr++ = *inptr++; \
789 *nextptr++ = *inptr++; \
791 #define GetComponent(raw, cshift, c) \
795 else if (cshift >= MAX_COLOR) \
796 cshift = MAX_COLOR-1; \
798 cshift >>= COLOR_SHIFT;
801 quant_fsdither(TIFF
* in
, TIFF
* out
)
803 unsigned char *outline
, *inputline
, *inptr
;
804 short *thisline
, *nextline
;
805 register unsigned char *outptr
;
806 register short *thisptr
, *nextptr
;
807 register uint32 i
, j
;
809 int lastline
, lastpixel
;
811 imax
= imagelength
- 1;
812 jmax
= imagewidth
- 1;
813 inputline
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in
));
814 thisline
= (short *)_TIFFmalloc(imagewidth
* 3 * sizeof (short));
815 nextline
= (short *)_TIFFmalloc(imagewidth
* 3 * sizeof (short));
816 outline
= (unsigned char *) _TIFFmalloc(TIFFScanlineSize(out
));
818 GetInputLine(in
, 0, goto bad
); /* get first line */
819 for (i
= 1; i
<= imagelength
; ++i
) {
820 SWAP(short *, thisline
, nextline
);
821 lastline
= (i
>= imax
);
823 GetInputLine(in
, i
, break);
827 for (j
= 0; j
< imagewidth
; ++j
) {
828 int red
, green
, blue
;
829 register int oval
, r2
, g2
, b2
;
831 lastpixel
= (j
== jmax
);
832 GetComponent(*thisptr
++, r2
, red
);
833 GetComponent(*thisptr
++, g2
, green
);
834 GetComponent(*thisptr
++, b2
, blue
);
835 oval
= histogram
[r2
][g2
][b2
];
838 register int cj
, tmp
, d2
, dist
;
839 register C_cell
*cell
;
841 cell
= *(ColorCells
+
842 (((r2
>>(B_DEPTH
-C_DEPTH
)) << C_DEPTH
*2) +
843 ((g2
>>(B_DEPTH
-C_DEPTH
)) << C_DEPTH
) +
844 (b2
>>(B_DEPTH
-C_DEPTH
))));
846 cell
= create_colorcell(red
,
849 for (ci
= 0; ci
< cell
->num_ents
&& dist
> cell
->entries
[ci
][1]; ++ci
) {
850 cj
= cell
->entries
[ci
][0];
851 d2
= (rm
[cj
] >> COLOR_SHIFT
) - r2
;
853 tmp
= (gm
[cj
] >> COLOR_SHIFT
) - g2
;
855 tmp
= (bm
[cj
] >> COLOR_SHIFT
) - b2
;
862 histogram
[r2
][g2
][b2
] = oval
;
869 thisptr
[0] += blue
* 7 / 16;
870 thisptr
[1] += green
* 7 / 16;
871 thisptr
[2] += red
* 7 / 16;
875 nextptr
[-3] += blue
* 3 / 16;
876 nextptr
[-2] += green
* 3 / 16;
877 nextptr
[-1] += red
* 3 / 16;
879 nextptr
[0] += blue
* 5 / 16;
880 nextptr
[1] += green
* 5 / 16;
881 nextptr
[2] += red
* 5 / 16;
883 nextptr
[3] += blue
/ 16;
884 nextptr
[4] += green
/ 16;
885 nextptr
[5] += red
/ 16;
890 if (TIFFWriteScanline(out
, outline
, i
-1, 0) < 0)
894 _TIFFfree(inputline
);