os/graphics/fbs/fontandbitmapserver/sfbs/BITBMPEX.CPP
changeset 0 bde4ae8d615e
     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 +	}