Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 2:解码数据(一)

2014-11-23 23:36:46 · 作者: · 浏览: 10
Tiny Jpeg Decoder是一个可以用于嵌入式 系统的JPEG解码器。也可以在Windows上编译通过。在此分析一下它部分的源代码,辅助学习JPEG解码知识。
通过TinyJpeg可以将JPEG(*.jpg)文件解码为YUV(*.yuv)或者RGB(*.tga)文件。
真正的解码数据开始于tinyjpeg_decode()函数:
注意:本代码中包含部分自己写的代码,用于提取DCT系数表,解码后亮度数据表等数据。
/** 
 * Decode and convert the jpeg image into @pixfmt@ image 
 *解码函数 
 * Note: components will be automaticaly allocated if no memory is attached. 
 */  
int tinyjpeg_decode(struct jdec_private *priv, int pixfmt)  
{  
  unsigned int x, y, xstride_by_mcu, ystride_by_mcu;  
  unsigned int bytes_per_blocklines[3], bytes_per_mcu[3];  
  decode_MCU_fct decode_MCU;  
  const decode_MCU_fct *decode_mcu_table;  
  const convert_colorspace_fct *colorspace_array_conv;  
  convert_colorspace_fct convert_to_pixfmt;  
  
  //-------------------------------------------  
    FILE *fp;  
    char *temp;  
    int j,k;  
  //-------------------------------------------  
  
  if (setjmp(priv->jump_state))  
    return -1;  
  
  /* To keep gcc happy initialize some array */  
  bytes_per_mcu[1] = 0;  
  bytes_per_mcu[2] = 0;  
  bytes_per_blocklines[1] = 0;  
  bytes_per_blocklines[2] = 0;  
  
  decode_mcu_table = decode_mcu_3comp_table;  
  switch (pixfmt) {  
     case TINYJPEG_FMT_YUV420P:  
       colorspace_array_conv = convert_colorspace_yuv420p;  
       if (priv->components[0] == NULL)  
     priv->components[0] = (uint8_t *)malloc(priv->width * priv->height);  
       if (priv->components[1] == NULL)  
     priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4);  
       if (priv->components[2] == NULL)  
     priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4);  
       bytes_per_blocklines[0] = priv->width;  
       bytes_per_blocklines[1] = priv->
width/4; bytes_per_blocklines[2] = priv->width/4; bytes_per_mcu[0] = 8; bytes_per_mcu[1] = 4; bytes_per_mcu[2] = 4; break; case TINYJPEG_FMT_RGB24: colorspace_array_conv = convert_colorspace_rgb24; if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); bytes_per_blocklines[0] = priv->width * 3; bytes_per_mcu[0] = 3*8; break; case TINYJPEG_FMT_BGR24: colorspace_array_conv = convert_colorspace_bgr24; if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); bytes_per_blocklines[0] = priv->width * 3; bytes_per_mcu[0] = 3*8; break; case TINYJPEG_FMT_GREY: decode_mcu_table = decode_mcu_1comp_table; colorspace_array_conv = convert_colorspace_grey; if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height); bytes_per_blocklines[0] = priv->width; bytes_per_mcu[0] = 8; break; default: #if TRACE_PARAM fprintf(param_trace,"Bad pixel format\n"); fflush(param_trace); #endif return -1; } xstride_by_mcu = ystride_by_mcu = 8; if ((priv->component_infos[cY].Hfactor | priv->component_infos[cY].Vfactor) == 1) { decode_MCU = decode_mcu_table[0]; convert_to_pixfmt = colorspace_array_conv[0]; #if TRACE_PARAM fprintf(param_trace,"Use decode 1x1 sampling\n"); fflush(param_trace); #endif } else if (priv->component_infos[cY].Hfactor == 1) { decode_MCU = decode_mcu_table[1]; convert_to_pixfmt = colorspace_array_conv[1]; ystride_by_mcu = 16; #if TRACE_PARAM fprintf(param_trace,"Use decode 1x2 sampling (not supported)\n"); fflu