diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-03-18 20:19:51 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2017-03-18 21:07:40 +0000 |
commit | 6889fa826eef6bd1074d77507818e71dfe8ba152 (patch) | |
tree | c361b28e3ec247bb9cc056ac2ae4f2d9eba6890b /vcl/source/filter/jpeg/jpegc.cxx | |
parent | 78d3af7260e553b63f65befacbb40ac68d8b4ce5 (diff) |
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@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source/filter/jpeg/jpegc.cxx')
-rw-r--r-- | vcl/source/filter/jpeg/jpegc.cxx | 615 |
1 files changed, 313 insertions, 302 deletions
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; } |