~ubuntu-branches/debian/experimental/pygame/experimental

« back to all changes in this revision

Viewing changes to src/surface.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng, Vincent Cheng, Jakub Wilk
  • Date: 2014-02-19 01:41:42 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20140219014142-ab2ar7sw7yoisv7x
Tags: 1.9.2~pre~r3348-1
[ Vincent Cheng ]
* Set Debian Python Modules Team <python-modules-team@l.a.d.o> as new
  maintainer, and move Ed Boraas into Uploaders with his consent.
  - Update Vcs-* fields accordingly.
* Replace dependency ttf-freefont -> fonts-freefont-ttf. (Closes: #738244)
* Replace build-dep on python3.2 (>= 3.2.3-7) with build-conflicts instead.
* Remove dependency on ${python:Provides}.
* Remove Replaces+Conflicts with obsolete pygame packages.
* Update Standards version to 3.9.5.
* Update my email address.

[ Jakub Wilk ]
* Run tests only if DEB_BUILD_OPTIONS=nocheck is not set.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include "doc/surface_doc.h"
28
28
#include "structmember.h"
29
29
#include "pgcompat.h"
30
 
#include "pgview.h"
31
 
#include "pgarrinter.h"
 
30
#include "pgbufferproxy.h"
32
31
 
33
32
typedef enum {
 
33
    VIEWKIND_0D = 0,
 
34
    VIEWKIND_1D = 1,
34
35
    VIEWKIND_2D = 2,
35
36
    VIEWKIND_3D = 3,
36
37
    VIEWKIND_RED,
37
38
    VIEWKIND_GREEN,
38
39
    VIEWKIND_BLUE,
39
 
    VIEWKIND_ALPHA,
 
40
    VIEWKIND_ALPHA
40
41
} SurfViewKind;
41
42
 
 
43
/* To avoid problems with non-const Py_buffer format field */
 
44
static char FormatUint8[] = "B";
 
45
static char FormatUint16[] = "=H";
 
46
static char FormatUint24[] = "3x";
 
47
static char FormatUint32[] = "=I";
 
48
 
 
49
typedef struct pg_bufferinternal_s {
 
50
    PyObject *consumer_ref;    /* A weak reference to a bufferproxy object   */
 
51
    Py_ssize_t mem[6];         /* Enough memory for dim 3 shape and strides  */
 
52
} Pg_bufferinternal;
 
53
 
42
54
int
43
55
PySurface_Blit (PyObject * dstobj, PyObject * srcobj, SDL_Rect * dstrect,
44
56
                SDL_Rect * srcrect, int the_args);
101
113
static PyObject *surf_get_offset (PyObject *self);
102
114
static PyObject *surf_get_parent (PyObject *self);
103
115
static PyObject *surf_subsurface (PyObject *self, PyObject *args);
 
116
static PyObject *surf_get_view (PyObject *self, PyObject *args);
104
117
static PyObject *surf_get_buffer (PyObject *self);
105
 
static PyObject *surf_get_view (PyObject *self, PyObject *args, PyObject *kwds);
106
118
static PyObject *surf_get_bounding_rect (PyObject *self, PyObject *args,
107
119
                                         PyObject *kwargs);
108
120
static PyObject *surf_get_pixels_address (PyObject *self,
109
121
                                          PyObject *closure);
110
 
static int surf_view_kind(PyObject *obj, void *view_kind_vptr);
111
 
#if PY3
112
 
static void surf_arraystruct_capsule_destr(PyObject *capsule);
113
 
#endif
114
 
static void surf_view_destr(PyObject *view);
 
122
static int _view_kind (PyObject *obj, void *view_kind_vptr);
 
123
static int _get_buffer_0D (PyObject *obj, Py_buffer *view_p, int flags);
 
124
static int _get_buffer_1D (PyObject *obj, Py_buffer *view_p, int flags);
 
125
static int _get_buffer_2D (PyObject *obj, Py_buffer *view_p, int flags);
 
126
static int _get_buffer_3D (PyObject *obj, Py_buffer *view_p, int flags);
 
127
static int _get_buffer_red (PyObject *obj, Py_buffer *view_p, int flags);
 
128
static int _get_buffer_green (PyObject *obj, Py_buffer *view_p, int flags);
 
129
static int _get_buffer_blue (PyObject *obj, Py_buffer *view_p, int flags);
 
130
static int _get_buffer_alpha (PyObject *obj, Py_buffer *view_p, int flags);
 
131
static int _get_buffer_colorplane (PyObject *obj,
 
132
                                   Py_buffer *view_p,
 
133
                                   int flags,
 
134
                                   char *name,
 
135
                                   Uint32 mask);
 
136
static int _init_buffer(PyObject *surf, Py_buffer *view_p, int flags);
 
137
static void _release_buffer(Py_buffer *view_p);
115
138
static PyObject *_raise_get_view_ndim_error(int bitsize, SurfViewKind kind);
116
139
 
117
 
 
118
140
static PyGetSetDef surface_getsets[] = {
119
141
    { "_pixels_address", (getter)surf_get_pixels_address,
120
142
      NULL, "pixel buffer address (readonly)", NULL },
211
233
    { "get_bounding_rect", (PyCFunction) surf_get_bounding_rect,
212
234
      METH_VARARGS | METH_KEYWORDS,
213
235
      DOC_SURFACEGETBOUNDINGRECT},
 
236
    { "get_view", (PyCFunction) surf_get_view, METH_VARARGS,
 
237
      DOC_SURFACEGETVIEW},
214
238
    { "get_buffer", (PyCFunction) surf_get_buffer, METH_NOARGS,
215
239
      DOC_SURFACEGETBUFFER},
216
 
    { "get_view", (PyCFunction) surf_get_view, METH_VARARGS | METH_KEYWORDS,
217
 
      DOC_SURFACEGETVIEW},
218
240
 
219
241
    { NULL, NULL, 0, NULL }
220
242
};
295
317
}
296
318
 
297
319
/* surface object internals */
298
 
static void 
 
320
static void
299
321
surface_cleanup (PySurfaceObject *self)
300
322
{
301
323
    if (self->surf) {
323
345
    }
324
346
}
325
347
 
326
 
static void 
 
348
static void
327
349
surface_dealloc (PyObject *self)
328
350
{
329
351
    if (((PySurfaceObject *) self)->weakreflist)
351
373
    return Text_FromUTF8 (str);
352
374
}
353
375
 
354
 
static intptr_t 
 
376
static intptr_t
355
377
surface_init (PySurfaceObject *self, PyObject *args, PyObject *kwds)
356
378
{
357
379
    Uint32 flags = 0;
368
390
       return -1;
369
391
 
370
392
    if (PySequence_Check (size) && (length = PySequence_Length (size)) == 2) {
371
 
        if ( (!IntFromObjIndex (size, 0, &width)) || 
 
393
        if ( (!IntFromObjIndex (size, 0, &width)) ||
372
394
             (!IntFromObjIndex (size, 1, &height)) ) {
373
395
            RAISE (PyExc_ValueError, "size needs to be (int width, int height)");
374
396
            return -1;
524
546
        RAISE (PyExc_SDLError, SDL_GetError ());
525
547
        return -1;
526
548
    }
527
 
    
 
549
 
528
550
    if (masks) {
529
551
    /* Confirm the surface was created correctly (masks were valid).
530
552
       Also ensure that 24 and 32 bit surfaces have 8 bit fields
553
575
        self->surf = surface;
554
576
        self->subsurface = NULL;
555
577
    }
556
 
    
 
578
 
557
579
    return 0;
558
580
}
559
581
 
700
722
    SDL_PixelFormat *format = surf->format;
701
723
    Uint8 *pixels = (Uint8 *) surf->pixels;
702
724
    int x, y;
703
 
    Uint32 color;
 
725
    Sint32 color;
704
726
    Uint8 *pix;
705
727
 
706
728
    if (!PyArg_ParseTuple (args, "(ii)", &x, &y))
830
852
    tuple = PyTuple_New (len);
831
853
    if (!tuple)
832
854
        return NULL;
833
 
    
 
855
 
834
856
    for (i = 0; i < len; i++) {
835
857
        tmp = PyWeakref_GetObject (PyList_GetItem (surf->locklist, i));
836
858
        Py_INCREF (tmp);
980
1002
        return RAISE (PyExc_ValueError,
981
1003
                      "takes a sequence of integers of RGB for argument 2");
982
1004
    }
983
 
    
 
1005
 
984
1006
    if (!pal) {
985
1007
        PyErr_SetString (PyExc_SDLError, "Surface is not palettized\n");
986
1008
        return NULL;
1470
1492
 
1471
1493
 
1472
1494
        if (blendargs != 0) {
1473
 
            
1474
 
            /* 
 
1495
 
 
1496
            /*
1475
1497
            printf ("Using blendargs: %d\n", blendargs);
1476
1498
            */
1477
1499
            result = surface_fill_blend (surf, &sdlrect, color, blendargs);
1749
1771
{
1750
1772
    SDL_Surface *surf = PySurface_AsSurface (self);
1751
1773
    /* Need to use 64bit vars so this works on 64 bit pythons. */
1752
 
    Uint64 r, g, b, a;
 
1774
    unsigned long r, g, b, a;
1753
1775
 
1754
1776
    if (!PyArg_ParseTuple (args, "(kkkk)", &r, &g, &b, &a))
1755
1777
        return NULL;
1789
1811
surf_set_shifts (PyObject *self, PyObject *args)
1790
1812
{
1791
1813
    SDL_Surface *surf = PySurface_AsSurface (self);
1792
 
    Uint64 r, g, b, a;
 
1814
    unsigned long r, g, b, a;
1793
1815
 
1794
1816
    if (!PyArg_ParseTuple (args, "(kkkk)", &r, &g, &b, &a))
1795
1817
        return NULL;
1966
1988
static PyObject *
1967
1989
surf_get_bounding_rect (PyObject *self, PyObject *args, PyObject *kwargs)
1968
1990
{
 
1991
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
 
1992
    const int BYTE0 = 0;
 
1993
    const int BYTE1 = 1;
 
1994
    const int BYTE2 = 2;
 
1995
#else
 
1996
    const int BYTE0 = 2;
 
1997
    const int BYTE1 = 1;
 
1998
    const int BYTE2 = 0;
 
1999
#endif
1969
2000
    PyObject *rect;
1970
2001
    SDL_Surface *surf = PySurface_AsSurface (self);
1971
2002
    SDL_PixelFormat *format = surf->format;
1975
2006
    int min_x, min_y, max_x, max_y;
1976
2007
    int min_alpha = 1;
1977
2008
    int found_alpha = 0;
 
2009
    Uint32 value;
1978
2010
    Uint8 r, g, b, a;
1979
2011
    int has_colorkey = 0;
1980
2012
    Uint8 keyr, keyg, keyb;
1983
2015
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwids, &min_alpha))
1984
2016
       return RAISE (PyExc_ValueError,
1985
2017
                     "get_bounding_rect only accepts a single optional min_alpha argument");
1986
 
    
 
2018
 
1987
2019
    if (!surf)
1988
2020
        return RAISE (PyExc_SDLError, "display Surface quit");
1989
2021
 
1996
2028
                     surf->format,
1997
2029
                     &keyr, &keyg, &keyb, &a);
1998
2030
    }
1999
 
    
 
2031
 
2000
2032
    pixels = (Uint8 *) surf->pixels;
2001
 
    
 
2033
    if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
 
2034
        pixels += format->BytesPerPixel - sizeof (Uint32);
 
2035
    }
 
2036
 
2002
2037
    min_y = 0;
2003
2038
    min_x = 0;
2004
2039
    max_x = surf->w;
2008
2043
    for (y = max_y - 1; y >= min_y; --y) {
2009
2044
        for (x = min_x; x < max_x; ++x) {
2010
2045
            pixel = (pixels + y * surf->pitch) + x*format->BytesPerPixel;
2011
 
            SDL_GetRGBA (*((Uint32*)pixel), surf->format, &r, &g, &b, &a);
 
2046
            switch (format->BytesPerPixel) {
 
2047
 
 
2048
            case 1:
 
2049
                value = *pixel;
 
2050
                break;
 
2051
            case 2:
 
2052
                value = *(Uint16 *)pixel;
 
2053
                break;
 
2054
            case 3:
 
2055
                value = pixel[BYTE0];
 
2056
                value |= pixel[BYTE1] << 8;
 
2057
                value |= pixel[BYTE2] << 16;
 
2058
                break;
 
2059
            default:
 
2060
                assert(format->BytesPerPixel == 4);
 
2061
                value = *(Uint32 *)pixel;
 
2062
            }
 
2063
            SDL_GetRGBA (value, surf->format, &r, &g, &b, &a);
2012
2064
            if ((a >= min_alpha && has_colorkey == 0) ||
2013
2065
                (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) {
2014
2066
                found_alpha = 1;
2024
2076
    for (x = max_x - 1; x >= min_x; --x) {
2025
2077
        for (y = min_y; y < max_y; ++y) {
2026
2078
            pixel = (pixels + y * surf->pitch) + x*format->BytesPerPixel;
2027
 
            SDL_GetRGBA (*((Uint32*)pixel), surf->format, &r, &g, &b, &a);
 
2079
            switch (format->BytesPerPixel) {
 
2080
 
 
2081
            case 1:
 
2082
                value = *pixel;
 
2083
                break;
 
2084
            case 2:
 
2085
                value = *(Uint16 *)pixel;
 
2086
                break;
 
2087
            case 3:
 
2088
                value = pixel[BYTE0];
 
2089
                value |= pixel[BYTE1] << 8;
 
2090
                value |= pixel[BYTE2] << 16;
 
2091
                break;
 
2092
            default:
 
2093
                assert(format->BytesPerPixel == 4);
 
2094
                value = *(Uint32 *)pixel;
 
2095
            }
 
2096
            SDL_GetRGBA (value, surf->format, &r, &g, &b, &a);
2028
2097
            if ((a >= min_alpha && has_colorkey == 0) ||
2029
2098
                (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) {
2030
2099
                found_alpha = 1;
2041
2110
        min_y = y;
2042
2111
        for (x = min_x; x < max_x; ++x) {
2043
2112
            pixel = (pixels + y * surf->pitch) + x*format->BytesPerPixel;
2044
 
            SDL_GetRGBA (*((Uint32*)pixel), surf->format, &r, &g, &b, &a);
 
2113
            switch (format->BytesPerPixel) {
 
2114
 
 
2115
            case 1:
 
2116
                value = *pixel;
 
2117
                break;
 
2118
            case 2:
 
2119
                value = *(Uint16 *)pixel;
 
2120
                break;
 
2121
            case 3:
 
2122
                value = pixel[BYTE0];
 
2123
                value |= pixel[BYTE1] << 8;
 
2124
                value |= pixel[BYTE2] << 16;
 
2125
                break;
 
2126
            default:
 
2127
                assert(format->BytesPerPixel == 4);
 
2128
                value = *(Uint32 *)pixel;
 
2129
            }
 
2130
            SDL_GetRGBA (value, surf->format, &r, &g, &b, &a);
2045
2131
            if ((a >= min_alpha && has_colorkey == 0) ||
2046
2132
                (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) {
2047
2133
                found_alpha = 1;
2057
2143
        min_x = x;
2058
2144
        for (y = min_y; y < max_y; ++y) {
2059
2145
            pixel = (pixels + y * surf->pitch) + x*format->BytesPerPixel;
2060
 
            SDL_GetRGBA (*((Uint32*)pixel), surf->format, &r, &g, &b, &a);
 
2146
            switch (format->BytesPerPixel) {
 
2147
 
 
2148
            case 1:
 
2149
                value = *pixel;
 
2150
                break;
 
2151
            case 2:
 
2152
                value = *(Uint16 *)pixel;
 
2153
                break;
 
2154
            case 3:
 
2155
                value = pixel[BYTE0];
 
2156
                value |= pixel[BYTE1] << 8;
 
2157
                value |= pixel[BYTE2] << 16;
 
2158
                break;
 
2159
            default:
 
2160
                assert(format->BytesPerPixel == 4);
 
2161
                value = *(Uint32 *)pixel;
 
2162
            }
 
2163
            SDL_GetRGBA (value, surf->format, &r, &g, &b, &a);
2061
2164
            if ((a >= min_alpha && has_colorkey == 0) ||
2062
2165
                (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) {
2063
2166
                found_alpha = 1;
2075
2178
    return rect;
2076
2179
}
2077
2180
 
2078
 
static PyObject
2079
 
*surf_get_buffer (PyObject *self)
2080
 
{
2081
 
    PyObject *buffer;
2082
 
    PyObject *lock;
2083
 
    SDL_Surface *surface = PySurface_AsSurface (self);
2084
 
    Py_ssize_t length;
2085
 
 
2086
 
    length = (Py_ssize_t) surface->pitch * surface->h;
2087
 
 
2088
 
    buffer = PyBufferProxy_New (self, NULL, length, NULL);
2089
 
    if (!buffer) {
2090
 
        return RAISE (PyExc_SDLError,
2091
 
            "could not acquire a buffer for the surface");
2092
 
    }
2093
 
    
2094
 
    lock = PySurface_LockLifetime (self, buffer);
2095
 
    if (!lock) {
2096
 
        Py_DECREF (buffer);
2097
 
        return RAISE (PyExc_SDLError, "could not lock surface");
2098
 
    }
2099
 
    ((PyBufferProxy *) buffer)->buffer = surface->pixels;
2100
 
    ((PyBufferProxy *) buffer)->lock = lock;
2101
 
 
2102
 
    return buffer;
2103
 
}
2104
 
 
2105
2181
static PyObject *
2106
2182
_raise_get_view_ndim_error(int bitsize, SurfViewKind kind) {
2107
 
    const char *kind_names[] = {"2D", "3D", "red", "green", "blue", "alpha"};
2108
 
    const char *name;
 
2183
    const char *name = "<unknown>";  /* guard against a segfault */
2109
2184
 
 
2185
    /* Put a human readable name to a surface view kind */
2110
2186
    switch (kind) {
 
2187
        /* This switch statement is exhaustive over the SurfViewKind enum */
2111
2188
 
 
2189
    case VIEWKIND_0D:
 
2190
        name = "contiguous bytes";
 
2191
        break;
 
2192
    case VIEWKIND_1D:
 
2193
        name = "contigous pixels";
 
2194
        break;
2112
2195
    case VIEWKIND_2D:
2113
 
        name = kind_names[0];
 
2196
        name = "2D";
2114
2197
        break;
2115
2198
    case VIEWKIND_3D:
2116
 
        name = kind_names[1];
 
2199
        name = "3D";
2117
2200
        break;
2118
2201
    case VIEWKIND_RED:
2119
 
        name = kind_names[2];
 
2202
        name = "red";
2120
2203
        break;
2121
2204
    case VIEWKIND_GREEN:
2122
 
        name = kind_names[3];
 
2205
        name = "green";
2123
2206
        break;
2124
2207
    case VIEWKIND_BLUE:
2125
 
        name = kind_names[4];
 
2208
        name = "blue";
2126
2209
        break;
2127
2210
    case VIEWKIND_ALPHA:
2128
 
        name = kind_names[5];
 
2211
        name = "alpha";
2129
2212
        break;
 
2213
 
 
2214
#ifndef NDEBUG
 
2215
        /* Assert this switch statement is exhaustive */
2130
2216
    default:
 
2217
        /* Should not be here */
2131
2218
        PyErr_Format(PyExc_SystemError,
2132
2219
                     "pygame bug in _raise_get_view_ndim_error:"
2133
2220
                     " unknown view kind %d", (int) kind);
2134
2221
        return 0;
 
2222
#endif
2135
2223
    }
2136
 
    PyErr_Format(PyExc_ValueError, 
 
2224
    PyErr_Format(PyExc_ValueError,
2137
2225
         "unsupported bit depth %d for %s reference array",
2138
2226
                 bitsize, name);
2139
2227
    return 0;
2140
2228
}
2141
2229
 
2142
 
static PyObject *
2143
 
surf_get_view(PyObject *self, PyObject *args, PyObject *kwds)
 
2230
static PyObject*
 
2231
surf_get_view (PyObject *self, PyObject *args)
2144
2232
{
2145
 
#   define SURF_GET_VIEW_MAXDIM 3
2146
 
    const int lilendian = (SDL_BYTEORDER == SDL_LIL_ENDIAN);
2147
 
    const int maxdim = SURF_GET_VIEW_MAXDIM; 
2148
 
    typedef struct {
2149
 
        PyArrayInterface inter;
2150
 
        Py_intptr_t shape_mem[SURF_GET_VIEW_MAXDIM];
2151
 
        Py_intptr_t strides_mem[SURF_GET_VIEW_MAXDIM];
2152
 
    } Interface;
2153
 
#   undef SURF_GET_VIEW_MAXDIM
 
2233
    SDL_Surface *surface = PySurface_AsSurface (self);
 
2234
    SDL_PixelFormat *format;
 
2235
    Uint32 mask = 0;
2154
2236
    SurfViewKind view_kind = VIEWKIND_2D;
2155
 
    int ndim = maxdim;
2156
 
    PyObject *capsule;
2157
 
    Interface *allocation;
2158
 
    PyArrayInterface *inter;
2159
 
    SDL_Surface *surface = PySurface_AsSurface(self);
2160
 
    int pixelsize;
2161
 
    int itemsize = 0;
2162
 
    Py_intptr_t *shape;
2163
 
    Py_intptr_t *strides;
2164
 
    Uint8 *startpixel;
2165
 
    Uint32 mask = 0;
2166
 
    int pixelstep;
2167
 
    
2168
 
    PyObject *view;
2169
 
    char *keywords[] = {"kind", 0};
 
2237
    getbufferproc get_buffer = 0;
2170
2238
 
2171
 
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", keywords,
2172
 
                     surf_view_kind, &view_kind)) {
 
2239
    if (!PyArg_ParseTuple (args, "|O&", _view_kind, &view_kind)) {
2173
2240
        return 0;
2174
2241
    }
2175
2242
 
2176
2243
    if (!surface) {
2177
 
        return RAISE(PyExc_SDLError, "display Surface quit");
2178
 
    }
2179
 
 
2180
 
    allocation = PyMem_New(Interface, 1);
2181
 
    if (!allocation) {
2182
 
        return PyErr_NoMemory();
2183
 
    }
2184
 
    inter = (PyArrayInterface *)allocation;
2185
 
    inter->shape = allocation->shape_mem;
2186
 
    inter->strides = allocation->strides_mem;
2187
 
#if PY3
2188
 
    capsule = PyCapsule_New(inter, 0, surf_arraystruct_capsule_destr);
2189
 
#else
2190
 
    capsule = PyCObject_FromVoidPtr(inter, PyMem_Free);
2191
 
#endif
2192
 
    if (!capsule) {
2193
 
        PyMem_Free(inter);
2194
 
        return 0;
2195
 
    }
2196
 
    view = PgView_New(capsule, self, surf_view_destr);
2197
 
    Py_DECREF(capsule);
2198
 
    if (!view) {
2199
 
        return 0;
2200
 
    }
2201
 
    if (!PySurface_LockBy(self, view)) {
2202
 
        Py_DECREF(view);
2203
 
        return 0;
2204
 
    }
2205
 
 
2206
 
    startpixel = surface->pixels;
2207
 
    pixelsize = surface->format->BytesPerPixel;
2208
 
    inter->two = 2;
2209
 
    inter->typekind = 'u';
2210
 
    inter->flags = PAI_ALIGNED | PAI_NOTSWAPPED | PAI_WRITEABLE;
2211
 
    inter->descr = 0;
2212
 
    shape = inter->shape;
2213
 
    strides = inter->strides;
2214
 
    shape[0] = (Py_intptr_t)surface->w;
2215
 
    shape[1] = (Py_intptr_t)surface->h;
2216
 
    strides[0] = (Py_intptr_t)pixelsize;
2217
 
    strides[1] = (Py_intptr_t)surface->pitch;
 
2244
        return RAISE (PyExc_SDLError, "display Surface quit");
 
2245
    }
 
2246
 
 
2247
    format = surface->format;
2218
2248
    switch (view_kind) {
 
2249
        /* This switch statement is exhaustive over the SurfViewKind enum */
2219
2250
 
 
2251
    case VIEWKIND_0D:
 
2252
        if (surface->pitch != format->BytesPerPixel * surface->w) {
 
2253
            PyErr_SetString (PyExc_ValueError,
 
2254
                             "Surface data is not contiguous");
 
2255
            return 0;
 
2256
        }
 
2257
        get_buffer = _get_buffer_0D;
 
2258
        break;
 
2259
    case VIEWKIND_1D:
 
2260
        if (surface->pitch != format->BytesPerPixel * surface->w) {
 
2261
            PyErr_SetString (PyExc_ValueError,
 
2262
                             "Surface data is not contiguous");
 
2263
            return 0;
 
2264
        }
 
2265
        get_buffer = _get_buffer_1D;
 
2266
        break;
2220
2267
    case VIEWKIND_2D:
2221
 
        ndim = 2;
2222
 
        itemsize = pixelsize;
2223
 
        if (strides[1] == shape[0] * pixelsize) {
2224
 
            inter->flags |= PAI_CONTIGUOUS;
2225
 
        }
 
2268
        get_buffer = _get_buffer_2D;
2226
2269
        break;
2227
2270
    case VIEWKIND_3D:
2228
 
        if (pixelsize < 3) {
2229
 
            Py_DECREF(view);
2230
 
            return _raise_get_view_ndim_error(pixelsize * 8, view_kind);
2231
 
        }
2232
 
        ndim = 3;
2233
 
        itemsize = 1;
2234
 
        shape[2] = 3;
2235
 
        if (surface->format->Rmask == 0xff0000 &&
2236
 
            surface->format->Gmask == 0x00ff00 &&
2237
 
            surface->format->Bmask == 0x0000ff)
2238
 
        {
2239
 
            strides[2] = lilendian ? -1 : 1;
2240
 
            startpixel += lilendian ? 2 : 1;
2241
 
        }
2242
 
        else if (surface->format->Bmask == 0xff0000 &&
2243
 
                 surface->format->Gmask == 0x00ff00 &&
2244
 
                 surface->format->Rmask == 0x0000ff)
2245
 
        {
2246
 
            strides[2] = lilendian ? 1 : -1;
2247
 
            startpixel += lilendian ? 0 : (pixelsize - 1);
2248
 
        }
2249
 
        else {
2250
 
            Py_DECREF(view);
2251
 
            return RAISE(PyExc_ValueError,
2252
 
                         "unsupport colormasks for 3D reference array");
2253
 
        }
 
2271
        if (format->BytesPerPixel < 3) {
 
2272
            return _raise_get_view_ndim_error (format->BytesPerPixel * 8,
 
2273
                                               view_kind);
 
2274
        }
 
2275
        if (format->Gmask != 0x00ff00 &&
 
2276
            (format->BytesPerPixel != 4 ||
 
2277
             format->Gmask != 0xff0000)) {
 
2278
            return RAISE (PyExc_ValueError,
 
2279
                          "unsupport colormasks for 3D reference array");
 
2280
        }
 
2281
        get_buffer = _get_buffer_3D;
2254
2282
        break;
2255
2283
    case VIEWKIND_RED:
2256
 
        mask = surface->format->Rmask;
 
2284
        mask = format->Rmask;
 
2285
        if (mask != 0x000000ffU &&
 
2286
            mask != 0x0000ff00U &&
 
2287
            mask != 0x00ff0000U &&
 
2288
            mask != 0xff000000U    ) {
 
2289
            return RAISE (PyExc_ValueError,
 
2290
                          "unsupported colormasks for red reference array");
 
2291
        }
 
2292
        get_buffer = _get_buffer_red;
2257
2293
        break;
2258
2294
    case VIEWKIND_GREEN:
2259
 
        mask = surface->format->Gmask;
 
2295
        mask = format->Gmask;
 
2296
        if (mask != 0x000000ffU &&
 
2297
            mask != 0x0000ff00U &&
 
2298
            mask != 0x00ff0000U &&
 
2299
            mask != 0xff000000U    ) {
 
2300
            return RAISE (PyExc_ValueError,
 
2301
                          "unsupported colormasks for green reference array");
 
2302
        }
 
2303
        get_buffer = _get_buffer_green;
2260
2304
        break;
2261
2305
    case VIEWKIND_BLUE:
2262
 
        mask = surface->format->Bmask;
 
2306
        mask = format->Bmask;
 
2307
        if (mask != 0x000000ffU &&
 
2308
            mask != 0x0000ff00U &&
 
2309
            mask != 0x00ff0000U &&
 
2310
            mask != 0xff000000U    ) {
 
2311
            return RAISE (PyExc_ValueError,
 
2312
                          "unsupported colormasks for blue reference array");
 
2313
        }
 
2314
        get_buffer = _get_buffer_blue;
2263
2315
        break;
2264
2316
    case VIEWKIND_ALPHA:
2265
 
        mask = surface->format->Amask;
 
2317
        mask = format->Amask;
 
2318
        if (mask != 0x000000ffU &&
 
2319
            mask != 0x0000ff00U &&
 
2320
            mask != 0x00ff0000U &&
 
2321
            mask != 0xff000000U    ) {
 
2322
            return RAISE (PyExc_ValueError,
 
2323
                          "unsupported colormasks for alpha reference array");
 
2324
        }
 
2325
        get_buffer = _get_buffer_alpha;
2266
2326
        break;
 
2327
 
 
2328
#ifndef NDEBUG
 
2329
        /* Assert this switch statement is exhaustive */
2267
2330
    default:
2268
 
        Py_DECREF(view);
2269
 
        PyErr_Format(PyExc_SystemError,
2270
 
                     "pygame bug in surf_get_view:"
2271
 
                     " unrecognized view kind %d", (int)view_kind);
 
2331
        /* Should not be here */
 
2332
        PyErr_Format (PyExc_SystemError,
 
2333
                      "pygame bug in surf_get_view:"
 
2334
                      " unrecognized view kind %d", (int)view_kind);
2272
2335
        return 0;
2273
 
    }
2274
 
    if (!itemsize) {
2275
 
        /* Color plane */
2276
 
        ndim = 2;
2277
 
        pixelstep = pixelsize;
2278
 
        itemsize = 1;
2279
 
        switch (mask) {
2280
 
 
2281
 
        case 0x000000ffU:
2282
 
            startpixel += lilendian ? 0 : 3;
2283
 
            break;
2284
 
        case 0x0000ff00U:
2285
 
            startpixel += lilendian ? 1 : 2;
2286
 
            break;
2287
 
        case 0x00ff0000U:
2288
 
            startpixel += lilendian ? 2 : 1;
2289
 
            break;
2290
 
        case 0xff000000U:
2291
 
            startpixel += lilendian ? 3 : 0;
2292
 
            break;
2293
 
        default:
2294
 
            Py_DECREF(view);
2295
 
            return RAISE(PyExc_ValueError,
2296
 
                         "unsupported colormasks for alpha reference array");
2297
 
        }
2298
 
    }
2299
 
    if (ndim < 3) {
2300
 
        inter->flags |= PAI_FORTRAN;
2301
 
    }
2302
 
    inter->nd = ndim;
2303
 
    inter->itemsize = itemsize;
2304
 
    inter->data = startpixel;
2305
 
 
2306
 
    return view;
2307
 
}
2308
 
 
2309
 
static int
2310
 
surf_view_kind(PyObject *obj, void *view_kind_vptr)
 
2336
#endif
 
2337
    }
 
2338
    assert (get_buffer);
 
2339
    return PgBufproxy_New (self, get_buffer);
 
2340
}
 
2341
 
 
2342
static PyObject*
 
2343
surf_get_buffer (PyObject *self)
 
2344
{
 
2345
    SDL_Surface *surface = PySurface_AsSurface (self);
 
2346
    PyObject *proxy_obj;
 
2347
 
 
2348
    if (!surface) {
 
2349
        return RAISE (PyExc_SDLError, "display Surface quit");
 
2350
    }
 
2351
 
 
2352
    proxy_obj = PgBufproxy_New (self, _get_buffer_0D);
 
2353
    if (proxy_obj) {
 
2354
        if (PgBufproxy_Trip (proxy_obj)) {
 
2355
            Py_DECREF (proxy_obj);
 
2356
            proxy_obj = 0;
 
2357
        }
 
2358
    }
 
2359
    return proxy_obj;
 
2360
}
 
2361
 
 
2362
static int
 
2363
_get_buffer_0D (PyObject *obj, Py_buffer *view_p, int flags)
 
2364
{
 
2365
    SDL_Surface *surface = PySurface_AsSurface (obj);
 
2366
 
 
2367
    view_p->obj = 0;
 
2368
    if (_init_buffer (obj, view_p, flags)) {
 
2369
        return -1;
 
2370
    }
 
2371
    view_p->buf = surface->pixels;
 
2372
    view_p->itemsize = 1;
 
2373
    view_p->len = surface->pitch * surface->h;
 
2374
    view_p->readonly = 0;
 
2375
    if (PyBUF_HAS_FLAG(flags, PyBUF_FORMAT)) {
 
2376
        view_p->format = FormatUint8;
 
2377
    }
 
2378
    if (PyBUF_HAS_FLAG(flags, PyBUF_ND)) {
 
2379
        view_p->ndim = 1;
 
2380
        view_p->shape[0] = view_p->len;
 
2381
        if (PyBUF_HAS_FLAG(flags, PyBUF_STRIDES)) {
 
2382
            view_p->strides[0] = view_p->itemsize;
 
2383
        }
 
2384
    }
 
2385
    Py_INCREF (obj);
 
2386
    view_p->obj = obj;
 
2387
    return 0;
 
2388
}
 
2389
 
 
2390
static int
 
2391
_get_buffer_1D (PyObject *obj, Py_buffer *view_p, int flags)
 
2392
{
 
2393
    SDL_Surface *surface = PySurface_AsSurface (obj);
 
2394
    Py_ssize_t itemsize = surface->format->BytesPerPixel;
 
2395
 
 
2396
    view_p->obj = 0;
 
2397
    if (itemsize == 1) {
 
2398
        return _get_buffer_0D (obj, view_p, flags);
 
2399
    }
 
2400
    if (_init_buffer (obj, view_p, flags)) {
 
2401
        return -1;
 
2402
    }
 
2403
    if (PyBUF_HAS_FLAG (flags, PyBUF_FORMAT)) {
 
2404
        switch (itemsize) {
 
2405
            /* This switch statement is exhaustive over all remaining possible
 
2406
               itemsize values, the valid pixel byte sizes of non color-mapped
 
2407
               images */
 
2408
 
 
2409
        case 2:
 
2410
            view_p->format = FormatUint16;
 
2411
            break;
 
2412
        case 3:
 
2413
            view_p->format = FormatUint24;
 
2414
            break;
 
2415
        case 4:
 
2416
            view_p->format = FormatUint32;
 
2417
            break;
 
2418
 
 
2419
#ifndef NDEBUG
 
2420
            /* Assert this switch statement is exhaustive */
 
2421
        default:
 
2422
            /* Should not be here */
 
2423
            PyErr_Format (PyExc_SystemError,
 
2424
                          "Pygame bug caught at line %i in file %s: "
 
2425
                          "unknown pixel size %i. Please report",
 
2426
                          (int)__LINE__, __FILE__, itemsize);
 
2427
            return -1;
 
2428
#endif
 
2429
        }
 
2430
    }
 
2431
    view_p->buf = surface->pixels;
 
2432
    view_p->itemsize = itemsize;
 
2433
    view_p->readonly = 0;
 
2434
    view_p->len = surface->pitch * surface->h;
 
2435
    if (PyBUF_HAS_FLAG (flags, PyBUF_ND)) {
 
2436
        view_p->ndim = 1;
 
2437
        view_p->shape[0] = surface->w * surface->h;
 
2438
        if (PyBUF_HAS_FLAG (flags, PyBUF_STRIDES)) {
 
2439
            view_p->strides[0] = itemsize;
 
2440
        }
 
2441
    }
 
2442
    view_p->suboffsets = 0;
 
2443
    Py_INCREF (obj);
 
2444
    view_p->obj = obj;
 
2445
    return 0;
 
2446
}
 
2447
 
 
2448
static int
 
2449
_get_buffer_2D (PyObject *obj, Py_buffer *view_p, int flags)
 
2450
{
 
2451
    SDL_Surface *surface = PySurface_AsSurface (obj);
 
2452
    int itemsize = surface->format->BytesPerPixel;
 
2453
 
 
2454
    view_p->obj = 0;
 
2455
    if (!PyBUF_HAS_FLAG (flags, PyBUF_ND)) {
 
2456
        if (surface->pitch != surface->w * itemsize) {
 
2457
            PyErr_SetString (PgExc_BufferError,
 
2458
                             "A 2D surface view is not C contiguous");
 
2459
            return -1;
 
2460
        }
 
2461
        return _get_buffer_1D (obj, view_p, flags);
 
2462
    }
 
2463
    if (!PyBUF_HAS_FLAG (flags, PyBUF_STRIDES)) {
 
2464
            PyErr_SetString (PgExc_BufferError,
 
2465
                             "A 2D surface view is not C contiguous: "
 
2466
                             "need strides");
 
2467
            return -1;
 
2468
    }
 
2469
    if (PyBUF_HAS_FLAG (flags, PyBUF_C_CONTIGUOUS)) {
 
2470
        PyErr_SetString (PgExc_BufferError,
 
2471
                         "A 2D surface view is not C contiguous");
 
2472
        return -1;
 
2473
    }
 
2474
    if (PyBUF_HAS_FLAG (flags, PyBUF_F_CONTIGUOUS) &&
 
2475
        surface->pitch != surface->w * itemsize) {
 
2476
        PyErr_SetString (PgExc_BufferError,
 
2477
                         "This 2D surface view is not F contiguous");
 
2478
        return -1;
 
2479
    }
 
2480
    if (PyBUF_HAS_FLAG (flags, PyBUF_ANY_CONTIGUOUS) &&
 
2481
        surface->pitch != surface->w * itemsize) {
 
2482
        PyErr_SetString (PgExc_BufferError,
 
2483
                         "This 2D surface view is not contiguous");
 
2484
        return -1;
 
2485
    }
 
2486
    if (_init_buffer (obj, view_p, flags)) {
 
2487
        return -1;
 
2488
    }
 
2489
    if (PyBUF_HAS_FLAG (flags, PyBUF_FORMAT)) {
 
2490
        switch (itemsize) {
 
2491
            /* This switch statement is exhaustive over all possible itemsize
 
2492
               values, valid pixel byte sizes */
 
2493
 
 
2494
        case 1:
 
2495
            view_p->format = FormatUint8;
 
2496
            break;
 
2497
        case 2:
 
2498
            view_p->format = FormatUint16;
 
2499
            break;
 
2500
        case 3:
 
2501
            view_p->format = FormatUint24;
 
2502
            break;
 
2503
        case 4:
 
2504
            view_p->format = FormatUint32;
 
2505
            break;
 
2506
 
 
2507
#ifndef NDEBUG
 
2508
            /* Assert this switch statement is exhaustive */
 
2509
        default:
 
2510
            /* Should not be here */
 
2511
            PyErr_Format (PyExc_SystemError,
 
2512
                          "Pygame bug caught at line %i in file %s: "
 
2513
                          "unknown pixel size %i. Please report",
 
2514
                          (int)__LINE__, __FILE__, itemsize);
 
2515
            return -1;
 
2516
#endif
 
2517
        }
 
2518
    }
 
2519
    view_p->buf = surface->pixels;
 
2520
    view_p->itemsize = itemsize;
 
2521
    view_p->ndim = 2;
 
2522
    view_p->readonly = 0;
 
2523
    view_p->len = surface->w * surface->h * itemsize;
 
2524
    view_p->shape[0] = surface->w;
 
2525
    view_p->shape[1] = surface->h;
 
2526
    view_p->strides[0] = itemsize;
 
2527
    view_p->strides[1] = surface->pitch;
 
2528
    view_p->suboffsets = 0;
 
2529
    Py_INCREF (obj);
 
2530
    view_p->obj = obj;
 
2531
    return 0;
 
2532
}
 
2533
 
 
2534
static int
 
2535
_get_buffer_3D (PyObject *obj, Py_buffer *view_p, int flags)
 
2536
{
 
2537
    const int lilendian = (SDL_BYTEORDER == SDL_LIL_ENDIAN);
 
2538
    SDL_Surface *surface = PySurface_AsSurface (obj);
 
2539
    int pixelsize = surface->format->BytesPerPixel;
 
2540
    char *startpixel = (char *)surface->pixels;
 
2541
 
 
2542
    view_p->obj = 0;
 
2543
    if (!PyBUF_HAS_FLAG (flags, PyBUF_STRIDES)) {
 
2544
        PyErr_SetString (PgExc_BufferError,
 
2545
                         "A 3D surface view is not contiguous: needs strides");
 
2546
        return -1;
 
2547
    }
 
2548
    if (PyBUF_HAS_FLAG (flags, PyBUF_C_CONTIGUOUS) ||
 
2549
        PyBUF_HAS_FLAG (flags, PyBUF_F_CONTIGUOUS) ||
 
2550
        PyBUF_HAS_FLAG (flags, PyBUF_ANY_CONTIGUOUS)) {
 
2551
        PyErr_SetString (PgExc_BufferError,
 
2552
                         "A 3D surface view is not contiguous");
 
2553
        return -1;
 
2554
    }
 
2555
    if (_init_buffer (obj, view_p, flags)) {
 
2556
        return -1;
 
2557
    }
 
2558
    if (PyBUF_HAS_FLAG (flags, PyBUF_FORMAT)) {
 
2559
        view_p->format = FormatUint8;
 
2560
    }
 
2561
    view_p->itemsize = 1;
 
2562
    view_p->ndim = 3;
 
2563
    view_p->readonly = 0;
 
2564
    view_p->len = surface->w * surface->h * 3;
 
2565
    view_p->shape[0] = surface->w;
 
2566
    view_p->shape[1] = surface->h;
 
2567
    view_p->shape[2] = 3;
 
2568
    view_p->strides[0] = pixelsize;
 
2569
    view_p->strides[1] = surface->pitch;
 
2570
    switch (surface->format->Rmask) {
 
2571
 
 
2572
    case 0xffU:
 
2573
        view_p->strides[2] = lilendian ? 1 : -1;
 
2574
        startpixel += lilendian ? 0 : pixelsize - 1;
 
2575
        break;
 
2576
    case 0xff00U:
 
2577
        assert(pixelsize == 4);
 
2578
        view_p->strides[2] = lilendian ? 1 : -1;
 
2579
        startpixel += lilendian ? 1 : pixelsize - 2;
 
2580
        break;
 
2581
    case 0xff0000U:
 
2582
        view_p->strides[2] = lilendian ?  -1 : 1;
 
2583
        startpixel += lilendian ? 2 : pixelsize - 3;
 
2584
        break;
 
2585
    default: /* 0xff000000U */
 
2586
        assert(pixelsize == 4);
 
2587
        view_p->strides[2] = lilendian ? -1 : 1;
 
2588
        startpixel += lilendian ? 3 : 0;
 
2589
    }
 
2590
    view_p->buf = startpixel;
 
2591
    Py_INCREF (obj);
 
2592
    view_p->obj = obj;
 
2593
    return 0;
 
2594
}
 
2595
 
 
2596
static int
 
2597
_get_buffer_red (PyObject *obj, Py_buffer *view_p, int flags)
 
2598
{
 
2599
    return _get_buffer_colorplane(obj,
 
2600
                                  view_p,
 
2601
                                  flags,
 
2602
                                  "red",
 
2603
                                  PySurface_AsSurface (obj)->format->Rmask);
 
2604
}
 
2605
 
 
2606
static int
 
2607
_get_buffer_green (PyObject *obj, Py_buffer *view_p, int flags)
 
2608
{
 
2609
    return _get_buffer_colorplane(obj,
 
2610
                                  view_p,
 
2611
                                  flags,
 
2612
                                  "green",
 
2613
                                  PySurface_AsSurface (obj)->format->Gmask);
 
2614
}
 
2615
 
 
2616
static int
 
2617
_get_buffer_blue (PyObject *obj, Py_buffer *view_p, int flags)
 
2618
{
 
2619
    return _get_buffer_colorplane(obj,
 
2620
                                  view_p,
 
2621
                                  flags,
 
2622
                                  "blue",
 
2623
                                  PySurface_AsSurface (obj)->format->Bmask);
 
2624
}
 
2625
 
 
2626
static int
 
2627
_get_buffer_alpha (PyObject *obj, Py_buffer *view_p, int flags)
 
2628
{
 
2629
    return _get_buffer_colorplane(obj,
 
2630
                                  view_p,
 
2631
                                  flags,
 
2632
                                  "alpha",
 
2633
                                  PySurface_AsSurface (obj)->format->Amask);
 
2634
}
 
2635
 
 
2636
static int
 
2637
_get_buffer_colorplane (PyObject *obj,
 
2638
                        Py_buffer *view_p,
 
2639
                        int flags,
 
2640
                        char *name,
 
2641
                        Uint32 mask)
 
2642
{
 
2643
    const int lilendian = (SDL_BYTEORDER == SDL_LIL_ENDIAN);
 
2644
    SDL_Surface *surface = PySurface_AsSurface (obj);
 
2645
    int pixelsize = surface->format->BytesPerPixel;
 
2646
    char *startpixel = (char *)surface->pixels;
 
2647
 
 
2648
    view_p->obj = 0;
 
2649
    if (!PyBUF_HAS_FLAG (flags, PyBUF_STRIDES)) {
 
2650
        PyErr_SetString (PgExc_BufferError,
 
2651
                         "A surface color plane view is not contiguous: "
 
2652
                         "need strides");
 
2653
        return -1;
 
2654
    }
 
2655
    if (PyBUF_HAS_FLAG (flags, PyBUF_C_CONTIGUOUS) ||
 
2656
        PyBUF_HAS_FLAG (flags, PyBUF_F_CONTIGUOUS) ||
 
2657
        PyBUF_HAS_FLAG (flags, PyBUF_ANY_CONTIGUOUS)) {
 
2658
        PyErr_SetString (PgExc_BufferError,
 
2659
                         "A surface color plane view is not contiguous");
 
2660
        return -1;
 
2661
    }
 
2662
    switch (mask) {
 
2663
        /* This switch statement is exhaustive over possible mask value,
 
2664
           the allowable masks for 24 bit and 32 bit surfaces */
 
2665
 
 
2666
    case 0x000000ffU:
 
2667
        startpixel += lilendian ? 0 : pixelsize - 1;
 
2668
        break;
 
2669
    case 0x0000ff00U:
 
2670
        startpixel += lilendian ? 1 : pixelsize - 2;
 
2671
        break;
 
2672
    case 0x00ff0000U:
 
2673
        startpixel += lilendian ? 2 : pixelsize - 3;
 
2674
        break;
 
2675
    case 0xff000000U:
 
2676
        startpixel += lilendian ? 3 : 0;
 
2677
        break;
 
2678
 
 
2679
#ifndef NDEBUG
 
2680
        /* Assert this switch statement is exhaustive */
 
2681
    default:
 
2682
        /* Should not be here */
 
2683
        PyErr_Format (PyExc_SystemError,
 
2684
                      "Pygame bug caught at line %i in file %s: "
 
2685
                      "unknown mask value %p. Please report",
 
2686
                      (int)__LINE__, __FILE__, (void *)mask);
 
2687
        return -1;
 
2688
#endif
 
2689
    }
 
2690
    if (_init_buffer (obj, view_p, flags)) {
 
2691
        return -1;
 
2692
    }
 
2693
    view_p->buf = startpixel;
 
2694
    if (PyBUF_HAS_FLAG (flags, PyBUF_FORMAT)) {
 
2695
            view_p->format = FormatUint8;
 
2696
    }
 
2697
    view_p->itemsize = 1;
 
2698
    view_p->ndim = 2;
 
2699
    view_p->readonly = 0;
 
2700
    view_p->len = surface->w * surface->h;
 
2701
    view_p->shape[0] = surface->w;
 
2702
    view_p->shape[1] = surface->h;
 
2703
    view_p->strides[0] = pixelsize;
 
2704
    view_p->strides[1] = surface->pitch;
 
2705
    Py_INCREF (obj);
 
2706
    view_p->obj = obj;
 
2707
    return 0;
 
2708
}
 
2709
 
 
2710
static int
 
2711
_init_buffer (PyObject *surf, Py_buffer *view_p, int flags)
 
2712
{
 
2713
    PyObject *consumer;
 
2714
    Pg_bufferinternal *internal;
 
2715
 
 
2716
    assert (surf);
 
2717
    assert (view_p);
 
2718
    assert (PyObject_IsInstance (surf, (PyObject *)&PySurface_Type));
 
2719
    assert (PyBUF_HAS_FLAG (flags, PyBUF_PYGAME));
 
2720
    consumer = ((Pg_buffer *)view_p)->consumer;
 
2721
    assert (consumer);
 
2722
    internal = PyMem_New (Pg_bufferinternal, 1);
 
2723
    if (!internal) {
 
2724
        PyErr_NoMemory ();
 
2725
        return -1;
 
2726
    }
 
2727
    internal->consumer_ref = PyWeakref_NewRef (consumer, 0);
 
2728
    if (!internal->consumer_ref) {
 
2729
        PyMem_Free (internal);
 
2730
        return -1;
 
2731
    }
 
2732
    if (!PySurface_LockBy (surf, consumer)) {
 
2733
        PyErr_Format (PgExc_BufferError,
 
2734
                      "Unable to lock <%s at %p> by <%s at %p>",
 
2735
                      Py_TYPE(surf)->tp_name, (void *)surf,
 
2736
                      Py_TYPE(consumer)->tp_name, (void *)consumer);
 
2737
        Py_DECREF (internal->consumer_ref);
 
2738
        PyMem_Free (internal);
 
2739
        return -1;
 
2740
    }
 
2741
    if (PyBUF_HAS_FLAG (flags, PyBUF_ND)) {
 
2742
        view_p->shape = internal->mem;
 
2743
        if (PyBUF_HAS_FLAG (flags, PyBUF_STRIDES)) {
 
2744
            view_p->strides = internal->mem + 3;
 
2745
        }
 
2746
        else {
 
2747
            view_p->strides = 0;
 
2748
        }
 
2749
    }
 
2750
    else {
 
2751
        view_p->shape = 0;
 
2752
        view_p->strides = 0;
 
2753
    }
 
2754
    view_p->ndim = 0;
 
2755
    view_p->format = 0;
 
2756
    view_p->suboffsets = 0;
 
2757
    view_p->internal = internal;
 
2758
    ((Pg_buffer *)view_p)->release_buffer = _release_buffer;
 
2759
    return 0;
 
2760
}
 
2761
 
 
2762
static void
 
2763
_release_buffer (Py_buffer *view_p)
 
2764
{
 
2765
    Pg_bufferinternal *internal;
 
2766
    PyObject *consumer_ref;
 
2767
    PyObject *consumer;
 
2768
 
 
2769
    assert (view_p && view_p->obj && view_p->internal);
 
2770
    internal  = (Pg_bufferinternal *)view_p->internal;
 
2771
    consumer_ref = internal->consumer_ref;
 
2772
    assert (consumer_ref && PyWeakref_CheckRef (consumer_ref));
 
2773
    consumer = PyWeakref_GetObject (consumer_ref);
 
2774
    if (consumer) {
 
2775
        if (!PySurface_UnlockBy (view_p->obj, consumer)) {
 
2776
            PyErr_Clear ();
 
2777
        }
 
2778
    }
 
2779
    Py_DECREF (consumer_ref);
 
2780
    PyMem_Free (internal);
 
2781
    Py_DECREF (view_p->obj);
 
2782
    view_p->obj = 0;
 
2783
}
 
2784
 
 
2785
static int
 
2786
_view_kind (PyObject *obj, void *view_kind_vptr)
2311
2787
{
2312
2788
    unsigned long ch;
2313
2789
    SurfViewKind *view_kind_ptr = (SurfViewKind *)view_kind_vptr;
2314
2790
 
2315
 
    if (PyUnicode_Check(obj)) {
2316
 
        if (PyUnicode_GET_SIZE(obj) != 1) {
2317
 
            PyErr_SetString(PyExc_TypeError,
2318
 
                            "expected a length 1 string for argument 1");
 
2791
    if (PyUnicode_Check (obj)) {
 
2792
        if (PyUnicode_GET_SIZE (obj) != 1) {
 
2793
            PyErr_SetString (PyExc_TypeError,
 
2794
                             "expected a length 1 string for argument 1");
2319
2795
            return 0;
2320
2796
        }
2321
 
        ch = *PyUnicode_AS_UNICODE(obj);
 
2797
        ch = *PyUnicode_AS_UNICODE (obj);
2322
2798
    }
2323
 
    else if (Bytes_Check(obj)) {
2324
 
        if (Bytes_GET_SIZE(obj) != 1) {
2325
 
            PyErr_SetString(PyExc_TypeError,
2326
 
                            "expected a length 1 string for argument 1");
 
2799
    else if (Bytes_Check (obj)) {
 
2800
        if (Bytes_GET_SIZE (obj) != 1) {
 
2801
            PyErr_SetString (PyExc_TypeError,
 
2802
                             "expected a length 1 string for argument 1");
2327
2803
            return 0;
2328
2804
        }
2329
 
        ch = *Bytes_AS_STRING(obj);
 
2805
        ch = *Bytes_AS_STRING (obj);
2330
2806
    }
2331
2807
    else {
2332
 
        PyErr_Format(PyExc_TypeError,
2333
 
                     "expected a length one string for argument 1: got '%s'",
2334
 
                     Py_TYPE(obj)->tp_name);
 
2808
        PyErr_Format (PyExc_TypeError,
 
2809
                      "expected a length one string for argument 1: got '%s'",
 
2810
                      Py_TYPE (obj)->tp_name);
2335
2811
        return 0;
2336
2812
    }
2337
2813
    switch (ch) {
2338
2814
 
 
2815
    case '0':
 
2816
        *view_kind_ptr = VIEWKIND_0D;
 
2817
        break;
 
2818
    case '1':
 
2819
        *view_kind_ptr = VIEWKIND_1D;
 
2820
        break;
2339
2821
    case '2':
2340
2822
        *view_kind_ptr = VIEWKIND_2D;
2341
2823
        break;
2359
2841
        *view_kind_ptr = VIEWKIND_3D;
2360
2842
        break;
2361
2843
    default:
2362
 
        PyErr_Format(PyExc_TypeError,
2363
 
                     "unrecognized view kind '%c' for argument 1", (int)ch);
 
2844
        PyErr_Format (PyExc_TypeError,
 
2845
                      "unrecognized view kind '%c' for argument 1", (int)ch);
2364
2846
        return 0;
2365
2847
    }
2366
2848
    return 1;
2367
2849
}
2368
2850
 
2369
 
#if PY3
2370
 
static void
2371
 
surf_arraystruct_capsule_destr(PyObject *capsule)
2372
 
{
2373
 
    PyMem_Free(PyCapsule_GetPointer(capsule, 0));
2374
 
}
2375
 
#endif
2376
 
 
2377
 
static void
2378
 
surf_view_destr(PyObject *view)
2379
 
{
2380
 
    PyObject *surf = PgView_GetParent(view);
2381
 
 
2382
 
    PySurface_UnlockBy(surf, view);
2383
 
    Py_DECREF(surf);
2384
 
}
2385
 
 
2386
2851
static PyObject *
2387
2852
surf_get_pixels_address(PyObject *self, PyObject *closure)
2388
2853
{
2494
2959
    }
2495
2960
 
2496
2961
    span = w * src->format->BytesPerPixel;
2497
 
    
 
2962
 
2498
2963
    if (dstpixels >= srcpixels + (h - 1) * src->pitch + span) {
2499
2964
        return 0;
2500
2965
    }
2505
2970
}
2506
2971
 
2507
2972
/*this internal blit function is accessable through the C api*/
2508
 
int 
 
2973
int
2509
2974
PySurface_Blit (PyObject * dstobj, PyObject * srcobj, SDL_Rect * dstrect,
2510
2975
                SDL_Rect * srcrect, int the_args)
2511
2976
{
2654
3119
    PyObject *module, *dict, *apiobj, *lockmodule;
2655
3120
    int ecode;
2656
3121
    static void* c_api[PYGAMEAPI_SURFACE_NUMSLOTS];
2657
 
    
 
3122
 
2658
3123
#if PY3
2659
3124
    static struct PyModuleDef _module = {
2660
3125
        PyModuleDef_HEAD_INIT,
2685
3150
    if (PyErr_Occurred ()) {
2686
3151
        MODINIT_ERROR;
2687
3152
    }
2688
 
    import_pygame_view ();
2689
 
    if (PyErr_Occurred ()) {
2690
 
        MODINIT_ERROR;
2691
 
    }
2692
3153
 
2693
3154
    /* import the surflock module manually */
2694
3155
    lockmodule = PyImport_ImportModule (IMPPREFIX "surflock");
2698
3159
 
2699
3160
        if (PyCapsule_CheckExact (_c_api)) {
2700
3161
            int i;
2701
 
            void **localptr = 
 
3162
            void **localptr =
2702
3163
                (void *)PyCapsule_GetPointer (_c_api,
2703
3164
                                              PG_CAPSULE_NAME("surflock"));
2704
3165
 
2715
3176
    if (PyType_Ready(&PySurface_Type) < 0) {
2716
3177
        MODINIT_ERROR;
2717
3178
    }
2718
 
    
 
3179
 
2719
3180
    /* create the module */
2720
3181
#if PY3
2721
3182
    module = PyModule_Create (&_module);