1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * Gimp-Python - allows the writing of Gimp plugins in Python.
3  * Copyright (C) 1997-2002  James Henstridge <james@daa.com.au>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22 
23 #include "pygimp.h"
24 
25 static PyObject *
img_add_channel(PyGimpImage * self,PyObject * args)26 img_add_channel(PyGimpImage *self, PyObject *args)
27 {
28     PyGimpChannel *chn;
29     int pos = -1;
30 
31     if (!PyArg_ParseTuple(args, "O!|i:add_channel",
32 	                        &PyGimpChannel_Type, &chn, &pos))
33 	return NULL;
34 
35     if (!gimp_image_insert_channel(self->ID, chn->ID, -1, pos)) {
36 	PyErr_Format(pygimp_error,
37 		     "could not add channel (ID %d) to image (ID %d)",
38 		     chn->ID, self->ID);
39 	return NULL;
40     }
41 
42     Py_INCREF(Py_None);
43     return Py_None;
44 }
45 
46 static PyObject *
img_insert_channel(PyGimpImage * self,PyObject * args,PyObject * kwargs)47 img_insert_channel(PyGimpImage *self, PyObject *args, PyObject *kwargs)
48 {
49     PyGimpChannel *chn;
50     PyGimpChannel *parent = NULL;
51     int pos = -1;
52 
53     static char *kwlist[] = { "channel", "parent", "position", NULL };
54 
55     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
56                                      "O!|O!i:insert_channel", kwlist,
57                                      &PyGimpChannel_Type, &chn,
58                                      &PyGimpChannel_Type, &parent,
59                                      &pos))
60 	return NULL;
61 
62     if (!gimp_image_insert_channel(self->ID,
63                                    chn->ID, parent ? parent->ID : -1, pos)) {
64 	PyErr_Format(pygimp_error,
65 		     "could not insert channel (ID %d) to image (ID %d)",
66 		     chn->ID, self->ID);
67 	return NULL;
68     }
69 
70     Py_INCREF(Py_None);
71     return Py_None;
72 }
73 
74 static PyObject *
img_add_layer(PyGimpImage * self,PyObject * args)75 img_add_layer(PyGimpImage *self, PyObject *args)
76 {
77     PyGimpLayer *lay;
78     int pos = -1;
79 
80     if (!PyArg_ParseTuple(args, "O!|i:add_layer", &PyGimpLayer_Type, &lay,
81 			  &pos))
82 	return NULL;
83 
84     if (!gimp_image_insert_layer(self->ID, lay->ID, -1, pos)) {
85 	PyErr_Format(pygimp_error,
86 		     "could not add layer (ID %d) to image (ID %d)",
87 		     lay->ID, self->ID);
88 	return NULL;
89     }
90 
91     Py_INCREF(Py_None);
92     return Py_None;
93 }
94 
95 static PyObject *
img_insert_layer(PyGimpImage * self,PyObject * args,PyObject * kwargs)96 img_insert_layer(PyGimpImage *self, PyObject *args, PyObject *kwargs)
97 {
98     PyGimpLayer *lay;
99     PyGimpLayer *parent = NULL;
100     int pos = -1;
101 
102     static char *kwlist[] = { "layer", "parent", "position", NULL };
103 
104     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
105                                      "O!|O!i:insert_layer", kwlist,
106                                      &PyGimpLayer_Type, &lay,
107                                      &PyGimpLayer_Type, &parent,
108                                      &pos))
109 	return NULL;
110 
111     if (!gimp_image_insert_layer(self->ID,
112                                  lay->ID, parent ? parent->ID : -1, pos)) {
113 	PyErr_Format(pygimp_error,
114 		     "could not insert layer (ID %d) to image (ID %d)",
115 		     lay->ID, self->ID);
116 	return NULL;
117     }
118 
119     Py_INCREF(Py_None);
120     return Py_None;
121 }
122 
123 static PyObject *
img_new_layer(PyGimpImage * self,PyObject * args,PyObject * kwargs)124 img_new_layer(PyGimpImage *self, PyObject *args, PyObject *kwargs)
125 {
126     char *layer_name;
127     int layer_id;
128     int width, height;
129     int layer_type;
130     int offs_x = 0, offs_y = 0;
131     gboolean alpha = TRUE;
132     int pos = -1;
133     double opacity = 100.0;
134     GimpLayerMode mode = GIMP_LAYER_MODE_NORMAL;
135     GimpFillType fill_mode = -1;
136 
137     static char *kwlist[] = { "name", "width", "height", "offset_x", "offset_y",
138                               "alpha", "pos", "opacity", "mode", "fill_mode",
139                               NULL };
140 
141     layer_name = "New Layer";
142 
143     width = gimp_image_width(self->ID);
144     height = gimp_image_height(self->ID);
145 
146     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
147                                      "|siiiiiidii:new_layer", kwlist,
148                                      &layer_name, &width, &height,
149                                      &offs_x, &offs_y, &alpha, &pos,
150                                      &opacity, &mode, &fill_mode))
151         return NULL;
152 
153 
154     switch (gimp_image_base_type(self->ID))  {
155         case GIMP_RGB:
156             layer_type = alpha ? GIMP_RGBA_IMAGE: GIMP_RGB_IMAGE;
157             break;
158         case GIMP_GRAY:
159             layer_type = alpha ? GIMP_GRAYA_IMAGE: GIMP_GRAY_IMAGE;
160             break;
161         case GIMP_INDEXED:
162             layer_type = alpha ? GIMP_INDEXEDA_IMAGE: GIMP_INDEXED_IMAGE;
163             break;
164         default:
165             PyErr_SetString(pygimp_error, "Unknown image base type");
166             return NULL;
167     }
168 
169     if (fill_mode == -1)
170         fill_mode = alpha ? GIMP_FILL_TRANSPARENT: GIMP_FILL_BACKGROUND;
171 
172 
173     layer_id = gimp_layer_new(self->ID, layer_name, width, height,
174                               layer_type, opacity, mode);
175 
176     if (!layer_id) {
177         PyErr_Format(pygimp_error,
178                      "could not create new layer in image (ID %d)",
179                      self->ID);
180         return NULL;
181     }
182 
183     if (!gimp_drawable_fill(layer_id, fill_mode)) {
184         gimp_item_delete(layer_id);
185         PyErr_Format(pygimp_error,
186                      "could not fill new layer with fill mode %d",
187                      fill_mode);
188         return NULL;
189     }
190 
191     if (!gimp_image_insert_layer(self->ID, layer_id, -1, pos)) {
192         gimp_item_delete(layer_id);
193         PyErr_Format(pygimp_error,
194                      "could not add layer (ID %d) to image (ID %d)",
195                      layer_id, self->ID);
196         return NULL;
197     }
198 
199     if (!gimp_layer_set_offsets(layer_id, offs_x, offs_y)) {
200         gimp_image_remove_layer(self->ID, layer_id);
201         PyErr_Format(pygimp_error,
202                      "could not set offset %d, %d on layer (ID %d)",
203                       offs_x, offs_y, layer_id);
204         return NULL;
205     }
206 
207     return pygimp_group_layer_new(layer_id);
208 }
209 
210 
211 static PyObject *
img_clean_all(PyGimpImage * self)212 img_clean_all(PyGimpImage *self)
213 {
214     if (!gimp_image_clean_all(self->ID)) {
215 	PyErr_Format(pygimp_error, "could not clean all on image (ID %d)",
216 		     self->ID);
217 	return NULL;
218     }
219 
220     Py_INCREF(Py_None);
221     return Py_None;
222 }
223 
224 static PyObject *
img_disable_undo(PyGimpImage * self)225 img_disable_undo(PyGimpImage *self)
226 {
227     return PyBool_FromLong(gimp_image_undo_disable(self->ID));
228 }
229 
230 static PyObject *
img_enable_undo(PyGimpImage * self)231 img_enable_undo(PyGimpImage *self)
232 {
233     return PyBool_FromLong(gimp_image_undo_enable(self->ID));
234 }
235 
236 static PyObject *
img_flatten(PyGimpImage * self)237 img_flatten(PyGimpImage *self)
238 {
239     return pygimp_group_layer_new(gimp_image_flatten(self->ID));
240 }
241 
242 static PyObject *
img_lower_channel(PyGimpImage * self,PyObject * args)243 img_lower_channel(PyGimpImage *self, PyObject *args)
244 {
245     PyGimpChannel *chn;
246 
247     if (!PyArg_ParseTuple(args, "O!:lower_channel", &PyGimpChannel_Type, &chn))
248 	return NULL;
249 
250     if (!gimp_image_lower_item(self->ID, chn->ID)) {
251 	PyErr_Format(pygimp_error,
252 		     "could not lower channel (ID %d) on image (ID %d)",
253 		     chn->ID, self->ID);
254 	return NULL;
255     }
256 
257     Py_INCREF(Py_None);
258     return Py_None;
259 }
260 
261 static PyObject *
img_lower_layer(PyGimpImage * self,PyObject * args)262 img_lower_layer(PyGimpImage *self, PyObject *args)
263 {
264     PyGimpLayer *lay;
265 
266     if (!PyArg_ParseTuple(args, "O!:lower_layer", &PyGimpLayer_Type, &lay))
267 	return NULL;
268 
269     if (!gimp_image_lower_item(self->ID, lay->ID)) {
270 	PyErr_Format(pygimp_error,
271 		     "could not lower layer (ID %d) on image (ID %d)",
272 		     lay->ID, self->ID);
273 	return NULL;
274     }
275 
276     Py_INCREF(Py_None);
277     return Py_None;
278 }
279 
280 static PyObject *
img_lower_layer_to_bottom(PyGimpImage * self,PyObject * args)281 img_lower_layer_to_bottom(PyGimpImage *self, PyObject *args)
282 {
283     PyGimpLayer *lay;
284 
285     if (!PyArg_ParseTuple(args, "O!:lower_layer_to_bottom",
286 			  &PyGimpLayer_Type, &lay))
287 	return NULL;
288 
289     if (!gimp_image_lower_item_to_bottom(self->ID, lay->ID)) {
290 	PyErr_Format(pygimp_error,
291 		     "could not lower layer (ID %d) to bottom on image (ID %d)",
292 		     lay->ID, self->ID);
293 	return NULL;
294     }
295 
296     Py_INCREF(Py_None);
297     return Py_None;
298 }
299 
300 static PyObject *
img_merge_visible_layers(PyGimpImage * self,PyObject * args)301 img_merge_visible_layers(PyGimpImage *self, PyObject *args)
302 {
303     gint32 id;
304     int merge;
305 
306     if (!PyArg_ParseTuple(args, "i:merge_visible_layers", &merge))
307 	return NULL;
308 
309     id = gimp_image_merge_visible_layers(self->ID, merge);
310 
311     if (id == -1) {
312 	PyErr_Format(pygimp_error,
313 		     "could not merge visible layers on image (ID %d) "
314 		     "with merge type %d",
315 		     self->ID, merge);
316 	return NULL;
317     }
318 
319     return pygimp_group_layer_new(id);
320 }
321 
322 static PyObject *
img_merge_down(PyGimpImage * self,PyObject * args)323 img_merge_down(PyGimpImage *self, PyObject *args)
324 {
325     gint32 id;
326     PyGimpLayer *layer;
327     int merge;
328 
329     if (!PyArg_ParseTuple(args, "O!i:merge_down",
330 			  &PyGimpLayer_Type, &layer, &merge))
331 	return NULL;
332 
333     id = gimp_image_merge_down(self->ID, layer->ID, merge);
334 
335     if (id == -1) {
336 	PyErr_Format(pygimp_error,
337 		     "could not merge down layer (ID %d) on image (ID %d) "
338 		     "with merge type %d",
339 		     layer->ID, self->ID, merge);
340 	return NULL;
341     }
342 
343     return pygimp_group_layer_new(id);
344 }
345 
346 static PyObject *
img_pick_correlate_layer(PyGimpImage * self,PyObject * args)347 img_pick_correlate_layer(PyGimpImage *self, PyObject *args)
348 {
349     int x,y;
350     gint32 id;
351 
352     if (!PyArg_ParseTuple(args, "ii:pick_correlate_layer", &x, &y))
353 	return NULL;
354 
355     id = gimp_image_pick_correlate_layer(self->ID, x, y);
356 
357     if (id == -1) {
358 	Py_INCREF(Py_None);
359 	return Py_None;
360     }
361 
362     return pygimp_group_layer_new(id);
363 }
364 
365 static PyObject *
img_raise_channel(PyGimpImage * self,PyObject * args)366 img_raise_channel(PyGimpImage *self, PyObject *args)
367 {
368     PyGimpChannel *chn;
369 
370     if (!PyArg_ParseTuple(args, "O!:raise_channel", &PyGimpChannel_Type, &chn))
371 	return NULL;
372 
373     if (!gimp_image_raise_item(self->ID, chn->ID)) {
374 	PyErr_Format(pygimp_error,
375 		     "could not raise channel (ID %d) on image (ID %d)",
376 		     chn->ID, self->ID);
377 	return NULL;
378     }
379 
380     Py_INCREF(Py_None);
381     return Py_None;
382 }
383 
384 static PyObject *
img_raise_layer(PyGimpImage * self,PyObject * args)385 img_raise_layer(PyGimpImage *self, PyObject *args)
386 {
387     PyGimpLayer *lay;
388 
389     if (!PyArg_ParseTuple(args, "O!:raise_layer", &PyGimpLayer_Type, &lay))
390 	return NULL;
391 
392     if (!gimp_image_raise_item(self->ID, lay->ID)) {
393 	PyErr_Format(pygimp_error,
394 		     "could not raise layer (ID %d) on image (ID %d)",
395 		     lay->ID, self->ID);
396 	return NULL;
397     }
398 
399     Py_INCREF(Py_None);
400     return Py_None;
401 }
402 
403 static PyObject *
img_raise_layer_to_top(PyGimpImage * self,PyObject * args)404 img_raise_layer_to_top(PyGimpImage *self, PyObject *args)
405 {
406     PyGimpLayer *lay;
407 
408     if (!PyArg_ParseTuple(args, "O!:raise_layer_to_top",
409 			  &PyGimpLayer_Type, &lay))
410 	return NULL;
411 
412     if (!gimp_image_raise_item_to_top(self->ID, lay->ID)) {
413 	PyErr_Format(pygimp_error,
414 		     "could not raise layer (ID %d) to top on image (ID %d)",
415 		     lay->ID, self->ID);
416 	return NULL;
417     }
418 
419     Py_INCREF(Py_None);
420     return Py_None;
421 }
422 
423 static PyObject *
img_remove_channel(PyGimpImage * self,PyObject * args)424 img_remove_channel(PyGimpImage *self, PyObject *args)
425 {
426     PyGimpChannel *chn;
427 
428     if (!PyArg_ParseTuple(args, "O!:remove_channel", &PyGimpChannel_Type, &chn))
429 	return NULL;
430 
431     if (!gimp_image_remove_channel(self->ID, chn->ID)) {
432 	PyErr_Format(pygimp_error,
433 		     "could not remove channel (ID %d) from image (ID %d)",
434 		     chn->ID, self->ID);
435 	return NULL;
436     }
437 
438     Py_INCREF(Py_None);
439     return Py_None;
440 }
441 
442 static PyObject *
img_remove_layer(PyGimpImage * self,PyObject * args)443 img_remove_layer(PyGimpImage *self, PyObject *args)
444 {
445     PyGimpLayer *lay;
446 
447     if (!PyArg_ParseTuple(args, "O!:remove_layer", &PyGimpLayer_Type, &lay))
448 	return NULL;
449 
450     if (!gimp_image_remove_layer(self->ID, lay->ID)) {
451 	PyErr_Format(pygimp_error,
452 		     "could not remove layer (ID %d) from image (ID %d)",
453 		     lay->ID, self->ID);
454 	return NULL;
455     }
456 
457     Py_INCREF(Py_None);
458     return Py_None;
459 }
460 
461 static PyObject *
img_resize(PyGimpImage * self,PyObject * args,PyObject * kwargs)462 img_resize(PyGimpImage *self, PyObject *args, PyObject *kwargs)
463 {
464     int new_w, new_h;
465     int offs_x = 0, offs_y = 0;
466 
467     static char *kwlist[] = { "width", "height", "offset_x", "offset_y",
468 			      NULL };
469 
470     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii:resize", kwlist,
471 				     &new_w, &new_h, &offs_x, &offs_y))
472 	return NULL;
473 
474     if (!gimp_image_resize(self->ID, new_w, new_h, offs_x, offs_y)) {
475 	PyErr_Format(pygimp_error,
476 		     "could not resize image (ID %d) to %dx%d, offset %d, %d",
477 		     self->ID, new_w, new_h, offs_x, offs_y);
478 	return NULL;
479     }
480 
481     Py_INCREF(Py_None);
482     return Py_None;
483 }
484 
485 static PyObject *
img_resize_to_layers(PyGimpImage * self)486 img_resize_to_layers(PyGimpImage *self)
487 {
488     if (!gimp_image_resize_to_layers(self->ID)) {
489 	PyErr_Format(pygimp_error, "could not resize to layers on image "
490 	                           "(ID %d)",
491 		     self->ID);
492 	return NULL;
493     }
494 
495     Py_INCREF(Py_None);
496     return Py_None;
497 }
498 
499 static PyObject *
img_scale(PyGimpImage * self,PyObject * args,PyObject * kwargs)500 img_scale(PyGimpImage *self, PyObject *args, PyObject *kwargs)
501 {
502     int new_width, new_height;
503     int interpolation = -1;
504 
505     static char *kwlist[] = { "width", "height", "interpolation", NULL };
506 
507     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:scale", kwlist,
508 				     &new_width, &new_height, &interpolation))
509 	return NULL;
510 
511     if (interpolation != -1) {
512         gimp_context_push();
513         gimp_context_set_interpolation(interpolation);
514     }
515 
516     if (!gimp_image_scale(self->ID, new_width, new_height)) {
517         PyErr_Format(pygimp_error, "could not scale image (ID %d) to %dx%d",
518                      self->ID, new_width, new_height);
519         if (interpolation != -1) {
520             gimp_context_pop();
521         }
522         return NULL;
523     }
524 
525     if (interpolation != -1) {
526         gimp_context_pop();
527     }
528 
529     Py_INCREF(Py_None);
530     return Py_None;
531 }
532 
533 static PyObject *
img_crop(PyGimpImage * self,PyObject * args,PyObject * kwargs)534 img_crop(PyGimpImage *self, PyObject *args, PyObject *kwargs)
535 {
536     int new_w, new_h;
537     int offs_x = 0, offs_y = 0;
538 
539     static char *kwlist[] = { "width", "height", "offset_x", "offset_y",
540 			      NULL };
541 
542     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii:crop", kwlist,
543 				     &new_w, &new_h, &offs_x, &offs_y))
544 	return NULL;
545 
546     if (!gimp_image_crop(self->ID, new_w, new_h, offs_x, offs_y)) {
547 	PyErr_Format(pygimp_error,
548 		     "could not crop image (ID %d) to %dx%d, offset %d, %d",
549 		     self->ID, new_w, new_h, offs_x, offs_y);
550 	return NULL;
551     }
552 
553     Py_INCREF(Py_None);
554     return Py_None;
555 }
556 
557 static PyObject *
img_free_shadow(PyGimpImage * self)558 img_free_shadow(PyGimpImage *self)
559 {
560     /* this procedure is deprecated and does absolutely nothing */
561 
562     Py_INCREF(Py_None);
563     return Py_None;
564 }
565 
566 static PyObject *
img_unset_active_channel(PyGimpImage * self)567 img_unset_active_channel(PyGimpImage *self)
568 {
569     if (!gimp_image_unset_active_channel(self->ID)) {
570 	PyErr_Format(pygimp_error,
571 		     "could not unset active channel on image (ID %d)",
572 		     self->ID);
573 	return NULL;
574     }
575 
576     Py_INCREF(Py_None);
577     return Py_None;
578 }
579 
580 static PyObject *
img_get_component_active(PyGimpImage * self,PyObject * args)581 img_get_component_active(PyGimpImage *self, PyObject *args)
582 {
583     int comp;
584 
585     if (!PyArg_ParseTuple(args, "i:get_component_active", &comp))
586 	return NULL;
587 
588     return PyBool_FromLong(gimp_image_get_component_active(self->ID, comp));
589 }
590 
591 
592 static PyObject *
img_get_component_visible(PyGimpImage * self,PyObject * args)593 img_get_component_visible(PyGimpImage *self, PyObject *args)
594 {
595     int comp;
596 
597     if (!PyArg_ParseTuple(args, "i:get_component_visible", &comp))
598 	return NULL;
599 
600     return PyBool_FromLong(gimp_image_get_component_visible(self->ID, comp));
601 }
602 
603 
604 static PyObject *
img_set_component_active(PyGimpImage * self,PyObject * args)605 img_set_component_active(PyGimpImage *self, PyObject *args)
606 {
607     int comp, a;
608 
609     if (!PyArg_ParseTuple(args, "ii:set_component_active", &comp, &a))
610 	return NULL;
611 
612     if (!gimp_image_set_component_active(self->ID, comp, a)) {
613 	PyErr_Format(pygimp_error,
614 		     "could not set component (%d) %sactive on image (ID %d)",
615 		     comp, a ? "" : "in", self->ID);
616 	return NULL;
617     }
618 
619     Py_INCREF(Py_None);
620     return Py_None;
621 }
622 
623 static PyObject *
img_set_component_visible(PyGimpImage * self,PyObject * args)624 img_set_component_visible(PyGimpImage *self, PyObject *args)
625 {
626     int comp, v;
627 
628     if (!PyArg_ParseTuple(args, "ii:set_component_visible", &comp, &v))
629 	return NULL;
630 
631     if (!gimp_image_set_component_visible(self->ID, comp, v)) {
632 	PyErr_Format(pygimp_error,
633 		     "could not set component (%d) %svisible on image (ID %d)",
634 		     comp, v ? "" : "in", self->ID);
635 	return NULL;
636     }
637 
638     Py_INCREF(Py_None);
639     return Py_None;
640 }
641 
642 static PyObject *
img_parasite_find(PyGimpImage * self,PyObject * args)643 img_parasite_find(PyGimpImage *self, PyObject *args)
644 {
645     char *name;
646 
647     if (!PyArg_ParseTuple(args, "s:parasite_find", &name))
648 	return NULL;
649 
650     return pygimp_parasite_new (gimp_image_get_parasite (self->ID, name));
651 }
652 
653 static PyObject *
img_parasite_attach(PyGimpImage * self,PyObject * args)654 img_parasite_attach(PyGimpImage *self, PyObject *args)
655 {
656     PyGimpParasite *parasite;
657 
658     if (!PyArg_ParseTuple(args, "O!:parasite_attach", &PyGimpParasite_Type,
659 			  &parasite))
660 	return NULL;
661 
662     if (! gimp_image_attach_parasite (self->ID, parasite->para)) {
663 	PyErr_Format(pygimp_error,
664 		     "could not attach parasite '%s' to image (ID %d)",
665 		     parasite->para->name, self->ID);
666 	return NULL;
667     }
668 
669     Py_INCREF(Py_None);
670     return Py_None;
671 }
672 
673 static PyObject *
img_attach_new_parasite(PyGimpImage * self,PyObject * args,PyObject * kwargs)674 img_attach_new_parasite(PyGimpImage *self, PyObject *args, PyObject *kwargs)
675 {
676     char *name;
677     int flags, size;
678     guint8 *data;
679     GimpParasite *parasite;
680     gboolean success;
681 
682     static char *kwlist[] = { "name", "flags", "data", NULL };
683 
684     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
685 				     "sis#:attach_new_parasite", kwlist,
686 				     &name, &flags, &data, &size))
687 	return NULL;
688 
689     parasite = gimp_parasite_new (name, flags, size, data);
690     success = gimp_image_attach_parasite (self->ID, parasite);
691     gimp_parasite_free (parasite);
692 
693     if (!success) {
694 	PyErr_Format(pygimp_error,
695 		     "could not attach new parasite '%s' to image (ID %d)",
696 		     name, self->ID);
697 	return NULL;
698     }
699 
700     Py_INCREF(Py_None);
701     return Py_None;
702 }
703 
704 static PyObject *
img_parasite_detach(PyGimpImage * self,PyObject * args)705 img_parasite_detach(PyGimpImage *self, PyObject *args)
706 {
707     char *name;
708 
709     if (!PyArg_ParseTuple(args, "s:parasite_detach", &name))
710 	return NULL;
711 
712     if (!gimp_image_detach_parasite (self->ID, name)) {
713 	PyErr_Format(pygimp_error,
714 		     "could not detach parasite '%s' from image (ID %d)",
715 		     name, self->ID);
716 	return NULL;
717     }
718 
719     Py_INCREF(Py_None);
720     return Py_None;
721 }
722 
723 static PyObject *
img_parasite_list(PyGimpImage * self)724 img_parasite_list(PyGimpImage *self)
725 {
726     gint num_parasites;
727     gchar **parasites;
728     PyObject *ret;
729     gint i;
730 
731     parasites = gimp_image_get_parasite_list (self->ID, &num_parasites);
732 
733     ret = PyTuple_New(num_parasites);
734 
735     for (i = 0; i < num_parasites; i++)
736         PyTuple_SetItem(ret, i, PyString_FromString(parasites[i]));
737 
738     g_strfreev(parasites);
739     return ret;
740 }
741 
742 static PyObject *
img_get_layer_by_tattoo(PyGimpImage * self,PyObject * args)743 img_get_layer_by_tattoo(PyGimpImage *self, PyObject *args)
744 {
745     int tattoo;
746 
747     if (!PyArg_ParseTuple(args, "i:get_layer_by_tattoo", &tattoo))
748 	return NULL;
749 
750     return pygimp_group_layer_new(gimp_image_get_layer_by_tattoo(self->ID, tattoo));
751 }
752 
753 static PyObject *
img_get_channel_by_tattoo(PyGimpImage * self,PyObject * args)754 img_get_channel_by_tattoo(PyGimpImage *self, PyObject *args)
755 {
756     int tattoo;
757 
758     if (!PyArg_ParseTuple(args, "i:get_channel_by_tattoo", &tattoo))
759 	return NULL;
760 
761     return pygimp_channel_new(gimp_image_get_channel_by_tattoo(self->ID,
762 							       tattoo));
763 }
764 
765 static PyObject *
img_add_hguide(PyGimpImage * self,PyObject * args)766 img_add_hguide(PyGimpImage *self, PyObject *args)
767 {
768     int ypos;
769 
770     if (!PyArg_ParseTuple(args, "i:add_hguide", &ypos))
771 	return NULL;
772 
773     return PyInt_FromLong(gimp_image_add_hguide(self->ID, ypos));
774 }
775 
776 static PyObject *
img_add_vguide(PyGimpImage * self,PyObject * args)777 img_add_vguide(PyGimpImage *self, PyObject *args)
778 {
779     int xpos;
780 
781     if (!PyArg_ParseTuple(args, "i:add_vguide", &xpos))
782 	return NULL;
783 
784     return PyInt_FromLong(gimp_image_add_vguide(self->ID, xpos));
785 }
786 
787 static PyObject *
img_delete_guide(PyGimpImage * self,PyObject * args)788 img_delete_guide(PyGimpImage *self, PyObject *args)
789 {
790     int guide;
791 
792     if (!PyArg_ParseTuple(args, "i:delete_guide", &guide))
793 	return NULL;
794 
795     if (!gimp_image_delete_guide(self->ID, guide)) {
796 	PyErr_Format(pygimp_error,
797 		     "could not delete guide (ID %d) from image (ID %d)",
798 		     guide, self->ID);
799 	return NULL;
800     }
801 
802     Py_INCREF(Py_None);
803     return Py_None;
804 }
805 
806 static PyObject *
img_find_next_guide(PyGimpImage * self,PyObject * args)807 img_find_next_guide(PyGimpImage *self, PyObject *args)
808 {
809     int guide;
810 
811     if (!PyArg_ParseTuple(args, "i:find_next_guide", &guide))
812 	return NULL;
813 
814     return PyInt_FromLong(gimp_image_find_next_guide(self->ID, guide));
815 }
816 
817 static PyObject *
img_get_guide_orientation(PyGimpImage * self,PyObject * args)818 img_get_guide_orientation(PyGimpImage *self, PyObject *args)
819 {
820     int guide;
821 
822     if (!PyArg_ParseTuple(args, "i:get_guide_orientation", &guide))
823 	return NULL;
824 
825     return PyInt_FromLong(gimp_image_get_guide_orientation(self->ID, guide));
826 }
827 
828 static PyObject *
img_get_guide_position(PyGimpImage * self,PyObject * args)829 img_get_guide_position(PyGimpImage *self, PyObject *args)
830 {
831     int guide;
832 
833     if (!PyArg_ParseTuple(args, "i:get_guide_position", &guide))
834 	return NULL;
835 
836     return PyInt_FromLong(gimp_image_get_guide_position(self->ID, guide));
837 }
838 
839 static PyObject *
img_undo_is_enabled(PyGimpImage * self)840 img_undo_is_enabled(PyGimpImage *self)
841 {
842     return PyBool_FromLong(gimp_image_undo_is_enabled(self->ID));
843 }
844 
845 static PyObject *
img_undo_freeze(PyGimpImage * self)846 img_undo_freeze(PyGimpImage *self)
847 {
848     return PyBool_FromLong(gimp_image_undo_freeze(self->ID));
849 }
850 
851 static PyObject *
img_undo_thaw(PyGimpImage * self)852 img_undo_thaw(PyGimpImage *self)
853 {
854     return PyBool_FromLong(gimp_image_undo_thaw(self->ID));
855 }
856 
857 static PyObject *
img_duplicate(PyGimpImage * self)858 img_duplicate(PyGimpImage *self)
859 {
860     return pygimp_image_new(gimp_image_duplicate(self->ID));
861 }
862 
863 static PyObject *
img_undo_group_start(PyGimpImage * self)864 img_undo_group_start(PyGimpImage *self)
865 {
866     if (!gimp_image_undo_group_start(self->ID)) {
867 	PyErr_Format(pygimp_error,
868 		     "could not start undo group on image (ID %d)",
869 		     self->ID);
870 	return NULL;
871     }
872 
873     Py_INCREF(Py_None);
874     return Py_None;
875 }
876 
877 static PyObject *
img_undo_group_end(PyGimpImage * self)878 img_undo_group_end(PyGimpImage *self)
879 {
880     if (!gimp_image_undo_group_end(self->ID)) {
881 	PyErr_Format(pygimp_error,
882 		     "could not end undo group on image (ID %d)",
883 		     self->ID);
884 	return NULL;
885     }
886 
887     Py_INCREF(Py_None);
888     return Py_None;
889 }
890 
891 static PyMethodDef img_methods[] = {
892     {"add_channel",	(PyCFunction)img_add_channel,	METH_VARARGS},
893     {"insert_channel",	(PyCFunction)img_insert_channel,	METH_VARARGS | METH_KEYWORDS},
894     {"add_layer",	(PyCFunction)img_add_layer,	METH_VARARGS},
895     {"insert_layer",	(PyCFunction)img_insert_layer,	METH_VARARGS | METH_KEYWORDS},
896     {"new_layer",       (PyCFunction)img_new_layer, METH_VARARGS | METH_KEYWORDS},
897     {"clean_all",	(PyCFunction)img_clean_all,	METH_NOARGS},
898     {"disable_undo",	(PyCFunction)img_disable_undo,	METH_NOARGS},
899     {"enable_undo",	(PyCFunction)img_enable_undo,	METH_NOARGS},
900     {"flatten",	(PyCFunction)img_flatten,	METH_NOARGS},
901     {"lower_channel",	(PyCFunction)img_lower_channel,	METH_VARARGS},
902     {"lower_layer",	(PyCFunction)img_lower_layer,	METH_VARARGS},
903     {"lower_layer_to_bottom",	(PyCFunction)img_lower_layer_to_bottom,	METH_VARARGS},
904     {"merge_visible_layers",	(PyCFunction)img_merge_visible_layers,	METH_VARARGS},
905     {"merge_down",	(PyCFunction)img_merge_down,	METH_VARARGS},
906     {"pick_correlate_layer",	(PyCFunction)img_pick_correlate_layer,	METH_VARARGS},
907     {"raise_channel",	(PyCFunction)img_raise_channel,	METH_VARARGS},
908     {"raise_layer",	(PyCFunction)img_raise_layer,	METH_VARARGS},
909     {"raise_layer_to_top",	(PyCFunction)img_raise_layer_to_top,	METH_VARARGS},
910     {"remove_channel",	(PyCFunction)img_remove_channel,	METH_VARARGS},
911     {"remove_layer",	(PyCFunction)img_remove_layer,	METH_VARARGS},
912     {"resize",	(PyCFunction)img_resize,	METH_VARARGS | METH_KEYWORDS},
913     {"resize_to_layers",	(PyCFunction)img_resize_to_layers,	METH_NOARGS},
914     {"get_component_active",	(PyCFunction)img_get_component_active,	METH_VARARGS},
915     {"get_component_visible",	(PyCFunction)img_get_component_visible,	METH_VARARGS},
916     {"set_component_active",	(PyCFunction)img_set_component_active,	METH_VARARGS},
917     {"set_component_visible",	(PyCFunction)img_set_component_visible,	METH_VARARGS},
918     {"parasite_find",       (PyCFunction)img_parasite_find,      METH_VARARGS},
919     {"parasite_attach",     (PyCFunction)img_parasite_attach,    METH_VARARGS},
920     {"attach_new_parasite", (PyCFunction)img_attach_new_parasite,	METH_VARARGS | METH_KEYWORDS},
921     {"parasite_detach",     (PyCFunction)img_parasite_detach,    METH_VARARGS},
922     {"parasite_list", (PyCFunction)img_parasite_list, METH_NOARGS},
923     {"get_layer_by_tattoo",(PyCFunction)img_get_layer_by_tattoo,METH_VARARGS},
924     {"get_channel_by_tattoo",(PyCFunction)img_get_channel_by_tattoo,METH_VARARGS},
925     {"add_hguide", (PyCFunction)img_add_hguide, METH_VARARGS},
926     {"add_vguide", (PyCFunction)img_add_vguide, METH_VARARGS},
927     {"delete_guide", (PyCFunction)img_delete_guide, METH_VARARGS},
928     {"find_next_guide", (PyCFunction)img_find_next_guide, METH_VARARGS},
929     {"get_guide_orientation",(PyCFunction)img_get_guide_orientation,METH_VARARGS},
930     {"get_guide_position", (PyCFunction)img_get_guide_position, METH_VARARGS},
931     {"scale", (PyCFunction)img_scale, METH_VARARGS | METH_KEYWORDS},
932     {"crop", (PyCFunction)img_crop, METH_VARARGS | METH_KEYWORDS},
933     {"free_shadow", (PyCFunction)img_free_shadow, METH_NOARGS},
934     {"unset_active_channel", (PyCFunction)img_unset_active_channel, METH_NOARGS},
935     {"undo_is_enabled", (PyCFunction)img_undo_is_enabled, METH_NOARGS},
936     {"undo_freeze", (PyCFunction)img_undo_freeze, METH_NOARGS},
937     {"undo_thaw", (PyCFunction)img_undo_thaw, METH_NOARGS},
938     {"duplicate", (PyCFunction)img_duplicate, METH_NOARGS},
939     {"undo_group_start", (PyCFunction)img_undo_group_start, METH_NOARGS},
940     {"undo_group_end", (PyCFunction)img_undo_group_end, METH_NOARGS},
941     {NULL,		NULL}		/* sentinel */
942 };
943 
944 static PyObject *
img_get_ID(PyGimpImage * self,void * closure)945 img_get_ID(PyGimpImage *self, void *closure)
946 {
947     return PyInt_FromLong(self->ID);
948 }
949 
950 static PyObject *
img_get_active_channel(PyGimpImage * self,void * closure)951 img_get_active_channel(PyGimpImage *self, void *closure)
952 {
953     gint32 id = gimp_image_get_active_channel(self->ID);
954 
955     if (id == -1) {
956 	Py_INCREF(Py_None);
957 	return Py_None;
958     }
959 
960     return pygimp_channel_new(id);
961 }
962 
963 static int
img_set_active_channel(PyGimpImage * self,PyObject * value,void * closure)964 img_set_active_channel(PyGimpImage *self, PyObject *value, void *closure)
965 {
966     PyGimpChannel *chn;
967 
968     if (value == NULL) {
969 	PyErr_SetString(PyExc_TypeError, "cannot delete active_channel");
970 	return -1;
971     }
972 
973     if (!pygimp_channel_check(value)) {
974 	PyErr_SetString(PyExc_TypeError, "type mismatch");
975 	return -1;
976     }
977 
978     chn = (PyGimpChannel *)value;
979 
980     if (!gimp_image_set_active_channel(self->ID, chn->ID)) {
981 	PyErr_Format(pygimp_error,
982 		     "could not set active channel (ID %d) on image (ID %d)",
983 		     chn->ID, self->ID);
984         return -1;
985     }
986 
987     return 0;
988 }
989 
990 static PyObject *
img_get_active_drawable(PyGimpImage * self,void * closure)991 img_get_active_drawable(PyGimpImage *self, void *closure)
992 {
993     gint32 id = gimp_image_get_active_drawable(self->ID);
994 
995     if (id == -1) {
996 	Py_INCREF(Py_None);
997 	return Py_None;
998     }
999 
1000     return pygimp_drawable_new(NULL, id);
1001 }
1002 
1003 static PyObject *
img_get_active_layer(PyGimpImage * self,void * closure)1004 img_get_active_layer(PyGimpImage *self, void *closure)
1005 {
1006     gint32 id = gimp_image_get_active_layer(self->ID);
1007 
1008     if (id == -1) {
1009 	Py_INCREF(Py_None);
1010 	return Py_None;
1011     }
1012 
1013     return pygimp_group_layer_new(id);
1014 }
1015 
1016 static int
img_set_active_layer(PyGimpImage * self,PyObject * value,void * closure)1017 img_set_active_layer(PyGimpImage *self, PyObject *value, void *closure)
1018 {
1019     PyGimpLayer *lay;
1020 
1021     if (value == NULL) {
1022 	PyErr_SetString(PyExc_TypeError, "cannot delete active_layer");
1023 	return -1;
1024     }
1025 
1026     if (!pygimp_layer_check(value)) {
1027 	PyErr_SetString(PyExc_TypeError, "type mismatch");
1028 	return -1;
1029     }
1030 
1031     lay = (PyGimpLayer *)value;
1032 
1033     if (!gimp_image_set_active_layer(self->ID, lay->ID)) {
1034 	PyErr_Format(pygimp_error,
1035 		     "could not set active layer (ID %d) on image (ID %d)",
1036 		     lay->ID, self->ID);
1037         return -1;
1038     }
1039 
1040     return 0;
1041 }
1042 
1043 static PyObject *
img_get_base_type(PyGimpImage * self,void * closure)1044 img_get_base_type(PyGimpImage *self, void *closure)
1045 {
1046     return PyInt_FromLong(gimp_image_base_type(self->ID));
1047 }
1048 
1049 static PyObject *
img_get_channels(PyGimpImage * self,void * closure)1050 img_get_channels(PyGimpImage *self, void *closure)
1051 {
1052     gint32 *channels;
1053     gint n_channels, i;
1054     PyObject *ret;
1055 
1056     channels = gimp_image_get_channels(self->ID, &n_channels);
1057 
1058     ret = PyList_New(n_channels);
1059 
1060     for (i = 0; i < n_channels; i++)
1061 	PyList_SetItem(ret, i, pygimp_channel_new(channels[i]));
1062 
1063     g_free(channels);
1064 
1065     return ret;
1066 }
1067 
1068 static PyObject *
img_get_colormap(PyGimpImage * self,void * closure)1069 img_get_colormap(PyGimpImage *self, void *closure)
1070 {
1071     guchar *cmap;
1072     gint n_colours;
1073     PyObject *ret;
1074 
1075     cmap = gimp_image_get_colormap(self->ID, &n_colours);
1076 
1077     if (cmap == NULL) {
1078 	PyErr_Format(pygimp_error, "could not get colormap for image (ID %d)",
1079 		     self->ID);
1080 	return NULL;
1081     }
1082 
1083     ret = PyString_FromStringAndSize((char *)cmap, n_colours * 3);
1084     g_free(cmap);
1085 
1086     return ret;
1087 }
1088 
1089 static int
img_set_colormap(PyGimpImage * self,PyObject * value,void * closure)1090 img_set_colormap(PyGimpImage *self, PyObject *value, void *closure)
1091 {
1092     if (value == NULL) {
1093 	PyErr_SetString(PyExc_TypeError, "cannot delete colormap");
1094 	return -1;
1095     }
1096 
1097     if (!PyString_Check(value)) {
1098 	PyErr_SetString(PyExc_TypeError, "type mismatch");
1099 	return -1;
1100     }
1101 
1102     if (!gimp_image_set_colormap(self->ID, (guchar *)PyString_AsString(value),
1103                                  PyString_Size(value) / 3)) {
1104 	PyErr_Format(pygimp_error, "could not set colormap on image (ID %d)",
1105 		     self->ID);
1106         return -1;
1107     }
1108 
1109     return 0;
1110 }
1111 
1112 static PyObject *
img_get_is_dirty(PyGimpImage * self,void * closure)1113 img_get_is_dirty(PyGimpImage *self, void *closure)
1114 {
1115     return PyBool_FromLong(gimp_image_is_dirty(self->ID));
1116 }
1117 
1118 static PyObject *
img_get_filename(PyGimpImage * self,void * closure)1119 img_get_filename(PyGimpImage *self, void *closure)
1120 {
1121     gchar *filename;
1122 
1123     filename = gimp_image_get_filename(self->ID);
1124 
1125     if (filename) {
1126 	PyObject *ret = PyString_FromString(filename);
1127 	g_free(filename);
1128 	return ret;
1129     }
1130 
1131     Py_INCREF(Py_None);
1132     return Py_None;
1133 }
1134 
1135 static int
img_set_filename(PyGimpImage * self,PyObject * value,void * closure)1136 img_set_filename(PyGimpImage *self, PyObject *value, void *closure)
1137 {
1138     if (value == NULL) {
1139 	PyErr_SetString(PyExc_TypeError, "cannot delete filename");
1140 	return -1;
1141     }
1142 
1143     if (!PyString_Check(value)) {
1144 	PyErr_SetString(PyExc_TypeError, "type mismatch");
1145 	return -1;
1146     }
1147 
1148     if (!gimp_image_set_filename(self->ID, PyString_AsString(value))) {
1149         PyErr_SetString(PyExc_TypeError, "could not set filename "
1150 	                                 "(possibly bad encoding)");
1151         return -1;
1152     }
1153 
1154     return 0;
1155 }
1156 
1157 static PyObject *
img_get_uri(PyGimpImage * self,void * closure)1158 img_get_uri(PyGimpImage *self, void *closure)
1159 {
1160     gchar *uri;
1161 
1162     uri = gimp_image_get_uri(self->ID);
1163 
1164     if (uri) {
1165 	PyObject *ret = PyString_FromString(uri);
1166 	g_free(uri);
1167 	return ret;
1168     }
1169 
1170     Py_INCREF(Py_None);
1171     return Py_None;
1172 }
1173 
1174 static PyObject *
img_get_floating_selection(PyGimpImage * self,void * closure)1175 img_get_floating_selection(PyGimpImage *self, void *closure)
1176 {
1177     gint32 id;
1178 
1179     id = gimp_image_get_floating_sel(self->ID);
1180 
1181     if (id == -1) {
1182 	Py_INCREF(Py_None);
1183 	return Py_None;
1184     }
1185 
1186     return pygimp_layer_new(id);
1187 }
1188 
1189 static PyObject *
img_get_floating_sel_attached_to(PyGimpImage * self,void * closure)1190 img_get_floating_sel_attached_to(PyGimpImage *self, void *closure)
1191 {
1192     gint32 id;
1193 
1194     id = gimp_image_floating_sel_attached_to(self->ID);
1195 
1196     if (id == -1) {
1197 	Py_INCREF(Py_None);
1198 	return Py_None;
1199     }
1200 
1201     return pygimp_layer_new(id);
1202 }
1203 
1204 static PyObject *
img_get_layers(PyGimpImage * self,void * closure)1205 img_get_layers(PyGimpImage *self, void *closure)
1206 {
1207     gint32 *layers;
1208     gint n_layers, i;
1209     PyObject *ret;
1210 
1211     layers = gimp_image_get_layers(self->ID, &n_layers);
1212 
1213     ret = PyList_New(n_layers);
1214 
1215     for (i = 0; i < n_layers; i++)
1216 	PyList_SetItem(ret, i, pygimp_group_layer_new(layers[i]));
1217 
1218     g_free(layers);
1219 
1220     return ret;
1221 }
1222 
1223 static PyObject *
img_get_name(PyGimpImage * self,void * closure)1224 img_get_name(PyGimpImage *self, void *closure)
1225 {
1226     gchar *name;
1227 
1228     name = gimp_image_get_name(self->ID);
1229 
1230     if (name) {
1231 	PyObject *ret = PyString_FromString(name);
1232 	g_free(name);
1233 	return ret;
1234     }
1235 
1236     Py_INCREF(Py_None);
1237     return Py_None;
1238 }
1239 
1240 static PyObject *
img_get_selection(PyGimpImage * self,void * closure)1241 img_get_selection(PyGimpImage *self, void *closure)
1242 {
1243     return pygimp_channel_new(gimp_image_get_selection(self->ID));
1244 }
1245 
1246 static PyObject *
img_get_tattoo_state(PyGimpImage * self,void * closure)1247 img_get_tattoo_state(PyGimpImage *self, void *closure)
1248 {
1249     return PyInt_FromLong(gimp_image_get_tattoo_state(self->ID));
1250 }
1251 
1252 static int
img_set_tattoo_state(PyGimpImage * self,PyObject * value,void * closure)1253 img_set_tattoo_state(PyGimpImage *self, PyObject *value, void *closure)
1254 {
1255     if (value == NULL) {
1256 	PyErr_SetString(PyExc_TypeError, "cannot delete tattoo_state");
1257 	return -1;
1258     }
1259 
1260     if (!PyInt_Check(value)) {
1261 	PyErr_SetString(PyExc_TypeError, "type mismatch");
1262 	return -1;
1263     }
1264 
1265     gimp_image_set_tattoo_state(self->ID, PyInt_AsLong(value));
1266 
1267     return 0;
1268 }
1269 
1270 static PyObject *
img_get_height(PyGimpImage * self,void * closure)1271 img_get_height(PyGimpImage *self, void *closure)
1272 {
1273     return PyInt_FromLong(gimp_image_height(self->ID));
1274 }
1275 
1276 static PyObject *
img_get_width(PyGimpImage * self,void * closure)1277 img_get_width(PyGimpImage *self, void *closure)
1278 {
1279     return PyInt_FromLong(gimp_image_width(self->ID));
1280 }
1281 
1282 
1283 static PyObject *
img_get_precision(PyGimpImage * self,void * closure)1284 img_get_precision(PyGimpImage *self, void *closure)
1285 {
1286     return PyInt_FromLong(gimp_image_get_precision(self->ID));
1287 }
1288 
1289 static PyObject *
img_get_resolution(PyGimpImage * self,void * closure)1290 img_get_resolution(PyGimpImage *self, void *closure)
1291 {
1292     double xres, yres;
1293 
1294     gimp_image_get_resolution(self->ID, &xres, &yres);
1295 
1296     return Py_BuildValue("(dd)", xres, yres);
1297 }
1298 
1299 static int
img_set_resolution(PyGimpImage * self,PyObject * value,void * closure)1300 img_set_resolution(PyGimpImage *self, PyObject *value, void *closure)
1301 {
1302     gdouble xres, yres;
1303 
1304     if (value == NULL) {
1305 	PyErr_SetString(PyExc_TypeError, "cannot delete resolution");
1306 	return -1;
1307     }
1308 
1309     if (!PySequence_Check(value) ||
1310 	!PyArg_ParseTuple(value, "dd", &xres, &yres)) {
1311 	PyErr_Clear();
1312 	PyErr_SetString(PyExc_TypeError, "type mismatch");
1313 	return -1;
1314     }
1315 
1316     if (!gimp_image_set_resolution(self->ID, xres, yres)) {
1317         PyErr_SetString(PyExc_TypeError, "could not set resolution");
1318         return -1;
1319     }
1320 
1321     return 0;
1322 }
1323 
1324 static PyObject *
img_get_unit(PyGimpImage * self,void * closure)1325 img_get_unit(PyGimpImage *self, void *closure)
1326 {
1327     return PyInt_FromLong(gimp_image_get_unit(self->ID));
1328 }
1329 
1330 static int
img_set_unit(PyGimpImage * self,PyObject * value,void * closure)1331 img_set_unit(PyGimpImage *self, PyObject *value, void *closure)
1332 {
1333     if (value == NULL) {
1334 	PyErr_SetString(PyExc_TypeError, "cannot delete unit");
1335 	return -1;
1336     }
1337 
1338     if (!PyInt_Check(value)) {
1339 	PyErr_SetString(PyExc_TypeError, "type mismatch");
1340 	return -1;
1341     }
1342 
1343     if (!gimp_image_set_unit(self->ID, PyInt_AsLong(value))) {
1344         PyErr_SetString(PyExc_TypeError, "could not set unit");
1345         return -1;
1346     }
1347 
1348     return 0;
1349 }
1350 
1351 static PyObject *
img_get_vectors(PyGimpImage * self,void * closure)1352 img_get_vectors(PyGimpImage *self, void *closure)
1353 {
1354     int *vectors;
1355     int i, num_vectors;
1356     PyObject *ret;
1357 
1358     vectors = gimp_image_get_vectors(self->ID, &num_vectors);
1359 
1360     ret = PyList_New(num_vectors);
1361 
1362     for (i = 0; i < num_vectors; i++)
1363         PyList_SetItem(ret, i, pygimp_vectors_new(vectors[i]));
1364 
1365     g_free(vectors);
1366 
1367     return ret;
1368 }
1369 
1370 static PyObject *
img_get_active_vectors(PyGimpImage * self,void * closure)1371 img_get_active_vectors(PyGimpImage *self, void *closure)
1372 {
1373     gint32 id = gimp_image_get_active_vectors(self->ID);
1374 
1375     if (id == -1) {
1376         Py_INCREF(Py_None);
1377         return Py_None;
1378     }
1379 
1380     return pygimp_vectors_new(id);
1381 }
1382 
1383 static int
img_set_active_vectors(PyGimpImage * self,PyObject * value,void * closure)1384 img_set_active_vectors(PyGimpImage *self, PyObject *value, void *closure)
1385 {
1386     PyGimpVectors *vtr;
1387 
1388     if (value == NULL) {
1389         PyErr_SetString(PyExc_TypeError, "cannot delete active_vectors");
1390         return -1;
1391     }
1392 
1393     if (!pygimp_vectors_check(value)) {
1394         PyErr_SetString(PyExc_TypeError, "type mismatch");
1395         return -1;
1396     }
1397 
1398     vtr = (PyGimpVectors *)value;
1399 
1400     if (!gimp_image_set_active_vectors(self->ID, vtr->ID)) {
1401         PyErr_Format(pygimp_error,
1402                      "could not set active vectors (ID %d) on image (ID %d)",
1403                      vtr->ID, self->ID);
1404         return -1;
1405     }
1406 
1407     return 0;
1408 }
1409 
1410 static PyGetSetDef img_getsets[] = {
1411     { "ID", (getter)img_get_ID, (setter)0 },
1412     { "active_channel", (getter)img_get_active_channel,
1413       (setter)img_set_active_channel },
1414     { "active_drawable", (getter)img_get_active_drawable, (setter)0 },
1415     { "active_layer", (getter)img_get_active_layer,
1416       (setter)img_set_active_layer },
1417     { "active_vectors", (getter)img_get_active_vectors,
1418       (setter)img_set_active_vectors},
1419     { "base_type", (getter)img_get_base_type, (setter)0 },
1420     { "channels", (getter)img_get_channels, (setter)0 },
1421     { "colormap", (getter)img_get_colormap, (setter)img_set_colormap },
1422     { "dirty", (getter)img_get_is_dirty, (setter)0 },
1423     { "filename", (getter)img_get_filename, (setter)img_set_filename },
1424     { "floating_selection", (getter)img_get_floating_selection, (setter)0 },
1425     { "floating_sel_attached_to", (getter)img_get_floating_sel_attached_to,
1426       (setter)0 },
1427     { "height", (getter)img_get_height, (setter)0 },
1428     { "layers", (getter)img_get_layers, (setter)0 },
1429     { "name", (getter)img_get_name, (setter)0 },
1430     { "precision", (getter)img_get_precision, (setter)0 },
1431     { "resolution", (getter)img_get_resolution, (setter)img_set_resolution },
1432     { "selection", (getter)img_get_selection, (setter)0 },
1433     { "tattoo_state", (getter)img_get_tattoo_state,
1434       (setter)img_set_tattoo_state },
1435     { "unit", (getter)img_get_unit, (setter)img_set_unit },
1436     { "uri", (getter)img_get_uri, (setter)0 },
1437     { "vectors", (getter)img_get_vectors, (setter)0 },
1438     { "width", (getter)img_get_width, (setter)0 },
1439     { NULL, (getter)0, (setter)0 }
1440 };
1441 
1442 /* ---------- */
1443 
1444 
1445 PyObject *
pygimp_image_new(gint32 ID)1446 pygimp_image_new(gint32 ID)
1447 {
1448     PyGimpImage *self;
1449 
1450     if (!gimp_image_is_valid(ID)) {
1451 	Py_INCREF(Py_None);
1452 	return Py_None;
1453     }
1454 
1455     self = PyObject_NEW(PyGimpImage, &PyGimpImage_Type);
1456 
1457     if (self == NULL)
1458 	return NULL;
1459 
1460     self->ID = ID;
1461 
1462     return (PyObject *)self;
1463 }
1464 
1465 
1466 static void
img_dealloc(PyGimpImage * self)1467 img_dealloc(PyGimpImage *self)
1468 {
1469     /* XXXX Add your own cleanup code here */
1470     PyObject_DEL(self);
1471 }
1472 
1473 static PyObject *
img_repr(PyGimpImage * self)1474 img_repr(PyGimpImage *self)
1475 {
1476     PyObject *s;
1477     gchar *name;
1478 
1479     name = gimp_image_get_name(self->ID);
1480     s = PyString_FromFormat("<gimp.Image '%s'>", name ? name : "(null)");
1481     g_free(name);
1482 
1483     return s;
1484 }
1485 
1486 static int
img_cmp(PyGimpImage * self,PyGimpImage * other)1487 img_cmp(PyGimpImage *self, PyGimpImage *other)
1488 {
1489     if (self->ID == other->ID)
1490         return 0;
1491 
1492     if (self->ID > other->ID)
1493         return -1;
1494 
1495     return 1;
1496 }
1497 
1498 static int
img_init(PyGimpImage * self,PyObject * args,PyObject * kwargs)1499 img_init(PyGimpImage *self, PyObject *args, PyObject *kwargs)
1500 {
1501     guint width, height;
1502     GimpImageBaseType type = GIMP_RGB;
1503 
1504     static char *kwlist[] = { "width", "height", "type", NULL };
1505 
1506     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1507 				     "ii|i:gimp.Image.__init__", kwlist,
1508 				     &width, &height, &type))
1509         return -1;
1510 
1511     self->ID = gimp_image_new(width, height, type);
1512 
1513     if (self->ID < 0) {
1514 	PyErr_Format(pygimp_error,
1515 		     "could not create image (width: %d, height: %d, type: %d)",
1516 		     width, height, type);
1517 	return -1;
1518     }
1519 
1520     return 0;
1521 }
1522 
1523 PyTypeObject PyGimpImage_Type = {
1524     PyObject_HEAD_INIT(NULL)
1525     0,                                  /* ob_size */
1526     "gimp.Image",                       /* tp_name */
1527     sizeof(PyGimpImage),                /* tp_basicsize */
1528     0,                                  /* tp_itemsize */
1529     /* methods */
1530     (destructor)img_dealloc,            /* tp_dealloc */
1531     (printfunc)0,                       /* tp_print */
1532     (getattrfunc)0,                     /* tp_getattr */
1533     (setattrfunc)0,                     /* tp_setattr */
1534     (cmpfunc)img_cmp,                   /* tp_compare */
1535     (reprfunc)img_repr,                 /* tp_repr */
1536     0,                                  /* tp_as_number */
1537     0,                                  /* tp_as_sequence */
1538     0,                                  /* tp_as_mapping */
1539     (hashfunc)0,                        /* tp_hash */
1540     (ternaryfunc)0,                     /* tp_call */
1541     (reprfunc)0,                        /* tp_str */
1542     (getattrofunc)0,                    /* tp_getattro */
1543     (setattrofunc)0,                    /* tp_setattro */
1544     0,					/* tp_as_buffer */
1545     Py_TPFLAGS_DEFAULT,	                /* tp_flags */
1546     NULL, /* Documentation string */
1547     (traverseproc)0,			/* tp_traverse */
1548     (inquiry)0,				/* tp_clear */
1549     (richcmpfunc)0,			/* tp_richcompare */
1550     0,					/* tp_weaklistoffset */
1551     (getiterfunc)0,			/* tp_iter */
1552     (iternextfunc)0,			/* tp_iternext */
1553     img_methods,			/* tp_methods */
1554     0,					/* tp_members */
1555     img_getsets,			/* tp_getset */
1556     (PyTypeObject *)0,			/* tp_base */
1557     (PyObject *)0,			/* tp_dict */
1558     0,					/* tp_descr_get */
1559     0,					/* tp_descr_set */
1560     0,					/* tp_dictoffset */
1561     (initproc)img_init,                 /* tp_init */
1562     (allocfunc)0,			/* tp_alloc */
1563     (newfunc)0,				/* tp_new */
1564 };
1565