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 + -
显示快捷键?