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 ] ]));
+                }
+            }
+        }
+    }
 }
 
 // ------------------------------------------------------------------------


Reply via email to