Author: alg
Date: Thu Sep 5 13:01:45 2013
New Revision: 1520296
URL: http://svn.apache.org/r1520296
Log:
i122985 Various speedups for graphic object swapping to enhance user experience
Modified:
openoffice/trunk/main/svtools/source/filter/jpeg/jpeg.cxx
openoffice/trunk/main/svx/inc/svx/svdundo.hxx
openoffice/trunk/main/svx/source/svdraw/svdograf.cxx
openoffice/trunk/main/svx/source/svdraw/svdundo.cxx
openoffice/trunk/main/vcl/source/gdi/pngread.cxx
Modified: openoffice/trunk/main/svtools/source/filter/jpeg/jpeg.cxx
URL:
http://svn.apache.org/viewvc/openoffice/trunk/main/svtools/source/filter/jpeg/jpeg.cxx?rev=1520296&r1=1520295&r2=1520296&view=diff
==============================================================================
--- openoffice/trunk/main/svtools/source/filter/jpeg/jpeg.cxx (original)
+++ openoffice/trunk/main/svtools/source/filter/jpeg/jpeg.cxx Thu Sep 5
13:01:45 2013
@@ -474,15 +474,39 @@ void JPEGReader::FillBitmap()
for( long nY = 0L; nY < nHeight; nY++ )
{
- pTmp = (sal_uInt8*) pBuffer + nY *
nAlignedWidth;
+ // #122985# Added fast-lane implementations using CopyScanline
with direct supported mem formats
+ static bool bCheckOwnReader(true);
- for( long nX = 0L; nX < nWidth; nX++ )
- {
- aColor.SetRed( *pTmp++ );
- aColor.SetGreen( *pTmp++ );
- aColor.SetBlue( *pTmp++ );
- pAcc->SetPixel( nY, nX, aColor );
- }
+ if(bCheckOwnReader)
+ {
+ // #122985# Trying to copy the RGB data from jpeg import
to make things faster. Unfortunately
+ // it has no GBR format, so RGB three-byte groups need to
be 'flipped' to GBR first,
+ // then CopyScanline can use a memcpy to do the data
transport. CopyScanline can also
+ // do the needed conversion from BMP_FORMAT_24BIT_TC_RGB
(and it works well), but this
+ // is not faster that the old loop below using SetPixel.
+ sal_uInt8* aSource((sal_uInt8*)pBuffer + nY *
nAlignedWidth);
+ sal_uInt8* aEnd(aSource + (nWidth * 3));
+
+ for(sal_uInt8* aTmp(aSource); aTmp < aEnd; aTmp += 3)
+ {
+ ::std::swap(*aTmp, *(aTmp + 2));
+ }
+
+ pAcc->CopyScanline(nY, aSource, BMP_FORMAT_24BIT_TC_BGR,
nWidth * 3);
+ }
+ else
+ {
+ // old version: WritePixel
+ pTmp = (sal_uInt8*) pBuffer + nY * nAlignedWidth;
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aColor.SetRed( *pTmp++ );
+ aColor.SetGreen( *pTmp++ );
+ aColor.SetBlue( *pTmp++ );
+ pAcc->SetPixel( nY, nX, aColor );
+ }
+ }
}
}
}
Modified: openoffice/trunk/main/svx/inc/svx/svdundo.hxx
URL:
http://svn.apache.org/viewvc/openoffice/trunk/main/svx/inc/svx/svdundo.hxx?rev=1520296&r1=1520295&r2=1520296&view=diff
==============================================================================
--- openoffice/trunk/main/svx/inc/svx/svdundo.hxx (original)
+++ openoffice/trunk/main/svx/inc/svx/svdundo.hxx Thu Sep 5 13:01:45 2013
@@ -335,19 +335,21 @@ public:
class SVX_DLLPUBLIC SdrUndoDelObj : public SdrUndoRemoveObj
{
+private:
+ void TryToFlushGraphicContent();
+
public:
- SdrUndoDelObj(SdrObject& rNewObj, FASTBOOL bOrdNumDirect=sal_False)
- : SdrUndoRemoveObj(rNewObj,bOrdNumDirect) { SetOwner(sal_True); }
- virtual ~SdrUndoDelObj() {}
+ SdrUndoDelObj(SdrObject& rNewObj, FASTBOOL bOrdNumDirect=sal_False);
+ virtual ~SdrUndoDelObj();
- virtual void Undo();
- virtual void Redo();
+ virtual void Undo();
+ virtual void Redo();
- virtual String GetComment() const;
- virtual String GetSdrRepeatComment(SdrView& rView) const;
+ virtual String GetComment() const;
+ virtual String GetSdrRepeatComment(SdrView& rView) const;
- virtual void SdrRepeat(SdrView& rView);
- virtual bool CanSdrRepeat(SdrView& rView) const;
+ virtual void SdrRepeat(SdrView& rView);
+ virtual bool CanSdrRepeat(SdrView& rView) const;
};
//************************************************************
Modified: openoffice/trunk/main/svx/source/svdraw/svdograf.cxx
URL:
http://svn.apache.org/viewvc/openoffice/trunk/main/svx/source/svdraw/svdograf.cxx?rev=1520296&r1=1520295&r2=1520296&view=diff
==============================================================================
--- openoffice/trunk/main/svx/source/svdraw/svdograf.cxx (original)
+++ openoffice/trunk/main/svx/source/svdraw/svdograf.cxx Thu Sep 5 13:01:45
2013
@@ -69,6 +69,7 @@
#include <vos/mutex.hxx>
#include <drawinglayer/processor2d/objectinfoextractor2d.hxx>
#include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
+#include <unotools/cacheoptions.hxx>
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::io;
@@ -80,6 +81,37 @@ using namespace ::com::sun::star::io;
#define GRAFSTREAMPOS_INVALID 0xffffffff
#define SWAPGRAPHIC_TIMEOUT 5000
+// #122985# it is not correct to se the swap-timeout to a hard-coded 5000ms as
it was before.
+// Added code and experimented what to do as a good compromize, see description
+sal_uInt32 getCacheTimeInMs()
+{
+ static bool bSetAtAll(true);
+
+ if(bSetAtAll)
+ {
+ static bool bSetToPreferenceTime(true);
+
+ if(bSetToPreferenceTime)
+ {
+ const SvtCacheOptions aCacheOptions;
+ const sal_Int32
nSeconds(aCacheOptions.GetGraphicManagerObjectReleaseTime());
+
+ // the default is 10 minutes. The minimum is one minute, thus 60
seconds. When the minimum
+ // should match to the former hard-coded 5 seconds, we have a
divisor of 12 to use. For the
+ // default of 10 minutes this would mean 50 seconds. Compared to
before this is ten times
+ // more (would allow better navigation by switching through pages)
and is controllable
+ // by the user by setting the
tools/options/memory/Remove_from_memory_after setting. Seems
+ // to be a good compromize to me.
+ return nSeconds * 1000 / 12;
+ }
+ else
+ {
+ return SWAPGRAPHIC_TIMEOUT;
+ }
+ }
+
+ return 0;
+}
// ------------------
// - SdrGraphicLink -
@@ -375,7 +407,7 @@ SdrGrafObj::SdrGrafObj()
{
pGraphic = new GraphicObject;
mpReplacementGraphic = 0;
- pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ),
SWAPGRAPHIC_TIMEOUT );
+ pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ),
getCacheTimeInMs() );
onGraphicChanged();
// #i118485# Shear allowed and possible now
@@ -402,7 +434,7 @@ SdrGrafObj::SdrGrafObj(const Graphic& rG
{
pGraphic = new GraphicObject( rGrf );
mpReplacementGraphic = 0;
- pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ),
SWAPGRAPHIC_TIMEOUT );
+ pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ),
getCacheTimeInMs() );
onGraphicChanged();
// #i118485# Shear allowed and possible now
@@ -429,7 +461,7 @@ SdrGrafObj::SdrGrafObj( const Graphic& r
{
pGraphic = new GraphicObject( rGrf );
mpReplacementGraphic = 0;
- pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ),
SWAPGRAPHIC_TIMEOUT );
+ pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ),
getCacheTimeInMs() );
onGraphicChanged();
// #i118485# Shear allowed and possible now
@@ -463,7 +495,7 @@ void SdrGrafObj::SetGraphicObject( const
*pGraphic = rGrfObj;
delete mpReplacementGraphic;
mpReplacementGraphic = 0;
- pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ),
SWAPGRAPHIC_TIMEOUT );
+ pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ),
getCacheTimeInMs() );
pGraphic->SetUserData();
mbIsPreview = sal_False;
SetChanged();
Modified: openoffice/trunk/main/svx/source/svdraw/svdundo.cxx
URL:
http://svn.apache.org/viewvc/openoffice/trunk/main/svx/source/svdraw/svdundo.cxx?rev=1520296&r1=1520295&r2=1520296&view=diff
==============================================================================
--- openoffice/trunk/main/svx/source/svdraw/svdundo.cxx (original)
+++ openoffice/trunk/main/svx/source/svdraw/svdundo.cxx Thu Sep 5 13:01:45 2013
@@ -42,8 +42,9 @@
#include <svx/svdocapt.hxx>
#include <svl/whiter.hxx>
#include <svx/e3dsceneupdater.hxx>
-
-#include "svx/svdviter.hxx"
+#include <svx/svdviter.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/sdr/contact/viewcontactofgraphic.hxx>
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -882,6 +883,38 @@ void SdrUndoInsertObj::Redo()
////////////////////////////////////////////////////////////////////////////////////////////////////
+void SdrUndoDelObj::TryToFlushGraphicContent()
+{
+ SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
+
+ if(pSdrGrafObj)
+ {
+ sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast<
sdr::contact::ViewContactOfGraphic* >(&pSdrGrafObj->GetViewContact());
+
+ if(pVC)
+ {
+ pVC->flushViewObjectContacts();
+ pVC->flushGraphicObjects();
+ }
+
+ pSdrGrafObj->ForceSwapOut();
+ }
+}
+
+SdrUndoDelObj::SdrUndoDelObj(SdrObject& rNewObj, FASTBOOL bOrdNumDirect)
+: SdrUndoRemoveObj(rNewObj,bOrdNumDirect)
+{
+ SetOwner(sal_True);
+
+ // #122985# if graphic object is deleted (but goes to undo) flush it's
graphic content
+ // since it is potentially no longer needed
+ TryToFlushGraphicContent();
+}
+
+SdrUndoDelObj::~SdrUndoDelObj()
+{
+}
+
void SdrUndoDelObj::Undo()
{
SdrUndoRemoveObj::Undo();
@@ -894,6 +927,10 @@ void SdrUndoDelObj::Redo()
SdrUndoRemoveObj::Redo();
DBG_ASSERT(!IsOwner(),"RedoDeleteObj: pObj gehoert bereits der
UndoAction");
SetOwner(sal_True);
+
+ // #122985# if graphic object is deleted (but goes to undo) flush it's
graphic content
+ // since it is potentially no longer needed
+ TryToFlushGraphicContent();
}
XubString SdrUndoDelObj::GetComment() const
Modified: openoffice/trunk/main/vcl/source/gdi/pngread.cxx
URL:
http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/pngread.cxx?rev=1520296&r1=1520295&r2=1520296&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/source/gdi/pngread.cxx (original)
+++ openoffice/trunk/main/vcl/source/gdi/pngread.cxx Thu Sep 5 13:01:45 2013
@@ -151,6 +151,15 @@ private:
sal_Bool mbpHYs; //
sal_True if pysical size of pixel available
sal_Bool mbIgnoreGammaChunk;
+#ifdef DBG_UTIL
+ // do some checks in debug mode
+ sal_uInt32 mnAllocSizeScanline;
+ sal_uInt32 mnAllocSizeScanlineAlpha;
+#endif
+ // the temporary Scanline (and alpha) for direct scanline copy to Bitmap
+ sal_uInt8* mpScanline;
+ sal_uInt8* mpScanlineAlpha;
+
bool ReadNextChunk();
void ReadRemainingChunks();
void SkipRemainingChunks();
@@ -204,7 +213,13 @@ PNGReaderImpl::PNGReaderImpl( SvStream&
mbIDAT( sal_False ),
mbGamma ( sal_False ),
mbpHYs ( sal_False ),
- mbIgnoreGammaChunk ( sal_False )
+ mbIgnoreGammaChunk ( sal_False ),
+#ifdef DBG_UTIL
+ mnAllocSizeScanline(0),
+ mnAllocSizeScanlineAlpha(0),
+#endif
+ mpScanline(0),
+ mpScanlineAlpha(0)
{
// prepare the PNG data stream
mnOrigStreamMode = mrPNGStream.GetNumberFormatInt();
@@ -250,6 +265,9 @@ PNGReaderImpl::~PNGReaderImpl()
delete[] mpInflateInBuf;
delete[] mpScanPrior;
delete mpZCodec;
+
+ delete[] mpScanline;
+ delete[] mpScanlineAlpha;
}
// ------------------------------------------------------------------------
@@ -1358,110 +1376,247 @@ void PNGReaderImpl::ImplDrawScanline( sa
}
else // no palette => truecolor
{
- if( mbAlphaChannel ) // has RGB + alpha
- { // BMP_FORMAT_32BIT_TC_RGBA
- if ( mnPngDepth == 8 ) // maybe the source has 16 bit
per sample
- {
- if ( mpColorTable != mpDefaultColorTable )
+ // #122985# Added fast-lane implementations using CopyScanline with
direct supported mem formats
+ static bool bCkeckDirectScanline(true);
+
+ if( mbAlphaChannel )
+ {
+ // has RGB + alpha
+ if ( mnPngDepth == 8 ) // maybe the source has 16 bit per sample
+ {
+ // BMP_FORMAT_32BIT_TC_RGBA
+ // only use DirectScanline when we have no preview shifting
stuff and accesses to content and alpha
+ const bool bDoDirectScanline(
+ bCkeckDirectScanline && !nXStart && 1 == nXAdd &&
!mnPreviewShift && mpAcc && mpMaskAcc);
+ const bool bCustomColorTable(mpColorTable !=
mpDefaultColorTable);
+
+ if(bDoDirectScanline)
{
- for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width(); nX
+= nXAdd, pTmp += 4 )
- ImplSetAlphaPixel( nY, nX, BitmapColor( mpColorTable[
pTmp[ 0 ] ],
- mpColorTable[
pTmp[ 1 ] ],
- mpColorTable[
pTmp[ 2 ] ] ), pTmp[ 3 ] );
+ // allocate scanlines on demand, reused for next line
+ if(!mpScanline)
+ {
+#ifdef DBG_UTIL
+ mnAllocSizeScanline = maOrigSize.Width() * 3;
+#endif
+ mpScanline = new sal_uInt8[maOrigSize.Width() * 3];
+ }
+
+ if(!mpScanlineAlpha)
+ {
+#ifdef DBG_UTIL
+ mnAllocSizeScanlineAlpha = maOrigSize.Width();
+#endif
+ mpScanlineAlpha = new sal_uInt8[maOrigSize.Width()];
+ }
+ }
+
+ if(bDoDirectScanline)
+ {
+ OSL_ENSURE(mpScanline, "No Scanline allocated (!)");
+ OSL_ENSURE(mpScanlineAlpha, "No ScanlineAlpha allocated
(!)");
+ OSL_ENSURE(mnAllocSizeScanline >= maOrigSize.Width() * 3,
"Allocated Scanline too small (!)");
+ OSL_ENSURE(mnAllocSizeScanlineAlpha >= maOrigSize.Width(),
"Allocated ScanlineAlpha too small (!)");
+ sal_uInt8* pScanline(mpScanline);
+ sal_uInt8* pScanlineAlpha(mpScanlineAlpha);
+
+ for(sal_uInt32 nX(0); nX < maOrigSize.Width(); nX++, pTmp
+= 4)
+ {
+ // prepare content line as BGR by reordering when
copying
+ // do not forget to invert alpha (source is alpha,
target is opacity)
+ if(bCustomColorTable)
+ {
+ *pScanline++ = mpColorTable[pTmp[2]];
+ *pScanline++ = mpColorTable[pTmp[1]];
+ *pScanline++ = mpColorTable[pTmp[0]];
+ *pScanlineAlpha++ = ~pTmp[3];
+ }
+ else
+ {
+ *pScanline++ = pTmp[2];
+ *pScanline++ = pTmp[1];
+ *pScanline++ = pTmp[0];
+ *pScanlineAlpha++ = ~pTmp[3];
+ }
+ }
+
+ // copy scanlines directly to bitmaps for content and
alpha; use the formats which
+ // are able to copy directly to BitmapBuffer
+ mpAcc->CopyScanline(nY, mpScanline,
BMP_FORMAT_24BIT_TC_BGR, maOrigSize.Width() * 3);
+ mpMaskAcc->CopyScanline(nY, mpScanlineAlpha,
BMP_FORMAT_8BIT_PAL, maOrigSize.Width());
}
else
{
-// if ( nXAdd == 1 && mnPreviewShift == 0 ) // copy raw line
data if possible
-// {
-// int nLineBytes = 4 * maOrigSize.Width();
-// mpAcc->CopyScanline( nY, pTmp,
BMP_FORMAT_32BIT_TC_RGBA, nLineBytes );
-// pTmp += nLineBytes;
-// }
-// else
+ for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width(); nX
+= nXAdd, pTmp += 4 )
{
- for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width();
nX += nXAdd, pTmp += 4 )
- ImplSetAlphaPixel( nY, nX, BitmapColor( pTmp[0],
pTmp[1], pTmp[2] ), pTmp[3] );
+ if(bCustomColorTable)
+ {
+ ImplSetAlphaPixel(
+ nY,
+ nX,
+ BitmapColor(
+ mpColorTable[ pTmp[ 0 ] ],
+ mpColorTable[ pTmp[ 1 ] ],
+ mpColorTable[ pTmp[ 2 ] ]),
+ pTmp[ 3 ]);
+ }
+ else
+ {
+ ImplSetAlphaPixel(
+ nY,
+ nX,
+ BitmapColor(
+ pTmp[0],
+ pTmp[1],
+ pTmp[2]),
+ pTmp[3]);
+ }
}
}
- }
- else
- { // BMP_FORMAT_64BIT_TC_RGBA
- for ( sal_Int32 nX = nXStart; nX <
maOrigSize.Width(); nX += nXAdd, pTmp += 8 )
- ImplSetAlphaPixel( nY, nX, BitmapColor(
mpColorTable[ pTmp[ 0 ] ],
-
mpColorTable[ pTmp[ 2 ] ],
-
mpColorTable[ pTmp[ 4 ] ] ), pTmp[6] );
- }
- }
- else if( mbTransparent ) // has RGB + transparency
- { // BMP_FORMAT_24BIT_TC_RGB
- if ( mnPngDepth == 8 ) // maybe the source has 16 bit
per sample
- {
- for ( sal_Int32 nX = nXStart; nX <
maOrigSize.Width(); nX += nXAdd, pTmp += 3 )
- {
- sal_uInt8 nRed = pTmp[ 0 ];
- sal_uInt8 nGreen = pTmp[ 1 ];
- sal_uInt8 nBlue = pTmp[ 2 ];
- sal_Bool bTransparent = ( ( nRed ==
mnTransRed )
-
&& ( nGreen == mnTransGreen )
-
&& ( nBlue == mnTransBlue ) );
-
- ImplSetTranspPixel( nY, nX,
BitmapColor( mpColorTable[ nRed ],
-
mpColorTable[ nGreen ],
-
mpColorTable[ nBlue ] ), bTransparent );
- }
- }
- else
- { // BMP_FORMAT_48BIT_TC_RGB
- for ( sal_Int32 nX = nXStart; nX <
maOrigSize.Width(); nX += nXAdd, pTmp += 6 )
- {
- sal_uInt8 nRed = pTmp[ 0 ];
- sal_uInt8 nGreen = pTmp[ 2 ];
- sal_uInt8 nBlue = pTmp[ 4 ];
- sal_Bool bTransparent = ( ( nRed ==
mnTransRed )
-
&& ( nGreen == mnTransGreen )
-
&& ( nBlue == mnTransBlue ) );
-
- ImplSetTranspPixel( nY, nX,
BitmapColor( mpColorTable[ nRed ],
-
mpColorTable[ nGreen ],
-
mpColorTable[ nBlue ] ), bTransparent );
- }
- }
- }
- else // has RGB but neither alpha nor transparency
- { // BMP_FORMAT_24BIT_TC_RGB
- if ( mnPngDepth == 8 ) // maybe the source has 16 bit
per sample
- {
- if ( mpColorTable != mpDefaultColorTable )
+ }
+ else
+ {
+ // BMP_FORMAT_64BIT_TC_RGBA
+ for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width(); nX +=
nXAdd, pTmp += 8 )
{
- for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width(); nX
+= nXAdd, pTmp += 3 )
- ImplSetPixel( nY, nX, BitmapColor( mpColorTable[ pTmp[
0 ] ],
- mpColorTable[
pTmp[ 1 ] ],
- mpColorTable[
pTmp[ 2 ] ] ) );
+ ImplSetAlphaPixel(
+ nY,
+ nX,
+ BitmapColor(
+ mpColorTable[ pTmp[ 0 ] ],
+ mpColorTable[ pTmp[ 2 ] ],
+ mpColorTable[ pTmp[ 4 ] ]),
+ pTmp[6]);
}
- else
+ }
+ }
+ else if( mbTransparent ) // has RGB + transparency
+ {
+ // BMP_FORMAT_24BIT_TC_RGB
+ // no support currently for DirectScanline, found no real usages
in current PNGs, may be added on demand
+ if ( mnPngDepth == 8 ) // maybe the source has 16 bit per sample
+ {
+ for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width(); nX +=
nXAdd, pTmp += 3 )
+ {
+ sal_uInt8 nRed = pTmp[ 0 ];
+ sal_uInt8 nGreen = pTmp[ 1 ];
+ sal_uInt8 nBlue = pTmp[ 2 ];
+ sal_Bool bTransparent = ( ( nRed == mnTransRed )
+ && ( nGreen == mnTransGreen )
+ && ( nBlue == mnTransBlue ) );
+
+ ImplSetTranspPixel( nY, nX, BitmapColor( mpColorTable[
nRed ],
+ mpColorTable[ nGreen ],
+ mpColorTable[ nBlue ]
), bTransparent );
+ }
+ }
+ else
+ {
+ // BMP_FORMAT_48BIT_TC_RGB
+ for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width(); nX +=
nXAdd, pTmp += 6 )
{
- if( nXAdd == 1 && mnPreviewShift == 0 ) // copy raw line
data if possible
+ sal_uInt8 nRed = pTmp[ 0 ];
+ sal_uInt8 nGreen = pTmp[ 2 ];
+ sal_uInt8 nBlue = pTmp[ 4 ];
+ sal_Bool bTransparent = ( ( nRed == mnTransRed )
+ && ( nGreen == mnTransGreen )
+ && ( nBlue == mnTransBlue ) );
+
+ ImplSetTranspPixel( nY, nX, BitmapColor( mpColorTable[
nRed ],
+ mpColorTable[ nGreen ],
+ mpColorTable[ nBlue ]
), bTransparent );
+ }
+ }
+ }
+ else // has RGB but neither alpha nor transparency
+ {
+ // BMP_FORMAT_24BIT_TC_RGB
+ // only use DirectScanline when we have no preview shifting stuff
and access to content
+ const bool bDoDirectScanline(
+ bCkeckDirectScanline && !nXStart && 1 == nXAdd &&
!mnPreviewShift && mpAcc);
+ const bool bCustomColorTable(mpColorTable != mpDefaultColorTable);
+
+ if(bDoDirectScanline && !mpScanline)
+ {
+ // allocate scanlines on demand, reused for next line
+#ifdef DBG_UTIL
+ mnAllocSizeScanline = maOrigSize.Width() * 3;
+#endif
+ mpScanline = new sal_uInt8[maOrigSize.Width() * 3];
+ }
+
+ if ( mnPngDepth == 8 ) // maybe the source has 16 bit per sample
+ {
+ if(bDoDirectScanline)
+ {
+ OSL_ENSURE(mpScanline, "No Scanline allocated (!)");
+ OSL_ENSURE(mnAllocSizeScanline >= maOrigSize.Width() * 3,
"Allocated Scanline too small (!)");
+ sal_uInt8* pScanline(mpScanline);
+
+ for(sal_uInt32 nX(0); nX < maOrigSize.Width(); nX++, pTmp
+= 3)
{
- int nLineBytes = maOrigSize.Width() * 3;
- mpAcc->CopyScanline( nY, pTmp,
BMP_FORMAT_24BIT_TC_RGB, nLineBytes );
- pTmp += nLineBytes;
+ // prepare content line as BGR by reordering when
copying
+ if(bCustomColorTable)
+ {
+ *pScanline++ = mpColorTable[pTmp[2]];
+ *pScanline++ = mpColorTable[pTmp[1]];
+ *pScanline++ = mpColorTable[pTmp[0]];
+ }
+ else
+ {
+ *pScanline++ = pTmp[2];
+ *pScanline++ = pTmp[1];
+ *pScanline++ = pTmp[0];
+ }
}
- else
+
+ // copy scanline directly to bitmap for content; use the
format which is able to
+ // copy directly to BitmapBuffer
+ mpAcc->CopyScanline(nY, mpScanline,
BMP_FORMAT_24BIT_TC_BGR, maOrigSize.Width() * 3);
+ }
+ else
+ {
+ for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width(); nX
+= nXAdd, pTmp += 3 )
{
- for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width();
nX += nXAdd, pTmp += 3 )
- ImplSetPixel( nY, nX, BitmapColor( pTmp[0],
pTmp[1], pTmp[2] ) );
+ if(bCustomColorTable)
+ {
+ ImplSetPixel(
+ nY,
+ nX,
+ BitmapColor(
+ mpColorTable[ pTmp[ 0 ] ],
+ mpColorTable[ pTmp[ 1 ] ],
+ mpColorTable[ pTmp[ 2 ] ]));
+ }
+ else
+ {
+ ImplSetPixel(
+ nY,
+ nX,
+ BitmapColor(
+ pTmp[0],
+ pTmp[1],
+ pTmp[2]));
+ }
}
}
- }
- else
- { // BMP_FORMAT_48BIT_TC_RGB
- for ( sal_Int32 nX = nXStart; nX <
maOrigSize.Width(); nX += nXAdd, pTmp += 6 )
- ImplSetPixel( nY, nX, BitmapColor(
mpColorTable[ pTmp[ 0 ] ],
-
mpColorTable[ pTmp[ 2 ] ],
-
mpColorTable[ pTmp[ 4 ] ] ) );
- }
- }
- }
+ }
+ else
+ {
+ // BMP_FORMAT_48BIT_TC_RGB
+ // no support currently for DirectScanline, found no real
usages in current PNGs, may be added on demand
+ for ( sal_Int32 nX = nXStart; nX < maOrigSize.Width(); nX +=
nXAdd, pTmp += 6 )
+ {
+ ImplSetPixel(
+ nY,
+ nX,
+ BitmapColor(
+ mpColorTable[ pTmp[ 0 ] ],
+ mpColorTable[ pTmp[ 2 ] ],
+ mpColorTable[ pTmp[ 4 ] ]));
+ }
+ }
+ }
+ }
}
// ------------------------------------------------------------------------