Ticket #47280: patch-ipelib-ipebitmap.cpp.diff

File patch-ipelib-ipebitmap.cpp.diff, 2.8 KB (added by m.thon@…, 9 years ago)
  • ipelib/ipebitmap.cpp

    old new  
    3232#include "ipeutils.h"
    3333#include <zlib.h>
    3434
    35 #include <turbojpeg.h>
     35#include <cstdio>
     36#include <csetjmp>
     37#include <jpeglib.h>
     38
    3639#include <png.h>
    3740
    3841using namespace ipe;
     
    332335
    333336// --------------------------------------------------------------------
    334337
     338// The following is error-handling code for decopressing jpeg using the
     339// standard libjpeg API. Taken from the example.c and stackoverflow.
     340struct jpegErrorManager {
     341  struct jpeg_error_mgr pub;
     342  jmp_buf setjmp_buffer;
     343};
     344char jpegLastErrorMsg[JMSG_LENGTH_MAX];
     345void jpegErrorExit (j_common_ptr cinfo) {
     346  jpegErrorManager *myerr = (jpegErrorManager*) cinfo->err;
     347  (*(cinfo->err->format_message)) (cinfo, jpegLastErrorMsg);
     348  longjmp(myerr->setjmp_buffer, 1);
     349}
     350
     351// Decode jpeg image using the standard libjpeg API with errorhandling
    335352bool dctDecode(Buffer dctData, Buffer pixelData, int components)
    336353{
    337   tjhandle handle = tjInitDecompress();
    338   if (!handle) {
    339     ipeDebug("tjInitDecompress failed: %s",  tjGetErrorStr());
     354  struct jpeg_decompress_struct cinfo;
     355  // Error handling:
     356  struct jpegErrorManager jerr;
     357  cinfo.err = jpeg_std_error(&jerr.pub);
     358  jerr.pub.error_exit = jpegErrorExit;
     359  if (setjmp(jerr.setjmp_buffer)) {
     360    ipeDebug("jpeg decompression failed: %s", jpegLastErrorMsg);
     361    jpeg_destroy_decompress(&cinfo);
    340362    return false;
    341363  }
    342 
    343   int width, height, jpegSubsamp;
    344   if (tjDecompressHeader2(handle, (uchar *) dctData.data(), dctData.size(),
    345                           &width, &height, &jpegSubsamp) < 0) {
    346     ipeDebug("tjDecompressHeader2 failed: %s",  tjGetErrorStr());
    347     tjDestroy(handle);
    348     return false;
    349   }
    350 
    351   int flags = 0;
    352   // if (fast)
    353   // flags |= TJFLAG_FASTDCT;
    354 
    355   if (tjDecompress2(handle, (uchar *) dctData.data(), dctData.size(),
    356                     (uchar *) pixelData.data(),
    357                     width, components * width, height,
    358                     (components == 3) ? TJPF_RGB : TJPF_GRAY,
    359                     flags) < 0) {
    360     ipeDebug("tjDecompress2 failed: %s",  tjGetErrorStr());
    361     tjDestroy(handle);
    362     return false;
     364  // Decompression:
     365  jpeg_create_decompress(&cinfo);
     366  jpeg_mem_src(&cinfo, (unsigned char *) dctData.data(), dctData.size());
     367  jpeg_read_header(&cinfo, 1);
     368        cinfo.out_color_space = ((components == 3) ? JCS_RGB : JCS_GRAYSCALE);
     369  jpeg_start_decompress(&cinfo);
     370  while (cinfo.output_scanline < cinfo.output_height) {
     371                int row_stride = cinfo.output_width * cinfo.output_components;
     372                int index = cinfo.output_scanline * row_stride;
     373                unsigned char *buffer[1];
     374                buffer[0] = (unsigned char *) &(pixelData[index]);
     375    jpeg_read_scanlines(&cinfo, buffer, 1);
    363376  }
    364   tjDestroy(handle);
     377  jpeg_finish_decompress(&cinfo);
     378  jpeg_destroy_decompress(&cinfo);
    365379  return true;
    366380}
    367381