3 { This file contains 1-pass color quantization (color mapping) routines.
4 These routines provide mapping to a fixed color map using equally spaced
5 color values. Optional Floyd-Steinberg or ordered dithering is available. }
7 { Original: jquant1.c; Copyright (C) 1991-1996, Thomas G. Lane. }
9 interface
11 {$I imjconfig.inc}
13 uses
14 imjpeglib;
16 {GLOBAL}
19 implementation
21 uses
22 imjmorecfg,
23 imjdeferr,
24 imjerror,
25 imjutils;
27 { The main purpose of 1-pass quantization is to provide a fast, if not very
28 high quality, colormapped output capability. A 2-pass quantizer usually
29 gives better visual quality; however, for quantized grayscale output this
30 quantizer is perfectly adequate. Dithering is highly recommended with this
31 quantizer, though you can turn it off if you really want to.
33 In 1-pass quantization the colormap must be chosen in advance of seeing the
34 image. We use a map consisting of all combinations of Ncolors[i] color
35 values for the i'th component. The Ncolors[] values are chosen so that
36 their product, the total number of colors, is no more than that requested.
37 (In most cases, the product will be somewhat less.)
39 Since the colormap is orthogonal, the representative value for each color
40 component can be determined without considering the other components;
41 then these indexes can be combined into a colormap index by a standard
42 N-dimensional-array-subscript calculation. Most of the arithmetic involved
43 can be precalculated and stored in the lookup table colorindex[].
44 colorindex[i][j] maps pixel value j in component i to the nearest
45 representative value (grid plane) for that component; this index is
46 multiplied by the array stride for component i, so that the
47 index of the colormap entry closest to a given pixel value is just
48 sum( colorindex[component-number][pixel-component-value] )
49 Aside from being fast, this scheme allows for variable spacing between
50 representative values with no additional lookup cost.
52 If gamma correction has been applied in color conversion, it might be wise
53 to adjust the color grid spacing so that the representative colors are
54 equidistant in linear space. At this writing, gamma correction is not
55 implemented by jdcolor, so nothing is done here. }
58 { Declarations for ordered dithering.
60 We use a standard 16x16 ordered dither array. The basic concept of ordered
61 dithering is described in many references, for instance Dale Schumacher's
62 chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
63 In place of Schumacher's comparisons against a "threshold" value, we add a
64 "dither" value to the input pixel and then round the result to the nearest
65 output value. The dither value is equivalent to (0.5 - threshold) times
66 the distance between output values. For ordered dithering, we assume that
67 the output colors are equally spaced; if not, results will probably be
68 worse, since the dither may be too much or too little at a given point.
70 The normal calculation would be to form pixel value + dither, range-limit
71 this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
72 We can skip the separate range-limiting step by extending the colorindex
73 table in both directions. }
76 const
78 { NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break }
82 type
85 {ODITHER_MATRIX_PTR = ^array[0..ODITHER_SIZE-1] of int;}
88 const
90 = (
91 { Bayer's order-4 dither array. Generated by the code given in
92 Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
93 The values in this array must range from 0 to ODITHER_CELLS-1. }
111 );
114 { Declarations for Floyd-Steinberg dithering.
116 Errors are accumulated into the array fserrors[], at a resolution of
117 1/16th of a pixel count. The error at a given pixel is propagated
118 to its not-yet-processed neighbors using the standard F-S fractions,
119 ... (here) 7/16
120 3/16 5/16 1/16
121 We work left-to-right on even rows, right-to-left on odd rows.
123 We can get away with a single array (holding one row's worth of errors)
124 by using it to store the current row's errors at pixel columns not yet
125 processed, but the next row's errors at columns already processed. We
126 need only a few extra variables to hold the errors immediately around the
127 current column. (If we are lucky, those variables are in registers, but
128 even if not, they're probably cheaper to access than array elements are.)
130 The fserrors[] array is indexed [component#][position].
131 We provide (#columns + 2) entries per component; the extra entry at each
132 end saves us from special-casing the first and last pixels.
134 Note: on a wide image, we might not have enough room in a PC's near data
135 segment to hold the error array; so it is allocated with alloc_large. }
137 {$ifdef BITS_IN_JSAMPLE_IS_8}
138 type
141 {$else}
142 type
145 {$endif}
147 type
151 { pointer to error array (in FAR storage!) }
155 { Private subobject }
157 const
160 type
165 { Initially allocated colormap is saved here }
170 { colorindex[i][j] = index of color closest to pixel value j in component i,
171 premultiplied as described above. Since colormap indexes must fit into
172 JSAMPLEs, the entries of this array will too. }
177 { # of values alloced to each component }
179 { Variables for ordered dithering }
182 { one dither array per component }
183 { Variables for Floyd-Steinberg dithering }
185 { accumulated errors }
190 { Policy-making subroutines for create_colormap and create_colorindex.
191 These routines determine the colormap to be used. The rest of the module
192 only assumes that the colormap is orthogonal.
194 * select_ncolors decides how to divvy up the available colors
195 among the components.
196 * output_value defines the set of representative values for a component.
197 * largest_input_value defines the mapping from input values to
198 representative values for a component.
199 Note that the latter two routines may impose different policies for
200 different components, though this is not currently done. }
204 {LOCAL}
207 { Determine allocation of desired colors to components, }
208 { and fill in Ncolors[] array to indicate choice. }
209 { Return value is total number of colors (product of Ncolors[] values). }
210 var
216 const
218 begin
222 { We can allocate at least the nc'th root of max_colors per component. }
223 { Compute floor(nc'th root of max_colors). }
225 repeat
233 { Must have at least 2 color values per component }
237 { Initialize to iroot color values for each component }
240 begin
245 { We may be able to increment the count for one or more components without
246 exceeding max_colors, though we know not all can be incremented.
247 Sometimes, the first component can be incremented more than once!
248 (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
249 In RGB colorspace, try to increment G first, then R, then B. }
251 repeat
254 begin
257 else
259 { calculate new total_colors if Ncolors[j] is incremented }
274 {LOCAL}
277 { Return j'th output value, where j will range from 0 to maxj }
278 { The output values must fall in 0..MAXJSAMPLE in increasing order }
279 begin
280 { We always provide values 0 and MAXJSAMPLE for each component;
281 any additional values are equally spaced between these limits.
282 (Forcing the upper and lower values to the limits ensures that
283 dithering can't produce a color outside the selected gamut.) }
289 {LOCAL}
292 { Return largest input value that should map to j'th output value }
293 { Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE }
294 begin
295 { Breakpoints are halfway between values returned by output_value }
301 { Create the colormap. }
303 {LOCAL}
305 var
311 begin
314 { Select number of colors for each component }
317 { Report selected color counts }
318 {$IFDEF DEBUG}
323 else
325 {$ENDIF}
327 { Allocate and fill in the colormap. }
328 { The colors are ordered in the map in standard row-major order, }
329 { i.e. rightmost (highest-indexed) color changes most rapidly. }
335 { blksize is number of adjacent repeated entries for a component }
336 { blkdist is distance between groups of identical entries for a component }
340 begin
341 { fill in colormap entries for i'th color component }
345 begin
346 { Compute j'th output value (out of nci) for component }
348 { Fill in all colormap entries that have this value of this component }
351 begin
352 { fill in blksize entries beginning at ptr }
362 { Save the colormap in private storage,
363 where it will survive color quantization mode changes. }
369 { Create the color index table. }
371 {LOCAL}
373 var
375 indexptr,
378 begin
380 { For ordered dither, we pad the color index tables by MAXJSAMPLE in
381 each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
382 This is not necessary in the other dithering modes. However, we
383 flag whether it was done in case user changes dithering mode. }
386 begin
389 end
390 else
391 begin
401 { blksize is number of adjacent repeated entries for a component }
405 begin
406 { fill in colorindex entries for i'th color component }
410 { adjust colorindex pointers to provide padding at negative indexes. }
414 { in loop, val = index of current output value, }
415 { and k = largest j that maps to current val }
420 begin
422 begin
426 { premultiply so that no multiplication needed in main processing }
429 { Pad at both ends if necessary }
431 begin
433 { adjust the help pointer to avoid negative offsets }
437 begin
438 {indexptr^[-j] := indexptr^[0];}
447 { Create an ordered-dither array for a component having ncolors
448 distinct output values. }
450 {LOCAL}
453 var
457 begin
461 { The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
462 Hence the dither value for the matrix cell with fill order f
463 (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
464 On 16-bit-int machine, be careful to avoid overflow. }
468 begin
470 begin
473 { Ensure round towards zero despite C's lack of consistency
474 about rounding negative values in integer division... }
478 else
486 { Create the ordered-dither tables.
487 Components having the same number of representative colors may
488 share a dither table. }
490 {LOCAL}
492 var
496 begin
500 begin
504 begin
506 begin
508 break;
518 { Map some rows of pixels to the output colormapped representation. }
520 {METHODDEF}
525 { General case, no dithering }
526 var
535 begin
542 begin
546 begin
549 begin
560 {METHODDEF}
565 { Fast path for out_color_components=3, no dithering }
566 var
576 begin
584 begin
588 begin
602 {METHODDEF}
607 { General case, with ordered dithering }
608 var
620 var
622 begin
627 { Nomssi: work around negative offset }
629 pad_offset := MAXJSAMPLE
630 else
634 begin
635 { Initialize output values to 0 so can process components separately }
640 begin
644 { Nomssi }
651 begin
652 { Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
653 select output value, accumulate into output code for this pixel.
654 Range-limiting need not be done explicitly, as we have extended
655 the colorindex table to produce the right answers for out-of-range
656 inputs. The maximum dither is +- MAXJSAMPLE; this sets the
657 required amount of padding. }
667 { Advance row index for next row }
673 {METHODDEF}
678 { Fast path for out_color_components=3, with ordered dithering }
679 var
694 var
696 begin
703 { Nomssi: work around negative offset }
705 pad_offset := MAXJSAMPLE
706 else
714 begin
725 begin
745 {METHODDEF}
750 { General case, with Floyd-Steinberg dithering }
751 var
758 prev_errorptr,
773 begin
780 begin
781 { Initialize output values to 0 so can process components separately }
785 begin
790 begin
791 { work right to left in this row }
797 end
798 else
799 begin
800 { work left to right in this row }
803 {errorptr := cquantize^.fserrors[ci];}
809 { Preset error values: no error propagated to first pixel from left }
811 { and no error propagated to row below yet }
816 begin
820 { cur holds the error propagated from the previous pixel on the
821 current line. Add the error propagated from the previous line
822 to form the complete error correction term for this pixel, and
823 round the error term (which is expressed * 16) to an integer.
824 RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
825 for either sign of the error value.
826 Note: errorptr points to *previous* column's array entry. }
830 { Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
831 The maximum error is +- MAXJSAMPLE; this sets the required size
832 of the range_limit array. }
836 { Select output value, accumulate into output code for this pixel }
839 { Compute actual representation error at this pixel }
840 { Note: we can do this even though we don't have the final }
841 { pixel code, because the colormap is orthogonal. }
843 { Compute error fractions to be propagated to adjacent pixels.
844 Add these into the running sums, and simultaneously shift the
845 next-line error sums left by 1 column. }
855 { At this point cur contains the 7/16 error value to be propagated
856 to the next pixel on the current line, and all the errors for the
857 next line have been shifted over. We are therefore ready to move on. }
863 { Post-loop cleanup: we must unload the final error value into the
864 final fserrors[] entry. Note we need not unload belowerr because
865 it is for the dummy column before or after the actual array. }
868 { Nomssi : ?? }
875 { Allocate workspace for Floyd-Steinberg errors. }
877 {LOCAL}
879 var
883 begin
887 begin
894 { Initialize for one-pass color quantization. }
896 {METHODDEF}
899 var
903 begin
905 { Install my colormap. }
909 { Initialize for desired dithering mode. }
911 JDITHER_NONE:
914 else
916 JDITHER_ORDERED:
917 begin
920 else
923 { If user changed to ordered dither from another mode,
924 we must recreate the color index table with padding.
925 This will cost extra space, but probably isn't very likely. }
929 { Create ordered-dither tables if we didn't already. }
933 JDITHER_FS:
934 begin
937 { Allocate Floyd-Steinberg workspace if didn't already. }
940 { Initialize the propagated errors to zero. }
945 else
951 { Finish up at the end of the pass. }
953 {METHODDEF}
955 begin
956 { no work in 1-pass case }
960 { Switch to a new external colormap between output passes.
961 Shouldn't get to this module! }
963 {METHODDEF}
965 begin
970 { Module initialization routine for 1-pass color quantization. }
972 {GLOBAL}
974 var
976 begin
987 { Make sure my internal arrays won't overflow }
990 { Make sure colormap indexes can be represented by JSAMPLEs }
994 { Create the colormap and color index table. }
998 { Allocate Floyd-Steinberg workspace now if requested.
999 We do this now since it is FAR storage and may affect the memory
1000 manager's space calculations. If the user changes to FS dither
1001 mode in a later pass, we will allocate the space then, and will
1002 possibly overrun the max_memory_to_use setting. }