1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/fbs/fontandbitmapserver/sfbs/BITBMPEX.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1479 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <f32file.h>
1.20 +#include <s32file.h>
1.21 +#include <fbs.h>
1.22 +#include <bitmap.h>
1.23 +#include "UTILS.H"
1.24 +#include <graphics/blendingalgorithms.h>
1.25 +#include <graphics/lookuptable.h>
1.26 +//#include "12to16.h" // lookup table for 12->16 bpp conversion
1.27 +
1.28 +#ifdef __ARMCC__
1.29 +#pragma arm
1.30 +#pragma O3
1.31 +#pragma Otime
1.32 +#endif
1.33 +
1.34 +GLREF_C void Panic(TFbsPanic aPanic);
1.35 +
1.36 +#define COLOR_VALUE(ScanLinePtr, XPos) (*((ScanLinePtr) + ((XPos) >> 5)) & ( 1 << ((XPos) & 0x1F)))
1.37 +
1.38 +
1.39 +void CBitwiseBitmap::GetScanLineGray2(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TBool aDither,const TPoint& aDitherOffset,TUint32* aScanlinePtr) const
1.40 + {
1.41 + aLength = Min(aLength,(TInt)((aBuf.MaxLength()) << 3));
1.42 + aBuf.SetLength((aLength + 7) >> 3);
1.43 +
1.44 + TUint8* ptr = (TUint8*)aBuf.Ptr();
1.45 +
1.46 + TUint8 mask = 1;
1.47 + TInt x = aPixel.iX;
1.48 + *ptr=0;
1.49 +
1.50 + if (aDither)
1.51 + {
1.52 + TBool oddx = aDitherOffset.iX & 1;
1.53 + TBool oddy = aDitherOffset.iY & 1;
1.54 +
1.55 + for(TInt count = 0;count < aLength;count++)
1.56 + {
1.57 + if (!mask)
1.58 + {
1.59 + mask = 1;
1.60 + ptr++;
1.61 + *ptr = 0;
1.62 + }
1.63 + if (HashTo1bpp(GetGrayPixelEx(x,aScanlinePtr),oddx,oddy))
1.64 + *ptr |= mask;
1.65 + mask <<= 1;
1.66 + oddx ^= 1;
1.67 + x++;
1.68 + }
1.69 + }
1.70 + else
1.71 + {
1.72 + for(TInt count = 0;count < aLength;count++)
1.73 + {
1.74 + if (!mask)
1.75 + {
1.76 + mask = 1;
1.77 + ptr++;
1.78 + *ptr = 0;
1.79 + }
1.80 + if (GetGrayPixelEx(x,aScanlinePtr) > 127)
1.81 + *ptr |= mask;
1.82 + mask <<= 1;
1.83 + x++;
1.84 + }
1.85 + }
1.86 + }
1.87 +
1.88 +void CBitwiseBitmap::GetScanLineGray4(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TBool aDither,const TPoint& aDitherOffset,TUint32* aScanlinePtr) const
1.89 + {
1.90 + aLength = Min(aLength,(TInt)((aBuf.MaxLength())<<2));
1.91 + aBuf.SetLength((aLength + 3) >> 2);
1.92 +
1.93 + TUint8* ptr=(TUint8*)aBuf.Ptr();
1.94 +
1.95 + TInt x = aPixel.iX;
1.96 + if (iSettings.CurrentDisplayMode() == EGray16 && aDither)
1.97 + {
1.98 + *ptr=0;
1.99 + TInt shift = 0;
1.100 + TUint8 col = 0;
1.101 + const TInt hasharray[4]={0,3,2,1};
1.102 + TInt index = (aDitherOffset.iX&1)+((aDitherOffset.iY&1)<<1);
1.103 + for(TInt count=0;count<aLength;count++,shift+=2)
1.104 + {
1.105 + if (shift==8)
1.106 + {
1.107 + shift = 0;
1.108 + ptr++;
1.109 + *ptr = 0;
1.110 + }
1.111 + col = TUint8(GetGrayPixelEx(x+count,aScanlinePtr) >> 4);
1.112 + TInt value=col/5;
1.113 + col%=5;
1.114 + if (col>2) col--;
1.115 + if (hasharray[index]<TInt(col))
1.116 + value++;
1.117 + value<<=shift;
1.118 + *ptr|=value;
1.119 + index^=1;
1.120 + }
1.121 + }
1.122 + else
1.123 + {
1.124 + TUint8* ptrLimit = ptr + ((aLength + 3) >> 2);
1.125 + while (ptr < ptrLimit)
1.126 + {
1.127 + TUint8 pixelGrayShade = TUint8(GetGrayPixelEx(x++,aScanlinePtr) >> 6);
1.128 + pixelGrayShade |= TUint8((GetGrayPixelEx(x++,aScanlinePtr) >> 4) & 0x0c);
1.129 + pixelGrayShade |= TUint8((GetGrayPixelEx(x++,aScanlinePtr) >> 2) & 0x30);
1.130 + pixelGrayShade |= TUint8(GetGrayPixelEx(x++,aScanlinePtr) & 0xc0);
1.131 + *ptr++ = pixelGrayShade;
1.132 + }
1.133 + }
1.134 + }
1.135 +
1.136 +void CBitwiseBitmap::GetScanLineGray16(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.137 + {
1.138 + aLength=Min(aLength,(TInt)(aBuf.MaxLength()<<1));
1.139 + aBuf.SetLength((aLength + 1) >> 1);
1.140 +
1.141 + TUint8* ptr = (TUint8*)aBuf.Ptr();
1.142 + TUint8* ptrLimit = ptr + aBuf.Length();
1.143 + TInt x = aPixel.iX;
1.144 +
1.145 + if(iHeader.iBitsPerPixel == 1)
1.146 + {
1.147 + while (ptr < ptrLimit)
1.148 + {
1.149 + TUint8 pixelGrayShade = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0x0F : 0);
1.150 + x++;
1.151 + pixelGrayShade |= TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xF0 : 0);
1.152 + x++;
1.153 + *ptr++ = pixelGrayShade;
1.154 + }
1.155 + }
1.156 + else
1.157 + {
1.158 + while (ptr < ptrLimit)
1.159 + {
1.160 + TUint8 pixelGrayShade = TUint8(GetGrayPixelEx(x++,aScanlinePtr) >> 4);
1.161 + pixelGrayShade |= GetGrayPixelEx(x++,aScanlinePtr) & 0xf0;
1.162 + *ptr++ = pixelGrayShade;
1.163 + }
1.164 + }
1.165 + }
1.166 +
1.167 +void CBitwiseBitmap::GetScanLineGray256(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.168 + {
1.169 + aLength = Min(aLength,aBuf.MaxLength());
1.170 + aBuf.SetLength(aLength);
1.171 +
1.172 + TUint8* ptr = (TUint8*)aBuf.Ptr();
1.173 + TUint8* ptrLimit = ptr + aLength;
1.174 + TInt xCoord = aPixel.iX;
1.175 +
1.176 + if(iHeader.iBitsPerPixel == 1)
1.177 + {
1.178 + while (ptr < ptrLimit)
1.179 + {
1.180 + *ptr++ = TUint8(COLOR_VALUE(aScanlinePtr, xCoord) ? 0xFF : 0);
1.181 + xCoord++;
1.182 + }
1.183 + }
1.184 + else
1.185 + {
1.186 + while (ptr < ptrLimit)
1.187 + *ptr++ = GetGrayPixelEx(xCoord++,aScanlinePtr);
1.188 + }
1.189 + }
1.190 +
1.191 +void CBitwiseBitmap::GetScanLineColor16(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.192 + {
1.193 + aLength=Min(aLength,(TInt)(aBuf.MaxLength()<<1));
1.194 + aBuf.SetLength((aLength + 1) >> 1);
1.195 +
1.196 + TUint8* ptr = (TUint8*)aBuf.Ptr();
1.197 + TUint8* ptrLimit = ptr + aBuf.Length();
1.198 + TInt x = aPixel.iX;
1.199 +
1.200 + if(iHeader.iBitsPerPixel == 1)
1.201 + {
1.202 + while (ptr < ptrLimit)
1.203 + {
1.204 + TUint8 pixelGrayShade = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0x0F : 0);
1.205 + x++;
1.206 + pixelGrayShade |= TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xF0 : 0);
1.207 + x++;
1.208 + *ptr++ = pixelGrayShade;
1.209 + }
1.210 + }
1.211 + else
1.212 + {
1.213 + while (ptr < ptrLimit)
1.214 + {
1.215 + TUint8 pixelGrayShade = TUint8(GetRgbPixelEx(x++,aScanlinePtr).Color16());
1.216 + pixelGrayShade |= GetRgbPixelEx(x++,aScanlinePtr).Color16() << 4;
1.217 + *ptr++ = pixelGrayShade;
1.218 + }
1.219 + }
1.220 + }
1.221 +
1.222 +void CBitwiseBitmap::GetScanLineColor256(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.223 + {
1.224 + aLength = Min(aLength,aBuf.MaxLength());
1.225 + aBuf.SetLength(aLength);
1.226 +
1.227 + TUint8* ptr = (TUint8*)aBuf.Ptr();
1.228 + TUint8* ptrLimit = ptr + aLength;
1.229 + TInt xCoord = aPixel.iX;
1.230 +
1.231 + if(iHeader.iBitsPerPixel == 1)
1.232 + {
1.233 + while (ptr < ptrLimit)
1.234 + {
1.235 + *ptr++ = TUint8(COLOR_VALUE(aScanlinePtr, xCoord) ? 0xFF : 0);
1.236 + xCoord++;
1.237 + }
1.238 + }
1.239 + else
1.240 + {
1.241 + while (ptr < ptrLimit)
1.242 + *ptr++ = TUint8(GetRgbPixelEx(xCoord++,aScanlinePtr).Color256());
1.243 + }
1.244 + }
1.245 +
1.246 +void CBitwiseBitmap::GetScanLineColor4K(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.247 + {
1.248 + aLength = Min(aLength,aBuf.MaxLength() >> 1);
1.249 + aBuf.SetLength(aLength << 1);
1.250 +
1.251 + TUint16* ptr = (TUint16*)aBuf.Ptr();
1.252 + const TUint16* ptrLimit = ptr + aLength;
1.253 + TInt x = aPixel.iX;
1.254 +
1.255 + if(iHeader.iBitsPerPixel == 1)
1.256 + {
1.257 + while (ptr < ptrLimit)
1.258 + {
1.259 + *ptr++ = TUint16(COLOR_VALUE(aScanlinePtr, x) ? 0x0FFF : 0);
1.260 + x++;
1.261 + }
1.262 + }
1.263 + else
1.264 + {
1.265 + while (ptr < ptrLimit)
1.266 + *ptr++ = TUint16(GetRgbPixelEx(x++,aScanlinePtr)._Color4K());
1.267 + }
1.268 + }
1.269 +
1.270 +void CBitwiseBitmap::GetScanLineColor64K(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.271 + {
1.272 + aLength = Min(aLength,aBuf.MaxLength() >> 1);
1.273 + aBuf.SetLength(aLength << 1);
1.274 +
1.275 + TUint16* ptr = (TUint16*)aBuf.Ptr();
1.276 + TUint16* ptrLimit = ptr + aLength;
1.277 + TInt x = aPixel.iX;
1.278 +
1.279 + if(iHeader.iBitsPerPixel == 1)
1.280 + {
1.281 + while (ptr < ptrLimit)
1.282 + {
1.283 + *ptr++ = TUint16(COLOR_VALUE(aScanlinePtr, x) ? 0xFFFF : 0);
1.284 + x++;
1.285 + }
1.286 + }
1.287 + else if(iHeader.iBitsPerPixel == 12)
1.288 + {
1.289 +/*
1.290 + // use lookup table for 12->16 conversion
1.291 + TUint16* pixel4K = ((TUint16*) aScanlinePtr) + x;
1.292 + while(ptr < ptrLimit)
1.293 + {
1.294 + // this takes the 12 bit value, this is a number between 0 and 4095,
1.295 + // and looks up its corrosponding 16 bit value in the lookup table.
1.296 + // the colour should be identical, and but just in a different format
1.297 + // see below for an explaination of 12 & 16 bit colour values
1.298 + *ptr++ = K12to16LUT[*pixel4K++];
1.299 + }
1.300 +*/
1.301 +/* This code uses logic rather than a lookup table
1.302 + to convert from 12->16 bpp and can be used instead of the above code
1.303 + if the 8k the lookup table uses becomes an issue
1.304 +
1.305 + 12 bit colour
1.306 + -------------
1.307 + The 12 bit colour format uses 4 bits for the red, green and blue values.
1.308 + The colour is stored as a word with the most significant 4 bits having a
1.309 + value of zero.
1.310 + i.e. 0000RRRR GGGGBBBB where R,G & B represent single bits in the word.
1.311 +
1.312 + The code below labeled 'conversion of 4k colour...' changes the colour from
1.313 + 16 bit to 32 bit where each colour nibble in the 16 bit version is changed
1.314 + to a byte in the 32 bit version e.g.
1.315 + 0000RRRR GGGGBBBB -> 00000000 RRRRRRRR GGGGGGGG BBBBBBBB
1.316 +
1.317 +
1.318 + 16 bit colour
1.319 + -------------
1.320 + The 16 bit colour format uses all 16 bits to represent the required colour.
1.321 + There are two possible 16 bit formats 5-5-5 and 5-6-5.
1.322 + Symbian uses the 5-6-5 format, with this all 16 bits are used to make the colour
1.323 + giving a possible value between 0..65535. The RGB components are divided up
1.324 + as follows RRRR RGGG GGGB BBBB i.e. 5 bits for red and blue, and 6 for green.
1.325 +
1.326 + The code below labeled 'conversion to 64k' converts the colour from a 16 bit
1.327 + 0000 RRRR GGGG BBBB -> RRRR RGGG GGGB BBBB format.
1.328 +*/
1.329 + register TUint16* pixel4K = ((TUint16*) aScanlinePtr) + x;
1.330 + while (ptr < ptrLimit)
1.331 + {
1.332 + // conversion of 4k colour from 16 to 32 bits
1.333 + // this changes from a 16 to 32 bit value while keeping colour unchanged
1.334 + register TUint16 pixelVal = *pixel4K++;
1.335 + register TUint32 value32 = ((pixelVal & 0x0f00) >> 8) |
1.336 + ((pixelVal & 0x00f0) << 4) |
1.337 + ((pixelVal & 0x000f) << 16);
1.338 + value32 |= (value32 << 4);
1.339 + // conversion to 64k (RRRR RGGG GGGB BBBB)
1.340 + // this will make the change from (16 bit) 4-4-4 bpp to 5-6-5 bpp format
1.341 + register TUint32 color64K = ((value32 & 0x000000f8) << 8) |
1.342 + ((value32 & 0x0000fc00) >> 5) |
1.343 + ((value32 & 0x00f80000) >> 19);
1.344 + // store new colour value
1.345 + *ptr++ = static_cast <TUint16> (color64K);
1.346 + }
1.347 + }
1.348 + else
1.349 + {
1.350 + while (ptr < ptrLimit)
1.351 + *ptr++ = TUint16(GetRgbPixelEx(x++,aScanlinePtr)._Color64K());
1.352 + }
1.353 + }
1.354 +
1.355 +void CBitwiseBitmap::GetScanLineColor16M(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.356 + {
1.357 + aLength = Min(aLength,aBuf.MaxLength() / 3);
1.358 + aBuf.SetLength(aLength * 3);
1.359 +
1.360 + TUint8* ptr = (TUint8*)aBuf.Ptr();
1.361 + TUint8* ptrLimit = ptr + (aLength * 3);
1.362 + TInt x = aPixel.iX;
1.363 +
1.364 + if(iHeader.iBitsPerPixel == 1)
1.365 + {
1.366 + while (ptr < ptrLimit)
1.367 + {
1.368 + const TUint8 color = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xFF : 0);
1.369 + *ptr++ = color;
1.370 + *ptr++ = color;
1.371 + *ptr++ = color;
1.372 + x++;
1.373 + }
1.374 + }
1.375 + else
1.376 + {
1.377 + GetRgbPixelExMany16M(aPixel.iX,aScanlinePtr,ptr,aLength);
1.378 + }
1.379 + }
1.380 +
1.381 +void CBitwiseBitmap::GetScanLineColor16MU(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.382 + {
1.383 + aLength = Min(aLength,aBuf.MaxLength() >> 2);
1.384 + aBuf.SetLength(aLength << 2);
1.385 +
1.386 + TUint32* ptr = (TUint32*)aBuf.Ptr();
1.387 +
1.388 + GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength);
1.389 + }
1.390 +
1.391 +void CBitwiseBitmap::GetScanLineColor16MA(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.392 + {
1.393 + aLength = Min(aLength,aBuf.MaxLength() >> 2);
1.394 + aBuf.SetLength(aLength << 2);
1.395 +
1.396 + TUint32* ptr = (TUint32*)aBuf.Ptr();
1.397 + GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength);
1.398 + }
1.399 +
1.400 +/**
1.401 +Get the scanline data into the destination buffer in the EColor16MAP format.
1.402 +@param aDestBuf - destination buffer
1.403 +@param aPixel - the start position of the scanline.
1.404 +@param aLength - scanline length, as word length
1.405 +@param aScanlinePtr - scanline pointer
1.406 +*/
1.407 +void CBitwiseBitmap::GetScanLineColor16MAP(TDes8& aDestBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.408 + {
1.409 + aLength = Min(aLength, aDestBuf.MaxLength() >> 2);
1.410 + aDestBuf.SetLength(aLength << 2);
1.411 + TUint32* ptr = (TUint32*)aDestBuf.Ptr();
1.412 + GetRgbPixelExMany16MAP(aPixel.iX,aScanlinePtr,ptr,aLength);
1.413 + }
1.414 +
1.415 +
1.416 +void CBitwiseBitmap::GetScanLineColorRgb(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
1.417 + {
1.418 + aLength = Min(aLength,aBuf.MaxLength() / sizeof(TRgb));
1.419 + aBuf.SetLength(aLength * sizeof(TRgb));
1.420 +
1.421 + TUint32* ptr = (TUint32*)aBuf.Ptr();
1.422 + GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength);
1.423 + }
1.424 +
1.425 +void CBitwiseBitmap::GetScanLineExBits(TDes8& aBuf,TInt aX,TInt aLength,TUint32* aScanlinePtr) const
1.426 + {
1.427 + TInt bitshift = 1;
1.428 + TInt pixelsPerWord = 8;
1.429 + TInt roundingmask = ~0x7;
1.430 + TInt logbpp = 2;
1.431 + TInt roundupfactor = 1;
1.432 + const TDisplayMode displayMode = iSettings.CurrentDisplayMode();
1.433 +
1.434 + switch(displayMode)
1.435 + {
1.436 + case EGray16:
1.437 + case EColor16:
1.438 + break; // set by default
1.439 + case EGray4:
1.440 + {
1.441 + bitshift = 2;
1.442 + pixelsPerWord = 16;
1.443 + roundingmask = ~0xf;
1.444 + logbpp = 1;
1.445 + roundupfactor = 3;
1.446 + break;
1.447 + }
1.448 + case EGray2:
1.449 + {
1.450 + bitshift = 3;
1.451 + pixelsPerWord = 32;
1.452 + roundingmask = ~0x1f;
1.453 + logbpp = 0;
1.454 + roundupfactor = 7;
1.455 + break;
1.456 + }
1.457 + default:
1.458 + Panic(EFbsBitmapInvalidMode);
1.459 + }
1.460 +
1.461 + aLength = Min(aLength,aBuf.MaxLength() << bitshift);
1.462 + aBuf.SetLength((aLength + roundupfactor) >> bitshift);
1.463 +
1.464 + TUint32* ptr = (TUint32*)aBuf.Ptr(); // guaranteed to be word aligned by the calling function
1.465 + TInt startlong = aX & roundingmask;
1.466 + TInt finishlong = (aX + aLength + pixelsPerWord - 1) & roundingmask;
1.467 + bitshift += 2; // Convert pixels per byte shift to pixels per word shift
1.468 + TUint32* wordptr = aScanlinePtr + (startlong >> bitshift);
1.469 + TInt wordLength = (finishlong - startlong) >> bitshift;
1.470 + TUint32* wordptrLimit = wordptr + wordLength;
1.471 +
1.472 + const TInt destinationWords = Min(aBuf.MaxLength() >> 2,wordLength);
1.473 + TUint32* ptrlimit = ptr + destinationWords;
1.474 +
1.475 + TInt offset = (aX - startlong) << logbpp;
1.476 +
1.477 + if (offset)
1.478 + {
1.479 + TInt offsetextra = 32-offset;
1.480 + TUint32 data = *wordptr++;
1.481 + data >>= offset;
1.482 +
1.483 + while (ptr < ptrlimit - 1)
1.484 + {
1.485 + TUint32 tmp = *wordptr++;
1.486 + data |= tmp << offsetextra;
1.487 + *ptr++ = data;
1.488 + data = tmp >> offset;
1.489 + }
1.490 +
1.491 + if (wordptr < wordptrLimit)
1.492 + *ptr = data | (*wordptr << offsetextra);
1.493 + else
1.494 + *ptr = data;
1.495 + }
1.496 + else
1.497 + {
1.498 + while (ptr < ptrlimit)
1.499 + *ptr++ = *wordptr++;
1.500 +
1.501 + // if the buffer isn't a whole number of words long,
1.502 + // we need to copy the remaining bytes
1.503 + const TInt bytesRemaining = aBuf.Length() - (destinationWords * sizeof(TUint32));
1.504 + if (bytesRemaining > 0)
1.505 + Mem::Copy(ptr,wordptr,bytesRemaining);
1.506 +
1.507 + }
1.508 + }
1.509 +
1.510 +void CBitwiseBitmap::GetScanLineExBytes(TDes8& aBuf,TInt aX,TInt aLength,TUint32* aScanlinePtr) const
1.511 + {
1.512 + TInt numberOfBytesToCopy = 0;
1.513 + TUint8* ptr = (TUint8*)aScanlinePtr;
1.514 + TDisplayMode displayMode = iSettings.CurrentDisplayMode();
1.515 + switch(displayMode)
1.516 + {
1.517 + case EGray256:
1.518 + case EColor256:
1.519 + {
1.520 + aLength = Min(aLength,aBuf.MaxLength());
1.521 + numberOfBytesToCopy = aLength;
1.522 + ptr += aX;
1.523 + break;
1.524 + }
1.525 + case EColor4K:
1.526 + case EColor64K:
1.527 + {
1.528 + aLength = Min(aLength,aBuf.MaxLength() / 2);
1.529 + numberOfBytesToCopy = aLength * 2;
1.530 + ptr += (aX << 1);
1.531 + break;
1.532 + }
1.533 + case EColor16M:
1.534 + {
1.535 + aLength = Min(aLength,aBuf.MaxLength() / 3);
1.536 + numberOfBytesToCopy = aLength * 3;
1.537 + ptr += (aX * 3);
1.538 + break;
1.539 + }
1.540 + case EColor16MU:
1.541 + case EColor16MA:
1.542 + case EColor16MAP:
1.543 + {
1.544 + aLength = Min(aLength,aBuf.MaxLength() / 4);
1.545 + numberOfBytesToCopy = aLength * 4;
1.546 + ptr += (aX * 4);
1.547 + break;
1.548 + }
1.549 + default:
1.550 + Panic(EFbsBitmapInvalidMode);
1.551 + }
1.552 +
1.553 + aBuf.SetLength(numberOfBytesToCopy);
1.554 +
1.555 + Mem::Copy((TAny*)aBuf.Ptr(),ptr,numberOfBytesToCopy);
1.556 + }
1.557 +
1.558 +void CBitwiseBitmap::DoStretchScanLine(TDes8& aBuf,TInt x,TInt y,TInt aClipStrchX,
1.559 + TInt aClipStrchLen,TInt aStretchLength,TInt aOrgX,TInt aOrgLen,
1.560 + const TPoint& aDitherOffset,TDisplayMode aDispMode,TUint32* aBase,
1.561 + TLineScanningPosition& aLineScanningPosition) const
1.562 + {
1.563 + TInt lastValue = 0;
1.564 + TUint32* bufptr=(TUint32*)((TInt)(&aBuf[0]+3)&~3);
1.565 + TUint32* buflimit=bufptr;
1.566 + TUint32* slptr=NULL;
1.567 + TPoint pixel(aOrgX,y);
1.568 + const TDisplayMode displayMode = iSettings.CurrentDisplayMode();
1.569 + GetScanLinePtr(slptr, aOrgLen, pixel,aBase, aLineScanningPosition);
1.570 + if (!slptr)
1.571 + {
1.572 + WhiteFill((TUint8*)aBuf.Ptr(),aBuf.MaxLength(),displayMode);
1.573 + return;
1.574 + }
1.575 +
1.576 + TInt lastcoord=-1;
1.577 + TLinearDDA stretchmap;
1.578 + TPoint coordmap(aOrgX,0);
1.579 + stretchmap.Construct(coordmap,coordmap+TPoint(aOrgLen,aStretchLength),TLinearDDA::ELeft);
1.580 + coordmap.iY=aClipStrchX;
1.581 + if (aClipStrchX>0) stretchmap.JumpToYCoord(coordmap.iX,coordmap.iY);
1.582 + else stretchmap.SingleStep(coordmap);
1.583 + switch(aDispMode)
1.584 + {
1.585 + case EGray4:
1.586 + {
1.587 + aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<4));
1.588 + aBuf.SetLength((aClipStrchLen+3)>>2);
1.589 + buflimit+=(aBuf.Length()+3)>>2;
1.590 + if (displayMode == EGray16)
1.591 + {
1.592 + TInt index=((aDitherOffset.iY&1)<<1)+((aDitherOffset.iX+x)&1);
1.593 + while(bufptr<buflimit)
1.594 + {
1.595 + TInt shift=0;
1.596 + *bufptr=0;
1.597 + while(shift<32)
1.598 + {
1.599 + if (coordmap.iX>lastcoord)
1.600 + {
1.601 + lastValue=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
1.602 + lastcoord=coordmap.iX;
1.603 + }
1.604 + *bufptr|=(lastValue<<shift);
1.605 + index^=1;
1.606 + shift+=2;
1.607 + if (stretchmap.SingleStep(coordmap)) break;
1.608 + }
1.609 + bufptr++;
1.610 + }
1.611 + }
1.612 + else
1.613 + {
1.614 + while (bufptr < buflimit)
1.615 + {
1.616 + TInt shift = 0;
1.617 + *bufptr = 0;
1.618 + while (shift < 32)
1.619 + {
1.620 + if (coordmap.iX>lastcoord)
1.621 + {
1.622 + lastValue = GetGrayPixelEx(coordmap.iX,slptr) >> 6;
1.623 + lastcoord = coordmap.iX;
1.624 + }
1.625 + *bufptr |= (lastValue << shift);
1.626 + shift += 2;
1.627 + if (stretchmap.SingleStep(coordmap)) break;
1.628 + }
1.629 + bufptr++;
1.630 + }
1.631 + }
1.632 + break;
1.633 + }
1.634 + case EGray16:
1.635 + {
1.636 + aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<3));
1.637 + aBuf.SetLength((aClipStrchLen+1)>>1);
1.638 + buflimit+=(aBuf.Length()+3)>>2;
1.639 + while(bufptr<buflimit)
1.640 + {
1.641 + TInt shift=0;
1.642 + *bufptr=0;
1.643 + while(shift<32)
1.644 + {
1.645 + if (coordmap.iX>lastcoord)
1.646 + {
1.647 + lastValue = GetGrayPixelEx(coordmap.iX,slptr) >> 4;
1.648 + lastcoord=coordmap.iX;
1.649 + }
1.650 + *bufptr |= lastValue << shift;
1.651 + shift+=4;
1.652 + if (stretchmap.SingleStep(coordmap)) break;
1.653 + }
1.654 + bufptr++;
1.655 + }
1.656 + break;
1.657 + }
1.658 + case EColor16:
1.659 + {
1.660 + aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<3));
1.661 + aBuf.SetLength((aClipStrchLen+1)>>1);
1.662 + buflimit+=(aBuf.Length()+3)>>2;
1.663 + while(bufptr<buflimit)
1.664 + {
1.665 + TInt shift=0;
1.666 + *bufptr=0;
1.667 + while(shift<32)
1.668 + {
1.669 + if (coordmap.iX>lastcoord)
1.670 + {
1.671 + lastValue = GetRgbPixelEx(coordmap.iX,slptr).Color16();
1.672 + lastcoord = coordmap.iX;
1.673 + }
1.674 + *bufptr |= lastValue << shift;
1.675 + shift+=4;
1.676 + if (stretchmap.SingleStep(coordmap)) break;
1.677 + }
1.678 + bufptr++;
1.679 + }
1.680 + break;
1.681 + }
1.682 + case EGray256:
1.683 + {
1.684 + aClipStrchLen = Min(aClipStrchLen,(TInt)(aBuf.MaxLength() & ~3));
1.685 + aBuf.SetLength(aClipStrchLen);
1.686 + buflimit += (aBuf.Length() + 3) >> 2;
1.687 +
1.688 + while (bufptr < buflimit)
1.689 + {
1.690 + TInt shift=0;
1.691 + *bufptr=0;
1.692 + while(shift<32)
1.693 + {
1.694 + if (coordmap.iX>lastcoord)
1.695 + {
1.696 + lastValue = GetGrayPixelEx(coordmap.iX,slptr);
1.697 + lastcoord=coordmap.iX;
1.698 + }
1.699 + *bufptr |= lastValue << shift;
1.700 + shift += 8;
1.701 + if (stretchmap.SingleStep(coordmap))
1.702 + break;
1.703 + }
1.704 + bufptr++;
1.705 + }
1.706 + break;
1.707 + }
1.708 + case EColor256:
1.709 + {
1.710 + aClipStrchLen = Min(aClipStrchLen,(TInt)(aBuf.MaxLength() & ~3));
1.711 + aBuf.SetLength(aClipStrchLen);
1.712 + buflimit += (aBuf.Length() + 3) >> 2;
1.713 +
1.714 + while (bufptr < buflimit)
1.715 + {
1.716 + TInt shift=0;
1.717 + *bufptr=0;
1.718 + while(shift<32)
1.719 + {
1.720 + if (coordmap.iX>lastcoord)
1.721 + {
1.722 + lastValue = TUint8(GetRgbPixelEx(coordmap.iX,slptr).Color256());
1.723 + lastcoord = coordmap.iX;
1.724 + }
1.725 + *bufptr |= lastValue << shift;
1.726 + shift += 8;
1.727 + if (stretchmap.SingleStep(coordmap))
1.728 + break;
1.729 + }
1.730 + bufptr++;
1.731 + }
1.732 + break;
1.733 + }
1.734 + case EColor4K:
1.735 + {
1.736 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1);
1.737 + aBuf.SetLength(aClipStrchLen << 1);
1.738 + buflimit += (aBuf.Length() + 3) >> 2;
1.739 +
1.740 + while (bufptr < buflimit)
1.741 + {
1.742 + if (coordmap.iX>lastcoord)
1.743 + {
1.744 + lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color4K();
1.745 + lastcoord=coordmap.iX;
1.746 + }
1.747 + *bufptr = lastValue;
1.748 + if (stretchmap.SingleStep(coordmap))
1.749 + break;
1.750 + if (coordmap.iX>lastcoord)
1.751 + {
1.752 + lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color4K();
1.753 + lastcoord=coordmap.iX;
1.754 + }
1.755 + *bufptr |= lastValue << 16;
1.756 + if (stretchmap.SingleStep(coordmap))
1.757 + break;
1.758 + bufptr++;
1.759 + }
1.760 + break;
1.761 + }
1.762 + case EColor64K:
1.763 + {
1.764 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1);
1.765 + aBuf.SetLength(aClipStrchLen << 1);
1.766 + buflimit += (aBuf.Length() + 3) >> 2;
1.767 +
1.768 + while (bufptr < buflimit)
1.769 + {
1.770 + if (coordmap.iX>lastcoord)
1.771 + {
1.772 + lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color64K();
1.773 + lastcoord=coordmap.iX;
1.774 + }
1.775 + *bufptr = lastValue;
1.776 + if (stretchmap.SingleStep(coordmap))
1.777 + break;
1.778 + if (coordmap.iX>lastcoord)
1.779 + {
1.780 + lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color64K();
1.781 + lastcoord=coordmap.iX;
1.782 + }
1.783 + *bufptr |= lastValue << 16;
1.784 + if (stretchmap.SingleStep(coordmap))
1.785 + break;
1.786 + bufptr++;
1.787 + }
1.788 + break;
1.789 + }
1.790 + case EColor16M: // Destination Mode
1.791 + {
1.792 + // Optimisation: Both of conditions on 32bpp and 24bpp were added to avoid to use
1.793 + // GetRgbPixelEx() for each pixel
1.794 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / 3);
1.795 + aBuf.SetLength(aClipStrchLen * 3);
1.796 + TUint8* ptr = (TUint8*)bufptr;
1.797 + TUint8* ptrLimit = ptr + aBuf.Length();
1.798 +
1.799 + if (iHeader.iBitsPerPixel == 32) // 32bpp source image => color
1.800 + {
1.801 + TInt lastColor = 0;
1.802 + if(displayMode == EColor16MAP)
1.803 + {
1.804 + const TUint16* normTable = PtrTo16BitNormalisationTable();
1.805 + while (ptr < ptrLimit)
1.806 + {
1.807 + if (coordmap.iX > lastcoord)
1.808 + {
1.809 + lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable);
1.810 + lastcoord = coordmap.iX;
1.811 + }
1.812 + *ptr++ = TUint8(lastColor);
1.813 + *ptr++ = TUint8(lastColor >> 8);
1.814 + *ptr++ = TUint8(lastColor >> 16);
1.815 + if (stretchmap.SingleStep(coordmap))
1.816 + break;
1.817 + }
1.818 + }
1.819 + else{
1.820 + while (ptr < ptrLimit)
1.821 + {
1.822 + if (coordmap.iX > lastcoord)
1.823 + {
1.824 + lastColor = *(slptr + coordmap.iX);
1.825 + lastcoord = coordmap.iX;
1.826 + }
1.827 + *ptr++ = TUint8(lastColor);
1.828 + *ptr++ = TUint8(lastColor >> 8);
1.829 + *ptr++ = TUint8(lastColor >> 16);
1.830 + if (stretchmap.SingleStep(coordmap))
1.831 + break;
1.832 + }
1.833 + }
1.834 + }
1.835 + else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color
1.836 + {
1.837 + TInt lastColor = 0;
1.838 + while (ptr < ptrLimit)
1.839 + {
1.840 + if (coordmap.iX > lastcoord)
1.841 + {
1.842 + TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3;
1.843 + lastColor = TUint8(*scanLineBytePointer);
1.844 + scanLineBytePointer++;
1.845 + lastColor |= TUint8(*scanLineBytePointer) << 8;
1.846 + scanLineBytePointer++;
1.847 + lastColor |= TUint8(*scanLineBytePointer) << 16;
1.848 + lastcoord = coordmap.iX;
1.849 + }
1.850 + *ptr++ = TUint8(lastColor);
1.851 + *ptr++ = TUint8(lastColor >> 8);
1.852 + *ptr++ = TUint8(lastColor >> 16);
1.853 + if (stretchmap.SingleStep(coordmap))
1.854 + break;
1.855 + }
1.856 + }
1.857 + else
1.858 + {
1.859 + TRgb lastColor;
1.860 + while (ptr < ptrLimit)
1.861 + {
1.862 + if (coordmap.iX>lastcoord)
1.863 + {
1.864 + lastColor = GetRgbPixelEx(coordmap.iX,slptr);
1.865 + lastcoord=coordmap.iX;
1.866 + }
1.867 + TInt color16M = lastColor._Color16M();
1.868 + *ptr++ = TUint8(color16M);
1.869 + *ptr++ = TUint8(color16M >> 8);
1.870 + *ptr++ = TUint8(color16M >> 16);
1.871 + if (stretchmap.SingleStep(coordmap))
1.872 + break;
1.873 + }
1.874 + }
1.875 + break;
1.876 + }
1.877 + case ERgb:
1.878 + {
1.879 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / sizeof(TRgb));
1.880 + aBuf.SetLength(aClipStrchLen * sizeof(TRgb));
1.881 + TRgb* pixelPtr = (TRgb*)bufptr;
1.882 + TRgb* pixelPtrLimit = pixelPtr + aClipStrchLen;
1.883 + TRgb lastColor;
1.884 +
1.885 + while (pixelPtr < pixelPtrLimit)
1.886 + {
1.887 + if (coordmap.iX > lastcoord)
1.888 + {
1.889 + lastColor = GetRgbPixelEx(coordmap.iX,slptr);
1.890 + lastcoord = coordmap.iX;
1.891 + }
1.892 + *pixelPtr++ = lastColor;
1.893 + if (stretchmap.SingleStep(coordmap))
1.894 + break;
1.895 + }
1.896 + break;
1.897 + }
1.898 + case EColor16MU: // Destination Mode
1.899 + {
1.900 + // Optimisation: The condition 32bpp was added to avoid to use
1.901 + //GetRgbPixelEx() for each pixel (construction of a TRgb object each time)
1.902 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2);
1.903 + aBuf.SetLength(aClipStrchLen << 2);
1.904 + TInt32* pixelPtr = (TInt32*)bufptr;
1.905 + TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen;
1.906 +
1.907 + if (iHeader.iBitsPerPixel == 32) //32bpp source image => color
1.908 + {
1.909 + TInt lastColor = 0;
1.910 + if(displayMode == EColor16MAP)
1.911 + {
1.912 + const TUint16* normTable = PtrTo16BitNormalisationTable();
1.913 + while (pixelPtr < pixelPtrLimit)
1.914 + {
1.915 + if (coordmap.iX > lastcoord)
1.916 + {
1.917 + lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable);
1.918 + lastcoord = coordmap.iX;
1.919 + }
1.920 + *pixelPtr++ = (lastColor | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order
1.921 + if (stretchmap.SingleStep(coordmap))
1.922 + break;
1.923 + }
1.924 + }
1.925 + else{
1.926 + while (pixelPtr < pixelPtrLimit)
1.927 + {
1.928 + if (coordmap.iX > lastcoord)
1.929 + {
1.930 + lastColor = *(slptr + coordmap.iX);
1.931 + lastcoord = coordmap.iX;
1.932 + }
1.933 + *pixelPtr++ = (lastColor | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order
1.934 + if (stretchmap.SingleStep(coordmap))
1.935 + break;
1.936 + }
1.937 + }
1.938 + }
1.939 +
1.940 + else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color
1.941 + {
1.942 + TInt lastColor = 0;
1.943 + while (pixelPtr < pixelPtrLimit)
1.944 + {
1.945 + if (coordmap.iX > lastcoord)
1.946 + {
1.947 + TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3;
1.948 + lastColor = TUint8(*scanLineBytePointer);
1.949 + scanLineBytePointer++;
1.950 + lastColor |= TUint8(*scanLineBytePointer) << 8;
1.951 + scanLineBytePointer++;
1.952 + lastColor |= TUint8(*scanLineBytePointer) << 16;
1.953 + lastcoord = coordmap.iX;
1.954 + }
1.955 + *pixelPtr++ = (lastColor | 0xff000000);
1.956 + if (stretchmap.SingleStep(coordmap))
1.957 + break;
1.958 + }
1.959 + }
1.960 + else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color
1.961 + {
1.962 + TInt lastColor = 0;
1.963 + while (pixelPtr < pixelPtrLimit)
1.964 + {
1.965 + if (coordmap.iX > lastcoord)
1.966 + {
1.967 + TUint rawColor = *(((TUint16*)slptr) + coordmap.iX);
1.968 + TInt red = (rawColor & 0xF800)>>8;
1.969 + red += red>>5;
1.970 + TInt green = (rawColor & 0x07E0)>>3;
1.971 + green += green>>6;
1.972 + TInt blue = (rawColor & 0x001F)<<3;
1.973 + blue += blue>>5;
1.974 + lastColor = 0xff000000 | (red << 16) | (green << 8) | blue;
1.975 + lastcoord = coordmap.iX;
1.976 + }
1.977 + *pixelPtr++ = lastColor;
1.978 + if (stretchmap.SingleStep(coordmap))
1.979 + break;
1.980 + }
1.981 + }
1.982 + else
1.983 + {
1.984 + TRgb lastColor;
1.985 + while (pixelPtr < pixelPtrLimit)
1.986 + {
1.987 + if (coordmap.iX > lastcoord)
1.988 + {
1.989 + lastColor = GetRgbPixelEx(coordmap.iX,slptr);
1.990 + lastcoord = coordmap.iX;
1.991 + }
1.992 + *pixelPtr++ = (lastColor._Color16MU() | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order
1.993 + if (stretchmap.SingleStep(coordmap))
1.994 + break;
1.995 + }
1.996 + }
1.997 + break;
1.998 + }
1.999 + case EColor16MA:
1.1000 + {
1.1001 + // Optimisation: The condition 32bpp was added to avoid to use
1.1002 + // GetRgbPixelEx() for each pixel (construction of a TRgb object each time)
1.1003 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2);
1.1004 + aBuf.SetLength(aClipStrchLen << 2);
1.1005 + TInt32* pixelPtr = (TInt32*)bufptr;
1.1006 + TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen;
1.1007 + const TUint16* normTable = PtrTo16BitNormalisationTable();
1.1008 + if (iHeader.iBitsPerPixel == 32) //32bpp source image => color
1.1009 + {
1.1010 + TInt lastColor = 0;
1.1011 + if(displayMode == EColor16MAP)
1.1012 + {
1.1013 + while (pixelPtr < pixelPtrLimit)
1.1014 + {
1.1015 + if (coordmap.iX > lastcoord)
1.1016 + {
1.1017 + lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable);
1.1018 + lastcoord = coordmap.iX;
1.1019 + }
1.1020 + *pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order
1.1021 + if (stretchmap.SingleStep(coordmap))
1.1022 + break;
1.1023 + }
1.1024 + }
1.1025 + else
1.1026 + {
1.1027 + while (pixelPtr < pixelPtrLimit)
1.1028 + {
1.1029 + if (coordmap.iX > lastcoord)
1.1030 + {
1.1031 + lastColor = *(slptr + coordmap.iX);
1.1032 + lastcoord = coordmap.iX;
1.1033 + }
1.1034 + *pixelPtr++ = lastColor;
1.1035 + if (stretchmap.SingleStep(coordmap))
1.1036 + break;
1.1037 + }
1.1038 + }
1.1039 + }
1.1040 + else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color
1.1041 + {
1.1042 + TInt lastColor = 0;
1.1043 + while (pixelPtr < pixelPtrLimit)
1.1044 + {
1.1045 + if (coordmap.iX > lastcoord)
1.1046 + {
1.1047 + TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3;
1.1048 + lastColor = TUint8(*scanLineBytePointer);
1.1049 + scanLineBytePointer++;
1.1050 + lastColor |= TUint8(*scanLineBytePointer) << 8;
1.1051 + scanLineBytePointer++;
1.1052 + lastColor |= TUint8(*scanLineBytePointer) << 16;
1.1053 + lastcoord = coordmap.iX;
1.1054 + }
1.1055 + *pixelPtr++ = (lastColor | 0xff000000);
1.1056 + if (stretchmap.SingleStep(coordmap))
1.1057 + break;
1.1058 + }
1.1059 + }
1.1060 + else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color
1.1061 + {
1.1062 + TInt lastColor = 0;
1.1063 + while (pixelPtr < pixelPtrLimit)
1.1064 + {
1.1065 + if (coordmap.iX > lastcoord)
1.1066 + {
1.1067 + TUint rawColor = *(((TUint16*)slptr) + coordmap.iX);
1.1068 + TInt red = (rawColor & 0xF800)>>8;
1.1069 + red += red>>5;
1.1070 + TInt green = (rawColor & 0x07E0)>>3;
1.1071 + green += green>>6;
1.1072 + TInt blue = (rawColor & 0x001F)<<3;
1.1073 + blue += blue>>5;
1.1074 + lastColor = 0xff000000 | (red << 16) | (green << 8) | blue;
1.1075 + lastcoord = coordmap.iX;
1.1076 + }
1.1077 + *pixelPtr++ = lastColor;
1.1078 + if (stretchmap.SingleStep(coordmap))
1.1079 + break;
1.1080 + }
1.1081 + }
1.1082 + else
1.1083 + {
1.1084 + TRgb lastColor;
1.1085 +
1.1086 + while (pixelPtr < pixelPtrLimit)
1.1087 + {
1.1088 + if (coordmap.iX > lastcoord)
1.1089 + {
1.1090 + lastColor = GetRgbPixelEx(coordmap.iX,slptr);
1.1091 + lastcoord = coordmap.iX;
1.1092 + }
1.1093 + *pixelPtr++ = lastColor._Color16MA();//BGRA (Blue/Green/Red) as little endian byte order
1.1094 + if (stretchmap.SingleStep(coordmap))
1.1095 + break;
1.1096 + }
1.1097 + }
1.1098 + break;
1.1099 + }
1.1100 + case EColor16MAP:
1.1101 + { //if alpha is not available, assign 255 as alpha (opaque).
1.1102 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2);
1.1103 + aBuf.SetLength(aClipStrchLen << 2);
1.1104 + TInt32* pixelPtr = (TInt32*)bufptr;
1.1105 + TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen;
1.1106 + if (iHeader.iBitsPerPixel == 32) //32bpp source image => color
1.1107 + {
1.1108 + TInt lastColor = 0;
1.1109 + //pre-multiply if alpha IS available.
1.1110 + if(displayMode == EColor16MA)
1.1111 + {
1.1112 + while (pixelPtr < pixelPtrLimit)
1.1113 + {
1.1114 + if (coordmap.iX > lastcoord)
1.1115 + {
1.1116 + lastColor = NonPMA2PMAPixel(*(slptr + coordmap.iX));
1.1117 + lastcoord = coordmap.iX;
1.1118 + }
1.1119 + *pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order
1.1120 + if (stretchmap.SingleStep(coordmap))
1.1121 + break;
1.1122 + }
1.1123 + }
1.1124 + else if(displayMode == EColor16MU)
1.1125 + {
1.1126 + while (pixelPtr < pixelPtrLimit)
1.1127 + {
1.1128 + if (coordmap.iX > lastcoord)
1.1129 + {
1.1130 + //do not want to convert to non pma, since keep transparency
1.1131 + //e.g. alpha 0.5, red 0.5. Want to keep red as 0.5 since it
1.1132 + //is not fully red. For 16MA convert to 1, and keep 0.5 alpha
1.1133 + lastColor = (*(slptr + coordmap.iX))|0xff000000;
1.1134 + lastcoord = coordmap.iX;
1.1135 + }
1.1136 + *pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order
1.1137 + if (stretchmap.SingleStep(coordmap))
1.1138 + break;
1.1139 + }
1.1140 + }
1.1141 + else
1.1142 + {
1.1143 + while (pixelPtr < pixelPtrLimit)
1.1144 + {
1.1145 + if (coordmap.iX > lastcoord)
1.1146 + {
1.1147 + lastColor = *(slptr + coordmap.iX);
1.1148 + lastcoord = coordmap.iX;
1.1149 + }
1.1150 + *pixelPtr++ = lastColor;
1.1151 + if (stretchmap.SingleStep(coordmap))
1.1152 + break;
1.1153 + }
1.1154 + }
1.1155 + }
1.1156 + else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color
1.1157 + {
1.1158 + TInt lastColor = 0;
1.1159 + while (pixelPtr < pixelPtrLimit)
1.1160 + {
1.1161 + if (coordmap.iX > lastcoord)
1.1162 + {
1.1163 + TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3;
1.1164 + lastColor = TUint8(*scanLineBytePointer);
1.1165 + scanLineBytePointer++;
1.1166 + lastColor |= TUint8(*scanLineBytePointer) << 8;
1.1167 + scanLineBytePointer++;
1.1168 + lastColor |= TUint8(*scanLineBytePointer) << 16;
1.1169 + lastcoord = coordmap.iX;
1.1170 + }
1.1171 + *pixelPtr++ = (lastColor | 0xff000000);
1.1172 + if (stretchmap.SingleStep(coordmap))
1.1173 + break;
1.1174 + }
1.1175 + }
1.1176 + else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color
1.1177 + {
1.1178 + TInt lastColor = 0;
1.1179 + while (pixelPtr < pixelPtrLimit)
1.1180 + {
1.1181 + if (coordmap.iX > lastcoord)
1.1182 + {
1.1183 + TUint rawColor = *(((TUint16*)slptr) + coordmap.iX);
1.1184 + TInt red = (rawColor & 0xF800)>>8;
1.1185 + red += red>>5;
1.1186 + TInt green = (rawColor & 0x07E0)>>3;
1.1187 + green += green>>6;
1.1188 + TInt blue = (rawColor & 0x001F)<<3;
1.1189 + blue += blue>>5;
1.1190 + lastColor = 0xff000000 | (red << 16) | (green << 8) | blue;
1.1191 + lastcoord = coordmap.iX;
1.1192 + }
1.1193 + *pixelPtr++ = lastColor;
1.1194 + if (stretchmap.SingleStep(coordmap))
1.1195 + break;
1.1196 + }
1.1197 + }
1.1198 + else
1.1199 + {
1.1200 + TRgb lastColor;
1.1201 +
1.1202 + while (pixelPtr < pixelPtrLimit)
1.1203 + {
1.1204 + if (coordmap.iX > lastcoord)
1.1205 + {
1.1206 + lastColor = GetRgbPixelEx(coordmap.iX,slptr);
1.1207 + lastcoord = coordmap.iX;
1.1208 + }
1.1209 + *pixelPtr++ = lastColor._Color16MA();//BGRA (Blue/Green/Red) as little endian byte order
1.1210 + if (stretchmap.SingleStep(coordmap))
1.1211 + break;
1.1212 + }
1.1213 + }
1.1214 + break;
1.1215 + }
1.1216 + case EGray2:
1.1217 + {
1.1218 + TBool oddx=(aDitherOffset.iX&1);
1.1219 + TBool oddy=(aDitherOffset.iY&1);
1.1220 + aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<5));
1.1221 + aBuf.SetLength((aClipStrchLen+7)>>3);
1.1222 + buflimit+=(aBuf.Length()+3)>>2;
1.1223 + while(bufptr<buflimit)
1.1224 + {
1.1225 + TUint32 mask=1;
1.1226 + *bufptr=0;
1.1227 + while(mask)
1.1228 + {
1.1229 + if (coordmap.iX > lastcoord)
1.1230 + {
1.1231 + lastValue = GetGrayPixelEx(coordmap.iX,slptr);
1.1232 + lastcoord = coordmap.iX;
1.1233 + }
1.1234 + if (HashTo1bpp(lastValue,oddx,oddy))
1.1235 + *bufptr|=mask;
1.1236 + mask<<=1;
1.1237 + oddx^=1;
1.1238 + if (stretchmap.SingleStep(coordmap)) break;
1.1239 + }
1.1240 + bufptr++;
1.1241 + }
1.1242 + break;
1.1243 + }
1.1244 + default:
1.1245 + Panic(EFbsBitmapInvalidMode);
1.1246 + }
1.1247 + }
1.1248 +
1.1249 +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
1.1250 + {
1.1251 + TInt first=0,second=0,third=0,fourth=0,fifth=0,sixth=0,seventh=0,eighth=0;
1.1252 + TUint8* bufptr=&aBuf[0];
1.1253 + TUint8* buflimit=bufptr;
1.1254 + TUint32* slptr=NULL;
1.1255 + TPoint pixel(aOrgX,y);
1.1256 + TDisplayMode displayMode = iSettings.CurrentDisplayMode();
1.1257 + GetScanLinePtr(slptr,aOrgLen,pixel,aBase, aLineScanningPosition);
1.1258 + if (!slptr)
1.1259 + {
1.1260 + WhiteFill((TUint8*)aBuf.Ptr(),aBuf.MaxLength(),displayMode);
1.1261 + return;
1.1262 + }
1.1263 + TLinearDDA stretchmap;
1.1264 + TPoint coordmap(aOrgX,0);
1.1265 + stretchmap.Construct(coordmap,coordmap+TPoint(aOrgLen,aStretchLength),TLinearDDA::ELeft);
1.1266 + coordmap.iY=aClipStrchX;
1.1267 + if (aClipStrchX>0) stretchmap.JumpToYCoord(coordmap.iX,coordmap.iY);
1.1268 + else stretchmap.NextStep(coordmap);
1.1269 + switch(aDispMode)
1.1270 + {
1.1271 + case EGray4:
1.1272 + {
1.1273 + aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<2));
1.1274 + aBuf.SetLength((aClipStrchLen+3)>>2);
1.1275 + TInt index=((aDitherOffset.iY&1)<<1)+((aDitherOffset.iX+x)&1);
1.1276 + buflimit+=aBuf.Length();
1.1277 + if (displayMode==EGray16)
1.1278 + {
1.1279 + while(bufptr<buflimit)
1.1280 + {
1.1281 + first=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
1.1282 + index^=1;
1.1283 + stretchmap.NextStep(coordmap);
1.1284 + second=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
1.1285 + index^=1;
1.1286 + stretchmap.NextStep(coordmap);
1.1287 + third=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
1.1288 + index^=1;
1.1289 + stretchmap.NextStep(coordmap);
1.1290 + fourth=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
1.1291 + index^=1;
1.1292 + *bufptr++=TUint8(first|(second<<2)|(third<<4)|(fourth<<6));
1.1293 + stretchmap.NextStep(coordmap);
1.1294 + }
1.1295 + }
1.1296 + else
1.1297 + {
1.1298 + while(bufptr<buflimit)
1.1299 + {
1.1300 + first=GetGrayPixelEx(coordmap.iX,slptr)>>6;
1.1301 + stretchmap.NextStep(coordmap);
1.1302 + second=GetGrayPixelEx(coordmap.iX,slptr)>>6;
1.1303 + stretchmap.NextStep(coordmap);
1.1304 + third=GetGrayPixelEx(coordmap.iX,slptr)>>6;
1.1305 + stretchmap.NextStep(coordmap);
1.1306 + fourth=GetGrayPixelEx(coordmap.iX,slptr)>>6;
1.1307 + *bufptr++=TUint8(first|(second<<2)|(third<<4)|(fourth<<6));
1.1308 + stretchmap.NextStep(coordmap);
1.1309 + }
1.1310 + }
1.1311 + break;
1.1312 + }
1.1313 + case EGray16:
1.1314 + {
1.1315 + aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<1));
1.1316 + aBuf.SetLength((aClipStrchLen+1)>>1);
1.1317 + buflimit+=aBuf.Length();
1.1318 + while(bufptr<buflimit)
1.1319 + {
1.1320 + first = GetGrayPixelEx(coordmap.iX,slptr) >> 4;
1.1321 + stretchmap.NextStep(coordmap);
1.1322 + first |= GetGrayPixelEx(coordmap.iX,slptr) & 0xf0;
1.1323 + *bufptr++ = TUint8(first);
1.1324 + stretchmap.NextStep(coordmap);
1.1325 + }
1.1326 + break;
1.1327 + }
1.1328 + case EColor16:
1.1329 + {
1.1330 + aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<1));
1.1331 + aBuf.SetLength((aClipStrchLen+1)>>1);
1.1332 + buflimit+=aBuf.Length();
1.1333 + while(bufptr<buflimit)
1.1334 + {
1.1335 + first = GetRgbPixelEx(coordmap.iX,slptr).Color16();
1.1336 + stretchmap.NextStep(coordmap);
1.1337 + first |= GetRgbPixelEx(coordmap.iX,slptr).Color16() << 4;
1.1338 + *bufptr++ = TUint8(first);
1.1339 + stretchmap.NextStep(coordmap);
1.1340 + }
1.1341 + break;
1.1342 + }
1.1343 + case EGray256:
1.1344 + {
1.1345 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength());
1.1346 + aBuf.SetLength(aClipStrchLen);
1.1347 + buflimit += aBuf.Length();
1.1348 +
1.1349 + while(bufptr < buflimit)
1.1350 + {
1.1351 + *bufptr++ = GetGrayPixelEx(coordmap.iX,slptr);
1.1352 + stretchmap.NextStep(coordmap);
1.1353 + }
1.1354 + break;
1.1355 + }
1.1356 + case EColor256:
1.1357 + {
1.1358 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength());
1.1359 + aBuf.SetLength(aClipStrchLen);
1.1360 + buflimit += aBuf.Length();
1.1361 +
1.1362 + while(bufptr < buflimit)
1.1363 + {
1.1364 + *bufptr++ = TUint8(GetRgbPixelEx(coordmap.iX,slptr).Color256());
1.1365 + stretchmap.NextStep(coordmap);
1.1366 + }
1.1367 + break;
1.1368 + }
1.1369 + case EColor4K:
1.1370 + {
1.1371 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1);
1.1372 + aBuf.SetLength(aClipStrchLen << 1);
1.1373 + buflimit += aBuf.Length();
1.1374 +
1.1375 + while(bufptr < buflimit)
1.1376 + {
1.1377 + *((TUint16*)bufptr) = TUint16(GetRgbPixelEx(coordmap.iX,slptr)._Color4K());
1.1378 + bufptr += 2;
1.1379 + stretchmap.NextStep(coordmap);
1.1380 + }
1.1381 + break;
1.1382 + }
1.1383 + case EColor64K:
1.1384 + {
1.1385 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1);
1.1386 + aBuf.SetLength(aClipStrchLen << 1);
1.1387 + buflimit += aBuf.Length();
1.1388 +
1.1389 + while(bufptr < buflimit)
1.1390 + {
1.1391 + *((TUint16*)bufptr) = TUint16(GetRgbPixelEx(coordmap.iX,slptr)._Color64K());
1.1392 + bufptr += 2;
1.1393 + stretchmap.NextStep(coordmap);
1.1394 + }
1.1395 + break;
1.1396 + }
1.1397 + case EColor16M:
1.1398 + {
1.1399 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / 3);
1.1400 + aBuf.SetLength(aClipStrchLen * 3);
1.1401 + buflimit += aBuf.Length();
1.1402 +
1.1403 + while(bufptr<buflimit)
1.1404 + {
1.1405 + TInt color16M = GetRgbPixelEx(coordmap.iX,slptr)._Color16M();
1.1406 + *bufptr++ = TUint8(color16M);
1.1407 + *bufptr++ = TUint8(color16M >> 8);
1.1408 + *bufptr++ = TUint8(color16M >> 16);
1.1409 + stretchmap.NextStep(coordmap);
1.1410 + }
1.1411 + break;
1.1412 + }
1.1413 + case ERgb:
1.1414 + case EColor16MU:
1.1415 + case EColor16MA:
1.1416 + case EColor16MAP:
1.1417 + {
1.1418 + aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2);
1.1419 + aBuf.SetLength(aClipStrchLen << 2);
1.1420 + TUint32* pixelPtr = (TUint32*)bufptr;
1.1421 + TUint32* pixelPtrLimit = pixelPtr + aClipStrchLen;
1.1422 + if (aDispMode == EColor16MAP && displayMode == EColor16MA)
1.1423 + while(pixelPtr < pixelPtrLimit)
1.1424 + {
1.1425 + *pixelPtr++ = NonPMA2PMAPixel(*(slptr + coordmap.iX));
1.1426 + stretchmap.NextStep(coordmap);
1.1427 + }
1.1428 + else if (aDispMode == EColor16MAP && displayMode == EColor16MAP)
1.1429 + while(pixelPtr < pixelPtrLimit)
1.1430 + {
1.1431 + *pixelPtr++ = *(slptr + coordmap.iX);
1.1432 + stretchmap.NextStep(coordmap);
1.1433 + }
1.1434 + else if (aDispMode == EColor16MU)
1.1435 + while(pixelPtr < pixelPtrLimit)
1.1436 + {
1.1437 + *pixelPtr++ = GetRgbPixelEx(coordmap.iX, slptr).Internal();
1.1438 + stretchmap.NextStep(coordmap);
1.1439 + }
1.1440 + else
1.1441 + while(pixelPtr < pixelPtrLimit)
1.1442 + {
1.1443 + *pixelPtr++ = GetRgbPixelEx(coordmap.iX, slptr).Internal();
1.1444 + stretchmap.NextStep(coordmap);
1.1445 + }
1.1446 + break;
1.1447 + }
1.1448 + case EGray2:
1.1449 + {
1.1450 + TBool oddx=(aDitherOffset.iX&1);
1.1451 + TBool oddy=(aDitherOffset.iY&1);
1.1452 + aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<3));
1.1453 + aBuf.SetLength((aClipStrchLen+7)>>3);
1.1454 + buflimit+=aBuf.Length();
1.1455 + while(bufptr<buflimit)
1.1456 + {
1.1457 + first=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
1.1458 + stretchmap.NextStep(coordmap);
1.1459 + second=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
1.1460 + stretchmap.NextStep(coordmap);
1.1461 + third=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
1.1462 + stretchmap.NextStep(coordmap);
1.1463 + fourth=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
1.1464 + stretchmap.NextStep(coordmap);
1.1465 + fifth=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
1.1466 + stretchmap.NextStep(coordmap);
1.1467 + sixth=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
1.1468 + stretchmap.NextStep(coordmap);
1.1469 + seventh=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
1.1470 + stretchmap.NextStep(coordmap);
1.1471 + eighth=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
1.1472 + *bufptr++=TUint8(first|(second<<1)|(third<<2)|(fourth<<3)|
1.1473 + (fifth<<4)|(sixth<<5)|(seventh<<6)|(eighth<<7));
1.1474 + stretchmap.NextStep(coordmap);
1.1475 + oddx^=1;
1.1476 + }
1.1477 + break;
1.1478 + }
1.1479 + default:
1.1480 + Panic(EFbsBitmapInvalidMode);
1.1481 + }
1.1482 + }