C# Class BitMiracle.LibJpeg.Classic.Internal.my_1pass_cquantizer

The main purpose of 1-pass quantization is to provide a fast, if not very high quality, colormapped output capability. A 2-pass quantizer usually gives better visual quality; however, for quantized grayscale output this quantizer is perfectly adequate. Dithering is highly recommended with this quantizer, though you can turn it off if you really want to. In 1-pass quantization the colormap must be chosen in advance of seeing the image. We use a map consisting of all combinations of Ncolors[i] color values for the i'th component. The Ncolors[] values are chosen so that their product, the total number of colors, is no more than that requested. (In most cases, the product will be somewhat less.) Since the colormap is orthogonal, the representative value for each color component can be determined without considering the other components; then these indexes can be combined into a colormap index by a standard N-dimensional-array-subscript calculation. Most of the arithmetic involved can be precalculated and stored in the lookup table colorindex[]. colorindex[i][j] maps pixel value j in component i to the nearest representative value (grid plane) for that component; this index is multiplied by the array stride for component i, so that the index of the colormap entry closest to a given pixel value is just sum( colorindex[component-number][pixel-component-value] ) Aside from being fast, this scheme allows for variable spacing between representative values with no additional lookup cost. If gamma correction has been applied in color conversion, it might be wise to adjust the color grid spacing so that the representative colors are equidistant in linear space. At this writing, gamma correction is not implemented, so nothing is done here. Declarations for Floyd-Steinberg dithering. Errors are accumulated into the array fserrors[], at a resolution of 1/16th of a pixel count. The error at a given pixel is propagated to its not-yet-processed neighbors using the standard F-S fractions, ... (here) 7/16 3/16 5/16 1/16 We work left-to-right on even rows, right-to-left on odd rows. We can get away with a single array (holding one row's worth of errors) by using it to store the current row's errors at pixel columns not yet processed, but the next row's errors at columns already processed. We need only a few extra variables to hold the errors immediately around the current column. (If we are lucky, those variables are in registers, but even if not, they're probably cheaper to access than array elements are.) The fserrors[] array is indexed [component#][position]. We provide (#columns + 2) entries per component; the extra entry at each end saves us from special-casing the first and last pixels. Declarations for ordered dithering. We use a standard 16x16 ordered dither array. The basic concept of ordered dithering is described in many references, for instance Dale Schumacher's chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). In place of Schumacher's comparisons against a "threshold" value, we add a "dither" value to the input pixel and then round the result to the nearest output value. The dither value is equivalent to (0.5 - threshold) times the distance between output values. For ordered dithering, we assume that the output colors are equally spaced; if not, results will probably be worse, since the dither may be too much or too little at a given point. The normal calculation would be to form pixel value + dither, range-limit this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. We can skip the separate range-limiting step by extending the colorindex table in both directions.
Inheritance: jpeg_color_quantizer
Show file Open project: prepare/HTML-Renderer

Public Methods

Method Description
color_quantize ( byte input_buf, int in_row, byte output_buf, int out_row, int num_rows ) : void
finish_pass ( ) : void

Finish up at the end of the pass.

my_1pass_cquantizer ( jpeg_decompress_struct cinfo ) : System

Module initialization routine for 1-pass color quantization.

new_color_map ( ) : void

Switch to a new external colormap between output passes. Shouldn't get to this!

start_pass ( bool is_pre_scan ) : void

Initialize for one-pass color quantization.

Private Methods

Method Description
alloc_fs_workspace ( ) : void

Allocate workspace for Floyd-Steinberg errors.

create_colorindex ( ) : void

Create the color index table.

create_colormap ( ) : void

Create the colormap.

create_odither_tables ( ) : void

Create the ordered-dither tables. Components having the same number of representative colors may share a dither table.

largest_input_value ( int j, int maxj ) : int

Return largest input value that should map to j'th output value Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE

make_odither_array ( int ncolors ) : int[][]

Create an ordered-dither array for a component having ncolors distinct output values.

output_value ( int j, int maxj ) : int

Return j'th output value, where j will range from 0 to maxj The output values must fall in 0..MAXJSAMPLE in increasing order

quantize ( byte input_buf, int in_row, byte output_buf, int out_row, int num_rows ) : void

Map some rows of pixels to the output colormapped representation. General case, no dithering.

quantize3 ( byte input_buf, int in_row, byte output_buf, int out_row, int num_rows ) : void

Map some rows of pixels to the output colormapped representation. Fast path for out_color_components==3, no dithering

quantize3_ord_dither ( byte input_buf, int in_row, byte output_buf, int out_row, int num_rows ) : void

Map some rows of pixels to the output colormapped representation. Fast path for out_color_components==3, with ordered dithering

quantize_fs_dither ( byte input_buf, int in_row, byte output_buf, int out_row, int num_rows ) : void

Map some rows of pixels to the output colormapped representation. General case, with Floyd-Steinberg dithering

quantize_ord_dither ( byte input_buf, int in_row, byte output_buf, int out_row, int num_rows ) : void

Map some rows of pixels to the output colormapped representation. General case, with ordered dithering.

select_ncolors ( int Ncolors ) : int

Determine allocation of desired colors to components, and fill in Ncolors[] array to indicate choice. Return value is total number of colors (product of Ncolors[] values).

Method Details

color_quantize() public method

public color_quantize ( byte input_buf, int in_row, byte output_buf, int out_row, int num_rows ) : void
input_buf byte
in_row int
output_buf byte
out_row int
num_rows int
return void

finish_pass() public method

Finish up at the end of the pass.
public finish_pass ( ) : void
return void

my_1pass_cquantizer() public method

Module initialization routine for 1-pass color quantization.
public my_1pass_cquantizer ( jpeg_decompress_struct cinfo ) : System
cinfo jpeg_decompress_struct The cinfo.
return System

new_color_map() public method

Switch to a new external colormap between output passes. Shouldn't get to this!
public new_color_map ( ) : void
return void

start_pass() public method

Initialize for one-pass color quantization.
public start_pass ( bool is_pre_scan ) : void
is_pre_scan bool
return void