mmplugins/imagingplugins/codecs/JPEGCodec/rgbbufferptr.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <fbs.h>
       
    17 #include "JpegConsts.h"
       
    18 
       
    19 #include "rgbbufferptr.h"
       
    20 
       
    21 
       
    22 /*static*/
       
    23 CRgbBufferPtr* CRgbBufferPtr::NewL(CFbsBitmap& aBitmap, const TSize& aMCUSizeinPixels)
       
    24     {
       
    25     CRgbBufferPtr* self = new (ELeave) CRgbBufferPtr(aBitmap, aMCUSizeinPixels);
       
    26     CleanupStack::PushL(self);
       
    27     self->ConstructL();
       
    28     CleanupStack::Pop(self);
       
    29     return self;
       
    30     }
       
    31     
       
    32 CRgbBufferPtr::CRgbBufferPtr(CFbsBitmap& aBitmap, const TSize& aMCUSizeinPixels):
       
    33                                     iBitmapSize( aBitmap.SizeInPixels() ),
       
    34 									iMCUSizeinPixels( aMCUSizeinPixels ),
       
    35 									iBufferPos(-1,-1),
       
    36                                     iBitmap( &aBitmap )
       
    37     {
       
    38     }
       
    39     
       
    40 void CRgbBufferPtr::ConstructL()
       
    41     {
       
    42     if ((iBitmapSize.iWidth <= 0) || (iBitmapSize.iHeight <= 0))
       
    43     	{
       
    44     	User::Leave(KErrArgument);
       
    45     	}
       
    46     
       
    47     iBitmapData = iBitmap->DataAddress();
       
    48 	iBitmapScanlineLength = iBitmap->ScanLineLength(iBitmapSize.iWidth, iBitmap->DisplayMode());
       
    49 
       
    50 	if (iBitmap->DisplayMode() == EColor16M)
       
    51         {
       
    52         iBufferSizeInPixels.SetSize( iMCUSizeinPixels.iWidth, iMCUSizeinPixels.iHeight);
       
    53 		iBitmapDirectAccess = ETrue;
       
    54         }
       
    55     else
       
    56         {
       
    57         // we reduce number of bitmap round-robins using horizontally-widened buffer ONLY!
       
    58         TInt width = Max(iMCUSizeinPixels.iWidth, Min(iMCUSizeinPixels.iWidth<<2, iBitmapSize.iWidth));
       
    59         if (width == iBitmapSize.iWidth )
       
    60         	{
       
    61         	TInt oddPixels = width % iMCUSizeinPixels.iWidth;
       
    62         	if (oddPixels)
       
    63         		{
       
    64         		width += iMCUSizeinPixels.iWidth - oddPixels;
       
    65         		}
       
    66         	}
       
    67         iBufferSizeInPixels.SetSize( width, iMCUSizeinPixels.iHeight);
       
    68 		iBitmapDirectAccess = EFalse;
       
    69 		}
       
    70     
       
    71     iOriginalRgbBuffer = reinterpret_cast<TRgbBufferPtr>(User::AllocL(Coord2Size(iBufferSizeInPixels.iWidth, iBufferSizeInPixels.iHeight) + sizeof(TUint32)));
       
    72     iRgbBuffer = Align4(iOriginalRgbBuffer);
       
    73 	
       
    74     iBufferScanlineLength = iBufferSizeInPixels.iWidth * KRgbBufferPixelSize;
       
    75 	}
       
    76     
       
    77 CRgbBufferPtr::~CRgbBufferPtr()
       
    78     {
       
    79     User::Free( iOriginalRgbBuffer);
       
    80     iOriginalRgbBuffer = NULL;
       
    81     iRgbBuffer = NULL;    
       
    82     }
       
    83     
       
    84 
       
    85 CRgbBufferPtr::TConstRgbBufferPtr CRgbBufferPtr::LockBuffer(const TPoint& aTopLeft)
       
    86     {
       
    87     ASSERT( aTopLeft.iX < iBitmapSize.iWidth );
       
    88     ASSERT( aTopLeft.iY < iBitmapSize.iHeight );
       
    89     
       
    90     //const TBool KDirectAccess = ( iBitmap->DisplayMode() == EColor16M );
       
    91     const TBool KInplaceAccess= iBitmapDirectAccess;
       
    92     
       
    93     if ( !KInplaceAccess &&
       
    94          aTopLeft.iY >= iBufferPos.iY && aTopLeft.iY + iMCUSizeinPixels.iHeight <= iBufferPos.iY + iBufferSizeInPixels.iHeight &&
       
    95          aTopLeft.iX >= iBufferPos.iX && aTopLeft.iX + iMCUSizeinPixels.iWidth  <= iBufferPos.iX + iBufferSizeInPixels.iWidth
       
    96        )
       
    97         {
       
    98         iLockedPtr = ShiftPtr(iRgbBuffer, aTopLeft.iX - iBufferPos.iX); 
       
    99         return iLockedPtr;
       
   100         }
       
   101     
       
   102     iLockedPtr = reinterpret_cast<TRgbBufferPtr>(iBitmapData) + iBitmapScanlineLength * aTopLeft.iY + KRgbBufferPixelSize * aTopLeft.iX;
       
   103     
       
   104     if (aTopLeft.iX + iMCUSizeinPixels.iWidth <= iBitmapSize.iWidth &&
       
   105         aTopLeft.iY + iMCUSizeinPixels.iHeight <= iBitmapSize.iHeight &&
       
   106         KInplaceAccess)
       
   107         {
       
   108         //ASSERT( iBitmapScanlineLength % KRgbBufferPixelSize == 0 );
       
   109         iNextLineOffset = iBitmapScanlineLength;
       
   110 		iBufferPos.iX = -1;
       
   111         }
       
   112     else
       
   113         {
       
   114         const TInt KLineLen  = KRgbBufferPixelSize * Min(iBufferSizeInPixels.iWidth, iBitmapSize.iWidth - aTopLeft.iX);
       
   115         const TInt KNumLines = Min(iBufferSizeInPixels.iHeight, iBitmapSize.iHeight - aTopLeft.iY);
       
   116         
       
   117         const TInt KBufferLineLen = iBufferScanlineLength;
       
   118         
       
   119         TRgbBufferPtr pixelBufferPtr = iRgbBuffer;
       
   120         if (KInplaceAccess)
       
   121             {
       
   122     	    for (TInt y = KNumLines; y--;  )
       
   123                 {
       
   124     		    Mem::Copy(pixelBufferPtr, iLockedPtr, KLineLen);
       
   125     		    iLockedPtr      += iBitmapScanlineLength;
       
   126     		    
       
   127     		    // now fill out hor trail using grey
       
   128     		    const TInt green = pixelBufferPtr[ KLineLen - KRgbBufferPixelSize + 1 ]; // green of the last pixel
       
   129     		    for (TInt f = KLineLen; f < KBufferLineLen; ++f)
       
   130     		        {
       
   131     		        pixelBufferPtr[ f ] = green;
       
   132     		        }
       
   133     		    pixelBufferPtr = ShiftPtr(pixelBufferPtr, iBufferSizeInPixels.iWidth );
       
   134     		    }            
       
   135             }
       
   136         else
       
   137             {
       
   138     	    for (TInt y = aTopLeft.iY; y < aTopLeft.iY + KNumLines; y++ )
       
   139                 {
       
   140     		    TPtr8 pixelDes(reinterpret_cast<TUint8*>(pixelBufferPtr), KLineLen, KLineLen );
       
   141     		    // GetScanLine() is extremely slow, so if support for bitmap modes other than EColor16M is require
       
   142     		    // it shouldn't be used
       
   143     		    iBitmap->GetScanLine(pixelDes, TPoint(aTopLeft.iX, y), iBufferSizeInPixels.iWidth, EColor16M);
       
   144     		    
       
   145     		    // now fill out hor trail using grey
       
   146     		    const TInt green = pixelBufferPtr[ KLineLen - KRgbBufferPixelSize + 1 ]; // green of the last pixel
       
   147     		    for (TInt f = KLineLen; f < KBufferLineLen; ++f)
       
   148     		        {
       
   149     		        pixelBufferPtr[ f ] = green;
       
   150     		        }
       
   151     		    pixelBufferPtr  = ShiftPtr(pixelBufferPtr, iBufferSizeInPixels.iWidth );
       
   152                 }
       
   153     		}
       
   154         // fill out vertical trail    		
       
   155     	if ( KNumLines < iMCUSizeinPixels.iHeight )
       
   156     	    {
       
   157         	TUint32* fillBufferPtr = reinterpret_cast<TUint32*>( pixelBufferPtr );
       
   158             // we're filling the whole buffer with mid-gray, so to reduce 
       
   159             // color entropy of padded block
       
   160             pixelBufferPtr  = ShiftPtr(pixelBufferPtr, -iBufferSizeInPixels.iWidth ); // go to the previous line
       
   161             // make a grey using green component
       
   162             TUint32 fillValue = (pixelBufferPtr[1] | pixelBufferPtr[1]<<8);
       
   163             fillValue |= fillValue << 16;
       
   164             TInt i =  Coord2Size( iBufferSizeInPixels.iWidth, iBufferSizeInPixels.iHeight - KNumLines) >> 3; // /8
       
   165             do 
       
   166                 {
       
   167                 *fillBufferPtr++ = fillValue;
       
   168                 *fillBufferPtr++ = fillValue;
       
   169                 } while (--i);    	
       
   170     	    }
       
   171     	iLockedPtr              = iRgbBuffer;
       
   172         iNextLineOffset			= iBufferScanlineLength;
       
   173         iBufferPos              = aTopLeft;
       
   174         }
       
   175     
       
   176     return iLockedPtr;
       
   177     }
       
   178     
       
   179 void CRgbBufferPtr::UnlockBuffer()
       
   180     {
       
   181     ASSERT( iLockedPtr != NULL );
       
   182     iLockedPtr  = NULL;        
       
   183     }
       
   184