📄 jp3.txt
字号:
/* 解码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 + -