[Libreoffice-commits] core.git: vcl/qa vcl/source

Caolán McNamara caolanm at redhat.com
Sat Mar 18 21:08:02 UTC 2017


 vcl/qa/cppunit/graphicfilter/data/jpg/pass/fatalerror-1.jpg |binary
 vcl/source/filter/jpeg/jpegc.cxx                            |  615 ++++++------
 2 files changed, 313 insertions(+), 302 deletions(-)

New commits:
commit 6889fa826eef6bd1074d77507818e71dfe8ba152
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Mar 18 20:19:51 2017 +0000

    rework jpeg error handling to throw rather than setjmp to avoid leaks
    
    Change-Id: I00e5041db7dcfb71d646438f7fda538d90ce6223
    Reviewed-on: https://gerrit.libreoffice.org/35414
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/qa/cppunit/graphicfilter/data/jpg/pass/fatalerror-1.jpg b/vcl/qa/cppunit/graphicfilter/data/jpg/pass/fatalerror-1.jpg
new file mode 100644
index 000000000000..c6ee53505944
Binary files /dev/null and b/vcl/qa/cppunit/graphicfilter/data/jpg/pass/fatalerror-1.jpg differ
diff --git a/vcl/source/filter/jpeg/jpegc.cxx b/vcl/source/filter/jpeg/jpegc.cxx
index e73065e668f0..c47bb126d65e 100644
--- a/vcl/source/filter/jpeg/jpegc.cxx
+++ b/vcl/source/filter/jpeg/jpegc.cxx
@@ -21,7 +21,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <setjmp.h>
 #include <jpeglib.h>
 #include <jerror.h>
 
@@ -38,26 +37,12 @@ extern "C" {
 #include <memory>
 #include <vcl/bitmapaccess.hxx>
 
-#ifdef _MSC_VER
-#pragma warning(push, 1) /* disable to __declspec(align()) aligned warning */
-#pragma warning (disable: 4324)
-#endif
-
-struct ErrorManagerStruct
-{
-    jpeg_error_mgr pub;
-    jmp_buf setjmp_buffer;
-};
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
 extern "C" void errorExit (j_common_ptr cinfo)
 {
-    ErrorManagerStruct * error = reinterpret_cast<ErrorManagerStruct *>(cinfo->err);
-    (*cinfo->err->output_message) (cinfo);
-    longjmp(error->setjmp_buffer, 1);
+    char buffer[JMSG_LENGTH_MAX];
+    (*cinfo->err->format_message) (cinfo, buffer);
+    SAL_WARN("vcl.filter", "fatal failure reading JPEG: " << buffer);
+    throw css::uno::RuntimeException(OUString(buffer, strlen(buffer), RTL_TEXTENCODING_ASCII_US));
 }
 
 extern "C" void outputMessage (j_common_ptr cinfo)
@@ -67,211 +52,238 @@ extern "C" void outputMessage (j_common_ptr cinfo)
     SAL_WARN("vcl.filter", "failure reading JPEG: " << buffer);
 }
 
-void ReadJPEG( JPEGReader* pJPEGReader, void* pInputStream, long* pLines,
-               Size const & previewSize )
+class JpegDecompressOwner
 {
-    jpeg_decompress_struct cinfo;
-    ErrorManagerStruct jerr;
+public:
+    JpegDecompressOwner(jpeg_decompress_struct &cinfo) : m_cinfo(cinfo)
+    {
+    }
+    ~JpegDecompressOwner()
+    {
+        jpeg_destroy_decompress(&m_cinfo);
+    }
+private:
+    jpeg_decompress_struct &m_cinfo;
+};
 
-    if ( setjmp( jerr.setjmp_buffer ) )
+class JpegCompressOwner
+{
+public:
+    JpegCompressOwner(jpeg_compress_struct &cinfo) : m_cinfo(cinfo)
+    {
+    }
+    ~JpegCompressOwner()
     {
-        jpeg_destroy_decompress( &cinfo );
-        return;
+        jpeg_destroy_compress(&m_cinfo);
     }
+private:
+    jpeg_compress_struct &m_cinfo;
+};
 
-    cinfo.err = jpeg_std_error( &jerr.pub );
-    jerr.pub.error_exit = errorExit;
-    jerr.pub.output_message = outputMessage;
-
-    jpeg_create_decompress( &cinfo );
-    jpeg_svstream_src( &cinfo, pInputStream );
-    SourceManagerStruct *source = reinterpret_cast<SourceManagerStruct*>(cinfo.src);
-    jpeg_read_header( &cinfo, TRUE );
-
-    cinfo.scale_num = 1;
-    cinfo.scale_denom = 1;
-    cinfo.output_gamma = 1.0;
-    cinfo.raw_data_out = FALSE;
-    cinfo.quantize_colors = FALSE;
-
-    /* change scale for preview import */
-    long nPreviewWidth = previewSize.Width();
-    long nPreviewHeight = previewSize.Height();
-    if( nPreviewWidth || nPreviewHeight )
+void ReadJPEG( JPEGReader* pJPEGReader, void* pInputStream, long* pLines,
+               Size const & previewSize )
+{
+    try
     {
-        if( nPreviewWidth == 0 )
+        jpeg_decompress_struct cinfo;
+        jpeg_error_mgr jerr;
+
+        cinfo.err = jpeg_std_error( &jerr );
+        jerr.error_exit = errorExit;
+        jerr.output_message = outputMessage;
+
+        jpeg_create_decompress( &cinfo );
+        JpegDecompressOwner aOwner(cinfo);
+        jpeg_svstream_src( &cinfo, pInputStream );
+        SourceManagerStruct *source = reinterpret_cast<SourceManagerStruct*>(cinfo.src);
+        jpeg_read_header( &cinfo, TRUE );
+
+        cinfo.scale_num = 1;
+        cinfo.scale_denom = 1;
+        cinfo.output_gamma = 1.0;
+        cinfo.raw_data_out = FALSE;
+        cinfo.quantize_colors = FALSE;
+
+        /* change scale for preview import */
+        long nPreviewWidth = previewSize.Width();
+        long nPreviewHeight = previewSize.Height();
+        if( nPreviewWidth || nPreviewHeight )
         {
-            nPreviewWidth = ( cinfo.image_width * nPreviewHeight ) / cinfo.image_height;
-            if( nPreviewWidth <= 0 )
+            if( nPreviewWidth == 0 )
             {
-                nPreviewWidth = 1;
+                nPreviewWidth = ( cinfo.image_width * nPreviewHeight ) / cinfo.image_height;
+                if( nPreviewWidth <= 0 )
+                {
+                    nPreviewWidth = 1;
+                }
             }
-        }
-        else if( nPreviewHeight == 0 )
-        {
-            nPreviewHeight = ( cinfo.image_height * nPreviewWidth ) / cinfo.image_width;
-            if( nPreviewHeight <= 0 )
+            else if( nPreviewHeight == 0 )
             {
-                nPreviewHeight = 1;
+                nPreviewHeight = ( cinfo.image_height * nPreviewWidth ) / cinfo.image_width;
+                if( nPreviewHeight <= 0 )
+                {
+                    nPreviewHeight = 1;
+                }
             }
-        }
 
-        for( cinfo.scale_denom = 1; cinfo.scale_denom < 8; cinfo.scale_denom *= 2 )
-        {
-            if( cinfo.image_width < nPreviewWidth * cinfo.scale_denom )
-                break;
-            if( cinfo.image_height < nPreviewHeight * cinfo.scale_denom )
-                break;
-        }
+            for( cinfo.scale_denom = 1; cinfo.scale_denom < 8; cinfo.scale_denom *= 2 )
+            {
+                if( cinfo.image_width < nPreviewWidth * cinfo.scale_denom )
+                    break;
+                if( cinfo.image_height < nPreviewHeight * cinfo.scale_denom )
+                    break;
+            }
 
-        if( cinfo.scale_denom > 1 )
-        {
-            cinfo.dct_method            = JDCT_FASTEST;
-            cinfo.do_fancy_upsampling   = FALSE;
-            cinfo.do_block_smoothing    = FALSE;
+            if( cinfo.scale_denom > 1 )
+            {
+                cinfo.dct_method            = JDCT_FASTEST;
+                cinfo.do_fancy_upsampling   = FALSE;
+                cinfo.do_block_smoothing    = FALSE;
+            }
         }
-    }
 
-    jpeg_calc_output_dimensions(&cinfo);
+        jpeg_calc_output_dimensions(&cinfo);
 
-    long nWidth = cinfo.output_width;
-    long nHeight = cinfo.output_height;
+        long nWidth = cinfo.output_width;
+        long nHeight = cinfo.output_height;
 
-    bool bGray = (cinfo.output_components == 1);
+        bool bGray = (cinfo.output_components == 1);
 
-    JPEGCreateBitmapParam aCreateBitmapParam;
+        JPEGCreateBitmapParam aCreateBitmapParam;
 
-    aCreateBitmapParam.nWidth = nWidth;
-    aCreateBitmapParam.nHeight = nHeight;
+        aCreateBitmapParam.nWidth = nWidth;
+        aCreateBitmapParam.nHeight = nHeight;
 
-    aCreateBitmapParam.density_unit = cinfo.density_unit;
-    aCreateBitmapParam.X_density = cinfo.X_density;
-    aCreateBitmapParam.Y_density = cinfo.Y_density;
-    aCreateBitmapParam.bGray = bGray;
+        aCreateBitmapParam.density_unit = cinfo.density_unit;
+        aCreateBitmapParam.X_density = cinfo.X_density;
+        aCreateBitmapParam.Y_density = cinfo.Y_density;
+        aCreateBitmapParam.bGray = bGray;
 
-    bool bBitmapCreated = pJPEGReader->CreateBitmap(aCreateBitmapParam);
+        bool bBitmapCreated = pJPEGReader->CreateBitmap(aCreateBitmapParam);
 
-    if (bBitmapCreated)
-    {
-        Bitmap::ScopedWriteAccess pAccess(pJPEGReader->GetBitmap());
-
-        if (pAccess)
+        if (bBitmapCreated)
         {
-            int nPixelSize = 3;
-            J_COLOR_SPACE best_out_color_space = JCS_RGB;
-            ScanlineFormat eScanlineFormat = ScanlineFormat::N24BitTcRgb;
-            ScanlineFormat eFinalFormat = pAccess->GetScanlineFormat();
-            if (eFinalFormat == ScanlineFormat::N32BitTcBgra)
-            {
-                best_out_color_space = JCS_EXT_BGRA;
-                eScanlineFormat = eFinalFormat;
-                nPixelSize = 4;
-            }
-            else if (eFinalFormat == ScanlineFormat::N32BitTcRgba)
-            {
-                best_out_color_space = JCS_EXT_RGBA;
-                eScanlineFormat = eFinalFormat;
-                nPixelSize = 4;
-            }
-            else if (eFinalFormat == ScanlineFormat::N32BitTcArgb)
-            {
-                best_out_color_space = JCS_EXT_ARGB;
-                eScanlineFormat = eFinalFormat;
-                nPixelSize = 4;
-            }
+            Bitmap::ScopedWriteAccess pAccess(pJPEGReader->GetBitmap());
 
-            if ( cinfo.jpeg_color_space == JCS_YCbCr )
-                cinfo.out_color_space = best_out_color_space;
-            else if ( cinfo.jpeg_color_space == JCS_YCCK )
-                cinfo.out_color_space = JCS_CMYK;
-
-            if (cinfo.out_color_space != JCS_CMYK &&
-                cinfo.out_color_space != JCS_GRAYSCALE &&
-                cinfo.out_color_space != best_out_color_space)
+            if (pAccess)
             {
-                SAL_WARN("vcl.filter", "jpg with unknown out color space, forcing to :" << best_out_color_space << " gray ");
-                cinfo.out_color_space = best_out_color_space;
-            }
-
-            jpeg_start_decompress(&cinfo);
+                int nPixelSize = 3;
+                J_COLOR_SPACE best_out_color_space = JCS_RGB;
+                ScanlineFormat eScanlineFormat = ScanlineFormat::N24BitTcRgb;
+                ScanlineFormat eFinalFormat = pAccess->GetScanlineFormat();
+                if (eFinalFormat == ScanlineFormat::N32BitTcBgra)
+                {
+                    best_out_color_space = JCS_EXT_BGRA;
+                    eScanlineFormat = eFinalFormat;
+                    nPixelSize = 4;
+                }
+                else if (eFinalFormat == ScanlineFormat::N32BitTcRgba)
+                {
+                    best_out_color_space = JCS_EXT_RGBA;
+                    eScanlineFormat = eFinalFormat;
+                    nPixelSize = 4;
+                }
+                else if (eFinalFormat == ScanlineFormat::N32BitTcArgb)
+                {
+                    best_out_color_space = JCS_EXT_ARGB;
+                    eScanlineFormat = eFinalFormat;
+                    nPixelSize = 4;
+                }
 
-            JSAMPLE* aRangeLimit = cinfo.sample_range_limit;
+                if ( cinfo.jpeg_color_space == JCS_YCbCr )
+                    cinfo.out_color_space = best_out_color_space;
+                else if ( cinfo.jpeg_color_space == JCS_YCCK )
+                    cinfo.out_color_space = JCS_CMYK;
 
-            std::vector<sal_uInt8> pScanLineBuffer(nWidth * (bGray ? 1 : nPixelSize));
-            std::vector<sal_uInt8> pCYMKBuffer;
+                if (cinfo.out_color_space != JCS_CMYK &&
+                    cinfo.out_color_space != JCS_GRAYSCALE &&
+                    cinfo.out_color_space != best_out_color_space)
+                {
+                    SAL_WARN("vcl.filter", "jpg with unknown out color space, forcing to :" << best_out_color_space << " gray ");
+                    cinfo.out_color_space = best_out_color_space;
+                }
 
-            if (cinfo.out_color_space == JCS_CMYK)
-            {
-                pCYMKBuffer.resize(nWidth * 4);
-            }
+                jpeg_start_decompress(&cinfo);
 
-            std::unique_ptr<BitmapColor[]> pCols;
+                JSAMPLE* aRangeLimit = cinfo.sample_range_limit;
 
-            if (bGray)
-            {
-                pCols.reset(new BitmapColor[256]);
+                std::vector<sal_uInt8> pScanLineBuffer(nWidth * (bGray ? 1 : nPixelSize));
+                std::vector<sal_uInt8> pCYMKBuffer;
 
-                for (sal_uInt16 n = 0; n < 256; n++)
+                if (cinfo.out_color_space == JCS_CMYK)
                 {
-                    const sal_uInt8 cGray = n;
-                    pCols[n] = pAccess->GetBestMatchingColor(BitmapColor(cGray, cGray, cGray));
+                    pCYMKBuffer.resize(nWidth * 4);
                 }
-            }
 
-            for (*pLines = 0; *pLines < nHeight && !source->no_data_available; (*pLines)++)
-            {
-                size_t yIndex = *pLines;
-
-                sal_uInt8* p = (cinfo.out_color_space == JCS_CMYK) ? pCYMKBuffer.data() : pScanLineBuffer.data();
-                jpeg_read_scanlines(&cinfo, reinterpret_cast<JSAMPARRAY>(&p), 1);
+                std::unique_ptr<BitmapColor[]> pCols;
 
                 if (bGray)
                 {
-                    for (long x = 0; x < nWidth; ++x)
+                    pCols.reset(new BitmapColor[256]);
+
+                    for (sal_uInt16 n = 0; n < 256; n++)
                     {
-                        sal_uInt8 nColorGray = pScanLineBuffer[x];
-                        pAccess->SetPixel(yIndex, x, pCols[nColorGray]);
+                        const sal_uInt8 cGray = n;
+                        pCols[n] = pAccess->GetBestMatchingColor(BitmapColor(cGray, cGray, cGray));
                     }
                 }
-                else if (cinfo.out_color_space == JCS_CMYK)
+
+                for (*pLines = 0; *pLines < nHeight && !source->no_data_available; (*pLines)++)
                 {
-                    // convert CMYK to RGB
-                    for (long cmyk = 0, x = 0; cmyk < nWidth * 4; cmyk += 4, ++x)
-                    {
-                        int color_C = 255 - pCYMKBuffer[cmyk + 0];
-                        int color_M = 255 - pCYMKBuffer[cmyk + 1];
-                        int color_Y = 255 - pCYMKBuffer[cmyk + 2];
-                        int color_K = 255 - pCYMKBuffer[cmyk + 3];
+                    size_t yIndex = *pLines;
 
-                        sal_uInt8 cRed = aRangeLimit[255L - (color_C + color_K)];
-                        sal_uInt8 cGreen = aRangeLimit[255L - (color_M + color_K)];
-                        sal_uInt8 cBlue = aRangeLimit[255L - (color_Y + color_K)];
+                    sal_uInt8* p = (cinfo.out_color_space == JCS_CMYK) ? pCYMKBuffer.data() : pScanLineBuffer.data();
+                    jpeg_read_scanlines(&cinfo, reinterpret_cast<JSAMPARRAY>(&p), 1);
 
-                        pAccess->SetPixel(yIndex, x, BitmapColor(cRed, cGreen, cBlue));
+                    if (bGray)
+                    {
+                        for (long x = 0; x < nWidth; ++x)
+                        {
+                            sal_uInt8 nColorGray = pScanLineBuffer[x];
+                            pAccess->SetPixel(yIndex, x, pCols[nColorGray]);
+                        }
+                    }
+                    else if (cinfo.out_color_space == JCS_CMYK)
+                    {
+                        // convert CMYK to RGB
+                        for (long cmyk = 0, x = 0; cmyk < nWidth * 4; cmyk += 4, ++x)
+                        {
+                            int color_C = 255 - pCYMKBuffer[cmyk + 0];
+                            int color_M = 255 - pCYMKBuffer[cmyk + 1];
+                            int color_Y = 255 - pCYMKBuffer[cmyk + 2];
+                            int color_K = 255 - pCYMKBuffer[cmyk + 3];
+
+                            sal_uInt8 cRed = aRangeLimit[255L - (color_C + color_K)];
+                            sal_uInt8 cGreen = aRangeLimit[255L - (color_M + color_K)];
+                            sal_uInt8 cBlue = aRangeLimit[255L - (color_Y + color_K)];
+
+                            pAccess->SetPixel(yIndex, x, BitmapColor(cRed, cGreen, cBlue));
+                        }
+                    }
+                    else
+                    {
+                        pAccess->CopyScanline(yIndex, pScanLineBuffer.data(), eScanlineFormat, pScanLineBuffer.size());
                     }
-                }
-                else
-                {
-                    pAccess->CopyScanline(yIndex, pScanLineBuffer.data(), eScanlineFormat, pScanLineBuffer.size());
-                }
 
-                /* PENDING ??? */
-                if (cinfo.err->msg_code == 113)
-                    break;
+                    /* PENDING ??? */
+                    if (cinfo.err->msg_code == 113)
+                        break;
+                }
             }
         }
-    }
 
-    if (bBitmapCreated)
-    {
-        jpeg_finish_decompress( &cinfo );
+        if (bBitmapCreated)
+        {
+            jpeg_finish_decompress( &cinfo );
+        }
+        else
+        {
+            jpeg_abort_decompress( &cinfo );
+        }
     }
-    else
+    catch (const css::uno::RuntimeException&)
     {
-        jpeg_abort_decompress( &cinfo );
     }
-
-    jpeg_destroy_decompress( &cinfo );
 }
 
 bool WriteJPEG( JPEGWriter* pJPEGWriter, void* pOutputStream,
@@ -279,167 +291,166 @@ bool WriteJPEG( JPEGWriter* pJPEGWriter, void* pOutputStream,
                 long nQualityPercent, long aChromaSubsampling,
                 css::uno::Reference<css::task::XStatusIndicator> const & status )
 {
-    jpeg_compress_struct        cinfo;
-    ErrorManagerStruct          jerr;
-    void*                       pScanline;
-    long                        nY;
-
-    if ( setjmp( jerr.setjmp_buffer ) )
+    try
     {
-        jpeg_destroy_compress( &cinfo );
-        return false;
-    }
-
-    cinfo.err = jpeg_std_error( &jerr.pub );
-    jerr.pub.error_exit = errorExit;
-    jerr.pub.output_message = outputMessage;
-
-    jpeg_create_compress( &cinfo );
-    jpeg_svstream_dest( &cinfo, pOutputStream );
+        jpeg_compress_struct        cinfo;
+        jpeg_error_mgr              jerr;
+        void*                       pScanline;
+        long                        nY;
+
+        cinfo.err = jpeg_std_error( &jerr );
+        jerr.error_exit = errorExit;
+        jerr.output_message = outputMessage;
+
+        jpeg_create_compress( &cinfo );
+        JpegCompressOwner aOwner(cinfo);
+        jpeg_svstream_dest( &cinfo, pOutputStream );
+
+        cinfo.image_width = (JDIMENSION) nWidth;
+        cinfo.image_height = (JDIMENSION) nHeight;
+        if ( bGreys )
+        {
+            cinfo.input_components = 1;
+            cinfo.in_color_space = JCS_GRAYSCALE;
+        }
+        else
+        {
+            cinfo.input_components = 3;
+            cinfo.in_color_space = JCS_RGB;
+        }
 
-    cinfo.image_width = (JDIMENSION) nWidth;
-    cinfo.image_height = (JDIMENSION) nHeight;
-    if ( bGreys )
-    {
-        cinfo.input_components = 1;
-        cinfo.in_color_space = JCS_GRAYSCALE;
-    }
-    else
-    {
-        cinfo.input_components = 3;
-        cinfo.in_color_space = JCS_RGB;
-    }
+        jpeg_set_defaults( &cinfo );
+        jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE );
 
-    jpeg_set_defaults( &cinfo );
-    jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE );
+        cinfo.density_unit = 1;
+        cinfo.X_density = aPPI.getX();
+        cinfo.Y_density = aPPI.getY();
 
-    cinfo.density_unit = 1;
-    cinfo.X_density = aPPI.getX();
-    cinfo.Y_density = aPPI.getY();
+        if ( ( nWidth > 128 ) || ( nHeight > 128 ) )
+            jpeg_simple_progression( &cinfo );
 
-    if ( ( nWidth > 128 ) || ( nHeight > 128 ) )
-        jpeg_simple_progression( &cinfo );
+        if (aChromaSubsampling == 1) // YUV 4:4:4
+        {
+            cinfo.comp_info[0].h_samp_factor = 1;
+            cinfo.comp_info[0].v_samp_factor = 1;
+        }
+        else if (aChromaSubsampling == 2) // YUV 4:2:2
+        {
+            cinfo.comp_info[0].h_samp_factor = 2;
+            cinfo.comp_info[0].v_samp_factor = 1;
+        }
+        else if (aChromaSubsampling == 3) // YUV 4:2:0
+        {
+            cinfo.comp_info[0].h_samp_factor = 2;
+            cinfo.comp_info[0].v_samp_factor = 2;
+        }
 
-    if (aChromaSubsampling == 1) // YUV 4:4:4
-    {
-        cinfo.comp_info[0].h_samp_factor = 1;
-        cinfo.comp_info[0].v_samp_factor = 1;
-    }
-    else if (aChromaSubsampling == 2) // YUV 4:2:2
-    {
-        cinfo.comp_info[0].h_samp_factor = 2;
-        cinfo.comp_info[0].v_samp_factor = 1;
-    }
-    else if (aChromaSubsampling == 3) // YUV 4:2:0
-    {
-        cinfo.comp_info[0].h_samp_factor = 2;
-        cinfo.comp_info[0].v_samp_factor = 2;
-    }
+        jpeg_start_compress( &cinfo, TRUE );
 
-    jpeg_start_compress( &cinfo, TRUE );
+        for( nY = 0; nY < nHeight; nY++ )
+        {
+            pScanline = pJPEGWriter->GetScanline( nY );
 
-    for( nY = 0; nY < nHeight; nY++ )
-    {
-        pScanline = pJPEGWriter->GetScanline( nY );
+            if( pScanline )
+            {
+                jpeg_write_scanlines( &cinfo, reinterpret_cast<JSAMPARRAY>(&pScanline), 1 );
+            }
 
-        if( pScanline )
-        {
-            jpeg_write_scanlines( &cinfo, reinterpret_cast<JSAMPARRAY>(&pScanline), 1 );
+            if( status.is() )
+            {
+                status->setValue( nY * 100L / nHeight );
+            }
         }
 
-        if( status.is() )
-        {
-            status->setValue( nY * 100L / nHeight );
-        }
+        jpeg_finish_compress(&cinfo);
+    }
+    catch (const css::uno::RuntimeException&)
+    {
+        return false;
     }
-
-    jpeg_finish_compress(&cinfo);
-    jpeg_destroy_compress( &cinfo );
-
     return true;
 }
 
 long Transform(void* pInputStream, void* pOutputStream, long nAngle)
 {
-    jpeg_transform_info aTransformOption;
-    JCOPY_OPTION        aCopyOption = JCOPYOPT_ALL;
-
-    jpeg_decompress_struct   aSourceInfo;
-    jpeg_compress_struct     aDestinationInfo;
-    ErrorManagerStruct       aSourceError;
-    ErrorManagerStruct       aDestinationError;
-
-    jvirt_barray_ptr* aSourceCoefArrays      = nullptr;
-    jvirt_barray_ptr* aDestinationCoefArrays = nullptr;
+    try
+    {
+        jpeg_transform_info aTransformOption;
+        JCOPY_OPTION        aCopyOption = JCOPYOPT_ALL;
 
-    aTransformOption.force_grayscale = FALSE;
-    aTransformOption.trim            = FALSE;
-    aTransformOption.perfect         = FALSE;
-    aTransformOption.crop            = FALSE;
+        jpeg_decompress_struct   aSourceInfo;
+        jpeg_compress_struct     aDestinationInfo;
+        jpeg_error_mgr           aSourceError;
+        jpeg_error_mgr           aDestinationError;
 
-    // Angle to transform option
-    // 90 Clockwise = 270 Counterclockwise
-    switch (nAngle)
-    {
-        case 2700:
-            aTransformOption.transform  = JXFORM_ROT_90;
-            break;
-        case 1800:
-            aTransformOption.transform  = JXFORM_ROT_180;
-            break;
-        case 900:
-            aTransformOption.transform  = JXFORM_ROT_270;
-            break;
-        default:
-            aTransformOption.transform  = JXFORM_NONE;
-    }
+        jvirt_barray_ptr* aSourceCoefArrays      = nullptr;
+        jvirt_barray_ptr* aDestinationCoefArrays = nullptr;
 
-    // Decompression
-    aSourceInfo.err                 = jpeg_std_error(&aSourceError.pub);
-    aSourceInfo.err->error_exit     = errorExit;
-    aSourceInfo.err->output_message = outputMessage;
+        aTransformOption.force_grayscale = FALSE;
+        aTransformOption.trim            = FALSE;
+        aTransformOption.perfect         = FALSE;
+        aTransformOption.crop            = FALSE;
 
-    // Compression
-    aDestinationInfo.err                 = jpeg_std_error(&aDestinationError.pub);
-    aDestinationInfo.err->error_exit     = errorExit;
-    aDestinationInfo.err->output_message = outputMessage;
+        // Angle to transform option
+        // 90 Clockwise = 270 Counterclockwise
+        switch (nAngle)
+        {
+            case 2700:
+                aTransformOption.transform  = JXFORM_ROT_90;
+                break;
+            case 1800:
+                aTransformOption.transform  = JXFORM_ROT_180;
+                break;
+            case 900:
+                aTransformOption.transform  = JXFORM_ROT_270;
+                break;
+            default:
+                aTransformOption.transform  = JXFORM_NONE;
+        }
 
-    aDestinationInfo.optimize_coding = TRUE;
+        // Decompression
+        aSourceInfo.err                 = jpeg_std_error(&aSourceError);
+        aSourceInfo.err->error_exit     = errorExit;
+        aSourceInfo.err->output_message = outputMessage;
 
-    if (setjmp(aSourceError.setjmp_buffer) || setjmp(aDestinationError.setjmp_buffer))
-    {
-        jpeg_destroy_decompress(&aSourceInfo);
-        jpeg_destroy_compress(&aDestinationInfo);
-        return 0;
-    }
+        // Compression
+        aDestinationInfo.err                 = jpeg_std_error(&aDestinationError);
+        aDestinationInfo.err->error_exit     = errorExit;
+        aDestinationInfo.err->output_message = outputMessage;
 
-    jpeg_create_decompress(&aSourceInfo);
-    jpeg_create_compress(&aDestinationInfo);
+        aDestinationInfo.optimize_coding = TRUE;
 
-    jpeg_svstream_src (&aSourceInfo, pInputStream);
+        jpeg_create_decompress(&aSourceInfo);
+        JpegDecompressOwner aDecompressOwner(aSourceInfo);
+        jpeg_create_compress(&aDestinationInfo);
+        JpegCompressOwner aCompressOwner(aDestinationInfo);
 
-    jcopy_markers_setup(&aSourceInfo, aCopyOption);
-    jpeg_read_header(&aSourceInfo, TRUE);
-    jtransform_request_workspace(&aSourceInfo, &aTransformOption);
+        jpeg_svstream_src (&aSourceInfo, pInputStream);
 
-    aSourceCoefArrays = jpeg_read_coefficients(&aSourceInfo);
-    jpeg_copy_critical_parameters(&aSourceInfo, &aDestinationInfo);
+        jcopy_markers_setup(&aSourceInfo, aCopyOption);
+        jpeg_read_header(&aSourceInfo, TRUE);
+        jtransform_request_workspace(&aSourceInfo, &aTransformOption);
 
-    aDestinationCoefArrays = jtransform_adjust_parameters(&aSourceInfo, &aDestinationInfo, aSourceCoefArrays, &aTransformOption);
-    jpeg_svstream_dest (&aDestinationInfo, pOutputStream);
+        aSourceCoefArrays = jpeg_read_coefficients(&aSourceInfo);
+        jpeg_copy_critical_parameters(&aSourceInfo, &aDestinationInfo);
 
-    // Compute optimal Huffman coding tables instead of precomuted tables
-    aDestinationInfo.optimize_coding = TRUE;
-    jpeg_write_coefficients(&aDestinationInfo, aDestinationCoefArrays);
-    jcopy_markers_execute(&aSourceInfo, &aDestinationInfo, aCopyOption);
-    jtransform_execute_transformation(&aSourceInfo, &aDestinationInfo, aSourceCoefArrays, &aTransformOption);
+        aDestinationCoefArrays = jtransform_adjust_parameters(&aSourceInfo, &aDestinationInfo, aSourceCoefArrays, &aTransformOption);
+        jpeg_svstream_dest (&aDestinationInfo, pOutputStream);
 
-    jpeg_finish_compress(&aDestinationInfo);
-    jpeg_destroy_compress(&aDestinationInfo);
+        // Compute optimal Huffman coding tables instead of precomuted tables
+        aDestinationInfo.optimize_coding = TRUE;
+        jpeg_write_coefficients(&aDestinationInfo, aDestinationCoefArrays);
+        jcopy_markers_execute(&aSourceInfo, &aDestinationInfo, aCopyOption);
+        jtransform_execute_transformation(&aSourceInfo, &aDestinationInfo, aSourceCoefArrays, &aTransformOption);
 
-    jpeg_finish_decompress(&aSourceInfo);
-    jpeg_destroy_decompress(&aSourceInfo);
+        jpeg_finish_compress(&aDestinationInfo);
 
+        jpeg_finish_decompress(&aSourceInfo);
+    }
+    catch (const css::uno::RuntimeException&)
+    {
+        return 0;
+    }
     return 1;
 }
 


More information about the Libreoffice-commits mailing list