Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.  
  65. LOCAL(void)
  66. do_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.  
  114. LOCAL(void)
  115. do_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.  
  185. LOCAL(void)
  186. do_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.  
  229. LOCAL(void)
  230. do_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.  
  293. LOCAL(void)
  294. do_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.  
  357. LOCAL(void)
  358. do_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.  
  458. LOCAL(void)
  459. do_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.  
  567. GLOBAL(void)
  568. jtransform_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.  
  639. LOCAL(void)
  640. transpose_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.  
  679. LOCAL(void)
  680. trim_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.  
  699. LOCAL(void)
  700. trim_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.  
  731. GLOBAL(jvirt_barray_ptr *)
  732. jtransform_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.  
  818. GLOBAL(void)
  819. jtransform_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.  
  860. GLOBAL(void)
  861. jcopy_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.  
  885. GLOBAL(void)
  886. jcopy_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. }
  929.