]> git.zerfleddert.de Git - rigol/blobdiff - png.c
beginning of png
[rigol] / png.c
diff --git a/png.c b/png.c
new file mode 100644 (file)
index 0000000..98d5993
--- /dev/null
+++ b/png.c
@@ -0,0 +1,117 @@
+#include <string.h>
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <zlib.h>
+
+#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;
+}
Impressum, Datenschutz