drawable-cmds.c 90.9 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2
 * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
Elliot Lee's avatar
Elliot Lee committed
3
 *
4
 * This program is free software: you can redistribute it and/or modify
Elliot Lee's avatar
Elliot Lee committed
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
Elliot Lee's avatar
Elliot Lee committed
7
8
9
10
11
12
13
14
 * (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
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Elliot Lee's avatar
Elliot Lee committed
16
 */
17

18
/* NOTE: This file is auto-generated by pdbgen.pl. */
Elliot Lee's avatar
Elliot Lee committed
19

20
#include "config.h"
Elliot Lee's avatar
Elliot Lee committed
21

22
#include <gegl.h>
23

24
25
#include <gdk-pixbuf/gdk-pixbuf.h>

26
27
#include "libgimpbase/gimpbase.h"

28
#include "pdb-types.h"
29

30
#include "config/gimpcoreconfig.h"
Michael Natterer's avatar
Michael Natterer committed
31
#include "core/gimp.h"
32
#include "core/gimpdrawable-foreground-extract.h"
33
#include "core/gimpdrawable-offset.h"
34
#include "core/gimpdrawable-preview.h"
35
#include "core/gimpdrawable-shadow.h"
36
37
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
38
#include "core/gimpparamspecs.h"
39
#include "core/gimptempbuf.h"
40
#include "gegl/gimp-babl-compat.h"
41
#include "gegl/gimp-babl.h"
42
#include "plug-in/gimpplugin-cleanup.h"
43
#include "plug-in/gimpplugin.h"
44
#include "plug-in/gimppluginmanager.h"
45

46
47
48
#include "gimppdb.h"
#include "gimppdb-utils.h"
#include "gimpprocedure.h"
49
#include "internal-procs.h"
50

51
52
#include "gimp-intl.h"

53

54
static GimpValueArray *
55
drawable_get_format_invoker (GimpProcedure         *procedure,
56
57
58
59
60
                             Gimp                  *gimp,
                             GimpContext           *context,
                             GimpProgress          *progress,
                             const GimpValueArray  *args,
                             GError               **error)
61
62
{
  gboolean success = TRUE;
63
  GimpValueArray *return_vals;
64
65
66
  GimpDrawable *drawable;
  gchar *format = NULL;

67
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
68
69
70

  if (success)
    {
71
72
73
      if (gimp->plug_in_manager->current_plug_in)
        gimp_plug_in_enable_precision (gimp->plug_in_manager->current_plug_in);

74
75
76
77
78
79
80
      format = g_strdup (babl_get_name (gimp_drawable_get_format (drawable)));
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
81
    g_value_take_string (gimp_value_array_index (return_vals, 1), format);
82
83
84
85

  return return_vals;
}

86
static GimpValueArray *
87
drawable_type_invoker (GimpProcedure         *procedure,
88
89
90
91
92
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
93
94
{
  gboolean success = TRUE;
95
  GimpValueArray *return_vals;
96
97
  GimpDrawable *drawable;
  gint32 type = 0;
98

99
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
100

101
102
  if (success)
    {
103
      type = gimp_babl_format_get_image_type (gimp_drawable_get_format (drawable));
104
    }
105

106
107
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
Manish Singh's avatar
Manish Singh committed
108
109

  if (success)
110
    g_value_set_enum (gimp_value_array_index (return_vals, 1), type);
Elliot Lee's avatar
Elliot Lee committed
111

112
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
113
114
}

115
static GimpValueArray *
116
drawable_type_with_alpha_invoker (GimpProcedure         *procedure,
117
118
119
120
121
                                  Gimp                  *gimp,
                                  GimpContext           *context,
                                  GimpProgress          *progress,
                                  const GimpValueArray  *args,
                                  GError               **error)
122
123
{
  gboolean success = TRUE;
124
  GimpValueArray *return_vals;
125
  GimpDrawable *drawable;
126
  gint32 type_with_alpha = 0;
127

128
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
129

130
131
  if (success)
    {
132
133
134
      const Babl *format = gimp_drawable_get_format_with_alpha (drawable);

      type_with_alpha = gimp_babl_format_get_image_type (format);
135
136
    }

137
138
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
139
140

  if (success)
141
    g_value_set_enum (gimp_value_array_index (return_vals, 1), type_with_alpha);
142

143
  return return_vals;
144
145
}

146
static GimpValueArray *
147
drawable_has_alpha_invoker (GimpProcedure         *procedure,
148
149
150
151
152
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
153
154
{
  gboolean success = TRUE;
155
  GimpValueArray *return_vals;
156
  GimpDrawable *drawable;
157
  gboolean has_alpha = FALSE;
158

159
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
160

161
162
163
164
165
  if (success)
    {
      has_alpha = gimp_drawable_has_alpha (drawable);
    }

166
167
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
168
169

  if (success)
170
    g_value_set_boolean (gimp_value_array_index (return_vals, 1), has_alpha);
171

172
  return return_vals;
173
174
}

175
static GimpValueArray *
176
drawable_is_rgb_invoker (GimpProcedure         *procedure,
177
178
179
180
181
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
Elliot Lee's avatar
Elliot Lee committed
182
{
Manish Singh's avatar
Manish Singh committed
183
  gboolean success = TRUE;
184
  GimpValueArray *return_vals;
185
  GimpDrawable *drawable;
186
  gboolean is_rgb = FALSE;
Elliot Lee's avatar
Elliot Lee committed
187

188
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
Elliot Lee's avatar
Elliot Lee committed
189

190
191
192
193
194
  if (success)
    {
      is_rgb = gimp_drawable_is_rgb (drawable);
    }

195
196
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
Manish Singh's avatar
Manish Singh committed
197
198

  if (success)
199
    g_value_set_boolean (gimp_value_array_index (return_vals, 1), is_rgb);
Elliot Lee's avatar
Elliot Lee committed
200

201
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
202
203
}

204
static GimpValueArray *
205
drawable_is_gray_invoker (GimpProcedure         *procedure,
206
207
208
209
210
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
Elliot Lee's avatar
Elliot Lee committed
211
{
Manish Singh's avatar
Manish Singh committed
212
  gboolean success = TRUE;
213
  GimpValueArray *return_vals;
214
  GimpDrawable *drawable;
215
  gboolean is_gray = FALSE;
Elliot Lee's avatar
Elliot Lee committed
216

217
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
Elliot Lee's avatar
Elliot Lee committed
218

219
220
221
222
223
  if (success)
    {
      is_gray = gimp_drawable_is_gray (drawable);
    }

224
225
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
Manish Singh's avatar
Manish Singh committed
226
227

  if (success)
228
    g_value_set_boolean (gimp_value_array_index (return_vals, 1), is_gray);
Elliot Lee's avatar
Elliot Lee committed
229

230
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
231
232
}

233
static GimpValueArray *
234
drawable_is_indexed_invoker (GimpProcedure         *procedure,
235
236
237
238
239
                             Gimp                  *gimp,
                             GimpContext           *context,
                             GimpProgress          *progress,
                             const GimpValueArray  *args,
                             GError               **error)
Elliot Lee's avatar
Elliot Lee committed
240
{
Manish Singh's avatar
Manish Singh committed
241
  gboolean success = TRUE;
242
  GimpValueArray *return_vals;
243
  GimpDrawable *drawable;
244
  gboolean is_indexed = FALSE;
Elliot Lee's avatar
Elliot Lee committed
245

246
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
Manish Singh's avatar
Manish Singh committed
247

248
249
250
251
252
  if (success)
    {
      is_indexed = gimp_drawable_is_indexed (drawable);
    }

253
254
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
Elliot Lee's avatar
Elliot Lee committed
255

Manish Singh's avatar
Manish Singh committed
256
  if (success)
257
    g_value_set_boolean (gimp_value_array_index (return_vals, 1), is_indexed);
Elliot Lee's avatar
Elliot Lee committed
258

259
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
260
261
}

262
static GimpValueArray *
263
drawable_bpp_invoker (GimpProcedure         *procedure,
264
265
266
267
268
                      Gimp                  *gimp,
                      GimpContext           *context,
                      GimpProgress          *progress,
                      const GimpValueArray  *args,
                      GError               **error)
Elliot Lee's avatar
Elliot Lee committed
269
{
Manish Singh's avatar
Manish Singh committed
270
  gboolean success = TRUE;
271
  GimpValueArray *return_vals;
272
  GimpDrawable *drawable;
273
  gint32 bpp = 0;
Elliot Lee's avatar
Elliot Lee committed
274

275
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
Elliot Lee's avatar
Elliot Lee committed
276

277
278
  if (success)
    {
279
280
281
282
283
      const Babl *format = gimp_drawable_get_format (drawable);

      if (! gimp->plug_in_manager->current_plug_in ||
          ! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
        {
284
          format = gimp_babl_compat_u8_format (format);
285
286
287
        }

      bpp = babl_format_get_bytes_per_pixel (format);
288
289
    }

290
291
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
Manish Singh's avatar
Manish Singh committed
292
293

  if (success)
294
    g_value_set_int (gimp_value_array_index (return_vals, 1), bpp);
Elliot Lee's avatar
Elliot Lee committed
295

296
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
297
298
}

299
static GimpValueArray *
300
drawable_width_invoker (GimpProcedure         *procedure,
301
302
303
304
305
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
Elliot Lee's avatar
Elliot Lee committed
306
{
Manish Singh's avatar
Manish Singh committed
307
  gboolean success = TRUE;
308
  GimpValueArray *return_vals;
309
  GimpDrawable *drawable;
310
  gint32 width = 0;
Elliot Lee's avatar
Elliot Lee committed
311

312
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
Elliot Lee's avatar
Elliot Lee committed
313

314
315
  if (success)
    {
316
      width = gimp_item_get_width (GIMP_ITEM (drawable));
317
318
    }

319
320
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
Manish Singh's avatar
Manish Singh committed
321
322

  if (success)
323
    g_value_set_int (gimp_value_array_index (return_vals, 1), width);
Elliot Lee's avatar
Elliot Lee committed
324

325
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
326
327
}

328
static GimpValueArray *
329
drawable_height_invoker (GimpProcedure         *procedure,
330
331
332
333
334
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
Elliot Lee's avatar
Elliot Lee committed
335
{
Manish Singh's avatar
Manish Singh committed
336
  gboolean success = TRUE;
337
  GimpValueArray *return_vals;
338
  GimpDrawable *drawable;
339
  gint32 height = 0;
Elliot Lee's avatar
Elliot Lee committed
340

341
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
Manish Singh's avatar
Manish Singh committed
342

343
344
  if (success)
    {
345
      height = gimp_item_get_height (GIMP_ITEM (drawable));
346
347
    }

348
349
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
Elliot Lee's avatar
Elliot Lee committed
350

Manish Singh's avatar
Manish Singh committed
351
  if (success)
352
    g_value_set_int (gimp_value_array_index (return_vals, 1), height);
Elliot Lee's avatar
Elliot Lee committed
353

354
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
355
356
}

357
static GimpValueArray *
358
drawable_offsets_invoker (GimpProcedure         *procedure,
359
360
361
362
363
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
364
365
{
  gboolean success = TRUE;
366
  GimpValueArray *return_vals;
367
  GimpDrawable *drawable;
368
369
  gint32 offset_x = 0;
  gint32 offset_y = 0;
370

371
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
372
373
374

  if (success)
    {
375
      gimp_item_get_offset (GIMP_ITEM (drawable), &offset_x, &offset_y);
376
377
    }

378
379
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
380
381

  if (success)
382
    {
383
384
      g_value_set_int (gimp_value_array_index (return_vals, 1), offset_x);
      g_value_set_int (gimp_value_array_index (return_vals, 2), offset_y);
385
    }
386
387
388
389

  return return_vals;
}

390
static GimpValueArray *
391
drawable_set_image_invoker (GimpProcedure         *procedure,
392
393
394
395
396
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
397
398
399
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
400
  GimpImage *image;
401

402
403
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
404
405
406

  if (success)
    {
407
408
      if (image != gimp_item_get_image (GIMP_ITEM (drawable)))
        success = FALSE;
409
410
    }

411
412
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
413
414
}

415
static GimpValueArray *
416
drawable_mask_bounds_invoker (GimpProcedure         *procedure,
417
418
419
420
421
                              Gimp                  *gimp,
                              GimpContext           *context,
                              GimpProgress          *progress,
                              const GimpValueArray  *args,
                              GError               **error)
422
423
{
  gboolean success = TRUE;
424
  GimpValueArray *return_vals;
425
  GimpDrawable *drawable;
426
427
428
429
430
  gboolean non_empty = FALSE;
  gint32 x1 = 0;
  gint32 y1 = 0;
  gint32 x2 = 0;
  gint32 y2 = 0;
431

432
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
433

434
435
  if (success)
    {
436
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error))
437
        non_empty = gimp_item_mask_bounds (GIMP_ITEM (drawable), &x1, &y1, &x2, &y2);
438
439
      else
        success = FALSE;
440
441
    }

442
443
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
444
445

  if (success)
446
    {
447
448
449
450
451
      g_value_set_boolean (gimp_value_array_index (return_vals, 1), non_empty);
      g_value_set_int (gimp_value_array_index (return_vals, 2), x1);
      g_value_set_int (gimp_value_array_index (return_vals, 3), y1);
      g_value_set_int (gimp_value_array_index (return_vals, 4), x2);
      g_value_set_int (gimp_value_array_index (return_vals, 5), y2);
452
    }
453

454
  return return_vals;
455
456
}

457
static GimpValueArray *
458
drawable_mask_intersect_invoker (GimpProcedure         *procedure,
459
460
461
462
463
                                 Gimp                  *gimp,
                                 GimpContext           *context,
                                 GimpProgress          *progress,
                                 const GimpValueArray  *args,
                                 GError               **error)
464
465
{
  gboolean success = TRUE;
466
  GimpValueArray *return_vals;
467
  GimpDrawable *drawable;
468
469
470
471
472
  gboolean non_empty = FALSE;
  gint32 x = 0;
  gint32 y = 0;
  gint32 width = 0;
  gint32 height = 0;
473

474
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
475
476

  if (success)
477
    {
478
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error))
479
480
        non_empty = gimp_item_mask_intersect (GIMP_ITEM (drawable),
                                              &x, &y, &width, &height);
481
482
      else
        success = FALSE;
483
    }
484

485
486
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
487

488
489
  if (success)
    {
490
491
492
493
494
      g_value_set_boolean (gimp_value_array_index (return_vals, 1), non_empty);
      g_value_set_int (gimp_value_array_index (return_vals, 2), x);
      g_value_set_int (gimp_value_array_index (return_vals, 3), y);
      g_value_set_int (gimp_value_array_index (return_vals, 4), width);
      g_value_set_int (gimp_value_array_index (return_vals, 5), height);
495
496
497
498
    }

  return return_vals;
}
499

500
static GimpValueArray *
501
drawable_merge_shadow_invoker (GimpProcedure         *procedure,
502
503
504
505
506
                               Gimp                  *gimp,
                               GimpContext           *context,
                               GimpProgress          *progress,
                               const GimpValueArray  *args,
                               GError               **error)
507
508
509
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
510
  gboolean undo;
511

512
513
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  undo = g_value_get_boolean (gimp_value_array_index (args, 1));
514

515
516
  if (success)
    {
517
518
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
519
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
520
        {
521
          const gchar *undo_desc = _("Plug-In");
522

523
          if (gimp->plug_in_manager->current_plug_in)
524
            undo_desc = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in);
525

526
          gimp_drawable_merge_shadow_buffer (drawable, undo, undo_desc);
527
528
529
530
531
        }
      else
        success = FALSE;
    }

532
533
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
534
}
535

536
static GimpValueArray *
537
drawable_free_shadow_invoker (GimpProcedure         *procedure,
538
539
540
541
542
                              Gimp                  *gimp,
                              GimpContext           *context,
                              GimpProgress          *progress,
                              const GimpValueArray  *args,
                              GError               **error)
543
544
545
546
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

547
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
548
549
550
551
552
553
554

  if (success)
    {
      if (gimp->plug_in_manager->current_plug_in)
        gimp_plug_in_cleanup_remove_shadow (gimp->plug_in_manager->current_plug_in,
                                            drawable);

555
      gimp_drawable_free_shadow_buffer (drawable);
556
557
    }

558
559
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
560
561
}

562
static GimpValueArray *
563
drawable_update_invoker (GimpProcedure         *procedure,
564
565
566
567
568
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
569
570
571
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
572
573
574
575
  gint32 x;
  gint32 y;
  gint32 width;
  gint32 height;
576

577
578
579
580
581
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  x = g_value_get_int (gimp_value_array_index (args, 1));
  y = g_value_get_int (gimp_value_array_index (args, 2));
  width = g_value_get_int (gimp_value_array_index (args, 3));
  height = g_value_get_int (gimp_value_array_index (args, 4));
582
583

  if (success)
584
    {
585
      gimp_drawable_update (drawable, x, y, width, height);
586
    }
587

588
589
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
590
591
}

592
static GimpValueArray *
593
drawable_get_pixel_invoker (GimpProcedure         *procedure,
594
595
596
597
598
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
599
600
{
  gboolean success = TRUE;
601
  GimpValueArray *return_vals;
602
  GimpDrawable *drawable;
603
604
605
606
  gint32 x_coord;
  gint32 y_coord;
  gint32 num_channels = 0;
  guint8 *pixel = NULL;
607

608
609
610
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  x_coord = g_value_get_int (gimp_value_array_index (args, 1));
  y_coord = g_value_get_int (gimp_value_array_index (args, 2));
611

612
613
  if (success)
    {
614
615
616
617
618
      const Babl *format = gimp_drawable_get_format (drawable);

      if (! gimp->plug_in_manager->current_plug_in ||
          ! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
        {
619
          format = gimp_babl_compat_u8_format (format);
620
621
        }

622
623
      if (x_coord < gimp_item_get_width  (GIMP_ITEM (drawable)) &&
          y_coord < gimp_item_get_height (GIMP_ITEM (drawable)))
624
        {
625
          gegl_buffer_sample (gimp_drawable_get_buffer (drawable),
626
                              x_coord, y_coord, NULL, pixel, format,
627
                              GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
628
629
630
        }
      else
        success = FALSE;
631
632
    }

633
634
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
635
636

  if (success)
637
    {
638
639
      g_value_set_int (gimp_value_array_index (return_vals, 1), num_channels);
      gimp_value_take_int8array (gimp_value_array_index (return_vals, 2), pixel, num_channels);
640
    }
641

642
  return return_vals;
643
644
}

645
static GimpValueArray *
646
drawable_set_pixel_invoker (GimpProcedure         *procedure,
647
648
649
650
651
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
652
653
654
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
655
656
657
658
  gint32 x_coord;
  gint32 y_coord;
  gint32 num_channels;
  const guint8 *pixel;
659

660
661
662
663
664
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  x_coord = g_value_get_int (gimp_value_array_index (args, 1));
  y_coord = g_value_get_int (gimp_value_array_index (args, 2));
  num_channels = g_value_get_int (gimp_value_array_index (args, 3));
  pixel = gimp_value_get_int8array (gimp_value_array_index (args, 4));
665
666

  if (success)
667
    {
668
669
670
671
672
      const Babl *format = gimp_drawable_get_format (drawable);

      if (! gimp->plug_in_manager->current_plug_in ||
          ! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
        {
673
          format = gimp_babl_compat_u8_format (format);
674
675
        }

676
677
      if (gimp_pdb_item_is_modifyable (GIMP_ITEM (drawable),
                                       GIMP_PDB_ITEM_CONTENT, error) &&
678
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
679
          x_coord < gimp_item_get_width  (GIMP_ITEM (drawable)) &&
680
          y_coord < gimp_item_get_height (GIMP_ITEM (drawable)) &&
681
          num_channels == babl_format_get_bytes_per_pixel (format))
682
        {
683
          gegl_buffer_set (gimp_drawable_get_buffer (drawable),
684
                           GEGL_RECTANGLE (x_coord, y_coord, 1, 1),
685
                           1.0, format, pixel, GEGL_AUTO_ROWSTRIDE);
686
687
688
        }
      else
        success = FALSE;
689
    }
690

691
692
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
693
694
}

695
static GimpValueArray *
696
drawable_fill_invoker (GimpProcedure         *procedure,
697
698
699
700
701
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
702
703
704
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
705
  gint32 fill_type;
706

707
708
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  fill_type = g_value_get_enum (gimp_value_array_index (args, 1));
709

710
711
  if (success)
    {
712
713
      if (gimp_pdb_item_is_modifyable (GIMP_ITEM (drawable),
                                       GIMP_PDB_ITEM_CONTENT, error) &&
714
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
715
716
717
        gimp_drawable_fill_by_type (drawable, context, (GimpFillType) fill_type);
      else
        success = FALSE;
718
719
    }

720
721
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
722
723
}

724
static GimpValueArray *
725
drawable_offset_invoker (GimpProcedure         *procedure,
726
727
728
729
730
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
731
732
733
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
734
735
736
737
  gboolean wrap_around;
  gint32 fill_type;
  gint32 offset_x;
  gint32 offset_y;
738

739
740
741
742
743
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  wrap_around = g_value_get_boolean (gimp_value_array_index (args, 1));
  fill_type = g_value_get_enum (gimp_value_array_index (args, 2));
  offset_x = g_value_get_int (gimp_value_array_index (args, 3));
  offset_y = g_value_get_int (gimp_value_array_index (args, 4));
744
745

  if (success)
746
    {
747
748
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
749
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
750
751
752
753
        gimp_drawable_offset (drawable, context, wrap_around, fill_type,
                              offset_x, offset_y);
      else
        success = FALSE;
754
    }
755

756
757
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
758
759
}

760
static GimpValueArray *
761
drawable_thumbnail_invoker (GimpProcedure         *procedure,
762
763
764
765
766
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
767
768
{
  gboolean success = TRUE;
769
  GimpValueArray *return_vals;
770
  GimpDrawable *drawable;
771
772
773
774
775
776
777
  gint32 width;
  gint32 height;
  gint32 actual_width = 0;
  gint32 actual_height = 0;
  gint32 bpp = 0;
  gint32 thumbnail_data_count = 0;
  guint8 *thumbnail_data = NULL;
778

779
780
781
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  width = g_value_get_int (gimp_value_array_index (args, 1));
  height = g_value_get_int (gimp_value_array_index (args, 2));
782
783

  if (success)
784
    {
785
786
787
      GimpImage   *image = gimp_item_get_image (GIMP_ITEM (drawable));
      GimpTempBuf *buf;
      gint         dwidth, dheight;
788

789
790
      g_assert (GIMP_VIEWABLE_MAX_PREVIEW_SIZE >= 1024);

791
      /* Adjust the width/height ratio */
792
793
      dwidth  = gimp_item_get_width  (GIMP_ITEM (drawable));
      dheight = gimp_item_get_height (GIMP_ITEM (drawable));
794
795
796
797
798
799
800

      if (dwidth > dheight)
        height = MAX (1, (width * dheight) / dwidth);
      else
        width  = MAX (1, (height * dwidth) / dheight);

      if (image->gimp->config->layer_previews)
801
802
        buf = gimp_viewable_get_new_preview (GIMP_VIEWABLE (drawable), context,
                                             width, height);
803
      else
804
805
806
        buf = gimp_viewable_get_dummy_preview (GIMP_VIEWABLE (drawable),
                                               width, height,
                                               gimp_drawable_get_preview_format (drawable));
807
808
809

      if (buf)
        {
810
811
812
          actual_width         = gimp_temp_buf_get_width  (buf);
          actual_height        = gimp_temp_buf_get_height (buf);
          bpp                  = babl_format_get_bytes_per_pixel (gimp_temp_buf_get_format (buf));
813
814
          thumbnail_data_count = gimp_temp_buf_get_data_size (buf);
          thumbnail_data       = g_memdup (gimp_temp_buf_get_data (buf),
815
816
                                           thumbnail_data_count);

817
          gimp_temp_buf_unref (buf);
818
819
820
        }
      else
        success = FALSE;
821
    }
822

823
824
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
825
826
827

  if (success)
    {
828
829
830
831
832
      g_value_set_int (gimp_value_array_index (return_vals, 1), actual_width);
      g_value_set_int (gimp_value_array_index (return_vals, 2), actual_height);
      g_value_set_int (gimp_value_array_index (return_vals, 3), bpp);
      g_value_set_int (gimp_value_array_index (return_vals, 4), thumbnail_data_count);
      gimp_value_take_int8array (gimp_value_array_index (return_vals, 5), thumbnail_data, thumbnail_data_count);
833
834
    }

835
  return return_vals;
836
837
}

838
static GimpValueArray *
839
drawable_sub_thumbnail_invoker (GimpProcedure         *procedure,
840
841
842
843
844
                                Gimp                  *gimp,
                                GimpContext           *context,
                                GimpProgress          *progress,
                                const GimpValueArray  *args,
                                GError               **error)
845
846
{
  gboolean success = TRUE;
847
  GimpValueArray *return_vals;
848
  GimpDrawable *drawable;
849
850
851
852
853
854
  gint32 src_x;
  gint32 src_y;
  gint32 src_width;
  gint32 src_height;
  gint32 dest_width;
  gint32 dest_height;
855
856
  gint32 width = 0;
  gint32 height = 0;
857
858
859
  gint32 bpp = 0;
  gint32 thumbnail_data_count = 0;
  guint8 *thumbnail_data = NULL;
860

861
862
863
864
865
866
867
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  src_x = g_value_get_int (gimp_value_array_index (args, 1));
  src_y = g_value_get_int (gimp_value_array_index (args, 2));
  src_width = g_value_get_int (gimp_value_array_index (args, 3));
  src_height = g_value_get_int (gimp_value_array_index (args, 4));
  dest_width = g_value_get_int (gimp_value_array_index (args, 5));
  dest_height = g_value_get_int (gimp_value_array_index (args, 6));
868
869

  if (success)
870
    {
871
872
      if ((src_x + src_width)  <= gimp_item_get_width  (GIMP_ITEM (drawable)) &&
          (src_y + src_height) <= gimp_item_get_height (GIMP_ITEM (drawable)))