]>
Commit | Line | Data |
---|---|---|
3df14711 MG |
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 | } |