Skip to content

Instantly share code, notes, and snippets.

@thegabriele97
Created November 11, 2021 22:50
Show Gist options
  • Save thegabriele97/2c4877e001dac8089bd31b13a94e000f to your computer and use it in GitHub Desktop.
Save thegabriele97/2c4877e001dac8089bd31b13a94e000f to your computer and use it in GitHub Desktop.
bmp file reader and diff computation pixel by pixel
#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