19f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 29f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jquant1.c 39f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 49f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Copyright (C) 1991-1996, Thomas G. Lane. 59f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file is part of the Independent JPEG Group's software. 69f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * For conditions of distribution and use, see the accompanying README file. 79f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 89f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file contains 1-pass color quantization (color mapping) routines. 99f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * These routines provide mapping to a fixed color map using equally spaced 109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * color values. Optional Floyd-Steinberg or ordered dithering is available. 119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define JPEG_INTERNALS 149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jinclude.h" 159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jpeglib.h" 169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef QUANT_1PASS_SUPPORTED 189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The main purpose of 1-pass quantization is to provide a fast, if not very 229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * high quality, colormapped output capability. A 2-pass quantizer usually 239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * gives better visual quality; however, for quantized grayscale output this 249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * quantizer is perfectly adequate. Dithering is highly recommended with this 259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * quantizer, though you can turn it off if you really want to. 269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In 1-pass quantization the colormap must be chosen in advance of seeing the 289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * image. We use a map consisting of all combinations of Ncolors[i] color 299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * values for the i'th component. The Ncolors[] values are chosen so that 309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * their product, the total number of colors, is no more than that requested. 319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (In most cases, the product will be somewhat less.) 329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Since the colormap is orthogonal, the representative value for each color 349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * component can be determined without considering the other components; 359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * then these indexes can be combined into a colormap index by a standard 369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * N-dimensional-array-subscript calculation. Most of the arithmetic involved 379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * can be precalculated and stored in the lookup table colorindex[]. 389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * colorindex[i][j] maps pixel value j in component i to the nearest 399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * representative value (grid plane) for that component; this index is 409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * multiplied by the array stride for component i, so that the 419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * index of the colormap entry closest to a given pixel value is just 429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * sum( colorindex[component-number][pixel-component-value] ) 439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Aside from being fast, this scheme allows for variable spacing between 449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * representative values with no additional lookup cost. 459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * If gamma correction has been applied in color conversion, it might be wise 479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to adjust the color grid spacing so that the representative colors are 489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * equidistant in linear space. At this writing, gamma correction is not 499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * implemented by jdcolor, so nothing is done here. 509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Declarations for ordered dithering. 549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We use a standard 16x16 ordered dither array. The basic concept of ordered 569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * dithering is described in many references, for instance Dale Schumacher's 579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). 589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In place of Schumacher's comparisons against a "threshold" value, we add a 599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * "dither" value to the input pixel and then round the result to the nearest 609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * output value. The dither value is equivalent to (0.5 - threshold) times 619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the distance between output values. For ordered dithering, we assume that 629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the output colors are equally spaced; if not, results will probably be 639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * worse, since the dither may be too much or too little at a given point. 649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The normal calculation would be to form pixel value + dither, range-limit 669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. 679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We can skip the separate range-limiting step by extending the colorindex 689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * table in both directions. 699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define ODITHER_SIZE 16 /* dimension of dither matrix */ 729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ 739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ 749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ 759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; 779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; 789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectstatic const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { 809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Bayer's order-4 dither array. Generated by the code given in 819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. 829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The values in this array must range from 0 to ODITHER_CELLS-1. 839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, 859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, 869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, 879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, 889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, 899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, 909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, 919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, 929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, 939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, 949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, 959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, 969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, 979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, 989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, 999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } 1009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}; 1019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Declarations for Floyd-Steinberg dithering. 1049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Errors are accumulated into the array fserrors[], at a resolution of 1069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1/16th of a pixel count. The error at a given pixel is propagated 1079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to its not-yet-processed neighbors using the standard F-S fractions, 1089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * ... (here) 7/16 1099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 3/16 5/16 1/16 1109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We work left-to-right on even rows, right-to-left on odd rows. 1119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We can get away with a single array (holding one row's worth of errors) 1139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by using it to store the current row's errors at pixel columns not yet 1149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * processed, but the next row's errors at columns already processed. We 1159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * need only a few extra variables to hold the errors immediately around the 1169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * current column. (If we are lucky, those variables are in registers, but 1179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * even if not, they're probably cheaper to access than array elements are.) 1189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The fserrors[] array is indexed [component#][position]. 1209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We provide (#columns + 2) entries per component; the extra entry at each 1219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * end saves us from special-casing the first and last pixels. 1229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Note: on a wide image, we might not have enough room in a PC's near data 1249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * segment to hold the error array; so it is allocated with alloc_large. 1259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if BITS_IN_JSAMPLE == 8 1289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef INT16 FSERROR; /* 16 bits should be enough */ 1299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef int LOCFSERROR; /* use 'int' for calculation temps */ 1309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else 1319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef INT32 FSERROR; /* may need more than 16 bits */ 1329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ 1339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif 1349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ 1369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Private subobject */ 1399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define MAX_Q_COMPS 4 /* max components I can handle */ 1419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef struct { 1439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project struct jpeg_color_quantizer pub; /* public fields */ 1449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Initially allocated colormap is saved here */ 1469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ 1479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int sv_actual; /* number of entries in use */ 1489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY colorindex; /* Precomputed mapping for speed */ 1509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* colorindex[i][j] = index of color closest to pixel value j in component i, 1519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * premultiplied as described above. Since colormap indexes must fit into 1529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * JSAMPLEs, the entries of this array will too. 1539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project boolean is_padded; /* is the colorindex padded for odither? */ 1559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ 1579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Variables for ordered dithering */ 1599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row_index; /* cur row's vertical index in dither matrix */ 1609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ 1619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Variables for Floyd-Steinberg dithering */ 1639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ 1649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project boolean on_odd_row; /* flag to remember which row we are on */ 1659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} my_cquantizer; 1669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef my_cquantizer * my_cquantize_ptr; 1689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 1719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Policy-making subroutines for create_colormap and create_colorindex. 1729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * These routines determine the colormap to be used. The rest of the module 1739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * only assumes that the colormap is orthogonal. 1749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * * select_ncolors decides how to divvy up the available colors 1769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * among the components. 1779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * * output_value defines the set of representative values for a component. 1789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * * largest_input_value defines the mapping from input values to 1799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * representative values for a component. 1809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Note that the latter two routines may impose different policies for 1819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * different components, though this is not currently done. 1829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(int) 1869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectselect_ncolors (j_decompress_ptr cinfo, int Ncolors[]) 1879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Determine allocation of desired colors to components, */ 1889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* and fill in Ncolors[] array to indicate choice. */ 1899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Return value is total number of colors (product of Ncolors[] values). */ 1909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 1919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int nc = cinfo->out_color_components; /* number of color components */ 1929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int max_colors = cinfo->desired_number_of_colors; 1939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int total_colors, iroot, i, j; 1949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project boolean changed; 1959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project long temp; 1969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; 1979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* We can allocate at least the nc'th root of max_colors per component. */ 1999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Compute floor(nc'th root of max_colors). */ 2009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project iroot = 1; 2019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project do { 2029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project iroot++; 2039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project temp = iroot; /* set temp = iroot ** nc */ 2049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (i = 1; i < nc; i++) 2059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project temp *= iroot; 2069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ 2079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project iroot--; /* now iroot = floor(root) */ 2089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Must have at least 2 color values per component */ 2109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (iroot < 2) 2119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); 2129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Initialize to iroot color values for each component */ 2149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project total_colors = 1; 2159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (i = 0; i < nc; i++) { 2169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project Ncolors[i] = iroot; 2179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project total_colors *= iroot; 2189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 2199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* We may be able to increment the count for one or more components without 2209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * exceeding max_colors, though we know not all can be incremented. 2219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Sometimes, the first component can be incremented more than once! 2229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) 2239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In RGB colorspace, try to increment G first, then R, then B. 2249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 2259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project do { 2269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project changed = FALSE; 2279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (i = 0; i < nc; i++) { 2289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); 2299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* calculate new total_colors if Ncolors[j] is incremented */ 2309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project temp = total_colors / Ncolors[j]; 2319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ 2329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (temp > (long) max_colors) 2339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project break; /* won't fit, done with this pass */ 2349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project Ncolors[j]++; /* OK, apply the increment */ 2359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project total_colors = (int) temp; 2369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project changed = TRUE; 2379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 2389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } while (changed); 2399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project return total_colors; 2419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 2429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(int) 2459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectoutput_value (j_decompress_ptr cinfo, int ci, int j, int maxj) 2469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Return j'th output value, where j will range from 0 to maxj */ 2479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* The output values must fall in 0..MAXJSAMPLE in increasing order */ 2489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 2499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* We always provide values 0 and MAXJSAMPLE for each component; 2509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * any additional values are equally spaced between these limits. 2519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (Forcing the upper and lower values to the limits ensures that 2529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * dithering can't produce a color outside the selected gamut.) 2539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 2549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); 2559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 2569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(int) 2599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectlargest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) 2609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Return largest input value that should map to j'th output value */ 2619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ 2629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 2639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Breakpoints are halfway between values returned by output_value */ 2649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); 2659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 2669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 2699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Create the colormap. 2709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 2719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void) 2739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectcreate_colormap (j_decompress_ptr cinfo) 2749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 2759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 2769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY colormap; /* Created colormap */ 2779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int total_colors; /* Number of distinct output colors */ 2789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int i,j,k, nci, blksize, blkdist, ptr, val; 2799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Select number of colors for each component */ 2819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project total_colors = select_ncolors(cinfo, cquantize->Ncolors); 2829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Report selected color counts */ 2849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->out_color_components == 3) 2859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, 2869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project total_colors, cquantize->Ncolors[0], 2879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->Ncolors[1], cquantize->Ncolors[2]); 2889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project else 2899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); 2909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Allocate and fill in the colormap. */ 2929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* The colors are ordered in the map in standard row-major order, */ 2939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* i.e. rightmost (highest-indexed) color changes most rapidly. */ 2949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project colormap = (*cinfo->mem->alloc_sarray) 2969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ((j_common_ptr) cinfo, JPOOL_IMAGE, 2979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); 2989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* blksize is number of adjacent repeated entries for a component */ 3009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* blkdist is distance between groups of identical entries for a component */ 3019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project blkdist = total_colors; 3029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (i = 0; i < cinfo->out_color_components; i++) { 3049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* fill in colormap entries for i'th color component */ 3059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ 3069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project blksize = blkdist / nci; 3079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (j = 0; j < nci; j++) { 3089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Compute j'th output value (out of nci) for component */ 3099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project val = output_value(cinfo, i, j, nci-1); 3109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Fill in all colormap entries that have this value of this component */ 3119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { 3129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* fill in blksize entries beginning at ptr */ 3139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (k = 0; k < blksize; k++) 3149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project colormap[i][ptr+k] = (JSAMPLE) val; 3159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project blkdist = blksize; /* blksize of this color is blkdist of next */ 3189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Save the colormap in private storage, 3219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * where it will survive color quantization mode changes. 3229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 3239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->sv_colormap = colormap; 3249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->sv_actual = total_colors; 3259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 3269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 3299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Create the color index table. 3309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 3319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void) 3339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectcreate_colorindex (j_decompress_ptr cinfo) 3349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 3359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 3369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW indexptr; 3379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int i,j,k, nci, blksize, val, pad; 3389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* For ordered dither, we pad the color index tables by MAXJSAMPLE in 3409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). 3419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This is not necessary in the other dithering modes. However, we 3429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * flag whether it was done in case user changes dithering mode. 3439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 3449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->dither_mode == JDITHER_ORDERED) { 3459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pad = MAXJSAMPLE*2; 3469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->is_padded = TRUE; 3479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } else { 3489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pad = 0; 3499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->is_padded = FALSE; 3509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->colorindex = (*cinfo->mem->alloc_sarray) 3539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ((j_common_ptr) cinfo, JPOOL_IMAGE, 3549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (JDIMENSION) (MAXJSAMPLE+1 + pad), 3559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (JDIMENSION) cinfo->out_color_components); 3569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* blksize is number of adjacent repeated entries for a component */ 3589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project blksize = cquantize->sv_actual; 3599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (i = 0; i < cinfo->out_color_components; i++) { 3619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* fill in colorindex entries for i'th color component */ 3629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ 3639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project blksize = blksize / nci; 3649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* adjust colorindex pointers to provide padding at negative indexes. */ 3669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (pad) 3679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->colorindex[i] += MAXJSAMPLE; 3689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* in loop, val = index of current output value, */ 3709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* and k = largest j that maps to current val */ 3719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project indexptr = cquantize->colorindex[i]; 3729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project val = 0; 3739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project k = largest_input_value(cinfo, i, 0, nci-1); 3749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (j = 0; j <= MAXJSAMPLE; j++) { 3759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project while (j > k) /* advance val if past boundary */ 3769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project k = largest_input_value(cinfo, i, ++val, nci-1); 3779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* premultiply so that no multiplication needed in main processing */ 3789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project indexptr[j] = (JSAMPLE) (val * blksize); 3799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Pad at both ends if necessary */ 3819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (pad) 3829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (j = 1; j <= MAXJSAMPLE; j++) { 3839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project indexptr[-j] = indexptr[0]; 3849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; 3859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 3889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 3919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Create an ordered-dither array for a component having ncolors 3929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * distinct output values. 3939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 3949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(ODITHER_MATRIX_PTR) 3969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectmake_odither_array (j_decompress_ptr cinfo, int ncolors) 3979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 3989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ODITHER_MATRIX_PTR odither; 3999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int j,k; 4009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project INT32 num,den; 4019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project odither = (ODITHER_MATRIX_PTR) 4039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 4049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project SIZEOF(ODITHER_MATRIX)); 4059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). 4069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Hence the dither value for the matrix cell with fill order f 4079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). 4089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * On 16-bit-int machine, be careful to avoid overflow. 4099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 4109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); 4119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (j = 0; j < ODITHER_SIZE; j++) { 4129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (k = 0; k < ODITHER_SIZE; k++) { 4139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) 4149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * MAXJSAMPLE; 4159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Ensure round towards zero despite C's lack of consistency 4169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * about rounding negative values in integer division... 4179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 4189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); 4199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project return odither; 4229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 4239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 4269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Create the ordered-dither tables. 4279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Components having the same number of representative colors may 4289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * share a dither table. 4299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 4309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void) 4329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectcreate_odither_tables (j_decompress_ptr cinfo) 4339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 4349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 4359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ODITHER_MATRIX_PTR odither; 4369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int i, j, nci; 4379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (i = 0; i < cinfo->out_color_components; i++) { 4399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ 4409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project odither = NULL; /* search for matching prior component */ 4419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (j = 0; j < i; j++) { 4429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (nci == cquantize->Ncolors[j]) { 4439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project odither = cquantize->odither[j]; 4449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project break; 4459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (odither == NULL) /* need a new table? */ 4489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project odither = make_odither_array(cinfo, nci); 4499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->odither[i] = odither; 4509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 4529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 4559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Map some rows of pixels to the output colormapped representation. 4569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 4579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 4599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectcolor_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 4609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY output_buf, int num_rows) 4619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* General case, no dithering */ 4629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 4639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 4649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY colorindex = cquantize->colorindex; 4659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register int pixcode, ci; 4669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW ptrin, ptrout; 4679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row; 4689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION col; 4699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION width = cinfo->output_width; 4709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register int nc = cinfo->out_color_components; 4719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (row = 0; row < num_rows; row++) { 4739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ptrin = input_buf[row]; 4749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ptrout = output_buf[row]; 4759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (col = width; col > 0; col--) { 4769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode = 0; 4779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (ci = 0; ci < nc; ci++) { 4789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); 4799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *ptrout++ = (JSAMPLE) pixcode; 4819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 4849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 4879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectcolor_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 4889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY output_buf, int num_rows) 4899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Fast path for out_color_components==3, no dithering */ 4909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 4919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 4929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register int pixcode; 4939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW ptrin, ptrout; 4949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colorindex0 = cquantize->colorindex[0]; 4959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colorindex1 = cquantize->colorindex[1]; 4969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colorindex2 = cquantize->colorindex[2]; 4979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row; 4989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION col; 4999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION width = cinfo->output_width; 5009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (row = 0; row < num_rows; row++) { 5029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ptrin = input_buf[row]; 5039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ptrout = output_buf[row]; 5049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (col = width; col > 0; col--) { 5059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); 5069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); 5079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); 5089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *ptrout++ = (JSAMPLE) pixcode; 5099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 5109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 5119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 5129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 5159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectquantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 5169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY output_buf, int num_rows) 5179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* General case, with ordered dithering */ 5189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 5199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 5209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW input_ptr; 5219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW output_ptr; 5229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colorindex_ci; 5239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int * dither; /* points to active row of dither matrix */ 5249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row_index, col_index; /* current indexes into dither matrix */ 5259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int nc = cinfo->out_color_components; 5269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int ci; 5279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row; 5289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION col; 5299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION width = cinfo->output_width; 5309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (row = 0; row < num_rows; row++) { 5329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Initialize output values to 0 so can process components separately */ 5339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project jzero_far((void FAR *) output_buf[row], 5349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (size_t) (width * SIZEOF(JSAMPLE))); 5359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project row_index = cquantize->row_index; 5369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (ci = 0; ci < nc; ci++) { 5379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project input_ptr = input_buf[row] + ci; 5389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project output_ptr = output_buf[row]; 5399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project colorindex_ci = cquantize->colorindex[ci]; 5409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dither = cquantize->odither[ci][row_index]; 5419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project col_index = 0; 5429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (col = width; col > 0; col--) { 5449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, 5459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * select output value, accumulate into output code for this pixel. 5469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Range-limiting need not be done explicitly, as we have extended 5479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the colorindex table to produce the right answers for out-of-range 5489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * inputs. The maximum dither is +- MAXJSAMPLE; this sets the 5499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * required amount of padding. 5509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 5519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; 5529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project input_ptr += nc; 5539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project output_ptr++; 5549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project col_index = (col_index + 1) & ODITHER_MASK; 5559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 5569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 5579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Advance row index for next row */ 5589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project row_index = (row_index + 1) & ODITHER_MASK; 5599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->row_index = row_index; 5609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 5619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 5629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 5659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectquantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 5669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY output_buf, int num_rows) 5679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Fast path for out_color_components==3, with ordered dithering */ 5689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 5699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 5709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register int pixcode; 5719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW input_ptr; 5729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW output_ptr; 5739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colorindex0 = cquantize->colorindex[0]; 5749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colorindex1 = cquantize->colorindex[1]; 5759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colorindex2 = cquantize->colorindex[2]; 5769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int * dither0; /* points to active row of dither matrix */ 5779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int * dither1; 5789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int * dither2; 5799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row_index, col_index; /* current indexes into dither matrix */ 5809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row; 5819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION col; 5829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION width = cinfo->output_width; 5839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (row = 0; row < num_rows; row++) { 5859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project row_index = cquantize->row_index; 5869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project input_ptr = input_buf[row]; 5879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project output_ptr = output_buf[row]; 5889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dither0 = cquantize->odither[0][row_index]; 5899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dither1 = cquantize->odither[1][row_index]; 5909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dither2 = cquantize->odither[2][row_index]; 5919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project col_index = 0; 5929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (col = width; col > 0; col--) { 5949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + 5959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dither0[col_index]]); 5969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + 5979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dither1[col_index]]); 5989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + 5999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dither2[col_index]]); 6009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *output_ptr++ = (JSAMPLE) pixcode; 6019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project col_index = (col_index + 1) & ODITHER_MASK; 6029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 6039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project row_index = (row_index + 1) & ODITHER_MASK; 6049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->row_index = row_index; 6059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 6069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 6079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 6089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 6099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 6109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectquantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 6119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY output_buf, int num_rows) 6129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* General case, with Floyd-Steinberg dithering */ 6139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 6149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 6159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register LOCFSERROR cur; /* current error or pixel value */ 6169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project LOCFSERROR belowerr; /* error for pixel below cur */ 6179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project LOCFSERROR bpreverr; /* error for below/prev col */ 6189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project LOCFSERROR bnexterr; /* error for below/next col */ 6199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project LOCFSERROR delta; 6209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register FSERRPTR errorptr; /* => fserrors[] at column before current */ 6219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW input_ptr; 6229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW output_ptr; 6239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colorindex_ci; 6249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW colormap_ci; 6259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int pixcode; 6269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int nc = cinfo->out_color_components; 6279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int dir; /* 1 for left-to-right, -1 for right-to-left */ 6289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int dirnc; /* dir * nc */ 6299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int ci; 6309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row; 6319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION col; 6329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION width = cinfo->output_width; 6339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPLE *range_limit = cinfo->sample_range_limit; 6349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project SHIFT_TEMPS 6359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 6369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (row = 0; row < num_rows; row++) { 6379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Initialize output values to 0 so can process components separately */ 6389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project jzero_far((void FAR *) output_buf[row], 6399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (size_t) (width * SIZEOF(JSAMPLE))); 6409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (ci = 0; ci < nc; ci++) { 6419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project input_ptr = input_buf[row] + ci; 6429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project output_ptr = output_buf[row]; 6439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cquantize->on_odd_row) { 6449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* work right to left in this row */ 6459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project input_ptr += (width-1) * nc; /* so point to rightmost pixel */ 6469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project output_ptr += width-1; 6479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dir = -1; 6489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dirnc = -nc; 6499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */ 6509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } else { 6519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* work left to right in this row */ 6529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dir = 1; 6539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dirnc = nc; 6549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project errorptr = cquantize->fserrors[ci]; /* => entry before first column */ 6559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 6569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project colorindex_ci = cquantize->colorindex[ci]; 6579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project colormap_ci = cquantize->sv_colormap[ci]; 6589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Preset error values: no error propagated to first pixel from left */ 6599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cur = 0; 6609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* and no error propagated to row below yet */ 6619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project belowerr = bpreverr = 0; 6629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 6639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (col = width; col > 0; col--) { 6649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* cur holds the error propagated from the previous pixel on the 6659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * current line. Add the error propagated from the previous line 6669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to form the complete error correction term for this pixel, and 6679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * round the error term (which is expressed * 16) to an integer. 6689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct 6699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * for either sign of the error value. 6709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Note: errorptr points to *previous* column's array entry. 6719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 6729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); 6739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. 6749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The maximum error is +- MAXJSAMPLE; this sets the required size 6759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * of the range_limit array. 6769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 6779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cur += GETJSAMPLE(*input_ptr); 6789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cur = GETJSAMPLE(range_limit[cur]); 6799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Select output value, accumulate into output code for this pixel */ 6809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixcode = GETJSAMPLE(colorindex_ci[cur]); 6819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *output_ptr += (JSAMPLE) pixcode; 6829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Compute actual representation error at this pixel */ 6839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Note: we can do this even though we don't have the final */ 6849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* pixel code, because the colormap is orthogonal. */ 6859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cur -= GETJSAMPLE(colormap_ci[pixcode]); 6869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Compute error fractions to be propagated to adjacent pixels. 6879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Add these into the running sums, and simultaneously shift the 6889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * next-line error sums left by 1 column. 6899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 6909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project bnexterr = cur; 6919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project delta = cur * 2; 6929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cur += delta; /* form error * 3 */ 6939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project errorptr[0] = (FSERROR) (bpreverr + cur); 6949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cur += delta; /* form error * 5 */ 6959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project bpreverr = belowerr + cur; 6969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project belowerr = bnexterr; 6979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cur += delta; /* form error * 7 */ 6989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* At this point cur contains the 7/16 error value to be propagated 6999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to the next pixel on the current line, and all the errors for the 7009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * next line have been shifted over. We are therefore ready to move on. 7019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 7029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project input_ptr += dirnc; /* advance input ptr to next column */ 7039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project output_ptr += dir; /* advance output ptr to next column */ 7049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project errorptr += dir; /* advance errorptr to current column */ 7059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 7069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Post-loop cleanup: we must unload the final error value into the 7079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * final fserrors[] entry. Note we need not unload belowerr because 7089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * it is for the dummy column before or after the actual array. 7099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 7109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ 7119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 7129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); 7139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 7149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 7159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 7189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Allocate workspace for Floyd-Steinberg errors. 7199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 7209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void) 7229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectalloc_fs_workspace (j_decompress_ptr cinfo) 7239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 7249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 7259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project size_t arraysize; 7269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int i; 7279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); 7299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (i = 0; i < cinfo->out_color_components; i++) { 7309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->fserrors[i] = (FSERRPTR) 7319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); 7329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 7339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 7349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 7379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Initialize for one-pass color quantization. 7389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 7399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 7419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectstart_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) 7429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 7439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 7449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project size_t arraysize; 7459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int i; 7469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Install my colormap. */ 7489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->colormap = cquantize->sv_colormap; 7499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->actual_number_of_colors = cquantize->sv_actual; 7509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Initialize for desired dithering mode. */ 7529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project switch (cinfo->dither_mode) { 7539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project case JDITHER_NONE: 7549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->out_color_components == 3) 7559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->pub.color_quantize = color_quantize3; 7569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project else 7579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->pub.color_quantize = color_quantize; 7589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project break; 7599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project case JDITHER_ORDERED: 7609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->out_color_components == 3) 7619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->pub.color_quantize = quantize3_ord_dither; 7629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project else 7639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->pub.color_quantize = quantize_ord_dither; 7649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->row_index = 0; /* initialize state for ordered dither */ 7659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* If user changed to ordered dither from another mode, 7669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * we must recreate the color index table with padding. 7679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This will cost extra space, but probably isn't very likely. 7689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 7699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (! cquantize->is_padded) 7709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project create_colorindex(cinfo); 7719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Create ordered-dither tables if we didn't already. */ 7729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cquantize->odither[0] == NULL) 7739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project create_odither_tables(cinfo); 7749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project break; 7759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project case JDITHER_FS: 7769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->pub.color_quantize = quantize_fs_dither; 7779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ 7789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Allocate Floyd-Steinberg workspace if didn't already. */ 7799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cquantize->fserrors[0] == NULL) 7809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project alloc_fs_workspace(cinfo); 7819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Initialize the propagated errors to zero. */ 7829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); 7839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (i = 0; i < cinfo->out_color_components; i++) 7849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project jzero_far((void FAR *) cquantize->fserrors[i], arraysize); 7859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project break; 7869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project default: 7879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT(cinfo, JERR_NOT_COMPILED); 7889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project break; 7899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 7909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 7919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 7949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Finish up at the end of the pass. 7959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 7969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 7979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 7989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfinish_pass_1_quant (j_decompress_ptr cinfo) 7999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 8009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* no work in 1-pass case */ 8019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 8029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 8059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Switch to a new external colormap between output passes. 8069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Shouldn't get to this module! 8079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 8089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 8109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectnew_color_map_1_quant (j_decompress_ptr cinfo) 8119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 8129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT(cinfo, JERR_MODE_CHANGE); 8139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 8149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 8179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Module initialization routine for 1-pass color quantization. 8189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 8199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(void) 8219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjinit_1pass_quantizer (j_decompress_ptr cinfo) 8229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 8239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_cquantize_ptr cquantize; 8249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize = (my_cquantize_ptr) 8269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 8279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project SIZEOF(my_cquantizer)); 8289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; 8299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->pub.start_pass = start_pass_1_quant; 8309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->pub.finish_pass = finish_pass_1_quant; 8319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->pub.new_color_map = new_color_map_1_quant; 8329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ 8339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ 8349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Make sure my internal arrays won't overflow */ 8369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->out_color_components > MAX_Q_COMPS) 8379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); 8389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Make sure colormap indexes can be represented by JSAMPLEs */ 8399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) 8409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); 8419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Create the colormap and color index table. */ 8439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project create_colormap(cinfo); 8449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project create_colorindex(cinfo); 8459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Allocate Floyd-Steinberg workspace now if requested. 8479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We do this now since it is FAR storage and may affect the memory 8489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * manager's space calculations. If the user changes to FS dither 8499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * mode in a later pass, we will allocate the space then, and will 8509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * possibly overrun the max_memory_to_use setting. 8519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 8529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->dither_mode == JDITHER_FS) 8539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project alloc_fs_workspace(cinfo); 8549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 8559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 8569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif /* QUANT_1PASS_SUPPORTED */ 857