]>
git.zerfleddert.de Git - rigol/blob - png.c
a85e7d701c99e92c4e0ca2c0017d956b8d5f30ae
14 /* Table of CRCs of all 8-bit messages. */
15 static unsigned long crc_table
[256];
17 /* Flag: has the table been computed? Initially false. */
18 static int crc_table_computed
= 0;
20 /* Make the table for a fast CRC. */
21 static void make_crc_table(void)
26 for (n
= 0; n
< 256; n
++) {
27 c
= (unsigned long) n
;
28 for (k
= 0; k
< 8; k
++) {
30 c
= 0xedb88320L
^ (c
>> 1);
36 crc_table_computed
= 1;
39 /* Update a running CRC with the bytes buf[0..len-1]--the CRC
40 should be initialized to all 1's, and the transmitted value
41 is the 1's complement of the final running CRC (see the
42 crc() routine below). */
44 static unsigned long update_crc(unsigned long crc
, unsigned char *buf
,
47 unsigned long c
= crc
;
50 if (!crc_table_computed
)
52 for (n
= 0; n
< len
; n
++) {
53 c
= crc_table
[(c
^ buf
[n
]) & 0xff] ^ (c
>> 8);
58 /* Return the CRC of the bytes buf[0..len-1]. */
59 static unsigned long crc(unsigned char *buf
, int len
)
61 return update_crc(0xffffffffL
, buf
, len
) ^ 0xffffffffL
;
64 unsigned char *lcd2png(unsigned char *lcd
, int *len
)
66 unsigned char screen_conv
[(WIDTH
*HEIGHT
*3)+HEIGHT
]; /* 320*234 RGB + scanline filter byte */
68 unsigned char lut
[256][3];
69 unsigned char *screen_deflated
;
71 unsigned char *image
= NULL
;
72 unsigned char *outpos
;
73 static const unsigned char png
[] = {137, 80, 78, 71, 13, 10, 26, 10};
74 static unsigned char idat
[] = {'I', 'D', 'A', 'T'};
75 static unsigned char iend
[] = {'I', 'E', 'N', 'D'};
76 static unsigned char ihdr
[] = {'I', 'H', 'D', 'R',
77 0x00, 0x00, 0x01, 0x40, /* 320 - Width */
78 0x00, 0x00, 0x00, 0xea, /* 234 - Height */
80 0x02, /* RGB Truecolor, Colour type */
81 0x00, /* Deflate, Compression method */
82 0x00, /* Adaptive, Filter method */
83 0x00 /* No interlace, Interlace method */
92 for(i
= 0; i
< 256; i
++) {
93 lut
[i
][0] = ((i
>> 6) * 0x55);
94 lut
[i
][1] = ((((i
>> 3) & 7) * 0x49) >> 1);
95 lut
[i
][2] = (((i
& 7) * 0x49) >> 1);
99 for(i
= 0; i
< (WIDTH
*HEIGHT
); i
++) {
100 if ((i
% WIDTH
) == 0) {
101 *pos
++ = 0x00; /* No adaptive filter */
103 *pos
++ = lut
[lcd
[i
]][0];
104 *pos
++ = lut
[lcd
[i
]][1];
105 *pos
++ = lut
[lcd
[i
]][2];
108 strm
.zalloc
= Z_NULL
;
110 strm
.opaque
= Z_NULL
;
111 if (deflateInit(&strm
, Z_BEST_COMPRESSION
) != Z_OK
) {
112 perror("deflateInit");
116 strm
.avail_in
= sizeof(screen_conv
);
117 strm
.next_in
= screen_conv
;
121 screen_deflated
= NULL
;
125 if (strm
.avail_out
== 0) {
127 screen_deflated
= realloc(screen_deflated
, toalloc
);
128 if (screen_deflated
== NULL
) {
133 strm
.avail_out
= CHUNK
;
134 strm
.next_out
= screen_deflated
+ (toalloc
- CHUNK
);
137 ret
= deflate(&strm
, flush
);
138 if (ret
== Z_STREAM_ERROR
) {
143 if(strm
.avail_in
== 0) {
146 } while(ret
!= Z_STREAM_END
);
147 deflated_size
= toalloc
- strm
.avail_out
;
151 image
= malloc(sizeof(png
) +
152 sizeof(ihdr
) + 8 + /* 8 = length, csum */
153 sizeof(idat
) + deflated_size
+ 8 +
163 memcpy(outpos
, png
, sizeof(png
));
164 outpos
+= sizeof(png
);
167 l
= htonl(sizeof(ihdr
) - 4); /* "IHDR" is not counted */
168 memcpy(outpos
, &l
, sizeof(l
));
170 memcpy(outpos
, ihdr
, sizeof(ihdr
));
171 outpos
+= sizeof(ihdr
);
172 l
= htonl(crc(ihdr
, sizeof(ihdr
)));
173 memcpy(outpos
, &l
, sizeof(l
));
177 l
= htonl(deflated_size
);
178 memcpy(outpos
, &l
, sizeof(l
));
180 memcpy(outpos
, idat
, sizeof(idat
));
181 outpos
+= sizeof(idat
);
182 memcpy(outpos
, screen_deflated
, deflated_size
);
183 free(screen_deflated
);
184 outpos
+=deflated_size
;
185 l
= htonl(crc(outpos
-deflated_size
-sizeof(idat
), deflated_size
+sizeof(idat
)));
186 memcpy(outpos
, &l
, sizeof(l
));
190 l
= htonl(sizeof(iend
) - 4); /* "IEND" is not counted */
191 memcpy(outpos
, &l
, sizeof(l
));
193 memcpy(outpos
, iend
, sizeof(iend
));
194 outpos
+= sizeof(iend
);
195 l
= htonl(crc(iend
, sizeof(iend
)));
196 memcpy(outpos
, &l
, sizeof(l
));
199 *len
= (int)(outpos
- image
);