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. }
17 procedure jinit_1pass_quantizer (cinfo
: j_decompress_ptr
);
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. }
77 ODITHER_SIZE
= 16; { dimension of dither matrix }
78 { NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break }
79 ODITHER_CELLS
= (ODITHER_SIZE
*ODITHER_SIZE
); { # cells in matrix }
80 ODITHER_MASK
= (ODITHER_SIZE
-1); { mask for wrapping around counters }
83 ODITHER_vector
= Array[0..ODITHER_SIZE
-1] of int
;
84 ODITHER_MATRIX
= Array[0..ODITHER_SIZE
-1] of ODITHER_vector
;
85 {ODITHER_MATRIX_PTR = ^array[0..ODITHER_SIZE-1] of int;}
86 ODITHER_MATRIX_PTR
= ^ODITHER_MATRIX
;
89 base_dither_matrix
: Array[0..ODITHER_SIZE
-1,0..ODITHER_SIZE
-1] of UINT8
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. }
95 ( 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 ),
96 ( 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 ),
97 ( 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 ),
98 ( 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 ),
99 ( 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 ),
100 ( 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 ),
101 ( 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 ),
102 ( 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 ),
103 ( 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 ),
104 ( 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 ),
105 ( 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 ),
106 ( 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 ),
107 ( 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 ),
108 ( 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 ),
109 ( 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 ),
110 ( 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 )
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,
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}
139 FSERROR
= INT16
; { 16 bits should be enough }
140 LOCFSERROR
= int
; { use 'int' for calculation temps }
143 FSERROR
= INT32
; { may need more than 16 bits }
144 LOCFSERROR
= INT32
; { be sure calculation temps are big enough }
148 jFSError
= 0..(MaxInt
div SIZEOF(FSERROR
))-1;
149 FS_ERROR_FIELD
= array[jFSError
] of FSERROR
;
150 FS_ERROR_FIELD_PTR
= ^FS_ERROR_FIELD
;{far}
151 { pointer to error array (in FAR storage!) }
152 FSERRORPTR
= ^FSERROR
;
155 { Private subobject }
158 MAX_Q_COMPS
= 4; { max components I can handle }
161 my_cquantize_ptr
= ^my_cquantizer
;
162 my_cquantizer
= record
163 pub
: jpeg_color_quantizer
; { public fields }
165 { Initially allocated colormap is saved here }
166 sv_colormap
: JSAMPARRAY
; { The color map as a 2-D pixel array }
167 sv_actual
: int
; { number of entries in use }
169 colorindex
: JSAMPARRAY
; { Precomputed mapping for speed }
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. }
174 is_padded
: boolean; { is the colorindex padded for odither? }
176 Ncolors
: array[0..MAX_Q_COMPS
-1] of int
;
177 { # of values alloced to each component }
179 { Variables for ordered dithering }
180 row_index
: int
; { cur row's vertical index in dither matrix }
181 odither
: array[0..MAX_Q_COMPS
-1] of ODITHER_MATRIX_PTR
;
182 { one dither array per component }
183 { Variables for Floyd-Steinberg dithering }
184 fserrors
: array[0..MAX_Q_COMPS
-1] of FS_ERROR_FIELD_PTR
;
185 { accumulated errors }
186 on_odd_row
: boolean; { flag to remember which row we are on }
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. }
205 function select_ncolors (cinfo
: j_decompress_ptr
;
206 var Ncolors
: array of int
) : int
;
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). }
213 total_colors
, iroot
, i
, j
: int
;
217 RGB_order
:array[0..2] of int
= (RGB_GREEN
, RGB_RED
, RGB_BLUE
);
219 nc
:= cinfo
^.out_color_components
; { number of color components }
220 max_colors
:= cinfo
^.desired_number_of_colors
;
222 { We can allocate at least the nc'th root of max_colors per component. }
223 { Compute floor(nc'th root of max_colors). }
227 temp
:= iroot
; { set temp = iroot ** nc }
228 for i
:= 1 to pred(nc
) do
229 temp
:= temp
* iroot
;
230 until (temp
> long(max_colors
)); { repeat till iroot exceeds root }
231 Dec(iroot
); { now iroot = floor(root) }
233 { Must have at least 2 color values per component }
235 ERREXIT1(j_common_ptr(cinfo
), JERR_QUANT_FEW_COLORS
, int(temp
));
237 { Initialize to iroot color values for each component }
239 for i
:= 0 to pred(nc
) do
242 total_colors
:= total_colors
* iroot
;
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. }
253 for i
:= 0 to pred(nc
) do
255 if cinfo
^.out_color_space
= JCS_RGB
then
259 { calculate new total_colors if Ncolors[j] is incremented }
260 temp
:= total_colors
div Ncolors
[j
];
261 temp
:= temp
* (Ncolors
[j
]+1); { done in long arith to avoid oflo }
262 if (temp
> long(max_colors
)) then
263 break
; { won't fit, done with this pass }
264 Inc(Ncolors
[j
]); { OK, apply the increment }
265 total_colors
:= int(temp
);
270 select_ncolors
:= total_colors
;
275 function output_value (cinfo
: j_decompress_ptr
;
276 ci
: int
; j
: int
; maxj
: int
) : int
;
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 }
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.) }
285 output_value
:= int (( INT32(j
) * MAXJSAMPLE
+ maxj
div 2) div maxj
);
290 function largest_input_value (cinfo
: j_decompress_ptr
;
291 ci
: int
; j
: int
; maxj
: int
) : int
;
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 }
295 { Breakpoints are halfway between values returned by output_value }
296 largest_input_value
:= int (( INT32(2*j
+ 1) * MAXJSAMPLE
+
301 { Create the colormap. }
304 procedure create_colormap (cinfo
: j_decompress_ptr
);
306 cquantize
: my_cquantize_ptr
;
307 colormap
: JSAMPARRAY
; { Created colormap }
309 total_colors
: int
; { Number of distinct output colors }
310 i
,j
,k
, nci
, blksize
, blkdist
, ptr
, val
: int
;
312 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
314 { Select number of colors for each component }
315 total_colors
:= select_ncolors(cinfo
, cquantize
^.Ncolors
);
317 { Report selected color counts }
319 if (cinfo
^.out_color_components
= 3) then
320 TRACEMS4(j_common_ptr(cinfo
), 1, JTRC_QUANT_3_NCOLORS
,
321 total_colors
, cquantize
^.Ncolors
[0],
322 cquantize
^.Ncolors
[1], cquantize
^.Ncolors
[2])
324 TRACEMS1(j_common_ptr(cinfo
), 1, JTRC_QUANT_NCOLORS
, total_colors
);
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. }
331 colormap
:= cinfo
^.mem
^.alloc_sarray(
332 j_common_ptr(cinfo
), JPOOL_IMAGE
,
333 JDIMENSION(total_colors
), JDIMENSION(cinfo
^.out_color_components
));
335 { blksize is number of adjacent repeated entries for a component }
336 { blkdist is distance between groups of identical entries for a component }
337 blkdist
:= total_colors
;
339 for i
:= 0 to pred(cinfo
^.out_color_components
) do
341 { fill in colormap entries for i'th color component }
342 nci
:= cquantize
^.Ncolors
[i
]; { # of distinct values for this color }
343 blksize
:= blkdist
div nci
;
344 for j
:= 0 to pred(nci
) do
346 { Compute j'th output value (out of nci) for component }
347 val
:= output_value(cinfo
, i
, j
, nci
-1);
348 { Fill in all colormap entries that have this value of this component }
350 while (ptr
< total_colors
) do
352 { fill in blksize entries beginning at ptr }
353 for k
:= 0 to pred(blksize
) do
354 colormap
^[i
]^[ptr
+k
] := JSAMPLE(val
);
359 blkdist
:= blksize
; { blksize of this color is blkdist of next }
362 { Save the colormap in private storage,
363 where it will survive color quantization mode changes. }
365 cquantize
^.sv_colormap
:= colormap
;
366 cquantize
^.sv_actual
:= total_colors
;
369 { Create the color index table. }
372 procedure create_colorindex (cinfo
: j_decompress_ptr
);
374 cquantize
: my_cquantize_ptr
;
376 help_indexptr
: JSAMPROW
; { for negative offsets }
377 i
,j
,k
, nci
, blksize
, val
, pad
: int
;
379 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
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. }
385 if (cinfo
^.dither_mode
= JDITHER_ORDERED
) then
388 cquantize
^.is_padded
:= TRUE;
393 cquantize
^.is_padded
:= FALSE;
396 cquantize
^.colorindex
:= cinfo
^.mem
^.alloc_sarray
397 (j_common_ptr(cinfo
), JPOOL_IMAGE
,
398 JDIMENSION(MAXJSAMPLE
+1 + pad
),
399 JDIMENSION(cinfo
^.out_color_components
));
401 { blksize is number of adjacent repeated entries for a component }
402 blksize
:= cquantize
^.sv_actual
;
404 for i
:= 0 to pred(cinfo
^.out_color_components
) do
406 { fill in colorindex entries for i'th color component }
407 nci
:= cquantize
^.Ncolors
[i
]; { # of distinct values for this color }
408 blksize
:= blksize
div nci
;
410 { adjust colorindex pointers to provide padding at negative indexes. }
412 Inc(JSAMPLE_PTR(cquantize
^.colorindex
^[i
]), MAXJSAMPLE
);
414 { in loop, val = index of current output value, }
415 { and k = largest j that maps to current val }
416 indexptr
:= cquantize
^.colorindex
^[i
];
418 k
:= largest_input_value(cinfo
, i
, 0, nci
-1);
419 for j
:= 0 to MAXJSAMPLE
do
421 while (j
> k
) do { advance val if past boundary }
424 k
:= largest_input_value(cinfo
, i
, val
, nci
-1);
426 { premultiply so that no multiplication needed in main processing }
427 indexptr
^[j
] := JSAMPLE (val
* blksize
);
429 { Pad at both ends if necessary }
432 help_indexptr
:= indexptr
;
433 { adjust the help pointer to avoid negative offsets }
434 Dec(JSAMPLE_PTR(help_indexptr
), MAXJSAMPLE
);
436 for j
:= 1 to MAXJSAMPLE
do
438 {indexptr^[-j] := indexptr^[0];}
439 help_indexptr
^[MAXJSAMPLE
-j
] := indexptr
^[0];
440 indexptr
^[MAXJSAMPLE
+j
] := indexptr
^[MAXJSAMPLE
];
447 { Create an ordered-dither array for a component having ncolors
448 distinct output values. }
451 function make_odither_array (cinfo
: j_decompress_ptr
;
452 ncolors
: int
) : ODITHER_MATRIX_PTR
;
454 odither
: ODITHER_MATRIX_PTR
;
458 odither
:= ODITHER_MATRIX_PTR (
459 cinfo
^.mem
^.alloc_small(j_common_ptr(cinfo
), JPOOL_IMAGE
,
460 SIZEOF(ODITHER_MATRIX
)));
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. }
466 den
:= 2 * ODITHER_CELLS
* ( INT32(ncolors
- 1));
467 for j
:= 0 to pred(ODITHER_SIZE
) do
469 for k
:= 0 to pred(ODITHER_SIZE
) do
471 num
:= ( INT32(ODITHER_CELLS
-1 - 2*( int(base_dither_matrix
[j
][k
]))))
473 { Ensure round towards zero despite C's lack of consistency
474 about rounding negative values in integer division... }
477 odither
^[j
][k
] := int (-((-num
) div den
))
479 odither
^[j
][k
] := int (num
div den
);
482 make_odither_array
:= odither
;
486 { Create the ordered-dither tables.
487 Components having the same number of representative colors may
488 share a dither table. }
491 procedure create_odither_tables (cinfo
: j_decompress_ptr
);
493 cquantize
: my_cquantize_ptr
;
494 odither
: ODITHER_MATRIX_PTR
;
497 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
499 for i
:= 0 to pred(cinfo
^.out_color_components
) do
501 nci
:= cquantize
^.Ncolors
[i
]; { # of distinct values for this color }
502 odither
:= NIL; { search for matching prior component }
503 for j
:= 0 to pred(i
) do
505 if (nci
= cquantize
^.Ncolors
[j
]) then
507 odither
:= cquantize
^.odither
[j
];
511 if (odither
= NIL) then { need a new table? }
512 odither
:= make_odither_array(cinfo
, nci
);
513 cquantize
^.odither
[i
] := odither
;
518 { Map some rows of pixels to the output colormapped representation. }
521 procedure color_quantize (cinfo
: j_decompress_ptr
;
522 input_buf
: JSAMPARRAY
;
523 output_buf
: JSAMPARRAY
;
525 { General case, no dithering }
527 cquantize
: my_cquantize_ptr
;
528 colorindex
: JSAMPARRAY
;
529 pixcode
, ci
: int
; {register}
530 ptrin
, ptrout
: JSAMPLE_PTR
; {register}
536 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
537 colorindex
:= cquantize
^.colorindex
;
538 width
:= cinfo
^.output_width
;
539 nc
:= cinfo
^.out_color_components
;
541 for row
:= 0 to pred(num_rows
) do
543 ptrin
:= JSAMPLE_PTR(input_buf
^[row
]);
544 ptrout
:= JSAMPLE_PTR(output_buf
^[row
]);
545 for col
:= pred(width
) downto 0 do
548 for ci
:= 0 to pred(nc
) do
550 Inc(pixcode
, GETJSAMPLE(colorindex
^[ci
]^[GETJSAMPLE(ptrin
^)]) );
553 ptrout
^ := JSAMPLE (pixcode
);
561 procedure color_quantize3 (cinfo
: j_decompress_ptr
;
562 input_buf
: JSAMPARRAY
;
563 output_buf
: JSAMPARRAY
;
565 { Fast path for out_color_components=3, no dithering }
567 cquantize
: my_cquantize_ptr
;
568 pixcode
: int
; {register}
569 ptrin
, ptrout
: JSAMPLE_PTR
; {register}
570 colorindex0
: JSAMPROW
;
571 colorindex1
: JSAMPROW
;
572 colorindex2
: JSAMPROW
;
577 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
578 colorindex0
:= (cquantize
^.colorindex
)^[0];
579 colorindex1
:= (cquantize
^.colorindex
)^[1];
580 colorindex2
:= (cquantize
^.colorindex
)^[2];
581 width
:= cinfo
^.output_width
;
583 for row
:= 0 to pred(num_rows
) do
585 ptrin
:= JSAMPLE_PTR(input_buf
^[row
]);
586 ptrout
:= JSAMPLE_PTR(output_buf
^[row
]);
587 for col
:= pred(width
) downto 0 do
589 pixcode
:= GETJSAMPLE((colorindex0
)^[GETJSAMPLE(ptrin
^)]);
591 Inc( pixcode
, GETJSAMPLE((colorindex1
)^[GETJSAMPLE(ptrin
^)]) );
593 Inc( pixcode
, GETJSAMPLE((colorindex2
)^[GETJSAMPLE(ptrin
^)]) );
595 ptrout
^ := JSAMPLE (pixcode
);
603 procedure quantize_ord_dither (cinfo
: j_decompress_ptr
;
604 input_buf
: JSAMPARRAY
;
605 output_buf
: JSAMPARRAY
;
607 { General case, with ordered dithering }
609 cquantize
: my_cquantize_ptr
;
610 input_ptr
, {register}
611 output_ptr
: JSAMPLE_PTR
; {register}
612 colorindex_ci
: JSAMPROW
;
613 dither
: ^ODITHER_vector
; { points to active row of dither matrix }
614 row_index
, col_index
: int
; { current indexes into dither matrix }
623 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
624 nc
:= cinfo
^.out_color_components
;
625 width
:= cinfo
^.output_width
;
627 { Nomssi: work around negative offset }
628 if my_cquantize_ptr (cinfo
^.cquantize
)^.is_padded
then
629 pad_offset
:= MAXJSAMPLE
633 for row
:= 0 to pred(num_rows
) do
635 { Initialize output values to 0 so can process components separately }
636 jzero_far( {far} pointer(output_buf
^[row
]),
637 size_t(width
* SIZEOF(JSAMPLE
)));
638 row_index
:= cquantize
^.row_index
;
639 for ci
:= 0 to pred(nc
) do
641 input_ptr
:= JSAMPLE_PTR(@ input_buf
^[row
]^[ci
]);
642 output_ptr
:= JSAMPLE_PTR(output_buf
^[row
]);
643 colorindex_ci
:= cquantize
^.colorindex
^[ci
];
645 Dec(JSAMPLE_PTR(colorindex_ci
), pad_offset
);
647 dither
:= @(cquantize
^.odither
[ci
]^[row_index
]);
650 for col
:= pred(width
) downto 0 do
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. }
660 colorindex_ci
^[GETJSAMPLE(input_ptr
^)+ pad_offset
+
661 dither
^[col_index
]]);
664 col_index
:= (col_index
+ 1) and ODITHER_MASK
;
667 { Advance row index for next row }
668 row_index
:= (row_index
+ 1) and ODITHER_MASK
;
669 cquantize
^.row_index
:= row_index
;
674 procedure quantize3_ord_dither (cinfo
: j_decompress_ptr
;
675 input_buf
: JSAMPARRAY
;
676 output_buf
: JSAMPARRAY
;
678 { Fast path for out_color_components=3, with ordered dithering }
680 cquantize
: my_cquantize_ptr
;
681 pixcode
: int
; {register}
682 input_ptr
: JSAMPLE_PTR
; {register}
683 output_ptr
: JSAMPLE_PTR
; {register}
684 colorindex0
: JSAMPROW
;
685 colorindex1
: JSAMPROW
;
686 colorindex2
: JSAMPROW
;
687 dither0
: ^ODITHER_vector
; { points to active row of dither matrix }
688 dither1
: ^ODITHER_vector
;
689 dither2
: ^ODITHER_vector
;
690 row_index
, col_index
: int
; { current indexes into dither matrix }
697 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
698 colorindex0
:= (cquantize
^.colorindex
)^[0];
699 colorindex1
:= (cquantize
^.colorindex
)^[1];
700 colorindex2
:= (cquantize
^.colorindex
)^[2];
701 width
:= cinfo
^.output_width
;
703 { Nomssi: work around negative offset }
704 if my_cquantize_ptr (cinfo
^.cquantize
)^.is_padded
then
705 pad_offset
:= MAXJSAMPLE
709 Dec(JSAMPLE_PTR(colorindex0
), pad_offset
);
710 Dec(JSAMPLE_PTR(colorindex1
), pad_offset
);
711 Dec(JSAMPLE_PTR(colorindex2
), pad_offset
);
713 for row
:= 0 to pred(num_rows
) do
715 row_index
:= cquantize
^.row_index
;
716 input_ptr
:= JSAMPLE_PTR(input_buf
^[row
]);
717 output_ptr
:= JSAMPLE_PTR(output_buf
^[row
]);
718 dither0
:= @(cquantize
^.odither
[0]^[row_index
]);
719 dither1
:= @(cquantize
^.odither
[1]^[row_index
]);
720 dither2
:= @(cquantize
^.odither
[2]^[row_index
]);
724 for col
:= pred(width
) downto 0 do
726 pixcode
:= GETJSAMPLE(colorindex0
^[GETJSAMPLE(input_ptr
^) + pad_offset
727 + dither0
^[col_index
]]);
729 Inc(pixcode
, GETJSAMPLE(colorindex1
^[GETJSAMPLE(input_ptr
^) + pad_offset
730 + dither1
^[col_index
]]));
732 Inc(pixcode
, GETJSAMPLE(colorindex2
^[GETJSAMPLE(input_ptr
^) + pad_offset
733 + dither2
^[col_index
]]));
735 output_ptr
^ := JSAMPLE (pixcode
);
737 col_index
:= (col_index
+ 1) and ODITHER_MASK
;
739 row_index
:= (row_index
+ 1) and ODITHER_MASK
;
740 cquantize
^.row_index
:= row_index
;
746 procedure quantize_fs_dither (cinfo
: j_decompress_ptr
;
747 input_buf
: JSAMPARRAY
;
748 output_buf
: JSAMPARRAY
;
750 { General case, with Floyd-Steinberg dithering }
752 cquantize
: my_cquantize_ptr
;
753 cur
: LOCFSERROR
; {register} { current error or pixel value }
754 belowerr
: LOCFSERROR
; { error for pixel below cur }
755 bpreverr
: LOCFSERROR
; { error for below/prev col }
756 bnexterr
: LOCFSERROR
; { error for below/next col }
759 errorptr
: FSERRORPTR
; {register} { => fserrors[] at column before current }
760 input_ptr
, {register}
761 output_ptr
: JSAMPLE_PTR
; {register}
762 colorindex_ci
: JSAMPROW
;
763 colormap_ci
: JSAMPROW
;
766 dir
: int
; { 1 for left-to-right, -1 for right-to-left }
767 dirnc
: int
; { dir * nc }
772 range_limit
: range_limit_table_ptr
;
774 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
775 nc
:= cinfo
^.out_color_components
;
776 width
:= cinfo
^.output_width
;
777 range_limit
:= cinfo
^.sample_range_limit
;
779 for row
:= 0 to pred(num_rows
) do
781 { Initialize output values to 0 so can process components separately }
782 jzero_far( (output_buf
)^[row
],
783 size_t(width
* SIZEOF(JSAMPLE
)));
784 for ci
:= 0 to pred(nc
) do
786 input_ptr
:= JSAMPLE_PTR(@ input_buf
^[row
]^[ci
]);
787 output_ptr
:= JSAMPLE_PTR(output_buf
^[row
]);
788 errorptr
:= FSERRORPTR(cquantize
^.fserrors
[ci
]); { => entry before first column }
789 if (cquantize
^.on_odd_row
) then
791 { work right to left in this row }
792 Inc(input_ptr
, (width
-1) * JDIMENSION(nc
)); { so point to rightmost pixel }
793 Inc(output_ptr
, width
-1);
796 Inc(errorptr
, (width
+1)); { => entry after last column }
800 { work left to right in this row }
803 {errorptr := cquantize^.fserrors[ci];}
806 colorindex_ci
:= cquantize
^.colorindex
^[ci
];
808 colormap_ci
:= (cquantize
^.sv_colormap
)^[ci
];
809 { Preset error values: no error propagated to first pixel from left }
811 { and no error propagated to row below yet }
815 for col
:= pred(width
) downto 0 do
817 prev_errorptr
:= errorptr
;
818 Inc(errorptr
, dir
); { advance errorptr to current column }
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. }
828 cur
:= (cur
+ errorptr
^ + 8) div 16;
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. }
834 Inc( cur
, GETJSAMPLE(input_ptr
^));
835 cur
:= GETJSAMPLE(range_limit
^[cur
]);
836 { Select output value, accumulate into output code for this pixel }
837 pixcode
:= GETJSAMPLE(colorindex_ci
^[cur
]);
838 Inc(output_ptr
^, JSAMPLE (pixcode
));
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. }
842 Dec(cur
, GETJSAMPLE(colormap_ci
^[pixcode
]));
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. }
849 Inc(cur
, delta
); { form error * 3 }
850 prev_errorptr
^ := FSERROR (bpreverr
+ cur
);
851 Inc(cur
, delta
); { form error * 5 }
852 bpreverr
:= belowerr
+ cur
;
853 belowerr
:= bnexterr
;
854 Inc(cur
, delta
); { form error * 7 }
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. }
859 Inc(input_ptr
, dirnc
); { advance input ptr to next column }
860 Inc(output_ptr
, dir
); { advance output ptr to next column }
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. }
867 errorptr
^ := FSERROR (bpreverr
); { unload prev err into array }
870 cquantize
^.on_odd_row
:= not cquantize
^.on_odd_row
;
875 { Allocate workspace for Floyd-Steinberg errors. }
878 procedure alloc_fs_workspace (cinfo
: j_decompress_ptr
);
880 cquantize
: my_cquantize_ptr
;
884 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
885 arraysize
:= size_t ((cinfo
^.output_width
+ 2) * SIZEOF(FSERROR
));
886 for i
:= 0 to pred(cinfo
^.out_color_components
) do
888 cquantize
^.fserrors
[i
] := FS_ERROR_FIELD_PTR(
889 cinfo
^.mem
^.alloc_large(j_common_ptr(cinfo
), JPOOL_IMAGE
, arraysize
));
894 { Initialize for one-pass color quantization. }
897 procedure start_pass_1_quant (cinfo
: j_decompress_ptr
;
898 is_pre_scan
: boolean);
900 cquantize
: my_cquantize_ptr
;
904 cquantize
:= my_cquantize_ptr (cinfo
^.cquantize
);
905 { Install my colormap. }
906 cinfo
^.colormap
:= cquantize
^.sv_colormap
;
907 cinfo
^.actual_number_of_colors
:= cquantize
^.sv_actual
;
909 { Initialize for desired dithering mode. }
910 case (cinfo
^.dither_mode
) of
912 if (cinfo
^.out_color_components
= 3) then
913 cquantize
^.pub
.color_quantize
:= color_quantize3
915 cquantize
^.pub
.color_quantize
:= color_quantize
;
918 if (cinfo
^.out_color_components
= 3) then
919 cquantize
^.pub
.color_quantize
:= quantize3_ord_dither
921 cquantize
^.pub
.color_quantize
:= quantize_ord_dither
;
922 cquantize
^.row_index
:= 0; { initialize state for ordered dither }
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. }
927 if (not cquantize
^.is_padded
) then
928 create_colorindex(cinfo
);
929 { Create ordered-dither tables if we didn't already. }
930 if (cquantize
^.odither
[0] = NIL) then
931 create_odither_tables(cinfo
);
935 cquantize
^.pub
.color_quantize
:= quantize_fs_dither
;
936 cquantize
^.on_odd_row
:= FALSE; { initialize state for F-S dither }
937 { Allocate Floyd-Steinberg workspace if didn't already. }
938 if (cquantize
^.fserrors
[0] = NIL) then
939 alloc_fs_workspace(cinfo
);
940 { Initialize the propagated errors to zero. }
941 arraysize
:= size_t ((cinfo
^.output_width
+ 2) * SIZEOF(FSERROR
));
942 for i
:= 0 to pred(cinfo
^.out_color_components
) do
943 jzero_far({far} pointer( cquantize
^.fserrors
[i
] ), arraysize
);
946 ERREXIT(j_common_ptr(cinfo
), JERR_NOT_COMPILED
);
951 { Finish up at the end of the pass. }
954 procedure finish_pass_1_quant (cinfo
: j_decompress_ptr
);
956 { no work in 1-pass case }
960 { Switch to a new external colormap between output passes.
961 Shouldn't get to this module! }
964 procedure new_color_map_1_quant (cinfo
: j_decompress_ptr
);
966 ERREXIT(j_common_ptr(cinfo
), JERR_MODE_CHANGE
);
970 { Module initialization routine for 1-pass color quantization. }
973 procedure jinit_1pass_quantizer (cinfo
: j_decompress_ptr
);
975 cquantize
: my_cquantize_ptr
;
977 cquantize
:= my_cquantize_ptr(
978 cinfo
^.mem
^.alloc_small (j_common_ptr(cinfo
), JPOOL_IMAGE
,
979 SIZEOF(my_cquantizer
)));
980 cinfo
^.cquantize
:= jpeg_color_quantizer_ptr(cquantize
);
981 cquantize
^.pub
.start_pass
:= start_pass_1_quant
;
982 cquantize
^.pub
.finish_pass
:= finish_pass_1_quant
;
983 cquantize
^.pub
.new_color_map
:= new_color_map_1_quant
;
984 cquantize
^.fserrors
[0] := NIL; { Flag FS workspace not allocated }
985 cquantize
^.odither
[0] := NIL; { Also flag odither arrays not allocated }
987 { Make sure my internal arrays won't overflow }
988 if (cinfo
^.out_color_components
> MAX_Q_COMPS
) then
989 ERREXIT1(j_common_ptr(cinfo
), JERR_QUANT_COMPONENTS
, MAX_Q_COMPS
);
990 { Make sure colormap indexes can be represented by JSAMPLEs }
991 if (cinfo
^.desired_number_of_colors
> (MAXJSAMPLE
+1)) then
992 ERREXIT1(j_common_ptr(cinfo
), JERR_QUANT_MANY_COLORS
, MAXJSAMPLE
+1);
994 { Create the colormap and color index table. }
995 create_colormap(cinfo
);
996 create_colorindex(cinfo
);
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. }
1004 if (cinfo
^.dither_mode
= JDITHER_FS
) then
1005 alloc_fs_workspace(cinfo
);