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

📄 jp3.txt

📁 这是一组JPEG解码的说明和源代码
💻 TXT
📖 第 1 页 / 共 3 页
字号:
新一篇: 苏泊尔耗的JPEG解码器[四] | 旧一篇: 苏泊尔耗的JPEG解码器[二]
主控单元。包含普通和渐近两种方式的解码。

头文件

jpegdec2.h(为什么是2呢?因为两年前有一个一代的版本,不过还没问市就被卡嚓了-___-b 默哀ing...)

/**************************************************************************************************

  superarhow's JPEG decoder

  by superarhow(superarhow@hotmail.com).  All rights reserved.

 **************************************************************************************************/

#pragma once

#ifdef _MSC_VER #pragma warning( push ) #pragma warning(disable: 4142) #endif

typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned int DWORD; typedef int INT32; typedef short SHORT;

#ifdef _MSC_VER #pragma warning( pop ) #endif

typedef struct _tag_jpeg_huff_table {  /* 1-16位码长的代码的数量 */  BYTE n_counts[16];  /* 代码 */  BYTE codes[256];  /* 用于从codes中检索代码的索引 */  BYTE start_code_indexes[16];  /* 1-16位码长的代码最小值(generated) */  WORD huff_min_codes[16];  /* 1-16位码长的代码最大值(generated) */  WORD huff_max_codes[16];  /* 总代码数量 */  WORD n_code_count;  /* 当一个代码被确认为N位哈夫曼编码(Bits)时,其对应的Code由以下公式取得:  code = codes[Bits - huff_min_codes[N] + start_code_indexes[N]] */ } jpeg_huff_table, *p_jpeg_huff_table;

typedef struct _tag_jpeg_quality_table {  /* 量化精度标志。0表示8位,否则表示16位(有的文档上讲12位?) */  BYTE precision;  /* 值为非0表示在idct函数中处理 */  BYTE process_in_idct;  /* 量化表元素,64个,定义为DWORD是为了AA&N的需要保留精度 */  DWORD values[64]; } jpeg_quality_table, *p_jpeg_quality_table;

typedef struct _tag_jpeg_dec_rec {  /* 数据流指针 */  BYTE    *p_data;  /* 数据流最尾指针+1(pdata不得大于或等于此值) */  BYTE    *p_data_limit;  /* 剩余字节,第0到(left_bit_count-1)位有效 */  BYTE    left_bits;  /* 剩余位数 */  BYTE    n_left_bit_count;  /* 当前扫描的SS(Scan Start),用于渐近操作模式 */  BYTE    n_curr_scan_ss;  /* 当前扫描的SE(Scan End),用于渐近操作模式 */  BYTE    n_curr_scan_se;  /* 当前扫描的AH(上一行渐近的位数) */  BYTE    n_curr_scan_ah;  /* 当前扫描的AL(本行渐近的位数) */  BYTE    n_curr_scan_al;  /* 剩余的EOB数量,用于渐近操作模式 */  WORD    n_eob_count;  /* 目标位图每行字节数 */  DWORD    n_bytes_per_line;  /* 目标缓冲区,由jpeg_make_xxx_buffer函数分配 */  BYTE    *p_bgr_buffer;  /* 哈夫曼表。[0][0-3]为DC table, [1][0-3]为AC table */  jpeg_huff_table  huff_tables[2][4];  /* 量化表 */  jpeg_quality_table quality_tables[4];  /* 所有DU的数量 */  DWORD    n_du_count;  /* 所有工作矩阵,需释放(仅针对渐近模式) */  SHORT    *p_dus;  /* 采样精度(8,12 or 16, 只支持8) */  BYTE    n_bits_per_sample;  /* (当前帧)components 数量(1 byte), 灰度图是 1, YCbCr/YIQ 彩色图是 3, CMYK 彩色图是 4  component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q) 对应索引号需减1 */  BYTE    n_components;  /* 每个分量的ID */  BYTE    i_component_ids[4];  /* 纵向采样系数 */  BYTE    n_vert_sample_coes[4];  /* 横向采样系数 */  BYTE    n_horz_sample_coes[4];  /* 纵向采样系数最大值 */  BYTE    n_vert_sample_coes_max;  /* 横向采样系数最大值 */  BYTE    n_horz_sample_coes_max;  /* 纵向采样系数最小值 */  BYTE    n_vert_sample_coes_min;  /* 横向采样系数最小值 */  BYTE    n_horz_sample_coes_min;  /* 当前各组件选用的量化表0-3 */  BYTE    n_quality_table_indexes[4];  /* 当前各组件选用的哈夫曼表[0-1][0-3] 0 DC 1 AC */  BYTE    n_huff_tables_indexes[2][4];  /* 图片宽度 */  WORD    n_width;  /* 图片高度(为0表示用DNL段指出) */  WORD    n_height;  /* 由DRI段指出的重启动间隔。为0表示无此信息。此信息用于纠错处理。 */  WORD    n_reset_size;  /* 当前重启动MCU数,初始化为n_reset_size */  WORD    n_reset_cnt;  /* 当前DC分量 */  SHORT    i_dc;  /* 是否渐近方式 */  BYTE    i_progressive; } jpeg_dec_rec, *p_jpeg_dec_rec;

/*  * jpeg_decode_next_block函数返回码   */ #define JPEG_FAIL_UNEXPECTED_BYTE  -1  /* unexpected byte (0ffh expected) */ #define JPEG_FAIL_UNKNOWN_BLOCK_TYPE -2  /* unknown block type 未知类型块 */ #define JPEG_FAIL_DECODE_ERROR   -3  /* 已知块,但解码失败 */ #define JPEG_SUCCESS_NEXTBLOCK   0  /* 成功,等待下一个块的解码 */ #define JPEG_SUCCESS_LASTBLOCK   1  /* 成功,且已是最后一块 */ #define JPEG_SUCCESS_IGNORED   2  /* unsupported block type 不支持的块,已忽略 */

/* 初始化解码器 */ void jpeg_init_decoder(p_jpeg_dec_rec p_rec); /*  *  处理下一个块。返回值  * 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); /* 反初始化解码器 */ void jpeg_clear_up(p_jpeg_dec_rec p_rec); /* RST,内部使用 */ void jpeg_reset(p_jpeg_dec_rec p_rec);

******************************************* 广告位招租 *******************************************

jpegdec2.c(代码非常长,因为jpeg的格式实在是……其实最麻烦的不是什么哈夫曼编码、色彩

空间变换和IDCT…最麻烦的是处理扫描的过程,分量、分量的分块、Z字型、渐近,吐血啊……)

****************************************************************************************************

/**************************************************************************************************

  superarhow's JPEG decoder

  by superarhow(superarhow@hotmail.com).  All rights reserved.

 **************************************************************************************************/

#include "jpegdec2.h" #include "jpeghuff.h" #include "jpegbuf.h" #include "jpegidct.h"

#include "stdio.h" #include "windows.h"

#define NextByte(p) (*(p->p_data++)) #define CurByte(p) (*(p->p_data)) #define PrevByte(p) (*(--p->p_data)) #define WORD_ALIGN(p) (p) = (((p) + 1) / 2) * 2 #define DWORD_ALIGN(p) (p) = (((p) + 3) / 4) * 4

void jpeg_reset(p_jpeg_dec_rec p_rec) {  p_rec->n_left_bit_count = 0;  p_rec->n_reset_cnt = p_rec->n_reset_size;  p_rec->i_dc = 0;  p_rec->n_eob_count = 0; }

BYTE jpeg_next_byte(p_jpeg_dec_rec p_rec) {  BYTE b;  for ( ;; ) {   b = *p_rec->p_data++;   if (b == 0xFF) {    b = *p_rec->p_data++;    if (b == 0) return 0xFF;    if (b >= 0xD0 && b <= 0xD7) {     /* RSTn */     jpeg_reset(p_rec);    } else return b;   } else return b;  }  return 0; }

WORD jpeg_next_word(p_jpeg_dec_rec p_rec) {  WORD w = (p_rec->p_data[0] << 8) | (p_rec->p_data[1]);  p_rec->p_data += 2;  return w; }

/* 初始化解码器 */ void jpeg_init_decoder(p_jpeg_dec_rec p_rec) {  p_rec->n_width = 0;  p_rec->n_height = 0;  p_rec->n_reset_size = 0;  p_rec->left_bits = 0;  p_rec->n_left_bit_count = 0;  p_rec->n_horz_sample_coes_max = 0;  p_rec->n_vert_sample_coes_max = 0;  p_rec->n_horz_sample_coes_min = 0xff;  p_rec->n_vert_sample_coes_min = 0xff;  p_rec->p_bgr_buffer = NULL;  p_rec->p_data = NULL;  p_rec->i_dc = 0;  p_rec->i_progressive = 0;  p_rec->p_dus = NULL;  p_rec->n_eob_count = 0; }

/* 反初始化解码器 */ void jpeg_clear_up(p_jpeg_dec_rec p_rec) { }

/*  * 跳过下一个块  *  返回非0表示成功  */ int jpeg_skip_next_block(p_jpeg_dec_rec p_rec) {  BYTE b;  WORD n;  b = NextByte(p_rec);  if (b == 0x01 /* TEM 结束标志*/ || (b >= 0xd0 && b <= 0xd9 /* RSTn OR SOI OR EOI*/)) return 1;  n = jpeg_next_word(p_rec);  p_rec->p_data += (n - 2);  return 1; }

/*  * 处理帧开始标记  *  返回非0表示成功  */ int jpeg_decode_SOF0(p_jpeg_dec_rec p_rec) {  BYTE b, index, n;

 /* skip tag */  NextByte(p_rec);  jpeg_next_word(p_rec);

 /* 采样精度 */  p_rec->n_bits_per_sample = NextByte(p_rec);  /* 图像高度(为0表示通过DNL标记指定) */  p_rec->n_height = jpeg_next_word(p_rec);  /* 图像宽度 */  p_rec->n_width = jpeg_next_word(p_rec);  /* 每行字节数 */  p_rec->n_bytes_per_line = ((DWORD)p_rec->n_width) * 3;  DWORD_ALIGN(p_rec->n_bytes_per_line);

 /* 分量数 */  p_rec->n_components = NextByte(p_rec);

 if (p_rec->n_components <= 0 || p_rec->n_components > 4) return 0; /* 不支持的分量数 */

 for ( n = 0; n < p_rec->n_components; ++n ) {   /* 分量ID */   p_rec->i_component_ids[n] = jpeg_next_byte(p_rec);   /*    * Note!!!!    * Our index here doesn't mean component ids, its only an index    * We also reference our huffman-table & quanlity-table by index not by component id.    */   index = n;   if ( index >= p_rec->n_components ) return 0; /* 出现了错误的分量ID */   b = jpeg_next_byte(p_rec);   /* 分量采样率 */   p_rec->n_vert_sample_coes[index] = b & 0xf;   p_rec->n_horz_sample_coes[index] = b >> 4;   /* 计算分量采样率最大值 */   if (p_rec->n_vert_sample_coes[index] > p_rec->n_vert_sample_coes_max) p_rec->n_vert_sample_coes_max = p_rec->n_vert_sample_coes[index];   if (p_rec->n_horz_sample_coes[index] > p_rec->n_horz_sample_coes_max) p_rec->n_horz_sample_coes_max = p_rec->n_horz_sample_coes[index];   if (p_rec->n_vert_sample_coes[index] < p_rec->n_vert_sample_coes_min) p_rec->n_vert_sample_coes_min = p_rec->n_vert_sample_coes[index];   if (p_rec->n_horz_sample_coes[index] < p_rec->n_horz_sample_coes_min) p_rec->n_horz_sample_coes_min = p_rec->n_horz_sample_coes[index];   b = jpeg_next_byte(p_rec);   if (b >= 4) return 0; /* 出现了错误的量化表ID */   p_rec->n_quality_table_indexes[index] = b;  }

 return 1; }

/*  * 处理定义重启动段标志  *  返回非0表示成功  */ int jpeg_decode_DRI(p_jpeg_dec_rec p_rec) {  NextByte(p_rec);  jpeg_next_word(p_rec);  p_rec->n_reset_size = jpeg_next_word(p_rec);  p_rec->n_reset_cnt = p_rec->n_reset_size;  /* *NOT* jpeg_next_word(p_rec); */  return 1; }

/*  * 处理定义量化表标志  */ int jpeg_decode_DQT(p_jpeg_dec_rec p_rec) {  WORD size;  BYTE b, index, coe;  WORD 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 */   coe = b >> 4;   if ( coe != 0 ) coe = 1;   /* 量化表精度,0:8位 非0:16位 */   p_rec->quality_tables[index].precision = coe;   if ( coe == 0 ) {    /* 8位量化表 */    for ( i = 0; i < 64; i++ ) {     p_rec->quality_tables[index].values[i] = jpeg_next_byte(p_rec);    }    p_rec->quality_tables[index].process_in_idct = 0;    jpeg_idct_prepare_qualitytable(&p_rec->quality_tables[index]);    size -= (64 + 1);   } else {    /* 16位量化表 */    for ( i = 0; i < 64; i++ ) {     p_rec->quality_tables[index].values[i] = jpeg_next_word(p_rec);    }    p_rec->quality_tables[index].process_in_idct = 0;    jpeg_idct_prepare_qualitytable(&p_rec->quality_tables[index]);    size -= (64 * 2 + 1);   }  }  return 1; }

⌨️ 快捷键说明

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