sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: sl@0: #include "pixelutil.h" sl@0: #include "directgdiadapter.h" sl@0: #include "directgditypes.h" sl@0: sl@0: TBool PixelFormatUtil::HasAlpha(TUidPixelFormat aPixelFormat) sl@0: { sl@0: const TBool hasAlpha = sl@0: // short circuit format equivalent to legacy TDisplayMode with alpha channel sl@0: aPixelFormat == EUidPixelFormatARGB_8888 || sl@0: aPixelFormat == EUidPixelFormatARGB_8888_PRE || sl@0: sl@0: aPixelFormat == EUidPixelFormatBGRA_8888 || sl@0: aPixelFormat == EUidPixelFormatABGR_8888 || sl@0: aPixelFormat == EUidPixelFormatABGR_8888_PRE || sl@0: aPixelFormat == EUidPixelFormatBGRA_8888_PRE || sl@0: aPixelFormat == EUidPixelFormatARGB_2101010 || sl@0: aPixelFormat == EUidPixelFormatABGR_2101010 || sl@0: aPixelFormat == EUidPixelFormatARGB_1555 || sl@0: aPixelFormat == EUidPixelFormatARGB_4444 || sl@0: aPixelFormat == EUidPixelFormatARGB_8332 || sl@0: aPixelFormat == EUidPixelFormatBGRA_5551 || sl@0: aPixelFormat == EUidPixelFormatBGRA_4444 || sl@0: aPixelFormat == EUidPixelFormatAP_88 || sl@0: aPixelFormat == EUidPixelFormatA_8; sl@0: sl@0: return hasAlpha; sl@0: } sl@0: sl@0: TUidPixelFormat PixelFormatUtil::ConvertToPixelFormat(TDisplayMode aDisplayMode) sl@0: { sl@0: switch (aDisplayMode) sl@0: { sl@0: case EGray2: sl@0: return EUidPixelFormatL_1; sl@0: case EGray4: sl@0: return EUidPixelFormatL_2; sl@0: case EGray16: sl@0: return EUidPixelFormatL_4; sl@0: case EGray256: sl@0: return EUidPixelFormatL_8; sl@0: case EColor16: sl@0: return EUidPixelFormatP_4; sl@0: case EColor256: sl@0: return EUidPixelFormatP_8; sl@0: case EColor4K: sl@0: return EUidPixelFormatXRGB_4444; sl@0: case EColor64K: sl@0: return EUidPixelFormatRGB_565; sl@0: case EColor16M: sl@0: return EUidPixelFormatRGB_888; sl@0: case EColor16MU: sl@0: return EUidPixelFormatXRGB_8888; sl@0: case EColor16MA: sl@0: return EUidPixelFormatARGB_8888; sl@0: case EColor16MAP: sl@0: return EUidPixelFormatARGB_8888_PRE; sl@0: default: sl@0: return EUidPixelFormatUnknown; sl@0: }; sl@0: } sl@0: sl@0: TDisplayMode PixelFormatUtil::ConvertToDisplayMode(TUidPixelFormat aPixelFormat) sl@0: { sl@0: switch (aPixelFormat) sl@0: { sl@0: case EUidPixelFormatL_1: sl@0: return EGray2; sl@0: case EUidPixelFormatL_2: sl@0: return EGray4; sl@0: case EUidPixelFormatL_4: sl@0: return EGray16; sl@0: case EUidPixelFormatL_8: sl@0: return EGray256; sl@0: case EUidPixelFormatP_4: sl@0: return EColor16; sl@0: case EUidPixelFormatP_8: sl@0: return EColor256; sl@0: case EUidPixelFormatXRGB_4444: sl@0: return EColor4K; sl@0: case EUidPixelFormatRGB_565: sl@0: return EColor64K; sl@0: case EUidPixelFormatRGB_888: sl@0: return EColor16M; sl@0: case EUidPixelFormatXRGB_8888: sl@0: return EColor16MU; sl@0: case EUidPixelFormatARGB_8888: sl@0: return EColor16MA; sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: return EColor16MAP; sl@0: default: sl@0: return ENone; sl@0: } sl@0: } sl@0: sl@0: TInt PixelFormatUtil::BitsPerPixel(TUidPixelFormat aPixelFormat) sl@0: { sl@0: switch (aPixelFormat) sl@0: { sl@0: case EUidPixelFormatP_1: sl@0: case EUidPixelFormatL_1: sl@0: return 1; sl@0: case EUidPixelFormatP_2: sl@0: case EUidPixelFormatL_2: sl@0: return 2; sl@0: case EUidPixelFormatP_4: sl@0: case EUidPixelFormatL_4: sl@0: return 4; sl@0: case EUidPixelFormatRGB_332: sl@0: case EUidPixelFormatA_8: sl@0: case EUidPixelFormatBGR_332: sl@0: case EUidPixelFormatP_8: sl@0: case EUidPixelFormatL_8: sl@0: return 8; sl@0: case EUidPixelFormatRGB_565: sl@0: case EUidPixelFormatBGR_565: sl@0: case EUidPixelFormatARGB_1555: sl@0: case EUidPixelFormatXRGB_1555: sl@0: case EUidPixelFormatARGB_4444: sl@0: case EUidPixelFormatARGB_8332: sl@0: case EUidPixelFormatBGRX_5551: sl@0: case EUidPixelFormatBGRA_5551: sl@0: case EUidPixelFormatBGRA_4444: sl@0: case EUidPixelFormatBGRX_4444: sl@0: case EUidPixelFormatAP_88: sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatXBGR_4444: sl@0: return 16; sl@0: case EUidPixelFormatBGR_888: sl@0: case EUidPixelFormatRGB_888: sl@0: return 24; sl@0: case EUidPixelFormatXRGB_8888: sl@0: case EUidPixelFormatBGRX_8888: sl@0: case EUidPixelFormatXBGR_8888: sl@0: case EUidPixelFormatBGRA_8888: sl@0: case EUidPixelFormatARGB_8888: sl@0: case EUidPixelFormatABGR_8888: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: case EUidPixelFormatABGR_8888_PRE: sl@0: case EUidPixelFormatBGRA_8888_PRE: sl@0: case EUidPixelFormatARGB_2101010: sl@0: case EUidPixelFormatABGR_2101010: sl@0: return 32; sl@0: default: sl@0: GRAPHICS_ASSERT_DEBUG(EFalse, EDirectGdiPanicInvalidDisplayMode); sl@0: return 0; sl@0: }; sl@0: } sl@0: sl@0: /** sl@0: Create pixel buffer reader from a given pixel buffer by specifying its buffer addres and properties. sl@0: Supported format are: sl@0: -EUidPixelFormatRGB_565 sl@0: -EUidPixelFormatXRGB_8888 sl@0: -EUidPixelFormatARGB_8888 sl@0: -EUidPixelFormatARGB_8888_PRE sl@0: */ sl@0: TPixelBufferReader::TPixelBufferReader(const TUint32* aPixelBuffer, const TSize& aSize, TInt aStride, TUidPixelFormat aFormat): sl@0: iBuffer(aPixelBuffer), sl@0: iSize(aSize), sl@0: iStride(aStride), sl@0: iFormat(aFormat) sl@0: { sl@0: GRAPHICS_ASSERT_DEBUG(iBuffer && iStride!=0, EDirectGdiPanicInvalidBitmap); sl@0: GRAPHICS_ASSERT_DEBUG(iSize.iWidth!=0 && iSize.iHeight!=0, EDirectGdiPanicOutOfBounds); sl@0: GRAPHICS_ASSERT_DEBUG( sl@0: iFormat==EUidPixelFormatRGB_565 || sl@0: iFormat==EUidPixelFormatXRGB_8888 || sl@0: iFormat==EUidPixelFormatARGB_8888 || sl@0: iFormat==EUidPixelFormatARGB_8888_PRE, sl@0: EDirectGdiPanicInvalidDisplayMode); sl@0: } sl@0: sl@0: /** sl@0: Copies pixels into user buffer starting and ending based on the given read position and sl@0: read length (in pixels). Convert data into user pixel format if requested. sl@0: Copying will be done forward or backward (from a given read position) based on read direction parameter. sl@0: sl@0: @pre TPixelBufferReader object was constructed with valid pixel buffer and its properties. sl@0: Starting and ending read position is within the pixel buffer area. sl@0: Supported read format: sl@0: RGB_565 sl@0: XRGB_8888, ARGB_8888 or ARGB_8888_PRE. sl@0: @post Pixels copied into user buffer. sl@0: */ sl@0: void TPixelBufferReader::GetScanLine(TDes8& aReadBuf, const TPoint& aReadPos, TInt aReadLen, sl@0: TUidPixelFormat aReadFormat, TReadDirection aReadDir) const sl@0: { sl@0: GRAPHICS_ASSERT_DEBUG(aReadPos.iX>=0 && aReadPos.iX=0 && aReadPos.iY=0, EDirectGdiPanicOutOfBounds); sl@0: break; sl@0: sl@0: case EReadVertical: sl@0: GRAPHICS_ASSERT_DEBUG(aReadPos.iY+aReadLen<=iSize.iHeight, EDirectGdiPanicOutOfBounds); sl@0: break; sl@0: sl@0: case EReadVerticalReverse: sl@0: GRAPHICS_ASSERT_DEBUG(aReadPos.iY-aReadLen+1>=0, EDirectGdiPanicOutOfBounds); sl@0: break; sl@0: } sl@0: #endif sl@0: sl@0: switch(aReadFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: GetScanLineRGB_565(aReadBuf, aReadPos, aReadLen, aReadDir); sl@0: break; sl@0: case EUidPixelFormatXRGB_8888: sl@0: GetScanLineXRGB_8888(aReadBuf, aReadPos, aReadLen, aReadDir); sl@0: break; sl@0: case EUidPixelFormatARGB_8888: sl@0: GetScanLineARGB_8888(aReadBuf, aReadPos, aReadLen, aReadDir); sl@0: break; sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: GetScanLineARGB_8888_PRE(aReadBuf, aReadPos, aReadLen, aReadDir); sl@0: break; sl@0: default: sl@0: aReadBuf.SetLength(0); sl@0: break; sl@0: }; sl@0: } sl@0: sl@0: /** sl@0: Copies pixels into user buffer starting and ending based on the given read position and sl@0: read length (in pixels). Converts data into user pixel format and scales up or down depending sl@0: on the specified parameters. Copying will be done forward or backward (from a given read position) sl@0: based on read direction parameter. sl@0: sl@0: @pre TPixelBufferReader object was constructed with valid pixel buffer and its properties. sl@0: Starting and ending read position is within the pixel buffer area. sl@0: Supported read format: sl@0: RGB_565 sl@0: XRGB_8888, ARGB_8888 or ARGB_8888_PRE. sl@0: @post Pixels copied into user buffer. sl@0: */ sl@0: void TPixelBufferReader::GetScaledScanLine(TDes8& aReadBuf, const TPoint& aReadPos, TInt aClipPos, sl@0: TInt aClipLen, TInt aDestLen, TInt aSrcLen, TUidPixelFormat aReadFormat, sl@0: TReadDirection aReadDir) const sl@0: { sl@0: GRAPHICS_ASSERT_DEBUG(aReadPos.iX>=0 && aReadPos.iX=0 && aReadPos.iY> 2)); sl@0: } sl@0: sl@0: /** sl@0: Copies from 16-bit src to 32-bit dest sl@0: */ sl@0: void TPixelBufferReader::CopyFromRGB_565(TUint32* aDstPtr, const TUint16* aSrcPtr, sl@0: TInt aNumOfPixels, TInt aAdvance) const sl@0: { sl@0: const TUint16* lowAdd = Convert16to32bppLow(); sl@0: const TUint32* highAdd = Convert16to32bppHigh(); sl@0: sl@0: while (aNumOfPixels--) sl@0: { sl@0: const TUint8 low = *aSrcPtr & 0xff; sl@0: const TUint8 high = *aSrcPtr >> 8; sl@0: *aDstPtr++ = (*(highAdd+high)) | (*(lowAdd+low)); sl@0: sl@0: aSrcPtr += aAdvance; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Calculates pixel position increment based on a given read direction and buffer pixel format. sl@0: */ sl@0: TInt TPixelBufferReader::GetAdvance(TReadDirection aReadDir) const sl@0: { sl@0: TInt advance = 0; sl@0: // supported pixel buffer is either 16-bit or 32-bit sl@0: // sl@0: switch (aReadDir) sl@0: { sl@0: case EReadHorizontal: sl@0: advance = 1; sl@0: break; sl@0: case EReadHorizontalReverse: sl@0: advance = -1; sl@0: break; sl@0: case EReadVertical: sl@0: advance = PixelFormatUtil::BitsPerPixel(iFormat)==16? iStride >> 1 : iStride >> 2; sl@0: break; sl@0: case EReadVerticalReverse: sl@0: advance = PixelFormatUtil::BitsPerPixel(iFormat)==16? -(iStride >> 1) : -(iStride >> 2); sl@0: break; sl@0: } sl@0: sl@0: return advance; sl@0: } sl@0: sl@0: /** sl@0: Reads and converts scanline into RGB_565. sl@0: */ sl@0: void TPixelBufferReader::GetScanLineRGB_565(TDes8& aReadBuf, const TPoint& aReadPos, TInt aReadLen, sl@0: TReadDirection aReadDir) const sl@0: { sl@0: // read as much as buffer can hold sl@0: aReadLen = Min(aReadLen, aReadBuf.MaxLength() >> 1); sl@0: aReadBuf.SetLength(aReadLen << 1); sl@0: sl@0: TUint16* dstPtr = (TUint16*)aReadBuf.Ptr(); sl@0: const TUint32* scanLinePtr = GetScanLineAddr(aReadPos.iY); sl@0: TInt posX = aReadPos.iX; sl@0: const TInt advance = GetAdvance(aReadDir); sl@0: sl@0: // supported pixel buffer: sl@0: // RGB_565 sl@0: // XRGB_8888 sl@0: // ARGB_8888 sl@0: // ARGB_8888_PRE sl@0: // sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = *srcPtr; sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MU(*srcPtr).Color64K()); sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MA(*srcPtr).Color64K()); sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MAP(*srcPtr).Color64K()); sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Reads and converts scanline into XRGB_8888. sl@0: */ sl@0: void TPixelBufferReader::GetScanLineXRGB_8888(TDes8& aReadBuf, const TPoint& aReadPos, TInt aReadLen, sl@0: TReadDirection aReadDir) const sl@0: { sl@0: // read as much as buffer can hold sl@0: aReadLen = Min(aReadLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aReadLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: const TUint32* scanLinePtr = GetScanLineAddr(aReadPos.iY); sl@0: TInt posX = aReadPos.iX; sl@0: const TInt advance = GetAdvance(aReadDir); sl@0: sl@0: // supported pixel buffer: sl@0: // RGB_565 sl@0: // XRGB_8888 sl@0: // ARGB_8888 sl@0: // ARGB_8888_PRE sl@0: // sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)scanLinePtr + posX; sl@0: CopyFromRGB_565(dstPtr, srcPtr, aReadLen, advance); sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = *srcPtr; sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: while(aReadLen--) sl@0: { sl@0: *dstPtr++ = PMA2NonPMAPixel(*srcPtr, normTable); sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Reads and converts scanline into ARGB_8888. sl@0: */ sl@0: void TPixelBufferReader::GetScanLineARGB_8888(TDes8& aReadBuf, const TPoint& aReadPos, TInt aReadLen, sl@0: TReadDirection aReadDir) const sl@0: { sl@0: // read as much as buffer can hold sl@0: aReadLen = Min(aReadLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aReadLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: const TUint32* scanLinePtr = GetScanLineAddr(aReadPos.iY); sl@0: TInt posX = aReadPos.iX; sl@0: const TInt advance = GetAdvance(aReadDir); sl@0: sl@0: // supported pixel buffer: sl@0: // RGB_565 sl@0: // XRGB_8888 sl@0: // ARGB_8888 sl@0: // ARGB_8888_PRE sl@0: // sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)scanLinePtr + posX; sl@0: CopyFromRGB_565(dstPtr, srcPtr, aReadLen, advance); sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = 0xff000000 | *srcPtr; sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = *srcPtr; sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: while(aReadLen--) sl@0: { sl@0: *dstPtr++ = PMA2NonPMAPixel(*srcPtr, normTable); sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Read and convert scanline into ARGB_8888_PRE. sl@0: */ sl@0: void TPixelBufferReader::GetScanLineARGB_8888_PRE(TDes8& aReadBuf, const TPoint& aReadPos, TInt aReadLen, sl@0: TReadDirection aReadDir) const sl@0: { sl@0: // read as much as buffer can hold sl@0: aReadLen = Min(aReadLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aReadLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: const TUint32* scanLinePtr = GetScanLineAddr(aReadPos.iY); sl@0: TInt posX = aReadPos.iX; sl@0: const TInt advance = GetAdvance(aReadDir); sl@0: sl@0: // supported pixel buffer: sl@0: // RGB_565 sl@0: // XRGB_8888 sl@0: // ARGB_8888 sl@0: // ARGB_8888_PRE sl@0: // sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)scanLinePtr + posX; sl@0: CopyFromRGB_565(dstPtr, srcPtr, aReadLen, advance); sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = 0xff000000 | *srcPtr; sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: TUint32 argb = *srcPtr; sl@0: Convert2PMA(argb); sl@0: *dstPtr++ = argb; sl@0: sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr + posX; sl@0: while (aReadLen--) sl@0: { sl@0: *dstPtr++ = *srcPtr; sl@0: srcPtr += advance; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Reads and scales pixels horizontally from either left or right. Converts to other pixel format if sl@0: requested. sl@0: */ sl@0: void TPixelBufferReader::GetScaledScanLineH(TDes8& aReadBuf, const TPoint& aReadPos, TInt aClipDestPos, sl@0: TInt aClipDestLen, TInt aDestLen, TInt aSrcLen, TUidPixelFormat aReadFormat, sl@0: TReadDirection aReadDir) const sl@0: { sl@0: // setup DDA for scaling in X direction, use read pos as starting point and move right or left sl@0: // depending on the read direction sl@0: // sl@0: TLinearDDA xScaler; sl@0: TPoint xPos(aReadPos.iX, 0); sl@0: const TPoint delta = aReadDir==EReadHorizontal? TPoint(aSrcLen, aDestLen) : TPoint(-aSrcLen, aDestLen); sl@0: xScaler.Construct(xPos, xPos + delta, TLinearDDA::ELeft); sl@0: sl@0: // jump to dest X position and return the corresponding src X position sl@0: xPos.iY = aClipDestPos; sl@0: if (aClipDestPos > 0) sl@0: { sl@0: xScaler.JumpToYCoord(xPos.iX, xPos.iY); sl@0: } sl@0: else sl@0: { sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: sl@0: const TUint32* scanLinePtr = GetScanLineAddr(aReadPos.iY); sl@0: sl@0: // supported pixel buffer: sl@0: // RGB_565 sl@0: // XRGB_8888 sl@0: // ARGB_8888 sl@0: // ARGB_8888_PRE sl@0: sl@0: // supported read format sl@0: // RGB_565 sl@0: // XRGB_8888 sl@0: // ARGB_8888 sl@0: // ARGB_8888_PRE sl@0: sl@0: switch(aReadFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: aClipDestLen = Min(aClipDestLen, aReadBuf.MaxLength() >> 1); sl@0: aReadBuf.SetLength(aClipDestLen << 1); sl@0: sl@0: TUint16* dstPtr = (TUint16*)aReadBuf.Ptr(); sl@0: TUint16* dstLimit = dstPtr + aClipDestLen; sl@0: sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*) scanLinePtr; sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = *(srcPtr + xPos.iX); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MU(*(srcPtr + xPos.iX)).Color64K()); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MA(*(srcPtr + xPos.iX)).Color64K()); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MAP(*(srcPtr + xPos.iX)).Color64K()); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: aClipDestLen = Min(aClipDestLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aClipDestLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: TUint32* dstLimit = dstPtr + aClipDestLen; sl@0: sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)scanLinePtr; sl@0: sl@0: const TUint16* lowAdd = Convert16to32bppLow(); sl@0: const TUint32* highAdd = Convert16to32bppHigh(); sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: TUint16 c = *(srcPtr + xPos.iX); sl@0: const TUint8 low = c & 0xff; sl@0: const TUint8 high = c >> 8; sl@0: *dstPtr++ = (*(highAdd+high)) | (*(lowAdd+low)); sl@0: sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = *(srcPtr + xPos.iX); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = PMA2NonPMAPixel(*(srcPtr + xPos.iX), normTable); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: aClipDestLen = Min(aClipDestLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aClipDestLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: TUint32* dstLimit = dstPtr + aClipDestLen; sl@0: sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)scanLinePtr; sl@0: sl@0: const TUint16* lowAdd = Convert16to32bppLow(); sl@0: const TUint32* highAdd = Convert16to32bppHigh(); sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: TUint16 c = *(srcPtr + xPos.iX); sl@0: const TUint8 low = c & 0xff; sl@0: const TUint8 high = c >> 8; sl@0: *dstPtr++ = (*(highAdd+high)) | (*(lowAdd+low)); sl@0: sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = 0xff000000 | *(srcPtr + xPos.iX); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = *(srcPtr + xPos.iX); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = PMA2NonPMAPixel(*(srcPtr + xPos.iX), normTable); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: aClipDestLen = Min(aClipDestLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aClipDestLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: TUint32* dstLimit = dstPtr + aClipDestLen; sl@0: sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)scanLinePtr; sl@0: sl@0: const TUint16* lowAdd = Convert16to32bppLow(); sl@0: const TUint32* highAdd = Convert16to32bppHigh(); sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: TUint16 c = *(srcPtr + xPos.iX); sl@0: const TUint8 low = c & 0xff; sl@0: const TUint8 high = c >> 8; sl@0: *dstPtr++ = (*(highAdd+high)) | (*(lowAdd+low)); sl@0: sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = 0xff000000 | *(srcPtr + xPos.iX); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = *(srcPtr + xPos.iX); sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = scanLinePtr; sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: TUint32 argb = *(srcPtr + xPos.iX); sl@0: Convert2PMA(argb); sl@0: *dstPtr++ = argb; sl@0: sl@0: xScaler.NextStep(xPos); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Reads and scales pixels vertically from either top or bottom. Converts to other pixel format sl@0: if requested. sl@0: */ sl@0: void TPixelBufferReader::GetScaledScanLineV(TDes8& aReadBuf, const TPoint& aReadPos, TInt aClipDestPos, sl@0: TInt aClipDestLen, TInt aDestLen, TInt aSrcLen, TUidPixelFormat aReadFormat, sl@0: TReadDirection aReadDir) const sl@0: { sl@0: // setup DDA for scaling in Y direction, use read pos as starting point and move up or down sl@0: // depending on the read direction sl@0: // sl@0: TLinearDDA yScaler; sl@0: TPoint yPos(aReadPos.iY, 0); sl@0: const TPoint delta = aReadDir==EReadVertical? TPoint(aSrcLen, aDestLen) : TPoint(-aSrcLen, aDestLen); sl@0: yScaler.Construct(yPos, yPos + delta, TLinearDDA::ELeft); sl@0: sl@0: // jump to dest Y position and return the corresponding src Y position sl@0: yPos.iY = aClipDestPos; sl@0: if (aClipDestPos > 0) sl@0: { sl@0: yScaler.JumpToYCoord(yPos.iX, yPos.iY); sl@0: } sl@0: else sl@0: { sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: sl@0: // supported pixel buffer: sl@0: // RGB_565 sl@0: // XRGB_8888 sl@0: // ARGB_8888 sl@0: // ARGB_8888_PRE sl@0: sl@0: // supported read format sl@0: // RGB_565 sl@0: // XRGB_8888 sl@0: // ARGB_8888 sl@0: // ARGB_8888_PRE sl@0: sl@0: switch(aReadFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: aClipDestLen = Min(aClipDestLen, aReadBuf.MaxLength() >> 1); sl@0: aReadBuf.SetLength(aClipDestLen << 1); sl@0: sl@0: TUint16* dstPtr = (TUint16*)aReadBuf.Ptr(); sl@0: TUint16* dstLimit = dstPtr + aClipDestLen; sl@0: sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*) iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 1; sl@0: sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = *(srcPtr + yPos.iX * offset); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MU(*(srcPtr + yPos.iX * offset)).Color64K()); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MA(*(srcPtr + yPos.iX * offset)).Color64K()); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = TUint16(TRgb::Color16MAP(*(srcPtr + yPos.iX * offset)).Color64K()); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: aClipDestLen = Min(aClipDestLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aClipDestLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: TUint32* dstLimit = dstPtr + aClipDestLen; sl@0: sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 1; sl@0: sl@0: const TUint16* lowAdd = Convert16to32bppLow(); sl@0: const TUint32* highAdd = Convert16to32bppHigh(); sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: TUint16 c = *(srcPtr + yPos.iX * offset); sl@0: const TUint8 low = c & 0xff; sl@0: const TUint8 high = c >> 8; sl@0: *dstPtr++ = (*(highAdd+high)) | (*(lowAdd+low)); sl@0: sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = *(srcPtr + yPos.iX * offset); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = PMA2NonPMAPixel(*(srcPtr + yPos.iX * offset), normTable); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: aClipDestLen = Min(aClipDestLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aClipDestLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: TUint32* dstLimit = dstPtr + aClipDestLen; sl@0: sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 1; sl@0: sl@0: const TUint16* lowAdd = Convert16to32bppLow(); sl@0: const TUint32* highAdd = Convert16to32bppHigh(); sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: TUint16 c = *(srcPtr + yPos.iX * offset); sl@0: const TUint8 low = c & 0xff; sl@0: const TUint8 high = c >> 8; sl@0: *dstPtr++ = (*(highAdd+high)) | (*(lowAdd+low)); sl@0: sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = 0xff000000 | *(srcPtr + yPos.iX * offset); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = *(srcPtr + yPos.iX * offset); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = PMA2NonPMAPixel(*(srcPtr + yPos.iX * offset), normTable); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: aClipDestLen = Min(aClipDestLen, aReadBuf.MaxLength() >> 2); sl@0: aReadBuf.SetLength(aClipDestLen << 2); sl@0: sl@0: TUint32* dstPtr = (TUint32*)aReadBuf.Ptr(); sl@0: TUint32* dstLimit = dstPtr + aClipDestLen; sl@0: sl@0: switch (iFormat) sl@0: { sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TUint16* srcPtr = (TUint16*)iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 1; sl@0: sl@0: const TUint16* lowAdd = Convert16to32bppLow(); sl@0: const TUint32* highAdd = Convert16to32bppHigh(); sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: TUint16 c = *(srcPtr + yPos.iX * offset); sl@0: const TUint8 low = c & 0xff; sl@0: const TUint8 high = c >> 8; sl@0: *dstPtr++ = (*(highAdd+high)) | (*(lowAdd+low)); sl@0: sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = 0xff000000 | *(srcPtr + yPos.iX * offset); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while(dstPtr < dstLimit) sl@0: { sl@0: *dstPtr++ = *(srcPtr + yPos.iX * offset); sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TUint32* srcPtr = iBuffer + aReadPos.iX; sl@0: const TInt offset = iStride >> 2; sl@0: sl@0: while (dstPtr < dstLimit) sl@0: { sl@0: TUint32 argb = *(srcPtr + yPos.iX * offset); sl@0: Convert2PMA(argb); sl@0: *dstPtr++ = argb; sl@0: sl@0: yScaler.NextStep(yPos); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: }