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++)
1231 register IndexPacket
1237 register PixelPacket
1240 register unsigned short
1243 if (status == MagickFalse)
1245 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1247 if (q == (PixelPacket *) NULL)
1252 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1253 id=GetOpenMPThreadId();
1254 p=source_pixels[id];
1255 for (x=0; x < (ssize_t) image->columns; x++)
1257 *p++=ScaleQuantumToShort(q->red);
1258 if (source_channels > 1)
1260 *p++=ScaleQuantumToShort(q->green);
1261 *p++=ScaleQuantumToShort(q->blue);
1263 if (source_channels > 3)
1264 *p++=ScaleQuantumToShort(indexes[x]);
1267 cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
1268 (unsigned int) image->columns);
1269 p=target_pixels[id];
1271 for (x=0; x < (ssize_t) image->columns; x++)
1273 q->red=ScaleShortToQuantum(*p);
1277 if (target_channels > 1)
1279 q->green=ScaleShortToQuantum(*p);
1281 q->blue=ScaleShortToQuantum(*p);
1284 if (target_channels > 3)
1286 indexes[x]=ScaleShortToQuantum(*p);
1291 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1292 if (sync == MagickFalse)
1294 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1299 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1300 #pragma omp critical (MagickCore_ProfileImage)
1302 proceed=SetImageProgress(image,ProfileImageTag,progress++,
1304 if (proceed == MagickFalse)
1308 image_view=DestroyCacheView(image_view);
1309 (void) SetImageColorspace(image,target_colorspace);
1314 image->type=image->matte == MagickFalse ? TrueColorType :
1318 case cmsSigCmykData:
1320 image->type=image->matte == MagickFalse ? ColorSeparationType :
1321 ColorSeparationMatteType;
1324 case cmsSigGrayData:
1326 image->type=image->matte == MagickFalse ? GrayscaleType :
1333 target_pixels=DestroyPixelThreadSet(target_pixels);
1334 source_pixels=DestroyPixelThreadSet(source_pixels);
1335 transform=DestroyTransformThreadSet(transform);
1336 if (cmsGetDeviceClass(source_profile) != cmsSigLinkClass)
1337 status=SetImageProfile(image,name,profile);
1338 if (target_profile != (cmsHPROFILE) NULL)
1339 (void) cmsCloseProfile(target_profile);
1341 (void) cmsCloseProfile(source_profile);
1345 profile=DestroyStringInfo(profile);
1350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1354 % R e m o v e I m a g e P r o f i l e %
1358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1360 % RemoveImageProfile() removes a named profile from the image and returns its
1363 % The format of the RemoveImageProfile method is:
1365 % void *RemoveImageProfile(Image *image,const char *name)
1367 % A description of each parameter follows:
1369 % o image: the image.
1371 % o name: the profile name.
1374 MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
1379 assert(image != (Image *) NULL);
1380 assert(image->signature == MagickSignature);
1381 if (image->debug != MagickFalse)
1382 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1383 if (image->profiles == (SplayTreeInfo *) NULL)
1384 return((StringInfo *) NULL);
1385 if (LocaleCompare(name,"icc") == 0)
1388 Continue to support deprecated color profile for now.
1390 image->color_profile.length=0;
1391 image->color_profile.info=(unsigned char *) NULL;
1393 if (LocaleCompare(name,"iptc") == 0)
1396 Continue to support deprecated IPTC profile for now.
1398 image->iptc_profile.length=0;
1399 image->iptc_profile.info=(unsigned char *) NULL;
1401 profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
1402 image->profiles,name);
1407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1411 % R e s e t P r o f i l e I t e r a t o r %
1415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417 % ResetImageProfileIterator() resets the image profile iterator. Use it in
1418 % conjunction with GetNextImageProfile() to iterate over all the profiles
1419 % associated with an image.
1421 % The format of the ResetImageProfileIterator method is:
1423 % ResetImageProfileIterator(Image *image)
1425 % A description of each parameter follows:
1427 % o image: the image.
1430 MagickExport void ResetImageProfileIterator(const Image *image)
1432 assert(image != (Image *) NULL);
1433 assert(image->signature == MagickSignature);
1434 if (image->debug != MagickFalse)
1435 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1436 if (image->profiles == (SplayTreeInfo *) NULL)
1438 ResetSplayTreeIterator((SplayTreeInfo *) image->profiles);
1442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1446 % S e t I m a g e P r o f i l e %
1450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1452 % SetImageProfile() adds a named profile to the image. If a profile with the
1453 % same name already exists, it is replaced. This method differs from the
1454 % ProfileImage() method in that it does not apply CMS color profiles.
1456 % The format of the SetImageProfile method is:
1458 % MagickBooleanType SetImageProfile(Image *image,const char *name,
1459 % const StringInfo *profile)
1461 % A description of each parameter follows:
1463 % o image: the image.
1465 % o name: the profile name, for example icc, exif, and 8bim (8bim is the
1466 % Photoshop wrapper for iptc profiles).
1468 % o profile: A StringInfo structure that contains the named profile.
1472 static void *DestroyProfile(void *profile)
1474 return((void *) DestroyStringInfo((StringInfo *) profile));
1477 static inline const unsigned char *ReadResourceByte(const unsigned char *p,
1478 unsigned char *quantum)
1484 static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
1485 const ssize_t count,unsigned char *quantum)
1490 for (i=0; i < count; i++)
1495 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
1498 *quantum=(size_t) (*p++ << 24);
1499 *quantum|=(size_t) (*p++ << 16);
1500 *quantum|=(size_t) (*p++ << 8);
1501 *quantum|=(size_t) (*p++ << 0);
1505 static inline const unsigned char *ReadResourceShort(const unsigned char *p,
1506 unsigned short *quantum)
1508 *quantum=(unsigned short) (*p++ << 8);
1509 *quantum|=(unsigned short) (*p++ << 0);
1513 static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
1514 const StringInfo *resource_block)
1519 register const unsigned char
1537 datum=GetStringInfoDatum(resource_block);
1538 length=GetStringInfoLength(resource_block);
1539 for (p=datum; p < (datum+length-16); )
1541 if (LocaleNCompare((char *) p,"8BIM",4) != 0)
1544 p=ReadResourceShort(p,&id);
1545 p=ReadResourceByte(p,&length_byte);
1547 if (((length_byte+1) & 0x01) != 0)
1549 if (p > (datum+length-4))
1551 p=ReadResourceLong(p,&count);
1552 if ((p > (datum+length-count)) || (count > length))
1564 p=ReadResourceShort(p,&resolution)+6;
1565 image->x_resolution=(double) resolution;
1566 p=ReadResourceShort(p,&resolution)+6;
1567 image->y_resolution=(double) resolution;
1575 profile=AcquireStringInfo(count);
1576 SetStringInfoDatum(profile,p);
1577 (void) SetImageProfile(image,"iptc",profile);
1578 profile=DestroyStringInfo(profile);
1595 profile=AcquireStringInfo(count);
1596 SetStringInfoDatum(profile,p);
1597 (void) SetImageProfile(image,"icc",profile);
1598 profile=DestroyStringInfo(profile);
1607 profile=AcquireStringInfo(count);
1608 SetStringInfoDatum(profile,p);
1609 (void) SetImageProfile(image,"exif",profile);
1610 profile=DestroyStringInfo(profile);
1619 profile=AcquireStringInfo(count);
1620 SetStringInfoDatum(profile,p);
1621 (void) SetImageProfile(image,"xmp",profile);
1622 profile=DestroyStringInfo(profile);
1632 if ((count & 0x01) != 0)
1638 MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
1639 const StringInfo *profile)
1643 property[MaxTextExtent];
1648 assert(image != (Image *) NULL);
1649 assert(image->signature == MagickSignature);
1650 if (image->debug != MagickFalse)
1651 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1652 if (image->profiles == (SplayTreeInfo *) NULL)
1653 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1655 (void) CopyMagickString(key,name,MaxTextExtent);
1656 status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
1657 ConstantString(key),CloneStringInfo(profile));
1658 if ((status != MagickFalse) &&
1659 ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0)))
1665 Continue to support deprecated color profile member.
1667 icc_profile=GetImageProfile(image,name);
1668 if (icc_profile != (const StringInfo *) NULL)
1670 image->color_profile.length=GetStringInfoLength(icc_profile);
1671 image->color_profile.info=GetStringInfoDatum(icc_profile);
1674 if ((status != MagickFalse) &&
1675 ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
1681 Continue to support deprecated IPTC profile member.
1683 iptc_profile=GetImageProfile(image,name);
1684 if (iptc_profile != (const StringInfo *) NULL)
1686 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1687 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1689 (void) GetProfilesFromResourceBlock(image,profile);
1692 Inject profile into image properties.
1694 (void) FormatMagickString(property,MaxTextExtent,"%s:sans",name);
1695 (void) GetImageProperty(image,property);
1700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1704 % S y n c I m a g e P r o f i l e s %
1708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1710 % SyncImageProfiles() synchronizes image properties with the image profiles.
1711 % Currently we only support updating the EXIF resolution and orientation.
1713 % The format of the SyncImageProfiles method is:
1715 % MagickBooleanType SyncImageProfiles(Image *image)
1717 % A description of each parameter follows:
1719 % o image: the image.
1723 static inline int ReadProfileByte(unsigned char **p,size_t *length)
1735 static inline unsigned short ReadProfileShort(const EndianType endian,
1736 unsigned char *buffer)
1741 if (endian == MSBEndian)
1743 value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
1744 ((unsigned char *) buffer)[1]);
1745 return((unsigned short) (value & 0xffff));
1747 value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
1748 return((unsigned short) (value & 0xffff));
1751 static inline size_t ReadProfileLong(const EndianType endian,
1752 unsigned char *buffer)
1757 if (endian == MSBEndian)
1759 value=(size_t) ((buffer[0] << 24) | (buffer[1] << 16) |
1760 (buffer[2] << 8) | buffer[3]);
1761 return((size_t) (value & 0xffffffff));
1763 value=(size_t) ((buffer[3] << 24) | (buffer[2] << 16) |
1764 (buffer[1] << 8 ) | (buffer[0]));
1765 return((size_t) (value & 0xffffffff));
1768 static inline void WriteProfileLong(const EndianType endian,
1769 const size_t value,unsigned char *p)
1774 if (endian == MSBEndian)
1776 buffer[0]=(unsigned char) (value >> 24);
1777 buffer[1]=(unsigned char) (value >> 16);
1778 buffer[2]=(unsigned char) (value >> 8);
1779 buffer[3]=(unsigned char) value;
1780 (void) CopyMagickMemory(p,buffer,4);
1783 buffer[0]=(unsigned char) value;
1784 buffer[1]=(unsigned char) (value >> 8);
1785 buffer[2]=(unsigned char) (value >> 16);
1786 buffer[3]=(unsigned char) (value >> 24);
1787 (void) CopyMagickMemory(p,buffer,4);
1790 static void WriteProfileShort(const EndianType endian,
1791 const unsigned short value,unsigned char *p)
1796 if (endian == MSBEndian)
1798 buffer[0]=(unsigned char) (value >> 8);
1799 buffer[1]=(unsigned char) value;
1800 (void) CopyMagickMemory(p,buffer,2);
1803 buffer[0]=(unsigned char) value;
1804 buffer[1]=(unsigned char) (value >> 8);
1805 (void) CopyMagickMemory(p,buffer,2);
1808 MagickExport MagickBooleanType SyncImageProfiles(Image *image)
1810 #define MaxDirectoryStack 16
1811 #define EXIF_DELIMITER "\n"
1812 #define EXIF_NUM_FORMATS 12
1813 #define TAG_EXIF_OFFSET 0x8769
1814 #define TAG_INTEROP_OFFSET 0xa005
1816 typedef struct _DirectoryInfo
1826 directory_stack[MaxDirectoryStack];
1842 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
1856 Set EXIF resolution tag.
1858 profile=(StringInfo *) GetImageProfile(image,"EXIF");
1859 if (profile == (StringInfo *) NULL)
1861 length=GetStringInfoLength(profile);
1862 exif=GetStringInfoDatum(profile);
1865 if (ReadProfileByte(&exif,&length) != 0x45)
1867 if (ReadProfileByte(&exif,&length) != 0x78)
1869 if (ReadProfileByte(&exif,&length) != 0x69)
1871 if (ReadProfileByte(&exif,&length) != 0x66)
1873 if (ReadProfileByte(&exif,&length) != 0x00)
1875 if (ReadProfileByte(&exif,&length) != 0x00)
1880 return(MagickFalse);
1881 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
1889 return(MagickFalse);
1890 if (ReadProfileShort(endian,exif+2) != 0x002a)
1891 return(MagickFalse);
1893 This the offset to the first IFD.
1895 offset=(ssize_t) ReadProfileLong(endian,exif+4);
1896 if ((size_t) offset >= length)
1897 return(MagickFalse);
1898 directory=exif+offset;
1906 directory=directory_stack[level].directory;
1907 entry=directory_stack[level].entry;
1910 Determine how many entries there are in the current IFD.
1912 number_entries=ReadProfileShort(endian,directory);
1913 for ( ; entry < number_entries; entry++)
1920 register unsigned char
1927 q=(unsigned char *) (directory+2+(12*entry));
1928 tag_value=(ssize_t) ReadProfileShort(endian,q);
1929 format=(ssize_t) ReadProfileShort(endian,q+2);
1930 if ((format-1) >= EXIF_NUM_FORMATS)
1932 components=(ssize_t) ReadProfileLong(endian,q+4);
1933 number_bytes=(size_t) components*format_bytes[format];
1934 if (number_bytes <= 4)
1942 The directory entry contains an offset.
1944 offset=(ssize_t) ReadProfileLong(endian,q+8);
1945 if ((size_t) (offset+number_bytes) > length)
1947 p=(unsigned char *) (exif+offset);
1953 (void) WriteProfileLong(endian,(size_t)
1954 (image->x_resolution+0.5),p);
1955 (void) WriteProfileLong(endian,1UL,p+4);
1960 (void) WriteProfileLong(endian,(size_t)
1961 (image->y_resolution+0.5),p);
1962 (void) WriteProfileLong(endian,1UL,p+4);
1967 (void) WriteProfileShort(endian,(unsigned short)
1968 image->orientation,p);
1973 (void) WriteProfileShort(endian,(unsigned short)
1974 (image->units+1),p);
1980 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
1985 offset=(size_t) ReadProfileLong(endian,p);
1986 if ((offset < length) && (level < (MaxDirectoryStack-2)))
1988 directory_stack[level].directory=directory;
1990 directory_stack[level].entry=entry;
1992 directory_stack[level].directory=exif+offset;
1993 directory_stack[level].entry=0;
1995 if ((directory+2+(12*number_entries)) > (exif+length))
1997 offset=(size_t) ReadProfileLong(endian,directory+2+(12*
1999 if ((offset != 0) && (offset < length) &&
2000 (level < (MaxDirectoryStack-2)))
2002 directory_stack[level].directory=exif+offset;
2003 directory_stack[level].entry=0;
2010 } while (level > 0);