summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTomaž Vajngerl <quikee@gmail.com>2013-04-21 13:50:09 +0200
committerTomaž Vajngerl <quikee@gmail.com>2013-04-21 21:55:44 +0200
commit759f24152a2ab44189de0fd242c3e409c9a479a8 (patch)
tree2412fb6166d63425e6e0b6541c787b2676dc87ab /vcl
parent252b6b608f5fc35b154846c3487809fe5e147ab7 (diff)
Split JpegWriter and JpegReader out from jpeg.cxx/hxx
jpeg.cxx/hxx contains classes JpegWriter and JpegReader which are considered private. Split this two classes and other related functions into its own files. Change-Id: I41c1139b30a4dc19e03b2232dfe0986cc05d0c08
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vcl.mk2
-rw-r--r--vcl/source/filter/jpeg/JpegReader.cxx473
-rw-r--r--vcl/source/filter/jpeg/JpegReader.hxx62
-rw-r--r--vcl/source/filter/jpeg/JpegWriter.cxx274
-rw-r--r--vcl/source/filter/jpeg/JpegWriter.hxx58
-rw-r--r--vcl/source/filter/jpeg/jpeg.cxx712
-rw-r--r--vcl/source/filter/jpeg/jpeg.h8
-rw-r--r--vcl/source/filter/jpeg/jpeg.hxx72
-rw-r--r--vcl/source/filter/jpeg/jpegc.c108
9 files changed, 961 insertions, 808 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 17d1ef6c1723..057e508b7be0 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -178,6 +178,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/filter/ixbm/xbmread \
vcl/source/filter/ixpm/xpmread \
vcl/source/filter/jpeg/jpeg \
+ vcl/source/filter/jpeg/JpegReader \
+ vcl/source/filter/jpeg/JpegWriter \
vcl/source/filter/wmf/emfwr \
vcl/source/filter/wmf/enhwmf \
vcl/source/filter/wmf/winmtf \
diff --git a/vcl/source/filter/jpeg/JpegReader.cxx b/vcl/source/filter/jpeg/JpegReader.cxx
new file mode 100644
index 000000000000..1fa4fa9edf10
--- /dev/null
+++ b/vcl/source/filter/jpeg/JpegReader.cxx
@@ -0,0 +1,473 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <tools/solar.h>
+
+extern "C"
+{
+ #include "stdio.h"
+ #include "jpeg.h"
+ #include <jpeglib.h>
+ #include <jerror.h>
+}
+
+#include "JpegReader.hxx"
+#include <vcl/bmpacc.hxx>
+#include <vcl/FilterConfigItem.hxx>
+#include <vcl/graphicfilter.hxx>
+
+#define JPEG_MIN_READ 512
+#define BUFFER_SIZE 4096
+
+extern "C" void* CreateBitmapFromJPEGReader( void* pJPEGReader, void* pJPEGCreateBitmapParam )
+{
+ return ( (JPEGReader*) pJPEGReader )->CreateBitmap( pJPEGCreateBitmapParam );
+}
+
+/* Expanded data source object for stdio input */
+
+typedef struct {
+ struct jpeg_source_mgr pub; /* public fields */
+ SvStream* stream; /* source stream */
+ JOCTET* buffer; /* start of buffer */
+ boolean start_of_file; /* have we gotten any data yet? */
+} SourceManagerStruct;
+
+typedef SourceManagerStruct* SourceManagerStructPointer;
+
+/*
+ * Initialize source --- called by jpeg_read_header
+ * before any data is actually read.
+ */
+extern "C" void init_source (j_decompress_ptr cinfo)
+{
+ SourceManagerStructPointer source = (SourceManagerStructPointer) cinfo->src;
+
+ /* We reset the empty-input-file flag for each image,
+ * but we don't clear the input buffer.
+ * This is correct behavior for reading a series of images from one source.
+ */
+ source->start_of_file = sal_True;
+}
+
+long StreamRead( SvStream* pStream, void* pBuffer, long nBufferSize )
+{
+ long nRead = 0;
+
+ if( pStream->GetError() != ERRCODE_IO_PENDING )
+ {
+ long nInitialPosition = pStream->Tell();
+
+ nRead = (long) pStream->Read( pBuffer, nBufferSize );
+
+ if( pStream->GetError() == ERRCODE_IO_PENDING )
+ {
+ // Damit wir wieder an die alte Position
+ // seeken koennen, setzen wir den Error temp.zurueck
+ pStream->ResetError();
+ pStream->Seek( nInitialPosition );
+ pStream->SetError( ERRCODE_IO_PENDING );
+ }
+ }
+
+ return nRead;
+}
+
+extern "C" boolean fill_input_buffer (j_decompress_ptr cinfo)
+{
+ SourceManagerStructPointer source = (SourceManagerStructPointer) cinfo->src;
+ size_t nbytes;
+
+ nbytes = StreamRead(source->stream, source->buffer, BUFFER_SIZE);
+
+ if (!nbytes)
+ {
+ if (source->start_of_file) /* Treat empty input file as fatal error */
+ {
+ ERREXIT(cinfo, JERR_INPUT_EMPTY);
+ }
+ WARNMS(cinfo, JWRN_JPEG_EOF);
+ /* Insert a fake EOI marker */
+ source->buffer[0] = (JOCTET) 0xFF;
+ source->buffer[1] = (JOCTET) JPEG_EOI;
+ nbytes = 2;
+ }
+
+ source->pub.next_input_byte = source->buffer;
+ source->pub.bytes_in_buffer = nbytes;
+ source->start_of_file = sal_False;
+
+ return sal_True;
+}
+
+extern "C" void skip_input_data (j_decompress_ptr cinfo, long numberOfBytes)
+{
+ SourceManagerStructPointer source = (SourceManagerStructPointer) cinfo->src;
+
+ /* Just a dumb implementation for now. Could use fseek() except
+ * it doesn't work on pipes. Not clear that being smart is worth
+ * any trouble anyway --- large skips are infrequent.
+ */
+ if (numberOfBytes > 0)
+ {
+ while (numberOfBytes > (long) source->pub.bytes_in_buffer)
+ {
+ numberOfBytes -= (long) source->pub.bytes_in_buffer;
+ (void) fill_input_buffer(cinfo);
+
+ /* note we assume that fill_input_buffer will never return sal_False,
+ * so suspension need not be handled.
+ */
+ }
+ source->pub.next_input_byte += (size_t) numberOfBytes;
+ source->pub.bytes_in_buffer -= (size_t) numberOfBytes;
+ }
+}
+
+extern "C" void term_source (j_decompress_ptr)
+{
+ /* no work necessary here */
+}
+
+extern "C" void jpeg_svstream_src (j_decompress_ptr cinfo, void* input)
+{
+ SourceManagerStructPointer source;
+ SvStream* stream = (SvStream*)input;
+
+ /* The source object and input buffer are made permanent so that a series
+ * of JPEG images can be read from the same file by calling jpeg_stdio_src
+ * only before the first one. (If we discarded the buffer at the end of
+ * one image, we'd likely lose the start of the next one.)
+ * This makes it unsafe to use this manager and a different source
+ * manager serially with the same JPEG object. Caveat programmer.
+ */
+
+ if (cinfo->src == NULL)
+ { /* first time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(SourceManagerStruct));
+ source = (SourceManagerStructPointer) cinfo->src;
+ source->buffer = (JOCTET *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, BUFFER_SIZE * sizeof(JOCTET));
+ }
+
+ source = (SourceManagerStructPointer) cinfo->src;
+ source->pub.init_source = init_source;
+ source->pub.fill_input_buffer = fill_input_buffer;
+ source->pub.skip_input_data = skip_input_data;
+ source->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ source->pub.term_source = term_source;
+ source->stream = stream;
+ source->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+ source->pub.next_input_byte = NULL; /* until buffer loaded */
+}
+
+JPEGReader::JPEGReader( SvStream& rStream, void* /*pCallData*/, sal_Bool bSetLogSize ) :
+ mrStream ( rStream ),
+ mpAcc ( NULL ),
+ mpAcc1 ( NULL ),
+ mpBuffer ( NULL ),
+ mnLastPos ( rStream.Tell() ),
+ mnLastLines ( 0 ),
+ mbSetLogSize ( bSetLogSize )
+{
+ maUpperName = OUString("SVIJPEG");
+ mnFormerPos = mnLastPos;
+}
+
+JPEGReader::~JPEGReader()
+{
+ if( mpBuffer )
+ rtl_freeMemory( mpBuffer );
+
+ if( mpAcc )
+ maBmp.ReleaseAccess( mpAcc );
+
+ if( mpAcc1 )
+ maBmp1.ReleaseAccess( mpAcc1 );
+}
+
+void* JPEGReader::CreateBitmap( void* _pParam )
+{
+ JPEGCreateBitmapParam *pParam = (JPEGCreateBitmapParam *) _pParam;
+
+ if (pParam->nWidth > SAL_MAX_INT32 / 8 || pParam->nHeight > SAL_MAX_INT32 / 8)
+ return NULL; // avoid overflows later
+
+ Size aSize( pParam->nWidth, pParam->nHeight );
+ sal_Bool bGray = pParam->bGray != 0;
+
+ void* pBmpBuf = NULL;
+
+ if( mpAcc )
+ {
+ maBmp.ReleaseAccess( mpAcc );
+ }
+
+ sal_uInt64 nSize = aSize.Width();
+ nSize *= aSize.Height();
+ if (nSize > SAL_MAX_INT32 / 24)
+ return NULL;
+
+ if( bGray )
+ {
+ BitmapPalette aGrayPal( 256 );
+
+ for( sal_uInt16 n = 0; n < 256; n++ )
+ {
+ const sal_uInt8 cGray = (sal_uInt8) n;
+ aGrayPal[ n ] = BitmapColor( cGray, cGray, cGray );
+ }
+
+ maBmp = Bitmap( aSize, 8, &aGrayPal );
+ }
+ else
+ {
+ maBmp = Bitmap( aSize, 24 );
+ }
+
+ if ( mbSetLogSize )
+ {
+ unsigned long nUnit = ((JPEGCreateBitmapParam*)pParam)->density_unit;
+
+ if( ( ( 1 == nUnit ) || ( 2 == nUnit ) ) && pParam->X_density && pParam->Y_density )
+ {
+ Point aEmptyPoint;
+ Fraction aFractX( 1, pParam->X_density );
+ Fraction aFractY( 1, pParam->Y_density );
+ MapMode aMapMode( nUnit == 1 ? MAP_INCH : MAP_CM, aEmptyPoint, aFractX, aFractY );
+ Size aPrefSize = OutputDevice::LogicToLogic( aSize, aMapMode, MAP_100TH_MM );
+
+ maBmp.SetPrefSize( aPrefSize );
+ maBmp.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
+ }
+ }
+
+ mpAcc = maBmp.AcquireWriteAccess();
+
+ if( mpAcc )
+ {
+ const sal_uLong nFormat = mpAcc->GetScanlineFormat();
+
+ if(
+ ( bGray && ( BMP_FORMAT_8BIT_PAL == nFormat ) ) ||
+ ( !bGray && ( BMP_FORMAT_24BIT_TC_RGB == nFormat ) )
+ )
+ {
+ pBmpBuf = mpAcc->GetBuffer();
+ pParam->nAlignedWidth = mpAcc->GetScanlineSize();
+ pParam->bTopDown = mpAcc->IsTopDown();
+ }
+ else
+ {
+ pParam->nAlignedWidth = AlignedWidth4Bytes( aSize.Width() * ( bGray ? 8 : 24 ) );
+ pParam->bTopDown = sal_True;
+ pBmpBuf = mpBuffer = rtl_allocateMemory( pParam->nAlignedWidth * aSize.Height() );
+ }
+ }
+
+ // clean up, if no Bitmap buffer can be provided.
+ if ( !pBmpBuf )
+ {
+ maBmp.ReleaseAccess( mpAcc );
+ mpAcc = NULL;
+ }
+
+ return pBmpBuf;
+}
+
+void JPEGReader::FillBitmap()
+{
+ if( mpBuffer && mpAcc )
+ {
+ HPBYTE pTmp;
+ BitmapColor aColor;
+ long nAlignedWidth;
+ long nWidth = mpAcc->Width();
+ long nHeight = mpAcc->Height();
+
+ if( mpAcc->GetBitCount() == 8 )
+ {
+ BitmapColor* pCols = new BitmapColor[ 256 ];
+
+ for( sal_uInt16 n = 0; n < 256; n++ )
+ {
+ const sal_uInt8 cGray = (sal_uInt8) n;
+ pCols[ n ] = mpAcc->GetBestMatchingColor( BitmapColor( cGray, cGray, cGray ) );
+ }
+
+ nAlignedWidth = AlignedWidth4Bytes( mpAcc->Width() * 8L );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ pTmp = (sal_uInt8*) mpBuffer + nY * nAlignedWidth;
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ mpAcc->SetPixel( nY, nX, pCols[ *pTmp++ ] );
+ }
+ }
+
+ delete[] pCols;
+ }
+ else
+ {
+ nAlignedWidth = AlignedWidth4Bytes( mpAcc->Width() * 24L );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ pTmp = (sal_uInt8*) mpBuffer + nY * nAlignedWidth;
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aColor.SetRed( *pTmp++ );
+ aColor.SetGreen( *pTmp++ );
+ aColor.SetBlue( *pTmp++ );
+ mpAcc->SetPixel( nY, nX, aColor );
+ }
+ }
+ }
+ }
+}
+
+Graphic JPEGReader::CreateIntermediateGraphic( const Bitmap& rBitmap, long nLines )
+{
+ Graphic aGraphic;
+ const Size aSizePixel( rBitmap.GetSizePixel() );
+
+ if( !mnLastLines )
+ {
+ if( mpAcc1 )
+ {
+ maBmp1.ReleaseAccess( mpAcc1 );
+ }
+
+ maBmp1 = Bitmap( rBitmap.GetSizePixel(), 1 );
+ maBmp1.Erase( Color( COL_WHITE ) );
+ mpAcc1 = maBmp1.AcquireWriteAccess();
+ }
+
+ if( nLines && ( nLines < aSizePixel.Height() ) )
+ {
+ if( mpAcc1 )
+ {
+ const long nNewLines = nLines - mnLastLines;
+
+ if( nNewLines )
+ {
+ mpAcc1->SetFillColor( Color( COL_BLACK ) );
+ mpAcc1->FillRect( Rectangle( Point( 0, mnLastLines ), Size( mpAcc1->Width(), nNewLines ) ) );
+ }
+
+ maBmp1.ReleaseAccess( mpAcc1 );
+ aGraphic = BitmapEx( rBitmap, maBmp1 );
+ mpAcc1 = maBmp1.AcquireWriteAccess();
+ }
+ else
+ {
+ aGraphic = rBitmap;
+ }
+ }
+ else
+ aGraphic = rBitmap;
+
+ mnLastLines = nLines;
+
+ return aGraphic;
+}
+
+ReadState JPEGReader::Read( Graphic& rGraphic )
+{
+ long nEndPosition;
+ long nLines;
+ ReadState eReadState;
+ sal_Bool bRet = sal_False;
+ sal_uInt8 cDummy;
+
+ // TODO: is it possible to get rid of this seek to the end?
+ // check if the stream's end is already available
+ mrStream.Seek( STREAM_SEEK_TO_END );
+ mrStream >> cDummy;
+ nEndPosition = mrStream.Tell();
+
+ // else check if at least JPEG_MIN_READ bytes can be read
+ if( mrStream.GetError() == ERRCODE_IO_PENDING )
+ {
+ mrStream.ResetError();
+ if( ( nEndPosition - mnFormerPos ) < JPEG_MIN_READ )
+ {
+ mrStream.Seek( mnLastPos );
+ return JPEGREAD_NEED_MORE;
+ }
+ }
+
+ // seek back to the original position
+ mrStream.Seek( mnLastPos );
+
+ Size aPreviewSize = GetPreviewSize();
+ SetJpegPreviewSizeHint( aPreviewSize.Width(), aPreviewSize.Height() );
+
+ // read the (partial) image
+ ReadJPEG( this, &mrStream, &nLines );
+
+ if( mpAcc )
+ {
+ if( mpBuffer )
+ {
+ FillBitmap();
+ rtl_freeMemory( mpBuffer );
+ mpBuffer = NULL;
+ }
+
+ maBmp.ReleaseAccess( mpAcc );
+ mpAcc = NULL;
+
+ if( mrStream.GetError() == ERRCODE_IO_PENDING )
+ {
+ rGraphic = CreateIntermediateGraphic( maBmp, nLines );
+ }
+ else
+ {
+ rGraphic = maBmp;
+ }
+
+ bRet = sal_True;
+ }
+ else if( mrStream.GetError() == ERRCODE_IO_PENDING )
+ {
+ bRet = sal_True;
+ }
+
+ // Set status ( Pending has priority )
+ if( mrStream.GetError() == ERRCODE_IO_PENDING )
+ {
+ eReadState = JPEGREAD_NEED_MORE;
+ mrStream.ResetError();
+ mnFormerPos = mrStream.Tell();
+ }
+ else
+ {
+ eReadState = bRet ? JPEGREAD_OK : JPEGREAD_ERROR;
+ }
+
+ return eReadState;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/jpeg/JpegReader.hxx b/vcl/source/filter/jpeg/JpegReader.hxx
new file mode 100644
index 000000000000..792792fb24d0
--- /dev/null
+++ b/vcl/source/filter/jpeg/JpegReader.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef _JPEG_READER_HXX
+#define _JPEG_READER_HXX
+
+#include <vcl/graph.hxx>
+#include <vcl/fltcall.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+
+enum ReadState
+{
+ JPEGREAD_OK,
+ JPEGREAD_ERROR,
+ JPEGREAD_NEED_MORE
+};
+
+class JPEGReader : public GraphicReader
+{
+ SvStream& mrStream;
+ Bitmap maBmp;
+ Bitmap maBmp1;
+ BitmapWriteAccess* mpAcc;
+ BitmapWriteAccess* mpAcc1;
+ void* mpBuffer;
+ long mnLastPos;
+ long mnFormerPos;
+ long mnLastLines;
+ sal_Bool mbSetLogSize;
+
+ Graphic CreateIntermediateGraphic( const Bitmap& rBitmap, long nLines );
+ void FillBitmap();
+
+public:
+ JPEGReader( SvStream& rStream, void* pCallData, sal_Bool bSetLogSize );
+ virtual ~JPEGReader();
+
+ ReadState Read( Graphic& rGraphic );
+ void* CreateBitmap( void* JPEGCreateBitmapParam );
+};
+
+#endif //_JPEG_READER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/jpeg/JpegWriter.cxx b/vcl/source/filter/jpeg/JpegWriter.cxx
new file mode 100644
index 000000000000..44d77ea3caf9
--- /dev/null
+++ b/vcl/source/filter/jpeg/JpegWriter.cxx
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+extern "C"
+{
+ #include "stdio.h"
+ #include "jpeg.h"
+ #include <jpeglib.h>
+ #include <jerror.h>
+}
+
+#include <tools/solar.h>
+#include <vcl/bmpacc.hxx>
+#include <vcl/FilterConfigItem.hxx>
+#include <vcl/graphicfilter.hxx>
+#include "JpegWriter.hxx"
+
+#define BUFFER_SIZE 4096
+
+extern "C" void* GetScanline( void* pJPEGWriter, long nY )
+{
+ return ( (JPEGWriter*) pJPEGWriter )->GetScanline( nY );
+}
+
+struct JPEGCallbackStruct
+{
+ css::uno::Reference< css::task::XStatusIndicator > xStatusIndicator;
+};
+
+extern "C" long JPEGCallback( void* pCallbackData, long nPercent )
+{
+ JPEGCallbackStruct* pCallbackStruct = (JPEGCallbackStruct*)pCallbackData;
+ if ( pCallbackStruct && pCallbackStruct->xStatusIndicator.is() )
+ {
+ pCallbackStruct->xStatusIndicator->setValue( nPercent );
+ }
+ return 0L;
+}
+
+typedef struct
+{
+ struct jpeg_destination_mgr pub; /* public fields */
+ SvStream* stream; /* target stream */
+ JOCTET * buffer; /* start of buffer */
+} DestinationManagerStruct;
+
+typedef DestinationManagerStruct* DestinationManagerStructPointer;
+
+extern "C" void init_destination (j_compress_ptr cinfo)
+{
+ DestinationManagerStructPointer destination = (DestinationManagerStructPointer) cinfo->dest;
+
+ /* Allocate the output buffer -- it will be released when done with image */
+ destination->buffer = (JOCTET *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, BUFFER_SIZE * sizeof(JOCTET));
+
+ destination->pub.next_output_byte = destination->buffer;
+ destination->pub.free_in_buffer = BUFFER_SIZE;
+}
+
+extern "C" boolean empty_output_buffer (j_compress_ptr cinfo)
+{
+ DestinationManagerStructPointer destination = (DestinationManagerStructPointer) cinfo->dest;
+
+ if (destination->stream->Write(destination->buffer, BUFFER_SIZE) != (size_t) BUFFER_SIZE)
+ {
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+ }
+
+ destination->pub.next_output_byte = destination->buffer;
+ destination->pub.free_in_buffer = BUFFER_SIZE;
+
+ return sal_True;
+}
+
+extern "C" void term_destination (j_compress_ptr cinfo)
+{
+ DestinationManagerStructPointer destination = (DestinationManagerStructPointer) cinfo->dest;
+ size_t datacount = BUFFER_SIZE - destination->pub.free_in_buffer;
+
+ /* Write any data remaining in the buffer */
+ if (datacount > 0)
+ {
+ if (destination->stream->Write(destination->buffer, datacount) != datacount)
+ {
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+ }
+ }
+}
+
+extern "C" void jpeg_svstream_dest (j_compress_ptr cinfo, void* output)
+{
+ SvStream* stream = (SvStream*) output;
+ DestinationManagerStructPointer destination;
+
+ /* The destination object is made permanent so that multiple JPEG images
+ * can be written to the same file without re-executing jpeg_svstream_dest.
+ * This makes it dangerous to use this manager and a different destination
+ * manager serially with the same JPEG object, because their private object
+ * sizes may be different. Caveat programmer.
+ */
+ if (cinfo->dest == NULL)
+ { /* first time for this JPEG object? */
+ cinfo->dest = (struct jpeg_destination_mgr*)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(DestinationManagerStruct));
+ }
+
+ destination = (DestinationManagerStructPointer) cinfo->dest;
+ destination->pub.init_destination = init_destination;
+ destination->pub.empty_output_buffer = empty_output_buffer;
+ destination->pub.term_destination = term_destination;
+ destination->stream = stream;
+}
+
+JPEGWriter::JPEGWriter( SvStream& rStream, const css::uno::Sequence< css::beans::PropertyValue >* pFilterData, bool* pExportWasGrey ) :
+ mrStream ( rStream ),
+ mpReadAccess ( NULL ),
+ mpBuffer ( NULL ),
+ mpExpWasGrey ( pExportWasGrey )
+{
+ FilterConfigItem aConfigItem( (css::uno::Sequence< css::beans::PropertyValue >*) pFilterData );
+ mbGreys = aConfigItem.ReadInt32( "ColorMode", 0 ) != 0;
+ mnQuality = aConfigItem.ReadInt32( "Quality", 75 );
+ maChromaSubsampling = aConfigItem.ReadInt32( "ChromaSubsamplingMode", 0 );
+
+ if ( pFilterData )
+ {
+ int nArgs = pFilterData->getLength();
+ const css::beans::PropertyValue* pValues = pFilterData->getConstArray();
+ while( nArgs-- )
+ {
+ if ( pValues->Name == "StatusIndicator" )
+ {
+ pValues->Value >>= mxStatusIndicator;
+ }
+ pValues++;
+ }
+ }
+}
+
+void* JPEGWriter::GetScanline( long nY )
+{
+ void* pScanline = NULL;
+
+ if( mpReadAccess )
+ {
+ if( mbNative )
+ {
+ pScanline = mpReadAccess->GetScanline( nY );
+ }
+ else if( mpBuffer )
+ {
+ BitmapColor aColor;
+ long nWidth = mpReadAccess->Width();
+ sal_uInt8* pTmp = mpBuffer;
+
+ if( mpReadAccess->HasPalette() )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aColor = mpReadAccess->GetPaletteColor( (sal_uInt8) mpReadAccess->GetPixel( nY, nX ) );
+ *pTmp++ = aColor.GetRed();
+ if ( !mbGreys )
+ {
+ *pTmp++ = aColor.GetGreen();
+ *pTmp++ = aColor.GetBlue();
+ }
+ }
+ }
+ else
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aColor = mpReadAccess->GetPixel( nY, nX );
+ *pTmp++ = aColor.GetRed();
+ if ( !mbGreys )
+ {
+ *pTmp++ = aColor.GetGreen();
+ *pTmp++ = aColor.GetBlue();
+ }
+ }
+ }
+
+ pScanline = mpBuffer;
+ }
+ }
+
+ return pScanline;
+}
+
+sal_Bool JPEGWriter::Write( const Graphic& rGraphic )
+{
+ sal_Bool bRet = sal_False;
+
+ if ( mxStatusIndicator.is() )
+ {
+ OUString aMsg;
+ mxStatusIndicator->start( aMsg, 100 );
+ }
+
+ Bitmap aGraphicBmp( rGraphic.GetBitmap() );
+
+ if ( mbGreys )
+ {
+ if ( !aGraphicBmp.Convert( BMP_CONVERSION_8BIT_GREYS ) )
+ aGraphicBmp = rGraphic.GetBitmap();
+ }
+
+ mpReadAccess = aGraphicBmp.AcquireReadAccess();
+
+ if ( !mbGreys ) // bitmap was not explicitly converted into greyscale,
+ { // check if source is greyscale only
+
+ sal_Bool bIsGrey = sal_True;
+
+ long nWidth = mpReadAccess->Width();
+ for ( long nY = 0; bIsGrey && ( nY < mpReadAccess->Height() ); nY++ )
+ {
+ BitmapColor aColor;
+ for( long nX = 0L; bIsGrey && ( nX < nWidth ); nX++ )
+ {
+ aColor = mpReadAccess->HasPalette() ? mpReadAccess->GetPaletteColor( (sal_uInt8) mpReadAccess->GetPixel( nY, nX ) )
+ : mpReadAccess->GetPixel( nY, nX );
+ bIsGrey = ( aColor.GetRed() == aColor.GetGreen() ) && ( aColor.GetRed() == aColor.GetBlue() );
+ }
+ }
+ if ( bIsGrey )
+ mbGreys = sal_True;
+ }
+
+ if( mpExpWasGrey )
+ *mpExpWasGrey = mbGreys;
+
+ if( mpReadAccess )
+ {
+ mbNative = ( mpReadAccess->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB );
+
+ if( !mbNative )
+ mpBuffer = new sal_uInt8[ AlignedWidth4Bytes( mbGreys ? mpReadAccess->Width() * 8L : mpReadAccess->Width() * 24L ) ];
+
+ JPEGCallbackStruct aCallbackData;
+ aCallbackData.xStatusIndicator = mxStatusIndicator;
+ bRet = (sal_Bool) WriteJPEG( this, &mrStream, mpReadAccess->Width(), mpReadAccess->Height(), mbGreys, mnQuality, maChromaSubsampling, &aCallbackData );
+
+ delete[] mpBuffer;
+ mpBuffer = NULL;
+
+ aGraphicBmp.ReleaseAccess( mpReadAccess );
+ mpReadAccess = NULL;
+ }
+ if ( mxStatusIndicator.is() )
+ mxStatusIndicator->end();
+
+ return bRet;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/jpeg/JpegWriter.hxx b/vcl/source/filter/jpeg/JpegWriter.hxx
new file mode 100644
index 000000000000..439f5474c09c
--- /dev/null
+++ b/vcl/source/filter/jpeg/JpegWriter.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef _JPEG_WRITER_HXX
+#define _JPEG_WRITER_HXX
+
+#include <vcl/graph.hxx>
+#include <vcl/fltcall.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+
+class JPEGWriter
+{
+ SvStream& mrStream;
+ Bitmap maBitmap;
+ BitmapReadAccess* mpReadAccess;
+ sal_uInt8* mpBuffer;
+ sal_Bool mbNative;
+ sal_Bool mbGreys;
+ sal_Int32 mnQuality;
+ sal_Int32 maChromaSubsampling;
+
+ bool* mpExpWasGrey;
+
+ com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > mxStatusIndicator;
+
+public:
+ JPEGWriter( SvStream& rStream,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData,
+ bool* pExportWasGrey = NULL );
+
+ virtual ~JPEGWriter() {};
+
+ void* GetScanline( long nY );
+ sal_Bool Write( const Graphic& rGraphic );
+
+};
+
+#endif // _JPEG_WRITER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/jpeg/jpeg.cxx b/vcl/source/filter/jpeg/jpeg.cxx
index a4d1b2dd5d52..6687df28b762 100644
--- a/vcl/source/filter/jpeg/jpeg.cxx
+++ b/vcl/source/filter/jpeg/jpeg.cxx
@@ -17,729 +17,61 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include "JpegReader.hxx"
+#include "JpegWriter.hxx"
#include <tools/solar.h>
-
-extern "C"
-{
- #include "stdio.h"
- #include "jpeg.h"
- #include <jpeglib.h>
- #include <jerror.h>
-}
-
-#define _JPEGPRIVATE
#include <vcl/bmpacc.hxx>
-#include "jpeg.hxx"
#include <vcl/FilterConfigItem.hxx>
#include <vcl/graphicfilter.hxx>
-using namespace ::com::sun::star;
-
-#define JPEGMINREAD 512
-
-extern "C" void* CreateBitmapFromJPEGReader( void* pJPEGReader, void* pJPEGCreateBitmapParam )
-{
- return ( (JPEGReader*) pJPEGReader )->CreateBitmap( pJPEGCreateBitmapParam );
-}
-
-extern "C" void* GetScanline( void* pJPEGWriter, long nY )
-{
- return ( (JPEGWriter*) pJPEGWriter )->GetScanline( nY );
-}
-
-struct JPEGCallbackStruct
-{
- uno::Reference< task::XStatusIndicator > xStatusIndicator;
-};
-
-extern "C" long JPEGCallback( void* pCallbackData, long nPercent )
-{
- JPEGCallbackStruct* pS = (JPEGCallbackStruct*)pCallbackData;
- if ( pS && pS->xStatusIndicator.is() )
- {
- pS->xStatusIndicator->setValue( nPercent );
- }
- return 0L;
-}
-
-#define BUF_SIZE 4096
-
-typedef struct
-{
- struct jpeg_destination_mgr pub; /* public fields */
-
- SvStream* outfile; /* target stream */
- JOCTET * buffer; /* start of buffer */
-} my_destination_mgr;
-
-typedef my_destination_mgr* my_dest_ptr;
-
-extern "C" void init_destination (j_compress_ptr cinfo)
-{
- my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
-
- /* Allocate the output buffer --- it will be released when done with image */
- dest->buffer = (JOCTET *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- BUF_SIZE * sizeof(JOCTET));
-
- dest->pub.next_output_byte = dest->buffer;
- dest->pub.free_in_buffer = BUF_SIZE;
-}
-
-extern "C" boolean empty_output_buffer (j_compress_ptr cinfo)
-{
- my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
-
- if (dest->outfile->Write(dest->buffer, BUF_SIZE) !=
- (size_t) BUF_SIZE)
- ERREXIT(cinfo, JERR_FILE_WRITE);
-
- dest->pub.next_output_byte = dest->buffer;
- dest->pub.free_in_buffer = BUF_SIZE;
-
- return sal_True;
-}
-
-extern "C" void term_destination (j_compress_ptr cinfo)
-{
- my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
- size_t datacount = BUF_SIZE - dest->pub.free_in_buffer;
-
- /* Write any data remaining in the buffer */
- if (datacount > 0) {
- if (dest->outfile->Write(dest->buffer, datacount) != datacount)
- ERREXIT(cinfo, JERR_FILE_WRITE);
- }
-}
-
-extern "C" void jpeg_svstream_dest (j_compress_ptr cinfo, void* out)
-{
- SvStream * outfile = (SvStream*)out;
- my_dest_ptr dest;
-
- /* The destination object is made permanent so that multiple JPEG images
- * can be written to the same file without re-executing jpeg_svstream_dest.
- * This makes it dangerous to use this manager and a different destination
- * manager serially with the same JPEG object, because their private object
- * sizes may be different. Caveat programmer.
- */
- if (cinfo->dest == NULL) { /* first time for this JPEG object? */
- cinfo->dest = (struct jpeg_destination_mgr *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- sizeof(my_destination_mgr));
- }
-
- dest = (my_dest_ptr) cinfo->dest;
- dest->pub.init_destination = init_destination;
- dest->pub.empty_output_buffer = empty_output_buffer;
- dest->pub.term_destination = term_destination;
- dest->outfile = outfile;
-}
-
-/* Expanded data source object for stdio input */
-
-typedef struct {
- struct jpeg_source_mgr pub; /* public fields */
-
- SvStream * infile; /* source stream */
- JOCTET * buffer; /* start of buffer */
- boolean start_of_file; /* have we gotten any data yet? */
-} my_source_mgr;
-
-typedef my_source_mgr * my_src_ptr;
-
-/*
- * Initialize source --- called by jpeg_read_header
- * before any data is actually read.
- */
-
-extern "C" void init_source (j_decompress_ptr cinfo)
-{
- my_src_ptr src = (my_src_ptr) cinfo->src;
-
- /* We reset the empty-input-file flag for each image,
- * but we don't clear the input buffer.
- * This is correct behavior for reading a series of images from one source.
- */
- src->start_of_file = sal_True;
-}
-
-long StreamRead( SvStream* pSvStm, void* pBuffer, long nBufferSize )
+sal_Bool ImportJPEG( SvStream& rInputStream, Graphic& rGraphic, void* pCallerData, sal_Int32 nImportFlags )
{
- long nRead = 0;
-
- if( pSvStm->GetError() != ERRCODE_IO_PENDING )
- {
- long nActPos = pSvStm->Tell();
-
- nRead = (long) pSvStm->Read( pBuffer, nBufferSize );
-
- if( pSvStm->GetError() == ERRCODE_IO_PENDING )
- {
- // Damit wir wieder an die alte Position
- // seeken koennen, setzen wir den Error temp.zurueck
- pSvStm->ResetError();
- pSvStm->Seek( nActPos );
- pSvStm->SetError( ERRCODE_IO_PENDING );
- }
- }
-
- return nRead;
-}
-
-extern "C" boolean fill_input_buffer (j_decompress_ptr cinfo)
-{
- my_src_ptr src = (my_src_ptr) cinfo->src;
- size_t nbytes;
-
- nbytes = StreamRead(src->infile, src->buffer, BUF_SIZE);
-
- if (!nbytes) {
- if (src->start_of_file) /* Treat empty input file as fatal error */
- ERREXIT(cinfo, JERR_INPUT_EMPTY);
- WARNMS(cinfo, JWRN_JPEG_EOF);
- /* Insert a fake EOI marker */
- src->buffer[0] = (JOCTET) 0xFF;
- src->buffer[1] = (JOCTET) JPEG_EOI;
- nbytes = 2;
- }
-
- src->pub.next_input_byte = src->buffer;
- src->pub.bytes_in_buffer = nbytes;
- src->start_of_file = sal_False;
-
- return sal_True;
-}
-
-extern "C" void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
-{
- my_src_ptr src = (my_src_ptr) cinfo->src;
-
- /* Just a dumb implementation for now. Could use fseek() except
- * it doesn't work on pipes. Not clear that being smart is worth
- * any trouble anyway --- large skips are infrequent.
- */
- if (num_bytes > 0) {
- while (num_bytes > (long) src->pub.bytes_in_buffer) {
- num_bytes -= (long) src->pub.bytes_in_buffer;
- (void) fill_input_buffer(cinfo);
- /* note we assume that fill_input_buffer will never return sal_False,
- * so suspension need not be handled.
- */
- }
- src->pub.next_input_byte += (size_t) num_bytes;
- src->pub.bytes_in_buffer -= (size_t) num_bytes;
- }
-}
-
-extern "C" void term_source (j_decompress_ptr)
-{
- /* no work necessary here */
-}
-
-extern "C" void jpeg_svstream_src (j_decompress_ptr cinfo, void * in)
-{
- my_src_ptr src;
- SvStream * infile = (SvStream*)in;
-
- /* The source object and input buffer are made permanent so that a series
- * of JPEG images can be read from the same file by calling jpeg_stdio_src
- * only before the first one. (If we discarded the buffer at the end of
- * one image, we'd likely lose the start of the next one.)
- * This makes it unsafe to use this manager and a different source
- * manager serially with the same JPEG object. Caveat programmer.
- */
- if (cinfo->src == NULL) { /* first time for this JPEG object? */
- cinfo->src = (struct jpeg_source_mgr *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- sizeof(my_source_mgr));
- src = (my_src_ptr) cinfo->src;
- src->buffer = (JOCTET *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- BUF_SIZE * sizeof(JOCTET));
- }
-
- src = (my_src_ptr) cinfo->src;
- src->pub.init_source = init_source;
- src->pub.fill_input_buffer = fill_input_buffer;
- src->pub.skip_input_data = skip_input_data;
- src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
- src->pub.term_source = term_source;
- src->infile = infile;
- src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
- src->pub.next_input_byte = NULL; /* until buffer loaded */
-}
-
-JPEGReader::JPEGReader( SvStream& rStm, void* /*pCallData*/, sal_Bool bSetLS ) :
- rIStm ( rStm ),
- pAcc ( NULL ),
- pAcc1 ( NULL ),
- pBuffer ( NULL ),
- nLastPos ( rStm.Tell() ),
- nLastLines ( 0 ),
- bSetLogSize ( bSetLS )
-{
- maUpperName = OUString("SVIJPEG");
- nFormerPos = nLastPos;
-}
-
-JPEGReader::~JPEGReader()
-{
- if( pBuffer )
- rtl_freeMemory( pBuffer );
-
- if( pAcc )
- aBmp.ReleaseAccess( pAcc );
-
- if( pAcc1 )
- aBmp1.ReleaseAccess( pAcc1 );
-}
-
-void* JPEGReader::CreateBitmap( void* _pParam )
-{
- JPEGCreateBitmapParam *pParam = (JPEGCreateBitmapParam *) _pParam;
-
- if (pParam->nWidth > SAL_MAX_INT32/8 || pParam->nHeight > SAL_MAX_INT32/8)
- return NULL; // avoid overflows later
-
- Size aSize( pParam->nWidth, pParam->nHeight );
- sal_Bool bGray = pParam->bGray != 0;
-
- void* pBmpBuf = NULL;
-
- if( pAcc )
- aBmp.ReleaseAccess( pAcc );
-
- sal_uInt64 nSize = aSize.Width();
- nSize *= aSize.Height();
- if (nSize > SAL_MAX_INT32 / 24)
- return NULL;
-
- if( bGray )
- {
- BitmapPalette aGrayPal( 256 );
-
- for( sal_uInt16 n = 0; n < 256; n++ )
- {
- const sal_uInt8 cGray = (sal_uInt8) n;
- aGrayPal[ n ] = BitmapColor( cGray, cGray, cGray );
- }
-
- aBmp = Bitmap( aSize, 8, &aGrayPal );
- }
- else
- aBmp = Bitmap( aSize, 24 );
-
- if ( bSetLogSize )
- {
- unsigned long nUnit = ((JPEGCreateBitmapParam*)pParam)->density_unit;
-
- if( ( ( 1 == nUnit ) || ( 2 == nUnit ) ) &&
- pParam->X_density && pParam->Y_density )
- {
- Point aEmptyPoint;
- Fraction aFractX( 1, pParam->X_density );
- Fraction aFractY( 1, pParam->Y_density );
- MapMode aMapMode( nUnit == 1 ? MAP_INCH : MAP_CM, aEmptyPoint, aFractX, aFractY );
- Size aPrefSize = OutputDevice::LogicToLogic( aSize, aMapMode, MAP_100TH_MM );
-
- aBmp.SetPrefSize( aPrefSize );
- aBmp.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
- }
- }
-
- pAcc = aBmp.AcquireWriteAccess();
-
- if( pAcc )
- {
- const sal_uLong nFormat = pAcc->GetScanlineFormat();
-
- if(
- ( bGray && ( BMP_FORMAT_8BIT_PAL == nFormat ) ) ||
- ( !bGray && ( BMP_FORMAT_24BIT_TC_RGB == nFormat ) )
- )
- {
- pBmpBuf = pAcc->GetBuffer();
- pParam->nAlignedWidth = pAcc->GetScanlineSize();
- pParam->bTopDown = pAcc->IsTopDown();
- }
- else
- {
- pParam->nAlignedWidth = AlignedWidth4Bytes( aSize.Width() * ( bGray ? 8 : 24 ) );
- pParam->bTopDown = sal_True;
- pBmpBuf = pBuffer = rtl_allocateMemory( pParam->nAlignedWidth * aSize.Height() );
- }
- }
-
- // clean up, if no Bitmap buffer can be provided.
- if ( !pBmpBuf )
- {
- aBmp.ReleaseAccess( pAcc );
- pAcc = NULL;
- }
-
- return pBmpBuf;
-}
-
-void JPEGReader::FillBitmap()
-{
- if( pBuffer && pAcc )
- {
- HPBYTE pTmp;
- BitmapColor aColor;
- long nAlignedWidth;
- long nWidth = pAcc->Width();
- long nHeight = pAcc->Height();
-
- if( pAcc->GetBitCount() == 8 )
- {
- BitmapColor* pCols = new BitmapColor[ 256 ];
-
- for( sal_uInt16 n = 0; n < 256; n++ )
- {
- const sal_uInt8 cGray = (sal_uInt8) n;
- pCols[ n ] = pAcc->GetBestMatchingColor( BitmapColor( cGray, cGray, cGray ) );
- }
-
- nAlignedWidth = AlignedWidth4Bytes( pAcc->Width() * 8L );
-
- for( long nY = 0L; nY < nHeight; nY++ )
- {
- pTmp = (sal_uInt8*) pBuffer + nY * nAlignedWidth;
-
- for( long nX = 0L; nX < nWidth; nX++ )
- pAcc->SetPixel( nY, nX, pCols[ *pTmp++ ] );
- }
-
- delete[] pCols;
- }
- else
- {
- nAlignedWidth = AlignedWidth4Bytes( pAcc->Width() * 24L );
-
- for( long nY = 0L; nY < nHeight; nY++ )
- {
- pTmp = (sal_uInt8*) pBuffer + nY * nAlignedWidth;
-
- for( long nX = 0L; nX < nWidth; nX++ )
- {
- aColor.SetRed( *pTmp++ );
- aColor.SetGreen( *pTmp++ );
- aColor.SetBlue( *pTmp++ );
- pAcc->SetPixel( nY, nX, aColor );
- }
- }
- }
- }
-}
-
-Graphic JPEGReader::CreateIntermediateGraphic( const Bitmap& rBitmap, long nLines )
-{
- Graphic aGraphic;
- const Size aSizePix( rBitmap.GetSizePixel() );
-
- if( !nLastLines )
- {
- if( pAcc1 )
- aBmp1.ReleaseAccess( pAcc1 );
-
- aBmp1 = Bitmap( rBitmap.GetSizePixel(), 1 );
- aBmp1.Erase( Color( COL_WHITE ) );
- pAcc1 = aBmp1.AcquireWriteAccess();
- }
-
- if( nLines && ( nLines < aSizePix.Height() ) )
- {
- if( pAcc1 )
- {
- const long nNewLines = nLines - nLastLines;
-
- if( nNewLines )
- {
- pAcc1->SetFillColor( Color( COL_BLACK ) );
- pAcc1->FillRect( Rectangle( Point( 0, nLastLines ),
- Size( pAcc1->Width(), nNewLines ) ) );
- }
-
- aBmp1.ReleaseAccess( pAcc1 );
- aGraphic = BitmapEx( rBitmap, aBmp1 );
- pAcc1 = aBmp1.AcquireWriteAccess();
- }
- else
- aGraphic = rBitmap;
- }
- else
- aGraphic = rBitmap;
-
- nLastLines = nLines;
-
- return aGraphic;
-}
-
-ReadState JPEGReader::Read( Graphic& rGraphic )
-{
- long nEndPos;
- long nLines;
+ JPEGReader* pJPEGReader = (JPEGReader*) rGraphic.GetContext();
ReadState eReadState;
- sal_Bool bRet = sal_False;
- sal_uInt8 cDummy;
-
- // TODO: is it possible to get rid of this seek to the end?
- // check if the stream's end is already available
- rIStm.Seek( STREAM_SEEK_TO_END );
- rIStm >> cDummy;
- nEndPos = rIStm.Tell();
-
- // else check if at least JPEGMINREAD bytes can be read
- if( rIStm.GetError() == ERRCODE_IO_PENDING )
- {
- rIStm.ResetError();
- if( ( nEndPos - nFormerPos ) < JPEGMINREAD )
- {
- rIStm.Seek( nLastPos );
- return JPEGREAD_NEED_MORE;
- }
- }
-
- // seek back to the original position
- rIStm.Seek( nLastPos );
+ sal_Bool bReturn = true;
-
- Size aPreviewSize = GetPreviewSize();
- SetJpegPreviewSizeHint( aPreviewSize.Width(), aPreviewSize.Height() );
-
- // read the (partial) image
- ReadJPEG( this, &rIStm, &nLines );
-
- if( pAcc )
+ if( !pJPEGReader )
{
- if( pBuffer )
- {
- FillBitmap();
- rtl_freeMemory( pBuffer );
- pBuffer = NULL;
- }
-
- aBmp.ReleaseAccess( pAcc );
- pAcc = NULL;
-
- if( rIStm.GetError() == ERRCODE_IO_PENDING )
- {
- rGraphic = CreateIntermediateGraphic( aBmp, nLines );
- }
- else
- {
- rGraphic = aBmp;
- }
-
- bRet = sal_True;
+ pJPEGReader = new JPEGReader( rInputStream, pCallerData, ( nImportFlags & GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG ) != 0 );
}
- else if( rIStm.GetError() == ERRCODE_IO_PENDING )
- bRet = sal_True;
- // Set status ( Pending has priority )
- if( rIStm.GetError() == ERRCODE_IO_PENDING )
+ if( nImportFlags & GRFILTER_I_FLAGS_FOR_PREVIEW )
{
- eReadState = JPEGREAD_NEED_MORE;
- rIStm.ResetError();
- nFormerPos = rIStm.Tell();
+ pJPEGReader->SetPreviewSize( Size(128,128) );
}
else
{
- if( bRet )
- eReadState = JPEGREAD_OK;
- else
- eReadState = JPEGREAD_ERROR;
- }
-
- return eReadState;
-}
-
-JPEGWriter::JPEGWriter( SvStream& rStream, const uno::Sequence< beans::PropertyValue >* pFilterData, bool* pExportWasGrey ) :
- rOStm ( rStream ),
- pAcc ( NULL ),
- pBuffer ( NULL ),
- pExpWasGrey ( pExportWasGrey )
-{
- FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*) pFilterData );
- bGreys = aConfigItem.ReadInt32( "ColorMode", 0 ) != 0;
- nQuality = aConfigItem.ReadInt32( "Quality", 75 );
- aChromaSubsampling = aConfigItem.ReadInt32( "ChromaSubsamplingMode", 0 );
-
- if ( pFilterData )
- {
- int nArgs = pFilterData->getLength();
- const beans::PropertyValue* pValues = pFilterData->getConstArray();
- while( nArgs-- )
- {
- if ( pValues->Name == "StatusIndicator" )
- {
- pValues->Value >>= xStatusIndicator;
- }
- pValues++;
- }
- }
-}
-
-void* JPEGWriter::GetScanline( long nY )
-{
- void* pScanline = NULL;
-
- if( pAcc )
- {
- if( bNative )
- {
- pScanline = pAcc->GetScanline( nY );
- }
- else if( pBuffer )
- {
- BitmapColor aColor;
- long nWidth = pAcc->Width();
- sal_uInt8* pTmp = pBuffer;
-
- if( pAcc->HasPalette() )
- {
- for( long nX = 0L; nX < nWidth; nX++ )
- {
- aColor = pAcc->GetPaletteColor( (sal_uInt8) pAcc->GetPixel( nY, nX ) );
- *pTmp++ = aColor.GetRed();
- if ( !bGreys )
- {
- *pTmp++ = aColor.GetGreen();
- *pTmp++ = aColor.GetBlue();
- }
- }
- }
- else
- {
- for( long nX = 0L; nX < nWidth; nX++ )
- {
- aColor = pAcc->GetPixel( nY, nX );
- *pTmp++ = aColor.GetRed();
- if ( !bGreys )
- {
- *pTmp++ = aColor.GetGreen();
- *pTmp++ = aColor.GetBlue();
- }
- }
- }
-
- pScanline = pBuffer;
- }
- }
-
- return pScanline;
-}
-
-sal_Bool JPEGWriter::Write( const Graphic& rGraphic )
-{
- sal_Bool bRet = sal_False;
-
- if ( xStatusIndicator.is() )
- {
- OUString aMsg;
- xStatusIndicator->start( aMsg, 100 );
- }
-
- Bitmap aGraphicBmp( rGraphic.GetBitmap() );
-
- if ( bGreys )
- {
- if ( !aGraphicBmp.Convert( BMP_CONVERSION_8BIT_GREYS ) )
- aGraphicBmp = rGraphic.GetBitmap();
- }
-
- pAcc = aGraphicBmp.AcquireReadAccess();
-
- if ( !bGreys ) // bitmap was not explicitly converted into greyscale,
- { // check if source is greyscale only
-
- sal_Bool bIsGrey = sal_True;
-
- long nWidth = pAcc->Width();
- for ( long nY = 0; bIsGrey && ( nY < pAcc->Height() ); nY++ )
- {
- BitmapColor aColor;
- for( long nX = 0L; bIsGrey && ( nX < nWidth ); nX++ )
- {
- aColor = pAcc->HasPalette() ? pAcc->GetPaletteColor( (sal_uInt8) pAcc->GetPixel( nY, nX ) )
- : pAcc->GetPixel( nY, nX );
- bIsGrey = ( aColor.GetRed() == aColor.GetGreen() ) && ( aColor.GetRed() == aColor.GetBlue() );
- }
- }
- if ( bIsGrey )
- bGreys = sal_True;
- }
-
- if( pExpWasGrey )
- *pExpWasGrey = bGreys;
-
- if( pAcc )
- {
- bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB );
-
- if( !bNative )
- pBuffer = new sal_uInt8[ AlignedWidth4Bytes( bGreys ? pAcc->Width() * 8L : pAcc->Width() * 24L ) ];
-
- JPEGCallbackStruct aCallbackData;
- aCallbackData.xStatusIndicator = xStatusIndicator;
- bRet = (sal_Bool) WriteJPEG( this, &rOStm, pAcc->Width(), pAcc->Height(), bGreys, nQuality, aChromaSubsampling, &aCallbackData );
-
- delete[] pBuffer;
- pBuffer = NULL;
-
- aGraphicBmp.ReleaseAccess( pAcc );
- pAcc = NULL;
- }
- if ( xStatusIndicator.is() )
- xStatusIndicator->end();
-
- return bRet;
-}
-
-sal_Bool ImportJPEG( SvStream& rStm, Graphic& rGraphic, void* pCallerData, sal_Int32 nImportFlags )
-{
- JPEGReader* pJPEGReader = (JPEGReader*) rGraphic.GetContext();
- ReadState eReadState;
- sal_Bool bRet = sal_True;
-
- if( !pJPEGReader )
- pJPEGReader = new JPEGReader( rStm, pCallerData, ( nImportFlags & GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG ) != 0 );
-
- if( nImportFlags & GRFILTER_I_FLAGS_FOR_PREVIEW )
- pJPEGReader->SetPreviewSize( Size(128,128) );
- else
pJPEGReader->DisablePreviewMode();
+ }
rGraphic.SetContext( NULL );
eReadState = pJPEGReader->Read( rGraphic );
if( eReadState == JPEGREAD_ERROR )
{
- bRet = sal_False;
+ bReturn = false;
delete pJPEGReader;
}
else if( eReadState == JPEGREAD_OK )
+ {
delete pJPEGReader;
+ }
else
+ {
rGraphic.SetContext( pJPEGReader );
+ }
- return bRet;
+ return bReturn;
}
-// --------------
-// - ExportJPEG -
-// --------------
-
-sal_Bool ExportJPEG( SvStream& rOStm, const Graphic& rGraphic,
- const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData,
- bool* pExportWasGrey
- )
+sal_Bool ExportJPEG(SvStream& rOutputStream, const Graphic& rGraphic,
+ const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>* pFilterData,
+ bool* pExportWasGrey)
{
- JPEGWriter aJPEGWriter( rOStm, pFilterData, pExportWasGrey );
- return aJPEGWriter.Write( rGraphic );
+ JPEGWriter aJPEGWriter( rOutputStream, pFilterData, pExportWasGrey );
+ bool bReturn = aJPEGWriter.Write( rGraphic );
+ return bReturn;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/jpeg/jpeg.h b/vcl/source/filter/jpeg/jpeg.h
index cebf81c85f7e..ffb47e76363b 100644
--- a/vcl/source/filter/jpeg/jpeg.h
+++ b/vcl/source/filter/jpeg/jpeg.h
@@ -41,18 +41,18 @@ struct JPEGCreateBitmapParam
long bTopDown; // CreateBitmap method in svtools
};
-typedef struct my_error_mgr* my_error_ptr;
-typedef unsigned char* HPBYTE;
+typedef struct ErrorManagerStruct* ErrorManagerPointer;
+typedef unsigned char* HPBYTE;
void* JPEGMalloc( size_t size );
void JPEGFree( void *ptr );
long JPEGCallback( void* pCallbackData, long nPercent );
-long WriteJPEG( void* pJPEGWriter, void* pOStm, long nWidth, long nHeight, long bGreyScale,
+long WriteJPEG( void* pJPEGWriter, void* pOutputStream, long nWidth, long nHeight, long bGreyScale,
long nQualityPercent, long aChromaSubsampling, void* pCallbackData );
void* GetScanline( void* pJPEGWriter, long nY );
-void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines );
+void ReadJPEG( void* pJPEGReader, void* pInputStream, long* pLines );
void* CreateBitmapFromJPEGReader( void* pJPEGReader, void* pJPEGCreateBitmapParam );
/* TODO: when incompatible changes are possible again
diff --git a/vcl/source/filter/jpeg/jpeg.hxx b/vcl/source/filter/jpeg/jpeg.hxx
index e2f11b6cfeec..3b9e6ae1133d 100644
--- a/vcl/source/filter/jpeg/jpeg.hxx
+++ b/vcl/source/filter/jpeg/jpeg.hxx
@@ -26,77 +26,9 @@
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
-#ifdef _JPEGPRIVATE
+sal_Bool ImportJPEG( SvStream& rInputStream, Graphic& rGraphic, void* pCallerData, sal_Int32 nImportFlags );
-enum ReadState
-{
- JPEGREAD_OK,
- JPEGREAD_ERROR,
- JPEGREAD_NEED_MORE
-};
-
-class JPEGReader : public GraphicReader
-{
- SvStream& rIStm;
- Bitmap aBmp;
- Bitmap aBmp1;
- BitmapWriteAccess* pAcc;
- BitmapWriteAccess* pAcc1;
- void* pBuffer;
- long nLastPos;
- long nFormerPos;
- long nLastLines;
- sal_Bool bSetLogSize;
-
- Graphic CreateIntermediateGraphic( const Bitmap& rBitmap, long nLines );
- void FillBitmap();
-
-public:
-
- void* CreateBitmap( void* JPEGCreateBitmapParam );
-
-public:
- JPEGReader( SvStream& rStm, void* pCallData, sal_Bool bSetLogSize );
- virtual ~JPEGReader();
-
-
- ReadState Read( Graphic& rGraphic );
-};
-
-class JPEGWriter
-{
- SvStream& rOStm;
- Bitmap aBmp;
- BitmapReadAccess* pAcc;
- sal_uInt8* pBuffer;
- sal_Bool bNative;
-
- sal_Bool bGreys;
- sal_Int32 nQuality;
- sal_Int32 aChromaSubsampling;
-
- bool* pExpWasGrey;
-
- com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
-
-public:
-
- void* GetScanline( long nY );
-
- JPEGWriter( SvStream& rOStm,
- const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData,
- bool* pExportWasGrey = NULL );
-
- ~JPEGWriter() {};
-
- sal_Bool Write( const Graphic& rGraphic );
-};
-
-#endif // _JPEGPRIVATE
-
-sal_Bool ImportJPEG( SvStream& rStream, Graphic& rGraphic, void* pCallerData, sal_Int32 nImportFlags );
-
-sal_Bool ExportJPEG(SvStream& rStream,
+sal_Bool ExportJPEG(SvStream& rOutputStream,
const Graphic& rGraphic,
const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData,
bool* pExportWasGrey = NULL);
diff --git a/vcl/source/filter/jpeg/jpegc.c b/vcl/source/filter/jpeg/jpegc.c
index 29d4ef01c8f9..4803984180d2 100644
--- a/vcl/source/filter/jpeg/jpegc.c
+++ b/vcl/source/filter/jpeg/jpegc.c
@@ -19,14 +19,15 @@
#include <stdio.h>
#include <stdlib.h>
-#include "setjmp.h"
+#include <setjmp.h>
#include <jpeglib.h>
#include <jerror.h>
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+
#include "jpeg.h"
-#include "rtl/alloc.h"
-#include "osl/diagnose.h"
-struct my_error_mgr
+struct ErrorManagerStruct
{
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
@@ -35,15 +36,15 @@ struct my_error_mgr
void jpeg_svstream_src (j_decompress_ptr cinfo, void* infile);
void jpeg_svstream_dest (j_compress_ptr cinfo, void* outfile);
-METHODDEF( void ) my_error_exit (j_common_ptr cinfo)
+METHODDEF( void ) errorExit (j_common_ptr cinfo)
{
- my_error_ptr myerr = (my_error_ptr) cinfo->err;
+ ErrorManagerPointer error = (ErrorManagerPointer) cinfo->err;
(*cinfo->err->output_message) (cinfo);
- longjmp(myerr->setjmp_buffer, 1);
+ longjmp(error->setjmp_buffer, 1);
}
-METHODDEF( void ) my_output_message (j_common_ptr cinfo)
+METHODDEF( void ) outputMessage (j_common_ptr cinfo)
{
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message) (cinfo, buffer);
@@ -59,19 +60,19 @@ void SetJpegPreviewSizeHint( int nWidth, int nHeight )
nPreviewHeight = nHeight;
}
-void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
+void ReadJPEG( void* pJPEGReader, void* pInputStream, long* pLines )
{
struct jpeg_decompress_struct cinfo;
- struct my_error_mgr jerr;
+ struct ErrorManagerStruct jerr;
struct JPEGCreateBitmapParam aCreateBitmapParam;
HPBYTE pDIB;
HPBYTE pTmp;
long nWidth;
long nHeight;
long nAlignedWidth;
- JSAMPLE * range_limit;
- HPBYTE pScanLineBuffer = NULL;
- long nScanLineBufferComponents = 0;
+ JSAMPLE* aRangeLimit;
+ HPBYTE pScanLineBuffer = NULL;
+ long nScanLineBufferComponents = 0;
if ( setjmp( jerr.setjmp_buffer ) )
{
@@ -80,11 +81,11 @@ void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
}
cinfo.err = jpeg_std_error( &jerr.pub );
- jerr.pub.error_exit = my_error_exit;
- jerr.pub.output_message = my_output_message;
+ jerr.pub.error_exit = errorExit;
+ jerr.pub.output_message = outputMessage;
jpeg_create_decompress( &cinfo );
- jpeg_svstream_src( &cinfo, pIStm );
+ jpeg_svstream_src( &cinfo, pInputStream );
jpeg_read_header( &cinfo, sal_True );
cinfo.scale_num = 1;
@@ -102,14 +103,21 @@ void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
/* change scale for preview import */
if( nPreviewWidth || nPreviewHeight )
{
- 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;
- } else if( nPreviewHeight == 0 ) {
- nPreviewHeight = ( cinfo.image_height*nPreviewWidth )/cinfo.image_width;
+ }
+ }
+ else if( nPreviewHeight == 0 )
+ {
+ 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 )
@@ -141,7 +149,7 @@ void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
aCreateBitmapParam.bGray = cinfo.output_components == 1;
pDIB = CreateBitmapFromJPEGReader( pJPEGReader, &aCreateBitmapParam );
nAlignedWidth = aCreateBitmapParam.nAlignedWidth;
- range_limit=cinfo.sample_range_limit;
+ aRangeLimit = cinfo.sample_range_limit;
if ( cinfo.out_color_space == JCS_CMYK )
{
@@ -152,7 +160,9 @@ void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
if( pDIB )
{
if( aCreateBitmapParam.bTopDown )
+ {
pTmp = pDIB;
+ }
else
{
pTmp = pDIB + ( nHeight - 1 ) * nAlignedWidth;
@@ -161,24 +171,28 @@ void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
for ( *pLines = 0; *pLines < nHeight; (*pLines)++ )
{
- if (pScanLineBuffer!=NULL) { // in other words cinfo.out_color_space == JCS_CMYK
- int i;
- int j;
- jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pScanLineBuffer, 1 );
- // convert CMYK to RGB
- for( i=0, j=0; i < nScanLineBufferComponents; i+=4, j+=3 )
- {
- int c_=255-pScanLineBuffer[i+0];
- int m_=255-pScanLineBuffer[i+1];
- int y_=255-pScanLineBuffer[i+2];
- int k_=255-pScanLineBuffer[i+3];
- pTmp[j+0]=range_limit[ 255L - ( c_ + k_ ) ];
- pTmp[j+1]=range_limit[ 255L - ( m_ + k_ ) ];
- pTmp[j+2]=range_limit[ 255L - ( y_ + k_ ) ];
+ if (pScanLineBuffer != NULL)
+ { // in other words cinfo.out_color_space == JCS_CMYK
+ int i;
+ int j;
+ jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pScanLineBuffer, 1 );
+ // convert CMYK to RGB
+ for( i=0, j=0; i < nScanLineBufferComponents; i+=4, j+=3 )
+ {
+ int color_C = 255 - pScanLineBuffer[i+0];
+ int color_M = 255 - pScanLineBuffer[i+1];
+ int color_Y = 255 - pScanLineBuffer[i+2];
+ int color_K = 255 - pScanLineBuffer[i+3];
+ pTmp[j+0] = aRangeLimit[ 255L - ( color_C + color_K ) ];
+ pTmp[j+1] = aRangeLimit[ 255L - ( color_M + color_K ) ];
+ pTmp[j+2] = aRangeLimit[ 255L - ( color_Y + color_K ) ];
+ }
}
- } else {
- jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pTmp, 1 );
+ else
+ {
+ jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pTmp, 1 );
}
+
/* PENDING ??? */
if ( cinfo.err->msg_code == 113 )
break;
@@ -188,25 +202,29 @@ void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
}
if ( pDIB )
+ {
jpeg_finish_decompress( &cinfo );
+ }
else
+ {
jpeg_abort_decompress( &cinfo );
+ }
- if (pScanLineBuffer!=NULL)
+ if (pScanLineBuffer != NULL)
{
rtl_freeMemory( pScanLineBuffer );
- pScanLineBuffer=NULL;
+ pScanLineBuffer = NULL;
}
jpeg_destroy_decompress( &cinfo );
}
-long WriteJPEG( void* pJPEGWriter, void* pOStm,
+long WriteJPEG( void* pJPEGWriter, void* pOutputStream,
long nWidth, long nHeight, long bGreys,
long nQualityPercent, long aChromaSubsampling, void* pCallbackData )
{
struct jpeg_compress_struct cinfo;
- struct my_error_mgr jerr;
+ struct ErrorManagerStruct jerr;
void* pScanline;
long nY;
@@ -217,11 +235,11 @@ long WriteJPEG( void* pJPEGWriter, void* pOStm,
}
cinfo.err = jpeg_std_error( &jerr.pub );
- jerr.pub.error_exit = my_error_exit;
- jerr.pub.output_message = my_output_message;
+ jerr.pub.error_exit = errorExit;
+ jerr.pub.output_message = outputMessage;
jpeg_create_compress( &cinfo );
- jpeg_svstream_dest( &cinfo, pOStm );
+ jpeg_svstream_dest( &cinfo, pOutputStream );
cinfo.image_width = (JDIMENSION) nWidth;
cinfo.image_height = (JDIMENSION) nHeight;
@@ -265,7 +283,9 @@ long WriteJPEG( void* pJPEGWriter, void* pOStm,
pScanline = GetScanline( pJPEGWriter, nY );
if( pScanline )
+ {
jpeg_write_scanlines( &cinfo, (JSAMPARRAY) &pScanline, 1 );
+ }
if( JPEGCallback( pCallbackData, nY * 100L / nHeight ) )
{