3 /// BMP conversion routines
7 Copyright (C) 2009-2010, Net Direct Inc. (http://www.netdirect.ca/)
8 Copyright (C) 2008-2009, Nicolas VIVIEN
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
24 #include "bmp-internal.h"
33 /// Returns the total number of bytes needed to convert a
34 /// screenshot of the given dimensions into a bitmap,
35 /// using the ScreenshotToBitmap() function.
37 BXEXPORT
size_t GetTotalBitmapSize(const JLScreenInfo
&info
)
39 return sizeof(bmp_file_header_t
) +
40 sizeof(bmp_info_header_t
) +
41 (info
.width
* info
.height
* 4); // 4 byte RGB per pixel
48 /// Converts screenshot data obtained via JavaLoader::GetScreenshot()
49 /// into uncompressed bitmap format, suitable for writing BMP files.
50 /// Arguments info and screenshot come from GetScreenshot() and the
51 /// converted data is stored in bitmap.
54 // This function assumes that the btoh() converter functions match
55 // the needs of the bitmap file format. Namely: little endian.
57 BXEXPORT
void ScreenshotToBitmap(const JLScreenInfo
&info
,
58 const Data
&screenshot
,
62 size_t width
= info
.width
;
63 size_t height
= info
.height
;
64 size_t total_bitmap_size
= GetTotalBitmapSize(info
);
66 // make sure there is enough screeshot pixel data for the
67 // given width and height
68 if( screenshot
.GetSize() < (width
* height
* 2) ) // 2 byte screenshot pixel data
69 throw Error("Screenshot data size is too small for given width+height");
72 // setup write pointer
73 unsigned char *write
= bitmap
.GetBuffer(total_bitmap_size
);
76 // Build header BMP file
78 bmp_file_header_t
*fileheader
= (bmp_file_header_t
*) write
;
79 write
+= sizeof(bmp_file_header_t
);
82 fileheader
->bfType
[0] = 'B';
83 fileheader
->bfType
[1] = 'M';
86 fileheader
->bfSize
= btohl(total_bitmap_size
);
89 fileheader
->bfReserved1
= 0;
90 fileheader
->bfReserved2
= 0;
92 // Offset to find the data
93 fileheader
->bfOffBits
= btohl(sizeof(bmp_file_header_t
) + sizeof(bmp_info_header_t
));
97 // Build info BMP file
99 bmp_info_header_t
*infoheader
= (bmp_info_header_t
*) write
;
100 write
+= sizeof(bmp_info_header_t
);
102 // Size of info section
103 infoheader
->biSize
= btohl(sizeof(bmp_info_header_t
));
106 infoheader
->biWidth
= btohl(width
);
107 infoheader
->biHeight
= btohl(height
);
110 infoheader
->biPlanes
= btohs(0x01);
113 infoheader
->biBitCount
= btohs(0x20);
116 infoheader
->biCompression
= 0;
119 infoheader
->biSizeImage
= btohl(4 * width
* height
);
122 infoheader
->biXPelsPerMeter
= 0;
123 infoheader
->biYPelsPerMeter
= 0;
125 // Color palette used : None
126 infoheader
->biClrUsed
= 0;
128 // Color palette important : None
129 infoheader
->biClrImportant
= 0;
132 // I work with 2 bytes (see the pixel format)
133 const uint16_t *data
= (const uint16_t*) screenshot
.GetData();
134 size_t pixel_count
= width
* height
;
136 // For each pixel... (note BMP format is up and backwards, hence
137 // offset calculation for each pixel in for loop)
138 for (size_t j
=0; j
<height
; j
++) {
139 for (size_t i
=0; i
<width
; i
++) {
140 // Read one pixel in the picture
141 short value
= data
[(pixel_count
- 1) - ((width
-1 - i
) + (width
* j
))];
143 // Pixel format used by the handheld is : 16 bits
144 // MSB < .... .... .... .... > LSB
145 // ^^^^^^ : Blue (between 0x00 and 0x1F)
146 // ^^^^^^^ : Green (between 0x00 and 0x3F)
147 // ^^^^^^ : Red (between 0x00 and 0x1F)
149 write
[3] = 0x00; // alpha
150 write
[2] = (((value
>> 11) & 0x1F) * 0xFF) / 0x1F; // red
151 write
[1] = (((value
>> 5) & 0x3F) * 0xFF) / 0x3F; // green
152 write
[0] = ((value
& 0x1F) * 0xFF) / 0x1F; // blue
158 bitmap
.ReleaseBuffer(total_bitmap_size
);