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

« back to all changes in this revision

Viewing changes to plug-ins/xjt/xjpeg.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
 
/* GIMP - The GNU Image Manipulation Program
2
 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or modify
5
 
 * it under the terms of the GNU General Public License as published by
6
 
 * the Free Software Foundation; either version 2 of the License, or
7
 
 * (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 General Public License
15
 
 * 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
 
 
19
 
/* JPEG loading and saving routines adapted for the GIMP XJT fileformat
20
 
 *  -Wolfgang Hofer
21
 
 *
22
 
 * This filter is heavily based upon the "example.c" file in libjpeg.
23
 
 * In fact most of the loading and saving code was simply cut-and-pasted
24
 
 *  from that file. The filter, therefore, also uses libjpeg.
25
 
 */
26
 
 
27
 
/* revision history:
28
 
 * version 1.1.15a; 2000/01/25  hof: use g_malloc, g_free
29
 
 * version 1.00.00; 1998/10/26  hof: 1.st (pre) release
30
 
 */
31
 
 
32
 
#include "config.h"
33
 
 
34
 
#include <stdlib.h>
35
 
#include <string.h>
36
 
#include <setjmp.h>
37
 
 
38
 
#include <glib/gstdio.h>
39
 
 
40
 
/* Include for External Libraries */
41
 
#include <jpeglib.h>
42
 
 
43
 
/* GIMP includes */
44
 
#include "libgimp/gimp.h"
45
 
 
46
 
#include "xjpeg.h"
47
 
 
48
 
extern int xjt_debug;
49
 
 
50
 
/* Declare local functions.
51
 
 */
52
 
 
53
 
 
54
 
typedef struct my_error_mgr {
55
 
  struct jpeg_error_mgr pub;    /* "public" fields */
56
 
 
57
 
  jmp_buf setjmp_buffer;        /* for return to caller */
58
 
} *my_error_ptr;
59
 
 
60
 
 
61
 
/*
62
 
 * Here's the routine that will replace the standard error_exit method:
63
 
 */
64
 
 
65
 
static void
66
 
my_error_exit (j_common_ptr cinfo)
67
 
{
68
 
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
69
 
  my_error_ptr myerr = (my_error_ptr) cinfo->err;
70
 
 
71
 
  /* Always display the message. */
72
 
  /* We could postpone this until after returning, if we chose. */
73
 
  (*cinfo->err->output_message) (cinfo);
74
 
 
75
 
  /* Return control to the setjmp point */
76
 
  longjmp (myerr->setjmp_buffer, 1);
77
 
}
78
 
 
79
 
 
80
 
/* ============================================================================
81
 
 * xjpg_load_layer
82
 
 *   load layer from jpeg file
83
 
 * ============================================================================
84
 
 */
85
 
 
86
 
gint32
87
 
xjpg_load_layer (const char    *filename,
88
 
                 gint32         image_id,
89
 
                 int            image_type,
90
 
                 char          *layer_name,
91
 
                 gdouble        layer_opacity,
92
 
                 GimpLayerModeEffects     layer_mode
93
 
            )
94
 
{
95
 
  GimpPixelRgn l_pixel_rgn;
96
 
  GimpDrawable *l_drawable;
97
 
  gint32     l_layer_id;
98
 
  GimpImageType  l_layer_type;
99
 
  struct jpeg_decompress_struct cinfo;
100
 
  struct my_error_mgr jerr;
101
 
  FILE *infile;
102
 
  guchar *l_buf;
103
 
  guchar **l_rowbuf;
104
 
  int l_tile_height;
105
 
  int l_scanlines;
106
 
  int l_idx, l_start, l_end;
107
 
 
108
 
  /* We set up the normal JPEG error routines. */
109
 
  cinfo.err = jpeg_std_error (&jerr.pub);
110
 
  jerr.pub.error_exit = my_error_exit;
111
 
 
112
 
  l_layer_type = GIMP_GRAY_IMAGE;
113
 
 
114
 
  if ((infile = g_fopen (filename, "rb")) == NULL)
115
 
  {
116
 
      g_warning ("can't open \"%s\"\n", filename);
117
 
      return -1;
118
 
  }
119
 
 
120
 
 
121
 
  /* Establish the setjmp return context for my_error_exit to use. */
122
 
  if (setjmp (jerr.setjmp_buffer))
123
 
  {
124
 
      /* If we get here, the JPEG code has signaled an error.
125
 
       * We need to clean up the JPEG object, close the input file, and return.
126
 
       */
127
 
      jpeg_destroy_decompress (&cinfo);
128
 
      if (infile)
129
 
        fclose (infile);
130
 
 
131
 
      g_printerr ("XJT: JPEG load error\n");
132
 
      return -1;
133
 
  }
134
 
 
135
 
  /* Now we can initialize the JPEG decompression object. */
136
 
  jpeg_create_decompress (&cinfo);
137
 
 
138
 
  /* Step 2: specify data source (eg, a file) */
139
 
 
140
 
  jpeg_stdio_src (&cinfo, infile);
141
 
 
142
 
  /* Step 3: read file parameters with jpeg_read_header() */
143
 
 
144
 
  (void) jpeg_read_header (&cinfo, TRUE);
145
 
  /* We can ignore the return value from jpeg_read_header since
146
 
   *   (a) suspension is not possible with the stdio data source, and
147
 
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
148
 
   * See libjpeg.doc for more info.
149
 
   */
150
 
 
151
 
  /* Step 4: set parameters for decompression */
152
 
 
153
 
  /* In this example, we don't need to change any of the defaults set by
154
 
   * jpeg_read_header(), so we do nothing here.
155
 
   */
156
 
 
157
 
  /* Step 5: Start decompressor */
158
 
 
159
 
  jpeg_start_decompress (&cinfo);
160
 
 
161
 
  /* We may need to do some setup of our own at this point before reading
162
 
   * the data.  After jpeg_start_decompress() we have the correct scaled
163
 
   * output image dimensions available, as well as the output colormap
164
 
   * if we asked for color quantization.
165
 
   * In this example, we need to make an output work buffer of the right size.
166
 
   */
167
 
  /* temporary buffer */
168
 
  l_tile_height = gimp_tile_height ();
169
 
  l_buf = g_new (guchar, l_tile_height * cinfo.output_width * cinfo.output_components);
170
 
  l_rowbuf = g_new (guchar*, l_tile_height);
171
 
 
172
 
  for (l_idx = 0; l_idx < l_tile_height; l_idx++)
173
 
  {
174
 
    l_rowbuf[l_idx] = l_buf + cinfo.output_width * cinfo.output_components * l_idx;
175
 
  }
176
 
 
177
 
  /* Check jpeg file for layer type */
178
 
  switch (cinfo.output_components)
179
 
    {
180
 
    case 1:
181
 
      l_layer_type = GIMP_GRAY_IMAGE;
182
 
      break;
183
 
    case 3:
184
 
      l_layer_type = GIMP_RGB_IMAGE;
185
 
      break;
186
 
    default:
187
 
      g_printerr ("XJT: cant load layer %s (type is not GRAY and not RGB)\n", filename);
188
 
      fclose (infile);
189
 
      return -1;
190
 
    }
191
 
 
192
 
 
193
 
  l_layer_id = gimp_layer_new (image_id, layer_name,
194
 
                             cinfo.output_width,
195
 
                             cinfo.output_height,
196
 
                             l_layer_type,
197
 
                             layer_opacity,
198
 
                             layer_mode);
199
 
  if(l_layer_id < 0)
200
 
  {
201
 
      g_printerr ("XJT: cant create new layer\n");
202
 
      fclose (infile);
203
 
      return -1;
204
 
  }
205
 
 
206
 
  l_drawable = gimp_drawable_get (l_layer_id);
207
 
  gimp_pixel_rgn_init (&l_pixel_rgn, l_drawable, 0, 0, l_drawable->width, l_drawable->height, TRUE, FALSE);
208
 
 
209
 
  /* Step 6: while (scan lines remain to be read) */
210
 
  /*           jpeg_read_scanlines(...); */
211
 
 
212
 
  /* Here we use the library's state variable cinfo.output_scanline as the
213
 
   * loop counter, so that we don't have to keep track ourselves.
214
 
   */
215
 
  while (cinfo.output_scanline < cinfo.output_height)
216
 
  {
217
 
      l_start = cinfo.output_scanline;
218
 
      l_end = cinfo.output_scanline + l_tile_height;
219
 
      l_end = MIN (l_end, cinfo.output_height);
220
 
      l_scanlines = l_end - l_start;
221
 
 
222
 
      for (l_idx = 0; l_idx < l_scanlines; l_idx++)
223
 
      {
224
 
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &l_rowbuf[l_idx], 1);
225
 
      }
226
 
 
227
 
      gimp_pixel_rgn_set_rect (&l_pixel_rgn, l_buf, 0, l_start, l_drawable->width, l_scanlines);
228
 
 
229
 
      gimp_progress_update ((double) cinfo.output_scanline / (double) cinfo.output_height);
230
 
  }
231
 
 
232
 
  /* Step 7: Finish decompression */
233
 
 
234
 
  jpeg_finish_decompress (&cinfo);
235
 
  /* We can ignore the return value since suspension is not possible
236
 
   * with the stdio data source.
237
 
   */
238
 
 
239
 
  /* Step 8: Release JPEG decompression object */
240
 
 
241
 
  /* This is an important step since it will release a good deal of memory. */
242
 
  jpeg_destroy_decompress (&cinfo);
243
 
 
244
 
  /* free up the temporary buffers */
245
 
  g_free (l_rowbuf);
246
 
  g_free (l_buf);
247
 
 
248
 
  /* After finish_decompress, we can close the input file.
249
 
   * Here we postpone it until after no more JPEG errors are possible,
250
 
   * so as to simplify the setjmp error logic above.  (Actually, I don't
251
 
   * think that jpeg_destroy can do an error exit, but why assume anything...)
252
 
   */
253
 
  fclose (infile);
254
 
 
255
 
  /* At this point you may want to check to see whether any corrupt-data
256
 
   * warnings occurred (test whether jerr.num_warnings is nonzero).
257
 
   */
258
 
 
259
 
  return (l_layer_id);
260
 
 
261
 
}       /* end xjpg_load_layer */
262
 
 
263
 
 
264
 
/* ============================================================================
265
 
 * xjpg_load_layer_alpha
266
 
 *   load the layers alpha channel from jpeg file.
267
 
 * ============================================================================
268
 
 */
269
 
 
270
 
gint
271
 
xjpg_load_layer_alpha (const char *filename,
272
 
                       gint32      image_id,
273
 
                       gint32      layer_id)
274
 
{
275
 
  GimpPixelRgn l_pixel_rgn;
276
 
  GimpDrawable *l_drawable;
277
 
  GimpImageType  l_layer_type;
278
 
  struct jpeg_decompress_struct cinfo;
279
 
  struct my_error_mgr jerr;
280
 
  FILE *infile;
281
 
  guchar *l_buf;
282
 
  guchar *l_dstbuf;
283
 
  guchar **l_rowbuf;
284
 
  int l_tile_height;
285
 
  int l_scanlines;
286
 
  int l_idx, l_start, l_end;
287
 
  int l_alpha_offset;
288
 
  guchar *l_buf_ptr;
289
 
  guchar *l_dstbuf_ptr;
290
 
 
291
 
  /* We set up the normal JPEG error routines. */
292
 
  cinfo.err = jpeg_std_error (&jerr.pub);
293
 
  jerr.pub.error_exit = my_error_exit;
294
 
 
295
 
  l_layer_type = GIMP_GRAY_IMAGE;
296
 
 
297
 
  /* add alpha channel */
298
 
  gimp_layer_add_alpha (layer_id);
299
 
 
300
 
  if ((infile = g_fopen (filename, "rb")) == NULL)
301
 
  {
302
 
      /* No alpha found, thats OK, use full opaque alpha channel
303
 
       * (there is no need not store alpha channels on full opaque channels)
304
 
       * (fixme: if filename exists but is not readable
305
 
       *         we should return -1 to indicate an error
306
 
       */
307
 
      return 0;  /* OK */
308
 
  }
309
 
 
310
 
  /* Establish the setjmp return context for my_error_exit to use. */
311
 
  if (setjmp (jerr.setjmp_buffer))
312
 
  {
313
 
      /* If we get here, the JPEG code has signaled an error.
314
 
       * We need to clean up the JPEG object, close the input file, and return.
315
 
       */
316
 
      jpeg_destroy_decompress (&cinfo);
317
 
      if (infile)
318
 
        fclose (infile);
319
 
 
320
 
      g_printerr ("XJT: JPEG alpha load error\n");
321
 
      return -1;
322
 
  }
323
 
 
324
 
  /* Now we can initialize the JPEG decompression object. */
325
 
  jpeg_create_decompress (&cinfo);
326
 
 
327
 
  /* Step 2: specify data source (eg, a file) */
328
 
 
329
 
  jpeg_stdio_src (&cinfo, infile);
330
 
 
331
 
  /* Step 3: read file parameters with jpeg_read_header() */
332
 
 
333
 
  (void) jpeg_read_header (&cinfo, TRUE);
334
 
  /* We can ignore the return value from jpeg_read_header since
335
 
   *   (a) suspension is not possible with the stdio data source, and
336
 
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
337
 
   * See libjpeg.doc for more info.
338
 
   */
339
 
 
340
 
  /* Step 4: set parameters for decompression */
341
 
 
342
 
  /* In this example, we don't need to change any of the defaults set by
343
 
   * jpeg_read_header(), so we do nothing here.
344
 
   */
345
 
 
346
 
  /* Step 5: Start decompressor */
347
 
 
348
 
  jpeg_start_decompress (&cinfo);
349
 
 
350
 
  /* We may need to do some setup of our own at this point before reading
351
 
   * the data.  After jpeg_start_decompress() we have the correct scaled
352
 
   * output image dimensions available, as well as the output colormap
353
 
   * if we asked for color quantization.
354
 
   * In this example, we need to make an output work buffer of the right size.
355
 
   */
356
 
  /* temporary buffer (for read in jpeg lines) */
357
 
  l_tile_height = gimp_tile_height ();
358
 
  l_buf = g_new (guchar, l_tile_height * cinfo.output_width * cinfo.output_components);
359
 
  l_rowbuf = g_new (guchar*, l_tile_height);
360
 
 
361
 
  for (l_idx = 0; l_idx < l_tile_height; l_idx++)
362
 
  {
363
 
    l_rowbuf[l_idx] = l_buf + cinfo.output_width * cinfo.output_components * l_idx;
364
 
  }
365
 
 
366
 
  l_drawable = gimp_drawable_get (layer_id);
367
 
  if(l_drawable == NULL)
368
 
  {
369
 
    g_printerr ("XJT: gimp_drawable_get failed on layer id %d\n", (int)layer_id);
370
 
    fclose(infile);
371
 
    return -1;
372
 
  }
373
 
 
374
 
  /* Check if jpeg file can be used as alpha channel
375
 
   */
376
 
  if((cinfo.output_components != 1) ||
377
 
     (cinfo.output_width  != l_drawable->width) ||
378
 
     (cinfo.output_height != l_drawable->height))
379
 
  {
380
 
     g_printerr ("XJT: cant load %s as alpha channel\n", filename);
381
 
     fclose (infile);
382
 
     return -1;
383
 
  }
384
 
 
385
 
  /* buffer to read in the layer and merge with the alpha from jpeg file */
386
 
  l_dstbuf = g_new (guchar, l_tile_height * l_drawable->width * l_drawable->bpp);
387
 
 
388
 
  gimp_pixel_rgn_init (&l_pixel_rgn, l_drawable, 0, 0, l_drawable->width, l_drawable->height, TRUE, FALSE);
389
 
  l_alpha_offset = l_drawable->bpp -1;
390
 
 
391
 
  /* Step 6: while (scan lines remain to be read) */
392
 
  /*           jpeg_read_scanlines(...); */
393
 
 
394
 
  /* Here we use the library's state variable cinfo.output_scanline as the
395
 
   * loop counter, so that we don't have to keep track ourselves.
396
 
   */
397
 
  while (cinfo.output_scanline < cinfo.output_height)
398
 
  {
399
 
      l_start = cinfo.output_scanline;
400
 
      l_end = cinfo.output_scanline + l_tile_height;
401
 
      l_end = MIN (l_end, cinfo.output_height);
402
 
      l_scanlines = l_end - l_start;
403
 
 
404
 
      for (l_idx = 0; l_idx < l_scanlines; l_idx++)
405
 
      {
406
 
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &l_rowbuf[l_idx], 1);
407
 
      }
408
 
 
409
 
      gimp_pixel_rgn_get_rect (&l_pixel_rgn, l_dstbuf, 0, l_start, l_drawable->width, l_scanlines);
410
 
 
411
 
      /* copy the loaded jpeg data (from buf) to the layers alpha channel data */
412
 
      l_idx = l_tile_height * l_drawable->width;
413
 
      l_buf_ptr = l_buf;
414
 
      l_dstbuf_ptr = l_dstbuf;
415
 
      while(l_idx--)
416
 
      {
417
 
         l_dstbuf_ptr  += l_alpha_offset;
418
 
         *l_dstbuf_ptr++ = *l_buf_ptr++;
419
 
      }
420
 
 
421
 
      gimp_pixel_rgn_set_rect (&l_pixel_rgn, l_dstbuf, 0, l_start, l_drawable->width, l_scanlines);
422
 
 
423
 
      gimp_progress_update ((double) cinfo.output_scanline / (double) cinfo.output_height);
424
 
  }
425
 
 
426
 
  /* Step 7: Finish decompression */
427
 
 
428
 
  jpeg_finish_decompress (&cinfo);
429
 
  /* We can ignore the return value since suspension is not possible
430
 
   * with the stdio data source.
431
 
   */
432
 
 
433
 
  /* Step 8: Release JPEG decompression object */
434
 
 
435
 
  /* This is an important step since it will release a good deal of memory. */
436
 
  jpeg_destroy_decompress (&cinfo);
437
 
 
438
 
  /* free up the temporary buffers */
439
 
  g_free (l_rowbuf);
440
 
  g_free (l_buf);
441
 
  g_free (l_dstbuf);
442
 
 
443
 
  /* After finish_decompress, we can close the input file.
444
 
   * Here we postpone it until after no more JPEG errors are possible,
445
 
   * so as to simplify the setjmp error logic above.  (Actually, I don't
446
 
   * think that jpeg_destroy can do an error exit, but why assume anything...)
447
 
   */
448
 
  fclose (infile);
449
 
 
450
 
  /* At this point you may want to check to see whether any corrupt-data
451
 
   * warnings occurred (test whether jerr.num_warnings is nonzero).
452
 
   */
453
 
 
454
 
 
455
 
  return (0);  /* OK */
456
 
 
457
 
}       /* xjpg_load_layer_alpha */
458
 
 
459
 
 
460
 
/* ============================================================================
461
 
 * xjpg_load_channel
462
 
 *   load channel from jpeg file
463
 
 *   (call this procedure with drawable_id == -1  to create a new channel,
464
 
 *    if a positive drawable_id is supplied, its content will be overwritten)
465
 
 * ============================================================================
466
 
 */
467
 
 
468
 
gint32
469
 
xjpg_load_channel (const char   *filename,
470
 
                   gint32        image_id,
471
 
                   gint32        drawable_id,
472
 
                   char         *channel_name,
473
 
                   gdouble       channel_opacity,
474
 
                   guchar red, guchar  green, guchar blue)
475
 
{
476
 
  GimpPixelRgn l_pixel_rgn;
477
 
  GimpDrawable *l_drawable;
478
 
  gint32     l_drawable_id;
479
 
  struct jpeg_decompress_struct cinfo;
480
 
  struct my_error_mgr jerr;
481
 
  FILE *infile;
482
 
  guchar *l_buf;
483
 
  guchar **l_rowbuf;
484
 
  int l_tile_height;
485
 
  int l_scanlines;
486
 
  int l_idx, l_start, l_end;
487
 
  GimpRGB l_color;
488
 
 
489
 
  gimp_rgba_set_uchar (&l_color, red, green, blue, 255);
490
 
 
491
 
  /* We set up the normal JPEG error routines. */
492
 
  cinfo.err = jpeg_std_error (&jerr.pub);
493
 
  jerr.pub.error_exit = my_error_exit;
494
 
 
495
 
  if ((infile = g_fopen (filename, "rb")) == NULL)
496
 
  {
497
 
      g_warning ("can't open \"%s\"\n", filename);
498
 
      return -1;
499
 
  }
500
 
 
501
 
 
502
 
  /* Establish the setjmp return context for my_error_exit to use. */
503
 
  if (setjmp (jerr.setjmp_buffer))
504
 
  {
505
 
      /* If we get here, the JPEG code has signaled an error.
506
 
       * We need to clean up the JPEG object, close the input file, and return.
507
 
       */
508
 
      jpeg_destroy_decompress (&cinfo);
509
 
      if (infile)
510
 
        fclose (infile);
511
 
 
512
 
      g_printerr ("XJT: JPEG load error\n");
513
 
      return -1;
514
 
  }
515
 
 
516
 
  /* Now we can initialize the JPEG decompression object. */
517
 
  jpeg_create_decompress (&cinfo);
518
 
 
519
 
  /* Step 2: specify data source (eg, a file) */
520
 
 
521
 
  jpeg_stdio_src (&cinfo, infile);
522
 
 
523
 
  /* Step 3: read file parameters with jpeg_read_header() */
524
 
 
525
 
  (void) jpeg_read_header (&cinfo, TRUE);
526
 
  /* We can ignore the return value from jpeg_read_header since
527
 
   *   (a) suspension is not possible with the stdio data source, and
528
 
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
529
 
   * See libjpeg.doc for more info.
530
 
   */
531
 
 
532
 
  /* Step 4: set parameters for decompression */
533
 
 
534
 
  /* In this example, we don't need to change any of the defaults set by
535
 
   * jpeg_read_header(), so we do nothing here.
536
 
   */
537
 
 
538
 
  /* Step 5: Start decompressor */
539
 
 
540
 
  jpeg_start_decompress (&cinfo);
541
 
 
542
 
  /* We may need to do some setup of our own at this point before reading
543
 
   * the data.  After jpeg_start_decompress() we have the correct scaled
544
 
   * output image dimensions available, as well as the output colormap
545
 
   * if we asked for color quantization.
546
 
   * In this example, we need to make an output work buffer of the right size.
547
 
   */
548
 
  /* temporary buffer */
549
 
  l_tile_height = gimp_tile_height ();
550
 
  l_buf = g_new (guchar, l_tile_height * cinfo.output_width * cinfo.output_components);
551
 
  l_rowbuf = g_new (guchar*, l_tile_height);
552
 
 
553
 
  for (l_idx = 0; l_idx < l_tile_height; l_idx++)
554
 
  {
555
 
    l_rowbuf[l_idx] = l_buf + cinfo.output_width * cinfo.output_components * l_idx;
556
 
  }
557
 
 
558
 
  /* Check if jpeg file has one component (a channel cant have more than one)
559
 
   */
560
 
  if(cinfo.output_components != 1)
561
 
  {
562
 
      g_printerr ("XJT: cant load RGB layer %s into GRAY Image\n", filename);
563
 
      fclose (infile);
564
 
      return -1;
565
 
  }
566
 
 
567
 
  if(drawable_id < 0)
568
 
  {
569
 
     l_drawable_id = gimp_channel_new (image_id,
570
 
                                       channel_name,
571
 
                                       cinfo.output_width,
572
 
                                       cinfo.output_height,
573
 
                                       channel_opacity,
574
 
                                       &l_color);
575
 
     if(l_drawable_id < 0)
576
 
     {
577
 
         g_printerr ("XJT: cant create new channel\n");
578
 
         fclose (infile);
579
 
         return -1;
580
 
     }
581
 
  }
582
 
  else
583
 
  {
584
 
    l_drawable_id = drawable_id;  /* overwrite the given drawable */
585
 
  }
586
 
 
587
 
  l_drawable = gimp_drawable_get (l_drawable_id);
588
 
 
589
 
  if((l_drawable->width != cinfo.output_width)
590
 
  || (l_drawable->height != cinfo.output_height)
591
 
  || (l_drawable->bpp != cinfo.output_components) )
592
 
  {
593
 
         g_printerr ("XJT: cant load-overwrite drawable (size missmatch)\n");
594
 
         fclose (infile);
595
 
         return -1;
596
 
  }
597
 
 
598
 
  gimp_pixel_rgn_init (&l_pixel_rgn, l_drawable, 0, 0, l_drawable->width, l_drawable->height, TRUE, FALSE);
599
 
 
600
 
  /* Step 6: while (scan lines remain to be read) */
601
 
  /*           jpeg_read_scanlines(...); */
602
 
 
603
 
  /* Here we use the library's state variable cinfo.output_scanline as the
604
 
   * loop counter, so that we don't have to keep track ourselves.
605
 
   */
606
 
  while (cinfo.output_scanline < cinfo.output_height)
607
 
  {
608
 
      l_start = cinfo.output_scanline;
609
 
      l_end = cinfo.output_scanline + l_tile_height;
610
 
      l_end = MIN (l_end, cinfo.output_height);
611
 
      l_scanlines = l_end - l_start;
612
 
 
613
 
      for (l_idx = 0; l_idx < l_scanlines; l_idx++)
614
 
      {
615
 
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &l_rowbuf[l_idx], 1);
616
 
      }
617
 
 
618
 
      gimp_pixel_rgn_set_rect (&l_pixel_rgn, l_buf, 0, l_start, l_drawable->width, l_scanlines);
619
 
 
620
 
      gimp_progress_update ((double) cinfo.output_scanline / (double) cinfo.output_height);
621
 
  }
622
 
 
623
 
  /* Step 7: Finish decompression */
624
 
 
625
 
  jpeg_finish_decompress (&cinfo);
626
 
  /* We can ignore the return value since suspension is not possible
627
 
   * with the stdio data source.
628
 
   */
629
 
 
630
 
  /* Step 8: Release JPEG decompression object */
631
 
 
632
 
  /* This is an important step since it will release a good deal of memory. */
633
 
  jpeg_destroy_decompress (&cinfo);
634
 
 
635
 
  /* free up the temporary buffers */
636
 
  g_free (l_rowbuf);
637
 
  g_free (l_buf);
638
 
 
639
 
  /* After finish_decompress, we can close the input file.
640
 
   * Here we postpone it until after no more JPEG errors are possible,
641
 
   * so as to simplify the setjmp error logic above.  (Actually, I don't
642
 
   * think that jpeg_destroy can do an error exit, but why assume anything...)
643
 
   */
644
 
  fclose (infile);
645
 
 
646
 
  /* At this point you may want to check to see whether any corrupt-data
647
 
   * warnings occurred (test whether jerr.num_warnings is nonzero).
648
 
   */
649
 
 
650
 
  /* Tell GIMP to display the image.
651
 
   */
652
 
  /* gimp_drawable_flush (l_drawable); */
653
 
 
654
 
  return (l_drawable_id);
655
 
 
656
 
}       /* end xjpg_load_channel */
657
 
 
658
 
 
659
 
 
660
 
/* ============================================================================
661
 
 * xjpg_save_drawable
662
 
 *   save as drawable as jpeg file depending on save_mode:
663
 
 *   - save the drawable without alpha channel.
664
 
 *     (optional clear full transparent pixels to 0,
665
 
 *      resulting in better compression)
666
 
 *   - save the alpha channel
667
 
 * ============================================================================
668
 
 */
669
 
 
670
 
 
671
 
gint
672
 
xjpg_save_drawable (const char     *filename,
673
 
                    gint32          image_ID,
674
 
                    gint32          drawable_ID,
675
 
                    gint            save_mode,
676
 
                    t_JpegSaveVals *jsvals)
677
 
{
678
 
  GimpPixelRgn pixel_rgn;
679
 
  GimpDrawable *drawable;
680
 
  GimpImageType drawable_type;
681
 
  struct jpeg_compress_struct cinfo;
682
 
  struct my_error_mgr jerr;
683
 
  FILE * volatile outfile;
684
 
  guchar *temp, *t;
685
 
  guchar *data;
686
 
  guchar *src, *s;
687
 
  int has_alpha;
688
 
  int rowstride, yend;
689
 
  int i, j;
690
 
  int alpha_offset;
691
 
  guchar alpha_byte;
692
 
  guchar volatile l_alpha_sum;
693
 
 
694
 
  alpha_offset = 0;
695
 
  has_alpha = 0;
696
 
  src = NULL;
697
 
  temp = NULL;
698
 
  data = NULL;
699
 
  l_alpha_sum = 0xff;
700
 
 
701
 
  drawable = gimp_drawable_get (drawable_ID);
702
 
  drawable_type = gimp_drawable_type (drawable_ID);
703
 
  switch (drawable_type)
704
 
  {
705
 
    case GIMP_RGB_IMAGE:
706
 
    case GIMP_GRAY_IMAGE:
707
 
      if(save_mode == JSVM_ALPHA)
708
 
        return FALSE;              /* there is no alpha to save */
709
 
      break;
710
 
    case GIMP_RGBA_IMAGE:
711
 
    case GIMP_GRAYA_IMAGE:
712
 
      break;
713
 
 
714
 
    case GIMP_INDEXED_IMAGE:
715
 
      /*g_message ("jpeg: cannot operate on indexed color images");*/
716
 
      return FALSE;
717
 
      break;
718
 
    default:
719
 
      /*g_message ("jpeg: cannot operate on unknown image types");*/
720
 
      return FALSE;
721
 
      break;
722
 
  }
723
 
 
724
 
 
725
 
 
726
 
  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
727
 
 
728
 
 
729
 
  /* Step 1: allocate and initialize JPEG compression object */
730
 
 
731
 
  /* We have to set up the error handler first, in case the initialization
732
 
   * step fails.  (Unlikely, but it could happen if you are out of memory.)
733
 
   * This routine fills in the contents of struct jerr, and returns jerr's
734
 
   * address which we place into the link field in cinfo.
735
 
   */
736
 
  cinfo.err = jpeg_std_error (&jerr.pub);
737
 
  jerr.pub.error_exit = my_error_exit;
738
 
 
739
 
  outfile = NULL;
740
 
  /* Establish the setjmp return context for my_error_exit to use. */
741
 
  if (setjmp (jerr.setjmp_buffer))
742
 
    {
743
 
      /* If we get here, the JPEG code has signaled an error.
744
 
       * We need to clean up the JPEG object, close the input file, and return.
745
 
       */
746
 
      jpeg_destroy_compress (&cinfo);
747
 
      if (outfile)
748
 
        fclose (outfile);
749
 
      if (drawable)
750
 
        gimp_drawable_detach (drawable);
751
 
 
752
 
      return FALSE;
753
 
    }
754
 
 
755
 
  /* Now we can initialize the JPEG compression object. */
756
 
  jpeg_create_compress (&cinfo);
757
 
 
758
 
  /* Step 2: specify data destination (eg, a file) */
759
 
  /* Note: steps 2 and 3 can be done in either order. */
760
 
 
761
 
  /* Here we use the library-supplied code to send compressed data to a
762
 
   * stdio stream.  You can also write your own code to do something else.
763
 
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
764
 
   * requires it in order to write binary files.
765
 
   */
766
 
  if ((outfile = g_fopen (filename, "wb")) == NULL)
767
 
    {
768
 
      g_message ("can't open %s\n", filename);
769
 
      return FALSE;
770
 
    }
771
 
  jpeg_stdio_dest (&cinfo, outfile);
772
 
 
773
 
  /* Get the input image and a pointer to its data.
774
 
   */
775
 
  switch (drawable_type)
776
 
  {
777
 
    case GIMP_RGB_IMAGE:
778
 
    case GIMP_GRAY_IMAGE:
779
 
      /* # of color components per pixel */
780
 
      cinfo.input_components = drawable->bpp;
781
 
      has_alpha = 0;
782
 
      alpha_offset = 0;
783
 
      break;
784
 
    case GIMP_RGBA_IMAGE:
785
 
    case GIMP_GRAYA_IMAGE:
786
 
      if(save_mode == JSVM_ALPHA)
787
 
      {
788
 
        cinfo.input_components = 1;
789
 
      }
790
 
      else
791
 
      {
792
 
        /* # of color components per pixel (minus the GIMP alpha channel) */
793
 
        cinfo.input_components = drawable->bpp - 1;
794
 
      }
795
 
      alpha_offset = drawable->bpp -1;
796
 
      has_alpha = 1;
797
 
      break;
798
 
    default:
799
 
      return FALSE;
800
 
      break;
801
 
  }
802
 
 
803
 
  /* Step 3: set parameters for compression */
804
 
 
805
 
  /* First we supply a description of the input image.
806
 
   * Four fields of the cinfo struct must be filled in:
807
 
   */
808
 
  /* image width and height, in pixels */
809
 
  cinfo.image_width = drawable->width;
810
 
  cinfo.image_height = drawable->height;
811
 
  /* colorspace of input image */
812
 
  cinfo.in_color_space = ( (save_mode != JSVM_ALPHA) &&
813
 
                          (drawable_type == GIMP_RGB_IMAGE ||
814
 
                           drawable_type == GIMP_RGBA_IMAGE))
815
 
    ? JCS_RGB : JCS_GRAYSCALE;
816
 
  /* Now use the library's routine to set default compression parameters.
817
 
   * (You must set at least cinfo.in_color_space before calling this,
818
 
   * since the defaults depend on the source color space.)
819
 
   */
820
 
  jpeg_set_defaults (&cinfo);
821
 
  /* Now you can set any non-default parameters you wish to.
822
 
   * Here we just illustrate the use of quality (quantization table) scaling:
823
 
   */
824
 
  jpeg_set_quality (&cinfo, (int) (jsvals->quality * 100), TRUE /* limit to baseline-JPEG values */);
825
 
  cinfo.smoothing_factor = (int) (jsvals->smoothing * 100);
826
 
  cinfo.optimize_coding = jsvals->optimize;
827
 
 
828
 
  /* Step 4: Start compressor */
829
 
 
830
 
  /* TRUE ensures that we will write a complete interchange-JPEG file.
831
 
   * Pass TRUE unless you are very sure of what you're doing.
832
 
   */
833
 
  jpeg_start_compress (&cinfo, TRUE);
834
 
 
835
 
  /* Step 5: while (scan lines remain to be written) */
836
 
  /*           jpeg_write_scanlines(...); */
837
 
 
838
 
  /* Here we use the library's state variable cinfo.next_scanline as the
839
 
   * loop counter, so that we don't have to keep track ourselves.
840
 
   * To keep things simple, we pass one scanline per call; you can pass
841
 
   * more if you wish, though.
842
 
   */
843
 
  /* JSAMPLEs per row in image_buffer */
844
 
  rowstride = drawable->bpp * drawable->width;
845
 
  temp = (guchar *) g_malloc (cinfo.image_width * cinfo.input_components);
846
 
  data = (guchar *) g_malloc (rowstride * gimp_tile_height ());
847
 
  src = data;
848
 
 
849
 
  while (cinfo.next_scanline < cinfo.image_height)
850
 
  {
851
 
      if ((cinfo.next_scanline % gimp_tile_height ()) == 0)
852
 
      {
853
 
          yend = cinfo.next_scanline + gimp_tile_height ();
854
 
          yend = MIN (yend, cinfo.image_height);
855
 
          gimp_pixel_rgn_get_rect (&pixel_rgn, data, 0, cinfo.next_scanline, cinfo.image_width,
856
 
                                   (yend - cinfo.next_scanline));
857
 
          src = data;
858
 
      }
859
 
 
860
 
      t = temp;
861
 
      s = src;
862
 
      i = cinfo.image_width;
863
 
 
864
 
      switch(save_mode)
865
 
      {
866
 
        case JSVM_DRAWABLE:
867
 
            if(jsvals->clr_transparent)
868
 
            {
869
 
              /* save drawable (clear pixels where alpha is full transparent) */
870
 
              while (i--)
871
 
              {
872
 
                  alpha_byte = s[cinfo.input_components];
873
 
                  for (j = 0; j < cinfo.input_components; j++)
874
 
                  {
875
 
                     if(alpha_byte != 0) { *t++ = *s++;   }
876
 
                     else                { *t++ = 0; s++; }
877
 
                  }
878
 
                  if (has_alpha)  /* ignore alpha channel */
879
 
                  {
880
 
                    s++;
881
 
                  }
882
 
              }
883
 
            }
884
 
            else
885
 
            {
886
 
              /* save the drawable as it is (ignore alpha channel) */
887
 
              while (i--)
888
 
              {
889
 
                  for (j = 0; j < cinfo.input_components; j++)
890
 
                  {
891
 
                    *t++ = *s++;
892
 
                  }
893
 
                  if (has_alpha)  /* ignore alpha channel */
894
 
                  {
895
 
                    s++;
896
 
                  }
897
 
              }
898
 
            }
899
 
            break;
900
 
        case JSVM_ALPHA:
901
 
            /* save the drawable's alpha cahnnel */
902
 
            while (i--)
903
 
            {
904
 
                s += alpha_offset;
905
 
                l_alpha_sum &= (*s);  /* check all alpha bytes for full opacity */
906
 
                *t++ = *s++;
907
 
            }
908
 
            break;
909
 
      }
910
 
 
911
 
      src += rowstride;
912
 
      jpeg_write_scanlines (&cinfo, (JSAMPARRAY) &temp, 1);
913
 
 
914
 
      if ((cinfo.next_scanline % 5) == 0)
915
 
        gimp_progress_update ((double) cinfo.next_scanline / (double) cinfo.image_height);
916
 
  }
917
 
 
918
 
  /* Step 6: Finish compression */
919
 
  jpeg_finish_compress (&cinfo);
920
 
  /* After finish_compress, we can close the output file. */
921
 
  fclose (outfile);
922
 
 
923
 
  if((save_mode == JSVM_ALPHA) && (l_alpha_sum == 0xff))
924
 
  {
925
 
    /* all bytes in the alpha channel are set to 0xff
926
 
     * == full opaque image. We can remove the file
927
 
     * to save diskspace
928
 
     */
929
 
    g_remove(filename);
930
 
  }
931
 
 
932
 
  /* Step 7: release JPEG compression object */
933
 
 
934
 
  /* This is an important step since it will release a good deal of memory. */
935
 
  jpeg_destroy_compress (&cinfo);
936
 
  /* free the temporary buffer */
937
 
  g_free (temp);
938
 
  g_free (data);
939
 
 
940
 
  gimp_drawable_detach (drawable);
941
 
 
942
 
  return TRUE;
943
 
}       /* end xjpg_save_drawable */