cinap_lenrekadd hg and python4bb9e2215 years agoHistory
785 lines · 16.9 KB · C
RawDownload
 /* imageopmodule - Various operations on pictures */ #ifdef sun#define signed#endif #include "Python.h" #if SIZEOF_INT == 4typedef int Py_Int32;typedef unsigned int Py_UInt32;#else#if SIZEOF_LONG == 4typedef long Py_Int32;typedef unsigned long Py_UInt32;#else#error "No 4-byte integral type"#endif#endif #define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x))#define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x)))#define LONGP(cp, xmax, x, y) ((Py_Int32 *)(cp+4*(y*xmax+x))) static PyObject *ImageopError;static PyObject *ImageopDict; /* If this function returns true (the default if anything goes wrong), we're   behaving in a backward-compatible way with respect to how multi-byte pixels   are stored in the strings.  The code in this module was originally written   for an SGI which is a big-endian system, and so the old code assumed that   4-byte integers hold the R, G, and B values in a particular order.   However, on little-endian systems the order is reversed, and so not   actually compatible with what gl.lrectwrite and imgfile expect.   (gl.lrectwrite and imgfile are also SGI-specific, however, it is   conceivable that the data handled here comes from or goes to an SGI or that   it is otherwise used in the expectation that the byte order in the strings   is as specified.)    The function returns the value of the module variable   "backward_compatible", or 1 if the variable does not exist or is not an   int. */ static intimageop_backward_compatible(void){	static PyObject *bcos;	PyObject *bco;	long rc; 	if (ImageopDict == NULL) /* "cannot happen" */		return 1;	if (bcos == NULL) {		/* cache string object for future use */		bcos = PyString_FromString("backward_compatible");		if (bcos == NULL)			return 1;	}	bco = PyDict_GetItem(ImageopDict, bcos);	if (bco == NULL)		return 1;	if (!PyInt_Check(bco))		return 1;	rc = PyInt_AsLong(bco);	if (PyErr_Occurred()) {		/* not an integer, or too large, or something */		PyErr_Clear();		rc = 1;	}	return rc != 0;		/* convert to values 0, 1 */} static PyObject *imageop_crop(PyObject *self, PyObject *args){	char *cp, *ncp;	short *nsp;	Py_Int32 *nlp;	int len, size, x, y, newx1, newx2, newy1, newy2;	int ix, iy, xstep, ystep;	PyObject *rv; 	if ( !PyArg_ParseTuple(args, "s#iiiiiii", &cp, &len, &size, &x, &y,			  &newx1, &newy1, &newx2, &newy2) )		return 0;    	if ( size != 1 && size != 2 && size != 4 ) {		PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");		return 0;	}	if ( len != size*x*y ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}	xstep = (newx1 < newx2)? 1 : -1;	ystep = (newy1 < newy2)? 1 : -1;    	rv = PyString_FromStringAndSize(NULL,			     (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);	if ( rv == 0 )		return 0;	ncp = (char *)PyString_AsString(rv);	nsp = (short *)ncp;	nlp = (Py_Int32 *)ncp;	newy2 += ystep;	newx2 += xstep;	for( iy = newy1; iy != newy2; iy+=ystep ) {		for ( ix = newx1; ix != newx2; ix+=xstep ) {			if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {				if ( size == 1 )					*ncp++ = 0;				else					*nlp++ = 0;			} else {				if ( size == 1 )					*ncp++ = *CHARP(cp, x, ix, iy);				else if ( size == 2 )					*nsp++ = *SHORTP(cp, x, ix, iy);				else					*nlp++ = *LONGP(cp, x, ix, iy);			}		}	}	return rv;} static PyObject *imageop_scale(PyObject *self, PyObject *args){	char *cp, *ncp;	short *nsp;	Py_Int32 *nlp;	int len, size, x, y, newx, newy;	int ix, iy;	int oix, oiy;	PyObject *rv; 	if ( !PyArg_ParseTuple(args, "s#iiiii",			  &cp, &len, &size, &x, &y, &newx, &newy) )		return 0;    	if ( size != 1 && size != 2 && size != 4 ) {		PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");		return 0;	}	if ( len != size*x*y ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, newx*newy*size);	if ( rv == 0 )		return 0;	ncp = (char *)PyString_AsString(rv);	nsp = (short *)ncp;	nlp = (Py_Int32 *)ncp;	for( iy = 0; iy < newy; iy++ ) {		for ( ix = 0; ix < newx; ix++ ) {			oix = ix * x / newx;			oiy = iy * y / newy;			if ( size == 1 )				*ncp++ = *CHARP(cp, x, oix, oiy);			else if ( size == 2 )				*nsp++ = *SHORTP(cp, x, oix, oiy);			else				*nlp++ = *LONGP(cp, x, oix, oiy);		}	}	return rv;} /* Note: this routine can use a bit of optimizing */ static PyObject *imageop_tovideo(PyObject *self, PyObject *args){	int maxx, maxy, x, y, len;	int i;	unsigned char *cp, *ncp;	int width;	PyObject *rv;       	if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &width, &maxx, &maxy) )		return 0; 	if ( width != 1 && width != 4 ) {		PyErr_SetString(ImageopError, "Size should be 1 or 4");		return 0;	}	if ( maxx*maxy*width != len ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, len);	if ( rv == 0 )		return 0;	ncp = (unsigned char *)PyString_AsString(rv); 	if ( width == 1 ) {		memcpy(ncp, cp, maxx);		/* Copy first line */		ncp += maxx;		for (y=1; y<maxy; y++) {	/* Interpolate other lines */			for(x=0; x<maxx; x++) {				i = y*maxx + x;				*ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;			}		}	} else {		memcpy(ncp, cp, maxx*4);		/* Copy first line */		ncp += maxx*4;		for (y=1; y<maxy; y++) {	/* Interpolate other lines */			for(x=0; x<maxx; x++) {				i = (y*maxx + x)*4 + 1;				*ncp++ = 0;	/* Skip alfa comp */				*ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;				i++;				*ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;				i++;				*ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;			}		}	}	return rv;} static PyObject *imageop_grey2mono(PyObject *self, PyObject *args){	int tres, x, y, len;	unsigned char *cp, *ncp;	unsigned char ovalue;	PyObject *rv;	int i, bit;       	if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &x, &y, &tres) )		return 0; 	if ( x*y != len ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, (len+7)/8);	if ( rv == 0 )		return 0;	ncp = (unsigned char *)PyString_AsString(rv); 	bit = 0x80;	ovalue = 0;	for ( i=0; i < len; i++ ) {		if ( (int)cp[i] > tres )			ovalue |= bit;		bit >>= 1;		if ( bit == 0 ) {			*ncp++ = ovalue;			bit = 0x80;			ovalue = 0;		}	}	if ( bit != 0x80 )		*ncp++ = ovalue;	return rv;} static PyObject *imageop_grey2grey4(PyObject *self, PyObject *args){	int x, y, len;	unsigned char *cp, *ncp;	unsigned char ovalue;	PyObject *rv;	int i;	int pos;       	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )		return 0; 	if ( x*y != len ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, (len+1)/2);	if ( rv == 0 )		return 0;	ncp = (unsigned char *)PyString_AsString(rv);	pos = 0;	ovalue = 0;	for ( i=0; i < len; i++ ) {		ovalue |= ((int)cp[i] & 0xf0) >> pos;		pos += 4;		if ( pos == 8 ) {			*ncp++ = ovalue;			ovalue = 0;			pos = 0;		}	}	if ( pos != 0 )		*ncp++ = ovalue;	return rv;} static PyObject *imageop_grey2grey2(PyObject *self, PyObject *args){	int x, y, len;	unsigned char *cp, *ncp;	unsigned char ovalue;	PyObject *rv;	int i;	int pos;       	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )		return 0; 	if ( x*y != len ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, (len+3)/4);	if ( rv == 0 )		return 0;	ncp = (unsigned char *)PyString_AsString(rv);	pos = 0;	ovalue = 0;	for ( i=0; i < len; i++ ) {		ovalue |= ((int)cp[i] & 0xc0) >> pos;		pos += 2;		if ( pos == 8 ) {			*ncp++ = ovalue;			ovalue = 0;			pos = 0;		}	}	if ( pos != 0 )		*ncp++ = ovalue;	return rv;} static PyObject *imageop_dither2mono(PyObject *self, PyObject *args){	int sum, x, y, len;	unsigned char *cp, *ncp;	unsigned char ovalue;	PyObject *rv;	int i, bit;       	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )		return 0; 	if ( x*y != len ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, (len+7)/8);	if ( rv == 0 )		return 0;	ncp = (unsigned char *)PyString_AsString(rv); 	bit = 0x80;	ovalue = 0;	sum = 0;	for ( i=0; i < len; i++ ) {		sum += cp[i];		if ( sum >= 256 ) {			sum -= 256;			ovalue |= bit;		}		bit >>= 1;		if ( bit == 0 ) {			*ncp++ = ovalue;			bit = 0x80;			ovalue = 0;		}	}	if ( bit != 0x80 )		*ncp++ = ovalue;	return rv;} static PyObject *imageop_dither2grey2(PyObject *self, PyObject *args){	int x, y, len;	unsigned char *cp, *ncp;	unsigned char ovalue;	PyObject *rv;	int i;	int pos;	int sum = 0, nvalue;       	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )		return 0; 	if ( x*y != len ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, (len+3)/4);	if ( rv == 0 )		return 0;	ncp = (unsigned char *)PyString_AsString(rv);	pos = 1;	ovalue = 0;	for ( i=0; i < len; i++ ) {		sum += cp[i];		nvalue = sum & 0x180;		sum -= nvalue;		ovalue |= nvalue >> pos;		pos += 2;		if ( pos == 9 ) {			*ncp++ = ovalue;			ovalue = 0;			pos = 1;		}	}	if ( pos != 0 )		*ncp++ = ovalue;	return rv;} static PyObject *imageop_mono2grey(PyObject *self, PyObject *args){	int v0, v1, x, y, len, nlen;	unsigned char *cp, *ncp;	PyObject *rv;	int i, bit;    	if ( !PyArg_ParseTuple(args, "s#iiii", &cp, &len, &x, &y, &v0, &v1) )		return 0; 	nlen = x*y;	if ( (nlen+7)/8 != len ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, nlen);	if ( rv == 0 )		return 0;	ncp = (unsigned char *)PyString_AsString(rv); 	bit = 0x80;	for ( i=0; i < nlen; i++ ) {		if ( *cp & bit )			*ncp++ = v1;		else			*ncp++ = v0;		bit >>= 1;		if ( bit == 0 ) {			bit = 0x80;			cp++;		}	}	return rv;} static PyObject *imageop_grey22grey(PyObject *self, PyObject *args){	int x, y, len, nlen;	unsigned char *cp, *ncp;	PyObject *rv;	int i, pos, value = 0, nvalue;    	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )		return 0; 	nlen = x*y;	if ( (nlen+3)/4 != len ) {		PyErr_SetString(ImageopError, "String has incorrect length");		return 0;	}    	rv = PyString_FromStringAndSize(NULL, nlen);	if ( rv == 0 )		return 0;	ncp = (unsigned char *)PyString_AsString(rv); 	pos = 0;	for ( i=0; i < nlen; i++ ) {		if ( pos == 0 ) {			value = *cp++;			pos = 8;		}		pos -= 2;

Lines 1–500 of 785.