cOMS/Image/Bitmap.h
Dennis Eichhorn 4ed50a08bc
Some checks failed
CI / code-tests: ${{ matrix.os }} / ${{ matrix.platform }} (ubuntu-latest, x64) (push) Has been cancelled
CI / code-tests: ${{ matrix.os }} / ${{ matrix.platform }} (ubuntu-latest, x86) (push) Has been cancelled
CI / general_module_workflow_c (push) Has been cancelled
update
2024-06-08 13:49:05 +02:00

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