cleaned code, transparency now actually working
parent
83ab573efb
commit
5e8bab38f0
@ -1,2 +1,4 @@
|
||||
*.out
|
||||
*.o
|
||||
|
||||
*.bmp
|
@ -0,0 +1,91 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "images.h"
|
||||
|
||||
// write an int to a byte array
|
||||
void bmp__write_int(char* bytes, int num) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bytes[i] = num >> (i * 8);
|
||||
}
|
||||
}
|
||||
|
||||
void bmp__write_byte(char* bytes, int num) {
|
||||
bytes[0] = (char) num;
|
||||
}
|
||||
|
||||
void bmp__write_16bit(char* bytes, int num) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
bytes[i] = num >> (i * 8);
|
||||
}
|
||||
}
|
||||
|
||||
int bmp__align_to_four_bytes(int size) {
|
||||
int os = size % 4;
|
||||
return os == 0 ? size : size + (4 - os);
|
||||
}
|
||||
|
||||
int bmp__image_byte_size(Image image) {
|
||||
// calculate size:
|
||||
// bitmap file header = 14
|
||||
// BITMAPCOREHEADER = 12 bytes
|
||||
int size = 14 + 12;
|
||||
// width must be padded to align to 4 bytes
|
||||
int width_bytes = bmp__align_to_four_bytes(image.width * 3); // 3 bytes per pixel
|
||||
// add width_bytes * height to total size
|
||||
size += width_bytes * image.height;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
// header format:
|
||||
// BMP header (14 bytes)
|
||||
// 0x42 0x4D "BM"
|
||||
// 0xAA 0xBB 0xCC 0xDD bmp file size (int)
|
||||
// 0x00 0x00 0x00 0x00 nulls
|
||||
// 0x1A 0x00 0x00 0x00 pixel array offset (int) (= 14 + 12);
|
||||
// DIB Header (BITMAPCOREHEADER) (12 bytes)
|
||||
// 0x0C 0x00 0x00 0x00 header size (int) (= 12)
|
||||
// 0xAA 0xBB width (unsigned 16 bit int)
|
||||
// 0xCC 0xDD height (unsigned 16 bit int)
|
||||
// 0x01 0x00 number of color planes (must be 1)
|
||||
// 0x18 0x00 number of bits per pixel (3 * 8 = 24)
|
||||
|
||||
int image_save_bmp(Image image, char* path) {
|
||||
int size = bmp__image_byte_size(image);
|
||||
char* bytes = calloc(sizeof(char), size);
|
||||
// magic bytes, signature "BM"
|
||||
bytes[0] = 0x42;
|
||||
bytes[1] = 0x4d;
|
||||
// write size to header
|
||||
bmp__write_int(bytes + 2, size);
|
||||
// the next 4 byte are zeros
|
||||
// piyel array offset
|
||||
bmp__write_int(bytes + 10, 14 + 12);
|
||||
bmp__write_int(bytes + 14, 12);
|
||||
bmp__write_16bit(bytes + 18, image.width); // width
|
||||
bmp__write_16bit(bytes + 20, image.height); // height
|
||||
bmp__write_16bit(bytes + 22, 1); // color planes
|
||||
bmp__write_16bit(bytes + 24, 3 * 8); // bits per pixel
|
||||
|
||||
int byte_offset = 26;
|
||||
int byte_pos = 0;
|
||||
int line;
|
||||
for (line = 0; line < image.height; line++) {
|
||||
byte_pos = 0;
|
||||
for (int px = 0; px < image.width * 3; px += 3) {
|
||||
bytes[byte_offset + byte_pos++] = image.bitmap[line][px + 2];
|
||||
bytes[byte_offset + byte_pos++] = image.bitmap[line][px + 1];
|
||||
bytes[byte_offset + byte_pos++] = image.bitmap[line][px + 0];
|
||||
}
|
||||
byte_offset += bmp__align_to_four_bytes(byte_pos);
|
||||
}
|
||||
|
||||
printf("generated %i bytes out of %i calculated ones\n", byte_offset, size);
|
||||
|
||||
FILE *fp = fopen(path, "w");
|
||||
int written = fwrite(bytes, sizeof(char), size, fp);
|
||||
printf("wrote %i bytes...\n", written);
|
||||
fclose(fp);
|
||||
free(bytes);
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue