]> git.zerfleddert.de Git - rigol/commitdiff
add png output for screenshots
authorMichael Gernoth <michael@gernoth.net>
Sun, 6 Jun 2010 10:10:56 +0000 (12:10 +0200)
committerMichael Gernoth <michael@gernoth.net>
Sun, 6 Jun 2010 10:10:56 +0000 (12:10 +0200)
.gitignore
png.c
rigol.c

index b8d6cba9a78ea754ddb11f919e6a8a9c9d17a8c7..7dae92ce3a6209a81413154d1003be34fe6c5bed 100644 (file)
@@ -2,3 +2,4 @@ raw2gp
 rigol
 rigol.o
 png.o
+screen_*.png
diff --git a/png.c b/png.c
index accf41540995ca4acee6274414e99790c7f0cb0f..7606f2bb5f7868895b96fd811f242f9824f175a5 100644 (file)
--- a/png.c
+++ b/png.c
@@ -7,6 +7,10 @@
 
 #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];
 
@@ -59,25 +63,30 @@ static unsigned long crc(unsigned char *buf, int len)
 
 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++) {
@@ -86,22 +95,68 @@ unsigned char *lcd2png(unsigned char *lcd, int *len)
                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);
@@ -111,7 +166,19 @@ unsigned char *lcd2png(unsigned char *lcd, int *len)
        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);
 
@@ -120,7 +187,7 @@ unsigned char *lcd2png(unsigned char *lcd, int *len)
        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);
 
diff --git a/rigol.c b/rigol.c
index 389253f7bddcc4b9412bf545a93d068c55937c76..818b7eac797ce22dad13eb170611604a7d13dd71 100644 (file)
--- a/rigol.c
+++ b/rigol.c
@@ -302,15 +302,12 @@ void do_get_buf (struct usb_dev_handle *sc)
 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 */
@@ -323,25 +320,11 @@ void do_get_screen(struct usb_dev_handle *sc)
                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(&lt));
-
-       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(&lt));
+       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);
 
@@ -357,12 +340,6 @@ void do_get_screen(struct usb_dev_handle *sc)
                default:
                        break;
        }
-
-       strftime(filename, sizeof(filename), "screen_%Y%m%d-%H%M%S.png", localtime(&lt));
-       fd=open(filename, O_CREAT|O_WRONLY, 0644);
-       png = lcd2png(screen, &i);
-       write(fd, png, i);
-       close(fd);
 }
 
 void child_reaper(int sig)
Impressum, Datenschutz