]> git.zerfleddert.de Git - rigol/blob - png.c
98d599371717c7f4fe3062d92328530fc426ad6f
[rigol] / png.c
1 #include <string.h>
2 #include <stdint.h>
3 #include <arpa/inet.h>
4 #include <zlib.h>
5
6 #include "png.h"
7
8 /* Table of CRCs of all 8-bit messages. */
9 static unsigned long crc_table[256];
10
11 /* Flag: has the table been computed? Initially false. */
12 static int crc_table_computed = 0;
13
14 /* Make the table for a fast CRC. */
15 static void make_crc_table(void)
16 {
17 unsigned long c;
18 int n, k;
19
20 for (n = 0; n < 256; n++) {
21 c = (unsigned long) n;
22 for (k = 0; k < 8; k++) {
23 if (c & 1)
24 c = 0xedb88320L ^ (c >> 1);
25 else
26 c = c >> 1;
27 }
28 crc_table[n] = c;
29 }
30 crc_table_computed = 1;
31 }
32
33 /* Update a running CRC with the bytes buf[0..len-1]--the CRC
34 should be initialized to all 1's, and the transmitted value
35 is the 1's complement of the final running CRC (see the
36 crc() routine below). */
37
38 static unsigned long update_crc(unsigned long crc, unsigned char *buf,
39 int len)
40 {
41 unsigned long c = crc;
42 int n;
43
44 if (!crc_table_computed)
45 make_crc_table();
46 for (n = 0; n < len; n++) {
47 c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
48 }
49 return c;
50 }
51
52 /* Return the CRC of the bytes buf[0..len-1]. */
53 static unsigned long crc(unsigned char *buf, int len)
54 {
55 return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
56 }
57
58 unsigned char *lcd2png(unsigned char *lcd, int *len)
59 {
60 unsigned char screen_conv[320*234*3];
61 unsigned char lut[256][3];
62 unsigned char *image;
63 unsigned char *outpos;
64 static const unsigned char png[] = {137, 80, 78, 71, 13, 10, 26, 10};
65 static unsigned char ihdr[] = {'I', 'H', 'D', 'R',
66 0x00, 0x00, 0x01, 0x40, /* 320 - Width */
67 0x00, 0x00, 0x00, 0xea, /* 234 - Height */
68 0x08, /* Bit depth */
69 0x02, /* RGB Truecolor, Colour type */
70 0x00, /* Deflate, Compression method */
71 0x00, /* None, Filter method */
72 0x00 /* No interlace, Interlace method */
73 };
74 static unsigned char idat[] = {'I', 'D', 'A', 'T'};
75 static unsigned char iend[] = {'I', 'E', 'N', 'D'};
76 uint32_t l;
77 int i;
78 int toalloc = 0;
79
80 for(i = 0; i < 256; i++) {
81 lut[i][0] = ((i >> 6) * 0x55);
82 lut[i][1] = ((((i >> 3) & 7) * 0x49) >> 1);
83 lut[i][2] = (((i & 7) * 0x49) >> 1);
84 }
85
86 for(i = 0; i < sizeof(screen_conv); i += 3) {
87 screen_conv[i] = lut[lcd[i/3]][0];
88 screen_conv[i+1] = lut[lcd[i/3]][1];
89 screen_conv[i+2] = lut[lcd[i/3]][2];
90 }
91
92 image = malloc(320*234*2); /* TODO: FIXME! */
93 outpos = image;
94 memcpy(outpos, png, sizeof(png));
95 outpos += sizeof(png);
96
97 l = htonl(sizeof(ihdr) - 4); /* "IHDR" is not counted */
98 memcpy(outpos, &l, sizeof(l));
99 outpos += sizeof(l);
100 memcpy(outpos, ihdr, sizeof(ihdr));
101 outpos += sizeof(ihdr);
102 l = crc(ihdr, sizeof(ihdr));
103 memcpy(outpos, &l, sizeof(l));
104 outpos += sizeof(l);
105
106 l = htonl(sizeof(iend) - 4); /* "IEND" is not counted */
107 memcpy(outpos, &l, sizeof(l));
108 outpos += sizeof(l);
109 memcpy(outpos, iend, sizeof(iend));
110 outpos += sizeof(iend);
111 l = crc(iend, sizeof(iend));
112 memcpy(outpos, &l, sizeof(l));
113 outpos += sizeof(l);
114
115 *len = (int)(outpos - image);
116 return image;
117 }
Impressum, Datenschutz