~ubuntu-branches/ubuntu/natty/eog/natty

« back to all changes in this revision

Viewing changes to jpegutils/transupp.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-05-20 15:09:47 UTC
  • mfrom: (1.14.6 upstream) (2.1.9 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100520150947-esb0vjp9p72g74qt
Tags: 2.30.1-1ubuntu1
* Resync on Debian
* debian/control.in, 
  debian/rules:
  - build with python
* debian/control.in,
  debian/patches/01_lpi.patch,
  debian/patches/99_autoconf.patch:
  - launchpad integration changes
* debian/patches/02_toolbar_edit_button.patch:
  - change by Ryan Lortie to add an edit button to the toolbar
  - set /apps/eog/ui/external_editor to f-spot-viewer, it can't do editing
    right now but that will be changed in lucid

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
 
 
3
 
/*
4
 
 *  GThumb
5
 
 *
6
 
 *  Copyright (C) 2001, 2002 The Free Software Foundation, Inc.
7
 
 *
8
 
 *  This program is free software; you can redistribute it and/or modify
9
 
 *  it under the terms of the GNU General Public License as published by
10
 
 *  the Free Software Foundation; either version 2 of the License, or
11
 
 *  (at your option) any later version.
12
 
 *
13
 
 *  This program is distributed in the hope that it will be useful,
14
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 *  GNU General Public License for more details.
17
 
 *
18
 
 *  You should have received a copy of the GNU General Public License
19
 
 *  along with this program; if not, write to the Free Software
20
 
 *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
21
 
 */
22
 
 
23
 
/* based upon file transupp.c from the libjpeg package, original copyright 
24
 
 * note follows:
25
 
.*
26
 
 *
27
 
 * transupp.c
28
 
 *
29
 
 * Copyright (C) 1997, Thomas G. Lane.
30
 
 * This file is part of the Independent JPEG Group's software.
31
 
 * For conditions of distribution and use, see the accompanying README file.
32
 
 *
33
 
 * This file contains image transformation routines and other utility code
34
 
 * used by the jpegtran sample application.  These are NOT part of the core
35
 
 * JPEG library.  But we keep these routines separate from jpegtran.c to
36
 
 * ease the task of maintaining jpegtran-like programs that have other user
37
 
 * interfaces.
38
 
 */
39
 
 
40
 
#include <config.h>
41
 
 
42
 
#ifdef HAVE_LIBJPEG
43
 
 
44
 
#define SAVE_MARKERS_SUPPORTED 1
45
 
 
46
 
#include <stdio.h>
47
 
#include <jpeglib.h>
48
 
#include "transupp.h"           /* My own external interface */
49
 
 
50
 
#ifndef MAX
51
 
#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
52
 
#endif
53
 
 
54
 
enum {
55
 
  JERR_CONVERSION_NOTIMPL
56
 
};
57
 
 
58
 
#define ERREXIT(cinfo,code)  \
59
 
  ((cinfo)->err->msg_code = (code), \
60
 
   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
61
 
 
62
 
 
63
 
static long
64
 
jround_up (long a, long b)
65
 
/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
66
 
/* Assumes a >= 0, b > 0 */
67
 
{
68
 
  a += b - 1L;
69
 
  return a - (a % b);
70
 
}
71
 
 
72
 
 
73
 
static void
74
 
jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
75
 
                 JDIMENSION num_blocks)
76
 
/* Copy a row of coefficient blocks from one place to another. */
77
 
{
78
 
  register JCOEFPTR inptr, outptr;
79
 
  register long count;
80
 
 
81
 
  inptr = (JCOEFPTR) input_row;
82
 
  outptr = (JCOEFPTR) output_row;
83
 
  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
84
 
    *outptr++ = *inptr++;
85
 
  }
86
 
}
87
 
 
88
 
 
89
 
/*
90
 
 * Lossless image transformation routines.  These routines work on DCT
91
 
 * coefficient arrays and thus do not require any lossy decompression
92
 
 * or recompression of the image.
93
 
 * Thanks to Guido Vollbeding for the initial design and code of this feature.
94
 
 *
95
 
 * Horizontal flipping is done in-place, using a single top-to-bottom
96
 
 * pass through the virtual source array.  It will thus be much the
97
 
 * fastest option for images larger than main memory.
98
 
 *
99
 
 * The other routines require a set of destination virtual arrays, so they
100
 
 * need twice as much memory as jpegtran normally does.  The destination
101
 
 * arrays are always written in normal scan order (top to bottom) because
102
 
 * the virtual array manager expects this.  The source arrays will be scanned
103
 
 * in the corresponding order, which means multiple passes through the source
104
 
 * arrays for most of the transforms.  That could result in much thrashing
105
 
 * if the image is larger than main memory.
106
 
 *
107
 
 * Some notes about the operating environment of the individual transform
108
 
 * routines:
109
 
 * 1. Both the source and destination virtual arrays are allocated from the
110
 
 *    source JPEG object, and therefore should be manipulated by calling the
111
 
 *    source's memory manager.
112
 
 * 2. The destination's component count should be used.  It may be smaller
113
 
 *    than the source's when forcing to grayscale.
114
 
 * 3. Likewise the destination's sampling factors should be used.  When
115
 
 *    forcing to grayscale the destination's sampling factors will be all 1,
116
 
 *    and we may as well take that as the effective iMCU size.
117
 
 * 4. When "trim" is in effect, the destination's dimensions will be the
118
 
 *    trimmed values but the source's will be untrimmed.
119
 
 * 5. All the routines assume that the source and destination buffers are
120
 
 *    padded out to a full iMCU boundary.  This is true, although for the
121
 
 *    source buffer it is an undocumented property of jdcoefct.c.
122
 
 * Notes 2,3,4 boil down to this: generally we should use the destination's
123
 
 * dimensions and ignore the source's.
124
 
 */
125
 
 
126
 
 
127
 
static void
128
 
do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
129
 
           jvirt_barray_ptr *src_coef_arrays)
130
 
/* Horizontal flip; done in-place, so no separate dest array is required */
131
 
{
132
 
  JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
133
 
  int ci, k, offset_y;
134
 
  JBLOCKARRAY buffer;
135
 
  JCOEFPTR ptr1, ptr2;
136
 
  JCOEF temp1, temp2;
137
 
  jpeg_component_info *compptr;
138
 
 
139
 
  /* Horizontal mirroring of DCT blocks is accomplished by swapping
140
 
   * pairs of blocks in-place.  Within a DCT block, we perform horizontal
141
 
   * mirroring by changing the signs of odd-numbered columns.
142
 
   * Partial iMCUs at the right edge are left untouched.
143
 
   */
144
 
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
145
 
 
146
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
147
 
    compptr = dstinfo->comp_info + ci;
148
 
    comp_width = MCU_cols * compptr->h_samp_factor;
149
 
    for (blk_y = 0; blk_y < compptr->height_in_blocks;
150
 
         blk_y += compptr->v_samp_factor) {
151
 
      buffer = (*srcinfo->mem->access_virt_barray)
152
 
        ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
153
 
         (JDIMENSION) compptr->v_samp_factor, TRUE);
154
 
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
155
 
        for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
156
 
          ptr1 = buffer[offset_y][blk_x];
157
 
          ptr2 = buffer[offset_y][comp_width - blk_x - 1];
158
 
          /* this unrolled loop doesn't need to know which row it's on... */
159
 
          for (k = 0; k < DCTSIZE2; k += 2) {
160
 
            temp1 = *ptr1;      /* swap even column */
161
 
            temp2 = *ptr2;
162
 
            *ptr1++ = temp2;
163
 
            *ptr2++ = temp1;
164
 
            temp1 = *ptr1;      /* swap odd column with sign change */
165
 
            temp2 = *ptr2;
166
 
            *ptr1++ = -temp2;
167
 
            *ptr2++ = -temp1;
168
 
          }
169
 
        }
170
 
      }
171
 
    }
172
 
  }
173
 
}
174
 
 
175
 
 
176
 
static void
177
 
do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
178
 
           jvirt_barray_ptr *src_coef_arrays,
179
 
           jvirt_barray_ptr *dst_coef_arrays)
180
 
/* Vertical flip */
181
 
{
182
 
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
183
 
  int ci, i, j, offset_y;
184
 
  JBLOCKARRAY src_buffer, dst_buffer;
185
 
  JBLOCKROW src_row_ptr, dst_row_ptr;
186
 
  JCOEFPTR src_ptr, dst_ptr;
187
 
  jpeg_component_info *compptr;
188
 
 
189
 
  /* We output into a separate array because we can't touch different
190
 
   * rows of the source virtual array simultaneously.  Otherwise, this
191
 
   * is a pretty straightforward analog of horizontal flip.
192
 
   * Within a DCT block, vertical mirroring is done by changing the signs
193
 
   * of odd-numbered rows.
194
 
   * Partial iMCUs at the bottom edge are copied verbatim.
195
 
   */
196
 
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
197
 
 
198
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
199
 
    compptr = dstinfo->comp_info + ci;
200
 
    comp_height = MCU_rows * compptr->v_samp_factor;
201
 
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
202
 
         dst_blk_y += compptr->v_samp_factor) {
203
 
      dst_buffer = (*srcinfo->mem->access_virt_barray)
204
 
        ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
205
 
         (JDIMENSION) compptr->v_samp_factor, TRUE);
206
 
      if (dst_blk_y < comp_height) {
207
 
        /* Row is within the mirrorable area. */
208
 
        src_buffer = (*srcinfo->mem->access_virt_barray)
209
 
          ((j_common_ptr) srcinfo, src_coef_arrays[ci],
210
 
           comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
211
 
           (JDIMENSION) compptr->v_samp_factor, FALSE);
212
 
      } else {
213
 
        /* Bottom-edge blocks will be copied verbatim. */
214
 
        src_buffer = (*srcinfo->mem->access_virt_barray)
215
 
          ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
216
 
           (JDIMENSION) compptr->v_samp_factor, FALSE);
217
 
      }
218
 
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
219
 
        if (dst_blk_y < comp_height) {
220
 
          /* Row is within the mirrorable area. */
221
 
          dst_row_ptr = dst_buffer[offset_y];
222
 
          src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
223
 
          for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
224
 
               dst_blk_x++) {
225
 
            dst_ptr = dst_row_ptr[dst_blk_x];
226
 
            src_ptr = src_row_ptr[dst_blk_x];
227
 
            for (i = 0; i < DCTSIZE; i += 2) {
228
 
              /* copy even row */
229
 
              for (j = 0; j < DCTSIZE; j++)
230
 
                *dst_ptr++ = *src_ptr++;
231
 
              /* copy odd row with sign change */
232
 
              for (j = 0; j < DCTSIZE; j++)
233
 
                *dst_ptr++ = - *src_ptr++;
234
 
            }
235
 
          }
236
 
        } else {
237
 
          /* Just copy row verbatim. */
238
 
          jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
239
 
                          compptr->width_in_blocks);
240
 
        }
241
 
      }
242
 
    }
243
 
  }
244
 
}
245
 
 
246
 
 
247
 
static void
248
 
do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
249
 
              jvirt_barray_ptr *src_coef_arrays,
250
 
              jvirt_barray_ptr *dst_coef_arrays)
251
 
/* Transpose source into destination */
252
 
{
253
 
  JDIMENSION dst_blk_x, dst_blk_y;
254
 
  int ci, i, j, offset_x, offset_y;
255
 
  JBLOCKARRAY src_buffer, dst_buffer;
256
 
  JCOEFPTR src_ptr, dst_ptr;
257
 
  jpeg_component_info *compptr;
258
 
 
259
 
  /* Transposing pixels within a block just requires transposing the
260
 
   * DCT coefficients.
261
 
   * Partial iMCUs at the edges require no special treatment; we simply
262
 
   * process all the available DCT blocks for every component.
263
 
   */
264
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
265
 
    compptr = dstinfo->comp_info + ci;
266
 
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
267
 
         dst_blk_y += compptr->v_samp_factor) {
268
 
      dst_buffer = (*srcinfo->mem->access_virt_barray)
269
 
        ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
270
 
         (JDIMENSION) compptr->v_samp_factor, TRUE);
271
 
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
272
 
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
273
 
             dst_blk_x += compptr->h_samp_factor) {
274
 
          src_buffer = (*srcinfo->mem->access_virt_barray)
275
 
            ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
276
 
             (JDIMENSION) compptr->h_samp_factor, FALSE);
277
 
          for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
278
 
            src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
279
 
            dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
280
 
            for (i = 0; i < DCTSIZE; i++)
281
 
              for (j = 0; j < DCTSIZE; j++)
282
 
                dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
283
 
          }
284
 
        }
285
 
      }
286
 
    }
287
 
  }
288
 
}
289
 
 
290
 
 
291
 
static void
292
 
do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
293
 
           jvirt_barray_ptr *src_coef_arrays,
294
 
           jvirt_barray_ptr *dst_coef_arrays)
295
 
/* 90 degree rotation is equivalent to
296
 
 *   1. Transposing the image;
297
 
 *   2. Horizontal mirroring.
298
 
 * These two steps are merged into a single processing routine.
299
 
 */
300
 
{
301
 
  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
302
 
  int ci, i, j, offset_x, offset_y;
303
 
  JBLOCKARRAY src_buffer, dst_buffer;
304
 
  JCOEFPTR src_ptr, dst_ptr;
305
 
  jpeg_component_info *compptr;
306
 
 
307
 
  /* Because of the horizontal mirror step, we can't process partial iMCUs
308
 
   * at the (output) right edge properly.  They just get transposed and
309
 
   * not mirrored.
310
 
   */
311
 
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
312
 
 
313
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
314
 
    compptr = dstinfo->comp_info + ci;
315
 
    comp_width = MCU_cols * compptr->h_samp_factor;
316
 
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
317
 
         dst_blk_y += compptr->v_samp_factor) {
318
 
      dst_buffer = (*srcinfo->mem->access_virt_barray)
319
 
        ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
320
 
         (JDIMENSION) compptr->v_samp_factor, TRUE);
321
 
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
322
 
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
323
 
             dst_blk_x += compptr->h_samp_factor) {
324
 
          src_buffer = (*srcinfo->mem->access_virt_barray)
325
 
            ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
326
 
             (JDIMENSION) compptr->h_samp_factor, FALSE);
327
 
          for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
328
 
            src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
329
 
            if (dst_blk_x < comp_width) {
330
 
              /* Block is within the mirrorable area. */
331
 
              dst_ptr = dst_buffer[offset_y]
332
 
                [comp_width - dst_blk_x - offset_x - 1];
333
 
              for (i = 0; i < DCTSIZE; i++) {
334
 
                for (j = 0; j < DCTSIZE; j++)
335
 
                  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
336
 
                i++;
337
 
                for (j = 0; j < DCTSIZE; j++)
338
 
                  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
339
 
              }
340
 
            } else {
341
 
              /* Edge blocks are transposed but not mirrored. */
342
 
              dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
343
 
              for (i = 0; i < DCTSIZE; i++)
344
 
                for (j = 0; j < DCTSIZE; j++)
345
 
                  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
346
 
            }
347
 
          }
348
 
        }
349
 
      }
350
 
    }
351
 
  }
352
 
}
353
 
 
354
 
 
355
 
static void
356
 
do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
357
 
            jvirt_barray_ptr *src_coef_arrays,
358
 
            jvirt_barray_ptr *dst_coef_arrays)
359
 
/* 270 degree rotation is equivalent to
360
 
 *   1. Horizontal mirroring;
361
 
 *   2. Transposing the image.
362
 
 * These two steps are merged into a single processing routine.
363
 
 */
364
 
{
365
 
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
366
 
  int ci, i, j, offset_x, offset_y;
367
 
  JBLOCKARRAY src_buffer, dst_buffer;
368
 
  JCOEFPTR src_ptr, dst_ptr;
369
 
  jpeg_component_info *compptr;
370
 
 
371
 
  /* Because of the horizontal mirror step, we can't process partial iMCUs
372
 
   * at the (output) bottom edge properly.  They just get transposed and
373
 
   * not mirrored.
374
 
   */
375
 
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
376
 
 
377
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
378
 
    compptr = dstinfo->comp_info + ci;
379
 
    comp_height = MCU_rows * compptr->v_samp_factor;
380
 
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
381
 
         dst_blk_y += compptr->v_samp_factor) {
382
 
      dst_buffer = (*srcinfo->mem->access_virt_barray)
383
 
        ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
384
 
         (JDIMENSION) compptr->v_samp_factor, TRUE);
385
 
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
386
 
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
387
 
             dst_blk_x += compptr->h_samp_factor) {
388
 
          src_buffer = (*srcinfo->mem->access_virt_barray)
389
 
            ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
390
 
             (JDIMENSION) compptr->h_samp_factor, FALSE);
391
 
          for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
392
 
            dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
393
 
            if (dst_blk_y < comp_height) {
394
 
              /* Block is within the mirrorable area. */
395
 
              src_ptr = src_buffer[offset_x]
396
 
                [comp_height - dst_blk_y - offset_y - 1];
397
 
              for (i = 0; i < DCTSIZE; i++) {
398
 
                for (j = 0; j < DCTSIZE; j++) {
399
 
                  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
400
 
                  j++;
401
 
                  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
402
 
                }
403
 
              }
404
 
            } else {
405
 
              /* Edge blocks are transposed but not mirrored. */
406
 
              src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
407
 
              for (i = 0; i < DCTSIZE; i++)
408
 
                for (j = 0; j < DCTSIZE; j++)
409
 
                  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
410
 
            }
411
 
          }
412
 
        }
413
 
      }
414
 
    }
415
 
  }
416
 
}
417
 
 
418
 
 
419
 
static void
420
 
do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
421
 
            jvirt_barray_ptr *src_coef_arrays,
422
 
            jvirt_barray_ptr *dst_coef_arrays)
423
 
/* 180 degree rotation is equivalent to
424
 
 *   1. Vertical mirroring;
425
 
 *   2. Horizontal mirroring.
426
 
 * These two steps are merged into a single processing routine.
427
 
 */
428
 
{
429
 
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
430
 
  int ci, i, j, offset_y;
431
 
  JBLOCKARRAY src_buffer, dst_buffer;
432
 
  JBLOCKROW src_row_ptr, dst_row_ptr;
433
 
  JCOEFPTR src_ptr, dst_ptr;
434
 
  jpeg_component_info *compptr;
435
 
 
436
 
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
437
 
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
438
 
 
439
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
440
 
    compptr = dstinfo->comp_info + ci;
441
 
    comp_width = MCU_cols * compptr->h_samp_factor;
442
 
    comp_height = MCU_rows * compptr->v_samp_factor;
443
 
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
444
 
         dst_blk_y += compptr->v_samp_factor) {
445
 
      dst_buffer = (*srcinfo->mem->access_virt_barray)
446
 
        ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
447
 
         (JDIMENSION) compptr->v_samp_factor, TRUE);
448
 
      if (dst_blk_y < comp_height) {
449
 
        /* Row is within the vertically mirrorable area. */
450
 
        src_buffer = (*srcinfo->mem->access_virt_barray)
451
 
          ((j_common_ptr) srcinfo, src_coef_arrays[ci],
452
 
           comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
453
 
           (JDIMENSION) compptr->v_samp_factor, FALSE);
454
 
      } else {
455
 
        /* Bottom-edge rows are only mirrored horizontally. */
456
 
        src_buffer = (*srcinfo->mem->access_virt_barray)
457
 
          ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
458
 
           (JDIMENSION) compptr->v_samp_factor, FALSE);
459
 
      }
460
 
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
461
 
        if (dst_blk_y < comp_height) {
462
 
          /* Row is within the mirrorable area. */
463
 
          dst_row_ptr = dst_buffer[offset_y];
464
 
          src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
465
 
          /* Process the blocks that can be mirrored both ways. */
466
 
          for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
467
 
            dst_ptr = dst_row_ptr[dst_blk_x];
468
 
            src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
469
 
            for (i = 0; i < DCTSIZE; i += 2) {
470
 
              /* For even row, negate every odd column. */
471
 
              for (j = 0; j < DCTSIZE; j += 2) {
472
 
                *dst_ptr++ = *src_ptr++;
473
 
                *dst_ptr++ = - *src_ptr++;
474
 
              }
475
 
              /* For odd row, negate every even column. */
476
 
              for (j = 0; j < DCTSIZE; j += 2) {
477
 
                *dst_ptr++ = - *src_ptr++;
478
 
                *dst_ptr++ = *src_ptr++;
479
 
              }
480
 
            }
481
 
          }
482
 
          /* Any remaining right-edge blocks are only mirrored vertically. */
483
 
          for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
484
 
            dst_ptr = dst_row_ptr[dst_blk_x];
485
 
            src_ptr = src_row_ptr[dst_blk_x];
486
 
            for (i = 0; i < DCTSIZE; i += 2) {
487
 
              for (j = 0; j < DCTSIZE; j++)
488
 
                *dst_ptr++ = *src_ptr++;
489
 
              for (j = 0; j < DCTSIZE; j++)
490
 
                *dst_ptr++ = - *src_ptr++;
491
 
            }
492
 
          }
493
 
        } else {
494
 
          /* Remaining rows are just mirrored horizontally. */
495
 
          dst_row_ptr = dst_buffer[offset_y];
496
 
          src_row_ptr = src_buffer[offset_y];
497
 
          /* Process the blocks that can be mirrored. */
498
 
          for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
499
 
            dst_ptr = dst_row_ptr[dst_blk_x];
500
 
            src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
501
 
            for (i = 0; i < DCTSIZE2; i += 2) {
502
 
              *dst_ptr++ = *src_ptr++;
503
 
              *dst_ptr++ = - *src_ptr++;
504
 
            }
505
 
          }
506
 
          /* Any remaining right-edge blocks are only copied. */
507
 
          for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
508
 
            dst_ptr = dst_row_ptr[dst_blk_x];
509
 
            src_ptr = src_row_ptr[dst_blk_x];
510
 
            for (i = 0; i < DCTSIZE2; i++)
511
 
              *dst_ptr++ = *src_ptr++;
512
 
          }
513
 
        }
514
 
      }
515
 
    }
516
 
  }
517
 
}
518
 
 
519
 
 
520
 
static void
521
 
do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
522
 
               jvirt_barray_ptr *src_coef_arrays,
523
 
               jvirt_barray_ptr *dst_coef_arrays)
524
 
/* Transverse transpose is equivalent to
525
 
 *   1. 180 degree rotation;
526
 
 *   2. Transposition;
527
 
 * or
528
 
 *   1. Horizontal mirroring;
529
 
 *   2. Transposition;
530
 
 *   3. Horizontal mirroring.
531
 
 * These steps are merged into a single processing routine.
532
 
 */
533
 
{
534
 
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
535
 
  int ci, i, j, offset_x, offset_y;
536
 
  JBLOCKARRAY src_buffer, dst_buffer;
537
 
  JCOEFPTR src_ptr, dst_ptr;
538
 
  jpeg_component_info *compptr;
539
 
 
540
 
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
541
 
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
542
 
 
543
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
544
 
    compptr = dstinfo->comp_info + ci;
545
 
    comp_width = MCU_cols * compptr->h_samp_factor;
546
 
    comp_height = MCU_rows * compptr->v_samp_factor;
547
 
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
548
 
         dst_blk_y += compptr->v_samp_factor) {
549
 
      dst_buffer = (*srcinfo->mem->access_virt_barray)
550
 
        ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
551
 
         (JDIMENSION) compptr->v_samp_factor, TRUE);
552
 
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
553
 
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
554
 
             dst_blk_x += compptr->h_samp_factor) {
555
 
          src_buffer = (*srcinfo->mem->access_virt_barray)
556
 
            ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
557
 
             (JDIMENSION) compptr->h_samp_factor, FALSE);
558
 
          for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
559
 
            if (dst_blk_y < comp_height) {
560
 
              src_ptr = src_buffer[offset_x]
561
 
                [comp_height - dst_blk_y - offset_y - 1];
562
 
              if (dst_blk_x < comp_width) {
563
 
                /* Block is within the mirrorable area. */
564
 
                dst_ptr = dst_buffer[offset_y]
565
 
                  [comp_width - dst_blk_x - offset_x - 1];
566
 
                for (i = 0; i < DCTSIZE; i++) {
567
 
                  for (j = 0; j < DCTSIZE; j++) {
568
 
                    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
569
 
                    j++;
570
 
                    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
571
 
                  }
572
 
                  i++;
573
 
                  for (j = 0; j < DCTSIZE; j++) {
574
 
                    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
575
 
                    j++;
576
 
                    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
577
 
                  }
578
 
                }
579
 
              } else {
580
 
                /* Right-edge blocks are mirrored in y only */
581
 
                dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
582
 
                for (i = 0; i < DCTSIZE; i++) {
583
 
                  for (j = 0; j < DCTSIZE; j++) {
584
 
                    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
585
 
                    j++;
586
 
                    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
587
 
                  }
588
 
                }
589
 
              }
590
 
            } else {
591
 
              src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
592
 
              if (dst_blk_x < comp_width) {
593
 
                /* Bottom-edge blocks are mirrored in x only */
594
 
                dst_ptr = dst_buffer[offset_y]
595
 
                  [comp_width - dst_blk_x - offset_x - 1];
596
 
                for (i = 0; i < DCTSIZE; i++) {
597
 
                  for (j = 0; j < DCTSIZE; j++)
598
 
                    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
599
 
                  i++;
600
 
                  for (j = 0; j < DCTSIZE; j++)
601
 
                    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
602
 
                }
603
 
              } else {
604
 
                /* At lower right corner, just transpose, no mirroring */
605
 
                dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
606
 
                for (i = 0; i < DCTSIZE; i++)
607
 
                  for (j = 0; j < DCTSIZE; j++)
608
 
                    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
609
 
              }
610
 
            }
611
 
          }
612
 
        }
613
 
      }
614
 
    }
615
 
  }
616
 
}
617
 
 
618
 
 
619
 
/* Request any required workspace.
620
 
 *
621
 
 * We allocate the workspace virtual arrays from the source decompression
622
 
 * object, so that all the arrays (both the original data and the workspace)
623
 
 * will be taken into account while making memory management decisions.
624
 
 * Hence, this routine must be called after jpeg_read_header (which reads
625
 
 * the image dimensions) and before jpeg_read_coefficients (which realizes
626
 
 * the source's virtual arrays).
627
 
 */
628
 
 
629
 
void
630
 
jtransform_request_workspace (j_decompress_ptr srcinfo,
631
 
                              jpeg_transform_info *info)
632
 
{
633
 
  jvirt_barray_ptr *coef_arrays = NULL;
634
 
  jpeg_component_info *compptr;
635
 
  int ci;
636
 
 
637
 
  if (info->force_grayscale &&
638
 
      srcinfo->jpeg_color_space == JCS_YCbCr &&
639
 
      srcinfo->num_components == 3) {
640
 
    /* We'll only process the first component */
641
 
    info->num_components = 1;
642
 
  } else {
643
 
    /* Process all the components */
644
 
    info->num_components = srcinfo->num_components;
645
 
  }
646
 
 
647
 
  switch (info->transform) {
648
 
  case JXFORM_NONE:
649
 
  case JXFORM_FLIP_H:
650
 
    /* Don't need a workspace array */
651
 
    break;
652
 
  case JXFORM_FLIP_V:
653
 
  case JXFORM_ROT_180:
654
 
    /* Need workspace arrays having same dimensions as source image.
655
 
     * Note that we allocate arrays padded out to the next iMCU boundary,
656
 
     * so that transform routines need not worry about missing edge blocks.
657
 
     */
658
 
    coef_arrays = (jvirt_barray_ptr *)
659
 
      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
660
 
        sizeof(jvirt_barray_ptr) * info->num_components);
661
 
    for (ci = 0; ci < info->num_components; ci++) {
662
 
      compptr = srcinfo->comp_info + ci;
663
 
      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
664
 
        ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
665
 
         (JDIMENSION) jround_up((long) compptr->width_in_blocks,
666
 
                                (long) compptr->h_samp_factor),
667
 
         (JDIMENSION) jround_up((long) compptr->height_in_blocks,
668
 
                                (long) compptr->v_samp_factor),
669
 
         (JDIMENSION) compptr->v_samp_factor);
670
 
    }
671
 
    break;
672
 
  case JXFORM_TRANSPOSE:
673
 
  case JXFORM_TRANSVERSE:
674
 
  case JXFORM_ROT_90:
675
 
  case JXFORM_ROT_270:
676
 
    /* Need workspace arrays having transposed dimensions.
677
 
     * Note that we allocate arrays padded out to the next iMCU boundary,
678
 
     * so that transform routines need not worry about missing edge blocks.
679
 
     */
680
 
    coef_arrays = (jvirt_barray_ptr *)
681
 
      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
682
 
        sizeof(jvirt_barray_ptr) * info->num_components);
683
 
    for (ci = 0; ci < info->num_components; ci++) {
684
 
      compptr = srcinfo->comp_info + ci;
685
 
      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
686
 
        ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
687
 
         (JDIMENSION) jround_up((long) compptr->height_in_blocks,
688
 
                                (long) compptr->v_samp_factor),
689
 
         (JDIMENSION) jround_up((long) compptr->width_in_blocks,
690
 
                                (long) compptr->h_samp_factor),
691
 
         (JDIMENSION) compptr->h_samp_factor);
692
 
    }
693
 
    break;
694
 
  }
695
 
  info->workspace_coef_arrays = coef_arrays;
696
 
}
697
 
 
698
 
 
699
 
/* Transpose destination image parameters */
700
 
 
701
 
static void
702
 
transpose_critical_parameters (j_compress_ptr dstinfo)
703
 
{
704
 
  int tblno, i, j, ci, itemp;
705
 
  jpeg_component_info *compptr;
706
 
  JQUANT_TBL *qtblptr;
707
 
  JDIMENSION dtemp;
708
 
  UINT16 qtemp;
709
 
 
710
 
  /* Transpose basic image dimensions */
711
 
  dtemp = dstinfo->image_width;
712
 
  dstinfo->image_width = dstinfo->image_height;
713
 
  dstinfo->image_height = dtemp;
714
 
 
715
 
  /* Transpose sampling factors */
716
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
717
 
    compptr = dstinfo->comp_info + ci;
718
 
    itemp = compptr->h_samp_factor;
719
 
    compptr->h_samp_factor = compptr->v_samp_factor;
720
 
    compptr->v_samp_factor = itemp;
721
 
  }
722
 
 
723
 
  /* Transpose quantization tables */
724
 
  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
725
 
    qtblptr = dstinfo->quant_tbl_ptrs[tblno];
726
 
    if (qtblptr != NULL) {
727
 
      for (i = 0; i < DCTSIZE; i++) {
728
 
        for (j = 0; j < i; j++) {
729
 
          qtemp = qtblptr->quantval[i*DCTSIZE+j];
730
 
          qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
731
 
          qtblptr->quantval[j*DCTSIZE+i] = qtemp;
732
 
        }
733
 
      }
734
 
    }
735
 
  }
736
 
}
737
 
 
738
 
 
739
 
/* Trim off any partial iMCUs on the indicated destination edge */
740
 
 
741
 
static void
742
 
trim_right_edge (j_compress_ptr dstinfo)
743
 
{
744
 
  int ci, max_h_samp_factor;
745
 
  JDIMENSION MCU_cols;
746
 
 
747
 
  /* We have to compute max_h_samp_factor ourselves,
748
 
   * because it hasn't been set yet in the destination
749
 
   * (and we don't want to use the source's value).
750
 
   */
751
 
  max_h_samp_factor = 1;
752
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
753
 
    int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor;
754
 
    max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor);
755
 
  }
756
 
  MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE);
757
 
  if (MCU_cols > 0)             /* can't trim to 0 pixels */
758
 
    dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE);
759
 
}
760
 
 
761
 
static void
762
 
trim_bottom_edge (j_compress_ptr dstinfo)
763
 
{
764
 
  int ci, max_v_samp_factor;
765
 
  JDIMENSION MCU_rows;
766
 
 
767
 
  /* We have to compute max_v_samp_factor ourselves,
768
 
   * because it hasn't been set yet in the destination
769
 
   * (and we don't want to use the source's value).
770
 
   */
771
 
  max_v_samp_factor = 1;
772
 
  for (ci = 0; ci < dstinfo->num_components; ci++) {
773
 
    int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor;
774
 
    max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor);
775
 
  }
776
 
  MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE);
777
 
  if (MCU_rows > 0)             /* can't trim to 0 pixels */
778
 
    dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE);
779
 
}
780
 
 
781
 
 
782
 
/* Adjust output image parameters as needed.
783
 
 *
784
 
 * This must be called after jpeg_copy_critical_parameters()
785
 
 * and before jpeg_write_coefficients().
786
 
 *
787
 
 * The return value is the set of virtual coefficient arrays to be written
788
 
 * (either the ones allocated by jtransform_request_workspace, or the
789
 
 * original source data arrays).  The caller will need to pass this value
790
 
 * to jpeg_write_coefficients().
791
 
 */
792
 
 
793
 
jvirt_barray_ptr *
794
 
jtransform_adjust_parameters (j_decompress_ptr srcinfo,
795
 
                              j_compress_ptr dstinfo,
796
 
                              jvirt_barray_ptr *src_coef_arrays,
797
 
                              jpeg_transform_info *info)
798
 
{
799
 
  /* If force-to-grayscale is requested, adjust destination parameters */
800
 
  if (info->force_grayscale) {
801
 
    /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
802
 
     * properly.  Among other things, the target h_samp_factor & v_samp_factor
803
 
     * will get set to 1, which typically won't match the source.
804
 
     * In fact we do this even if the source is already grayscale; that
805
 
     * provides an easy way of coercing a grayscale JPEG with funny sampling
806
 
     * factors to the customary 1,1.  (Some decoders fail on other factors.)
807
 
     */
808
 
    if ((dstinfo->jpeg_color_space == JCS_YCbCr &&
809
 
         dstinfo->num_components == 3) ||
810
 
        (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
811
 
         dstinfo->num_components == 1)) {
812
 
      /* We have to preserve the source's quantization table number. */
813
 
      int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
814
 
      jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
815
 
      dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
816
 
    } else {
817
 
      /* Sorry, can't do it */
818
 
      ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
819
 
    }
820
 
  }
821
 
 
822
 
  /* Correct the destination's image dimensions etc if necessary */
823
 
  switch (info->transform) {
824
 
  case JXFORM_NONE:
825
 
    /* Nothing to do */
826
 
    break;
827
 
  case JXFORM_FLIP_H:
828
 
    if (info->trim)
829
 
      trim_right_edge(dstinfo);
830
 
    break;
831
 
  case JXFORM_FLIP_V:
832
 
    if (info->trim)
833
 
      trim_bottom_edge(dstinfo);
834
 
    break;
835
 
  case JXFORM_TRANSPOSE:
836
 
    transpose_critical_parameters(dstinfo);
837
 
    /* transpose does NOT have to trim anything */
838
 
    break;
839
 
  case JXFORM_TRANSVERSE:
840
 
    transpose_critical_parameters(dstinfo);
841
 
    if (info->trim) {
842
 
      trim_right_edge(dstinfo);
843
 
      trim_bottom_edge(dstinfo);
844
 
    }
845
 
    break;
846
 
  case JXFORM_ROT_90:
847
 
    transpose_critical_parameters(dstinfo);
848
 
    if (info->trim)
849
 
      trim_right_edge(dstinfo);
850
 
    break;
851
 
  case JXFORM_ROT_180:
852
 
    if (info->trim) {
853
 
      trim_right_edge(dstinfo);
854
 
      trim_bottom_edge(dstinfo);
855
 
    }
856
 
    break;
857
 
  case JXFORM_ROT_270:
858
 
    transpose_critical_parameters(dstinfo);
859
 
    if (info->trim)
860
 
      trim_bottom_edge(dstinfo);
861
 
    break;
862
 
  }
863
 
 
864
 
  /* Return the appropriate output data set */
865
 
  if (info->workspace_coef_arrays != NULL)
866
 
    return info->workspace_coef_arrays;
867
 
  return src_coef_arrays;
868
 
}
869
 
 
870
 
 
871
 
/* Execute the actual transformation, if any.
872
 
 *
873
 
 * This must be called *after* jpeg_write_coefficients, because it depends
874
 
 * on jpeg_write_coefficients to have computed subsidiary values such as
875
 
 * the per-component width and height fields in the destination object.
876
 
 *
877
 
 * Note that some transformations will modify the source data arrays!
878
 
 */
879
 
 
880
 
void
881
 
jtransform_execute_transformation (j_decompress_ptr srcinfo,
882
 
                                   j_compress_ptr dstinfo,
883
 
                                   jvirt_barray_ptr *src_coef_arrays,
884
 
                                   jpeg_transform_info *info)
885
 
{
886
 
  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
887
 
 
888
 
  switch (info->transform) {
889
 
  case JXFORM_NONE:
890
 
    break;
891
 
  case JXFORM_FLIP_H:
892
 
    do_flip_h(srcinfo, dstinfo, src_coef_arrays);
893
 
    break;
894
 
  case JXFORM_FLIP_V:
895
 
    do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
896
 
    break;
897
 
  case JXFORM_TRANSPOSE:
898
 
    do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
899
 
    break;
900
 
  case JXFORM_TRANSVERSE:
901
 
    do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
902
 
    break;
903
 
  case JXFORM_ROT_90:
904
 
    do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
905
 
    break;
906
 
  case JXFORM_ROT_180:
907
 
    do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
908
 
    break;
909
 
  case JXFORM_ROT_270:
910
 
    do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
911
 
    break;
912
 
  }
913
 
}
914
 
 
915
 
 
916
 
/* Setup decompression object to save desired markers in memory.
917
 
 * This must be called before jpeg_read_header() to have the desired effect.
918
 
 */
919
 
 
920
 
void
921
 
jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
922
 
{
923
 
#ifdef SAVE_MARKERS_SUPPORTED
924
 
  int m;
925
 
 
926
 
  /* Save comments except under NONE option */
927
 
  if (option != JCOPYOPT_NONE) {
928
 
    jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
929
 
  }
930
 
  /* Save all types of APPn markers iff ALL option */
931
 
  if (option == JCOPYOPT_ALL) {
932
 
    for (m = 0; m < 16; m++)
933
 
      jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
934
 
  }
935
 
#endif /* SAVE_MARKERS_SUPPORTED */
936
 
}
937
 
 
938
 
/* Copy markers saved in the given source object to the destination object.
939
 
 * This should be called just after jpeg_start_compress() or
940
 
 * jpeg_write_coefficients().
941
 
 * Note that those routines will have written the SOI, and also the
942
 
 * JFIF APP0 or Adobe APP14 markers if selected.
943
 
 */
944
 
 
945
 
void
946
 
jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
947
 
                       JCOPY_OPTION option)
948
 
{
949
 
  jpeg_saved_marker_ptr marker;
950
 
 
951
 
  /* In the current implementation, we don't actually need to examine the
952
 
   * option flag here; we just copy everything that got saved.
953
 
   * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
954
 
   * if the encoder library already wrote one.
955
 
   */
956
 
  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
957
 
    if (dstinfo->write_JFIF_header &&
958
 
        marker->marker == JPEG_APP0 &&
959
 
        marker->data_length >= 5 &&
960
 
        GETJOCTET(marker->data[0]) == 0x4A &&
961
 
        GETJOCTET(marker->data[1]) == 0x46 &&
962
 
        GETJOCTET(marker->data[2]) == 0x49 &&
963
 
        GETJOCTET(marker->data[3]) == 0x46 &&
964
 
        GETJOCTET(marker->data[4]) == 0)
965
 
      continue;                 /* reject duplicate JFIF */
966
 
    if (dstinfo->write_Adobe_marker &&
967
 
        marker->marker == JPEG_APP0+14 &&
968
 
        marker->data_length >= 5 &&
969
 
        GETJOCTET(marker->data[0]) == 0x41 &&
970
 
        GETJOCTET(marker->data[1]) == 0x64 &&
971
 
        GETJOCTET(marker->data[2]) == 0x6F &&
972
 
        GETJOCTET(marker->data[3]) == 0x62 &&
973
 
        GETJOCTET(marker->data[4]) == 0x65)
974
 
      continue;                 /* reject duplicate Adobe */
975
 
 
976
 
#ifdef NEED_FAR_POINTERS
977
 
    /* We could use jpeg_write_marker if the data weren't FAR... */
978
 
    {
979
 
      unsigned int i;
980
 
      jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
981
 
      for (i = 0; i < marker->data_length; i++)
982
 
        jpeg_write_m_byte(dstinfo, marker->data[i]);
983
 
    }
984
 
#else
985
 
    jpeg_write_marker(dstinfo, marker->marker,
986
 
                      marker->data, marker->data_length);
987
 
#endif
988
 
  }
989
 
}
990
 
 
991
 
 
992
 
#endif /* HAVE_LIBJPEG */