]> granicus.if.org Git - imagemagick/blobdiff - magick/profile.c
(no commit message)
[imagemagick] / magick / profile.c
index 456797d5310bfb220f27f3f750112e46bfa54ab2..3531890221fbab15563aad0a8314b8f6c05b3d57 100644 (file)
 #endif
 \f
 /*
- *   Define declarations.
- *   */
-#if defined(MAGICKCORE_LCMS_DELEGATE)
-#if defined(LCMS_VERSION) && (LCMS_VERSION < 2000)
+  Define declarations.
+*/
+#if !defined(LCMS_VERSION) || (LCMS_VERSION < 2000)
+#define cmsSigCmykData icSigCmykData
+#define cmsSigGrayData icSigGrayData
+#define cmsSigLabData icSigLabData
+#define cmsSigLuvData icSigLuvData
+#define cmsSigRgbData icSigRgbData
+#define cmsSigXYZData icSigXYZData
+#define cmsSigYCbCrData icSigYCbCrData
+#define cmsSigLinkClass icSigLinkClass
+#define cmsColorSpaceSignature icColorSpaceSignature
 #define cmsUInt32Number  DWORD
-#define cmsSigCmykData icSigCmykData 
-#define cmsSigGrayData icSigGrayData 
-#define cmsSigLabData icSigLabData 
-#define cmsSigLuvData icSigLuvData 
-#define cmsSigRgbData icSigRgbData 
-#define cmsSigXYZData icSigXYZData 
-#define cmsSigYCbCrData icSigYCbCrData 
-#endif
+#define cmsSetLogErrorHandler(handler)  cmsSetErrorHandler(handler)
+#define cmsCreateTransformTHR(context,source_profile,source_type, \
+  target_profile,target_type,intent,flags)  cmsCreateTransform(source_profile, \
+  source_type,target_profile,target_type,intent,flags);
+#define cmsOpenProfileFromMemTHR(context,profile,length) \
+  cmsOpenProfileFromMem(profile,length)
 #endif
 \f
 /*
@@ -336,11 +342,11 @@ MagickExport char *GetNextImageProfile(const Image *image)
 
 static unsigned short **DestroyPixelThreadSet(unsigned short **pixels)
 {
-  register long
+  register ssize_t
     i;
 
   assert(pixels != (unsigned short **) NULL);
-  for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
+  for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
     if (pixels[i] != (unsigned short *) NULL)
       pixels[i]=(unsigned short *) RelinquishMagickMemory(pixels[i]);
   pixels=(unsigned short **) RelinquishAlignedMemory(pixels);
@@ -350,13 +356,13 @@ static unsigned short **DestroyPixelThreadSet(unsigned short **pixels)
 static unsigned short **AcquirePixelThreadSet(const size_t columns,
   const size_t channels)
 {
-  register long
+  register ssize_t
     i;
 
   unsigned short
     **pixels;
 
-  unsigned long
+  size_t
     number_threads;
 
   number_threads=GetOpenMPMaximumThreads();
@@ -365,7 +371,7 @@ static unsigned short **AcquirePixelThreadSet(const size_t columns,
   if (pixels == (unsigned short **) NULL)
     return((unsigned short **) NULL);
   (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels));
-  for (i=0; i < (long) number_threads; i++)
+  for (i=0; i < (ssize_t) number_threads; i++)
   {
     pixels[i]=(unsigned short *) AcquireQuantumMemory(columns,channels*
       sizeof(**pixels));
@@ -377,29 +383,29 @@ static unsigned short **AcquirePixelThreadSet(const size_t columns,
 
 static cmsHTRANSFORM *DestroyTransformThreadSet(cmsHTRANSFORM *transform)
 {
-  register long
+  register ssize_t
     i;
 
   assert(transform != (cmsHTRANSFORM *) NULL);
-  for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
+  for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
     if (transform[i] != (cmsHTRANSFORM) NULL)
       cmsDeleteTransform(transform[i]);
   transform=(cmsHTRANSFORM *) RelinquishAlignedMemory(transform);
   return(transform);
 }
 
-static cmsHTRANSFORM *AcquireTransformThreadSet(
+static cmsHTRANSFORM *AcquireTransformThreadSet(Image *image,
   const cmsHPROFILE source_profile,const cmsUInt32Number source_type,
-  const cmsHPROFILE target_profile,const cmsUInt32Number target_type,const int intent,
-  const cmsUInt32Number flags)
+  const cmsHPROFILE target_profile,const cmsUInt32Number target_type,
+  const int intent,const cmsUInt32Number flags)
 {
   cmsHTRANSFORM
     *transform;
 
-  register long
+  register ssize_t
     i;
 
-  unsigned long
+  size_t
     number_threads;
 
   number_threads=GetOpenMPMaximumThreads();
@@ -408,10 +414,10 @@ static cmsHTRANSFORM *AcquireTransformThreadSet(
   if (transform == (cmsHTRANSFORM *) NULL)
     return((cmsHTRANSFORM *) NULL);
   (void) ResetMagickMemory(transform,0,number_threads*sizeof(*transform));
-  for (i=0; i < (long) number_threads; i++)
+  for (i=0; i < (ssize_t) number_threads; i++)
   {
-    transform[i]=cmsCreateTransform(source_profile,source_type,target_profile,
-      target_type,intent,flags);
+    transform[i]=cmsCreateTransformTHR(image,source_profile,source_type,
+      target_profile,target_type,intent,flags);
     if (transform[i] == (cmsHTRANSFORM) NULL)
       return(DestroyTransformThreadSet(transform));
   }
@@ -804,9 +810,23 @@ static MagickBooleanType SetsRGBImageProfile(Image *image)
   return(status);
 }
 #if defined(MAGICKCORE_LCMS_DELEGATE)
-#if defined(LCMS_VERSION) && (LCMS_VERSION < 2000)
-#if defined(LCMS_VERSION) && (LCMS_VERSION > 1010)
-static int LCMSErrorHandler(int severity,const char *message)
+#if defined(LCMS_VERSION) && (LCMS_VERSION >= 2000)
+static void LCMSExceptionHandler(cmsContext context,cmsUInt32Number severity,
+  const char *message)
+{
+  Image
+    *image;
+
+  (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%u, %s",
+    severity,message != (char *) NULL ? message : "no message");
+  image=(Image *) context;
+  if (image != (Image *) NULL)
+    (void) ThrowMagickException(&image->exception,GetMagickModule(),
+      ImageWarning,"UnableToTransformColorspace","`%s'",image->filename);
+
+}
+#else
+static int LCMSExceptionHandler(int severity,const char *message)
 {
   (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%d, %s",
     severity,message != (char *) NULL ? message : "no message");
@@ -814,7 +834,6 @@ static int LCMSErrorHandler(int severity,const char *message)
 }
 #endif
 #endif
-#endif
 
 MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
   const void *datum,const size_t length,
@@ -823,8 +842,10 @@ MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
 #define ProfileImageTag  "Profile/Image"
 #define ThrowProfileException(severity,tag,context) \
 { \
-  (void) cmsCloseProfile(source_profile); \
-  (void) cmsCloseProfile(target_profile); \
+  if (source_profile != (cmsHPROFILE) NULL) \
+    (void) cmsCloseProfile(source_profile); \
+  if (target_profile != (cmsHPROFILE) NULL) \
+    (void) cmsCloseProfile(target_profile); \
   ThrowBinaryException(severity,tag,context); \
 }
 
@@ -848,7 +869,7 @@ MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
       int
         number_arguments;
 
-      register long
+      register ssize_t
         i;
 
       /*
@@ -863,7 +884,7 @@ MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
       ResetImageProfileIterator(image);
       for (name=GetNextImageProfile(image); name != (const char *) NULL; )
       {
-        for (i=1; i < number_arguments; i++)
+        for (i=1; i < (ssize_t) number_arguments; i++)
         {
           if ((*arguments[i] == '!') &&
               (LocaleCompare(name,arguments[i]+1) == 0))
@@ -877,7 +898,7 @@ MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
         }
         name=GetNextImageProfile(image);
       }
-      for (i=0; i < number_arguments; i++)
+      for (i=0; i < (ssize_t) number_arguments; i++)
         arguments[i]=DestroyString(arguments[i]);
       arguments=(char **) RelinquishMagickMemory(arguments);
       return(MagickTrue);
@@ -885,9 +906,12 @@ MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
   /*
     Add a ICC, IPTC, or generic profile to the image.
   */
+  status=MagickTrue;
   profile=AcquireStringInfo((size_t) length);
   SetStringInfoDatum(profile,(unsigned char *) datum);
-  if ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0))
+  if ((LocaleCompare(name,"icc") != 0) && (LocaleCompare(name,"icm") != 0))
+    status=SetImageProfile(image,name,profile);
+  else
     {
       const StringInfo
         *icc_profile;
@@ -921,379 +945,403 @@ MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
         MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","`%s' (LCMS)",
         image->filename);
 #else
-      if (icc_profile != (StringInfo *) NULL)
-        {
-          CacheView
-            *image_view;
+      {
+        cmsHPROFILE
+          source_profile;
 
-          ColorspaceType
-            source_colorspace,
-            target_colorspace;
+        /*
+          Transform pixel colors as defined by the color profiles.
+        */
+        cmsSetLogErrorHandler(LCMSExceptionHandler);
+        source_profile=cmsOpenProfileFromMemTHR(image,
+          GetStringInfoDatum(profile),(cmsUInt32Number)
+          GetStringInfoLength(profile));
+        if (source_profile == (cmsHPROFILE) NULL)
+          ThrowBinaryException(ResourceLimitError,
+            "ColorspaceColorProfileMismatch",name);
+        if ((cmsGetDeviceClass(source_profile) != cmsSigLinkClass) &&
+            (icc_profile == (StringInfo *) NULL))
+          status=SetImageProfile(image,name,profile);
+        else
+          {
+            CacheView
+              *image_view;
 
-          cmsHPROFILE
-            source_profile,
-            target_profile;
+            ColorspaceType
+              source_colorspace,
+              target_colorspace;
 
-          cmsHTRANSFORM
-            *restrict transform;
+            cmsColorSpaceSignature
+              signature;
 
-          cmsUInt32Number
-            flags,
-            source_type,
-            target_type;
+            cmsHPROFILE
+              target_profile;
 
-          ExceptionInfo
-            *exception;
+            cmsHTRANSFORM
+              *restrict transform;
 
-          int
-            intent;
+            cmsUInt32Number
+              flags,
+              source_type,
+              target_type;
 
-          long
-            progress,
-            y;
+            ExceptionInfo
+              *exception;
 
-          MagickBooleanType
-            status;
+            int
+              intent;
 
-          size_t
-            length,
-            source_channels,
-            target_channels;
+            MagickBooleanType
+              status;
 
-          unsigned short
-            **restrict source_pixels,
-            **restrict target_pixels;
+            MagickOffsetType
+              progress;
 
-          /*
-            Transform pixel colors as defined by the color profiles.
-          */
-#if defined(LCMS_VERSION) && (LCMS_VERSION < 2000)
-#if defined(LCMS_VERSION) && (LCMS_VERSION > 1010)
-          cmsSetErrorHandler(LCMSErrorHandler);
-#else
-          (void) cmsErrorAction(LCMS_ERROR_SHOW);
-#endif
-#endif
-          source_profile=cmsOpenProfileFromMem(GetStringInfoDatum(icc_profile),
-            (cmsUInt32Number) GetStringInfoLength(icc_profile));
-          target_profile=cmsOpenProfileFromMem(GetStringInfoDatum(profile),
-            (cmsUInt32Number) GetStringInfoLength(profile));
-          if ((source_profile == (cmsHPROFILE) NULL) ||
-              (target_profile == (cmsHPROFILE) NULL))
-            ThrowBinaryException(ResourceLimitError,
-              "ColorspaceColorProfileMismatch",name);
-          switch (cmsGetColorSpace(source_profile))
-          {
-            case cmsSigCmykData:
-            {
-              source_colorspace=CMYKColorspace;
-              source_type=(cmsUInt32Number) TYPE_CMYK_16;
-              source_channels=4;
-              break;
-            }
-            case cmsSigGrayData:
-            {
-              source_colorspace=GRAYColorspace;
-              source_type=(cmsUInt32Number) TYPE_GRAY_16;
-              source_channels=1;
-              break;
-            }
-            case cmsSigLabData:
-            {
-              source_colorspace=LabColorspace;
-              source_type=(cmsUInt32Number) TYPE_Lab_16;
-              source_channels=3;
-              break;
-            }
-            case cmsSigLuvData:
-            {
-              source_colorspace=YUVColorspace;
-              source_type=(cmsUInt32Number) TYPE_YUV_16;
-              source_channels=3;
-              break;
-            }
-            case cmsSigRgbData:
-            {
-              source_colorspace=RGBColorspace;
-              source_type=(cmsUInt32Number) TYPE_RGB_16;
-              source_channels=3;
-              break;
-            }
-            case cmsSigXYZData:
-            {
-              source_colorspace=XYZColorspace;
-              source_type=(cmsUInt32Number) TYPE_XYZ_16;
-              source_channels=3;
-              break;
-            }
-            case cmsSigYCbCrData:
-            {
-              source_colorspace=YCbCrColorspace;
-              source_type=(cmsUInt32Number) TYPE_YCbCr_16;
-              source_channels=3;
-              break;
-            }
-            default:
-            {
-              source_colorspace=UndefinedColorspace;
-              source_type=(cmsUInt32Number) TYPE_RGB_16;
-              source_channels=3;
-              break;
-            }
-          }
-          switch (cmsGetColorSpace(target_profile))
-          {
-            case cmsSigCmykData:
-            {
-              target_colorspace=CMYKColorspace;
-              target_type=(cmsUInt32Number) TYPE_CMYK_16;
-              target_channels=4;
-              break;
-            }
-            case cmsSigLabData:
-            {
-              target_colorspace=LabColorspace;
-              target_type=(cmsUInt32Number) TYPE_Lab_16;
-              target_channels=3;
-              break;
-            }
-            case cmsSigGrayData:
-            {
-              target_colorspace=GRAYColorspace;
-              target_type=(cmsUInt32Number) TYPE_GRAY_16;
-              target_channels=1;
-              break;
-            }
-            case cmsSigLuvData:
-            {
-              target_colorspace=YUVColorspace;
-              target_type=(cmsUInt32Number) TYPE_YUV_16;
-              target_channels=3;
-              break;
-            }
-            case cmsSigRgbData:
-            {
-              target_colorspace=RGBColorspace;
-              target_type=(cmsUInt32Number) TYPE_RGB_16;
-              target_channels=3;
-              break;
-            }
-            case cmsSigXYZData:
+            size_t
+              length,
+              source_channels,
+              target_channels;
+
+            ssize_t
+              y;
+
+            unsigned short
+              **restrict source_pixels,
+              **restrict target_pixels;
+
+            exception=(&image->exception);
+            target_profile=(cmsHPROFILE) NULL;
+            if (icc_profile != (StringInfo *) NULL)
+              {
+                target_profile=source_profile;
+                source_profile=cmsOpenProfileFromMemTHR(image,
+                  GetStringInfoDatum(icc_profile),(cmsUInt32Number)
+                  GetStringInfoLength(icc_profile));
+                if (source_profile == (cmsHPROFILE) NULL)
+                  ThrowProfileException(ResourceLimitError,
+                    "ColorspaceColorProfileMismatch",name);
+              }
+            switch (cmsGetColorSpace(source_profile))
             {
-              target_colorspace=XYZColorspace;
-              target_type=(cmsUInt32Number) TYPE_XYZ_16;
-              target_channels=3;
-              break;
+              case cmsSigCmykData:
+              {
+                source_colorspace=CMYKColorspace;
+                source_type=(cmsUInt32Number) TYPE_CMYK_16;
+                source_channels=4;
+                break;
+              }
+              case cmsSigGrayData:
+              {
+                source_colorspace=GRAYColorspace;
+                source_type=(cmsUInt32Number) TYPE_GRAY_16;
+                source_channels=1;
+                break;
+              }
+              case cmsSigLabData:
+              {
+                source_colorspace=LabColorspace;
+                source_type=(cmsUInt32Number) TYPE_Lab_16;
+                source_channels=3;
+                break;
+              }
+              case cmsSigLuvData:
+              {
+                source_colorspace=YUVColorspace;
+                source_type=(cmsUInt32Number) TYPE_YUV_16;
+                source_channels=3;
+                break;
+              }
+              case cmsSigRgbData:
+              {
+                source_colorspace=RGBColorspace;
+                source_type=(cmsUInt32Number) TYPE_RGB_16;
+                source_channels=3;
+                break;
+              }
+              case cmsSigXYZData:
+              {
+                source_colorspace=XYZColorspace;
+                source_type=(cmsUInt32Number) TYPE_XYZ_16;
+                source_channels=3;
+                break;
+              }
+              case cmsSigYCbCrData:
+              {
+                source_colorspace=YCbCrColorspace;
+                source_type=(cmsUInt32Number) TYPE_YCbCr_16;
+                source_channels=3;
+                break;
+              }
+              default:
+              {
+                source_colorspace=UndefinedColorspace;
+                source_type=(cmsUInt32Number) TYPE_RGB_16;
+                source_channels=3;
+                break;
+              }
             }
-            case cmsSigYCbCrData:
+            signature=cmsGetPCS(source_profile);
+            if (target_profile != (cmsHPROFILE) NULL)
+              signature=cmsGetColorSpace(target_profile);
+            switch (signature)
             {
-              target_colorspace=YCbCrColorspace;
-              target_type=(cmsUInt32Number) TYPE_YCbCr_16;
-              target_channels=3;
-              break;
+              case cmsSigCmykData:
+              {
+                target_colorspace=CMYKColorspace;
+                target_type=(cmsUInt32Number) TYPE_CMYK_16;
+                target_channels=4;
+                break;
+              }
+              case cmsSigLabData:
+              {
+                target_colorspace=LabColorspace;
+                target_type=(cmsUInt32Number) TYPE_Lab_16;
+                target_channels=3;
+                break;
+              }
+              case cmsSigGrayData:
+              {
+                target_colorspace=GRAYColorspace;
+                target_type=(cmsUInt32Number) TYPE_GRAY_16;
+                target_channels=1;
+                break;
+              }
+              case cmsSigLuvData:
+              {
+                target_colorspace=YUVColorspace;
+                target_type=(cmsUInt32Number) TYPE_YUV_16;
+                target_channels=3;
+                break;
+              }
+              case cmsSigRgbData:
+              {
+                target_colorspace=RGBColorspace;
+                target_type=(cmsUInt32Number) TYPE_RGB_16;
+                target_channels=3;
+                break;
+              }
+              case cmsSigXYZData:
+              {
+                target_colorspace=XYZColorspace;
+                target_type=(cmsUInt32Number) TYPE_XYZ_16;
+                target_channels=3;
+                break;
+              }
+              case cmsSigYCbCrData:
+              {
+                target_colorspace=YCbCrColorspace;
+                target_type=(cmsUInt32Number) TYPE_YCbCr_16;
+                target_channels=3;
+                break;
+              }
+              default:
+              {
+                target_colorspace=UndefinedColorspace;
+                target_type=(cmsUInt32Number) TYPE_RGB_16;
+                target_channels=3;
+                break;
+              }
             }
-            default:
+            if ((source_colorspace == UndefinedColorspace) ||
+                (target_colorspace == UndefinedColorspace))
+              ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
+                name);
+             if ((source_colorspace == GRAYColorspace) &&
+                 (IsGrayImage(image,exception) == MagickFalse))
+              ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
+                name);
+             if ((source_colorspace == CMYKColorspace) &&
+                 (image->colorspace != CMYKColorspace))
+              ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
+                name);
+             if ((source_colorspace == XYZColorspace) &&
+                 (image->colorspace != XYZColorspace))
+              ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
+                name);
+             if ((source_colorspace == YCbCrColorspace) &&
+                 (image->colorspace != YCbCrColorspace))
+              ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
+                name);
+             if ((source_colorspace != CMYKColorspace) &&
+                 (source_colorspace != GRAYColorspace) &&
+                 (source_colorspace != LabColorspace) &&
+                 (source_colorspace != XYZColorspace) &&
+                 (source_colorspace != YCbCrColorspace) &&
+                 (image->colorspace != RGBColorspace))
+              ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
+                name);
+            switch (image->rendering_intent)
             {
-              target_colorspace=UndefinedColorspace;
-              target_type=(cmsUInt32Number) TYPE_RGB_16;
-              target_channels=3;
-              break;
+              case AbsoluteIntent: intent=INTENT_ABSOLUTE_COLORIMETRIC; break;
+              case PerceptualIntent: intent=INTENT_PERCEPTUAL; break;
+              case RelativeIntent: intent=INTENT_RELATIVE_COLORIMETRIC; break;
+              case SaturationIntent: intent=INTENT_SATURATION; break;
+              default: intent=INTENT_PERCEPTUAL; break;
             }
-          }
-          exception=(&image->exception);
-          if ((source_colorspace == UndefinedColorspace) ||
-              (target_colorspace == UndefinedColorspace))
-            ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
-              name);
-           if ((source_colorspace == GRAYColorspace) &&
-               (IsGrayImage(image,exception) == MagickFalse))
-            ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
-              name);
-           if ((source_colorspace == CMYKColorspace) &&
-               (image->colorspace != CMYKColorspace))
-            ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
-              name);
-           if ((source_colorspace == XYZColorspace) &&
-               (image->colorspace != XYZColorspace))
-            ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
-              name);
-           if ((source_colorspace == YCbCrColorspace) &&
-               (image->colorspace != YCbCrColorspace))
-            ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
-              name);
-           if ((source_colorspace != CMYKColorspace) &&
-               (source_colorspace != GRAYColorspace) &&
-               (source_colorspace != LabColorspace) &&
-               (source_colorspace != XYZColorspace) &&
-               (source_colorspace != YCbCrColorspace) &&
-               (image->colorspace != RGBColorspace))
-            ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
-              name);
-          switch (image->rendering_intent)
-          {
-            case AbsoluteIntent: intent=INTENT_ABSOLUTE_COLORIMETRIC; break;
-            case PerceptualIntent: intent=INTENT_PERCEPTUAL; break;
-            case RelativeIntent: intent=INTENT_RELATIVE_COLORIMETRIC; break;
-            case SaturationIntent: intent=INTENT_SATURATION; break;
-            default: intent=INTENT_PERCEPTUAL; break;
-          }
-          flags=cmsFLAGS_HIGHRESPRECALC;
+            flags=cmsFLAGS_HIGHRESPRECALC;
 #if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
-          if (image->black_point_compensation != MagickFalse)
-            flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
+            if (image->black_point_compensation != MagickFalse)
+              flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
 #endif
-          transform=AcquireTransformThreadSet(source_profile,source_type,
-            target_profile,target_type,intent,flags);
-          (void) cmsCloseProfile(source_profile);
-          if (transform == (cmsHTRANSFORM *) NULL)
-            ThrowBinaryException(ImageError,"UnableToCreateColorTransform",
-              name);
-          /*
-            Transform image as dictated by the source and target image profiles.
-          */
-          length=(size_t) image->columns;
-          source_pixels=AcquirePixelThreadSet(image->columns,source_channels);
-          target_pixels=AcquirePixelThreadSet(image->columns,target_channels);
-          if ((source_pixels == (unsigned short **) NULL) ||
-              (target_pixels == (unsigned short **) NULL))
-            {
-              transform=DestroyTransformThreadSet(transform);
-              (void) cmsCloseProfile(target_profile);
-              ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
-                image->filename);
-            }
-          if (SetImageStorageClass(image,DirectClass) == MagickFalse)
-            {
-              target_pixels=DestroyPixelThreadSet(target_pixels);
-              source_pixels=DestroyPixelThreadSet(source_pixels);
-              transform=DestroyTransformThreadSet(transform);
-              (void) cmsCloseProfile(target_profile);
-              return(MagickFalse);
-            }
-          if (target_colorspace == CMYKColorspace)
-            (void) SetImageColorspace(image,target_colorspace);
-          status=MagickTrue;
-          progress=0;
-          image_view=AcquireCacheView(image);
+            transform=AcquireTransformThreadSet(image,source_profile,
+              source_type,target_profile,target_type,intent,flags);
+            if (transform == (cmsHTRANSFORM *) NULL)
+              ThrowProfileException(ImageError,"UnableToCreateColorTransform",
+                name);
+            /*
+              Transform image as dictated by the source & target image profiles.
+            */
+            length=(size_t) image->columns;
+            source_pixels=AcquirePixelThreadSet(image->columns,source_channels);
+            target_pixels=AcquirePixelThreadSet(image->columns,target_channels);
+            if ((source_pixels == (unsigned short **) NULL) ||
+                (target_pixels == (unsigned short **) NULL))
+              {
+                transform=DestroyTransformThreadSet(transform);
+                ThrowProfileException(ResourceLimitError,
+                  "MemoryAllocationFailed",image->filename);
+              }
+            if (SetImageStorageClass(image,DirectClass) == MagickFalse)
+              {
+                target_pixels=DestroyPixelThreadSet(target_pixels);
+                source_pixels=DestroyPixelThreadSet(source_pixels);
+                transform=DestroyTransformThreadSet(transform);
+                if (source_profile != (cmsHPROFILE) NULL)
+                  (void) cmsCloseProfile(source_profile);
+                if (target_profile != (cmsHPROFILE) NULL)
+                  (void) cmsCloseProfile(target_profile);
+                return(MagickFalse);
+              }
+            if (target_colorspace == CMYKColorspace)
+              (void) SetImageColorspace(image,target_colorspace);
+            status=MagickTrue;
+            progress=0;
+            image_view=AcquireCacheView(image);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-          #pragma omp parallel for schedule(dynamic,4) shared(status)
+            #pragma omp parallel for schedule(dynamic,4) shared(status)
 #endif
-          for (y=0; y < (long) image->rows; y++)
-          {
-            MagickBooleanType
-              sync;
+            for (y=0; y < (ssize_t) image->rows; y++)
+            {
+              int
+                id;
 
-            register IndexPacket
-              *restrict indexes;
+              MagickBooleanType
+                sync;
 
-            register long
-              id,
-              x;
+              register IndexPacket
+                *restrict indexes;
 
-            register PixelPacket
-              *restrict q;
+              register ssize_t
+                x;
 
-            register unsigned short
-              *p;
+              register PixelPacket
+                *restrict q;
 
-            if (status == MagickFalse)
-              continue;
-            q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
-              exception);
-            if (q == (PixelPacket *) NULL)
-              {
-                status=MagickFalse;
+              register unsigned short
+                *p;
+
+              if (status == MagickFalse)
                 continue;
-              }
-            indexes=GetCacheViewAuthenticIndexQueue(image_view);
-            id=GetOpenMPThreadId();
-            p=source_pixels[id];
-            for (x=0; x < (long) image->columns; x++)
-            {
-              *p++=ScaleQuantumToShort(q->red);
-              if (source_channels > 1)
-                {
-                  *p++=ScaleQuantumToShort(q->green);
-                  *p++=ScaleQuantumToShort(q->blue);
-                }
-              if (source_channels > 3)
-                *p++=ScaleQuantumToShort(indexes[x]);
-              q++;
-            }
-            cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
-              (unsigned int) image->columns);
-            p=target_pixels[id];
-            q-=image->columns;
-            for (x=0; x < (long) image->columns; x++)
-            {
-              q->red=ScaleShortToQuantum(*p);
-              q->green=q->red;
-              q->blue=q->red;
-              p++;
-              if (target_channels > 1)
+              q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
+                exception);
+              if (q == (PixelPacket *) NULL)
                 {
-                  q->green=ScaleShortToQuantum(*p);
-                  p++;
-                  q->blue=ScaleShortToQuantum(*p);
-                  p++;
-                }
-              if (target_channels > 3)
-                {
-                  indexes[x]=ScaleShortToQuantum(*p);
-                  p++;
+                  status=MagickFalse;
+                  continue;
                 }
-              q++;
-            }
-            sync=SyncCacheViewAuthenticPixels(image_view,exception);
-            if (sync == MagickFalse)
-              status=MagickFalse;
-            if (image->progress_monitor != (MagickProgressMonitor) NULL)
+              indexes=GetCacheViewAuthenticIndexQueue(image_view);
+              id=GetOpenMPThreadId();
+              p=source_pixels[id];
+              for (x=0; x < (ssize_t) image->columns; x++)
+              {
+                *p++=ScaleQuantumToShort(q->red);
+                if (source_channels > 1)
+                  {
+                    *p++=ScaleQuantumToShort(q->green);
+                    *p++=ScaleQuantumToShort(q->blue);
+                  }
+                if (source_channels > 3)
+                  *p++=ScaleQuantumToShort(indexes[x]);
+                q++;
+              }
+              cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
+                (unsigned int) image->columns);
+              p=target_pixels[id];
+              q-=image->columns;
+              for (x=0; x < (ssize_t) image->columns; x++)
               {
-                MagickBooleanType
-                  proceed;
+                q->red=ScaleShortToQuantum(*p);
+                q->green=q->red;
+                q->blue=q->red;
+                p++;
+                if (target_channels > 1)
+                  {
+                    q->green=ScaleShortToQuantum(*p);
+                    p++;
+                    q->blue=ScaleShortToQuantum(*p);
+                    p++;
+                  }
+                if (target_channels > 3)
+                  {
+                    indexes[x]=ScaleShortToQuantum(*p);
+                    p++;
+                  }
+                q++;
+              }
+              sync=SyncCacheViewAuthenticPixels(image_view,exception);
+              if (sync == MagickFalse)
+                status=MagickFalse;
+              if (image->progress_monitor != (MagickProgressMonitor) NULL)
+                {
+                  MagickBooleanType
+                    proceed;
 
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-  #pragma omp critical (MagickCore_ProfileImage)
+#pragma omp critical (MagickCore_ProfileImage)
 #endif
-                proceed=SetImageProgress(image,ProfileImageTag,progress++,
-                  image->rows);
-                if (proceed == MagickFalse)
-                  status=MagickFalse;
-              }
-          }
-          image_view=DestroyCacheView(image_view);
-          (void) SetImageColorspace(image,target_colorspace);
-          switch (cmsGetColorSpace(target_profile))
-          {
-            case cmsSigRgbData:
-            {
-              image->type=image->matte == MagickFalse ? TrueColorType :
-                TrueColorMatteType;
-              break;
-            }
-            case cmsSigCmykData:
-            {
-              image->type=image->matte == MagickFalse ? ColorSeparationType :
-                ColorSeparationMatteType;
-              break;
+                  proceed=SetImageProgress(image,ProfileImageTag,progress++,
+                    image->rows);
+                  if (proceed == MagickFalse)
+                    status=MagickFalse;
+                }
             }
-            case cmsSigGrayData:
+            image_view=DestroyCacheView(image_view);
+            (void) SetImageColorspace(image,target_colorspace);
+            switch (signature)
             {
-              image->type=image->matte == MagickFalse ? GrayscaleType :
-                GrayscaleMatteType;
-              break;
+              case cmsSigRgbData:
+              {
+                image->type=image->matte == MagickFalse ? TrueColorType :
+                  TrueColorMatteType;
+                break;
+              }
+              case cmsSigCmykData:
+              {
+                image->type=image->matte == MagickFalse ? ColorSeparationType :
+                  ColorSeparationMatteType;
+                break;
+              }
+              case cmsSigGrayData:
+              {
+                image->type=image->matte == MagickFalse ? GrayscaleType :
+                  GrayscaleMatteType;
+                break;
+              }
+              default:
+                break;
             }
-            default:
-              break;
+            target_pixels=DestroyPixelThreadSet(target_pixels);
+            source_pixels=DestroyPixelThreadSet(source_pixels);
+            transform=DestroyTransformThreadSet(transform);
+            if (cmsGetDeviceClass(source_profile) != cmsSigLinkClass)
+              status=SetImageProfile(image,name,profile);
+            if (target_profile != (cmsHPROFILE) NULL)
+              (void) cmsCloseProfile(target_profile);
           }
-          target_pixels=DestroyPixelThreadSet(target_pixels);
-          source_pixels=DestroyPixelThreadSet(source_pixels);
-          transform=DestroyTransformThreadSet(transform);
-          (void) cmsCloseProfile(target_profile);
-        }
+        (void) cmsCloseProfile(source_profile);
+      }
 #endif
     }
-  status=SetImageProfile(image,name,profile);
   profile=DestroyStringInfo(profile);
   return(status);
 }
@@ -1445,12 +1493,12 @@ static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
 }
 
 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
-  unsigned long *quantum)
+  size_t *quantum)
 {
-  *quantum=(unsigned long) (*p++ << 24);
-  *quantum|=(unsigned long) (*p++ << 16);
-  *quantum|=(unsigned long) (*p++ << 8);
-  *quantum|=(unsigned long) (*p++ << 0);
+  *quantum=(size_t) (*p++ << 24);
+  *quantum|=(size_t) (*p++ << 16);
+  *quantum|=(size_t) (*p++ << 8);
+  *quantum|=(size_t) (*p++ << 0);
   return(p);
 }
 
@@ -1480,7 +1528,7 @@ static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
   unsigned char
     length_byte;
 
-  unsigned long
+  size_t
     count;
 
   unsigned short
@@ -1700,25 +1748,25 @@ static inline unsigned short ReadProfileShort(const EndianType endian,
   return((unsigned short) (value & 0xffff));
 }
 
-static inline unsigned long ReadProfileLong(const EndianType endian,
+static inline size_t ReadProfileLong(const EndianType endian,
   unsigned char *buffer)
 {
-  unsigned long
+  size_t
     value;
 
   if (endian == MSBEndian)
     {
-      value=(unsigned long) ((buffer[0] << 24) | (buffer[1] << 16) |
+      value=(size_t) ((buffer[0] << 24) | (buffer[1] << 16) |
         (buffer[2] << 8) | buffer[3]);
-      return((unsigned long) (value & 0xffffffff));
+      return((size_t) (value & 0xffffffff));
     }
-  value=(unsigned long) ((buffer[3] << 24) | (buffer[2] << 16) |
+  value=(size_t) ((buffer[3] << 24) | (buffer[2] << 16) |
     (buffer[1] << 8 ) | (buffer[0]));
-  return((unsigned long) (value & 0xffffffff));
+  return((size_t) (value & 0xffffffff));
 }
 
 static inline void WriteProfileLong(const EndianType endian,
-  const unsigned long value,unsigned char *p)
+  const size_t value,unsigned char *p)
 {
   unsigned char
     buffer[4];
@@ -1770,7 +1818,7 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image)
     unsigned char
       *directory;
 
-    unsigned long
+    size_t
       entry;
   } DirectoryInfo;
 
@@ -1780,7 +1828,7 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image)
   EndianType
     endian;
 
-  long
+  ssize_t
     id,
     level;
 
@@ -1800,7 +1848,7 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image)
     *directory,
     *exif;
 
-  unsigned long
+  size_t
     entry,
     number_entries;
 
@@ -1830,7 +1878,7 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image)
   }
   if (length < 16)
     return(MagickFalse);
-  id=(int) ReadProfileShort(LSBEndian,exif);
+  id=(ssize_t) ReadProfileShort(LSBEndian,exif);
   endian=LSBEndian;
   if (id == 0x4949)
     endian=LSBEndian;
@@ -1864,7 +1912,7 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image)
     number_entries=ReadProfileShort(endian,directory);
     for ( ; entry < number_entries; entry++)
     {
-      long
+      ssize_t
         components,
         format,
         tag_value;
@@ -1877,11 +1925,11 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image)
         number_bytes;
 
       q=(unsigned char *) (directory+2+(12*entry));
-      tag_value=(long) ReadProfileShort(endian,q);
-      format=(long) ReadProfileShort(endian,q+2);
+      tag_value=(ssize_t) ReadProfileShort(endian,q);
+      format=(ssize_t) ReadProfileShort(endian,q+2);
       if ((format-1) >= EXIF_NUM_FORMATS)
         break;
-      components=(long) ReadProfileLong(endian,q+4);
+      components=(ssize_t) ReadProfileLong(endian,q+4);
       number_bytes=(size_t) components*format_bytes[format];
       if (number_bytes <= 4)
         p=q+8;
@@ -1902,14 +1950,14 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image)
       {
         case 0x011a:
         {
-          (void) WriteProfileLong(endian,(unsigned long)
+          (void) WriteProfileLong(endian,(size_t)
             (image->x_resolution+0.5),p);
           (void) WriteProfileLong(endian,1UL,p+4);
           break;
         }
         case 0x011b:
         {
-          (void) WriteProfileLong(endian,(unsigned long)
+          (void) WriteProfileLong(endian,(size_t)
             (image->y_resolution+0.5),p);
           (void) WriteProfileLong(endian,1UL,p+4);
           break;