1

我的应用程序使用 libjpeg 读取/写入 JPEG 图像。一切正常

最近我的应用程序在尝试编写 JPEG 图像时开始崩溃,并在调用 jpeg_create_compress() 时出现错误“错误的 JPEG 库版本:库为 80,调用者期望为 62”(因此崩溃似乎是 libjpeg 端的故意中止而不是段错误)

一些调查表明,确实我的应用程序是针对 libjpeg-62 头文件(安装在 /usr/local/include 中)编译的,然后使用来自 libjpeg-80 的 dylib(安装在 /usr/lib/i386-linux- gnu/).

删除 libjpeg-62 头文件并使用 libjpeg-80 头文件进行编译解决了该问题。

但是,即使某些最终用户安装的库版本与编译我的应用程序所针对的库版本不同,我也希望有一个解决方案可以让我防止此类崩溃。

1)如果我能以某种方式说服 libjpeg 即使出现致命错误也不要中止,那就太好了;例如:

jpeg_abort_on_error(0);

2)或有一个非中止检查是否安装了正确的库:

if(!jpeg_check_libraryversion()) return;

3)如果这不是开箱即用的,我可以手动检查编译时API版本(JPEG_LIB_VERSION)与运行时检测到的兼容版本。

不幸的是,我无法在 API 中找到任何可以让我使用其中任何一种方法的东西。

我只是盲人还是我需要完全不同的东西?

4

2 回答 2

1

为 error_exit 设置错误处理程序可防止应用程序崩溃。

(我的问题是我为加载功能完成了此操作,而不是为保存功能完成了此操作,因此在保存过程中出现问题时它退出了)。像下面这样的东西做了诀窍:

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_error_exit (j_common_ptr cinfo) {
 my_error_ptr myerr = reinterpret_cast<my_error_ptr> (cinfo->err);
 /* Return control to the setjmp point */
 longjmp(myerr->setjmp_buffer, 1);
}

/* ... */

void jpeg_save(const char*filename, struct image*img) {
  /* ... */
  /* We set up the normal JPEG error routines, then override error_exit */
  my_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  /* Establish the setjmp return context for my_error_exit to use. */
  if ( setjmp(jerr.setjmp_buffer) ) {
    /* If we get here, the JPEG code has signaled an error.
     * We need to clean up the JPEG object, close the input file, and return. */
    jpeg_destroy_compress(&cinfo);
    if(outfile)fclose(outfile);
    return(false);
  }
  /* ... */
}
于 2012-05-22T07:03:29.920 回答
1
#include "jpeglib.h"
#include <iostream>

// JPEG error handler
void JPEGVersionError(j_common_ptr cinfo)
   {
   int jpeg_version = cinfo->err->msg_parm.i[0];
   std::cout << "JPEG version: " << jpeg_version << std::endl;
   }

int main(int argc, char* argv[])
   {

    // Need to construct a decompress struct and give it an error handler
    // by passing an invalid version number we always trigger an error 
    // the error returns the linked version number as the first integer parameter
    jpeg_decompress_struct cinfo;
    jpeg_error_mgr error_mgr;
    error_mgr.error_exit = &JPEGVersionError;
    cinfo.err = &error_mgr;
    jpeg_CreateDecompress(&cinfo, -1 /*version*/, sizeof(cinfo)); // Pass -1 to always force an error

   }
于 2013-10-01T12:48:32.340 回答