// ==========================================================
// JPEG XR Loader & Writer
//
// Design and implementation by
// - Herve Drolon (drolon@infonie.fr)
//
// 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!
// ==========================================================

#include "FreeImage.h"
#include "Utilities.h"
#include "../Metadata/FreeImageTag.h"

#include "../LibJXR/jxrgluelib/JXRGlue.h"

// ==========================================================
// Plugin Interface
// ==========================================================

static int s_format_id;

// ==========================================================
// FreeImageIO interface (I/O streaming functions)
// ==========================================================

/**
JXR wrapper for FreeImage I/O handle
*/
typedef struct tagFreeImageJXRIO {
    FreeImageIO *io;
	fi_handle handle;
} FreeImageJXRIO;

static ERR 
_jxr_io_Read(WMPStream* pWS, void* pv, size_t cb) {
	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
	return (fio->io->read_proc(pv, (unsigned)cb, 1, fio->handle) == 1) ? WMP_errSuccess : WMP_errFileIO;
}

static ERR 
_jxr_io_Write(WMPStream* pWS, const void* pv, size_t cb) {
	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
	if(0 != cb) {
		return (fio->io->write_proc((void*)pv, (unsigned)cb, 1, fio->handle) == 1) ? WMP_errSuccess : WMP_errFileIO;
	}
	return WMP_errFileIO;
}

static ERR 
_jxr_io_SetPos(WMPStream* pWS, size_t offPos) {
	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
    return (fio->io->seek_proc(fio->handle, (long)offPos, SEEK_SET) == 0) ? WMP_errSuccess : WMP_errFileIO;
}

static ERR 
_jxr_io_GetPos(WMPStream* pWS, size_t* poffPos) {
	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
    long lOff = fio->io->tell_proc(fio->handle);
	if(lOff == -1) {
		return WMP_errFileIO;
	}
    *poffPos = (size_t)lOff;
	return WMP_errSuccess;
}

static Bool 
_jxr_io_EOS(WMPStream* pWS) {
	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
    long currentPos = fio->io->tell_proc(fio->handle);
    fio->io->seek_proc(fio->handle, 0, SEEK_END);
    long fileRemaining = fio->io->tell_proc(fio->handle) - currentPos;
    fio->io->seek_proc(fio->handle, currentPos, SEEK_SET);
    return (fileRemaining > 0);
}

static ERR 
_jxr_io_Close(WMPStream** ppWS) {
	WMPStream *pWS = *ppWS;
	// HACK : we use fMem to avoid a stream destruction by the library
	// because FreeImage MUST HAVE the ownership of the stream
	// see _jxr_io_Create
	if(pWS && pWS->fMem) {
		free(pWS);
		*ppWS = NULL;
	}
	return WMP_errSuccess;
}

static ERR 
_jxr_io_Create(WMPStream **ppWS, FreeImageJXRIO *jxr_io) {
	*ppWS = (WMPStream*)calloc(1, sizeof(**ppWS));
	if(*ppWS) {
		WMPStream *pWS = *ppWS;

		pWS->state.pvObj = jxr_io;
		pWS->Close = _jxr_io_Close;
		pWS->EOS = _jxr_io_EOS;
		pWS->Read = _jxr_io_Read;
		pWS->Write = _jxr_io_Write;
		pWS->SetPos = _jxr_io_SetPos;
		pWS->GetPos = _jxr_io_GetPos;

		// HACK : we use fMem to avoid a stream destruction by the library
		// because FreeImage MUST HAVE the ownership of the stream
		// see _jxr_io_Close
		pWS->fMem = FALSE;

		return WMP_errSuccess;
	}
	return WMP_errOutOfMemory;
}

// ==========================================================
// JPEG XR Error handling
// ==========================================================

static const char* 
JXR_ErrorMessage(const int error) {
	switch(error) {
		case WMP_errNotYetImplemented:
		case WMP_errAbstractMethod:
			return "Not yet implemented";
		case WMP_errOutOfMemory:
			return "Out of memory";
		case WMP_errFileIO:
			return "File I/O error";
		case WMP_errBufferOverflow:
			return "Buffer overflow";
		case WMP_errInvalidParameter:
			return "Invalid parameter";
		case WMP_errInvalidArgument:
			return "Invalid argument";
		case WMP_errUnsupportedFormat:
			return "Unsupported format";
		case WMP_errIncorrectCodecVersion:
			return "Incorrect codec version";
		case WMP_errIndexNotFound:
			return "Format converter: Index not found";
		case WMP_errOutOfSequence:
			return "Metadata: Out of sequence";
		case WMP_errMustBeMultipleOf16LinesUntilLastCall:
			return "Must be multiple of 16 lines until last call";
		case WMP_errPlanarAlphaBandedEncRequiresTempFile:
			return "Planar alpha banded encoder requires temp files";
		case WMP_errAlphaModeCannotBeTranscoded:
			return "Alpha mode cannot be transcoded";
		case WMP_errIncorrectCodecSubVersion:
			return "Incorrect codec subversion";
		case WMP_errFail:
		case WMP_errNotInitialized:
		default:
			return "Invalid instruction - please contact the FreeImage team";
	}
}

// ==========================================================
// Helper functions & macro
// ==========================================================

#define JXR_CHECK(error_code) \
	if(error_code < 0) { \
		const char *error_message = JXR_ErrorMessage(error_code); \
		throw error_message; \
	}

// --------------------------------------------------------------------------

/**
Input conversions natively understood by FreeImage
@see GetNativePixelFormat
*/
typedef struct tagJXRInputConversion {
	BITDEPTH_BITS bdBitDepth;
	U32 cbitUnit;
	FREE_IMAGE_TYPE image_type;
	unsigned red_mask;
	unsigned green_mask;
	unsigned blue_mask;
} JXRInputConversion;

/**
Conversion table for native FreeImage formats
@see GetNativePixelFormat
*/
static JXRInputConversion s_FreeImagePixelInfo[] = {
	// 1-bit bitmap
	{ BD_1, 1, FIT_BITMAP, 0, 0, 0 },
	// 8-, 24-, 32-bit bitmap
	{ BD_8, 8, FIT_BITMAP, 0, 0, 0 },
	{ BD_8, 24, FIT_BITMAP, 0, 0, 0 },
	{ BD_8, 32, FIT_BITMAP, 0, 0, 0 },
	// 16-bit RGB 565
	{ BD_565, 16, FIT_BITMAP, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK },
	// 16-bit RGB 555
	{ BD_5, 16, FIT_BITMAP, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK },
	// 16-bit greyscale, RGB16, RGBA16 bitmap
	{ BD_16, 16, FIT_UINT16, 0, 0, 0 },
	{ BD_16, 48, FIT_RGB16, 0, 0, 0 },
	{ BD_16, 64, FIT_RGBA16, 0, 0, 0 },
	// 32-bit float, RGBF, RGBAF bitmap
	{ BD_32F, 32, FIT_FLOAT, 0, 0, 0 },
	{ BD_32F, 96, FIT_RGBF, 0, 0, 0 },
	{ BD_32F, 128, FIT_RGBAF, 0, 0, 0 }
};

/**
Scan input pixelInfo specifications and return the equivalent FreeImage info for loading
@param pixelInfo Image specifications
@param out_guid_format (returned value) output pixel format
@param image_type (returned value) Image type
@param bpp (returned value) Image bit depth
@param red_mask (returned value) RGB mask
@param green_mask (returned value) RGB mask
@param blue_mask (returned value) RGB mask
@return Returns WMP_errSuccess if successful, returns WMP_errFail otherwise
@see GetInputPixelFormat
*/
static ERR
GetNativePixelFormat(const PKPixelInfo *pixelInfo, PKPixelFormatGUID *out_guid_format, FREE_IMAGE_TYPE *image_type, unsigned *bpp, unsigned *red_mask, unsigned *green_mask, unsigned *blue_mask) {
	const unsigned s_FreeImagePixelInfoSize = (unsigned)sizeof(s_FreeImagePixelInfo) / sizeof(*(s_FreeImagePixelInfo));

	for(unsigned i = 0; i < s_FreeImagePixelInfoSize; i++) {
		if(pixelInfo->bdBitDepth == s_FreeImagePixelInfo[i].bdBitDepth) {
			if(pixelInfo->cbitUnit == s_FreeImagePixelInfo[i].cbitUnit) {
				// found ! now get dst image format specifications
				memcpy(out_guid_format, pixelInfo->pGUIDPixFmt, sizeof(PKPixelFormatGUID));
				*image_type = s_FreeImagePixelInfo[i].image_type;
				*bpp = s_FreeImagePixelInfo[i].cbitUnit;
				*red_mask	= s_FreeImagePixelInfo[i].red_mask;
				*green_mask	= s_FreeImagePixelInfo[i].green_mask;
				*blue_mask	= s_FreeImagePixelInfo[i].blue_mask;
				return WMP_errSuccess;
			}
		}
	}

	// not found : need pixel format conversion
	return WMP_errFail;
}

/**
Scan input file guid format and return the equivalent FreeImage info & target guid format for loading
@param pDecoder Decoder handle
@param guid_format (returned value) Output pixel format
@param image_type (returned value) Image type
@param bpp (returned value) Image bit depth
@param red_mask (returned value) RGB mask
@param green_mask (returned value) RGB mask
@param blue_mask (returned value) RGB mask
@return Returns TRUE if successful, returns FALSE otherwise
*/
static ERR
GetInputPixelFormat(PKImageDecode *pDecoder, PKPixelFormatGUID *guid_format, FREE_IMAGE_TYPE *image_type, unsigned *bpp, unsigned *red_mask, unsigned *green_mask, unsigned *blue_mask) {
	ERR error_code = 0;		// error code as returned by the interface
	PKPixelInfo pixelInfo;	// image specifications

	try {		
		// get input file pixel format ...
		PKPixelFormatGUID pguidSourcePF;
		error_code = pDecoder->GetPixelFormat(pDecoder, &pguidSourcePF);
		JXR_CHECK(error_code);
		pixelInfo.pGUIDPixFmt = &pguidSourcePF;
		// ... check for a supported format and get the format specifications
		error_code = PixelFormatLookup(&pixelInfo, LOOKUP_FORWARD);
		JXR_CHECK(error_code);

		// search for an equivalent native FreeImage format
		error_code = GetNativePixelFormat(&pixelInfo, guid_format, image_type, bpp, red_mask, green_mask, blue_mask);

		if(error_code != WMP_errSuccess) {
			// try to find a suitable conversion function ...
			const PKPixelFormatGUID *ppguidTargetPF = NULL;	// target pixel format
			unsigned iIndex = 0;	// first available conversion function
			do {
				error_code = PKFormatConverter_EnumConversions(&pguidSourcePF, iIndex, &ppguidTargetPF);
				if(error_code == WMP_errSuccess) {
					// found a conversion function, is the converted format a native FreeImage format ?
					pixelInfo.pGUIDPixFmt = ppguidTargetPF;
					error_code = PixelFormatLookup(&pixelInfo, LOOKUP_FORWARD);
					JXR_CHECK(error_code);
					error_code = GetNativePixelFormat(&pixelInfo, guid_format, image_type, bpp, red_mask, green_mask, blue_mask);
					if(error_code == WMP_errSuccess) {
						break;
					}
				}
				// try next conversion function
				iIndex++;
			} while(error_code != WMP_errIndexNotFound);

		}

		return (error_code == WMP_errSuccess) ? WMP_errSuccess : WMP_errUnsupportedFormat;

	} catch(...) {
		return error_code;
	}
}

// --------------------------------------------------------------------------

/**
Scan input dib format and return the equivalent PKPixelFormatGUID format for saving
@param dib Image to be saved
@param guid_format (returned value) GUID format
@param bHasAlpha (returned value) TRUE if an alpha layer is present
@return Returns TRUE if successful, returns FALSE otherwise
*/
static ERR
GetOutputPixelFormat(FIBITMAP *dib, PKPixelFormatGUID *guid_format, BOOL *bHasAlpha) {
	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
	const unsigned bpp = FreeImage_GetBPP(dib);
	const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);

	*guid_format = GUID_PKPixelFormatDontCare;
	*bHasAlpha = FALSE;

	switch(image_type) {
		case FIT_BITMAP:	// standard image	: 1-, 4-, 8-, 16-, 24-, 32-bit
			switch(bpp) {
				case 1:
					// assume FIC_MINISBLACK
					if(color_type == FIC_MINISBLACK) {
						*guid_format = GUID_PKPixelFormatBlackWhite;
					}
					break;
				case 8:
					// assume FIC_MINISBLACK
					if(color_type == FIC_MINISBLACK) {
						*guid_format = GUID_PKPixelFormat8bppGray;
					}
					break;
				case 16:
					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
						*guid_format = GUID_PKPixelFormat16bppRGB565;
					} else {
						// includes case where all the masks are 0
						*guid_format = GUID_PKPixelFormat16bppRGB555;
					}
					break;
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
				case 24:
					*guid_format = GUID_PKPixelFormat24bppBGR;
					break;
				case 32:
					*guid_format = GUID_PKPixelFormat32bppBGRA;
					*bHasAlpha = TRUE;
					break;
#elif FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
				case 24:
					*guid_format = GUID_PKPixelFormat24bppRGB;
					break;
				case 32:
					*guid_format = GUID_PKPixelFormat32bppRGBA;
					*bHasAlpha = TRUE;
					break;
#endif
				case 4:
				default:
					// not supported
					break;
			}
			break;
		case FIT_UINT16:	// array of unsigned short	: unsigned 16-bit
			*guid_format = GUID_PKPixelFormat16bppGray;
			break;
		case FIT_FLOAT:		// array of float			: 32-bit IEEE floating point
			*guid_format = GUID_PKPixelFormat32bppGrayFloat;
			break;
		case FIT_RGB16:		// 48-bit RGB image			: 3 x 16-bit
			*guid_format = GUID_PKPixelFormat48bppRGB;
			break;
		case FIT_RGBA16:	// 64-bit RGBA image		: 4 x 16-bit
			*guid_format = GUID_PKPixelFormat64bppRGBA;
			*bHasAlpha = TRUE;
			break;
		case FIT_RGBF:		// 96-bit RGB float image	: 3 x 32-bit IEEE floating point
			*guid_format = GUID_PKPixelFormat96bppRGBFloat;
			break;
		case FIT_RGBAF:		// 128-bit RGBA float image	: 4 x 32-bit IEEE floating point
			*guid_format = GUID_PKPixelFormat128bppRGBAFloat;
			*bHasAlpha = TRUE;
			break;

		case FIT_INT16:		// array of short			: signed 16-bit
		case FIT_UINT32:	// array of unsigned long	: unsigned 32-bit
		case FIT_INT32:		// array of long			: signed 32-bit
		case FIT_DOUBLE:	// array of double			: 64-bit IEEE floating point
		case FIT_COMPLEX:	// array of FICOMPLEX		: 2 x 64-bit IEEE floating point

		default:
			// unsupported format
			break;
	}

	return (*guid_format != GUID_PKPixelFormatDontCare) ? WMP_errSuccess : WMP_errUnsupportedFormat;
}

// ==========================================================
// Metadata loading
// ==========================================================

/**
Read a JPEG-XR IFD as a buffer
@see ReadMetadata
*/
static ERR
ReadProfile(WMPStream* pStream, unsigned cbByteCount, unsigned uOffset, BYTE **ppbProfile) {
	// (re-)allocate profile buffer
	BYTE *pbProfile = *ppbProfile;
	pbProfile = (BYTE*)realloc(pbProfile, cbByteCount);
	if(!pbProfile) {
		return WMP_errOutOfMemory;
	}
	// read the profile
	if(WMP_errSuccess == pStream->SetPos(pStream, uOffset)) {
		if(WMP_errSuccess == pStream->Read(pStream, pbProfile, cbByteCount)) {
			*ppbProfile = pbProfile;
			return WMP_errSuccess;
		}
	}
	return WMP_errFileIO;
}

/**
Convert a DPKPROPVARIANT to a FITAG, then store the tag as FIMD_EXIF_MAIN
@see ReadDescriptiveMetadata
*/
static BOOL
ReadPropVariant(WORD tag_id, const DPKPROPVARIANT & varSrc, FIBITMAP *dib) {
	DWORD dwSize;

	if(varSrc.vt == DPKVT_EMPTY) {
		return FALSE;
	}

	// get the tag key
	TagLib& s = TagLib::instance();
	const char *key = s.getTagFieldName(TagLib::EXIF_MAIN, tag_id, NULL);
	if(!key) {
		return FALSE;
	}

	// create a tag
	FITAG *tag = FreeImage_CreateTag();
	if(tag) {
		// set tag ID
		FreeImage_SetTagID(tag, tag_id);
		// set tag type, count, length and value
		switch (varSrc.vt) {
			case DPKVT_LPSTR:
				FreeImage_SetTagType(tag, FIDT_ASCII);
				dwSize = (DWORD)strlen(varSrc.VT.pszVal) + 1;
				FreeImage_SetTagCount(tag, dwSize);
				FreeImage_SetTagLength(tag, dwSize);
				FreeImage_SetTagValue(tag, varSrc.VT.pszVal);
				break;
			
			case DPKVT_LPWSTR:
				FreeImage_SetTagType(tag, FIDT_UNDEFINED);
				dwSize = (DWORD)(sizeof(U16) * (wcslen((wchar_t *) varSrc.VT.pwszVal) + 1)); // +1 for NULL term
				FreeImage_SetTagCount(tag, dwSize);
				FreeImage_SetTagLength(tag, dwSize);
				FreeImage_SetTagValue(tag, varSrc.VT.pwszVal);
				break;
	            
			case DPKVT_UI2:
				FreeImage_SetTagType(tag, FIDT_SHORT);
				FreeImage_SetTagCount(tag, 1);
				FreeImage_SetTagLength(tag, 2);
				FreeImage_SetTagValue(tag, &varSrc.VT.uiVal);
				break;

			case DPKVT_UI4:
				FreeImage_SetTagType(tag, FIDT_LONG);
				FreeImage_SetTagCount(tag, 1);
				FreeImage_SetTagLength(tag, 4);
				FreeImage_SetTagValue(tag, &varSrc.VT.ulVal);
				break;

			default:
				assert(FALSE); // This case is not handled
				break;
		}
		// get the tag desctiption
		const char *description = s.getTagDescription(TagLib::EXIF_MAIN, tag_id);
		FreeImage_SetTagDescription(tag, description);

		// store the tag
		FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, key, tag);

		FreeImage_DeleteTag(tag);
	}
	return TRUE;
}

/**
Read JPEG-XR descriptive metadata and store as EXIF_MAIN metadata
@see ReadPropVariant
*/
static ERR
ReadDescriptiveMetadata(PKImageDecode *pID, FIBITMAP *dib) {
	// get Exif TIFF metadata
	const DESCRIPTIVEMETADATA *pDescMetadata = &pID->WMP.sDescMetadata;
	// convert metadata to FITAG and store into the EXIF_MAIN metadata model
	ReadPropVariant(WMP_tagImageDescription, pDescMetadata->pvarImageDescription, dib);
	ReadPropVariant(WMP_tagCameraMake, pDescMetadata->pvarCameraMake, dib);
	ReadPropVariant(WMP_tagCameraModel, pDescMetadata->pvarCameraModel, dib);
	ReadPropVariant(WMP_tagSoftware, pDescMetadata->pvarSoftware, dib);
	ReadPropVariant(WMP_tagDateTime, pDescMetadata->pvarDateTime, dib);
	ReadPropVariant(WMP_tagArtist, pDescMetadata->pvarArtist, dib);
	ReadPropVariant(WMP_tagCopyright, pDescMetadata->pvarCopyright, dib);
	ReadPropVariant(WMP_tagRatingStars, pDescMetadata->pvarRatingStars, dib);
	ReadPropVariant(WMP_tagRatingValue, pDescMetadata->pvarRatingValue, dib);
	ReadPropVariant(WMP_tagCaption, pDescMetadata->pvarCaption, dib);
	ReadPropVariant(WMP_tagDocumentName, pDescMetadata->pvarDocumentName, dib);
	ReadPropVariant(WMP_tagPageName, pDescMetadata->pvarPageName, dib);
	ReadPropVariant(WMP_tagPageNumber, pDescMetadata->pvarPageNumber, dib);
	ReadPropVariant(WMP_tagHostComputer, pDescMetadata->pvarHostComputer, dib);
	return WMP_errSuccess;
}

/**
Read ICC, XMP, Exif, Exif-GPS, IPTC, descriptive (i.e. Exif-TIFF) metadata
@see ReadProfile, ReadDescriptiveMetadata
*/
static ERR
ReadMetadata(PKImageDecode *pID, FIBITMAP *dib) {
	ERR error_code = 0;		// error code as returned by the interface
	size_t currentPos = 0;	// current stream position
	
	WMPStream *pStream = pID->pStream;
	WmpDEMisc *wmiDEMisc = &pID->WMP.wmiDEMisc;
	BYTE *pbProfile = NULL;

	try {
		// save current position
		error_code = pStream->GetPos(pStream, &currentPos);
		JXR_CHECK(error_code);

		// ICC profile
		if(0 != wmiDEMisc->uColorProfileByteCount) {
			unsigned cbByteCount = wmiDEMisc->uColorProfileByteCount;
			unsigned uOffset = wmiDEMisc->uColorProfileOffset;
			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
			JXR_CHECK(error_code);
			FreeImage_CreateICCProfile(dib, pbProfile, cbByteCount);
		}

		// XMP metadata
		if(0 != wmiDEMisc->uXMPMetadataByteCount) {
			unsigned cbByteCount = wmiDEMisc->uXMPMetadataByteCount;
			unsigned uOffset = wmiDEMisc->uXMPMetadataOffset;
			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
			JXR_CHECK(error_code);
			// store the tag as XMP
			FITAG *tag = FreeImage_CreateTag();
			if(tag) {
				FreeImage_SetTagLength(tag, cbByteCount);
				FreeImage_SetTagCount(tag, cbByteCount);
				FreeImage_SetTagType(tag, FIDT_ASCII);
				FreeImage_SetTagValue(tag, pbProfile);
				FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
				FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);
				FreeImage_DeleteTag(tag);
			}
		}

		// IPTC metadata
		if(0 != wmiDEMisc->uIPTCNAAMetadataByteCount) {
			unsigned cbByteCount = wmiDEMisc->uIPTCNAAMetadataByteCount;
			unsigned uOffset = wmiDEMisc->uIPTCNAAMetadataOffset;
			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
			JXR_CHECK(error_code);
			// decode the IPTC profile
			read_iptc_profile(dib, pbProfile, cbByteCount);
		}

		// Exif metadata
		if(0 != wmiDEMisc->uEXIFMetadataByteCount) {
			unsigned cbByteCount = wmiDEMisc->uEXIFMetadataByteCount;
			unsigned uOffset = wmiDEMisc->uEXIFMetadataOffset;
			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
			JXR_CHECK(error_code);
			// decode the Exif profile
			jpegxr_read_exif_profile(dib, pbProfile, cbByteCount, uOffset);
		}

		// Exif-GPS metadata
		if(0 != wmiDEMisc->uGPSInfoMetadataByteCount) {
			unsigned cbByteCount = wmiDEMisc->uGPSInfoMetadataByteCount;
			unsigned uOffset = wmiDEMisc->uGPSInfoMetadataOffset;
			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
			JXR_CHECK(error_code);
			// decode the Exif-GPS profile
			jpegxr_read_exif_gps_profile(dib, pbProfile, cbByteCount, uOffset);
		}

		// free profile buffer
		free(pbProfile);
		// restore initial position
		error_code = pID->pStream->SetPos(pID->pStream, currentPos);
		JXR_CHECK(error_code);

		// as a LAST STEP, read descriptive metadata
		// these metadata overwrite possible identical Exif-TIFF metadata 
		// that could have been read inside the Exif IFD
		
		return ReadDescriptiveMetadata(pID, dib);

	} catch(...) {
		// free profile buffer
		free(pbProfile);
		if(currentPos) {
			// restore initial position
			pStream->SetPos(pStream, currentPos);
		}
		return error_code;
	}
}

// ==========================================================
// Metadata saving
// ==========================================================

/**
Convert a FITAG (coming from FIMD_EXIF_MAIN) to a DPKPROPVARIANT.
No allocation is needed here, the function just copy pointers when needed. 
@see WriteDescriptiveMetadata
*/
static BOOL
WritePropVariant(FIBITMAP *dib, WORD tag_id, DPKPROPVARIANT & varDst) {
	FITAG *tag = NULL;

	TagLib& s = TagLib::instance();
	
	// clear output DPKPROPVARIANT
	varDst.vt = DPKVT_EMPTY;

	// given the tag id, get the tag key
	const char *key = s.getTagFieldName(TagLib::EXIF_MAIN, tag_id, NULL);
	// then, get the tag info
	if(!FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, key, &tag)) {
		return FALSE;
	}

	// set the tag value
	switch(FreeImage_GetTagType(tag)) {
		case FIDT_ASCII:
			varDst.vt = DPKVT_LPSTR;
			varDst.VT.pszVal = (char*)FreeImage_GetTagValue(tag);
			break;
		case FIDT_BYTE:
		case FIDT_UNDEFINED:
			varDst.vt = DPKVT_LPWSTR;
			varDst.VT.pwszVal = (U16*)FreeImage_GetTagValue(tag);
			break;
		case FIDT_SHORT:
			varDst.vt = DPKVT_UI2;
			varDst.VT.uiVal = *((U16*)FreeImage_GetTagValue(tag));
			break;
		case FIDT_LONG:
			varDst.vt = DPKVT_UI4;
			varDst.VT.ulVal = *((U32*)FreeImage_GetTagValue(tag));
			break;
		default:
			break;
	}
	
	return TRUE;
}

/**
Write EXIF_MAIN metadata to JPEG-XR descriptive metadata
@see WritePropVariant
*/
static ERR
WriteDescriptiveMetadata(PKImageEncode *pIE, FIBITMAP *dib) {
	ERR error_code = 0;		// error code as returned by the interface
	DESCRIPTIVEMETADATA DescMetadata;

	// fill the DESCRIPTIVEMETADATA structure (use pointers to arrays when needed)
	WritePropVariant(dib, WMP_tagImageDescription, DescMetadata.pvarImageDescription);
	WritePropVariant(dib, WMP_tagCameraMake, DescMetadata.pvarCameraMake);
	WritePropVariant(dib, WMP_tagCameraModel, DescMetadata.pvarCameraModel);
	WritePropVariant(dib, WMP_tagSoftware, DescMetadata.pvarSoftware);
	WritePropVariant(dib, WMP_tagDateTime, DescMetadata.pvarDateTime);
	WritePropVariant(dib, WMP_tagArtist, DescMetadata.pvarArtist);
	WritePropVariant(dib, WMP_tagCopyright, DescMetadata.pvarCopyright);
	WritePropVariant(dib, WMP_tagRatingStars, DescMetadata.pvarRatingStars);
	WritePropVariant(dib, WMP_tagRatingValue, DescMetadata.pvarRatingValue);
	WritePropVariant(dib, WMP_tagCaption, DescMetadata.pvarCaption);
	WritePropVariant(dib, WMP_tagDocumentName, DescMetadata.pvarDocumentName);
	WritePropVariant(dib, WMP_tagPageName, DescMetadata.pvarPageName);
	WritePropVariant(dib, WMP_tagPageNumber, DescMetadata.pvarPageNumber);
	WritePropVariant(dib, WMP_tagHostComputer, DescMetadata.pvarHostComputer);

	// copy the structure to the encoder
	error_code = pIE->SetDescriptiveMetadata(pIE, &DescMetadata);

	// no need to free anything here
	return error_code;
}

/**
Write ICC, XMP, Exif, Exif-GPS, IPTC, descriptive (i.e. Exif-TIFF) metadata
*/
static ERR
WriteMetadata(PKImageEncode *pIE, FIBITMAP *dib) {
	ERR error_code = 0;		// error code as returned by the interface
	BYTE *profile = NULL;
	unsigned profile_size = 0;
	
	try {
		// write ICC profile
		{
			FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
			if(iccProfile->data) {
				error_code = pIE->SetColorContext(pIE, (U8*)iccProfile->data, iccProfile->size);
				JXR_CHECK(error_code);
			}
		}
		
		// write descriptive metadata
		if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, dib)) {
			error_code = WriteDescriptiveMetadata(pIE, dib);
			JXR_CHECK(error_code);
		}

		// write IPTC metadata
		if(FreeImage_GetMetadataCount(FIMD_IPTC, dib)) {
			// create a binary profile
			if(write_iptc_profile(dib, &profile, &profile_size)) {
				// write the profile
				error_code = PKImageEncode_SetIPTCNAAMetadata_WMP(pIE, profile, profile_size);
				JXR_CHECK(error_code);
				// release profile
				free(profile);
				profile = NULL;
			}
		}

		// write XMP metadata
		{
			FITAG *tag_xmp = NULL;
			if(FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag_xmp)) {
				error_code = PKImageEncode_SetXMPMetadata_WMP(pIE, (BYTE*)FreeImage_GetTagValue(tag_xmp), FreeImage_GetTagLength(tag_xmp));
				JXR_CHECK(error_code);
			}
		}

		// write Exif metadata
		{
			if(tiff_get_ifd_profile(dib, FIMD_EXIF_EXIF, &profile, &profile_size)) {
				error_code = PKImageEncode_SetEXIFMetadata_WMP(pIE, profile, profile_size);
				JXR_CHECK(error_code);
				// release profile
				free(profile);
				profile = NULL;
			}
		}

		// write Exif GPS metadata
		{
			if(tiff_get_ifd_profile(dib, FIMD_EXIF_GPS, &profile, &profile_size)) {
				error_code = PKImageEncode_SetGPSInfoMetadata_WMP(pIE, profile, profile_size);
				JXR_CHECK(error_code);
				// release profile
				free(profile);
				profile = NULL;
			}
		}

		return WMP_errSuccess;

	} catch(...) {
		free(profile);
		return error_code;
	}
}



// ==========================================================
// Quantization tables (Y, U, V, YHP, UHP, VHP), 
// optimized for PSNR
// ==========================================================

static const int DPK_QPS_420[11][6] = {      // for 8 bit only
    { 66, 65, 70, 72, 72, 77 },
    { 59, 58, 63, 64, 63, 68 },
    { 52, 51, 57, 56, 56, 61 },
    { 48, 48, 54, 51, 50, 55 },
    { 43, 44, 48, 46, 46, 49 },
    { 37, 37, 42, 38, 38, 43 },
    { 26, 28, 31, 27, 28, 31 },
    { 16, 17, 22, 16, 17, 21 },
    { 10, 11, 13, 10, 10, 13 },
    {  5,  5,  6,  5,  5,  6 },
    {  2,  2,  3,  2,  2,  2 }
};

static const int DPK_QPS_8[12][6] = {
    { 67, 79, 86, 72, 90, 98 },
    { 59, 74, 80, 64, 83, 89 },
    { 53, 68, 75, 57, 76, 83 },
    { 49, 64, 71, 53, 70, 77 },
    { 45, 60, 67, 48, 67, 74 },
    { 40, 56, 62, 42, 59, 66 },
    { 33, 49, 55, 35, 51, 58 },
    { 27, 44, 49, 28, 45, 50 },
    { 20, 36, 42, 20, 38, 44 },
    { 13, 27, 34, 13, 28, 34 },
    {  7, 17, 21,  8, 17, 21 }, // Photoshop 100%
    {  2,  5,  6,  2,  5,  6 }
};

static const int DPK_QPS_16[11][6] = {
    { 197, 203, 210, 202, 207, 213 },
    { 174, 188, 193, 180, 189, 196 },
    { 152, 167, 173, 156, 169, 174 },
    { 135, 152, 157, 137, 153, 158 },
    { 119, 137, 141, 119, 138, 142 },
    { 102, 120, 125, 100, 120, 124 },
    {  82,  98, 104,  79,  98, 103 },
    {  60,  76,  81,  58,  76,  81 },
    {  39,  52,  58,  36,  52,  58 },
    {  16,  27,  33,  14,  27,  33 },
    {   5,   8,   9,   4,   7,   8 }
};

static const int DPK_QPS_16f[11][6] = {
    { 148, 177, 171, 165, 187, 191 },
    { 133, 155, 153, 147, 172, 181 },
    { 114, 133, 138, 130, 157, 167 },
    {  97, 118, 120, 109, 137, 144 },
    {  76,  98, 103,  85, 115, 121 },
    {  63,  86,  91,  62,  96,  99 },
    {  46,  68,  71,  43,  73,  75 },
    {  29,  48,  52,  27,  48,  51 },
    {  16,  30,  35,  14,  29,  34 },
    {   8,  14,  17,   7,  13,  17 },
    {   3,   5,   7,   3,   5,   6 }
};

static const int DPK_QPS_32f[11][6] = {
    { 194, 206, 209, 204, 211, 217 },
    { 175, 187, 196, 186, 193, 205 },
    { 157, 170, 177, 167, 180, 190 },
    { 133, 152, 156, 144, 163, 168 },
    { 116, 138, 142, 117, 143, 148 },
    {  98, 120, 123,  96, 123, 126 },
    {  80,  99, 102,  78,  99, 102 },
    {  65,  79,  84,  63,  79,  84 },
    {  48,  61,  67,  45,  60,  66 },
    {  27,  41,  46,  24,  40,  45 },
    {   3,  22,  24,   2,  21,  22 }
};

// ==========================================================
// Plugin Implementation
// ==========================================================

static const char * DLL_CALLCONV
Format() {
	return "JPEG-XR";
}

static const char * DLL_CALLCONV
Description() {
	return "JPEG XR image format";
}

static const char * DLL_CALLCONV
Extension() {
	return "jxr,wdp,hdp";
}

static const char * DLL_CALLCONV
RegExpr() {
	return NULL;
}

static const char * DLL_CALLCONV
MimeType() {
	return "image/vnd.ms-photo";
}

static BOOL DLL_CALLCONV
Validate(FreeImageIO *io, fi_handle handle) {
	BYTE jxr_signature[3] = { 0x49, 0x49, 0xBC };
	BYTE signature[3] = { 0, 0, 0 };

	io->read_proc(&signature, 1, 3, handle);

	return (memcmp(jxr_signature, signature, 3) == 0);
}

static BOOL DLL_CALLCONV
SupportsExportDepth(int depth) {
	return (
		(depth == 1)  ||
		(depth == 8)  ||
		(depth == 16) ||
		(depth == 24) || 
		(depth == 32)
		);
}

static BOOL DLL_CALLCONV 
SupportsExportType(FREE_IMAGE_TYPE type) {
	return (
		(type == FIT_BITMAP) ||
		(type == FIT_UINT16) ||
		(type == FIT_RGB16)  ||
		(type == FIT_RGBA16) ||
		(type == FIT_FLOAT)  ||
		(type == FIT_RGBF)   ||
		(type == FIT_RGBAF)
	);
}

static BOOL DLL_CALLCONV
SupportsICCProfiles() {
	return TRUE;
}

static BOOL DLL_CALLCONV
SupportsNoPixels() {
	return TRUE;
}

// ==========================================================
//	Open & Close
// ==========================================================

static void * DLL_CALLCONV
Open(FreeImageIO *io, fi_handle handle, BOOL read) {
	WMPStream *pStream = NULL;	// stream interface
	if(io && handle) {
		// allocate the FreeImageIO stream wrapper
		FreeImageJXRIO *jxr_io = (FreeImageJXRIO*)malloc(sizeof(FreeImageJXRIO));
		if(jxr_io) {
			jxr_io->io = io;
			jxr_io->handle = handle;
			// create a JXR stream wrapper
			if(_jxr_io_Create(&pStream, jxr_io) != WMP_errSuccess) {
				free(jxr_io);
				return NULL;
			}
		}
	}
	return pStream;
}

static void DLL_CALLCONV
Close(FreeImageIO *io, fi_handle handle, void *data) {
	WMPStream *pStream = (WMPStream*)data;
	if(pStream) {
		// free the FreeImageIO stream wrapper
		FreeImageJXRIO *jxr_io = (FreeImageJXRIO*)pStream->state.pvObj;
		free(jxr_io);
		// free the JXR stream wrapper
		pStream->fMem = TRUE;
		_jxr_io_Close(&pStream);
	}
}

// ==========================================================
//	Load
// ==========================================================

/**
Set decoder parameters
@param pDecoder Decoder handle
@param flags FreeImage load flags
*/
static void 
SetDecoderParameters(PKImageDecode *pDecoder, int flags) {
	// load image & alpha for formats with alpha
	pDecoder->WMP.wmiSCP.uAlphaMode = 2;
	// more options to come ...
}

/**
Copy or convert & copy decoded pixels into the dib
@param pDecoder Decoder handle
@param out_guid_format Target guid format
@param dib Output dib
@param width Image width
@param height Image height
@return Returns 0 if successful, returns ERR otherwise
*/
static ERR
CopyPixels(PKImageDecode *pDecoder, PKPixelFormatGUID out_guid_format, FIBITMAP *dib, int width, int height) {
	PKFormatConverter *pConverter = NULL;	// pixel format converter
	ERR error_code = 0;	// error code as returned by the interface
	BYTE *pb = NULL;	// local buffer used for pixel format conversion
	
	// image dimensions
	const PKRect rect = {0, 0, width, height};

	try {
		// get input file pixel format ...
		PKPixelFormatGUID in_guid_format;
		error_code = pDecoder->GetPixelFormat(pDecoder, &in_guid_format);
		JXR_CHECK(error_code);
		
		// is a format conversion needed ?

		if(IsEqualGUID(out_guid_format, in_guid_format)) {
			// no conversion, load bytes "as is" ...

			// get a pointer to dst pixel data
			BYTE *dib_bits = FreeImage_GetBits(dib);

			// get dst pitch (count of BYTE for stride)
			const unsigned cbStride = FreeImage_GetPitch(dib);			

			// decode and copy bits to dst array
			error_code = pDecoder->Copy(pDecoder, &rect, dib_bits, cbStride);
			JXR_CHECK(error_code);		
		}
		else {
			// we need to use the conversion API ...
			
			// allocate the pixel format converter
			error_code = PKCodecFactory_CreateFormatConverter(&pConverter);
			JXR_CHECK(error_code);
			
			// set the conversion function
			error_code = pConverter->Initialize(pConverter, pDecoder, NULL, out_guid_format);
			JXR_CHECK(error_code);
			
			// get the maximum stride
			unsigned cbStride = 0;
			{
				PKPixelInfo pPIFrom;
				PKPixelInfo pPITo;
				
				pPIFrom.pGUIDPixFmt = &in_guid_format;
				error_code = PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
				JXR_CHECK(error_code);

				pPITo.pGUIDPixFmt = &out_guid_format;
				error_code = PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
				JXR_CHECK(error_code);

				unsigned cbStrideFrom = ((pPIFrom.cbitUnit + 7) >> 3) * width;
				unsigned cbStrideTo = ((pPITo.cbitUnit + 7) >> 3) * width;
				cbStride = MAX(cbStrideFrom, cbStrideTo);
			}

			// allocate a local decoder / encoder buffer
			error_code = PKAllocAligned((void **) &pb, cbStride * height, 128);
			JXR_CHECK(error_code);

			// copy / convert pixels
			error_code = pConverter->Copy(pConverter, &rect, pb, cbStride);
			JXR_CHECK(error_code);

			// now copy pixels into the dib
			const size_t line_size = FreeImage_GetLine(dib);
			for(int y = 0; y < height; y++) {
				BYTE *src_bits = (BYTE*)(pb + y * cbStride);
				BYTE *dst_bits = (BYTE*)FreeImage_GetScanLine(dib, y);
				memcpy(dst_bits, src_bits, line_size);
			}
			
			// free the local buffer
			PKFreeAligned((void **) &pb);

			// free the pixel format converter
			PKFormatConverter_Release(&pConverter);
		}

		// FreeImage DIB are upside-down relative to usual graphic conventions
		FreeImage_FlipVertical(dib);

		// post-processing ...
		// -------------------

		// swap RGB as needed

#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
		if(IsEqualGUID(out_guid_format, GUID_PKPixelFormat24bppRGB) || IsEqualGUID(out_guid_format, GUID_PKPixelFormat32bppRGB)) {
			SwapRedBlue32(dib);
		}
#elif FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
		if(IsEqualGUID(out_guid_format, GUID_PKPixelFormat24bppBGR) || IsEqualGUID(out_guid_format, GUID_PKPixelFormat32bppBGR)) {
			SwapRedBlue32(dib);
		}
#endif
		
		return WMP_errSuccess;

	} catch(...) {
		// free the local buffer
		PKFreeAligned((void **) &pb);
		// free the pixel format converter
		PKFormatConverter_Release(&pConverter);

		return error_code;
	}
}

// --------------------------------------------------------------------------

static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	PKImageDecode *pDecoder = NULL;	// decoder interface
	ERR error_code = 0;				// error code as returned by the interface
	PKPixelFormatGUID guid_format;	// loaded pixel format (== input file pixel format if no conversion needed)
	
	FREE_IMAGE_TYPE image_type = FIT_UNKNOWN;	// input image type
	unsigned bpp = 0;							// input image bit depth
	FIBITMAP *dib = NULL;
	
	// get the I/O stream wrapper
	WMPStream *pDecodeStream = (WMPStream*)data;

	if(!handle || !pDecodeStream) {
		return NULL;
	}

	BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;

	try {
		int width, height;	// image dimensions (in pixels)

		// create a JXR decoder interface and initialize function pointers with *_WMP functions
		error_code = PKImageDecode_Create_WMP(&pDecoder);
		JXR_CHECK(error_code);

		// attach the stream to the decoder ...
		// ... then read the image container and the metadata
		error_code = pDecoder->Initialize(pDecoder, pDecodeStream);
		JXR_CHECK(error_code);

		// set decoder parameters
		SetDecoderParameters(pDecoder, flags);

		// get dst image format specifications
		unsigned red_mask = 0, green_mask = 0, blue_mask = 0;
		error_code = GetInputPixelFormat(pDecoder, &guid_format, &image_type, &bpp, &red_mask, &green_mask, &blue_mask);
		JXR_CHECK(error_code);

		// get image dimensions
		pDecoder->GetSize(pDecoder, &width, &height);

		// allocate dst image
		{			
			dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, bpp, red_mask, green_mask, blue_mask);
			if(!dib) {
				throw FI_MSG_ERROR_DIB_MEMORY;
			}
			if(FreeImage_GetBPP(dib) == 1) {
				// BD_1 - build a FIC_MINISBLACK palette
				RGBQUAD *pal = FreeImage_GetPalette(dib);
				pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
				pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
			}
		}

		// get image resolution
		{
			float resX, resY;	// image resolution (in dots per inch)
			// convert from English units, i.e. dots per inch to universal units, i.e. dots per meter
			pDecoder->GetResolution(pDecoder, &resX, &resY);
			FreeImage_SetDotsPerMeterX(dib, (unsigned)(resX / 0.0254F + 0.5F));
			FreeImage_SetDotsPerMeterY(dib, (unsigned)(resY / 0.0254F + 0.5F));
		}

		// get metadata & ICC profile
		error_code = ReadMetadata(pDecoder, dib);
		JXR_CHECK(error_code);

		if(header_only) {
			// header only mode ...
			
			// free the decoder
			pDecoder->Release(&pDecoder);
			assert(pDecoder == NULL);

			return dib;
		}
		
		// copy pixels into the dib, perform pixel conversion if needed
		error_code = CopyPixels(pDecoder, guid_format, dib, width, height);
		JXR_CHECK(error_code);

		// free the decoder
		pDecoder->Release(&pDecoder);
		assert(pDecoder == NULL);

		return dib;

	} catch (const char *message) {
		// unload the dib
		FreeImage_Unload(dib);
		// free the decoder
		pDecoder->Release(&pDecoder);

		if(NULL != message) {
			FreeImage_OutputMessageProc(s_format_id, message);
		}
	}

	return NULL;
}

// ==========================================================
//	Save
// ==========================================================

/**
Configure compression parameters

ImageQuality  Q (BD==1)  Q (BD==8)   Q (BD==16)  Q (BD==32F) Subsample   Overlap
[0.0, 0.4]    8-IQ*5     (see table) (see table) (see table) 4:4:4       2
(0.4, 0.8)    8-IQ*5     (see table) (see table) (see table) 4:4:4       1
[0.8, 1.0)    8-IQ*5     (see table) (see table) (see table) 4:4:4       1
[1.0, 1.0]    1          1           1           1           4:4:4       0

@param wmiSCP Encoder parameters
@param pixelInfo Image specifications
@param fltImageQuality Image output quality in [0..1), 1 means lossless
*/
static void 
SetCompression(CWMIStrCodecParam *wmiSCP, const PKPixelInfo *pixelInfo, float fltImageQuality) {
    if(fltImageQuality < 1.0F) {
        // overlap
		if(fltImageQuality >= 0.5F) {
			wmiSCP->olOverlap = OL_ONE;
		} else {
			wmiSCP->olOverlap = OL_TWO;
		}
		// chroma sub-sampling
		if(fltImageQuality >= 0.5F || pixelInfo->uBitsPerSample > 8) {
			wmiSCP->cfColorFormat = YUV_444;
		} else {
			wmiSCP->cfColorFormat = YUV_420;
		}

	    // bit depth
		if(pixelInfo->bdBitDepth == BD_1) {
			wmiSCP->uiDefaultQPIndex = (U8)(8 - 5.0F * fltImageQuality + 0.5F);
		}
		else {
			// remap [0.8, 0.866, 0.933, 1.0] to [0.8, 0.9, 1.0, 1.1]
            // to use 8-bit DPK QP table (0.933 == Photoshop JPEG 100)
            if(fltImageQuality > 0.8F && pixelInfo->bdBitDepth == BD_8 && wmiSCP->cfColorFormat != YUV_420 && wmiSCP->cfColorFormat != YUV_422) {
				fltImageQuality = 0.8F + (fltImageQuality - 0.8F) * 1.5F;
			}

            const int qi = (int) (10.0F * fltImageQuality);
            const float qf = 10.0F * fltImageQuality - (float)qi;
			
			const int *pQPs = 
				(wmiSCP->cfColorFormat == YUV_420 || wmiSCP->cfColorFormat == YUV_422) ?
				DPK_QPS_420[qi] :
				(pixelInfo->bdBitDepth == BD_8 ? DPK_QPS_8[qi] :
				(pixelInfo->bdBitDepth == BD_16 ? DPK_QPS_16[qi] :
				(pixelInfo->bdBitDepth == BD_16F ? DPK_QPS_16f[qi] :
				DPK_QPS_32f[qi])));
				
			wmiSCP->uiDefaultQPIndex = (U8) (0.5F + (float) pQPs[0] * (1.0F - qf) + (float) (pQPs + 6)[0] * qf);
			wmiSCP->uiDefaultQPIndexU = (U8) (0.5F + (float) pQPs[1] * (1.0F - qf) + (float) (pQPs + 6)[1] * qf);
			wmiSCP->uiDefaultQPIndexV = (U8) (0.5F + (float) pQPs[2] * (1.0F - qf) + (float) (pQPs + 6)[2] * qf);
            wmiSCP->uiDefaultQPIndexYHP = (U8) (0.5F + (float) pQPs[3] * (1.0F - qf) + (float) (pQPs + 6)[3] * qf);
			wmiSCP->uiDefaultQPIndexUHP = (U8) (0.5F + (float) pQPs[4] * (1.0F - qf) + (float) (pQPs + 6)[4] * qf);
			wmiSCP->uiDefaultQPIndexVHP = (U8) (0.5F + (float) pQPs[5] * (1.0F - qf) + (float) (pQPs + 6)[5] * qf);
		}
	} // fltImageQuality < 1.0F
    else {
		// lossless mode
		wmiSCP->uiDefaultQPIndex = 1;
	}
}

/**
Set encoder parameters
@param wmiSCP Encoder parameters
@param pixelInfo Image specifications
@param flags FreeImage save flags
@param bHasAlpha TRUE if an alpha layer is present
*/
static void 
SetEncoderParameters(CWMIStrCodecParam *wmiSCP, const PKPixelInfo *pixelInfo, int flags, BOOL bHasAlpha) {
	float fltImageQuality = 1.0F;

	// all values have been set to zero by the API
	// update default values for some attributes
    wmiSCP->cfColorFormat = YUV_444;		// color format
    wmiSCP->bdBitDepth = BD_LONG;			// internal bit depth
    wmiSCP->bfBitstreamFormat = SPATIAL;	// compressed image data in spatial order
    wmiSCP->bProgressiveMode = FALSE;		// sequential mode
    wmiSCP->olOverlap = OL_ONE;				// single level overlap processing 
	wmiSCP->cNumOfSliceMinus1H = 0;			// # of horizontal slices
	wmiSCP->cNumOfSliceMinus1V = 0;			// # of vertical slices
    wmiSCP->sbSubband = SB_ALL;				// keep all subbands
    wmiSCP->uAlphaMode = 0;					// 0:no alpha 1: alpha only else: something + alpha 
    wmiSCP->uiDefaultQPIndex = 1;			// quantization for grey or rgb layer(s), 1: lossless
    wmiSCP->uiDefaultQPIndexAlpha = 1;		// quantization for alpha layer, 1: lossless

	// process the flags
	// -----------------

	// progressive mode
	if((flags & JXR_PROGRESSIVE) == JXR_PROGRESSIVE) {
		// turn on progressive mode (instead of sequential mode)
		wmiSCP->bProgressiveMode = TRUE;
	}

	// quality in [0.01 - 1.0), 1.0 means lossless - default is 0.80
	int quality = flags & 0x7F;
	if(quality == 0) {
		// defaut to 0.80
		fltImageQuality = 0.8F;
	} else if((flags & JXR_LOSSLESS) == JXR_LOSSLESS) {
		fltImageQuality = 1.0F;
	} else {
		quality = (quality >= 100) ? 100 : quality;
		fltImageQuality = quality / 100.0F;
	}
	SetCompression(wmiSCP, pixelInfo, fltImageQuality);

	// alpha compression
	if(bHasAlpha) {
		wmiSCP->uAlphaMode = 2;	// encode with a planar alpha channel
	}
}

// --------------------------------------------------------------------------

static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	BOOL bIsFlipped = FALSE;		// FreeImage DIB are upside-down relative to usual graphic conventions
	PKPixelFormatGUID guid_format;	// image format
	PKPixelInfo pixelInfo;			// image specifications
	BOOL bHasAlpha = FALSE;			// is alpha layer present ?

	PKImageEncode *pEncoder = NULL;		// encoder interface
	ERR error_code = 0;					// error code as returned by the interface

	// get the I/O stream wrapper
	WMPStream *pEncodeStream = (WMPStream*)data;

	if(!dib || !handle || !pEncodeStream) {
		return FALSE;
	}

	try {
		// get image dimensions
		unsigned width = FreeImage_GetWidth(dib);
		unsigned height = FreeImage_GetHeight(dib);

		// check JPEG-XR limits
		if((width < MB_WIDTH_PIXEL) || (height < MB_HEIGHT_PIXEL)) {
			FreeImage_OutputMessageProc(s_format_id, "Unsupported image size: width x height = %d x %d", width, height);
			throw (const char*)NULL;
		}

		// get output pixel format
		error_code = GetOutputPixelFormat(dib, &guid_format, &bHasAlpha);
		JXR_CHECK(error_code);
		pixelInfo.pGUIDPixFmt = &guid_format;
		error_code = PixelFormatLookup(&pixelInfo, LOOKUP_FORWARD);
		JXR_CHECK(error_code);

		// create a JXR encoder interface and initialize function pointers with *_WMP functions
		error_code = PKImageEncode_Create_WMP(&pEncoder);
		JXR_CHECK(error_code);

		// attach the stream to the encoder and set all encoder parameters to zero ...
		error_code = pEncoder->Initialize(pEncoder, pEncodeStream, &pEncoder->WMP.wmiSCP, sizeof(CWMIStrCodecParam));
		JXR_CHECK(error_code);

		// ... then configure the encoder
		SetEncoderParameters(&pEncoder->WMP.wmiSCP, &pixelInfo, flags, bHasAlpha);

		// set pixel format
		pEncoder->SetPixelFormat(pEncoder, guid_format);

		// set image size
		pEncoder->SetSize(pEncoder, width, height);
		
		// set resolution (convert from universal units to English units)
		float resX = (float)(unsigned)(0.5F + 0.0254F * FreeImage_GetDotsPerMeterX(dib));
		float resY = (float)(unsigned)(0.5F + 0.0254F * FreeImage_GetDotsPerMeterY(dib));
		pEncoder->SetResolution(pEncoder, resX, resY);

		// set metadata
		WriteMetadata(pEncoder, dib);

		// write metadata & pixels
		// -----------------------

		// dib coordinates are upside-down relative to usual conventions
		bIsFlipped = FreeImage_FlipVertical(dib);

		// get a pointer to dst pixel data
		BYTE *dib_bits = FreeImage_GetBits(dib);

		// get dst pitch (count of BYTE for stride)
		const unsigned cbStride = FreeImage_GetPitch(dib);

		// write metadata + pixels on output
		error_code = pEncoder->WritePixels(pEncoder, height, dib_bits, cbStride);
		JXR_CHECK(error_code);

		// recover dib coordinates
		FreeImage_FlipVertical(dib);

		// free the encoder
		pEncoder->Release(&pEncoder);
		assert(pEncoder == NULL);
		
		return TRUE;

	} catch (const char *message) {
		if(bIsFlipped) {
			// recover dib coordinates
			FreeImage_FlipVertical(dib);
		}
		if(pEncoder) {
			// free the encoder
			pEncoder->Release(&pEncoder);
			assert(pEncoder == NULL);
		}
		if(NULL != message) {
			FreeImage_OutputMessageProc(s_format_id, message);
		}
	}

	return FALSE;
}

// ==========================================================
//	 Init
// ==========================================================

void DLL_CALLCONV
InitJXR(Plugin *plugin, int format_id) {
	s_format_id = format_id;

	plugin->format_proc = Format;
	plugin->description_proc = Description;
	plugin->extension_proc = Extension;
	plugin->regexpr_proc = RegExpr;
	plugin->open_proc = Open;
	plugin->close_proc = Close;
	plugin->pagecount_proc = NULL;
	plugin->pagecapability_proc = NULL;
	plugin->load_proc = Load;
	plugin->save_proc = Save;
	plugin->validate_proc = Validate;
	plugin->mime_proc = MimeType;
	plugin->supports_export_bpp_proc = SupportsExportDepth;
	plugin->supports_export_type_proc = SupportsExportType;
	plugin->supports_icc_profiles_proc = SupportsICCProfiles;
	plugin->supports_no_pixels_proc = SupportsNoPixels;
}

