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

2014-11-23 23:36:45 · 作者: · 浏览: 18
t unsigned char *buf, unsigned int size)
{
int ret;
/* Identify the file */
//0x FF D8
//是否是JPEG格式文件?
if ((buf[0] != 0xFF) || (buf[1] != SOI))
snprintf(error_string, sizeof(error_string),"Not a JPG file \n");
//是
char temp_str[MAX_URL_LENGTH];
sprintf(temp_str,"0x %X %X",buf[0],buf[1]);
//JPEG格式文件固定的文件头
//begin指针前移2字节
priv->stream_begin = buf+2;
priv->stream_length = size-2;
priv->stream_end = priv->stream_begin + priv->stream_length;
//开始解析JFIF
ret = parse_JFIF(priv, priv->stream_begin);
return ret;
}
parse_JFIF()用于解析各种标签(SOF,SOS,DHT...):
[cpp] view plaincopy
//解各种不同的标签
static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
{
int chuck_len;
int marker;
int sos_marker_found = 0;
int dht_marker_found = 0;
const unsigned char *next_chunck;
/* Parse marker */
//在Start of scan标签之前
while (!sos_marker_found)
{
if (*stream++ != 0xff)
goto bogus_jpeg_format;
/* Skip any padding ff byte (this is normal) */
//跳过0xff字节
while (*stream == 0xff)
stream++;
//marker是跳过0xff字节后1个字节的内容
marker = *stream++;
//chunk_len是marker后面2个字节的内容(大端模式需要转换)
//包含自身,但不包含0xff+marker2字节
chuck_len = be16_to_cpu(stream);
//指向下一个chunk的指针
next_chunck = stream + chuck_len;
//各种不同的标签
switch (marker)
{
case SOF:
//开始解析SOF
if (parse_SOF(priv, stream) < 0)
return -1;
break;
//Define quantization table
case DQT:
//开始解析DQT
if (parse_DQT(priv, stream) < 0)
return -1;
break;
case SOS:
//开始解析SOS
if (parse_SOS(priv, stream) < 0)
return -1;
sos_marker_found = 1;
break;
//Define Huffman table
case DHT:
//开始解析DHT
if (parse_DHT(priv, stream) < 0)
return -1;
dht_marker_found = 1;
break;
case DRI:
//开始解析DRI
if (parse_DRI(priv, stream) < 0)
return -1;
break;
default:
#if TRACE_PARAM
fprintf(param_trace,"> Unknown marker %2.2x\n", marker);
fflush(param_trace);
#endif
break;
}
//解下一个segment
stream = next_chunck;
}
if (!dht_marker_found) {
#if TRACE_PARAM
fprintf(param_trace,"No Huffman table loaded, using the default one\n");
fflush(param_trace);
#endif
build_default_huffman_tables(priv);
}
#ifdef SANITY_CHECK
if ( (priv->component_infos[cY].Hfactor < priv->component_infos[cCb].Hfactor)
|| (priv->component_infos[cY].Hfactor < priv->component_infos[cCr].Hfactor))
snprintf(error_string, sizeof(error_string),"Horizontal sampling factor for Y should be greater than horitontal sampling factor for Cb or Cr\n");
if ( (priv->component_infos[cY].Vfactor < priv->component_infos[cCb].Vfactor)
|| (priv->component_infos[cY].Vfactor < priv->component_infos[cCr].Vfactor))
snprintf(error_string, sizeof(error_string),"Vertical sampling factor for Y should be greater than vertical sampling factor for Cb or Cr\n");
if ( (priv->component_infos[cCb].Hfactor!=1)
|| (priv->component_infos[cCr].Hfacto