diff options
85 files changed, 2238 insertions, 1840 deletions
diff --git a/avmedia/source/win/framegrabber.cxx b/avmedia/source/win/framegrabber.cxx index e72fc16058db..f5789e09e319 100644 --- a/avmedia/source/win/framegrabber.cxx +++ b/avmedia/source/win/framegrabber.cxx @@ -38,6 +38,7 @@ #include <tools/stream.hxx> #include <vcl/graph.hxx> #include <unotools/localfilehelper.hxx> +#include <vcl/dibtools.hxx> #define AVMEDIA_WIN_FRAMEGRABBER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.FrameGrabber_DirectX" #define AVMEDIA_WIN_FRAMEGRABBER_SERVICENAME "com.sun.star.media.FrameGrabber_DirectX" @@ -182,7 +183,7 @@ uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMe SvMemoryStream aMemStm( pBuffer, nSize, STREAM_READ | STREAM_WRITE ); Bitmap aBmp; - if( aBmp.Read( aMemStm, false ) && !aBmp.IsEmpty() ) + if( ReadDIB(aBmp, aMemStm, false ) && !aBmp.IsEmpty() ) { const Graphic aGraphic( aBmp ); xRet = aGraphic.GetXGraphic(); diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx index 118c80a356d0..1e49c1d3856f 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -20,6 +20,7 @@ #include <tools/date.hxx> #include <basic/sbxvar.hxx> #include <osl/process.h> +#include <vcl/dibtools.hxx> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> #include <vcl/sound.hxx> @@ -4331,8 +4332,8 @@ RTLFUNC(LoadPicture) if( pStream != NULL ) { Bitmap aBmp; - *pStream >> aBmp; - Graphic aGraphic( aBmp ); + ReadDIB(aBmp, *pStream, true); + Graphic aGraphic(aBmp); SbxObjectRef xRef = new SbStdPicture; ((SbStdPicture*)(SbxObject*)xRef)->SetGraphic( aGraphic ); diff --git a/canvas/source/cairo/cairo_devicehelper.cxx b/canvas/source/cairo/cairo_devicehelper.cxx index e8fe710b40a4..bbe35851185b 100644 --- a/canvas/source/cairo/cairo_devicehelper.cxx +++ b/canvas/source/cairo/cairo_devicehelper.cxx @@ -32,6 +32,7 @@ #include <basegfx/tools/unopolypolygon.hxx> #include <vcl/canvastools.hxx> +#include <vcl/dibtools.hxx> #include <tools/stream.hxx> @@ -261,8 +262,9 @@ namespace cairocanvas const ::Point aEmptyPoint; bool bOldMap( mpRefDevice->IsMapModeEnabled() ); mpRefDevice->EnableMapMode( sal_False ); - aStream << mpRefDevice->GetBitmap(aEmptyPoint, - mpRefDevice->GetOutputSizePixel()); + WriteDIB(mpRefDevice->GetBitmap(aEmptyPoint, + mpRefDevice->GetOutputSizePixel()), aStream, false, true); + mpRefDevice->EnableMapMode( bOldMap ); ++nFilePostfixCount; diff --git a/canvas/source/vcl/devicehelper.cxx b/canvas/source/vcl/devicehelper.cxx index 053326feb466..dc568749ee75 100644 --- a/canvas/source/vcl/devicehelper.cxx +++ b/canvas/source/vcl/devicehelper.cxx @@ -17,23 +17,21 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <canvas/debug.hxx> #include <tools/diagnose_ex.h> #include <canvas/canvastools.hxx> - #include <rtl/instance.hxx> #include <toolkit/helper/vclunohelper.hxx> #include <vcl/canvastools.hxx> #include <basegfx/tools/canvastools.hxx> #include <basegfx/tools/unopolypolygon.hxx> +#include <vcl/dibtools.hxx> #include "devicehelper.hxx" #include "spritecanvas.hxx" #include "spritecanvashelper.hxx" #include "canvasbitmap.hxx" - using namespace ::com::sun::star; namespace vclcanvas @@ -223,8 +221,7 @@ namespace vclcanvas OutputDevice& rOutDev = mpOutDev->getOutDev(); bool bOldMap( rOutDev.IsMapModeEnabled() ); rOutDev.EnableMapMode( sal_False ); - aStream << rOutDev.GetBitmap(aEmptyPoint, - rOutDev.GetOutputSizePixel()); + WriteDIB(rOutDev.GetBitmap(aEmptyPoint, rOutDev.GetOutputSizePixel()), aStream, false, true); rOutDev.EnableMapMode( bOldMap ); ++nFilePostfixCount; diff --git a/canvas/source/vcl/spritedevicehelper.cxx b/canvas/source/vcl/spritedevicehelper.cxx index beaf3545f82a..5f89521c35cb 100644 --- a/canvas/source/vcl/spritedevicehelper.cxx +++ b/canvas/source/vcl/spritedevicehelper.cxx @@ -17,20 +17,18 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <canvas/debug.hxx> #include <canvas/canvastools.hxx> - #include <toolkit/helper/vclunohelper.hxx> #include <vcl/canvastools.hxx> #include <basegfx/tools/canvastools.hxx> +#include <vcl/dibtools.hxx> #include "spritedevicehelper.hxx" #include "spritecanvas.hxx" #include "spritecanvashelper.hxx" #include "canvasbitmap.hxx" - using namespace ::com::sun::star; namespace vclcanvas @@ -138,8 +136,7 @@ namespace vclcanvas const ::Point aEmptyPoint; mpBackBuffer->getOutDev().EnableMapMode( sal_False ); - aStream << mpBackBuffer->getOutDev().GetBitmap(aEmptyPoint, - mpBackBuffer->getOutDev().GetOutputSizePixel()); + WriteDIB(mpBackBuffer->getOutDev().GetBitmap(aEmptyPoint, mpBackBuffer->getOutDev().GetOutputSizePixel()), aStream, false, true); } ++nFilePostfixCount; diff --git a/chart2/source/controller/main/ChartController_Tools.cxx b/chart2/source/controller/main/ChartController_Tools.cxx index 889be4313877..c25770f0d9a7 100644 --- a/chart2/source/controller/main/ChartController_Tools.cxx +++ b/chart2/source/controller/main/ChartController_Tools.cxx @@ -294,9 +294,9 @@ void ChartController::executeDispatch_Paste() else if( aDataHelper.HasFormat( FORMAT_BITMAP )) { // bitmap (non-graphic-manager) - Bitmap aBmp; - if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp )) - aGraphic = Graphic( aBmp ); + BitmapEx aBmpEx; + if( aDataHelper.GetBitmapEx( FORMAT_BITMAP, aBmpEx )) + aGraphic = Graphic( aBmpEx ); } else if( aDataHelper.HasFormat( FORMAT_STRING )) { diff --git a/chart2/source/controller/main/ChartTransferable.cxx b/chart2/source/controller/main/ChartTransferable.cxx index a1742ea40502..7e6360509136 100644 --- a/chart2/source/controller/main/ChartTransferable.cxx +++ b/chart2/source/controller/main/ChartTransferable.cxx @@ -94,7 +94,7 @@ sal_Bool ChartTransferable::GetData( const ::com::sun::star::datatransfer::DataF else if( nFormat == FORMAT_BITMAP ) { Graphic aGraphic( m_xMetaFileGraphic ); - bResult = SetBitmap( aGraphic.GetBitmap(), rFlavor ); + bResult = SetBitmapEx( aGraphic.GetBitmapEx(), rFlavor ); } } diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx index f87afc62ff2c..0dbd56ea379c 100644 --- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx +++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx @@ -25,6 +25,7 @@ #include <vcl/timer.hxx> #include <comphelper/broadcasthelper.hxx> #include <vcl/lazydelete.hxx> +#include <vcl/dibtools.hxx> ////////////////////////////////////////////////////////////////////////////// // buffered VDev usage @@ -292,7 +293,7 @@ namespace drawinglayer if(bDoSaveForVisualControl) { SvFileStream aNew((const String&)String( "c:\\content.bmp" ), STREAM_WRITE|STREAM_TRUNC); - aNew << aContent; + WriteDIB(aContent, aNew, false, true); } if(mpAlpha) @@ -303,7 +304,7 @@ namespace drawinglayer if(bDoSaveForVisualControl) { SvFileStream aNew((const String&)String( "c:\\transparence.bmp" ), STREAM_WRITE|STREAM_TRUNC); - aNew << aAlphaMask.GetBitmap(); + WriteDIB(aAlphaMask.GetBitmap(), aNew, false, true); } mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask)); @@ -316,7 +317,7 @@ namespace drawinglayer if(bDoSaveForVisualControl) { SvFileStream aNew((const String&)String( "c:\\mask.bmp" ), STREAM_WRITE|STREAM_TRUNC); - aNew << aMask; + WriteDIB(aMask, aNew, false, true); } mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask)); diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index acf1a7ee2d12..378961fbdcea 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -54,6 +54,7 @@ #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include <drawinglayer/primitive2d/epsprimitive2d.hxx> #include <basegfx/polygon/b2dlinegeometry.hxx> +#include <vcl/dibtools.hxx> ////////////////////////////////////////////////////////////////////////////// // for PDFExtOutDevData Graphic support diff --git a/drawinglayer/source/tools/converters.cxx b/drawinglayer/source/tools/converters.cxx index dc53f27d9b5d..1bbbe43b6359 100644 --- a/drawinglayer/source/tools/converters.cxx +++ b/drawinglayer/source/tools/converters.cxx @@ -27,6 +27,7 @@ #ifdef DBG_UTIL #include <tools/stream.hxx> +#include <vcl/pngwrite.hxx> #endif ////////////////////////////////////////////////////////////////////////////// @@ -123,7 +124,8 @@ namespace drawinglayer if(bDoSaveForVisualControl) { SvFileStream aNew(OUString("c:\\test.png"), STREAM_WRITE|STREAM_TRUNC); - aNew << aRetval; + ::vcl::PNGWriter aPNGWriter(aRetval); + aPNGWriter.Write(aNew); } #endif diff --git a/dtrans/source/win32/dtobj/DOTransferable.cxx b/dtrans/source/win32/dtobj/DOTransferable.cxx index 30d887d8a165..7e35ac24b0f3 100644 --- a/dtrans/source/win32/dtobj/DOTransferable.cxx +++ b/dtrans/source/win32/dtobj/DOTransferable.cxx @@ -338,10 +338,14 @@ CDOTransferable::ByteSequence_t SAL_CALL CDOTransferable::getClipboardData( CFor clipDataToByteStream( aFormatEtc.getClipformat( ), stgmedium, byteStream ); // format conversion if necessary - if ( CF_DIB == aFormatEtc.getClipformat() ) - byteStream = WinDIBToOOBMP( byteStream ); - else if ( CF_METAFILEPICT == aFormatEtc.getClipformat() ) - byteStream = WinMFPictToOOMFPict( byteStream ); + if(CF_DIBV5 == aFormatEtc.getClipformat() || CF_DIB == aFormatEtc.getClipformat()) + { + byteStream = WinDIBToOOBMP(byteStream); + } + else if(CF_METAFILEPICT == aFormatEtc.getClipformat()) + { + byteStream = WinMFPictToOOMFPict(byteStream); + } } ReleaseStgMedium( &stgmedium ); diff --git a/dtrans/source/win32/dtobj/FmtFilter.cxx b/dtrans/source/win32/dtobj/FmtFilter.cxx index f9327d8e82df..199d30163d06 100644 --- a/dtrans/source/win32/dtobj/FmtFilter.cxx +++ b/dtrans/source/win32/dtobj/FmtFilter.cxx @@ -190,28 +190,31 @@ HENHMETAFILE SAL_CALL OOMFPictToWinENHMFPict( Sequence< sal_Int8 >& aOOMetaFileP Sequence< sal_Int8 > SAL_CALL WinDIBToOOBMP( const Sequence< sal_Int8 >& aWinDIB ) { - OSL_ASSERT( aWinDIB.getLength( ) > sizeof( BITMAPINFOHEADER ) ); - + OSL_ENSURE(aWinDIB.getLength() > sizeof(BITMAPINFOHEADER), "CF_DIBV5/CF_DIB too small (!)"); Sequence< sal_Int8 > ooBmpStream; - ooBmpStream.realloc( aWinDIB.getLength( ) + sizeof(BITMAPFILEHEADER) ); - - const BITMAPINFOHEADER *pBmpInfoHdr = (const BITMAPINFOHEADER*)aWinDIB.getConstArray(); - BITMAPFILEHEADER *pBmpFileHdr = reinterpret_cast< BITMAPFILEHEADER* >( ooBmpStream.getArray() ); - DWORD nOffset = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ); + ooBmpStream.realloc(aWinDIB.getLength( ) + sizeof(BITMAPFILEHEADER)); + const BITMAPINFOHEADER* pBmpInfoHdr = reinterpret_cast< const BITMAPINFOHEADER* >(aWinDIB.getConstArray()); + BITMAPFILEHEADER* pBmpFileHdr = reinterpret_cast< BITMAPFILEHEADER* >(ooBmpStream.getArray()); + const DWORD nSizeInfoOrV5(pBmpInfoHdr->biSize > sizeof(BITMAPINFOHEADER) ? sizeof(BITMAPV5HEADER) : sizeof(BITMAPINFOHEADER)); + DWORD nOffset(sizeof(BITMAPFILEHEADER) + nSizeInfoOrV5); - memcpy( pBmpFileHdr + 1, pBmpInfoHdr, aWinDIB.getLength( ) ); + memcpy(pBmpFileHdr + 1, pBmpInfoHdr, aWinDIB.getLength()); - if( pBmpInfoHdr->biBitCount <= 8 ) - nOffset += ( pBmpInfoHdr->biClrUsed ? pBmpInfoHdr->biClrUsed : ( 1 << pBmpInfoHdr->biBitCount ) ) << 2; - else if( ( BI_BITFIELDS == pBmpInfoHdr->biCompression ) && ( ( 16 == pBmpInfoHdr->biBitCount ) || ( 32 == pBmpInfoHdr->biBitCount ) ) ) + if(pBmpInfoHdr->biBitCount <= 8) + { + nOffset += (pBmpInfoHdr->biClrUsed ? pBmpInfoHdr->biClrUsed : (1 << pBmpInfoHdr->biBitCount)) << 2; + } + else if((BI_BITFIELDS == pBmpInfoHdr->biCompression ) && ((16 == pBmpInfoHdr->biBitCount ) || (32 == pBmpInfoHdr->biBitCount ))) + { nOffset += 12; + } - pBmpFileHdr->bfType = ('M' << 8) | 'B'; - pBmpFileHdr->bfSize = 0; // maybe: nMemSize + sizeof(BITMAPFILEHEADER) + pBmpFileHdr->bfType = ('M' << 8) | 'B'; + pBmpFileHdr->bfSize = 0; // maybe: nMemSize + sizeof(BITMAPFILEHEADER) pBmpFileHdr->bfReserved1 = 0; pBmpFileHdr->bfReserved2 = 0; - pBmpFileHdr->bfOffBits = nOffset; + pBmpFileHdr->bfOffBits = nOffset; return ooBmpStream; } @@ -222,9 +225,6 @@ Sequence< sal_Int8 > SAL_CALL WinDIBToOOBMP( const Sequence< sal_Int8 >& aWinDIB Sequence< sal_Int8 > SAL_CALL OOBmpToWinDIB( Sequence< sal_Int8 >& aOOBmp ) { - OSL_ASSERT( aOOBmp.getLength( ) > - ( sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ) ); - Sequence< sal_Int8 > winDIBStream( aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) ); memcpy( winDIBStream.getArray( ), diff --git a/dtrans/source/win32/dtobj/FmtFilter.hxx b/dtrans/source/win32/dtobj/FmtFilter.hxx index a77d0a5fd5dc..b9f06b599af7 100644 --- a/dtrans/source/win32/dtobj/FmtFilter.hxx +++ b/dtrans/source/win32/dtobj/FmtFilter.hxx @@ -64,6 +64,8 @@ com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL WinBITMAPToOOBMP( HBITMAP ); /*------------------------------------------------------------------------ input: aOOBmp - sequence of bytes containing a openoffice bitmap + May contain CF_DIBV5 or CF_DIB, but removing the BITMAPFILEHEADER + is always the same size ------------------------------------------------------------------------*/ com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL OOBmpToWinDIB( com::sun::star::uno::Sequence< sal_Int8 >& aOOBmp ); diff --git a/dtrans/source/win32/dtobj/XTDataObject.cxx b/dtrans/source/win32/dtobj/XTDataObject.cxx index c213517cdd19..90805fbb8213 100644 --- a/dtrans/source/win32/dtobj/XTDataObject.cxx +++ b/dtrans/source/win32/dtobj/XTDataObject.cxx @@ -298,8 +298,22 @@ void SAL_CALL CXTDataObject::renderAnyDataAndSetupStgMedium( nRequiredMemSize = sizeof( sal_Int8 ) * clipDataStream.getLength( ) + 1; // prepare data for transmision - if ( CF_DIB == fetc.cfFormat ) + if ( CF_DIBV5 == fetc.cfFormat || CF_DIB == fetc.cfFormat ) + { +#ifdef DBG_UTIL + if(CF_DIBV5 == fetc.cfFormat) + { + OSL_ENSURE(clipDataStream.getLength( ) > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPV5HEADER)), "Wrong size on CF_DIBV5 data (!)"); + } + else // CF_DIB == fetc.cfFormat + { + OSL_ENSURE(clipDataStream.getLength( ) > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)), "Wrong size on CF_DIB data (!)"); + } +#endif + + // remove BITMAPFILEHEADER clipDataStream = OOBmpToWinDIB( clipDataStream ); + } if ( CF_METAFILEPICT == fetc.cfFormat ) { diff --git a/dtrans/source/win32/ftransl/ftransl.cxx b/dtrans/source/win32/ftransl/ftransl.cxx index 70724c1600a8..b808fe89c9b0 100644 --- a/dtrans/source/win32/ftransl/ftransl.cxx +++ b/dtrans/source/win32/ftransl/ftransl.cxx @@ -254,6 +254,7 @@ void SAL_CALL CDataFormatTranslator::initTranslationTable() //SOT_FORMATSTR_ID_DIF m_TranslTable.push_back(FormatEntry("application/x-openoffice-dif;windows_formatname=\"DIF\"", "DIF", "DIF", CF_DIF, CPPUTYPE_DEFAULT)); // SOT_FORMAT_BITMAP + m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIBV5, CPPUTYPE_DEFAULT)); m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIB, CPPUTYPE_DEFAULT)); m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_BITMAP, CPPUTYPE_DEFAULT)); // SOT_FORMAT_STRING @@ -485,6 +486,8 @@ void SAL_CALL CDataFormatTranslator::initTranslationTable() m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.dialog", "Dialog 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); //SOT_FORMATSTR_ID_BMP m_TranslTable.push_back(FormatEntry("image/bmp", "Windows Bitmap", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_PNG + m_TranslTable.push_back(FormatEntry("image/png", "PNG", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); //SOT_FORMATSTR_ID_DUMMY3 m_TranslTable.push_back(FormatEntry("application/x-openoffice-dummy3;windows_formatname=\"SO_DUMMYFORMAT_3\"", "SO_DUMMYFORMAT_3", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); //SOT_FORMATSTR_ID_DUMMY4 diff --git a/editeng/source/items/bulitem.cxx b/editeng/source/items/bulitem.cxx index c8de24a1d3f9..e76869e9575f 100644 --- a/editeng/source/items/bulitem.cxx +++ b/editeng/source/items/bulitem.cxx @@ -24,6 +24,7 @@ #include <editeng/editrids.hrc> #include <tools/tenccvt.hxx> +#include <vcl/dibtools.hxx> #define BULITEM_VERSION ((sal_uInt16)2) @@ -126,7 +127,8 @@ SvxBulletItem::SvxBulletItem( SvStream& rStrm, sal_uInt16 _nWhich ) : // Ignore Errorcode when reading Bitmap, // see comment in SvxBulletItem::Store() sal_Bool bOldError = rStrm.GetError() ? sal_True : sal_False; - rStrm >> aBmp; + ReadDIB(aBmp, rStrm, true); + if ( !bOldError && rStrm.GetError() ) { rStrm.ResetError(); @@ -332,7 +334,9 @@ SvStream& SvxBulletItem::Store( SvStream& rStrm, sal_uInt16 /*nItemVersion*/ ) c const Bitmap aBmp( pGraphicObject->GetGraphic().GetBitmap() ); sal_uLong nBytes = aBmp.GetSizeBytes(); if ( nBytes < sal_uLong(0xFF00*nFac) ) - rStrm << aBmp; + { + WriteDIB(aBmp, rStrm, false, true); + } sal_uLong nEnd = rStrm.Tell(); // Item can not write with an overhead more than 64K or SfxMultiRecord diff --git a/extensions/source/scanner/sanedlg.cxx b/extensions/source/scanner/sanedlg.cxx index f13b2434147b..42fd73a8f526 100644 --- a/extensions/source/scanner/sanedlg.cxx +++ b/extensions/source/scanner/sanedlg.cxx @@ -17,11 +17,10 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <stdio.h> #include <stdlib.h> #include <tools/config.hxx> - +#include <vcl/dibtools.hxx> #include <vcl/msgbox.hxx> #include <sanedlg.hxx> #include <sanedlg.hrc> @@ -734,7 +733,7 @@ void SaneDlg::AcquirePreview() fprintf( stderr, "Previewbitmapstream contains %d bytes\n", (int)aTransporter.getStream().Tell() ); #endif aTransporter.getStream().Seek( STREAM_SEEK_TO_BEGIN ); - maPreviewBitmap.Read( aTransporter.getStream(), sal_True ); + ReadDIB(maPreviewBitmap, aTransporter.getStream(), true); } SetAdjustedNumericalValue( "resolution", fResl ); diff --git a/filter/source/graphicfilter/eos2met/eos2met.cxx b/filter/source/graphicfilter/eos2met/eos2met.cxx index 761c4564e48f..fc9efad3a73e 100644 --- a/filter/source/graphicfilter/eos2met/eos2met.cxx +++ b/filter/source/graphicfilter/eos2met/eos2met.cxx @@ -35,6 +35,7 @@ #include <vcl/msgbox.hxx> #include <svl/solar.hrc> #include <vcl/gdimetafiletools.hxx> +#include <vcl/dibtools.hxx> // -----------------------------Field Types------------------------------- @@ -562,7 +563,7 @@ void METWriter::WriteImageObject(const Bitmap & rBitmap) WriteFieldId(nActBitmapId); // generate Windows-BMP file - aTemp << rBitmap; + WriteDIB(rBitmap, aTemp, false, true); // read header of the Windows-BMP file: aTemp.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN); diff --git a/filter/source/graphicfilter/ios2met/ios2met.cxx b/filter/source/graphicfilter/ios2met/ios2met.cxx index 834bd1155f6e..b50ce696600d 100644 --- a/filter/source/graphicfilter/ios2met/ios2met.cxx +++ b/filter/source/graphicfilter/ios2met/ios2met.cxx @@ -17,9 +17,9 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <vcl/graph.hxx> #include <tools/poly.hxx> +#include <vcl/dibtools.hxx> #include <vcl/virdev.hxx> #include <vcl/lineinfo.hxx> @@ -2362,7 +2362,7 @@ void OS2METReader::ReadField(sal_uInt16 nFieldType, sal_uInt16 nFieldSize) } pBitmapList->pBMP->Seek(0); - pBitmapList->aBitmap.Read( *( pBitmapList->pBMP ), sal_False ); + ReadDIB(pBitmapList->aBitmap, *(pBitmapList->pBMP), false); if (pBitmapList->pBMP->GetError()!=0) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx index a80bdfd64d2e..a580c432cf7f 100644 --- a/filter/source/msfilter/msdffimp.cxx +++ b/filter/source/msfilter/msdffimp.cxx @@ -114,6 +114,7 @@ #include "svx/gallery.hxx" #include <com/sun/star/drawing/ShadeMode.hpp> #include <svl/itempool.hxx> +#include <vcl/dibtools.hxx> #include <vcl/svapp.hxx> #include <svx/svx3ditems.hxx> #include <svx/svdoashp.hxx> @@ -6325,7 +6326,7 @@ sal_Bool SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, if( ( nInst & 0xFFFE ) == 0x7A8 ) { // getting the DIBs immediately Bitmap aNew; - if( aNew.Read( *pGrStream, sal_False ) ) + if( ReadDIB(aNew, *pGrStream, false) ) { rData = Graphic( aNew ); nRes = GRFILTER_OK; diff --git a/filter/source/msfilter/mstoolbar.cxx b/filter/source/msfilter/mstoolbar.cxx index fd08ddc11c55..0088fc7b2c37 100644 --- a/filter/source/msfilter/mstoolbar.cxx +++ b/filter/source/msfilter/mstoolbar.cxx @@ -15,6 +15,7 @@ #include <com/sun/star/ui/ItemStyle.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> #include <fstream> +#include <vcl/dibtools.hxx> #include <vcl/graph.hxx> #include <vcl/bitmapex.hxx> #include <vcl/image.hxx> @@ -712,7 +713,7 @@ bool TBCBitMap::Read( SvStream& rS) nOffSet = rS.Tell(); rS >> cbDIB; // cbDIB = sizeOf(biHeader) + sizeOf(colors) + sizeOf(bitmapData) + 10 - return mBitMap.Read( rS, sal_False, sal_True ); + return ReadDIB(mBitMap, rS, false); } void TBCBitMap::Print( FILE* fp ) diff --git a/fpicker/source/office/iodlg.cxx b/fpicker/source/office/iodlg.cxx index 1ed7a8c6db89..f4c8d3a9ba87 100644 --- a/fpicker/source/office/iodlg.cxx +++ b/fpicker/source/office/iodlg.cxx @@ -71,6 +71,7 @@ #include <comphelper/string.hxx> #include <osl/file.h> +#include <vcl/dibtools.hxx> #include <vcl/waitobj.hxx> #include <com/sun/star/task/InteractionHandler.hpp> @@ -3024,7 +3025,7 @@ void SvtFileDialog::setImage( sal_Int16 /*aImageFormat*/, const Any& rImage ) SvMemoryStream aData( aBmpSequence.getArray(), aBmpSequence.getLength(), STREAM_READ ); - aData >> aBmp; + ReadDIB(aBmp, aData, true); _pPrevBmp->SetBitmap( aBmp ); } diff --git a/framework/source/fwe/classes/addonsoptions.cxx b/framework/source/fwe/classes/addonsoptions.cxx index 0fdc325dd466..a94fe1c75165 100644 --- a/framework/source/fwe/classes/addonsoptions.cxx +++ b/framework/source/fwe/classes/addonsoptions.cxx @@ -29,6 +29,7 @@ #include <rtl/ustrbuf.hxx> #include <rtl/uri.hxx> #include <comphelper/processfactory.hxx> +#include <vcl/dibtools.hxx> #include <vcl/graph.hxx> #include <vcl/graphicfilter.hxx> @@ -1661,7 +1662,7 @@ sal_Bool AddonsOptions_Impl::CreateImageFromSequence( Image& rImage, sal_Bool bB SvMemoryStream aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), STREAM_STD_READ ); BitmapEx aBitmapEx; - aMemStream >> aBitmapEx; + ReadDIBBitmapEx(aBitmapEx, aMemStream); // Scale bitmap to fit the correct size for the menu/toolbar. Use best quality if ( aBitmapEx.GetSizePixel() != aSize ) diff --git a/framework/source/fwe/classes/imagewrapper.cxx b/framework/source/fwe/classes/imagewrapper.cxx index 054a63ae4866..ac42ab5f9238 100644 --- a/framework/source/fwe/classes/imagewrapper.cxx +++ b/framework/source/fwe/classes/imagewrapper.cxx @@ -25,6 +25,7 @@ #include <vcl/bitmapex.hxx> #include <tools/stream.hxx> #include <cppuhelper/typeprovider.hxx> +#include <vcl/dibtools.hxx> using namespace com::sun::star::lang; using namespace com::sun::star::uno; @@ -72,7 +73,7 @@ Sequence< sal_Int8 > SAL_CALL ImageWrapper::getDIB() throw ( RuntimeException ) SolarMutexGuard aGuard; SvMemoryStream aMem; - aMem << m_aImage.GetBitmapEx().GetBitmap(); + WriteDIB(m_aImage.GetBitmapEx().GetBitmap(), aMem, false, true); return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() ); } @@ -84,13 +85,13 @@ Sequence< sal_Int8 > SAL_CALL ImageWrapper::getMaskDIB() throw ( RuntimeExceptio if ( aBmpEx.IsAlpha() ) { SvMemoryStream aMem; - aMem << aBmpEx.GetAlpha().GetBitmap(); + WriteDIB(aBmpEx.GetAlpha().GetBitmap(), aMem, false, true); return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() ); } else if ( aBmpEx.IsTransparent() ) { SvMemoryStream aMem; - aMem << aBmpEx.GetMask(); + WriteDIB(aBmpEx.GetMask(), aMem, false, true); return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() ); } diff --git a/framework/source/fwe/helper/actiontriggerhelper.cxx b/framework/source/fwe/helper/actiontriggerhelper.cxx index 67fdd65ff413..96149e4338d2 100644 --- a/framework/source/fwe/helper/actiontriggerhelper.cxx +++ b/framework/source/fwe/helper/actiontriggerhelper.cxx @@ -30,7 +30,7 @@ #include <tools/stream.hxx> #include <cppuhelper/weak.hxx> #include <comphelper/processfactory.hxx> - +#include <vcl/dibtools.hxx> const sal_uInt16 START_ITEMID = 1000; @@ -183,7 +183,7 @@ void InsertSubMenuItems( Menu* pSubMenu, sal_uInt16& nItemId, Reference< XIndexC { aDIBSeq = xBitmap->getDIB(); SvMemoryStream aMem( (void *)aDIBSeq.getConstArray(), aDIBSeq.getLength(), STREAM_READ ); - aMem >> aBitmap; + ReadDIB(aBitmap, aMem, true); } aDIBSeq = xBitmap->getMaskDIB(); @@ -191,7 +191,7 @@ void InsertSubMenuItems( Menu* pSubMenu, sal_uInt16& nItemId, Reference< XIndexC { Bitmap aMaskBitmap; SvMemoryStream aMem( (void *)aDIBSeq.getConstArray(), aDIBSeq.getLength(), STREAM_READ ); - aMem >> aMaskBitmap; + ReadDIB(aMaskBitmap, aMem, true); aImage = Image( aBitmap, aMaskBitmap ); } else diff --git a/include/sot/formats.hxx b/include/sot/formats.hxx index 912947669e53..74d3552a0e26 100644 --- a/include/sot/formats.hxx +++ b/include/sot/formats.hxx @@ -175,7 +175,8 @@ #define SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE ((sal_uLong)138) #define SOT_FORMATSTR_ID_STARBASE_8 ((sal_uLong)139) #define SOT_FORMATSTR_ID_HC_GDIMETAFILE ((sal_uLong)140) -#define SOT_FORMATSTR_ID_USER_END SOT_FORMATSTR_ID_HC_GDIMETAFILE +#define SOT_FORMATSTR_ID_PNG ((sal_uLong)141) +#define SOT_FORMATSTR_ID_USER_END SOT_FORMATSTR_ID_PNG #endif // _SOT_FORMATS_HXX diff --git a/include/svtools/transfer.hxx b/include/svtools/transfer.hxx index 5d63d166bfa5..4f8966bcb4bf 100644 --- a/include/svtools/transfer.hxx +++ b/include/svtools/transfer.hxx @@ -40,7 +40,7 @@ #include <com/sun/star/embed/Aspects.hpp> #include <com/sun/star/io/XInputStream.hpp> -class Bitmap; +class BitmapEx; class GDIMetaFile; class Graphic; class ImageMap; @@ -224,7 +224,7 @@ protected: sal_Bool SetAny( const ::com::sun::star::uno::Any& rAny, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); sal_Bool SetString( const OUString& rString, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); - sal_Bool SetBitmap( const Bitmap& rBitmap, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); + sal_Bool SetBitmapEx( const BitmapEx& rBitmap, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); sal_Bool SetGDIMetaFile( const GDIMetaFile& rMtf, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); sal_Bool SetGraphic( const Graphic& rGraphic, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); sal_Bool SetImageMap( const ImageMap& rIMap, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); @@ -321,8 +321,8 @@ public: sal_Bool GetString( SotFormatStringId nFormat, OUString& rStr ); sal_Bool GetString( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, OUString& rStr ); - sal_Bool GetBitmap( SotFormatStringId nFormat, Bitmap& rBmp ); - sal_Bool GetBitmap( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, Bitmap& rBmp ); + sal_Bool GetBitmapEx( SotFormatStringId nFormat, BitmapEx& rBmp ); + sal_Bool GetBitmapEx( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, BitmapEx& rBmp ); sal_Bool GetGDIMetaFile( SotFormatStringId nFormat, GDIMetaFile& rMtf ); sal_Bool GetGDIMetaFile( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, GDIMetaFile& rMtf ); diff --git a/include/vcl/alpha.hxx b/include/vcl/alpha.hxx index 95bb0ea29de2..4ad3e28f9fb6 100644 --- a/include/vcl/alpha.hxx +++ b/include/vcl/alpha.hxx @@ -32,11 +32,10 @@ class BitmapEx; class VCL_DLLPUBLIC AlphaMask : private Bitmap { +private: friend class BitmapEx; friend class OutputDevice; - friend VCL_DLLPUBLIC SvStream& operator<<( SvStream&, const ImageList& ); - -private: + friend bool VCL_DLLPUBLIC ReadDIBBitmapEx(BitmapEx& rTarget, SvStream& rIStm); SAL_DLLPRIVATE const Bitmap& ImplGetBitmap() const; SAL_DLLPRIVATE void ImplSetBitmap( const Bitmap& rBitmap ); @@ -130,18 +129,6 @@ public: ScopedReadAccess; typedef vcl::ScopedBitmapAccess< BitmapWriteAccess, AlphaMask, &AlphaMask::AcquireWriteAccess > ScopedWriteAccess; - - sal_Bool Read( SvStream& rIStm, sal_Bool bFileHeader = sal_True ) - { - return Bitmap::Read( rIStm, bFileHeader ); - } - sal_Bool Write( SvStream& rOStm, sal_Bool bCompressed = sal_True, sal_Bool bFileHeader = sal_True ) const - { - return Bitmap::Write( rOStm, bCompressed, bFileHeader ); - } - - friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const BitmapEx& rBitmapEx ); - friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, BitmapEx& rBitmapEx ); }; #endif // _SV_ALPHA_HXX diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx index a5388fa2c25d..b4e07fb77aa5 100644 --- a/include/vcl/bitmap.hxx +++ b/include/vcl/bitmap.hxx @@ -290,8 +290,6 @@ class BitmapWriteAccess; class BitmapPalette; class ImpBitmap; class Color; -class SvStream; -struct DIBInfoHeader; class ResId; class GDIMetaFile; class AlphaMask; @@ -328,20 +326,6 @@ public: SAL_DLLPRIVATE void ImplSetImpBitmap( ImpBitmap* pImpBmp ); SAL_DLLPRIVATE void ImplAssignWithSize( const Bitmap& rBitmap ); - SAL_DLLPRIVATE static sal_Bool ImplReadDIB( SvStream& rIStm, Bitmap& rBmp, sal_uLong nOffset, sal_Bool bMSOFormat = sal_False ); - SAL_DLLPRIVATE static sal_Bool ImplReadDIBFileHeader( SvStream& rIStm, sal_uLong& rOffset ); - SAL_DLLPRIVATE static sal_Bool ImplReadDIBInfoHeader( SvStream& rIStm, DIBInfoHeader& rHeader, sal_Bool& bTopDown, sal_Bool bMSOFormat = sal_False ); - SAL_DLLPRIVATE static sal_Bool ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, sal_Bool bQuad ); - SAL_DLLPRIVATE static sal_Bool ImplReadDIBBits( SvStream& rIStm, DIBInfoHeader& rHeader, BitmapWriteAccess& rAcc, sal_Bool bTopDown ); - SAL_DLLPRIVATE sal_Bool ImplWriteDIB( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bCompressed ) const; - SAL_DLLPRIVATE static sal_Bool ImplWriteDIBFileHeader( SvStream& rOStm, BitmapReadAccess& rAcc ); - SAL_DLLPRIVATE static sal_Bool ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc ); - SAL_DLLPRIVATE static sal_Bool ImplWriteDIBBits( SvStream& rOStm, BitmapReadAccess& rAcc, - sal_uLong nCompression, sal_uInt32& rImageSize ); - SAL_DLLPRIVATE static void ImplDecodeRLE( sal_uInt8* pBuffer, DIBInfoHeader& rHeader, - BitmapWriteAccess& rAcc, sal_Bool bRLE4 ); - SAL_DLLPRIVATE static sal_Bool ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bRLE4 ); - SAL_DLLPRIVATE void ImplAdaptBitCount(Bitmap& rNew) const; SAL_DLLPRIVATE sal_Bool ImplScaleFast( const double& rScaleX, const double& rScaleY ); SAL_DLLPRIVATE sal_Bool ImplScaleInterpolate( const double& rScaleX, const double& rScaleY ); @@ -865,14 +849,6 @@ public: ScopedReadAccess; typedef vcl::ScopedBitmapAccess< BitmapWriteAccess, Bitmap, &Bitmap::AcquireWriteAccess > ScopedWriteAccess; - -public: - - sal_Bool Read( SvStream& rIStm, sal_Bool bFileHeader = sal_True, sal_Bool bMSOFormat = sal_False ); - sal_Bool Write( SvStream& rOStm, sal_Bool bCompressed = sal_True, sal_Bool bFileHeader = sal_True ) const; - - friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, Bitmap& rBitmap ); - friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const Bitmap& rBitmap ); }; inline sal_Bool Bitmap::operator!() const diff --git a/include/vcl/bitmapex.hxx b/include/vcl/bitmapex.hxx index ce1b2ae0bd99..f26ef9611d42 100644 --- a/include/vcl/bitmapex.hxx +++ b/include/vcl/bitmapex.hxx @@ -48,9 +48,9 @@ enum TransparentType class VCL_DLLPUBLIC BitmapEx { - friend class ImpGraphic; - private: + friend class ImpGraphic; + friend bool VCL_DLLPUBLIC WriteDIBBitmapEx(const BitmapEx& rSource, SvStream& rOStm); Bitmap aBitmap; Bitmap aMask; @@ -65,8 +65,6 @@ public: SAL_DLLPRIVATE ImpBitmap* ImplGetBitmapImpBitmap() const { return aBitmap.ImplGetImpBitmap(); } SAL_DLLPRIVATE ImpBitmap* ImplGetMaskImpBitmap() const { return aMask.ImplGetImpBitmap(); } -public: - BitmapEx(); BitmapEx( const ResId& rResId ); BitmapEx( const BitmapEx& rBitmapEx ); @@ -385,8 +383,6 @@ public: public: - friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const BitmapEx& rBitmapEx ); - friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, BitmapEx& rBitmapEx ); static BitmapEx AutoScaleBitmap(BitmapEx & aBitmap, const long aStandardSize); /// populate from a canvas implementation diff --git a/include/vcl/dibtools.hxx b/include/vcl/dibtools.hxx new file mode 100644 index 000000000000..a8b0336b02a1 --- /dev/null +++ b/include/vcl/dibtools.hxx @@ -0,0 +1,70 @@ +/* + * 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 _SV_DIBTOOLS_HXX +#define _SV_DIBTOOLS_HXX + +#include <vcl/dllapi.h> +#include <vcl/mapmod.hxx> +#include <tools/rc.hxx> +#include <vcl/region.hxx> + +////////////////////////////////////////////////////////////////////////////// +// predefines + +class SvStream; +class BitmapEx; +class Bitmap; + +////////////////////////////////////////////////////////////////////////////// + +bool VCL_DLLPUBLIC ReadDIB( // ReadDIB(rBitmap, rIStm, true); + Bitmap& rTarget, + SvStream& rIStm, + bool bFileHeader); + +bool VCL_DLLPUBLIC ReadDIBBitmapEx( + BitmapEx& rTarget, + SvStream& rIStm); + +bool VCL_DLLPUBLIC ReadDIBV5( + Bitmap& rTarget, + Bitmap& rTargetAlpha, + SvStream& rIStm); + +////////////////////////////////////////////////////////////////////////////// + +bool VCL_DLLPUBLIC WriteDIB( // WriteDIB(rBitmap, rOStm, false, true); + const Bitmap& rSource, + SvStream& rOStm, + bool bCompressed, + bool bFileHeader); + +bool VCL_DLLPUBLIC WriteDIBBitmapEx( + const BitmapEx& rSource, + SvStream& rOStm); + +bool VCL_DLLPUBLIC WriteDIBV5( + const Bitmap& rSource, + const Bitmap& rSourceAlpha, + SvStream& rOStm); + +////////////////////////////////////////////////////////////////////////////// + +#endif // _SV_DIBTOOLS_HXX + +////////////////////////////////////////////////////////////////////////////// diff --git a/include/vcl/pngwrite.hxx b/include/vcl/pngwrite.hxx index 921ad45ddf4d..bff25ad15041 100644 --- a/include/vcl/pngwrite.hxx +++ b/include/vcl/pngwrite.hxx @@ -40,7 +40,7 @@ namespace vcl public: - PNGWriter( const BitmapEx& BmpEx, + explicit PNGWriter( const BitmapEx&, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData = NULL ); ~PNGWriter(); diff --git a/include/vcl/salbtype.hxx b/include/vcl/salbtype.hxx index 3fc153dc0f2f..f926262c014c 100644 --- a/include/vcl/salbtype.hxx +++ b/include/vcl/salbtype.hxx @@ -240,6 +240,7 @@ public: inline void SetColorFor24Bit( const BitmapColor& rColor, HPBYTE pPixel ) const; inline void GetColorFor32Bit( BitmapColor& rColor, ConstHPBYTE pPixel ) const; + inline void GetColorAndAlphaFor32Bit( BitmapColor& rColor, sal_uInt8& rAlpha, ConstHPBYTE pPixel ) const; inline void SetColorFor32Bit( const BitmapColor& rColor, HPBYTE pPixel ) const; }; @@ -863,6 +864,21 @@ inline void ColorMask::GetColorFor32Bit( BitmapColor& rColor, ConstHPBYTE pPixel // ------------------------------------------------------------------ +inline void ColorMask::GetColorAndAlphaFor32Bit( BitmapColor& rColor, sal_uInt8& rAlpha, ConstHPBYTE pPixel ) const +{ +#ifdef OSL_BIGENDIAN + const sal_uInt32 nVal = (sal_uInt32) pPixel[ 0 ] | ( (sal_uInt32) pPixel[ 1 ] << 8UL ) | + ( (sal_uInt32) pPixel[ 2 ] << 16UL ) | ( (sal_uInt32) pPixel[ 3 ] << 24UL ); +#else + const sal_uInt32 nVal = *(sal_uInt32*) pPixel; +#endif + rAlpha = (sal_uInt8)(nVal >> 24); + + MASK_TO_COLOR( nVal, mnRMask, mnGMask, mnBMask, mnRShift, mnGShift, mnBShift, rColor ); +} + +// ------------------------------------------------------------------ + inline void ColorMask::SetColorFor32Bit( const BitmapColor& rColor, HPBYTE pPixel ) const { #ifdef OSL_BIGENDIAN diff --git a/include/vcl/wall.hxx b/include/vcl/wall.hxx index e18adf78f60b..18a90d3dccb9 100644 --- a/include/vcl/wall.hxx +++ b/include/vcl/wall.hxx @@ -92,7 +92,7 @@ public: Wallpaper(); Wallpaper( const Wallpaper& rWallpaper ); Wallpaper( const Color& rColor ); - Wallpaper( const BitmapEx& rBmpEx ); + explicit Wallpaper( const BitmapEx& rBmpEx ); Wallpaper( const Gradient& rGradient ); ~Wallpaper(); diff --git a/lotuswordpro/source/filter/lwpbackgroundstuff.cxx b/lotuswordpro/source/filter/lwpbackgroundstuff.cxx index 46bd2ed88d01..2b9da1c04347 100644 --- a/lotuswordpro/source/filter/lwpbackgroundstuff.cxx +++ b/lotuswordpro/source/filter/lwpbackgroundstuff.cxx @@ -64,6 +64,7 @@ #include "xfilter/xfbgimage.hxx" #include "tools/stream.hxx" +#include "vcl/dibtools.hxx" #include "vcl/bmpacc.hxx" #include "svx/xbitmap.hxx" @@ -159,7 +160,7 @@ XFBGImage* LwpBackgroundStuff::GetFillPattern() // transfer image data from XOBitmap->SvStream->BYTE-Array SvMemoryStream aPicMemStream; aXOBitmap.Array2Bitmap(); - aXOBitmap.GetBitmap().Write(aPicMemStream); + WriteDIB(aXOBitmap.GetBitmap(), aPicMemStream, true, true); sal_uInt32 nSize = aPicMemStream.GetEndOfData(); sal_uInt8* pImageBuff = new sal_uInt8 [nSize]; memcpy(pImageBuff, aPicMemStream.GetData(), nSize); diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index 354ea148dea8..89d384013602 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -45,6 +45,7 @@ #include <sfx2/objsh.hxx> #include <unotools/moduleoptions.hxx> #include <unotools/fltrcfg.hxx> +#include <vcl/dibtools.hxx> #include <vcl/wmf.hxx> #include <comphelper/types.hxx> #include <comphelper/classids.hxx> @@ -745,7 +746,7 @@ void XclImpDrawObjBase::ConvertFillStyle( SdrObject& rSdrObj, const XclObjFillDa aMemStrm << sal_uInt32( pnPattern[ nIdx ] ); // 32-bit little-endian aMemStrm.Seek( STREAM_SEEK_TO_BEGIN ); Bitmap aBitmap; - aBitmap.Read( aMemStrm, sal_False ); + ReadDIB(aBitmap, aMemStrm, false); XOBitmap aXOBitmap( aBitmap ); aXOBitmap.Bitmap2Array(); @@ -4054,7 +4055,7 @@ void XclImpDrawing::ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpS // import the graphic from memory stream aMemStrm.Seek( STREAM_SEEK_TO_BEGIN ); Bitmap aBitmap; - if( aBitmap.Read( aMemStrm, false ) ) // read DIB without file header + if( ReadDIB(aBitmap, aMemStrm, false) ) // read DIB without file header rGraphic = aBitmap; } diff --git a/sc/source/ui/app/drwtrans.cxx b/sc/source/ui/app/drwtrans.cxx index fab510e3e8b0..ba018efb8f53 100644 --- a/sc/source/ui/app/drwtrans.cxx +++ b/sc/source/ui/app/drwtrans.cxx @@ -427,7 +427,7 @@ sal_Bool ScDrawTransferObj::GetData( const ::com::sun::star::datatransfer::DataF if ( nFormat == SOT_FORMAT_GDIMETAFILE ) bOK = SetGDIMetaFile( aView.GetMarkedObjMetaFile(true), rFlavor ); else - bOK = SetBitmap( aView.GetMarkedObjBitmapEx(true).GetBitmap(), rFlavor ); + bOK = SetBitmapEx( aView.GetMarkedObjBitmapEx(true), rFlavor ); } else if ( nFormat == SOT_FORMATSTR_ID_SVXB ) { diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx index 8d773501e93c..1fecb4992cb4 100644 --- a/sc/source/ui/app/transobj.cxx +++ b/sc/source/ui/app/transobj.cxx @@ -350,7 +350,7 @@ sal_Bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor ) aVirtDev.SetMapMode( MapMode( MAP_PIXEL ) ); Bitmap aBmp = aVirtDev.GetBitmap( Point(), aVirtDev.GetOutputSize() ); - bOK = SetBitmap( aBmp, rFlavor ); + bOK = SetBitmapEx( aBmp, rFlavor ); } else if ( nFormat == SOT_FORMAT_GDIMETAFILE ) { diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 11c54390e412..c3c770513048 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -3169,6 +3169,4 @@ bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal return bRes; } - - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 7203b6b58ed6..3c6364cbf235 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -130,7 +130,7 @@ public: sal_Bool PasteFile( const Point&, const String&, sal_Bool bLink=false ); sal_Bool PasteObject( const Point&, const com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >&, const Size* = NULL, const Graphic* = NULL, const OUString& = OUString(), sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT ); - sal_Bool PasteBitmap( const Point&, const Bitmap& ); + sal_Bool PasteBitmapEx( const Point&, const BitmapEx& ); sal_Bool PasteMetaFile( const Point&, const GDIMetaFile& ); sal_Bool PasteGraphic( const Point& rPos, const Graphic& rGraphic, const String& rFile, const String& rFilter ); diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index 9f091a656406..afc2831dd798 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -719,9 +719,9 @@ sal_Bool ScViewFunc::PasteOnDrawObject( const uno::Reference<datatransfer::XTran } else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) ) { - Bitmap aBmp; - if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) ) - bRet = ApplyGraphicToObject( pHitObj, Graphic(aBmp) ); + BitmapEx aBmpEx; + if( aDataHelper.GetBitmapEx( FORMAT_BITMAP, aBmpEx ) ) + bRet = ApplyGraphicToObject( pHitObj, Graphic(aBmpEx) ); } } else diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx index 1611c7f37433..200a3fd658bf 100644 --- a/sc/source/ui/view/viewfun5.cxx +++ b/sc/source/ui/view/viewfun5.cxx @@ -454,9 +454,9 @@ sal_Bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId, } else if (nFormatId == SOT_FORMAT_BITMAP) { - Bitmap aBmp; - if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) ) - bRet = PasteBitmap( aPos, aBmp ); + BitmapEx aBmpEx; + if( aDataHelper.GetBitmapEx( FORMAT_BITMAP, aBmpEx ) ) + bRet = PasteBitmapEx( aPos, aBmpEx ); } else if (nFormatId == SOT_FORMAT_GDIMETAFILE) { diff --git a/sc/source/ui/view/viewfun7.cxx b/sc/source/ui/view/viewfun7.cxx index 922c781a7603..8fa0e3814310 100644 --- a/sc/source/ui/view/viewfun7.cxx +++ b/sc/source/ui/view/viewfun7.cxx @@ -359,10 +359,10 @@ sal_Bool ScViewFunc::PasteObject( const Point& rPos, const uno::Reference < embe return false; } -sal_Bool ScViewFunc::PasteBitmap( const Point& rPos, const Bitmap& rBmp ) +sal_Bool ScViewFunc::PasteBitmapEx( const Point& rPos, const BitmapEx& rBmpEx ) { String aEmpty; - Graphic aGraphic(rBmp); + Graphic aGraphic(rBmpEx); return PasteGraphic( rPos, aGraphic, aEmpty, aEmpty ); } diff --git a/sd/source/ui/app/sdxfer.cxx b/sd/source/ui/app/sdxfer.cxx index 16397d398f35..b13af5d097b8 100644 --- a/sd/source/ui/app/sdxfer.cxx +++ b/sd/source/ui/app/sdxfer.cxx @@ -505,10 +505,10 @@ sal_Bool SdTransferable::GetData( const DataFlavor& rFlavor ) if( mpSdViewIntern ) bOK = SetGDIMetaFile( mpSdViewIntern->GetMarkedObjMetaFile( true ), rFlavor ); } - else if( nFormat == FORMAT_BITMAP ) + else if( FORMAT_BITMAP == nFormat || SOT_FORMATSTR_ID_PNG == nFormat ) { if( mpSdViewIntern ) - bOK = SetBitmap( mpSdViewIntern->GetMarkedObjBitmapEx( true ).GetBitmap(), rFlavor ); + bOK = SetBitmapEx( mpSdViewIntern->GetMarkedObjBitmapEx(true), rFlavor ); } else if( ( nFormat == FORMAT_STRING ) && mpBookmark ) { diff --git a/sd/source/ui/unoidl/unopage.cxx b/sd/source/ui/unoidl/unopage.cxx index 1fb509a236f6..cb09121890bb 100644 --- a/sd/source/ui/unoidl/unopage.cxx +++ b/sd/source/ui/unoidl/unopage.cxx @@ -51,7 +51,6 @@ #include <osl/mutex.hxx> #include <svl/style.hxx> #include <comphelper/serviceinfohelper.hxx> - #include <comphelper/extract.hxx> #include <list> #include <svx/svditer.hxx> @@ -68,6 +67,7 @@ #include "unokywds.hxx" #include "unopback.hxx" #include "unohelp.hxx" +#include <vcl/dibtools.hxx> using ::com::sun::star::animations::XAnimationNode; using ::com::sun::star::animations::XAnimationNodeSupplier; @@ -1122,7 +1122,7 @@ Any SAL_CALL SdGenericDrawPage::getPropertyValue( const OUString& PropertyName ) aBitmap ) ) { SvMemoryStream aMemStream; - aBitmap.GetBitmap().Write( aMemStream, sal_False, sal_False ); + WriteDIB(aBitmap.GetBitmap(), aMemStream, false, false); uno::Sequence<sal_Int8> aSeq( (sal_Int8*)aMemStream.GetData(), aMemStream.Tell() ); aAny <<= aSeq; } diff --git a/sd/source/ui/view/sdview3.cxx b/sd/source/ui/view/sdview3.cxx index 94b2abb82a41..a0df92cabe90 100644 --- a/sd/source/ui/view/sdview3.cxx +++ b/sd/source/ui/view/sdview3.cxx @@ -1209,9 +1209,9 @@ sal_Bool View::InsertData( const TransferableDataHelper& rDataHelper, } else if( ( !bLink || pPickObj ) && CHECK_FORMAT_TRANS( FORMAT_BITMAP ) ) { - Bitmap aBmp; + BitmapEx aBmpEx; - if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) ) + if( aDataHelper.GetBitmapEx( FORMAT_BITMAP, aBmpEx ) ) { Point aInsertPos( rPos ); @@ -1232,10 +1232,10 @@ sal_Bool View::InsertData( const TransferableDataHelper& rDataHelper, } // restrict movement to WorkArea - Size aImageMapSize(aBmp.GetPrefSize()); + Size aImageMapSize(aBmpEx.GetPrefSize()); ImpCheckInsertPos(aInsertPos, aImageMapSize, GetWorkArea()); - InsertGraphic( aBmp, mnAction, aInsertPos, NULL, pImageMap ); + InsertGraphic( aBmpEx, mnAction, aInsertPos, NULL, pImageMap ); bReturn = sal_True; } } diff --git a/sfx2/source/appl/fileobj.cxx b/sfx2/source/appl/fileobj.cxx index 1083a85956a4..b99ef48cdf75 100644 --- a/sfx2/source/appl/fileobj.cxx +++ b/sfx2/source/appl/fileobj.cxx @@ -17,7 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <vcl/wrkwin.hxx> #include <vcl/msgbox.hxx> #include <tools/urlobj.hxx> @@ -41,6 +40,7 @@ #include "sfx2/sfxresid.hxx" #include "fileobj.hxx" #include "app.hrc" +#include <vcl/dibtools.hxx> #define FILETYPE_TEXT 1 #define FILETYPE_GRF 2 @@ -170,9 +170,16 @@ sal_Bool SvFileObject::GetData( ::com::sun::star::uno::Any & rData, break; case FORMAT_BITMAP: - if( !aGrf.GetBitmap().IsEmpty()) - aMemStm << aGrf.GetBitmap(); + { + const Bitmap aBitmap(aGrf.GetBitmap()); + + if(!aBitmap.IsEmpty()) + { + WriteDIB(aBitmap, aMemStm, false, true); + } + break; + } default: if( aGrf.GetGDIMetaFile().GetActionSize() ) diff --git a/sfx2/source/appl/linkmgr2.cxx b/sfx2/source/appl/linkmgr2.cxx index 6c0219b38a6b..7dcccadc2e85 100644 --- a/sfx2/source/appl/linkmgr2.cxx +++ b/sfx2/source/appl/linkmgr2.cxx @@ -36,6 +36,7 @@ #include <unotools/localfilehelper.hxx> #include <i18nlangtag/languagetag.hxx> #include <sfx2/request.hxx> +#include <vcl/dibtools.hxx> #include "fileobj.hxx" #include "impldde.hxx" @@ -570,7 +571,7 @@ sal_Bool LinkManager::GetGraphicFromAny( const String& rMimeType, case FORMAT_BITMAP: { Bitmap aBmp; - aMemStm >> aBmp; + ReadDIB(aBmp, aMemStm, true); rGrf = aBmp; bRet = sal_True; } diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index a927cfe35e74..d11cdf920aab 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -67,6 +67,7 @@ #include <svl/eitem.hxx> #include <svl/intitem.hxx> #include <svl/stritem.hxx> +#include <vcl/dibtools.hxx> #include <vcl/graphicfilter.hxx> #include <unotools/viewoptions.hxx> #include <unotools/moduleoptions.hxx> @@ -742,7 +743,7 @@ IMPL_LINK_NOARG(FileDialogHelper_Impl, TimeOutHdl_Impl) // and copy it into the Any SvMemoryStream aData; - aData << aBmp; + WriteDIB(aBmp, aData, false, true); const Sequence < sal_Int8 > aBuffer( static_cast< const sal_Int8* >(aData.GetData()), diff --git a/sfx2/source/doc/docinf.cxx b/sfx2/source/doc/docinf.cxx index 5dbb9dd97f29..172cfb7eeeaf 100644 --- a/sfx2/source/doc/docinf.cxx +++ b/sfx2/source/doc/docinf.cxx @@ -19,20 +19,18 @@ #include <sfx2/docinf.hxx> - #include <com/sun/star/beans/PropertyAttribute.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XPropertyContainer.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XCompatWriterDocProperties.hpp> #include <com/sun/star/uno/Exception.hpp> - #include <rtl/ustring.hxx> #include <tools/debug.hxx> #include <comphelper/string.hxx> #include <sot/storage.hxx> #include <vcl/gdimtf.hxx> - +#include <vcl/dibtools.hxx> #include "oleprops.hxx" // ============================================================================ @@ -310,7 +308,7 @@ uno::Sequence<sal_uInt8> SFX2_DLLPUBLIC convertMetaFile(GDIMetaFile* i_pThumb) SvMemoryStream aStream; // magic value 160 taken from GraphicHelper::getThumbnailFormatFromGDI_Impl() if( i_pThumb->CreateThumbnail( 160, aBitmap ) ) { - aBitmap.GetBitmap().Write( aStream, sal_False, sal_False ); + WriteDIB(aBitmap.GetBitmap(), aStream, false, false); aStream.Seek(STREAM_SEEK_TO_END); uno::Sequence<sal_uInt8> aSeq(aStream.Tell()); const sal_uInt8* pBlob( diff --git a/sot/source/base/exchange.cxx b/sot/source/base/exchange.cxx index c56cc5f9ec14..8aba2381776e 100644 --- a/sot/source/base/exchange.cxx +++ b/sot/source/base/exchange.cxx @@ -202,6 +202,7 @@ namespace /*138 SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE*/ { MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII, "Math 8 Template", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) }, /*139 SOT_FORMATSTR_ID_STARBASE_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII, "StarBase 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) }, /*140 SOT_FORMAT_GDIMETAFILE*/ { "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"", "High Contrast GDIMetaFile", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) }, + /*141 SOT_FORMATSTR_ID_PNG*/ { "image/png", "Windows Bitmap", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) }, }; return &aInstance[0]; } diff --git a/svtools/source/graphic/graphic.cxx b/svtools/source/graphic/graphic.cxx index a3c17517fb11..bec4e4f1724b 100644 --- a/svtools/source/graphic/graphic.cxx +++ b/svtools/source/graphic/graphic.cxx @@ -21,6 +21,7 @@ #include <vcl/svapp.hxx> #include <com/sun/star/graphic/GraphicType.hpp> #include <com/sun/star/graphic/XGraphicTransformer.hpp> +#include <vcl/dibtools.hxx> #include <vcl/graph.hxx> #include "graphic.hxx" #include <comphelper/servicehelper.hxx> @@ -239,7 +240,8 @@ uno::Sequence< ::sal_Int8 > SAL_CALL Graphic::getDIB( ) throw (uno::RuntimeExce if( mpGraphic && ( mpGraphic->GetType() != GRAPHIC_NONE ) ) { SvMemoryStream aMem; - aMem << mpGraphic->GetBitmapEx().GetBitmap(); + + WriteDIB(mpGraphic->GetBitmapEx().GetBitmap(), aMem, false, true); return ::com::sun::star::uno::Sequence<sal_Int8>( (sal_Int8*) aMem.GetData(), aMem.Tell() ); } else @@ -257,7 +259,8 @@ uno::Sequence< ::sal_Int8 > SAL_CALL Graphic::getMaskDIB( ) throw (uno::Runtime if( mpGraphic && ( mpGraphic->GetType() != GRAPHIC_NONE ) ) { SvMemoryStream aMem; - aMem << mpGraphic->GetBitmapEx().GetMask(); + + WriteDIB(mpGraphic->GetBitmapEx().GetMask(), aMem, false, true); return ::com::sun::star::uno::Sequence<sal_Int8>( (sal_Int8*) aMem.GetData(), aMem.Tell() ); } else diff --git a/svtools/source/graphic/provider.cxx b/svtools/source/graphic/provider.cxx index 18a68f9fe36e..9bc54b915211 100644 --- a/svtools/source/graphic/provider.cxx +++ b/svtools/source/graphic/provider.cxx @@ -39,6 +39,7 @@ #include "graphic.hxx" #include <svtools/grfmgr.hxx> #include "provider.hxx" +#include <vcl/dibtools.hxx> using namespace com::sun::star; @@ -244,15 +245,16 @@ uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadBitmap( const uno uno::Sequence< sal_Int8 > aMaskSeq( xBtm->getMaskDIB() ); SvMemoryStream aBmpStream( aBmpSeq.getArray(), aBmpSeq.getLength(), STREAM_READ ); Bitmap aBmp; - aBmpStream >> aBmp; - BitmapEx aBmpEx; + ReadDIB(aBmp, aBmpStream, true); + if( aMaskSeq.getLength() ) { SvMemoryStream aMaskStream( aMaskSeq.getArray(), aMaskSeq.getLength(), STREAM_READ ); Bitmap aMask; - aMaskStream >> aMask; + + ReadDIB(aMask, aMaskStream, true); aBmpEx = BitmapEx( aBmp, aMask ); } else diff --git a/svtools/source/misc/transfer.cxx b/svtools/source/misc/transfer.cxx index c1806c4fd1cf..8407e1926d9b 100644 --- a/svtools/source/misc/transfer.cxx +++ b/svtools/source/misc/transfer.cxx @@ -55,6 +55,9 @@ #include <svtools/transfer.hxx> #include <rtl/strbuf.hxx> #include <cstdio> +#include <vcl/dibtools.hxx> +#include <vcl/pngread.hxx> +#include <vcl/pngwrite.hxx> // -------------- // - Namespaces - @@ -358,9 +361,9 @@ Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor ) th GetData( aSubstFlavor ); bDone = maAny.hasValue(); } - else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) && - TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) && - SotExchange::GetFormatDataFlavor( FORMAT_BITMAP, aSubstFlavor ) ) + else if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_BMP, aSubstFlavor ) + && TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) + && SotExchange::GetFormatDataFlavor(FORMAT_BITMAP, aSubstFlavor)) { GetData( aSubstFlavor ); bDone = sal_True; @@ -672,6 +675,7 @@ void TransferableHelper::AddFormat( const DataFlavor& rFlavor ) if( FORMAT_BITMAP == aFlavorEx.mnSotId ) { AddFormat( SOT_FORMATSTR_ID_BMP ); + AddFormat( SOT_FORMATSTR_ID_PNG ); } else if( FORMAT_GDIMETAFILE == aFlavorEx.mnSotId ) { @@ -765,13 +769,37 @@ sal_Bool TransferableHelper::SetString( const OUString& rString, const DataFlavo // ----------------------------------------------------------------------------- -sal_Bool TransferableHelper::SetBitmap( const Bitmap& rBitmap, const DataFlavor& ) +sal_Bool TransferableHelper::SetBitmapEx( const BitmapEx& rBitmapEx, const DataFlavor& rFlavor ) { - if( !rBitmap.IsEmpty() ) + if( !rBitmapEx.IsEmpty() ) { SvMemoryStream aMemStm( 65535, 65535 ); - aMemStm << rBitmap; + if(rFlavor.MimeType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("image/png"))) + { + // write a PNG + ::vcl::PNGWriter aPNGWriter(rBitmapEx); + + aPNGWriter.Write(aMemStm); + } + else + { + const Bitmap aBitmap(rBitmapEx.GetBitmap()); + + if(rBitmapEx.IsTransparent()) + { + const Bitmap aMask(rBitmapEx.GetAlpha().GetBitmap()); + + // explicitely use Bitmap::Write with bCompressed = sal_False and bFileHeader = sal_True + WriteDIBV5(aBitmap, aMask, aMemStm); + } + else + { + // explicitely use Bitmap::Write with bCompressed = sal_False and bFileHeader = sal_True + WriteDIB(aBitmap, aMemStm, false, true); + } + } + maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ); } @@ -1358,7 +1386,7 @@ void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor rDataFlavorExVector.push_back( aFlavorEx ); // add additional formats for special mime types - if( SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId ) + if(SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_PNG == aFlavorEx.mnSotId) { if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) ) { @@ -1663,24 +1691,74 @@ sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, OUString& // ----------------------------------------------------------------------------- -sal_Bool TransferableDataHelper::GetBitmap( SotFormatStringId nFormat, Bitmap& rBmp ) +sal_Bool TransferableDataHelper::GetBitmapEx( SotFormatStringId nFormat, BitmapEx& rBmpEx ) { + if(FORMAT_BITMAP == nFormat) + { + // try to get PNG first + DataFlavor aFlavor; + + if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor)) + { + if(GetBitmapEx(aFlavor, rBmpEx)) + { + return true; + } + } + } + DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmap( aFlavor, rBmp ) ); + return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmapEx( aFlavor, rBmpEx ) ); } // ----------------------------------------------------------------------------- -sal_Bool TransferableDataHelper::GetBitmap( const DataFlavor& rFlavor, Bitmap& rBmp ) +sal_Bool TransferableDataHelper::GetBitmapEx( const DataFlavor& rFlavor, BitmapEx& rBmpEx ) { SotStorageStreamRef xStm; - DataFlavor aSubstFlavor; - sal_Bool bRet = GetSotStorageStream( rFlavor, xStm ); + DataFlavor aSubstFlavor; + bool bRet(GetSotStorageStream(rFlavor, xStm)); - if( bRet ) + if(!bRet && HasFormat(SOT_FORMATSTR_ID_PNG) && SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aSubstFlavor)) { - *xStm >> rBmp; - bRet = ( xStm->GetError() == ERRCODE_NONE ); + // when no direct success, try if PNG is available + bRet = GetSotStorageStream(aSubstFlavor, xStm); + } + + if(!bRet && HasFormat(SOT_FORMATSTR_ID_BMP) && SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_BMP, aSubstFlavor)) + { + // when no direct success, try if BMP is available + bRet = GetSotStorageStream(aSubstFlavor, xStm); + } + + if(bRet) + { + if(rFlavor.MimeType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("image/png"))) + { + // it's a PNG, import to BitmapEx + ::vcl::PNGReader aPNGReader(*xStm); + + rBmpEx = aPNGReader.Read(); + } + else + { + Bitmap aBitmap; + Bitmap aMask; + + // explicitely use Bitmap::Read with bFileHeader = sal_True + ReadDIBV5(aBitmap, aMask, *xStm); + + if(aMask.IsEmpty()) + { + rBmpEx = aBitmap; + } + else + { + rBmpEx = BitmapEx(aBitmap, aMask); + } + } + + bRet = (ERRCODE_NONE == xStm->GetError()); /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The problem is, that some graphics are inserted much too big because the nXPelsPerMeter @@ -1691,28 +1769,22 @@ sal_Bool TransferableDataHelper::GetBitmap( const DataFlavor& rFlavor, Bitmap& r The following code should be removed if DDBs and DIBs are supported via clipboard properly. */ - if ( bRet ) + if(bRet) { - MapMode aMapMode = rBmp.GetPrefMapMode(); - if ( aMapMode.GetMapUnit() != MAP_PIXEL ) + const MapMode aMapMode(rBmpEx.GetPrefMapMode()); + + if(MAP_PIXEL != aMapMode.GetMapUnit()) { - Size aSize = OutputDevice::LogicToLogic( rBmp.GetPrefSize(), aMapMode, MAP_100TH_MM ); - if ( ( aSize.Width() > 5000 ) || ( aSize.Height() > 5000 ) ) - rBmp.SetPrefMapMode( MAP_PIXEL ); + const Size aSize(OutputDevice::LogicToLogic(rBmpEx.GetPrefSize(), aMapMode, MAP_100TH_MM)); + + if((aSize.Width() > 5000) || (aSize.Height() > 5000)) + { + rBmpEx.SetPrefMapMode(MAP_PIXEL); + } } } } - if( !bRet && - HasFormat( SOT_FORMATSTR_ID_BMP ) && - SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) && - GetSotStorageStream( aSubstFlavor, xStm ) ) - { - xStm->ResetError(); - *xStm >> rBmp; - bRet = ( xStm->GetError() == ERRCODE_NONE ); - } - return bRet; } @@ -1773,6 +1845,20 @@ sal_Bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIM sal_Bool TransferableDataHelper::GetGraphic( SotFormatStringId nFormat, Graphic& rGraphic ) { + if(FORMAT_BITMAP == nFormat) + { + // try to get PNG first + DataFlavor aFlavor; + + if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor)) + { + if(GetGraphic(aFlavor, rGraphic)) + { + return true; + } + } + } + DataFlavor aFlavor; return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) ); } @@ -1784,13 +1870,22 @@ sal_Bool TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfe DataFlavor aFlavor; sal_Bool bRet = sal_False; - if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) && + if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor) && + TransferableDataHelper::IsEqual(aFlavor, rFlavor)) + { + // try to get PNG first + BitmapEx aBmpEx; + + if( ( bRet = GetBitmapEx( aFlavor, aBmpEx ) ) == sal_True ) + rGraphic = aBmpEx; + } + else if(SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) && TransferableDataHelper::IsEqual( aFlavor, rFlavor ) ) { - Bitmap aBmp; + BitmapEx aBmpEx; - if( ( bRet = GetBitmap( aFlavor, aBmp ) ) == sal_True ) - rGraphic = aBmp; + if( ( bRet = GetBitmapEx( aFlavor, aBmpEx ) ) == sal_True ) + rGraphic = aBmpEx; } else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavor ) && TransferableDataHelper::IsEqual( aFlavor, rFlavor ) ) diff --git a/svx/source/gallery2/galmisc.cxx b/svx/source/gallery2/galmisc.cxx index 499ab340d238..06c8d158af6c 100644 --- a/svx/source/gallery2/galmisc.cxx +++ b/svx/source/gallery2/galmisc.cxx @@ -590,7 +590,7 @@ sal_Bool GalleryTransferable::GetData( const datatransfer::DataFlavor& rFlavor ) } else if( ( FORMAT_BITMAP == nFormat ) && mpGraphicObject ) { - bRet = SetBitmap( mpGraphicObject->GetGraphic().GetBitmap(), rFlavor ); + bRet = SetBitmapEx( mpGraphicObject->GetGraphic().GetBitmapEx(), rFlavor ); } return bRet; diff --git a/svx/source/gallery2/galobj.cxx b/svx/source/gallery2/galobj.cxx index 573dcf6875cb..eb1b6e4e701d 100644 --- a/svx/source/gallery2/galobj.cxx +++ b/svx/source/gallery2/galobj.cxx @@ -21,11 +21,9 @@ #include <com/sun/star/lang/XUnoTunnel.hpp> #include <sfx2/objsh.hxx> #include <sfx2/docfac.hxx> - #include <comphelper/classids.hxx> #include <comphelper/string.hxx> #include <unotools/pathoptions.hxx> - #include <tools/rcid.h> #include <tools/vcompat.hxx> #include <tools/helpers.hxx> @@ -38,7 +36,7 @@ #include "svx/galmisc.hxx" #include "galobj.hxx" #include <vcl/svapp.hxx> - +#include <vcl/dibtools.hxx> #include "gallerydrawmodel.hxx" using namespace ::com::sun::star; @@ -150,7 +148,7 @@ void SgaObject::WriteData( SvStream& rOut, const String& rDestDir ) const rOut.SetCompressMode( COMPRESSMODE_ZBITMAP ); rOut.SetVersion( SOFFICE_FILEFORMAT_50 ); - rOut << aThumbBmp; + WriteDIBBitmapEx(aThumbBmp, rOut); rOut.SetVersion( nOldVersion ); rOut.SetCompressMode( nOldCompressMode ); @@ -173,9 +171,13 @@ void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion ) rIn >> nTmp32 >> nTmp16 >> rReadVersion >> nTmp16 >> bIsThumbBmp; if( bIsThumbBmp ) - rIn >> aThumbBmp; + { + ReadDIBBitmapEx(aThumbBmp, rIn); + } else + { rIn >> aThumbMtf; + } OUString aTmpStr = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIn, RTL_TEXTENCODING_UTF8); aURL = INetURLObject(aTmpStr); diff --git a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx index 47d76f835d00..d502094d55fb 100644 --- a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx +++ b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx @@ -26,6 +26,7 @@ #include <tools/stream.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <vcl/cursor.hxx> +#include <vcl/dibtools.hxx> ////////////////////////////////////////////////////////////////////////////// diff --git a/svx/source/xoutdev/_xoutbmp.cxx b/svx/source/xoutdev/_xoutbmp.cxx index 33e36ee0fd10..535d6b3299dc 100644 --- a/svx/source/xoutdev/_xoutbmp.cxx +++ b/svx/source/xoutdev/_xoutbmp.cxx @@ -17,7 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <sot/factory.hxx> #include <tools/poly.hxx> #include <vcl/bmpacc.hxx> @@ -27,6 +26,7 @@ #include <sfx2/docfile.hxx> #include <sfx2/app.hxx> #include "svx/xoutbmp.hxx" +#include <vcl/dibtools.hxx> #include <vcl/FilterConfigItem.hxx> #include <vcl/graphicfilter.hxx> @@ -363,8 +363,8 @@ Bitmap XOutBitmap::DetectEdges( const Bitmap& rBmp, const sal_uInt8 cThreshold ) const long nHeight = aSize.Height(); const long nHeight2 = nHeight - 2L; const long lThres2 = (long) cThreshold * cThreshold; - const sal_uInt8 nWhitePalIdx = pWriteAcc->GetBestPaletteIndex( Color( COL_WHITE ) ); - const sal_uInt8 nBlackPalIdx = pWriteAcc->GetBestPaletteIndex( Color( COL_BLACK ) ); + const sal_uInt8 nWhitePalIdx(static_cast< sal_uInt8 >(pWriteAcc->GetBestPaletteIndex(Color(COL_WHITE)))); + const sal_uInt8 nBlackPalIdx(static_cast< sal_uInt8 >(pWriteAcc->GetBestPaletteIndex(Color(COL_BLACK)))); long nSum1; long nSum2; long lGray; diff --git a/svx/source/xoutdev/xattrbmp.cxx b/svx/source/xoutdev/xattrbmp.cxx index 85255918e682..462bae6b5036 100644 --- a/svx/source/xoutdev/xattrbmp.cxx +++ b/svx/source/xoutdev/xattrbmp.cxx @@ -38,6 +38,7 @@ #include <com/sun/star/beans/PropertyValue.hpp> #include <vcl/salbtype.hxx> #include <vcl/bmpacc.hxx> +#include <vcl/dibtools.hxx> using namespace ::com::sun::star; @@ -357,7 +358,7 @@ XFillBitmapItem::XFillBitmapItem(SvStream& rIn, sal_uInt16 nVer) // Behandlung der alten Bitmaps Bitmap aBmp; - rIn >> aBmp; + ReadDIB(aBmp, rIn, true); maGraphicObject = Graphic(aBmp); } else if(1 == nVer) @@ -371,7 +372,7 @@ XFillBitmapItem::XFillBitmapItem(SvStream& rIn, sal_uInt16 nVer) { Bitmap aBmp; - rIn >> aBmp; + ReadDIB(aBmp, rIn, true); maGraphicObject = Graphic(aBmp); } else if(XBITMAP_8X8 == iTmp) @@ -398,7 +399,7 @@ XFillBitmapItem::XFillBitmapItem(SvStream& rIn, sal_uInt16 nVer) { BitmapEx aBmpEx; - rIn >> aBmpEx; + ReadDIBBitmapEx(aBmpEx, rIn); maGraphicObject = Graphic(aBmpEx); } } @@ -442,7 +443,7 @@ SvStream& XFillBitmapItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) cons if(!IsIndex()) { - rOut << maGraphicObject.GetGraphic().GetBitmapEx(); + WriteDIBBitmapEx(maGraphicObject.GetGraphic().GetBitmapEx(), rOut); } return rOut; diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index 6dabfbcd3319..5a26af271635 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -18,7 +18,6 @@ */ #include <com/sun/star/accessibility/XAccessible.hpp> - #include <sfx2/viewfrm.hxx> #include <sfx2/progress.hxx> #include <svx/srchdlg.hxx> @@ -61,10 +60,9 @@ #include "../../ui/inc/view.hxx" #include <PostItMgr.hxx> +#include <vcl/dibtools.hxx> #include <vcl/virdev.hxx> - #include <vcl/svapp.hxx> - #include <svx/sdrpaintwindow.hxx> sal_Bool ViewShell::mbLstAct = sal_False; diff --git a/sw/source/filter/ww1/w1filter.cxx b/sw/source/filter/ww1/w1filter.cxx index c2483488e24c..ce1c7d0fa5fc 100644 --- a/sw/source/filter/ww1/w1filter.cxx +++ b/sw/source/filter/ww1/w1filter.cxx @@ -18,7 +18,6 @@ */ #include <hintids.hxx> - #include <tools/solar.h> #include <comphelper/string.hxx> #include <editeng/paperinf.hxx> @@ -54,17 +53,14 @@ #include <section.hxx> // class SwSection #include <fltini.hxx> #include <w1par.hxx> - #include <docsh.hxx> #include <swerror.h> #include <mdiexp.hxx> #include <statstr.hrc> -#if OSL_DEBUG_LEVEL > 0 #include <stdio.h> -#endif - #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> +#include <vcl/dibtools.hxx> #define MAX_FIELDLEN 64000 @@ -1909,7 +1905,7 @@ void Ww1Picture::Out(Ww1Shell& rOut, Ww1Manager& /*rMan*/) SvMemoryStream aOut(nSiz, 8192); WriteBmp(aOut); Bitmap aBmp; - aOut >> aBmp; + ReadDIB(aBmp, aOut, true); pGraphic = new Graphic(aBmp); } default: diff --git a/sw/source/ui/dochdl/swdtflvr.cxx b/sw/source/ui/dochdl/swdtflvr.cxx index 31e0fa69f8ce..03efaa1bc0bb 100644 --- a/sw/source/ui/dochdl/swdtflvr.cxx +++ b/sw/source/ui/dochdl/swdtflvr.cxx @@ -549,11 +549,10 @@ sal_Bool SwTransferable::GetData( const DataFlavor& rFlavor ) bOK = SetGDIMetaFile( pClpGraphic->GetGDIMetaFile(), rFlavor ); break; case SOT_FORMAT_BITMAP: + case SOT_FORMATSTR_ID_PNG: // Neither pClpBitmap nor pClpGraphic are necessarily set if( (eBufferType & TRNSFR_GRAPHIC) && (pClpBitmap != 0 || pClpGraphic != 0)) - bOK = SetBitmap( (pClpBitmap ? pClpBitmap - : pClpGraphic)->GetBitmap(), - rFlavor ); + bOK = SetBitmapEx( (pClpBitmap ? pClpBitmap : pClpGraphic)->GetBitmapEx(), rFlavor ); break; case SOT_FORMATSTR_ID_SVIM: @@ -800,6 +799,7 @@ int SwTransferable::PrepareForCopy( sal_Bool bIsCut ) if( pGrf && pGrf->IsSupportedGraphic() ) { AddFormat( FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMATSTR_ID_PNG ); AddFormat( FORMAT_BITMAP ); } eBufferType = TRNSFR_GRAPHIC; @@ -905,6 +905,7 @@ int SwTransferable::PrepareForCopy( sal_Bool bIsCut ) if ( nSelection & nsSelectionType::SEL_DRW ) { AddFormat( FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMATSTR_ID_PNG ); AddFormat( FORMAT_BITMAP ); } eBufferType = (TransferBufferType)( TRNSFR_GRAPHIC | eBufferType ); @@ -2889,6 +2890,7 @@ void SwTransferable::SetDataForDragAndDrop( const Point& rSttPos ) if ( pGrf && pGrf->IsSupportedGraphic() ) { AddFormat( FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMATSTR_ID_PNG ); AddFormat( FORMAT_BITMAP ); } eBufferType = TRNSFR_GRAPHIC; @@ -2937,6 +2939,7 @@ void SwTransferable::SetDataForDragAndDrop( const Point& rSttPos ) if ( nSelection & nsSelectionType::SEL_DRW ) { AddFormat( FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMATSTR_ID_PNG ); AddFormat( FORMAT_BITMAP ); } eBufferType = (TransferBufferType)( TRNSFR_GRAPHIC | eBufferType ); diff --git a/toolkit/source/awt/vclxbitmap.cxx b/toolkit/source/awt/vclxbitmap.cxx index fd9b5aea22a8..7047f123ff9b 100644 --- a/toolkit/source/awt/vclxbitmap.cxx +++ b/toolkit/source/awt/vclxbitmap.cxx @@ -22,6 +22,7 @@ #include <cppuhelper/typeprovider.hxx> #include <tools/stream.hxx> #include <rtl/uuid.h> +#include <vcl/dibtools.hxx> // ---------------------------------------------------- // class VCLXBitmap @@ -62,7 +63,7 @@ IMPL_XTYPEPROVIDER_END ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); SvMemoryStream aMem; - aMem << maBitmap.GetBitmap(); + WriteDIB(maBitmap.GetBitmap(), aMem, false, true); return ::com::sun::star::uno::Sequence<sal_Int8>( (sal_Int8*) aMem.GetData(), aMem.Tell() ); } @@ -71,11 +72,8 @@ IMPL_XTYPEPROVIDER_END ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); SvMemoryStream aMem; - aMem << maBitmap.GetMask(); + WriteDIB(maBitmap.GetMask(), aMem, false, true); return ::com::sun::star::uno::Sequence<sal_Int8>( (sal_Int8*) aMem.GetData(), aMem.Tell() ); } - - - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/helper/vclunohelper.cxx b/toolkit/source/helper/vclunohelper.cxx index 3d275c1593b5..5767b27fe185 100644 --- a/toolkit/source/helper/vclunohelper.cxx +++ b/toolkit/source/helper/vclunohelper.cxx @@ -17,7 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <tools/stream.hxx> #include <vcl/bitmap.hxx> #include <vcl/window.hxx> @@ -36,9 +35,7 @@ #include <com/sun/star/awt/MouseButton.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/embed/EmbedMapUnits.hpp> - #include <com/sun/star/graphic/XGraphic.hpp> - #include <toolkit/helper/vclunohelper.hxx> #include <toolkit/helper/convert.hxx> #include <toolkit/awt/vclxbitmap.hxx> @@ -49,13 +46,13 @@ #include <toolkit/awt/vclxfont.hxx> #include <toolkit/controls/unocontrolcontainer.hxx> #include <toolkit/controls/unocontrolcontainermodel.hxx> - #include <vcl/graph.hxx> #include <comphelper/processfactory.hxx> #include <com/sun/star/awt/Toolkit.hpp> #include <com/sun/star/awt/Size.hpp> #include <com/sun/star/awt/Point.hpp> +#include <vcl/dibtools.hxx> using namespace ::com::sun::star; @@ -91,12 +88,12 @@ BitmapEx VCLUnoHelper::GetBitmap( const ::com::sun::star::uno::Reference< ::com: { ::com::sun::star::uno::Sequence<sal_Int8> aBytes = rxBitmap->getDIB(); SvMemoryStream aMem( (char*) aBytes.getArray(), aBytes.getLength(), STREAM_READ ); - aMem >> aDIB; + ReadDIB(aDIB, aMem, true); } { ::com::sun::star::uno::Sequence<sal_Int8> aBytes = rxBitmap->getMaskDIB(); SvMemoryStream aMem( (char*) aBytes.getArray(), aBytes.getLength(), STREAM_READ ); - aMem >> aMask; + ReadDIB(aMask, aMem, true); } aBmp = BitmapEx( aDIB, aMask ); } diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 45bdcfd82550..79d5326efb3f 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -189,7 +189,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/gdi/alpha \ vcl/source/gdi/animate \ vcl/source/gdi/base14 \ - vcl/source/gdi/bitmap2 \ vcl/source/gdi/bitmap3 \ vcl/source/gdi/bitmap4 \ vcl/source/gdi/bitmap \ @@ -202,6 +201,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/gdi/configsettings \ vcl/source/gdi/cvtgrf \ vcl/source/gdi/cvtsvm \ + vcl/source/gdi/dibtools \ vcl/source/gdi/embeddedfontshelper \ vcl/source/gdi/extoutdevdata \ vcl/source/gdi/font \ diff --git a/vcl/aqua/source/dtrans/DataFlavorMapping.cxx b/vcl/aqua/source/dtrans/DataFlavorMapping.cxx index d61d09bfe1b2..6381e4d83c63 100644 --- a/vcl/aqua/source/dtrans/DataFlavorMapping.cxx +++ b/vcl/aqua/source/dtrans/DataFlavorMapping.cxx @@ -124,8 +124,8 @@ namespace // private { { NSStringPboardType, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", true }, { NSRTFPboardType, "text/richtext", "Rich Text Format", false }, - { NSTIFFPboardType, "image/bmp", "Windows Bitmap", false }, - { NSPICTPboardType, "image/bmp", "Windows Bitmap", false }, + { NSTIFFPboardType, "image/png", "Portable Network Graphics", false }, + { NSPICTPboardType, "image/png", "Portable Network Graphics", false }, { NSHTMLPboardType, "text/html", "Plain Html", false }, { NSFilenamesPboardType, "application/x-openoffice-filelist;windows_formatname=\"FileList\"", "FileList", false }, { PBTYPE_SESX, FLAVOR_SESX, "Star Embed Source (XML)", false }, @@ -370,73 +370,65 @@ Any HTMLFormatDataProvider::getOOoData() //########################### -class BMPDataProvider : public DataProviderBaseImpl +class PNGDataProvider : public DataProviderBaseImpl { NSBitmapImageFileType meImageType; public: - BMPDataProvider(const Any& data, NSBitmapImageFileType eImageType ); + PNGDataProvider( const Any&, NSBitmapImageFileType); - BMPDataProvider(NSData* data, NSBitmapImageFileType eImageType); + PNGDataProvider( NSData*, NSBitmapImageFileType); - virtual NSData* getSystemData(); + virtual NSData* getSystemData(); - virtual Any getOOoData(); + virtual Any getOOoData(); }; -BMPDataProvider::BMPDataProvider(const Any& data, NSBitmapImageFileType eImageType) : +PNGDataProvider::PNGDataProvider( const Any& data, NSBitmapImageFileType eImageType) : DataProviderBaseImpl(data), meImageType( eImageType ) { } -BMPDataProvider::BMPDataProvider(NSData* data, NSBitmapImageFileType eImageType) : +PNGDataProvider::PNGDataProvider( NSData* data, NSBitmapImageFileType eImageType) : DataProviderBaseImpl(data), meImageType( eImageType ) { } -NSData* BMPDataProvider::getSystemData() +NSData* PNGDataProvider::getSystemData() { - Sequence<sal_Int8> bmpData; - mData >>= bmpData; + Sequence<sal_Int8> pngData; + mData >>= pngData; - Sequence<sal_Int8> pictData; - NSData* sysData = NULL; - - if (BMPToImage(bmpData, pictData, meImageType)) - { - sysData = [NSData dataWithBytes: pictData.getArray() length: pictData.getLength()]; - } + Sequence<sal_Int8> imgData; + NSData* sysData = NULL; + if( PNGToImage( pngData, imgData, meImageType)) + sysData = [NSData dataWithBytes: imgData.getArray() length: imgData.getLength()]; - return sysData; + return sysData; } -/* At the moment the OOo 'PCT' filter is not good enough to be used - and there is no flavor defined for exchanging 'PCT' with OOo so - we will at the moment convert 'PCT' to a Windows BMP and provide - this to OOo +/* The AOO 'PCT' filter is not yet good enough to be used + and there is no flavor defined for exchanging 'PCT' with AOO + so we convert 'PCT' to a PNG and provide this to AOO */ -Any BMPDataProvider::getOOoData() +Any PNGDataProvider::getOOoData() { - Any oOOData; + Any oOOData; - if (mSystemData) + if( mSystemData) { - unsigned int flavorDataLength = [mSystemData length]; - Sequence<sal_Int8> pictData(flavorDataLength); + const unsigned int flavorDataLength = [mSystemData length]; + Sequence<sal_Int8> imgData( flavorDataLength); + memcpy( imgData.getArray(), [mSystemData bytes], flavorDataLength); - memcpy(pictData.getArray(), [mSystemData bytes], flavorDataLength); - - Sequence<sal_Int8> bmpData; - - if (ImageToBMP(pictData, bmpData, meImageType)) - { - oOOData = makeAny(bmpData); - } + Sequence<sal_Int8> pngData; + if( ImageToPNG( imgData, pngData, meImageType)) + oOOData = makeAny( pngData); } - else + else { - oOOData = mData; + oOOData = mData; } return oOOData; @@ -612,11 +604,11 @@ DataProviderPtr_t DataFlavorMapper::getDataProvider(NSString* systemFlavor, Refe */ if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) { - dp = DataProviderPtr_t(new BMPDataProvider(data, PICTImageFileType)); + dp = DataProviderPtr_t( new PNGDataProvider( data, PICTImageFileType)); } else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame) { - dp = DataProviderPtr_t(new BMPDataProvider(data, NSTIFFFileType)); + dp = DataProviderPtr_t( new PNGDataProvider( data, NSTIFFFileType)); } else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) { @@ -663,11 +655,11 @@ DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor } else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) { - dp = DataProviderPtr_t(new BMPDataProvider(systemData, PICTImageFileType)); + dp = DataProviderPtr_t( new PNGDataProvider(systemData, PICTImageFileType)); } else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame) { - dp = DataProviderPtr_t(new BMPDataProvider(systemData, NSTIFFFileType)); + dp = DataProviderPtr_t( new PNGDataProvider(systemData, NSTIFFFileType)); } else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) { diff --git a/vcl/aqua/source/dtrans/OSXTransferable.cxx b/vcl/aqua/source/dtrans/OSXTransferable.cxx index c71bfc452b01..89e5c304c598 100644 --- a/vcl/aqua/source/dtrans/OSXTransferable.cxx +++ b/vcl/aqua/source/dtrans/OSXTransferable.cxx @@ -74,7 +74,7 @@ Any SAL_CALL OSXTransferable::getTransferData( const DataFlavor& aFlavor ) } NSString* sysFormat = - (aFlavor.MimeType.startsWith("image/bmp")) + (aFlavor.MimeType.startsWith("image/png")) ? mDataFlavorMapper->openOfficeImageToSystemFlavor( mPasteboard ) : mDataFlavorMapper->openOfficeToSystemFlavor(aFlavor); DataProviderPtr_t dp; diff --git a/vcl/aqua/source/dtrans/PictToBmpFlt.cxx b/vcl/aqua/source/dtrans/PictToBmpFlt.cxx index 0bbb33ba51a3..61cb721bed2c 100644 --- a/vcl/aqua/source/dtrans/PictToBmpFlt.cxx +++ b/vcl/aqua/source/dtrans/PictToBmpFlt.cxx @@ -33,58 +33,49 @@ #include "PictToBmpFlt.hxx" -bool PICTtoBMP(com::sun::star::uno::Sequence<sal_Int8>& aPict, - com::sun::star::uno::Sequence<sal_Int8>& aBmp) +bool PICTtoPNG( com::sun::star::uno::Sequence<sal_Int8>& rPictData, + com::sun::star::uno::Sequence<sal_Int8>& rPngData) { - - bool result = false; - #ifdef __LP64__ - // FIXME - (void) aPict; - (void) aBmp; + // FIXME + (void) rPictData; + (void) rPngData; + return false; #else - ComponentInstance bmpExporter; - if (OpenADefaultComponent(GraphicsExporterComponentType, - kQTFileTypeBMP, - &bmpExporter) != noErr) - { - return result; - } - - Handle hPict; - if (PtrToHand(aPict.getArray(), &hPict, aPict.getLength()) != noErr) + ComponentInstance pngExporter = NULL; + if( OpenADefaultComponent( GraphicsExporterComponentType, kQTFileTypePNG, &pngExporter) != noErr) + return false; + + Handle hPict = NULL; + if( PtrToHand( rPictData.getArray(), &hPict, rPictData.getLength()) != noErr) + hPict = NULL; + + Handle hPng = NULL; + if( hPict && GraphicsExportSetInputPicture( pngExporter, (PicHandle)hPict) == noErr) + hPng = NewHandleClear(0); + + size_t nPngSize = 0; + if( hPng + && (GraphicsExportSetOutputHandle( pngExporter, hPng) == noErr) + && (GraphicsExportDoExport( pngExporter, NULL) == noErr)) { - return result; - } + nPngSize = GetHandleSize( hPng); + rPngData.realloc( nPngSize); - Handle hBmp; - if ((GraphicsExportSetInputPicture(bmpExporter, (PicHandle)hPict) != noErr) || - ((hBmp = NewHandleClear(0)) == NULL)) - { - CloseComponent(bmpExporter); - DisposeHandle(hPict); - return result; + HLock( hPng); + rtl_copyMemory( rPngData.getArray(), ((sal_Int8*)*hPng), nPngSize); + HUnlock( hPng); } - if ((GraphicsExportSetOutputHandle(bmpExporter, hBmp) == noErr) && - (GraphicsExportDoExport(bmpExporter, NULL) == noErr)) - { - size_t sz = GetHandleSize(hBmp); - aBmp.realloc(sz); - - HLock(hBmp); - memcpy(aBmp.getArray(), ((sal_Int8*)*hBmp), sz); - HUnlock(hBmp); - - result = true; - } + if( hPict) + DisposeHandle( hPict); + if( hPng) + DisposeHandle( hPng); + if( pngExporter) + CloseComponent( pngExporter); - DisposeHandle(hPict); - DisposeHandle(hBmp); - CloseComponent(bmpExporter); + return (nPngSize > 0); #endif - return result; } #if MACOSX_SDK_VERSION >= 1070 @@ -102,118 +93,99 @@ extern void KillPicture(PicHandle myPicture); #endif -bool BMPtoPICT(com::sun::star::uno::Sequence<sal_Int8>& aBmp, - com::sun::star::uno::Sequence<sal_Int8>& aPict) +bool PNGtoPICT( com::sun::star::uno::Sequence<sal_Int8>& rPngData, + com::sun::star::uno::Sequence<sal_Int8>& rPictData) { - bool result = false; - - Handle hBmp; - if ((PtrToHand(aBmp.getArray(), &hBmp, aBmp.getLength()) != noErr)) - { - return result; - } - #ifdef __LP64__ - // FIXME - (void) aPict; + // FIXME + (void) rPngData; + (void) rPictData; + return false; #else - ComponentInstance pictExporter; - - if (OpenADefaultComponent(GraphicsImporterComponentType, - kQTFileTypeBMP, - &pictExporter) != noErr) + ComponentInstance pictExporter; + if( OpenADefaultComponent( GraphicsImporterComponentType, kQTFileTypePNG, &pictExporter) != noErr) + return false; + + Handle hPng = NULL; + if( PtrToHand( rPngData.getArray(), &hPng, rPngData.getLength()) != noErr) + hPng = NULL; + + size_t nPictSize = 0; + PicHandle hPict = NULL; + if( hPng + && (GraphicsImportSetDataHandle( pictExporter, hPng) == noErr) + && (GraphicsImportGetAsPicture( pictExporter, &hPict) == noErr)) { - DisposeHandle(hBmp); - return result; - } - - if (GraphicsImportSetDataHandle(pictExporter, hBmp) != noErr) - { - DisposeHandle(hBmp); - CloseComponent(pictExporter); - return result; - } - - PicHandle hPict; - if (GraphicsImportGetAsPicture(pictExporter, &hPict) == noErr) - { - size_t sz = GetHandleSize((Handle)hPict); - aPict.realloc(sz); - - HLock((Handle)hPict); - memcpy(aPict.getArray(), ((sal_Int8*)*hPict), sz); - HUnlock((Handle)hPict); - - // Release the data associated with the picture - // Note: This function is deprecated in Mac OS X - // 10.4. + nPictSize = GetHandleSize( (Handle)hPict); + rPictData.realloc( nPictSize); - KillPicture(hPict); + HLock( (Handle)hPict); + rtl_copyMemory( rPictData.getArray(), ((sal_Int8*)*hPict), nPictSize); + HUnlock( (Handle)hPict); - result = true; + // Release the data associated with the picture + // Note: This function is deprecated in Mac OSX 10.4 + KillPicture( hPict); } - DisposeHandle(hBmp); - CloseComponent(pictExporter); + if( hPng) + DisposeHandle( hPng); + if( pictExporter) + CloseComponent( pictExporter); + + return (nPictSize > 512); #endif - return result; } -bool ImageToBMP( com::sun::star::uno::Sequence<sal_Int8>& aPict, - com::sun::star::uno::Sequence<sal_Int8>& aBmp, +bool ImageToPNG( com::sun::star::uno::Sequence<sal_Int8>& rImgData, + com::sun::star::uno::Sequence<sal_Int8>& rPngData, NSBitmapImageFileType eInFormat) { - if( eInFormat == PICTImageFileType ) - return PICTtoBMP( aPict, aBmp ); + if( eInFormat == PICTImageFileType) + return PICTtoPNG( rImgData, rPngData); - bool bResult = false; + NSData* pData = [NSData dataWithBytesNoCopy: (void*)rImgData.getConstArray() length: rImgData.getLength() freeWhenDone: 0]; + if( !pData) + return false; - NSData* pData = [NSData dataWithBytesNoCopy: (void*)aPict.getConstArray() length: aPict.getLength() freeWhenDone: 0]; - if( pData ) - { - NSBitmapImageRep* pRep = [NSBitmapImageRep imageRepWithData: pData]; - if( pRep ) - { - NSData* pOut = [pRep representationUsingType: NSBMPFileType properties: nil]; - if( pOut ) - { - aBmp.realloc( [pOut length] ); - [pOut getBytes: aBmp.getArray() length: aBmp.getLength()]; - bResult = (aBmp.getLength() != 0); - } - } - } + NSBitmapImageRep* pRep =[NSBitmapImageRep imageRepWithData: pData]; + if( !pRep) + return false; - return bResult; + NSData* pOut = [pRep representationUsingType: NSPNGFileType properties: nil]; + if( !pOut) + return false; + + const size_t nPngSize = [pOut length]; + rPngData.realloc( nPngSize); + [pOut getBytes: rPngData.getArray() length: nPngSize]; + return (nPngSize > 0); } -bool BMPToImage( com::sun::star::uno::Sequence<sal_Int8>& aBmp, - com::sun::star::uno::Sequence<sal_Int8>& aPict, +bool PNGToImage( com::sun::star::uno::Sequence<sal_Int8>& rPngData, + com::sun::star::uno::Sequence<sal_Int8>& rImgData, NSBitmapImageFileType eOutFormat ) { - if( eOutFormat == PICTImageFileType ) - return BMPtoPICT( aBmp, aPict ); + if( eOutFormat == PICTImageFileType) + return PNGtoPICT( rPngData, rImgData); - bool bResult = false; + NSData* pData = [NSData dataWithBytesNoCopy: const_cast<sal_Int8*>(rPngData.getConstArray()) length: rPngData.getLength() freeWhenDone: 0]; + if( !pData) + return false; - NSData* pData = [NSData dataWithBytesNoCopy: const_cast<sal_Int8*>(aBmp.getConstArray()) length: aBmp.getLength() freeWhenDone: 0]; - if( pData ) - { NSBitmapImageRep* pRep = [NSBitmapImageRep imageRepWithData: pData]; - if( pRep ) - { - NSData* pOut = [pRep representationUsingType: eOutFormat properties: nil]; - if( pOut ) - { - aPict.realloc( [pOut length] ); - [pOut getBytes: aPict.getArray() length: aPict.getLength()]; - bResult = (aPict.getLength() != 0); - } - } - } + if( !pRep) + return false; + + NSData* pOut = [pRep representationUsingType: eOutFormat properties: nil]; + if( !pOut) + return false; - return bResult; + const size_t nImgSize = [pOut length]; + rImgData.realloc( nImgSize); + [pOut getBytes: rImgData.getArray() length: nImgSize]; + return (nImgSize > 0); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/aqua/source/dtrans/PictToBmpFlt.hxx b/vcl/aqua/source/dtrans/PictToBmpFlt.hxx index 50ee8c4d3108..12f29316c248 100644 --- a/vcl/aqua/source/dtrans/PictToBmpFlt.hxx +++ b/vcl/aqua/source/dtrans/PictToBmpFlt.hxx @@ -26,32 +26,31 @@ #include <Cocoa/Cocoa.h> #include <postmac.h> -/* Transform PICT into the a Window BMP. +/** Transform an image from PICT to PNG format Returns true if the conversion was successful false otherwise. */ -bool PICTtoBMP(com::sun::star::uno::Sequence<sal_Int8>& aPict, - com::sun::star::uno::Sequence<sal_Int8>& aBmp); +bool PICTtoPNG(com::sun::star::uno::Sequence<sal_Int8>& rPictData, + com::sun::star::uno::Sequence<sal_Int8>& rPngData); -/* Transform a Windows BMP to a PICT. +/** Transform an image from PNG to a PICT format Returns true if the conversion was successful false otherwise. */ -bool BMPtoPICT(com::sun::star::uno::Sequence<sal_Int8>& aBmp, - com::sun::star::uno::Sequence<sal_Int8>& aPict); +bool PNGtoPICT(com::sun::star::uno::Sequence<sal_Int8>& rPngData, + com::sun::star::uno::Sequence<sal_Int8>& rPictData); #define PICTImageFileType ((NSBitmapImageFileType)~0) -bool ImageToBMP( com::sun::star::uno::Sequence<sal_Int8>& aPict, - com::sun::star::uno::Sequence<sal_Int8>& aBmp, +bool ImageToPNG( com::sun::star::uno::Sequence<sal_Int8>& rImgData, + com::sun::star::uno::Sequence<sal_Int8>& rPngData, NSBitmapImageFileType eInFormat); -bool BMPToImage( com::sun::star::uno::Sequence<sal_Int8>& aBmp, - com::sun::star::uno::Sequence<sal_Int8>& aPict, - NSBitmapImageFileType eOutFormat - ); +bool PNGToImage( com::sun::star::uno::Sequence<sal_Int8>& rPngData, + com::sun::star::uno::Sequence<sal_Int8>& rImgData, + NSBitmapImageFileType eOutFormat); #endif diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index dafe348b76dd..82287f4703e9 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -23,6 +23,7 @@ #include <ucbhelper/content.hxx> #include <cppuhelper/implbase1.hxx> #include <tools/urlobj.hxx> +#include <vcl/dibtools.hxx> #include <vcl/salctype.hxx> #include <vcl/pngread.hxx> #include <vcl/pngwrite.hxx> @@ -1880,7 +1881,8 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& } sal_Bool bRleCoding = aConfigItem.ReadBool( "RLE_Coding", sal_True ); // save RLE encoded? - aBmp.Write( rOStm, bRleCoding ); + WriteDIB(aBmp, rOStm, bRleCoding, true); + if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; diff --git a/vcl/source/filter/wmf/emfwr.cxx b/vcl/source/filter/wmf/emfwr.cxx index 3adaaf2eeb9e..55af30248806 100644 --- a/vcl/source/filter/wmf/emfwr.cxx +++ b/vcl/source/filter/wmf/emfwr.cxx @@ -23,6 +23,7 @@ #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <vcl/lineinfo.hxx> +#include <vcl/dibtools.hxx> #define WIN_EMR_POLYGON 3 #define WIN_EMR_POLYLINE 4 @@ -841,7 +842,7 @@ void EMFWriter::ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt, m_rStm << (sal_uInt32) 0 << sal_Int32( ( ROP_XOR == maVDev.GetRasterOp() && WIN_SRCCOPY == nROP ) ? WIN_SRCINVERT : nROP ); ImplWriteSize( rSz ); - rBmp.Write( aMemStm, sal_True, sal_False ); + WriteDIB(rBmp, aMemStm, true, false); sal_uInt32 nDIBSize = aMemStm.Tell(), nHeaderSize, nCompression, nColsUsed, nPalCount, nImageSize; sal_uInt16 nBitCount; diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx index c97cfdc53296..11bc047bd70e 100644 --- a/vcl/source/filter/wmf/enhwmf.cxx +++ b/vcl/source/filter/wmf/enhwmf.cxx @@ -22,6 +22,7 @@ #include <osl/endian.h> #include <basegfx/matrix/b2dhommatrix.hxx> #include <boost/bind.hpp> +#include <vcl/dibtools.hxx> using namespace std; @@ -993,7 +994,8 @@ sal_Bool EnhWMFReader::ReadEnhWMF() pWMF->Seek( nStart + offBitsSrc ); pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); aTmp.Seek( 0 ); - aBitmap.Read( aTmp, sal_True ); + ReadDIB(aBitmap, aTmp, true); + // test if it is sensible to crop if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && ( xSrc >= 0 ) && ( ySrc >= 0 ) && @@ -1055,7 +1057,7 @@ sal_Bool EnhWMFReader::ReadEnhWMF() pWMF->Seek( nStart + offBitsSrc ); pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); aTmp.Seek( 0 ); - aBitmap.Read( aTmp, sal_True ); + ReadDIB(aBitmap, aTmp, true); // test if it is sensible to crop if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && @@ -1125,7 +1127,7 @@ sal_Bool EnhWMFReader::ReadEnhWMF() pWMF->Seek( nStart + offBitsSrc ); pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); aTmp.Seek( 0 ); - aBitmap.Read( aTmp, sal_True ); + ReadDIB(aBitmap, aTmp, true); // test if it is sensible to crop if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && @@ -1357,7 +1359,7 @@ sal_Bool EnhWMFReader::ReadEnhWMF() pWMF->Seek( nStart + offBits ); pWMF->Read( pBuf + 14 + cbBmi, cbBits ); aTmp.Seek( 0 ); - aBitmap.Read( aTmp, sal_True ); + ReadDIB(aBitmap, aTmp, true); } } } diff --git a/vcl/source/filter/wmf/winwmf.cxx b/vcl/source/filter/wmf/winwmf.cxx index 76df617c381d..6d3d40312703 100644 --- a/vcl/source/filter/wmf/winwmf.cxx +++ b/vcl/source/filter/wmf/winwmf.cxx @@ -26,6 +26,7 @@ #include <rtl/tencinfo.h> #include <osl/endian.h> #include <vcl/svapp.hxx> +#include <vcl/dibtools.hxx> //====================== MS-Windows-defines =============================== @@ -661,7 +662,7 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc ) { Rectangle aDestRect( ReadYX(), aDestSize ); if ( nWinROP != PATCOPY ) - aBmp.Read( *pWMF, sal_False ); + ReadDIB(aBmp, *pWMF, false); // test if it is sensible to crop if ( nSye && nSxe && @@ -686,7 +687,7 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc ) *pWMF >> nFunction >> nFunction; - aBmp.Read( *pWMF, sal_False ); + ReadDIB(aBmp, *pWMF, false); pBmp = aBmp.AcquireReadAccess(); if ( pBmp ) { diff --git a/vcl/source/filter/wmf/wmfwr.cxx b/vcl/source/filter/wmf/wmfwr.cxx index 3cc4dccd82c5..e980b79a71c4 100644 --- a/vcl/source/filter/wmf/wmfwr.cxx +++ b/vcl/source/filter/wmf/wmfwr.cxx @@ -27,7 +27,7 @@ #include <tools/tenccvt.hxx> #include <osl/endian.h> #include <i18nutil/unicode.hxx> //unicode::getUnicodeScriptType - +#include <vcl/dibtools.hxx> #include <vcl/metric.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> @@ -778,7 +778,10 @@ void WMFWriter::WMFRecord_StretchDIB( const Point & rPoint, const Size & rSize, *pWMF << (sal_Int32)0 << (sal_Int32)0; // 8 bytes auffuellen (diese 8 bytes + // 14 bytes ueberfluessigen FILEHEADER // = 22 bytes Parameter) - *pWMF << rBitmap; // Bitmap schreiben + + // write bitmap + WriteDIB(rBitmap, *pWMF, false, true); + // Parameter schreiben: nPosEnd=pWMF->Tell(); diff --git a/vcl/source/gdi/animate.cxx b/vcl/source/gdi/animate.cxx index e73d19f323ce..3e2c26d73d79 100644 --- a/vcl/source/gdi/animate.cxx +++ b/vcl/source/gdi/animate.cxx @@ -25,6 +25,8 @@ #include <vcl/virdev.hxx> #include <vcl/window.hxx> #include <impanmvw.hxx> +#include <vcl/dibtools.hxx> + DBG_NAME( Animation ) #define MIN_TIMEOUT 2L @@ -708,9 +710,9 @@ SvStream& operator<<( SvStream& rOStm, const Animation& rAnimation ) // If no BitmapEx was set we write the first Bitmap of // the Animation if( !rAnimation.GetBitmapEx().GetBitmap() ) - rOStm << rAnimation.Get( 0 ).aBmpEx; + WriteDIBBitmapEx(rAnimation.Get( 0 ).aBmpEx, rOStm); else - rOStm << rAnimation.GetBitmapEx(); + WriteDIBBitmapEx(rAnimation.GetBitmapEx(), rOStm); // Write identifier ( SDANIMA1 ) rOStm << (sal_uInt32) 0x5344414e << (sal_uInt32) 0x494d4931; @@ -721,7 +723,7 @@ SvStream& operator<<( SvStream& rOStm, const Animation& rAnimation ) const sal_uInt16 nRest = nCount - i - 1; // Write AnimationBitmap - rOStm << rAnimBmp.aBmpEx; + WriteDIBBitmapEx(rAnimBmp.aBmpEx, rOStm); rOStm << rAnimBmp.aPosPix; rOStm << rAnimBmp.aSizePix; rOStm << rAnimation.maGlobalSize; @@ -762,7 +764,7 @@ SvStream& operator>>( SvStream& rIStm, Animation& rAnimation ) else { rIStm.Seek( nStmPos ); - rIStm >> rAnimation.maBitmapEx; + ReadDIBBitmapEx(rAnimation.maBitmapEx, rIStm); nStmPos = rIStm.Tell(); rIStm >> nAnimMagic1 >> nAnimMagic2; @@ -783,7 +785,7 @@ SvStream& operator>>( SvStream& rIStm, Animation& rAnimation ) do { - rIStm >> aAnimBmp.aBmpEx; + ReadDIBBitmapEx(aAnimBmp.aBmpEx, rIStm); rIStm >> aAnimBmp.aPosPix; rIStm >> aAnimBmp.aSizePix; rIStm >> rAnimation.maGlobalSize; diff --git a/vcl/source/gdi/bitmap2.cxx b/vcl/source/gdi/bitmap2.cxx deleted file mode 100644 index 2866ac4a2e22..000000000000 --- a/vcl/source/gdi/bitmap2.cxx +++ /dev/null @@ -1,1268 +0,0 @@ -/* -*- 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/zcodec.hxx> -#include <tools/stream.hxx> -#include <vcl/salbtype.hxx> -#include <vcl/bmpacc.hxx> -#include <vcl/outdev.hxx> -#include <vcl/bitmap.hxx> - -#include <utility> - -#if defined HAVE_VALGRIND_HEADERS -#include <valgrind/memcheck.h> -#endif - -#define DIBCOREHEADERSIZE ( 12UL ) -#define DIBINFOHEADERSIZE ( sizeof( DIBInfoHeader ) ) -#define BITMAPINFOHEADER 0x28 - -// Compression defines -#define COMPRESS_OWN ('S'|('D'<<8UL)) -#define COMPRESS_NONE ( 0UL ) -#define RLE_8 ( 1UL ) -#define RLE_4 ( 2UL ) -#define BITFIELDS ( 3UL ) -#define ZCOMPRESS ( COMPRESS_OWN | 0x01000000UL ) /* == 'SD01' (binary) */ - -struct DIBInfoHeader -{ - sal_uInt32 nSize; - sal_Int32 nWidth; - sal_Int32 nHeight; - sal_uInt16 nPlanes; - sal_uInt16 nBitCount; - sal_uInt32 nCompression; - sal_uInt32 nSizeImage; - sal_Int32 nXPelsPerMeter; - sal_Int32 nYPelsPerMeter; - sal_uInt32 nColsUsed; - sal_uInt32 nColsImportant; - - DIBInfoHeader() : - nSize( 0UL ), - nWidth( 0UL ), - nHeight( 0UL ), - nPlanes( 0 ), - nBitCount( 0 ), - nCompression( 0 ), - nSizeImage( 0 ), - nXPelsPerMeter( 0UL ), - nYPelsPerMeter( 0UL ), - nColsUsed( 0UL ), - nColsImportant( 0UL ) {} - - ~DIBInfoHeader() {} -}; - -namespace -{ - inline sal_uInt16 discretizeBitcount( sal_uInt16 nInputCount ) - { - return ( nInputCount <= 1 ) ? 1 : - ( nInputCount <= 4 ) ? 4 : - ( nInputCount <= 8 ) ? 8 : 24; - } - - inline bool isBitfieldCompression( sal_uLong nScanlineFormat ) - { - return nScanlineFormat == BMP_FORMAT_16BIT_TC_LSB_MASK || - nScanlineFormat == BMP_FORMAT_32BIT_TC_MASK; - } -} - -SvStream& operator>>( SvStream& rIStm, Bitmap& rBitmap ) -{ - rBitmap.Read( rIStm, sal_True ); - return rIStm; -} - -SvStream& operator<<( SvStream& rOStm, const Bitmap& rBitmap ) -{ - rBitmap.Write( rOStm, sal_False, sal_True ); - return rOStm; -} - -sal_Bool Bitmap::Read( SvStream& rIStm, sal_Bool bFileHeader, sal_Bool bIsMSOFormat ) -{ - const sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt(); - const sal_uLong nOldPos = rIStm.Tell(); - sal_uLong nOffset = 0UL; - sal_Bool bRet = sal_False; - - rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - - if( bFileHeader ) - { - if( ImplReadDIBFileHeader( rIStm, nOffset ) ) - bRet = ImplReadDIB( rIStm, *this, nOffset ); - } - else - bRet = ImplReadDIB( rIStm, *this, nOffset, bIsMSOFormat ); - - if( !bRet ) - { - if( !rIStm.GetError() ) - rIStm.SetError( SVSTREAM_GENERALERROR ); - - rIStm.Seek( nOldPos ); - } - - rIStm.SetNumberFormatInt( nOldFormat ); - - return bRet; -} - -sal_Bool Bitmap::ImplReadDIB( SvStream& rIStm, Bitmap& rBmp, sal_uLong nOffset, sal_Bool bIsMSOFormat ) -{ - DIBInfoHeader aHeader; - const sal_uLong nStmPos = rIStm.Tell(); - sal_Bool bRet = sal_False; - sal_Bool bTopDown = sal_False; - - if( ImplReadDIBInfoHeader( rIStm, aHeader, bTopDown, bIsMSOFormat ) && aHeader.nWidth && aHeader.nHeight && aHeader.nBitCount ) - { - const sal_uInt16 nBitCount( discretizeBitcount(aHeader.nBitCount) ); - - const Size aSizePixel( aHeader.nWidth, abs(aHeader.nHeight) ); - BitmapPalette aDummyPal; - Bitmap aNewBmp( aSizePixel, nBitCount, &aDummyPal ); - BitmapWriteAccess* pAcc = aNewBmp.AcquireWriteAccess(); - - if( pAcc ) - { - sal_uInt16 nColors; - SvStream* pIStm; - SvMemoryStream* pMemStm = NULL; - sal_uInt8* pData = NULL; - - if( nBitCount <= 8 ) - { - if( aHeader.nColsUsed ) - nColors = (sal_uInt16) aHeader.nColsUsed; - else - nColors = ( 1 << aHeader.nBitCount ); - } - else - nColors = 0; - - if( ZCOMPRESS == aHeader.nCompression ) - { - ZCodec aCodec; - sal_uInt32 nCodedSize, nUncodedSize; - sal_uLong nCodedPos; - - // read coding information - rIStm >> nCodedSize >> nUncodedSize >> aHeader.nCompression; - pData = (sal_uInt8*) rtl_allocateMemory( nUncodedSize ); - - // decode buffer - nCodedPos = rIStm.Tell(); - aCodec.BeginCompression(); - aCodec.Read( rIStm, pData, nUncodedSize ); - aCodec.EndCompression(); - - // skip unread bytes from coded buffer - rIStm.SeekRel( nCodedSize - ( rIStm.Tell() - nCodedPos ) ); - - // set decoded bytes to memory stream, - // from which we will read the bitmap data - pMemStm = new SvMemoryStream; - pIStm = pMemStm; - pMemStm->SetBuffer( (char*) pData, nUncodedSize, sal_False, nUncodedSize ); - nOffset = 0; - } - else - pIStm = &rIStm; - - // read palette - if( nColors ) - { - pAcc->SetPaletteEntryCount( nColors ); - ImplReadDIBPalette( *pIStm, *pAcc, aHeader.nSize != DIBCOREHEADERSIZE ); - } - - // read bits - if( !pIStm->GetError() ) - { - if( nOffset ) - pIStm->SeekRel( nOffset - ( pIStm->Tell() - nStmPos ) ); - - bRet = ImplReadDIBBits( *pIStm, aHeader, *pAcc, bTopDown ); - - if( bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter ) - { - MapMode aMapMode( MAP_MM, Point(), - Fraction( 1000, aHeader.nXPelsPerMeter ), - Fraction( 1000, aHeader.nYPelsPerMeter ) ); - - aNewBmp.SetPrefMapMode( aMapMode ); - aNewBmp.SetPrefSize( Size( aHeader.nWidth, abs(aHeader.nHeight) ) ); - } - } - - if( pData ) - rtl_freeMemory( pData ); - - delete pMemStm; - aNewBmp.ReleaseAccess( pAcc ); - - if( bRet ) - rBmp = aNewBmp; - } - } - - return bRet; -} - -sal_Bool Bitmap::ImplReadDIBFileHeader( SvStream& rIStm, sal_uLong& rOffset ) -{ - sal_uInt32 nTmp32; - sal_uInt16 nTmp16 = 0; - sal_Bool bRet = sal_False; - - rIStm >> nTmp16; - - if ( ( 0x4D42 == nTmp16 ) || ( 0x4142 == nTmp16 ) ) - { - if ( 0x4142 == nTmp16 ) - { - rIStm.SeekRel( 12L ); - rIStm >> nTmp16; - rIStm.SeekRel( 8L ); - rIStm >> nTmp32; - rOffset = nTmp32 - 28UL; - bRet = ( 0x4D42 == nTmp16 ); - } - else - { - rIStm.SeekRel( 8L ); - rIStm >> nTmp32; - rOffset = nTmp32 - 14UL; - bRet = ( rIStm.GetError() == 0UL ); - } - } - else - rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR ); - - return bRet; -} - -sal_Bool Bitmap::ImplReadDIBInfoHeader( SvStream& rIStm, DIBInfoHeader& rHeader, sal_Bool& bTopDown, sal_Bool bIsMSOFormat ) -{ - // BITMAPINFOHEADER or BITMAPCOREHEADER - rIStm >> rHeader.nSize; - - // BITMAPCOREHEADER - sal_Int16 nTmp16 = 0; - if ( rHeader.nSize == DIBCOREHEADERSIZE ) - { - - rIStm >> nTmp16; rHeader.nWidth = nTmp16; - rIStm >> nTmp16; rHeader.nHeight = nTmp16; - rIStm >> rHeader.nPlanes; - rIStm >> rHeader.nBitCount; - } - else if ( bIsMSOFormat && ( rHeader.nSize == BITMAPINFOHEADER ) ) - { - sal_uInt8 nTmp8 = 0; - rIStm >> nTmp16; rHeader.nWidth = nTmp16; - rIStm >> nTmp16; rHeader.nHeight = nTmp16; - rIStm >> nTmp8; rHeader.nPlanes = nTmp8; - rIStm >> nTmp8; rHeader.nBitCount = nTmp8; - rIStm >> nTmp16; rHeader.nSizeImage = nTmp16; - rIStm >> nTmp16; rHeader.nCompression = nTmp16; - if ( !rHeader.nSizeImage ) // uncompressed? - rHeader.nSizeImage = ((rHeader.nWidth * rHeader.nBitCount + 31) & ~31) / 8 * rHeader.nHeight; - rIStm >> rHeader.nXPelsPerMeter; - rIStm >> rHeader.nYPelsPerMeter; - rIStm >> rHeader.nColsUsed; - rIStm >> rHeader.nColsImportant; - } - else - { - // unknown Header - if( rHeader.nSize < DIBINFOHEADERSIZE ) - { - sal_uLong nUnknownSize = sizeof( rHeader.nSize ); - - rIStm >> rHeader.nWidth; nUnknownSize += sizeof( rHeader.nWidth ); - rIStm >> rHeader.nHeight; nUnknownSize += sizeof( rHeader.nHeight ); - rIStm >> rHeader.nPlanes; nUnknownSize += sizeof( rHeader.nPlanes ); - rIStm >> rHeader.nBitCount; nUnknownSize += sizeof( rHeader.nBitCount ); - - if( nUnknownSize < rHeader.nSize ) - { - rIStm >> rHeader.nCompression; - nUnknownSize += sizeof( rHeader.nCompression ); - - if( nUnknownSize < rHeader.nSize ) - { - rIStm >> rHeader.nSizeImage; - nUnknownSize += sizeof( rHeader.nSizeImage ); - - if( nUnknownSize < rHeader.nSize ) - { - rIStm >> rHeader.nXPelsPerMeter; - nUnknownSize += sizeof( rHeader.nXPelsPerMeter ); - - if( nUnknownSize < rHeader.nSize ) - { - rIStm >> rHeader.nYPelsPerMeter; - nUnknownSize += sizeof( rHeader.nYPelsPerMeter ); - } - - if( nUnknownSize < rHeader.nSize ) - { - rIStm >> rHeader.nColsUsed; - nUnknownSize += sizeof( rHeader.nColsUsed ); - - if( nUnknownSize < rHeader.nSize ) - { - rIStm >> rHeader.nColsImportant; - nUnknownSize += sizeof( rHeader.nColsImportant ); - } - } - } - } - } - } - else - { - rIStm >> rHeader.nWidth; - rIStm >> rHeader.nHeight; //rHeader.nHeight=abs(rHeader.nHeight); - rIStm >> rHeader.nPlanes; - rIStm >> rHeader.nBitCount; - rIStm >> rHeader.nCompression; - rIStm >> rHeader.nSizeImage; - rIStm >> rHeader.nXPelsPerMeter; - rIStm >> rHeader.nYPelsPerMeter; - rIStm >> rHeader.nColsUsed; - rIStm >> rHeader.nColsImportant; - } - - // Skip to palette if we can - if ( rHeader.nSize > DIBINFOHEADERSIZE ) - rIStm.SeekRel( rHeader.nSize - DIBINFOHEADERSIZE ); - } - if ( rHeader.nHeight < 0 ) - { - bTopDown = sal_True; - rHeader.nHeight *= -1; - } - else - bTopDown = sal_False; - - if ( rHeader.nWidth < 0 ) - rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR ); - - // Protect against damaged files a little bit - if( rHeader.nSizeImage > ( 16 * static_cast< sal_uInt32 >( rHeader.nWidth * rHeader.nHeight ) ) ) - rHeader.nSizeImage = 0; - - return( ( rHeader.nPlanes == 1 ) && ( rIStm.GetError() == 0UL ) ); -} - -sal_Bool Bitmap::ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, sal_Bool bQuad ) -{ - const sal_uInt16 nColors = rAcc.GetPaletteEntryCount(); - const sal_uLong nPalSize = nColors * ( bQuad ? 4UL : 3UL ); - BitmapColor aPalColor; - - sal_uInt8* pEntries = new sal_uInt8[ nPalSize ]; - rIStm.Read( pEntries, nPalSize ); - - sal_uInt8* pTmpEntry = pEntries; - for( sal_uInt16 i = 0; i < nColors; i++ ) - { - aPalColor.SetBlue( *pTmpEntry++ ); - aPalColor.SetGreen( *pTmpEntry++ ); - aPalColor.SetRed( *pTmpEntry++ ); - - if( bQuad ) - pTmpEntry++; - - rAcc.SetPaletteColor( i, aPalColor ); - } - - delete[] pEntries; - - return( rIStm.GetError() == 0UL ); -} - -sal_Bool Bitmap::ImplReadDIBBits( SvStream& rIStm, DIBInfoHeader& rHeader, BitmapWriteAccess& rAcc, sal_Bool bTopDown ) -{ - const sal_uLong nAlignedWidth = AlignedWidth4Bytes( rHeader.nWidth * rHeader.nBitCount ); - sal_uInt32 nRMask = 0; - sal_uInt32 nGMask = 0; - sal_uInt32 nBMask = 0; - bool bNative; - bool bTCMask = ( rHeader.nBitCount == 16 ) || ( rHeader.nBitCount == 32 ); - bool bRLE = ( RLE_8 == rHeader.nCompression && rHeader.nBitCount == 8 ) || - ( RLE_4 == rHeader.nCompression && rHeader.nBitCount == 4 ); - - // Is native format? - switch( rAcc.GetScanlineFormat() ) - { - case( BMP_FORMAT_1BIT_MSB_PAL ): - case( BMP_FORMAT_4BIT_MSN_PAL ): - case( BMP_FORMAT_8BIT_PAL ): - case( BMP_FORMAT_24BIT_TC_BGR ): - bNative = ( ( rAcc.IsBottomUp() != bTopDown ) && !bRLE && !bTCMask && ( rAcc.GetScanlineSize() == nAlignedWidth ) ); - break; - - default: - bNative = false; - break; - } - // Read data - if( bNative ) - { - // true color DIB's can have a (optimization) palette - if( rHeader.nColsUsed && rHeader.nBitCount > 8 ) - rIStm.SeekRel( rHeader.nColsUsed * ( ( rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3 ) ); - - if ( rHeader.nHeight > 0 ) - rIStm.Read( rAcc.GetBuffer(), rHeader.nHeight * nAlignedWidth ); - else - { - for( int i = abs(rHeader.nHeight)-1; i >= 0; i-- ) - rIStm.Read( ((char*)rAcc.GetBuffer()) + (nAlignedWidth*i), nAlignedWidth ); - } - } - else - { - // Read color mask - if( bTCMask ) - { - if( rHeader.nCompression == BITFIELDS ) - { - rIStm.SeekRel( -12L ); - rIStm >> nRMask; - rIStm >> nGMask; - rIStm >> nBMask; - } - else - { - nRMask = ( rHeader.nBitCount == 16 ) ? 0x00007c00UL : 0x00ff0000UL; - nGMask = ( rHeader.nBitCount == 16 ) ? 0x000003e0UL : 0x0000ff00UL; - nBMask = ( rHeader.nBitCount == 16 ) ? 0x0000001fUL : 0x000000ffUL; - } - } - - if( bRLE ) - { - if ( !rHeader.nSizeImage ) - { - const sal_uLong nOldPos = rIStm.Tell(); - - rIStm.Seek( STREAM_SEEK_TO_END ); - rHeader.nSizeImage = rIStm.Tell() - nOldPos; - rIStm.Seek( nOldPos ); - } - - sal_uInt8* pBuffer = (sal_uInt8*) rtl_allocateMemory( rHeader.nSizeImage ); - - rIStm.Read( (char*) pBuffer, rHeader.nSizeImage ); - ImplDecodeRLE( pBuffer, rHeader, rAcc, RLE_4 == rHeader.nCompression ); - - rtl_freeMemory( pBuffer ); - } - else - { - const long nWidth = rHeader.nWidth; - const long nHeight = abs(rHeader.nHeight); - sal_uInt8* pBuf = new sal_uInt8[ nAlignedWidth ]; - - // true color DIB's can have a (optimization) palette - if( rHeader.nColsUsed && rHeader.nBitCount > 8 ) - rIStm.SeekRel( rHeader.nColsUsed * ( ( rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3 ) ); - - const long nI = bTopDown ? 1 : -1; - long nY = bTopDown ? 0 : nHeight - 1; - long nCount = nHeight; - - switch( rHeader.nBitCount ) - { - case( 1 ): - { - sal_uInt8* pTmp; - sal_uInt8 cTmp; - - for( ; nCount--; nY += nI ) - { - rIStm.Read( pTmp = pBuf, nAlignedWidth ); - cTmp = *pTmp++; - - for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ ) - { - if( !nShift ) - { - nShift = 8L, - cTmp = *pTmp++; - } - - rAcc.SetPixelIndex( nY, nX, (cTmp >> --nShift) & 1); - } - } - } - break; - - case( 4 ): - { - sal_uInt8* pTmp; - sal_uInt8 cTmp; - - for( ; nCount--; nY += nI ) - { - rIStm.Read( pTmp = pBuf, nAlignedWidth ); - cTmp = *pTmp++; - - for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ ) - { - if( !nShift ) - { - nShift = 2UL, - cTmp = *pTmp++; - } - - rAcc.SetPixelIndex( nY, nX, (cTmp >> ( --nShift << 2UL ) ) & 0x0f); - } - } - } - break; - - case( 8 ): - { - sal_uInt8* pTmp; - - for( ; nCount--; nY += nI ) - { - rIStm.Read( pTmp = pBuf, nAlignedWidth ); - - for( long nX = 0L; nX < nWidth; nX++ ) - rAcc.SetPixelIndex( nY, nX, *pTmp++ ); - } - } - break; - - case( 16 ): - { - ColorMask aMask( nRMask, nGMask, nBMask ); - BitmapColor aColor; - sal_uInt16* pTmp16; - - for( ; nCount--; nY += nI ) - { - rIStm.Read( (char*)( pTmp16 = (sal_uInt16*) pBuf ), nAlignedWidth ); - - for( long nX = 0L; nX < nWidth; nX++ ) - { - aMask.GetColorFor16BitLSB( aColor, (sal_uInt8*) pTmp16++ ); - rAcc.SetPixel( nY, nX, aColor ); - } - } - } - break; - - case( 24 ): - { - BitmapColor aPixelColor; - sal_uInt8* pTmp; - - for( ; nCount--; nY += nI ) - { - rIStm.Read( pTmp = pBuf, nAlignedWidth ); - - for( long nX = 0L; nX < nWidth; nX++ ) - { - aPixelColor.SetBlue( *pTmp++ ); - aPixelColor.SetGreen( *pTmp++ ); - aPixelColor.SetRed( *pTmp++ ); - rAcc.SetPixel( nY, nX, aPixelColor ); - } - } - } - break; - - case( 32 ): - { - ColorMask aMask( nRMask, nGMask, nBMask ); - BitmapColor aColor; - sal_uInt32* pTmp32; - - for( ; nCount--; nY += nI ) - { - rIStm.Read( (char*)( pTmp32 = (sal_uInt32*) pBuf ), nAlignedWidth ); - - for( long nX = 0L; nX < nWidth; nX++ ) - { - aMask.GetColorFor32Bit( aColor, (sal_uInt8*) pTmp32++ ); - rAcc.SetPixel( nY, nX, aColor ); - } - } - } - } - - delete[] pBuf; - } - } - - return( rIStm.GetError() == 0UL ); -} - -sal_Bool Bitmap::Write( SvStream& rOStm, sal_Bool bCompressed, sal_Bool bFileHeader ) const -{ - DBG_ASSERT( mpImpBmp, "Empty Bitmaps can't be saved" ); - - const Size aSizePix( GetSizePixel() ); - sal_Bool bRet = sal_False; - - if( mpImpBmp && aSizePix.Width() && aSizePix.Height() ) - { - BitmapReadAccess* pAcc = ( (Bitmap*) this)->AcquireReadAccess(); - const sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt(); - const sal_uLong nOldPos = rOStm.Tell(); - - rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - - if( pAcc ) - { - if( bFileHeader ) - { - if( ImplWriteDIBFileHeader( rOStm, *pAcc ) ) - bRet = ImplWriteDIB( rOStm, *pAcc, bCompressed ); - } - else - bRet = ImplWriteDIB( rOStm, *pAcc, bCompressed ); - - ( (Bitmap*) this)->ReleaseAccess( pAcc ); - } - - if( !bRet ) - { - rOStm.SetError( SVSTREAM_GENERALERROR ); - rOStm.Seek( nOldPos ); - } - - rOStm.SetNumberFormatInt( nOldFormat ); - } - - return bRet; -} - -sal_Bool Bitmap::ImplWriteDIB( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bCompressed ) const -{ - const MapMode aMapPixel( MAP_PIXEL ); - DIBInfoHeader aHeader; - sal_uLong nImageSizePos; - sal_uLong nEndPos; - sal_uInt32 nCompression = 0; - sal_Bool bRet = sal_False; - - aHeader.nSize = DIBINFOHEADERSIZE; - aHeader.nWidth = rAcc.Width(); - aHeader.nHeight = rAcc.Height(); - aHeader.nPlanes = 1; - - if( isBitfieldCompression( rAcc.GetScanlineFormat() ) ) - { - aHeader.nBitCount = ( rAcc.GetScanlineFormat() == BMP_FORMAT_16BIT_TC_LSB_MASK ) ? 16 : 32; - aHeader.nSizeImage = rAcc.Height() * rAcc.GetScanlineSize(); - - nCompression = BITFIELDS; - } - else - { - // #i5xxx# Limit bitcount to 24bit, the 32 bit cases are - // not handled properly below (would have to set color - // masks, and nCompression=BITFIELDS - but color mask is - // not set for formats != *_TC_*). Note that this very - // problem might cause trouble at other places - the - // introduction of 32 bit RGBA bitmaps is relatively - // recent. - // #i59239# discretize bitcount to 1,4,8,24 (other cases - // are not written below) - const sal_uInt16 nBitCount( sal::static_int_cast<sal_uInt16>(rAcc.GetBitCount()) ); - - aHeader.nBitCount = discretizeBitcount( nBitCount ); - aHeader.nSizeImage = rAcc.Height() * - AlignedWidth4Bytes( rAcc.Width()*aHeader.nBitCount ); - - if( bCompressed ) - { - if( 4 == nBitCount ) - nCompression = RLE_4; - else if( 8 == nBitCount ) - nCompression = RLE_8; - } - else - nCompression = COMPRESS_NONE; - } - - if( ( rOStm.GetCompressMode() & COMPRESSMODE_ZBITMAP ) && - ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_40 ) ) - { - aHeader.nCompression = ZCOMPRESS; - } - else - aHeader.nCompression = nCompression; - - if( maPrefSize.Width() && maPrefSize.Height() && ( maPrefMapMode != aMapPixel ) ) - { - // #i48108# Try to recover xpels/ypels as previously stored on - // disk. The problem with just converting maPrefSize to 100th - // mm and then relating that to the bitmap pixel size is that - // MapMode is integer-based, and suffers from roundoffs, - // especially if maPrefSize is small. Trying to circumvent - // that by performing part of the math in floating point. - const Size aScale100000( - OutputDevice::LogicToLogic( Size(100000L, - 100000L), - MAP_100TH_MM, - maPrefMapMode ) ); - const double fBmpWidthM((double)maPrefSize.Width() / aScale100000.Width() ); - const double fBmpHeightM((double)maPrefSize.Height() / aScale100000.Height() ); - if( fabs(fBmpWidthM) > 0.000000001 && - fabs(fBmpHeightM) > 0.000000001 ) - { - aHeader.nXPelsPerMeter = (sal_uInt32)(rAcc.Width() / fBmpWidthM + .5); - aHeader.nYPelsPerMeter = (sal_uInt32)(rAcc.Height() / fBmpHeightM + .5); - } - } - - aHeader.nColsUsed = ( ( aHeader.nBitCount <= 8 ) ? rAcc.GetPaletteEntryCount() : 0 ); - aHeader.nColsImportant = 0; - - rOStm << aHeader.nSize; - rOStm << aHeader.nWidth; - rOStm << aHeader.nHeight; - rOStm << aHeader.nPlanes; - rOStm << aHeader.nBitCount; - rOStm << aHeader.nCompression; - - nImageSizePos = rOStm.Tell(); - rOStm.SeekRel( sizeof( aHeader.nSizeImage ) ); - - rOStm << aHeader.nXPelsPerMeter; - rOStm << aHeader.nYPelsPerMeter; - rOStm << aHeader.nColsUsed; - rOStm << aHeader.nColsImportant; - - if( aHeader.nCompression == ZCOMPRESS ) - { - ZCodec aCodec; - SvMemoryStream aMemStm( aHeader.nSizeImage + 4096, 65535 ); - sal_uLong nCodedPos = rOStm.Tell(), nLastPos; - sal_uInt32 nCodedSize, nUncodedSize; - - // write uncoded data palette - if( aHeader.nColsUsed ) - ImplWriteDIBPalette( aMemStm, rAcc ); - - // write uncoded bits - bRet = ImplWriteDIBBits( aMemStm, rAcc, nCompression, aHeader.nSizeImage ); - - // get uncoded size - nUncodedSize = aMemStm.Tell(); - - // seek over compress info - rOStm.SeekRel( 12 ); - - // write compressed data - aCodec.BeginCompression( 3 ); - aCodec.Write( rOStm, (sal_uInt8*) aMemStm.GetData(), nUncodedSize ); - aCodec.EndCompression(); - - // update compress info ( coded size, uncoded size, uncoded compression ) - nCodedSize = ( nLastPos = rOStm.Tell() ) - nCodedPos - 12; - rOStm.Seek( nCodedPos ); - rOStm << nCodedSize << nUncodedSize << nCompression; - rOStm.Seek( nLastPos ); - - if( bRet ) - bRet = ( rOStm.GetError() == ERRCODE_NONE ); - } - else - { - if( aHeader.nColsUsed ) - ImplWriteDIBPalette( rOStm, rAcc ); - - bRet = ImplWriteDIBBits( rOStm, rAcc, aHeader.nCompression, aHeader.nSizeImage ); - } - - nEndPos = rOStm.Tell(); - rOStm.Seek( nImageSizePos ); - rOStm << aHeader.nSizeImage; - rOStm.Seek( nEndPos ); - - return bRet; -} - -sal_Bool Bitmap::ImplWriteDIBFileHeader( SvStream& rOStm, BitmapReadAccess& rAcc ) -{ - sal_uInt32 nPalCount = ( rAcc.HasPalette() ? rAcc.GetPaletteEntryCount() : - isBitfieldCompression( rAcc.GetScanlineFormat() ) ? 3UL : 0UL ); - sal_uInt32 nOffset = 14 + DIBINFOHEADERSIZE + nPalCount * 4UL; - - rOStm << (sal_uInt16) 0x4D42; - rOStm << (sal_uInt32) ( nOffset + ( rAcc.Height() * rAcc.GetScanlineSize() ) ); - rOStm << (sal_uInt16) 0; - rOStm << (sal_uInt16) 0; - rOStm << nOffset; - - return( rOStm.GetError() == 0UL ); -} - -sal_Bool Bitmap::ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc ) -{ - const sal_uInt16 nColors = rAcc.GetPaletteEntryCount(); - const sal_uLong nPalSize = nColors * 4UL; - sal_uInt8* pEntries = new sal_uInt8[ nPalSize ]; - sal_uInt8* pTmpEntry = pEntries; - BitmapColor aPalColor; - - for( sal_uInt16 i = 0; i < nColors; i++ ) - { - const BitmapColor& rPalColor = rAcc.GetPaletteColor( i ); - - *pTmpEntry++ = rPalColor.GetBlue(); - *pTmpEntry++ = rPalColor.GetGreen(); - *pTmpEntry++ = rPalColor.GetRed(); - *pTmpEntry++ = 0; - } - - rOStm.Write( pEntries, nPalSize ); - delete[] pEntries; - - return( rOStm.GetError() == 0UL ); -} - -#if defined HAVE_VALGRIND_HEADERS -namespace -{ - void blankExtraSpace(sal_uInt8 *pBits, long nWidth, long nScanlineSize, int nBitCount) - { - size_t nExtraSpaceInScanLine = nScanlineSize - nWidth * nBitCount / 8; - if (nExtraSpaceInScanLine) - memset(pBits + (nScanlineSize - nExtraSpaceInScanLine), 0, nExtraSpaceInScanLine); - } -} -#endif - -sal_Bool Bitmap::ImplWriteDIBBits( SvStream& rOStm, BitmapReadAccess& rAcc, - sal_uLong nCompression, sal_uInt32& rImageSize ) -{ - if( BITFIELDS == nCompression ) - { - const ColorMask& rMask = rAcc.GetColorMask(); - SVBT32 aVal32; - - UInt32ToSVBT32( rMask.GetRedMask(), aVal32 ); - rOStm.Write( (sal_uInt8*) aVal32, 4UL ); - - UInt32ToSVBT32( rMask.GetGreenMask(), aVal32 ); - rOStm.Write( (sal_uInt8*) aVal32, 4UL ); - - UInt32ToSVBT32( rMask.GetBlueMask(), aVal32 ); - rOStm.Write( (sal_uInt8*) aVal32, 4UL ); - - rImageSize = rOStm.Tell(); - - if( rAcc.IsBottomUp() ) - rOStm.Write( rAcc.GetBuffer(), rAcc.Height() * rAcc.GetScanlineSize() ); - else - { - for( long nY = rAcc.Height() - 1, nScanlineSize = rAcc.GetScanlineSize(); nY >= 0L; nY-- ) - rOStm.Write( rAcc.GetScanline( nY ), nScanlineSize ); - } - } - else if( ( RLE_4 == nCompression ) || ( RLE_8 == nCompression ) ) - { - rImageSize = rOStm.Tell(); - ImplWriteRLE( rOStm, rAcc, RLE_4 == nCompression ); - } - else if( !nCompression ) - { - // #i5xxx# Limit bitcount to 24bit, the 32 bit cases are not - // handled properly below (would have to set color masks, and - // nCompression=BITFIELDS - but color mask is not set for - // formats != *_TC_*). Note that this very problem might cause - // trouble at other places - the introduction of 32 bit RGBA - // bitmaps is relatively recent. - // #i59239# discretize bitcount for aligned width to 1,4,8,24 - // (other cases are not written below) - const sal_uInt16 nBitCount( sal::static_int_cast<sal_uInt16>(rAcc.GetBitCount()) ); - const sal_uLong nAlignedWidth = AlignedWidth4Bytes( rAcc.Width() * - discretizeBitcount(nBitCount)); - bool bNative = false; - - switch( rAcc.GetScanlineFormat() ) - { - case( BMP_FORMAT_1BIT_MSB_PAL ): - case( BMP_FORMAT_4BIT_MSN_PAL ): - case( BMP_FORMAT_8BIT_PAL ): - case( BMP_FORMAT_24BIT_TC_BGR ): - { - if( rAcc.IsBottomUp() && ( rAcc.GetScanlineSize() == nAlignedWidth ) ) - bNative = true; - } - break; - - default: - break; - } - - rImageSize = rOStm.Tell(); - - if( bNative ) - rOStm.Write( rAcc.GetBuffer(), nAlignedWidth * rAcc.Height() ); - else - { - const long nWidth = rAcc.Width(); - const long nHeight = rAcc.Height(); - sal_uInt8* pBuf = new sal_uInt8[ nAlignedWidth ]; -#if defined HAVE_VALGRIND_HEADERS - if (RUNNING_ON_VALGRIND) - blankExtraSpace(pBuf, nWidth, nAlignedWidth, discretizeBitcount(nBitCount)); -#endif - sal_uInt8* pTmp; - sal_uInt8 cTmp; - - switch( nBitCount ) - { - case( 1 ): - { - for( long nY = nHeight - 1; nY >= 0L; nY-- ) - { - pTmp = pBuf; - cTmp = 0; - - for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ ) - { - if( !nShift ) - { - nShift = 8L; - *pTmp++ = cTmp; - cTmp = 0; - } - - cTmp |= rAcc.GetPixelIndex( nY, nX ) << --nShift; - } - - *pTmp = cTmp; - rOStm.Write( pBuf, nAlignedWidth ); - } - } - break; - - case( 4 ): - { - for( long nY = nHeight - 1; nY >= 0L; nY-- ) - { - pTmp = pBuf; - cTmp = 0; - - for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ ) - { - if( !nShift ) - { - nShift = 2L; - *pTmp++ = cTmp; - cTmp = 0; - } - - cTmp |= rAcc.GetPixelIndex( nY, nX ) << ( --nShift << 2L ); - } - *pTmp = cTmp; - rOStm.Write( pBuf, nAlignedWidth ); - } - } - break; - - case( 8 ): - { - for( long nY = nHeight - 1; nY >= 0L; nY-- ) - { - pTmp = pBuf; - - for( long nX = 0L; nX < nWidth; nX++ ) - *pTmp++ = rAcc.GetPixelIndex( nY, nX ); - - rOStm.Write( pBuf, nAlignedWidth ); - } - } - break; - - // #i59239# fallback to 24 bit format, if bitcount is non-default - default: - // FALLTHROUGH intended - case( 24 ): - { - BitmapColor aPixelColor; - - for( long nY = nHeight - 1; nY >= 0L; nY-- ) - { - pTmp = pBuf; - - for( long nX = 0L; nX < nWidth; nX++ ) - { - aPixelColor = rAcc.GetPixel( nY, nX ); - *pTmp++ = aPixelColor.GetBlue(); - *pTmp++ = aPixelColor.GetGreen(); - *pTmp++ = aPixelColor.GetRed(); - } - - rOStm.Write( pBuf, nAlignedWidth ); - } - } - break; - } - - delete[] pBuf; - } - } - - rImageSize = rOStm.Tell() - rImageSize; - - return( rOStm.GetError() == 0UL ); -} - -void Bitmap::ImplDecodeRLE( sal_uInt8* pBuffer, DIBInfoHeader& rHeader, - BitmapWriteAccess& rAcc, sal_Bool bRLE4 ) -{ - Scanline pRLE = pBuffer; - long nY = abs(rHeader.nHeight) - 1L; - const sal_uLong nWidth = rAcc.Width(); - sal_uLong nCountByte; - sal_uLong nRunByte; - sal_uLong nX = 0UL; - sal_uInt8 cTmp; - bool bEndDecoding = false; - - do - { - if( ( nCountByte = *pRLE++ ) == 0 ) - { - nRunByte = *pRLE++; - - if( nRunByte > 2 ) - { - if( bRLE4 ) - { - nCountByte = nRunByte >> 1; - - for( sal_uLong i = 0UL; i < nCountByte; i++ ) - { - cTmp = *pRLE++; - - if( nX < nWidth ) - rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 ); - - if( nX < nWidth ) - rAcc.SetPixelIndex( nY, nX++, cTmp & 0x0f ); - } - - if( nRunByte & 1 ) - { - if( nX < nWidth ) - rAcc.SetPixelIndex( nY, nX++, *pRLE >> 4 ); - - pRLE++; - } - - if( ( ( nRunByte + 1 ) >> 1 ) & 1 ) - pRLE++; - } - else - { - for( sal_uLong i = 0UL; i < nRunByte; i++ ) - { - if( nX < nWidth ) - rAcc.SetPixelIndex( nY, nX++, *pRLE ); - - pRLE++; - } - - if( nRunByte & 1 ) - pRLE++; - } - } - else if( !nRunByte ) - { - nY--; - nX = 0UL; - } - else if( nRunByte == 1 ) - bEndDecoding = true; - else - { - nX += *pRLE++; - nY -= *pRLE++; - } - } - else - { - cTmp = *pRLE++; - - if( bRLE4 ) - { - nRunByte = nCountByte >> 1; - - for( sal_uLong i = 0UL; i < nRunByte; i++ ) - { - if( nX < nWidth ) - rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 ); - - if( nX < nWidth ) - rAcc.SetPixelIndex( nY, nX++, cTmp & 0x0f ); - } - - if( ( nCountByte & 1 ) && ( nX < nWidth ) ) - rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 ); - } - else - { - for( sal_uLong i = 0UL; ( i < nCountByte ) && ( nX < nWidth ); i++ ) - rAcc.SetPixelIndex( nY, nX++, cTmp ); - } - } - } - while ( !bEndDecoding && ( nY >= 0L ) ); -} - -sal_Bool Bitmap::ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bRLE4 ) -{ - const sal_uLong nWidth = rAcc.Width(); - const sal_uLong nHeight = rAcc.Height(); - sal_uLong nX; - sal_uLong nSaveIndex; - sal_uLong nCount; - sal_uLong nBufCount; - sal_uInt8* pBuf = new sal_uInt8[ ( nWidth << 1 ) + 2 ]; - sal_uInt8* pTmp; - sal_uInt8 cPix; - sal_uInt8 cLast; - bool bFound; - - for ( long nY = nHeight - 1L; nY >= 0L; nY-- ) - { - pTmp = pBuf; - nX = nBufCount = 0UL; - - while( nX < nWidth ) - { - nCount = 1L; - cPix = rAcc.GetPixelIndex( nY, nX++ ); - - while( ( nX < nWidth ) && ( nCount < 255L ) - && ( cPix == rAcc.GetPixelIndex( nY, nX ) ) ) - { - nX++; - nCount++; - } - - if ( nCount > 1 ) - { - *pTmp++ = (sal_uInt8) nCount; - *pTmp++ = ( bRLE4 ? ( ( cPix << 4 ) | cPix ) : cPix ); - nBufCount += 2; - } - else - { - cLast = cPix; - nSaveIndex = nX - 1UL; - bFound = false; - - while( ( nX < nWidth ) && ( nCount < 256L ) - && ( cPix = rAcc.GetPixelIndex( nY, nX ) ) != cLast ) - { - nX++; nCount++; - cLast = cPix; - bFound = true; - } - - if ( bFound ) - nX--; - - if ( nCount > 3 ) - { - *pTmp++ = 0; - *pTmp++ = (sal_uInt8) --nCount; - - if( bRLE4 ) - { - for ( sal_uLong i = 0; i < nCount; i++, pTmp++ ) - { - *pTmp = rAcc.GetPixelIndex( nY, nSaveIndex++ ) << 4; - - if ( ++i < nCount ) - *pTmp |= rAcc.GetPixelIndex( nY, nSaveIndex++ ); - } - - nCount = ( nCount + 1 ) >> 1; - } - else - { - for( sal_uLong i = 0UL; i < nCount; i++ ) - *pTmp++ = rAcc.GetPixelIndex( nY, nSaveIndex++ ); - } - - if ( nCount & 1 ) - { - *pTmp++ = 0; - nBufCount += ( nCount + 3 ); - } - else - nBufCount += ( nCount + 2 ); - } - else - { - *pTmp++ = 1; - *pTmp++ = rAcc.GetPixelIndex( nY, nSaveIndex ) << (bRLE4 ? 4 : 0); - - if ( nCount == 3 ) - { - *pTmp++ = 1; - *pTmp++ = rAcc.GetPixelIndex( nY, ++nSaveIndex ) << ( bRLE4 ? 4 : 0 ); - nBufCount += 4; - } - else - nBufCount += 2; - } - } - } - - pBuf[ nBufCount++ ] = 0; - pBuf[ nBufCount++ ] = 0; - - rOStm.Write( pBuf, nBufCount ); - } - - rOStm << (sal_uInt8) 0; - rOStm << (sal_uInt8) 1; - - delete[] pBuf; - - return( rOStm.GetError() == 0UL ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx index 5ac3c36c41c1..eeb68d2c101e 100644 --- a/vcl/source/gdi/bitmapex.cxx +++ b/vcl/source/gdi/bitmapex.cxx @@ -18,18 +18,17 @@ */ #include <ctype.h> - #include <rtl/crc.h> #include <rtl/strbuf.hxx> #include <tools/stream.hxx> #include <tools/debug.hxx> #include <tools/rc.h> - #include <vcl/salbtype.hxx> #include <vcl/outdev.hxx> #include <vcl/alpha.hxx> #include <vcl/bitmapex.hxx> +#include <vcl/dibtools.hxx> #include <vcl/pngread.hxx> #include <vcl/svapp.hxx> #include <vcl/bmpacc.hxx> @@ -781,104 +780,6 @@ sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const return nTransparency; } -SvStream& operator<<( SvStream& rOStm, const BitmapEx& rBitmapEx ) -{ - rBitmapEx.aBitmap.Write( rOStm ); - - rOStm << (sal_uInt32) 0x25091962; - rOStm << (sal_uInt32) 0xACB20201; - rOStm << (sal_uInt8) rBitmapEx.eTransparent; - - if( rBitmapEx.eTransparent == TRANSPARENT_BITMAP ) - rBitmapEx.aMask.Write( rOStm ); - else if( rBitmapEx.eTransparent == TRANSPARENT_COLOR ) - rOStm << rBitmapEx.aTransparentColor; - - return rOStm; -} - -SvStream& operator>>( SvStream& rIStm, BitmapEx& rBitmapEx ) -{ - Bitmap aBmp; - - rIStm >> aBmp; - - if( !rIStm.GetError() ) - { - const sal_uLong nStmPos = rIStm.Tell(); - sal_uInt32 nMagic1 = 0; - sal_uInt32 nMagic2 = 0; - - rIStm >> nMagic1 >> nMagic2; - - if( ( nMagic1 != 0x25091962 ) || ( nMagic2 != 0xACB20201 ) || rIStm.GetError() ) - { - rIStm.ResetError(); - rIStm.Seek( nStmPos ); - rBitmapEx = aBmp; - } - else - { - sal_uInt8 bTransparent = 0; - - rIStm >> bTransparent; - - if( bTransparent == (sal_uInt8) TRANSPARENT_BITMAP ) - { - Bitmap aMask; - - rIStm >> aMask; - - if( !!aMask) - { - // fdo#59616 enforce same size for both mask and content - if( aMask.GetSizePixel() != aBmp.GetSizePixel() ) - { - Bitmap aNewMask; - const Size aNominalSize=aBmp.GetSizePixel(); - BitmapReadAccess aAcc(aMask); - if( aAcc.HasPalette() ) - aNewMask = Bitmap(aNominalSize, - aMask.GetBitCount(), - &aAcc.GetPalette()); - else - aNewMask = Bitmap(aNominalSize, - aMask.GetBitCount()); - const Rectangle aCopyArea(Point(0,0), aNominalSize); - aNewMask.CopyPixel(aCopyArea, aCopyArea, &aMask); - aMask = aNewMask; - } - - // do we have an alpha mask? - if( ( 8 == aMask.GetBitCount() ) && aMask.HasGreyPalette() ) - { - AlphaMask aAlpha; - - // create alpha mask quickly (without greyscale conversion) - aAlpha.ImplSetBitmap( aMask ); - rBitmapEx = BitmapEx( aBmp, aAlpha ); - } - else - rBitmapEx = BitmapEx( aBmp, aMask ); - } - else - rBitmapEx = aBmp; - } - else if( bTransparent == (sal_uInt8) TRANSPARENT_COLOR ) - { - Color aTransparentColor; - - rIStm >> aTransparentColor; - rBitmapEx = BitmapEx( aBmp, aTransparentColor ); - } - else - rBitmapEx = aBmp; - } - } - - return rIStm; -} - // Shift alpha transparent pixels between cppcanvas/ implementations // and vcl in a generally grotesque and under-performing fashion bool BitmapEx::Create( const ::com::sun::star::uno::Reference< diff --git a/vcl/source/gdi/bmpconv.cxx b/vcl/source/gdi/bmpconv.cxx index e42a28e1c3b5..24bb15961398 100644 --- a/vcl/source/gdi/bmpconv.cxx +++ b/vcl/source/gdi/bmpconv.cxx @@ -17,7 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include "vcl/bitmap.hxx" #include "vcl/svapp.hxx" #include "vcl/salctype.hxx" @@ -26,7 +25,7 @@ #include "com/sun/star/script/XInvocation.hpp" #include "com/sun/star/awt/XBitmap.hpp" #include "cppuhelper/compbase1.hxx" - +#include <vcl/dibtools.hxx> using namespace com::sun::star::uno; using namespace com::sun::star::script; @@ -143,7 +142,9 @@ Any SAL_CALL BmpConverter::invoke( SvMemoryStream aStream( aDIB.getArray(), aDIB.getLength(), STREAM_READ | STREAM_WRITE ); Bitmap aBM; - aBM.Read( aStream, sal_True ); + + ReadDIB(aBM, aStream, true); + if( nTargetDepth < 4 ) nTargetDepth = 1; else if( nTargetDepth < 8 ) @@ -177,8 +178,11 @@ BmpTransporter::BmpTransporter( const Bitmap& rBM ) { m_aSize.Width = rBM.GetSizePixel().Width(); m_aSize.Height = rBM.GetSizePixel().Height(); + SvMemoryStream aStream; - rBM.Write( aStream, sal_False, sal_True ); + + WriteDIB(rBM, aStream, false, true); + m_aBM = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aStream.GetData()), aStream.GetEndOfData()); } diff --git a/vcl/source/gdi/cvtsvm.cxx b/vcl/source/gdi/cvtsvm.cxx index f7a8c49f16df..2334004e0ae0 100644 --- a/vcl/source/gdi/cvtsvm.cxx +++ b/vcl/source/gdi/cvtsvm.cxx @@ -22,6 +22,7 @@ #include <tools/debug.hxx> #include <tools/stream.hxx> #include <tools/helpers.hxx> +#include <vcl/dibtools.hxx> #include <vcl/virdev.hxx> #include <vcl/graph.hxx> #include <vcl/lineinfo.hxx> @@ -930,7 +931,8 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) { Bitmap aBmp; - rIStm >> aPt >> aBmp; + rIStm >> aPt; + ReadDIB(aBmp, rIStm, true); rMtf.AddAction( new MetaBmpAction( aPt, aBmp ) ); } break; @@ -939,7 +941,8 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) { Bitmap aBmp; - rIStm >> aPt >> aSz >> aBmp; + rIStm >> aPt >> aSz; + ReadDIB(aBmp, rIStm, true); rMtf.AddAction( new MetaBmpScaleAction( aPt, aSz, aBmp ) ); } break; @@ -949,7 +952,8 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) Bitmap aBmp; Size aSz2; - rIStm >> aPt >> aSz >> aPt1 >> aSz2 >> aBmp; + rIStm >> aPt >> aSz >> aPt1 >> aSz2; + ReadDIB(aBmp, rIStm, true); rMtf.AddAction( new MetaBmpScalePartAction( aPt, aSz, aPt1, aSz2, aBmp ) ); } break; @@ -1769,7 +1773,7 @@ sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, rOStm << (sal_Int16) GDI_BITMAP_ACTION; rOStm << (sal_Int32) 12; rOStm << pAct->GetPoint(); - rOStm << pAct->GetBitmap(); + WriteDIB(pAct->GetBitmap(), rOStm, false, true); nCount++; } break; @@ -1782,7 +1786,7 @@ sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, rOStm << (sal_Int32) 20; rOStm << pAct->GetPoint(); rOStm << pAct->GetSize(); - rOStm << pAct->GetBitmap(); + WriteDIB(pAct->GetBitmap(), rOStm, false, true); nCount++; } break; @@ -1797,7 +1801,7 @@ sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, rOStm << pAct->GetDestSize(); rOStm << pAct->GetSrcPoint(); rOStm << pAct->GetSrcSize(); - rOStm << pAct->GetBitmap(); + WriteDIB(pAct->GetBitmap(), rOStm, false, true); nCount++; } break; @@ -1810,7 +1814,7 @@ sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, rOStm << (sal_Int16) GDI_BITMAP_ACTION; rOStm << (sal_Int32) 12; rOStm << pAct->GetPoint(); - rOStm << aBmp; + WriteDIB(aBmp, rOStm, false, true); nCount++; } break; @@ -1824,7 +1828,7 @@ sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, rOStm << (sal_Int32) 20; rOStm << pAct->GetPoint(); rOStm << pAct->GetSize(); - rOStm << aBmp; + WriteDIB(aBmp, rOStm, false, true); nCount++; } break; @@ -1840,7 +1844,7 @@ sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, rOStm << pAct->GetDestSize(); rOStm << pAct->GetSrcPoint(); rOStm << pAct->GetSrcSize(); - rOStm << aBmp; + WriteDIB(aBmp, rOStm, false, true); nCount++; } break; diff --git a/vcl/source/gdi/dibtools.cxx b/vcl/source/gdi/dibtools.cxx new file mode 100644 index 000000000000..c4b3bfec31fd --- /dev/null +++ b/vcl/source/gdi/dibtools.cxx @@ -0,0 +1,1587 @@ +/* + * 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 <vcl/salbtype.hxx> +#include <vcl/dibtools.hxx> +#include <tools/zcodec.hxx> +#include <tools/stream.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/bmpacc.hxx> +#include <vcl/outdev.hxx> + +////////////////////////////////////////////////////////////////////////////// +// - Defines - + +#define DIBCOREHEADERSIZE ( 12UL ) +#define DIBINFOHEADERSIZE ( sizeof(DIBInfoHeader) ) +#define DIBV5HEADERSIZE ( sizeof(DIBV5Header) ) + +////////////////////////////////////////////////////////////////////////////// +// - Compression defines + +#define COMPRESS_OWN ('S'|('D'<<8UL)) +#define COMPRESS_NONE ( 0UL ) +#define RLE_8 ( 1UL ) +#define RLE_4 ( 2UL ) +#define BITFIELDS ( 3UL ) +#define ZCOMPRESS ( COMPRESS_OWN | 0x01000000UL ) /* == 'SD01' (binary) */ + +////////////////////////////////////////////////////////////////////////////// +// - DIBInfoHeader and DIBV5Header + +typedef sal_Int32 FXPT2DOT30; + +struct CIEXYZ +{ + FXPT2DOT30 aXyzX; + FXPT2DOT30 aXyzY; + FXPT2DOT30 aXyzZ; + + CIEXYZ() + : aXyzX(0L), + aXyzY(0L), + aXyzZ(0L) + {} + + ~CIEXYZ() + {} +}; + +struct CIEXYZTriple +{ + CIEXYZ aXyzRed; + CIEXYZ aXyzGreen; + CIEXYZ aXyzBlue; + + CIEXYZTriple() + : aXyzRed(), + aXyzGreen(), + aXyzBlue() + {} + + ~CIEXYZTriple() + {} +}; + +struct DIBInfoHeader +{ + sal_uInt32 nSize; + sal_Int32 nWidth; + sal_Int32 nHeight; + sal_uInt16 nPlanes; + sal_uInt16 nBitCount; + sal_uInt32 nCompression; + sal_uInt32 nSizeImage; + sal_Int32 nXPelsPerMeter; + sal_Int32 nYPelsPerMeter; + sal_uInt32 nColsUsed; + sal_uInt32 nColsImportant; + + DIBInfoHeader() + : nSize(0UL), + nWidth(0UL), + nHeight(0UL), + nPlanes(0), + nBitCount(0), + nCompression(0), + nSizeImage(0), + nXPelsPerMeter(0UL), + nYPelsPerMeter(0UL), + nColsUsed(0UL), + nColsImportant(0UL) + {} + + ~DIBInfoHeader() + {} +}; + +struct DIBV5Header : public DIBInfoHeader +{ + sal_uInt32 nV5RedMask; + sal_uInt32 nV5GreenMask; + sal_uInt32 nV5BlueMask; + sal_uInt32 nV5AlphaMask; + sal_uInt32 nV5CSType; + CIEXYZTriple aV5Endpoints; + sal_uInt32 nV5GammaRed; + sal_uInt32 nV5GammaGreen; + sal_uInt32 nV5GammaBlue; + sal_uInt32 nV5Intent; + sal_uInt32 nV5ProfileData; + sal_uInt32 nV5ProfileSize; + sal_uInt32 nV5Reserved; + + DIBV5Header() + : DIBInfoHeader(), + nV5RedMask(0UL), + nV5GreenMask(0UL), + nV5BlueMask(0UL), + nV5AlphaMask(0UL), + nV5CSType(0UL), + aV5Endpoints(), + nV5GammaRed(0UL), + nV5GammaGreen(0UL), + nV5GammaBlue(0UL), + nV5Intent(0UL), + nV5ProfileData(0UL), + nV5ProfileSize(0UL), + nV5Reserved(0UL) + {} + + ~DIBV5Header() + {} +}; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + inline sal_uInt16 discretizeBitcount( sal_uInt16 nInputCount ) + { + return ( nInputCount <= 1 ) ? 1 : + ( nInputCount <= 4 ) ? 4 : + ( nInputCount <= 8 ) ? 8 : 24; + } + + inline bool isBitfieldCompression( sal_uLong nScanlineFormat ) + { + return (BMP_FORMAT_16BIT_TC_LSB_MASK == nScanlineFormat) || (BMP_FORMAT_32BIT_TC_MASK == nScanlineFormat); + } +} + +////////////////////////////////////////////////////////////////////////////// + +bool ImplReadDIBInfoHeader(SvStream& rIStm, DIBV5Header& rHeader, bool& bTopDown) +{ + // BITMAPINFOHEADER or BITMAPCOREHEADER or BITMAPV5HEADER + const sal_Size aStartPos(rIStm.Tell()); + rIStm >> rHeader.nSize; + + // BITMAPCOREHEADER + if ( rHeader.nSize == DIBCOREHEADERSIZE ) + { + sal_Int16 nTmp16; + + rIStm >> nTmp16; rHeader.nWidth = nTmp16; + rIStm >> nTmp16; rHeader.nHeight = nTmp16; + rIStm >> rHeader.nPlanes; + rIStm >> rHeader.nBitCount; + } + else + { + // BITMAPCOREHEADER, BITMAPV5HEADER or unknown. Read as far as possible + sal_Size nUsed(sizeof(rHeader.nSize)); + + // read DIBInfoHeader entries + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nWidth; nUsed += sizeof(rHeader.nWidth); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nHeight; nUsed += sizeof(rHeader.nHeight); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nPlanes; nUsed += sizeof(rHeader.nPlanes); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nBitCount; nUsed += sizeof(rHeader.nBitCount); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nCompression; nUsed += sizeof(rHeader.nCompression); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nSizeImage; nUsed += sizeof(rHeader.nSizeImage); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nXPelsPerMeter; nUsed += sizeof(rHeader.nXPelsPerMeter); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nYPelsPerMeter; nUsed += sizeof(rHeader.nYPelsPerMeter); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nColsUsed; nUsed += sizeof(rHeader.nColsUsed); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nColsImportant; nUsed += sizeof(rHeader.nColsImportant); } + + // read DIBV5HEADER members + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5RedMask; nUsed += sizeof(rHeader.nV5RedMask); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5GreenMask; nUsed += sizeof(rHeader.nV5GreenMask); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5BlueMask; nUsed += sizeof(rHeader.nV5BlueMask); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5AlphaMask; nUsed += sizeof(rHeader.nV5AlphaMask); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5CSType; nUsed += sizeof(rHeader.nV5CSType); } + + // read contained CIEXYZTriple's + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzRed.aXyzX; nUsed += sizeof(rHeader.aV5Endpoints.aXyzRed.aXyzX); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzRed.aXyzY; nUsed += sizeof(rHeader.aV5Endpoints.aXyzRed.aXyzY); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzRed.aXyzZ; nUsed += sizeof(rHeader.aV5Endpoints.aXyzRed.aXyzZ); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzGreen.aXyzX; nUsed += sizeof(rHeader.aV5Endpoints.aXyzGreen.aXyzX); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzGreen.aXyzY; nUsed += sizeof(rHeader.aV5Endpoints.aXyzGreen.aXyzY); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzGreen.aXyzZ; nUsed += sizeof(rHeader.aV5Endpoints.aXyzGreen.aXyzZ); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzBlue.aXyzX; nUsed += sizeof(rHeader.aV5Endpoints.aXyzBlue.aXyzX); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzBlue.aXyzY; nUsed += sizeof(rHeader.aV5Endpoints.aXyzBlue.aXyzY); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzBlue.aXyzZ; nUsed += sizeof(rHeader.aV5Endpoints.aXyzBlue.aXyzZ); } + + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5GammaRed; nUsed += sizeof(rHeader.nV5GammaRed); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5GammaGreen; nUsed += sizeof(rHeader.nV5GammaGreen); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5GammaBlue; nUsed += sizeof(rHeader.nV5GammaBlue); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5Intent; nUsed += sizeof(rHeader.nV5Intent); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5ProfileData; nUsed += sizeof(rHeader.nV5ProfileData); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5ProfileSize; nUsed += sizeof(rHeader.nV5ProfileSize); } + if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5Reserved; nUsed += sizeof(rHeader.nV5Reserved); } + + // seek to EndPos + rIStm.Seek(aStartPos + rHeader.nSize); + } + + if ( rHeader.nHeight < 0 ) + { + bTopDown = true; + rHeader.nHeight *= -1; + } + else + { + bTopDown = false; + } + + if ( rHeader.nWidth < 0 ) + { + rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR ); + } + + // #144105# protect a little against damaged files + if( rHeader.nSizeImage > ( 16 * static_cast< sal_uInt32 >( rHeader.nWidth * rHeader.nHeight ) ) ) + { + rHeader.nSizeImage = 0; + } + + return( ( rHeader.nPlanes == 1 ) && ( rIStm.GetError() == 0UL ) ); +} + +bool ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, bool bQuad ) +{ + const sal_uInt16 nColors = rAcc.GetPaletteEntryCount(); + const sal_uLong nPalSize = nColors * ( bQuad ? 4UL : 3UL ); + BitmapColor aPalColor; + + sal_uInt8* pEntries = new sal_uInt8[ nPalSize ]; + rIStm.Read( pEntries, nPalSize ); + + sal_uInt8* pTmpEntry = pEntries; + for( sal_uInt16 i = 0; i < nColors; i++ ) + { + aPalColor.SetBlue( *pTmpEntry++ ); + aPalColor.SetGreen( *pTmpEntry++ ); + aPalColor.SetRed( *pTmpEntry++ ); + + if( bQuad ) + pTmpEntry++; + + rAcc.SetPaletteColor( i, aPalColor ); + } + + delete[] pEntries; + + return( rIStm.GetError() == 0UL ); +} + +void ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess& rAcc, bool bRLE4 ) +{ + Scanline pRLE = pBuffer; + long nY = rHeader.nHeight - 1L; + const sal_uLong nWidth = rAcc.Width(); + sal_uLong nCountByte; + sal_uLong nRunByte; + sal_uLong nX = 0UL; + sal_uInt8 cTmp; + bool bEndDecoding = false; + + do + { + if( ( nCountByte = *pRLE++ ) == 0 ) + { + nRunByte = *pRLE++; + + if( nRunByte > 2 ) + { + if( bRLE4 ) + { + nCountByte = nRunByte >> 1; + + for( sal_uLong i = 0UL; i < nCountByte; i++ ) + { + cTmp = *pRLE++; + + if( nX < nWidth ) + rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 ); + + if( nX < nWidth ) + rAcc.SetPixelIndex( nY, nX++, cTmp & 0x0f ); + } + + if( nRunByte & 1 ) + { + if( nX < nWidth ) + rAcc.SetPixelIndex( nY, nX++, *pRLE >> 4 ); + + pRLE++; + } + + if( ( ( nRunByte + 1 ) >> 1 ) & 1 ) + pRLE++; + } + else + { + for( sal_uLong i = 0UL; i < nRunByte; i++ ) + { + if( nX < nWidth ) + rAcc.SetPixelIndex( nY, nX++, *pRLE ); + + pRLE++; + } + + if( nRunByte & 1 ) + pRLE++; + } + } + else if( !nRunByte ) + { + nY--; + nX = 0UL; + } + else if( nRunByte == 1 ) + bEndDecoding = true; + else + { + nX += *pRLE++; + nY -= *pRLE++; + } + } + else + { + cTmp = *pRLE++; + + if( bRLE4 ) + { + nRunByte = nCountByte >> 1; + + for( sal_uLong i = 0UL; i < nRunByte; i++ ) + { + if( nX < nWidth ) + rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 ); + + if( nX < nWidth ) + rAcc.SetPixelIndex( nY, nX++, cTmp & 0x0f ); + } + + if( ( nCountByte & 1 ) && ( nX < nWidth ) ) + rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 ); + } + else + { + for( sal_uLong i = 0UL; ( i < nCountByte ) && ( nX < nWidth ); i++ ) + rAcc.SetPixelIndex( nY, nX++, cTmp ); + } + } + } + while ( !bEndDecoding && ( nY >= 0L ) ); +} + +bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& rAcc, BitmapWriteAccess* pAccAlpha, bool bTopDown) +{ + const sal_uLong nAlignedWidth = AlignedWidth4Bytes(rHeader.nWidth * rHeader.nBitCount); + sal_uInt32 nRMask(0); + sal_uInt32 nGMask(0); + sal_uInt32 nBMask(0); + bool bNative(false); + bool bTCMask(!pAccAlpha && ((16 == rHeader.nBitCount) || (32 == rHeader.nBitCount))); + bool bRLE((RLE_8 == rHeader.nCompression && 8 == rHeader.nBitCount) || (RLE_4 == rHeader.nCompression && 4 == rHeader.nBitCount)); + + // Is native format? + switch(rAcc.GetScanlineFormat()) + { + case( BMP_FORMAT_1BIT_MSB_PAL ): + case( BMP_FORMAT_4BIT_MSN_PAL ): + case( BMP_FORMAT_8BIT_PAL ): + case( BMP_FORMAT_24BIT_TC_BGR ): + { + bNative = ( ( static_cast< bool >(rAcc.IsBottomUp()) != bTopDown ) && !bRLE && !bTCMask && ( rAcc.GetScanlineSize() == nAlignedWidth ) ); + break; + } + + default: + { + break; + } + } + + // Read data + if(bNative) + { + // true color DIB's can have a (optimization) palette + if(rHeader.nColsUsed && 8 < rHeader.nBitCount) + { + rIStm.SeekRel(rHeader.nColsUsed * ((rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3)); + } + + rIStm.Read(rAcc.GetBuffer(), rHeader.nHeight * nAlignedWidth); + } + else + { + // Read color mask + if(bTCMask) + { + if(BITFIELDS == rHeader.nCompression) + { + rIStm.SeekRel( -12L ); + rIStm >> nRMask; + rIStm >> nGMask; + rIStm >> nBMask; + } + else + { + nRMask = ( rHeader.nBitCount == 16 ) ? 0x00007c00UL : 0x00ff0000UL; + nGMask = ( rHeader.nBitCount == 16 ) ? 0x000003e0UL : 0x0000ff00UL; + nBMask = ( rHeader.nBitCount == 16 ) ? 0x0000001fUL : 0x000000ffUL; + } + } + + if(bRLE) + { + if(!rHeader.nSizeImage) + { + const sal_uLong nOldPos(rIStm.Tell()); + + rIStm.Seek(STREAM_SEEK_TO_END); + rHeader.nSizeImage = rIStm.Tell() - nOldPos; + rIStm.Seek(nOldPos); + } + + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(rHeader.nSizeImage); + rIStm.Read((char*)pBuffer, rHeader.nSizeImage); + ImplDecodeRLE(pBuffer, rHeader, rAcc, RLE_4 == rHeader.nCompression); + rtl_freeMemory(pBuffer); + } + else + { + const long nWidth(rHeader.nWidth); + const long nHeight(rHeader.nHeight); + sal_uInt8* pBuf = new sal_uInt8[nAlignedWidth]; + + // true color DIB's can have a (optimization) palette + if(rHeader.nColsUsed && 8 < rHeader.nBitCount) + { + rIStm.SeekRel(rHeader.nColsUsed * ((rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3)); + } + + const long nI(bTopDown ? 1 : -1); + long nY(bTopDown ? 0 : nHeight - 1); + long nCount(nHeight); + + switch(rHeader.nBitCount) + { + case( 1 ): + { + sal_uInt8* pTmp; + sal_uInt8 cTmp; + + for( ; nCount--; nY += nI ) + { + rIStm.Read( pTmp = pBuf, nAlignedWidth ); + cTmp = *pTmp++; + + for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ ) + { + if( !nShift ) + { + nShift = 8L, + cTmp = *pTmp++; + } + + rAcc.SetPixelIndex( nY, nX, (cTmp >> --nShift) & 1); + } + } + } + break; + + case( 4 ): + { + sal_uInt8* pTmp; + sal_uInt8 cTmp; + + for( ; nCount--; nY += nI ) + { + rIStm.Read( pTmp = pBuf, nAlignedWidth ); + cTmp = *pTmp++; + + for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ ) + { + if( !nShift ) + { + nShift = 2UL, + cTmp = *pTmp++; + } + + rAcc.SetPixelIndex( nY, nX, (cTmp >> ( --nShift << 2UL ) ) & 0x0f); + } + } + } + break; + + case( 8 ): + { + sal_uInt8* pTmp; + + for( ; nCount--; nY += nI ) + { + rIStm.Read( pTmp = pBuf, nAlignedWidth ); + + for( long nX = 0L; nX < nWidth; nX++ ) + rAcc.SetPixelIndex( nY, nX, *pTmp++ ); + } + } + break; + + case( 16 ): + { + ColorMask aMask( nRMask, nGMask, nBMask ); + BitmapColor aColor; + sal_uInt16* pTmp16; + + for( ; nCount--; nY += nI ) + { + rIStm.Read( (char*)( pTmp16 = (sal_uInt16*) pBuf ), nAlignedWidth ); + + for( long nX = 0L; nX < nWidth; nX++ ) + { + aMask.GetColorFor16BitLSB( aColor, (sal_uInt8*) pTmp16++ ); + rAcc.SetPixel( nY, nX, aColor ); + } + } + } + break; + + case( 24 ): + { + BitmapColor aPixelColor; + sal_uInt8* pTmp; + + for( ; nCount--; nY += nI ) + { + rIStm.Read( pTmp = pBuf, nAlignedWidth ); + + for( long nX = 0L; nX < nWidth; nX++ ) + { + aPixelColor.SetBlue( *pTmp++ ); + aPixelColor.SetGreen( *pTmp++ ); + aPixelColor.SetRed( *pTmp++ ); + rAcc.SetPixel( nY, nX, aPixelColor ); + } + } + } + break; + + case( 32 ): + { + ColorMask aMask(nRMask, nGMask, nBMask); + BitmapColor aColor; + sal_uInt32* pTmp32; + + if(pAccAlpha) + { + sal_uInt8 aAlpha; + + for( ; nCount--; nY += nI ) + { + rIStm.Read( (char*)( pTmp32 = (sal_uInt32*) pBuf ), nAlignedWidth ); + + for( long nX = 0L; nX < nWidth; nX++ ) + { + aMask.GetColorAndAlphaFor32Bit( aColor, aAlpha, (sal_uInt8*) pTmp32++ ); + rAcc.SetPixel( nY, nX, aColor ); + pAccAlpha->SetPixelIndex(nY, nX, sal_uInt8(0xff) - aAlpha); + } + } + } + else + { + for( ; nCount--; nY += nI ) + { + rIStm.Read( (char*)( pTmp32 = (sal_uInt32*) pBuf ), nAlignedWidth ); + + for( long nX = 0L; nX < nWidth; nX++ ) + { + aMask.GetColorFor32Bit( aColor, (sal_uInt8*) pTmp32++ ); + rAcc.SetPixel( nY, nX, aColor ); + } + } + } + } + } + + delete[] pBuf; + } + } + + return( rIStm.GetError() == 0UL ); +} + +bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, Bitmap* pBmpAlpha, sal_uLong nOffset ) +{ + DIBV5Header aHeader; + const sal_uLong nStmPos = rIStm.Tell(); + bool bRet(false); + bool bTopDown(false); + + if(ImplReadDIBInfoHeader(rIStm, aHeader, bTopDown) && aHeader.nWidth && aHeader.nHeight && aHeader.nBitCount) + { + const sal_uInt16 nBitCount(discretizeBitcount(aHeader.nBitCount)); + const Size aSizePixel(aHeader.nWidth, aHeader.nHeight); + BitmapPalette aDummyPal; + Bitmap aNewBmp(aSizePixel, nBitCount, &aDummyPal); + Bitmap aNewBmpAlpha; + BitmapWriteAccess* pAcc = aNewBmp.AcquireWriteAccess(); + BitmapWriteAccess* pAccAlpha = 0; + bool bAlphaPossible(pBmpAlpha && aHeader.nBitCount == 32); + + if(bAlphaPossible) + { + const bool bRedSet(0 != aHeader.nV5RedMask); + const bool bGreenSet(0 != aHeader.nV5GreenMask); + const bool bBlueSet(0 != aHeader.nV5BlueMask); + + // some clipboard entries have alpha mask on zero to say that there is + // no alpha; do only use this when the other masks are set. The MS docu + // says that that masks are only to be set when bV5Compression is set to + // BI_BITFIELDS, but there seem to exist a wild variety of usages... + if((bRedSet || bGreenSet || bBlueSet) && (0 == aHeader.nV5AlphaMask)) + { + bAlphaPossible = false; + } + } + + if(bAlphaPossible) + { + aNewBmpAlpha = Bitmap(aSizePixel, 8); + pAccAlpha = aNewBmpAlpha.AcquireWriteAccess(); + } + + if(pAcc) + { + sal_uInt16 nColors(0); + SvStream* pIStm; + SvMemoryStream* pMemStm = NULL; + sal_uInt8* pData = NULL; + + if(nBitCount <= 8) + { + if(aHeader.nColsUsed) + { + nColors = (sal_uInt16)aHeader.nColsUsed; + } + else + { + nColors = ( 1 << aHeader.nBitCount ); + } + } + + if(ZCOMPRESS == aHeader.nCompression) + { + ZCodec aCodec; + sal_uInt32 nCodedSize(0); + sal_uInt32 nUncodedSize(0); + sal_uLong nCodedPos(0); + + // read coding information + rIStm >> nCodedSize >> nUncodedSize >> aHeader.nCompression; + pData = (sal_uInt8*) rtl_allocateMemory( nUncodedSize ); + + // decode buffer + nCodedPos = rIStm.Tell(); + aCodec.BeginCompression(); + aCodec.Read( rIStm, pData, nUncodedSize ); + aCodec.EndCompression(); + + // skip unread bytes from coded buffer + rIStm.SeekRel( nCodedSize - ( rIStm.Tell() - nCodedPos ) ); + + // set decoded bytes to memory stream, + // from which we will read the bitmap data + pIStm = pMemStm = new SvMemoryStream; + pMemStm->SetBuffer( (char*) pData, nUncodedSize, false, nUncodedSize ); + nOffset = 0; + } + else + { + pIStm = &rIStm; + } + + // read palette + if(nColors) + { + pAcc->SetPaletteEntryCount(nColors); + ImplReadDIBPalette(*pIStm, *pAcc, aHeader.nSize != DIBCOREHEADERSIZE); + } + + // read bits + if(!pIStm->GetError()) + { + if(nOffset) + { + pIStm->SeekRel(nOffset - (pIStm->Tell() - nStmPos)); + } + + bRet = ImplReadDIBBits(*pIStm, aHeader, *pAcc, pAccAlpha, bTopDown); + + if(bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter) + { + MapMode aMapMode( + MAP_MM, + Point(), + Fraction(1000, aHeader.nXPelsPerMeter), + Fraction(1000, aHeader.nYPelsPerMeter)); + + aNewBmp.SetPrefMapMode(aMapMode); + aNewBmp.SetPrefSize(Size(aHeader.nWidth, aHeader.nHeight)); + } + } + + if( pData ) + { + rtl_freeMemory(pData); + } + + delete pMemStm; + aNewBmp.ReleaseAccess(pAcc); + + if(bAlphaPossible) + { + aNewBmpAlpha.ReleaseAccess(pAccAlpha); + } + + if(bRet) + { + rBmp = aNewBmp; + + if(bAlphaPossible) + { + *pBmpAlpha = aNewBmpAlpha; + } + } + } + } + + return bRet; +} + +bool ImplReadDIBFileHeader( SvStream& rIStm, sal_uLong& rOffset ) +{ + sal_uInt32 nTmp32; + sal_uInt16 nTmp16 = 0; + bool bRet = false; + + rIStm >> nTmp16; + + if ( ( 0x4D42 == nTmp16 ) || ( 0x4142 == nTmp16 ) ) + { + if ( 0x4142 == nTmp16 ) + { + rIStm.SeekRel( 12L ); + rIStm >> nTmp16; + rIStm.SeekRel( 8L ); + rIStm >> nTmp32; + rOffset = nTmp32 - 28UL; + bRet = ( 0x4D42 == nTmp16 ); + } + else // 0x4D42 == nTmp16, 'MB' from BITMAPFILEHEADER + { + rIStm.SeekRel( 8L ); // we are on bfSize member of BITMAPFILEHEADER, forward to bfOffBits + rIStm >> nTmp32; // read bfOffBits + rOffset = nTmp32 - 14UL; // adapt offset by sizeof(BITMAPFILEHEADER) + bRet = ( rIStm.GetError() == 0UL ); + } + } + else + rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR ); + + return bRet; +} + +bool ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc ) +{ + const sal_uInt16 nColors = rAcc.GetPaletteEntryCount(); + const sal_uLong nPalSize = nColors * 4UL; + sal_uInt8* pEntries = new sal_uInt8[ nPalSize ]; + sal_uInt8* pTmpEntry = pEntries; + BitmapColor aPalColor; + + for( sal_uInt16 i = 0; i < nColors; i++ ) + { + const BitmapColor& rPalColor = rAcc.GetPaletteColor( i ); + + *pTmpEntry++ = rPalColor.GetBlue(); + *pTmpEntry++ = rPalColor.GetGreen(); + *pTmpEntry++ = rPalColor.GetRed(); + *pTmpEntry++ = 0; + } + + rOStm.Write( pEntries, nPalSize ); + delete[] pEntries; + + return( rOStm.GetError() == 0UL ); +} + +bool ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, bool bRLE4 ) +{ + const sal_uLong nWidth = rAcc.Width(); + const sal_uLong nHeight = rAcc.Height(); + sal_uLong nX; + sal_uLong nSaveIndex; + sal_uLong nCount; + sal_uLong nBufCount; + sal_uInt8* pBuf = new sal_uInt8[ ( nWidth << 1 ) + 2 ]; + sal_uInt8* pTmp; + sal_uInt8 cPix; + sal_uInt8 cLast; + bool bFound; + + for ( long nY = nHeight - 1L; nY >= 0L; nY-- ) + { + pTmp = pBuf; + nX = nBufCount = 0UL; + + while( nX < nWidth ) + { + nCount = 1L; + cPix = rAcc.GetPixelIndex( nY, nX++ ); + + while( ( nX < nWidth ) && ( nCount < 255L ) + && ( cPix == rAcc.GetPixelIndex( nY, nX ) ) ) + { + nX++; + nCount++; + } + + if ( nCount > 1 ) + { + *pTmp++ = (sal_uInt8) nCount; + *pTmp++ = ( bRLE4 ? ( ( cPix << 4 ) | cPix ) : cPix ); + nBufCount += 2; + } + else + { + cLast = cPix; + nSaveIndex = nX - 1UL; + bFound = false; + + while( ( nX < nWidth ) && ( nCount < 256L ) + && ( cPix = rAcc.GetPixelIndex( nY, nX ) ) != cLast ) + { + nX++; nCount++; + cLast = cPix; + bFound = true; + } + + if ( bFound ) + nX--; + + if ( nCount > 3 ) + { + *pTmp++ = 0; + *pTmp++ = (sal_uInt8) --nCount; + + if( bRLE4 ) + { + for ( sal_uLong i = 0; i < nCount; i++, pTmp++ ) + { + *pTmp = rAcc.GetPixelIndex( nY, nSaveIndex++ ) << 4; + + if ( ++i < nCount ) + *pTmp |= rAcc.GetPixelIndex( nY, nSaveIndex++ ); + } + + nCount = ( nCount + 1 ) >> 1; + } + else + { + for( sal_uLong i = 0UL; i < nCount; i++ ) + *pTmp++ = rAcc.GetPixelIndex( nY, nSaveIndex++ ); + } + + if ( nCount & 1 ) + { + *pTmp++ = 0; + nBufCount += ( nCount + 3 ); + } + else + nBufCount += ( nCount + 2 ); + } + else + { + *pTmp++ = 1; + *pTmp++ = rAcc.GetPixelIndex( nY, nSaveIndex ) << (bRLE4 ? 4 : 0); + + if ( nCount == 3 ) + { + *pTmp++ = 1; + *pTmp++ = rAcc.GetPixelIndex( nY, ++nSaveIndex ) << ( bRLE4 ? 4 : 0 ); + nBufCount += 4; + } + else + nBufCount += 2; + } + } + } + + pBuf[ nBufCount++ ] = 0; + pBuf[ nBufCount++ ] = 0; + + rOStm.Write( pBuf, nBufCount ); + } + + rOStm << (sal_uInt8) 0; + rOStm << (sal_uInt8) 1; + + delete[] pBuf; + + return( rOStm.GetError() == 0UL ); +} + +bool ImplWriteDIBBits(SvStream& rOStm, BitmapReadAccess& rAcc, BitmapReadAccess* pAccAlpha, sal_uLong nCompression, sal_uInt32& rImageSize) +{ + if(!pAccAlpha && BITFIELDS == nCompression) + { + const ColorMask& rMask = rAcc.GetColorMask(); + SVBT32 aVal32; + + UInt32ToSVBT32( rMask.GetRedMask(), aVal32 ); + rOStm.Write( (sal_uInt8*) aVal32, 4UL ); + + UInt32ToSVBT32( rMask.GetGreenMask(), aVal32 ); + rOStm.Write( (sal_uInt8*) aVal32, 4UL ); + + UInt32ToSVBT32( rMask.GetBlueMask(), aVal32 ); + rOStm.Write( (sal_uInt8*) aVal32, 4UL ); + + rImageSize = rOStm.Tell(); + + if( rAcc.IsBottomUp() ) + rOStm.Write( rAcc.GetBuffer(), rAcc.Height() * rAcc.GetScanlineSize() ); + else + { + for( long nY = rAcc.Height() - 1, nScanlineSize = rAcc.GetScanlineSize(); nY >= 0L; nY-- ) + rOStm.Write( rAcc.GetScanline( nY ), nScanlineSize ); + } + } + else if(!pAccAlpha && ((RLE_4 == nCompression) || (RLE_8 == nCompression))) + { + rImageSize = rOStm.Tell(); + ImplWriteRLE( rOStm, rAcc, RLE_4 == nCompression ); + } + else if(!nCompression) + { + // #i5xxx# Limit bitcount to 24bit, the 32 bit cases are not + // handled properly below (would have to set color masks, and + // nCompression=BITFIELDS - but color mask is not set for + // formats != *_TC_*). Note that this very problem might cause + // trouble at other places - the introduction of 32 bit RGBA + // bitmaps is relatively recent. + // #i59239# discretize bitcount for aligned width to 1,4,8,24 + // (other cases are not written below) + const sal_uInt16 nBitCount(pAccAlpha ? 32 : discretizeBitcount(static_cast< sal_uInt16 >(rAcc.GetBitCount()))); + const sal_uLong nAlignedWidth(AlignedWidth4Bytes(rAcc.Width() * nBitCount)); + bool bNative(false); + + switch(rAcc.GetScanlineFormat()) + { + case( BMP_FORMAT_1BIT_MSB_PAL ): + case( BMP_FORMAT_4BIT_MSN_PAL ): + case( BMP_FORMAT_8BIT_PAL ): + case( BMP_FORMAT_24BIT_TC_BGR ): + { + if(!pAccAlpha && rAcc.IsBottomUp() && (rAcc.GetScanlineSize() == nAlignedWidth)) + { + bNative = true; + } + + break; + } + + default: + { + break; + } + } + + rImageSize = rOStm.Tell(); + + if(bNative) + { + rOStm.Write(rAcc.GetBuffer(), nAlignedWidth * rAcc.Height()); + } + else + { + const long nWidth(rAcc.Width()); + const long nHeight(rAcc.Height()); + sal_uInt8* pBuf = new sal_uInt8[ nAlignedWidth ]; + sal_uInt8* pTmp(0); + sal_uInt8 cTmp(0); + + switch( nBitCount ) + { + case( 1 ): + { + for( long nY = nHeight - 1; nY >= 0L; nY-- ) + { + pTmp = pBuf; + cTmp = 0; + + for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ ) + { + if( !nShift ) + { + nShift = 8L; + *pTmp++ = cTmp; + cTmp = 0; + } + + cTmp |= rAcc.GetPixelIndex( nY, nX ) << --nShift; + } + + *pTmp = cTmp; + rOStm.Write( pBuf, nAlignedWidth ); + } + } + break; + + case( 4 ): + { + for( long nY = nHeight - 1; nY >= 0L; nY-- ) + { + pTmp = pBuf; + cTmp = 0; + + for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ ) + { + if( !nShift ) + { + nShift = 2L; + *pTmp++ = cTmp; + cTmp = 0; + } + + cTmp |= rAcc.GetPixelIndex( nY, nX ) << ( --nShift << 2L ); + } + *pTmp = cTmp; + rOStm.Write( pBuf, nAlignedWidth ); + } + } + break; + + case( 8 ): + { + for( long nY = nHeight - 1; nY >= 0L; nY-- ) + { + pTmp = pBuf; + + for( long nX = 0L; nX < nWidth; nX++ ) + *pTmp++ = rAcc.GetPixelIndex( nY, nX ); + + rOStm.Write( pBuf, nAlignedWidth ); + } + } + break; + + // #i59239# fallback to 24 bit format, if bitcount is non-default + default: + // FALLTHROUGH intended + case( 24 ): + { + BitmapColor aPixelColor; + const bool bWriteAlpha(32 == nBitCount && pAccAlpha); + + for( long nY = nHeight - 1; nY >= 0L; nY-- ) + { + pTmp = pBuf; + + for( long nX = 0L; nX < nWidth; nX++ ) + { + // when alpha is used, this may be non-24bit main bitmap, so use GetColor + // instead of GetPixel to ensure RGB value + aPixelColor = rAcc.GetColor( nY, nX ); + + *pTmp++ = aPixelColor.GetBlue(); + *pTmp++ = aPixelColor.GetGreen(); + *pTmp++ = aPixelColor.GetRed(); + + if(bWriteAlpha) + { + if(pAccAlpha) + { + *pTmp++ = (sal_uInt8)0xff - (sal_uInt8)pAccAlpha->GetPixelIndex( nY, nX ); + } + else + { + *pTmp++ = (sal_uInt8)0xff; + } + } + } + + rOStm.Write( pBuf, nAlignedWidth ); + } + } + break; + } + + delete[] pBuf; + } + } + + rImageSize = rOStm.Tell() - rImageSize; + + return (!rOStm.GetError()); +} + +bool ImplWriteDIBBody(const Bitmap& rBitmap, SvStream& rOStm, BitmapReadAccess& rAcc, BitmapReadAccess* pAccAlpha, bool bCompressed) +{ + const MapMode aMapPixel(MAP_PIXEL); + DIBV5Header aHeader; + sal_uLong nImageSizePos(0); + sal_uLong nEndPos(0); + sal_uInt32 nCompression(COMPRESS_NONE); + bool bRet(false); + + aHeader.nSize = pAccAlpha ? DIBV5HEADERSIZE : DIBINFOHEADERSIZE; // size dependent on CF_DIB type to use + aHeader.nWidth = rAcc.Width(); + aHeader.nHeight = rAcc.Height(); + aHeader.nPlanes = 1; + + if(!pAccAlpha && isBitfieldCompression(rAcc.GetScanlineFormat())) + { + aHeader.nBitCount = (BMP_FORMAT_16BIT_TC_LSB_MASK == rAcc.GetScanlineFormat()) ? 16 : 32; + aHeader.nSizeImage = rAcc.Height() * rAcc.GetScanlineSize(); + nCompression = BITFIELDS; + } + else + { + // #i5xxx# Limit bitcount to 24bit, the 32 bit cases are + // not handled properly below (would have to set color + // masks, and nCompression=BITFIELDS - but color mask is + // not set for formats != *_TC_*). Note that this very + // problem might cause trouble at other places - the + // introduction of 32 bit RGBA bitmaps is relatively + // recent. + // #i59239# discretize bitcount to 1,4,8,24 (other cases + // are not written below) + const sal_uInt16 nBitCount(pAccAlpha ? 32 : discretizeBitcount(static_cast< sal_uInt16 >(rAcc.GetBitCount()))); + aHeader.nBitCount = nBitCount; + aHeader.nSizeImage = rAcc.Height() * AlignedWidth4Bytes(rAcc.Width() * aHeader.nBitCount); + + if(bCompressed) + { + if(4 == nBitCount) + { + nCompression = RLE_4; + } + else if(8 == nBitCount) + { + nCompression = RLE_8; + } + } + } + + if((rOStm.GetCompressMode() & COMPRESSMODE_ZBITMAP) && (rOStm.GetVersion() >= SOFFICE_FILEFORMAT_40)) + { + aHeader.nCompression = ZCOMPRESS; + } + else + { + aHeader.nCompression = nCompression; + } + + if(rBitmap.GetPrefSize().Width() && rBitmap.GetPrefSize().Height() && (rBitmap.GetPrefMapMode() != aMapPixel)) + { + // #i48108# Try to recover xpels/ypels as previously stored on + // disk. The problem with just converting maPrefSize to 100th + // mm and then relating that to the bitmap pixel size is that + // MapMode is integer-based, and suffers from roundoffs, + // especially if maPrefSize is small. Trying to circumvent + // that by performing part of the math in floating point. + const Size aScale100000(OutputDevice::LogicToLogic(Size(100000L, 100000L), MAP_100TH_MM, rBitmap.GetPrefMapMode())); + const double fBmpWidthM((double)rBitmap.GetPrefSize().Width() / aScale100000.Width()); + const double fBmpHeightM((double)rBitmap.GetPrefSize().Height() / aScale100000.Height()); + + if(!basegfx::fTools::equalZero(fBmpWidthM) && !basegfx::fTools::equalZero(fBmpHeightM)) + { + aHeader.nXPelsPerMeter = basegfx::fround(rAcc.Width() / fabs(fBmpWidthM)); + aHeader.nYPelsPerMeter = basegfx::fround(rAcc.Height() / fabs(fBmpHeightM)); + } + } + + aHeader.nColsUsed = ((!pAccAlpha && aHeader.nBitCount <= 8) ? rAcc.GetPaletteEntryCount() : 0); + aHeader.nColsImportant = 0; + + rOStm << aHeader.nSize; + rOStm << aHeader.nWidth; + rOStm << aHeader.nHeight; + rOStm << aHeader.nPlanes; + rOStm << aHeader.nBitCount; + rOStm << aHeader.nCompression; + + nImageSizePos = rOStm.Tell(); + rOStm.SeekRel( sizeof( aHeader.nSizeImage ) ); + + rOStm << aHeader.nXPelsPerMeter; + rOStm << aHeader.nYPelsPerMeter; + rOStm << aHeader.nColsUsed; + rOStm << aHeader.nColsImportant; + + if(pAccAlpha) // only write DIBV5 when asked to do so + { + aHeader.nV5CSType = 0x57696E20; // LCS_WINDOWS_COLOR_SPACE + aHeader.nV5Intent = 0x00000008; // LCS_GM_ABS_COLORIMETRIC + + rOStm << aHeader.nV5RedMask; + rOStm << aHeader.nV5GreenMask; + rOStm << aHeader.nV5BlueMask; + rOStm << aHeader.nV5AlphaMask; + rOStm << aHeader.nV5CSType; + + rOStm << aHeader.aV5Endpoints.aXyzRed.aXyzX; + rOStm << aHeader.aV5Endpoints.aXyzRed.aXyzY; + rOStm << aHeader.aV5Endpoints.aXyzRed.aXyzZ; + rOStm << aHeader.aV5Endpoints.aXyzGreen.aXyzX; + rOStm << aHeader.aV5Endpoints.aXyzGreen.aXyzY; + rOStm << aHeader.aV5Endpoints.aXyzGreen.aXyzZ; + rOStm << aHeader.aV5Endpoints.aXyzBlue.aXyzX; + rOStm << aHeader.aV5Endpoints.aXyzBlue.aXyzY; + rOStm << aHeader.aV5Endpoints.aXyzBlue.aXyzZ; + + rOStm << aHeader.nV5GammaRed; + rOStm << aHeader.nV5GammaGreen; + rOStm << aHeader.nV5GammaBlue; + rOStm << aHeader.nV5Intent; + rOStm << aHeader.nV5ProfileData; + rOStm << aHeader.nV5ProfileSize; + rOStm << aHeader.nV5Reserved; + } + + if(ZCOMPRESS == aHeader.nCompression) + { + ZCodec aCodec; + SvMemoryStream aMemStm(aHeader.nSizeImage + 4096, 65535); + sal_uLong nCodedPos(rOStm.Tell()); + sal_uLong nLastPos(0); + sal_uInt32 nCodedSize(0); + sal_uInt32 nUncodedSize(0); + + // write uncoded data palette + if(aHeader.nColsUsed) + { + ImplWriteDIBPalette(aMemStm, rAcc); + } + + // write uncoded bits + bRet = ImplWriteDIBBits(aMemStm, rAcc, pAccAlpha, nCompression, aHeader.nSizeImage); + + // get uncoded size + nUncodedSize = aMemStm.Tell(); + + // seek over compress info + rOStm.SeekRel(12); + + // write compressed data + aCodec.BeginCompression(3); + aCodec.Write(rOStm, (sal_uInt8*)aMemStm.GetData(), nUncodedSize); + aCodec.EndCompression(); + + // update compress info ( coded size, uncoded size, uncoded compression ) + nLastPos = rOStm.Tell(); + nCodedSize = nLastPos - nCodedPos - 12; + rOStm.Seek(nCodedPos); + rOStm << nCodedSize << nUncodedSize << nCompression; + rOStm.Seek(nLastPos); + + if(bRet) + { + bRet = (ERRCODE_NONE == rOStm.GetError()); + } + } + else + { + if(aHeader.nColsUsed) + { + ImplWriteDIBPalette(rOStm, rAcc); + } + + bRet = ImplWriteDIBBits(rOStm, rAcc, pAccAlpha, aHeader.nCompression, aHeader.nSizeImage); + } + + nEndPos = rOStm.Tell(); + rOStm.Seek(nImageSizePos); + rOStm << aHeader.nSizeImage; + rOStm.Seek(nEndPos); + + return bRet; +} + +bool ImplWriteDIBFileHeader(SvStream& rOStm, BitmapReadAccess& rAcc, bool bUseDIBV5) +{ + const sal_uInt32 nPalCount((rAcc.HasPalette() ? rAcc.GetPaletteEntryCount() : isBitfieldCompression(rAcc.GetScanlineFormat()) ? 3UL : 0UL)); + const sal_uInt32 nOffset(14 + (bUseDIBV5 ? DIBV5HEADERSIZE : DIBINFOHEADERSIZE) + nPalCount * 4UL); + + rOStm << (sal_uInt16)0x4D42; // 'MB' from BITMAPFILEHEADER + rOStm << (sal_uInt32)(nOffset + (rAcc.Height() * rAcc.GetScanlineSize())); + rOStm << (sal_uInt16)0; + rOStm << (sal_uInt16)0; + rOStm << nOffset; + + return( rOStm.GetError() == 0UL ); +} + +////////////////////////////////////////////////////////////////////////////// + +bool ImplReadDIB( + Bitmap& rTarget, Bitmap* + pTargetAlpha, + SvStream& rIStm, + bool bFileHeader) +{ + const sal_uInt16 nOldFormat(rIStm.GetNumberFormatInt()); + const sal_uLong nOldPos(rIStm.Tell()); + sal_uLong nOffset(0UL); + bool bRet(false); + + rIStm.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN); + + if(bFileHeader) + { + if(ImplReadDIBFileHeader(rIStm, nOffset)) + { + bRet = ImplReadDIBBody(rIStm, rTarget, nOffset >= DIBV5HEADERSIZE ? pTargetAlpha : 0, nOffset); + } + } + else + { + bRet = ImplReadDIBBody(rIStm, rTarget, 0, nOffset); + } + + if(!bRet) + { + if(!rIStm.GetError()) + { + rIStm.SetError(SVSTREAM_GENERALERROR); + } + + rIStm.Seek(nOldPos); + } + + rIStm.SetNumberFormatInt(nOldFormat); + + return bRet; +} + +bool ImplWriteDIB( + const Bitmap& rSource, + const Bitmap* pSourceAlpha, + SvStream& rOStm, + bool bCompressed, + bool bFileHeader) +{ + const Size aSizePix(rSource.GetSizePixel()); + bool bRet(false); + + if(aSizePix.Width() && aSizePix.Height()) + { + BitmapReadAccess* pAcc = const_cast< Bitmap& >(rSource).AcquireReadAccess(); + BitmapReadAccess* pAccAlpha = 0; + const sal_uInt16 nOldFormat(rOStm.GetNumberFormatInt()); + const sal_uLong nOldPos(rOStm.Tell()); + + if(pSourceAlpha) + { + const Size aSizePixAlpha(pSourceAlpha->GetSizePixel()); + + if(aSizePixAlpha == aSizePix) + { + pAccAlpha = const_cast< Bitmap* >(pSourceAlpha)->AcquireReadAccess(); + } + else + { + OSL_ENSURE(false, "WriteDIB got an alpha channel, but it's pixel size differs from the base bitmap (!)"); + } + } + + rOStm.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN); + + if(pAcc) + { + if(bFileHeader) + { + if(ImplWriteDIBFileHeader(rOStm, *pAcc, 0 != pSourceAlpha)) + { + bRet = ImplWriteDIBBody(rSource, rOStm, *pAcc, pAccAlpha, bCompressed); + } + } + else + { + bRet = ImplWriteDIBBody(rSource, rOStm, *pAcc, pAccAlpha, bCompressed); + } + + const_cast< Bitmap& >(rSource).ReleaseAccess(pAcc); + + if(pAccAlpha) + { + const_cast< Bitmap* >(pSourceAlpha)->ReleaseAccess(pAccAlpha); + } + } + + if(!bRet) + { + rOStm.SetError(SVSTREAM_GENERALERROR); + rOStm.Seek(nOldPos); + } + + rOStm.SetNumberFormatInt(nOldFormat); + } + + return bRet; +} + +////////////////////////////////////////////////////////////////////////////// + +bool ReadDIB( + Bitmap& rTarget, + SvStream& rIStm, + bool bFileHeader) +{ + return ImplReadDIB(rTarget, 0, rIStm, bFileHeader); +} + +bool ReadDIBBitmapEx( + BitmapEx& rTarget, + SvStream& rIStm) +{ + Bitmap aBmp; + bool bRetval(ImplReadDIB(aBmp, 0, rIStm, true) && !rIStm.GetError()); + + if(bRetval) + { + // base bitmap was read, set as return value and try to read alpha extra-data + const sal_uLong nStmPos(rIStm.Tell()); + sal_uInt32 nMagic1(0); + sal_uInt32 nMagic2(0); + + rTarget = BitmapEx(aBmp); + rIStm >> nMagic1 >> nMagic2; + bRetval = (0x25091962 == nMagic1) && (0xACB20201 == nMagic2) && !rIStm.GetError(); + + if(bRetval) + { + sal_uInt8 bTransparent(false); + + rIStm >> bTransparent; + bRetval = !rIStm.GetError(); + + if(bRetval) + { + if((sal_uInt8)TRANSPARENT_BITMAP == bTransparent) + { + Bitmap aMask; + + bRetval = ImplReadDIB(aMask, 0, rIStm, true); + + if(bRetval) + { + if(!!aMask) + { + // do we have an alpha mask? + if((8 == aMask.GetBitCount()) && aMask.HasGreyPalette()) + { + AlphaMask aAlpha; + + // create alpha mask quickly (without greyscale conversion) + aAlpha.ImplSetBitmap(aMask); + rTarget = BitmapEx(aBmp, aAlpha); + } + else + { + rTarget = BitmapEx(aBmp, aMask); + } + } + } + } + else if((sal_uInt8)TRANSPARENT_COLOR == bTransparent) + { + Color aTransparentColor; + + rIStm >> aTransparentColor; + bRetval = !rIStm.GetError(); + + if(bRetval) + { + rTarget = BitmapEx(aBmp, aTransparentColor); + } + } + } + } + + if(!bRetval) + { + // alpha extra data could not be read; reset, but use base bitmap as result + rIStm.ResetError(); + rIStm.Seek(nStmPos); + bRetval = true; + } + } + + return bRetval; +} + +bool ReadDIBV5( + Bitmap& rTarget, + Bitmap& rTargetAlpha, + SvStream& rIStm) +{ + return ImplReadDIB(rTarget, &rTargetAlpha, rIStm, true); +} + +////////////////////////////////////////////////////////////////////////////// + +bool WriteDIB( + const Bitmap& rSource, + SvStream& rOStm, + bool bCompressed, + bool bFileHeader) +{ + return ImplWriteDIB(rSource, 0, rOStm, bCompressed, bFileHeader); +} + +bool WriteDIBBitmapEx( + const BitmapEx& rSource, + SvStream& rOStm) +{ + if(ImplWriteDIB(rSource.GetBitmap(), 0, rOStm, true, true)) + { + rOStm << (sal_uInt32)0x25091962; + rOStm << (sal_uInt32)0xACB20201; + rOStm << (sal_uInt8)rSource.eTransparent; + + if(TRANSPARENT_BITMAP == rSource.eTransparent) + { + return ImplWriteDIB(rSource.aMask, 0, rOStm, true, true); + } + else if(TRANSPARENT_COLOR == rSource.eTransparent) + { + rOStm << rSource.aTransparentColor; + return true; + } + } + + return false; +} + +bool WriteDIBV5( + const Bitmap& rSource, + const Bitmap& rSourceAlpha, + SvStream& rOStm) +{ + return ImplWriteDIB(rSource, &rSourceAlpha, rOStm, false, true); +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 2786b6deaa8f..7132284d6b12 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -36,6 +36,7 @@ #include <vcl/metaact.hxx> #include <impgraph.hxx> #include <com/sun/star/ucb/CommandAbortedException.hpp> +#include <vcl/dibtools.hxx> #define GRAPHIC_MAXPARTLEN 256000L #define GRAPHIC_MTFTOBMP_MAXEXT 2048 @@ -1652,7 +1653,7 @@ SvStream& operator>>( SvStream& rIStm, ImpGraphic& rImpGraphic ) rIStm.SeekRel( -4 ); rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - rIStm >> aBmpEx; + ReadDIBBitmapEx(aBmpEx, rIStm); if( !rIStm.GetError() ) { @@ -1794,7 +1795,7 @@ SvStream& operator<<( SvStream& rOStm, const ImpGraphic& rImpGraphic ) } else { - rOStm << rImpGraphic.maEx; + WriteDIBBitmapEx(rImpGraphic.maEx, rOStm); } } break; diff --git a/vcl/source/gdi/impimagetree.cxx b/vcl/source/gdi/impimagetree.cxx index 1ab5e23bf911..1bb37cab1fd1 100644 --- a/vcl/source/gdi/impimagetree.cxx +++ b/vcl/source/gdi/impimagetree.cxx @@ -31,23 +31,20 @@ #include "com/sun/star/uno/Exception.hpp" #include "com/sun/star/uno/RuntimeException.hpp" #include "com/sun/star/uno/Sequence.hxx" - #include "comphelper/processfactory.hxx" - #include "osl/file.hxx" #include "osl/diagnose.h" - #include "rtl/bootstrap.hxx" #include "tools/stream.hxx" #include "tools/urlobj.hxx" - #include "vcl/bitmapex.hxx" +#include <vcl/dibtools.hxx> #include "vcl/pngread.hxx" #include "vcl/settings.hxx" #include "vcl/svapp.hxx" - #include "impimagetree.hxx" +#include <vcl/dibtools.hxx> namespace { @@ -109,7 +106,7 @@ static void loadImageFromStream( aPNGReader.SetIgnoreGammaChunk( true ); rBitmap = aPNGReader.Read(); } else { - *pStream >> rBitmap; + ReadDIBBitmapEx(rBitmap, *pStream); } } diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 6b684fb11e5b..ed066a2b9cf9 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -22,6 +22,7 @@ #include <tools/stream.hxx> #include <tools/vcompat.hxx> #include <tools/helpers.hxx> +#include <vcl/dibtools.hxx> #include <vcl/outdev.hxx> #include <vcl/metaact.hxx> #include <vcl/graphictools.hxx> @@ -1770,7 +1771,8 @@ void MetaBmpAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) if( !!maBmp ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmp << maPt; + WriteDIB(maBmp, rOStm, false, true); + rOStm << maPt; } } @@ -1779,7 +1781,8 @@ void MetaBmpAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) void MetaBmpAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmp >> maPt; + ReadDIB(maBmp, rIStm, true); + rIStm >> maPt; } // ======================================================================== @@ -1846,7 +1849,8 @@ void MetaBmpScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) if( !!maBmp ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmp << maPt << maSz; + WriteDIB(maBmp, rOStm, false, true); + rOStm << maPt << maSz; } } @@ -1855,7 +1859,8 @@ void MetaBmpScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) void MetaBmpScaleAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmp >> maPt >> maSz; + ReadDIB(maBmp, rIStm, true); + rIStm >> maPt >> maSz; } // ======================================================================== @@ -1927,7 +1932,8 @@ void MetaBmpScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) if( !!maBmp ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmp << maDstPt << maDstSz << maSrcPt << maSrcSz; + WriteDIB(maBmp, rOStm, false, true); + rOStm << maDstPt << maDstSz << maSrcPt << maSrcSz; } } @@ -1936,7 +1942,8 @@ void MetaBmpScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) void MetaBmpScalePartAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmp >> maDstPt >> maDstSz >> maSrcPt >> maSrcSz; + ReadDIB(maBmp, rIStm, true); + rIStm >> maDstPt >> maDstSz >> maSrcPt >> maSrcSz; } // ======================================================================== @@ -1997,7 +2004,8 @@ void MetaBmpExAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) if( !!maBmpEx.GetBitmap() ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmpEx << maPt; + WriteDIBBitmapEx(maBmpEx, rOStm); + rOStm << maPt; } } @@ -2006,7 +2014,8 @@ void MetaBmpExAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) void MetaBmpExAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmpEx >> maPt; + ReadDIBBitmapEx(maBmpEx, rIStm); + rIStm >> maPt; } // ======================================================================== @@ -2073,7 +2082,8 @@ void MetaBmpExScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) if( !!maBmpEx.GetBitmap() ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmpEx << maPt << maSz; + WriteDIBBitmapEx(maBmpEx, rOStm); + rOStm << maPt << maSz; } } @@ -2082,7 +2092,8 @@ void MetaBmpExScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) void MetaBmpExScaleAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmpEx >> maPt >> maSz; + ReadDIBBitmapEx(maBmpEx, rIStm); + rIStm >> maPt >> maSz; } // ======================================================================== @@ -2154,7 +2165,8 @@ void MetaBmpExScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData if( !!maBmpEx.GetBitmap() ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmpEx << maDstPt << maDstSz << maSrcPt << maSrcSz; + WriteDIBBitmapEx(maBmpEx, rOStm); + rOStm << maDstPt << maDstSz << maSrcPt << maSrcSz; } } @@ -2163,7 +2175,8 @@ void MetaBmpExScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData void MetaBmpExScalePartAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmpEx >> maDstPt >> maDstSz >> maSrcPt >> maSrcSz; + ReadDIBBitmapEx(maBmpEx, rIStm); + rIStm >> maDstPt >> maDstSz >> maSrcPt >> maSrcSz; } // ======================================================================== @@ -2228,7 +2241,8 @@ void MetaMaskAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) if( !!maBmp ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmp << maPt; + WriteDIB(maBmp, rOStm, false, true); + rOStm << maPt; } } @@ -2237,7 +2251,8 @@ void MetaMaskAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) void MetaMaskAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmp >> maPt; + ReadDIB(maBmp, rIStm, true); + rIStm >> maPt; } // ======================================================================== @@ -2307,7 +2322,8 @@ void MetaMaskScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) if( !!maBmp ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmp << maPt << maSz; + WriteDIB(maBmp, rOStm, false, true); + rOStm << maPt << maSz; } } @@ -2316,7 +2332,8 @@ void MetaMaskScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) void MetaMaskScaleAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmp >> maPt >> maSz; + ReadDIB(maBmp, rIStm, true); + rIStm >> maPt >> maSz; } // ======================================================================== @@ -2391,7 +2408,7 @@ void MetaMaskScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) if( !!maBmp ) { WRITE_BASE_COMPAT( rOStm, 1, pData ); - rOStm << maBmp; + WriteDIB(maBmp, rOStm, false, true); maColor.Write( rOStm, sal_True ); rOStm << maDstPt << maDstSz << maSrcPt << maSrcSz; } @@ -2402,7 +2419,7 @@ void MetaMaskScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) void MetaMaskScalePartAction::Read( SvStream& rIStm, ImplMetaReadData* ) { COMPAT( rIStm ); - rIStm >> maBmp; + ReadDIB(maBmp, rIStm, true); maColor.Read( rIStm, sal_True ); rIStm >> maDstPt >> maDstSz >> maSrcPt >> maSrcSz; } diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx index 56765434b943..c38186baab11 100644 --- a/vcl/source/gdi/pdfwriter_impl2.cxx +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -166,7 +166,7 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz SvMemoryStream aTemp; aTemp.SetCompressMode( aTemp.GetCompressMode() | COMPRESSMODE_ZBITMAP ); aTemp.SetVersion( SOFFICE_FILEFORMAT_40 ); // sj: up from version 40 our bitmap stream operator - aTemp << aBitmapEx; // is capable of zlib stream compression + WriteDIBBitmapEx(aBitmapEx, aTemp); // is capable of zlib stream compression aTemp.Seek( STREAM_SEEK_TO_END ); nZippedFileSize = aTemp.Tell(); } diff --git a/vcl/source/gdi/wall.cxx b/vcl/source/gdi/wall.cxx index 5c2522de02db..b6a00293080d 100644 --- a/vcl/source/gdi/wall.cxx +++ b/vcl/source/gdi/wall.cxx @@ -17,18 +17,15 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <tools/stream.hxx> #include <tools/vcompat.hxx> #include <tools/debug.hxx> - #include <vcl/bitmapex.hxx> #include <vcl/gradient.hxx> #include <vcl/wall.hxx> #include <vcl/svapp.hxx> - #include <wall2.hxx> - +#include <vcl/dibtools.hxx> DBG_NAME( Wallpaper ) @@ -141,7 +138,7 @@ SvStream& operator>>( SvStream& rIStm, ImplWallpaper& rImplWallpaper ) if( bBmp ) { rImplWallpaper.mpBitmap = new BitmapEx; - rIStm >> *rImplWallpaper.mpBitmap; + ReadDIBBitmapEx(*rImplWallpaper.mpBitmap, rIStm); } // version 3 (new color format) @@ -177,7 +174,7 @@ SvStream& operator<<( SvStream& rOStm, const ImplWallpaper& rImplWallpaper ) rOStm << *rImplWallpaper.mpGradient; if( bBmp ) - rOStm << *rImplWallpaper.mpBitmap; + WriteDIBBitmapEx(*rImplWallpaper.mpBitmap, rOStm); // version 3 (new color format) ( (Color&) rImplWallpaper.maColor ).Write( rOStm, sal_True ); |