os/graphics/fbs/fontandbitmapserver/sfbs/BITBMPEX.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <f32file.h>
sl@0
    17
#include <s32file.h>
sl@0
    18
#include <fbs.h>
sl@0
    19
#include <bitmap.h>
sl@0
    20
#include "UTILS.H"
sl@0
    21
#include <graphics/blendingalgorithms.h>
sl@0
    22
#include <graphics/lookuptable.h>
sl@0
    23
//#include "12to16.h"	// lookup table for 12->16 bpp conversion
sl@0
    24
sl@0
    25
#ifdef __ARMCC__
sl@0
    26
#pragma arm
sl@0
    27
#pragma O3
sl@0
    28
#pragma Otime
sl@0
    29
#endif
sl@0
    30
sl@0
    31
GLREF_C void Panic(TFbsPanic aPanic);
sl@0
    32
sl@0
    33
#define COLOR_VALUE(ScanLinePtr, XPos) (*((ScanLinePtr) + ((XPos) >> 5)) & ( 1 << ((XPos) & 0x1F)))
sl@0
    34
sl@0
    35
sl@0
    36
void CBitwiseBitmap::GetScanLineGray2(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TBool aDither,const TPoint& aDitherOffset,TUint32* aScanlinePtr) const
sl@0
    37
	{
sl@0
    38
	aLength = Min(aLength,(TInt)((aBuf.MaxLength()) << 3));
sl@0
    39
	aBuf.SetLength((aLength + 7) >> 3);
sl@0
    40
sl@0
    41
	TUint8* ptr = (TUint8*)aBuf.Ptr();
sl@0
    42
sl@0
    43
	TUint8 mask = 1;
sl@0
    44
	TInt x = aPixel.iX;
sl@0
    45
	*ptr=0;
sl@0
    46
sl@0
    47
	if (aDither)
sl@0
    48
		{
sl@0
    49
		TBool oddx = aDitherOffset.iX & 1;
sl@0
    50
		TBool oddy = aDitherOffset.iY & 1;
sl@0
    51
sl@0
    52
		for(TInt count = 0;count < aLength;count++)
sl@0
    53
			{
sl@0
    54
			if (!mask)
sl@0
    55
				{
sl@0
    56
				mask = 1;
sl@0
    57
				ptr++;
sl@0
    58
				*ptr = 0;
sl@0
    59
				}
sl@0
    60
			if (HashTo1bpp(GetGrayPixelEx(x,aScanlinePtr),oddx,oddy))
sl@0
    61
				*ptr |= mask;
sl@0
    62
			mask <<= 1;
sl@0
    63
			oddx ^= 1;
sl@0
    64
			x++;
sl@0
    65
			}
sl@0
    66
		}
sl@0
    67
	else
sl@0
    68
		{
sl@0
    69
		for(TInt count = 0;count < aLength;count++)
sl@0
    70
			{
sl@0
    71
			if (!mask)
sl@0
    72
				{
sl@0
    73
				mask = 1;
sl@0
    74
				ptr++;
sl@0
    75
				*ptr = 0;
sl@0
    76
				}
sl@0
    77
			if (GetGrayPixelEx(x,aScanlinePtr) > 127)
sl@0
    78
				*ptr |= mask;
sl@0
    79
			mask <<= 1;
sl@0
    80
			x++;
sl@0
    81
			}
sl@0
    82
		}
sl@0
    83
	}
sl@0
    84
sl@0
    85
void CBitwiseBitmap::GetScanLineGray4(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TBool aDither,const TPoint& aDitherOffset,TUint32* aScanlinePtr) const
sl@0
    86
	{
sl@0
    87
	aLength = Min(aLength,(TInt)((aBuf.MaxLength())<<2));
sl@0
    88
	aBuf.SetLength((aLength + 3) >> 2);
sl@0
    89
sl@0
    90
	TUint8* ptr=(TUint8*)aBuf.Ptr();
sl@0
    91
sl@0
    92
	TInt x = aPixel.iX;
sl@0
    93
	if (iSettings.CurrentDisplayMode() == EGray16 && aDither)
sl@0
    94
		{
sl@0
    95
		*ptr=0;
sl@0
    96
		TInt shift = 0;
sl@0
    97
		TUint8 col = 0;
sl@0
    98
		const TInt hasharray[4]={0,3,2,1};
sl@0
    99
		TInt index = (aDitherOffset.iX&1)+((aDitherOffset.iY&1)<<1);
sl@0
   100
		for(TInt count=0;count<aLength;count++,shift+=2)
sl@0
   101
			{
sl@0
   102
			if (shift==8)
sl@0
   103
				{
sl@0
   104
				shift = 0;
sl@0
   105
				ptr++;
sl@0
   106
				*ptr = 0;
sl@0
   107
				}
sl@0
   108
			col = TUint8(GetGrayPixelEx(x+count,aScanlinePtr) >> 4);
sl@0
   109
			TInt value=col/5;
sl@0
   110
			col%=5;
sl@0
   111
			if (col>2) col--;
sl@0
   112
			if (hasharray[index]<TInt(col))
sl@0
   113
				value++;
sl@0
   114
			value<<=shift;
sl@0
   115
			*ptr|=value;
sl@0
   116
			index^=1;
sl@0
   117
			}
sl@0
   118
		}
sl@0
   119
	else
sl@0
   120
		{
sl@0
   121
		TUint8* ptrLimit = ptr + ((aLength + 3) >> 2);
sl@0
   122
		while (ptr < ptrLimit)
sl@0
   123
			{
sl@0
   124
			TUint8 pixelGrayShade = TUint8(GetGrayPixelEx(x++,aScanlinePtr) >> 6);
sl@0
   125
			pixelGrayShade |= TUint8((GetGrayPixelEx(x++,aScanlinePtr) >> 4) & 0x0c);
sl@0
   126
			pixelGrayShade |= TUint8((GetGrayPixelEx(x++,aScanlinePtr) >> 2) & 0x30);
sl@0
   127
			pixelGrayShade |= TUint8(GetGrayPixelEx(x++,aScanlinePtr) & 0xc0);
sl@0
   128
			*ptr++ = pixelGrayShade;
sl@0
   129
			}
sl@0
   130
		}
sl@0
   131
	}
sl@0
   132
sl@0
   133
void CBitwiseBitmap::GetScanLineGray16(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   134
	{
sl@0
   135
	aLength=Min(aLength,(TInt)(aBuf.MaxLength()<<1));
sl@0
   136
	aBuf.SetLength((aLength + 1) >> 1);
sl@0
   137
sl@0
   138
	TUint8* ptr = (TUint8*)aBuf.Ptr();
sl@0
   139
	TUint8* ptrLimit = ptr + aBuf.Length();
sl@0
   140
	TInt x = aPixel.iX;
sl@0
   141
sl@0
   142
	if(iHeader.iBitsPerPixel == 1)
sl@0
   143
		{
sl@0
   144
		while (ptr < ptrLimit)
sl@0
   145
			{
sl@0
   146
			TUint8 pixelGrayShade = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0x0F : 0);
sl@0
   147
			x++;
sl@0
   148
			pixelGrayShade |= TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xF0 : 0);
sl@0
   149
			x++;
sl@0
   150
			*ptr++ = pixelGrayShade;
sl@0
   151
			}
sl@0
   152
		}
sl@0
   153
	else
sl@0
   154
		{
sl@0
   155
		while (ptr < ptrLimit)
sl@0
   156
			{
sl@0
   157
			TUint8 pixelGrayShade = TUint8(GetGrayPixelEx(x++,aScanlinePtr) >> 4);
sl@0
   158
			pixelGrayShade |= GetGrayPixelEx(x++,aScanlinePtr) & 0xf0;
sl@0
   159
			*ptr++ = pixelGrayShade;
sl@0
   160
			}
sl@0
   161
		}
sl@0
   162
	}
sl@0
   163
sl@0
   164
void CBitwiseBitmap::GetScanLineGray256(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   165
	{
sl@0
   166
	aLength = Min(aLength,aBuf.MaxLength());
sl@0
   167
	aBuf.SetLength(aLength);
sl@0
   168
sl@0
   169
	TUint8* ptr = (TUint8*)aBuf.Ptr();
sl@0
   170
	TUint8* ptrLimit = ptr + aLength;
sl@0
   171
	TInt xCoord = aPixel.iX;
sl@0
   172
sl@0
   173
	if(iHeader.iBitsPerPixel == 1)
sl@0
   174
		{
sl@0
   175
		while (ptr < ptrLimit)
sl@0
   176
			{
sl@0
   177
			*ptr++ = TUint8(COLOR_VALUE(aScanlinePtr, xCoord) ? 0xFF : 0);
sl@0
   178
			xCoord++;
sl@0
   179
			}
sl@0
   180
		}
sl@0
   181
	else
sl@0
   182
		{
sl@0
   183
		while (ptr < ptrLimit)
sl@0
   184
			*ptr++ = GetGrayPixelEx(xCoord++,aScanlinePtr);
sl@0
   185
		}
sl@0
   186
	}
sl@0
   187
sl@0
   188
void CBitwiseBitmap::GetScanLineColor16(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   189
	{
sl@0
   190
	aLength=Min(aLength,(TInt)(aBuf.MaxLength()<<1));
sl@0
   191
	aBuf.SetLength((aLength + 1) >> 1);
sl@0
   192
sl@0
   193
	TUint8* ptr = (TUint8*)aBuf.Ptr();
sl@0
   194
	TUint8* ptrLimit = ptr + aBuf.Length();
sl@0
   195
	TInt x = aPixel.iX;
sl@0
   196
sl@0
   197
	if(iHeader.iBitsPerPixel == 1)
sl@0
   198
		{
sl@0
   199
		while (ptr < ptrLimit)
sl@0
   200
			{
sl@0
   201
			TUint8 pixelGrayShade = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0x0F : 0);
sl@0
   202
			x++;
sl@0
   203
			pixelGrayShade |= TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xF0 : 0);
sl@0
   204
			x++;
sl@0
   205
			*ptr++ = pixelGrayShade;
sl@0
   206
			}
sl@0
   207
		}
sl@0
   208
	else
sl@0
   209
		{
sl@0
   210
		while (ptr < ptrLimit)
sl@0
   211
			{
sl@0
   212
			TUint8 pixelGrayShade = TUint8(GetRgbPixelEx(x++,aScanlinePtr).Color16());
sl@0
   213
			pixelGrayShade |= GetRgbPixelEx(x++,aScanlinePtr).Color16() << 4;
sl@0
   214
			*ptr++ = pixelGrayShade;
sl@0
   215
			}
sl@0
   216
		}
sl@0
   217
	}
sl@0
   218
sl@0
   219
void CBitwiseBitmap::GetScanLineColor256(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   220
	{
sl@0
   221
	aLength = Min(aLength,aBuf.MaxLength());
sl@0
   222
	aBuf.SetLength(aLength);
sl@0
   223
sl@0
   224
	TUint8* ptr = (TUint8*)aBuf.Ptr();
sl@0
   225
	TUint8* ptrLimit = ptr + aLength;
sl@0
   226
	TInt xCoord = aPixel.iX;
sl@0
   227
sl@0
   228
	if(iHeader.iBitsPerPixel == 1)
sl@0
   229
		{
sl@0
   230
		while (ptr < ptrLimit)
sl@0
   231
			{
sl@0
   232
			*ptr++ = TUint8(COLOR_VALUE(aScanlinePtr, xCoord) ? 0xFF : 0);
sl@0
   233
			xCoord++;
sl@0
   234
			}
sl@0
   235
		}
sl@0
   236
	else
sl@0
   237
		{
sl@0
   238
		while (ptr < ptrLimit)
sl@0
   239
			*ptr++ = TUint8(GetRgbPixelEx(xCoord++,aScanlinePtr).Color256());
sl@0
   240
		}
sl@0
   241
	}
sl@0
   242
sl@0
   243
void CBitwiseBitmap::GetScanLineColor4K(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   244
	{
sl@0
   245
	aLength = Min(aLength,aBuf.MaxLength() >> 1);
sl@0
   246
	aBuf.SetLength(aLength << 1);
sl@0
   247
sl@0
   248
	TUint16* ptr = (TUint16*)aBuf.Ptr();
sl@0
   249
	const TUint16* ptrLimit = ptr + aLength;
sl@0
   250
	TInt x = aPixel.iX;
sl@0
   251
sl@0
   252
	if(iHeader.iBitsPerPixel == 1)
sl@0
   253
		{
sl@0
   254
		while (ptr < ptrLimit)
sl@0
   255
			{
sl@0
   256
			*ptr++ = TUint16(COLOR_VALUE(aScanlinePtr, x) ? 0x0FFF : 0);
sl@0
   257
			x++;
sl@0
   258
			}
sl@0
   259
		}
sl@0
   260
	else
sl@0
   261
		{
sl@0
   262
		while (ptr < ptrLimit)
sl@0
   263
			*ptr++ = TUint16(GetRgbPixelEx(x++,aScanlinePtr)._Color4K());
sl@0
   264
		}
sl@0
   265
	}
sl@0
   266
sl@0
   267
void CBitwiseBitmap::GetScanLineColor64K(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   268
	{
sl@0
   269
	aLength = Min(aLength,aBuf.MaxLength() >> 1);
sl@0
   270
	aBuf.SetLength(aLength << 1);
sl@0
   271
sl@0
   272
	TUint16* ptr = (TUint16*)aBuf.Ptr();
sl@0
   273
	TUint16* ptrLimit = ptr + aLength;
sl@0
   274
	TInt x = aPixel.iX;
sl@0
   275
sl@0
   276
	if(iHeader.iBitsPerPixel == 1)
sl@0
   277
		{
sl@0
   278
		while (ptr < ptrLimit)
sl@0
   279
			{
sl@0
   280
			*ptr++ = TUint16(COLOR_VALUE(aScanlinePtr, x) ? 0xFFFF : 0);
sl@0
   281
			x++;
sl@0
   282
			}
sl@0
   283
		}
sl@0
   284
	else if(iHeader.iBitsPerPixel == 12)
sl@0
   285
		{
sl@0
   286
/*
sl@0
   287
		// use lookup table for 12->16 conversion
sl@0
   288
		TUint16* pixel4K = ((TUint16*) aScanlinePtr) + x;
sl@0
   289
		while(ptr < ptrLimit)
sl@0
   290
			{
sl@0
   291
			// this takes the 12 bit value, this is a number between 0 and 4095,
sl@0
   292
			// and looks up its corrosponding 16 bit value in the lookup table.
sl@0
   293
			// the colour should be identical, and but just in a different format
sl@0
   294
			// see below for an explaination of 12 & 16 bit colour values
sl@0
   295
			*ptr++ = K12to16LUT[*pixel4K++];
sl@0
   296
			}
sl@0
   297
*/
sl@0
   298
/*		This code uses logic rather than a lookup table
sl@0
   299
		to convert from 12->16 bpp and can be used instead of the above code
sl@0
   300
		if the 8k the lookup table uses becomes an issue
sl@0
   301
sl@0
   302
		12 bit colour
sl@0
   303
		-------------
sl@0
   304
		The 12 bit colour format uses 4 bits for the red, green and blue values.
sl@0
   305
		The colour is stored as a word with the most significant 4 bits having a
sl@0
   306
		value of zero.
sl@0
   307
		i.e. 0000RRRR GGGGBBBB where R,G & B represent single bits in the word.
sl@0
   308
sl@0
   309
		The code below labeled 'conversion of 4k colour...' changes the colour from
sl@0
   310
		16 bit to 32 bit where each colour nibble in the 16 bit version is changed
sl@0
   311
		to a byte in the 32 bit version e.g.
sl@0
   312
		0000RRRR GGGGBBBB -> 00000000 RRRRRRRR GGGGGGGG BBBBBBBB
sl@0
   313
sl@0
   314
sl@0
   315
		16 bit colour
sl@0
   316
		-------------
sl@0
   317
		The 16 bit colour format uses all 16 bits to represent the required colour.
sl@0
   318
		There are two possible 16 bit formats 5-5-5 and 5-6-5.
sl@0
   319
		Symbian uses the 5-6-5 format, with this all 16 bits are used to make the colour
sl@0
   320
		giving a possible value between 0..65535.  The RGB components are divided up
sl@0
   321
		as follows RRRR RGGG GGGB BBBB i.e. 5 bits for red and blue, and 6 for green.
sl@0
   322
sl@0
   323
		The code below labeled 'conversion to 64k' converts the colour from a 16 bit
sl@0
   324
		0000 RRRR GGGG BBBB -> RRRR RGGG GGGB BBBB format.
sl@0
   325
*/
sl@0
   326
		register TUint16* pixel4K = ((TUint16*) aScanlinePtr) + x;
sl@0
   327
		while (ptr < ptrLimit)
sl@0
   328
			{
sl@0
   329
			// conversion of 4k colour from 16 to 32 bits
sl@0
   330
			// this changes from a 16 to 32 bit value while keeping colour unchanged
sl@0
   331
			register TUint16 pixelVal = *pixel4K++;
sl@0
   332
			register TUint32 value32 = ((pixelVal & 0x0f00) >> 8) |
sl@0
   333
									   ((pixelVal & 0x00f0) << 4) |
sl@0
   334
									   ((pixelVal & 0x000f) << 16);
sl@0
   335
			value32 |= (value32 << 4);
sl@0
   336
			// conversion to 64k (RRRR RGGG GGGB BBBB)
sl@0
   337
			// this will make the change from (16 bit) 4-4-4 bpp to 5-6-5 bpp format
sl@0
   338
			register TUint32 color64K = ((value32 & 0x000000f8) << 8) |
sl@0
   339
										((value32 & 0x0000fc00) >> 5) |
sl@0
   340
										((value32 & 0x00f80000) >> 19);
sl@0
   341
			// store new colour value
sl@0
   342
			*ptr++ = static_cast <TUint16> (color64K);
sl@0
   343
			}
sl@0
   344
		}
sl@0
   345
	else
sl@0
   346
		{
sl@0
   347
		while (ptr < ptrLimit)
sl@0
   348
			*ptr++ = TUint16(GetRgbPixelEx(x++,aScanlinePtr)._Color64K());
sl@0
   349
		}
sl@0
   350
	}
sl@0
   351
sl@0
   352
void CBitwiseBitmap::GetScanLineColor16M(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   353
	{
sl@0
   354
	aLength = Min(aLength,aBuf.MaxLength() / 3);
sl@0
   355
	aBuf.SetLength(aLength * 3);
sl@0
   356
sl@0
   357
	TUint8* ptr = (TUint8*)aBuf.Ptr();
sl@0
   358
	TUint8* ptrLimit = ptr + (aLength * 3);
sl@0
   359
	TInt x = aPixel.iX;
sl@0
   360
sl@0
   361
	if(iHeader.iBitsPerPixel == 1)
sl@0
   362
		{
sl@0
   363
		while (ptr < ptrLimit)
sl@0
   364
			{
sl@0
   365
			const TUint8 color = TUint8(COLOR_VALUE(aScanlinePtr, x) ? 0xFF : 0);
sl@0
   366
			*ptr++ = color;
sl@0
   367
			*ptr++ = color;
sl@0
   368
			*ptr++ = color;
sl@0
   369
			x++;
sl@0
   370
			}
sl@0
   371
		}
sl@0
   372
	else
sl@0
   373
		{
sl@0
   374
		GetRgbPixelExMany16M(aPixel.iX,aScanlinePtr,ptr,aLength);
sl@0
   375
		}
sl@0
   376
	}
sl@0
   377
sl@0
   378
void CBitwiseBitmap::GetScanLineColor16MU(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   379
	{
sl@0
   380
	aLength = Min(aLength,aBuf.MaxLength() >> 2);
sl@0
   381
	aBuf.SetLength(aLength << 2);
sl@0
   382
sl@0
   383
	TUint32* ptr = (TUint32*)aBuf.Ptr();
sl@0
   384
sl@0
   385
	GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength);
sl@0
   386
	}
sl@0
   387
sl@0
   388
void CBitwiseBitmap::GetScanLineColor16MA(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   389
	{
sl@0
   390
	aLength = Min(aLength,aBuf.MaxLength() >> 2);
sl@0
   391
	aBuf.SetLength(aLength << 2);
sl@0
   392
sl@0
   393
	TUint32* ptr = (TUint32*)aBuf.Ptr();
sl@0
   394
	GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength);
sl@0
   395
	}
sl@0
   396
sl@0
   397
/**
sl@0
   398
Get the scanline data into the destination buffer in the EColor16MAP format.
sl@0
   399
@param	aDestBuf - destination buffer
sl@0
   400
@param	aPixel - the start position of the scanline.
sl@0
   401
@param	aLength - scanline length, as word length
sl@0
   402
@param	aScanlinePtr - scanline pointer
sl@0
   403
*/
sl@0
   404
void CBitwiseBitmap::GetScanLineColor16MAP(TDes8& aDestBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   405
	{
sl@0
   406
	aLength = Min(aLength, aDestBuf.MaxLength() >> 2);
sl@0
   407
	aDestBuf.SetLength(aLength << 2);
sl@0
   408
	TUint32* ptr = (TUint32*)aDestBuf.Ptr();
sl@0
   409
	GetRgbPixelExMany16MAP(aPixel.iX,aScanlinePtr,ptr,aLength);
sl@0
   410
	}
sl@0
   411
sl@0
   412
sl@0
   413
void CBitwiseBitmap::GetScanLineColorRgb(TDes8& aBuf,const TPoint& aPixel,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   414
	{
sl@0
   415
	aLength = Min(aLength,aBuf.MaxLength() / sizeof(TRgb));
sl@0
   416
	aBuf.SetLength(aLength * sizeof(TRgb));
sl@0
   417
sl@0
   418
	TUint32* ptr = (TUint32*)aBuf.Ptr();
sl@0
   419
	GetRgbPixelExMany(aPixel.iX,aScanlinePtr,ptr,aLength);
sl@0
   420
	}
sl@0
   421
sl@0
   422
void CBitwiseBitmap::GetScanLineExBits(TDes8& aBuf,TInt aX,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   423
	{
sl@0
   424
	TInt bitshift = 1;
sl@0
   425
	TInt pixelsPerWord = 8;
sl@0
   426
	TInt roundingmask = ~0x7;
sl@0
   427
	TInt logbpp = 2;
sl@0
   428
	TInt roundupfactor = 1;
sl@0
   429
	const TDisplayMode displayMode = iSettings.CurrentDisplayMode();
sl@0
   430
sl@0
   431
	switch(displayMode)
sl@0
   432
		{
sl@0
   433
		case EGray16:
sl@0
   434
		case EColor16:
sl@0
   435
			break; // set by default
sl@0
   436
		case EGray4:
sl@0
   437
			{
sl@0
   438
			bitshift = 2;
sl@0
   439
			pixelsPerWord = 16;
sl@0
   440
			roundingmask = ~0xf;
sl@0
   441
			logbpp = 1;
sl@0
   442
			roundupfactor = 3;
sl@0
   443
			break;
sl@0
   444
			}
sl@0
   445
		case EGray2:
sl@0
   446
			{
sl@0
   447
			bitshift = 3;
sl@0
   448
			pixelsPerWord = 32;
sl@0
   449
			roundingmask = ~0x1f;
sl@0
   450
			logbpp = 0;
sl@0
   451
			roundupfactor = 7;
sl@0
   452
			break;
sl@0
   453
			}
sl@0
   454
		default:
sl@0
   455
			Panic(EFbsBitmapInvalidMode);
sl@0
   456
		}
sl@0
   457
sl@0
   458
	aLength = Min(aLength,aBuf.MaxLength() << bitshift);
sl@0
   459
	aBuf.SetLength((aLength + roundupfactor) >> bitshift);
sl@0
   460
sl@0
   461
	TUint32* ptr = (TUint32*)aBuf.Ptr(); // guaranteed to be word aligned by the calling function
sl@0
   462
	TInt startlong = aX & roundingmask;
sl@0
   463
	TInt finishlong = (aX + aLength + pixelsPerWord - 1) & roundingmask;
sl@0
   464
	bitshift += 2; // Convert pixels per byte shift to pixels per word shift
sl@0
   465
	TUint32* wordptr = aScanlinePtr + (startlong >> bitshift);
sl@0
   466
	TInt wordLength = (finishlong - startlong) >> bitshift;
sl@0
   467
	TUint32* wordptrLimit = wordptr + wordLength;
sl@0
   468
sl@0
   469
	const TInt destinationWords = Min(aBuf.MaxLength() >> 2,wordLength);
sl@0
   470
	TUint32* ptrlimit = ptr + destinationWords;
sl@0
   471
sl@0
   472
	TInt offset = (aX - startlong) << logbpp;
sl@0
   473
sl@0
   474
	if (offset)
sl@0
   475
		{
sl@0
   476
		TInt offsetextra = 32-offset;
sl@0
   477
		TUint32 data = *wordptr++;
sl@0
   478
		data >>= offset;
sl@0
   479
sl@0
   480
		while (ptr < ptrlimit - 1)
sl@0
   481
			{
sl@0
   482
			TUint32 tmp = *wordptr++;
sl@0
   483
			data |= tmp << offsetextra;
sl@0
   484
			*ptr++ = data;
sl@0
   485
			data = tmp >> offset;
sl@0
   486
			}
sl@0
   487
sl@0
   488
		if (wordptr < wordptrLimit)
sl@0
   489
			*ptr = data | (*wordptr << offsetextra);
sl@0
   490
		else
sl@0
   491
			*ptr = data;
sl@0
   492
		}
sl@0
   493
	else
sl@0
   494
		{
sl@0
   495
		while (ptr < ptrlimit)
sl@0
   496
			*ptr++ = *wordptr++;
sl@0
   497
sl@0
   498
		// if the buffer isn't a whole number of words long,
sl@0
   499
		// we need to copy the remaining bytes
sl@0
   500
		const TInt bytesRemaining = aBuf.Length() - (destinationWords * sizeof(TUint32));
sl@0
   501
		if (bytesRemaining > 0)
sl@0
   502
			Mem::Copy(ptr,wordptr,bytesRemaining);
sl@0
   503
sl@0
   504
		}
sl@0
   505
	}
sl@0
   506
sl@0
   507
void CBitwiseBitmap::GetScanLineExBytes(TDes8& aBuf,TInt aX,TInt aLength,TUint32* aScanlinePtr) const
sl@0
   508
	{
sl@0
   509
	TInt numberOfBytesToCopy = 0;
sl@0
   510
	TUint8* ptr = (TUint8*)aScanlinePtr;
sl@0
   511
	TDisplayMode displayMode = iSettings.CurrentDisplayMode();
sl@0
   512
	switch(displayMode)
sl@0
   513
		{
sl@0
   514
		case EGray256:
sl@0
   515
		case EColor256:
sl@0
   516
			{
sl@0
   517
			aLength = Min(aLength,aBuf.MaxLength());
sl@0
   518
			numberOfBytesToCopy = aLength;
sl@0
   519
			ptr += aX;
sl@0
   520
			break;
sl@0
   521
			}
sl@0
   522
		case EColor4K:
sl@0
   523
		case EColor64K:
sl@0
   524
			{
sl@0
   525
			aLength = Min(aLength,aBuf.MaxLength() / 2);
sl@0
   526
			numberOfBytesToCopy = aLength * 2;
sl@0
   527
			ptr += (aX << 1);
sl@0
   528
			break;
sl@0
   529
			}
sl@0
   530
		case EColor16M:
sl@0
   531
			{
sl@0
   532
			aLength = Min(aLength,aBuf.MaxLength() / 3);
sl@0
   533
			numberOfBytesToCopy = aLength * 3;
sl@0
   534
			ptr += (aX * 3);
sl@0
   535
			break;
sl@0
   536
			}
sl@0
   537
		case EColor16MU:
sl@0
   538
		case EColor16MA:
sl@0
   539
		case EColor16MAP:
sl@0
   540
			{
sl@0
   541
			aLength = Min(aLength,aBuf.MaxLength() / 4);
sl@0
   542
			numberOfBytesToCopy = aLength * 4;
sl@0
   543
			ptr += (aX * 4);
sl@0
   544
			break;
sl@0
   545
			}
sl@0
   546
		default:
sl@0
   547
			Panic(EFbsBitmapInvalidMode);
sl@0
   548
		}
sl@0
   549
sl@0
   550
	aBuf.SetLength(numberOfBytesToCopy);
sl@0
   551
sl@0
   552
	Mem::Copy((TAny*)aBuf.Ptr(),ptr,numberOfBytesToCopy);
sl@0
   553
	}
sl@0
   554
sl@0
   555
void CBitwiseBitmap::DoStretchScanLine(TDes8& aBuf,TInt x,TInt y,TInt aClipStrchX,
sl@0
   556
	TInt aClipStrchLen,TInt aStretchLength,TInt aOrgX,TInt aOrgLen,
sl@0
   557
	const TPoint& aDitherOffset,TDisplayMode aDispMode,TUint32* aBase,
sl@0
   558
	TLineScanningPosition& aLineScanningPosition) const
sl@0
   559
	{
sl@0
   560
	TInt lastValue = 0;
sl@0
   561
	TUint32* bufptr=(TUint32*)((TInt)(&aBuf[0]+3)&~3);
sl@0
   562
	TUint32* buflimit=bufptr;
sl@0
   563
	TUint32* slptr=NULL;
sl@0
   564
	TPoint pixel(aOrgX,y);
sl@0
   565
	const TDisplayMode displayMode = iSettings.CurrentDisplayMode();
sl@0
   566
	GetScanLinePtr(slptr, aOrgLen, pixel,aBase, aLineScanningPosition);
sl@0
   567
	if (!slptr)
sl@0
   568
		{
sl@0
   569
		WhiteFill((TUint8*)aBuf.Ptr(),aBuf.MaxLength(),displayMode);
sl@0
   570
		return;
sl@0
   571
		}
sl@0
   572
sl@0
   573
	TInt lastcoord=-1;
sl@0
   574
	TLinearDDA stretchmap;
sl@0
   575
	TPoint coordmap(aOrgX,0);
sl@0
   576
	stretchmap.Construct(coordmap,coordmap+TPoint(aOrgLen,aStretchLength),TLinearDDA::ELeft);
sl@0
   577
	coordmap.iY=aClipStrchX;
sl@0
   578
	if (aClipStrchX>0) stretchmap.JumpToYCoord(coordmap.iX,coordmap.iY);
sl@0
   579
	else stretchmap.SingleStep(coordmap);
sl@0
   580
	switch(aDispMode)
sl@0
   581
		{
sl@0
   582
		case EGray4:
sl@0
   583
			{
sl@0
   584
			aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<4));
sl@0
   585
			aBuf.SetLength((aClipStrchLen+3)>>2);
sl@0
   586
			buflimit+=(aBuf.Length()+3)>>2;
sl@0
   587
			if (displayMode == EGray16)
sl@0
   588
				{
sl@0
   589
				TInt index=((aDitherOffset.iY&1)<<1)+((aDitherOffset.iX+x)&1);
sl@0
   590
				while(bufptr<buflimit)
sl@0
   591
					{
sl@0
   592
					TInt shift=0;
sl@0
   593
					*bufptr=0;
sl@0
   594
					while(shift<32)
sl@0
   595
						{
sl@0
   596
						if (coordmap.iX>lastcoord)
sl@0
   597
							{
sl@0
   598
							lastValue=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
sl@0
   599
							lastcoord=coordmap.iX;
sl@0
   600
							}
sl@0
   601
						*bufptr|=(lastValue<<shift);
sl@0
   602
						index^=1;
sl@0
   603
						shift+=2;
sl@0
   604
						if (stretchmap.SingleStep(coordmap)) break;
sl@0
   605
						}
sl@0
   606
					bufptr++;
sl@0
   607
					}
sl@0
   608
				}
sl@0
   609
			else
sl@0
   610
				{
sl@0
   611
				while (bufptr < buflimit)
sl@0
   612
					{
sl@0
   613
					TInt shift = 0;
sl@0
   614
					*bufptr = 0;
sl@0
   615
					while (shift < 32)
sl@0
   616
						{
sl@0
   617
						if (coordmap.iX>lastcoord)
sl@0
   618
							{
sl@0
   619
							lastValue = GetGrayPixelEx(coordmap.iX,slptr) >> 6;
sl@0
   620
							lastcoord = coordmap.iX;
sl@0
   621
							}
sl@0
   622
						*bufptr |= (lastValue << shift);
sl@0
   623
						shift += 2;
sl@0
   624
						if (stretchmap.SingleStep(coordmap)) break;
sl@0
   625
						}
sl@0
   626
					bufptr++;
sl@0
   627
					}
sl@0
   628
				}
sl@0
   629
			break;
sl@0
   630
			}
sl@0
   631
		case EGray16:
sl@0
   632
			{
sl@0
   633
			aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<3));
sl@0
   634
			aBuf.SetLength((aClipStrchLen+1)>>1);
sl@0
   635
			buflimit+=(aBuf.Length()+3)>>2;
sl@0
   636
			while(bufptr<buflimit)
sl@0
   637
				{
sl@0
   638
				TInt shift=0;
sl@0
   639
				*bufptr=0;
sl@0
   640
				while(shift<32)
sl@0
   641
					{
sl@0
   642
					if (coordmap.iX>lastcoord)
sl@0
   643
						{
sl@0
   644
						lastValue = GetGrayPixelEx(coordmap.iX,slptr) >> 4;
sl@0
   645
						lastcoord=coordmap.iX;
sl@0
   646
						}
sl@0
   647
					*bufptr |= lastValue << shift;
sl@0
   648
					shift+=4;
sl@0
   649
					if (stretchmap.SingleStep(coordmap)) break;
sl@0
   650
					}
sl@0
   651
				bufptr++;
sl@0
   652
				}
sl@0
   653
			break;
sl@0
   654
			}
sl@0
   655
		case EColor16:
sl@0
   656
			{
sl@0
   657
			aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<3));
sl@0
   658
			aBuf.SetLength((aClipStrchLen+1)>>1);
sl@0
   659
			buflimit+=(aBuf.Length()+3)>>2;
sl@0
   660
			while(bufptr<buflimit)
sl@0
   661
				{
sl@0
   662
				TInt shift=0;
sl@0
   663
				*bufptr=0;
sl@0
   664
				while(shift<32)
sl@0
   665
					{
sl@0
   666
					if (coordmap.iX>lastcoord)
sl@0
   667
						{
sl@0
   668
						lastValue = GetRgbPixelEx(coordmap.iX,slptr).Color16();
sl@0
   669
						lastcoord = coordmap.iX;
sl@0
   670
						}
sl@0
   671
					*bufptr |= lastValue << shift;
sl@0
   672
					shift+=4;
sl@0
   673
					if (stretchmap.SingleStep(coordmap)) break;
sl@0
   674
					}
sl@0
   675
				bufptr++;
sl@0
   676
				}
sl@0
   677
			break;
sl@0
   678
			}
sl@0
   679
		case EGray256:
sl@0
   680
			{
sl@0
   681
			aClipStrchLen = Min(aClipStrchLen,(TInt)(aBuf.MaxLength() & ~3));
sl@0
   682
			aBuf.SetLength(aClipStrchLen);
sl@0
   683
			buflimit += (aBuf.Length() + 3) >> 2;
sl@0
   684
sl@0
   685
			while (bufptr < buflimit)
sl@0
   686
				{
sl@0
   687
				TInt shift=0;
sl@0
   688
				*bufptr=0;
sl@0
   689
				while(shift<32)
sl@0
   690
					{
sl@0
   691
					if (coordmap.iX>lastcoord)
sl@0
   692
						{
sl@0
   693
						lastValue = GetGrayPixelEx(coordmap.iX,slptr);
sl@0
   694
						lastcoord=coordmap.iX;
sl@0
   695
						}
sl@0
   696
					*bufptr |= lastValue << shift;
sl@0
   697
					shift += 8;
sl@0
   698
					if (stretchmap.SingleStep(coordmap))
sl@0
   699
						break;
sl@0
   700
					}
sl@0
   701
				bufptr++;
sl@0
   702
				}
sl@0
   703
			break;
sl@0
   704
			}
sl@0
   705
		case EColor256:
sl@0
   706
			{
sl@0
   707
			aClipStrchLen = Min(aClipStrchLen,(TInt)(aBuf.MaxLength() & ~3));
sl@0
   708
			aBuf.SetLength(aClipStrchLen);
sl@0
   709
			buflimit += (aBuf.Length() + 3) >> 2;
sl@0
   710
sl@0
   711
			while (bufptr < buflimit)
sl@0
   712
				{
sl@0
   713
				TInt shift=0;
sl@0
   714
				*bufptr=0;
sl@0
   715
				while(shift<32)
sl@0
   716
					{
sl@0
   717
					if (coordmap.iX>lastcoord)
sl@0
   718
						{
sl@0
   719
						lastValue = TUint8(GetRgbPixelEx(coordmap.iX,slptr).Color256());
sl@0
   720
						lastcoord = coordmap.iX;
sl@0
   721
						}
sl@0
   722
					*bufptr |= lastValue << shift;
sl@0
   723
					shift += 8;
sl@0
   724
					if (stretchmap.SingleStep(coordmap))
sl@0
   725
						break;
sl@0
   726
					}
sl@0
   727
				bufptr++;
sl@0
   728
				}
sl@0
   729
			break;
sl@0
   730
			}
sl@0
   731
		case EColor4K:
sl@0
   732
			{
sl@0
   733
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1);
sl@0
   734
			aBuf.SetLength(aClipStrchLen << 1);
sl@0
   735
			buflimit += (aBuf.Length() + 3) >> 2;
sl@0
   736
sl@0
   737
			while (bufptr < buflimit)
sl@0
   738
				{
sl@0
   739
				if (coordmap.iX>lastcoord)
sl@0
   740
					{
sl@0
   741
					lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color4K();
sl@0
   742
					lastcoord=coordmap.iX;
sl@0
   743
					}
sl@0
   744
				*bufptr = lastValue;
sl@0
   745
				if (stretchmap.SingleStep(coordmap))
sl@0
   746
					break;
sl@0
   747
				if (coordmap.iX>lastcoord)
sl@0
   748
					{
sl@0
   749
					lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color4K();
sl@0
   750
					lastcoord=coordmap.iX;
sl@0
   751
					}
sl@0
   752
				*bufptr |= lastValue << 16;
sl@0
   753
				if (stretchmap.SingleStep(coordmap))
sl@0
   754
					break;
sl@0
   755
				bufptr++;
sl@0
   756
				}
sl@0
   757
			break;
sl@0
   758
			}
sl@0
   759
		case EColor64K:
sl@0
   760
			{
sl@0
   761
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1);
sl@0
   762
			aBuf.SetLength(aClipStrchLen << 1);
sl@0
   763
			buflimit += (aBuf.Length() + 3) >> 2;
sl@0
   764
sl@0
   765
			while (bufptr < buflimit)
sl@0
   766
				{
sl@0
   767
				if (coordmap.iX>lastcoord)
sl@0
   768
					{
sl@0
   769
					lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color64K();
sl@0
   770
					lastcoord=coordmap.iX;
sl@0
   771
					}
sl@0
   772
				*bufptr = lastValue;
sl@0
   773
				if (stretchmap.SingleStep(coordmap))
sl@0
   774
					break;
sl@0
   775
				if (coordmap.iX>lastcoord)
sl@0
   776
					{
sl@0
   777
					lastValue = GetRgbPixelEx(coordmap.iX,slptr)._Color64K();
sl@0
   778
					lastcoord=coordmap.iX;
sl@0
   779
					}
sl@0
   780
				*bufptr |= lastValue << 16;
sl@0
   781
				if (stretchmap.SingleStep(coordmap))
sl@0
   782
					break;
sl@0
   783
				bufptr++;
sl@0
   784
				}
sl@0
   785
			break;
sl@0
   786
			}
sl@0
   787
		case EColor16M: // Destination Mode
sl@0
   788
			{
sl@0
   789
			// Optimisation: Both of conditions on 32bpp and 24bpp were added to avoid to use
sl@0
   790
			// GetRgbPixelEx() for each pixel
sl@0
   791
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / 3);
sl@0
   792
			aBuf.SetLength(aClipStrchLen * 3);
sl@0
   793
			TUint8* ptr = (TUint8*)bufptr;
sl@0
   794
			TUint8* ptrLimit = ptr + aBuf.Length();
sl@0
   795
sl@0
   796
			if (iHeader.iBitsPerPixel == 32) // 32bpp source image => color
sl@0
   797
				{
sl@0
   798
				TInt lastColor = 0;
sl@0
   799
				if(displayMode == EColor16MAP)
sl@0
   800
					{
sl@0
   801
					const TUint16* normTable = PtrTo16BitNormalisationTable();
sl@0
   802
					while (ptr < ptrLimit)
sl@0
   803
						{
sl@0
   804
						if (coordmap.iX > lastcoord)
sl@0
   805
							{
sl@0
   806
							lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable);
sl@0
   807
							lastcoord = coordmap.iX;
sl@0
   808
							}
sl@0
   809
						*ptr++ = TUint8(lastColor);
sl@0
   810
						*ptr++ = TUint8(lastColor >> 8);
sl@0
   811
						*ptr++ = TUint8(lastColor >> 16);
sl@0
   812
						if (stretchmap.SingleStep(coordmap))
sl@0
   813
							break;
sl@0
   814
						}
sl@0
   815
					}
sl@0
   816
				else{
sl@0
   817
					while (ptr < ptrLimit)
sl@0
   818
						{
sl@0
   819
						if (coordmap.iX > lastcoord)
sl@0
   820
							{
sl@0
   821
							lastColor = *(slptr + coordmap.iX);
sl@0
   822
							lastcoord = coordmap.iX;
sl@0
   823
							}
sl@0
   824
						*ptr++ = TUint8(lastColor);
sl@0
   825
						*ptr++ = TUint8(lastColor >> 8);
sl@0
   826
						*ptr++ = TUint8(lastColor >> 16);
sl@0
   827
						if (stretchmap.SingleStep(coordmap))
sl@0
   828
							break;
sl@0
   829
						}
sl@0
   830
					}
sl@0
   831
				}
sl@0
   832
			else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color
sl@0
   833
				{
sl@0
   834
				TInt lastColor = 0;
sl@0
   835
				while (ptr < ptrLimit)
sl@0
   836
					{
sl@0
   837
					if (coordmap.iX > lastcoord)
sl@0
   838
						{
sl@0
   839
						TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3;
sl@0
   840
						lastColor = TUint8(*scanLineBytePointer);
sl@0
   841
						scanLineBytePointer++;
sl@0
   842
						lastColor |= TUint8(*scanLineBytePointer) << 8;
sl@0
   843
						scanLineBytePointer++;
sl@0
   844
						lastColor |= TUint8(*scanLineBytePointer) << 16;
sl@0
   845
						lastcoord = coordmap.iX;
sl@0
   846
						}
sl@0
   847
					*ptr++ = TUint8(lastColor);
sl@0
   848
					*ptr++ = TUint8(lastColor >> 8);
sl@0
   849
					*ptr++ = TUint8(lastColor >> 16);
sl@0
   850
					if (stretchmap.SingleStep(coordmap))
sl@0
   851
						break;
sl@0
   852
					}
sl@0
   853
				}
sl@0
   854
			else
sl@0
   855
				{
sl@0
   856
				TRgb lastColor;
sl@0
   857
				while (ptr < ptrLimit)
sl@0
   858
					{
sl@0
   859
					if (coordmap.iX>lastcoord)
sl@0
   860
						{
sl@0
   861
						lastColor = GetRgbPixelEx(coordmap.iX,slptr);
sl@0
   862
						lastcoord=coordmap.iX;
sl@0
   863
						}
sl@0
   864
					TInt color16M = lastColor._Color16M();
sl@0
   865
					*ptr++ = TUint8(color16M);
sl@0
   866
					*ptr++ = TUint8(color16M >> 8);
sl@0
   867
					*ptr++ = TUint8(color16M >> 16);
sl@0
   868
					if (stretchmap.SingleStep(coordmap))
sl@0
   869
						break;
sl@0
   870
					}
sl@0
   871
				}
sl@0
   872
			break;
sl@0
   873
			}
sl@0
   874
		case ERgb:
sl@0
   875
			{
sl@0
   876
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / sizeof(TRgb));
sl@0
   877
			aBuf.SetLength(aClipStrchLen * sizeof(TRgb));
sl@0
   878
			TRgb* pixelPtr = (TRgb*)bufptr;
sl@0
   879
			TRgb* pixelPtrLimit = pixelPtr + aClipStrchLen;
sl@0
   880
			TRgb lastColor;
sl@0
   881
sl@0
   882
			while (pixelPtr < pixelPtrLimit)
sl@0
   883
				{
sl@0
   884
				if (coordmap.iX > lastcoord)
sl@0
   885
					{
sl@0
   886
					lastColor = GetRgbPixelEx(coordmap.iX,slptr);
sl@0
   887
					lastcoord = coordmap.iX;
sl@0
   888
					}
sl@0
   889
				*pixelPtr++ = lastColor;
sl@0
   890
				if (stretchmap.SingleStep(coordmap))
sl@0
   891
					break;
sl@0
   892
				}
sl@0
   893
			break;
sl@0
   894
			}
sl@0
   895
		case EColor16MU: // Destination Mode
sl@0
   896
			{
sl@0
   897
			// Optimisation: The condition 32bpp was added to avoid to use
sl@0
   898
			//GetRgbPixelEx() for each pixel (construction of a TRgb object each time)
sl@0
   899
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2);
sl@0
   900
			aBuf.SetLength(aClipStrchLen << 2);
sl@0
   901
			TInt32* pixelPtr = (TInt32*)bufptr;
sl@0
   902
			TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen;
sl@0
   903
sl@0
   904
			if (iHeader.iBitsPerPixel == 32) //32bpp source image => color
sl@0
   905
				{
sl@0
   906
				TInt lastColor = 0;
sl@0
   907
				if(displayMode == EColor16MAP)
sl@0
   908
					{
sl@0
   909
					const TUint16* normTable = PtrTo16BitNormalisationTable();
sl@0
   910
					while (pixelPtr < pixelPtrLimit)
sl@0
   911
						{
sl@0
   912
						if (coordmap.iX > lastcoord)
sl@0
   913
							{
sl@0
   914
							lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable);
sl@0
   915
							lastcoord = coordmap.iX;
sl@0
   916
							}
sl@0
   917
						*pixelPtr++ = (lastColor | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order
sl@0
   918
						if (stretchmap.SingleStep(coordmap))
sl@0
   919
							break;
sl@0
   920
						}
sl@0
   921
					}
sl@0
   922
				else{
sl@0
   923
					while (pixelPtr < pixelPtrLimit)
sl@0
   924
						{
sl@0
   925
						if (coordmap.iX > lastcoord)
sl@0
   926
							{
sl@0
   927
							lastColor = *(slptr + coordmap.iX);
sl@0
   928
							lastcoord = coordmap.iX;
sl@0
   929
							}
sl@0
   930
						*pixelPtr++ = (lastColor | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order
sl@0
   931
						if (stretchmap.SingleStep(coordmap))
sl@0
   932
							break;
sl@0
   933
						}
sl@0
   934
					}
sl@0
   935
				}
sl@0
   936
				
sl@0
   937
			else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color
sl@0
   938
				{
sl@0
   939
				TInt lastColor = 0;
sl@0
   940
				while (pixelPtr < pixelPtrLimit)
sl@0
   941
					{
sl@0
   942
					if (coordmap.iX > lastcoord)
sl@0
   943
						{
sl@0
   944
						TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3;
sl@0
   945
						lastColor = TUint8(*scanLineBytePointer);
sl@0
   946
						scanLineBytePointer++;
sl@0
   947
						lastColor |= TUint8(*scanLineBytePointer) << 8;
sl@0
   948
						scanLineBytePointer++;
sl@0
   949
						lastColor |= TUint8(*scanLineBytePointer) << 16;
sl@0
   950
						lastcoord = coordmap.iX;
sl@0
   951
						}
sl@0
   952
					*pixelPtr++ = (lastColor | 0xff000000);
sl@0
   953
					if (stretchmap.SingleStep(coordmap))
sl@0
   954
						break;
sl@0
   955
					}
sl@0
   956
				}
sl@0
   957
			else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color
sl@0
   958
				{
sl@0
   959
				TInt lastColor = 0;
sl@0
   960
				while (pixelPtr < pixelPtrLimit)
sl@0
   961
					{
sl@0
   962
					if (coordmap.iX > lastcoord)
sl@0
   963
						{
sl@0
   964
						TUint rawColor = *(((TUint16*)slptr) + coordmap.iX);
sl@0
   965
						TInt red = (rawColor   & 0xF800)>>8;
sl@0
   966
						red += red>>5;
sl@0
   967
						TInt green = (rawColor & 0x07E0)>>3;
sl@0
   968
						green += green>>6;
sl@0
   969
						TInt blue = (rawColor  & 0x001F)<<3;
sl@0
   970
						blue += blue>>5;
sl@0
   971
						lastColor = 0xff000000 | (red << 16) | (green << 8) | blue;
sl@0
   972
						lastcoord = coordmap.iX;
sl@0
   973
						}
sl@0
   974
					*pixelPtr++ = lastColor;
sl@0
   975
					if (stretchmap.SingleStep(coordmap))
sl@0
   976
						break;
sl@0
   977
					}
sl@0
   978
				}
sl@0
   979
			else
sl@0
   980
				{
sl@0
   981
				TRgb lastColor;
sl@0
   982
				while (pixelPtr < pixelPtrLimit)
sl@0
   983
					{
sl@0
   984
					if (coordmap.iX > lastcoord)
sl@0
   985
						{
sl@0
   986
						lastColor = GetRgbPixelEx(coordmap.iX,slptr);
sl@0
   987
						lastcoord = coordmap.iX;
sl@0
   988
						}
sl@0
   989
					*pixelPtr++ = (lastColor._Color16MU() | 0xff000000);//BGR0 (Blue/Green/Red) as little endian byte order
sl@0
   990
					if (stretchmap.SingleStep(coordmap))
sl@0
   991
						break;
sl@0
   992
					}
sl@0
   993
				}
sl@0
   994
			break;
sl@0
   995
			}
sl@0
   996
		case EColor16MA:
sl@0
   997
			{
sl@0
   998
			// Optimisation: The condition 32bpp was added to avoid to use
sl@0
   999
			// GetRgbPixelEx() for each pixel (construction of a TRgb object each time)
sl@0
  1000
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2);
sl@0
  1001
			aBuf.SetLength(aClipStrchLen << 2);
sl@0
  1002
			TInt32* pixelPtr = (TInt32*)bufptr;
sl@0
  1003
			TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen;
sl@0
  1004
			const TUint16* normTable = PtrTo16BitNormalisationTable();
sl@0
  1005
			if (iHeader.iBitsPerPixel == 32) //32bpp source image => color
sl@0
  1006
				{
sl@0
  1007
				TInt lastColor = 0;
sl@0
  1008
				if(displayMode == EColor16MAP)
sl@0
  1009
					{
sl@0
  1010
					while (pixelPtr < pixelPtrLimit)
sl@0
  1011
						{
sl@0
  1012
						if (coordmap.iX > lastcoord)
sl@0
  1013
							{
sl@0
  1014
							lastColor = PMA2NonPMAPixel(*(slptr + coordmap.iX), normTable);
sl@0
  1015
							lastcoord = coordmap.iX;
sl@0
  1016
							}
sl@0
  1017
						*pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order
sl@0
  1018
						if (stretchmap.SingleStep(coordmap))
sl@0
  1019
							break;
sl@0
  1020
						}
sl@0
  1021
					}
sl@0
  1022
				else
sl@0
  1023
					{
sl@0
  1024
					while (pixelPtr < pixelPtrLimit)
sl@0
  1025
						{
sl@0
  1026
						if (coordmap.iX > lastcoord)
sl@0
  1027
							{
sl@0
  1028
							lastColor = *(slptr + coordmap.iX);
sl@0
  1029
							lastcoord = coordmap.iX;
sl@0
  1030
							}
sl@0
  1031
						*pixelPtr++ = lastColor;
sl@0
  1032
						if (stretchmap.SingleStep(coordmap))
sl@0
  1033
								break;
sl@0
  1034
						}
sl@0
  1035
					}
sl@0
  1036
				}
sl@0
  1037
			else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color
sl@0
  1038
				{
sl@0
  1039
				TInt lastColor = 0;
sl@0
  1040
				while (pixelPtr < pixelPtrLimit)
sl@0
  1041
					{
sl@0
  1042
					if (coordmap.iX > lastcoord)
sl@0
  1043
						{
sl@0
  1044
						TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3;
sl@0
  1045
						lastColor = TUint8(*scanLineBytePointer);
sl@0
  1046
						scanLineBytePointer++;
sl@0
  1047
						lastColor |= TUint8(*scanLineBytePointer) << 8;
sl@0
  1048
						scanLineBytePointer++;
sl@0
  1049
						lastColor |= TUint8(*scanLineBytePointer) << 16;
sl@0
  1050
						lastcoord = coordmap.iX;
sl@0
  1051
						}
sl@0
  1052
					*pixelPtr++ = (lastColor | 0xff000000);
sl@0
  1053
					if (stretchmap.SingleStep(coordmap))
sl@0
  1054
						break;
sl@0
  1055
					}
sl@0
  1056
				}
sl@0
  1057
			else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color
sl@0
  1058
				{
sl@0
  1059
				TInt lastColor = 0;
sl@0
  1060
				while (pixelPtr < pixelPtrLimit)
sl@0
  1061
					{
sl@0
  1062
					if (coordmap.iX > lastcoord)
sl@0
  1063
						{
sl@0
  1064
						TUint rawColor = *(((TUint16*)slptr) + coordmap.iX);
sl@0
  1065
						TInt red = (rawColor   & 0xF800)>>8;
sl@0
  1066
						red += red>>5;
sl@0
  1067
						TInt green = (rawColor & 0x07E0)>>3;
sl@0
  1068
						green += green>>6;
sl@0
  1069
						TInt blue = (rawColor  & 0x001F)<<3;
sl@0
  1070
						blue += blue>>5;
sl@0
  1071
						lastColor = 0xff000000 | (red << 16) | (green << 8) | blue;
sl@0
  1072
						lastcoord = coordmap.iX;
sl@0
  1073
						}
sl@0
  1074
					*pixelPtr++ = lastColor;
sl@0
  1075
					if (stretchmap.SingleStep(coordmap))
sl@0
  1076
						break;
sl@0
  1077
					}
sl@0
  1078
				}
sl@0
  1079
			else
sl@0
  1080
				{
sl@0
  1081
				TRgb lastColor;
sl@0
  1082
sl@0
  1083
				while (pixelPtr < pixelPtrLimit)
sl@0
  1084
					{
sl@0
  1085
					if (coordmap.iX > lastcoord)
sl@0
  1086
						{
sl@0
  1087
						lastColor = GetRgbPixelEx(coordmap.iX,slptr);
sl@0
  1088
						lastcoord = coordmap.iX;
sl@0
  1089
						}
sl@0
  1090
					*pixelPtr++ = lastColor._Color16MA();//BGRA (Blue/Green/Red) as little endian byte order
sl@0
  1091
					if (stretchmap.SingleStep(coordmap))
sl@0
  1092
						break;
sl@0
  1093
					}
sl@0
  1094
				}
sl@0
  1095
			break;
sl@0
  1096
			}
sl@0
  1097
		case EColor16MAP:
sl@0
  1098
			{ //if alpha is not available, assign 255 as alpha (opaque).
sl@0
  1099
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2);
sl@0
  1100
			aBuf.SetLength(aClipStrchLen << 2);
sl@0
  1101
			TInt32* pixelPtr = (TInt32*)bufptr;
sl@0
  1102
			TInt32* pixelPtrLimit = pixelPtr + aClipStrchLen;
sl@0
  1103
			if (iHeader.iBitsPerPixel == 32) //32bpp source image => color
sl@0
  1104
				{
sl@0
  1105
				TInt lastColor = 0;
sl@0
  1106
				//pre-multiply if alpha IS available.
sl@0
  1107
				if(displayMode == EColor16MA)
sl@0
  1108
					{
sl@0
  1109
					while (pixelPtr < pixelPtrLimit)
sl@0
  1110
						{
sl@0
  1111
						if (coordmap.iX > lastcoord)
sl@0
  1112
							{
sl@0
  1113
							lastColor = NonPMA2PMAPixel(*(slptr + coordmap.iX));
sl@0
  1114
							lastcoord = coordmap.iX;
sl@0
  1115
							}
sl@0
  1116
						*pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order
sl@0
  1117
						if (stretchmap.SingleStep(coordmap))
sl@0
  1118
							break;
sl@0
  1119
						}
sl@0
  1120
					}
sl@0
  1121
				else if(displayMode == EColor16MU)
sl@0
  1122
					{
sl@0
  1123
					while (pixelPtr < pixelPtrLimit)
sl@0
  1124
						{
sl@0
  1125
						if (coordmap.iX > lastcoord)
sl@0
  1126
							{
sl@0
  1127
							//do not want to convert to non pma, since keep transparency
sl@0
  1128
							//e.g. alpha 0.5, red 0.5.  Want to keep red as 0.5 since it
sl@0
  1129
							//is not fully red.  For 16MA convert to 1, and keep 0.5 alpha
sl@0
  1130
							lastColor = (*(slptr + coordmap.iX))|0xff000000;
sl@0
  1131
							lastcoord = coordmap.iX;
sl@0
  1132
							}
sl@0
  1133
						*pixelPtr++ = lastColor;//BGRA (Blue/Green/Red) as little endian byte order
sl@0
  1134
						if (stretchmap.SingleStep(coordmap))
sl@0
  1135
							break;
sl@0
  1136
						}
sl@0
  1137
					}
sl@0
  1138
				else	
sl@0
  1139
					{
sl@0
  1140
					while (pixelPtr < pixelPtrLimit)
sl@0
  1141
						{
sl@0
  1142
						if (coordmap.iX > lastcoord)
sl@0
  1143
							{
sl@0
  1144
							lastColor = *(slptr + coordmap.iX);
sl@0
  1145
							lastcoord = coordmap.iX;
sl@0
  1146
							}
sl@0
  1147
						*pixelPtr++ = lastColor;
sl@0
  1148
						if (stretchmap.SingleStep(coordmap))
sl@0
  1149
								break;
sl@0
  1150
						}
sl@0
  1151
					}
sl@0
  1152
				}
sl@0
  1153
				else if (iHeader.iBitsPerPixel == 24) //24bpp source image => color
sl@0
  1154
					{
sl@0
  1155
					TInt lastColor = 0;
sl@0
  1156
					while (pixelPtr < pixelPtrLimit)
sl@0
  1157
						{
sl@0
  1158
						if (coordmap.iX > lastcoord)
sl@0
  1159
							{
sl@0
  1160
							TUint8* scanLineBytePointer = (TUint8*)slptr + coordmap.iX*3;
sl@0
  1161
							lastColor = TUint8(*scanLineBytePointer);
sl@0
  1162
							scanLineBytePointer++;
sl@0
  1163
							lastColor |= TUint8(*scanLineBytePointer) << 8;
sl@0
  1164
							scanLineBytePointer++;
sl@0
  1165
							lastColor |= TUint8(*scanLineBytePointer) << 16;
sl@0
  1166
							lastcoord = coordmap.iX;
sl@0
  1167
							}
sl@0
  1168
						*pixelPtr++ = (lastColor | 0xff000000);
sl@0
  1169
						if (stretchmap.SingleStep(coordmap))
sl@0
  1170
							break;
sl@0
  1171
						}
sl@0
  1172
					}
sl@0
  1173
				else if (iHeader.iBitsPerPixel == 16) //16bpp source image => color
sl@0
  1174
					{
sl@0
  1175
					TInt lastColor = 0;
sl@0
  1176
					while (pixelPtr < pixelPtrLimit)
sl@0
  1177
						{
sl@0
  1178
						if (coordmap.iX > lastcoord)
sl@0
  1179
							{
sl@0
  1180
							TUint rawColor = *(((TUint16*)slptr) + coordmap.iX);
sl@0
  1181
							TInt red = (rawColor   & 0xF800)>>8;
sl@0
  1182
							red += red>>5;
sl@0
  1183
							TInt green = (rawColor & 0x07E0)>>3;
sl@0
  1184
							green += green>>6;
sl@0
  1185
							TInt blue = (rawColor  & 0x001F)<<3;
sl@0
  1186
							blue += blue>>5;
sl@0
  1187
							lastColor = 0xff000000 | (red << 16) | (green << 8) | blue;
sl@0
  1188
							lastcoord = coordmap.iX;
sl@0
  1189
							}
sl@0
  1190
						*pixelPtr++ = lastColor;
sl@0
  1191
						if (stretchmap.SingleStep(coordmap))
sl@0
  1192
							break;
sl@0
  1193
						}
sl@0
  1194
					}
sl@0
  1195
				else
sl@0
  1196
					{
sl@0
  1197
					TRgb lastColor;
sl@0
  1198
sl@0
  1199
					while (pixelPtr < pixelPtrLimit)
sl@0
  1200
						{
sl@0
  1201
						if (coordmap.iX > lastcoord)
sl@0
  1202
							{
sl@0
  1203
							lastColor = GetRgbPixelEx(coordmap.iX,slptr);
sl@0
  1204
							lastcoord = coordmap.iX;
sl@0
  1205
							}
sl@0
  1206
						*pixelPtr++ = lastColor._Color16MA();//BGRA (Blue/Green/Red) as little endian byte order
sl@0
  1207
						if (stretchmap.SingleStep(coordmap))
sl@0
  1208
							break;
sl@0
  1209
						}
sl@0
  1210
					}
sl@0
  1211
				break;
sl@0
  1212
			}
sl@0
  1213
		case EGray2:
sl@0
  1214
			{
sl@0
  1215
			TBool oddx=(aDitherOffset.iX&1);
sl@0
  1216
			TBool oddy=(aDitherOffset.iY&1);
sl@0
  1217
			aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength()>>2)<<5));
sl@0
  1218
			aBuf.SetLength((aClipStrchLen+7)>>3);
sl@0
  1219
			buflimit+=(aBuf.Length()+3)>>2;
sl@0
  1220
			while(bufptr<buflimit)
sl@0
  1221
				{
sl@0
  1222
				TUint32 mask=1;
sl@0
  1223
				*bufptr=0;
sl@0
  1224
				while(mask)
sl@0
  1225
					{
sl@0
  1226
					if (coordmap.iX > lastcoord)
sl@0
  1227
						{
sl@0
  1228
						lastValue = GetGrayPixelEx(coordmap.iX,slptr);
sl@0
  1229
						lastcoord = coordmap.iX;
sl@0
  1230
						}
sl@0
  1231
					if (HashTo1bpp(lastValue,oddx,oddy))
sl@0
  1232
						*bufptr|=mask;
sl@0
  1233
					mask<<=1;
sl@0
  1234
					oddx^=1;
sl@0
  1235
					if (stretchmap.SingleStep(coordmap)) break;
sl@0
  1236
					}
sl@0
  1237
				bufptr++;
sl@0
  1238
				}
sl@0
  1239
			break;
sl@0
  1240
			}
sl@0
  1241
		default:
sl@0
  1242
			Panic(EFbsBitmapInvalidMode);
sl@0
  1243
		}
sl@0
  1244
	}
sl@0
  1245
sl@0
  1246
void CBitwiseBitmap::DoCompressScanLine(TDes8& aBuf,TInt x,TInt y,TInt aClipStrchX,TInt aClipStrchLen,TInt aStretchLength,TInt aOrgX,TInt aOrgLen,const TPoint& aDitherOffset,TDisplayMode aDispMode,TUint32* aBase,TLineScanningPosition& aLineScanningPosition) const
sl@0
  1247
	{
sl@0
  1248
	TInt first=0,second=0,third=0,fourth=0,fifth=0,sixth=0,seventh=0,eighth=0;
sl@0
  1249
	TUint8* bufptr=&aBuf[0];
sl@0
  1250
	TUint8* buflimit=bufptr;
sl@0
  1251
	TUint32* slptr=NULL;
sl@0
  1252
	TPoint pixel(aOrgX,y);
sl@0
  1253
	TDisplayMode displayMode = iSettings.CurrentDisplayMode();
sl@0
  1254
	GetScanLinePtr(slptr,aOrgLen,pixel,aBase, aLineScanningPosition);
sl@0
  1255
	if (!slptr)
sl@0
  1256
		{
sl@0
  1257
		WhiteFill((TUint8*)aBuf.Ptr(),aBuf.MaxLength(),displayMode);
sl@0
  1258
		return;
sl@0
  1259
		}
sl@0
  1260
	TLinearDDA stretchmap;
sl@0
  1261
	TPoint coordmap(aOrgX,0);
sl@0
  1262
	stretchmap.Construct(coordmap,coordmap+TPoint(aOrgLen,aStretchLength),TLinearDDA::ELeft);
sl@0
  1263
	coordmap.iY=aClipStrchX;
sl@0
  1264
	if (aClipStrchX>0) stretchmap.JumpToYCoord(coordmap.iX,coordmap.iY);
sl@0
  1265
	else stretchmap.NextStep(coordmap);
sl@0
  1266
	switch(aDispMode)
sl@0
  1267
		{
sl@0
  1268
		case EGray4:
sl@0
  1269
			{
sl@0
  1270
			aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<2));
sl@0
  1271
			aBuf.SetLength((aClipStrchLen+3)>>2);
sl@0
  1272
			TInt index=((aDitherOffset.iY&1)<<1)+((aDitherOffset.iX+x)&1);
sl@0
  1273
			buflimit+=aBuf.Length();
sl@0
  1274
			if (displayMode==EGray16)
sl@0
  1275
				{
sl@0
  1276
				while(bufptr<buflimit)
sl@0
  1277
					{
sl@0
  1278
					first=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
sl@0
  1279
					index^=1;
sl@0
  1280
					stretchmap.NextStep(coordmap);
sl@0
  1281
					second=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
sl@0
  1282
					index^=1;
sl@0
  1283
					stretchmap.NextStep(coordmap);
sl@0
  1284
					third=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
sl@0
  1285
					index^=1;
sl@0
  1286
					stretchmap.NextStep(coordmap);
sl@0
  1287
					fourth=HashTo2bpp(GetGrayPixelEx(coordmap.iX,slptr),index);
sl@0
  1288
					index^=1;
sl@0
  1289
					*bufptr++=TUint8(first|(second<<2)|(third<<4)|(fourth<<6));
sl@0
  1290
					stretchmap.NextStep(coordmap);
sl@0
  1291
					}
sl@0
  1292
				}
sl@0
  1293
			else
sl@0
  1294
				{
sl@0
  1295
				while(bufptr<buflimit)
sl@0
  1296
					{
sl@0
  1297
					first=GetGrayPixelEx(coordmap.iX,slptr)>>6;
sl@0
  1298
					stretchmap.NextStep(coordmap);
sl@0
  1299
					second=GetGrayPixelEx(coordmap.iX,slptr)>>6;
sl@0
  1300
					stretchmap.NextStep(coordmap);
sl@0
  1301
					third=GetGrayPixelEx(coordmap.iX,slptr)>>6;
sl@0
  1302
					stretchmap.NextStep(coordmap);
sl@0
  1303
					fourth=GetGrayPixelEx(coordmap.iX,slptr)>>6;
sl@0
  1304
					*bufptr++=TUint8(first|(second<<2)|(third<<4)|(fourth<<6));
sl@0
  1305
					stretchmap.NextStep(coordmap);
sl@0
  1306
					}
sl@0
  1307
				}
sl@0
  1308
			break;
sl@0
  1309
			}
sl@0
  1310
		case EGray16:
sl@0
  1311
			{
sl@0
  1312
			aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<1));
sl@0
  1313
			aBuf.SetLength((aClipStrchLen+1)>>1);
sl@0
  1314
			buflimit+=aBuf.Length();
sl@0
  1315
			while(bufptr<buflimit)
sl@0
  1316
				{
sl@0
  1317
				first = GetGrayPixelEx(coordmap.iX,slptr) >> 4;
sl@0
  1318
				stretchmap.NextStep(coordmap);
sl@0
  1319
				first |= GetGrayPixelEx(coordmap.iX,slptr) & 0xf0;
sl@0
  1320
				*bufptr++ = TUint8(first);
sl@0
  1321
				stretchmap.NextStep(coordmap);
sl@0
  1322
				}
sl@0
  1323
			break;
sl@0
  1324
			}
sl@0
  1325
		case EColor16:
sl@0
  1326
			{
sl@0
  1327
			aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<1));
sl@0
  1328
			aBuf.SetLength((aClipStrchLen+1)>>1);
sl@0
  1329
			buflimit+=aBuf.Length();
sl@0
  1330
			while(bufptr<buflimit)
sl@0
  1331
				{
sl@0
  1332
				first = GetRgbPixelEx(coordmap.iX,slptr).Color16();
sl@0
  1333
				stretchmap.NextStep(coordmap);
sl@0
  1334
				first |= GetRgbPixelEx(coordmap.iX,slptr).Color16() << 4;
sl@0
  1335
				*bufptr++ = TUint8(first);
sl@0
  1336
				stretchmap.NextStep(coordmap);
sl@0
  1337
				}
sl@0
  1338
			break;
sl@0
  1339
			}
sl@0
  1340
		case EGray256:
sl@0
  1341
			{
sl@0
  1342
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength());
sl@0
  1343
			aBuf.SetLength(aClipStrchLen);
sl@0
  1344
			buflimit += aBuf.Length();
sl@0
  1345
sl@0
  1346
			while(bufptr < buflimit)
sl@0
  1347
				{
sl@0
  1348
				*bufptr++ = GetGrayPixelEx(coordmap.iX,slptr);
sl@0
  1349
				stretchmap.NextStep(coordmap);
sl@0
  1350
				}
sl@0
  1351
			break;
sl@0
  1352
			}
sl@0
  1353
		case EColor256:
sl@0
  1354
			{
sl@0
  1355
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength());
sl@0
  1356
			aBuf.SetLength(aClipStrchLen);
sl@0
  1357
			buflimit += aBuf.Length();
sl@0
  1358
sl@0
  1359
			while(bufptr < buflimit)
sl@0
  1360
				{
sl@0
  1361
				*bufptr++ = TUint8(GetRgbPixelEx(coordmap.iX,slptr).Color256());
sl@0
  1362
				stretchmap.NextStep(coordmap);
sl@0
  1363
				}
sl@0
  1364
			break;
sl@0
  1365
			}
sl@0
  1366
		case EColor4K:
sl@0
  1367
			{
sl@0
  1368
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1);
sl@0
  1369
			aBuf.SetLength(aClipStrchLen << 1);
sl@0
  1370
			buflimit += aBuf.Length();
sl@0
  1371
sl@0
  1372
			while(bufptr < buflimit)
sl@0
  1373
				{
sl@0
  1374
				*((TUint16*)bufptr) = TUint16(GetRgbPixelEx(coordmap.iX,slptr)._Color4K());
sl@0
  1375
				bufptr += 2;
sl@0
  1376
				stretchmap.NextStep(coordmap);
sl@0
  1377
				}
sl@0
  1378
			break;
sl@0
  1379
			}
sl@0
  1380
		case EColor64K:
sl@0
  1381
			{
sl@0
  1382
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 1);
sl@0
  1383
			aBuf.SetLength(aClipStrchLen << 1);
sl@0
  1384
			buflimit += aBuf.Length();
sl@0
  1385
sl@0
  1386
			while(bufptr < buflimit)
sl@0
  1387
				{
sl@0
  1388
				*((TUint16*)bufptr) = TUint16(GetRgbPixelEx(coordmap.iX,slptr)._Color64K());
sl@0
  1389
				bufptr += 2;
sl@0
  1390
				stretchmap.NextStep(coordmap);
sl@0
  1391
				}
sl@0
  1392
			break;
sl@0
  1393
			}
sl@0
  1394
		case EColor16M:
sl@0
  1395
			{
sl@0
  1396
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() / 3);
sl@0
  1397
			aBuf.SetLength(aClipStrchLen * 3);
sl@0
  1398
			buflimit += aBuf.Length();
sl@0
  1399
sl@0
  1400
			while(bufptr<buflimit)
sl@0
  1401
				{
sl@0
  1402
				TInt color16M = GetRgbPixelEx(coordmap.iX,slptr)._Color16M();
sl@0
  1403
				*bufptr++ = TUint8(color16M);
sl@0
  1404
				*bufptr++ = TUint8(color16M >> 8);
sl@0
  1405
				*bufptr++ = TUint8(color16M >> 16);
sl@0
  1406
				stretchmap.NextStep(coordmap);
sl@0
  1407
				}
sl@0
  1408
			break;
sl@0
  1409
			}
sl@0
  1410
		case ERgb:
sl@0
  1411
		case EColor16MU:
sl@0
  1412
		case EColor16MA:
sl@0
  1413
		case EColor16MAP:
sl@0
  1414
			{
sl@0
  1415
			aClipStrchLen = Min(aClipStrchLen,aBuf.MaxLength() >> 2);
sl@0
  1416
			aBuf.SetLength(aClipStrchLen << 2);
sl@0
  1417
			TUint32* pixelPtr = (TUint32*)bufptr;
sl@0
  1418
			TUint32* pixelPtrLimit = pixelPtr + aClipStrchLen;
sl@0
  1419
			if (aDispMode == EColor16MAP && displayMode == EColor16MA)
sl@0
  1420
			while(pixelPtr < pixelPtrLimit)
sl@0
  1421
				{
sl@0
  1422
					*pixelPtr++ = NonPMA2PMAPixel(*(slptr + coordmap.iX));
sl@0
  1423
				stretchmap.NextStep(coordmap);
sl@0
  1424
				}
sl@0
  1425
			else if (aDispMode == EColor16MAP && displayMode == EColor16MAP)
sl@0
  1426
				while(pixelPtr < pixelPtrLimit)
sl@0
  1427
					{
sl@0
  1428
					*pixelPtr++ = *(slptr + coordmap.iX);
sl@0
  1429
					stretchmap.NextStep(coordmap);
sl@0
  1430
					}
sl@0
  1431
			else if (aDispMode == EColor16MU)
sl@0
  1432
				while(pixelPtr < pixelPtrLimit)
sl@0
  1433
					{
sl@0
  1434
					*pixelPtr++ = GetRgbPixelEx(coordmap.iX, slptr).Internal();
sl@0
  1435
					stretchmap.NextStep(coordmap);
sl@0
  1436
					}
sl@0
  1437
			else
sl@0
  1438
				while(pixelPtr < pixelPtrLimit)
sl@0
  1439
					{
sl@0
  1440
					*pixelPtr++ = GetRgbPixelEx(coordmap.iX, slptr).Internal();
sl@0
  1441
					stretchmap.NextStep(coordmap);
sl@0
  1442
				}
sl@0
  1443
			break;
sl@0
  1444
			}
sl@0
  1445
		case EGray2:
sl@0
  1446
			{
sl@0
  1447
			TBool oddx=(aDitherOffset.iX&1);
sl@0
  1448
			TBool oddy=(aDitherOffset.iY&1);
sl@0
  1449
			aClipStrchLen=Min(aClipStrchLen,(TInt)((aBuf.MaxLength())<<3));
sl@0
  1450
			aBuf.SetLength((aClipStrchLen+7)>>3);
sl@0
  1451
			buflimit+=aBuf.Length();
sl@0
  1452
			while(bufptr<buflimit)
sl@0
  1453
				{
sl@0
  1454
				first=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
sl@0
  1455
				stretchmap.NextStep(coordmap);
sl@0
  1456
				second=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
sl@0
  1457
				stretchmap.NextStep(coordmap);
sl@0
  1458
				third=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
sl@0
  1459
				stretchmap.NextStep(coordmap);
sl@0
  1460
				fourth=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
sl@0
  1461
				stretchmap.NextStep(coordmap);
sl@0
  1462
				fifth=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
sl@0
  1463
				stretchmap.NextStep(coordmap);
sl@0
  1464
				sixth=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
sl@0
  1465
				stretchmap.NextStep(coordmap);
sl@0
  1466
				seventh=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
sl@0
  1467
				stretchmap.NextStep(coordmap);
sl@0
  1468
				eighth=HashTo1bpp(GetGrayPixelEx(coordmap.iX,slptr),oddx,oddy);
sl@0
  1469
				*bufptr++=TUint8(first|(second<<1)|(third<<2)|(fourth<<3)|
sl@0
  1470
					(fifth<<4)|(sixth<<5)|(seventh<<6)|(eighth<<7));
sl@0
  1471
				stretchmap.NextStep(coordmap);
sl@0
  1472
				oddx^=1;
sl@0
  1473
				}
sl@0
  1474
			break;
sl@0
  1475
			}
sl@0
  1476
		default:
sl@0
  1477
			Panic(EFbsBitmapInvalidMode);
sl@0
  1478
		}
sl@0
  1479
	}