#include "png.h"
+#define CHUNK 16384
+#define WIDTH 320
+#define HEIGHT 234
+
/* Table of CRCs of all 8-bit messages. */
static unsigned long crc_table[256];
unsigned char *lcd2png(unsigned char *lcd, int *len)
{
- unsigned char screen_conv[320*234*3];
+ unsigned char screen_conv[(WIDTH*HEIGHT*3)+HEIGHT]; /* 320*234 RGB + scanline filter byte */
+ unsigned char *pos;
unsigned char lut[256][3];
+ unsigned char *screen_deflated;
+ int deflated_size;
unsigned char *image;
unsigned char *outpos;
static const unsigned char png[] = {137, 80, 78, 71, 13, 10, 26, 10};
+ static unsigned char idat[] = {'I', 'D', 'A', 'T'};
+ static unsigned char iend[] = {'I', 'E', 'N', 'D'};
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, /* Adaptive, 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 ret;
int toalloc = 0;
+ int flush;
z_stream strm;
for(i = 0; i < 256; i++) {
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];
+ pos = screen_conv;
+ for(i = 0; i < (WIDTH*HEIGHT); i++) {
+ if ((i % WIDTH) == 0) {
+ *pos++ = 0x00; /* No adaptive filter */
+ }
+ *pos++ = lut[lcd[i]][0];
+ *pos++ = lut[lcd[i]][1];
+ *pos++ = lut[lcd[i]][2];
}
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
- if (deflateInit(&strm, 9) != Z_OK) {
+ if (deflateInit(&strm, Z_BEST_COMPRESSION) != Z_OK) {
perror("deflateInit");
exit(EXIT_FAILURE);
}
+ strm.avail_in = sizeof(screen_conv);
+ strm.next_in = screen_conv;
+
+ toalloc = 0;
+ screen_deflated = NULL;
+ flush = Z_NO_FLUSH;
+
+ do {
+ if (strm.avail_out == 0) {
+ toalloc += CHUNK;
+ screen_deflated = realloc(screen_deflated, toalloc);
+ if (screen_deflated == NULL) {
+ perror("realloc");
+ exit(EXIT_FAILURE);
+ }
+
+ strm.avail_out = CHUNK;
+ strm.next_out = screen_deflated + (toalloc - CHUNK);
+ }
+
+ ret = deflate(&strm, flush);
+ if (ret == Z_STREAM_ERROR) {
+ perror("deflate");
+ exit(EXIT_FAILURE);
+ }
+
+ if(strm.avail_in == 0) {
+ flush = Z_FINISH;
+ }
+ } while(ret != Z_STREAM_END);
+ deflated_size = toalloc - strm.avail_out;
- image = malloc(320*234*2); /* TODO: FIXME! */
+ deflateEnd(&strm);
+
+
+ image = malloc(sizeof(png) +
+ sizeof(ihdr) + 8 + /* 8 = length, csum */
+ sizeof(idat) + deflated_size + 8 +
+ sizeof(iend) + 8);
+
+ if (image == NULL) {
+ perror("malloc");
+ }
+
outpos = image;
memcpy(outpos, png, sizeof(png));
outpos += sizeof(png);
outpos += sizeof(l);
memcpy(outpos, ihdr, sizeof(ihdr));
outpos += sizeof(ihdr);
- l = crc(ihdr, sizeof(ihdr));
+ l = htonl(crc(ihdr, sizeof(ihdr)));
+ memcpy(outpos, &l, sizeof(l));
+ outpos += sizeof(l);
+
+ l = htonl(deflated_size);
+ memcpy(outpos, &l, sizeof(l));
+ outpos += sizeof(l);
+ memcpy(outpos, idat, sizeof(idat));
+ outpos += sizeof(idat);
+ memcpy(outpos, screen_deflated, deflated_size);
+ free(screen_deflated);
+ outpos +=deflated_size;
+ l = htonl(crc(outpos-deflated_size-sizeof(idat), deflated_size+sizeof(idat)));
memcpy(outpos, &l, sizeof(l));
outpos += sizeof(l);
outpos += sizeof(l);
memcpy(outpos, iend, sizeof(iend));
outpos += sizeof(iend);
- l = crc(iend, sizeof(iend));
+ l = htonl(crc(iend, sizeof(iend)));
memcpy(outpos, &l, sizeof(l));
outpos += sizeof(l);
void do_get_screen(struct usb_dev_handle *sc)
{
unsigned char screen[320*234];
- unsigned char screen_conv[320*234*3];
- unsigned char lut[256][3];
time_t lt;
char filename[256];
unsigned char *png;
- int i;
+ int imglen;
int l;
int fd;
- FILE *fp;
pid_t display;
/* Hide "RMT" from screen */
printf ("hmm. didnt' get %d bytes, but %d\n\n", sizeof(screen), l);
}
- 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[screen[i/3]][0];
- screen_conv[i+1] = lut[screen[i/3]][1];
- screen_conv[i+2] = lut[screen[i/3]][2];
- }
-
- lt = time(NULL);
- strftime(filename, sizeof(filename), "screen_%Y%m%d-%H%M%S.ppm", localtime(<));
-
- fp = fopen (filename, "w");
- fprintf(fp, "P6\n320 234\n255\n");
- fwrite(screen_conv, sizeof(screen_conv), 1, fp);
- fclose (fp);
+ strftime(filename, sizeof(filename), "screen_%Y%m%d-%H%M%S.png", localtime(<));
+ fd=open(filename, O_CREAT|O_WRONLY, 0644);
+ png = lcd2png(screen, &imglen);
+ write(fd, png, imglen);
+ close(fd);
printf("Waveform saved as %s\n", filename);
default:
break;
}
-
- strftime(filename, sizeof(filename), "screen_%Y%m%d-%H%M%S.png", localtime(<));
- fd=open(filename, O_CREAT|O_WRONLY, 0644);
- png = lcd2png(screen, &i);
- write(fd, png, i);
- close(fd);
}
void child_reaper(int sig)