IJG JPEG库运行时错误:Corrupt JPEG data 的解决方案

时间:2022-01-06 15:22:32

做嵌入式图像识别,用V4L2捕获图像为JPEG格式,用IJG JPEG库转成BMP格式时偶尔出现如下错误或警告:

Corrupt JPEG data: XX extraneous bytes before marker 0xXX

Corrupt JPEG data: premature end of data segment

由于这些错误在IJG JPEG库里只认为是警告,如果不对其处理,代码将继续执行,因而捕获的图像不正常。这个错误对我的处理算法结果造成影响,决定排除。

Google百度下来发现没有什么好的解决方案,最好的一个是对 Corrupt JPEG data: XX extraneous bytes before marker 0xXX的解决,他是这样做的:

view plaincopy to clipboardprint?
First, I've noticed that in jpegsrc.v6b.tar.gz there is a file called jerror.h, which has these lines:  
 
JMESSAGE(JWRN_EXTRANEOUS_DATA,  
"Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")  
 
 
Then, I looked for JWRN_EXTRANEOUS_DATA string and found it in jdmarker.c  
And then, I commented out the warning line in that file, as below:  
 
if (cinfo->marker->discarded_bytes != 0) {  
/*WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); Commented out by Denny! */ 
cinfo->marker->discarded_bytes = 0;  

First, I've noticed that in jpegsrc.v6b.tar.gz there is a file called jerror.h, which has these lines:

JMESSAGE(JWRN_EXTRANEOUS_DATA,
"Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")


Then, I looked for JWRN_EXTRANEOUS_DATA string and found it in jdmarker.c
And then, I commented out the warning line in that file, as below:

if (cinfo->marker->discarded_bytes != 0) {
/*WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); Commented out by Denny! */
cinfo->marker->discarded_bytes = 0;
}
 

意思是把WARNMS2()注掉,然后重新编译IJG JPEG源码,就不会出现Corrupt JPEG data: XX extraneous bytes before marker 0xXX。这个可有点勉强。。。太麻烦了,总应该有好的办法。

Google百度一下 WARNMS2,没有~于是找 JWRN_EXTRANEOUS_DATA,

找到了jerror.h的源码,看到下面有一段:

view plaincopy to clipboardprint?
#define WARNMS2(cinfo,code,p1,p2)    
   
    ((cinfo)->err->msg_code = (code),   
   
     (cinfo)->err->msg_parm.i[0] = (p1),   
   
     (cinfo)->err->msg_parm.i[1] = (p2),   
   
     (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))  
  
#define WARNMS2(cinfo,code,p1,p2) 
 
    ((cinfo)->err->msg_code = (code),
 
     (cinfo)->err->msg_parm.i[0] = (p1),
 
     (cinfo)->err->msg_parm.i[1] = (p2),
 
     (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
 
 

发现发出的异常消息是emit_message,异常等级为-1, 于是处理掉这个异常就OK了!

代码如下:

先声名一个异常处理函数:my_emit_message

view plaincopy to clipboardprint?
METHODDEF(void) my_emit_message(j_common_ptr cinfo, int msg_level)  
{  
    my_error_ptr myerr = (my_error_ptr) cinfo->err;  
    if(msg_level == -1) longjmp(myerr->setjmp_buffer, 1);  

METHODDEF(void) my_emit_message(j_common_ptr cinfo, int msg_level)
{
 my_error_ptr myerr = (my_error_ptr) cinfo->err;
 if(msg_level == -1) longjmp(myerr->setjmp_buffer, 1);
}

再捕获这个异常(注意这里没写出其它异常类型处理,如error_exit):

view plaincopy to clipboardprint?
struct my_error_mgr jerr;  
cinfo.err = jpeg_std_error(&jerr.pub);  
jerr.pub.emit_message = my_emit_message;  
 
if (setjmp(jerr.setjmp_buffer) != 0)  
{  
    jpeg_destroy_decompress(&cinfo);//printf("jpeg_destroy_decompress/n");  
 
    //...  
    return 0;  

struct my_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.emit_message = my_emit_message;

if (setjmp(jerr.setjmp_buffer) != 0)
{
 jpeg_destroy_decompress(&cinfo);//printf("jpeg_destroy_decompress/n");

 //...
 return 0;
}

这样就解决了,Corrupt JPEG data: XX extraneous bytes before marker 0xXX 问题,不过把所有的emit_message异常都屏蔽了,并认为是失败,代码运行后发现Corrupt JPEG data: premature end of data segment也是其中之一,所以也正好都解决了。代码运行了几分钟很正常,都显示屏蔽了。

这个方法发上来备忘一下,也给需要的人参考。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gzz2424/archive/2010/09/15/5885656.aspx