异常jpg图片判断接口封装, 使用IJG JPEG库
起因: 最近在做图片聚合, 遇到一个麻烦的问题是, opencv提供的接口不能够判断残缺图片(corrupt image)。 所谓残缺图片, 就是人为的把一个正常的jpeg格式结尾数据删除一些, 在展示端内可以显示上半段图片, 又逃避图片识别程序的判断。opencv封装lib jpeg 太深, 觉得单独用lib jpeg 比较方便。
目标: 封装libjpeg , 提供接口判断jpeg图片是否完整。
用到的库: jpegsrc.v9b.tar.gz
#include <csetjmp> extern "C" { #include "jpeglib.h" } using namespace std; struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; typedef struct my_error_mgr * my_error_ptr; 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); } } bool isJpegCorrupt(void *mem,int msize) { bool ret = false; int row_width; JSAMPARRAY buffer; struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; if (setjmp(jerr.setjmp_buffer) != 0) { jpeg_destroy_decompress(&cinfo); return true; } cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.emit_message = my_emit_message; jpeg_create_decompress(&cinfo); jpeg_mem_src(&cinfo, (const unsigned char*)mem, msize); (void) jpeg_read_header(&cinfo, TRUE); (void) jpeg_start_decompress(&cinfo); row_width = cinfo.output_width * cinfo.output_components; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_width, 1); /* Process data */ while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); } (void) jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return ret; }
具体原理参考了: http://blog.csdn.net/gzz2424/article/details/5885656, 还有库自带的example.c 。
上面程序的关键点是
jpeg_mem_src(&cinfo, (const unsigned char*)mem, msize);
直接加载内存块, 若想直接加载文件可用
jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
初步满足需要 , 如果后续发现其他需要完善再更新。
2016 4 21 writen by 雷健辉(luikimfai)

浙公网安备 33010602011771号