blob: b529d03db3fbaaa3433daaf61d90abdf165bdf35 [file] [log] [blame]
Guido van Rossumaa9de671992-03-04 16:40:03 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumaa9de671992-03-04 16:40:03 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumaa9de671992-03-04 16:40:03 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumaa9de671992-03-04 16:40:03 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumaa9de671992-03-04 16:40:03 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumaa9de671992-03-04 16:40:03 +000029
30******************************************************************/
31
Guido van Rossuma5f61381992-09-03 20:41:22 +000032/* IMGFILE module - Interface to sgi libimage */
Guido van Rossumaa9de671992-03-04 16:40:03 +000033
Guido van Rossum2c4be641992-06-03 17:06:36 +000034/* XXX This modele should be done better at some point. It should return
Guido van Rossumaa9de671992-03-04 16:40:03 +000035** an object of image file class, and have routines to manipulate these
36** image files in a neater way (so you can get rgb images off a greyscale
37** file, for instance, or do a straight display without having to get the
38** image bits into python, etc).
Jack Jansen3c2eb5c1993-01-19 15:17:13 +000039**
40** Warning: this module is very non-reentrant (esp. the readscaled stuff)
Guido van Rossumaa9de671992-03-04 16:40:03 +000041*/
42
43#include "allobjects.h"
44#include "modsupport.h"
45
46#include <gl/image.h>
Guido van Rossuma5f61381992-09-03 20:41:22 +000047#include <errno.h>
Guido van Rossumaa9de671992-03-04 16:40:03 +000048
Jack Jansen09cbf9a1993-01-19 15:33:13 +000049#include "/usr/people/4Dgifts/iristools/include/izoom.h"
Jack Jansen3c2eb5c1993-01-19 15:17:13 +000050
Guido van Rossum665f9191996-12-09 18:49:42 +000051/* Bunch of missing extern decls; keep gcc -Wall happy... */
52extern void i_seterror();
53extern void iclose();
54extern void filterzoom();
55extern void putrow();
56extern void getrow();
57
Guido van Rossuma5f61381992-09-03 20:41:22 +000058static object * ImgfileError; /* Exception we raise for various trouble */
Guido van Rossumaa9de671992-03-04 16:40:03 +000059
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000060static int top_to_bottom; /* True if we want top-to-bottom images */
Guido van Rossumaa9de671992-03-04 16:40:03 +000061
Guido van Rossuma5f61381992-09-03 20:41:22 +000062/* The image library does not always call the error hander :-(,
63 therefore we have a global variable indicating that it was called.
64 It is cleared by imgfile_open(). */
Guido van Rossumaa9de671992-03-04 16:40:03 +000065
Guido van Rossum3e941971992-03-23 18:21:32 +000066static int error_called;
67
Guido van Rossuma5f61381992-09-03 20:41:22 +000068
69/* The error handler */
70
Guido van Rossuma376cc51996-12-05 23:43:35 +000071static void
72imgfile_error(str)
Guido van Rossum3e941971992-03-23 18:21:32 +000073 char *str;
74{
75 err_setstr(ImgfileError, str);
76 error_called = 1;
Guido van Rossum9bfef441993-03-29 10:43:31 +000077 return; /* To imglib, which will return a failure indicator */
Guido van Rossum3e941971992-03-23 18:21:32 +000078}
Guido van Rossumaa9de671992-03-04 16:40:03 +000079
Guido van Rossuma5f61381992-09-03 20:41:22 +000080
81/* Open an image file and return a pointer to it.
82 Make sure we raise an exception if we fail. */
83
84static IMAGE *
Guido van Rossum2c4be641992-06-03 17:06:36 +000085imgfile_open(fname)
Guido van Rossumaa9de671992-03-04 16:40:03 +000086 char *fname;
Guido van Rossum2c4be641992-06-03 17:06:36 +000087{
Guido van Rossuma5f61381992-09-03 20:41:22 +000088 IMAGE *image;
Guido van Rossum3e941971992-03-23 18:21:32 +000089 i_seterror(imgfile_error);
90 error_called = 0;
Guido van Rossuma5f61381992-09-03 20:41:22 +000091 errno = 0;
92 if ( (image = iopen(fname, "r")) == NULL ) {
Guido van Rossum3e941971992-03-23 18:21:32 +000093 /* Error may already be set by imgfile_error */
Guido van Rossuma5f61381992-09-03 20:41:22 +000094 if ( !error_called ) {
95 if (errno)
96 err_errno(ImgfileError);
97 else
98 err_setstr(ImgfileError, "Can't open image file");
99 }
100 return NULL;
Guido van Rossumaa9de671992-03-04 16:40:03 +0000101 }
Guido van Rossuma5f61381992-09-03 20:41:22 +0000102 return image;
Guido van Rossumaa9de671992-03-04 16:40:03 +0000103}
104
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000105static object *
106imgfile_ttob(self, args)
107 object *self;
108 object *args;
109{
110 int newval;
111 object *rv;
112
113 if (!getargs(args, "i", &newval))
114 return NULL;
115 rv = newintobject(top_to_bottom);
116 top_to_bottom = newval;
117 return rv;
118}
Guido van Rossuma5f61381992-09-03 20:41:22 +0000119
Guido van Rossumaa9de671992-03-04 16:40:03 +0000120static object *
121imgfile_read(self, args)
122 object *self;
123 object *args;
124{
125 char *fname;
126 object *rv;
127 int xsize, ysize, zsize;
128 char *cdatap;
129 long *idatap;
130 static short rs[8192], gs[8192], bs[8192];
131 int x, y;
Guido van Rossuma5f61381992-09-03 20:41:22 +0000132 IMAGE *image;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000133 int yfirst, ylast, ystep;
134
Guido van Rossum2c4be641992-06-03 17:06:36 +0000135 if ( !getargs(args, "s", &fname) )
Guido van Rossuma5f61381992-09-03 20:41:22 +0000136 return NULL;
Guido van Rossum2c4be641992-06-03 17:06:36 +0000137
Guido van Rossuma5f61381992-09-03 20:41:22 +0000138 if ( (image = imgfile_open(fname)) == NULL )
Guido van Rossumaa9de671992-03-04 16:40:03 +0000139 return NULL;
140
141 if ( image->colormap != CM_NORMAL ) {
Guido van Rossuma5f61381992-09-03 20:41:22 +0000142 iclose(image);
Guido van Rossumaa9de671992-03-04 16:40:03 +0000143 err_setstr(ImgfileError, "Can only handle CM_NORMAL images");
144 return NULL;
145 }
146 if ( BPP(image->type) != 1 ) {
Guido van Rossuma5f61381992-09-03 20:41:22 +0000147 iclose(image);
148 err_setstr(ImgfileError, "Can't handle imgfiles with bpp!=1");
Guido van Rossumaa9de671992-03-04 16:40:03 +0000149 return NULL;
150 }
151 xsize = image->xsize;
152 ysize = image->ysize;
153 zsize = image->zsize;
154 if ( zsize != 1 && zsize != 3) {
Guido van Rossuma5f61381992-09-03 20:41:22 +0000155 iclose(image);
Guido van Rossumaa9de671992-03-04 16:40:03 +0000156 err_setstr(ImgfileError, "Can only handle 1 or 3 byte pixels");
157 return NULL;
158 }
Guido van Rossuma5f61381992-09-03 20:41:22 +0000159 if ( xsize > 8192 ) {
160 iclose(image);
161 err_setstr(ImgfileError, "Can't handle image with > 8192 columns");
162 return NULL;
163 }
Guido van Rossumaa9de671992-03-04 16:40:03 +0000164
165 if ( zsize == 3 ) zsize = 4;
Guido van Rossuma5f61381992-09-03 20:41:22 +0000166 rv = newsizedstringobject((char *)NULL, xsize*ysize*zsize);
167 if ( rv == NULL ) {
168 iclose(image);
Guido van Rossumaa9de671992-03-04 16:40:03 +0000169 return NULL;
Guido van Rossuma5f61381992-09-03 20:41:22 +0000170 }
Guido van Rossumaa9de671992-03-04 16:40:03 +0000171 cdatap = getstringvalue(rv);
172 idatap = (long *)cdatap;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000173
174 if (top_to_bottom) {
175 yfirst = ysize-1;
176 ylast = -1;
177 ystep = -1;
178 } else {
179 yfirst = 0;
180 ylast = ysize;
181 ystep = 1;
182 }
183 for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
Guido van Rossumaa9de671992-03-04 16:40:03 +0000184 if ( zsize == 1 ) {
185 getrow(image, rs, y, 0);
186 for(x=0; x<xsize; x++ )
187 *cdatap++ = rs[x];
188 } else {
189 getrow(image, rs, y, 0);
190 getrow(image, gs, y, 1);
191 getrow(image, bs, y, 2);
192 for(x=0; x<xsize; x++ )
193 *idatap++ = (rs[x] & 0xff) |
194 ((gs[x] & 0xff)<<8) |
195 ((bs[x] & 0xff)<<16);
196 }
197 }
Jack Jansen3accf981992-08-20 11:54:27 +0000198 iclose(image);
Guido van Rossum3e941971992-03-23 18:21:32 +0000199 if ( error_called ) {
200 DECREF(rv);
201 return NULL;
202 }
Guido van Rossumaa9de671992-03-04 16:40:03 +0000203 return rv;
204}
205
Guido van Rossum234f9421993-06-17 12:35:49 +0000206static IMAGE *glob_image;
207static long *glob_datap;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000208static int glob_width, glob_z, glob_ysize;
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000209
Guido van Rossuma376cc51996-12-05 23:43:35 +0000210static void
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000211xs_get(buf, y)
212 short *buf;
213 int y;
214{
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000215 if (top_to_bottom)
216 getrow(glob_image, buf, (glob_ysize-1-y), glob_z);
217 else
218 getrow(glob_image, buf, y, glob_z);
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000219}
220
Guido van Rossuma376cc51996-12-05 23:43:35 +0000221static void
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000222xs_put_c(buf, y)
223 short *buf;
224 int y;
225{
226 char *datap = (char *)glob_datap + y*glob_width;
227 int width = glob_width;
228
229 while ( width-- )
230 *datap++ = (*buf++) & 0xff;
231}
232
Guido van Rossuma376cc51996-12-05 23:43:35 +0000233static void
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000234xs_put_0(buf, y)
235 short *buf;
236 int y;
237{
238 long *datap = glob_datap + y*glob_width;
239 int width = glob_width;
240
241 while ( width-- )
242 *datap++ = (*buf++) & 0xff;
243}
Guido van Rossuma376cc51996-12-05 23:43:35 +0000244static void
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000245xs_put_12(buf, y)
246 short *buf;
247 int y;
248{
249 long *datap = glob_datap + y*glob_width;
250 int width = glob_width;
251
252 while ( width-- )
253 *datap++ |= ((*buf++) & 0xff) << (glob_z*8);
254}
255
256static void
257xscale(image, xsize, ysize, zsize, datap, xnew, ynew, fmode, blur)
258 IMAGE *image;
259 int xsize, ysize, zsize;
260 long *datap;
261 int xnew, ynew;
262 int fmode;
263 double blur;
264{
265 glob_image = image;
266 glob_datap = datap;
267 glob_width = xnew;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000268 glob_ysize = ysize;
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000269 if ( zsize == 1 ) {
270 glob_z = 0;
271 filterzoom(xs_get, xs_put_c, xsize, ysize, xnew, ynew, fmode, blur);
272 } else {
273 glob_z = 0;
274 filterzoom(xs_get, xs_put_0, xsize, ysize, xnew, ynew, fmode, blur);
275 glob_z = 1;
276 filterzoom(xs_get, xs_put_12, xsize, ysize, xnew, ynew, fmode, blur);
277 glob_z = 2;
278 filterzoom(xs_get, xs_put_12, xsize, ysize, xnew, ynew, fmode, blur);
279 }
280}
281
Guido van Rossuma5f61381992-09-03 20:41:22 +0000282
Guido van Rossumaa9de671992-03-04 16:40:03 +0000283static object *
Guido van Rossum2c4be641992-06-03 17:06:36 +0000284imgfile_readscaled(self, args)
285 object *self;
286 object *args;
287{
288 char *fname;
289 object *rv;
290 int xsize, ysize, zsize;
291 char *cdatap;
292 long *idatap;
293 static short rs[8192], gs[8192], bs[8192];
294 int x, y;
295 int xwtd, ywtd, xorig, yorig;
296 float xfac, yfac;
297 int cnt;
Guido van Rossuma5f61381992-09-03 20:41:22 +0000298 IMAGE *image;
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000299 char *filter;
300 double blur;
301 int extended;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000302 int fmode = 0;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000303 int yfirst, ylast, ystep;
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000304
305 /*
306 ** Parse args. Funny, since arg 4 and 5 are optional
307 ** (filter name and blur factor). Also, 4 or 5 arguments indicates
308 ** extended scale algorithm in stead of simple-minded pixel drop/dup.
309 */
310 extended = 0;
311 cnt = gettuplesize(args);
312 if ( cnt == 5 ) {
313 extended = 1;
314 if ( !getargs(args, "(siisd)", &fname, &xwtd, &ywtd, &filter, &blur) )
315 return NULL;
316 } else if ( cnt == 4 ) {
317 extended = 1;
318 if ( !getargs(args, "(siis)", &fname, &xwtd, &ywtd, &filter) )
319 return NULL;
320 blur = 1.0;
321 } else if ( !getargs(args, "(sii)", &fname, &xwtd, &ywtd) )
Guido van Rossuma5f61381992-09-03 20:41:22 +0000322 return NULL;
Guido van Rossum2c4be641992-06-03 17:06:36 +0000323
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000324 /*
325 ** Check parameters, open file and check type, rows, etc.
326 */
327 if ( extended ) {
328 if ( strcmp(filter, "impulse") == 0 ) fmode = IMPULSE;
329 else if ( strcmp( filter, "box") == 0 ) fmode = BOX;
330 else if ( strcmp( filter, "triangle") == 0 ) fmode = TRIANGLE;
331 else if ( strcmp( filter, "quadratic") == 0 ) fmode = QUADRATIC;
332 else if ( strcmp( filter, "gaussian") == 0 ) fmode = GAUSSIAN;
333 else {
334 err_setstr(ImgfileError, "Unknown filter type");
335 return NULL;
336 }
337 }
338
Guido van Rossuma5f61381992-09-03 20:41:22 +0000339 if ( (image = imgfile_open(fname)) == NULL )
Guido van Rossum2c4be641992-06-03 17:06:36 +0000340 return NULL;
341
342 if ( image->colormap != CM_NORMAL ) {
Guido van Rossuma5f61381992-09-03 20:41:22 +0000343 iclose(image);
Guido van Rossum2c4be641992-06-03 17:06:36 +0000344 err_setstr(ImgfileError, "Can only handle CM_NORMAL images");
345 return NULL;
346 }
347 if ( BPP(image->type) != 1 ) {
Guido van Rossuma5f61381992-09-03 20:41:22 +0000348 iclose(image);
349 err_setstr(ImgfileError, "Can't handle imgfiles with bpp!=1");
Guido van Rossum2c4be641992-06-03 17:06:36 +0000350 return NULL;
351 }
352 xsize = image->xsize;
353 ysize = image->ysize;
354 zsize = image->zsize;
355 if ( zsize != 1 && zsize != 3) {
Guido van Rossuma5f61381992-09-03 20:41:22 +0000356 iclose(image);
Guido van Rossum2c4be641992-06-03 17:06:36 +0000357 err_setstr(ImgfileError, "Can only handle 1 or 3 byte pixels");
358 return NULL;
359 }
Guido van Rossuma5f61381992-09-03 20:41:22 +0000360 if ( xsize > 8192 ) {
361 iclose(image);
362 err_setstr(ImgfileError, "Can't handle image with > 8192 columns");
363 return NULL;
364 }
Guido van Rossum2c4be641992-06-03 17:06:36 +0000365
366 if ( zsize == 3 ) zsize = 4;
367 rv = newsizedstringobject(NULL, xwtd*ywtd*zsize);
Guido van Rossuma5f61381992-09-03 20:41:22 +0000368 if ( rv == NULL ) {
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000369 iclose(image);
370 return NULL;
Guido van Rossuma5f61381992-09-03 20:41:22 +0000371 }
Guido van Rossum2c4be641992-06-03 17:06:36 +0000372 xfac = (float)xsize/(float)xwtd;
373 yfac = (float)ysize/(float)ywtd;
Guido van Rossum2c4be641992-06-03 17:06:36 +0000374 cdatap = getstringvalue(rv);
375 idatap = (long *)cdatap;
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000376
377 if ( extended ) {
378 xscale(image, xsize, ysize, zsize, idatap, xwtd, ywtd, fmode, blur);
379 } else {
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000380 if (top_to_bottom) {
381 yfirst = ywtd-1;
382 ylast = -1;
383 ystep = -1;
384 } else {
385 yfirst = 0;
386 ylast = ywtd;
387 ystep = 1;
388 }
389 for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000390 yorig = (int)(y*yfac);
391 if ( zsize == 1 ) {
392 getrow(image, rs, yorig, 0);
393 for(x=0; x<xwtd; x++ ) {
394 *cdatap++ = rs[(int)(x*xfac)];
395 }
396 } else {
397 getrow(image, rs, yorig, 0);
398 getrow(image, gs, yorig, 1);
399 getrow(image, bs, yorig, 2);
400 for(x=0; x<xwtd; x++ ) {
401 xorig = (int)(x*xfac);
402 *idatap++ = (rs[xorig] & 0xff) |
403 ((gs[xorig] & 0xff)<<8) |
404 ((bs[xorig] & 0xff)<<16);
405 }
406 }
Guido van Rossum2c4be641992-06-03 17:06:36 +0000407 }
408 }
Guido van Rossuma5f61381992-09-03 20:41:22 +0000409 iclose(image);
Guido van Rossum2c4be641992-06-03 17:06:36 +0000410 if ( error_called ) {
411 DECREF(rv);
412 return NULL;
413 }
414 return rv;
415}
416
417static object *
Guido van Rossumaa9de671992-03-04 16:40:03 +0000418imgfile_getsizes(self, args)
419 object *self;
420 object *args;
421{
422 char *fname;
423 object *rv;
Guido van Rossuma5f61381992-09-03 20:41:22 +0000424 IMAGE *image;
Guido van Rossumaa9de671992-03-04 16:40:03 +0000425
Guido van Rossum2c4be641992-06-03 17:06:36 +0000426 if ( !getargs(args, "s", &fname) )
Guido van Rossuma5f61381992-09-03 20:41:22 +0000427 return NULL;
Guido van Rossum2c4be641992-06-03 17:06:36 +0000428
Guido van Rossuma5f61381992-09-03 20:41:22 +0000429 if ( (image = imgfile_open(fname)) == NULL )
Guido van Rossumaa9de671992-03-04 16:40:03 +0000430 return NULL;
Guido van Rossuma5f61381992-09-03 20:41:22 +0000431 rv = mkvalue("(iii)", image->xsize, image->ysize, image->zsize);
432 iclose(image);
Guido van Rossumaa9de671992-03-04 16:40:03 +0000433 return rv;
434}
435
Jack Jansen3accf981992-08-20 11:54:27 +0000436static object *
437imgfile_write(self, args)
438 object *self;
439 object *args;
440{
441 IMAGE *image;
442 char *fname;
443 int xsize, ysize, zsize, len;
444 char *cdatap;
445 long *idatap;
446 short rs[8192], gs[8192], bs[8192];
447 short r, g, b;
448 long rgb;
449 int x, y;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000450 int yfirst, ylast, ystep;
451
Jack Jansen3accf981992-08-20 11:54:27 +0000452
453 if ( !getargs(args, "(ss#iii)",
454 &fname, &cdatap, &len, &xsize, &ysize, &zsize) )
Guido van Rossuma5f61381992-09-03 20:41:22 +0000455 return NULL;
Jack Jansen3accf981992-08-20 11:54:27 +0000456
457 if ( zsize != 1 && zsize != 3 ) {
458 err_setstr(ImgfileError, "Can only handle 1 or 3 byte pixels");
Guido van Rossuma5f61381992-09-03 20:41:22 +0000459 return NULL;
Jack Jansen3accf981992-08-20 11:54:27 +0000460 }
Guido van Rossuma5f61381992-09-03 20:41:22 +0000461 if ( len != xsize * ysize * (zsize == 1 ? 1 : 4) ) {
Jack Jansen3accf981992-08-20 11:54:27 +0000462 err_setstr(ImgfileError, "Data does not match sizes");
Guido van Rossuma5f61381992-09-03 20:41:22 +0000463 return NULL;
464 }
465 if ( xsize > 8192 ) {
466 err_setstr(ImgfileError, "Can't handle image with > 8192 columns");
467 return NULL;
Jack Jansen3accf981992-08-20 11:54:27 +0000468 }
469
Guido van Rossuma5f61381992-09-03 20:41:22 +0000470 error_called = 0;
471 errno = 0;
Jack Jansen3accf981992-08-20 11:54:27 +0000472 image =iopen(fname, "w", RLE(1), 3, xsize, ysize, zsize);
473 if ( image == 0 ) {
Guido van Rossuma5f61381992-09-03 20:41:22 +0000474 if ( ! error_called ) {
475 if (errno)
476 err_errno(ImgfileError);
477 else
478 err_setstr(ImgfileError, "Can't create image file");
479 }
480 return NULL;
Jack Jansen3accf981992-08-20 11:54:27 +0000481 }
482
483 idatap = (long *)cdatap;
484
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000485 if (top_to_bottom) {
486 yfirst = ysize-1;
487 ylast = -1;
488 ystep = -1;
489 } else {
490 yfirst = 0;
491 ylast = ysize;
492 ystep = 1;
493 }
494 for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
Jack Jansen3accf981992-08-20 11:54:27 +0000495 if ( zsize == 1 ) {
496 for( x=0; x<xsize; x++ )
497 rs[x] = *cdatap++;
498 putrow(image, rs, y, 0);
499 } else {
500 for( x=0; x<xsize; x++ ) {
501 rgb = *idatap++;
502 r = rgb & 0xff;
503 g = (rgb >> 8 ) & 0xff;
504 b = (rgb >> 16 ) & 0xff;
505 rs[x] = r;
506 gs[x] = g;
507 bs[x] = b;
508 }
509 putrow(image, rs, y, 0);
510 putrow(image, gs, y, 1);
511 putrow(image, bs, y, 2);
512 }
513 }
514 iclose(image);
515 if ( error_called )
Guido van Rossuma5f61381992-09-03 20:41:22 +0000516 return NULL;
Jack Jansen3accf981992-08-20 11:54:27 +0000517 INCREF(None);
518 return None;
519
520}
Guido van Rossumaa9de671992-03-04 16:40:03 +0000521
Guido van Rossuma5f61381992-09-03 20:41:22 +0000522
Guido van Rossumaa9de671992-03-04 16:40:03 +0000523static struct methodlist imgfile_methods[] = {
Guido van Rossum2c4be641992-06-03 17:06:36 +0000524 { "getsizes", imgfile_getsizes },
525 { "read", imgfile_read },
Jack Jansen3c2eb5c1993-01-19 15:17:13 +0000526 { "readscaled", imgfile_readscaled, 1},
Jack Jansen3accf981992-08-20 11:54:27 +0000527 { "write", imgfile_write },
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000528 { "ttob", imgfile_ttob },
Guido van Rossuma5f61381992-09-03 20:41:22 +0000529 { NULL, NULL } /* Sentinel */
Guido van Rossumaa9de671992-03-04 16:40:03 +0000530};
531
532
533void
534initimgfile()
535{
536 object *m, *d;
537 m = initmodule("imgfile", imgfile_methods);
538 d = getmoduledict(m);
539 ImgfileError = newstringobject("imgfile.error");
Guido van Rossuma5f61381992-09-03 20:41:22 +0000540 if ( ImgfileError == NULL || dictinsert(d, "error", ImgfileError) )
Guido van Rossumaa9de671992-03-04 16:40:03 +0000541 fatal("can't define imgfile.error");
542}