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 ****/