Skip to content

Instantly share code, notes, and snippets.

@anakojm
Forked from mmalex/pngencode.cpp
Last active January 24, 2024 13:58
Show Gist options
  • Save anakojm/69f8ec1dfab5253203ac1f6c32be13f2 to your computer and use it in GitHub Desktop.
Save anakojm/69f8ec1dfab5253203ac1f6c32be13f2 to your computer and use it in GitHub Desktop.
anakojm
/* gcc -lz anakojm.c && ./a.out 1 1 */
#include <zlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
uint8_t* CompressPNG(void *img, int w, int h, int numchans, unsigned int* len_out) {
int p = w * numchans;
z_stream z = {0};
deflateInit(&z, -1);
uint8_t *zbuf = malloc(57 + (z.avail_out = deflateBound(&z, (1 + p)*h)) + 1);
if (!zbuf) return 0;
z.next_out = zbuf + 41;
for (int y = 0; y < h; ++y) {
Bytef zero = 0;
z.avail_in = 1;
z.next_in = &zero;
deflate(&z, Z_NO_FLUSH);
z.avail_in = p;
z.next_in = ((Bytef*)img) + y*p;
deflate(&z, (y == h - 1) ? Z_FINISH : Z_NO_FLUSH);
}
*len_out = z.next_out - zbuf - 41;
uint8_t pnghdr[41] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0, 0, w>>8, w, 0, 0, h>>8, h, 8, "\0\0\04\02\06"[numchans], 0, 0, 0, 0, 0, 0, 0,
*len_out>>24, *len_out>>16, *len_out>>8, *len_out, 0x49, 0x44, 0x41, 0x54};
*(unsigned int*)(pnghdr + 29) = htonl(crc32(0, pnghdr + 12, 17));
memcpy(zbuf, pnghdr, 41);
memcpy(z.next_out + 4, "\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 12); /* footer */
*(unsigned int*)z.next_out = htonl(crc32(0, zbuf+41-4, *len_out+4));
deflateEnd(&z);
*len_out += 57;
return zbuf;
}
int main(int argc, char *argv[]) {
if (argc != 3) return 1;
int Y = strtol(argv[1], NULL, 10);
int X = strtol(argv[2], NULL, 10);
unsigned int img[Y][X];
for (int y = 0; y < Y; ++y) for (int x = 0; x < X; ++x) img[y][x] = 0xff0000ff;
unsigned int blen;
uint8_t* zbuf = CompressPNG(img, X, Y, 4, &blen);
FILE *f = fopen("anakojm.png", "wb");
fwrite(zbuf, 1, blen, f);
fclose(f);
free(zbuf);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment