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

File patch-ipelib-ipebitmap.cpp.diff, 2.8 KB (added by m.thon@…, 10 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>
    3638
    3739using namespace ipe;
    3840
     
    331333
    332334// --------------------------------------------------------------------
    333335
     336// The following is error-handling code for decopressing jpeg using the
     337// standard libjpeg API. Taken from the example.c and stackoverflow.
     338struct jpegErrorManager {
     339  struct jpeg_error_mgr pub;
     340  jmp_buf setjmp_buffer;
     341};
     342char jpegLastErrorMsg[JMSG_LENGTH_MAX];
     343void jpegErrorExit (j_common_ptr cinfo) {
     344  jpegErrorManager *myerr = (jpegErrorManager*) cinfo->err;
     345  (*(cinfo->err->format_message)) (cinfo, jpegLastErrorMsg);
     346  longjmp(myerr->setjmp_buffer, 1);
     347}
     348
     349// Decode jpeg image using the standard libjpeg API with errorhandling
    334350bool dctDecode(Buffer dctData, Buffer pixelData, int components)
    335351{
    336   tjhandle handle = tjInitDecompress();
    337   if (!handle) {
    338     ipeDebug("tjInitDecompress failed: %s",  tjGetErrorStr());
     352  struct jpeg_decompress_struct cinfo;
     353  // Error handling:
     354  struct jpegErrorManager jerr;
     355  cinfo.err = jpeg_std_error(&jerr.pub);
     356  jerr.pub.error_exit = jpegErrorExit;
     357  if (setjmp(jerr.setjmp_buffer)) {
     358    ipeDebug("jpeg decompression failed: %s", jpegLastErrorMsg);
     359    jpeg_destroy_decompress(&cinfo);
    339360    return false;
    340361  }
    341 
    342   int width, height, jpegSubsamp;
    343   if (tjDecompressHeader2(handle, (uchar *) dctData.data(), dctData.size(),
    344                           &width, &height, &jpegSubsamp) < 0) {
    345     ipeDebug("tjDecompressHeader2 failed: %s",  tjGetErrorStr());
    346     tjDestroy(handle);
    347     return false;
    348   }
    349 
    350   int flags = 0;
    351   // if (fast)
    352   // flags |= TJFLAG_FASTDCT;
    353 
    354   if (tjDecompress2(handle, (uchar *) dctData.data(), dctData.size(),
    355                     (uchar *) pixelData.data(),
    356                     width, components * width, height,
    357                     (components == 3) ? TJPF_RGB : TJPF_GRAY,
    358                     flags) < 0) {
    359     ipeDebug("tjDecompress2 failed: %s",  tjGetErrorStr());
    360     tjDestroy(handle);
    361     return false;
     362  // Decompression:
     363  jpeg_create_decompress(&cinfo);
     364  jpeg_mem_src(&cinfo, (unsigned char *) dctData.data(), dctData.size());
     365  jpeg_read_header(&cinfo, 1);
     366        cinfo.out_color_space = ((components == 3) ? JCS_RGB : JCS_GRAYSCALE);
     367  jpeg_start_decompress(&cinfo);
     368  while (cinfo.output_scanline < cinfo.output_height) {
     369                int row_stride = cinfo.output_width * cinfo.output_components;
     370                int index = cinfo.output_scanline * row_stride;
     371                unsigned char *buffer[1];
     372                buffer[0] = (unsigned char *) &(pixelData[index]);
     373    jpeg_read_scanlines(&cinfo, buffer, 1);
    362374  }
    363   tjDestroy(handle);
     375  jpeg_finish_decompress(&cinfo);
     376  jpeg_destroy_decompress(&cinfo);
    364377  return true;
    365378}
    366379