Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibJPEG/transupp.c view on Meta::CPAN
/*
* transupp.c
*
* Copyright (C) 1997-2013, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains image transformation routines and other utility code
* used by the jpegtran sample application. These are NOT part of the core
* JPEG library. But we keep these routines separate from jpegtran.c to
* ease the task of maintaining jpegtran-like programs that have other user
* interfaces.
*/
/* Although this file really shouldn't have access to the library internals,
* it's helpful to let it call jround_up() and jcopy_block_row().
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "transupp.h" /* My own external interface */
#include <ctype.h> /* to declare isdigit() */
#if TRANSFORMS_SUPPORTED
/*
* Lossless image transformation routines. These routines work on DCT
* coefficient arrays and thus do not require any lossy decompression
* or recompression of the image.
* Thanks to Guido Vollbeding for the initial design and code of this feature,
* and to Ben Jackson for introducing the cropping feature.
*
* Horizontal flipping is done in-place, using a single top-to-bottom
* pass through the virtual source array. It will thus be much the
* fastest option for images larger than main memory.
*
* The other routines require a set of destination virtual arrays, so they
* need twice as much memory as jpegtran normally does. The destination
* arrays are always written in normal scan order (top to bottom) because
* the virtual array manager expects this. The source arrays will be scanned
* in the corresponding order, which means multiple passes through the source
* arrays for most of the transforms. That could result in much thrashing
* if the image is larger than main memory.
*
* If cropping or trimming is involved, the destination arrays may be smaller
* than the source arrays. Note it is not possible to do horizontal flip
* in-place when a nonzero Y crop offset is specified, since we'd have to move
* data from one block row to another but the virtual array manager doesn't
* guarantee we can touch more than one row at a time. So in that case,
* we have to use a separate destination array.
*
* Some notes about the operating environment of the individual transform
* routines:
* 1. Both the source and destination virtual arrays are allocated from the
* source JPEG object, and therefore should be manipulated by calling the
* source's memory manager.
* 2. The destination's component count should be used. It may be smaller
* than the source's when forcing to grayscale.
* 3. Likewise the destination's sampling factors should be used. When
* forcing to grayscale the destination's sampling factors will be all 1,
* and we may as well take that as the effective iMCU size.
* 4. When "trim" is in effect, the destination's dimensions will be the
* trimmed values but the source's will be untrimmed.
* 5. When "crop" is in effect, the destination's dimensions will be the
* cropped values but the source's will be uncropped. Each transform
* routine is responsible for picking up source data starting at the
* correct X and Y offset for the crop region. (The X and Y offsets
* passed to the transform routines are measured in iMCU blocks of the
* destination.)
* 6. All the routines assume that the source and destination buffers are
* padded out to a full iMCU boundary. This is true, although for the
* source buffer it is an undocumented property of jdcoefct.c.
*/
LOCAL(void)
do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
jvirt_barray_ptr *src_coef_arrays,
jvirt_barray_ptr *dst_coef_arrays)
/* Crop. This is only used when no rotate/flip is requested with the crop. */
{
JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
int ci, offset_y;
JBLOCKARRAY src_buffer, dst_buffer;
jpeg_component_info *compptr;
src/Source/LibJPEG/transupp.c view on Meta::CPAN
j_compress_ptr dstinfo,
jvirt_barray_ptr *src_coef_arrays,
jpeg_transform_info *info)
{
jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
/* Note: conditions tested here should match those in switch statement
* in jtransform_request_workspace()
*/
switch (info->transform) {
case JXFORM_NONE:
if (info->output_width > srcinfo->output_width ||
info->output_height > srcinfo->output_height)
do_crop_ext(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
else if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_FLIP_H:
if (info->y_crop_offset != 0)
do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
else
do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
src_coef_arrays);
break;
case JXFORM_FLIP_V:
do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_TRANSPOSE:
do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_TRANSVERSE:
do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_ROT_90:
do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_ROT_180:
do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_ROT_270:
do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_WIPE:
do_wipe(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, info->drop_width, info->drop_height);
break;
}
}
/* jtransform_perfect_transform
*
* Determine whether lossless transformation is perfectly
* possible for a specified image and transformation.
*
* Inputs:
* image_width, image_height: source image dimensions.
* MCU_width, MCU_height: pixel dimensions of MCU.
* transform: transformation identifier.
* Parameter sources from initialized jpeg_struct
* (after reading source header):
* image_width = cinfo.image_width
* image_height = cinfo.image_height
* MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
* MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
* Result:
* TRUE = perfect transformation possible
* FALSE = perfect transformation not possible
* (may use custom action then)
*/
GLOBAL(boolean)
jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
int MCU_width, int MCU_height,
JXFORM_CODE transform)
{
boolean result = TRUE; /* initialize TRUE */
switch (transform) {
case JXFORM_FLIP_H:
case JXFORM_ROT_270:
if (image_width % (JDIMENSION) MCU_width)
result = FALSE;
break;
case JXFORM_FLIP_V:
case JXFORM_ROT_90:
if (image_height % (JDIMENSION) MCU_height)
result = FALSE;
break;
case JXFORM_TRANSVERSE:
case JXFORM_ROT_180:
if (image_width % (JDIMENSION) MCU_width)
result = FALSE;
if (image_height % (JDIMENSION) MCU_height)
result = FALSE;
break;
default:
break;
}
return result;
}
#endif /* TRANSFORMS_SUPPORTED */
/* Setup decompression object to save desired markers in memory.
* This must be called before jpeg_read_header() to have the desired effect.
*/
GLOBAL(void)
jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
{
( run in 0.710 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )