gif_dither.c
来自「ucOS 模拟环境」· C语言 代码 · 共 1,012 行 · 第 1/3 页
C
1,012 行
/* Allocate and fill in the colormap. */
/* The colors are ordered in the map in standard row-major order, */
/* i.e. rightmost (highest-indexed) color changes most rapidly. */
colormap = gif_alloc_memr(cinfo->out_color_components,total_colors);
if(colormap == NULL)
return FALSE;
/* blksize is number of adjacent repeated entries for a component */
/* blkdist is distance between groups of identical entries for a component */
blkdist = total_colors;
for (i = 0; i < cinfo->out_color_components ; i++)
{
/* fill in colormap entries for i'th color component */
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
blksize = blkdist / nci;
for (j = 0; j < nci; j++)
{
/* Compute j'th output value (out of nci) for component */
val = output_value(cinfo, i, j, nci-1);
/* Fill in all colormap entries that have this value of this component */
for (ptr = j * blksize; ptr < total_colors; ptr += blkdist)
{
/* fill in blksize entries beginning at ptr */
for (k = 0; k < blksize; k++)
{
colormap[i][ptr+k] = (JSAMPLE) val;
}
}
}
blkdist = blksize; /* blksize of this color is blkdist of next */
}
/* Save the colormap in private storage,
* where it will survive color quantization mode changes.*/
cquantize->sv_colormap = colormap;
cquantize->sv_actual = total_colors;
return TRUE;
}
//====================================================================================
// Function Name: static int largest_input_value (decompress_info_ptr cinfo, int ci, int j, int maxj)
// Purpose : Return largest input value that should map to j'th output value
// Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
static int largest_input_value (decompress_info_ptr cinfo, int ci, int j, int maxj)
{
/* Breakpoints are halfway between values returned by output_value */
return (int) (((long) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj));
}
//====================================================================================
// Function Name: void gif_alloc_fs_workspace (decompress_info_ptr cinfo)
// Purpose :
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
Bool gif_alloc_fs_workspace (decompress_info_ptr cinfo)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
size_t arraysize;
int i;
arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
for (i = 0; i < cinfo->out_color_components; i++)
{
cquantize->fserrors[i] = (FSERRPTR) gif_alloc_buf(arraysize);
if(cquantize->fserrors[i] == NULL)
{
return FALSE;
}
}
return TRUE;
}
//====================================================================================
// Function Name: static void create_colorindex (decompress_info_ptr cinfo)
// Purpose :
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
static Bool gif_create_colorindex (decompress_info_ptr cinfo)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
JSAMPROW indexptr;
int i,j,k, nci, blksize, val, pad;
/* For ordered dither, we pad the color index tables by MAXJSAMPLE in
* each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
* This is not necessary in the other dithering modes. However, we
* flag whether it was done in case user changes dithering mode.
*/
if (cinfo->dither_mode == GIF_DITHER_ORDERED)
{
pad = MAXJSAMPLE*2;
cquantize->is_padded = TRUE;
}
else
{
pad = 0;
cquantize->is_padded = FALSE;
}
cquantize->colorindex[0] = gif_alloc_buf(MAXJSAMPLE+1 + pad);
if(cquantize->colorindex[0] == NULL)
{
return FALSE;
}
cquantize->colorindex[1] = gif_alloc_buf(MAXJSAMPLE+1 + pad);
if(cquantize->colorindex[1] == NULL)
{
return FALSE;
}
cquantize->colorindex[2] = gif_alloc_buf(MAXJSAMPLE+1 + pad);
if(cquantize->colorindex[2] == NULL)
{
return FALSE;
}
/* blksize is number of adjacent repeated entries for a component */
blksize = cquantize->sv_actual;
for (i = 0; i < cinfo->out_color_components; i++)
{
/* fill in colorindex entries for i'th color component */
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
blksize = blksize / nci;
/* adjust colorindex pointers to provide padding at negative indexes. */
if (pad)
{
cquantize->colorindex[i] += MAXJSAMPLE;
}
/* in loop, val = index of current output value, */
/* and k = largest j that maps to current val */
indexptr = cquantize->colorindex[i];
val = 0;
k = largest_input_value(cinfo, i, 0, nci-1);
for (j = 0; j <= MAXJSAMPLE; j++)
{
while (j > k) /* advance val if past boundary */
{
k = largest_input_value(cinfo, i, ++val, nci-1);
}
/* premultiply so that no multiplication needed in main processing */
indexptr[j] = (JSAMPLE) (val * blksize);
}
/* Pad at both ends if necessary */
if (pad)
{
for (j = 1; j <= MAXJSAMPLE; j++)
{
indexptr[-j] = indexptr[0];
indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
}
}
}
return TRUE;
}
//====================================================================================
// Function Name: static ODITHER_MATRIX_PTR make_odither_array (decompress_info_ptr cinfo, int ncolors)
// Purpose :
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
static ODITHER_MATRIX_PTR gif_make_odither_array (decompress_info_ptr cinfo, int ncolors)
{
ODITHER_MATRIX_PTR odither;
int j,k;
INT32 num,den;
odither = (ODITHER_MATRIX_PTR)gif_alloc_buf(SIZEOF(ODITHER_MATRIX));
if(odither == NULL)
{
return NULL;
}
/* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
* Hence the dither value for the matrix cell with fill order f
* (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
* On 16-bit-int machine, be careful to avoid overflow.
*/
den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
for (j = 0; j < ODITHER_SIZE; j++)
{
for (k = 0; k < ODITHER_SIZE; k++)
{
num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
* MAXJSAMPLE;
/* Ensure round towards zero despite C's lack of consistency
* about rounding negative values in integer division...
*/
odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
}
}
return odither;
}
//====================================================================================
// Function Name: static void create_odither_tables (decompress_info_ptr cinfo)
// Purpose :
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
static Bool create_odither_tables (decompress_info_ptr cinfo)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
ODITHER_MATRIX_PTR odither;
int i, j, nci;
for (i = 0; i < cinfo->out_color_components; i++)
{
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
odither = NULL; /* search for matching prior component */
for (j = 0; j < i; j++)
{
if (nci == cquantize->Ncolors[j])
{
odither = cquantize->odither[j];
break;
}
}
if (odither == NULL) /* need a new table? */
{
odither = gif_make_odither_array(cinfo, nci);
if(odither== NULL)
return FALSE;
}
cquantize->odither[i] = odither;
}
return TRUE;
}
//====================================================================================
// Function Name: void color_quantize (decompress_info_ptr cinfo, JSAMPARRAY input_buf,
// JSAMPARRAY output_buf, int num_rows)
// Purpose : General case, no dithering
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
void gif_color_quantize (decompress_info_ptr cinfo, uchar* input_buf,
uchar* output_buf, int num_rows)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
JSAMPARRAY colorindex = cquantize->colorindex;
register int pixcode, ci;
register JSAMPROW ptrin, ptrout;
int row;
JDIMENSION col;
JDIMENSION width = cinfo->output_width;
register int nc = cinfo->out_color_components;
for (row = 0; row < num_rows; row++)
{
ptrin = (uchar*)(input_buf + row * width);
ptrout = (uchar*)(output_buf + row * width);
for (col = width; col > 0; col--)
{
pixcode = 0;
for (ci = 0; ci < nc; ci++)
{
pixcode += colorindex[ci][*ptrin++];
}
*ptrout++ = (JSAMPLE) pixcode;
}
}
}
//====================================================================================
// Function Name: void color_quantize3 (decompress_info_ptr cinfo, uchar* input_buf,
// uchar* output_buf, int num_rows)
// Purpose : Fast path for out_color_components==3, no dithering
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
void gif_color_quantize3 (decompress_info_ptr cinfo, uchar* input_buf,
uchar* output_buf, int num_rows)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
register int pixcode;
register JSAMPROW ptrin, ptrout;
JSAMPROW colorindex0 = cquantize->colorindex[0];
JSAMPROW colorindex1 = cquantize->colorindex[1];
JSAMPROW colorindex2 = cquantize->colorindex[2];
int row;
JDIMENSION col;
JDIMENSION width = cinfo->output_width;
for (row = 0; row < num_rows; row++)
{
ptrin = (uchar*)(input_buf + row * width *3) ;
ptrout = (uchar*)(output_buf + row* width );
for (col = width; col > 0; col--)
{
pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
*ptrout++ = (JSAMPLE) pixcode;
}
}
}
//====================================================================================
// Function Name: static void gif_zero_far (void FAR * target, size_t bytestozero)
// Purpose : Zero out a chunk of FAR memory.This might be sample-array data,
// block-array data, or alloc_large data.
// Parameter :
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?