1 /* 2 * imagesource_gdkpixbuf.cpp 3 * GdkPixbuf-based image loader 4 * Supports Random Access 5 * 6 * Copyright (c) 2004 by Alastair M. Robinson 7 * Distributed under the terms of the GNU General Public License - 8 * see the file named "COPYING" for more details. 9 * 10 * 11 */ 12 13 #include <iostream> 14 #include <stdio.h> 15 #include <stdlib.h> 16 17 #include "../support/debug.h" 18 19 #include "imagesource_gdkpixbuf.h" 20 21 using namespace std; 22 23 ~ImageSource_GdkPixbuf()24ImageSource_GdkPixbuf::~ImageSource_GdkPixbuf() 25 { 26 if(pixbuf) 27 g_object_unref(G_OBJECT(pixbuf)); 28 } 29 30 31 #define OFFSET(pb, x, y) ((x) * (gdk_pixbuf_get_n_channels(pb)) + (y) * gdk_pixbuf_get_rowstride(pb)) 32 GetRow(int row)33ISDataType *ImageSource_GdkPixbuf::GetRow(int row) 34 { 35 unsigned char *src; 36 ISDataType *dst; 37 38 if(currentrow==row) 39 return(rowbuffer); 40 41 if(row>=height) 42 { 43 Debug[WARN] << "ImageSource_GdkPixbuf - Warning: row " << row+1 << " of " << height << " requested." << endl; 44 return(rowbuffer); 45 } 46 47 src=gdk_pixbuf_get_pixels(pixbuf)+OFFSET(pixbuf,0,row); 48 dst=rowbuffer; 49 50 switch(type) 51 { 52 case IS_TYPE_RGB: 53 if(hasalpha) 54 { 55 for(int x=0;x<width;++x) 56 { 57 unsigned int r,g,b,a; 58 r=*src++; 59 g=*src++; 60 b=*src++; 61 a=*src++; 62 r=IS_SAMPLEMAX-(a*EIGHTTOIS(255-r))/255; 63 g=IS_SAMPLEMAX-(a*EIGHTTOIS(255-g))/255; 64 b=IS_SAMPLEMAX-(a*EIGHTTOIS(255-b))/255; 65 *dst++=r; 66 *dst++=g; 67 *dst++=b; 68 } 69 } 70 else 71 { 72 for(int x=0;x<width;++x) 73 { 74 unsigned int g; 75 g=*src++; 76 *dst++=EIGHTTOIS(g); 77 g=*src++; 78 *dst++=EIGHTTOIS(g); 79 g=*src++; 80 *dst++=EIGHTTOIS(g); 81 } 82 } 83 break; 84 case IS_TYPE_RGBA: 85 for(int x=0;x<width;++x) 86 { 87 unsigned int g; 88 g=*src++; 89 *dst++=EIGHTTOIS(g); 90 g=*src++; 91 *dst++=EIGHTTOIS(g); 92 g=*src++; 93 *dst++=EIGHTTOIS(g); 94 g=*src++; 95 *dst++=EIGHTTOIS(g); 96 } 97 break; 98 default: 99 throw "Only RGB pixbufs are currently supported"; 100 break; 101 } 102 103 currentrow=row; 104 return(rowbuffer); 105 } 106 107 ImageSource_GdkPixbuf(const char * filename)108ImageSource_GdkPixbuf::ImageSource_GdkPixbuf(const char *filename) : pixbuf(NULL) 109 { 110 GError *err=NULL; 111 pixbuf=gdk_pixbuf_new_from_file(filename,&err); 112 if(!pixbuf) 113 throw err->message; 114 Init(); 115 } 116 117 ImageSource_GdkPixbuf(GdkPixbuf * pixbuf)118ImageSource_GdkPixbuf::ImageSource_GdkPixbuf(GdkPixbuf *pixbuf) : pixbuf(pixbuf) 119 { 120 g_object_ref(G_OBJECT(pixbuf)); 121 Init(); 122 } 123 124 Init()125void ImageSource_GdkPixbuf::Init() 126 { 127 xres=yres=72; // FIXME - read these from the file 128 embeddedprofile=NULL; 129 130 if(gdk_pixbuf_get_colorspace(pixbuf)!=GDK_COLORSPACE_RGB) 131 throw "GdkPixbuf loader only supports RGB images!"; 132 133 if(gdk_pixbuf_get_bits_per_sample(pixbuf)!=8) 134 throw "GdxPixbuf loader doesn't yet support 16 bit images\n"\ 135 "Please contact me at blackfive@fakenhamweb.co.uk\n"\ 136 "And I'll try to add native support for this file format."; 137 138 type=IS_TYPE_RGB; 139 samplesperpixel=3; 140 141 width=gdk_pixbuf_get_width(pixbuf); 142 height=gdk_pixbuf_get_height(pixbuf); 143 rowstride=gdk_pixbuf_get_rowstride(pixbuf); 144 pixels=gdk_pixbuf_get_pixels(pixbuf); 145 hasalpha=gdk_pixbuf_get_has_alpha(pixbuf); 146 147 if(hasalpha) 148 { 149 type=IS_TYPE_RGBA; 150 ++samplesperpixel; 151 } 152 153 MakeRowBuffer(); 154 randomaccess=true; 155 } 156 157