Skip to content

Instantly share code, notes, and snippets.

@12Me21
Created May 31, 2022 17:32
Show Gist options
  • Save 12Me21/c6d4df4908082dfb6332a5a933f8db26 to your computer and use it in GitHub Desktop.
Save 12Me21/c6d4df4908082dfb6332a5a933f8db26 to your computer and use it in GitHub Desktop.
run like: cat source.png dest.png | a.out >out.png
#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
typedef uint32_t U32;
typedef uint8_t U8;
typedef uint16_t U16;
U8 temp[100000]; //hopefully no png chunks are larger than this!
U8* read2(ssize_t n) {
U8* dest = temp;
while (n) {
ssize_t amt = read(0, dest, n);
n -= amt;
dest += amt;
}
return temp;
}
void write2(U8* buffer, ssize_t n) {
while (n) {
ssize_t amt = write(1, buffer, n);
n -= amt;
buffer += amt;
}
}
U32 read32be(void) {
read2(4);
U32 res = *(U32*)temp; // uh idk if this is allowed... alignment and all
return ntohl(res);
}
void write32be(U32 d) {
d = htonl(d);
write2((U8*)&d, 4);
}
void skip(ssize_t b) {
read2(b);
}
void trans(ssize_t b) {
read2(b);
write2(temp, b);
}
int main(int argc, char** argv) {
dprintf(2, "start\n");
U8 buffer2[1000];
U8* buffer;
for (int i=0; i<2; i++) {
if (i==1)
trans(8);
else
skip(8);
dprintf(2, "starting image %d\n", i+1);
for (;;) {
U32 len = read32be();
U32 type = read32be();
dprintf(2, "read chunk: %4.4s\n", (U8*)&type);
if (i==0) { // source image
if (type != 0x504C5445ul) // not PLTE chunk
skip(len+4);
else {
buffer = read2(len+4);
memcpy(buffer2, buffer, len+4);
}
} else { // dest image
write32be(len);
write32be(type);
if (type != 0x504C5445ul) // not PLTE chunk
trans(len+4);
else {
skip(len+4);
write2(buffer2, len+4);
}
}
if (type==0x49454E44ul) // IEND chunk
break;
}
}
dprintf(2, "done\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment