#include /* Copyright 2013 Glenn Randers-Pehrson */ /* Usage: * pngiend.exe < file.png > file.iend * * file.iend is the image datastream, minus everything through the * last IDAT chunk. */ main() { unsigned int c; unsigned int i; unsigned int len[5]; unsigned int length; unsigned int mode; unsigned int name[5]; len[4]='\0'; name[4]='\0'; mode=0; /* Looking for IDAT */ /* Skip 8-byte signature */ for (i=8; i; i--) { c=getchar(); if (c == EOF) break; } for (;;) { /* read length */ len[0]=getchar(); if (len[0] == EOF) break; len[1]=getchar(); len[2]=getchar(); len[3]=getchar(); if (len[3] == EOF) break; length=len[0]<<24 | len[1]<<16 | len[2]<< 8 | len[3]; /* read chunkname */ name[0]=getchar(); name[1]=getchar(); name[2]=getchar(); name[3]=getchar(); if (name[3] == EOF) break; if (name[0] == 'I' && name[1] == 'D' && name[2] == 'A' && \ name[3] == 'T') { if (mode == 0) mode = 1; /* found IDAT */ } else { if (mode == 1) mode = 2; /* found chunk after IDAT */ } if (mode == 2) { /* copy the length bytes */ putchar(len[0]); putchar(len[1]); putchar(len[2]); putchar(len[3]); /* copy the name bytes */ putchar(name[0]); putchar(name[1]); putchar(name[2]); putchar(name[3]); } /* skip or copy the data bytes */ for (i=length; i; i--) { c=getchar(); if (c == EOF) break; if (mode == 2) putchar(c); } if (c == EOF) break; /* skip or copy crc bytes */ for (i=4; i; i--) { c=getchar(); if (c == EOF) break; if (mode == 2) putchar(c); } if (c == EOF) break; if (name[0] == 'I' && name[1] == 'E' && name[2] == 'N' && \ name[3] == 'D') { break; } } }