summaryrefslogtreecommitdiffstats
path: root/Modules/imgfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/imgfile.c')
-rw-r--r--Modules/imgfile.c162
1 files changed, 138 insertions, 24 deletions
diff --git a/Modules/imgfile.c b/Modules/imgfile.c
index 7d71a35..d6a636b 100644
--- a/Modules/imgfile.c
+++ b/Modules/imgfile.c
@@ -29,6 +29,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
** image files in a neater way (so you can get rgb images off a greyscale
** file, for instance, or do a straight display without having to get the
** image bits into python, etc).
+**
+** Warning: this module is very non-reentrant (esp. the readscaled stuff)
*/
#include "allobjects.h"
@@ -37,6 +39,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <gl/image.h>
#include <errno.h>
+#include <izoom.h>
+
static object * ImgfileError; /* Exception we raise for various trouble */
@@ -158,6 +162,78 @@ imgfile_read(self, args)
return rv;
}
+IMAGE *glob_image;
+long *glob_datap;
+int glob_width, glob_z;
+
+static
+xs_get(buf, y)
+ short *buf;
+ int y;
+{
+ getrow(glob_image, buf, y, glob_z);
+}
+
+static
+xs_put_c(buf, y)
+ short *buf;
+ int y;
+{
+ char *datap = (char *)glob_datap + y*glob_width;
+ int width = glob_width;
+
+ while ( width-- )
+ *datap++ = (*buf++) & 0xff;
+}
+
+static
+xs_put_0(buf, y)
+ short *buf;
+ int y;
+{
+ long *datap = glob_datap + y*glob_width;
+ int width = glob_width;
+
+ while ( width-- )
+ *datap++ = (*buf++) & 0xff;
+}
+static
+xs_put_12(buf, y)
+ short *buf;
+ int y;
+{
+ long *datap = glob_datap + y*glob_width;
+ int width = glob_width;
+
+ while ( width-- )
+ *datap++ |= ((*buf++) & 0xff) << (glob_z*8);
+}
+
+static void
+xscale(image, xsize, ysize, zsize, datap, xnew, ynew, fmode, blur)
+ IMAGE *image;
+ int xsize, ysize, zsize;
+ long *datap;
+ int xnew, ynew;
+ int fmode;
+ double blur;
+{
+ glob_image = image;
+ glob_datap = datap;
+ glob_width = xnew;
+ if ( zsize == 1 ) {
+ glob_z = 0;
+ filterzoom(xs_get, xs_put_c, xsize, ysize, xnew, ynew, fmode, blur);
+ } else {
+ glob_z = 0;
+ filterzoom(xs_get, xs_put_0, xsize, ysize, xnew, ynew, fmode, blur);
+ glob_z = 1;
+ filterzoom(xs_get, xs_put_12, xsize, ysize, xnew, ynew, fmode, blur);
+ glob_z = 2;
+ filterzoom(xs_get, xs_put_12, xsize, ysize, xnew, ynew, fmode, blur);
+ }
+}
+
static object *
imgfile_readscaled(self, args)
@@ -175,10 +251,45 @@ imgfile_readscaled(self, args)
float xfac, yfac;
int cnt;
IMAGE *image;
-
- if ( !getargs(args, "(sii)", &fname, &xwtd, &ywtd) )
+ char *filter;
+ double blur;
+ int extended;
+ int fmode;
+
+ /*
+ ** Parse args. Funny, since arg 4 and 5 are optional
+ ** (filter name and blur factor). Also, 4 or 5 arguments indicates
+ ** extended scale algorithm in stead of simple-minded pixel drop/dup.
+ */
+ extended = 0;
+ cnt = gettuplesize(args);
+ if ( cnt == 5 ) {
+ extended = 1;
+ if ( !getargs(args, "(siisd)", &fname, &xwtd, &ywtd, &filter, &blur) )
+ return NULL;
+ } else if ( cnt == 4 ) {
+ extended = 1;
+ if ( !getargs(args, "(siis)", &fname, &xwtd, &ywtd, &filter) )
+ return NULL;
+ blur = 1.0;
+ } else if ( !getargs(args, "(sii)", &fname, &xwtd, &ywtd) )
return NULL;
+ /*
+ ** Check parameters, open file and check type, rows, etc.
+ */
+ if ( extended ) {
+ if ( strcmp(filter, "impulse") == 0 ) fmode = IMPULSE;
+ else if ( strcmp( filter, "box") == 0 ) fmode = BOX;
+ else if ( strcmp( filter, "triangle") == 0 ) fmode = TRIANGLE;
+ else if ( strcmp( filter, "quadratic") == 0 ) fmode = QUADRATIC;
+ else if ( strcmp( filter, "gaussian") == 0 ) fmode = GAUSSIAN;
+ else {
+ err_setstr(ImgfileError, "Unknown filter type");
+ return NULL;
+ }
+ }
+
if ( (image = imgfile_open(fname)) == NULL )
return NULL;
@@ -209,30 +320,35 @@ imgfile_readscaled(self, args)
if ( zsize == 3 ) zsize = 4;
rv = newsizedstringobject(NULL, xwtd*ywtd*zsize);
if ( rv == NULL ) {
- iclose(image);
- return NULL;
+ iclose(image);
+ return NULL;
}
xfac = (float)xsize/(float)xwtd;
yfac = (float)ysize/(float)ywtd;
cdatap = getstringvalue(rv);
idatap = (long *)cdatap;
- for ( y=0; y < ywtd && !error_called; y++ ) {
- yorig = (int)(y*yfac);
- if ( zsize == 1 ) {
- getrow(image, rs, yorig, 0);
- for(x=0; x<xwtd; x++ ) {
- *cdatap++ = rs[(int)(x*xfac)];
- }
- } else {
- getrow(image, rs, yorig, 0);
- getrow(image, gs, yorig, 1);
- getrow(image, bs, yorig, 2);
- for(x=0; x<xwtd; x++ ) {
- xorig = (int)(x*xfac);
- *idatap++ = (rs[xorig] & 0xff) |
- ((gs[xorig] & 0xff)<<8) |
- ((bs[xorig] & 0xff)<<16);
- }
+
+ if ( extended ) {
+ xscale(image, xsize, ysize, zsize, idatap, xwtd, ywtd, fmode, blur);
+ } else {
+ for ( y=0; y < ywtd && !error_called; y++ ) {
+ yorig = (int)(y*yfac);
+ if ( zsize == 1 ) {
+ getrow(image, rs, yorig, 0);
+ for(x=0; x<xwtd; x++ ) {
+ *cdatap++ = rs[(int)(x*xfac)];
+ }
+ } else {
+ getrow(image, rs, yorig, 0);
+ getrow(image, gs, yorig, 1);
+ getrow(image, bs, yorig, 2);
+ for(x=0; x<xwtd; x++ ) {
+ xorig = (int)(x*xfac);
+ *idatap++ = (rs[xorig] & 0xff) |
+ ((gs[xorig] & 0xff)<<8) |
+ ((bs[xorig] & 0xff)<<16);
+ }
+ }
}
}
iclose(image);
@@ -243,7 +359,6 @@ imgfile_readscaled(self, args)
return rv;
}
-
static object *
imgfile_getsizes(self, args)
object *self;
@@ -263,7 +378,6 @@ imgfile_getsizes(self, args)
return rv;
}
-
static object *
imgfile_write(self, args)
object *self;
@@ -343,7 +457,7 @@ imgfile_write(self, args)
static struct methodlist imgfile_methods[] = {
{ "getsizes", imgfile_getsizes },
{ "read", imgfile_read },
- { "readscaled", imgfile_readscaled },
+ { "readscaled", imgfile_readscaled, 1},
{ "write", imgfile_write },
{ NULL, NULL } /* Sentinel */
};