bmp.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       bmp.cc
00003 ///             BMP conversion routines
00004 ///
00005 
00006 /*
00007     Copyright (C) 2009-2011, Net Direct Inc. (http://www.netdirect.ca/)
00008     Copyright (C) 2008-2009, Nicolas VIVIEN
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 
00019     See the GNU General Public License in the COPYING file at the
00020     root directory of this project for more details.
00021 */
00022 
00023 #include "bmp.h"
00024 #include "bmp-internal.h"
00025 #include "error.h"
00026 #include "endian.h"
00027 
00028 namespace Barry {
00029 
00030 //
00031 // GetTotalBitmapSize
00032 //
00033 /// Returns the total number of bytes needed to convert a
00034 /// screenshot of the given dimensions into a bitmap,
00035 /// using the ScreenshotToBitmap() function.
00036 ///
00037 BXEXPORT size_t GetTotalBitmapSize(const JLScreenInfo &info)
00038 {
00039         return sizeof(bmp_file_header_t) +
00040                 sizeof(bmp_info_header_t) +
00041                 (info.width * info.height * 4); // 4 byte RGB per pixel
00042 
00043 }
00044 
00045 //
00046 // ScreenshotToBitmap
00047 //
00048 /// Converts screenshot data obtained via JavaLoader::GetScreenshot()
00049 /// into uncompressed bitmap format, suitable for writing BMP files.
00050 /// Arguments info and screenshot come from GetScreenshot() and the
00051 /// converted data is stored in bitmap.
00052 ///
00053 //
00054 // This function assumes that the btoh() converter functions match
00055 // the needs of the bitmap file format.  Namely: little endian.
00056 //
00057 BXEXPORT void ScreenshotToBitmap(const JLScreenInfo &info,
00058                                  const Data &screenshot,
00059                                  Data &bitmap)
00060 {
00061         // Read screen info
00062         size_t width = info.width;
00063         size_t height = info.height;
00064         size_t total_bitmap_size = GetTotalBitmapSize(info);
00065 
00066         // make sure there is enough screeshot pixel data for the
00067         // given width and height
00068         if( screenshot.GetSize() < (width * height * 2) ) // 2 byte screenshot pixel data
00069                 throw Error("Screenshot data size is too small for given width+height");
00070 
00071 
00072         // setup write pointer
00073         unsigned char *write = bitmap.GetBuffer(total_bitmap_size);
00074 
00075         //
00076         // Build header BMP file
00077         //
00078         bmp_file_header_t *fileheader = (bmp_file_header_t*) write;
00079         write += sizeof(bmp_file_header_t);
00080 
00081         // BMP
00082         fileheader->bfType[0] = 'B';
00083         fileheader->bfType[1] = 'M';
00084 
00085         // Size of file
00086         fileheader->bfSize = btohl(total_bitmap_size);
00087 
00088         // Always 0x00
00089         fileheader->bfReserved1 = 0;
00090         fileheader->bfReserved2 = 0;
00091 
00092         // Offset to find the data
00093         fileheader->bfOffBits = btohl(sizeof(bmp_file_header_t) + sizeof(bmp_info_header_t));
00094 
00095 
00096         //
00097         // Build info BMP file
00098         //
00099         bmp_info_header_t *infoheader = (bmp_info_header_t*) write;
00100         write += sizeof(bmp_info_header_t);
00101 
00102         // Size of info section
00103         infoheader->biSize = btohl(sizeof(bmp_info_header_t));
00104 
00105         // Width x Height
00106         infoheader->biWidth = btohl(width);
00107         infoheader->biHeight = btohl(height);
00108 
00109         // Planes number
00110         infoheader->biPlanes = btohs(0x01);
00111 
00112         // Bit count
00113         infoheader->biBitCount = btohs(0x20);
00114 
00115         // Compression : No
00116         infoheader->biCompression = 0;
00117 
00118         // Size of image
00119         infoheader->biSizeImage = btohl(4 * width * height);
00120 
00121         // Pels Per Meter
00122         infoheader->biXPelsPerMeter = 0;
00123         infoheader->biYPelsPerMeter = 0;
00124 
00125         // Color palette used : None
00126         infoheader->biClrUsed = 0;
00127 
00128         // Color palette important : None
00129         infoheader->biClrImportant = 0;
00130 
00131 
00132         // I work with 2 bytes (see the pixel format)
00133         const uint16_t *data = (const uint16_t*) screenshot.GetData();
00134         size_t pixel_count = width * height;
00135 
00136         // For each pixel... (note BMP format is up and backwards, hence
00137         // offset calculation for each pixel in for loop)
00138         for (size_t j=0; j<height; j++) {
00139                 for (size_t i=0; i<width; i++) {
00140                         // Read one pixel in the picture
00141                         short value = data[(pixel_count - 1) - ((width-1 - i) + (width * j))];
00142 
00143                         // Pixel format used by the handheld is : 16 bits
00144                         // MSB < .... .... .... .... > LSB
00145                         //                    ^^^^^^ : Blue (between 0x00 and 0x1F)
00146                         //             ^^^^^^^ : Green (between 0x00 and 0x3F)
00147                         //       ^^^^^^ : Red (between 0x00 and 0x1F)
00148 
00149                         write[3] = 0x00;                                        // alpha
00150                         write[2] = (((value >> 11) & 0x1F) * 0xFF) / 0x1F;      // red
00151                         write[1] = (((value >> 5) & 0x3F) * 0xFF) / 0x3F;       // green
00152                         write[0] = ((value & 0x1F) * 0xFF) / 0x1F;              // blue
00153 
00154                         write += 4;
00155                 }
00156         }
00157 
00158         bitmap.ReleaseBuffer(total_bitmap_size);
00159 }
00160 
00161 } // namespace Barry
00162 

Generated on Tue Mar 1 17:50:14 2011 for Barry by  doxygen 1.5.6