image-viewer/img_png.c
2025-06-05 20:40:23 +02:00

68 lines
1.5 KiB
C

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "img_png.h"
#define BUFSIZE 1024
const unsigned char img_png_signature[] = {0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n'};
uint32_t char_to_uint32 (unsigned char* input) {
uint32_t val = (input[0] << 24) + (input[1] << 16) + (input[2] << 8) + input[3];
return val;
}
uint8_t* img_png_decode(FILE *fp) {
unsigned char buffer[BUFSIZE];
unsigned char magic[8];
enum chunk_state {
LENGTH,
TYPE,
DATA,
CRC
};
// Check PNG Magic
if(fread(magic, sizeof(*magic), 8, fp) < 8) {
fprintf(stderr, "Couldn\'t read PNG magic.");
exit(EXIT_FAILURE);
}
if(memcmp(magic, img_png_signature, 8) != 0) {
fprintf(stderr, "Invalid PNG magic\n");
exit(EXIT_FAILURE);
}
printf("PNG Magic: %#04x%02x%02x%02x%02x%02x%02x%02x\n", magic[0], magic[1], magic[2],
magic[3], magic[4], magic[5], magic[6], magic[7]);
// After the magic number is read, we should hit the length of the chunk first.
enum chunk_state state = LENGTH;
struct img_png_chunk cur_chunk;
while(fread(buffer, sizeof(*buffer), BUFSIZE, fp) > 0){
// Refine later!!!
switch (state) {
case LENGTH: {
unsigned char length[4];
for (size_t i = 0; i < 4; i++) {
length[i] = buffer[i];
}
cur_chunk.length = char_to_uint32(length);
printf("Chunk length: %lu\n", (unsigned long)cur_chunk.length);
}
}
}
if(!feof(fp)) {
perror("fread() failed!");
exit(EXIT_FAILURE);
}
return NULL;
}