drawable-cmds.c 92.7 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/gimpchannel-select.h"
33
#include "core/gimpdrawable-foreground-extract.h"
34
#include "core/gimpdrawable-offset.h"
35
#include "core/gimpdrawable-preview.h"
36
#include "core/gimpdrawable-shadow.h"
37
38
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
39
#include "core/gimpparamspecs.h"
40
#include "core/gimptempbuf.h"
41
#include "gegl/gimp-babl-compat.h"
42
#include "gegl/gimp-babl.h"
43
#include "plug-in/gimpplugin-cleanup.h"
44
#include "plug-in/gimpplugin.h"
45
#include "plug-in/gimppluginmanager.h"
46

47
48
#include "gimppdb.h"
#include "gimppdb-utils.h"
49
#include "gimppdbcontext.h"
50
#include "gimpprocedure.h"
51
#include "internal-procs.h"
52

53
54
#include "gimp-intl.h"

55

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

69
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
70
71
72

  if (success)
    {
73
74
75
      if (gimp->plug_in_manager->current_plug_in)
        gimp_plug_in_enable_precision (gimp->plug_in_manager->current_plug_in);

76
77
78
79
80
81
82
      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)
83
    g_value_take_string (gimp_value_array_index (return_vals, 1), format);
84
85
86
87

  return return_vals;
}

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

101
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
102

103
104
  if (success)
    {
105
      type = gimp_babl_format_get_image_type (gimp_drawable_get_format (drawable));
106
    }
107

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

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

114
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
115
116
}

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

130
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
131

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

      type_with_alpha = gimp_babl_format_get_image_type (format);
137
138
    }

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

  if (success)
143
    g_value_set_enum (gimp_value_array_index (return_vals, 1), type_with_alpha);
144

145
  return return_vals;
146
147
}

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

161
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
162

163
164
165
166
167
  if (success)
    {
      has_alpha = gimp_drawable_has_alpha (drawable);
    }

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

  if (success)
172
    g_value_set_boolean (gimp_value_array_index (return_vals, 1), has_alpha);
173

174
  return return_vals;
175
176
}

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

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

192
193
194
195
196
  if (success)
    {
      is_rgb = gimp_drawable_is_rgb (drawable);
    }

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

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

203
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
204
205
}

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

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

221
222
223
224
225
  if (success)
    {
      is_gray = gimp_drawable_is_gray (drawable);
    }

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

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

232
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
233
234
}

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

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

250
251
252
253
254
  if (success)
    {
      is_indexed = gimp_drawable_is_indexed (drawable);
    }

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

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

261
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
262
263
}

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

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

279
280
  if (success)
    {
281
282
283
284
285
      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))
        {
286
          format = gimp_babl_compat_u8_format (format);
287
288
289
        }

      bpp = babl_format_get_bytes_per_pixel (format);
290
291
    }

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

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

298
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
299
300
}

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

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

316
317
  if (success)
    {
318
      width = gimp_item_get_width (GIMP_ITEM (drawable));
319
320
    }

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

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

327
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
328
329
}

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

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

345
346
  if (success)
    {
347
      height = gimp_item_get_height (GIMP_ITEM (drawable));
348
349
    }

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

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

356
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
357
358
}

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

373
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
374
375
376

  if (success)
    {
377
      gimp_item_get_offset (GIMP_ITEM (drawable), &offset_x, &offset_y);
378
379
    }

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

  if (success)
384
    {
385
386
      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);
387
    }
388
389
390
391

  return return_vals;
}

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

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

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

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

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

434
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
435

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

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

  if (success)
448
    {
449
450
451
452
453
      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);
454
    }
455

456
  return return_vals;
457
458
}

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

476
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
477
478

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

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

490
491
  if (success)
    {
492
493
494
495
496
      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);
497
498
499
500
    }

  return return_vals;
}
501

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

514
515
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  undo = g_value_get_boolean (gimp_value_array_index (args, 1));
516

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

525
          if (gimp->plug_in_manager->current_plug_in)
526
            undo_desc = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in);
527

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

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

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

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

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

557
      gimp_drawable_free_shadow_buffer (drawable);
558
559
    }

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

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

579
580
581
582
583
  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));
584
585

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

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

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

610
611
612
  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));
613

614
615
  if (success)
    {
616
617
618
619
620
      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))
        {
621
          format = gimp_babl_compat_u8_format (format);
622
623
        }

624
625
      if (x_coord < gimp_item_get_width  (GIMP_ITEM (drawable)) &&
          y_coord < gimp_item_get_height (GIMP_ITEM (drawable)))
626
        {
627
628
629
          num_channels = babl_format_get_bytes_per_pixel (format);
          pixel = g_new0 (guint8, num_channels);

630
          gegl_buffer_sample (gimp_drawable_get_buffer (drawable),
631
                              x_coord, y_coord, NULL, pixel, format,
632
                              GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
633
634
635
        }
      else
        success = FALSE;
636
637
    }

638
639
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
640
641

  if (success)
642
    {
643
644
      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);
645
    }
646

647
  return return_vals;
648
649
}

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

665
666
667
668
669
  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));
670
671

  if (success)
672
    {
673
674
675
676
677
      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))
        {
678
          format = gimp_babl_compat_u8_format (format);
679
680
        }

681
682
      if (gimp_pdb_item_is_modifyable (GIMP_ITEM (drawable),
                                       GIMP_PDB_ITEM_CONTENT, error) &&
683
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
684
          x_coord < gimp_item_get_width  (GIMP_ITEM (drawable)) &&
685
          y_coord < gimp_item_get_height (GIMP_ITEM (drawable)) &&
686
          num_channels == babl_format_get_bytes_per_pixel (format))
687
        {
688
          gegl_buffer_set (gimp_drawable_get_buffer (drawable),
689
                           GEGL_RECTANGLE (x_coord, y_coord, 1, 1),
690
                           0, format, pixel, GEGL_AUTO_ROWSTRIDE);
691
692
693
        }
      else
        success = FALSE;
694
    }
695

696
697
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
698
699
}

700
static GimpValueArray *
701
drawable_fill_invoker (GimpProcedure         *procedure,
702
703
704
705
706
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
707
708
709
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
710
  gint32 fill_type;
711

712
713
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  fill_type = g_value_get_enum (gimp_value_array_index (args, 1));
714

715
716
  if (success)
    {
717
718
      if (gimp_pdb_item_is_modifyable (GIMP_ITEM (drawable),
                                       GIMP_PDB_ITEM_CONTENT, error) &&
719
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
720
721
722
        {
          gimp_drawable_fill (drawable, context, (GimpFillType) fill_type);
        }
723
724
      else
        success = FALSE;
725
726
    }

727
728
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
729
730
}

731
static GimpValueArray *
732
drawable_offset_invoker (GimpProcedure         *procedure,
733
734
735
736
737
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
738
739
740
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
741
742
743
744
  gboolean wrap_around;
  gint32 fill_type;
  gint32 offset_x;
  gint32 offset_y;
745

746
747
748
749
750
  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));
751
752

  if (success)
753
    {
754
755
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
756
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
757
758
759
760
        gimp_drawable_offset (drawable, context, wrap_around, fill_type,
                              offset_x, offset_y);
      else
        success = FALSE;
761
    }
762

763
764
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
765
766
}

767
static GimpValueArray *
768
drawable_thumbnail_invoker (GimpProcedure         *procedure,
769
770
771
772
773
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
774
775
{
  gboolean success = TRUE;
776
  GimpValueArray *return_vals;
777
  GimpDrawable *drawable;
778
779
780
781
782
783
784
  gint32 width;
  gint32 height;
  gint32 actual_width = 0;
  gint32 actual_height = 0;
  gint32 bpp = 0;
  gint32 thumbnail_data_count = 0;
  guint8 *thumbnail_data = NULL;
785

786
787
788
  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));
789
790

  if (success)
791
    {
792
793
794
      GimpImage   *image = gimp_item_get_image (GIMP_ITEM (drawable));
      GimpTempBuf *buf;
      gint         dwidth, dheight;
795

796
797
      g_assert (GIMP_VIEWABLE_MAX_PREVIEW_SIZE >= 1024);

798
      /* Adjust the width/height ratio */
799
800
      dwidth  = gimp_item_get_width  (GIMP_ITEM (drawable));
      dheight = gimp_item_get_height (GIMP_ITEM (drawable));
801
802
803
804
805
806
807

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

      if (image->gimp->config->layer_previews)
808
809
        buf = gimp_viewable_get_new_preview (GIMP_VIEWABLE (drawable), context,
                                             width, height);
810
      else
811
812
813
        buf = gimp_viewable_get_dummy_preview (GIMP_VIEWABLE (drawable),
                                               width, height,
                                               gimp_drawable_get_preview_format (drawable));
814
815
816

      if (buf)
        {
817
818
819
          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));
820
821
          thumbnail_data_count = gimp_temp_buf_get_data_size (buf);
          thumbnail_data       = g_memdup (gimp_temp_buf_get_data (buf),
822
823
                                           thumbnail_data_count);

824
          gimp_temp_buf_unref (buf);
825
826
827
        }
      else
        success = FALSE;
828
    }
829

830
831
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
832
833
834

  if (success)
    {
835
836
837
838
839
      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);
840
841
    }

842
  return return_vals;
843
844
}

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

868
869
870
871
872
873