~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2008-10-06 13:30:41 UTC
  • mto: This revision was merged to the branch mainline in revision 35.
  • Revision ID: james.westby@ubuntu.com-20081006133041-3panbkcanaymfsmp
Tags: upstream-2.6.0
ImportĀ upstreamĀ versionĀ 2.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * aa.c version 1.0
3
 
 * A plugin that uses libaa (ftp://ftp.ta.jcu.cz/pub/aa) to save images as
4
 
 * ASCII.
5
 
 * NOTE: This plugin *requires* aalib 1.2 or later. Earlier versions will
6
 
 * not work.
7
 
 * Code copied from all over the GIMP source.
8
 
 * Tim Newsome <nuisance@cmu.edu>
9
 
 */
10
 
 
11
 
/* GIMP - The GNU Image Manipulation Program
12
 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
13
 
 *
14
 
 * This program is free software; you can redistribute it and/or modify
15
 
 * it under the terms of the GNU General Public License as published by
16
 
 * the Free Software Foundation; either version 2 of the License, or
17
 
 * (at your option) any later version.
18
 
 *
19
 
 * This program is distributed in the hope that it will be useful,
20
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 
 * GNU General Public License for more details.
23
 
 *
24
 
 * You should have received a copy of the GNU General Public License
25
 
 * along with this program; if not, write to the Free Software
26
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27
 
 */
28
 
 
29
 
#include "config.h"
30
 
 
31
 
#include <string.h>
32
 
 
33
 
#include <aalib.h>
34
 
 
35
 
#include <libgimp/gimp.h>
36
 
#include <libgimp/gimpui.h>
37
 
 
38
 
#include "libgimp/stdplugins-intl.h"
39
 
 
40
 
 
41
 
#define SAVE_PROC      "file-aa-save"
42
 
#define PLUG_IN_BINARY "aa"
43
 
 
44
 
 
45
 
/*
46
 
 * Declare some local functions.
47
 
 */
48
 
static void     query       (void);
49
 
static void     run         (const gchar      *name,
50
 
                             gint              nparams,
51
 
                             const GimpParam  *param,
52
 
                             gint             *nreturn_vals,
53
 
                             GimpParam       **return_vals);
54
 
static gboolean save_aa     (gint32            drawable_ID,
55
 
                             gchar            *filename,
56
 
                             gint              output_type);
57
 
static void     gimp2aa     (gint32            drawable_ID,
58
 
                             aa_context       *context);
59
 
 
60
 
static gint     aa_dialog   (gint              selected);
61
 
 
62
 
 
63
 
/*
64
 
 * Some global variables.
65
 
 */
66
 
 
67
 
const GimpPlugInInfo PLUG_IN_INFO =
68
 
{
69
 
  NULL,  /* init_proc  */
70
 
  NULL,  /* quit_proc  */
71
 
  query, /* query_proc */
72
 
  run,   /* run_proc   */
73
 
};
74
 
 
75
 
 
76
 
MAIN ()
77
 
 
78
 
static void
79
 
query (void)
80
 
{
81
 
  static const GimpParamDef save_args[] =
82
 
  {
83
 
    {GIMP_PDB_INT32,    "run-mode",     "Interactive, non-interactive"},
84
 
    {GIMP_PDB_IMAGE,    "image",        "Input image"},
85
 
    {GIMP_PDB_DRAWABLE, "drawable",     "Drawable to save"},
86
 
    {GIMP_PDB_STRING,   "filename",     "The name of the file to save the image in"},
87
 
    {GIMP_PDB_STRING,   "raw-filename", "The name entered"},
88
 
    {GIMP_PDB_STRING,   "file-type",    "File type to use"}
89
 
  };
90
 
 
91
 
  gimp_install_procedure (SAVE_PROC,
92
 
                          "Saves grayscale image in various text formats",
93
 
                          "This plug-in uses aalib to save grayscale image "
94
 
                          "as ascii art into a variety of text formats",
95
 
                          "Tim Newsome <nuisance@cmu.edu>",
96
 
                          "Tim Newsome <nuisance@cmu.edu>",
97
 
                          "1997",
98
 
                          N_("ASCII art"),
99
 
                          "RGB*, GRAY*",
100
 
                          GIMP_PLUGIN,
101
 
                          G_N_ELEMENTS (save_args), 0,
102
 
                          save_args, NULL);
103
 
 
104
 
  gimp_register_file_handler_mime (SAVE_PROC, "text/plain");
105
 
  gimp_register_save_handler (SAVE_PROC, "txt,ansi,text", "");
106
 
}
107
 
 
108
 
/**
109
 
 * Searches aa_formats defined by aalib to find the index of the type
110
 
 * specified by string.
111
 
 * -1 means it wasn't found.
112
 
 */
113
 
static gint
114
 
get_type_from_string (const gchar *string)
115
 
{
116
 
  gint type = 0;
117
 
  aa_format **p = (aa_format **) aa_formats;
118
 
 
119
 
  while (*p && strcmp ((*p)->formatname, string))
120
 
    {
121
 
      p++;
122
 
      type++;
123
 
    }
124
 
 
125
 
  if (*p == NULL)
126
 
    return -1;
127
 
 
128
 
  return type;
129
 
}
130
 
 
131
 
static void
132
 
run (const gchar      *name,
133
 
     gint              nparams,
134
 
     const GimpParam  *param,
135
 
     gint             *nreturn_vals,
136
 
     GimpParam       **return_vals)
137
 
{
138
 
  static GimpParam  values[2];
139
 
  GimpRunMode       run_mode;
140
 
  GimpPDBStatusType status = GIMP_PDB_SUCCESS;
141
 
  gint              output_type = 0;
142
 
  gint32            image_ID;
143
 
  gint32            drawable_ID;
144
 
  GimpExportReturn  export = GIMP_EXPORT_CANCEL;
145
 
 
146
 
  INIT_I18N ();
147
 
 
148
 
  /* Set us up to return a status. */
149
 
  *nreturn_vals = 1;
150
 
  *return_vals  = values;
151
 
  values[0].type          = GIMP_PDB_STATUS;
152
 
  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
153
 
  run_mode    = param[0].data.d_int32;
154
 
  image_ID    = param[1].data.d_int32;
155
 
  drawable_ID = param[2].data.d_int32;
156
 
 
157
 
  /*  eventually export the image */
158
 
  switch (run_mode)
159
 
    {
160
 
    case GIMP_RUN_INTERACTIVE:
161
 
    case GIMP_RUN_WITH_LAST_VALS:
162
 
      gimp_ui_init (PLUG_IN_BINARY, FALSE);
163
 
      export = gimp_export_image (&image_ID, &drawable_ID, "AA",
164
 
                                  (GIMP_EXPORT_CAN_HANDLE_RGB  |
165
 
                                   GIMP_EXPORT_CAN_HANDLE_GRAY |
166
 
                                   GIMP_EXPORT_CAN_HANDLE_ALPHA ));
167
 
      if (export == GIMP_EXPORT_CANCEL)
168
 
        {
169
 
          values[0].data.d_status = GIMP_PDB_CANCEL;
170
 
          return;
171
 
        }
172
 
      break;
173
 
    default:
174
 
      break;
175
 
    }
176
 
 
177
 
  if (! (gimp_drawable_is_rgb (drawable_ID) ||
178
 
         gimp_drawable_is_gray (drawable_ID)))
179
 
    {
180
 
      status = GIMP_PDB_CALLING_ERROR;
181
 
    }
182
 
 
183
 
  if (status == GIMP_PDB_SUCCESS)
184
 
    {
185
 
      switch (run_mode)
186
 
        {
187
 
        case GIMP_RUN_INTERACTIVE:
188
 
          gimp_get_data (SAVE_PROC, &output_type);
189
 
          output_type = aa_dialog (output_type);
190
 
          if (output_type < 0)
191
 
            status = GIMP_PDB_CANCEL;
192
 
          break;
193
 
 
194
 
        case GIMP_RUN_NONINTERACTIVE:
195
 
          /*  Make sure all the arguments are there!  */
196
 
          if (nparams != 6)
197
 
            {
198
 
              status = GIMP_PDB_CALLING_ERROR;
199
 
            }
200
 
          else
201
 
            {
202
 
              output_type = get_type_from_string (param[5].data.d_string);
203
 
              if (output_type < 0)
204
 
                status = GIMP_PDB_CALLING_ERROR;
205
 
            }
206
 
          break;
207
 
 
208
 
        case GIMP_RUN_WITH_LAST_VALS:
209
 
          gimp_get_data (SAVE_PROC, &output_type);
210
 
          break;
211
 
 
212
 
        default:
213
 
          break;
214
 
        }
215
 
    }
216
 
 
217
 
  if (status == GIMP_PDB_SUCCESS)
218
 
    {
219
 
      if (save_aa (drawable_ID, param[3].data.d_string, output_type))
220
 
        {
221
 
          gimp_set_data (SAVE_PROC, &output_type, sizeof (output_type));
222
 
        }
223
 
      else
224
 
        {
225
 
          status = GIMP_PDB_EXECUTION_ERROR;
226
 
        }
227
 
    }
228
 
 
229
 
  if (export == GIMP_EXPORT_EXPORT)
230
 
    gimp_image_delete (image_ID);
231
 
 
232
 
  values[0].data.d_status = status;
233
 
}
234
 
 
235
 
/**
236
 
 * The actual save function. What it's all about.
237
 
 * The image type has to be GRAY.
238
 
 */
239
 
static gboolean
240
 
save_aa (gint32  drawable_ID,
241
 
         gchar  *filename,
242
 
         gint    output_type)
243
 
{
244
 
  aa_savedata  savedata;
245
 
  aa_context  *context;
246
 
  aa_format    format = *aa_formats[output_type];
247
 
 
248
 
  format.width  = gimp_drawable_width (drawable_ID)  / 2;
249
 
  format.height = gimp_drawable_height (drawable_ID) / 2;
250
 
 
251
 
  /* Get a libaa context which will save its output to filename. */
252
 
  savedata.name   = filename;
253
 
  savedata.format = &format;
254
 
 
255
 
  context = aa_init (&save_d, &aa_defparams, &savedata);
256
 
  if (!context)
257
 
    return FALSE;
258
 
 
259
 
  gimp2aa (drawable_ID, context);
260
 
  aa_flush (context);
261
 
  aa_close (context);
262
 
 
263
 
  return TRUE;
264
 
}
265
 
 
266
 
static void
267
 
gimp2aa (gint32      drawable_ID,
268
 
         aa_context *context)
269
 
{
270
 
  GimpDrawable    *drawable;
271
 
  GimpPixelRgn     pixel_rgn;
272
 
  aa_renderparams *renderparams;
273
 
 
274
 
  gint    width;
275
 
  gint    height;
276
 
  gint    x, y;
277
 
  gint    bpp;
278
 
  guchar *buffer;
279
 
  guchar *p;
280
 
 
281
 
  drawable = gimp_drawable_get (drawable_ID);
282
 
 
283
 
  width  = aa_imgwidth  (context);
284
 
  height = aa_imgheight (context);
285
 
  bpp    = drawable->bpp;
286
 
 
287
 
  gimp_tile_cache_ntiles ((width / gimp_tile_width ()) + 1);
288
 
 
289
 
  gimp_pixel_rgn_init (&pixel_rgn,
290
 
                       drawable, 0, 0, width, height,
291
 
                       FALSE, FALSE);
292
 
 
293
 
  buffer = g_new (guchar, width * bpp);
294
 
 
295
 
  for (y = 0; y < height; y++)
296
 
    {
297
 
      gimp_pixel_rgn_get_row (&pixel_rgn, buffer, 0, y, width);
298
 
 
299
 
      switch (bpp)
300
 
        {
301
 
        case 1:  /* GRAY */
302
 
          for (x = 0, p = buffer; x < width; x++, p++)
303
 
            aa_putpixel (context, x, y, *p);
304
 
          break;
305
 
 
306
 
        case 2:  /* GRAYA, blend over black */
307
 
          for (x = 0, p = buffer; x < width; x++, p += 2)
308
 
            aa_putpixel (context, x, y, (p[0] * (p[1] + 1)) >> 8);
309
 
          break;
310
 
 
311
 
        case 3:  /* RGB */
312
 
          for (x = 0, p = buffer; x < width; x++, p += 3)
313
 
            aa_putpixel (context, x, y,
314
 
                         GIMP_RGB_LUMINANCE (p[0], p[1], p[2]) + 0.5);
315
 
          break;
316
 
 
317
 
        case 4:  /* RGBA, blend over black */
318
 
          for (x = 0, p = buffer; x < width; x++, p += 4)
319
 
            aa_putpixel (context, x, y,
320
 
                         ((guchar) (GIMP_RGB_LUMINANCE (p[0], p[1], p[2]) + 0.5)
321
 
                          * (p[3] + 1)) >> 8);
322
 
          break;
323
 
 
324
 
        default:
325
 
          g_assert_not_reached ();
326
 
          break;
327
 
        }
328
 
    }
329
 
 
330
 
  g_free (buffer);
331
 
 
332
 
  renderparams = aa_getrenderparams ();
333
 
  renderparams->dither = AA_FLOYD_S;
334
 
 
335
 
  aa_render (context, renderparams, 0, 0,
336
 
             aa_scrwidth (context), aa_scrheight (context));
337
 
}
338
 
 
339
 
static gint
340
 
aa_dialog (gint selected)
341
 
{
342
 
  GtkWidget *dialog;
343
 
  GtkWidget *hbox;
344
 
  GtkWidget *label;
345
 
  GtkWidget *combo;
346
 
  gint       i;
347
 
 
348
 
  /* Create the actual window. */
349
 
  dialog = gimp_dialog_new (_("Save as Text"), PLUG_IN_BINARY,
350
 
                         NULL, 0,
351
 
                         gimp_standard_help_func, SAVE_PROC,
352
 
 
353
 
                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
354
 
                         GTK_STOCK_SAVE,   GTK_RESPONSE_OK,
355
 
 
356
 
                         NULL);
357
 
 
358
 
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
359
 
                                           GTK_RESPONSE_OK,
360
 
                                           GTK_RESPONSE_CANCEL,
361
 
                                           -1);
362
 
 
363
 
  gimp_window_set_transient (GTK_WINDOW (dialog));
364
 
 
365
 
  hbox = gtk_hbox_new (FALSE, 6);
366
 
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
367
 
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
368
 
                      hbox, FALSE, FALSE, 0);
369
 
  gtk_widget_show (hbox);
370
 
 
371
 
  label = gtk_label_new_with_mnemonic (_("_Format:"));
372
 
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
373
 
  gtk_widget_show (label);
374
 
 
375
 
  combo = g_object_new (GIMP_TYPE_INT_COMBO_BOX, NULL);
376
 
  gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
377
 
  gtk_widget_show (combo);
378
 
 
379
 
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
380
 
 
381
 
  for (i = 0; aa_formats[i]; i++)
382
 
    gimp_int_combo_box_append (GIMP_INT_COMBO_BOX (combo),
383
 
                               GIMP_INT_STORE_VALUE, i,
384
 
                               GIMP_INT_STORE_LABEL, aa_formats[i]->formatname,
385
 
                               -1);
386
 
 
387
 
  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), selected,
388
 
                              G_CALLBACK (gimp_int_combo_box_get_active),
389
 
                              &selected);
390
 
 
391
 
  gtk_widget_show (dialog);
392
 
 
393
 
  if (gimp_dialog_run (GIMP_DIALOG (dialog)) != GTK_RESPONSE_OK)
394
 
    selected = -1;
395
 
 
396
 
  gtk_widget_destroy (dialog);
397
 
 
398
 
  return selected;
399
 
}