1/* 2 * Buffer an Image 3 * 4 * Copyright 2007 Sascha Sommer <saschasommer@freenet.de> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 21#ifdef HAVE_CONFIG_H 22#include <config.h> 23#endif 24#include <gutenprint/gutenprint.h> 25#include "gutenprint-internal.h" 26 27struct buffered_image_priv 28{ 29 stp_image_t* image; 30 unsigned char** buf; 31 unsigned int flags; 32}; 33 34static void 35buffered_image_init(stp_image_t* image) 36{ 37 struct buffered_image_priv *priv = image->rep; 38 if(priv->image->init) 39 priv->image->init(priv->image); 40} 41 42 43static int 44buffered_image_width(stp_image_t * image) 45{ 46 struct buffered_image_priv *priv = image->rep; 47 return priv->image->width(priv->image); 48} 49 50static int 51buffered_image_height(stp_image_t * image) 52{ 53 struct buffered_image_priv *priv = image->rep; 54 return priv->image->height(priv->image); 55} 56 57static const char * 58buffered_image_get_appname(stp_image_t *image) 59{ 60 struct buffered_image_priv *priv = image->rep; 61 return priv->image->get_appname(priv->image); 62} 63 64 65static stp_image_status_t 66buffered_image_get_row(stp_image_t* image,unsigned char *data, size_t byte_limit, int row) 67{ 68 struct buffered_image_priv *priv = image->rep; 69 int width = buffered_image_width(image); 70 int height = buffered_image_height(image); 71 /* FIXME this will break with padding bytes */ 72 int bytes_per_pixel = byte_limit / width; 73 int inc = bytes_per_pixel; 74 unsigned char* src; 75 int i; 76 /* fill buffer */ 77 if(!priv->buf){ 78 priv->buf = stp_zalloc((sizeof(unsigned short*) + 1) * height); 79 if(!priv->buf){ 80 return STP_IMAGE_STATUS_ABORT; 81 } 82 for(i=0;i<height;i++){ 83 priv->buf[i] = stp_malloc(byte_limit); 84 if(STP_IMAGE_STATUS_OK != priv->image->get_row(priv->image,priv->buf[i],byte_limit,i)) 85 return STP_IMAGE_STATUS_ABORT; 86 } 87 } 88 if(priv->flags & BUFFER_FLAG_FLIP_Y) 89 row = height - row - 1; 90 91 src = priv->buf[row]; 92 93 if(priv->flags & BUFFER_FLAG_FLIP_X){ 94 src += byte_limit - bytes_per_pixel; 95 inc = -bytes_per_pixel; 96 } 97 98 /* copy data */ 99 for( i = 0 ; i < width ; i++){ 100 memcpy(data,src,bytes_per_pixel); 101 src += inc; 102 data += bytes_per_pixel; 103 } 104 return STP_IMAGE_STATUS_OK; 105} 106 107static void 108buffered_image_conclude(stp_image_t * image) 109{ 110 struct buffered_image_priv *priv = image->rep; 111 if(priv->buf){ 112 int i = 0; 113 while(priv->buf[i]){ 114 stp_free(priv->buf[i]); 115 ++i; 116 } 117 stp_free(priv->buf); 118 priv->buf = NULL; 119 } 120 if(priv->image->conclude) 121 priv->image->conclude(priv->image); 122 123 stp_free(priv); 124 stp_free(image); 125} 126 127stp_image_t* 128stpi_buffer_image(stp_image_t* image, unsigned int flags) 129{ 130 struct buffered_image_priv *priv; 131 stp_image_t* buffered_image = stp_zalloc(sizeof(stp_image_t)); 132 if(!buffered_image){ 133 return NULL; 134 } 135 priv = buffered_image->rep = stp_zalloc(sizeof(struct buffered_image_priv)); 136 if(!priv){ 137 stp_free(buffered_image); 138 return NULL; 139 } 140 141 if(image->init) 142 buffered_image->init = buffered_image_init; 143 buffered_image->width = buffered_image_width; 144 buffered_image->height = buffered_image_height; 145 buffered_image->get_row = buffered_image_get_row; 146 buffered_image->conclude = buffered_image_conclude; 147 priv->image = image; 148 priv->flags = flags; 149 if(image->get_appname) 150 buffered_image->get_appname = buffered_image_get_appname; 151 152 153 return buffered_image; 154} 155 156 157