sl@0: // Copyright (c) 1997-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: #include sl@0: #include sl@0: #include "UTILS.H" sl@0: #include sl@0: #include sl@0: //#include "12to16.h" // lookup table for 12->16 bpp conversion sl@0: sl@0: #ifdef __ARMCC__ sl@0: #pragma arm sl@0: #pragma O3 sl@0: #pragma Otime sl@0: #endif sl@0: sl@0: GLREF_C void Panic(TFbsPanic aPanic); sl@0: sl@0: #define COLOR_VALUE(ScanLinePtr, XPos) (*((ScanLinePtr) + ((XPos) >> 5)) & ( 1 << ((XPos) & 0x1F))) sl@0: sl@0: sl@0: void CBitwiseBitmap::GetScanLineGray2(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TBool aDither,const TPoint& aDitherOffset,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,(TInt)((aBuf.MaxLength()) << 3)); sl@0: aBuf.SetLength((aLength + 7) >> 3); sl@0: sl@0: TUint8* ptr = (TUint8*)aBuf.Ptr(); sl@0: sl@0: TUint8 mask = 1; sl@0: TInt x = aPixel.iX; sl@0: *ptr=0; sl@0: sl@0: if (aDither) sl@0: { sl@0: TBool oddx = aDitherOffset.iX & 1; sl@0: TBool oddy = aDitherOffset.iY & 1; sl@0: sl@0: for(TInt count = 0;count < aLength;count++) sl@0: { sl@0: if (!mask) sl@0: { sl@0: mask = 1; sl@0: ptr++; sl@0: *ptr = 0; sl@0: } sl@0: if (HashTo1bpp(GetGrayPixelEx(x,aScanlinePtr),oddx,oddy)) sl@0: *ptr |= mask; sl@0: mask <<= 1; sl@0: oddx ^= 1; sl@0: x++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: for(TInt count = 0;count < aLength;count++) sl@0: { sl@0: if (!mask) sl@0: { sl@0: mask = 1; sl@0: ptr++; sl@0: *ptr = 0; sl@0: } sl@0: if (GetGrayPixelEx(x,aScanlinePtr) > 127) sl@0: *ptr |= mask; sl@0: mask <<= 1; sl@0: x++; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineGray4(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TBool aDither,const TPoint& aDitherOffset,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,(TInt)((aBuf.MaxLength())<<2)); sl@0: aBuf.SetLength((aLength + 3) >> 2); sl@0: sl@0: TUint8* ptr=(TUint8*)aBuf.Ptr(); sl@0: sl@0: TInt x = aPixel.iX; sl@0: if (iSettings.CurrentDisplayMode() == EGray16 && aDither) sl@0: { sl@0: *ptr=0; sl@0: TInt shift = 0; sl@0: TUint8 col = 0; sl@0: const TInt hasharray[4]={0,3,2,1}; sl@0: TInt index = (aDitherOffset.iX&1)+((aDitherOffset.iY&1)<<1); sl@0: for(TInt count=0;count> 4); sl@0: TInt value=col/5; sl@0: col%=5; sl@0: if (col>2) col--; sl@0: if (hasharray[index]> 2); sl@0: while (ptr < ptrLimit) sl@0: { sl@0: TUint8 pixelGrayShade = TUint8(GetGrayPixelEx(x++,aScanlinePtr) >> 6); sl@0: pixelGrayShade |= TUint8((GetGrayPixelEx(x++,aScanlinePtr) >> 4) & 0x0c); sl@0: pixelGrayShade |= TUint8((GetGrayPixelEx(x++,aScanlinePtr) >> 2) & 0x30); sl@0: pixelGrayShade |= TUint8(GetGrayPixelEx(x++,aScanlinePtr) & 0xc0); sl@0: *ptr++ = pixelGrayShade; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineGray16(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength=Min(aLength,(TInt)(aBuf.MaxLength()<<1)); sl@0: aBuf.SetLength((aLength + 1) >> 1); sl@0: sl@0: TUint8* ptr = (TUint8*)aBuf.Ptr(); sl@0: TUint8* ptrLimit = ptr + aBuf.Length(); sl@0: TInt x = aPixel.iX; sl@0: sl@0: if(iHeader.iBitsPerPixel == 1) sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: TUint8 pixelGrayShade = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0x0F : 0); sl@0: x++; sl@0: pixelGrayShade |= TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xF0 : 0); sl@0: x++; sl@0: *ptr++ = pixelGrayShade; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: TUint8 pixelGrayShade = TUint8(GetGrayPixelEx(x++,aScanlinePtr) >> 4); sl@0: pixelGrayShade |= GetGrayPixelEx(x++,aScanlinePtr) & 0xf0; sl@0: *ptr++ = pixelGrayShade; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineGray256(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength()); sl@0: aBuf.SetLength(aLength); sl@0: sl@0: TUint8* ptr = (TUint8*)aBuf.Ptr(); sl@0: TUint8* ptrLimit = ptr + aLength; sl@0: TInt xCoord = aPixel.iX; sl@0: sl@0: if(iHeader.iBitsPerPixel == 1) sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: *ptr++ = TUint8(COLOR_VALUE(aScanlinePtr, xCoord) ? 0xFF : 0); sl@0: xCoord++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: while (ptr < ptrLimit) sl@0: *ptr++ = GetGrayPixelEx(xCoord++,aScanlinePtr); sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineColor16(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength=Min(aLength,(TInt)(aBuf.MaxLength()<<1)); sl@0: aBuf.SetLength((aLength + 1) >> 1); sl@0: sl@0: TUint8* ptr = (TUint8*)aBuf.Ptr(); sl@0: TUint8* ptrLimit = ptr + aBuf.Length(); sl@0: TInt x = aPixel.iX; sl@0: sl@0: if(iHeader.iBitsPerPixel == 1) sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: TUint8 pixelGrayShade = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0x0F : 0); sl@0: x++; sl@0: pixelGrayShade |= TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xF0 : 0); sl@0: x++; sl@0: *ptr++ = pixelGrayShade; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: TUint8 pixelGrayShade = TUint8(GetRgbPixelEx(x++,aScanlinePtr).Color16()); sl@0: pixelGrayShade |= GetRgbPixelEx(x++,aScanlinePtr).Color16() << 4; sl@0: *ptr++ = pixelGrayShade; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineColor256(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength()); sl@0: aBuf.SetLength(aLength); sl@0: sl@0: TUint8* ptr = (TUint8*)aBuf.Ptr(); sl@0: TUint8* ptrLimit = ptr + aLength; sl@0: TInt xCoord = aPixel.iX; sl@0: sl@0: if(iHeader.iBitsPerPixel == 1) sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: *ptr++ = TUint8(COLOR_VALUE(aScanlinePtr, xCoord) ? 0xFF : 0); sl@0: xCoord++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: while (ptr < ptrLimit) sl@0: *ptr++ = TUint8(GetRgbPixelEx(xCoord++,aScanlinePtr).Color256()); sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineColor4K(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() >> 1); sl@0: aBuf.SetLength(aLength << 1); sl@0: sl@0: TUint16* ptr = (TUint16*)aBuf.Ptr(); sl@0: const TUint16* ptrLimit = ptr + aLength; sl@0: TInt x = aPixel.iX; sl@0: sl@0: if(iHeader.iBitsPerPixel == 1) sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: *ptr++ = TUint16(COLOR_VALUE(aScanlinePtr, x) ? 0x0FFF : 0); sl@0: x++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: while (ptr < ptrLimit) sl@0: *ptr++ = TUint16(GetRgbPixelEx(x++,aScanlinePtr)._Color4K()); sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineColor64K(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() >> 1); sl@0: aBuf.SetLength(aLength << 1); sl@0: sl@0: TUint16* ptr = (TUint16*)aBuf.Ptr(); sl@0: TUint16* ptrLimit = ptr + aLength; sl@0: TInt x = aPixel.iX; sl@0: sl@0: if(iHeader.iBitsPerPixel == 1) sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: *ptr++ = TUint16(COLOR_VALUE(aScanlinePtr, x) ? 0xFFFF : 0); sl@0: x++; sl@0: } sl@0: } sl@0: else if(iHeader.iBitsPerPixel == 12) sl@0: { sl@0: /* sl@0: // use lookup table for 12->16 conversion sl@0: TUint16* pixel4K = ((TUint16*) aScanlinePtr) + x; sl@0: while(ptr < ptrLimit) sl@0: { sl@0: // this takes the 12 bit value, this is a number between 0 and 4095, sl@0: // and looks up its corrosponding 16 bit value in the lookup table. sl@0: // the colour should be identical, and but just in a different format sl@0: // see below for an explaination of 12 & 16 bit colour values sl@0: *ptr++ = K12to16LUT[*pixel4K++]; sl@0: } sl@0: */ sl@0: /* This code uses logic rather than a lookup table sl@0: to convert from 12->16 bpp and can be used instead of the above code sl@0: if the 8k the lookup table uses becomes an issue sl@0: sl@0: 12 bit colour sl@0: ------------- sl@0: The 12 bit colour format uses 4 bits for the red, green and blue values. sl@0: The colour is stored as a word with the most significant 4 bits having a sl@0: value of zero. sl@0: i.e. 0000RRRR GGGGBBBB where R,G & B represent single bits in the word. sl@0: sl@0: The code below labeled 'conversion of 4k colour...' changes the colour from sl@0: 16 bit to 32 bit where each colour nibble in the 16 bit version is changed sl@0: to a byte in the 32 bit version e.g. sl@0: 0000RRRR GGGGBBBB -> 00000000 RRRRRRRR GGGGGGGG BBBBBBBB sl@0: sl@0: sl@0: 16 bit colour sl@0: ------------- sl@0: The 16 bit colour format uses all 16 bits to represent the required colour. sl@0: There are two possible 16 bit formats 5-5-5 and 5-6-5. sl@0: Symbian uses the 5-6-5 format, with this all 16 bits are used to make the colour sl@0: giving a possible value between 0..65535. The RGB components are divided up sl@0: as follows RRRR RGGG GGGB BBBB i.e. 5 bits for red and blue, and 6 for green. sl@0: sl@0: The code below labeled 'conversion to 64k' converts the colour from a 16 bit sl@0: 0000 RRRR GGGG BBBB -> RRRR RGGG GGGB BBBB format. sl@0: */ sl@0: register TUint16* pixel4K = ((TUint16*) aScanlinePtr) + x; sl@0: while (ptr < ptrLimit) sl@0: { sl@0: // conversion of 4k colour from 16 to 32 bits sl@0: // this changes from a 16 to 32 bit value while keeping colour unchanged sl@0: register TUint16 pixelVal = *pixel4K++; sl@0: register TUint32 value32 = ((pixelVal & 0x0f00) >> 8) | sl@0: ((pixelVal & 0x00f0) << 4) | sl@0: ((pixelVal & 0x000f) << 16); sl@0: value32 |= (value32 << 4); sl@0: // conversion to 64k (RRRR RGGG GGGB BBBB) sl@0: // this will make the change from (16 bit) 4-4-4 bpp to 5-6-5 bpp format sl@0: register TUint32 color64K = ((value32 & 0x000000f8) << 8) | sl@0: ((value32 & 0x0000fc00) >> 5) | sl@0: ((value32 & 0x00f80000) >> 19); sl@0: // store new colour value sl@0: *ptr++ = static_cast (color64K); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: while (ptr < ptrLimit) sl@0: *ptr++ = TUint16(GetRgbPixelEx(x++,aScanlinePtr)._Color64K()); sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineColor16M(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() / 3); sl@0: aBuf.SetLength(aLength * 3); sl@0: sl@0: TUint8* ptr = (TUint8*)aBuf.Ptr(); sl@0: TUint8* ptrLimit = ptr + (aLength * 3); sl@0: TInt x = aPixel.iX; sl@0: sl@0: if(iHeader.iBitsPerPixel == 1) sl@0: { sl@0: while (ptr < ptrLimit) sl@0: { sl@0: const TUint8 color = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xFF : 0); sl@0: *ptr++ = color; sl@0: *ptr++ = color; sl@0: *ptr++ = color; sl@0: x++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: GetRgbPixelExMany16M(aPixel.iX,aScanlinePtr,ptr,aLength); sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineColor16MU(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() >> 2); sl@0: aBuf.SetLength(aLength << 2); sl@0: sl@0: TUint32* ptr = (TUint32*)aBuf.Ptr(); sl@0: sl@0: GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength); sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineColor16MA(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() >> 2); sl@0: aBuf.SetLength(aLength << 2); sl@0: sl@0: TUint32* ptr = (TUint32*)aBuf.Ptr(); sl@0: GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength); sl@0: } sl@0: sl@0: /** sl@0: Get the scanline data into the destination buffer in the EColor16MAP format. sl@0: @param aDestBuf - destination buffer sl@0: @param aPixel - the start position of the scanline. sl@0: @param aLength - scanline length, as word length sl@0: @param aScanlinePtr - scanline pointer sl@0: */ sl@0: void CBitwiseBitmap::GetScanLineColor16MAP(TDes8& aDestBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength, aDestBuf.MaxLength() >> 2); sl@0: aDestBuf.SetLength(aLength << 2); sl@0: TUint32* ptr = (TUint32*)aDestBuf.Ptr(); sl@0: GetRgbPixelExMany16MAP(aPixel.iX,aScanlinePtr,ptr,aLength); sl@0: } sl@0: sl@0: sl@0: void CBitwiseBitmap::GetScanLineColorRgb(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() / sizeof(TRgb)); sl@0: aBuf.SetLength(aLength * sizeof(TRgb)); sl@0: sl@0: TUint32* ptr = (TUint32*)aBuf.Ptr(); sl@0: GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength); sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineExBits(TDes8& aBuf,TInt aX,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: TInt bitshift = 1; sl@0: TInt pixelsPerWord = 8; sl@0: TInt roundingmask = ~0x7; sl@0: TInt logbpp = 2; sl@0: TInt roundupfactor = 1; sl@0: const TDisplayMode displayMode = iSettings.CurrentDisplayMode(); sl@0: sl@0: switch(displayMode) sl@0: { sl@0: case EGray16: sl@0: case EColor16: sl@0: break; // set by default sl@0: case EGray4: sl@0: { sl@0: bitshift = 2; sl@0: pixelsPerWord = 16; sl@0: roundingmask = ~0xf; sl@0: logbpp = 1; sl@0: roundupfactor = 3; sl@0: break; sl@0: } sl@0: case EGray2: sl@0: { sl@0: bitshift = 3; sl@0: pixelsPerWord = 32; sl@0: roundingmask = ~0x1f; sl@0: logbpp = 0; sl@0: roundupfactor = 7; sl@0: break; sl@0: } sl@0: default: sl@0: Panic(EFbsBitmapInvalidMode); sl@0: } sl@0: sl@0: aLength = Min(aLength,aBuf.MaxLength() << bitshift); sl@0: aBuf.SetLength((aLength + roundupfactor) >> bitshift); sl@0: sl@0: TUint32* ptr = (TUint32*)aBuf.Ptr(); // guaranteed to be word aligned by the calling function sl@0: TInt startlong = aX & roundingmask; sl@0: TInt finishlong = (aX + aLength + pixelsPerWord - 1) & roundingmask; sl@0: bitshift += 2; // Convert pixels per byte shift to pixels per word shift sl@0: TUint32* wordptr = aScanlinePtr + (startlong >> bitshift); sl@0: TInt wordLength = (finishlong - startlong) >> bitshift; sl@0: TUint32* wordptrLimit = wordptr + wordLength; sl@0: sl@0: const TInt destinationWords = Min(aBuf.MaxLength() >> 2,wordLength); sl@0: TUint32* ptrlimit = ptr + destinationWords; sl@0: sl@0: TInt offset = (aX - startlong) << logbpp; sl@0: sl@0: if (offset) sl@0: { sl@0: TInt offsetextra = 32-offset; sl@0: TUint32 data = *wordptr++; sl@0: data >>= offset; sl@0: sl@0: while (ptr < ptrlimit - 1) sl@0: { sl@0: TUint32 tmp = *wordptr++; sl@0: data |= tmp << offsetextra; sl@0: *ptr++ = data; sl@0: data = tmp >> offset; sl@0: } sl@0: sl@0: if (wordptr < wordptrLimit) sl@0: *ptr = data | (*wordptr << offsetextra); sl@0: else sl@0: *ptr = data; sl@0: } sl@0: else sl@0: { sl@0: while (ptr < ptrlimit) sl@0: *ptr++ = *wordptr++; sl@0: sl@0: // if the buffer isn't a whole number of words long, sl@0: // we need to copy the remaining bytes sl@0: const TInt bytesRemaining = aBuf.Length() - (destinationWords * sizeof(TUint32)); sl@0: if (bytesRemaining > 0) sl@0: Mem::Copy(ptr,wordptr,bytesRemaining); sl@0: sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::GetScanLineExBytes(TDes8& aBuf,TInt aX,TInt aLength,TUint32* aScanlinePtr) const sl@0: { sl@0: TInt numberOfBytesToCopy = 0; sl@0: TUint8* ptr = (TUint8*)aScanlinePtr; sl@0: TDisplayMode displayMode = iSettings.CurrentDisplayMode(); sl@0: switch(displayMode) sl@0: { sl@0: case EGray256: sl@0: case EColor256: sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength()); sl@0: numberOfBytesToCopy = aLength; sl@0: ptr += aX; sl@0: break; sl@0: } sl@0: case EColor4K: sl@0: case EColor64K: sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() / 2); sl@0: numberOfBytesToCopy = aLength * 2; sl@0: ptr += (aX << 1); sl@0: break; sl@0: } sl@0: case EColor16M: sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() / 3); sl@0: numberOfBytesToCopy = aLength * 3; sl@0: ptr += (aX * 3); sl@0: break; sl@0: } sl@0: case EColor16MU: sl@0: case EColor16MA: sl@0: case EColor16MAP: sl@0: { sl@0: aLength = Min(aLength,aBuf.MaxLength() / 4); sl@0: numberOfBytesToCopy = aLength * 4; sl@0: ptr += (aX * 4); sl@0: break; sl@0: } sl@0: default: sl@0: Panic(EFbsBitmapInvalidMode); sl@0: } sl@0: sl@0: aBuf.SetLength(numberOfBytesToCopy); sl@0: sl@0: Mem::Copy((TAny*)aBuf.Ptr(),ptr,numberOfBytesToCopy); sl@0: } sl@0: sl@0: void CBitwiseBitmap::DoStretchScanLine(TDes8& aBuf,TInt x,TInt y,TInt aClipStrchX, sl@0: TInt aClipStrchLen,TInt aStretchLength,TInt aOrgX,TInt aOrgLen, sl@0: const TPoint& aDitherOffset,TDisplayMode aDispMode,TUint32* aBase, sl@0: TLineScanningPosition& aLineScanningPosition) const sl@0: { sl@0: TInt lastValue = 0; sl@0: TUint32* bufptr=(TUint32*)((TInt)(&aBuf[0]+3)&~3); sl@0: TUint32* buflimit=bufptr; sl@0: TUint32* slptr=NULL; sl@0: TPoint pixel(aOrgX,y); sl@0: const TDisplayMode displayMode = iSettings.CurrentDisplayMode(); sl@0: GetScanLinePtr(slptr, aOrgLen, pixel,aBase, aLineScanningPosition); sl@0: if (!slptr) sl@0: { sl@0: WhiteFill((TUint8*)aBuf.Ptr(),aBuf.MaxLength(),displayMode); sl@0: return; sl@0: } sl@0: sl@0: TInt lastcoord=-1; sl@0: TLinearDDA stretchmap; sl@0: TPoint coordmap(aOrgX,0); sl@0: stretchmap.Construct(coordmap,coordmap+TPoint(aOrgLen,aStretchLength),TLinearDDA::ELeft); sl@0: coordmap.iY=aClipStrchX; sl@0: if (aClipStrchX>0) stretchmap.JumpToYCoord(coordmap.iX,coordmap.iY); sl@0: else stretchmap.SingleStep(coordmap); sl@0: switch(aDispMode) sl@0: { sl@0: case EGray4: sl@0: { sl@0: aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<4)); sl@0: aBuf.SetLength((aClipStrchLen+3)>>2); sl@0: buflimit+=(aBuf.Length()+3)>>2; sl@0: if (displayMode == EGray16) sl@0: { sl@0: TInt index=((aDitherOffset.iY&1)<<1)+((aDitherOffset.iX+x)&1); sl@0: while(bufptrlastcoord) sl@0: { sl@0: lastValue=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index); sl@0: lastcoord=coordmap.iX; sl@0: } sl@0: *bufptr|=(lastValue<lastcoord) sl@0: { sl@0: lastValue = GetGrayPixelEx(coordmap.iX,slptr) >> 6; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *bufptr |= (lastValue << shift); sl@0: shift += 2; sl@0: if (stretchmap.SingleStep(coordmap)) break; sl@0: } sl@0: bufptr++; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case EGray16: sl@0: { sl@0: aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<3)); sl@0: aBuf.SetLength((aClipStrchLen+1)>>1); sl@0: buflimit+=(aBuf.Length()+3)>>2; sl@0: while(bufptrlastcoord) sl@0: { sl@0: lastValue = GetGrayPixelEx(coordmap.iX,slptr) >> 4; sl@0: lastcoord=coordmap.iX; sl@0: } sl@0: *bufptr |= lastValue << shift; sl@0: shift+=4; sl@0: if (stretchmap.SingleStep(coordmap)) break; sl@0: } sl@0: bufptr++; sl@0: } sl@0: break; sl@0: } sl@0: case EColor16: sl@0: { sl@0: aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<3)); sl@0: aBuf.SetLength((aClipStrchLen+1)>>1); sl@0: buflimit+=(aBuf.Length()+3)>>2; sl@0: while(bufptrlastcoord) sl@0: { sl@0: lastValue = GetRgbPixelEx(coordmap.iX,slptr).Color16(); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *bufptr |= lastValue << shift; sl@0: shift+=4; sl@0: if (stretchmap.SingleStep(coordmap)) break; sl@0: } sl@0: bufptr++; sl@0: } sl@0: break; sl@0: } sl@0: case EGray256: sl@0: { sl@0: aClipStrchLen = Min(aClipStrchLen,(TInt)(aBuf.MaxLength() & ~3)); sl@0: aBuf.SetLength(aClipStrchLen); sl@0: buflimit += (aBuf.Length() + 3) >> 2; sl@0: sl@0: while (bufptr < buflimit) sl@0: { sl@0: TInt shift=0; sl@0: *bufptr=0; sl@0: while(shift<32) sl@0: { sl@0: if (coordmap.iX>lastcoord) sl@0: { sl@0: lastValue = GetGrayPixelEx(coordmap.iX,slptr); sl@0: lastcoord=coordmap.iX; sl@0: } sl@0: *bufptr |= lastValue << shift; sl@0: shift += 8; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: bufptr++; sl@0: } sl@0: break; sl@0: } sl@0: case EColor256: sl@0: { sl@0: aClipStrchLen = Min(aClipStrchLen,(TInt)(aBuf.MaxLength() & ~3)); sl@0: aBuf.SetLength(aClipStrchLen); sl@0: buflimit += (aBuf.Length() + 3) >> 2; sl@0: sl@0: while (bufptr < buflimit) sl@0: { sl@0: TInt shift=0; sl@0: *bufptr=0; sl@0: while(shift<32) sl@0: { sl@0: if (coordmap.iX>lastcoord) sl@0: { sl@0: lastValue = TUint8(GetRgbPixelEx(coordmap.iX,slptr).Color256()); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *bufptr |= lastValue << shift; sl@0: shift += 8; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: bufptr++; sl@0: } sl@0: break; sl@0: } sl@0: case EColor4K: sl@0: { sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1); sl@0: aBuf.SetLength(aClipStrchLen << 1); sl@0: buflimit += (aBuf.Length() + 3) >> 2; sl@0: sl@0: while (bufptr < buflimit) sl@0: { sl@0: if (coordmap.iX>lastcoord) sl@0: { sl@0: lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color4K(); sl@0: lastcoord=coordmap.iX; sl@0: } sl@0: *bufptr = lastValue; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: if (coordmap.iX>lastcoord) sl@0: { sl@0: lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color4K(); sl@0: lastcoord=coordmap.iX; sl@0: } sl@0: *bufptr |= lastValue << 16; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: bufptr++; sl@0: } sl@0: break; sl@0: } sl@0: case EColor64K: sl@0: { sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1); sl@0: aBuf.SetLength(aClipStrchLen << 1); sl@0: buflimit += (aBuf.Length() + 3) >> 2; sl@0: sl@0: while (bufptr < buflimit) sl@0: { sl@0: if (coordmap.iX>lastcoord) sl@0: { sl@0: lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color64K(); sl@0: lastcoord=coordmap.iX; sl@0: } sl@0: *bufptr = lastValue; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: if (coordmap.iX>lastcoord) sl@0: { sl@0: lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color64K(); sl@0: lastcoord=coordmap.iX; sl@0: } sl@0: *bufptr |= lastValue << 16; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: bufptr++; sl@0: } sl@0: break; sl@0: } sl@0: case EColor16M: // Destination Mode sl@0: { sl@0: // Optimisation: Both of conditions on 32bpp and 24bpp were added to avoid to use sl@0: // GetRgbPixelEx() for each pixel sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / 3); sl@0: aBuf.SetLength(aClipStrchLen * 3); sl@0: TUint8* ptr = (TUint8*)bufptr; sl@0: TUint8* ptrLimit = ptr + aBuf.Length(); sl@0: sl@0: if (iHeader.iBitsPerPixel == 32) // 32bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: if(displayMode == EColor16MAP) sl@0: { sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: while (ptr < ptrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *ptr++ = TUint8(lastColor); sl@0: *ptr++ = TUint8(lastColor >> 8); sl@0: *ptr++ = TUint8(lastColor >> 16); sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else{ sl@0: while (ptr < ptrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = *(slptr + coordmap.iX); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *ptr++ = TUint8(lastColor); sl@0: *ptr++ = TUint8(lastColor >> 8); sl@0: *ptr++ = TUint8(lastColor >> 16); sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: while (ptr < ptrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3; sl@0: lastColor = TUint8(*scanLineBytePointer); sl@0: scanLineBytePointer++; sl@0: lastColor |= TUint8(*scanLineBytePointer) << 8; sl@0: scanLineBytePointer++; sl@0: lastColor |= TUint8(*scanLineBytePointer) << 16; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *ptr++ = TUint8(lastColor); sl@0: *ptr++ = TUint8(lastColor >> 8); sl@0: *ptr++ = TUint8(lastColor >> 16); sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TRgb lastColor; sl@0: while (ptr < ptrLimit) sl@0: { sl@0: if (coordmap.iX>lastcoord) sl@0: { sl@0: lastColor = GetRgbPixelEx(coordmap.iX,slptr); sl@0: lastcoord=coordmap.iX; sl@0: } sl@0: TInt color16M = lastColor._Color16M(); sl@0: *ptr++ = TUint8(color16M); sl@0: *ptr++ = TUint8(color16M >> 8); sl@0: *ptr++ = TUint8(color16M >> 16); sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case ERgb: sl@0: { sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / sizeof(TRgb)); sl@0: aBuf.SetLength(aClipStrchLen * sizeof(TRgb)); sl@0: TRgb* pixelPtr = (TRgb*)bufptr; sl@0: TRgb* pixelPtrLimit = pixelPtr + aClipStrchLen; sl@0: TRgb lastColor; sl@0: sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = GetRgbPixelEx(coordmap.iX,slptr); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: break; sl@0: } sl@0: case EColor16MU: // Destination Mode sl@0: { sl@0: // Optimisation: The condition 32bpp was added to avoid to use sl@0: //GetRgbPixelEx() for each pixel (construction of a TRgb object each time) sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2); sl@0: aBuf.SetLength(aClipStrchLen << 2); sl@0: TInt32* pixelPtr = (TInt32*)bufptr; sl@0: TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen; sl@0: sl@0: if (iHeader.iBitsPerPixel == 32) //32bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: if(displayMode == EColor16MAP) sl@0: { sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = (lastColor | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else{ sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = *(slptr + coordmap.iX); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = (lastColor | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3; sl@0: lastColor = TUint8(*scanLineBytePointer); sl@0: scanLineBytePointer++; sl@0: lastColor |= TUint8(*scanLineBytePointer) << 8; sl@0: scanLineBytePointer++; sl@0: lastColor |= TUint8(*scanLineBytePointer) << 16; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = (lastColor | 0xff000000); sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: TUint rawColor = *(((TUint16*)slptr) + coordmap.iX); sl@0: TInt red = (rawColor & 0xF800)>>8; sl@0: red += red>>5; sl@0: TInt green = (rawColor & 0x07E0)>>3; sl@0: green += green>>6; sl@0: TInt blue = (rawColor & 0x001F)<<3; sl@0: blue += blue>>5; sl@0: lastColor = 0xff000000 | (red << 16) | (green << 8) | blue; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TRgb lastColor; sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = GetRgbPixelEx(coordmap.iX,slptr); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = (lastColor._Color16MU() | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case EColor16MA: sl@0: { sl@0: // Optimisation: The condition 32bpp was added to avoid to use sl@0: // GetRgbPixelEx() for each pixel (construction of a TRgb object each time) sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2); sl@0: aBuf.SetLength(aClipStrchLen << 2); sl@0: TInt32* pixelPtr = (TInt32*)bufptr; sl@0: TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen; sl@0: const TUint16* normTable = PtrTo16BitNormalisationTable(); sl@0: if (iHeader.iBitsPerPixel == 32) //32bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: if(displayMode == EColor16MAP) sl@0: { sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = *(slptr + coordmap.iX); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3; sl@0: lastColor = TUint8(*scanLineBytePointer); sl@0: scanLineBytePointer++; sl@0: lastColor |= TUint8(*scanLineBytePointer) << 8; sl@0: scanLineBytePointer++; sl@0: lastColor |= TUint8(*scanLineBytePointer) << 16; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = (lastColor | 0xff000000); sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: TUint rawColor = *(((TUint16*)slptr) + coordmap.iX); sl@0: TInt red = (rawColor & 0xF800)>>8; sl@0: red += red>>5; sl@0: TInt green = (rawColor & 0x07E0)>>3; sl@0: green += green>>6; sl@0: TInt blue = (rawColor & 0x001F)<<3; sl@0: blue += blue>>5; sl@0: lastColor = 0xff000000 | (red << 16) | (green << 8) | blue; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TRgb lastColor; sl@0: sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = GetRgbPixelEx(coordmap.iX,slptr); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor._Color16MA();//BGRA (Blue/Green/Red) as little endian byte order sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case EColor16MAP: sl@0: { //if alpha is not available, assign 255 as alpha (opaque). sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2); sl@0: aBuf.SetLength(aClipStrchLen << 2); sl@0: TInt32* pixelPtr = (TInt32*)bufptr; sl@0: TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen; sl@0: if (iHeader.iBitsPerPixel == 32) //32bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: //pre-multiply if alpha IS available. sl@0: if(displayMode == EColor16MA) sl@0: { sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = NonPMA2PMAPixel(*(slptr + coordmap.iX)); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else if(displayMode == EColor16MU) sl@0: { sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: //do not want to convert to non pma, since keep transparency sl@0: //e.g. alpha 0.5, red 0.5. Want to keep red as 0.5 since it sl@0: //is not fully red. For 16MA convert to 1, and keep 0.5 alpha sl@0: lastColor = (*(slptr + coordmap.iX))|0xff000000; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = *(slptr + coordmap.iX); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3; sl@0: lastColor = TUint8(*scanLineBytePointer); sl@0: scanLineBytePointer++; sl@0: lastColor |= TUint8(*scanLineBytePointer) << 8; sl@0: scanLineBytePointer++; sl@0: lastColor |= TUint8(*scanLineBytePointer) << 16; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = (lastColor | 0xff000000); sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color sl@0: { sl@0: TInt lastColor = 0; sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: TUint rawColor = *(((TUint16*)slptr) + coordmap.iX); sl@0: TInt red = (rawColor & 0xF800)>>8; sl@0: red += red>>5; sl@0: TInt green = (rawColor & 0x07E0)>>3; sl@0: green += green>>6; sl@0: TInt blue = (rawColor & 0x001F)<<3; sl@0: blue += blue>>5; sl@0: lastColor = 0xff000000 | (red << 16) | (green << 8) | blue; sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor; sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TRgb lastColor; sl@0: sl@0: while (pixelPtr < pixelPtrLimit) sl@0: { sl@0: if (coordmap.iX > lastcoord) sl@0: { sl@0: lastColor = GetRgbPixelEx(coordmap.iX,slptr); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: *pixelPtr++ = lastColor._Color16MA();//BGRA (Blue/Green/Red) as little endian byte order sl@0: if (stretchmap.SingleStep(coordmap)) sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case EGray2: sl@0: { sl@0: TBool oddx=(aDitherOffset.iX&1); sl@0: TBool oddy=(aDitherOffset.iY&1); sl@0: aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<5)); sl@0: aBuf.SetLength((aClipStrchLen+7)>>3); sl@0: buflimit+=(aBuf.Length()+3)>>2; sl@0: while(bufptr lastcoord) sl@0: { sl@0: lastValue = GetGrayPixelEx(coordmap.iX,slptr); sl@0: lastcoord = coordmap.iX; sl@0: } sl@0: if (HashTo1bpp(lastValue,oddx,oddy)) sl@0: *bufptr|=mask; sl@0: mask<<=1; sl@0: oddx^=1; sl@0: if (stretchmap.SingleStep(coordmap)) break; sl@0: } sl@0: bufptr++; sl@0: } sl@0: break; sl@0: } sl@0: default: sl@0: Panic(EFbsBitmapInvalidMode); sl@0: } sl@0: } sl@0: sl@0: void CBitwiseBitmap::DoCompressScanLine(TDes8& aBuf,TInt x,TInt y,TInt aClipStrchX,TInt aClipStrchLen,TInt aStretchLength,TInt aOrgX,TInt aOrgLen,const TPoint& aDitherOffset,TDisplayMode aDispMode,TUint32* aBase,TLineScanningPosition& aLineScanningPosition) const sl@0: { sl@0: TInt first=0,second=0,third=0,fourth=0,fifth=0,sixth=0,seventh=0,eighth=0; sl@0: TUint8* bufptr=&aBuf[0]; sl@0: TUint8* buflimit=bufptr; sl@0: TUint32* slptr=NULL; sl@0: TPoint pixel(aOrgX,y); sl@0: TDisplayMode displayMode = iSettings.CurrentDisplayMode(); sl@0: GetScanLinePtr(slptr,aOrgLen,pixel,aBase, aLineScanningPosition); sl@0: if (!slptr) sl@0: { sl@0: WhiteFill((TUint8*)aBuf.Ptr(),aBuf.MaxLength(),displayMode); sl@0: return; sl@0: } sl@0: TLinearDDA stretchmap; sl@0: TPoint coordmap(aOrgX,0); sl@0: stretchmap.Construct(coordmap,coordmap+TPoint(aOrgLen,aStretchLength),TLinearDDA::ELeft); sl@0: coordmap.iY=aClipStrchX; sl@0: if (aClipStrchX>0) stretchmap.JumpToYCoord(coordmap.iX,coordmap.iY); sl@0: else stretchmap.NextStep(coordmap); sl@0: switch(aDispMode) sl@0: { sl@0: case EGray4: sl@0: { sl@0: aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<2)); sl@0: aBuf.SetLength((aClipStrchLen+3)>>2); sl@0: TInt index=((aDitherOffset.iY&1)<<1)+((aDitherOffset.iX+x)&1); sl@0: buflimit+=aBuf.Length(); sl@0: if (displayMode==EGray16) sl@0: { sl@0: while(bufptr>6; sl@0: stretchmap.NextStep(coordmap); sl@0: second=GetGrayPixelEx(coordmap.iX,slptr)>>6; sl@0: stretchmap.NextStep(coordmap); sl@0: third=GetGrayPixelEx(coordmap.iX,slptr)>>6; sl@0: stretchmap.NextStep(coordmap); sl@0: fourth=GetGrayPixelEx(coordmap.iX,slptr)>>6; sl@0: *bufptr++=TUint8(first|(second<<2)|(third<<4)|(fourth<<6)); sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case EGray16: sl@0: { sl@0: aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<1)); sl@0: aBuf.SetLength((aClipStrchLen+1)>>1); sl@0: buflimit+=aBuf.Length(); sl@0: while(bufptr> 4; sl@0: stretchmap.NextStep(coordmap); sl@0: first |= GetGrayPixelEx(coordmap.iX,slptr) & 0xf0; sl@0: *bufptr++ = TUint8(first); sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: break; sl@0: } sl@0: case EColor16: sl@0: { sl@0: aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<1)); sl@0: aBuf.SetLength((aClipStrchLen+1)>>1); sl@0: buflimit+=aBuf.Length(); sl@0: while(bufptr> 1); sl@0: aBuf.SetLength(aClipStrchLen << 1); sl@0: buflimit += aBuf.Length(); sl@0: sl@0: while(bufptr < buflimit) sl@0: { sl@0: *((TUint16*)bufptr) = TUint16(GetRgbPixelEx(coordmap.iX,slptr)._Color4K()); sl@0: bufptr += 2; sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: break; sl@0: } sl@0: case EColor64K: sl@0: { sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1); sl@0: aBuf.SetLength(aClipStrchLen << 1); sl@0: buflimit += aBuf.Length(); sl@0: sl@0: while(bufptr < buflimit) sl@0: { sl@0: *((TUint16*)bufptr) = TUint16(GetRgbPixelEx(coordmap.iX,slptr)._Color64K()); sl@0: bufptr += 2; sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: break; sl@0: } sl@0: case EColor16M: sl@0: { sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / 3); sl@0: aBuf.SetLength(aClipStrchLen * 3); sl@0: buflimit += aBuf.Length(); sl@0: sl@0: while(bufptr> 8); sl@0: *bufptr++ = TUint8(color16M >> 16); sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: break; sl@0: } sl@0: case ERgb: sl@0: case EColor16MU: sl@0: case EColor16MA: sl@0: case EColor16MAP: sl@0: { sl@0: aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2); sl@0: aBuf.SetLength(aClipStrchLen << 2); sl@0: TUint32* pixelPtr = (TUint32*)bufptr; sl@0: TUint32* pixelPtrLimit = pixelPtr + aClipStrchLen; sl@0: if (aDispMode == EColor16MAP && displayMode == EColor16MA) sl@0: while(pixelPtr < pixelPtrLimit) sl@0: { sl@0: *pixelPtr++ = NonPMA2PMAPixel(*(slptr + coordmap.iX)); sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: else if (aDispMode == EColor16MAP && displayMode == EColor16MAP) sl@0: while(pixelPtr < pixelPtrLimit) sl@0: { sl@0: *pixelPtr++ = *(slptr + coordmap.iX); sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: else if (aDispMode == EColor16MU) sl@0: while(pixelPtr < pixelPtrLimit) sl@0: { sl@0: *pixelPtr++ = GetRgbPixelEx(coordmap.iX, slptr).Internal(); sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: else sl@0: while(pixelPtr < pixelPtrLimit) sl@0: { sl@0: *pixelPtr++ = GetRgbPixelEx(coordmap.iX, slptr).Internal(); sl@0: stretchmap.NextStep(coordmap); sl@0: } sl@0: break; sl@0: } sl@0: case EGray2: sl@0: { sl@0: TBool oddx=(aDitherOffset.iX&1); sl@0: TBool oddy=(aDitherOffset.iY&1); sl@0: aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<3)); sl@0: aBuf.SetLength((aClipStrchLen+7)>>3); sl@0: buflimit+=aBuf.Length(); sl@0: while(bufptr