| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #include "CmBitmapWriter.h"
- #include "CmPixelData.h"
- namespace CamelotEngine
- {
- #pragma pack(push, 2) // Align to 2byte boundary so we don't get extra 2 bytes for this struct
- struct BMP_HEADER
- {
- UINT16 BM;
- UINT32 size_of_file;
- UINT32 reserve;
- UINT32 offset_of_pixel_data;
- UINT32 size_of_header;
- UINT32 width;
- UINT32 hight;
- UINT16 num_of_color_plane;
- UINT16 num_of_bit_per_pix;
- UINT32 compression;
- UINT32 size_of_pix_data;
- UINT32 h_resolution;
- UINT32 v_resolution;
- UINT32 num_of_color_in_palette;
- UINT32 important_colors;
- };
- #pragma pack(pop)
- void BitmapWriter::rawPixelsToBMP(const UINT8* input, UINT8* output, UINT32 width, UINT32 height, UINT32 bytesPerPixel)
- {
- UINT16 bmpBytesPerPixel = 3;
- if(bytesPerPixel >= 4)
- bmpBytesPerPixel = 4;
- UINT32 padding = (width * bmpBytesPerPixel) % 4;
- if(padding != 0)
- padding = 4 - padding;
- UINT32 rowPitch = (width * bmpBytesPerPixel) + padding;
- UINT32 dataSize = height * rowPitch;
- BMP_HEADER header;
- header.BM = 0x4d42;
- header.size_of_file = sizeof(header) + dataSize;
- header.reserve = 0000;
- header.offset_of_pixel_data = 54;
- header.size_of_header = 40;
- header.width = width;
- header.hight = height;
- header.num_of_color_plane = 1;
- header.num_of_bit_per_pix = bmpBytesPerPixel * 8;
- header.compression = 0;
- header.size_of_pix_data = dataSize;
- header.h_resolution = 2835;
- header.v_resolution = 2835;
- header.num_of_color_in_palette = 0;
- header.important_colors = 0;
- // Write header
- memcpy(output, &header, sizeof(header));
- output += sizeof(header);
- // Write bytes
- UINT32 widthBytes = width * bytesPerPixel;
-
- // BPP matches so we can just copy directly
- if(bmpBytesPerPixel == bytesPerPixel)
- {
- for(INT32 y = height - 1; y >= 0 ; y--)
- {
- UINT8* outputPtr = output + y * rowPitch;
- memcpy(outputPtr, input, widthBytes);
- memset(outputPtr + widthBytes, 0, padding);
- input += widthBytes;
- }
- }
- else if(bmpBytesPerPixel < bytesPerPixel) // More bytes in source than supported in BMP, just truncate excess data
- {
- for(INT32 y = height - 1; y >= 0 ; y--)
- {
- UINT8* outputPtr = output + y * rowPitch;
- for(UINT32 x = 0; x < width; x++)
- {
- memcpy(outputPtr, input, bmpBytesPerPixel);
- outputPtr += bmpBytesPerPixel;
- input += bytesPerPixel;
- }
- memset(outputPtr, 0, padding);
- }
- }
- else // More bytes in BMP than in source (BMP must be 24bit minimum)
- {
- for(INT32 y = height - 1; y >= 0 ; y--)
- {
- UINT8* outputPtr = output + y * rowPitch;
- for(UINT32 x = 0; x < width; x++)
- {
- memcpy(outputPtr, input, bytesPerPixel);
- // Fill the empty bytes with the last available byte from input
- UINT32 remainingBytes = bmpBytesPerPixel - bytesPerPixel;
- while(remainingBytes > 0)
- {
- memcpy(outputPtr + (bmpBytesPerPixel - remainingBytes), input, 1);
- remainingBytes--;
- }
- outputPtr += bmpBytesPerPixel;
- input += bytesPerPixel;
- }
- memset(outputPtr, 0, padding);
- }
- }
- }
- UINT32 BitmapWriter::getBMPSize(UINT32 width, UINT32 height, UINT32 bytesPerPixel)
- {
- UINT16 bmpBytesPerPixel = 3;
- if(bytesPerPixel >= 4)
- bmpBytesPerPixel = 4;
- UINT32 padding = (width * bmpBytesPerPixel) % 4;
- if(padding != 0)
- padding = 4 - padding;
- UINT32 rowPitch = (width * bmpBytesPerPixel) + padding;
- UINT32 dataSize = height * rowPitch;
- return sizeof(BMP_HEADER) + dataSize;
- }
- }
|