]>
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
);