Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头(一)

2014-11-23 23:36:45 · 作者: · 浏览: 20
Tiny Jpeg Decoder是一个可以用于嵌入式 系统的JPEG解码器。也可以在Windows上编译通过。在此分析一下它部分的源代码,辅助学习JPEG解码知识。
通过TinyJpeg可以将JPEG(*.jpg)文件解码为YUV(*.yuv)或者RGB(*.tga)文件。
真正的解码开始于convert_one_image()函数:
[cpp]
/**
* Load one jpeg image, and decompress it, and save the result.
*/
int convert_one_image(LPVOID lparam,const char *infilename, const char *outfilename, int output_format)
{
FILE *fp;
unsigned int length_of_file;
unsigned int width, height;
unsigned char *buf;
struct jdec_private *jdec;
unsigned char *components[3];
/* Load the Jpeg into memory */
fp = fopen(infilename, "rb");
if (fp == NULL)
exitmessage("Cannot open filename\n");
length_of_file = filesize(fp);
buf = (unsigned char *)malloc(length_of_file + 4);
if (buf == NULL)
exitmessage("Not enough memory for loading file\n");
fread(buf, length_of_file, 1, fp);
fclose(fp);
/* Decompress it */
//分配内存
jdec = tinyjpeg_init();
//传入句柄--------------
jdec->dlg=(CSpecialVIJPGDlg *)lparam;
if (jdec == NULL)
exitmessage("Not enough memory to alloc the structure need for decompressing\n");
//解头部
if (tinyjpeg_parse_header(jdec, buf, length_of_file)<0)
exitmessage(tinyjpeg_get_errorstring(jdec));
/* Get the size of the image */
//获得图像长宽
tinyjpeg_get_size(jdec, &width, &height);
snprintf(error_string, sizeof(error_string),"Decoding JPEG image...\n");
//解码实际数据
if (tinyjpeg_decode(jdec, output_format) < 0)
exitmessage(tinyjpeg_get_errorstring(jdec));
/*
* Get address for each plane (not only max 3 planes is supported), and
* depending of the output mode, only some components will be filled
* RGB: 1 plane, YUV420P: 3 planes, GREY: 1 plane
*/
tinyjpeg_get_components(jdec, components);
/* Save it */
switch (output_format)
{
case TINYJPEG_FMT_RGB24:
case TINYJPEG_FMT_BGR24:
write_tga(outfilename, output_format, width, height, components);
break;
case TINYJPEG_FMT_YUV420P:
//开始写入成YUV420P文件
write_yuv(outfilename, width, height, components);
break;
case TINYJPEG_FMT_GREY:
//开始写入成灰度文件
write_pgm(outfilename, width, height, components);
break;
}
/* Only called this if the buffers were allocated by tinyjpeg_decode() */
//modify by lei! tinyjpeg_free(jdec);
/* else called just free(jdec); */
free(buf);
return 0;
}
tinyjpeg_init()用于初始化:
[cpp]
/**
* Allocate a new tinyjpeg decoder object.
*
* Before calling any other functions, an object need to be called.
*/
struct jdec_private *tinyjpeg_init(void)
{
struct jdec_private *priv;
priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private));
if (priv == NULL)
return NULL;
priv->DQT_table_num=0;
return priv;
}
tinyjpeg_parse_header()用于解码JPEG文件头,可见函数前几句主要验证文件是否为JPEG文件:
[cpp]
/**
* Initialize the tinyjpeg object and prepare the decoding of the stream.
*
* Check if the jpeg can be decoded with this jpeg decoder.
* Fill some table used for preprocessing.
*/
int tinyjpeg_parse_header(struct jdec_private *priv, cons