// // Vrml 97 library // Copyright (C) 1998 Chris Morley // // %W% %G% // Image.cpp #include "config.h" #include "VRMLImage.h" #include "Doc.h" #include "System.h" #include // free() #include // gif support is builtin # include "gifread.h" #if HAVE_LIBJPEG #include "jpgread.h" #endif #if HAVE_LIBPNG #include "pngread.h" #endif typedef enum { ImageFile_UNKNOWN, ImageFile_GIF, ImageFile_JPG, ImageFile_PNG } ImageFileType; static ImageFileType imageFileType(const char *, FILE *); Image::Image(const char *url, Doc *relative) : d_url(0), d_w(0), d_h(0), d_nc(0), d_pixels(0), d_frame(0) { if (url) (void) setURL(url, relative); } Image::~Image() { delete d_url; if (d_pixels) free(d_pixels); // assumes file readers use malloc... if (d_frame) free(d_frame); } bool Image::setURL(const char *url, Doc *relative) { if (d_url) delete d_url; if (d_pixels) free(d_pixels); // assumes file readers use malloc... if (d_frame) free(d_frame); d_pixels = 0; d_frame = 0; d_w = d_h = d_nc = d_nFrames = 0; if (! url) return true; d_url = new Doc(url, relative); // theSystem->debug("Image: trying to create Doc(%s, %s)\n", // url, relative ? relative->url() : ""); FILE *fp = d_url->fopen("rb"); if (fp) { switch (imageFileType(url, fp)) { case ImageFile_GIF: d_pixels = gifread(fp, &d_w, &d_h, &d_nc, &d_nFrames, &d_frame); break; #if HAVE_LIBJPEG case ImageFile_JPG: d_pixels = jpgread(fp, &d_w, &d_h, &d_nc); break; #endif #if HAVE_LIBPNG case ImageFile_PNG: d_pixels = pngread(fp, &d_w, &d_h, &d_nc); break; #endif default: fprintf(stderr,"Error: unrecognized image file format (%s).\n", url); break; } if (! d_pixels) fprintf(stderr,"Error: unable to read image file (%s).\n", url); d_url->fclose(); } return (d_pixels != 0); } bool Image::tryURLs(int nUrls, char **urls, Doc *relative) { int i; for (i=0; iurl() : 0; } // Could peek at file header... static ImageFileType imageFileType(const char *url, FILE *) { const char *suffix = strrchr(url, '.'); if (suffix) ++suffix; if (strcmp(suffix,"gif") == 0 || strcmp(suffix,"GIF") == 0) return ImageFile_GIF; else if (strcmp(suffix,"jpg") == 0 || strcmp(suffix,"JPG") == 0 || strcmp(suffix,"jpeg") == 0 || strcmp(suffix,"JPEG") == 0) return ImageFile_JPG; else if (strcmp(suffix,"png") == 0 || strcmp(suffix,"PNG") == 0) return ImageFile_PNG; else return ImageFile_UNKNOWN; } unsigned char *Image::pixels(int frame) { return (frame < d_nFrames) ? d_frame[ frame ] : 0; }