build: Adding support for choice of USB library to configure
[barry.git] / src / bmp.cc
blob3988572f8df7f079da450e51662ec095b0024a1d
1 ///
2 /// \file bmp.cc
3 /// BMP conversion routines
4 ///
6 /*
7 Copyright (C) 2009-2011, 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.
23 #include "bmp.h"
24 #include "bmp-internal.h"
25 #include "error.h"
26 #include "endian.h"
27 #include "data.h"
28 #include "m_javaloader.h"
30 namespace Barry {
33 // GetTotalBitmapSize
35 /// Returns the total number of bytes needed to convert a
36 /// screenshot of the given dimensions into a bitmap,
37 /// using the ScreenshotToBitmap() function.
38 ///
39 BXEXPORT size_t GetTotalBitmapSize(const JLScreenInfo &info)
41 return sizeof(bmp_file_header_t) +
42 sizeof(bmp_info_header_t) +
43 (info.width * info.height * 4); // 4 byte RGB per pixel
48 // ScreenshotToBitmap
50 /// Converts screenshot data obtained via JavaLoader::GetScreenshot()
51 /// into uncompressed bitmap format, suitable for writing BMP files.
52 /// Arguments info and screenshot come from GetScreenshot() and the
53 /// converted data is stored in bitmap.
54 ///
56 // This function assumes that the btoh() converter functions match
57 // the needs of the bitmap file format. Namely: little endian.
59 BXEXPORT void ScreenshotToBitmap(const JLScreenInfo &info,
60 const Data &screenshot,
61 Data &bitmap)
63 // Read screen info
64 size_t width = info.width;
65 size_t height = info.height;
66 size_t total_bitmap_size = GetTotalBitmapSize(info);
68 // make sure there is enough screeshot pixel data for the
69 // given width and height
70 if( screenshot.GetSize() < (width * height * 2) ) // 2 byte screenshot pixel data
71 throw Error("Screenshot data size is too small for given width+height");
74 // setup write pointer
75 unsigned char *write = bitmap.GetBuffer(total_bitmap_size);
78 // Build header BMP file
80 bmp_file_header_t *fileheader = (bmp_file_header_t*) write;
81 write += sizeof(bmp_file_header_t);
83 // BMP
84 fileheader->bfType[0] = 'B';
85 fileheader->bfType[1] = 'M';
87 // Size of file
88 fileheader->bfSize = btohl(total_bitmap_size);
90 // Always 0x00
91 fileheader->bfReserved1 = 0;
92 fileheader->bfReserved2 = 0;
94 // Offset to find the data
95 fileheader->bfOffBits = btohl(sizeof(bmp_file_header_t) + sizeof(bmp_info_header_t));
99 // Build info BMP file
101 bmp_info_header_t *infoheader = (bmp_info_header_t*) write;
102 write += sizeof(bmp_info_header_t);
104 // Size of info section
105 infoheader->biSize = btohl(sizeof(bmp_info_header_t));
107 // Width x Height
108 infoheader->biWidth = btohl(width);
109 infoheader->biHeight = btohl(height);
111 // Planes number
112 infoheader->biPlanes = btohs(0x01);
114 // Bit count
115 infoheader->biBitCount = btohs(0x20);
117 // Compression : No
118 infoheader->biCompression = 0;
120 // Size of image
121 infoheader->biSizeImage = btohl(4 * width * height);
123 // Pels Per Meter
124 infoheader->biXPelsPerMeter = 0;
125 infoheader->biYPelsPerMeter = 0;
127 // Color palette used : None
128 infoheader->biClrUsed = 0;
130 // Color palette important : None
131 infoheader->biClrImportant = 0;
134 // I work with 2 bytes (see the pixel format)
135 const uint16_t *data = (const uint16_t*) screenshot.GetData();
136 size_t pixel_count = width * height;
138 // For each pixel... (note BMP format is up and backwards, hence
139 // offset calculation for each pixel in for loop)
140 for (size_t j=0; j<height; j++) {
141 for (size_t i=0; i<width; i++) {
142 // Read one pixel in the picture
143 short value = data[(pixel_count - 1) - ((width-1 - i) + (width * j))];
145 // Pixel format used by the handheld is : 16 bits
146 // MSB < .... .... .... .... > LSB
147 // ^^^^^^ : Blue (between 0x00 and 0x1F)
148 // ^^^^^^^ : Green (between 0x00 and 0x3F)
149 // ^^^^^^ : Red (between 0x00 and 0x1F)
151 write[3] = 0x00; // alpha
152 write[2] = (((value >> 11) & 0x1F) * 0xFF) / 0x1F; // red
153 write[1] = (((value >> 5) & 0x3F) * 0xFF) / 0x3F; // green
154 write[0] = ((value & 0x1F) * 0xFF) / 0x1F; // blue
156 write += 4;
160 bitmap.ReleaseBuffer(total_bitmap_size);
163 } // namespace Barry