summaryrefslogtreecommitdiff
path: root/plugins/AdvaImg/src/FreeImageToolkit/JPEGTransform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/AdvaImg/src/FreeImageToolkit/JPEGTransform.cpp')
-rw-r--r--plugins/AdvaImg/src/FreeImageToolkit/JPEGTransform.cpp623
1 files changed, 0 insertions, 623 deletions
diff --git a/plugins/AdvaImg/src/FreeImageToolkit/JPEGTransform.cpp b/plugins/AdvaImg/src/FreeImageToolkit/JPEGTransform.cpp
deleted file mode 100644
index 6f9ba8e1f2..0000000000
--- a/plugins/AdvaImg/src/FreeImageToolkit/JPEGTransform.cpp
+++ /dev/null
@@ -1,623 +0,0 @@
-// ==========================================================
-// JPEG lossless transformations
-//
-// Design and implementation by
-// - Petr Pytelka (pyta@lightcomp.com)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-extern "C" {
-#define XMD_H
-#undef FAR
-#include <setjmp.h>
-
-#include "../LibJPEG/jinclude.h"
-#include "../LibJPEG/jpeglib.h"
-#include "../LibJPEG/jerror.h"
-#include "../LibJPEG/transupp.h"
-}
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "FreeImageIO.h"
-
-// ----------------------------------------------------------
-// Source manager & Destination manager setup
-// (see PluginJPEG.cpp)
-// ----------------------------------------------------------
-
-void jpeg_freeimage_src(j_decompress_ptr cinfo, fi_handle infile, FreeImageIO *io);
-void jpeg_freeimage_dst(j_compress_ptr cinfo, fi_handle outfile, FreeImageIO *io);
-
-// ----------------------------------------------------------
-// Error handling
-// (see also PluginJPEG.cpp)
-// ----------------------------------------------------------
-
-/**
- Receives control for a fatal error. Information sufficient to
- generate the error message has been stored in cinfo->err; call
- output_message to display it. Control must NOT return to the caller;
- generally this routine will exit() or longjmp() somewhere.
-*/
-METHODDEF(void)
-ls_jpeg_error_exit (j_common_ptr cinfo) {
- // always display the message
- (*cinfo->err->output_message)(cinfo);
-
- // allow JPEG with a premature end of file
- if((cinfo)->err->msg_parm.i[0] != 13) {
-
- // let the memory manager delete any temp files before we die
- jpeg_destroy(cinfo);
-
- throw FIF_JPEG;
- }
-}
-
-/**
- Actual output of any JPEG message. Note that this method does not know
- how to generate a message, only where to send it.
-*/
-METHODDEF(void)
-ls_jpeg_output_message (j_common_ptr cinfo) {
- char buffer[JMSG_LENGTH_MAX];
-
- // create the message
- (*cinfo->err->format_message)(cinfo, buffer);
- // send it to user's message proc
- FreeImage_OutputMessageProc(FIF_JPEG, buffer);
-}
-
-// ----------------------------------------------------------
-// Main program
-// ----------------------------------------------------------
-
-/**
-Build a crop string.
-
-@param crop Output crop string
-@param left Specifies the left position of the cropped rectangle
-@param top Specifies the top position of the cropped rectangle
-@param right Specifies the right position of the cropped rectangle
-@param bottom Specifies the bottom position of the cropped rectangle
-@param width Image width
-@param height Image height
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-getCropString(char* crop, int* left, int* top, int* right, int* bottom, int width, int height) {
- if(!left || !top || !right || !bottom) {
- return FALSE;
- }
-
- *left = CLAMP(*left, 0, width);
- *top = CLAMP(*top, 0, height);
-
- // negative/zero right and bottom count from the edges inwards
-
- if(*right <= 0) {
- *right = width + *right;
- }
- if(*bottom <= 0) {
- *bottom = height + *bottom;
- }
-
- *right = CLAMP(*right, 0, width);
- *bottom = CLAMP(*bottom, 0, height);
-
- // test for empty rect
-
- if(((*left - *right) == 0) || ((*top - *bottom) == 0)) {
- return FALSE;
- }
-
- // normalize the rectangle
-
- if(*right < *left) {
- INPLACESWAP(*left, *right);
- }
- if(*bottom < *top) {
- INPLACESWAP(*top, *bottom);
- }
-
- // test for "noop" rect
-
- if(*left == 0 && *right == width && *top == 0 && *bottom == height) {
- return FALSE;
- }
-
- // build the crop option
- sprintf(crop, "%dx%d+%d+%d", *right - *left, *bottom - *top, *left, *top);
-
- return TRUE;
-}
-
-static BOOL
-JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
- const BOOL onlyReturnCropRect = (dst_io == NULL) || (dst_handle == NULL);
- const long stream_start = onlyReturnCropRect ? 0 : dst_io->tell_proc(dst_handle);
- BOOL swappedDim = FALSE;
- BOOL trimH = FALSE;
- BOOL trimV = FALSE;
-
- // Set up the jpeglib structures
- jpeg_decompress_struct srcinfo;
- jpeg_compress_struct dstinfo;
- jpeg_error_mgr jsrcerr, jdsterr;
- jvirt_barray_ptr *src_coef_arrays = NULL;
- jvirt_barray_ptr *dst_coef_arrays = NULL;
- // Support for copying optional markers from source to destination file
- JCOPY_OPTION copyoption;
- // Image transformation options
- jpeg_transform_info transfoptions;
-
- // Initialize structures
- memset(&srcinfo, 0, sizeof(srcinfo));
- memset(&jsrcerr, 0, sizeof(jsrcerr));
- memset(&jdsterr, 0, sizeof(jdsterr));
- memset(&dstinfo, 0, sizeof(dstinfo));
- memset(&transfoptions, 0, sizeof(transfoptions));
-
- // Copy all extra markers from source file
- copyoption = JCOPYOPT_ALL;
-
- // Set up default JPEG parameters
- transfoptions.force_grayscale = FALSE;
- transfoptions.crop = FALSE;
-
- // Select the transform option
- switch(operation) {
- case FIJPEG_OP_FLIP_H: // horizontal flip
- transfoptions.transform = JXFORM_FLIP_H;
- trimH = TRUE;
- break;
- case FIJPEG_OP_FLIP_V: // vertical flip
- transfoptions.transform = JXFORM_FLIP_V;
- trimV = TRUE;
- break;
- case FIJPEG_OP_TRANSPOSE: // transpose across UL-to-LR axis
- transfoptions.transform = JXFORM_TRANSPOSE;
- swappedDim = TRUE;
- break;
- case FIJPEG_OP_TRANSVERSE: // transpose across UR-to-LL axis
- transfoptions.transform = JXFORM_TRANSVERSE;
- trimH = TRUE;
- trimV = TRUE;
- swappedDim = TRUE;
- break;
- case FIJPEG_OP_ROTATE_90: // 90-degree clockwise rotation
- transfoptions.transform = JXFORM_ROT_90;
- trimH = TRUE;
- swappedDim = TRUE;
- break;
- case FIJPEG_OP_ROTATE_180: // 180-degree rotation
- trimH = TRUE;
- trimV = TRUE;
- transfoptions.transform = JXFORM_ROT_180;
- break;
- case FIJPEG_OP_ROTATE_270: // 270-degree clockwise (or 90 ccw)
- transfoptions.transform = JXFORM_ROT_270;
- trimV = TRUE;
- swappedDim = TRUE;
- break;
- default:
- case FIJPEG_OP_NONE: // no transformation
- transfoptions.transform = JXFORM_NONE;
- break;
- }
- // (perfect == TRUE) ==> fail if there is non-transformable edge blocks
- transfoptions.perfect = (perfect == TRUE) ? TRUE : FALSE;
- // Drop non-transformable edge blocks: trim off any partial edge MCUs that the transform can't handle.
- transfoptions.trim = TRUE;
-
- try {
-
- // Initialize the JPEG decompression object with default error handling
- srcinfo.err = jpeg_std_error(&jsrcerr);
- srcinfo.err->error_exit = ls_jpeg_error_exit;
- srcinfo.err->output_message = ls_jpeg_output_message;
- jpeg_create_decompress(&srcinfo);
-
- // Initialize the JPEG compression object with default error handling
- dstinfo.err = jpeg_std_error(&jdsterr);
- dstinfo.err->error_exit = ls_jpeg_error_exit;
- dstinfo.err->output_message = ls_jpeg_output_message;
- jpeg_create_compress(&dstinfo);
-
- // Specify data source for decompression
- jpeg_freeimage_src(&srcinfo, src_handle, src_io);
-
- // Enable saving of extra markers that we want to copy
- jcopy_markers_setup(&srcinfo, copyoption);
-
- // Read the file header
- jpeg_read_header(&srcinfo, TRUE);
-
- // crop option
- char crop[64];
- const BOOL hasCrop = getCropString(crop, left, top, right, bottom, swappedDim ? srcinfo.image_height : srcinfo.image_width, swappedDim ? srcinfo.image_width : srcinfo.image_height);
-
- if(hasCrop) {
- if(!jtransform_parse_crop_spec(&transfoptions, crop)) {
- FreeImage_OutputMessageProc(FIF_JPEG, "Bogus crop argument %s", crop);
- throw(1);
- }
- }
-
- // Any space needed by a transform option must be requested before
- // jpeg_read_coefficients so that memory allocation will be done right
-
- // Prepare transformation workspace
- // Fails right away if perfect flag is TRUE and transformation is not perfect
- if( !jtransform_request_workspace(&srcinfo, &transfoptions) ) {
- FreeImage_OutputMessageProc(FIF_JPEG, "Transformation is not perfect");
- throw(1);
- }
-
- if(left || top) {
- // compute left and top offsets, it's a bit tricky, taking into account both
- // transform, which might have trimed the image,
- // and crop itself, which is adjusted to lie on a iMCU boundary
-
- const int fullWidth = swappedDim ? srcinfo.image_height : srcinfo.image_width;
- const int fullHeight = swappedDim ? srcinfo.image_width : srcinfo.image_height;
-
- int transformedFullWidth = fullWidth;
- int transformedFullHeight = fullHeight;
-
- if(trimH && transformedFullWidth/transfoptions.iMCU_sample_width > 0) {
- transformedFullWidth = (transformedFullWidth/transfoptions.iMCU_sample_width) * transfoptions.iMCU_sample_width;
- }
- if(trimV && transformedFullHeight/transfoptions.iMCU_sample_height > 0) {
- transformedFullHeight = (transformedFullHeight/transfoptions.iMCU_sample_height) * transfoptions.iMCU_sample_height;
- }
-
- const int trimmedWidth = fullWidth - transformedFullWidth;
- const int trimmedHeight = fullHeight - transformedFullHeight;
-
- if(left) {
- *left = trimmedWidth + transfoptions.x_crop_offset * transfoptions.iMCU_sample_width;
- }
- if(top) {
- *top = trimmedHeight + transfoptions.y_crop_offset * transfoptions.iMCU_sample_height;
- }
- }
-
- if(right) {
- *right = (left ? *left : 0) + transfoptions.output_width;
- }
- if(bottom) {
- *bottom = (top ? *top : 0) + transfoptions.output_height;
- }
-
- // if only the crop rect is requested, we are done
-
- if(onlyReturnCropRect) {
- jpeg_destroy_compress(&dstinfo);
- jpeg_destroy_decompress(&srcinfo);
- return TRUE;
- }
-
- // Read source file as DCT coefficients
- src_coef_arrays = jpeg_read_coefficients(&srcinfo);
-
- // Initialize destination compression parameters from source values
- jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
-
- // Adjust destination parameters if required by transform options;
- // also find out which set of coefficient arrays will hold the output
- dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo, src_coef_arrays, &transfoptions);
-
- // Note: we assume that jpeg_read_coefficients consumed all input
- // until JPEG_REACHED_EOI, and that jpeg_finish_decompress will
- // only consume more while (! cinfo->inputctl->eoi_reached).
- // We cannot call jpeg_finish_decompress here since we still need the
- // virtual arrays allocated from the source object for processing.
-
- if(src_handle == dst_handle) {
- dst_io->seek_proc(dst_handle, stream_start, SEEK_SET);
- }
-
- // Specify data destination for compression
- jpeg_freeimage_dst(&dstinfo, dst_handle, dst_io);
-
- // Start compressor (note no image data is actually written here)
- jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
-
- // Copy to the output file any extra markers that we want to preserve
- jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
-
- // Execute image transformation, if any
- jtransform_execute_transformation(&srcinfo, &dstinfo, src_coef_arrays, &transfoptions);
-
- // Finish compression and release memory
- jpeg_finish_compress(&dstinfo);
- jpeg_destroy_compress(&dstinfo);
- jpeg_finish_decompress(&srcinfo);
- jpeg_destroy_decompress(&srcinfo);
-
- }
- catch(...) {
- jpeg_destroy_compress(&dstinfo);
- jpeg_destroy_decompress(&srcinfo);
- return FALSE;
- }
-
- return TRUE;
-}
-
-// ----------------------------------------------------------
-// FreeImage interface
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
- return JPEGTransformFromHandle(src_io, src_handle, dst_io, dst_handle, operation, left, top, right, bottom, perfect);
-}
-
-static void
-closeStdIO(fi_handle src_handle, fi_handle dst_handle) {
- if(src_handle) {
- fclose((FILE*)src_handle);
- }
- if(dst_handle && (dst_handle != src_handle)) {
- fclose((FILE*)dst_handle);
- }
-}
-
-static BOOL
-openStdIO(const char* src_file, const char* dst_file, FreeImageIO* dst_io, fi_handle* src_handle, fi_handle* dst_handle) {
- *src_handle = NULL;
- *dst_handle = NULL;
-
- FreeImageIO io;
- SetDefaultIO (&io);
-
- const BOOL isSameFile = (dst_file && (strcmp(src_file, dst_file) == 0)) ? TRUE : FALSE;
-
- FILE* srcp = NULL;
- FILE* dstp = NULL;
-
- if(isSameFile) {
- srcp = fopen(src_file, "r+b");
- dstp = srcp;
- }
- else {
- srcp = fopen(src_file, "rb");
- if(dst_file) {
- dstp = fopen(dst_file, "wb");
- }
- }
-
- if(!srcp || (dst_file && !dstp)) {
- if(!srcp) {
- FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open \"%s\" for reading", src_file);
- } else {
- FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open \"%s\" for writing", dst_file);
- }
- closeStdIO(srcp, dstp);
- return FALSE;
- }
-
- if(FreeImage_GetFileTypeFromHandle(&io, srcp) != FIF_JPEG) {
- FreeImage_OutputMessageProc(FIF_JPEG, " Source file \"%s\" is not jpeg", src_file);
- closeStdIO(srcp, dstp);
- return FALSE;
- }
-
- *dst_io = io;
- *src_handle = srcp;
- *dst_handle = dstp;
-
- return TRUE;
-}
-
-static BOOL
-openStdIOU(const wchar_t* src_file, const wchar_t* dst_file, FreeImageIO* dst_io, fi_handle* src_handle, fi_handle* dst_handle) {
-#ifdef _WIN32
-
- *src_handle = NULL;
- *dst_handle = NULL;
-
- FreeImageIO io;
- SetDefaultIO (&io);
-
- const BOOL isSameFile = (dst_file && (wcscmp(src_file, dst_file) == 0)) ? TRUE : FALSE;
-
- FILE* srcp = NULL;
- FILE* dstp = NULL;
-
- if(isSameFile) {
- srcp = _wfopen(src_file, L"r+b");
- dstp = srcp;
- } else {
- srcp = _wfopen(src_file, L"rb");
- if(dst_file) {
- dstp = _wfopen(dst_file, L"wb");
- }
- }
-
- if(!srcp || (dst_file && !dstp)) {
- if(!srcp) {
- FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open source file for reading");
- } else {
- FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open destination file for writing");
- }
- closeStdIO(srcp, dstp);
- return FALSE;
- }
-
- if(FreeImage_GetFileTypeFromHandle(&io, srcp) != FIF_JPEG) {
- FreeImage_OutputMessageProc(FIF_JPEG, " Source file is not jpeg");
- closeStdIO(srcp, dstp);
- return FALSE;
- }
-
- *dst_io = io;
- *src_handle = srcp;
- *dst_handle = dstp;
-
- return TRUE;
-
-#else
- return FALSE;
-#endif // _WIN32
-}
-
-BOOL DLL_CALLCONV
-FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect) {
- FreeImageIO io;
- fi_handle src;
- fi_handle dst;
-
- if(!openStdIO(src_file, dst_file, &io, &src, &dst)) {
- return FALSE;
- }
-
- BOOL ret = JPEGTransformFromHandle(&io, src, &io, dst, operation, NULL, NULL, NULL, NULL, perfect);
-
- closeStdIO(src, dst);
-
- return ret;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom) {
- FreeImageIO io;
- fi_handle src;
- fi_handle dst;
-
- if(!openStdIO(src_file, dst_file, &io, &src, &dst)) {
- return FALSE;
- }
-
- BOOL ret = FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, FIJPEG_OP_NONE, &left, &top, &right, &bottom, FALSE);
-
- closeStdIO(src, dst);
-
- return ret;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect) {
- FreeImageIO io;
- fi_handle src;
- fi_handle dst;
-
- if(!openStdIOU(src_file, dst_file, &io, &src, &dst)) {
- return FALSE;
- }
-
- BOOL ret = JPEGTransformFromHandle(&io, src, &io, dst, operation, NULL, NULL, NULL, NULL, perfect);
-
- closeStdIO(src, dst);
-
- return ret;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom) {
- FreeImageIO io;
- fi_handle src;
- fi_handle dst;
-
- if(!openStdIOU(src_file, dst_file, &io, &src, &dst)) {
- return FALSE;
- }
-
- BOOL ret = FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, FIJPEG_OP_NONE, &left, &top, &right, &bottom, FALSE);
-
- closeStdIO(src, dst);
-
- return ret;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_JPEGTransformCombined(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
- FreeImageIO io;
- fi_handle src;
- fi_handle dst;
-
- if(!openStdIO(src_file, dst_file, &io, &src, &dst)) {
- return FALSE;
- }
-
- BOOL ret = FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, operation, left, top, right, bottom, perfect);
-
- closeStdIO(src, dst);
-
- return ret;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_JPEGTransformCombinedU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
- FreeImageIO io;
- fi_handle src;
- fi_handle dst;
-
- if(!openStdIOU(src_file, dst_file, &io, &src, &dst)) {
- return FALSE;
- }
-
- BOOL ret = FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, operation, left, top, right, bottom, perfect);
-
- closeStdIO(src, dst);
-
- return ret;
-}
-
-// --------------------------------------------------------------------------
-
-static BOOL
-getMemIO(FIMEMORY* src_stream, FIMEMORY* dst_stream, FreeImageIO* dst_io, fi_handle* src_handle, fi_handle* dst_handle) {
- *src_handle = NULL;
- *dst_handle = NULL;
-
- FreeImageIO io;
- SetMemoryIO (&io);
-
- if(dst_stream) {
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(dst_stream->data);
- if(mem_header->delete_me != TRUE) {
- // do not save in a user buffer
- FreeImage_OutputMessageProc(FIF_JPEG, "Destination memory buffer is read only");
- return FALSE;
- }
- }
-
- *dst_io = io;
- *src_handle = src_stream;
- *dst_handle = dst_stream;
-
- return TRUE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* src_stream, FIMEMORY* dst_stream, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
- FreeImageIO io;
- fi_handle src;
- fi_handle dst;
-
- if(!getMemIO(src_stream, dst_stream, &io, &src, &dst)) {
- return FALSE;
- }
-
- return FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, operation, left, top, right, bottom, perfect);
-}
-