2006-01-17 20:43:50 +08:00
|
|
|
/* -*- Mode: C; c-basic-offset: 4 -*-
|
2002-08-28 23:17:29 +08:00
|
|
|
Gimp-Python - allows the writing of Gimp plugins in Python.
|
|
|
|
Copyright (C) 1997-2002 James Henstridge <james@daa.com.au>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
#include "pygimp.h"
|
|
|
|
#include <structmember.h>
|
|
|
|
|
|
|
|
/* maximum bits per pixel ... */
|
|
|
|
#define MAX_BPP 4
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
tile_flush(PyGimpTile *self, PyObject *args)
|
|
|
|
{
|
|
|
|
if (!PyArg_ParseTuple(args, ":flush"))
|
|
|
|
return NULL;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
gimp_tile_flush(self->tile);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
Py_INCREF(Py_None);
|
|
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-30 20:46:27 +08:00
|
|
|
static PyMethodDef tile_methods[] = {
|
2002-08-28 23:17:29 +08:00
|
|
|
{"flush", (PyCFunction)tile_flush, METH_VARARGS},
|
|
|
|
{NULL, NULL} /* sentinel */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* ---------- */
|
|
|
|
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
pygimp_tile_new(GimpTile *t, PyGimpDrawable *drw)
|
|
|
|
{
|
|
|
|
PyGimpTile *self;
|
|
|
|
|
|
|
|
self = PyObject_NEW(PyGimpTile, &PyGimpTile_Type);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (self == NULL)
|
|
|
|
return NULL;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
gimp_tile_ref(t);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
self->tile = t;
|
|
|
|
|
|
|
|
Py_INCREF(drw);
|
|
|
|
self->drawable = drw;
|
|
|
|
|
|
|
|
return (PyObject *)self;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
tile_dealloc(PyGimpTile *self)
|
|
|
|
{
|
|
|
|
gimp_tile_unref(self->tile, FALSE);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
Py_DECREF(self->drawable);
|
|
|
|
PyObject_DEL(self);
|
|
|
|
}
|
|
|
|
|
2002-08-30 11:01:35 +08:00
|
|
|
static PyObject *
|
|
|
|
tile_get_uint_field(PyGimpTile *self, void *closure)
|
|
|
|
{
|
|
|
|
gint offset = GPOINTER_TO_INT(closure);
|
|
|
|
guint value;
|
|
|
|
gchar *addr;
|
|
|
|
|
|
|
|
addr = (gchar *)self->tile;
|
|
|
|
addr += offset;
|
|
|
|
value = *(guint *)addr;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-30 11:01:35 +08:00
|
|
|
return PyInt_FromLong(value);
|
|
|
|
}
|
2002-08-28 23:17:29 +08:00
|
|
|
|
2002-08-30 11:01:35 +08:00
|
|
|
static PyObject *
|
|
|
|
tile_get_dirty(PyGimpTile *self, void *closure)
|
|
|
|
{
|
2005-03-03 16:43:55 +08:00
|
|
|
return PyBool_FromLong(self->tile->dirty);
|
2002-08-30 11:01:35 +08:00
|
|
|
}
|
2002-08-28 23:17:29 +08:00
|
|
|
|
|
|
|
static PyObject *
|
2002-08-30 11:01:35 +08:00
|
|
|
tile_get_shadow(PyGimpTile *self, void *closure)
|
2002-08-28 23:17:29 +08:00
|
|
|
{
|
2005-03-03 16:43:55 +08:00
|
|
|
return PyBool_FromLong(self->tile->shadow);
|
2002-08-28 23:17:29 +08:00
|
|
|
}
|
|
|
|
|
2002-08-30 11:01:35 +08:00
|
|
|
static PyObject *
|
|
|
|
tile_get_drawable(PyGimpTile *self, void *closure)
|
|
|
|
{
|
|
|
|
return pygimp_drawable_new(self->tile->drawable, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define OFF(x) GINT_TO_POINTER(offsetof(GimpTile, x))
|
|
|
|
static PyGetSetDef tile_getsets[] = {
|
|
|
|
{ "ewidth", (getter)tile_get_uint_field, 0, NULL, OFF(ewidth) },
|
|
|
|
{ "eheight", (getter)tile_get_uint_field, 0, NULL, OFF(eheight) },
|
|
|
|
{ "bpp", (getter)tile_get_uint_field, 0, NULL, OFF(bpp) },
|
|
|
|
{ "tile_num", (getter)tile_get_uint_field, 0, NULL, OFF(tile_num) },
|
|
|
|
{ "dirty", (getter)tile_get_dirty, 0, NULL },
|
|
|
|
{ "shadow", (getter)tile_get_shadow, 0, NULL },
|
|
|
|
{ "drawable", (getter)tile_get_drawable, 0, NULL },
|
|
|
|
{ NULL, (getter)0, (setter)0 }
|
|
|
|
};
|
|
|
|
#undef OFF
|
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
static PyObject *
|
|
|
|
tile_repr(PyGimpTile *self)
|
|
|
|
{
|
|
|
|
PyObject *s;
|
|
|
|
gchar *name;
|
|
|
|
|
2003-12-04 01:41:36 +08:00
|
|
|
name = gimp_drawable_get_name(self->tile->drawable->drawable_id);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (self->tile->shadow)
|
2004-09-01 15:57:15 +08:00
|
|
|
s = PyString_FromFormat("<gimp.Tile for drawable '%s' (shadow)>", name);
|
2002-08-28 23:17:29 +08:00
|
|
|
else
|
2002-08-30 20:46:27 +08:00
|
|
|
s = PyString_FromFormat("<gimp.Tile for drawable '%s'>", name);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
g_free(name);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
tile_length(PyGimpTile *self)
|
|
|
|
{
|
|
|
|
return self->tile->ewidth * self->tile->eheight;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
tile_subscript(PyGimpTile *self, PyObject *sub)
|
|
|
|
{
|
|
|
|
GimpTile *tile = self->tile;
|
|
|
|
int bpp = tile->bpp;
|
|
|
|
long x, y;
|
|
|
|
|
|
|
|
if (PyInt_Check(sub)) {
|
|
|
|
x = PyInt_AsLong(sub);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (x < 0 || x >= tile->ewidth * tile->eheight) {
|
2004-09-01 15:57:15 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "index out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2007-05-29 06:26:22 +08:00
|
|
|
return PyString_FromStringAndSize
|
|
|
|
((char *)tile->data + bpp * x, bpp);
|
2002-08-28 23:17:29 +08:00
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (PyTuple_Check(sub)) {
|
|
|
|
if (!PyArg_ParseTuple(sub, "ll", &x, &y))
|
|
|
|
return NULL;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (x < 0 || y < 0 || x >= tile->ewidth || y>=tile->eheight) {
|
2004-09-01 15:57:15 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "index out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2007-05-29 06:26:22 +08:00
|
|
|
return PyString_FromStringAndSize
|
|
|
|
((char *)tile->data + bpp * (x + y * tile->ewidth), bpp);
|
2002-08-28 23:17:29 +08:00
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "tile subscript not int or 2-tuple");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
tile_ass_sub(PyGimpTile *self, PyObject *v, PyObject *w)
|
|
|
|
{
|
|
|
|
GimpTile *tile = self->tile;
|
|
|
|
int bpp = tile->bpp, i;
|
|
|
|
long x, y;
|
2007-05-29 06:26:22 +08:00
|
|
|
guchar *pix, *data;
|
2002-08-28 23:17:29 +08:00
|
|
|
|
|
|
|
if (w == NULL) {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"can not delete pixels in tile");
|
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (!PyString_Check(w) && PyString_Size(w) == bpp) {
|
|
|
|
PyErr_SetString(PyExc_TypeError, "invalid subscript");
|
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2007-05-29 06:26:22 +08:00
|
|
|
pix = (guchar *)PyString_AsString(w);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (PyInt_Check(v)) {
|
|
|
|
x = PyInt_AsLong(v);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (x < 0 || x >= tile->ewidth * tile->eheight) {
|
2004-09-01 15:57:15 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "index out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
data = tile->data + x * bpp;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
for (i = 0; i < bpp; i++)
|
|
|
|
data[i] = pix[i];
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
tile->dirty = TRUE;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (PyTuple_Check(v)) {
|
|
|
|
if (!PyArg_ParseTuple(v, "ll", &x, &y))
|
|
|
|
return -1;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (x < 0 || y < 0 || x >= tile->ewidth || y>=tile->eheight) {
|
2004-09-01 15:57:15 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "index out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
data = tile->data + bpp * (x + y * tile->ewidth);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
for (i = 0; i < bpp; i++)
|
|
|
|
data[i] = pix[i];
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
tile->dirty = TRUE;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "tile subscript not int or 2-tuple");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyMappingMethods tile_as_mapping = {
|
|
|
|
(inquiry)tile_length, /*length*/
|
|
|
|
(binaryfunc)tile_subscript, /*subscript*/
|
|
|
|
(objobjargproc)tile_ass_sub, /*ass_sub*/
|
|
|
|
};
|
|
|
|
|
|
|
|
PyTypeObject PyGimpTile_Type = {
|
|
|
|
PyObject_HEAD_INIT(NULL)
|
|
|
|
0, /* ob_size */
|
|
|
|
"gimp.Tile", /* tp_name */
|
|
|
|
sizeof(PyGimpTile), /* tp_basicsize */
|
|
|
|
0, /* tp_itemsize */
|
|
|
|
/* methods */
|
|
|
|
(destructor)tile_dealloc, /* tp_dealloc */
|
|
|
|
(printfunc)0, /* tp_print */
|
2002-08-30 11:01:35 +08:00
|
|
|
(getattrfunc)0, /* tp_getattr */
|
2002-08-28 23:17:29 +08:00
|
|
|
(setattrfunc)0, /* tp_setattr */
|
|
|
|
(cmpfunc)0, /* tp_compare */
|
|
|
|
(reprfunc)tile_repr, /* tp_repr */
|
|
|
|
0, /* tp_as_number */
|
|
|
|
0, /* tp_as_sequence */
|
|
|
|
&tile_as_mapping, /* tp_as_mapping */
|
|
|
|
(hashfunc)0, /* tp_hash */
|
|
|
|
(ternaryfunc)0, /* tp_call */
|
|
|
|
(reprfunc)0, /* tp_str */
|
|
|
|
(getattrofunc)0, /* tp_getattro */
|
|
|
|
(setattrofunc)0, /* tp_setattro */
|
|
|
|
0, /* tp_as_buffer */
|
|
|
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
|
|
|
NULL, /* Documentation string */
|
|
|
|
(traverseproc)0, /* tp_traverse */
|
|
|
|
(inquiry)0, /* tp_clear */
|
|
|
|
(richcmpfunc)0, /* tp_richcompare */
|
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
(getiterfunc)0, /* tp_iter */
|
|
|
|
(iternextfunc)0, /* tp_iternext */
|
|
|
|
tile_methods, /* tp_methods */
|
|
|
|
0, /* tp_members */
|
2002-08-30 11:01:35 +08:00
|
|
|
tile_getsets, /* tp_getset */
|
2002-08-28 23:17:29 +08:00
|
|
|
(PyTypeObject *)0, /* tp_base */
|
|
|
|
(PyObject *)0, /* tp_dict */
|
|
|
|
0, /* tp_descr_get */
|
|
|
|
0, /* tp_descr_set */
|
|
|
|
0, /* tp_dictoffset */
|
|
|
|
(initproc)0, /* tp_init */
|
|
|
|
(allocfunc)0, /* tp_alloc */
|
|
|
|
(newfunc)0, /* tp_new */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* End of code for Tile objects */
|
|
|
|
/* -------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
pr_resize(PyGimpPixelRgn *self, PyObject *args)
|
|
|
|
{
|
|
|
|
int x, y, w, h;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (!PyArg_ParseTuple(args, "iiii:resize", &x, &y, &w, &h))
|
|
|
|
return NULL;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
gimp_pixel_rgn_resize(&(self->pr), x, y, w, h);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
Py_INCREF(Py_None);
|
|
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-08-30 20:46:27 +08:00
|
|
|
static PyMethodDef pr_methods[] = {
|
2002-08-28 23:17:29 +08:00
|
|
|
{"resize", (PyCFunction)pr_resize, METH_VARARGS},
|
2006-01-17 20:43:50 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
{NULL, NULL} /* sentinel */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* ---------- */
|
|
|
|
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
pygimp_pixel_rgn_new(PyGimpDrawable *drawable, int x, int y,
|
|
|
|
int width, int height, int dirty, int shadow)
|
|
|
|
{
|
|
|
|
PyGimpPixelRgn *self;
|
|
|
|
|
|
|
|
self = PyObject_NEW(PyGimpPixelRgn, &PyGimpPixelRgn_Type);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (self == NULL)
|
|
|
|
return NULL;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
gimp_pixel_rgn_init(&(self->pr), drawable->drawable, x, y, width, height,
|
|
|
|
dirty, shadow);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
self->drawable = drawable;
|
|
|
|
Py_INCREF(drawable);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
return (PyObject *)self;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
pr_dealloc(PyGimpPixelRgn *self)
|
|
|
|
{
|
|
|
|
Py_DECREF(self->drawable);
|
|
|
|
PyObject_DEL(self);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Code to access pr objects as mappings */
|
|
|
|
|
|
|
|
static int
|
|
|
|
pr_length(PyGimpPixelRgn *self)
|
|
|
|
{
|
2003-12-04 05:52:09 +08:00
|
|
|
PyErr_SetString(pygimp_error, "Can't get size of pixel region");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
pr_subscript(PyGimpPixelRgn *self, PyObject *key)
|
|
|
|
{
|
|
|
|
GimpPixelRgn *pr = &(self->pr);
|
|
|
|
int bpp = pr->bpp;
|
|
|
|
PyObject *x, *y;
|
|
|
|
int x1, y1, x2, y2, xs, ys;
|
|
|
|
|
|
|
|
if (!PyTuple_Check(key) || PyTuple_Size(key) != 2) {
|
2003-12-04 05:52:09 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "subscript must be a 2-tuple");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (!PyArg_ParseTuple(key, "OO", &x, &y))
|
|
|
|
return NULL;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (PyInt_Check(x)) {
|
|
|
|
x1 = PyInt_AsLong(x);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (pr->x > x1 || x1 >= pr->x + pr->w) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "x subscript out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (PyInt_Check(y)) {
|
2007-05-29 06:26:22 +08:00
|
|
|
guchar buf[MAX_BPP];
|
2002-08-28 23:17:29 +08:00
|
|
|
|
|
|
|
y1 = PyInt_AsLong(y);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (pr->y > y1 || y1 >= pr->y + pr->h) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "y subscript out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
gimp_pixel_rgn_get_pixel(pr, buf, x1, y1);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2007-05-29 06:26:22 +08:00
|
|
|
return PyString_FromStringAndSize((char *)buf, bpp);
|
2002-08-28 23:17:29 +08:00
|
|
|
} else if (PySlice_Check(y))
|
|
|
|
if (PySlice_GetIndices((PySliceObject *)y,
|
|
|
|
pr->y + pr->h, &y1, &y2, &ys) ||
|
|
|
|
(y1 != 0 && pr->y > y1) ||
|
|
|
|
pr->y > y2 || ys != 1) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "invalid y slice");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
} else {
|
2007-05-29 06:26:22 +08:00
|
|
|
guchar *buf = g_new(guchar, bpp * (y2 - y1));
|
2002-08-28 23:17:29 +08:00
|
|
|
PyObject *ret;
|
|
|
|
|
|
|
|
if (y1 == 0) y1 = pr->y;
|
|
|
|
gimp_pixel_rgn_get_col(pr, buf, x1, y1, y2-y1);
|
2007-05-29 06:26:22 +08:00
|
|
|
ret = PyString_FromStringAndSize((char *)buf, bpp * (y2 - y1));
|
2002-08-28 23:17:29 +08:00
|
|
|
g_free(buf);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
PyErr_SetString(PyExc_TypeError,"invalid y subscript");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
} else if (PySlice_Check(x)) {
|
|
|
|
if (PySlice_GetIndices((PySliceObject *)x, pr->x + pr->w,
|
|
|
|
&x1, &x2, &xs) || (x1 != 0 && pr->x > x1) ||
|
|
|
|
pr->x > x2 || xs != 1) {
|
|
|
|
PyErr_SetString(PyExc_IndexError, "invalid x slice");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (x1 == 0) x1 = pr->x;
|
|
|
|
if (PyInt_Check(y)) {
|
2007-05-29 06:26:22 +08:00
|
|
|
guchar *buf;
|
2002-08-28 23:17:29 +08:00
|
|
|
PyObject *ret;
|
|
|
|
|
|
|
|
y1 = PyInt_AsLong(y);
|
|
|
|
if (pr->y > y1 || y1 >= pr->y + pr->h) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "y subscript out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2007-05-29 06:26:22 +08:00
|
|
|
buf = g_new(guchar, bpp * (x2 - x1));
|
2002-08-28 23:17:29 +08:00
|
|
|
gimp_pixel_rgn_get_row(pr, buf, x1, y1, x2 - x1);
|
2007-05-29 06:26:22 +08:00
|
|
|
ret = PyString_FromStringAndSize((char *)buf, bpp * (x2-x1));
|
2002-08-28 23:17:29 +08:00
|
|
|
g_free(buf);
|
|
|
|
return ret;
|
|
|
|
} else if (PySlice_Check(y))
|
|
|
|
if (PySlice_GetIndices((PySliceObject *)y,
|
|
|
|
pr->y + pr->h, &y1, &y2, &ys) ||
|
|
|
|
(y1 != 0 && pr->y) > y1 ||
|
|
|
|
pr->y > y2 || ys != 1) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "invalid y slice");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
} else {
|
2007-05-29 06:26:22 +08:00
|
|
|
guchar *buf = g_new(guchar, bpp * (x2 - x1) * (y2 - y1));
|
2002-08-28 23:17:29 +08:00
|
|
|
PyObject *ret;
|
|
|
|
|
|
|
|
if (y1 == 0) y1 = pr->y;
|
|
|
|
gimp_pixel_rgn_get_rect(pr, buf, x1, y1,
|
|
|
|
x2 - x1, y2 - y1);
|
2007-05-29 06:26:22 +08:00
|
|
|
ret = PyString_FromStringAndSize((char *)buf, bpp * (x2-x1) * (y2-y1));
|
2002-08-28 23:17:29 +08:00
|
|
|
g_free(buf);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "invalid y subscript");
|
2002-08-28 23:17:29 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
PyErr_SetString(PyExc_TypeError, "invalid x subscript");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
pr_ass_sub(PyGimpPixelRgn *self, PyObject *v, PyObject *w)
|
|
|
|
{
|
|
|
|
GimpPixelRgn *pr = &(self->pr);
|
|
|
|
int bpp = pr->bpp;
|
|
|
|
PyObject *x, *y;
|
2007-05-29 06:26:22 +08:00
|
|
|
guchar *buf;
|
2002-08-28 23:17:29 +08:00
|
|
|
int len, x1, x2, xs, y1, y2, ys;
|
|
|
|
|
|
|
|
if (w == NULL) {
|
2003-12-04 05:52:09 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "can't delete subscripts");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (!PyString_Check(w)) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "must assign string to subscript");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (!PyTuple_Check(v) || PyTuple_Size(v) != 2) {
|
2003-12-04 05:52:09 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "subscript must be a 2-tuple");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (!PyArg_ParseTuple(v, "OO", &x, &y))
|
|
|
|
return -1;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2007-05-29 06:26:22 +08:00
|
|
|
buf = (guchar *)PyString_AsString(w);
|
2002-08-28 23:17:29 +08:00
|
|
|
len = PyString_Size(w);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (PyInt_Check(x)) {
|
|
|
|
x1 = PyInt_AsLong(x);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (pr->x > x1 || x1 >= pr->x + pr->w) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "x subscript out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (PyInt_Check(y)) {
|
|
|
|
y1 = PyInt_AsLong(y);
|
2006-01-17 20:43:50 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (pr->y > y1 || y1 >= pr->y + pr->h) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "y subscript out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
if (len != bpp) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "string is wrong length");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
gimp_pixel_rgn_set_pixel(pr, buf, x1, y1);
|
|
|
|
return 0;
|
|
|
|
} else if (PySlice_Check(y)) {
|
|
|
|
if (PySlice_GetIndices((PySliceObject *)y,
|
|
|
|
pr->y + pr->h, &y1, &y2, &ys) ||
|
|
|
|
(y1 != 0 && pr->y > y1) ||
|
|
|
|
pr->y > y2 || ys != 1) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "invalid y slice");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (y1 == 0) y1 = pr->y;
|
|
|
|
if (len != bpp * (y2 - y1)) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "string is wrong length");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
gimp_pixel_rgn_set_col(pr, buf, x1, y1, y2 - y1);
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
PyErr_SetString(PyExc_IndexError,"invalid y subscript");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else if (PySlice_Check(x)) {
|
|
|
|
if (PySlice_GetIndices((PySliceObject *)x, pr->x + pr->w,
|
|
|
|
&x1, &x2, &xs) || (x1 != 0 && pr->x > x1) ||
|
|
|
|
pr->x > x2 || xs != 1) {
|
|
|
|
PyErr_SetString(PyExc_IndexError, "invalid x slice");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (x1 == 0) x1 = pr->x;
|
|
|
|
if (PyInt_Check(y)) {
|
|
|
|
y1 = PyInt_AsLong(y);
|
|
|
|
if (pr->y > y1 || y1 >= pr->y + pr->h) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "y subscript out of range");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (len != bpp * (x2 - x1)) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "string is wrong length");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
gimp_pixel_rgn_set_row(pr, buf, x1, y1, x2 - x1);
|
|
|
|
return 0;
|
|
|
|
} else if (PySlice_Check(y)) {
|
|
|
|
if (PySlice_GetIndices((PySliceObject *)y,
|
|
|
|
pr->y + pr->h, &y1, &y2, &ys) ||
|
|
|
|
(y1 != 0 && pr->y > y1) ||
|
|
|
|
pr->y > y2 || ys != 1) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_IndexError, "invalid y slice");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (y1 == 0) y1 = pr->y;
|
|
|
|
if (len != bpp * (x2 - x1) * (y2 - y1)) {
|
2005-03-03 16:43:55 +08:00
|
|
|
PyErr_SetString(PyExc_TypeError, "string is wrong length");
|
2002-08-28 23:17:29 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
gimp_pixel_rgn_set_rect(pr, buf, x1, y1, x2-x1, y2-y1);
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
PyErr_SetString(PyExc_TypeError,"invalid y subscript");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
PyErr_SetString(PyExc_TypeError, "invalid x subscript");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyMappingMethods pr_as_mapping = {
|
|
|
|
(inquiry)pr_length, /*mp_length*/
|
|
|
|
(binaryfunc)pr_subscript, /*mp_subscript*/
|
|
|
|
(objobjargproc)pr_ass_sub, /*mp_ass_subscript*/
|
|
|
|
};
|
|
|
|
|
|
|
|
/* -------------------------------------------------------- */
|
|
|
|
|
2002-08-30 11:01:35 +08:00
|
|
|
static PyObject *
|
|
|
|
pr_get_drawable(PyGimpPixelRgn *self, void *closure)
|
|
|
|
{
|
|
|
|
return pygimp_drawable_new(self->pr.drawable, 0);
|
|
|
|
}
|
2002-08-28 23:17:29 +08:00
|
|
|
|
2002-08-30 11:01:35 +08:00
|
|
|
static PyObject *
|
|
|
|
pr_get_uint_field(PyGimpPixelRgn *self, void *closure)
|
|
|
|
{
|
|
|
|
gint offset = GPOINTER_TO_INT(closure);
|
|
|
|
guint value;
|
|
|
|
gchar *addr;
|
|
|
|
|
|
|
|
addr = (gchar *)&self->pr;
|
|
|
|
addr += offset;
|
|
|
|
value = *(guint *)addr;
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-30 11:01:35 +08:00
|
|
|
return PyInt_FromLong(value);
|
|
|
|
}
|
2002-08-28 23:17:29 +08:00
|
|
|
|
|
|
|
static PyObject *
|
2002-08-30 11:01:35 +08:00
|
|
|
pr_get_dirty(PyGimpPixelRgn *self, void *closure)
|
2002-08-28 23:17:29 +08:00
|
|
|
{
|
2005-03-03 16:43:55 +08:00
|
|
|
return PyBool_FromLong(self->pr.dirty);
|
2002-08-30 11:01:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
pr_get_shadow(PyGimpPixelRgn *self, void *closure)
|
|
|
|
{
|
2005-03-03 16:43:55 +08:00
|
|
|
return PyBool_FromLong(self->pr.shadow);
|
2002-08-28 23:17:29 +08:00
|
|
|
}
|
|
|
|
|
2002-08-30 11:01:35 +08:00
|
|
|
#define OFF(x) GINT_TO_POINTER(offsetof(GimpPixelRgn, x))
|
|
|
|
static PyGetSetDef pr_getsets[] = {
|
|
|
|
{ "drawable", (getter)pr_get_drawable, 0, NULL },
|
|
|
|
{ "bpp", (getter)pr_get_uint_field, 0, NULL, OFF(bpp) },
|
|
|
|
{ "rowstride", (getter)pr_get_uint_field, 0, NULL, OFF(rowstride) },
|
|
|
|
{ "x", (getter)pr_get_uint_field, 0, NULL, OFF(x) },
|
|
|
|
{ "y", (getter)pr_get_uint_field, 0, NULL, OFF(y) },
|
|
|
|
{ "w", (getter)pr_get_uint_field, 0, NULL, OFF(w) },
|
|
|
|
{ "h", (getter)pr_get_uint_field, 0, NULL, OFF(h) },
|
|
|
|
{ "dirty", (getter)pr_get_dirty, 0, NULL },
|
|
|
|
{ "shadow", (getter)pr_get_shadow, 0, NULL },
|
|
|
|
{ NULL, (getter)0, (setter)0 },
|
|
|
|
};
|
|
|
|
#undef OFF
|
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
static PyObject *
|
|
|
|
pr_repr(PyGimpPixelRgn *self)
|
|
|
|
{
|
|
|
|
PyObject *s;
|
|
|
|
gchar *name;
|
|
|
|
|
2003-12-04 01:41:36 +08:00
|
|
|
name = gimp_drawable_get_name(self->drawable->drawable->drawable_id);
|
2002-08-30 20:46:27 +08:00
|
|
|
s = PyString_FromFormat("<gimp.PixelRgn for drawable '%s'>", name);
|
2002-08-28 23:17:29 +08:00
|
|
|
g_free(name);
|
2005-03-03 16:43:55 +08:00
|
|
|
|
2002-08-28 23:17:29 +08:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
PyTypeObject PyGimpPixelRgn_Type = {
|
|
|
|
PyObject_HEAD_INIT(NULL)
|
|
|
|
0, /* ob_size */
|
|
|
|
"gimp.PixelRgn", /* tp_name */
|
|
|
|
sizeof(PyGimpPixelRgn), /* tp_basicsize */
|
|
|
|
0, /* tp_itemsize */
|
|
|
|
/* methods */
|
|
|
|
(destructor)pr_dealloc, /* tp_dealloc */
|
|
|
|
(printfunc)0, /* tp_print */
|
2002-08-30 11:01:35 +08:00
|
|
|
(getattrfunc)0, /* tp_getattr */
|
2002-08-28 23:17:29 +08:00
|
|
|
(setattrfunc)0, /* tp_setattr */
|
|
|
|
(cmpfunc)0, /* tp_compare */
|
|
|
|
(reprfunc)pr_repr, /* tp_repr */
|
|
|
|
0, /* tp_as_number */
|
|
|
|
0, /* tp_as_sequence */
|
|
|
|
&pr_as_mapping, /* tp_as_mapping */
|
|
|
|
(hashfunc)0, /* tp_hash */
|
|
|
|
(ternaryfunc)0, /* tp_call */
|
|
|
|
(reprfunc)0, /* tp_str */
|
|
|
|
(getattrofunc)0, /* tp_getattro */
|
|
|
|
(setattrofunc)0, /* tp_setattro */
|
|
|
|
0, /* tp_as_buffer */
|
|
|
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
|
|
|
NULL, /* Documentation string */
|
|
|
|
(traverseproc)0, /* tp_traverse */
|
|
|
|
(inquiry)0, /* tp_clear */
|
|
|
|
(richcmpfunc)0, /* tp_richcompare */
|
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
(getiterfunc)0, /* tp_iter */
|
|
|
|
(iternextfunc)0, /* tp_iternext */
|
|
|
|
pr_methods, /* tp_methods */
|
|
|
|
0, /* tp_members */
|
2002-08-30 11:01:35 +08:00
|
|
|
pr_getsets, /* tp_getset */
|
2002-08-28 23:17:29 +08:00
|
|
|
(PyTypeObject *)0, /* tp_base */
|
|
|
|
(PyObject *)0, /* tp_dict */
|
|
|
|
0, /* tp_descr_get */
|
|
|
|
0, /* tp_descr_set */
|
|
|
|
0, /* tp_dictoffset */
|
|
|
|
(initproc)0, /* tp_init */
|
|
|
|
(allocfunc)0, /* tp_alloc */
|
|
|
|
(newfunc)0, /* tp_new */
|
|
|
|
};
|