#include #include #include typedef struct __attribute__((__packed__)) BMPHeader { uint16_t type; // Magic identifier: 0x4d42 uint32_t size; // File size in bytes uint16_t reserved1; // Not used uint16_t reserved2; // Not used uint32_t offset; // Offset to image data in bytes from beginning of file uint32_t dib_header_size; // DIB Header size in bytes int32_t width_px; // Width of the image int32_t height_px; // Height of image uint16_t num_planes; // Number of color planes uint16_t bits_per_pixel; // Bits per pixel uint32_t compression; // Compression type uint32_t image_size_bytes; // Image size in bytes int32_t x_resolution_ppm; // Pixels per meter int32_t y_resolution_ppm; // Pixels per meter uint32_t num_colors; // Number of colors uint32_t important_colors; // Important colors } BMPHeader; int main (int argc, char* argv[]) { FILE* in, *out; if(argc < 3) { printf("Usage: %s \n", argv[0]); return 1; } in = fopen(argv[1], "rb"); if(!in) { printf("Could not open input file.\n"); return 1; } out = fopen(argv[2], "wb"); if(!out) { printf("Could not open output file.\n"); return 1; } BMPHeader in_header = {0}; fread(&in_header, sizeof(BMPHeader), 1, in); fseek(in, in_header.offset, SEEK_SET); uint8_t* px = malloc(in_header.image_size_bytes); fread(px, in_header.image_size_bytes, 1, in); fclose(in); printf("%d x %d\n", in_header.width_px, in_header.height_px); printf("bpp: %d\n", in_header.bits_per_pixel); uint8_t* out_buffer = malloc(32 * 32 / 8); for(int out_y = 0; out_y < 32; out_y++) { for(int out_x = 0; out_x < 32; out_x++) { // input is bigger than output // so we need to skip some pixels int in_x = out_x * in_header.width_px / 32; int in_y = out_y * in_header.height_px / 32; int in_offset = (in_y * in_header.width_px + in_x) * 3; uint8_t v = (px[in_offset + 2] + px[in_offset + 1] + px[in_offset + 0]) / 3; int out_offset = out_y * 32 / 8 + out_x / 8; if(v > 127) { out_buffer[out_offset] |= 1 << (7 - out_x % 8); } else { out_buffer[out_offset] &= ~(1 << (7 - out_x % 8)); } } } free(px); BMPHeader out_header = {0}; out_header.type = 0x4d42; out_header.size = sizeof(BMPHeader) + 32 * 32 / 8; out_header.offset = sizeof(BMPHeader); out_header.dib_header_size = sizeof(BMPHeader) - 14; out_header.width_px = 32; out_header.height_px = 32; out_header.bits_per_pixel = 1; out_header.image_size_bytes = 32 * 32 / 8; out_header.num_colors = 2; out_header.important_colors = 2; fwrite(&out_header, sizeof(BMPHeader), 1, out); fwrite(out_buffer, out_header.image_size_bytes, 1, out); fclose(out); free(out_buffer); }