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

📄 jp3.txt

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

       /* 解码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;        i_dc_diff = BITS;        if ( RS != 0 ) {         if ( BITS < (1 << (RS - 1)) ) i_dc_diff -= ((1 << RS) - 1);        }        p_rec->i_dc += i_dc_diff;        p_curr_du[0] = p_rec->i_dc << p_rec->n_curr_scan_al;        dc[index] = p_rec->i_dc;       } else {        /* 后续DC扫描行 */        if ( jpeg_get_next_bits(p_rec, 1) != 0 ) {         p_curr_du[0] |= (1 << p_rec->n_curr_scan_al);        }       }

     } else {

      j = p_rec->n_curr_scan_ss;       /* 解Z字型地址 */       p = &_un_zig_zag[j];

      while ( j <= p_rec->n_curr_scan_se ) {

       /* 处理EOB */        if ( p_rec->n_eob_count > 0 ) {         --p_rec->n_eob_count;         if ( !i_first_scan ) {          /* 处理在0串中的带有非0历史的系数的校正位 */          while ( j <= p_rec->n_curr_scan_se ) {           if ( p_curr_du[*p] != 0 ) {            if ( jpeg_get_next_bits(p_rec, 1) ) {             /* 有校正 */             if ( p_curr_du[*p] >= 0 ) p_curr_du[*p] += (1 << p_rec->n_curr_scan_al);             else p_curr_du[*p] -= (1 << p_rec->n_curr_scan_al);            } /* else 没有校正 */           }           ++j; ++p;          }         }         break;        }

       RS = jpeg_dec_next_huff_code(p_rec, p_ac_huff_table);

       if ( !RS ) {                 if ( !i_first_scan ) {          /* 处理在0串中的带有非0历史的系数的校正位 */          while ( j <= p_rec->n_curr_scan_se ) {           if ( p_curr_du[*p] != 0 ) {            if ( jpeg_get_next_bits(p_rec, 1) ) {             /* 有校正 */             if ( p_curr_du[*p] >= 0 ) p_curr_du[*p] += (1 << p_rec->n_curr_scan_al);             else p_curr_du[*p] -= (1 << p_rec->n_curr_scan_al);            } /* else 没有校正 */           }           ++j; ++p;          }         }         break;        }

       RRRR = RS >> 4;        SSSS = RS & 0xf;

       if ( (!SSSS) && (RRRR < 15) ) {

        /* EOBn */         if ( RRRR == 0 ) BITS = 1;         else {          BITS = jpeg_get_next_bits(p_rec, RRRR);          BITS += (1 << RRRR);         }         p_rec->n_eob_count = BITS;         continue;

       }

       if ( SSSS ) {         i_ac = jpeg_get_next_bits(p_rec, SSSS);        }

       /* 跳过的0分量数 */        if ( i_first_scan ) {         j += RRRR;         p += RRRR;        } else {         if ( SSSS != 1 && SSSS != 0 ) _asm int 3;

        /* 处理在0串中的带有非0历史的系数的校正位 */         while ( j <= p_rec->n_curr_scan_se ) {          if ( p_curr_du[*p] != 0 ) {           if ( jpeg_get_next_bits(p_rec, 1) ) {            /* 有校正 */            if ( p_curr_du[*p] >= 0 ) p_curr_du[*p] += (1 << p_rec->n_curr_scan_al);            else p_curr_du[*p] -= (1 << p_rec->n_curr_scan_al);           } /* else 没有校正 */          } else {           /* !!! 校正扫描中,在计算行程时忽略非0值 */           if ( RRRR-- == 0 ) break;          }          ++j; ++p;         }        }        if ( j > p_rec->n_curr_scan_se )         break;                if ( !SSSS ) {

        ++j; ++p;

       } else {

        if ( i_first_scan ) {

         if ( i_ac < (1 << (SSSS - 1)) ) i_ac -= ((1 << SSSS) - 1);

         p_curr_du[*p] = (i_ac << p_rec->n_curr_scan_al);

        } else {

         /* SSSS must equals 1 here */          /* p_curr_du[*p] must equals 0 here */          /* 1位符号位 */          if ( i_ac ) {           /* 正 */           p_curr_du[*p] = 1 << p_rec->n_curr_scan_al;          } else {           /* 负 */           p_curr_du[*p] = -(1 << p_rec->n_curr_scan_al);          }         }         ++j; ++p; 

       }       } /* DU 解码(+反量化)完成 */      }      p_curr_du += 64;      if ( n_curr_scan_components == 1 ) {       ++du_index;      }     } /* 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 */   if ( --w_leftlines == 0 )   {    if ( p_rec->n_left_bit_count != 0 ) {     p_rec->n_left_bit_count = 0;    }    p_rec->n_reset_cnt = p_rec->n_reset_size;    p_rec->i_dc = 0;    memset(dc, 0, 4 * sizeof(SHORT));    break;   }  } /* scanlines */ _exit:  if ( progressive_du_indexes ) free(progressive_du_indexes);  return 1; }

int jpeg_make_buf_progressive(p_jpeg_dec_rec p_rec) {  /* 当前工作矩阵(Data Unit) */  SHORT    *p_curr_du;  /* 各组件缓冲区,需释放 */  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;  /* 当前量化表 */  p_jpeg_quality_table p_quality_table;  /* 当前量化表数值 */  DWORD    *pw_quality_values;  DWORD    dw_offset, dw_old_offset;  DWORD    n_du_count;  BYTE    i, j, m, n, cnt;  BYTE    *p;  SHORT    *p_i;  WORD    k;

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

 w_segments = (WORD)( (p_rec->n_width + p_rec->n_horz_sample_coes_max * 8 - 1) / (p_rec->n_horz_sample_coes_max * 8) );  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_leftlines = w_scanlines;

 /* 预分配各组件扫描临时区域 */  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*) );   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];  }

 p_curr_du = p_rec->p_dus;  n_du_count = p_rec->n_du_count;  for ( w_leftlines = w_scanlines; w_leftlines > 0; --w_leftlines ) {   /* 段扫描 */   for ( k = 0; k < w_segments; ++k ) {    /* 交错扫描方式:组件1,组件2,组件3... */    for ( i = 0; i < p_rec->n_components; ++i ) {     for ( cnt = 0; cnt < n_com_counts[i]; ++cnt ) {      /* 当前量化表 */      p_quality_table = &p_rec->quality_tables[p_rec->n_quality_table_indexes[i]];      if ( !p_quality_table->process_in_idct ) {       /* 当前量化表值 */       pw_quality_values = p_quality_table->values;       /* 反量化 */       for ( j = 0; j < 64; ++j ) {        p_curr_du[j] *= (*pw_quality_values);        ++pw_quality_values;       }      }      /* IDCT */      jpeg_idct( p_quality_table, p_curr_du );      p_curr_du += 64;     }    }   }  }  p_curr_du = p_rec->p_dus;  for ( w_leftlines = w_scanlines; w_leftlines > 0; --w_leftlines ) {   /* 段扫描 */   for ( k = 0; k < w_segments; ++k ) {    /* 交错扫描方式:组件1,组件2,组件3... */    for ( i = 0; i < p_rec->n_components; ++i ) {     for ( cnt = 0; cnt < n_com_counts[i]; ++cnt ) {      p = p_com_ptrs[i];      p_i = p_curr_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];      p_curr_du += 64;     } /* cnt */    } /* i */   } /* k */   /* 下一行 */   for ( i = 0; i < p_rec->n_components; ++i ) p_com_ptrs[i] += dw_com_scanline_incs[i];  }

 free(p_rec->p_dus);  p_rec->p_dus = NULL;

 /* 生成位图 */  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 )  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; }

/*  * 解码SOS(Start Of Scan)标记,并解码帧  *  成功返回非0  */ int jpeg_decode_SOS(p_jpeg_dec_rec p_rec) {  BYTE i, j, b, index, id;  BYTE component_indexes[4];  BYTE n_curr_scan_components;    NextByte(p_rec);  jpeg_next_word(p_rec);

 n_curr_scan_components = jpeg_next_byte(p_rec);  if ( n_curr_scan_components <= 0 || n_curr_scan_components > 4 ) return 0;

 /* 0xFF means this component does not appear in the scan */  component_indexes[0] = component_indexes[1] = component_indexes[2] = component_indexes[3] = 0xFF;

 for ( i = 0; i < n_curr_scan_components; ++i ) {   /* component id */   id = jpeg_next_byte(p_rec);   for ( j = 0; j < 4; ++j ) {    if ( p_rec->i_component_ids[j] == id ) {     component_indexes[i] = j;     break;    }   }   if ( j == 4 ) return 0;   index = j;   b = jpeg_next_byte(p_rec);   p_rec->n_huff_tables_indexes[0][index] = b >> 4;   p_rec->n_huff_tables_indexes[1][index] = b & 0xf;  }

 p_rec->n_curr_scan_ss = NextByte(p_rec);  p_rec->n_curr_scan_se = NextByte(p_rec);  b = NextByte(p_rec);  p_rec->n_curr_scan_ah = b >> 4;  p_rec->n_curr_scan_al = b & 0xf;

 if ( p_rec->i_progressive ) jpeg_decode_scanlines_progressive(p_rec, component_indexes, n_curr_scan_components);  else jpeg_decode_scanlines(p_rec);

 return 1; }

/*  *  处理下一个块。返回值  * JPEG_FAIL_UNEXPECTED_BYTE  unexpected byte (0ffh expected)  * JPEG_FAIL_UNKNOWN_BLOCK_TYPE unknown block type 未知类型块  * JPEG_FAIL_DECODE_ERROR   已知块,但解码失败  * JPEG_SUCCESS_NEXTBLOCK   成功,等待下一个块的解码  * JPEG_SUCCESS_LASTBLOCK   成功,且已是最后一块  * JPEG_SUCCESS_IGNORED   unsupported block type 不支持的块,已忽略  * 在处理每个块时,将先过滤掉前面的0xff。因此在各明确的块处理段将无0xff  */ int jpeg_decode_next_block(p_jpeg_dec_rec p_rec) {  BYTE b, curb;  b = NextByte(p_rec);  if ( b != 0xff )  {   return JPEG_FAIL_UNEXPECTED_BYTE;  }  curb = CurByte(p_rec);  switch( curb ) {   case 0xD8:  /* SOI */    jpeg_skip_next_block(p_rec);    break;   case 0xD9:  /* EOI */    jpeg_skip_next_block(p_rec);    if ( p_rec->i_progressive ) {     jpeg_make_buf_progressive(p_rec);    }    return JPEG_SUCCESS_LASTBLOCK;   case 0xC0:  /* SOF0 */   case 0xC2:    if ( curb == 0xC2 ) p_rec->i_progressive = 1;    if ( !jpeg_decode_SOF0(p_rec)) return JPEG_FAIL_DECODE_ERROR;    break;   case 0xDD:  /* DRI */    if ( !jpeg_decode_DRI(p_rec) ) return JPEG_FAIL_DECODE_ERROR;    break;   case 0xDB:  /* DQT */    if ( !jpeg_decode_DQT(p_rec) ) return JPEG_FAIL_DECODE_ERROR;    break;   case 0xC4:  /* DHT */    if ( !jpeg_decode_DHT(p_rec) ) return JPEG_FAIL_DECODE_ERROR;    break;   case 0xE0:  /* APP0-APPF */   case 0xE1:   case 0xE2:   case 0xE3:   case 0xE4:   case 0xE5:   case 0xE6:   case 0xE7:   case 0xE8:   case 0xE9:   case 0xEA:   case 0xEB:   case 0xEC:   case 0xED:   case 0xEE:   case 0xEF:   case 0xFE:  /* COM */    jpeg_skip_next_block(p_rec);    break;   case 0xDA:  /* SOS */    if ( !jpeg_decode_SOS(p_rec) ) return JPEG_FAIL_DECODE_ERROR;    break;   case 0xFF:  /* 段之间无论有多少 $ff 都是合法的, 必须被忽略掉 */    break;   default:    jpeg_skip_next_block(p_rec);    return JPEG_SUCCESS_IGNORED;  }  return JPEG_SUCCESS_NEXTBLOCK; }

发表于 @ 2006年10月21日 01:51:00|评论(1)|编辑|收藏

新一篇: 苏泊尔耗的JPEG解码器[四] | 旧一篇: 苏泊尔耗的JPEG解码器[二]

⌨️ 快捷键说明

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