blob: bccfe85ca4c26820df638b43c543a833c74310f3 [file] [log] [blame]
Guido van Rossumaa9de671992-03-04 16:40:03 +00001/***********************************************************
Guido van Rossumbab9d031992-04-05 14:26:55 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumaa9de671992-03-04 16:40:03 +00003Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* IMGFILE module - Interface to sgi libimg */
26
Guido van Rossum2c4be641992-06-03 17:06:36 +000027/* XXX This modele should be done better at some point. It should return
Guido van Rossumaa9de671992-03-04 16:40:03 +000028** an object of image file class, and have routines to manipulate these
29** image files in a neater way (so you can get rgb images off a greyscale
30** file, for instance, or do a straight display without having to get the
31** image bits into python, etc).
32*/
33
34#include "allobjects.h"
35#include "modsupport.h"
36
37#include <gl/image.h>
38
39/* #include "sigtype.h" */
40
41static object * ImgfileError;
42
43static char gfname[1024];
44static IMAGE *image;
45
Guido van Rossum3e941971992-03-23 18:21:32 +000046static int error_called;
47
48static imgfile_error(str)
49 char *str;
50{
51 err_setstr(ImgfileError, str);
52 error_called = 1;
53 return; /* To imglib, which will return a failure indictaor */
54}
Guido van Rossumaa9de671992-03-04 16:40:03 +000055
56static
Guido van Rossum2c4be641992-06-03 17:06:36 +000057imgfile_open(fname)
Guido van Rossumaa9de671992-03-04 16:40:03 +000058 char *fname;
Guido van Rossum2c4be641992-06-03 17:06:36 +000059{
Guido van Rossum3e941971992-03-23 18:21:32 +000060 i_seterror(imgfile_error);
61 error_called = 0;
Guido van Rossumaa9de671992-03-04 16:40:03 +000062 if ( image != NULL && strcmp(fname, gfname) != 0 ) {
63 iclose(image);
64 image = NULL;
65 gfname[0] = '\0';
66 }
67 if ( (image=iopen(fname, "r")) == NULL ) {
Guido van Rossum3e941971992-03-23 18:21:32 +000068 /* Error may already be set by imgfile_error */
69 if ( !error_called )
70 err_setstr(ImgfileError, "Cannot open image file");
Guido van Rossumaa9de671992-03-04 16:40:03 +000071 return 0;
72 }
73 strcpy(gfname, fname);
74 return 1;
75}
76
77static object *
78imgfile_read(self, args)
79 object *self;
80 object *args;
81{
82 char *fname;
83 object *rv;
84 int xsize, ysize, zsize;
85 char *cdatap;
86 long *idatap;
87 static short rs[8192], gs[8192], bs[8192];
88 int x, y;
89
Guido van Rossum2c4be641992-06-03 17:06:36 +000090 if ( !getargs(args, "s", &fname) )
91 return 0;
92
93 if ( !imgfile_open(fname) )
Guido van Rossumaa9de671992-03-04 16:40:03 +000094 return NULL;
95
96 if ( image->colormap != CM_NORMAL ) {
97 err_setstr(ImgfileError, "Can only handle CM_NORMAL images");
98 return NULL;
99 }
100 if ( BPP(image->type) != 1 ) {
101 err_setstr(ImgfileError, "Cannot handle imgfiles with bpp!=1");
102 return NULL;
103 }
104 xsize = image->xsize;
105 ysize = image->ysize;
106 zsize = image->zsize;
107 if ( zsize != 1 && zsize != 3) {
108 err_setstr(ImgfileError, "Can only handle 1 or 3 byte pixels");
109 return NULL;
110 }
111
112 if ( zsize == 3 ) zsize = 4;
113 rv = newsizedstringobject(NULL, xsize*ysize*zsize);
114 if ( rv == NULL )
115 return NULL;
116 cdatap = getstringvalue(rv);
117 idatap = (long *)cdatap;
Guido van Rossum3e941971992-03-23 18:21:32 +0000118 for ( y=0; y < ysize && !error_called; y++ ) {
Guido van Rossumaa9de671992-03-04 16:40:03 +0000119 if ( zsize == 1 ) {
120 getrow(image, rs, y, 0);
121 for(x=0; x<xsize; x++ )
122 *cdatap++ = rs[x];
123 } else {
124 getrow(image, rs, y, 0);
125 getrow(image, gs, y, 1);
126 getrow(image, bs, y, 2);
127 for(x=0; x<xsize; x++ )
128 *idatap++ = (rs[x] & 0xff) |
129 ((gs[x] & 0xff)<<8) |
130 ((bs[x] & 0xff)<<16);
131 }
132 }
Jack Jansen3accf981992-08-20 11:54:27 +0000133 iclose(image);
Guido van Rossum3e941971992-03-23 18:21:32 +0000134 if ( error_called ) {
135 DECREF(rv);
136 return NULL;
137 }
Guido van Rossumaa9de671992-03-04 16:40:03 +0000138 return rv;
139}
140
141static object *
Guido van Rossum2c4be641992-06-03 17:06:36 +0000142imgfile_readscaled(self, args)
143 object *self;
144 object *args;
145{
146 char *fname;
147 object *rv;
148 int xsize, ysize, zsize;
149 char *cdatap;
150 long *idatap;
151 static short rs[8192], gs[8192], bs[8192];
152 int x, y;
153 int xwtd, ywtd, xorig, yorig;
154 float xfac, yfac;
155 int cnt;
156
157 if ( !getargs(args, "(sii)", &fname, &xwtd, &ywtd) )
158 return 0;
159
160 if ( !imgfile_open(fname) )
161 return NULL;
162
163 if ( image->colormap != CM_NORMAL ) {
164 err_setstr(ImgfileError, "Can only handle CM_NORMAL images");
165 return NULL;
166 }
167 if ( BPP(image->type) != 1 ) {
168 err_setstr(ImgfileError, "Cannot handle imgfiles with bpp!=1");
169 return NULL;
170 }
171 xsize = image->xsize;
172 ysize = image->ysize;
173 zsize = image->zsize;
174 if ( zsize != 1 && zsize != 3) {
175 err_setstr(ImgfileError, "Can only handle 1 or 3 byte pixels");
176 return NULL;
177 }
178
179 if ( zsize == 3 ) zsize = 4;
180 rv = newsizedstringobject(NULL, xwtd*ywtd*zsize);
181 xfac = (float)xsize/(float)xwtd;
182 yfac = (float)ysize/(float)ywtd;
183 if ( rv == NULL )
184 return NULL;
185 cdatap = getstringvalue(rv);
186 idatap = (long *)cdatap;
187 for ( y=0; y < ywtd && !error_called; y++ ) {
188 yorig = (int)(y*yfac);
189 if ( zsize == 1 ) {
190 getrow(image, rs, yorig, 0);
191 for(x=0; x<xwtd; x++ ) {
192 *cdatap++ = rs[(int)(x*xfac)];
193 }
194 } else {
195 getrow(image, rs, yorig, 0);
196 getrow(image, gs, yorig, 1);
197 getrow(image, bs, yorig, 2);
198 for(x=0; x<xwtd; x++ ) {
199 xorig = (int)(x*xfac);
200 *idatap++ = (rs[xorig] & 0xff) |
201 ((gs[xorig] & 0xff)<<8) |
202 ((bs[xorig] & 0xff)<<16);
203 }
204 }
205 }
206 if ( error_called ) {
207 DECREF(rv);
208 return NULL;
209 }
210 return rv;
211}
212
213static object *
Guido van Rossumaa9de671992-03-04 16:40:03 +0000214imgfile_getsizes(self, args)
215 object *self;
216 object *args;
217{
218 char *fname;
219 object *rv;
220
Guido van Rossum2c4be641992-06-03 17:06:36 +0000221 if ( !getargs(args, "s", &fname) )
222 return 0;
223
224 if ( !imgfile_open(fname) )
Guido van Rossumaa9de671992-03-04 16:40:03 +0000225 return NULL;
226 rv = newtupleobject(3);
227 if ( rv == NULL )
228 return NULL;
229 settupleitem(rv, 0, newintobject(image->xsize));
230 settupleitem(rv, 1, newintobject(image->ysize));
231 settupleitem(rv, 2, newintobject(image->zsize));
232 return rv;
233}
234
Jack Jansen3accf981992-08-20 11:54:27 +0000235static object *
236imgfile_write(self, args)
237 object *self;
238 object *args;
239{
240 IMAGE *image;
241 char *fname;
242 int xsize, ysize, zsize, len;
243 char *cdatap;
244 long *idatap;
245 short rs[8192], gs[8192], bs[8192];
246 short r, g, b;
247 long rgb;
248 int x, y;
249
250 if ( !getargs(args, "(ss#iii)",
251 &fname, &cdatap, &len, &xsize, &ysize, &zsize) )
252 return 0;
253
254 if ( zsize != 1 && zsize != 3 ) {
255 err_setstr(ImgfileError, "Can only handle 1 or 3 byte pixels");
256 return 0;
257 }
258 if ( (zsize == 1 && len != xsize*ysize) ||
259 (zsize == 3 && len != xsize*ysize*4) ) {
260 err_setstr(ImgfileError, "Data does not match sizes");
261 return 0;
262 }
263
Jack Jansen3accf981992-08-20 11:54:27 +0000264 image =iopen(fname, "w", RLE(1), 3, xsize, ysize, zsize);
265 if ( image == 0 ) {
266 if ( ! error_called )
267 err_setstr(ImgfileError, "Cannot create image file");
268 return 0;
269 }
270
271 idatap = (long *)cdatap;
272
273 for( y=0; y<ysize && !error_called; y++ ) {
274 if ( zsize == 1 ) {
275 for( x=0; x<xsize; x++ )
276 rs[x] = *cdatap++;
277 putrow(image, rs, y, 0);
278 } else {
279 for( x=0; x<xsize; x++ ) {
280 rgb = *idatap++;
281 r = rgb & 0xff;
282 g = (rgb >> 8 ) & 0xff;
283 b = (rgb >> 16 ) & 0xff;
284 rs[x] = r;
285 gs[x] = g;
286 bs[x] = b;
287 }
288 putrow(image, rs, y, 0);
289 putrow(image, gs, y, 1);
290 putrow(image, bs, y, 2);
291 }
292 }
293 iclose(image);
294 if ( error_called )
295 return 0;
296 INCREF(None);
297 return None;
298
299}
Guido van Rossumaa9de671992-03-04 16:40:03 +0000300
301static struct methodlist imgfile_methods[] = {
Guido van Rossum2c4be641992-06-03 17:06:36 +0000302 { "getsizes", imgfile_getsizes },
303 { "read", imgfile_read },
304 { "readscaled", imgfile_readscaled },
Jack Jansen3accf981992-08-20 11:54:27 +0000305 { "write", imgfile_write },
Guido van Rossumaa9de671992-03-04 16:40:03 +0000306 { 0, 0 }
307};
308
309
310void
311initimgfile()
312{
313 object *m, *d;
314 m = initmodule("imgfile", imgfile_methods);
315 d = getmoduledict(m);
316 ImgfileError = newstringobject("imgfile.error");
317 if ( ImgfileError == NULL || dictinsert(d,"error",ImgfileError) )
318 fatal("can't define imgfile.error");
319}