From 3df147113765d5a8ba192795d2be9b7e3e295749 Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Sun, 6 Jun 2010 03:30:31 +0200 Subject: [PATCH] beginning of png --- .gitignore | 1 + Makefile | 6 +-- png.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ png.h | 1 + rigol.c | 10 +++++ 5 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 png.c create mode 100644 png.h diff --git a/.gitignore b/.gitignore index b382455..b8d6cba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ raw2gp rigol rigol.o +png.o diff --git a/Makefile b/Makefile index 8674bf8..2c14bad 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,12 @@ CFILES=rigol.c -OFILES=rigol.o +OFILES=rigol.o png.o CFLAGS=-O2 -Wall -LDFLAGS=-lusb -lreadline +LDFLAGS=-lusb -lreadline -lz CC=gcc all: rigol raw2gp - - rigol: $(OFILES) rigol.o: rigol.c diff --git a/png.c b/png.c new file mode 100644 index 0000000..98d5993 --- /dev/null +++ b/png.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include + +#include "png.h" + +/* Table of CRCs of all 8-bit messages. */ +static unsigned long crc_table[256]; + +/* Flag: has the table been computed? Initially false. */ +static int crc_table_computed = 0; + +/* Make the table for a fast CRC. */ +static void make_crc_table(void) +{ + unsigned long c; + int n, k; + + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) + c = 0xedb88320L ^ (c >> 1); + else + c = c >> 1; + } + crc_table[n] = c; + } + crc_table_computed = 1; +} + +/* Update a running CRC with the bytes buf[0..len-1]--the CRC + should be initialized to all 1's, and the transmitted value + is the 1's complement of the final running CRC (see the + crc() routine below). */ + +static unsigned long update_crc(unsigned long crc, unsigned char *buf, + int len) +{ + unsigned long c = crc; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c; +} + +/* Return the CRC of the bytes buf[0..len-1]. */ +static unsigned long crc(unsigned char *buf, int len) +{ + return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL; +} + +unsigned char *lcd2png(unsigned char *lcd, int *len) +{ + unsigned char screen_conv[320*234*3]; + unsigned char lut[256][3]; + unsigned char *image; + unsigned char *outpos; + static const unsigned char png[] = {137, 80, 78, 71, 13, 10, 26, 10}; + 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 /* 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 toalloc = 0; + + 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[lcd[i/3]][0]; + screen_conv[i+1] = lut[lcd[i/3]][1]; + screen_conv[i+2] = lut[lcd[i/3]][2]; + } + + image = malloc(320*234*2); /* TODO: FIXME! */ + outpos = image; + memcpy(outpos, png, sizeof(png)); + outpos += sizeof(png); + + l = htonl(sizeof(ihdr) - 4); /* "IHDR" is not counted */ + memcpy(outpos, &l, sizeof(l)); + outpos += sizeof(l); + memcpy(outpos, ihdr, sizeof(ihdr)); + outpos += sizeof(ihdr); + l = crc(ihdr, sizeof(ihdr)); + memcpy(outpos, &l, sizeof(l)); + outpos += sizeof(l); + + l = htonl(sizeof(iend) - 4); /* "IEND" is not counted */ + memcpy(outpos, &l, sizeof(l)); + outpos += sizeof(l); + memcpy(outpos, iend, sizeof(iend)); + outpos += sizeof(iend); + l = crc(iend, sizeof(iend)); + memcpy(outpos, &l, sizeof(l)); + outpos += sizeof(l); + + *len = (int)(outpos - image); + return image; +} diff --git a/png.h b/png.h new file mode 100644 index 0000000..1879b71 --- /dev/null +++ b/png.h @@ -0,0 +1 @@ +unsigned char *lcd2png(unsigned char *lcd, int *len); diff --git a/rigol.c b/rigol.c index e7497ac..389253f 100644 --- a/rigol.c +++ b/rigol.c @@ -23,6 +23,8 @@ rmmod uhci_hcd; modprobe uhci_hcd #include #include +#include "png.h" + //This routine locates a scope by VID/PID and returns an opened handle to it. usb_dev_handle *find_scope() { @@ -304,8 +306,10 @@ void do_get_screen(struct usb_dev_handle *sc) unsigned char lut[256][3]; time_t lt; char filename[256]; + unsigned char *png; int i; int l; + int fd; FILE *fp; pid_t display; @@ -353,6 +357,12 @@ void do_get_screen(struct usb_dev_handle *sc) 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) -- 2.39.2