os/kernelhwsrv/kerneltest/e32test/multimedia/t_camera_bitmap.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) 2008-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 the License "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
// e32test/multimedia/t_camera_bitmap.cpp
sl@0
    15
// This is a basic Windows bitmap file writer, that can be used for converting YUV422 data into
sl@0
    16
// RGB format and dumping it to a Windows .bmp file, for manual examination.
sl@0
    17
// 
sl@0
    18
//
sl@0
    19
sl@0
    20
#include <e32test.h>
sl@0
    21
#include <f32file.h>
sl@0
    22
#include "t_camera_bitmap.h"
sl@0
    23
sl@0
    24
#define CLIP(a) if (a < 0) a = 0; else if (a > 255) a = 255;
sl@0
    25
sl@0
    26
/**
sl@0
    27
Converts a RGB565 buffer into 24 bit RGB format in a second buffer.
sl@0
    28
@param	aDest		Pointer to the buffer into which to place the 24 bit RGB data
sl@0
    29
@param	aSource		Pointer to the buffer containing the RGB565 data to be converted
sl@0
    30
@param	aWidth		The width of the data in the buffer in pixels
sl@0
    31
@param	aHeight		The height of the data in the buffer in pixels
sl@0
    32
*/
sl@0
    33
void RBitmap::RGBToRGB(TUint8* aDest, TUint8* aSource, TInt aWidth, TInt aHeight)
sl@0
    34
	{
sl@0
    35
	TUint16* source = (TUint16*) aSource;
sl@0
    36
	TUint16 pixel;
sl@0
    37
sl@0
    38
	for (TInt y = 0; y < aHeight; ++y)
sl@0
    39
		{
sl@0
    40
		for (TInt x = 0; x < aWidth; ++x)
sl@0
    41
			{
sl@0
    42
			pixel = *source++;
sl@0
    43
			*aDest++ = (TUint8) ((pixel & 0xf800) >> 8);
sl@0
    44
			*aDest++ = (TUint8) ((pixel & 0x07e0) >> 3);
sl@0
    45
			*aDest++ = (TUint8) ((pixel & 0x001f) << 3);
sl@0
    46
			}
sl@0
    47
		}
sl@0
    48
	}
sl@0
    49
sl@0
    50
/**
sl@0
    51
Converts a YUV422 buffer into 24 bit RGB format in a second buffer.
sl@0
    52
@param	aDest		Pointer to the buffer into which to place the 24 bit RGB data
sl@0
    53
@param	aSource		Pointer to the buffer containing the YUV422 data to be converted
sl@0
    54
@param	aWidth		The width of the data in the buffer in pixels
sl@0
    55
@param	aHeight		The height of the data in the buffer in pixels
sl@0
    56
*/
sl@0
    57
void RBitmap::YUVToRGB(TUint8* aDest, TUint8* aSource, TInt aWidth, TInt aHeight)
sl@0
    58
	{
sl@0
    59
	TInt y, u, v, r, g, b;
sl@0
    60
sl@0
    61
	aDest += ((aWidth * 3) * (aHeight - 1));
sl@0
    62
sl@0
    63
	for (TInt l = 0; l < aHeight; ++l)
sl@0
    64
		{
sl@0
    65
		for (TInt x = 0; x < (aWidth / 2); ++x)
sl@0
    66
			{
sl@0
    67
			u = (aSource[0] - 128);
sl@0
    68
			v = (aSource[2] - 128);
sl@0
    69
			y = (aSource[3] - 16);
sl@0
    70
sl@0
    71
			r = ((298 * y + 409 * u) / 256);
sl@0
    72
			g = ((298 * y - 100 * v - 208 * u) / 256);
sl@0
    73
			b = ((298 * y + 516 * v) / 256);
sl@0
    74
sl@0
    75
			CLIP(r);
sl@0
    76
			CLIP(g);
sl@0
    77
			CLIP(b);
sl@0
    78
sl@0
    79
			*aDest++ = (TUint8) r;
sl@0
    80
			*aDest++ = (TUint8) g;
sl@0
    81
			*aDest++ = (TUint8) b;
sl@0
    82
sl@0
    83
			y = (aSource[1] - 16);
sl@0
    84
sl@0
    85
			r = ((298 * y + 409 * u) / 256);
sl@0
    86
			g = ((298 * y - 100 * v - 208 * u) / 256);
sl@0
    87
			b = ((298 * y + 516 * v) / 256);
sl@0
    88
sl@0
    89
			CLIP(r);
sl@0
    90
			CLIP(g);
sl@0
    91
			CLIP(b);
sl@0
    92
sl@0
    93
			*aDest++ = (TUint8) r;
sl@0
    94
			*aDest++ = (TUint8) g;
sl@0
    95
			*aDest++ = (TUint8) b;
sl@0
    96
			aSource += 4;
sl@0
    97
			}
sl@0
    98
sl@0
    99
		aDest -= (aWidth * 3 * 2);
sl@0
   100
		}
sl@0
   101
	}
sl@0
   102
sl@0
   103
/**
sl@0
   104
Converts a 32 bit long from whatever the host format is into little endian format in a user supplied buffer.
sl@0
   105
@param	aBuffer		Pointer to the buffer into which to write the value
sl@0
   106
@param	aLong		The value to be written
sl@0
   107
*/
sl@0
   108
void RBitmap::PutLong(TUint8* aBuffer, TInt aLong)
sl@0
   109
	{
sl@0
   110
	*aBuffer++ = (TUint8) (aLong & 0xff);
sl@0
   111
	*aBuffer++ = (TUint8) ((aLong >> 8) & 0xff);
sl@0
   112
	*aBuffer++ = (TUint8) ((aLong >> 16) & 0xff);
sl@0
   113
	*aBuffer++ = (TUint8) ((aLong >> 24) & 0xff);
sl@0
   114
	}
sl@0
   115
sl@0
   116
/**
sl@0
   117
Converts a 16 bit short from whatever the host format is into little endian format in a user supplied buffer.
sl@0
   118
@param	aBuffer		Pointer to the buffer into which to write the value
sl@0
   119
@param	aShort		The value to be written
sl@0
   120
*/
sl@0
   121
void RBitmap::PutShort(TUint8* aBuffer, TInt16 aShort)
sl@0
   122
	{
sl@0
   123
	*aBuffer++ = (TUint8) (aShort & 0xff);
sl@0
   124
	*aBuffer++ = (TUint8) ((aShort >> 8) & 0xff);
sl@0
   125
	}
sl@0
   126
sl@0
   127
/**
sl@0
   128
Writes a standard Windows .bmp header to a file, including the standard .bmp file header, followed
sl@0
   129
by a V3 DIB header.
sl@0
   130
@param	aFile		A reference to the file to which to write the header
sl@0
   131
@param	aWidth		The width of the bitmap in pixels
sl@0
   132
@param	aHeight		The height of the bitmap in pixels
sl@0
   133
@return	KErrNone if write was successful, otherwise one of the other system wide error codes
sl@0
   134
*/
sl@0
   135
TInt RBitmap::WriteHeader(RFile& aFile, TInt aWidth, TInt aHeight)
sl@0
   136
	{
sl@0
   137
	TBuf8<14> header(14);
sl@0
   138
	TUint8* buffer = (TUint8*) header.Ptr();
sl@0
   139
sl@0
   140
	header.Fill(0);
sl@0
   141
sl@0
   142
	header[0] = 'B';
sl@0
   143
	header[1] = 'M';
sl@0
   144
	PutLong((buffer + 2), (14 + 40 + (aWidth * aHeight * 3)));
sl@0
   145
	PutLong((buffer + 10), (14 + 40));
sl@0
   146
sl@0
   147
	TInt r = aFile.Write(header);
sl@0
   148
sl@0
   149
	if (r == KErrNone)
sl@0
   150
		{
sl@0
   151
		TBuf8<40> bitmapInfoHeader(40);
sl@0
   152
		TUint8* buffer = (TUint8*) bitmapInfoHeader.Ptr();
sl@0
   153
sl@0
   154
		bitmapInfoHeader.Fill(0);
sl@0
   155
sl@0
   156
		PutLong(buffer, 40);
sl@0
   157
		PutLong((buffer + 4), aWidth);
sl@0
   158
		PutLong((buffer + 8), aHeight);
sl@0
   159
		PutShort((buffer + 12), 1);
sl@0
   160
		PutShort((buffer + 14), 24);
sl@0
   161
		PutLong((buffer + 20), (aWidth * aHeight * 3));
sl@0
   162
sl@0
   163
		r = aFile.Write(bitmapInfoHeader);
sl@0
   164
		}
sl@0
   165
sl@0
   166
	return r;
sl@0
   167
	}
sl@0
   168
sl@0
   169
/**
sl@0
   170
Converts a YUV422 or RGB565 buffer into 24 bit RGB format and writes it to a file.
sl@0
   171
@param	aFile			A reference to the file to which to write the data
sl@0
   172
@param	aBuffer			A pointer to the buffer containing the data to be converted and written
sl@0
   173
@param	aPixelFormat	UID specifying the format of the source data
sl@0
   174
@param	aWidth			The width of the data in the buffer in pixels
sl@0
   175
@param	aHeight			The height of the data in the buffer in pixels
sl@0
   176
@return	KErrNone if write was successful, otherwise one of the other system wide error codes
sl@0
   177
*/
sl@0
   178
TInt RBitmap::WriteBitmapData(RFile& aFile, TUint8* aBuffer, SDevCamPixelFormat aPixelFormat, TInt aWidth, TInt aHeight)
sl@0
   179
	{
sl@0
   180
	TInt length = (aWidth * aHeight * 3);
sl@0
   181
	TUint8* rgbBuffer = new TUint8[length];
sl@0
   182
sl@0
   183
	TInt r = KErrNone;
sl@0
   184
sl@0
   185
	if (rgbBuffer)
sl@0
   186
		{
sl@0
   187
		if (aPixelFormat.iPixelFormat == EUidPixelFormatYUV_422Interleaved)
sl@0
   188
			{
sl@0
   189
			YUVToRGB(rgbBuffer, aBuffer, aWidth, aHeight);
sl@0
   190
			}
sl@0
   191
		else if (aPixelFormat.iPixelFormat == EUidPixelFormatRGB_565)
sl@0
   192
			{
sl@0
   193
			RGBToRGB(rgbBuffer, aBuffer, aWidth, aHeight);
sl@0
   194
			}
sl@0
   195
		else
sl@0
   196
			{
sl@0
   197
			r = KErrNotSupported;
sl@0
   198
			}
sl@0
   199
sl@0
   200
		if (r == KErrNone)
sl@0
   201
			{
sl@0
   202
			TPtr8 buffer(rgbBuffer, length, length);
sl@0
   203
			r = aFile.Write(buffer);
sl@0
   204
			}
sl@0
   205
sl@0
   206
		delete [] rgbBuffer;
sl@0
   207
		}
sl@0
   208
	else
sl@0
   209
		{
sl@0
   210
		r = KErrNoMemory;
sl@0
   211
		}
sl@0
   212
sl@0
   213
	return r;
sl@0
   214
	}
sl@0
   215
sl@0
   216
/**
sl@0
   217
Converts a YUV422 or RGB565 buffer into 24 bit RGB format and writes it to a Windows .bmp file.
sl@0
   218
@param	aFileName		A reference to the fully qualified name of the file to write the .bmp file to
sl@0
   219
@param	aBuffer			A pointer to the buffer containing the data to be converted and written
sl@0
   220
@param	aPixelFormat	UID specifying the format of the source data
sl@0
   221
@param	aWidth			The width of the data in the buffer in pixels
sl@0
   222
@param	aHeight			The height of the data in the buffer in pixels
sl@0
   223
@return	KErrNone if write was successful, otherwise one of the other system wide error codes
sl@0
   224
*/
sl@0
   225
TInt RBitmap::WriteBMP(const TDesC& aFileName, TUint8* aBuffer, SDevCamPixelFormat aPixelFormat, TInt aWidth, TInt aHeight)
sl@0
   226
	{
sl@0
   227
	TInt r;
sl@0
   228
	RFile file;
sl@0
   229
	RFs fs;
sl@0
   230
sl@0
   231
	if ((r = fs.Connect()) == KErrNone)
sl@0
   232
		{
sl@0
   233
		if ((r = file.Replace(fs, aFileName, EFileWrite)) == KErrNone)
sl@0
   234
			{
sl@0
   235
			if ((r = WriteHeader(file, aWidth, aHeight)) == KErrNone)
sl@0
   236
				{
sl@0
   237
				r = WriteBitmapData(file, aBuffer, aPixelFormat, aWidth, aHeight);
sl@0
   238
				}
sl@0
   239
sl@0
   240
			file.Close();
sl@0
   241
sl@0
   242
			// If anything went wrong, delete the file so that we do not leave partial files that
sl@0
   243
			// might cause confusion
sl@0
   244
			if (r != KErrNone)
sl@0
   245
				{
sl@0
   246
				fs.Delete(aFileName);
sl@0
   247
				}
sl@0
   248
			}
sl@0
   249
sl@0
   250
		fs.Close();
sl@0
   251
		}
sl@0
   252
sl@0
   253
	return r;
sl@0
   254
	}
sl@0
   255
sl@0
   256
/**
sl@0
   257
Dumps a buffer straight to disk, without any kind of processing.
sl@0
   258
@param	aFileName		A reference to the fully qualified name of the file to write the file to
sl@0
   259
@param	aBuffer			A pointer to the buffer containing the data to be converted written
sl@0
   260
@param	aSize			The size of the buffer to be written, in bytes
sl@0
   261
@return	KErrNone if write was successful, otherwise one of the other system wide error codes
sl@0
   262
*/
sl@0
   263
TInt RBitmap::WriteBuffer(const TDesC& aFileName, TUint8* aBuffer, TInt aSize)
sl@0
   264
	{
sl@0
   265
	TInt r;
sl@0
   266
	RFile file;
sl@0
   267
	RFs fs;
sl@0
   268
sl@0
   269
	if ((r = fs.Connect()) == KErrNone)
sl@0
   270
		{
sl@0
   271
		if ((r = file.Replace(fs, aFileName, EFileWrite)) == KErrNone)
sl@0
   272
			{
sl@0
   273
			TPtrC8 buffer(aBuffer, aSize);
sl@0
   274
sl@0
   275
			r = file.Write(buffer);
sl@0
   276
sl@0
   277
			file.Close();
sl@0
   278
sl@0
   279
			// If anything went wrong, delete the file so that we do not leave partial files that
sl@0
   280
			// might cause confusion
sl@0
   281
			if (r != KErrNone)
sl@0
   282
				{
sl@0
   283
				fs.Delete(aFileName);
sl@0
   284
				}
sl@0
   285
			}
sl@0
   286
sl@0
   287
		fs.Close();
sl@0
   288
		}
sl@0
   289
sl@0
   290
	return r;
sl@0
   291
	}