mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-25 17:28:39 +00:00
234 lines
8.0 KiB
C++
234 lines
8.0 KiB
C++
/**
|
|
* Jingga
|
|
*
|
|
* @package Image
|
|
* @copyright Dennis Eichhorn
|
|
* @license OMS License 1.0
|
|
* @version 1.0.0
|
|
* @link https://jingga.app
|
|
*/
|
|
#ifndef IMAGE_BITMAP_H
|
|
#define IMAGE_BITMAP_H
|
|
|
|
#include "../Stdlib/Types.h"
|
|
|
|
namespace Image
|
|
{
|
|
#define BITMAP_HEADER_SIZE 14
|
|
struct BitmapHeader {
|
|
byte identifier[2]; // 2 bytes - bitmap identifier
|
|
uint32 size; // 4 bytes - size in bytes
|
|
byte app_data[4]; // 4 bytes - generated by the image software
|
|
uint32 offset; // 4 bytes - defines starting address for pixels
|
|
};
|
|
|
|
#define DIB_BITMAP_TYPE_BITMAPCOREHEADER 12
|
|
struct DIB_BITMAPCOREHEADER {
|
|
uint32 size;
|
|
uint16 width;
|
|
uint16 height;
|
|
uint16 color_planes;
|
|
uint16 bits_per_pixel;
|
|
};
|
|
|
|
#define DIB_BITMAP_TYPE_OS21XBITMAPHEADER DIB_BITMAP_TYPE_BITMAPCOREHEADER
|
|
#define DIB_OS21XBITMAPHEADER DIB_BITMAPCOREHEADER
|
|
|
|
#define DIB_BITMAP_TYPE_OS22XBITMAPHEADER 64
|
|
struct DIB_OS22XBITMAPHEADER {
|
|
// @todo implement
|
|
// They don't use a size as first value? how do I know if this is the correct header?
|
|
};
|
|
|
|
#define DIB_BITMAP_TYPE_BITMAPINFOHEADER 40
|
|
struct DIB_BITMAPINFOHEADER {
|
|
uint32 size;
|
|
int32 width;
|
|
int32 height;
|
|
uint16 color_planes;
|
|
uint16 bits_per_pixel;
|
|
uint32 compression_method;
|
|
uint32 raw_image_size;
|
|
//int32 horizontal_ppm;
|
|
//int32 vertical_ppm;
|
|
uint32 color_palette;
|
|
uint32 important_colors;
|
|
};
|
|
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RGB 0x0000
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RLE8 0x0001
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RLE4 0x0002
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_BITFIELDS 0x0003
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_JPEG 0x0004
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_PNG 0x0005
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_ALPHABITFIELDS 0x0006
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_CMYK 0x000B
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_CMYKRLE8 0x000C
|
|
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_CMYKRLE4 0x000D
|
|
|
|
#define DIB_BITMAPINFOHEADER_HALFTONING_NONE 0
|
|
#define DIB_BITMAPINFOHEADER_HALFTONING_ERROR_DIFFUSION 1
|
|
#define DIB_BITMAPINFOHEADER_HALFTONING_PANDA 2
|
|
#define DIB_BITMAPINFOHEADER_HALFTONING_SUPER_CIRCLE 3
|
|
|
|
#define DIB_BITMAP_TYPE_BITMAPV2INFOHEADER 52
|
|
struct DIB_BITMAPV2INFOHEADER {
|
|
|
|
};
|
|
|
|
#define DIB_BITMAP_TYPE_BITMAPV3INFOHEADER 56
|
|
struct DIB_BITMAPV3INFOHEADER {
|
|
|
|
};
|
|
|
|
struct CIEXYZ {
|
|
int32 ciexyzX;
|
|
int32 ciexyzY;
|
|
int32 ciexyzZ;
|
|
};
|
|
|
|
struct CIEXYZTRIPLE {
|
|
CIEXYZ ciexyzRed;
|
|
CIEXYZ ciexyzGreen;
|
|
CIEXYZ ciexyzBlue;
|
|
};
|
|
|
|
#define DIB_BITMAP_TYPE_BITMAPV4HEADER 108
|
|
struct DIB_BITMAPV4HEADER {
|
|
int32 size;
|
|
int32 width;
|
|
int32 height;
|
|
uint16 color_planes;
|
|
uint16 bits_per_pixel;
|
|
int32 compression_method;
|
|
int32 raw_image_size;
|
|
//int32 horizontal_ppm;
|
|
//int32 vertical_ppm;
|
|
uint32 color_palette;
|
|
uint32 important_colors;
|
|
|
|
int32 bV4RedMask;
|
|
int32 bV4GreenMask;
|
|
int32 bV4BlueMask;
|
|
int32 bV4AlphaMask;
|
|
int32 bV4CSType;
|
|
CIEXYZTRIPLE bV4Endpoints;
|
|
int32 bV4GammaRed;
|
|
int32 bV4GammaGreen;
|
|
int32 bV4GammaBlue;
|
|
};
|
|
|
|
#define DIB_BITMAP_TYPE_BITMAPV5HEADER 124
|
|
struct DIB_BITMAPV5HEADER {
|
|
int32 size;
|
|
int32 width;
|
|
int32 height;
|
|
uint16 color_planes;
|
|
uint16 bits_per_pixel;
|
|
int32 compression_method;
|
|
int32 raw_image_size;
|
|
//int32 horizontal_ppm;
|
|
//int32 vertical_ppm;
|
|
uint32 color_palette;
|
|
uint32 important_colors;
|
|
|
|
int32 bV5RedMask;
|
|
int32 bV5GreenMask;
|
|
int32 bV5BlueMask;
|
|
int32 bV5AlphaMask;
|
|
int32 bV5CSType;
|
|
CIEXYZTRIPLE bV5Endpoints;
|
|
int32 bV5GammaRed;
|
|
int32 bV5GammaGreen;
|
|
int32 bV5GammaBlue;
|
|
int32 bV5Intent;
|
|
int32 bV5ProfileData;
|
|
int32 bV5ProfileSize;
|
|
int32 bV5Reserved;
|
|
};
|
|
|
|
struct Bitmap {
|
|
BitmapHeader header;
|
|
byte dib_header_type;
|
|
DIB_BITMAPINFOHEADER dib_header; // Despite the different header types we use this one for simplicity
|
|
uint32* extra_bit_mask; // 3-4 = 12-16 bytes
|
|
byte color_table_size;
|
|
byte* color_table;
|
|
|
|
// Pixels are stored in rows
|
|
// Rows are padded in multiples of 4 bytes
|
|
byte* pixels;
|
|
|
|
byte* data;
|
|
};
|
|
|
|
Bitmap generate_bitmap_references(byte* data)
|
|
{
|
|
Bitmap bitmap = {};
|
|
|
|
// Fill header
|
|
bitmap.header.identifier[0] = *(data + 0);
|
|
bitmap.header.identifier[1] = *(data + 1);
|
|
|
|
bitmap.header.size = *((uint32 *) (data + 2));
|
|
bitmap.header.app_data[0] = *(data + 6);
|
|
bitmap.header.app_data[1] = *(data + 7);
|
|
bitmap.header.app_data[2] = *(data + 8);
|
|
bitmap.header.app_data[3] = *(data + 9);
|
|
bitmap.header.offset = *((uint32 *) (data + 10));
|
|
|
|
byte* dib_header_offset = data + BITMAP_HEADER_SIZE;
|
|
bitmap.dib_header_type = *dib_header_offset;
|
|
|
|
byte* color_table_offset = data + BITMAP_HEADER_SIZE + bitmap.dib_header_type;
|
|
|
|
// Fill DIB header
|
|
switch(bitmap.dib_header_type) {
|
|
case DIB_BITMAP_TYPE_BITMAPCOREHEADER: {
|
|
bitmap.dib_header.size = *((uint32 *) (dib_header_offset));
|
|
bitmap.dib_header.width = *((uint16 *) (dib_header_offset + 4));
|
|
bitmap.dib_header.height = *((uint16 *) (dib_header_offset + 6));
|
|
bitmap.dib_header.color_planes = *((uint16 *) (dib_header_offset + 8));
|
|
bitmap.dib_header.bits_per_pixel = *((uint16 *) (dib_header_offset + 10));
|
|
bitmap.dib_header.color_palette = 1U << bitmap.dib_header.bits_per_pixel;
|
|
} break;
|
|
case DIB_BITMAP_TYPE_BITMAPV5HEADER:
|
|
case DIB_BITMAP_TYPE_BITMAPV4HEADER:
|
|
case DIB_BITMAP_TYPE_BITMAPV3INFOHEADER:
|
|
case DIB_BITMAP_TYPE_BITMAPV2INFOHEADER:
|
|
case DIB_BITMAP_TYPE_BITMAPINFOHEADER: {
|
|
bitmap.dib_header.size = *((uint32 *) (dib_header_offset));
|
|
bitmap.dib_header.width = *((int32 *) (dib_header_offset + 4));
|
|
bitmap.dib_header.height = *((int32 *) (dib_header_offset + 8));
|
|
bitmap.dib_header.color_planes = *((uint16 *) (dib_header_offset + 12));
|
|
bitmap.dib_header.bits_per_pixel = *((uint16 *) (dib_header_offset + 14));
|
|
bitmap.dib_header.compression_method = *((uint32 *) (dib_header_offset + 16));
|
|
bitmap.dib_header.raw_image_size = *((uint32 *) (dib_header_offset + 20));
|
|
bitmap.dib_header.color_palette = *((uint32 *) (dib_header_offset + 32));
|
|
bitmap.dib_header.important_colors = *((uint32 *) (dib_header_offset + 36));
|
|
|
|
if (bitmap.dib_header.compression_method == DIB_BITMAPINFOHEADER_COMPRESSION_BI_BITFIELDS) {
|
|
// 12 bytes
|
|
bitmap.extra_bit_mask = (uint32 *) (dib_header_offset + DIB_BITMAP_TYPE_BITMAPINFOHEADER);
|
|
color_table_offset += 12;
|
|
} else if (bitmap.dib_header.compression_method == DIB_BITMAPINFOHEADER_COMPRESSION_BI_ALPHABITFIELDS) {
|
|
// 16 bytes
|
|
bitmap.extra_bit_mask = (uint32 *) (dib_header_offset + DIB_BITMAP_TYPE_BITMAPINFOHEADER);
|
|
color_table_offset += 16;
|
|
}
|
|
} break;
|
|
default: {
|
|
|
|
}
|
|
}
|
|
|
|
// Fill other
|
|
bitmap.color_table = color_table_offset;
|
|
bitmap.pixels = (byte *) (data + bitmap.header.offset);
|
|
bitmap.data = data;
|
|
|
|
return bitmap;
|
|
}
|
|
}
|
|
|
|
#endif |