/* * file2pixmap.c * Copyright (C) 1996-1998 Teemu Maijala - uucee@sci.fi * * 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 * of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include "file2pixmap.h" #include "gif_lib.h" #ifdef USE_JPEG_LIB #include #include #endif /* Filetypes */ typedef int FILETYPE; #define UNKNOWN 0 #define GIF 1 #define JPEG 2 #define TOTAL_NUMBER_OF_FILETYPES 2 char *postfixes[2] = {".gif", ".jpg"}; FILETYPE filetypes[2] = {GIF, JPEG}; typedef unsigned long Pixel; /* function prototypes */ int load_gif_to_pixmap(char *filename, Display *display, int screennum, int *witdh, int *height, Pixmap *pixmap); int load_jpeg_to_pixmap(char *filename, Display *display, int screennum, int *witdh, int *height, Pixmap *pixmap); int gif_errorhandler(); FILETYPE filetype(char *filename); /* function definitions */ int load_file_to_pixmap(char *filename, Display *display, int screennum, int *width, int *height, Pixmap *pixmap) { switch(filetype(filename)) { #ifdef USE_JPEG_LIB case JPEG: return load_jpeg_to_pixmap(filename, display, screennum, width, height, pixmap); break; #endif case GIF: return load_gif_to_pixmap(filename, display, screennum, width, height, pixmap); break; case UNKNOWN: return NOT_VALID_FILETYPE; break; } return NOT_VALID_FILETYPE; } int load_gif_to_pixmap(char *filename, Display *display, int screennum, int *width, int *height, Pixmap *pixmap) { int startline[4] = {0, 4, 2, 1}; int offset[4] = {8, 8, 4, 2}; int x, y, i, group; unsigned char colorvalue; GifFileType *giftype; Pixel *pixels; GC gc; XImage *image; XColor color; if (!(giftype = DGifOpenFileName(filename))) return gif_errorhandler(); if (DGifSlurp(giftype)!=GIF_OK) return gif_errorhandler(); *pixmap = XCreatePixmap(display, RootWindow(display, screennum), giftype->SWidth, giftype->SHeight, DefaultDepth(display, screennum)); image = XGetImage(display, *pixmap, 0,0, giftype->SWidth, giftype->SHeight, AllPlanes, ZPixmap); gc = XCreateGC(display, *pixmap, 0, NULL); pixels = (Pixel*)malloc(sizeof(Pixel)*giftype->SColorMap->ColorCount); for(i=0;iSColorMap->ColorCount;i++) { color.red = giftype->SColorMap->Colors[i].Red*255; color.green = giftype->SColorMap->Colors[i].Green*255; color.blue = giftype->SColorMap->Colors[i].Blue*255; XAllocColor(display, DefaultColormap(display, screennum), &color); pixels[i] = color.pixel; } if (!giftype->Image.Interlace) { for(y=0;ySHeight;y++) { for(x=0;xSWidth;x++) { colorvalue = giftype->SavedImages->RasterBits[y*giftype->SWidth+x]; XPutPixel(image, x, y, pixels[colorvalue]); } } } else { for(group=0,i=0;group<4;group++) { for(y=startline[group];ySHeight;y+=offset[group],i++) { for(x=0;xSWidth;x++) { colorvalue = giftype->SavedImages->RasterBits[i*giftype->SWidth+x]; XPutPixel(image, x, y, pixels[colorvalue]); } } } } *width = giftype->SWidth; *height = giftype->SHeight; XPutImage(display, *pixmap, gc, image, 0, 0, 0, 0, giftype->SWidth, giftype->SHeight); free(pixels); DGifCloseFile(giftype); XDestroyImage(image); return LOADING_OK; } int gif_errorhandler() { PrintGifError(); switch(GifLastError()) { case D_GIF_ERR_OPEN_FAILED: return CANNOT_OPEN_FILE; break; case D_GIF_ERR_READ_FAILED: return CANNOT_READ_FILE; break; case D_GIF_ERR_NOT_GIF_FILE: return NOT_VALID_FILETYPE; break; default: return NOT_VALID_FILETYPE; break; } } #ifdef USE_JPEG_LIB int load_jpeg_to_pixmap(char *filename, Display *display, int screennum, int *width, int *height, Pixmap *pixmap) { FILE *jpegfile; GC gc; JSAMPROW scanline; Pixel *pixels; XColor color; XImage *image; int i, x, y; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; unsigned char colorvalue; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); if ((jpegfile = fopen(filename, "rb")) == NULL) return 0; jpeg_stdio_src(&cinfo, jpegfile); jpeg_read_header(&cinfo, TRUE); cinfo.quantize_colors = TRUE; /* colormap wanted */ cinfo.dither_mode = JDITHER_ORDERED; jpeg_start_decompress(&cinfo); *pixmap = XCreatePixmap(display, RootWindow(display, screennum), cinfo.output_width, cinfo.output_height, DefaultDepth(display, screennum)); image = XGetImage(display, *pixmap, 0,0, cinfo.output_width, cinfo.output_height, AllPlanes, ZPixmap); gc = XCreateGC(display, *pixmap, 0, NULL); pixels = (Pixel*)malloc(sizeof(Pixel)*cinfo.actual_number_of_colors); if (cinfo.out_color_components > 1) { for(i=0;i