initial commit
commit
107588ae7f
@ -0,0 +1,2 @@
|
|||||||
|
*.out
|
||||||
|
*.o
|
@ -0,0 +1,140 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "images.h"
|
||||||
|
|
||||||
|
// write an int to a byte array
|
||||||
|
void write_int(char* bytes, int num) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
bytes[i] = num >> (i * 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_byte(char* bytes, int num) {
|
||||||
|
bytes[0] = (char) num;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_16bit(char* bytes, int num) {
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
bytes[i] = num >> (i * 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int align_to_four_bytes(int size) {
|
||||||
|
int os = size % 4;
|
||||||
|
return os == 0 ? size : size + (4 - os);
|
||||||
|
}
|
||||||
|
|
||||||
|
int image_new(int width, int height, Image* img) {
|
||||||
|
//Image* img = malloc(sizeof(Image));
|
||||||
|
|
||||||
|
if (img == NULL) return 0;
|
||||||
|
|
||||||
|
img->height = height;
|
||||||
|
img->width = width;
|
||||||
|
|
||||||
|
// initialize bitmap...
|
||||||
|
img->bitmap = malloc(height * sizeof(int*));
|
||||||
|
for (int i = 0; i < height; i++) {
|
||||||
|
img->bitmap[i] = malloc(width * sizeof(int*));
|
||||||
|
for (int j = 0; j < width; j++) {
|
||||||
|
img->bitmap[i][j] = malloc(3 * sizeof(int));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*image = *img;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int 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 = 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(Image* image, char* path) {
|
||||||
|
int size = image_byte_size(image);
|
||||||
|
char* bytes = calloc(sizeof(char), size);
|
||||||
|
// magic bytes, signature "BM"
|
||||||
|
bytes[0] = 0x42;
|
||||||
|
bytes[1] = 0x4d;
|
||||||
|
// write size to header
|
||||||
|
write_int(bytes + 2, size);
|
||||||
|
// the next 4 byte are zeros
|
||||||
|
// piyel array offset
|
||||||
|
write_int(bytes + 10, 14 + 12);
|
||||||
|
write_int(bytes + 14, 12);
|
||||||
|
write_16bit(bytes + 18, image->width); // width
|
||||||
|
write_16bit(bytes + 20, image->height); // height
|
||||||
|
write_16bit(bytes + 22, 1); // color planes
|
||||||
|
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; px++) {
|
||||||
|
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 += 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int image_set_px(Image* image, int x, int y, int r, int g, int b) {
|
||||||
|
if (!image_check_coords(image, x, y)) return 0;
|
||||||
|
|
||||||
|
image->bitmap[y][x][0] = (char) r;
|
||||||
|
image->bitmap[y][x][1] = (char) g;
|
||||||
|
image->bitmap[y][x][2] = (char) b;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int image_check_coords(Image* image, int x, int y) {
|
||||||
|
return x >= 0 && x < image->width &&
|
||||||
|
y >= 0 && y < image->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int image_destroy(Image* image) {
|
||||||
|
for (int i = 0; i < image->height; i++) {
|
||||||
|
for (int j = 0; j < image->width; j++) {
|
||||||
|
free(image->bitmap[i][j]);
|
||||||
|
}
|
||||||
|
free(image->bitmap[i]);
|
||||||
|
}
|
||||||
|
free(image->bitmap);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef IMAGES_H
|
||||||
|
#define IMAGES_H
|
||||||
|
|
||||||
|
typedef struct _image {
|
||||||
|
char*** bitmap;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} Image;
|
||||||
|
|
||||||
|
int image_new(int width, int height, Image* image);
|
||||||
|
|
||||||
|
int image_save(Image* image, char* path);
|
||||||
|
|
||||||
|
int image_set_px(Image* image, int x, int y, int r, int g, int b);
|
||||||
|
|
||||||
|
int image_check_coords(Image* image, int x, int y);
|
||||||
|
|
||||||
|
int image_destroy(Image* image);
|
||||||
|
|
||||||
|
int image_byte_size(Image *image);
|
||||||
|
|
||||||
|
#include "images.c"
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,33 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "images/images.h"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
Image img;
|
||||||
|
image_new(255,255, &img);
|
||||||
|
|
||||||
|
int r,g,b;
|
||||||
|
|
||||||
|
for (int i = 0; i < 255; i++) {
|
||||||
|
for (int j = 0; j < 255; j++) {
|
||||||
|
double factor = (i*i + j*j) / (100*100);
|
||||||
|
r = i;
|
||||||
|
g = 255 -j;
|
||||||
|
b = i -255;
|
||||||
|
|
||||||
|
|
||||||
|
image_set_px(&img, i, j, factor * r, factor * g, factor * b);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Writing file to /home/anton/projects/mona/chaos/test.bmp\n");
|
||||||
|
|
||||||
|
if (!image_save(&img, "/home/anton/projects/mona/chaos/test.bmp")) {
|
||||||
|
printf("Error writing file!\n");
|
||||||
|
} else {
|
||||||
|
printf("Wrote file successfully\n");
|
||||||
|
}
|
||||||
|
image_destroy(&img);
|
||||||
|
}
|
Loading…
Reference in New Issue