source: trunk/third/jpeg/transupp.c @ 15227

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