static void PySurface_Prep (PyObject* surfobj) { struct SubSurface_Data* data = ((PySurfaceObject*) surfobj)->subsurface; if (data) { SDL_Surface* surf = PySurface_AsSurface (surfobj); SDL_Surface* owner = PySurface_AsSurface (data->owner); PySurface_LockBy (data->owner, surfobj); surf->pixels = ((char*) owner->pixels) + data->pixeloffset; } }
static PyObject* movie_set_display (PyObject* self, PyObject* args) { SMPEG* movie = PyMovie_AsSMPEG (self); PyObject* surfobj, *posobj=NULL; GAME_Rect *rect, temp; int x=0, y=0; if (!PyArg_ParseTuple (args, "O|O", &surfobj, &posobj)) return NULL; if (!SDL_WasInit (SDL_INIT_VIDEO)) return RAISE (PyExc_SDLError, "cannot convert without pygame.display initialized"); Py_XDECREF (((PyMovieObject*) self)->surftarget); ((PyMovieObject*) self)->surftarget = NULL; if (PySurface_Check (surfobj)) { SMPEG_Info info; SDL_Surface* surf; if (posobj == NULL) { Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); SMPEG_scaleXY (movie, info.width, info.height); Py_END_ALLOW_THREADS; x = y = 0; } else if (TwoIntsFromObj (posobj, &x, &y)) { Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); SMPEG_scaleXY (movie, info.width, info.height); Py_END_ALLOW_THREADS; } else if ((rect = GameRect_FromObject (posobj, &temp))) { x = rect->x; y = rect->y; Py_BEGIN_ALLOW_THREADS; SMPEG_scaleXY (movie, rect->w, rect->h); Py_END_ALLOW_THREADS; } else return RAISE (PyExc_TypeError, "Invalid position argument"); surf = PySurface_AsSurface (surfobj); Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); SMPEG_enablevideo (movie, 1); SMPEG_setdisplay (movie, surf, NULL, NULL); SMPEG_move (movie, x, y); Py_END_ALLOW_THREADS; } else { Py_BEGIN_ALLOW_THREADS; SMPEG_enablevideo (movie, 0); Py_END_ALLOW_THREADS; if (surfobj != Py_None) return RAISE (PyExc_TypeError, "destination must be a Surface"); } Py_RETURN_NONE; }
static PyObject* blit_array(PyObject* self, PyObject* arg) { PyObject *surfobj, *arrayobj; PyObject *cobj; PyArrayInterface *inter; char *array_data; SDL_Surface* surf; SDL_PixelFormat* format; int loopx, loopy; int stridex, stridey, stridez=0, stridez2=0, sizex, sizey; int Rloss, Gloss, Bloss, Rshift, Gshift, Bshift; if (!PyArg_ParseTuple(arg, "O!O", &PySurface_Type, &surfobj, &arrayobj)) { return NULL; } surf = PySurface_AsSurface(surfobj); format = surf->format; if (!_get_array_interface(arrayobj, &cobj, &inter)) { return 0; } switch (inter->typekind) { case 'i': /* integer */ break; case 'u': /* unsigned integer */ break; case 'S': /* fixed length character field */ break; case 'V': /* structured element: record */ break; default: Py_DECREF(cobj); PyErr_Format(PyExc_ValueError, "unsupported array type '%c'", inter->typekind); return NULL; } if (!(inter->nd == 2 || (inter->nd == 3 && inter->shape[2] == 3))) return RAISE(PyExc_ValueError, "must be a valid 2d or 3d array\n"); if (surf->format->BytesPerPixel <= 0 || surf->format->BytesPerPixel > 4) return RAISE(PyExc_ValueError, "unsupport bit depth for surface"); stridex = inter->strides[0]; stridey = inter->strides[1]; if (inter->nd == 3) { stridez = inter->strides[2]; stridez2 = stridez*2; } sizex = inter->shape[0]; sizey = inter->shape[1]; Rloss = format->Rloss; Gloss = format->Gloss; Bloss = format->Bloss; Rshift = format->Rshift; Gshift = format->Gshift; Bshift = format->Bshift; if (sizex != surf->w || sizey != surf->h) { Py_DECREF(cobj); return RAISE(PyExc_ValueError, "array must match surface dimensions"); } if (!PySurface_LockBy(surfobj, (PyObject *) arrayobj)) { Py_DECREF(cobj); return NULL; } array_data = (char *)inter->data; switch (surf->format->BytesPerPixel) { case 1: if (inter->nd == 2) { switch (inter->itemsize) { case sizeof (Uint8): COPYMACRO_2D(Uint8, Uint8); break; case sizeof (Uint16): COPYMACRO_2D(Uint8, Uint16); break; case sizeof (Uint32): COPYMACRO_2D(Uint8, Uint32); break; case sizeof (Uint64): COPYMACRO_2D(Uint8, Uint64); break; default: Py_DECREF(cobj); if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } else { Py_DECREF(cobj); if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } break; case 2: if (inter->nd == 2) { switch (inter->itemsize) { case sizeof (Uint16): COPYMACRO_2D(Uint16, Uint16); break; case sizeof (Uint32): COPYMACRO_2D(Uint16, Uint32); break; case sizeof (Uint64): COPYMACRO_2D(Uint16, Uint64); break; default: Py_DECREF(cobj); if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } else { Uint16 alpha = 0; if (format->Amask) { alpha = 255 >> format->Aloss << format->Ashift; } switch (inter->itemsize) { case sizeof (Uint8): COPYMACRO_3D(Uint16, Uint8); break; case sizeof (Uint16): COPYMACRO_3D(Uint16, Uint16); break; case sizeof (Uint32): COPYMACRO_3D(Uint16, Uint32); break; case sizeof (Uint64): COPYMACRO_3D(Uint16, Uint64); break; default: Py_DECREF(cobj); if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } break; case 3: /* Assumption: The rgb components of a 24 bit pixel are in separate bytes. */ if (inter->nd == 2) { switch (inter->itemsize) { case sizeof (Uint32): COPYMACRO_2D_24(Uint32); break; case sizeof (Uint64): COPYMACRO_2D_24(Uint64); break; default: Py_DECREF(cobj); if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } else { #if SDL_BYTEORDER == SDL_LIL_ENDIAN size_t stridez_0 = (Rshift == 0 ? 0 : Gshift == 0 ? stridez : stridez2 ); size_t stridez_1 = (Rshift == 8 ? 0 : Gshift == 8 ? stridez : stridez2 ); size_t stridez_2 = (Rshift == 16 ? 0 : Gshift == 16 ? stridez : stridez2 ); #else size_t stridez_2 = (Rshift == 0 ? 0 : Gshift == 0 ? stridez : stridez2 ); size_t stridez_1 = (Rshift == 8 ? 0 : Gshift == 8 ? stridez : stridez2 ); size_t stridez_0 = (Rshift == 16 ? 0 : Gshift == 16 ? stridez : stridez2 ); #endif switch (inter->itemsize) { case sizeof (Uint8): COPYMACRO_3D_24(Uint8); break; case sizeof (Uint16): COPYMACRO_3D_24(Uint16); break; case sizeof (Uint32): COPYMACRO_3D_24(Uint32); break; case sizeof (Uint64): COPYMACRO_3D_24(Uint64); break; default: Py_DECREF(cobj); if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } break; case 4: if (inter->nd == 2) { switch (inter->itemsize) { case sizeof (Uint32): COPYMACRO_2D(Uint32, Uint32); break; case sizeof (Uint64): COPYMACRO_2D(Uint32, Uint64); break; default: Py_DECREF(cobj); if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } else { Uint32 alpha = 0; if (format->Amask) { alpha = 255 >> format->Aloss << format->Ashift; } switch (inter->itemsize) { case sizeof (Uint8): COPYMACRO_3D(Uint32, Uint8); break; case sizeof (Uint16): COPYMACRO_3D(Uint32, Uint16); break; case sizeof (Uint32): COPYMACRO_3D(Uint32, Uint32); break; case sizeof (Uint64): COPYMACRO_3D(Uint32, Uint64); break; default: Py_DECREF(cobj); if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } }
static PyObject* array_to_surface(PyObject *self, PyObject *arg) { PyObject *surfobj, *arrayobj; Pg_buffer pg_view; Py_buffer *view_p = (Py_buffer *)&pg_view; char *array_data; SDL_Surface* surf; SDL_PixelFormat* format; int loopx, loopy; int stridex, stridey, stridez=0, stridez2=0, sizex, sizey; int Rloss, Gloss, Bloss, Rshift, Gshift, Bshift; if (!PyArg_ParseTuple(arg, "O!O", &PySurface_Type, &surfobj, &arrayobj)) { return NULL; } surf = PySurface_AsSurface(surfobj); format = surf->format; if (PgObject_GetBuffer(arrayobj, &pg_view, PyBUF_RECORDS_RO)) { return 0; } if (_validate_view_format(view_p->format)) { return 0; } if (!(view_p->ndim == 2 || (view_p->ndim == 3 && view_p->shape[2] == 3))) { return RAISE(PyExc_ValueError, "must be a valid 2d or 3d array\n"); } if (surf->format->BytesPerPixel <= 0 || surf->format->BytesPerPixel > 4) return RAISE(PyExc_ValueError, "unsupport bit depth for surface"); stridex = view_p->strides[0]; stridey = view_p->strides[1]; if (view_p->ndim == 3) { stridez = view_p->strides[2]; stridez2 = stridez*2; } else { stridez = 1; stridez2 = 2; } sizex = view_p->shape[0]; sizey = view_p->shape[1]; Rloss = format->Rloss; Gloss = format->Gloss; Bloss = format->Bloss; Rshift = format->Rshift; Gshift = format->Gshift; Bshift = format->Bshift; /* Do any required broadcasting. */ if (sizex == 1) { sizex = surf->w; stridex = 0; } if (sizey == 1) { sizey = surf->h; stridey = 0; } if (sizex != surf->w || sizey != surf->h) { PgBuffer_Release(&pg_view); return RAISE(PyExc_ValueError, "array must match surface dimensions"); } if (!PySurface_LockBy(surfobj, arrayobj)) { PgBuffer_Release(&pg_view); return NULL; } array_data = (char *)view_p->buf; switch (surf->format->BytesPerPixel) { case 1: if (view_p->ndim == 2) { switch (view_p->itemsize) { case sizeof (Uint8): COPYMACRO_2D(Uint8, Uint8); break; case sizeof (Uint16): COPYMACRO_2D(Uint8, Uint16); break; case sizeof (Uint32): COPYMACRO_2D(Uint8, Uint32); break; case sizeof (Uint64): COPYMACRO_2D(Uint8, Uint64); break; default: PgBuffer_Release(&pg_view); if (!PySurface_UnlockBy(surfobj, arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } else { PgBuffer_Release(&pg_view); if (!PySurface_UnlockBy(surfobj, arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } break; case 2: if (view_p->ndim == 2) { switch (view_p->itemsize) { case sizeof (Uint16): COPYMACRO_2D(Uint16, Uint16); break; case sizeof (Uint32): COPYMACRO_2D(Uint16, Uint32); break; case sizeof (Uint64): COPYMACRO_2D(Uint16, Uint64); break; default: PgBuffer_Release(&pg_view); if (!PySurface_UnlockBy(surfobj, arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } else { Uint16 alpha = 0; if (format->Amask) { alpha = 255 >> format->Aloss << format->Ashift; } switch (view_p->itemsize) { case sizeof (Uint8): COPYMACRO_3D(Uint16, Uint8); break; case sizeof (Uint16): COPYMACRO_3D(Uint16, Uint16); break; case sizeof (Uint32): COPYMACRO_3D(Uint16, Uint32); break; case sizeof (Uint64): COPYMACRO_3D(Uint16, Uint64); break; default: PgBuffer_Release(&pg_view); if (!PySurface_UnlockBy(surfobj, arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } break; case 3: /* Assumption: The rgb components of a 24 bit pixel are in separate bytes. */ if (view_p->itemsize >= (view_p->ndim == 2 ? 3 : 1) && view_p->itemsize <= 9) { size_t stridez_0 = 0; size_t stridez_1 = 0; size_t stridez_2 = 0; #if SDL_BYTEORDER == SDL_LIL_ENDIAN if (view_p->ndim == 2) { stridez_1 = 1; stridez_2 = 2; } else { size_t offset = _is_swapped(view_p) ? view_p->itemsize - 1 : 0; stridez_0 = ((Rshift == 0 ? 0 : (Gshift == 0 ? stridez : stridez2)) + offset); stridez_1 = ((Rshift == 8 ? 0 : (Gshift == 8 ? stridez : stridez2)) + offset); stridez_2 = ((Rshift == 16 ? 0 : (Gshift == 16 ? stridez : stridez2)) + offset); } #else if (view_p->ndim == 2) { stridez_0 = view_p->itemsize - 3; stridez_1 = stridez_0 + 1; stridez_2 = stridez_1 + 1; } else { size_t offset = _is_swapped(view_p) ? 0 : view_p->itemsize - 1; stridez_2 = ((Rshift == 0 ? 0 : (Gshift == 0 ? stridez : stridez2)) + offset); stridez_1 = ((Rshift == 8 ? 0 : (Gshift == 8 ? stridez : stridez2)) + offset); stridez_0 = ((Rshift == 16 ? 0 : (Gshift == 16 ? stridez : stridez2)) + offset); } #endif for (loopy = 0; loopy < sizey; ++loopy) { Uint8 *pix = ((Uint8*)surf->pixels) + surf->pitch * loopy; Uint8 *data = (Uint8*)array_data + stridey * loopy; Uint8 *end = pix + 3 * sizex; while (pix != end) { *pix++ = *(data + stridez_0); *pix++ = *(data + stridez_1); *pix++ = *(data + stridez_2); data += stridex; } } } else { PgBuffer_Release(&pg_view); if (!PySurface_UnlockBy(surfobj, arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } break; case 4: if (view_p->ndim == 2) { switch (view_p->itemsize) { case sizeof (Uint32): COPYMACRO_2D(Uint32, Uint32); break; case sizeof (Uint64): COPYMACRO_2D(Uint32, Uint64); break; default: PgBuffer_Release(&pg_view); if (!PySurface_UnlockBy(surfobj, arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } } else { Uint32 alpha = 0; if (format->Amask) { alpha = 255 >> format->Aloss << format->Ashift; } switch (view_p->itemsize) { case sizeof (Uint8): COPYMACRO_3D(Uint32, Uint8); break; case sizeof (Uint16): COPYMACRO_3D(Uint32, Uint16); break; case sizeof (Uint32): COPYMACRO_3D(Uint32, Uint32); break; case sizeof (Uint64): COPYMACRO_3D(Uint32, Uint64); break; default: PgBuffer_Release(&pg_view); if (!PySurface_UnlockBy(surfobj, arrayobj)) { return NULL; } return RAISE(PyExc_ValueError, "unsupported datatype for array\n"); } }