Mercurial > pygame
diff src/pixelarray.c @ 989:1bbdc02af359
Added PixelArray.replace() method. Moved pixelarray methods into an own source file.
| author | marcus |
|---|---|
| date | Fri, 04 Apr 2008 08:04:49 +0000 |
| parents | a708d9ecb43c |
| children | 404e3a0be4f8 |
line wrap: on
line diff
--- a/src/pixelarray.c Thu Apr 03 07:12:58 2008 +0000 +++ b/src/pixelarray.c Fri Apr 04 08:04:49 2008 +0000 @@ -1,6 +1,6 @@ /* pygame - Python Game Library - Copyright (C) 2007 Marcus von Appen + Copyright (C) 2007-2008 Marcus von Appen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -19,7 +19,7 @@ */ #define PYGAMEAPI_PIXELARRAY_INTERNAL - + #include "pygame.h" #include "pygamedocs.h" #include "surface.h" @@ -55,18 +55,10 @@ static PyObject* _pxarray_get_dict (PyPixelArray *self, void *closure); static PyObject* _pxarray_get_surface (PyPixelArray *self, void *closure); - static PyObject* _pxarray_repr (PyPixelArray *array); -static int _get_color_from_object (PyObject *val, SDL_PixelFormat *format, - Uint32 *color); -static PyObject* _get_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, - Uint32 row); -static void _set_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, - Uint32 row, SDL_PixelFormat *format, Uint32 color); static PyObject* _array_slice_internal (PyPixelArray *array, Sint32 _start, Sint32 _end, Sint32 _step); -static PyObject* _make_surface(PyPixelArray *array); /* Sequence methods */ static Py_ssize_t _pxarray_length (PyPixelArray *array); @@ -96,11 +88,15 @@ /* C API interfaces */ static PyObject* PyPixelArray_New (PyObject *surfobj); +#include "pixelarray_methods.c" + /** * Methods, which are bound to the PyPixelArray type. */ static PyMethodDef _pxarray_methods[] = { + { "replace", (PyCFunction) _replace_color, METH_VARARGS, + DOC_PIXELARRAYREPLACE }, { "make_surface", (PyCFunction) _make_surface, METH_NOARGS, DOC_PIXELARRAYMAKESURFACE }, { NULL, NULL, 0, NULL } @@ -467,120 +463,6 @@ return string; } -/** - * Tries to retrieve a valid color for a Surface. - */ -static int -_get_color_from_object (PyObject *val, SDL_PixelFormat *format, Uint32 *color) -{ - Uint8 rgba[4]; - - if (PyInt_Check (val)) - { - long intval = PyInt_AsLong (val); - if ((intval < INT_MIN) || (intval > INT_MAX)) - { - if (!PyErr_Occurred ()) - PyErr_SetString (PyExc_ValueError, "invalid color argument"); - return 0; - } - *color = (Uint32) intval; - return 1; - } - else if (PyLong_Check (val)) - { - long long longval = PyLong_AsLong (val); - if ((longval < INT_MIN) || (longval > INT_MAX)) - { - PyErr_SetString(PyExc_ValueError, "invalid color argument"); - return 0; - } - *color = (Uint32) longval; - return 1; - } - else if (RGBAFromObj (val, rgba)) - { - *color = (Uint32) SDL_MapRGBA - (format, rgba[0], rgba[1], rgba[2], rgba[3]); - return 1; - } - else - PyErr_SetString (PyExc_ValueError, "invalid color argument"); - return 0; -} - -/** - * Retrieves a single pixel located at index from the surface pixel - * array. - */ -static PyObject* -_get_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, Uint32 row) -{ - Uint32 pixel; - - switch (bpp) - { - case 1: - pixel = (Uint32)*((Uint8 *) pixels + row + _index); - break; - case 2: - pixel = (Uint32)*((Uint16 *) (pixels + row) + _index); - break; - case 3: - { - Uint8 *px = ((Uint8 *) (pixels + row) + _index * 3); -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - pixel = (px[0]) + (px[1] << 8) + (px[2] << 16); -#else - pixel = (px[2]) + (px[1] << 8) + (px[0] << 16); -#endif - break; - } - default: /* 4 bpp */ - pixel = *((Uint32 *) (pixels + row) + _index); - break; - } - - return PyInt_FromLong ((long)pixel); -} - -/** - * Sets a single pixel located at index from the surface pixel array. - */ -static void -_set_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, Uint32 row, - SDL_PixelFormat *format, Uint32 color) -{ - switch (bpp) - { - case 1: - *((Uint8 *) pixels + row + _index) = (Uint8) color; - break; - case 2: - *((Uint16 *) (pixels + row) + _index) = (Uint16) color; - break; - case 3: -#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) - *((Uint8 *) (pixels + row) + _index * 3 + (format->Rshift >> 3)) = - (Uint8) (color >> 16); - *((Uint8 *) (pixels + row) + _index * 3 + (format->Gshift >> 3)) = - (Uint8) (color >> 8); - *((Uint8 *) (pixels + row) + _index * 3 + (format->Bshift >> 3)) = - (Uint8) color; -#else - *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Rshift >> 3)) = - (Uint8) (color >> 16); - *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Gshift >> 3)) = - (Uint8) (color >> 8); - *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Bshift >> 3)) = - (Uint8) color; -#endif - break; - default: /* 4 bpp */ - *((Uint32 *) (pixels + row) + _index) = color; - break; - } -} /** * Creates a 2D slice of the array. @@ -638,173 +520,6 @@ xstep, ystep, padding, (PyObject *) array); } -/** - * Creates a new surface using the currently applied dimensions, step - * size, etc. - */ -static PyObject* -_make_surface(PyPixelArray *array) -{ - PyObject *newsf; - SDL_Surface *tmpsf; - SDL_Surface *newsurf; - Uint8 *pixels; - Uint8 *origpixels; - - SDL_Surface *surface; - int bpp; - Uint32 x = 0; - Uint32 y = 0; - Uint32 vx = 0; - Uint32 vy = 0; - Uint32 posx = 0; - Uint32 posy = 0; - Uint32 absxstep; - Uint32 absystep; - - surface = PySurface_AsSurface (array->surface); - bpp = surface->format->BytesPerPixel; - - /* Create the second surface. */ - tmpsf = SDL_CreateRGBSurface (surface->flags, - (int) (array->xlen / ABS (array->xstep)), - (int) (array->ylen / ABS (array->ystep)), bpp, surface->format->Rmask, - surface->format->Gmask, surface->format->Bmask, surface->format->Amask); - if (!tmpsf) - return RAISE (PyExc_SDLError, SDL_GetError ()); - - /* Guarantee an identical format. */ - newsurf = SDL_ConvertSurface (tmpsf, surface->format, surface->flags); - if (!newsurf) - { - SDL_FreeSurface (tmpsf); - return RAISE (PyExc_SDLError, SDL_GetError ()); - } - SDL_FreeSurface (tmpsf); - - /* Acquire a temporary lock. */ - if (SDL_MUSTLOCK (newsurf) == 0) - SDL_LockSurface (newsurf); - - pixels = (Uint8 *) newsurf->pixels; - origpixels = (Uint8 *) surface->pixels; - - absxstep = ABS (array->xstep); - absystep = ABS (array->ystep); - y = array->ystart; - - /* Single value assignment. */ - switch (bpp) - { - case 1: - while (posy < array->ylen) - { - vx = 0; - x = array->xstart; - posx = 0; - while (posx < array->xlen) - { - *((Uint8 *) pixels + vy * newsurf->pitch + vx) = - (Uint8)*((Uint8 *) origpixels + y * array->padding + x); - vx++; - x += array->xstep; - posx += absxstep; - } - vy++; - y += array->ystep; - posy += absystep; - } - break; - case 2: - while (posy < array->ylen) - { - vx = 0; - x = array->xstart; - posx = 0; - while (posx < array->xlen) - { - *((Uint16 *) (pixels + vy * newsurf->pitch) + vx) = - (Uint16)*((Uint16 *) (origpixels + y * array->padding) + x); - vx++; - x += array->xstep; - posx += absxstep; - } - vy++; - y += array->ystep; - posy += absystep; - } - break; - case 3: - { - Uint8 *px; - Uint8 *vpx; - SDL_PixelFormat *format = newsurf->format; - SDL_PixelFormat *vformat = surface->format; - - while (posy < array->ylen) - { - vx = 0; - x = array->xstart; - posx = 0; - while (posx < array->xlen) - { - px = (Uint8 *) (pixels + vy * newsurf->pitch) + vx * 3; - vpx = (Uint8 *) ((Uint8*) origpixels + y * array->padding) + - x * 3; - -#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) - *(px + (format->Rshift >> 3)) = - *(vpx + (vformat->Rshift >> 3)); - *(px + (format->Gshift >> 3)) = - *(vpx + (vformat->Gshift >> 3)); - *(px + (format->Bshift >> 3)) = - *(vpx + (vformat->Bshift >> 3)); -#else - *(px + 2 - (format->Rshift >> 3)) = - *(vpx + 2 - (vformat->Rshift >> 3)); - *(px + 2 - (format->Gshift >> 3)) = - *(vpx + 2 - (vformat->Gshift >> 3)); - *(px + 2 - (format->Bshift >> 3)) = - *(vpx + 2 - (vformat->Bshift >> 3)); -#endif - vx++; - x += array->xstep; - posx += absxstep; - } - vy++; - y += array->ystep; - posy += absystep; - } - break; - } - default: - while (posy < array->ylen) - { - vx = 0; - x = array->xstart; - posx = 0; - while (posx < array->xlen) - { - *((Uint32 *) (pixels + vy * newsurf->pitch) + vx) = - (Uint32)*((Uint32 *) (origpixels + y * array->padding) + x); - vx++; - x += array->xstep; - posx += absxstep; - } - vy++; - y += array->ystep; - posy += absystep; - } - break; - } - if (SDL_MUSTLOCK (newsurf) == 0) - SDL_UnlockSurface (newsurf); - newsf = PySurface_New (newsurf); - if (!newsf) - return NULL; - return newsf; -} - /**** Sequence interfaces ****/
