summaryrefslogtreecommitdiff
path: root/vcl/source/filter/jpeg/jpegc.cxx
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-03-18 20:19:51 +0000
committerCaolán McNamara <caolanm@redhat.com>2017-03-18 21:07:40 +0000
commit6889fa826eef6bd1074d77507818e71dfe8ba152 (patch)
treec361b28e3ec247bb9cc056ac2ae4f2d9eba6890b /vcl/source/filter/jpeg/jpegc.cxx
parent78d3af7260e553b63f65befacbb40ac68d8b4ce5 (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.cxx615
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;
}