Hey Jeff,
I've finally finished it. I just need to test compatibility with older versions of ImageMagick, but everything else works great for me! (with the exception of Photoshop EPS files, which I just noticed). I believe though that everything except EPS/AI and PDF files should work correctly, where EPS/AI and PDF files will assume sRGB (which I believe is the same as previous behaviour).
Here's the new code;
In config.php add the following (this replaces any other colour management related settings in config.php);
# ICC Colour Management Features (Experimental)
# Requires Exiftool and either Imagemagick or GraphicsMagick where ImageMagick is preferred
# Note that ImageMagick must be installed with LCMS or LCMS2 support
# The web server user (e.g. www-data) should have permissions to write to /iccprofiles to allow profile extraction
# Uncomment below to activate colour management
$colour_management=true;
# Display warnings when profiles are either incorrectly set in config.php or are required and are missing from the /iccprofiles directory
$display_profile_warnings=true;
# If $assign_profiles_to_untagged_images=true;, defining profiles for untagged images here will enable tagging for any untagged image of the corresponding colour mode (RGB, CMYK, Gray)
# Profiles must exist in the /iccprofiles directory of ResourceSpace for this to function and, apart from sRGB, are NOT included in the default installation.
# High quality CMYK offset printing profiles may be freely downloaded from http://colormanagement.org/
$assign_profiles_to_untagged_images=true;
$untagged_rgb_profile = 'sRGB_IEC61966-2-1_black_scaled.icc';
$untagged_cmyk_profile = 'ISOcoated_v2_bas.ICC';
$untagged_gray_profile = 'ISOcoated_v2_grey1c_bas.ICC';
# Turning on auto assigning of profiles will use Exiftool to check JPEG or TIFF captures from digital cameras to see if they indicate a profile in EXIF tags but do not have a profile embedded.
# Profiles are then assigned based upon the definitions below.
# Profiles must exist in the /iccprofiles directory of ResourceSpace for this to function and, apart from sRGB, are NOT included in the default installation.
# Some of these profiles may be downloadable from http://www.adobe.com/support/downloads/detail.jsp?ftpID=4076
# and http://color.org/profiles.xalter
# NOTE that $assign_profiles_to_untagged_images must be set to true for this section to apply
$auto_assign_based_on_exif_tags=true;
$default_srgb_profile = 'sRGB_IEC61966-2-1_black_scaled.icc';
$default_widegamut_profile = 'WideGamutRGB.icc';
$default_adobergb_profile = 'AdobeRGB1998.icc';
# This target profile will be used for the conversion for display but is discarded after conversion unless $preserve_target_profiles=true;
# In almost all cases, this should be set to 'sRGB_IEC61966-2-1_black_scaled.icc'
$icc_preview_profile = 'sRGB_IEC61966-2-1_black_scaled.icc';
# Additional options for profile conversion during preview generation
$icc_preview_options = '-intent relative -black-point-compensation';
# With $linear_resize enabled, ResourceSpace will tell ImageMagick/GraphicsMagick to convert the file to a linear tonal response curve before performing the resize operation. In some situations this may enable more accurate colour during resizing.
# Setting this option may increase preview generation time.
# See http://www.imagemagick.org/Usage/resize/#resize_colorspace
# CMYK images are not resized in linear as the colours become inaccurate in the conversion to linear and back to non-linear space.
#$linear_resize=true;
# Uncomment ONLY if using GraphicsMagick or ImageMagick v6.7.6-3 or older.
# Setting $tonal_response_curve_compatibility=true; sets the correct colour mode options for non-linear RGB when converting the image for compatibility with GraphicsMagick and ImageMagick v6.7.6-3 or older.
#$tonal_response_curve_compatibility=true;
# With $preserve_source_profiles=true;, source profiles are preserved for all files tagged with an ICC profile. No ICC colour space conversions are made.
# This option requires a colour managed browser with colour management turned on for correct display of preview images and thumbnails. E.g. Safari 2.0+, Chrome 22.0+, Firefox 3.6+ (ICC v2, v4 with manual config), Opera 12.10+
# Check browser compatibility here - http://www.color.org/version4html.xalter
#$preserve_source_profiles=true;
# With $preserve_source_profiles_large_only=true;, only Thumbnails, Screen resolution previews and Collection Thumbnails are converted to the target profile set by $icc_preview_profile. All other file sizes retain the original source profile.
#$preserve_source_profiles_large_only=true;
# Set $preserve_target_profiles=true; to ensure that images which have been converted to the target profile set by $icc_preview_profile preserve the target profile after conversion.
# If the target profile set in $icc_preview_profile is NOT sRGB IEC61966-2.1 then this setting is required for properly colour managed images. A colour managed browser is also required (see comments for $preserve_source_profiles=true; for details about browsers).
# If the target profile set in $icc_preview_profile is sRGB IEC61966-2.1 then, dependent upon browser behaviour, this setting may still be required for properly colour managed images (with the safest assumption to be that it IS required).
# Enabling this setting will add to the preview file size (approximately 4k per image).
$preserve_target_profiles=true;
In image_processing.php (replacing the section labelled # EXPERIMENTAL CODE TO USE EXISTING ICC PROFILE IF PRESENT);
/* ----------------------------------------
Colour Management section.
Requires Exiftool and ImageMagick
(GraphicsMagick is compatible however
all functions may not work correctly)
----------------------------------------
*/
// If GraphicsMagick or Imagemagick v6.7.6-3 or earlier is being used, set appropriate colourspace option.
// In each case, this setting will tell ImageMagick or GraphicsMagick to assume a non-linear (sRGB) tonal response curve when converting if the source file is non-linear. Only needed if there is no embedded profile and no profile will be assigned.
global $tonal_response_curve_compatibility, $tonal_response_curve_compatibility_options;
if ($tonal_response_curve_compatibility){
// Set 'RGB' for compatibility for GraphicsMagick or ImageMagick v6.7.6-3 or earlier
$tonal_response_curve_compatibility_options="RGB";
} else {
// Set 'sRGB' for ImageMagick v6.7.6-4 or newer
$tonal_response_curve_compatibility_options="sRGB";
}
// Check if colour management is enabled
global $colour_management;
if($colour_management){
global $imagemagick_path, $exiftool_path, $preserve_source_profiles, $preserve_target_profiles, $preserve_source_profiles_large_only, $assign_profiles_to_untagged_images, $tonal_response_curve_compatibility, $tonal_response_curve_compatibility_options, $assign_profile, $icc_profile, $icc_preview_profile, $icc_preview_options, $colourspace, $profile, $linear_resize, $display_profile_warnings, $supported_icc_colour_modes, $use_target_profile, $ffmpeg_supported_extensions;
/* ----------------------------------------
This section checks that a target profile
is defined and exists. All basic functions
of the Colour Managment section require a
target profile to work.
----------------------------------------
*/
if (!isset($icc_preview_profile)){
// No target profile set, exit
exit("No ICC target profile is set. An ICC preview profile must be set in config.php and the file exist to enable colour management.");
} else {
// A profile is set - check if it exists
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
if (!file_exists($targetprofile)){
exit("An ICC target profile is set however it cannot be found at the location $targetprofile. Check icc_preview_profile settings in config.php. Also check that the webserver user has access to /iccprofiles and has permissions to access the target profile. An ICC preview profile must be set in config.php and the file exist to enable colour management.");
}
}
/* ----------------------------------------
This section determines information about
the file including colour mode and if it
has an ICC profile or not
----------------------------------------
*/
// Locate Exiftool
$exiftool_fullpath = get_utility_path("exiftool");
if ($exiftool_fullpath==false){
// Exiftool not found, exit
exit("Could not find Exiftool utility at location '$exiftool_path'.");
} else {
// Extract the ICC profile description from image (if exist) using Exiftool
$icc_profile_extract=run_command($exiftool_fullpath.' -profiledescription '.escapeshellarg($file));
// Remove non profile name information
$icc_profile_extended_name = substr(strrchr($icc_profile_extract, ":"), 1);
$icc_profile=trim($icc_profile_extended_name);
// Remove special characters from the profile name for file naming purposes
$icc_profile = str_replace(" ", "_", $icc_profile); // Replaces all spaces with hyphens.
$icc_profile = preg_replace('/[^A-Za-z0-9\-]/', '', $icc_profile); // Removes special chars.
$icc_profile = preg_replace('/-+/', '_', $icc_profile); // Replaces multiple hyphens with single one.
}
// Define array of colour modes with specific handling
$supported_icc_colour_modes = array(
"RGB",
"sRGB",
"CMYK",
"Gray",
"CIELab",
);
// Locate ImageMagick
$convert_fullpath = get_utility_path("im-convert");
if ($convert_fullpath==false){
// ImageMagick not found, exit
exit("Could not find ImageMagick 'convert' utility at location '$imagemagick_path'.");
} else {
// Determine colour mode of image
$colourspace=run_command($convert_fullpath.' '.escapeshellarg($file).' -print "%[colorspace]\n" null:');
}
/* ----------------------------------------
This section determines behaviour of
colour space conversion.
----------------------------------------
*/
global $convert_profile, $strip_profile, $assign_profile;
// If the file is linear RGB, CIELab, an unsupported colourspace or a RAW file, then don't attempt to preserve profiles
if(preg_match('/^(dng|nef|x3f|cr2|crw|mrw|orf|raf|dcr)$/i', $extension, $rawext) || in_array($extension,$ffmpeg_supported_extensions) || (!$tonal_response_curve_compatibility && $colourspace=="RGB") || ($tonal_response_curve_compatibility && $colourspace=="sRGB") || $colourspace=="CIELab" || !in_array($colourspace, $supported_icc_colour_modes)){
$preserve_source_profiles="";
$preserve_source_profiles_large_only="";
}
// If $preserve_source_profiles=false;
if(!$preserve_source_profiles || !$preserve_source_profiles_large_only){
// Preserve the embedded source profile for all sizes then convert to the target profile.
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -profile '.escapeshellarg($targetprofile);
}
// If $preserve_source_profiles_large_only=true; then 'scr' sizes and smaller will be converted to the target profile specified.
if($preserve_source_profiles_large_only && ($id=="thm" || $id=="col" || $id=="pre" || $id=="scr")){
// Preserve the embedded source profile then convert smaller sizes to target display profile.
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -profile '.escapeshellarg($targetprofile);
$assign_profile="";
}
// If $preserve_source_profiles=true; and there is an embedded profile then preserve the embedded profile.
if($preserve_source_profiles){
// Preserve the embedded source or assigned profile for all sizes. No conversion will take place.
$convert_profile="";
}
// If $preserve_source_profiles_large_only=true; and there is an embedded profile then for sizes larger than 'scr', the embedded source profile will be preserved and no conversion will take place.
if($preserve_source_profiles_large_only && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr"){
// Preserve embedded source or assigned profile for larger sizes only.
$convert_profile="";
}
/* ----------------------------------------
This section determines specific behaviour
based upon colour mode. Special conditions
need to be considered for certain colour
modes.
----------------------------------------
*/
// Non-linear RGB
if ((!$tonal_response_curve_compatibility && $colourspace=="sRGB") || ($tonal_response_curve_compatibility && $colourspace=="RGB")){
// File is non-linear RGB
//echo "File is non-linear RGB";
/* ----------------------------------------
This section handles assigning ICC profiles
to untagged images. Profiles are assigned
dependent upon colour mode and the profiles
defined in config.php
----------------------------------------
*/
global $untagged_rgb_profile;
// Check if assigning profiles is set. Don't try to assign profiles for RAW images or video files.
if($assign_profiles_to_untagged_images && !$icc_profile && !preg_match('/^(dng|nef|x3f|cr2|crw|mrw|orf|raf|dcr)$/i', $extension, $rawext) && !in_array($extension,$ffmpeg_supported_extensions) && (isset($untagged_rgb_profile))){
global $auto_assign_based_on_exif_tags, $exiftool_fullpath, $default_srgb_profile, $default_widegamut_profile, $default_adobergb_profile;
// Attempt to automatically assign appropriate profile based upon EXIF tag information
if ($auto_assign_based_on_exif_tags){
// First try ColorSpace tag
// Locate Exiftool
$exiftool_fullpath = get_utility_path("exiftool");
if ($exiftool_fullpath==false){
// Exiftool not found, exit
exit("Could not find Exiftool utility at location '$exiftool_path'.");
} else {
// Determine Colorspace EXIF tag of image (if exist) using Exiftool
$exif_colorspace=run_command($exiftool_fullpath.' -ColorSpace '.escapeshellarg($file));
}
// If Exiftool returns sRGB
if (!$assign_profile && (preg_match("/sRGB/",$exif_colorspace))){
$target_rgb_profile = dirname(__FILE__) . '/../iccprofiles/' . $default_srgb_profile;
// Check if profile exists
if ((isset($default_srgb_profile)) && !file_exists($target_rgb_profile)){
if ($display_profile_warnings){
echo "An ICC target profile is set however it cannot be found at the location $target_rgb_profile. Check default_srgb_profile settings in config.php. An ICC preview profile must be set in config.php and the file exist to enable colour management for this file.";
}
} else {
// Define profile to assign during conversion
$assign_profile=' -profile '.escapeshellarg($target_rgb_profile);
}
}
// If Exiftool returns Wide Gamut RGB
if (!$assign_profile && (preg_match("/Wide Gamut RGB/",$exif_colorspace))){
$target_rgb_profile = dirname(__FILE__) . '/../iccprofiles/' . $default_widegamut_profile;
// Check if profile exists
if ((isset($default_widegamut_profile)) && !file_exists($target_rgb_profile)){
if ($display_profile_warnings){
echo "An ICC target profile is set however it cannot be found at the location $target_rgb_profile. Check default_widegamut_profile settings in config.php. An ICC preview profile must be set in config.php and the file exist to enable colour management for this file.";
}
} else {
// Define profile to assign during conversion
$assign_profile=' -profile '.escapeshellarg($target_rgb_profile);
}
}
// If Exiftool returns Uncalibrated, check for AdobeRGB
if (!$assign_profile && (preg_match("/Uncalibrated/",$exif_colorspace))){
// Check InteropIndex for AdobeRGB
$exiftool_fullpath = get_utility_path("exiftool");
if ($exiftool_fullpath==false){
// Exiftool not found, exit
exit("Could not find Exiftool utility at location '$exiftool_path'.");
} else {
// Determine InteropIndex EXIF tag of image (if exist) using Exiftool
$exif_interop_index=run_command($exiftool_fullpath.' -InteropIndex '.escapeshellarg($file));
}
if (preg_match("/Adobe RGB/",$exif_interop_index)){
$target_rgb_profile = dirname(__FILE__) . '/../iccprofiles/' . $default_adobergb_profile;
// Check if profile exists
if ((isset($default_adobergb_profile)) && !file_exists($target_rgb_profile)){
if ($display_profile_warnings){
echo "An ICC target profile is set however it cannot be found at the location $target_rgb_profile. Check default_adobergb_profile settings in config.php. An ICC preview profile must be set in config.php and the file exist to enable colour management for this file.";
}
} else {
// Define profile to assign during conversion
$assign_profile=' -profile '.escapeshellarg($target_rgb_profile);
}
}
}
}
// If there is still no profile assigned, assign a default RGB profile as defined in config.php
if(!$assign_profile){
$target_rgb_profile = dirname(__FILE__) . '/../iccprofiles/' . $untagged_rgb_profile;
// Check profile exists
if (!file_exists($target_rgb_profile) && $display_profile_warnings){
echo "An ICC target profile is set however it cannot be found at the location $target_rgb_profile. Check settings in config.php. An ICC preview profile must be set in config.php and the file exist to enable colour management for this file.";
}
// Define profile to assign during conversion
$assign_profile=' -profile '.escapeshellarg($target_rgb_profile);
}
}
// If not assigning profiles, tell ImageMagick to explicity set -colorspace for untagged images (Compatibility for GraphicsMagick or ImageMagick v6.7.6-3 or earlier)
if (!$assign_profiles_to_untagged_images && !$icc_profile && $tonal_response_curve_compatibility){
// Define profile to assign during conversion
$assign_profile=' -set colorspace $tonal_response_curve_compatibility_options ';
}
/* ----------------------------------------
This section determines behaviour of
preservation of ICC profiles after
conversion.
----------------------------------------
*/
// If $preserve_target_profiles=false; we want to strip the profiles after conversion to save space
if(!$preserve_target_profiles){
// If $preserve_source_profiles is enabled, preserve all profiles
// If $preserve_source_profiles_large_only is enabled, preserve only the profiles of larger previews
if($preserve_source_profiles || ($preserve_source_profiles_large_only && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr")){
// Keep target profile.
$strip_profile="";
} else {
// Strip target profile.
$strip_profile=" +profile ic*";
// Preserve the embedded source profile then convert smaller sizes to target display profile.
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -profile '.escapeshellarg($targetprofile);
$assign_profile="";
}
}
// If $preserve_target_profiles=true; we want to keep the target profile
if($preserve_target_profiles){
// Keep target profile.
$strip_profile="";
}
/* ----------------------------------------
This section determines appropriate options
to enable resize operations to take place
in a linear colourspace to ensure accurate
colours.
See http://www.imagemagick.org/Usage/resize/#resize_colorspace
----------------------------------------
*/
global $resize_prefix, $resize_suffix, $tonal_response_curve_compatibility, $colourspace, $profile, $icc_preview_options, $convert_profile;
if ($linear_resize){
global $restore_profile, $assign_profile, $strip_profile, $icc_path, $icc_transform_complete, $icc_preview_profile;
// If the profile is to be preserved, the file has an embedded profile, we must extract the profile so we can convert back from linear space to the original profile.
if (($preserve_source_profiles || ($preserve_source_profiles_large_only && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr")) && !empty($icc_profile)){
$iccpath = dirname(__FILE__) . '/../iccprofiles/' . $icc_profile .'.icc';
if (!file_exists($iccpath) && !isset($iccfound)) {
// Extracted profile doesn't exist. Try extracting.
if (extract_icc_profile($ref,$extension)){
$iccfound = true;
} else {
$iccfound = false;
// Profile extraction failed. Fall back to target preview profile.
if ($display_profile_warnings){
echo "WARNING! Profile extraction failed.";
}
}
}
if(file_exists($iccpath)){
// We have an extracted ICC profile, so use it as source
// Set option to assign extracted profile
$restore_profile=" -set profile ".escapeshellarg($iccpath);
$icc_transform_complete=true;
}
}
// If $preserve_source_profiles=true;
if($preserve_source_profiles && isset($assign_profile)){
// Preserve the embedded source profile for all sizes. No conversion will take place.
$restore_profile=$assign_profile;
}
// If $preserve_source_profiles_large_only=true; then for sizes larger than 'scr', the embedded source profile will be preserved and no conversion will take place.
if($preserve_source_profiles_large_only && isset($assign_profile) && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr"){
// Preserve embedded source profile for larger sizes only.
$restore_profile=$assign_profile;
}
// If $preserve_source_profiles_large_only=true; then 'scr' sizes and smaller will be converted to the target profile specified.
if ($preserve_source_profiles_large_only && ($id=="thm" || $id=="col" || $id=="pre" || $id=="scr")){
$restore_profile="";
}
// Set linear resize options for GraphicsMagick or ImageMagick v6.7.6-3 or earlier
if ($tonal_response_curve_compatibility){
// Convert the file to linear space before resizing
$resize_prefix=" -colorspace sRGB";
// Convert the file back to the target profile after resizing
$resize_suffix=" -colorspace RGB $restore_profile $convert_profile $strip_profile";
}
// Set linear resize options for GraphicsMagick or ImageMagick v6.7.6-4 or later
if (!$tonal_response_curve_compatibility){
// Convert the file to linear space before resizing
$resize_prefix=" -colorspace RGB";
// Convert the file back to the target profile after resizing
$resize_suffix=" -colorspace sRGB $restore_profile $convert_profile $strip_profile";
}
}
}
// Linear RGB
if ((!$tonal_response_curve_compatibility && $colourspace=="RGB") || ($tonal_response_curve_compatibility && $colourspace=="sRGB")){
// File is linear RGB
//echo "File is linear RGB";
// Always convert to the target profile as linear RGB does not have any profiles to preserve
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -profile '.escapeshellarg($targetprofile);
global $resize_prefix, $resize_suffix, $tonal_response_curve_compatibility, $colourspace, $profile, $icc_preview_options, $convert_profile;
global $restore_profile, $assign_profile, $icc_path, $icc_transform_complete, $icc_preview_profile;
// Convert linear file for display using target profile
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -profile '.escapeshellarg($targetprofile);
$resize_suffix=" -colorspace sRGB $convert_profile $strip_profile";
// Skip first conversion as file is linear already
$resize_prefix="";
$convert_profile="";
}
// CMYK
if ($colourspace=="CMYK"){
// File is CMYK
//echo "File is CMYK";
/* ----------------------------------------
This section handles assigning ICC profiles
to untagged images. Profiles are assigned
dependent upon colour mode and the profiles
defined in config.php
----------------------------------------
*/
global $untagged_cmyk_profile;
// Assign profile for untagged CMYK images
if ($assign_profiles_to_untagged_images && !$icc_profile && (isset($untagged_cmyk_profile))){
$target_cmyk_profile = dirname(__FILE__) . '/../iccprofiles/' . $untagged_cmyk_profile;
// Check profile exists
if (!file_exists($target_cmyk_profile) && $display_profile_warnings){
echo "An ICC target profile is set however it cannot be found at the location $target_cmyk_profile. Check settings in config.php. An ICC preview profile must be set in config.php and the file exist to enable colour management for this file.";
}
// Define profile to assign during conversion
$assign_profile=' -profile '.escapeshellarg($target_cmyk_profile);
}
// If not assigning profiles, tell ImageMagick to explicity set -colorspace for untagged images (Compatibility for GraphicsMagick or ImageMagick v6.7.6-3 or earlier)
if (!$assign_profiles_to_untagged_images && !$icc_profile && $tonal_response_curve_compatibility){
// Define profile to assign during conversion
$assign_profile=' -set colorspace CMYK ';
}
/* ----------------------------------------
This section determines behaviour of
preservation of ICC profiles after
conversion.
----------------------------------------
*/
// If $preserve_target_profiles=false; we want to strip the profiles after conversion to save space
if(!$preserve_target_profiles){
// If $preserve_source_profiles is enabled, preserve all profiles
// If $preserve_source_profiles_large_only is enabled, preserve only the profiles of larger previews
if($preserve_source_profiles || ($preserve_source_profiles_large_only && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr")){
// Keep target profile.
$strip_profile="";
} else {
// Strip target profile.
$strip_profile=" +profile ic*";
// Preserve the embedded source profile then convert smaller sizes to target display profile.
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -profile '.escapeshellarg($targetprofile);
$assign_profile="";
}
}
// If $preserve_target_profiles=true; we want to keep the target profile
if($preserve_target_profiles){
// Keep target profile.
$strip_profile="";
}
}
// Gray
if ($colourspace=="Gray"){
// File is Gray
//echo "File is Gray";
/* ----------------------------------------
This section handles assigning ICC profiles
to untagged images. Profiles are assigned
dependent upon colour mode and the profiles
defined in config.php
----------------------------------------
*/
global $untagged_gray_profile;
// Assign profile for untagged grayscale images
if ($assign_profiles_to_untagged_images && !$icc_profile && (isset($untagged_gray_profile))){
$target_gray_profile = dirname(__FILE__) . '/../iccprofiles/' . $untagged_gray_profile;
// Check profile exists
if (!file_exists($target_gray_profile) && $display_profile_warnings){
echo "An ICC target profile is set however it cannot be found at the location $target_gray_profile. Check settings in config.php. An ICC preview profile must be set in config.php and the file exist to enable colour management for this file.";
}
// Define profile to assign during conversion
$assign_profile=' -profile '.escapeshellarg($target_gray_profile);
}
// If not assigning profiles, tell ImageMagick to explicity set -colorspace for untagged images (Compatibility for GraphicsMagick or ImageMagick v6.7.6-3 or earlier)
if (!$assign_profiles_to_untagged_images && !$icc_profile && $tonal_response_curve_compatibility){
// Define profile to assign during conversion
$assign_profile=' -set colorspace Gray ';
}
/* ----------------------------------------
This section determines behaviour of
preservation of ICC profiles after
conversion.
----------------------------------------
*/
// If $preserve_target_profiles=false; we want to strip the profiles after conversion to save space
if(!$preserve_target_profiles){
// If $preserve_source_profiles is enabled, preserve all profiles
// If $preserve_source_profiles_large_only is enabled, preserve only the profiles of larger previews
if($preserve_source_profiles || ($preserve_source_profiles_large_only && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr")){
// Keep target profile.
$strip_profile="";
} else {
// Strip target profile.
$strip_profile=" +profile ic*";
// Preserve the embedded source profile then convert smaller sizes to target display profile.
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -profile '.escapeshellarg($targetprofile);
$assign_profile="";
}
}
// If $preserve_target_profiles=true; we want to keep the target profile
if($preserve_target_profiles){
// Keep target profile.
$strip_profile="";
}
/* ----------------------------------------
This section determines appropriate options
to enable resize operations to take place
in a linear colourspace to ensure accurate
colours.
See http://www.imagemagick.org/Usage/resize/#resize_colorspace
----------------------------------------
*/
global $resize_prefix, $resize_suffix, $tonal_response_curve_compatibility, $colourspace, $profile, $icc_preview_options, $convert_profile;
if ($linear_resize){
global $restore_profile, $assign_profile, $strip_profile, $icc_path, $icc_transform_complete, $icc_preview_profile;
// If the profile is to be preserved, the file has an embedded profile, we must extract the profile so we can convert back from linear space to the original profile.
if (($preserve_source_profiles || ($preserve_source_profiles_large_only && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr")) && !empty($icc_profile)){
$iccpath = dirname(__FILE__) . '/../iccprofiles/' . $icc_profile .'.icc';
if (!file_exists($iccpath) && !isset($iccfound)) {
// Extracted profile doesn't exist. Try extracting.
if (extract_icc_profile($ref,$extension)){
$iccfound = true;
} else {
$iccfound = false;
// Profile extraction failed. Fall back to target preview profile.
if ($display_profile_warnings){
echo "WARNING! Profile extraction failed.";
}
}
}
if(file_exists($iccpath)){
// We have an extracted ICC profile, so use it as source
// Set option to assign extracted profile
$restore_profile=" -set profile ".escapeshellarg($iccpath);
$icc_transform_complete=true;
}
}
// If $preserve_source_profiles=true;
if($preserve_source_profiles && isset($assign_profile)){
// Preserve the embedded source profile for all sizes. No conversion will take place.
$restore_profile=$assign_profile;
}
// If $preserve_source_profiles_large_only=true; then for sizes larger than 'scr', the embedded source profile will be preserved and no conversion will take place.
if($preserve_source_profiles_large_only && isset($assign_profile) && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr"){
// Preserve embedded source profile for larger sizes only.
$restore_profile=$assign_profile;
}
// If $preserve_source_profiles_large_only=true; then 'scr' sizes and smaller will be converted to the target profile specified.
if ($preserve_source_profiles_large_only && ($id=="thm" || $id=="col" || $id=="pre" || $id=="scr")){
$restore_profile="";
// Make sure conversions to the target display profile are in the correct colour mode
if ($tonal_response_curve_compatibility){
$colourspace="RGB";
}
if (!$tonal_response_curve_compatibility){
$colourspace="sRGB";
}
}
// Set linear resize options for GraphicsMagick or ImageMagick v6.7.6-3 or earlier
if ($tonal_response_curve_compatibility){
// Convert the file to linear space before resizing
$resize_prefix=" -colorspace sRGB";
// Convert the file back to the target profile after resizing
$resize_suffix=" -colorspace $colourspace $restore_profile $convert_profile $strip_profile";
}
// Set linear resize options for GraphicsMagick or ImageMagick v6.7.6-4 or later
if (!$tonal_response_curve_compatibility){
// Convert the file to linear space before resizing
$resize_prefix=" -colorspace RGB";
// Convert the file back to the target profile after resizing
$resize_suffix=" -colorspace $colourspace $restore_profile $convert_profile $strip_profile";
}
}
}
// CIELab
if ($colourspace=="CIELab"){
// File is CIELab
//echo "File is CIELab";
// Always convert to the target profile as CIELab does not have any profiles to preserve
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -colorspace '.$tonal_response_curve_compatibility_options.' -profile '.escapeshellarg($targetprofile);
global $resize_prefix, $resize_suffix, $tonal_response_curve_compatibility, $colourspace, $profile, $icc_preview_options, $convert_profile, $strip_profile, $icc_path, $icc_preview_profile;
if ($linear_resize){
// Set linear resize options for GraphicsMagick or ImageMagick v6.7.6-3 or earlier
if ($tonal_response_curve_compatibility){
// Convert the file to linear space before resizing
$resize_prefix=" -colorspace sRGB";
// Convert the file back to the target profile after resizing
$resize_suffix=" -colorspace RGB $convert_profile $strip_profile";
}
// Set linear resize options for GraphicsMagick or ImageMagick v6.7.6-4 or later
if (!$tonal_response_curve_compatibility){
// Convert the file to linear space before resizing
$resize_prefix=" -colorspace RGB";
// Convert the file back to the target profile after resizing
$resize_suffix=" -colorspace sRGB $convert_profile $strip_profile";
}
}
}
// All other colour modes
if (!in_array($colourspace, $supported_icc_colour_modes)){
// File is in an unsupported colour mode - use default handling
//echo "File is in an unsupported colour mode - use default handling";
// Always convert to the target profile as unsupported colour modes do not have any profiles to preserve
$targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
$convert_profile=$icc_preview_options.' -colorspace '.$tonal_response_curve_compatibility_options.' -profile '.escapeshellarg($targetprofile);
global $resize_prefix, $resize_suffix, $tonal_response_curve_compatibility, $colourspace, $profile, $icc_preview_options, $convert_profile, $restore_profile, $assign_profile, $strip_profile, $icc_path, $icc_preview_profile;
if ($linear_resize){
// Set linear resize options for GraphicsMagick or ImageMagick v6.7.6-3 or earlier
if ($tonal_response_curve_compatibility){
// Convert the file to linear space before resizing
$resize_prefix=" -colorspace sRGB";
// Convert the file back to the target profile after resizing
$resize_suffix=" -colorspace RGB $convert_profile $strip_profile";
}
// Set linear resize options for GraphicsMagick or ImageMagick v6.7.6-4 or later
if (!$tonal_response_curve_compatibility){
// Convert the file to linear space before resizing
$resize_prefix=" -colorspace RGB";
// Convert the file back to the target profile after resizing
$resize_suffix=" -colorspace sRGB $convert_profile $strip_profile";
}
}
}
/* ----------------------------------------
This section handles ICC extraction for
PSD and PSB files so that ImageMagick
will handle the conversion correctly.
----------------------------------------
*/
// If this is the high resolution preview being generated, extract and use the embedded ICC profile in the PSD or PSB file
if (($extension=="psd" || $extension=="psb") && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr" && $id!="lpr"){
global $assign_profile, $icc_path, $icc_transform_complete;
$iccpath = dirname(__FILE__) . '/../iccprofiles/' . $icc_profile .'.icc';
if (!file_exists($iccpath) && !isset($iccfound)) {
// Extracted profile doesn't exist. Try extracting.
if (extract_icc_profile($ref,$extension)){
$iccfound = true;
} else {
$iccfound = false;
}
}
if(file_exists($iccpath)){
// We have an extracted ICC profile, so use it as source
// Set option to remove any existing embedded ICC profiles and explicitly assign extracted profile
$assign_profile=" +profile \"*\" -profile ".escapeshellarg($iccpath);
$icc_transform_complete=true;
}
} else {
global $icc_transform_complete, $assign_profile;
// When generating smaller PSD or PSB previews from the high resolution preview JPEG, don't attempt to reassign the original source profile
if (($extension=="psd" || $extension=="psb") && ($id=="thm" || $id=="col" || $id=="pre" || $id=="scr" || $id=="lpr")){
$assign_profile="";
}
$icc_transform_complete=true;
}
/* ----------------------------------------
Set the conversion options ready for the
preview generation commands.
----------------------------------------
*/
if ($linear_resize){
$profile=$assign_profile.' '.$convert_profile.' ';
} else {
$profile=$assign_profile.' '.$convert_profile.' '.$strip_profile;
}
} else {
/* ----------------------------------------
This section is the default behaviour
for ResourceSpace when colour management
is turned off. The embedded profile (if
it exists) is stripped, then the file is
converted to RGB. ICC profiles, if any,
are stripped from the resulting file.
----------------------------------------
*/
global $tonal_response_curve_compatibility_options, $colourspace_options, $icc_preview_profile;
if (!isset($colourspace_options)){
// Define default -colorspace options
$colourspace_options="-colorspace $tonal_response_curve_compatibility_options";
}
// Convert to sRGB tonal response curve. Strip profiles. No other colour handling is applied.
$profile = $colourspace_options.'+profile ic* ';
}
/* ----------------------------------------
End colour management section.
----------------------------------------
*/
In image_processing.php, just below the old experimental ICC code, we need to find the following lines and replace them;
Find this line;
$runcommand = $command ." +matte $profile -resize " . $tw . "x" . $th . "\">\" ".escapeshellarg($path);
And replace with this;
global $resize_prefix, $resize_suffix;
$runcommand = $command ." +matte $profile $resize_prefix -resize " . $tw . "x" . $th . "\">\" $resize_suffix ".escapeshellarg($path);
Find this line;
$runcommand = $command ." +matte $profile -resize " . $tw . "x" . $th . "\">\" -tile ".escapeshellarg($watermarkreal)." -draw \"rectangle 0,0 $tw,$th\" ".escapeshellarg($path);
And replace with this;
$runcommand = $command ." +matte $profile $resize_prefix -resize " . $tw . "x" . $th . "\">\" $resize_suffix -tile ".escapeshellarg($watermarkreal)." -draw \"rectangle 0,0 $tw,$th\" ".escapeshellarg($path);
At the bottom of image_processing.php, we need to replace the old ICC function 'function extract_icc'. Replace the whole function with this;
function extract_icc($infile) {
global $icc_profile;
// Locate Imagemagick, or fail this if it isn't installed
$convert_fullpath = get_utility_path("im-convert");
if ($convert_fullpath==false) {return false;}
// Set directory for storing the ICC profile to the ResourceSpace iccprofiles folder
$outfile = dirname(__FILE__) . '/../iccprofiles/' . $icc_profile .'.icc';
// Extract ICC profile. Use [0] to extract a single profile from multi-layer PSD/PSBs
$cmdout = run_command($convert_fullpath.' '.escapeshellarg($infile).'[0] '.escapeshellarg($outfile));
// Check if file was extracted successfully
if ((!file_exists($outfile)) || (filesize($outfile))==0){
// The ICC profile extraction failed. So delete file.
if (file_exists($outfile)){ unlink ($outfile); };
return false;
}
if (file_exists($outfile)) { return true; } else { return false; }
}Lastly, we need to replace some code in preview_preprocessing.php. I've not been able to test it thoroughly at the stage (not too sure what test data to throw at it?). We need to find the lines;
# Preserve colour profiles?
$profile="+profile icc -colorspace ".$imagemagick_colorspace; # By default, strip the colour profiles ('+' is remove the profile, confusingly)
if ($imagemagick_preserve_profiles) {$profile="";}And replace with;
global $tonal_response_curve_compatibility, $tonal_response_curve_compatibility_options;
if ($tonal_response_curve_compatibility){
// Set 'RGB' for compatibility for GraphicsMagick or ImageMagick v6.7.6-3 or earlier
$tonal_response_curve_compatibility_options="RGB";
} else {
// Set 'sRGB' for ImageMagick v6.7.6-4 or newer
$tonal_response_curve_compatibility_options="sRGB";
}
We need to find any instances of $imagemagick_colorspace and replace it with $tonal_response_curve_compatibility_options
At the moment I've noticed that Photoshop EPS files do not retain their colour profile information due to a lack of appropriate code within preview_preprocessing.php. I will try to make something for this soon. Basically it will involve extracting the profile to re-add it after the EPS has been converted to non-linear sRGB and flattened.
Honestly I may not have time though, and this might be the end of what I can do for now. But I believe this to be a vast improvement on where it was, and should your testing go ok, perhaps we can integrate this into the ResourceSpace code?
Let me know what you think...
thanks,
Tristan.