| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 1 |  | 
 | 2 | /* imageopmodule - Various operations on pictures */ | 
 | 3 |  | 
 | 4 | #ifdef sun | 
 | 5 | #define signed | 
 | 6 | #endif | 
 | 7 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 8 | #include "Python.h" | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 9 |  | 
| Guido van Rossum | 6901196 | 1998-04-23 20:23:00 +0000 | [diff] [blame] | 10 | #if SIZEOF_INT == 4 | 
 | 11 | typedef int Py_Int32; | 
 | 12 | typedef unsigned int Py_UInt32; | 
 | 13 | #else | 
 | 14 | #if SIZEOF_LONG == 4 | 
 | 15 | typedef long Py_Int32; | 
 | 16 | typedef unsigned long Py_UInt32; | 
 | 17 | #else | 
 | 18 | #error "No 4-byte integral type" | 
 | 19 | #endif | 
 | 20 | #endif | 
 | 21 |  | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 22 | #define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x)) | 
| Jack Jansen | 76c79e9 | 1996-01-22 14:55:15 +0000 | [diff] [blame] | 23 | #define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x))) | 
| Guido van Rossum | 6901196 | 1998-04-23 20:23:00 +0000 | [diff] [blame] | 24 | #define LONGP(cp, xmax, x, y) ((Py_Int32 *)(cp+4*(y*xmax+x))) | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 25 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 26 | static PyObject *ImageopError; | 
| Sjoerd Mullender | 7e6bbe1 | 2004-01-10 20:43:43 +0000 | [diff] [blame] | 27 | static PyObject *ImageopDict; | 
 | 28 |  | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 29 | /** | 
 | 30 |  * Check a coordonnate, make sure that (0 < value). | 
 | 31 |  * Return 0 on error. | 
 | 32 |  */ | 
 | 33 | static int | 
 | 34 | check_coordonnate(int value, const char* name) | 
 | 35 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 36 |     if ( 0 < value) | 
 | 37 |         return 1; | 
 | 38 |     PyErr_Format(PyExc_ValueError, "%s value is negative or nul", name); | 
 | 39 |     return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 40 | } | 
 | 41 |  | 
 | 42 | /** | 
 | 43 |  * Check integer overflow to make sure that product == x*y*size. | 
 | 44 |  * Return 0 on error. | 
 | 45 |  */ | 
 | 46 | static int | 
 | 47 | check_multiply_size(int product, int x, const char* xname, int y, const char* yname, int size) | 
 | 48 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 49 |     if ( !check_coordonnate(x, xname) ) | 
 | 50 |         return 0; | 
 | 51 |     if ( !check_coordonnate(y, yname) ) | 
 | 52 |         return 0; | 
 | 53 |     if ( size == (product / y) / x ) | 
 | 54 |         return 1; | 
 | 55 |     PyErr_SetString(ImageopError, "String has incorrect length"); | 
 | 56 |     return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 57 | } | 
 | 58 |  | 
 | 59 | /** | 
 | 60 |  * Check integer overflow to make sure that product == x*y. | 
 | 61 |  * Return 0 on error. | 
 | 62 |  */ | 
 | 63 | static int | 
 | 64 | check_multiply(int product, int x, int y) | 
 | 65 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 66 |     return check_multiply_size(product, x, "x", y, "y", 1); | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 67 | } | 
 | 68 |  | 
| Sjoerd Mullender | 7e6bbe1 | 2004-01-10 20:43:43 +0000 | [diff] [blame] | 69 | /* If this function returns true (the default if anything goes wrong), we're | 
 | 70 |    behaving in a backward-compatible way with respect to how multi-byte pixels | 
 | 71 |    are stored in the strings.  The code in this module was originally written | 
 | 72 |    for an SGI which is a big-endian system, and so the old code assumed that | 
 | 73 |    4-byte integers hold the R, G, and B values in a particular order. | 
 | 74 |    However, on little-endian systems the order is reversed, and so not | 
 | 75 |    actually compatible with what gl.lrectwrite and imgfile expect. | 
 | 76 |    (gl.lrectwrite and imgfile are also SGI-specific, however, it is | 
 | 77 |    conceivable that the data handled here comes from or goes to an SGI or that | 
 | 78 |    it is otherwise used in the expectation that the byte order in the strings | 
 | 79 |    is as specified.) | 
 | 80 |  | 
 | 81 |    The function returns the value of the module variable | 
 | 82 |    "backward_compatible", or 1 if the variable does not exist or is not an | 
 | 83 |    int. | 
 | 84 |  */ | 
 | 85 |  | 
 | 86 | static int | 
 | 87 | imageop_backward_compatible(void) | 
 | 88 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 89 |     static PyObject *bcos; | 
 | 90 |     PyObject *bco; | 
 | 91 |     long rc; | 
| Sjoerd Mullender | 7e6bbe1 | 2004-01-10 20:43:43 +0000 | [diff] [blame] | 92 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 93 |     if (ImageopDict == NULL) /* "cannot happen" */ | 
 | 94 |         return 1; | 
 | 95 |     if (bcos == NULL) { | 
 | 96 |         /* cache string object for future use */ | 
 | 97 |         bcos = PyString_FromString("backward_compatible"); | 
 | 98 |         if (bcos == NULL) | 
 | 99 |             return 1; | 
 | 100 |     } | 
 | 101 |     bco = PyDict_GetItem(ImageopDict, bcos); | 
 | 102 |     if (bco == NULL) | 
 | 103 |         return 1; | 
 | 104 |     if (!PyInt_Check(bco)) | 
 | 105 |         return 1; | 
 | 106 |     rc = PyInt_AsLong(bco); | 
 | 107 |     if (PyErr_Occurred()) { | 
 | 108 |         /* not an integer, or too large, or something */ | 
 | 109 |         PyErr_Clear(); | 
 | 110 |         rc = 1; | 
 | 111 |     } | 
 | 112 |     return rc != 0;             /* convert to values 0, 1 */ | 
| Sjoerd Mullender | 7e6bbe1 | 2004-01-10 20:43:43 +0000 | [diff] [blame] | 113 | } | 
 | 114 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 115 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 116 | imageop_crop(PyObject *self, PyObject *args) | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 117 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 118 |     char *cp, *ncp; | 
 | 119 |     short *nsp; | 
 | 120 |     Py_Int32 *nlp; | 
 | 121 |     int len, size, x, y, newx1, newx2, newy1, newy2, nlen; | 
 | 122 |     int ix, iy, xstep, ystep; | 
 | 123 |     PyObject *rv; | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 124 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 125 |     if ( !PyArg_ParseTuple(args, "s#iiiiiii", &cp, &len, &size, &x, &y, | 
 | 126 |                       &newx1, &newy1, &newx2, &newy2) ) | 
 | 127 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 128 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 129 |     if ( size != 1 && size != 2 && size != 4 ) { | 
 | 130 |         PyErr_SetString(ImageopError, "Size should be 1, 2 or 4"); | 
 | 131 |         return 0; | 
 | 132 |     } | 
 | 133 |     if ( !check_multiply_size(len, x, "x", y, "y", size) ) | 
 | 134 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 135 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 136 |     xstep = (newx1 < newx2)? 1 : -1; | 
 | 137 |     ystep = (newy1 < newy2)? 1 : -1; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 138 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 139 |     nlen = (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size; | 
 | 140 |     if ( !check_multiply_size(nlen, abs(newx2-newx1)+1, "abs(newx2-newx1)+1", abs(newy2-newy1)+1, "abs(newy2-newy1)+1", size) ) | 
 | 141 |         return 0; | 
 | 142 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 143 |     if ( rv == 0 ) | 
 | 144 |         return 0; | 
 | 145 |     ncp = (char *)PyString_AsString(rv); | 
 | 146 |     nsp = (short *)ncp; | 
 | 147 |     nlp = (Py_Int32 *)ncp; | 
 | 148 |     newy2 += ystep; | 
 | 149 |     newx2 += xstep; | 
 | 150 |     for( iy = newy1; iy != newy2; iy+=ystep ) { | 
 | 151 |         for ( ix = newx1; ix != newx2; ix+=xstep ) { | 
 | 152 |             if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) { | 
 | 153 |                 if ( size == 1 ) | 
 | 154 |                     *ncp++ = 0; | 
 | 155 |                 else | 
 | 156 |                     *nlp++ = 0; | 
 | 157 |             } else { | 
 | 158 |                 if ( size == 1 ) | 
 | 159 |                     *ncp++ = *CHARP(cp, x, ix, iy); | 
 | 160 |                 else if ( size == 2 ) | 
 | 161 |                     *nsp++ = *SHORTP(cp, x, ix, iy); | 
 | 162 |                 else | 
 | 163 |                     *nlp++ = *LONGP(cp, x, ix, iy); | 
 | 164 |             } | 
 | 165 |         } | 
 | 166 |     } | 
 | 167 |     return rv; | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 168 | } | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 169 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 170 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 171 | imageop_scale(PyObject *self, PyObject *args) | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 172 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 173 |     char *cp, *ncp; | 
 | 174 |     short *nsp; | 
 | 175 |     Py_Int32 *nlp; | 
 | 176 |     int len, size, x, y, newx, newy, nlen; | 
 | 177 |     int ix, iy; | 
 | 178 |     int oix, oiy; | 
 | 179 |     PyObject *rv; | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 180 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 181 |     if ( !PyArg_ParseTuple(args, "s#iiiii", | 
 | 182 |                       &cp, &len, &size, &x, &y, &newx, &newy) ) | 
 | 183 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 184 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 185 |     if ( size != 1 && size != 2 && size != 4 ) { | 
 | 186 |         PyErr_SetString(ImageopError, "Size should be 1, 2 or 4"); | 
 | 187 |         return 0; | 
 | 188 |     } | 
 | 189 |     if ( !check_multiply_size(len, x, "x", y, "y", size) ) | 
 | 190 |         return 0; | 
 | 191 |     nlen = newx*newy*size; | 
 | 192 |     if ( !check_multiply_size(nlen, newx, "newx", newy, "newy", size) ) | 
 | 193 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 194 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 195 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 196 |     if ( rv == 0 ) | 
 | 197 |         return 0; | 
 | 198 |     ncp = (char *)PyString_AsString(rv); | 
 | 199 |     nsp = (short *)ncp; | 
 | 200 |     nlp = (Py_Int32 *)ncp; | 
 | 201 |     for( iy = 0; iy < newy; iy++ ) { | 
 | 202 |         for ( ix = 0; ix < newx; ix++ ) { | 
 | 203 |             oix = ix * x / newx; | 
 | 204 |             oiy = iy * y / newy; | 
 | 205 |             if ( size == 1 ) | 
 | 206 |                 *ncp++ = *CHARP(cp, x, oix, oiy); | 
 | 207 |             else if ( size == 2 ) | 
 | 208 |                 *nsp++ = *SHORTP(cp, x, oix, oiy); | 
 | 209 |             else | 
 | 210 |                 *nlp++ = *LONGP(cp, x, oix, oiy); | 
 | 211 |         } | 
 | 212 |     } | 
 | 213 |     return rv; | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 214 | } | 
 | 215 |  | 
| Jack Jansen | d26b458 | 1993-01-22 15:34:43 +0000 | [diff] [blame] | 216 | /* Note: this routine can use a bit of optimizing */ | 
 | 217 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 218 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 219 | imageop_tovideo(PyObject *self, PyObject *args) | 
| Jack Jansen | d26b458 | 1993-01-22 15:34:43 +0000 | [diff] [blame] | 220 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 221 |     int maxx, maxy, x, y, len; | 
 | 222 |     int i; | 
 | 223 |     unsigned char *cp, *ncp; | 
 | 224 |     int width; | 
 | 225 |     PyObject *rv; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 226 |  | 
 | 227 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 228 |     if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &width, &maxx, &maxy) ) | 
 | 229 |         return 0; | 
| Jack Jansen | d26b458 | 1993-01-22 15:34:43 +0000 | [diff] [blame] | 230 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 231 |     if ( width != 1 && width != 4 ) { | 
 | 232 |         PyErr_SetString(ImageopError, "Size should be 1 or 4"); | 
 | 233 |         return 0; | 
 | 234 |     } | 
 | 235 |     if ( !check_multiply_size(len, maxx, "max", maxy, "maxy", width) ) | 
 | 236 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 237 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 238 |     rv = PyString_FromStringAndSize(NULL, len); | 
 | 239 |     if ( rv == 0 ) | 
 | 240 |         return 0; | 
 | 241 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Jack Jansen | d26b458 | 1993-01-22 15:34:43 +0000 | [diff] [blame] | 242 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 243 |     if ( width == 1 ) { | 
 | 244 |         memcpy(ncp, cp, maxx);                  /* Copy first line */ | 
 | 245 |         ncp += maxx; | 
 | 246 |         for (y=1; y<maxy; y++) {                /* Interpolate other lines */ | 
 | 247 |             for(x=0; x<maxx; x++) { | 
 | 248 |                 i = y*maxx + x; | 
 | 249 |                 *ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1; | 
 | 250 |             } | 
 | 251 |         } | 
 | 252 |     } else { | 
 | 253 |         memcpy(ncp, cp, maxx*4);                        /* Copy first line */ | 
 | 254 |         ncp += maxx*4; | 
 | 255 |         for (y=1; y<maxy; y++) {                /* Interpolate other lines */ | 
 | 256 |             for(x=0; x<maxx; x++) { | 
 | 257 |                 i = (y*maxx + x)*4 + 1; | 
 | 258 |                 *ncp++ = 0;                     /* Skip alfa comp */ | 
 | 259 |                 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1; | 
 | 260 |                 i++; | 
 | 261 |                 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1; | 
 | 262 |                 i++; | 
 | 263 |                 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1; | 
 | 264 |             } | 
 | 265 |         } | 
 | 266 |     } | 
 | 267 |     return rv; | 
| Jack Jansen | d26b458 | 1993-01-22 15:34:43 +0000 | [diff] [blame] | 268 | } | 
 | 269 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 270 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 271 | imageop_grey2mono(PyObject *self, PyObject *args) | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 272 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 273 |     int tres, x, y, len; | 
 | 274 |     unsigned char *cp, *ncp; | 
 | 275 |     unsigned char ovalue; | 
 | 276 |     PyObject *rv; | 
 | 277 |     int i, bit; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 278 |  | 
 | 279 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 280 |     if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &x, &y, &tres) ) | 
 | 281 |         return 0; | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 282 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 283 |     if ( !check_multiply(len, x, y) ) | 
 | 284 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 285 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 286 |     rv = PyString_FromStringAndSize(NULL, (len+7)/8); | 
 | 287 |     if ( rv == 0 ) | 
 | 288 |         return 0; | 
 | 289 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 290 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 291 |     bit = 0x80; | 
 | 292 |     ovalue = 0; | 
 | 293 |     for ( i=0; i < len; i++ ) { | 
 | 294 |         if ( (int)cp[i] > tres ) | 
 | 295 |             ovalue |= bit; | 
 | 296 |         bit >>= 1; | 
 | 297 |         if ( bit == 0 ) { | 
 | 298 |             *ncp++ = ovalue; | 
 | 299 |             bit = 0x80; | 
 | 300 |             ovalue = 0; | 
 | 301 |         } | 
 | 302 |     } | 
 | 303 |     if ( bit != 0x80 ) | 
 | 304 |         *ncp++ = ovalue; | 
 | 305 |     return rv; | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 306 | } | 
 | 307 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 308 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 309 | imageop_grey2grey4(PyObject *self, PyObject *args) | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 310 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 311 |     int x, y, len; | 
 | 312 |     unsigned char *cp, *ncp; | 
 | 313 |     unsigned char ovalue; | 
 | 314 |     PyObject *rv; | 
 | 315 |     int i; | 
 | 316 |     int pos; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 317 |  | 
 | 318 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 319 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 320 |         return 0; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 321 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 322 |     if ( !check_multiply(len, x, y) ) | 
 | 323 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 324 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 325 |     rv = PyString_FromStringAndSize(NULL, (len+1)/2); | 
 | 326 |     if ( rv == 0 ) | 
 | 327 |         return 0; | 
 | 328 |     ncp = (unsigned char *)PyString_AsString(rv); | 
 | 329 |     pos = 0; | 
 | 330 |     ovalue = 0; | 
 | 331 |     for ( i=0; i < len; i++ ) { | 
 | 332 |         ovalue |= ((int)cp[i] & 0xf0) >> pos; | 
 | 333 |         pos += 4; | 
 | 334 |         if ( pos == 8 ) { | 
 | 335 |             *ncp++ = ovalue; | 
 | 336 |             ovalue = 0; | 
 | 337 |             pos = 0; | 
 | 338 |         } | 
 | 339 |     } | 
 | 340 |     if ( pos != 0 ) | 
 | 341 |         *ncp++ = ovalue; | 
 | 342 |     return rv; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 343 | } | 
 | 344 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 345 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 346 | imageop_grey2grey2(PyObject *self, PyObject *args) | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 347 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 348 |     int x, y, len; | 
 | 349 |     unsigned char *cp, *ncp; | 
 | 350 |     unsigned char ovalue; | 
 | 351 |     PyObject *rv; | 
 | 352 |     int i; | 
 | 353 |     int pos; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 354 |  | 
 | 355 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 356 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 357 |         return 0; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 358 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 359 |     if ( !check_multiply(len, x, y) ) | 
 | 360 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 361 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 362 |     rv = PyString_FromStringAndSize(NULL, (len+3)/4); | 
 | 363 |     if ( rv == 0 ) | 
 | 364 |         return 0; | 
 | 365 |     ncp = (unsigned char *)PyString_AsString(rv); | 
 | 366 |     pos = 0; | 
 | 367 |     ovalue = 0; | 
 | 368 |     for ( i=0; i < len; i++ ) { | 
 | 369 |         ovalue |= ((int)cp[i] & 0xc0) >> pos; | 
 | 370 |         pos += 2; | 
 | 371 |         if ( pos == 8 ) { | 
 | 372 |             *ncp++ = ovalue; | 
 | 373 |             ovalue = 0; | 
 | 374 |             pos = 0; | 
 | 375 |         } | 
 | 376 |     } | 
 | 377 |     if ( pos != 0 ) | 
 | 378 |         *ncp++ = ovalue; | 
 | 379 |     return rv; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 380 | } | 
 | 381 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 382 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 383 | imageop_dither2mono(PyObject *self, PyObject *args) | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 384 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 385 |     int sum, x, y, len; | 
 | 386 |     unsigned char *cp, *ncp; | 
 | 387 |     unsigned char ovalue; | 
 | 388 |     PyObject *rv; | 
 | 389 |     int i, bit; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 390 |  | 
 | 391 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 392 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 393 |         return 0; | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 394 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 395 |     if ( !check_multiply(len, x, y) ) | 
 | 396 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 397 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 398 |     rv = PyString_FromStringAndSize(NULL, (len+7)/8); | 
 | 399 |     if ( rv == 0 ) | 
 | 400 |         return 0; | 
 | 401 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 402 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 403 |     bit = 0x80; | 
 | 404 |     ovalue = 0; | 
 | 405 |     sum = 0; | 
 | 406 |     for ( i=0; i < len; i++ ) { | 
 | 407 |         sum += cp[i]; | 
 | 408 |         if ( sum >= 256 ) { | 
 | 409 |             sum -= 256; | 
 | 410 |             ovalue |= bit; | 
 | 411 |         } | 
 | 412 |         bit >>= 1; | 
 | 413 |         if ( bit == 0 ) { | 
 | 414 |             *ncp++ = ovalue; | 
 | 415 |             bit = 0x80; | 
 | 416 |             ovalue = 0; | 
 | 417 |         } | 
 | 418 |     } | 
 | 419 |     if ( bit != 0x80 ) | 
 | 420 |         *ncp++ = ovalue; | 
 | 421 |     return rv; | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 422 | } | 
 | 423 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 424 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 425 | imageop_dither2grey2(PyObject *self, PyObject *args) | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 426 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 427 |     int x, y, len; | 
 | 428 |     unsigned char *cp, *ncp; | 
 | 429 |     unsigned char ovalue; | 
 | 430 |     PyObject *rv; | 
 | 431 |     int i; | 
 | 432 |     int pos; | 
 | 433 |     int sum = 0, nvalue; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 434 |  | 
 | 435 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 436 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 437 |         return 0; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 438 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 439 |     if ( !check_multiply(len, x, y) ) | 
 | 440 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 441 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 442 |     rv = PyString_FromStringAndSize(NULL, (len+3)/4); | 
 | 443 |     if ( rv == 0 ) | 
 | 444 |         return 0; | 
 | 445 |     ncp = (unsigned char *)PyString_AsString(rv); | 
 | 446 |     pos = 1; | 
 | 447 |     ovalue = 0; | 
 | 448 |     for ( i=0; i < len; i++ ) { | 
 | 449 |         sum += cp[i]; | 
 | 450 |         nvalue = sum & 0x180; | 
 | 451 |         sum -= nvalue; | 
 | 452 |         ovalue |= nvalue >> pos; | 
 | 453 |         pos += 2; | 
 | 454 |         if ( pos == 9 ) { | 
 | 455 |             *ncp++ = ovalue; | 
 | 456 |             ovalue = 0; | 
 | 457 |             pos = 1; | 
 | 458 |         } | 
 | 459 |     } | 
 | 460 |     if ( pos != 0 ) | 
 | 461 |         *ncp++ = ovalue; | 
 | 462 |     return rv; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 463 | } | 
 | 464 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 465 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 466 | imageop_mono2grey(PyObject *self, PyObject *args) | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 467 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 468 |     int v0, v1, x, y, len, nlen; | 
 | 469 |     unsigned char *cp, *ncp; | 
 | 470 |     PyObject *rv; | 
 | 471 |     int i, bit; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 472 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 473 |     if ( !PyArg_ParseTuple(args, "s#iiii", &cp, &len, &x, &y, &v0, &v1) ) | 
 | 474 |         return 0; | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 475 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 476 |     nlen = x*y; | 
 | 477 |     if ( !check_multiply(nlen, x, y) ) | 
 | 478 |         return 0; | 
 | 479 |     if ( (nlen+7)/8 != len ) { | 
 | 480 |         PyErr_SetString(ImageopError, "String has incorrect length"); | 
 | 481 |         return 0; | 
 | 482 |     } | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 483 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 484 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 485 |     if ( rv == 0 ) | 
 | 486 |         return 0; | 
 | 487 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 488 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 489 |     bit = 0x80; | 
 | 490 |     for ( i=0; i < nlen; i++ ) { | 
 | 491 |         if ( *cp & bit ) | 
 | 492 |             *ncp++ = v1; | 
 | 493 |         else | 
 | 494 |             *ncp++ = v0; | 
 | 495 |         bit >>= 1; | 
 | 496 |         if ( bit == 0 ) { | 
 | 497 |             bit = 0x80; | 
 | 498 |             cp++; | 
 | 499 |         } | 
 | 500 |     } | 
 | 501 |     return rv; | 
| Guido van Rossum | 5f59d60 | 1992-12-14 16:59:51 +0000 | [diff] [blame] | 502 | } | 
 | 503 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 504 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 505 | imageop_grey22grey(PyObject *self, PyObject *args) | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 506 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 507 |     int x, y, len, nlen; | 
 | 508 |     unsigned char *cp, *ncp; | 
 | 509 |     PyObject *rv; | 
 | 510 |     int i, pos, value = 0, nvalue; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 511 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 512 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 513 |         return 0; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 514 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 515 |     nlen = x*y; | 
 | 516 |     if ( !check_multiply(nlen, x, y) ) { | 
 | 517 |         return 0; | 
 | 518 |     } | 
 | 519 |     if ( (nlen+3)/4 != len ) { | 
 | 520 |         PyErr_SetString(ImageopError, "String has incorrect length"); | 
 | 521 |         return 0; | 
 | 522 |     } | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 523 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 524 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 525 |     if ( rv == 0 ) | 
 | 526 |         return 0; | 
 | 527 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 528 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 529 |     pos = 0; | 
 | 530 |     for ( i=0; i < nlen; i++ ) { | 
 | 531 |         if ( pos == 0 ) { | 
 | 532 |             value = *cp++; | 
 | 533 |             pos = 8; | 
 | 534 |         } | 
 | 535 |         pos -= 2; | 
 | 536 |         nvalue = (value >> pos) & 0x03; | 
 | 537 |         *ncp++ = nvalue | (nvalue << 2) | | 
 | 538 |                  (nvalue << 4) | (nvalue << 6); | 
 | 539 |     } | 
 | 540 |     return rv; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 541 | } | 
 | 542 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 543 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 544 | imageop_grey42grey(PyObject *self, PyObject *args) | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 545 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 546 |     int x, y, len, nlen; | 
 | 547 |     unsigned char *cp, *ncp; | 
 | 548 |     PyObject *rv; | 
 | 549 |     int i, pos, value = 0, nvalue; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 550 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 551 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 552 |         return 0; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 553 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 554 |     nlen = x*y; | 
 | 555 |     if ( !check_multiply(nlen, x, y) ) | 
 | 556 |         return 0; | 
 | 557 |     if ( (nlen+1)/2 != len ) { | 
 | 558 |         PyErr_SetString(ImageopError, "String has incorrect length"); | 
 | 559 |         return 0; | 
 | 560 |     } | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 561 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 562 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 563 |     if ( rv == 0 ) | 
 | 564 |         return 0; | 
 | 565 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 566 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 567 |     pos = 0; | 
 | 568 |     for ( i=0; i < nlen; i++ ) { | 
 | 569 |         if ( pos == 0 ) { | 
 | 570 |             value = *cp++; | 
 | 571 |             pos = 8; | 
 | 572 |         } | 
 | 573 |         pos -= 4; | 
 | 574 |         nvalue = (value >> pos) & 0x0f; | 
 | 575 |         *ncp++ = nvalue | (nvalue << 4); | 
 | 576 |     } | 
 | 577 |     return rv; | 
| Jack Jansen | de3adf9 | 1992-12-22 14:05:55 +0000 | [diff] [blame] | 578 | } | 
 | 579 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 580 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 581 | imageop_rgb2rgb8(PyObject *self, PyObject *args) | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 582 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 583 |     int x, y, len, nlen; | 
 | 584 |     unsigned char *cp; | 
 | 585 |     unsigned char *ncp; | 
 | 586 |     PyObject *rv; | 
 | 587 |     int i, r, g, b; | 
 | 588 |     int backward_compatible = imageop_backward_compatible(); | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 589 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 590 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 591 |         return 0; | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 592 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 593 |     if ( !check_multiply_size(len, x, "x", y, "y", 4) ) | 
 | 594 |         return 0; | 
 | 595 |     nlen = x*y; | 
 | 596 |     if ( !check_multiply(nlen, x, y) ) | 
 | 597 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 598 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 599 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 600 |     if ( rv == 0 ) | 
 | 601 |         return 0; | 
 | 602 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 603 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 604 |     for ( i=0; i < nlen; i++ ) { | 
 | 605 |         /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */ | 
 | 606 |         if (backward_compatible) { | 
 | 607 |             Py_UInt32 value = * (Py_UInt32 *) cp; | 
 | 608 |             cp += 4; | 
 | 609 |             r = (int) ((value & 0xff) / 255. * 7. + .5); | 
 | 610 |             g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5); | 
 | 611 |             b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5); | 
 | 612 |         } else { | 
 | 613 |             cp++;                       /* skip alpha channel */ | 
 | 614 |             b = (int) (*cp++ / 255. * 3. + .5); | 
 | 615 |             g = (int) (*cp++ / 255. * 7. + .5); | 
 | 616 |             r = (int) (*cp++ / 255. * 7. + .5); | 
 | 617 |         } | 
 | 618 |         *ncp++ = (unsigned char)((r<<5) | (b<<3) | g); | 
 | 619 |     } | 
 | 620 |     return rv; | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 621 | } | 
 | 622 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 623 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 624 | imageop_rgb82rgb(PyObject *self, PyObject *args) | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 625 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 626 |     int x, y, len, nlen; | 
 | 627 |     unsigned char *cp; | 
 | 628 |     unsigned char *ncp; | 
 | 629 |     PyObject *rv; | 
 | 630 |     int i, r, g, b; | 
 | 631 |     unsigned char value; | 
 | 632 |     int backward_compatible = imageop_backward_compatible(); | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 633 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 634 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 635 |         return 0; | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 636 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 637 |     if ( !check_multiply(len, x, y) ) | 
 | 638 |         return 0; | 
 | 639 |     nlen = x*y*4; | 
 | 640 |     if ( !check_multiply_size(nlen, x, "x", y, "y", 4) ) | 
 | 641 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 642 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 643 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 644 |     if ( rv == 0 ) | 
 | 645 |         return 0; | 
 | 646 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 647 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 648 |     for ( i=0; i < len; i++ ) { | 
 | 649 |         /* Bits in source: RRRBBGGG | 
 | 650 |         ** Red and Green are multiplied by 36.5, Blue by 85 | 
 | 651 |         */ | 
 | 652 |         value = *cp++; | 
 | 653 |         r = (value >> 5) & 7; | 
 | 654 |         g = (value     ) & 7; | 
 | 655 |         b = (value >> 3) & 3; | 
 | 656 |         r = (r<<5) | (r<<3) | (r>>1); | 
 | 657 |         g = (g<<5) | (g<<3) | (g>>1); | 
 | 658 |         b = (b<<6) | (b<<4) | (b<<2) | b; | 
 | 659 |         if (backward_compatible) { | 
 | 660 |             Py_UInt32 nvalue = r | (g<<8) | (b<<16); | 
 | 661 |             * (Py_UInt32 *) ncp = nvalue; | 
 | 662 |             ncp += 4; | 
 | 663 |         } else { | 
 | 664 |             *ncp++ = 0; | 
 | 665 |             *ncp++ = b; | 
 | 666 |             *ncp++ = g; | 
 | 667 |             *ncp++ = r; | 
 | 668 |         } | 
 | 669 |     } | 
 | 670 |     return rv; | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 671 | } | 
 | 672 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 673 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 674 | imageop_rgb2grey(PyObject *self, PyObject *args) | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 675 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 676 |     int x, y, len, nlen; | 
 | 677 |     unsigned char *cp; | 
 | 678 |     unsigned char *ncp; | 
 | 679 |     PyObject *rv; | 
 | 680 |     int i, r, g, b; | 
 | 681 |     int nvalue; | 
 | 682 |     int backward_compatible = imageop_backward_compatible(); | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 683 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 684 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 685 |         return 0; | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 686 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 687 |     if ( !check_multiply_size(len, x, "x", y, "y", 4) ) | 
 | 688 |         return 0; | 
 | 689 |     nlen = x*y; | 
 | 690 |     if ( !check_multiply(nlen, x, y) ) | 
 | 691 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 692 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 693 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 694 |     if ( rv == 0 ) | 
 | 695 |         return 0; | 
 | 696 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 697 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 698 |     for ( i=0; i < nlen; i++ ) { | 
 | 699 |         if (backward_compatible) { | 
 | 700 |             Py_UInt32 value = * (Py_UInt32 *) cp; | 
 | 701 |             cp += 4; | 
 | 702 |             r = (int) ((value & 0xff) / 255. * 7. + .5); | 
 | 703 |             g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5); | 
 | 704 |             b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5); | 
 | 705 |         } else { | 
 | 706 |             cp++;                       /* skip alpha channel */ | 
 | 707 |             b = *cp++; | 
 | 708 |             g = *cp++; | 
 | 709 |             r = *cp++; | 
 | 710 |         } | 
 | 711 |         nvalue = (int)(0.30*r + 0.59*g + 0.11*b); | 
 | 712 |         if ( nvalue > 255 ) nvalue = 255; | 
 | 713 |         *ncp++ = (unsigned char)nvalue; | 
 | 714 |     } | 
 | 715 |     return rv; | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 716 | } | 
 | 717 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 718 | static PyObject * | 
| Peter Schneider-Kamp | fe74263 | 2000-07-10 09:55:32 +0000 | [diff] [blame] | 719 | imageop_grey2rgb(PyObject *self, PyObject *args) | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 720 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 721 |     int x, y, len, nlen; | 
 | 722 |     unsigned char *cp; | 
 | 723 |     unsigned char *ncp; | 
 | 724 |     PyObject *rv; | 
 | 725 |     int i; | 
 | 726 |     unsigned char value; | 
 | 727 |     int backward_compatible = imageop_backward_compatible(); | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 728 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 729 |     if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) ) | 
 | 730 |         return 0; | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 731 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 732 |     if ( !check_multiply(len, x, y) ) | 
 | 733 |         return 0; | 
 | 734 |     nlen = x*y*4; | 
 | 735 |     if ( !check_multiply_size(nlen, x, "x", y, "y", 4) ) | 
 | 736 |         return 0; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 737 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 738 |     rv = PyString_FromStringAndSize(NULL, nlen); | 
 | 739 |     if ( rv == 0 ) | 
 | 740 |         return 0; | 
 | 741 |     ncp = (unsigned char *)PyString_AsString(rv); | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 742 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 743 |     for ( i=0; i < len; i++ ) { | 
 | 744 |         value = *cp++; | 
 | 745 |         if (backward_compatible) { | 
 | 746 |             * (Py_UInt32 *) ncp = (Py_UInt32) value | ((Py_UInt32) value << 8 ) | ((Py_UInt32) value << 16); | 
 | 747 |             ncp += 4; | 
 | 748 |         } else { | 
 | 749 |             *ncp++ = 0; | 
 | 750 |             *ncp++ = value; | 
 | 751 |             *ncp++ = value; | 
 | 752 |             *ncp++ = value; | 
 | 753 |         } | 
 | 754 |     } | 
 | 755 |     return rv; | 
| Jack Jansen | 4fada9c | 1993-02-19 15:51:41 +0000 | [diff] [blame] | 756 | } | 
 | 757 |  | 
| Roger E. Masse | a141f8a | 1996-12-20 20:50:39 +0000 | [diff] [blame] | 758 | static PyMethodDef imageop_methods[] = { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 759 |     { "crop",                   imageop_crop, METH_VARARGS }, | 
 | 760 |     { "scale",                  imageop_scale, METH_VARARGS }, | 
 | 761 |     { "grey2mono",              imageop_grey2mono, METH_VARARGS }, | 
 | 762 |     { "grey2grey2",             imageop_grey2grey2, METH_VARARGS }, | 
 | 763 |     { "grey2grey4",             imageop_grey2grey4, METH_VARARGS }, | 
 | 764 |     { "dither2mono",            imageop_dither2mono, METH_VARARGS }, | 
 | 765 |     { "dither2grey2",           imageop_dither2grey2, METH_VARARGS }, | 
 | 766 |     { "mono2grey",              imageop_mono2grey, METH_VARARGS }, | 
 | 767 |     { "grey22grey",             imageop_grey22grey, METH_VARARGS }, | 
 | 768 |     { "grey42grey",             imageop_grey42grey, METH_VARARGS }, | 
 | 769 |     { "tovideo",                imageop_tovideo, METH_VARARGS }, | 
 | 770 |     { "rgb2rgb8",               imageop_rgb2rgb8, METH_VARARGS }, | 
 | 771 |     { "rgb82rgb",               imageop_rgb82rgb, METH_VARARGS }, | 
 | 772 |     { "rgb2grey",               imageop_rgb2grey, METH_VARARGS }, | 
 | 773 |     { "grey2rgb",               imageop_grey2rgb, METH_VARARGS }, | 
 | 774 |     { 0,                    0 } | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 775 | }; | 
 | 776 |  | 
 | 777 |  | 
| Mark Hammond | fe51c6d | 2002-08-02 02:27:13 +0000 | [diff] [blame] | 778 | PyMODINIT_FUNC | 
| Thomas Wouters | f3f33dc | 2000-07-21 06:00:07 +0000 | [diff] [blame] | 779 | initimageop(void) | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 780 | { | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 781 |     PyObject *m; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 782 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 783 |     if (PyErr_WarnPy3k("the imageop module has been removed in " | 
 | 784 |                        "Python 3.0", 2) < 0) | 
 | 785 |         return; | 
| Benjamin Peterson | 8d77d44 | 2008-09-30 01:31:49 +0000 | [diff] [blame] | 786 |  | 
| Antoine Pitrou | c83ea13 | 2010-05-09 14:46:46 +0000 | [diff] [blame] | 787 |     m = Py_InitModule("imageop", imageop_methods); | 
 | 788 |     if (m == NULL) | 
 | 789 |         return; | 
 | 790 |     ImageopDict = PyModule_GetDict(m); | 
 | 791 |     ImageopError = PyErr_NewException("imageop.error", NULL, NULL); | 
 | 792 |     if (ImageopError != NULL) | 
 | 793 |         PyDict_SetItemString(ImageopDict, "error", ImageopError); | 
| Guido van Rossum | 0317a47 | 1992-10-26 13:40:15 +0000 | [diff] [blame] | 794 | } |