~ubuntu-branches/ubuntu/hoary/gimp/hoary

« back to all changes in this revision

Viewing changes to plug-ins/common/csource.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-04-04 14:51:23 UTC
  • Revision ID: james.westby@ubuntu.com-20050404145123-9py049eeelfymur8
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* CSource - GIMP Plugin to dump image data in RGB(A) format for C source
 
2
 * Copyright (C) 1999 Tim Janik
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Library General Public
 
15
 * License along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
17
 *
 
18
 * This plugin is heavily based on the header plugin by Spencer Kimball and
 
19
 * Peter Mattis.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <stdio.h>
 
27
 
 
28
#include <gtk/gtk.h>
 
29
 
 
30
#include <libgimp/gimp.h>
 
31
#include <libgimp/gimpui.h>
 
32
 
 
33
#include "libgimp/stdplugins-intl.h"
 
34
 
 
35
 
 
36
typedef struct
 
37
{
 
38
  gchar    *file_name;
 
39
  gchar    *prefixed_name;
 
40
  gchar    *comment;
 
41
  gboolean  use_comment;
 
42
  gboolean  glib_types;
 
43
  gboolean  alpha;
 
44
  gboolean  use_macros;
 
45
  gboolean  use_rle;
 
46
  gdouble   opacity;
 
47
} Config;
 
48
 
 
49
 
 
50
/* --- prototypes --- */
 
51
static void     query           (void);
 
52
static void     run             (const gchar      *name,
 
53
                                 gint              nparams,
 
54
                                 const GimpParam  *param,
 
55
                                 gint             *nreturn_vals,
 
56
                                 GimpParam       **return_vals);
 
57
 
 
58
static gint     save_image      (Config           *config,
 
59
                                 gint32            image_ID,
 
60
                                 gint32            drawable_ID);
 
61
static gboolean run_save_dialog (Config           *config);
 
62
 
 
63
 
 
64
/* --- variables --- */
 
65
GimpPlugInInfo PLUG_IN_INFO =
 
66
{
 
67
  NULL,  /* init_proc  */
 
68
  NULL,  /* quit_proc  */
 
69
  query, /* query_proc */
 
70
  run,   /* run_proc   */
 
71
};
 
72
 
 
73
Config config =
 
74
{
 
75
  NULL,         /* file_name */
 
76
  "gimp_image", /* prefixed_name */
 
77
  NULL,         /* comment */
 
78
  FALSE,        /* use_comment */
 
79
  TRUE,         /* glib_types */
 
80
  FALSE,        /* alpha */
 
81
  FALSE,        /* use_macros */
 
82
  FALSE,        /* use_rle */
 
83
  100.0,        /* opacity */
 
84
};
 
85
 
 
86
/* --- implement main (), provided by libgimp --- */
 
87
MAIN ()
 
88
 
 
89
/* --- functions --- */
 
90
static void
 
91
query (void)
 
92
{
 
93
  static GimpParamDef save_args[] =
 
94
  {
 
95
    { GIMP_PDB_INT32, "run_mode", "Interactive" },
 
96
    { GIMP_PDB_IMAGE, "image", "Input image" },
 
97
    { GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" },
 
98
    { GIMP_PDB_STRING, "filename", "The name of the file to save the image in" },
 
99
    { GIMP_PDB_STRING, "raw_filename", "The name of the file to save the image in" }
 
100
  };
 
101
 
 
102
  gimp_install_procedure ("file_csource_save",
 
103
                          "Dump image data in RGB(A) format for C source",
 
104
                          "CSource cannot be run non-interactively.",
 
105
                          "Tim Janik",
 
106
                          "Tim Janik",
 
107
                          "1999",
 
108
                          N_("C source code"),
 
109
                          "RGB*",
 
110
                          GIMP_PLUGIN,
 
111
                          G_N_ELEMENTS (save_args), 0,
 
112
                          save_args, NULL);
 
113
 
 
114
  gimp_register_file_handler_mime ("file_csource_save", "text/x-csrc");
 
115
  gimp_register_save_handler ("file_csource_save", "c", "");
 
116
}
 
117
 
 
118
static void
 
119
run (const gchar      *name,
 
120
     gint              nparams,
 
121
     const GimpParam  *param,
 
122
     gint             *nreturn_vals,
 
123
     GimpParam       **return_vals)
 
124
{
 
125
  static GimpParam  values[2];
 
126
  GimpRunMode       run_mode;
 
127
  GimpPDBStatusType status = GIMP_PDB_SUCCESS;
 
128
  GimpExportReturn  export = GIMP_EXPORT_CANCEL;
 
129
 
 
130
  run_mode = param[0].data.d_int32;
 
131
 
 
132
  *nreturn_vals = 1;
 
133
  *return_vals  = values;
 
134
 
 
135
  INIT_I18N ();
 
136
 
 
137
  values[0].type          = GIMP_PDB_STATUS;
 
138
  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
 
139
 
 
140
  if (run_mode == GIMP_RUN_INTERACTIVE &&
 
141
      strcmp (name, "file_csource_save") == 0)
 
142
    {
 
143
      gint32         image_ID    = param[1].data.d_int32;
 
144
      gint32         drawable_ID = param[2].data.d_int32;
 
145
      GimpParasite  *parasite;
 
146
      gchar         *x;
 
147
      GimpImageType  drawable_type = gimp_drawable_type (drawable_ID);
 
148
 
 
149
      gimp_get_data ("file_csource_save", &config);
 
150
      config.prefixed_name = "gimp_image";
 
151
      config.comment       = NULL;
 
152
 
 
153
      config.file_name = param[3].data.d_string;
 
154
      config.alpha = (drawable_type == GIMP_RGBA_IMAGE ||
 
155
                      drawable_type == GIMP_GRAYA_IMAGE ||
 
156
                      drawable_type == GIMP_INDEXEDA_IMAGE);
 
157
 
 
158
      parasite = gimp_image_parasite_find (image_ID, "gimp-comment");
 
159
      if (parasite)
 
160
        {
 
161
          config.comment = g_strndup (gimp_parasite_data (parasite),
 
162
                                      gimp_parasite_data_size (parasite));
 
163
          gimp_parasite_free (parasite);
 
164
        }
 
165
      x = config.comment;
 
166
 
 
167
      gimp_ui_init ("csource", FALSE);
 
168
      export = gimp_export_image (&image_ID, &drawable_ID, "C Source",
 
169
                                  (GIMP_EXPORT_CAN_HANDLE_RGB |
 
170
                                   GIMP_EXPORT_CAN_HANDLE_ALPHA ));
 
171
      if (export == GIMP_EXPORT_CANCEL)
 
172
        {
 
173
          values[0].data.d_status = GIMP_PDB_CANCEL;
 
174
          return;
 
175
        }
 
176
 
 
177
      if (run_save_dialog (&config))
 
178
        {
 
179
          if (x != config.comment &&
 
180
              !(x && config.comment && strcmp (x, config.comment) == 0))
 
181
            {
 
182
              if (!config.comment || !config.comment[0])
 
183
                gimp_image_parasite_detach (image_ID, "gimp-comment");
 
184
              else
 
185
                {
 
186
                  parasite = gimp_parasite_new ("gimp-comment",
 
187
                                                GIMP_PARASITE_PERSISTENT,
 
188
                                                strlen (config.comment) + 1,
 
189
                                                config.comment);
 
190
                  gimp_image_parasite_attach (image_ID, parasite);
 
191
                  gimp_parasite_free (parasite);
 
192
                }
 
193
            }
 
194
 
 
195
          if (! save_image (&config, image_ID, drawable_ID))
 
196
            {
 
197
              status = GIMP_PDB_EXECUTION_ERROR;
 
198
            }
 
199
          else
 
200
            {
 
201
              gimp_set_data ("file_csource_save", &config, sizeof (config));
 
202
            }
 
203
        }
 
204
      else
 
205
        {
 
206
          status = GIMP_PDB_CANCEL;
 
207
        }
 
208
 
 
209
      if (export == GIMP_EXPORT_EXPORT)
 
210
        gimp_image_delete (image_ID);
 
211
    }
 
212
  else
 
213
    {
 
214
      status = GIMP_PDB_CALLING_ERROR;
 
215
    }
 
216
 
 
217
  values[0].data.d_status = status;
 
218
}
 
219
 
 
220
static gboolean
 
221
diff2_rgb (guint8 *ip)
 
222
{
 
223
  return ip[0] != ip[3] || ip[1] != ip[4] || ip[2] != ip[5];
 
224
}
 
225
 
 
226
static gboolean
 
227
diff2_rgba (guint8 *ip)
 
228
{
 
229
  return ip[0] != ip[4] || ip[1] != ip[5] || ip[2] != ip[6] || ip[3] != ip[7];
 
230
}
 
231
 
 
232
static guint8 *
 
233
rl_encode_rgbx (guint8 *bp,
 
234
                guint8 *ip,
 
235
                guint8 *limit,
 
236
                guint   n_ch)
 
237
{
 
238
  gboolean (*diff2_pix) (guint8 *) = n_ch > 3 ? diff2_rgba : diff2_rgb;
 
239
  guint8 *ilimit = limit - n_ch;
 
240
 
 
241
  while (ip < limit)
 
242
    {
 
243
      g_assert (ip < ilimit); /* paranoid */
 
244
 
 
245
      if (diff2_pix (ip))
 
246
        {
 
247
          guint8 *s_ip = ip;
 
248
          guint l = 1;
 
249
 
 
250
          ip += n_ch;
 
251
          while (l < 127 && ip < ilimit && diff2_pix (ip))
 
252
            { ip += n_ch; l += 1; }
 
253
          if (ip == ilimit && l < 127)
 
254
            { ip += n_ch; l += 1; }
 
255
          *(bp++) = l;
 
256
          memcpy (bp, s_ip, l * n_ch);
 
257
          bp += l * n_ch;
 
258
        }
 
259
      else
 
260
        {
 
261
          guint l = 2;
 
262
 
 
263
          ip += n_ch;
 
264
          while (l < 127 && ip < ilimit && !diff2_pix (ip))
 
265
            { ip += n_ch; l += 1; }
 
266
          *(bp++) = l | 128;
 
267
          memcpy (bp, ip, n_ch);
 
268
          ip += n_ch;
 
269
          bp += n_ch;
 
270
        }
 
271
      if (ip == ilimit)
 
272
        {
 
273
          *(bp++) = 1;
 
274
          memcpy (bp, ip, n_ch);
 
275
          ip += n_ch;
 
276
          bp += n_ch;
 
277
        }
 
278
    }
 
279
 
 
280
  return bp;
 
281
}
 
282
 
 
283
static inline void
 
284
save_rle_decoder (FILE        *fp,
 
285
                  const gchar *macro_name,
 
286
                  const gchar *s_uint,
 
287
                  const gchar *s_uint_8,
 
288
                  guint        n_ch)
 
289
{
 
290
  fprintf (fp, "#define %s_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do \\\n",
 
291
           macro_name);
 
292
  fprintf (fp, "{ %s __bpp; %s *__ip; const %s *__il, *__rd; \\\n", s_uint, s_uint_8, s_uint_8);
 
293
  fprintf (fp, "  __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp; \\\n");
 
294
 
 
295
  fprintf (fp, "  __rd = (rle_data); if (__bpp > 3) { /* RGBA */ \\\n");
 
296
 
 
297
  fprintf (fp, "    while (__ip < __il) { %s __l = *(__rd++); \\\n", s_uint);
 
298
  fprintf (fp, "      if (__l & 128) { __l = __l - 128; \\\n");
 
299
  fprintf (fp, "        do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4; \\\n");
 
300
  fprintf (fp, "      } else { __l *= 4; memcpy (__ip, __rd, __l); \\\n");
 
301
  fprintf (fp, "               __ip += __l; __rd += __l; } } \\\n");
 
302
 
 
303
  fprintf (fp, "  } else { /* RGB */ \\\n");
 
304
 
 
305
  fprintf (fp, "    while (__ip < __il) { %s __l = *(__rd++); \\\n", s_uint);
 
306
  fprintf (fp, "      if (__l & 128) { __l = __l - 128; \\\n");
 
307
  fprintf (fp, "        do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3; \\\n");
 
308
  fprintf (fp, "      } else { __l *= 3; memcpy (__ip, __rd, __l); \\\n");
 
309
  fprintf (fp, "               __ip += __l; __rd += __l; } } \\\n");
 
310
 
 
311
  fprintf (fp, "  } } while (0)\n");
 
312
}
 
313
 
 
314
static inline guint
 
315
save_uchar (FILE   *fp,
 
316
            guint   c,
 
317
            guint8  d,
 
318
            Config *config)
 
319
{
 
320
  static guint8 pad = 0;
 
321
 
 
322
  if (c > 74)
 
323
    {
 
324
      if (!config->use_macros)
 
325
        {
 
326
          fprintf (fp, "\"\n  \"");
 
327
          c = 3;
 
328
        }
 
329
      else
 
330
        {
 
331
          fprintf (fp, "\"\n \"");
 
332
          c = 2;
 
333
        }
 
334
    }
 
335
  if (d < 33 || d > 126)
 
336
    {
 
337
      fprintf (fp, "\\%o", d);
 
338
      c += 1 + 1 + (d > 7) + (d > 63);
 
339
      pad = d < 64;
 
340
 
 
341
      return c;
 
342
    }
 
343
 
 
344
  if (d == '\\')
 
345
    {
 
346
      fputs ("\\\\", fp);
 
347
      c += 2;
 
348
    }
 
349
  else if (d == '"')
 
350
    {
 
351
      fputs ("\\\"", fp);
 
352
      c += 2;
 
353
    }
 
354
  else if (pad && d >= '0' && d <= '9')
 
355
    {
 
356
      fputs ("\"\"", fp);
 
357
      fputc (d, fp);
 
358
      c += 3;
 
359
    }
 
360
  else
 
361
    {
 
362
      fputc (d, fp);
 
363
      c += 1;
 
364
    }
 
365
  pad = 0;
 
366
 
 
367
  return c;
 
368
}
 
369
 
 
370
static gint
 
371
save_image (Config *config,
 
372
            gint32  image_ID,
 
373
            gint32  drawable_ID)
 
374
{
 
375
  GimpDrawable *drawable      = gimp_drawable_get (drawable_ID);
 
376
  GimpImageType drawable_type = gimp_drawable_type (drawable_ID);
 
377
  GimpPixelRgn pixel_rgn;
 
378
  gchar *s_uint_8, *s_uint_32, *s_uint, *s_char, *s_null;
 
379
  FILE *fp;
 
380
  guint c;
 
381
  gchar *macro_name;
 
382
  guint8 *img_buffer, *img_buffer_end;
 
383
  gchar *basename;
 
384
 
 
385
  fp = fopen (config->file_name, "w");
 
386
  if (!fp)
 
387
    return FALSE;
 
388
 
 
389
  gimp_pixel_rgn_init (&pixel_rgn, drawable,
 
390
                       0, 0, drawable->width, drawable->height, FALSE, FALSE);
 
391
 
 
392
  if (1)
 
393
    {
 
394
      guint8 *data, *p;
 
395
      gint x, y, pad, n_bytes, bpp;
 
396
 
 
397
      bpp = config->alpha ? 4 : 3;
 
398
      n_bytes = drawable->width * drawable->height * bpp;
 
399
      pad = drawable->width * drawable->bpp;
 
400
      if (config->use_rle)
 
401
        pad = MAX (pad, 130 + n_bytes / 127);
 
402
      data = g_new (guint8, pad + n_bytes);
 
403
      p = data + pad;
 
404
      for (y = 0; y < drawable->height; y++)
 
405
        {
 
406
          gimp_pixel_rgn_get_row (&pixel_rgn, data, 0, y, drawable->width);
 
407
          if (config->alpha)
 
408
            for (x = 0; x < drawable->width; x++)
 
409
              {
 
410
                guint8 *d = data + x * drawable->bpp;
 
411
                gdouble alpha = drawable_type == GIMP_RGBA_IMAGE ? d[3] : 0xff;
 
412
 
 
413
                alpha *= config->opacity / 100.0;
 
414
                *(p++) = d[0];
 
415
                *(p++) = d[1];
 
416
                *(p++) = d[2];
 
417
                *(p++) = alpha + 0.5;
 
418
              }
 
419
          else
 
420
            for (x = 0; x < drawable->width; x++)
 
421
              {
 
422
                guint8 *d = data + x * drawable->bpp;
 
423
                gdouble alpha = drawable_type == GIMP_RGBA_IMAGE ? d[3] : 0xff;
 
424
 
 
425
                alpha *= config->opacity / 25600.0;
 
426
                *(p++) = 0.5 + alpha * (gdouble) d[0];
 
427
                *(p++) = 0.5 + alpha * (gdouble) d[1];
 
428
                *(p++) = 0.5 + alpha * (gdouble) d[2];
 
429
              }
 
430
        }
 
431
      img_buffer = data + pad;
 
432
      if (config->use_rle)
 
433
        {
 
434
          img_buffer_end = rl_encode_rgbx (data, img_buffer,
 
435
                                           img_buffer + n_bytes, bpp);
 
436
          img_buffer = data;
 
437
        }
 
438
      else
 
439
        img_buffer_end = img_buffer + n_bytes;
 
440
    }
 
441
 
 
442
  if (!config->use_macros && config->glib_types)
 
443
    {
 
444
      s_uint_8 =  "guint8 ";
 
445
      s_uint_32 = "guint32";
 
446
      s_uint  =   "guint  ";
 
447
      s_char =    "gchar  ";
 
448
      s_null =    "NULL";
 
449
    }
 
450
  else if (!config->use_macros)
 
451
    {
 
452
      s_uint_8 =  "unsigned char";
 
453
      s_uint_32 = "unsigned int ";
 
454
      s_uint =    "unsigned int ";
 
455
      s_char =    "char         ";
 
456
      s_null =    "(char*) 0";
 
457
    }
 
458
  else if (config->use_macros && config->glib_types)
 
459
    {
 
460
      s_uint_8 =  "guint8";
 
461
      s_uint_32 = "guint32";
 
462
      s_uint  =   "guint";
 
463
      s_char =    "gchar";
 
464
      s_null =    "NULL";
 
465
    }
 
466
  else /* config->use_macros && !config->glib_types */
 
467
    {
 
468
      s_uint_8 =  "unsigned char";
 
469
      s_uint_32 = "unsigned int";
 
470
      s_uint =    "unsigned int";
 
471
      s_char =    "char";
 
472
      s_null =    "(char*) 0";
 
473
    }
 
474
 
 
475
  macro_name = g_ascii_strup (config->prefixed_name, -1);
 
476
 
 
477
  basename = g_path_get_basename (config->file_name);
 
478
 
 
479
  fprintf (fp, "/* GIMP %s C-Source image dump %s(%s) */\n\n",
 
480
           config->alpha ? "RGBA" : "RGB",
 
481
           config->use_rle ? "1-byte-run-length-encoded " : "",
 
482
           basename);
 
483
 
 
484
  g_free (basename);
 
485
 
 
486
  if (config->use_rle && !config->use_macros)
 
487
    save_rle_decoder (fp,
 
488
                      macro_name,
 
489
                      config->glib_types ? "guint" : "unsigned int",
 
490
                      config->glib_types ? "guint8" : "unsigned char",
 
491
                      config->alpha ? 4 : 3);
 
492
 
 
493
  if (!config->use_macros)
 
494
    {
 
495
      fprintf (fp, "static const struct {\n");
 
496
      fprintf (fp, "  %s\t width;\n", s_uint);
 
497
      fprintf (fp, "  %s\t height;\n", s_uint);
 
498
      fprintf (fp, "  %s\t bytes_per_pixel; /* 3:RGB, 4:RGBA */ \n", s_uint);
 
499
      if (config->use_comment)
 
500
        fprintf (fp, "  %s\t*comment;\n", s_char);
 
501
      fprintf (fp, "  %s\t %spixel_data[",
 
502
               s_uint_8,
 
503
               config->use_rle ? "rle_" : "");
 
504
      if (config->use_rle)
 
505
        fprintf (fp, "%u + 1];\n", (guint) (img_buffer_end - img_buffer));
 
506
      else
 
507
        fprintf (fp, "%u * %u * %u + 1];\n",
 
508
                 drawable->width,
 
509
                 drawable->height,
 
510
                 config->alpha ? 4 : 3);
 
511
      fprintf (fp, "} %s = {\n", config->prefixed_name);
 
512
      fprintf (fp, "  %u, %u, %u,\n",
 
513
               drawable->width,
 
514
               drawable->height,
 
515
               config->alpha ? 4 : 3);
 
516
    }
 
517
  else /* use macros */
 
518
    {
 
519
      fprintf (fp, "#define %s_WIDTH (%u)\n",
 
520
               macro_name, drawable->width);
 
521
      fprintf (fp, "#define %s_HEIGHT (%u)\n",
 
522
               macro_name, drawable->height);
 
523
      fprintf (fp, "#define %s_BYTES_PER_PIXEL (%u) /* 3:RGB, 4:RGBA */\n",
 
524
               macro_name, config->alpha ? 4 : 3);
 
525
    }
 
526
  if (config->use_comment && !config->comment)
 
527
    {
 
528
      if (!config->use_macros)
 
529
        fprintf (fp, "  %s,\n", s_null);
 
530
      else /* use macros */
 
531
        fprintf (fp, "#define %s_COMMENT (%s)\n", macro_name, s_null);
 
532
    }
 
533
  else if (config->use_comment)
 
534
    {
 
535
      gchar *p = config->comment - 1;
 
536
 
 
537
      if (config->use_macros)
 
538
        fprintf (fp, "#define %s_COMMENT \\\n", macro_name);
 
539
      fprintf (fp, "  \"");
 
540
      while (*(++p))
 
541
        if (*p == '\\')
 
542
          fprintf (fp, "\\\\");
 
543
        else if (*p == '"')
 
544
          fprintf (fp, "\\\"");
 
545
        else if (*p == '\n' && p[1])
 
546
          fprintf (fp, "\\n\"%s\n  \"",
 
547
                   config->use_macros ? " \\" : "");
 
548
        else if (*p == '\n')
 
549
          fprintf (fp, "\\n");
 
550
        else if (*p == '\r')
 
551
          fprintf (fp, "\\r");
 
552
        else if (*p == '\b')
 
553
          fprintf (fp, "\\b");
 
554
        else if (*p == '\f')
 
555
          fprintf (fp, "\\f");
 
556
        else if (*p >= 32 && *p <= 126)
 
557
          fprintf (fp, "%c", *p);
 
558
        else
 
559
          fprintf (fp, "\\%03o", *p);
 
560
      if (!config->use_macros)
 
561
        fprintf (fp, "\",\n");
 
562
      else /* use macros */
 
563
        fprintf (fp, "\"\n");
 
564
    }
 
565
  if (config->use_macros)
 
566
    {
 
567
      fprintf (fp, "#define %s_%sPIXEL_DATA ((%s*) %s_%spixel_data)\n",
 
568
               macro_name,
 
569
               config->use_rle ? "RLE_" : "",
 
570
               s_uint_8,
 
571
               macro_name,
 
572
               config->use_rle ? "rle_" : "");
 
573
      if (config->use_rle)
 
574
        save_rle_decoder (fp,
 
575
                          macro_name,
 
576
                          s_uint,
 
577
                          s_uint_8,
 
578
                          config->alpha ? 4 : 3);
 
579
      fprintf (fp, "static const %s %s_%spixel_data[",
 
580
               s_uint_8,
 
581
               macro_name,
 
582
               config->use_rle ? "rle_" : "");
 
583
      if (config->use_rle)
 
584
        fprintf (fp, "%u] =\n", (guint) (img_buffer_end - img_buffer));
 
585
      else
 
586
        fprintf (fp, "%u * %u * %u + 1] =\n",
 
587
                 drawable->width,
 
588
                 drawable->height,
 
589
                 config->alpha ? 4 : 3);
 
590
      fprintf (fp, "(\"");
 
591
      c = 2;
 
592
    }
 
593
  else
 
594
    {
 
595
      fprintf (fp, "  \"");
 
596
      c = 3;
 
597
    }
 
598
  switch (drawable_type)
 
599
    {
 
600
    case GIMP_RGB_IMAGE:
 
601
    case GIMP_RGBA_IMAGE:
 
602
      do
 
603
        c = save_uchar (fp, c, *(img_buffer++), config);
 
604
      while (img_buffer < img_buffer_end);
 
605
      break;
 
606
    default:
 
607
      g_warning ("unhandled drawable type (%d)", drawable_type);
 
608
      return FALSE;
 
609
    }
 
610
  if (!config->use_macros)
 
611
    fprintf (fp, "\",\n};\n\n");
 
612
  else /* use macros */
 
613
    fprintf (fp, "\");\n\n");
 
614
 
 
615
  fclose (fp);
 
616
 
 
617
  gimp_drawable_detach (drawable);
 
618
 
 
619
  return TRUE;
 
620
}
 
621
 
 
622
static GtkWidget *prefixed_name;
 
623
static GtkWidget *centry;
 
624
 
 
625
static gboolean
 
626
run_save_dialog (Config *config)
 
627
{
 
628
  GtkWidget *dialog;
 
629
  GtkWidget *vbox;
 
630
  GtkWidget *table;
 
631
  GtkWidget *toggle;
 
632
  GtkObject *adj;
 
633
  gboolean   run;
 
634
 
 
635
  dialog = gimp_dialog_new (_("Save as C-Source"), "csource",
 
636
                            NULL, 0,
 
637
                            gimp_standard_help_func, "file-csource-save",
 
638
 
 
639
                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
640
                            GTK_STOCK_OK,     GTK_RESPONSE_OK,
 
641
 
 
642
                            NULL);
 
643
 
 
644
  vbox = gtk_vbox_new (FALSE, 12);
 
645
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
 
646
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
 
647
  gtk_widget_show (vbox);
 
648
 
 
649
  table = gtk_table_new (2, 2, FALSE);
 
650
  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
 
651
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
 
652
  gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
 
653
  gtk_widget_show (table);
 
654
 
 
655
  /* Prefixed Name
 
656
   */
 
657
  prefixed_name = gtk_entry_new ();
 
658
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
 
659
                             _("_Prefixed name:"), 0.0, 0.5,
 
660
                             prefixed_name, 1, FALSE);
 
661
  gtk_entry_set_text (GTK_ENTRY (prefixed_name),
 
662
                      config->prefixed_name ? config->prefixed_name : "");
 
663
 
 
664
  /* Comment Entry
 
665
   */
 
666
  centry = gtk_entry_new ();
 
667
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
 
668
                             _("Co_mment:"), 0.0, 0.5,
 
669
                             centry, 1, FALSE);
 
670
  gtk_entry_set_text (GTK_ENTRY (centry),
 
671
                      config->comment ? config->comment : "");
 
672
 
 
673
  /* Use Comment
 
674
   */
 
675
  toggle = gtk_check_button_new_with_mnemonic (_("_Save comment to file"));
 
676
  gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
 
677
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
 
678
                                config->use_comment);
 
679
  gtk_widget_show (toggle);
 
680
 
 
681
  g_signal_connect (toggle, "toggled",
 
682
                    G_CALLBACK (gimp_toggle_button_update),
 
683
                    &config->use_comment);
 
684
 
 
685
  /* GLib types
 
686
   */
 
687
  toggle = gtk_check_button_new_with_mnemonic (_("_Use GLib types (guint8*)"));
 
688
  gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
 
689
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
 
690
                                config->glib_types);
 
691
  gtk_widget_show (toggle);
 
692
 
 
693
  g_signal_connect (toggle, "toggled",
 
694
                    G_CALLBACK (gimp_toggle_button_update),
 
695
                    &config->glib_types);
 
696
 
 
697
  /* Use Macros
 
698
   */
 
699
  toggle = gtk_check_button_new_with_mnemonic (_("Us_e macros instead of struct"));
 
700
  gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
 
701
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
 
702
                                config->use_macros);
 
703
  gtk_widget_show (toggle);
 
704
 
 
705
  g_signal_connect (toggle, "toggled",
 
706
                    G_CALLBACK (gimp_toggle_button_update),
 
707
                    &config->use_macros);
 
708
 
 
709
  /* Use RLE
 
710
   */
 
711
  toggle = gtk_check_button_new_with_mnemonic (_("Use _1 byte Run-Length-Encoding"));
 
712
  gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
 
713
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
 
714
                                config->use_rle);
 
715
  gtk_widget_show (toggle);
 
716
 
 
717
  g_signal_connect (toggle, "toggled",
 
718
                    G_CALLBACK (gimp_toggle_button_update),
 
719
                    &config->use_rle);
 
720
 
 
721
  /* Alpha
 
722
   */
 
723
  toggle = gtk_check_button_new_with_mnemonic (_("Sa_ve alpha channel (RGBA/RGB)"));
 
724
  gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
 
725
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
 
726
                                config->alpha);
 
727
  gtk_widget_show (toggle);
 
728
 
 
729
  g_signal_connect (toggle, "toggled",
 
730
                    G_CALLBACK (gimp_toggle_button_update),
 
731
                    &config->alpha);
 
732
 
 
733
  /* Max Alpha Value
 
734
   */
 
735
  table = gtk_table_new (1, 3, FALSE);
 
736
  gtk_table_set_col_spacings (GTK_TABLE (table), 4);
 
737
  gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
 
738
  gtk_widget_show (table);
 
739
 
 
740
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
 
741
                              _("Op_acity:"), 100, 0,
 
742
                              config->opacity, 0, 100, 1, 10, 1,
 
743
                              TRUE, 0, 0,
 
744
                              NULL, NULL);
 
745
  g_signal_connect (adj, "value_changed",
 
746
                    G_CALLBACK (gimp_double_adjustment_update),
 
747
                    &config->opacity);
 
748
 
 
749
  gtk_widget_show (dialog);
 
750
 
 
751
  run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
 
752
 
 
753
  if (run)
 
754
    {
 
755
      config->prefixed_name =
 
756
        g_strdup (gtk_entry_get_text (GTK_ENTRY (prefixed_name)));
 
757
      config->comment = g_strdup (gtk_entry_get_text (GTK_ENTRY (centry)));
 
758
    }
 
759
 
 
760
  gtk_widget_destroy (dialog);
 
761
 
 
762
  if (!config->prefixed_name || !config->prefixed_name[0])
 
763
    config->prefixed_name = "tmp";
 
764
  if (config->comment && !config->comment[0])
 
765
    config->comment = NULL;
 
766
 
 
767
  return run;
 
768
}