Created
November 11, 2021 22:50
-
-
Save thegabriele97/2c4877e001dac8089bd31b13a94e000f to your computer and use it in GitHub Desktop.
bmp file reader and diff computation pixel by pixel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <stdint.h> | |
#include <sys/stat.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define memcpy_lol(_dst, _src, _size, _loc) {\ | |
memcpy(_dst, _src, _size);\ | |
(_loc) = (uint8_t *)((uint8_t *)_src + (size_t)_size);\ | |
} | |
#define memcpy_ultra(_dst_noptr, _src, _loc) memcpy_lol(&_dst_noptr, _src, sizeof _dst_noptr, _loc) | |
struct rgb_s { | |
uint8_t red; | |
uint8_t green; | |
uint8_t blue; | |
}; | |
struct bmp_s { | |
struct header_s { | |
uint8_t id[2]; | |
uint32_t size; | |
uint16_t _reserved0; | |
uint16_t _reserved1; | |
uint32_t offset; | |
} header; | |
struct dip_s { | |
uint16_t width; | |
uint16_t heigth; | |
} dip; | |
struct rgb_s *pixels; | |
}; | |
typedef union { | |
uint8_t byte; | |
struct { | |
unsigned red: 1; | |
unsigned green: 1; | |
unsigned blue: 1; | |
unsigned _reserved: 5; | |
} channels; | |
} diffsign_t; | |
void read_bmp(struct bmp_s *bmp, const char *bmpfile) { | |
int fd, i; | |
struct stat sb; | |
uint8_t *file; | |
uint8_t *bmap; | |
lstat(bmpfile, &sb); | |
file = malloc(sb.st_size * sizeof *file); | |
fd = open(bmpfile, O_RDONLY); | |
if (read(fd, file, sb.st_size * sizeof *file) != sb.st_size) { | |
fprintf(stderr, "WTF!\n"); | |
} | |
memcpy(bmp->header.id, file + 0x00, 2 * sizeof *bmp->header.id); | |
memcpy(&bmp->header.size, file + 0x02, sizeof bmp->header.size); | |
memcpy(&bmp->header.offset, file + 0x0a, sizeof bmp->header.offset); | |
memcpy(&bmp->dip.width, file + 0x12, sizeof bmp->dip.width); | |
memcpy(&bmp->dip.heigth, file + 0x16, sizeof bmp->dip.heigth); | |
bmap = malloc(bmp->header.size * sizeof *bmap); | |
memcpy(bmap, file + bmp->header.offset, bmp->header.size * sizeof *bmap); | |
bmp->pixels = malloc((bmp->header.size / 3) * sizeof *bmp->pixels); | |
for (i = 0; i < bmp->dip.heigth * bmp->dip.width; i++) { | |
bmp->pixels[i].red = bmap[3 * i + 2]; | |
bmp->pixels[i].green = bmap[3 * i + 1]; | |
bmp->pixels[i].blue = bmap[3 * i + 0]; | |
} | |
free(bmap); | |
free(file); | |
close(fd); | |
} | |
int main(int argc, char **argv) { | |
struct bmp_s bmp1, bmp2; | |
int i, j, max; | |
struct rgb_s *diff; | |
diffsign_t *diffsign; | |
if (argc < 3) { | |
fprintf(stderr, "ERROR: no image specified!\n"); | |
} | |
read_bmp(&bmp1, argv[1]); | |
read_bmp(&bmp2, argv[2]); | |
diff = malloc(bmp1.dip.heigth * bmp1.dip.width * sizeof *diff); | |
diffsign = malloc(bmp1.dip.heigth * bmp1.dip.width * sizeof *diffsign); | |
// for (i = 0, max = bmp1.dip.heigth * bmp1.dip.width; i < max; i++) { | |
// diff[i].red = abs(bmp2.pixels[i].red - bmp1.pixels[i].red); | |
// diff[i].green = abs(bmp2.pixels[i].green - bmp1.pixels[i].green); | |
// diff[i].blue = abs(bmp2.pixels[i].blue - bmp1.pixels[i].blue); | |
// diffsign[i].channels.red = bmp2.pixels[i].red < bmp1.pixels[i].red; | |
// diffsign[i].channels.green = bmp2.pixels[i].green < bmp1.pixels[i].green; | |
// diffsign[i].channels.blue = bmp2.pixels[i].blue < bmp1.pixels[i].blue; | |
// // if (diff[i].red || diff[i].green || diff[i].blue) { | |
// // printf("\tbmp1 [%04d][%04d] r: %03d g: %03d b: %03d\n", i / bmp1.dip.width, j % bmp1.dip.width, bmp1.pixels[i].red, bmp1.pixels[i].green, bmp1.pixels[i].blue); | |
// // printf("\tbmp2 [%04d][%04d] r: %03d g: %03d b: %03d\n", i / bmp1.dip.width, j % bmp1.dip.width, bmp2.pixels[i].red, bmp2.pixels[i].green, bmp2.pixels[i].blue); | |
// // printf("\tdiff [%04d][%04d] r: %03d g: %03d b: %03d\n", i / bmp1.dip.width, j % bmp1.dip.width, diff[i].red, diff[i].green, diff[i].blue); | |
// // printf("\tsign [%04d][%04d] r: %03d g: %03d b: %03d\n", i / bmp1.dip.width, j % bmp1.dip.width, diffsign[i].channels.red, diffsign[i].channels.green, diffsign[i].channels.blue); | |
// // printf("\n"); | |
// // } | |
// } | |
for (i = 0; i < bmp1.dip.heigth; i++) { | |
for (j = 0; j < bmp1.dip.width; j++) { | |
diff[i * bmp1.dip.width + j].red = abs(bmp2.pixels[i * bmp1.dip.width + j].red - bmp1.pixels[i * bmp1.dip.width + j].red); | |
diff[i * bmp1.dip.width + j].green = abs(bmp2.pixels[i * bmp1.dip.width + j].green - bmp1.pixels[i * bmp1.dip.width + j].green); | |
diff[i * bmp1.dip.width + j].blue = abs(bmp2.pixels[i * bmp1.dip.width + j].blue - bmp1.pixels[i * bmp1.dip.width + j].blue); | |
diffsign[i * bmp1.dip.width + j].channels.red = bmp2.pixels[i * bmp1.dip.width + j].red < bmp1.pixels[i * bmp1.dip.width + j].red; | |
diffsign[i * bmp1.dip.width + j].channels.green = bmp2.pixels[i * bmp1.dip.width + j].green < bmp1.pixels[i * bmp1.dip.width + j].green; | |
diffsign[i * bmp1.dip.width + j].channels.blue = bmp2.pixels[i * bmp1.dip.width + j].blue < bmp1.pixels[i * bmp1.dip.width + j].blue; | |
// if (diff[i * bmp1.dip.width + j].red || diff[i * bmp1.dip.width + j].green || diff[i * bmp1.dip.width + j].blue) { | |
// printf("\tbmp1 [%04d][%04d] r: %03d g: %03d b: %03d\n", i, j, bmp1.pixels[i * bmp1.dip.width + j].red, bmp1.pixels[i * bmp1.dip.width + j].green, bmp1.pixels[i * bmp1.dip.width + j].blue); | |
// printf("\tbmp2 [%04d][%04d] r: %03d g: %03d b: %03d\n", i, j, bmp2.pixels[i * bmp1.dip.width + j].red, bmp2.pixels[i * bmp1.dip.width + j].green, bmp2.pixels[i * bmp1.dip.width + j].blue); | |
// printf("\tdiff [%04d][%04d] r: %03d g: %03d b: %03d\n", i, j, diff[i * bmp1.dip.width + j].red, diff[i * bmp1.dip.width + j].green, diff[i * bmp1.dip.width + j].blue); | |
// printf("\tsign [%04d][%04d] r: %03d g: %03d b: %03d\n", i, j, diffsign[i * bmp1.dip.width + j].channels.red, diffsign[i * bmp1.dip.width + j].channels.green, diffsign[i * bmp1.dip.width + j].channels.blue); | |
// printf("\n"); | |
// } | |
} | |
} | |
free(diff); | |
free(diffsign); | |
free(bmp1.pixels); | |
free(bmp2.pixels); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment