2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % PPPP RRRR OOO FFFFF IIIII L EEEEE %
7 % P P R R O O F I L E %
8 % PPPP RRRR O O FFF I L EEE %
10 % P R R OOO F IIIII LLLLL EEEEE %
13 % MagickCore Image Profile Methods %
20 % Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "magick/studio.h"
43 #include "magick/cache.h"
44 #include "magick/color.h"
45 #include "magick/configure.h"
46 #include "magick/exception.h"
47 #include "magick/exception-private.h"
48 #include "magick/hashmap.h"
49 #include "magick/image.h"
50 #include "magick/memory_.h"
51 #include "magick/monitor.h"
52 #include "magick/monitor-private.h"
53 #include "magick/option.h"
54 #include "magick/profile.h"
55 #include "magick/property.h"
56 #include "magick/quantum.h"
57 #include "magick/quantum-private.h"
58 #include "magick/splay-tree.h"
59 #include "magick/string_.h"
60 #include "magick/thread-private.h"
61 #include "magick/token.h"
62 #include "magick/utility.h"
63 #if defined(MAGICKCORE_LCMS_DELEGATE)
64 #if defined(MAGICKCORE_HAVE_LCMS_LCMS2_H)
66 #include <lcms/lcms2.h>
67 #elif defined(MAGICKCORE_HAVE_LCMS2_H)
70 #elif defined(MAGICKCORE_HAVE_LCMS_LCMS_H)
71 #include <lcms/lcms.h>
80 #if !defined(LCMS_VERSION) || (LCMS_VERSION < 2000)
81 #define cmsSigCmykData icSigCmykData
82 #define cmsSigGrayData icSigGrayData
83 #define cmsSigLabData icSigLabData
84 #define cmsSigLuvData icSigLuvData
85 #define cmsSigRgbData icSigRgbData
86 #define cmsSigXYZData icSigXYZData
87 #define cmsSigYCbCrData icSigYCbCrData
88 #define cmsSigLinkClass icSigLinkClass
89 #define cmsColorSpaceSignature icColorSpaceSignature
90 #define cmsUInt32Number DWORD
91 #define cmsSetLogErrorHandler(handler) cmsSetErrorHandler(handler)
92 #define cmsCreateTransformTHR(context,source_profile,source_type, \
93 target_profile,target_type,intent,flags) cmsCreateTransform(source_profile, \
94 source_type,target_profile,target_type,intent,flags);
95 #define cmsOpenProfileFromMemTHR(context,profile,length) \
96 cmsOpenProfileFromMem(profile,length)
100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 % C l o n e I m a g e P r o f i l e s %
108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110 % CloneImageProfiles() clones one or more image profiles.
112 % The format of the CloneImageProfiles method is:
114 % MagickBooleanType CloneImageProfiles(Image *image,
115 % const Image *clone_image)
117 % A description of each parameter follows:
119 % o image: the image.
121 % o clone_image: the clone image.
124 MagickExport MagickBooleanType CloneImageProfiles(Image *image,
125 const Image *clone_image)
127 assert(image != (Image *) NULL);
128 assert(image->signature == MagickSignature);
129 if (image->debug != MagickFalse)
130 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
131 assert(clone_image != (const Image *) NULL);
132 assert(clone_image->signature == MagickSignature);
133 image->color_profile.length=clone_image->color_profile.length;
134 image->color_profile.info=clone_image->color_profile.info;
135 image->iptc_profile.length=clone_image->iptc_profile.length;
136 image->iptc_profile.info=clone_image->iptc_profile.info;
137 if (clone_image->profiles != (void *) NULL)
138 image->profiles=CloneSplayTree((SplayTreeInfo *) clone_image->profiles,
139 (void *(*)(void *)) ConstantString,(void *(*)(void *)) CloneStringInfo);
144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
148 % D e l e t e I m a g e P r o f i l e %
152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 % DeleteImageProfile() deletes a profile from the image by its name.
156 % The format of the DeleteImageProfile method is:
158 % MagickBooleanTyupe DeleteImageProfile(Image *image,const char *name)
160 % A description of each parameter follows:
162 % o image: the image.
164 % o name: the profile name.
167 MagickExport MagickBooleanType DeleteImageProfile(Image *image,const char *name)
169 assert(image != (Image *) NULL);
170 assert(image->signature == MagickSignature);
171 if (image->debug != MagickFalse)
172 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
173 if (image->profiles == (SplayTreeInfo *) NULL)
175 if (LocaleCompare(name,"icc") == 0)
178 Continue to support deprecated color profile for now.
180 image->color_profile.length=0;
181 image->color_profile.info=(unsigned char *) NULL;
183 if (LocaleCompare(name,"iptc") == 0)
186 Continue to support deprecated IPTC profile for now.
188 image->iptc_profile.length=0;
189 image->iptc_profile.info=(unsigned char *) NULL;
191 return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->profiles,name));
195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199 % D e s t r o y I m a g e P r o f i l e s %
203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205 % DestroyImageProfiles() releases memory associated with an image profile map.
207 % The format of the DestroyProfiles method is:
209 % void DestroyImageProfiles(Image *image)
211 % A description of each parameter follows:
213 % o image: the image.
216 MagickExport void DestroyImageProfiles(Image *image)
218 if (image->profiles != (SplayTreeInfo *) NULL)
219 image->profiles=DestroySplayTree((SplayTreeInfo *) image->profiles);
223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 % G e t I m a g e P r o f i l e %
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
233 % GetImageProfile() gets a profile associated with an image by name.
235 % The format of the GetImageProfile method is:
237 % const StringInfo *GetImageProfile(const Image *image,const char *name)
239 % A description of each parameter follows:
241 % o image: the image.
243 % o name: the profile name.
246 MagickExport const StringInfo *GetImageProfile(const Image *image,
255 assert(image != (Image *) NULL);
256 assert(image->signature == MagickSignature);
257 if (image->debug != MagickFalse)
258 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
259 if (image->profiles == (SplayTreeInfo *) NULL)
260 return((StringInfo *) NULL);
261 (void) CopyMagickString(key,name,MaxTextExtent);
262 profile=(const StringInfo *) GetValueFromSplayTree((SplayTreeInfo *)
263 image->profiles,key);
268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272 % G e t N e x t I m a g e P r o f i l e %
276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278 % GetNextImageProfile() gets the next profile name for an image.
280 % The format of the GetNextImageProfile method is:
282 % char *GetNextImageProfile(const Image *image)
284 % A description of each parameter follows:
286 % o hash_info: the hash info.
289 MagickExport char *GetNextImageProfile(const Image *image)
291 assert(image != (Image *) NULL);
292 assert(image->signature == MagickSignature);
293 if (image->debug != MagickFalse)
294 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
295 if (image->profiles == (SplayTreeInfo *) NULL)
296 return((char *) NULL);
297 return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->profiles));
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 % P r o f i l e I m a g e %
309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 % ProfileImage() associates, applies, or removes an ICM, IPTC, or generic
312 % profile with / to / from an image. If the profile is NULL, it is removed
313 % from the image otherwise added or applied. Use a name of '*' and a profile
314 % of NULL to remove all profiles from the image.
316 % ICC and ICM profiles are handled as follows: If the image does not have
317 % an associated color profile, the one you provide is associated with the
318 % image and the image pixels are not transformed. Otherwise, the colorspace
319 % transform defined by the existing and new profile are applied to the image
320 % pixels and the new profile is associated with the image.
322 % The format of the ProfileImage method is:
324 % MagickBooleanType ProfileImage(Image *image,const char *name,
325 % const void *datum,const size_t length,const MagickBooleanType clone)
327 % A description of each parameter follows:
329 % o image: the image.
331 % o name: Name of profile to add or remove: ICC, IPTC, or generic profile.
333 % o datum: the profile data.
335 % o length: the length of the profile.
337 % o clone: should be MagickFalse.
341 #if defined(MAGICKCORE_LCMS_DELEGATE)
343 static unsigned short **DestroyPixelThreadSet(unsigned short **pixels)
348 assert(pixels != (unsigned short **) NULL);
349 for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
350 if (pixels[i] != (unsigned short *) NULL)
351 pixels[i]=(unsigned short *) RelinquishMagickMemory(pixels[i]);
352 pixels=(unsigned short **) RelinquishAlignedMemory(pixels);
356 static unsigned short **AcquirePixelThreadSet(const size_t columns,
357 const size_t channels)
368 number_threads=GetOpenMPMaximumThreads();
369 pixels=(unsigned short **) AcquireAlignedMemory(number_threads,
371 if (pixels == (unsigned short **) NULL)
372 return((unsigned short **) NULL);
373 (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels));
374 for (i=0; i < (ssize_t) number_threads; i++)
376 pixels[i]=(unsigned short *) AcquireQuantumMemory(columns,channels*
378 if (pixels[i] == (unsigned short *) NULL)
379 return(DestroyPixelThreadSet(pixels));
384 static cmsHTRANSFORM *DestroyTransformThreadSet(cmsHTRANSFORM *transform)
389 assert(transform != (cmsHTRANSFORM *) NULL);
390 for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
391 if (transform[i] != (cmsHTRANSFORM) NULL)
392 cmsDeleteTransform(transform[i]);
393 transform=(cmsHTRANSFORM *) RelinquishAlignedMemory(transform);
397 static cmsHTRANSFORM *AcquireTransformThreadSet(Image *image,
398 const cmsHPROFILE source_profile,const cmsUInt32Number source_type,
399 const cmsHPROFILE target_profile,const cmsUInt32Number target_type,
400 const int intent,const cmsUInt32Number flags)
411 number_threads=GetOpenMPMaximumThreads();
412 transform=(cmsHTRANSFORM *) AcquireAlignedMemory(number_threads,
414 if (transform == (cmsHTRANSFORM *) NULL)
415 return((cmsHTRANSFORM *) NULL);
416 (void) ResetMagickMemory(transform,0,number_threads*sizeof(*transform));
417 for (i=0; i < (ssize_t) number_threads; i++)
419 transform[i]=cmsCreateTransformTHR(image,source_profile,source_type,
420 target_profile,target_type,intent,flags);
421 if (transform[i] == (cmsHTRANSFORM) NULL)
422 return(DestroyTransformThreadSet(transform));
428 static MagickBooleanType SetAdobeRGB1998ImageProfile(Image *image)
431 AdobeRGB1998Profile[] =
433 0x00, 0x00, 0x02, 0x30, 0x41, 0x44, 0x42, 0x45, 0x02, 0x10, 0x00,
434 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
435 0x5a, 0x20, 0x07, 0xd0, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x13, 0x00,
436 0x33, 0x00, 0x3b, 0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c,
437 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00,
438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
440 0x00, 0xd3, 0x2d, 0x41, 0x44, 0x42, 0x45, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
445 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
446 0x32, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00,
447 0x00, 0x6b, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x9c, 0x00,
448 0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x01, 0xb0,
449 0x00, 0x00, 0x00, 0x14, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01,
450 0xc4, 0x00, 0x00, 0x00, 0x0e, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00,
451 0x01, 0xd4, 0x00, 0x00, 0x00, 0x0e, 0x62, 0x54, 0x52, 0x43, 0x00,
452 0x00, 0x01, 0xe4, 0x00, 0x00, 0x00, 0x0e, 0x72, 0x58, 0x59, 0x5a,
453 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59,
454 0x5a, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58,
455 0x59, 0x5a, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x14, 0x74,
456 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79,
457 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20,
458 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65,
459 0x6d, 0x73, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72,
460 0x61, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x41, 0x64, 0x6f,
462 0x62, 0x65, 0x20, 0x52, 0x47, 0x42, 0x20, 0x28, 0x31, 0x39, 0x39,
463 0x38, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00,
471 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00,
472 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0x00, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475 0x00, 0x01, 0x02, 0x33, 0x00, 0x00, 0x63, 0x75, 0x72, 0x76, 0x00,
476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33, 0x00, 0x00,
477 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x01, 0x02, 0x33, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00,
479 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, 0x00, 0x00, 0x4f, 0xa5, 0x00,
480 0x00, 0x04, 0xfc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, 0x00, 0x00, 0x0f,
482 0x95, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483 0x26, 0x31, 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9c
492 assert(image != (Image *) NULL);
493 assert(image->signature == MagickSignature);
494 if (GetImageProfile(image,"icm") != (const StringInfo *) NULL)
496 profile=AcquireStringInfo(sizeof(AdobeRGB1998Profile));
497 SetStringInfoDatum(profile,AdobeRGB1998Profile);
498 status=SetImageProfile(image,"icm",profile);
499 profile=DestroyStringInfo(profile);
503 static MagickBooleanType SetsRGBImageProfile(Image *image)
508 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
509 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
510 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
511 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
512 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
513 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
514 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
515 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
520 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00,
521 0x33, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00,
522 0x00, 0x6c, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0xf0, 0x00,
523 0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04,
524 0x00, 0x00, 0x00, 0x14, 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02,
525 0x18, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00,
526 0x02, 0x2c, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58, 0x59, 0x5a, 0x00,
527 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, 0x64, 0x6d, 0x6e, 0x64,
528 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70, 0x64, 0x6d, 0x64,
529 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, 0x76, 0x75,
530 0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x76,
531 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24,
532 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00,
533 0x14, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00,
534 0x00, 0x24, 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, 0x00,
535 0x00, 0x00, 0x0c, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c,
536 0x00, 0x00, 0x08, 0x0c, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04,
537 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x62, 0x54, 0x52, 0x43, 0x00, 0x00,
538 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x74, 0x65, 0x78, 0x74, 0x00,
539 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
540 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20,
541 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74, 0x74, 0x2d, 0x50, 0x61, 0x63,
542 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e,
543 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45,
545 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
547 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39,
548 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58,
555 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a,
557 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00,
558 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, 0x00, 0x00, 0xb7, 0x85,
560 0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00,
562 0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
564 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
565 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
567 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
568 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31,
574 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, 0x65, 0x66,
575 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, 0x6f,
576 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
577 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20,
579 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
580 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20,
581 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63,
582 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73,
585 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
586 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
587 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
588 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
589 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
591 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
592 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
593 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
594 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
598 0xa4, 0xfe, 0x00, 0x14, 0x5f, 0x2e, 0x00, 0x10, 0xcf, 0x14, 0x00,
599 0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, 0x00, 0x03, 0x5c, 0x9e,
600 0x00, 0x00, 0x00, 0x01, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, 0x00, 0x57,
602 0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
605 0x8f, 0x00, 0x00, 0x00, 0x02, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00,
606 0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05,
608 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00,
609 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b,
610 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54, 0x00,
611 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
612 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00,
613 0x90, 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9,
614 0x00, 0xae, 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00,
615 0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0,
616 0x00, 0xe5, 0x00, 0xeb, 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01,
617 0x01, 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f,
618 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, 0x01, 0x38, 0x01, 0x3e, 0x01,
619 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67,
620 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, 0x01, 0x8b, 0x01,
621 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9,
622 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, 0x01,
623 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
624 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02,
625 0x4b, 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a,
626 0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02,
627 0xb6, 0x02, 0xc1, 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb,
628 0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03,
629 0x2d, 0x03, 0x38, 0x03, 0x43, 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66,
630 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, 0x03,
631 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, 0x03, 0xe0, 0x03, 0xec,
632 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04,
633 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, 0x04, 0x7e,
634 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4, 0x04,
635 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
636 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05,
637 0x77, 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5,
638 0x05, 0xd5, 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06,
639 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b,
640 0x06, 0x8c, 0x06, 0x9d, 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06,
641 0xe3, 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d,
642 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, 0x07, 0x86, 0x07, 0x99, 0x07,
643 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b,
644 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, 0x08, 0x6e, 0x08,
645 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7,
646 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, 0x09,
647 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
648 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a,
649 0x54, 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5,
650 0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b,
651 0x51, 0x0b, 0x69, 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8,
652 0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c,
653 0x5c, 0x0c, 0x75, 0x0c, 0x8e, 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9,
654 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, 0x0d,
655 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, 0x0d, 0xde, 0x0d, 0xf8,
656 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e,
657 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, 0x0f, 0x25,
658 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3, 0x0f,
659 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
660 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11,
661 0x13, 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa,
662 0x11, 0xc9, 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12,
663 0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03,
664 0x13, 0x23, 0x13, 0x43, 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13,
665 0xc5, 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a,
666 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, 0x14, 0xf0, 0x15, 0x12, 0x15,
667 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0,
668 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, 0x16, 0x8f, 0x16,
669 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65,
670 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, 0x18,
671 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
672 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19,
673 0xdd, 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e,
674 0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b,
675 0x8a, 0x1b, 0xb2, 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52,
676 0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d,
677 0x47, 0x1d, 0x70, 0x1d, 0x99, 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16,
678 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, 0x1f,
679 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, 0x1f, 0xbf, 0x1f, 0xea,
680 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20,
681 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, 0x21, 0xce,
682 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf, 0x22,
683 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
684 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24,
685 0xda, 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7,
686 0x25, 0xf7, 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26,
687 0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc,
688 0x28, 0x0d, 0x28, 0x3f, 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29,
689 0x06, 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02,
690 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, 0x2a, 0xcf, 0x2b, 0x02, 0x2b,
691 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39,
692 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, 0x2d, 0x41, 0x2d,
693 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82,
694 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, 0x2f,
695 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
696 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32,
697 0x2a, 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46,
698 0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34,
699 0x9e, 0x34, 0xd8, 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2,
700 0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37,
701 0x24, 0x37, 0x60, 0x37, 0x9c, 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50,
702 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, 0x39,
703 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, 0x3a, 0xb2, 0x3a, 0xef,
704 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c,
705 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, 0x3d, 0xa1,
706 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0, 0x3f,
707 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
708 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41,
709 0xee, 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a,
710 0x43, 0x7d, 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44,
711 0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22,
712 0x46, 0x67, 0x46, 0xab, 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47,
713 0xc0, 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d,
714 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, 0x4a, 0x37, 0x4a, 0x7d, 0x4a,
715 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a,
716 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, 0x4d, 0x93, 0x4d,
717 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49,
718 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, 0x51,
719 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
720 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54,
721 0x42, 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2,
722 0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57,
723 0x92, 0x57, 0xe0, 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a,
724 0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a,
725 0xf5, 0x5b, 0x45, 0x5b, 0x95, 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86,
726 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, 0x5e,
727 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, 0x5f, 0xb3, 0x60, 0x05,
728 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61,
729 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, 0x63, 0x97,
730 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d, 0x65,
731 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
732 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69,
733 0x43, 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7,
734 0x6b, 0x4f, 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d,
735 0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4,
736 0x6f, 0x1e, 0x6f, 0x78, 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70,
737 0xe0, 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6,
738 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, 0x74, 0x14, 0x74, 0x70, 0x74,
739 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b,
740 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, 0x78, 0x6e, 0x78,
741 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5,
742 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, 0x7c,
743 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
744 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81,
745 0x0a, 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4,
746 0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85,
747 0x47, 0x85, 0xab, 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b,
748 0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89,
749 0x99, 0x89, 0xfe, 0x8a, 0x64, 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96,
750 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, 0x8d,
751 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, 0x8f, 0x9e, 0x90, 0x06,
752 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92,
753 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, 0x94, 0x8a,
754 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f, 0x97,
755 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
756 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b,
757 0xaf, 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2,
758 0x9e, 0x40, 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0,
759 0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96,
760 0xa3, 0x06, 0xa3, 0x76, 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5,
761 0x38, 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e,
762 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, 0xa9, 0x37, 0xa9, 0xa9, 0xaa,
763 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c,
764 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, 0xae, 0xa1, 0xaf,
765 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60,
766 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, 0xb4,
767 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
768 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9,
769 0x4a, 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7,
770 0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe,
771 0x84, 0xbe, 0xff, 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec,
772 0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3,
773 0xd4, 0xc4, 0x51, 0xc4, 0xce, 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46,
774 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, 0xc9,
775 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, 0xcb, 0x36, 0xcb, 0xb6,
776 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce,
777 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, 0xd1, 0x3c,
778 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6, 0xd4,
779 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
780 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9,
781 0xf1, 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a,
782 0xdd, 0x10, 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf,
783 0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53,
784 0xe2, 0xdb, 0xe3, 0x63, 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5,
785 0x84, 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32,
786 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, 0xea, 0x5b, 0xea, 0xe5, 0xeb,
787 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28,
788 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, 0xf0, 0xe5, 0xf1,
789 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34,
790 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, 0xf7,
791 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
792 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd,
793 0xba, 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
802 assert(image != (Image *) NULL);
803 assert(image->signature == MagickSignature);
804 if (GetImageProfile(image,"icm") != (const StringInfo *) NULL)
806 profile=AcquireStringInfo(sizeof(sRGBProfile));
807 SetStringInfoDatum(profile,sRGBProfile);
808 status=SetImageProfile(image,"icm",profile);
809 profile=DestroyStringInfo(profile);
812 #if defined(MAGICKCORE_LCMS_DELEGATE)
813 #if defined(LCMS_VERSION) && (LCMS_VERSION >= 2000)
814 static void LCMSExceptionHandler(cmsContext context,cmsUInt32Number severity,
820 (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%u, %s",
821 severity,message != (char *) NULL ? message : "no message");
822 image=(Image *) context;
823 if (image != (Image *) NULL)
824 (void) ThrowMagickException(&image->exception,GetMagickModule(),
825 ImageWarning,"UnableToTransformColorspace","`%s'",image->filename);
829 static int LCMSExceptionHandler(int severity,const char *message)
831 (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%d, %s",
832 severity,message != (char *) NULL ? message : "no message");
838 MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
839 const void *datum,const size_t length,
840 const MagickBooleanType magick_unused(clone))
842 #define ProfileImageTag "Profile/Image"
843 #define ThrowProfileException(severity,tag,context) \
845 if (source_profile != (cmsHPROFILE) NULL) \
846 (void) cmsCloseProfile(source_profile); \
847 if (target_profile != (cmsHPROFILE) NULL) \
848 (void) cmsCloseProfile(target_profile); \
849 ThrowBinaryException(severity,tag,context); \
858 assert(image != (Image *) NULL);
859 assert(image->signature == MagickSignature);
860 if (image->debug != MagickFalse)
861 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
862 assert(name != (const char *) NULL);
863 if ((datum == (const void *) NULL) || (length == 0))
876 Delete image profile(s).
878 names=ConstantString(name);
879 (void) SubstituteString(&names,","," ");
880 arguments=StringToArgv(names,&number_arguments);
881 names=DestroyString(names);
882 if (arguments == (char **) NULL)
884 ResetImageProfileIterator(image);
885 for (name=GetNextImageProfile(image); name != (const char *) NULL; )
887 for (i=1; i < (ssize_t) number_arguments; i++)
889 if ((*arguments[i] == '!') &&
890 (LocaleCompare(name,arguments[i]+1) == 0))
892 if (GlobExpression(name,arguments[i],MagickTrue) != MagickFalse)
894 (void) DeleteImageProfile(image,name);
895 ResetImageProfileIterator(image);
899 name=GetNextImageProfile(image);
901 for (i=0; i < (ssize_t) number_arguments; i++)
902 arguments[i]=DestroyString(arguments[i]);
903 arguments=(char **) RelinquishMagickMemory(arguments);
907 Add a ICC, IPTC, or generic profile to the image.
910 profile=AcquireStringInfo((size_t) length);
911 SetStringInfoDatum(profile,(unsigned char *) datum);
912 if ((LocaleCompare(name,"icc") != 0) && (LocaleCompare(name,"icm") != 0))
913 status=SetImageProfile(image,name,profile);
919 icc_profile=GetImageProfile(image,"icc");
920 if ((icc_profile != (const StringInfo *) NULL) &&
921 (CompareStringInfo(icc_profile,profile) == 0))
926 value=GetImageProperty(image,"exif:ColorSpace");
927 if (LocaleCompare(value,"1") != 0)
928 (void) SetsRGBImageProfile(image);
929 value=GetImageProperty(image,"exif:InteroperabilityIndex");
930 if (LocaleCompare(value,"R98.") != 0)
931 (void) SetsRGBImageProfile(image);
932 value=GetImageProperty(image,"exif:InteroperabilityIndex");
933 if (LocaleCompare(value,"R03.") != 0)
934 (void) SetAdobeRGB1998ImageProfile(image);
935 icc_profile=GetImageProfile(image,"icc");
937 if ((icc_profile != (const StringInfo *) NULL) &&
938 (CompareStringInfo(icc_profile,profile) == 0))
940 profile=DestroyStringInfo(profile);
943 #if !defined(MAGICKCORE_LCMS_DELEGATE)
944 (void) ThrowMagickException(&image->exception,GetMagickModule(),
945 MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","`%s' (LCMS)",
953 Transform pixel colors as defined by the color profiles.
955 cmsSetLogErrorHandler(LCMSExceptionHandler);
956 source_profile=cmsOpenProfileFromMemTHR(image,
957 GetStringInfoDatum(profile),(cmsUInt32Number)
958 GetStringInfoLength(profile));
959 if (source_profile == (cmsHPROFILE) NULL)
960 ThrowBinaryException(ResourceLimitError,
961 "ColorspaceColorProfileMismatch",name);
962 if ((cmsGetDeviceClass(source_profile) != cmsSigLinkClass) &&
963 (icc_profile == (StringInfo *) NULL))
964 status=SetImageProfile(image,name,profile);
974 cmsColorSpaceSignature
1009 **restrict source_pixels,
1010 **restrict target_pixels;
1012 exception=(&image->exception);
1013 target_profile=(cmsHPROFILE) NULL;
1014 if (icc_profile != (StringInfo *) NULL)
1016 target_profile=source_profile;
1017 source_profile=cmsOpenProfileFromMemTHR(image,
1018 GetStringInfoDatum(icc_profile),(cmsUInt32Number)
1019 GetStringInfoLength(icc_profile));
1020 if (source_profile == (cmsHPROFILE) NULL)
1021 ThrowProfileException(ResourceLimitError,
1022 "ColorspaceColorProfileMismatch",name);
1024 switch (cmsGetColorSpace(source_profile))
1026 case cmsSigCmykData:
1028 source_colorspace=CMYKColorspace;
1029 source_type=(cmsUInt32Number) TYPE_CMYK_16;
1033 case cmsSigGrayData:
1035 source_colorspace=GRAYColorspace;
1036 source_type=(cmsUInt32Number) TYPE_GRAY_16;
1042 source_colorspace=LabColorspace;
1043 source_type=(cmsUInt32Number) TYPE_Lab_16;
1049 source_colorspace=YUVColorspace;
1050 source_type=(cmsUInt32Number) TYPE_YUV_16;
1056 source_colorspace=RGBColorspace;
1057 source_type=(cmsUInt32Number) TYPE_RGB_16;
1063 source_colorspace=XYZColorspace;
1064 source_type=(cmsUInt32Number) TYPE_XYZ_16;
1068 case cmsSigYCbCrData:
1070 source_colorspace=YCbCrColorspace;
1071 source_type=(cmsUInt32Number) TYPE_YCbCr_16;
1077 source_colorspace=UndefinedColorspace;
1078 source_type=(cmsUInt32Number) TYPE_RGB_16;
1083 signature=cmsGetPCS(source_profile);
1084 if (target_profile != (cmsHPROFILE) NULL)
1085 signature=cmsGetColorSpace(target_profile);
1088 case cmsSigCmykData:
1090 target_colorspace=CMYKColorspace;
1091 target_type=(cmsUInt32Number) TYPE_CMYK_16;
1097 target_colorspace=LabColorspace;
1098 target_type=(cmsUInt32Number) TYPE_Lab_16;
1102 case cmsSigGrayData:
1104 target_colorspace=GRAYColorspace;
1105 target_type=(cmsUInt32Number) TYPE_GRAY_16;
1111 target_colorspace=YUVColorspace;
1112 target_type=(cmsUInt32Number) TYPE_YUV_16;
1118 target_colorspace=RGBColorspace;
1119 target_type=(cmsUInt32Number) TYPE_RGB_16;
1125 target_colorspace=XYZColorspace;
1126 target_type=(cmsUInt32Number) TYPE_XYZ_16;
1130 case cmsSigYCbCrData:
1132 target_colorspace=YCbCrColorspace;
1133 target_type=(cmsUInt32Number) TYPE_YCbCr_16;
1139 target_colorspace=UndefinedColorspace;
1140 target_type=(cmsUInt32Number) TYPE_RGB_16;
1145 if ((source_colorspace == UndefinedColorspace) ||
1146 (target_colorspace == UndefinedColorspace))
1147 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1149 if ((source_colorspace == GRAYColorspace) &&
1150 (IsGrayImage(image,exception) == MagickFalse))
1151 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1153 if ((source_colorspace == CMYKColorspace) &&
1154 (image->colorspace != CMYKColorspace))
1155 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1157 if ((source_colorspace == XYZColorspace) &&
1158 (image->colorspace != XYZColorspace))
1159 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1161 if ((source_colorspace == YCbCrColorspace) &&
1162 (image->colorspace != YCbCrColorspace))
1163 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1165 if ((source_colorspace != CMYKColorspace) &&
1166 (source_colorspace != GRAYColorspace) &&
1167 (source_colorspace != LabColorspace) &&
1168 (source_colorspace != XYZColorspace) &&
1169 (source_colorspace != YCbCrColorspace) &&
1170 (image->colorspace != RGBColorspace))
1171 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1173 switch (image->rendering_intent)
1175 case AbsoluteIntent: intent=INTENT_ABSOLUTE_COLORIMETRIC; break;
1176 case PerceptualIntent: intent=INTENT_PERCEPTUAL; break;
1177 case RelativeIntent: intent=INTENT_RELATIVE_COLORIMETRIC; break;
1178 case SaturationIntent: intent=INTENT_SATURATION; break;
1179 default: intent=INTENT_PERCEPTUAL; break;
1181 flags=cmsFLAGS_HIGHRESPRECALC;
1182 #if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1183 if (image->black_point_compensation != MagickFalse)
1184 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1186 transform=AcquireTransformThreadSet(image,source_profile,
1187 source_type,target_profile,target_type,intent,flags);
1188 if (transform == (cmsHTRANSFORM *) NULL)
1189 ThrowProfileException(ImageError,"UnableToCreateColorTransform",
1192 Transform image as dictated by the source & target image profiles.
1194 length=(size_t) image->columns;
1195 source_pixels=AcquirePixelThreadSet(image->columns,source_channels);
1196 target_pixels=AcquirePixelThreadSet(image->columns,target_channels);
1197 if ((source_pixels == (unsigned short **) NULL) ||
1198 (target_pixels == (unsigned short **) NULL))
1200 transform=DestroyTransformThreadSet(transform);
1201 ThrowProfileException(ResourceLimitError,
1202 "MemoryAllocationFailed",image->filename);
1204 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1206 target_pixels=DestroyPixelThreadSet(target_pixels);
1207 source_pixels=DestroyPixelThreadSet(source_pixels);
1208 transform=DestroyTransformThreadSet(transform);
1209 if (source_profile != (cmsHPROFILE) NULL)
1210 (void) cmsCloseProfile(source_profile);
1211 if (target_profile != (cmsHPROFILE) NULL)
1212 (void) cmsCloseProfile(target_profile);
1213 return(MagickFalse);
1215 if (target_colorspace == CMYKColorspace)
1216 (void) SetImageColorspace(image,target_colorspace);
1219 image_view=AcquireCacheView(image);
1220 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1221 #pragma omp parallel for schedule(dynamic,4) shared(status)
1223 for (y=0; y < (ssize_t) image->rows; y++)
1228 register IndexPacket
1235 register PixelPacket
1238 register unsigned short
1241 if (status == MagickFalse)
1243 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1245 if (q == (PixelPacket *) NULL)
1250 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1251 id=GetOpenMPThreadId();
1252 p=source_pixels[id];
1253 for (x=0; x < (ssize_t) image->columns; x++)
1255 *p++=ScaleQuantumToShort(q->red);
1256 if (source_channels > 1)
1258 *p++=ScaleQuantumToShort(q->green);
1259 *p++=ScaleQuantumToShort(q->blue);
1261 if (source_channels > 3)
1262 *p++=ScaleQuantumToShort(indexes[x]);
1265 cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
1266 (unsigned int) image->columns);
1267 p=target_pixels[id];
1269 for (x=0; x < (ssize_t) image->columns; x++)
1271 q->red=ScaleShortToQuantum(*p);
1275 if (target_channels > 1)
1277 q->green=ScaleShortToQuantum(*p);
1279 q->blue=ScaleShortToQuantum(*p);
1282 if (target_channels > 3)
1284 indexes[x]=ScaleShortToQuantum(*p);
1289 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1290 if (sync == MagickFalse)
1292 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1297 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1298 #pragma omp critical (MagickCore_ProfileImage)
1300 proceed=SetImageProgress(image,ProfileImageTag,progress++,
1302 if (proceed == MagickFalse)
1306 image_view=DestroyCacheView(image_view);
1307 (void) SetImageColorspace(image,target_colorspace);
1312 image->type=image->matte == MagickFalse ? TrueColorType :
1316 case cmsSigCmykData:
1318 image->type=image->matte == MagickFalse ? ColorSeparationType :
1319 ColorSeparationMatteType;
1322 case cmsSigGrayData:
1324 image->type=image->matte == MagickFalse ? GrayscaleType :
1331 target_pixels=DestroyPixelThreadSet(target_pixels);
1332 source_pixels=DestroyPixelThreadSet(source_pixels);
1333 transform=DestroyTransformThreadSet(transform);
1334 if (cmsGetDeviceClass(source_profile) != cmsSigLinkClass)
1335 status=SetImageProfile(image,name,profile);
1336 if (target_profile != (cmsHPROFILE) NULL)
1337 (void) cmsCloseProfile(target_profile);
1339 (void) cmsCloseProfile(source_profile);
1343 profile=DestroyStringInfo(profile);
1348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1352 % R e m o v e I m a g e P r o f i l e %
1356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1358 % RemoveImageProfile() removes a named profile from the image and returns its
1361 % The format of the RemoveImageProfile method is:
1363 % void *RemoveImageProfile(Image *image,const char *name)
1365 % A description of each parameter follows:
1367 % o image: the image.
1369 % o name: the profile name.
1372 MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
1377 assert(image != (Image *) NULL);
1378 assert(image->signature == MagickSignature);
1379 if (image->debug != MagickFalse)
1380 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1381 if (image->profiles == (SplayTreeInfo *) NULL)
1382 return((StringInfo *) NULL);
1383 if (LocaleCompare(name,"icc") == 0)
1386 Continue to support deprecated color profile for now.
1388 image->color_profile.length=0;
1389 image->color_profile.info=(unsigned char *) NULL;
1391 if (LocaleCompare(name,"iptc") == 0)
1394 Continue to support deprecated IPTC profile for now.
1396 image->iptc_profile.length=0;
1397 image->iptc_profile.info=(unsigned char *) NULL;
1399 profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
1400 image->profiles,name);
1405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409 % R e s e t P r o f i l e I t e r a t o r %
1413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415 % ResetImageProfileIterator() resets the image profile iterator. Use it in
1416 % conjunction with GetNextImageProfile() to iterate over all the profiles
1417 % associated with an image.
1419 % The format of the ResetImageProfileIterator method is:
1421 % ResetImageProfileIterator(Image *image)
1423 % A description of each parameter follows:
1425 % o image: the image.
1428 MagickExport void ResetImageProfileIterator(const Image *image)
1430 assert(image != (Image *) NULL);
1431 assert(image->signature == MagickSignature);
1432 if (image->debug != MagickFalse)
1433 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1434 if (image->profiles == (SplayTreeInfo *) NULL)
1436 ResetSplayTreeIterator((SplayTreeInfo *) image->profiles);
1440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1444 % S e t I m a g e P r o f i l e %
1448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1450 % SetImageProfile() adds a named profile to the image. If a profile with the
1451 % same name already exists, it is replaced. This method differs from the
1452 % ProfileImage() method in that it does not apply CMS color profiles.
1454 % The format of the SetImageProfile method is:
1456 % MagickBooleanType SetImageProfile(Image *image,const char *name,
1457 % const StringInfo *profile)
1459 % A description of each parameter follows:
1461 % o image: the image.
1463 % o name: the profile name, for example icc, exif, and 8bim (8bim is the
1464 % Photoshop wrapper for iptc profiles).
1466 % o profile: A StringInfo structure that contains the named profile.
1470 static void *DestroyProfile(void *profile)
1472 return((void *) DestroyStringInfo((StringInfo *) profile));
1475 static inline const unsigned char *ReadResourceByte(const unsigned char *p,
1476 unsigned char *quantum)
1482 static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
1483 const ssize_t count,unsigned char *quantum)
1488 for (i=0; i < count; i++)
1493 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
1496 *quantum=(size_t) (*p++ << 24);
1497 *quantum|=(size_t) (*p++ << 16);
1498 *quantum|=(size_t) (*p++ << 8);
1499 *quantum|=(size_t) (*p++ << 0);
1503 static inline const unsigned char *ReadResourceShort(const unsigned char *p,
1504 unsigned short *quantum)
1506 *quantum=(unsigned short) (*p++ << 8);
1507 *quantum|=(unsigned short) (*p++ << 0);
1511 static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
1512 const StringInfo *resource_block)
1517 register const unsigned char
1535 datum=GetStringInfoDatum(resource_block);
1536 length=GetStringInfoLength(resource_block);
1537 for (p=datum; p < (datum+length-16); )
1539 if (LocaleNCompare((char *) p,"8BIM",4) != 0)
1542 p=ReadResourceShort(p,&id);
1543 p=ReadResourceByte(p,&length_byte);
1545 if (((length_byte+1) & 0x01) != 0)
1547 if (p > (datum+length-4))
1549 p=ReadResourceLong(p,&count);
1550 if ((p > (datum+length-count)) || (count > length))
1562 p=ReadResourceShort(p,&resolution)+6;
1563 image->x_resolution=(double) resolution;
1564 p=ReadResourceShort(p,&resolution)+6;
1565 image->y_resolution=(double) resolution;
1573 profile=AcquireStringInfo(count);
1574 SetStringInfoDatum(profile,p);
1575 (void) SetImageProfile(image,"iptc",profile);
1576 profile=DestroyStringInfo(profile);
1593 profile=AcquireStringInfo(count);
1594 SetStringInfoDatum(profile,p);
1595 (void) SetImageProfile(image,"icc",profile);
1596 profile=DestroyStringInfo(profile);
1605 profile=AcquireStringInfo(count);
1606 SetStringInfoDatum(profile,p);
1607 (void) SetImageProfile(image,"exif",profile);
1608 profile=DestroyStringInfo(profile);
1617 profile=AcquireStringInfo(count);
1618 SetStringInfoDatum(profile,p);
1619 (void) SetImageProfile(image,"xmp",profile);
1620 profile=DestroyStringInfo(profile);
1630 if ((count & 0x01) != 0)
1636 MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
1637 const StringInfo *profile)
1641 property[MaxTextExtent];
1646 assert(image != (Image *) NULL);
1647 assert(image->signature == MagickSignature);
1648 if (image->debug != MagickFalse)
1649 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1650 if (image->profiles == (SplayTreeInfo *) NULL)
1651 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1653 (void) CopyMagickString(key,name,MaxTextExtent);
1654 status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
1655 ConstantString(key),CloneStringInfo(profile));
1656 if ((status != MagickFalse) &&
1657 ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0)))
1663 Continue to support deprecated color profile member.
1665 icc_profile=GetImageProfile(image,name);
1666 if (icc_profile != (const StringInfo *) NULL)
1668 image->color_profile.length=GetStringInfoLength(icc_profile);
1669 image->color_profile.info=GetStringInfoDatum(icc_profile);
1672 if ((status != MagickFalse) &&
1673 ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
1679 Continue to support deprecated IPTC profile member.
1681 iptc_profile=GetImageProfile(image,name);
1682 if (iptc_profile != (const StringInfo *) NULL)
1684 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1685 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1687 (void) GetProfilesFromResourceBlock(image,profile);
1690 Inject profile into image properties.
1692 (void) FormatMagickString(property,MaxTextExtent,"%s:sans",name);
1693 (void) GetImageProperty(image,property);
1698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1702 % S y n c I m a g e P r o f i l e s %
1706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1708 % SyncImageProfiles() synchronizes image properties with the image profiles.
1709 % Currently we only support updating the EXIF resolution and orientation.
1711 % The format of the SyncImageProfiles method is:
1713 % MagickBooleanType SyncImageProfiles(Image *image)
1715 % A description of each parameter follows:
1717 % o image: the image.
1721 static inline int ReadProfileByte(unsigned char **p,size_t *length)
1733 static inline unsigned short ReadProfileShort(const EndianType endian,
1734 unsigned char *buffer)
1739 if (endian == MSBEndian)
1741 value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
1742 ((unsigned char *) buffer)[1]);
1743 return((unsigned short) (value & 0xffff));
1745 value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
1746 return((unsigned short) (value & 0xffff));
1749 static inline size_t ReadProfileLong(const EndianType endian,
1750 unsigned char *buffer)
1755 if (endian == MSBEndian)
1757 value=(size_t) ((buffer[0] << 24) | (buffer[1] << 16) |
1758 (buffer[2] << 8) | buffer[3]);
1759 return((size_t) (value & 0xffffffff));
1761 value=(size_t) ((buffer[3] << 24) | (buffer[2] << 16) |
1762 (buffer[1] << 8 ) | (buffer[0]));
1763 return((size_t) (value & 0xffffffff));
1766 static inline void WriteProfileLong(const EndianType endian,
1767 const size_t value,unsigned char *p)
1772 if (endian == MSBEndian)
1774 buffer[0]=(unsigned char) (value >> 24);
1775 buffer[1]=(unsigned char) (value >> 16);
1776 buffer[2]=(unsigned char) (value >> 8);
1777 buffer[3]=(unsigned char) value;
1778 (void) CopyMagickMemory(p,buffer,4);
1781 buffer[0]=(unsigned char) value;
1782 buffer[1]=(unsigned char) (value >> 8);
1783 buffer[2]=(unsigned char) (value >> 16);
1784 buffer[3]=(unsigned char) (value >> 24);
1785 (void) CopyMagickMemory(p,buffer,4);
1788 static void WriteProfileShort(const EndianType endian,
1789 const unsigned short value,unsigned char *p)
1794 if (endian == MSBEndian)
1796 buffer[0]=(unsigned char) (value >> 8);
1797 buffer[1]=(unsigned char) value;
1798 (void) CopyMagickMemory(p,buffer,2);
1801 buffer[0]=(unsigned char) value;
1802 buffer[1]=(unsigned char) (value >> 8);
1803 (void) CopyMagickMemory(p,buffer,2);
1806 MagickExport MagickBooleanType SyncImageProfiles(Image *image)
1808 #define MaxDirectoryStack 16
1809 #define EXIF_DELIMITER "\n"
1810 #define EXIF_NUM_FORMATS 12
1811 #define TAG_EXIF_OFFSET 0x8769
1812 #define TAG_INTEROP_OFFSET 0xa005
1814 typedef struct _DirectoryInfo
1824 directory_stack[MaxDirectoryStack];
1840 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
1854 Set EXIF resolution tag.
1856 profile=(StringInfo *) GetImageProfile(image,"EXIF");
1857 if (profile == (StringInfo *) NULL)
1859 length=GetStringInfoLength(profile);
1860 exif=GetStringInfoDatum(profile);
1863 if (ReadProfileByte(&exif,&length) != 0x45)
1865 if (ReadProfileByte(&exif,&length) != 0x78)
1867 if (ReadProfileByte(&exif,&length) != 0x69)
1869 if (ReadProfileByte(&exif,&length) != 0x66)
1871 if (ReadProfileByte(&exif,&length) != 0x00)
1873 if (ReadProfileByte(&exif,&length) != 0x00)
1878 return(MagickFalse);
1879 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
1887 return(MagickFalse);
1888 if (ReadProfileShort(endian,exif+2) != 0x002a)
1889 return(MagickFalse);
1891 This the offset to the first IFD.
1893 offset=(ssize_t) ReadProfileLong(endian,exif+4);
1894 if ((size_t) offset >= length)
1895 return(MagickFalse);
1896 directory=exif+offset;
1904 directory=directory_stack[level].directory;
1905 entry=directory_stack[level].entry;
1908 Determine how many entries there are in the current IFD.
1910 number_entries=ReadProfileShort(endian,directory);
1911 for ( ; entry < number_entries; entry++)
1918 register unsigned char
1925 q=(unsigned char *) (directory+2+(12*entry));
1926 tag_value=(ssize_t) ReadProfileShort(endian,q);
1927 format=(ssize_t) ReadProfileShort(endian,q+2);
1928 if ((format-1) >= EXIF_NUM_FORMATS)
1930 components=(ssize_t) ReadProfileLong(endian,q+4);
1931 number_bytes=(size_t) components*format_bytes[format];
1932 if (number_bytes <= 4)
1940 The directory entry contains an offset.
1942 offset=(ssize_t) ReadProfileLong(endian,q+8);
1943 if ((size_t) (offset+number_bytes) > length)
1945 p=(unsigned char *) (exif+offset);
1951 (void) WriteProfileLong(endian,(size_t)
1952 (image->x_resolution+0.5),p);
1953 (void) WriteProfileLong(endian,1UL,p+4);
1958 (void) WriteProfileLong(endian,(size_t)
1959 (image->y_resolution+0.5),p);
1960 (void) WriteProfileLong(endian,1UL,p+4);
1965 (void) WriteProfileShort(endian,(unsigned short)
1966 image->orientation,p);
1971 (void) WriteProfileShort(endian,(unsigned short)
1972 (image->units+1),p);
1978 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
1983 offset=(size_t) ReadProfileLong(endian,p);
1984 if ((offset < length) && (level < (MaxDirectoryStack-2)))
1986 directory_stack[level].directory=directory;
1988 directory_stack[level].entry=entry;
1990 directory_stack[level].directory=exif+offset;
1991 directory_stack[level].entry=0;
1993 if ((directory+2+(12*number_entries)) > (exif+length))
1995 offset=(size_t) ReadProfileLong(endian,directory+2+(12*
1997 if ((offset != 0) && (offset < length) &&
1998 (level < (MaxDirectoryStack-2)))
2000 directory_stack[level].directory=exif+offset;
2001 directory_stack[level].entry=0;
2008 } while (level > 0);