vcl/source/filter/jpeg/jpegc.cxx | 607 ++++++++++++++++++++------------------- 1 file changed, 321 insertions(+), 286 deletions(-)
New commits: commit cfbb8b5090537e79ba70e250ddee86d53facbe15 Author: Stephan Bergmann <sberg...@redhat.com> Date: Wed Oct 18 13:02:28 2017 +0200 Avoid throwing C++ exception across libjpeg C frames It causes trouble at least for (non-debug) 32-bit ARM Flatpak builds, where CppunitTest_vcl_filters_test aborts with an uncaught css::uno::RuntimeException. This is a partial revert of 6889fa826eef6bd1074d77507818e71dfe8ba152 "rework jpeg error handling to throw rather than setjmp to avoid leaks", switching back to setjmp/longjmp but trying to keep the leaks fixed by introducing any relevant local variables before the setjmps. Change-Id: Ia5984528ea98be1c89a21aee800b247120f88a89 Reviewed-on: https://gerrit.libreoffice.org/43494 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Stephan Bergmann <sberg...@redhat.com> diff --git a/vcl/source/filter/jpeg/jpegc.cxx b/vcl/source/filter/jpeg/jpegc.cxx index 4305f065ed54..86dd30b71c7e 100644 --- a/vcl/source/filter/jpeg/jpegc.cxx +++ b/vcl/source/filter/jpeg/jpegc.cxx @@ -21,6 +21,7 @@ #include <stdio.h> #include <stdlib.h> +#include <setjmp.h> #include <jpeglib.h> #include <jerror.h> @@ -37,12 +38,28 @@ extern "C" { #include <vcl/bitmapaccess.hxx> #include <vcl/graphicfilter.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) { 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)); + ErrorManagerStruct * error = reinterpret_cast<ErrorManagerStruct *>(cinfo->err); + longjmp(error->setjmp_buffer, 1); } extern "C" void outputMessage (j_common_ptr cinfo) @@ -55,226 +72,239 @@ extern "C" void outputMessage (j_common_ptr cinfo) class JpegDecompressOwner { public: - JpegDecompressOwner(jpeg_decompress_struct &cinfo) : m_cinfo(cinfo) + void set(jpeg_decompress_struct *cinfo) { + m_cinfo = cinfo; } ~JpegDecompressOwner() { - jpeg_destroy_decompress(&m_cinfo); + if (m_cinfo != nullptr) + { + jpeg_destroy_decompress(m_cinfo); + } } private: - jpeg_decompress_struct &m_cinfo; + jpeg_decompress_struct *m_cinfo = nullptr; }; class JpegCompressOwner { public: - JpegCompressOwner(jpeg_compress_struct &cinfo) : m_cinfo(cinfo) + void set(jpeg_compress_struct *cinfo) { + m_cinfo = cinfo; } ~JpegCompressOwner() { - jpeg_destroy_compress(&m_cinfo); + if (m_cinfo != nullptr) + { + jpeg_destroy_compress(m_cinfo); + } } private: - jpeg_compress_struct &m_cinfo; + jpeg_compress_struct *m_cinfo = nullptr; }; void ReadJPEG( JPEGReader* pJPEGReader, void* pInputStream, long* pLines, Size const & previewSize, GraphicFilterImportFlags nImportFlags, Bitmap::ScopedWriteAccess* ppAccess ) { - try + jpeg_decompress_struct cinfo; + ErrorManagerStruct jerr; + + JpegDecompressOwner aOwner; + std::unique_ptr<Bitmap::ScopedWriteAccess> pScopedAccess; + std::vector<sal_uInt8> pScanLineBuffer; + std::vector<sal_uInt8> pCYMKBuffer; + + if ( setjmp( jerr.setjmp_buffer ) ) + { + return; + } + + cinfo.err = jpeg_std_error( &jerr.pub ); + jerr.pub.error_exit = errorExit; + jerr.pub.output_message = outputMessage; + + jpeg_create_decompress( &cinfo ); + aOwner.set(&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 ) { - 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 ) + if( nPreviewWidth == 0 ) { - if( nPreviewWidth == 0 ) + nPreviewWidth = ( cinfo.image_width * nPreviewHeight ) / cinfo.image_height; + if( nPreviewWidth <= 0 ) { - nPreviewWidth = ( cinfo.image_width * nPreviewHeight ) / cinfo.image_height; - if( nPreviewWidth <= 0 ) - { - nPreviewWidth = 1; - } + nPreviewWidth = 1; } - else if( nPreviewHeight == 0 ) + } + else if( nPreviewHeight == 0 ) + { + nPreviewHeight = ( cinfo.image_height * nPreviewWidth ) / cinfo.image_width; + if( nPreviewHeight <= 0 ) { - nPreviewHeight = ( cinfo.image_height * nPreviewWidth ) / cinfo.image_width; - if( nPreviewHeight <= 0 ) - { - nPreviewHeight = 1; - } + 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; - const auto bOnlyCreateBitmap = static_cast<bool>(nImportFlags & GraphicFilterImportFlags::OnlyCreateBitmap); - const auto bUseExistingBitmap = static_cast<bool>(nImportFlags & GraphicFilterImportFlags::UseExistingBitmap); - bool bBitmapCreated = bUseExistingBitmap; - if (!bBitmapCreated) - bBitmapCreated = pJPEGReader->CreateBitmap(aCreateBitmapParam); + const auto bOnlyCreateBitmap = static_cast<bool>(nImportFlags & GraphicFilterImportFlags::OnlyCreateBitmap); + const auto bUseExistingBitmap = static_cast<bool>(nImportFlags & GraphicFilterImportFlags::UseExistingBitmap); + bool bBitmapCreated = bUseExistingBitmap; + if (!bBitmapCreated) + bBitmapCreated = pJPEGReader->CreateBitmap(aCreateBitmapParam); - if (bBitmapCreated && !bOnlyCreateBitmap) - { - std::unique_ptr<Bitmap::ScopedWriteAccess> pScopedAccess; + if (bBitmapCreated && !bOnlyCreateBitmap) + { + if (nImportFlags & GraphicFilterImportFlags::UseExistingBitmap) + // ppAccess must be set if this flag is used. + assert(ppAccess); + else + pScopedAccess.reset(new Bitmap::ScopedWriteAccess(pJPEGReader->GetBitmap())); - if (nImportFlags & GraphicFilterImportFlags::UseExistingBitmap) - // ppAccess must be set if this flag is used. - assert(ppAccess); - else - pScopedAccess.reset(new Bitmap::ScopedWriteAccess(pJPEGReader->GetBitmap())); + Bitmap::ScopedWriteAccess& pAccess = bUseExistingBitmap ? *ppAccess : *pScopedAccess.get(); - Bitmap::ScopedWriteAccess& pAccess = bUseExistingBitmap ? *ppAccess : *pScopedAccess.get(); + if (pAccess) + { + int nPixelSize = 3; + J_COLOR_SPACE best_out_color_space = JCS_RGB; + ScanlineFormat eScanlineFormat = ScanlineFormat::N24BitTcRgb; + ScanlineFormat eFinalFormat = pAccess->GetScanlineFormat(); - if (pAccess) + if (bGray) + { + best_out_color_space = JCS_GRAYSCALE; + eScanlineFormat = ScanlineFormat::N8BitPal; + nPixelSize = 1; + } + else 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) { - int nPixelSize = 3; - J_COLOR_SPACE best_out_color_space = JCS_RGB; - ScanlineFormat eScanlineFormat = ScanlineFormat::N24BitTcRgb; - ScanlineFormat eFinalFormat = pAccess->GetScanlineFormat(); + best_out_color_space = JCS_EXT_ARGB; + eScanlineFormat = eFinalFormat; + nPixelSize = 4; + } - if (bGray) - { - best_out_color_space = JCS_GRAYSCALE; - eScanlineFormat = ScanlineFormat::N8BitPal; - nPixelSize = 1; - } - else 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; - } + if (cinfo.jpeg_color_space == JCS_YCCK) + cinfo.out_color_space = JCS_CMYK; - if (cinfo.jpeg_color_space == JCS_YCCK) - cinfo.out_color_space = JCS_CMYK; + if (cinfo.out_color_space != JCS_CMYK) + cinfo.out_color_space = best_out_color_space; - if (cinfo.out_color_space != JCS_CMYK) - cinfo.out_color_space = best_out_color_space; + jpeg_start_decompress(&cinfo); - jpeg_start_decompress(&cinfo); + JSAMPLE* aRangeLimit = cinfo.sample_range_limit; - JSAMPLE* aRangeLimit = cinfo.sample_range_limit; + pScanLineBuffer.resize(nWidth * nPixelSize); - std::vector<sal_uInt8> pScanLineBuffer(nWidth * nPixelSize); - std::vector<sal_uInt8> pCYMKBuffer; + if (cinfo.out_color_space == JCS_CMYK) + { + pCYMKBuffer.resize(nWidth * 4); + } - if (cinfo.out_color_space == JCS_CMYK) - { - 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); - for (*pLines = 0; *pLines < nHeight && !source->no_data_available; (*pLines)++) + if (cinfo.out_color_space == JCS_CMYK) { - size_t yIndex = *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]; - sal_uInt8* p = (cinfo.out_color_space == JCS_CMYK) ? pCYMKBuffer.data() : pScanLineBuffer.data(); - jpeg_read_scanlines(&cinfo, reinterpret_cast<JSAMPARRAY>(&p), 1); + 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)]; - 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()); + pAccess->SetPixel(yIndex, x, BitmapColor(cRed, cGreen, cBlue)); } - - /* PENDING ??? */ - if (cinfo.err->msg_code == 113) - break; } + else + { + pAccess->CopyScanline(yIndex, pScanLineBuffer.data(), eScanlineFormat, pScanLineBuffer.size()); + } + + /* PENDING ??? */ + if (cinfo.err->msg_code == 113) + break; } - } - if (bBitmapCreated && !bOnlyCreateBitmap) - { - jpeg_finish_decompress( &cinfo ); - } - else - { - jpeg_abort_decompress( &cinfo ); + pScanLineBuffer.clear(); + pCYMKBuffer.clear(); } + pScopedAccess.reset(); } - catch (const css::uno::RuntimeException&) + + if (bBitmapCreated && !bOnlyCreateBitmap) { + jpeg_finish_decompress( &cinfo ); + } + else + { + jpeg_abort_decompress( &cinfo ); } } @@ -283,165 +313,170 @@ bool WriteJPEG( JPEGWriter* pJPEGWriter, void* pOutputStream, long nQualityPercent, long aChromaSubsampling, css::uno::Reference<css::task::XStatusIndicator> const & status ) { - try - { - 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; - } + jpeg_compress_struct cinfo; + ErrorManagerStruct jerr; + void* pScanline; + long nY; - jpeg_set_defaults( &cinfo ); - jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE ); + JpegCompressOwner aOwner; - cinfo.density_unit = 1; - cinfo.X_density = rPPI.getX(); - cinfo.Y_density = rPPI.getY(); + if ( setjmp( jerr.setjmp_buffer ) ) + { + return false; + } - if ( ( nWidth > 128 ) || ( nHeight > 128 ) ) - jpeg_simple_progression( &cinfo ); + cinfo.err = jpeg_std_error( &jerr.pub ); + jerr.pub.error_exit = errorExit; + jerr.pub.output_message = outputMessage; - 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_create_compress( &cinfo ); + aOwner.set(&cinfo); + jpeg_svstream_dest( &cinfo, pOutputStream ); - jpeg_start_compress( &cinfo, TRUE ); + 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; + } - for( nY = 0; nY < nHeight; nY++ ) - { - pScanline = pJPEGWriter->GetScanline( nY ); + jpeg_set_defaults( &cinfo ); + jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE ); - if( pScanline ) - { - jpeg_write_scanlines( &cinfo, reinterpret_cast<JSAMPARRAY>(&pScanline), 1 ); - } + cinfo.density_unit = 1; + cinfo.X_density = rPPI.getX(); + cinfo.Y_density = rPPI.getY(); - if( status.is() ) - { - status->setValue( nY * 100L / nHeight ); - } - } + if ( ( nWidth > 128 ) || ( nHeight > 128 ) ) + jpeg_simple_progression( &cinfo ); - jpeg_finish_compress(&cinfo); + if (aChromaSubsampling == 1) // YUV 4:4:4 + { + cinfo.comp_info[0].h_samp_factor = 1; + cinfo.comp_info[0].v_samp_factor = 1; } - catch (const css::uno::RuntimeException&) + else if (aChromaSubsampling == 2) // YUV 4:2:2 { - return false; + cinfo.comp_info[0].h_samp_factor = 2; + cinfo.comp_info[0].v_samp_factor = 1; } - return true; -} - -void Transform(void* pInputStream, void* pOutputStream, long nAngle) -{ - try + else if (aChromaSubsampling == 3) // YUV 4:2:0 { - jpeg_transform_info aTransformOption; - JCOPY_OPTION aCopyOption = JCOPYOPT_ALL; + cinfo.comp_info[0].h_samp_factor = 2; + cinfo.comp_info[0].v_samp_factor = 2; + } - jpeg_decompress_struct aSourceInfo; - jpeg_compress_struct aDestinationInfo; - jpeg_error_mgr aSourceError; - jpeg_error_mgr aDestinationError; + jpeg_start_compress( &cinfo, TRUE ); - jvirt_barray_ptr* aSourceCoefArrays = nullptr; - jvirt_barray_ptr* aDestinationCoefArrays = nullptr; + for( nY = 0; nY < nHeight; nY++ ) + { + pScanline = pJPEGWriter->GetScanline( nY ); - aTransformOption.force_grayscale = FALSE; - aTransformOption.trim = FALSE; - aTransformOption.perfect = FALSE; - aTransformOption.crop = FALSE; + if( pScanline ) + { + jpeg_write_scanlines( &cinfo, reinterpret_cast<JSAMPARRAY>(&pScanline), 1 ); + } - // Angle to transform option - // 90 Clockwise = 270 Counterclockwise - switch (nAngle) + if( status.is() ) { - 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; + status->setValue( nY * 100L / nHeight ); } + } - // Decompression - aSourceInfo.err = jpeg_std_error(&aSourceError); - aSourceInfo.err->error_exit = errorExit; - aSourceInfo.err->output_message = outputMessage; + jpeg_finish_compress(&cinfo); - // Compression - aDestinationInfo.err = jpeg_std_error(&aDestinationError); - aDestinationInfo.err->error_exit = errorExit; - aDestinationInfo.err->output_message = outputMessage; + return true; +} + +void Transform(void* pInputStream, void* pOutputStream, long nAngle) +{ + jpeg_transform_info aTransformOption; + JCOPY_OPTION aCopyOption = JCOPYOPT_ALL; - aDestinationInfo.optimize_coding = TRUE; + jpeg_decompress_struct aSourceInfo; + jpeg_compress_struct aDestinationInfo; + ErrorManagerStruct aSourceError; + ErrorManagerStruct aDestinationError; - jpeg_create_decompress(&aSourceInfo); - JpegDecompressOwner aDecompressOwner(aSourceInfo); - jpeg_create_compress(&aDestinationInfo); - JpegCompressOwner aCompressOwner(aDestinationInfo); + jvirt_barray_ptr* aSourceCoefArrays = nullptr; + jvirt_barray_ptr* aDestinationCoefArrays = nullptr; - jpeg_svstream_src (&aSourceInfo, pInputStream); + aTransformOption.force_grayscale = FALSE; + aTransformOption.trim = FALSE; + aTransformOption.perfect = FALSE; + aTransformOption.crop = FALSE; - jcopy_markers_setup(&aSourceInfo, aCopyOption); - jpeg_read_header(&aSourceInfo, TRUE); - jtransform_request_workspace(&aSourceInfo, &aTransformOption); + // 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; + } - aSourceCoefArrays = jpeg_read_coefficients(&aSourceInfo); - jpeg_copy_critical_parameters(&aSourceInfo, &aDestinationInfo); + // Decompression + aSourceInfo.err = jpeg_std_error(&aSourceError.pub); + aSourceInfo.err->error_exit = errorExit; + aSourceInfo.err->output_message = outputMessage; - aDestinationCoefArrays = jtransform_adjust_parameters(&aSourceInfo, &aDestinationInfo, aSourceCoefArrays, &aTransformOption); - jpeg_svstream_dest (&aDestinationInfo, pOutputStream); + // Compression + aDestinationInfo.err = jpeg_std_error(&aDestinationError.pub); + aDestinationInfo.err->error_exit = errorExit; + aDestinationInfo.err->output_message = outputMessage; - // Compute optimal Huffman coding tables instead of precomputed tables - aDestinationInfo.optimize_coding = TRUE; - jpeg_write_coefficients(&aDestinationInfo, aDestinationCoefArrays); - jcopy_markers_execute(&aSourceInfo, &aDestinationInfo, aCopyOption); - jtransform_execute_transformation(&aSourceInfo, &aDestinationInfo, aSourceCoefArrays, &aTransformOption); + aDestinationInfo.optimize_coding = TRUE; - jpeg_finish_compress(&aDestinationInfo); + JpegDecompressOwner aDecompressOwner; + JpegCompressOwner aCompressOwner; - jpeg_finish_decompress(&aSourceInfo); - } - catch (const css::uno::RuntimeException&) + if (setjmp(aSourceError.setjmp_buffer) || setjmp(aDestinationError.setjmp_buffer)) { + jpeg_destroy_decompress(&aSourceInfo); + jpeg_destroy_compress(&aDestinationInfo); + return; } + + jpeg_create_decompress(&aSourceInfo); + aDecompressOwner.set(&aSourceInfo); + jpeg_create_compress(&aDestinationInfo); + aCompressOwner.set(&aDestinationInfo); + + jpeg_svstream_src (&aSourceInfo, pInputStream); + + jcopy_markers_setup(&aSourceInfo, aCopyOption); + jpeg_read_header(&aSourceInfo, TRUE); + jtransform_request_workspace(&aSourceInfo, &aTransformOption); + + aSourceCoefArrays = jpeg_read_coefficients(&aSourceInfo); + jpeg_copy_critical_parameters(&aSourceInfo, &aDestinationInfo); + + aDestinationCoefArrays = jtransform_adjust_parameters(&aSourceInfo, &aDestinationInfo, aSourceCoefArrays, &aTransformOption); + jpeg_svstream_dest (&aDestinationInfo, pOutputStream); + + // Compute optimal Huffman coding tables instead of precomputed 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_compress(&aDestinationInfo); + + jpeg_finish_decompress(&aSourceInfo); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits