From: Scott F. <sc...@st...> - 2009-06-22 21:32:30
|
/* $Id: widget_gif.c 1035 2009-05-19 10:42:01Z michael $ * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/widget_gif.c $ * * gif widget handling * * Copyright (C) 2003, 2004 Michael Reinelt <mi...@re...> * Copyright (C) 2004 The LCD4Linux Team <lcd...@us...> * * This program 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. * * This program 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. * */ /* * exported functions: * * WIDGET_CLASS Widget_Gif * the gif widget * */ #include "config.h" #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <FreeImage.h> #include "debug.h" #include "cfg.h" #include "qprintf.h" #include "property.h" #include "timer.h" #include "rgb.h" #include "widget.h" #include "widget_gif.h" #ifdef WITH_DMALLOC #include <dmalloc.h> #endif extern int XRES, YRES; void widget_gif_update(void *Self) { WIDGET *W = (WIDGET *) Self; WIDGET_GIF *Gif = W->data; BYTE pixel; int row, col; FIBITMAP *dib, *dib2; if(W->parent == NULL) { dib = FreeImage_LockPage(Gif->image, Gif->pagePtr); if (!dib) { error("Unable to lock gif page: %s", W->name); return; } dib2 = FreeImage_ConvertTo8Bits(dib); memset(Gif->bitmap, 0, Gif->width * Gif->height * sizeof(RGBA)); for(row = Gif->ypoint; row < Gif->ypoint + Gif->height; row++) { for(col = Gif->xpoint; col < Gif->xpoint + Gif->width; col++) { if( FreeImage_GetPixelIndex(dib2, col, row, &pixel) ) { if((int)pixel != Gif->background && (int)pixel != Gif->transparent) { // error("pixel %d, r: %d, g: %d, b: %d", pixel, Gif->palette[pixel].rgbRed, Gif->palette[pixel].rgbGreen, Gif->palette[pixel].rgbBlue ); Gif->bitmap[(Gif->height-row-1) * Gif->width + col].R = Gif->palette[pixel].rgbRed; Gif->bitmap[(Gif->height-row-1) * Gif->width + col].G = Gif->palette[pixel].rgbGreen; Gif->bitmap[(Gif->height-row-1) * Gif->width + col].B = Gif->palette[pixel].rgbBlue; Gif->bitmap[(Gif->height-row-1) * Gif->width + col].A = 255; } } } } FreeImage_UnlockPage(Gif->image, dib, FALSE); Gif->pagePtr++; if( Gif->pagePtr > Gif->end) { Gif->pagePtr = Gif->start; } property_eval(&Gif->visible); } /* finally, draw it! */ if (W->class->draw) W->class->draw(W); } int widget_gif_init(WIDGET * Self) { char *section, *file; int i; /* prepare config section */ /* strlen("Widget:")=7 */ RGBQUAD bkcolor; WIDGET_GIF *Gif; FIBITMAP *dib2; section = malloc(strlen(Self->name) + 8); strcpy(section, "Widget:"); strcat(section, Self->name); Gif = malloc(sizeof(WIDGET_GIF)); memset(Gif, 0, sizeof(WIDGET_GIF)); /* load properties */ property_load(section, "update", "200", &Gif->update); property_load(section, "visible", "1", &Gif->visible); property_eval(&Gif->update); if (Self->parent == NULL) { file = cfg_get(section, "file", NULL); if( file == NULL ) { error("You must specify a gif file: %s", Self->name); return 0; } Gif->image = FreeImage_OpenMultiBitmap(FIF_GIF, file, FALSE, TRUE, FALSE, GIF_PLAYBACK);; Gif->lastFrame = FreeImage_GetPageCount(Gif->image) - 1; FIBITMAP *dib = FreeImage_LockPage(Gif->image, 0); if( !dib ) { error("Unable to iterate gif: %s", Self->name); return 0; } dib2 = FreeImage_ConvertTo8Bits(dib); FreeImage_GetBackgroundColor(dib2, &bkcolor); Gif->background = (&bkcolor)->rgbReserved; Gif->transparent = FreeImage_GetTransparentIndex(dib2); Gif->palette = FreeImage_GetPalette(dib2); cfg_number(section, "start", 0, 0, Gif->lastFrame, &Gif->start); cfg_number(section, "end", Gif->lastFrame, 0, Gif->lastFrame, &Gif->end); cfg_number(section, "width", -1, 0, -1, &Gif->width); cfg_number(section, "height", -1, 0, -1, &Gif->height); cfg_number(section, "xpoint", 0, 0, Gif->width - 1, &Gif->xpoint); cfg_number(section, "ypoint", 0, 0, Gif->height - 1, &Gif->ypoint); Gif->pagePtr = Gif->start; if( Gif->height == -1 ) { Gif->height = FreeImage_GetHeight(dib2); } if( Gif->width == -1 ) { Gif->width = FreeImage_GetWidth(dib2); } FreeImage_UnlockPage(Gif->image, dib, FALSE); free(section); Self->data = Gif; Self->x2 = Self->col + Gif->width / XRES - 1; Self->y2 = Self->row + Gif->height / YRES - 1; /* reset ascii */ for(i = 0; i < Gif->width / XRES * Gif->height / YRES; i++) { Gif->ascii[i] = -1; } Gif->bitmap = malloc(Gif->width * Gif->height * sizeof(RGBA)); } else { Gif = Self->data = Self->parent->data; Self->x2 = Self->col + Gif->width / XRES - 1; Self->y2 = Self->row + Gif->height / YRES - 1; } /* just do it! */ timer_add(widget_gif_update, Self, P2N(&Gif->update), 0); return 0; } int widget_gif_quit(WIDGET * Self) { if (Self) { if (Self->parent == NULL ) { if (Self->data) { WIDGET_GIF *Gif = Self->data; property_free(&Gif->update); property_free(&Gif->visible); if (Gif->bitmap) free(Gif->bitmap); if (Gif->image) FreeImage_CloseMultiBitmap(Gif->image, GIF_PLAYBACK); free(Self->data); Self->data = NULL; } } } return 0; } WIDGET_CLASS Widget_Gif = { .name = "gif", .type = WIDGET_TYPE_RC, .init = widget_gif_init, .draw = NULL, .quit = widget_gif_quit, }; |