Created
July 2, 2018 09:34
-
-
Save samthor/fbcb82a28e5edda4709e7dece54f1cb9 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <stdint.h> | |
#include <string.h> | |
#include <stdlib.h> | |
typedef struct { | |
int chunks, w, h; | |
} info_t; | |
const char expected_header[8] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; | |
extern int chunk_callback(uint32_t type, uint32_t len, void *p); | |
uint32_t flip_endian(uint32_t val) { | |
val = ((val << 8) & 0xff00ff00) | ((val >> 8) & 0xff00ff ); | |
return (val << 16) | ((val >> 16) & 0xffff); | |
} | |
char *parse_png(void *p, uint32_t plen, info_t *out) { | |
if (plen < 8 || memcmp(p, expected_header, 8)) { | |
return "invalid header"; | |
} | |
int found_header = 0; | |
out->chunks = 0; | |
void *curr = p + 8; | |
while (curr - p < plen) { | |
uint32_t *lp = (uint32_t *) curr; | |
uint32_t len = flip_endian(lp[0]); | |
if ((curr - p) + (len + 12) > plen) { | |
return "chunk too large"; | |
} | |
if (!memcmp(curr + 4, "IHDR", 4)) { | |
if (len != 13) { | |
return "IHDR has wrong size"; | |
} | |
found_header = 1; | |
out->w = lp[2]; | |
out->h = lp[3]; | |
} | |
// demonstrate malloc/free: copy chunk so caller can change it | |
void *copy = malloc(len); | |
if (!copy) { | |
return "couldn't malloc for copy"; | |
} | |
memcpy(copy, curr + 8, len); | |
chunk_callback(lp[1], len, copy); | |
free(copy); | |
curr += (len + 12); // chunk length plus 3 x 32-bit ints | |
++out->chunks; | |
} | |
if (!found_header) { | |
return "header not found"; | |
} | |
return NULL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment