Commit 97556a8a authored by Sjoerd Mullender's avatar Sjoerd Mullender

rgbimgmodule.c, Makefile, config.c: new module to read RGB image files.

	Does not need any SGI-specific libraries.
cgen.py, cstubs, Makefile: Generate glmodule.c differently so that it
	can be compiled using an ANSI compiler.
parent 3bbed7a5
...@@ -59,7 +59,7 @@ return_types = ['void', 'short', 'long'] ...@@ -59,7 +59,7 @@ return_types = ['void', 'short', 'long']
# Allowed function argument types # Allowed function argument types
# #
arg_types = ['char', 'string', 'short', 'float', 'long', 'double'] arg_types = ['char', 'string', 'short', 'u_short', 'float', 'long', 'double']
# Need to classify arguments as follows # Need to classify arguments as follows
...@@ -111,6 +111,8 @@ def checkarg(type, arg): ...@@ -111,6 +111,8 @@ def checkarg(type, arg):
# #
if type not in arg_types: if type not in arg_types:
raise arg_error, ('bad type', type) raise arg_error, ('bad type', type)
if type[:2] == 'u_':
type = 'unsigned ' + type[2:]
# #
# Split it in the mode (first character) and the rest. # Split it in the mode (first character) and the rest.
# #
...@@ -157,7 +159,7 @@ def checkarg(type, arg): ...@@ -157,7 +159,7 @@ def checkarg(type, arg):
# size is retval -- must be a reply argument # size is retval -- must be a reply argument
if mode <> 'r': if mode <> 'r':
raise arg_error, ('non-r mode with [retval]', mode) raise arg_error, ('non-r mode with [retval]', mode)
elif sub[:3] <> 'arg' or not isnum(sub[3:]): elif not isnum(sub) and (sub[:3] <> 'arg' or not isnum(sub[3:])):
raise arg_error, ('bad subscript', sub) raise arg_error, ('bad subscript', sub)
# #
return type, mode, num, sub return type, mode, num, sub
...@@ -214,10 +216,16 @@ def generate(type, func, database): ...@@ -214,10 +216,16 @@ def generate(type, func, database):
for i in range(len(database)): for i in range(len(database)):
a_type, a_mode, a_factor, a_sub = database[i] a_type, a_mode, a_factor, a_sub = database[i]
print '\t' + a_type, print '\t' + a_type,
if a_sub: brac = ket = ''
print '*', if a_sub and not isnum(a_sub):
print 'arg' + `i+1`, if a_factor:
if a_factor and not a_sub: brac = '('
ket = ')'
print brac + '*',
print 'arg' + `i+1` + ket,
if a_sub and isnum(a_sub):
print '[', a_sub, ']',
if a_factor:
print '[', a_factor, ']', print '[', a_factor, ']',
print ';' print ';'
# #
...@@ -250,6 +258,10 @@ def generate(type, func, database): ...@@ -250,6 +258,10 @@ def generate(type, func, database):
# #
for i in range(len(database)): for i in range(len(database)):
a_type, a_mode, a_factor, a_sub = database[i] a_type, a_mode, a_factor, a_sub = database[i]
if a_type[:9] == 'unsigned ':
xtype = a_type[9:]
else:
xtype = a_type
if a_mode == 'i': if a_mode == 'i':
# #
# Implicit argument; # Implicit argument;
...@@ -258,9 +270,11 @@ def generate(type, func, database): ...@@ -258,9 +270,11 @@ def generate(type, func, database):
# #
j = eval(a_sub) j = eval(a_sub)
print '\tif', print '\tif',
print '(!geti' + a_type + 'arraysize(args,', print '(!geti' + xtype + 'arraysize(args,',
print `n_in_args` + ',', print `n_in_args` + ',',
print `in_pos[j]` + ',', print `in_pos[j]` + ',',
if xtype <> a_type:
print '('+xtype+' *)',
print '&arg' + `i+1` + '))' print '&arg' + `i+1` + '))'
print '\t\treturn NULL;' print '\t\treturn NULL;'
if a_factor: if a_factor:
...@@ -268,25 +282,34 @@ def generate(type, func, database): ...@@ -268,25 +282,34 @@ def generate(type, func, database):
print '= arg' + `i+1`, print '= arg' + `i+1`,
print '/', a_factor + ';' print '/', a_factor + ';'
elif a_mode == 's': elif a_mode == 's':
if a_sub: # Allocate memory for varsize array if a_sub and not isnum(a_sub):
# Allocate memory for varsize array
print '\tif ((arg' + `i+1`, '=', print '\tif ((arg' + `i+1`, '=',
print 'NEW(' + a_type + ',', if a_factor:
if a_factor: print a_factor, '*', print '('+a_type+'(*)['+a_factor+'])',
print 'NEW(' + a_type, ',',
if a_factor:
print a_factor, '*',
print a_sub, ')) == NULL)' print a_sub, ')) == NULL)'
print '\t\treturn err_nomem();' print '\t\treturn err_nomem();'
print '\tif', print '\tif',
if a_factor or a_sub: # Get a fixed-size array array if a_factor or a_sub: # Get a fixed-size array array
print '(!geti' + a_type + 'array(args,', print '(!geti' + xtype + 'array(args,',
print `n_in_args` + ',', print `n_in_args` + ',',
print `in_pos[i]` + ',', print `in_pos[i]` + ',',
if a_factor: print a_factor, if a_factor: print a_factor,
if a_factor and a_sub: print '*', if a_factor and a_sub: print '*',
if a_sub: print a_sub, if a_sub: print a_sub,
print ', arg' + `i+1` + '))' print ',',
if (a_sub and a_factor) or xtype <> a_type:
print '('+xtype+' *)',
print 'arg' + `i+1` + '))'
else: # Get a simple variable else: # Get a simple variable
print '(!geti' + a_type + 'arg(args,', print '(!geti' + xtype + 'arg(args,',
print `n_in_args` + ',', print `n_in_args` + ',',
print `in_pos[i]` + ',', print `in_pos[i]` + ',',
if xtype <> a_type:
print '('+xtype+' *)',
print '&arg' + `i+1` + '))' print '&arg' + `i+1` + '))'
print '\t\treturn NULL;' print '\t\treturn NULL;'
# #
...@@ -314,7 +337,7 @@ def generate(type, func, database): ...@@ -314,7 +337,7 @@ def generate(type, func, database):
# #
for i in range(len(database)): for i in range(len(database)):
a_type, a_mode, a_factor, a_sub = database[i] a_type, a_mode, a_factor, a_sub = database[i]
if a_mode == 's' and a_sub: if a_mode == 's' and a_sub and not isnum(a_sub):
print '\tDEL(arg' + `i+1` + ');' print '\tDEL(arg' + `i+1` + ');'
# #
# Return # Return
...@@ -373,12 +396,21 @@ def generate(type, func, database): ...@@ -373,12 +396,21 @@ def generate(type, func, database):
# Subroutine to return a function call to mknew<type>object(<arg>) # Subroutine to return a function call to mknew<type>object(<arg>)
# #
def mkobject(type, arg): def mkobject(type, arg):
if type[:9] == 'unsigned ':
type = type[9:]
return 'mknew' + type + 'object((' + type + ') ' + arg + ')'
return 'mknew' + type + 'object(' + arg + ')' return 'mknew' + type + 'object(' + arg + ')'
# Open optional file argument defined_archs = []
if sys.argv[1:]:
sys.stdin = open(sys.argv[1], 'r') # usage: cgen [ -Dmach ... ] [ file ]
for arg in sys.argv[1:]:
if arg[:2] == '-D':
defined_archs.append(arg[2:])
else:
# Open optional file argument
sys.stdin = open(arg, 'r')
# Input line number # Input line number
...@@ -426,9 +458,19 @@ while 1: ...@@ -426,9 +458,19 @@ while 1:
functions.append(func) functions.append(func)
else: else:
print line print line
elif not words: continue
pass # skip empty line if not words:
elif words[0] == '#include': continue # skip empty line
elif words[0] == 'if':
# if XXX rest
# if !XXX rest
if words[1][0] == '!':
if words[1][1:] in defined_archs:
continue
elif words[1] not in defined_archs:
continue
words = words[2:]
if words[0] == '#include':
print line print line
elif words[0][:1] == '#': elif words[0][:1] == '#':
pass # ignore comment pass # ignore comment
......
...@@ -299,6 +299,9 @@ extern void initXlib(); ...@@ -299,6 +299,9 @@ extern void initXlib();
#ifdef USE_PARSER #ifdef USE_PARSER
extern void initparser(); extern void initparser();
#endif #endif
#ifdef USE_RGBIMG
extern void initrgbimg();
#endif
/* -- ADDMODULE MARKER 1 -- */ /* -- ADDMODULE MARKER 1 -- */
struct { struct {
...@@ -482,6 +485,10 @@ struct { ...@@ -482,6 +485,10 @@ struct {
{"parser", initparser}, {"parser", initparser},
#endif #endif
#ifdef USE_RGBIMG
{"rgbimg", initrgbimg},
#endif
/* -- ADDMODULE MARKER 2 -- */ /* -- ADDMODULE MARKER 2 -- */
{0, 0} /* Sentinel */ {0, 0} /* Sentinel */
......
...@@ -22,7 +22,13 @@ Each definition must be contained on one line: ...@@ -22,7 +22,13 @@ Each definition must be contained on one line:
argI argI
retval retval
N*argI N*argI
N*I
N*retval N*retval
In the case where the subscript consists of two parts
separated by *, the first part is the width of the matrix, and
the second part is the length of the matrix. This order is
opposite from the order used in C to declare a two-dimensional
matrix.
*/ */
/* /*
...@@ -847,7 +853,7 @@ gl_gversion(self, args) ...@@ -847,7 +853,7 @@ gl_gversion(self, args)
%% %%
long getshade long getshade
void devport short s long s if !solaris void devport short s long s
void rdr2i long s long s void rdr2i long s long s
void rectfs short s short s short s short s void rectfs short s short s short s short s
void rects short s short s short s short s void rects short s short s short s short s
...@@ -888,7 +894,7 @@ void textinit ...@@ -888,7 +894,7 @@ void textinit
void initnames void initnames
void pclos void pclos
void popname void popname
void spclos if !solaris void spclos
void zclear void zclear
void screenspace void screenspace
void reshapeviewport void reshapeviewport
...@@ -896,9 +902,9 @@ void winpush ...@@ -896,9 +902,9 @@ void winpush
void winpop void winpop
void foreground void foreground
void endfullscrn void endfullscrn
void endpupmode if !solaris void endpupmode
void fullscrn void fullscrn
void pupmode if !solaris void pupmode
void winconstraints void winconstraints
void pagecolor short s void pagecolor short s
void textcolor short s void textcolor short s
...@@ -910,7 +916,7 @@ void setlinestyle short s ...@@ -910,7 +916,7 @@ void setlinestyle short s
void setmap short s void setmap short s
void swapinterval short s void swapinterval short s
void writemask short s void writemask short s
void textwritemask short s if !solaris void textwritemask short s
void qdevice short s void qdevice short s
void unqdevice short s void unqdevice short s
void curvebasis short s void curvebasis short s
...@@ -919,9 +925,9 @@ void loadname short s ...@@ -919,9 +925,9 @@ void loadname short s
void passthrough short s void passthrough short s
void pushname short s void pushname short s
void setmonitor short s void setmonitor short s
void setshade short s if !solaris void setshade short s
void setpattern short s void setpattern short s
void pagewritemask short s if !solaris void pagewritemask short s
# #
void callobj long s void callobj long s
void delobj long s void delobj long s
...@@ -942,7 +948,7 @@ void freepup long s ...@@ -942,7 +948,7 @@ void freepup long s
# #
void backbuffer long s void backbuffer long s
void frontbuffer long s void frontbuffer long s
void lsbackup long s if !solaris void lsbackup long s
void resetls long s void resetls long s
void lampon long s void lampon long s
void lampoff long s void lampoff long s
...@@ -1003,13 +1009,13 @@ void rpdr2 float s float s ...@@ -1003,13 +1009,13 @@ void rpdr2 float s float s
void rpmv2 float s float s void rpmv2 float s float s
void xfpt2 float s float s void xfpt2 float s float s
# #
void loadmatrix float s[16] void loadmatrix float s[4*4]
# Really [4][4] # Really [4][4]
void multmatrix float s[16] void multmatrix float s[4*4]
# Really [4][4] # Really [4][4]
void crv float s[12] void crv float s[3*4]
# Really [4][3] # Really [4][3]
void rcrv float s[16] void rcrv float s[4*4]
# Really [4][4] # Really [4][4]
# #
# Methods that have strings. # Methods that have strings.
...@@ -1040,12 +1046,12 @@ void polfs long s short s[3*arg1] ...@@ -1040,12 +1046,12 @@ void polfs long s short s[3*arg1]
void polys long s short s[3*arg1] void polys long s short s[3*arg1]
void poly2s long s short s[2*arg1] void poly2s long s short s[2*arg1]
# #
void defcursor short s short s[128] void defcursor short s u_short s[128]
# Is this useful? # Is this useful?
void writepixels short s short s[arg1] void writepixels short s u_short s[arg1]
# Should be unsigned short... # Should be unsigned short...
void defbasis long s float s[16] void defbasis long s float s[4*4]
void gewrite short s short s[arg1] if !solaris void gewrite short s short s[arg1]
# #
void rotate short s char s void rotate short s char s
# This is not in the library!? # This is not in the library!?
...@@ -1103,16 +1109,16 @@ void xfpts short s short s short s ...@@ -1103,16 +1109,16 @@ void xfpts short s short s short s
void curorigin short s short s short s void curorigin short s short s short s
void cyclemap short s short s short s void cyclemap short s short s short s
# #
void patch float s[16] float s[16] float s[16] void patch float s[4*4] float s[4*4] float s[4*4]
void splf long s float s[3*arg1] short s[arg1] void splf long s float s[3*arg1] u_short s[arg1]
void splf2 long s float s[2*arg1] short s[arg1] void splf2 long s float s[2*arg1] u_short s[arg1]
void splfi long s long s[3*arg1] short s[arg1] void splfi long s long s[3*arg1] u_short s[arg1]
void splf2i long s long s[2*arg1] short s[arg1] void splf2i long s long s[2*arg1] u_short s[arg1]
void splfs long s short s[3*arg1] short s[arg1] void splfs long s short s[3*arg1] u_short s[arg1]
void splf2s long s short s[2*arg1] short s[arg1] void splf2s long s short s[2*arg1] u_short s[arg1]
###void defpattern short s short s short s[arg2*arg2/16] ###void defpattern short s short s u_short s[arg2*arg2/16]
# #
void rpatch float s[16] float s[16] float s[16] float s[16] void rpatch float s[4*4] float s[4*4] float s[4*4] float s[4*4]
# #
# routines that send 4 floats # routines that send 4 floats
# #
...@@ -1154,7 +1160,7 @@ void polarview float s short s short s short s ...@@ -1154,7 +1160,7 @@ void polarview float s short s short s short s
void arcfs short s short s short s short s short s void arcfs short s short s short s short s short s
void arcs short s short s short s short s short s void arcs short s short s short s short s short s
void rectcopy short s short s short s short s short s short s void rectcopy short s short s short s short s short s short s
void RGBcursor short s short s short s short s short s short s short s if !solaris void RGBcursor short s short s short s short s short s short s short s
# #
long getbutton short s long getbutton short s
long getcmmode long getcmmode
...@@ -1198,7 +1204,7 @@ void getcpos short r short r ...@@ -1198,7 +1204,7 @@ void getcpos short r short r
void getsize long r long r void getsize long r long r
void getorigin long r long r void getorigin long r long r
void getviewport short r short r short r short r void getviewport short r short r short r short r
void gettp short r short r short r short r if !solaris void gettp short r short r short r short r
void getgpos float r float r float r float r void getgpos float r float r float r float r
void winposition long s long s long s long s void winposition long s long s long s long s
void gRGBcolor short r short r short r void gRGBcolor short r short r short r
...@@ -1210,7 +1216,7 @@ void mapw long s short s short s float r float r float r float r float r float ...@@ -1210,7 +1216,7 @@ void mapw long s short s short s float r float r float r float r float r float
void mapw2 long s short s short s float r float r void mapw2 long s short s short s float r float r
###void defrasterfont short s short s short s Fontchar s[arg3] short s short s[4*arg5] ###void defrasterfont short s short s short s Fontchar s[arg3] short s short s[4*arg5]
###long qread short r ###long qread short r
void getcursor short r short r short r long r void getcursor short r u_short r u_short r long r
# #
# For these we receive arrays of stuff # For these we receive arrays of stuff
# #
...@@ -1241,7 +1247,7 @@ void mmode long s ...@@ -1241,7 +1247,7 @@ void mmode long s
void normal float s[3] void normal float s[3]
void overlay long s void overlay long s
void RGBrange short s short s short s short s short s short s short s short s void RGBrange short s short s short s short s short s short s short s short s
void setvideo long s long s if !solaris void setvideo long s long s
void shademodel long s void shademodel long s
void underlay long s void underlay long s
# #
......
/*
* fastimg -
* Faster reading and writing of image files.
*
* This code should work on machines with any byte order.
*
* Could someone make this run real fast using multiple processors
* or how about using memory mapped files to speed it up?
*
* Paul Haeberli - 1991
*
* Changed to return sizes.
* Sjoerd Mullender - 1993
* Changed to incorporate into Python.
* Sjoerd Mullender - 1993
*/
#include "allobjects.h"
#include "modsupport.h"
#include <unistd.h>
/*
* from image.h
*
*/
typedef struct {
unsigned short imagic; /* stuff saved on disk . . */
unsigned short type;
unsigned short dim;
unsigned short xsize;
unsigned short ysize;
unsigned short zsize;
unsigned long min;
unsigned long max;
unsigned long wastebytes;
char name[80];
unsigned long colormap;
long file; /* stuff used in core only */
unsigned short flags;
short dorev;
short x;
short y;
short z;
short cnt;
unsigned short *ptr;
unsigned short *base;
unsigned short *tmpbuf;
unsigned long offset;
unsigned long rleend; /* for rle images */
unsigned long *rowstart; /* for rle images */
long *rowsize; /* for rle images */
} IMAGE;
#define IMAGIC 0732
#define TYPEMASK 0xff00
#define BPPMASK 0x00ff
#define ITYPE_VERBATIM 0x0000
#define ITYPE_RLE 0x0100
#define ISRLE(type) (((type) & 0xff00) == ITYPE_RLE)
#define ISVERBATIM(type) (((type) & 0xff00) == ITYPE_VERBATIM)
#define BPP(type) ((type) & BPPMASK)
#define RLE(bpp) (ITYPE_RLE | (bpp))
#define VERBATIM(bpp) (ITYPE_VERBATIM | (bpp))
/*
* end of image.h stuff
*
*/
#define RINTLUM (79)
#define GINTLUM (156)
#define BINTLUM (21)
#define ILUM(r,g,b) ((int)(RINTLUM*(r)+GINTLUM*(g)+BINTLUM*(b))>>8)
#define OFFSET_R 3 /* this is byte order dependent */
#define OFFSET_G 2
#define OFFSET_B 1
#define OFFSET_A 0
#define CHANOFFSET(z) (3-(z)) /* this is byte order dependent */
static expandrow();
static setalpha();
static copybw();
static interleaverow();
static int compressrow();
static lumrow();
#ifdef ADD_TAGS
#define TAGLEN (5)
#else
#define TAGLEN (0)
#endif
static object *ImgfileError;
#ifdef ADD_TAGS
/*
* addlongimgtag -
* this is used to extract image data from core dumps.
*
*/
addlongimgtag(dptr,xsize,ysize)
unsigned long *dptr;
int xsize, ysize;
{
dptr = dptr+(xsize*ysize);
dptr[0] = 0x12345678;
dptr[1] = 0x59493333;
dptr[2] = 0x69434222;
dptr[3] = xsize;
dptr[4] = ysize;
}
#endif
/*
* byte order independent read/write of shorts and longs.
*
*/
static unsigned short getshort(inf)
FILE *inf;
{
unsigned char buf[2];
fread(buf,2,1,inf);
return (buf[0]<<8)+(buf[1]<<0);
}
static unsigned long getlong(inf)
FILE *inf;
{
unsigned char buf[4];
fread(buf,4,1,inf);
return (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0);
}
static putshort(outf,val)
FILE *outf;
unsigned short val;
{
unsigned char buf[2];
buf[0] = (val>>8);
buf[1] = (val>>0);
fwrite(buf,2,1,outf);
}
static int putlong(outf,val)
FILE *outf;
unsigned long val;
{
unsigned char buf[4];
buf[0] = (val>>24);
buf[1] = (val>>16);
buf[2] = (val>>8);
buf[3] = (val>>0);
return fwrite(buf,4,1,outf);
}
static readheader(inf,image)
FILE *inf;
IMAGE *image;
{
bzero(image,sizeof(IMAGE));
image->imagic = getshort(inf);
image->type = getshort(inf);
image->dim = getshort(inf);
image->xsize = getshort(inf);
image->ysize = getshort(inf);
image->zsize = getshort(inf);
}
static int writeheader(outf,image)
FILE *outf;
IMAGE *image;
{
IMAGE t;
bzero(&t,sizeof(IMAGE));
fwrite(&t,sizeof(IMAGE),1,outf);
fseek(outf,0,SEEK_SET);
putshort(outf,image->imagic);
putshort(outf,image->type);
putshort(outf,image->dim);
putshort(outf,image->xsize);
putshort(outf,image->ysize);
putshort(outf,image->zsize);
putlong(outf,image->min);
putlong(outf,image->max);
putlong(outf,0);
return fwrite("no name",8,1,outf);
}
static int writetab(outf,tab,len)
FILE *outf;
unsigned long *tab;
int len;
{
int r;
while(len) {
r = putlong(outf,*tab++);
len -= 4;
}
return r;
}
static readtab(inf,tab,len)
FILE *inf;
unsigned long *tab;
int len;
{
while(len) {
*tab++ = getlong(inf);
len -= 4;
}
}
/*
* sizeofimage -
* return the xsize and ysize of an iris image file.
*
*/
static object *
sizeofimage(self, args)
object *self, *args;
{
char *name;
IMAGE image;
FILE *inf;
if (!getargs(args, "s", &name))
return NULL;
inf = fopen(name,"r");
if(!inf) {
err_setstr(ImgfileError, "can't open image file");
return NULL;
}
readheader(inf,&image);
fclose(inf);
if(image.imagic != IMAGIC) {
err_setstr(ImgfileError, "bad magic number in image file");
return NULL;
}
return mkvalue("(ii)", image.xsize, image.ysize);
}
/*
* longimagedata -
* read in a B/W RGB or RGBA iris image file and return a
* pointer to an array of longs.
*
*/
static object *
longimagedata(self, args)
object *self, *args;
{
char *name;
unsigned long *base, *lptr;
unsigned char *rledat, *verdat;
long *starttab, *lengthtab;
FILE *inf;
IMAGE image;
int y, z, pos, len, tablen;
int xsize, ysize, zsize;
int bpp, rle, cur, badorder;
int rlebuflen;
object *rv;
if (!getargs(args, "s", &name))
return NULL;
inf = fopen(name,"r");
if(!inf) {
err_setstr(ImgfileError,"can't open image file");
return NULL;
}
readheader(inf,&image);
if(image.imagic != IMAGIC) {
err_setstr(ImgfileError,"bad magic number in image file");
fclose(inf);
return NULL;
}
rle = ISRLE(image.type);
bpp = BPP(image.type);
if(bpp != 1 ) {
err_setstr(ImgfileError,"image must have 1 byte per pix chan");
fclose(inf);
return NULL;
}
xsize = image.xsize;
ysize = image.ysize;
zsize = image.zsize;
if(rle) {
tablen = ysize*zsize*sizeof(long);
starttab = (long *)malloc(tablen);
lengthtab = (long *)malloc(tablen);
rlebuflen = 1.05*xsize+10;
rledat = (unsigned char *)malloc(rlebuflen);
fseek(inf,512,SEEK_SET);
readtab(inf,starttab,tablen);
readtab(inf,lengthtab,tablen);
/* check data order */
cur = 0;
badorder = 0;
for(y=0; y<ysize; y++) {
for(z=0; z<zsize; z++) {
if(starttab[y+z*ysize]<cur) {
badorder = 1;
break;
}
cur = starttab[y+z*ysize];
}
if(badorder)
break;
}
fseek(inf,512+2*tablen,SEEK_SET);
cur = 512+2*tablen;
rv = newsizedstringobject((char *) 0,
(xsize*ysize+TAGLEN)*sizeof(long));
if (rv == NULL) {
fclose(inf);
free(lengthtab);
free(starttab);
free(rledat);
return NULL;
}
base = (unsigned long *) getstringvalue(rv);
#ifdef ADD_TAGS
addlongimgtag(base,xsize,ysize);
#endif
if(badorder) {
for(z=0; z<zsize; z++) {
lptr = base;
for(y=0; y<ysize; y++) {
if(cur != starttab[y+z*ysize]) {
fseek(inf,starttab[y+z*ysize],SEEK_SET);
cur = starttab[y+z*ysize];
}
if(lengthtab[y+z*ysize]>rlebuflen) {
err_setstr(ImgfileError,"rlebuf is too small - bad poop");
fclose(inf);
DECREF(rv);
free(rledat);
free(starttab);
free(lengthtab);
return NULL;
}
fread(rledat,lengthtab[y+z*ysize],1,inf);
cur += lengthtab[y+z*ysize];
expandrow(lptr,rledat,3-z);
lptr += xsize;
}
}
} else {
lptr = base;
for(y=0; y<ysize; y++) {
for(z=0; z<zsize; z++) {
if(cur != starttab[y+z*ysize]) {
fseek(inf,starttab[y+z*ysize],SEEK_SET);
cur = starttab[y+z*ysize];
}
fread(rledat,lengthtab[y+z*ysize],1,inf);
cur += lengthtab[y+z*ysize];
expandrow(lptr,rledat,3-z);
}
lptr += xsize;
}
}
if(zsize == 3)
setalpha(base,xsize*ysize);
else if(zsize<3)
copybw(base,xsize*ysize);
fclose(inf);
free(starttab);
free(lengthtab);
free(rledat);
return rv;
} else {
rv = newsizedstringobject((char *) 0,
(xsize*ysize+TAGLEN)*sizeof(long));
if (rv == NULL) {
fclose(inf);
return NULL;
}
base = (unsigned long *) getstringvalue(rv);
#ifdef ADD_TAGS
addlongimgtag(base,xsize,ysize);
#endif
verdat = (unsigned char *)malloc(xsize);
fseek(inf,512,SEEK_SET);
for(z=0; z<zsize; z++) {
lptr = base;
for(y=0; y<ysize; y++) {
fread(verdat,xsize,1,inf);
interleaverow(lptr,verdat,3-z,xsize);
lptr += xsize;
}
}
if(zsize == 3)
setalpha(base,xsize*ysize);
else if(zsize<3)
copybw(base,xsize*ysize);
fclose(inf);
free(verdat);
return rv;
}
}
/* static utility functions for longimagedata */
static interleaverow(lptr,cptr,z,n)
unsigned char *lptr, *cptr;
int z, n;
{
lptr += z;
while(n--) {
*lptr = *cptr++;
lptr += 4;
}
}
static copybw(lptr,n)
long *lptr;
int n;
{
while(n>=8) {
lptr[0] = 0xff000000+(0x010101*(lptr[0]&0xff));
lptr[1] = 0xff000000+(0x010101*(lptr[1]&0xff));
lptr[2] = 0xff000000+(0x010101*(lptr[2]&0xff));
lptr[3] = 0xff000000+(0x010101*(lptr[3]&0xff));
lptr[4] = 0xff000000+(0x010101*(lptr[4]&0xff));
lptr[5] = 0xff000000+(0x010101*(lptr[5]&0xff));
lptr[6] = 0xff000000+(0x010101*(lptr[6]&0xff));
lptr[7] = 0xff000000+(0x010101*(lptr[7]&0xff));
lptr += 8;
n-=8;
}
while(n--) {
*lptr = 0xff000000+(0x010101*(*lptr&0xff));
lptr++;
}
}
static setalpha(lptr,n)
unsigned char *lptr;
{
while(n>=8) {
lptr[0*4] = 0xff;
lptr[1*4] = 0xff;
lptr[2*4] = 0xff;
lptr[3*4] = 0xff;
lptr[4*4] = 0xff;
lptr[5*4] = 0xff;
lptr[6*4] = 0xff;
lptr[7*4] = 0xff;
lptr += 4*8;
n -= 8;
}
while(n--) {
*lptr = 0xff;
lptr += 4;
}
}
static expandrow(optr,iptr,z)
unsigned char *optr, *iptr;
int z;
{
unsigned char pixel, count;
optr += z;
while(1) {
pixel = *iptr++;
if ( !(count = (pixel & 0x7f)) )
return;
if(pixel & 0x80) {
while(count>=8) {
optr[0*4] = iptr[0];
optr[1*4] = iptr[1];
optr[2*4] = iptr[2];
optr[3*4] = iptr[3];
optr[4*4] = iptr[4];
optr[5*4] = iptr[5];
optr[6*4] = iptr[6];
optr[7*4] = iptr[7];
optr += 8*4;
iptr += 8;
count -= 8;
}
while(count--) {
*optr = *iptr++;
optr+=4;
}
} else {
pixel = *iptr++;
while(count>=8) {
optr[0*4] = pixel;
optr[1*4] = pixel;
optr[2*4] = pixel;
optr[3*4] = pixel;
optr[4*4] = pixel;
optr[5*4] = pixel;
optr[6*4] = pixel;
optr[7*4] = pixel;
optr += 8*4;
count -= 8;
}
while(count--) {
*optr = pixel;
optr+=4;
}
}
}
}
/*
* longstoimage -
* copy an array of longs to an iris image file. Each long
* represents one pixel. xsize and ysize specify the dimensions of
* the pixel array. zsize specifies what kind of image file to
* write out. if zsize is 1, the luminance of the pixels are
* calculated, and a sinlge channel black and white image is saved.
* If zsize is 3, an RGB image file is saved. If zsize is 4, an
* RGBA image file is saved.
*
*/
static object *
longstoimage(self, args)
object *self, *args;
{
unsigned long *lptr;
char *name;
int xsize, ysize, zsize;
FILE *outf;
IMAGE image;
int tablen, y, z, pos, len;
long *starttab, *lengthtab;
unsigned char *rlebuf;
unsigned long *lumbuf;
int rlebuflen, goodwrite;
if (!getargs(args, "(s#iiis)", &lptr, &len, &xsize, &ysize, &zsize, &name))
return NULL;
goodwrite = 1;
outf = fopen(name,"w");
if(!outf) {
err_setstr(ImgfileError,"can't open output file");
return NULL;
}
tablen = ysize*zsize*sizeof(long);
starttab = (long *)malloc(tablen);
lengthtab = (long *)malloc(tablen);
rlebuflen = 1.05*xsize+10;
rlebuf = (unsigned char *)malloc(rlebuflen);
lumbuf = (unsigned long *)malloc(xsize*sizeof(long));
bzero(&image,sizeof(IMAGE));
image.imagic = IMAGIC;
image.type = RLE(1);
if(zsize>1)
image.dim = 3;
else
image.dim = 2;
image.xsize = xsize;
image.ysize = ysize;
image.zsize = zsize;
image.min = 0;
image.max = 255;
goodwrite *= writeheader(outf,&image);
fseek(outf,512+2*tablen,SEEK_SET);
pos = 512+2*tablen;
for(y=0; y<ysize; y++) {
for(z=0; z<zsize; z++) {
if(zsize == 1) {
lumrow(lptr,lumbuf,xsize);
len = compressrow(lumbuf,rlebuf,CHANOFFSET(z),xsize);
} else {
len = compressrow(lptr,rlebuf,CHANOFFSET(z),xsize);
}
if(len>rlebuflen) {
err_setstr(ImgfileError,"rlebuf is too small - bad poop");
free(starttab);
free(lengthtab);
free(rlebuf);
free(lumbuf);
fclose(outf);
return NULL;
}
goodwrite *= fwrite(rlebuf,len,1,outf);
starttab[y+z*ysize] = pos;
lengthtab[y+z*ysize] = len;
pos += len;
}
lptr += xsize;
}
fseek(outf,512,SEEK_SET);
goodwrite *= writetab(outf,starttab,tablen);
goodwrite *= writetab(outf,lengthtab,tablen);
free(starttab);
free(lengthtab);
free(rlebuf);
free(lumbuf);
fclose(outf);
if(goodwrite) {
INCREF(None);
return None;
} else {
err_setstr(ImgfileError,"not enough space for image!!");
return NULL;
}
}
/* static utility functions for longstoimage */
static lumrow(rgbptr,lumptr,n)
unsigned char *rgbptr, *lumptr;
int n;
{
lumptr += CHANOFFSET(0);
while(n--) {
*lumptr = ILUM(rgbptr[OFFSET_R],rgbptr[OFFSET_G],rgbptr[OFFSET_B]);
lumptr += 4;
rgbptr += 4;
}
}
static int compressrow(lbuf,rlebuf,z,cnt)
unsigned char *lbuf, *rlebuf;
int z, cnt;
{
unsigned char *iptr, *ibufend, *sptr, *optr;
short todo, cc;
long count;
lbuf += z;
iptr = lbuf;
ibufend = iptr+cnt*4;
optr = rlebuf;
while(iptr<ibufend) {
sptr = iptr;
iptr += 8;
while((iptr<ibufend)&& ((iptr[-8]!=iptr[-4])||(iptr[-4]!=iptr[0])))
iptr+=4;
iptr -= 8;
count = (iptr-sptr)/4;
while(count) {
todo = count>126 ? 126:count;
count -= todo;
*optr++ = 0x80|todo;
while(todo>8) {
optr[0] = sptr[0*4];
optr[1] = sptr[1*4];
optr[2] = sptr[2*4];
optr[3] = sptr[3*4];
optr[4] = sptr[4*4];
optr[5] = sptr[5*4];
optr[6] = sptr[6*4];
optr[7] = sptr[7*4];
optr += 8;
sptr += 8*4;
todo -= 8;
}
while(todo--) {
*optr++ = *sptr;
sptr += 4;
}
}
sptr = iptr;
cc = *iptr;
iptr += 4;
while( (iptr<ibufend) && (*iptr == cc) )
iptr += 4;
count = (iptr-sptr)/4;
while(count) {
todo = count>126 ? 126:count;
count -= todo;
*optr++ = todo;
*optr++ = cc;
}
}
*optr++ = 0;
return optr - (unsigned char *)rlebuf;
}
static struct methodlist rgbimg_methods[] = {
{"sizeofimage", sizeofimage},
{"longimagedata", longimagedata},
{"longstoimage", longstoimage},
{NULL, NULL} /* sentinel */
};
void
initrgbimg()
{
object *m, *d;
m = initmodule("rgbimg", rgbimg_methods);
d = getmoduledict(m);
ImgfileError = newstringobject("rgbimg,error");
if (ImgfileError == NULL || dictinsert(d, "error", ImgfileError))
fatal("can't define rgbimg.error");
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment