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