From c5e2e9afcd9e73b81344a55000c0f5235babe4a6 Mon Sep 17 00:00:00 2001 From: reinelt Date: Tue, 25 May 2004 14:27:21 +0000 Subject: [lcd4linux @ 2004-05-25 14:27:21 by reinelt] added drv_Image.c (this time really!) git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@431 3ae390bd-cb1e-0410-b409-cd5a39f66f1f --- drv_Image.c | 506 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 506 insertions(+) create mode 100644 drv_Image.c (limited to 'drv_Image.c') diff --git a/drv_Image.c b/drv_Image.c new file mode 100644 index 0000000..43f4192 --- /dev/null +++ b/drv_Image.c @@ -0,0 +1,506 @@ +/* $Id: drv_Image.c,v 1.1 2004/05/25 14:27:21 reinelt Exp $ + * + * new style Image (PPM/PNG) Driver for LCD4Linux + * + * Copyright 1999-2004 Michael Reinelt + * Copyright 2004 The LCD4Linux Team + * + * This file is part of LCD4Linux. + * + * LCD4Linux is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * LCD4Linux is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * $Log: drv_Image.c,v $ + * Revision 1.1 2004/05/25 14:27:21 reinelt + * + * added drv_Image.c (this time really!) + * + */ + +/* + * + * exported fuctions: + * + * struct DRIVER drv_Image + * + */ + + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_PNG +#ifdef HAVE_GD_GD_H +#include +#else +#ifdef HAVE_GD_H +#include +#else +#error "gd.h not found!" +#error "cannot compile PNG driver" +#endif +#endif +#endif + + +#include "debug.h" +#include "cfg.h" +#include "timer.h" +#include "qprintf.h" +#include "plugin.h" +#include "widget.h" +#include "widget_text.h" +#include "widget_icon.h" +#include "widget_bar.h" +#include "drv.h" +#include "drv_generic_graphic.h" + +#ifdef WITH_DMALLOC +#include +#endif + +static char Name[]="Image"; + +static enum {PPM, PNG} Format; + +static unsigned int fg_col, bg_col, hg_col; + +static int pixel = -1; // pointsize in pixel +static int pgap = 0; // gap between points +static int rgap = 0; // row gap between lines +static int cgap = 0; // column gap between characters +static int border = 0; // window border + +static int dimx, dimy; // total window dimension in pixel + +static unsigned char *drv_IMG_FB = NULL; + +static int dirty = 1; + +// **************************************** +// *** hardware dependant functions *** +// **************************************** + +#ifdef WITH_PPM +static int drv_IMG_flush_PPM (void) +{ + static int seq=0; + static unsigned char *bitbuf=NULL; + static unsigned char *rowbuf=NULL; + int xsize, ysize, row, col; + unsigned char R[3], G[3], B[3]; + char path[256], tmp[256], buffer[256]; + int fd; + + xsize = 2*border + (DCOLS/XRES-1)*cgap + DCOLS*pixel + (DCOLS-1)*pgap; + ysize = 2*border + (DROWS/YRES-1)*rgap + DROWS*pixel + (DROWS-1)*pgap; + + if (bitbuf == NULL) { + if ((bitbuf = malloc(xsize*ysize*sizeof(*bitbuf))) == NULL) { + error ("%s: malloc(%d) failed: %s", Name, xsize*ysize*sizeof(*bitbuf), strerror(errno)); + return -1; + } + } + + if (rowbuf == NULL) { + if ((rowbuf = malloc(3*xsize*sizeof(*rowbuf))) == NULL) { + error ("Raster: malloc(%d) failed: %s", 3*xsize*sizeof(*rowbuf), strerror(errno)); + return -1; + } + } + + memset (bitbuf, 0, xsize*ysize*sizeof(*bitbuf)); + + for (row = 0; row < DROWS; row++) { + int y = border + (row/YRES)*rgap + row*(pixel+pgap); + for (col = 0; col < DCOLS; col++) { + int x = border + (col/XRES)*cgap + col*(pixel+pgap); + int a, b; + for (a = 0; a < pixel; a++) + for (b = 0; b < pixel; b++) + bitbuf[y*xsize+x+a*xsize+b] = drv_IMG_FB[row*DCOLS+col]+1; + } + } + + snprintf (path, sizeof(path), output, seq++); + qprintf(tmp, sizeof(tmp), "%s.tmp", path); + + if ((fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, 0644))<0) { + error ("%s: open(%s) failed: %s", Name, tmp, strerror(errno)); + return -1; + } + + qprintf(buffer, sizeof(buffer), "P6\n%d %d\n255\n", xsize, ysize); + if (write (fd, buffer, strlen(buffer)) < 0) { + error ("%s: write(%s) failed: %s", Name, tmp, strerror(errno)); + return -1; + } + + R[0] = 0xff & bg_col>>16; + G[0] = 0xff & bg_col>>8; + B[0] = 0xff & bg_col; + + R[1] = 0xff & hg_col>>16; + G[1] = 0xff & hg_col>>8; + B[1] = 0xff & hg_col; + + R[2] = 0xff & fg_col>>16; + G[2] = 0xff & fg_col>>8; + B[2] = 0xff & fg_col; + + for (row = 0; row < ysize; row++) { + int c = 0; + for (col = 0; col < xsize; col++) { + int i = bitbuf[row*xsize+col]; + rowbuf[c++] = R[i]; + rowbuf[c++] = G[i]; + rowbuf[c++] = B[i]; + } + if (write (fd, rowbuf, c) < 0) { + error ("%s: write(%s) failed: %s", Name, tmp, strerror(errno)); + break; + } + } + + if (close (fd) < 0) { + error ("%s: close(%s) failed: %s", Name, tmp, strerror(errno)); + return -1; + } + if (rename (tmp, path)<0) { + error ("%s: rename(%s) failed: %s", Name, tmp, strerror(errno)); + return -1; + } + + return 0; +} +#endif + +#ifdef WITH_PNG +static int drv_IMG_flush_PNG (void) +{ + static int seq = 0; + int xsize, ysize, row, col; + char path[256], tmp[256]; + FILE *fp; + gdImagePtr im; + int bg, hg, fg; + + xsize = 2*border + (DCOLS/XRES-1)*cgap + DCOLS*pixel + (DCOLS-1)*pgap; + ysize = 2*border + (DROWS/YRES-1)*rgap + DROWS*pixel + (DROWS-1)*pgap; + + im = gdImageCreate(xsize, ysize); + + /* first color = background */ + bg = gdImageColorAllocate(im, + 0xff & bg_col>>16, + 0xff & bg_col>>8, + 0xff & bg_col); + + hg = gdImageColorAllocate(im, + 0xff & hg_col>>16, + 0xff & hg_col>>8, + 0xff & hg_col); + + + fg = gdImageColorAllocate(im, + 0xff & fg_col>>16, + 0xff & fg_col>>8, + 0xff & fg_col); + + + for (row = 0; row < DROWS; row++) { + int y = border + (row/YRES)*rgap + row*(pixel+pgap); + for (col = 0; col < DCOLS; col++) { + int x = border + (col/XRES)*cgap + col*(pixel+pgap); + gdImageFilledRectangle(im, x, y, x + pixel - 1 , y + pixel - 1, + drv_IMG_FB[row*DCOLS+col]? fg : hg); + } + } + + snprintf (path, sizeof(path), output, seq++); + qprintf (tmp, sizeof(tmp), "%s.tmp", path); + + if ((fp = fopen(tmp, "w")) == NULL) { + error("%s: fopen(%s) failed: %s\n", Name, tmp, strerror(errno)); + return -1; + } + + gdImagePng(im, fp); + gdImageDestroy(im); + + + if (fclose (fp) != 0) { + error("%s: fclose(%s) failed: %s\n", Name, tmp, strerror(errno)); + return -1; + } + + if (rename (tmp, path) < 0) { + error("%s: rename(%s) failed: %s\n", Name, tmp, strerror(errno)); + return -1; + } + + return 0; +} +#endif + + +static void drv_IMG_flush (void) +{ + switch (Format) { + case PPM: + drv_IMG_flush_PPM(); + break; + case PNG: + drv_IMG_flush_PNG(); + break; + } +} + + +static void drv_IMG_timer (void *notused) +{ + if (dirty) { + drv_IMG_flush(); + dirty = 0; + } +} + + +static void drv_IMG_blit(int row, int col, int height, int width) +{ + int r, c; + + for (r=row; r