summaryrefslogtreecommitdiff
path: root/libs/freeimage/src/FreeImage/PluginJPEG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/freeimage/src/FreeImage/PluginJPEG.cpp')
-rw-r--r--libs/freeimage/src/FreeImage/PluginJPEG.cpp55
1 files changed, 45 insertions, 10 deletions
diff --git a/libs/freeimage/src/FreeImage/PluginJPEG.cpp b/libs/freeimage/src/FreeImage/PluginJPEG.cpp
index 49e653d9e0..4dbd5d26a6 100644
--- a/libs/freeimage/src/FreeImage/PluginJPEG.cpp
+++ b/libs/freeimage/src/FreeImage/PluginJPEG.cpp
@@ -1,4 +1,4 @@
-// ==========================================================
+// ==========================================================
// JPEG Loader and writer
// Based on code developed by The Independent JPEG Group
//
@@ -1126,8 +1126,9 @@ Validate(FreeImageIO *io, fi_handle handle) {
static BOOL DLL_CALLCONV
SupportsExportDepth(int depth) {
return (
- (depth == 8) ||
- (depth == 24)
+ (depth == 8) ||
+ (depth == 24) ||
+ (depth == 32) // only if 32-bit CMYK
);
}
@@ -1315,6 +1316,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
dst += 3;
}
}
+
+ // if original image is CMYK but is converted to RGB, remove ICC profile from Exif-TIFF metadata
+ FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, "InterColorProfile", NULL);
+
} else if((cinfo.out_color_space == JCS_CMYK) && ((flags & JPEG_CMYK) == JPEG_CMYK)) {
// convert from LibJPEG CMYK to standard CMYK
@@ -1400,12 +1405,12 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
try {
// Check dib format
- const char *sError = "only 24-bit highcolor or 8-bit greyscale/palette bitmaps can be saved as JPEG";
+ const char *sError = "only 24-bit RGB, 8-bit greyscale/palette or 32-bit CMYK bitmaps can be saved as JPEG";
FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
WORD bpp = (WORD)FreeImage_GetBPP(dib);
- if ((bpp != 24) && (bpp != 8)) {
+ if ((bpp != 24) && (bpp != 8) && !(bpp == 32 && (color_type == FIC_CMYK))) {
throw sError;
}
@@ -1454,7 +1459,10 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
cinfo.in_color_space = JCS_GRAYSCALE;
cinfo.input_components = 1;
break;
-
+ case FIC_CMYK:
+ cinfo.in_color_space = JCS_CMYK;
+ cinfo.input_components = 4;
+ break;
default :
cinfo.in_color_space = JCS_RGB;
cinfo.input_components = 3;
@@ -1481,14 +1489,14 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
// thumbnail support (JFIF 1.02 extension markers)
if(FreeImage_GetThumbnail(dib) != NULL) {
- cinfo.write_JFIF_header = 1; //<### force it, though when color is CMYK it will be incorrect
+ cinfo.write_JFIF_header = static_cast<boolean>(1); //<### force it, though when color is CMYK it will be incorrect
cinfo.JFIF_minor_version = 2;
}
// baseline JPEG support
- if ((flags & JPEG_BASELINE) == JPEG_BASELINE) {
- cinfo.write_JFIF_header = 0; // No marker for non-JFIF colorspaces
- cinfo.write_Adobe_marker = 0; // write no Adobe marker by default
+ if ((flags & JPEG_BASELINE) == JPEG_BASELINE) {
+ cinfo.write_JFIF_header = static_cast<boolean>(0); // No marker for non-JFIF colorspaces
+ cinfo.write_Adobe_marker = static_cast<boolean>(0); // write no Adobe marker by default
}
// set subsampling options if required
@@ -1598,6 +1606,33 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
}
free(target);
}
+ else if(color_type == FIC_CMYK) {
+ unsigned pitch = FreeImage_GetPitch(dib);
+ BYTE *target = (BYTE*)malloc(pitch * sizeof(BYTE));
+ if (target == NULL) {
+ throw FI_MSG_ERROR_MEMORY;
+ }
+
+ while (cinfo.next_scanline < cinfo.image_height) {
+ // get a copy of the scanline
+ memcpy(target, FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1), pitch);
+
+ BYTE *target_p = target;
+ for(unsigned x = 0; x < cinfo.image_width; x++) {
+ // CMYK pixels are inverted
+ target_p[0] = ~target_p[0]; // C
+ target_p[1] = ~target_p[1]; // M
+ target_p[2] = ~target_p[2]; // Y
+ target_p[3] = ~target_p[3]; // K
+
+ target_p += 4;
+ }
+
+ // write the scanline
+ jpeg_write_scanlines(&cinfo, &target, 1);
+ }
+ free(target);
+ }
else if(color_type == FIC_MINISBLACK) {
// 8-bit standard greyscale images
while (cinfo.next_scanline < cinfo.image_height) {