[Python-checkins] python/dist/src/Modules imageop.c,2.28,2.29

sjoerd at users.sourceforge.net sjoerd at users.sourceforge.net
Sat Jan 10 15:43:45 EST 2004


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv5552/Modules

Modified Files:
	imageop.c 
Log Message:
The format of the string data used in the imageop module is described
as "This is the same format as used by gl.lrectwrite() and the imgfile
module."  This implies a certain byte order in multi-byte pixel
formats.  However, the code was originally written on an SGI
(big-endian) and *uses* the fact that bytes are stored in a particular
order in ints.  This means that the code uses and produces different
byte order on little-endian systems.

This fix adds a module-level flag "backward_compatible" (default not
set, and if not set, behaves as if set to 1--i.e. backward compatible)
that can be used on a little-endian system to use the same byte order
as the SGI.  Using this flag it is then possible to prepare
SGI-compatible images on a little-endian system.

This patch is the result of a (small) discussion on python-dev and was
submitted to SourceForge as patch #874358.


Index: imageop.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/imageop.c,v
retrieving revision 2.28
retrieving revision 2.29
diff -C2 -d -r2.28 -r2.29
*** imageop.c	2 Aug 2002 02:27:13 -0000	2.28
--- imageop.c	10 Jan 2004 20:43:43 -0000	2.29
***************
*** 25,29 ****
  
  static PyObject *ImageopError;
!  
  static PyObject *
  imageop_crop(PyObject *self, PyObject *args)
--- 25,76 ----
  
  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 int
! imageop_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)
***************
*** 498,506 ****
  {
  	int x, y, len, nlen;
! 	Py_UInt32 *cp;
  	unsigned char *ncp;
  	PyObject *rv;
  	int i, r, g, b;
! 	Py_UInt32 value, nvalue;
      
  	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
--- 545,553 ----
  {
  	int x, y, len, nlen;
! 	unsigned char *cp;
  	unsigned char *ncp;
  	PyObject *rv;
  	int i, r, g, b;
! 	int backward_compatible = imageop_backward_compatible();
      
  	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
***************
*** 520,535 ****
  	for ( i=0; i < nlen; i++ ) {
  		/* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
! 		value = *cp++;
! #if 0
! 		r = (value >>  5) & 7;
! 		g = (value >> 13) & 7;
! 		b = (value >> 22) & 3;
! #else
! 		r = (int) ((value & 0xff) / 255. * 7. + .5);
! 		g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
! 		b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
! #endif
! 		nvalue = (r<<5) | (b<<3) | g;
! 		*ncp++ = (unsigned char)nvalue;
  	}
  	return rv;
--- 567,583 ----
  	for ( i=0; i < nlen; i++ ) {
  		/* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
! 		if (backward_compatible) {
! 			Py_UInt32 value = * (Py_UInt32 *) cp;
! 			cp += 4;
! 			r = (int) ((value & 0xff) / 255. * 7. + .5);
! 			g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
! 			b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
! 		} else {
! 			cp++;		/* skip alpha channel */
! 			b = (int) (*cp++ / 255. * 3. + .5);
! 			g = (int) (*cp++ / 255. * 7. + .5);
! 			r = (int) (*cp++ / 255. * 7. + .5);
! 		}
! 		*ncp++ = (unsigned char)((r<<5) | (b<<3) | g);
  	}
  	return rv;
***************
*** 541,548 ****
  	int x, y, len, nlen;
  	unsigned char *cp;
! 	Py_UInt32 *ncp;
  	PyObject *rv;
  	int i, r, g, b;
! 	Py_UInt32 value, nvalue;
      
  	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
--- 589,597 ----
  	int x, y, len, nlen;
  	unsigned char *cp;
! 	unsigned char *ncp;
  	PyObject *rv;
  	int i, r, g, b;
! 	unsigned char value;
! 	int backward_compatible = imageop_backward_compatible();
      
  	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
***************
*** 558,562 ****
  	if ( rv == 0 )
  		return 0;
! 	ncp = (Py_UInt32 *)PyString_AsString(rv);
  
  	for ( i=0; i < nlen; i++ ) {
--- 607,611 ----
  	if ( rv == 0 )
  		return 0;
! 	ncp = (unsigned char *)PyString_AsString(rv);
  
  	for ( i=0; i < nlen; i++ ) {
***************
*** 571,576 ****
  		g = (g<<5) | (g<<3) | (g>>1);
  		b = (b<<6) | (b<<4) | (b<<2) | b;
! 		nvalue = r | (g<<8) | (b<<16);
! 		*ncp++ = nvalue;
  	}
  	return rv;
--- 620,633 ----
  		g = (g<<5) | (g<<3) | (g>>1);
  		b = (b<<6) | (b<<4) | (b<<2) | b;
! 		if (backward_compatible) {
! 			Py_UInt32 nvalue = r | (g<<8) | (b<<16);
! 			* (Py_UInt32 *) ncp = nvalue;
! 			ncp += 4;
! 		} else {
! 			*ncp++ = 0;
! 			*ncp++ = b;
! 			*ncp++ = g;
! 			*ncp++ = r;
! 		}
  	}
  	return rv;
***************
*** 581,589 ****
  {
  	int x, y, len, nlen;
! 	Py_UInt32 *cp;
  	unsigned char *ncp;
  	PyObject *rv;
  	int i, r, g, b;
! 	Py_UInt32 value, nvalue;
      
  	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
--- 638,647 ----
  {
  	int x, y, len, nlen;
! 	unsigned char *cp;
  	unsigned char *ncp;
  	PyObject *rv;
  	int i, r, g, b;
! 	int nvalue;
! 	int backward_compatible = imageop_backward_compatible();
      
  	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
***************
*** 602,609 ****
  
  	for ( i=0; i < nlen; i++ ) {
! 		value = *cp++;
! 		r = (value      ) & 0xff;
! 		g = (value >>  8) & 0xff;
! 		b = (value >> 16) & 0xff;
  		nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
  		if ( nvalue > 255 ) nvalue = 255;
--- 660,675 ----
  
  	for ( i=0; i < nlen; i++ ) {
! 		if (backward_compatible) {
! 			Py_UInt32 value = * (Py_UInt32 *) cp;
! 			cp += 4;
! 			r = (int) ((value & 0xff) / 255. * 7. + .5);
! 			g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
! 			b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
! 		} else {
! 			cp++;		/* skip alpha channel */
! 			b = *cp++;
! 			g = *cp++;
! 			r = *cp++;
! 		}
  		nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
  		if ( nvalue > 255 ) nvalue = 255;
***************
*** 618,625 ****
  	int x, y, len, nlen;
  	unsigned char *cp;
! 	Py_UInt32 *ncp;
  	PyObject *rv;
  	int i;
! 	Py_UInt32 value;
      
  	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
--- 684,692 ----
  	int x, y, len, nlen;
  	unsigned char *cp;
! 	unsigned char *ncp;
  	PyObject *rv;
  	int i;
! 	unsigned char value;
! 	int backward_compatible = imageop_backward_compatible();
      
  	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
***************
*** 635,643 ****
  	if ( rv == 0 )
  		return 0;
! 	ncp = (Py_UInt32 *)PyString_AsString(rv);
  
  	for ( i=0; i < nlen; i++ ) {
  		value = *cp++;
! 		*ncp++ = value | (value << 8 ) | (value << 16);
  	}
  	return rv;
--- 702,718 ----
  	if ( rv == 0 )
  		return 0;
! 	ncp = (unsigned char *)PyString_AsString(rv);
  
  	for ( i=0; i < nlen; i++ ) {
  		value = *cp++;
! 		if (backward_compatible) {
! 			* (Py_UInt32 *) ncp = (Py_UInt32) value | ((Py_UInt32) value << 8 ) | ((Py_UInt32) value << 16);
! 			ncp += 4;
! 		} else {
! 			*ncp++ = 0;
! 			*ncp++ = value;
! 			*ncp++ = value;
! 			*ncp++ = value;
! 		}
  	}
  	return rv;
***************
*** 700,708 ****
  initimageop(void)
  {
! 	PyObject *m, *d;
  	m = Py_InitModule("imageop", imageop_methods);
! 	d = PyModule_GetDict(m);
  	ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
  	if (ImageopError != NULL)
! 		PyDict_SetItemString(d, "error", ImageopError);
  }
--- 775,783 ----
  initimageop(void)
  {
! 	PyObject *m;
  	m = Py_InitModule("imageop", imageop_methods);
! 	ImageopDict = PyModule_GetDict(m);
  	ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
  	if (ImageopError != NULL)
! 		PyDict_SetItemString(ImageopDict, "error", ImageopError);
  }





More information about the Python-checkins mailing list