⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jp3.txt

📁 这是一组JPEG解码的说明和源代码
💻 TXT
📖 第 1 页 / 共 3 页
字号:

/*  * 生成解码用哈夫曼表  */ void jpeg_make_huff_table(p_jpeg_huff_table p_table) {  WORD mask;  WORD i, j, k;  p_table->huff_min_codes[0] = 0;  for ( i = 0, mask = 0, j = 0, k = 0; i < p_table->n_code_count; ) {

  if ( j >= p_table->n_counts[k] ) {

   if ( j == 0 ) {     /* 无k位Huffman码,则置huff_max_codes[k]为0、huff_min_codes[k]为0xffff以示区别 */     p_table->huff_min_codes[k] = 0xffff;     p_table->huff_max_codes[k] = 0;    } else {     j = 0;    }

   mask <<= 1;    k++;    if ( k < 16 ) p_table->huff_min_codes[k] = mask;

  } else {

   p_table->huff_max_codes[k] = mask;    mask++;    j++;    i++;

  }

 } /* end of for(...) */ }

/*  * 处理定义哈夫曼表标志  */ int jpeg_decode_DHT(p_jpeg_dec_rec p_rec) {  BYTE b, index, type;  WORD size, total, i;  NextByte(p_rec);  size = jpeg_next_word(p_rec) - 2;  while ( size > 0 ) {   b = jpeg_next_byte(p_rec);   index = b & 0xf;   if (index >= 4) return 0; /* 出现了非法的哈夫曼表ID */

  type = b >> 4;   if (type > 1) return 0; /* 非法的哈夫曼表类型 */

  total = 0;   for ( i = 0; i < 16; i++ ) {    b = jpeg_next_byte(p_rec);    p_rec->huff_tables[type][index].n_counts[i] = b;    p_rec->huff_tables[type][index].start_code_indexes[i] = (BYTE)total;    total += b;   }

  p_rec->huff_tables[type][index].n_code_count = total;   memcpy(p_rec->huff_tables[type][index].codes, p_rec->p_data, total);   jpeg_make_huff_table( &(p_rec->huff_tables[type][index]) );      p_rec->p_data += total;   if ( p_rec->p_data >= p_rec->p_data_limit ) return 0; /* 数据不够 */   size -= (total + 16 + 1);  }  return 1; }

/*  * 查找EOI标记。找到返回非0  */ int jpeg_scan_for_eoi( p_jpeg_dec_rec p_rec ) {  BYTE *p = p_rec->p_data;  for ( ;; ) {   if ( p + 1 >= p_rec->p_data_limit ) break;   if ( *p == 0xff ) {    if ( p[1] == 0xD9 ) break;    else {     if ( p[1] >= 0xD0 && p[1] <= 0xD7 ) {      /* RSTn */      p += 2;     } else if ( p[1] == 0 ) {      return 0;     } else {      jpeg_decode_next_block(p_rec);     }    }   } else {    return 0;   }  }  return 1; }

/*  * 解码帧(非渐近方式)  *  返回非0表示成功  */ int jpeg_decode_scanlines(p_jpeg_dec_rec p_rec) {  static BYTE _un_zig_zag[64] = {    0, 1, 8, 16, 9, 2, 3,10,    17,24,32,25,18,11, 4, 5,    12,19,26,33,40,48,41,34,    27,20,13, 6, 7,14,21,28,    35,42,49,56,57,50,43,36,    29,22,15,23,30,37,44,51,    58,59,52,45,38,31,39,46,    53,60,61,54,47,55,62,63  };  /* 工作矩阵(Data Unit) */  SHORT    du[64];  /* 指向当前量化表数值 */  DWORD    *pw_quality_values;  /* 各组件DC分量值 */  SHORT    dc[5] = { 0, 0, 0, 0, 0 };  /* 各组件缓冲区,需释放 */  BYTE*    p_com_bufs[5] = { NULL, NULL, NULL, NULL, NULL };  /* 每段每组件扫描完后地址偏移量,需释放 */  int*    p_com_buf_incs[5] = { NULL, NULL, NULL, NULL, NULL };  /* 指向p_com_bufs的当前地址(当p_com_bufs被重新分配时,应当重新计算!!!) */  BYTE*    p_com_ptrs[5] = { NULL, NULL, NULL, NULL, NULL };  /* 组件宽度(像素) */  WORD    w_com_widths[5] = { 0, 0, 0, 0, 0 };  /* 组件宽度(像素),若w_scanlines为0,则此值持续变动 */  WORD    w_com_heights[5] = { 0, 0, 0, 0, 0 };  /* 每组件长宽方向上的数量 */  BYTE    n_com_counts[5] = { 0, 0, 0, 0, 0 };  /* 每组件每像素行扫描完后地址增加字节数 */  DWORD    dw_com_line_incs[5] = { 0, 0, 0, 0, 0 };  /* 每组件每扫描行扫描完后地址增加字节数 */  DWORD    dw_com_scanline_incs[5] = { 0, 0, 0, 0, 0 };  /* 段数,扫描行数(为0表示在扫描过程中指定),剩余行数 */  WORD    w_segments, w_scanlines, w_leftlines;  /* 当w_scanlines为0时,此值表示当前已分配的扫描行数 */  WORD    w_alloc_scanlines;  /* 当前AC哈夫曼表,当前DC哈夫曼表 */  p_jpeg_huff_table p_ac_huff_table, p_dc_huff_table;  /* 当前量化表 */  p_jpeg_quality_table p_quality_table;  /* RS(游程码) */  BYTE    RS;  /* BITS(剩余位) */  WORD    BITS;  /* RRRR(RS的高4位), SSSS(RS的低4位) */  BYTE    RRRR, SSSS;  DWORD    dw_offset, dw_old_offset;  BYTE    i, j, m, n, cnt;  BYTE    *p;  SHORT    *p_i;  SHORT    i_ac;  WORD    k;

 w_segments = (WORD)( (p_rec->n_width + p_rec->n_horz_sample_coes_max * 8 - 1) / (p_rec->n_horz_sample_coes_max * 8) );  if ( p_rec->n_height != 0 ) {   w_scanlines = (WORD)( (p_rec->n_height + p_rec->n_vert_sample_coes_max * 8 - 1) / (p_rec->n_vert_sample_coes_max * 8) );   w_alloc_scanlines = w_scanlines;   w_leftlines = w_scanlines;  } else w_scanlines = 0;

 /* 预分配各组件扫描临时区域 */  for ( i = 0; i < p_rec->n_components; i++ ) {   n_com_counts[i] = p_rec->n_horz_sample_coes[i] * p_rec->n_vert_sample_coes[i];   w_com_widths[i] = (WORD)(w_segments * p_rec->n_horz_sample_coes[i] * 8);   dw_com_line_incs[i] = w_com_widths[i] - 8;   dw_com_scanline_incs[i] = (DWORD)w_com_widths[i] * p_rec->n_vert_sample_coes[i] * 8 - w_com_widths[i];  

  p_com_buf_incs[i] = (int*)malloc( w_com_widths[i] * sizeof(int*) );   if ( w_scanlines == 0 ) {    /* 宽度不定,先分配1行 */    w_alloc_scanlines = 1;    w_com_heights[i] = (WORD)(w_alloc_scanlines * p_rec->n_vert_sample_coes[i] * 8);    p_com_bufs[i] = (BYTE*)malloc( (DWORD)w_com_widths[i] * (DWORD)w_com_heights[i] );   } else {    /* 宽度已知 */    w_com_heights[i] = (WORD)(w_scanlines * p_rec->n_vert_sample_coes[i] * 8);    p_com_bufs[i] = (BYTE*)malloc( (DWORD)w_com_widths[i] * (DWORD)w_com_heights[i] );   }   if ( p_com_buf_incs[i] != NULL ) {    dw_old_offset = dw_offset = 0;    for ( j = 0, n = 0; n < p_rec->n_vert_sample_coes[i]; ++n ) {     for ( m = 0; m < p_rec->n_vert_sample_coes[i]; ++m, ++j ) {      dw_offset = (DWORD)n * 8 * w_com_widths[i] + m * 8;      if ( j > 0 ) p_com_buf_incs[i][j - 1] = dw_offset - dw_old_offset;      dw_old_offset = dw_offset;     }    }    dw_offset = (DWORD)p_rec->n_horz_sample_coes[i] * 8;    p_com_buf_incs[i][j - 1] = dw_offset - dw_old_offset;   }   p_com_ptrs[i] = p_com_bufs[i];  }

 /* Check for invalid buffers */  for ( i = 0; i < p_rec->n_components; ++i )  {   /* 有缓冲区未正确分配? */   if (p_com_bufs[i] == NULL || p_com_buf_incs[i] == NULL)   {    // 释放所有已分配的缓冲区并返回失败    for ( j = 0; j < p_rec->n_components; ++j )    {     if (p_com_bufs[j] != NULL) free(p_com_bufs[j]);     if (p_com_buf_incs[j] != NULL) free(p_com_buf_incs[j]);    }    return 0;   }  }

 /* 行扫描 */  for ( ;; ) {   /* 段扫描 */   for ( k = 0; k < w_segments; ++k ) {    /* 交错扫描方式:组件1,组件2,组件3... */    for ( i = 0; i < p_rec->n_components; ++i ) {     /* 组件i使用的DC表 */     p_dc_huff_table = &p_rec->huff_tables[0][p_rec->n_huff_tables_indexes[0][i]];     /* 组件i使用的AC表 */     p_ac_huff_table = &p_rec->huff_tables[1][p_rec->n_huff_tables_indexes[1][i]];     for ( cnt = 0; cnt < n_com_counts[i]; ++cnt ) {      /* 初始化工作矩阵 */      memset(du, 0, 64 * sizeof(SHORT));

     /* 当前DC系数 */      p_rec->i_dc = dc[i];      /* 当前量化表 */      p_quality_table = &p_rec->quality_tables[p_rec->n_quality_table_indexes[i]];      /* 当前量化表值 */      pw_quality_values = p_quality_table->values;

     /* 解码RS(流程码值) */      RS = jpeg_dec_next_huff_code(p_rec, p_dc_huff_table);      /* 对于DC,RS直接指出位数 */      if (RS > 0) BITS = jpeg_get_next_bits(p_rec, RS);      else BITS = 0;      p_rec->i_dc += BITS;      if ( RS != 0 ) {       if ( BITS < (1 << (RS - 1)) ) p_rec->i_dc -= ((1 << RS) - 1);      }      dc[i] = p_rec->i_dc;      if ( !p_quality_table->process_in_idct ) {       /* 反量化 */       du[0] = p_rec->i_dc * (*pw_quality_values);       ++pw_quality_values;      } else {       du[0] = p_rec->i_dc;      }      

     j = 1;      /* 解Z字型地址 */      p = &_un_zig_zag[j];

     while ( j < 64 ) {       RS = jpeg_dec_next_huff_code(p_rec, p_ac_huff_table);       if ( !RS ) {        /* EOB */        break;       }       RRRR = RS >> 4;       /* 跳过的0分量数 */       j += RRRR;       p += RRRR;       pw_quality_values += RRRR;       if ( j >= 64 ) break;       SSSS = RS & 0xf;       if ( !SSSS ) {        /* 分量为0 */        ++j; ++p; ++pw_quality_values;       } else {        i_ac = jpeg_get_next_bits(p_rec, SSSS);        if ( i_ac < (1 << (SSSS - 1)) ) i_ac -= ((1 << SSSS) - 1);        if ( !p_quality_table->process_in_idct ) {         i_ac *= *pw_quality_values;         ++pw_quality_values;        } else {

       }        du[*p] = i_ac;        ++j; ++p;       }      } /* DU 解码(+反量化)完成 */

     /* IDCT */      jpeg_idct(p_quality_table, du);

     p = p_com_ptrs[i];      p_i = du;      for ( n = 0; n < 8; ++n ) {       *p++ = (BYTE)*p_i++;       *p++ = (BYTE)*p_i++;       *p++ = (BYTE)*p_i++;       *p++ = (BYTE)*p_i++;       *p++ = (BYTE)*p_i++;       *p++ = (BYTE)*p_i++;       *p++ = (BYTE)*p_i++;       *p++ = (BYTE)*p_i++;       p += dw_com_line_incs[i];      }      p_com_ptrs[i] += p_com_buf_incs[i][cnt];     } /* cnt */    } /* i */        if ( p_rec->n_reset_size != 0 && --p_rec->n_reset_cnt == 0 ) {     /* RESET间隔已到,检查RSTn标志 */     if ( p_rec->p_data + 1 >= p_rec->p_data_limit ) goto _exit;     if ( CurByte(p_rec) == 0xff && p_rec->p_data[1] >= 0xD0 && p_rec->p_data[1] <= 0xD7 ) {      /* RSTn标志出现 */      p_rec->p_data += 2;      jpeg_reset(p_rec);      memset(dc, 0, 4 * sizeof(SHORT));     } else {      /* next??? */      ++p_rec->n_reset_cnt;     }    }   } /* k */   /* 下一行 */   for ( i = 0; i < p_rec->n_components; ++i ) p_com_ptrs[i] += dw_com_scanline_incs[i];   /* 动态高度? */   if ( w_scanlines == 0 ) {    /* 检查并重新分配各组件缓冲区,并调整指针 */    p_rec->n_height += p_rec->n_horz_sample_coes_max * 8;    while ( (WORD)( (p_rec->n_height + p_rec->n_vert_sample_coes_max * 8 - 1) / (p_rec->n_vert_sample_coes_max * 8) ) > w_alloc_scanlines ) {     w_alloc_scanlines *= 2;     for ( i = 0; i < p_rec->n_components; ++i ) {      w_com_heights[i] = (WORD)(w_alloc_scanlines * p_rec->n_vert_sample_coes[i] * 8);      p = p_com_bufs[i];      /* 重新分配 */      p_com_bufs[i] = (BYTE*)realloc( p_com_bufs[i], (DWORD)w_com_widths[i] * (DWORD)w_com_heights[i] );      if ( p_com_ptrs[i] == NULL ) goto _exit;      /* 重新计算偏移 */      p_com_ptrs[i] = p_com_bufs[i] + (p_com_ptrs[i] - p);     }    }    /* TODO: parse the DNL */   } else {    /* 高度已知 */    if ( --w_leftlines == 0 ) break;   }  } /* scanlines */  /* 生成位图 */  if ( p_rec->n_components == 3 ) jpeg_make_rgb_buffer(p_rec, p_com_bufs, w_com_widths);  else if ( p_rec->n_components == 1 ) jpeg_make_gray_buffer(p_rec, p_com_bufs, w_com_widths);  //else if ( p_rec->n_components == 4 ) _exit:  for ( i = 0; i < p_rec->n_components; ++i )  {   if (p_com_bufs[i] != NULL) free(p_com_bufs[i]);   if (p_com_buf_incs[i] != NULL) free(p_com_buf_incs[i]);  }  return 1; }

int jpeg_check_for_scan_end(p_jpeg_dec_rec p_rec) {  if ( *p_rec->p_data == 0xFF ) {   if ( p_rec->p_data + 1 >= p_rec->p_data_limit ) return 1;   if ( p_rec->p_data[1] == 0 ) return 0;   if ( p_rec->p_data[1] >= 0xD0 && p_rec->p_data[1] <= 0xD7 ) return 0;   return 1;  }  return 0; }

#define CEIL_DIV(p, q)  (((p) + (q) - 1) / (q))

/* * 解码帧(渐近方式) *  返回非0表示成功 */ int jpeg_decode_scanlines_progressive(p_jpeg_dec_rec p_rec, BYTE *component_indexes, BYTE n_curr_scan_components) {  /* Z字型->DU顺序索引 */  static BYTE _un_zig_zag[64] = {   0, 1, 8, 16, 9, 2, 3,10,   17,24,32,25,18,11, 4, 5,   12,19,26,33,40,48,41,34,   27,20,13, 6, 7,14,21,28,   35,42,49,56,57,50,43,36,   29,22,15,23,30,37,44,51,   58,59,52,45,38,31,39,46,   53,60,61,54,47,55,62,63  };  /* 当前工作矩阵(Data Unit) */  SHORT    *p_curr_du;  /* 各组件DC分量值 */  SHORT    dc[5] = { 0, 0, 0, 0, 0 };  /* 每组件长宽方向上的数量 */  BYTE    n_com_counts[5] = { 0, 0, 0, 0, 0 };  BYTE    n_com_offsets[5] = { 0, 0, 0, 0, 0 };  BYTE    n_com_total_count = 0;  BYTE    n_curr_scan_component_index;  DWORD    n_com_offset;  WORD    w_segments, w_scanlines, w_leftlines, w_max_segments, w_max_scanlines;  /* 当前AC哈夫曼表,当前DC哈夫曼表 */  p_jpeg_huff_table p_ac_huff_table, p_dc_huff_table;  /* RS(游程码) */  BYTE    RS;  /* BITS(剩余位) */  WORD    BITS;  /* RRRR(RS的高4位), SSSS(RS的低4位) */  BYTE    RRRR, SSSS;  BYTE    i, j, index, cnt;  BYTE    i_first_scan;  BYTE    *p;  SHORT    i_ac, i_dc_diff;  WORD    k, du_index, x_block, y_block, du_cnt, x_inc, y_inc, x_pos, y_pos, x, y;  /* 渐近方式,du索引转换表 */  WORD    *progressive_du_indexes = NULL;

 /* 渐近方式不支持动态高度 */  if ( p_rec->n_height == 0 ) return 0;

 w_max_segments = (WORD)CEIL_DIV(p_rec->n_width, p_rec->n_horz_sample_coes_max * 8);  w_max_scanlines = (WORD)CEIL_DIV(p_rec->n_height, p_rec->n_vert_sample_coes_max * 8);

 if ( n_curr_scan_components == 1 ) {   for ( i = 0; i < p_rec->n_components; ++i ) {    if ( component_indexes[i] <= 3 ) {     /* curr scan component index */     j = component_indexes[i];     n_curr_scan_component_index = j;     w_segments = (WORD)CEIL_DIV(p_rec->n_width, p_rec->n_horz_sample_coes_max / p_rec->n_horz_sample_coes[j] * 8);     w_scanlines = (WORD)CEIL_DIV(p_rec->n_height, p_rec->n_vert_sample_coes_max / p_rec->n_vert_sample_coes[j] * 8);     x_inc = p_rec->n_horz_sample_coes[j];     y_inc = p_rec->n_vert_sample_coes[j];     break;    }   }   progressive_du_indexes = (WORD*)malloc( w_segments * w_scanlines * sizeof(WORD) );   du_index = 0;   du_cnt = 0;   for ( i = 0; i < p_rec->n_components; i++ ) {    n_com_counts[i] = p_rec->n_horz_sample_coes[i] * p_rec->n_vert_sample_coes[i];   }   for ( y_block = 0, y_pos = 0; y_block < w_max_scanlines; ++y_block, y_pos += y_inc ) {    for ( x_block = 0, x_pos = 0; x_block < w_max_segments; ++x_block, x_pos += x_inc ) {     x = x_pos;     y = y_pos;     for ( i = 0; i < p_rec->n_components; ++i ) {      for ( j = 0; j < n_com_counts[i]; ++j, ++du_cnt ) {       du_index = y * w_segments + x;       if ( i == n_curr_scan_component_index ) {        if ( y < w_scanlines && x < w_segments ) {         progressive_du_indexes[du_index] = du_cnt;        }        ++x;        if ( x >= x_pos + x_inc ) {         x = x_pos;         ++y;        }       }      }     }    }   }  } else {   w_segments = w_max_segments;   w_scanlines = w_max_scanlines;  }  w_leftlines = w_scanlines;

 /* 预分配各组件扫描临时区域 */  p_rec->n_du_count = 0;  n_com_total_count = 0;  for ( i = 0; i < p_rec->n_components; i++ ) {   n_com_counts[i] = p_rec->n_horz_sample_coes[i] * p_rec->n_vert_sample_coes[i];   n_com_offsets[i] = n_com_total_count;   n_com_total_count += n_com_counts[i];   p_rec->n_du_count += (DWORD)w_max_segments * p_rec->n_horz_sample_coes[i] * w_max_scanlines * p_rec->n_vert_sample_coes[i];  }

 /* Allocate DUs */  if ( !p_rec->p_dus ) {   p_rec->p_dus = (SHORT*)malloc( p_rec->n_du_count * sizeof(SHORT) * 64 );   memset( p_rec->p_dus, 0, p_rec->n_du_count * sizeof(SHORT) * 64 );  }

 /* Check for invalid buffer */  if (p_rec->p_dus == NULL) return 0;

 i_first_scan = p_rec->n_curr_scan_ah == 0;  p_curr_du = p_rec->p_dus;  /* TODO: reorder the scan process */  /* 行扫描 */  du_index = 0;  for ( ;; ) {   /* 段扫描 */   for ( k = 0; k < w_segments; ++k ) {    /* 交错扫描方式:组件1,组件2,组件3... */    for ( i = 0; i < p_rec->n_components; ++i ) {

    index = component_indexes[i];     /* 本次没有扫描此组件 */     if ( index >= 4 ) {      p_curr_du += 64 * n_com_counts[i];      continue;     }

    if ( n_curr_scan_components == 1 ) {      n_com_offset = progressive_du_indexes[du_index];      p_curr_du = p_rec->p_dus + (DWORD)n_com_offset * 64;     }

    /* 组件i使用的DC表 */     p_dc_huff_table = &p_rec->huff_tables[0][p_rec->n_huff_tables_indexes[0][index]];     /* 组件i使用的AC表 */     p_ac_huff_table = &p_rec->huff_tables[1][p_rec->n_huff_tables_indexes[1][index]];    

    cnt = n_com_counts[index];     if ( n_curr_scan_components == 1 ) cnt = 1;     for ( ; cnt > 0; --cnt ) {

     if ( p_rec->n_curr_scan_ss == 0 /* DC扫描行 */ ) {

      /* 第一次DC扫描 */       if ( i_first_scan ) {        /* 当前DC系数 */        p_rec->i_dc = dc[index];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -