// ==========================================================
// 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 "third_party/jpeg/jinclude.h"
#include "third_party/jpeg/jpeglib.h"
#include "third_party/jpeg/jerror.h"
#include "third_party/jpeg/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);
}

