find out libjpeg version at runtime (or other ways to prevent aborts)?

点点圈 提交于 2019-12-23 01:40:12

问题


my application uses libjpeg to read/write JPEG-images. everything worked fine

recently my app started to crash when trying to write JPEG images with an error "Wrong JPEG library version: library is 80, caller expects 62" when calling jpeg_create_compress() (so the crash seems to be an intentional abort on the libjpeg side rather than a segfault)

a bit of investigation showed that indeed my application was compiled against libjpeg-62 headers (that were installed in /usr/local/include) and was then using the dylibs from libjpeg-80 (installed in /usr/lib/i386-linux-gnu/).

removing the libjpeg-62 headers and compiling using the libjpeg-80 headers solved the problem.

however, i would appreciate a solution that would allow me to prevent such crashes, even if some end-user has a different library version installed than my app was compiled against.

1) it would be great if i could somehow convince libjpeg to not abort even on fatal errors; e.g. something like:

jpeg_abort_on_error(0);

2) or have a non-aborting check whether the correct library is installed:

if(!jpeg_check_libraryversion()) return;

3) if that's not doable out of the box, i'm fine with manually checking the compile-time API-version (JPEG_LIB_VERSION) against a compat-version detected at runtime.

unfortunately i have not been able to find anything in the API that would allow me to use either of those methods.

am i just blind or do i need a something completely different?


回答1:


setting up an error-handler for error_exit prevents the application from crashing.

(my problem was that i had this done for the load-functionality, but not for the save-functionality, hence it exited when there were problems during saving). something like the following did the trick:

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);
  }
  /* ... */
}



回答2:


#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

   }


来源:https://stackoverflow.com/questions/10332908/find-out-libjpeg-version-at-runtime-or-other-ways-to-prevent-aborts

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!