X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/rigol/blobdiff_plain/a8982973a30709b358876498572df8d2e96ef5cf..3df147113765d5a8ba192795d2be9b7e3e295749:/png.c diff --git a/png.c b/png.c new file mode 100644 index 0000000..98d5993 --- /dev/null +++ b/png.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include + +#include "png.h" + +/* Table of CRCs of all 8-bit messages. */ +static unsigned long crc_table[256]; + +/* Flag: has the table been computed? Initially false. */ +static int crc_table_computed = 0; + +/* Make the table for a fast CRC. */ +static void make_crc_table(void) +{ + unsigned long c; + int n, k; + + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) + c = 0xedb88320L ^ (c >> 1); + else + c = c >> 1; + } + crc_table[n] = c; + } + crc_table_computed = 1; +} + +/* Update a running CRC with the bytes buf[0..len-1]--the CRC + should be initialized to all 1's, and the transmitted value + is the 1's complement of the final running CRC (see the + crc() routine below). */ + +static unsigned long update_crc(unsigned long crc, unsigned char *buf, + int len) +{ + unsigned long c = crc; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c; +} + +/* Return the CRC of the bytes buf[0..len-1]. */ +static unsigned long crc(unsigned char *buf, int len) +{ + return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL; +} + +unsigned char *lcd2png(unsigned char *lcd, int *len) +{ + unsigned char screen_conv[320*234*3]; + unsigned char lut[256][3]; + unsigned char *image; + unsigned char *outpos; + static const unsigned char png[] = {137, 80, 78, 71, 13, 10, 26, 10}; + static unsigned char ihdr[] = {'I', 'H', 'D', 'R', + 0x00, 0x00, 0x01, 0x40, /* 320 - Width */ + 0x00, 0x00, 0x00, 0xea, /* 234 - Height */ + 0x08, /* Bit depth */ + 0x02, /* RGB Truecolor, Colour type */ + 0x00, /* Deflate, Compression method */ + 0x00, /* None, Filter method */ + 0x00 /* No interlace, Interlace method */ + }; + static unsigned char idat[] = {'I', 'D', 'A', 'T'}; + static unsigned char iend[] = {'I', 'E', 'N', 'D'}; + uint32_t l; + int i; + int toalloc = 0; + + for(i = 0; i < 256; i++) { + lut[i][0] = ((i >> 6) * 0x55); + lut[i][1] = ((((i >> 3) & 7) * 0x49) >> 1); + lut[i][2] = (((i & 7) * 0x49) >> 1); + } + + for(i = 0; i < sizeof(screen_conv); i += 3) { + screen_conv[i] = lut[lcd[i/3]][0]; + screen_conv[i+1] = lut[lcd[i/3]][1]; + screen_conv[i+2] = lut[lcd[i/3]][2]; + } + + image = malloc(320*234*2); /* TODO: FIXME! */ + outpos = image; + memcpy(outpos, png, sizeof(png)); + outpos += sizeof(png); + + l = htonl(sizeof(ihdr) - 4); /* "IHDR" is not counted */ + memcpy(outpos, &l, sizeof(l)); + outpos += sizeof(l); + memcpy(outpos, ihdr, sizeof(ihdr)); + outpos += sizeof(ihdr); + l = crc(ihdr, sizeof(ihdr)); + memcpy(outpos, &l, sizeof(l)); + outpos += sizeof(l); + + l = htonl(sizeof(iend) - 4); /* "IEND" is not counted */ + memcpy(outpos, &l, sizeof(l)); + outpos += sizeof(l); + memcpy(outpos, iend, sizeof(iend)); + outpos += sizeof(iend); + l = crc(iend, sizeof(iend)); + memcpy(outpos, &l, sizeof(l)); + outpos += sizeof(l); + + *len = (int)(outpos - image); + return image; +}