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-2011 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 **) RelinquishMagickMemory(pixels);
356 static unsigned short **AcquirePixelThreadSet(const size_t columns,
357 const size_t channels)
368 number_threads=GetOpenMPMaximumThreads();
369 pixels=(unsigned short **) AcquireQuantumMemory(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 *) RelinquishMagickMemory(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 *) AcquireQuantumMemory(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
1008 **restrict source_pixels,
1009 **restrict target_pixels;
1011 exception=(&image->exception);
1012 target_profile=(cmsHPROFILE) NULL;
1013 if (icc_profile != (StringInfo *) NULL)
1015 target_profile=source_profile;
1016 source_profile=cmsOpenProfileFromMemTHR(image,
1017 GetStringInfoDatum(icc_profile),(cmsUInt32Number)
1018 GetStringInfoLength(icc_profile));
1019 if (source_profile == (cmsHPROFILE) NULL)
1020 ThrowProfileException(ResourceLimitError,
1021 "ColorspaceColorProfileMismatch",name);
1023 switch (cmsGetColorSpace(source_profile))
1025 case cmsSigCmykData:
1027 source_colorspace=CMYKColorspace;
1028 source_type=(cmsUInt32Number) TYPE_CMYK_16;
1032 case cmsSigGrayData:
1034 source_colorspace=GRAYColorspace;
1035 source_type=(cmsUInt32Number) TYPE_GRAY_16;
1041 source_colorspace=LabColorspace;
1042 source_type=(cmsUInt32Number) TYPE_Lab_16;
1048 source_colorspace=YUVColorspace;
1049 source_type=(cmsUInt32Number) TYPE_YUV_16;
1055 source_colorspace=RGBColorspace;
1056 source_type=(cmsUInt32Number) TYPE_RGB_16;
1062 source_colorspace=XYZColorspace;
1063 source_type=(cmsUInt32Number) TYPE_XYZ_16;
1067 case cmsSigYCbCrData:
1069 source_colorspace=YCbCrColorspace;
1070 source_type=(cmsUInt32Number) TYPE_YCbCr_16;
1076 source_colorspace=UndefinedColorspace;
1077 source_type=(cmsUInt32Number) TYPE_RGB_16;
1082 signature=cmsGetPCS(source_profile);
1083 if (target_profile != (cmsHPROFILE) NULL)
1084 signature=cmsGetColorSpace(target_profile);
1087 case cmsSigCmykData:
1089 target_colorspace=CMYKColorspace;
1090 target_type=(cmsUInt32Number) TYPE_CMYK_16;
1096 target_colorspace=LabColorspace;
1097 target_type=(cmsUInt32Number) TYPE_Lab_16;
1101 case cmsSigGrayData:
1103 target_colorspace=GRAYColorspace;
1104 target_type=(cmsUInt32Number) TYPE_GRAY_16;
1110 target_colorspace=YUVColorspace;
1111 target_type=(cmsUInt32Number) TYPE_YUV_16;
1117 target_colorspace=RGBColorspace;
1118 target_type=(cmsUInt32Number) TYPE_RGB_16;
1124 target_colorspace=XYZColorspace;
1125 target_type=(cmsUInt32Number) TYPE_XYZ_16;
1129 case cmsSigYCbCrData:
1131 target_colorspace=YCbCrColorspace;
1132 target_type=(cmsUInt32Number) TYPE_YCbCr_16;
1138 target_colorspace=UndefinedColorspace;
1139 target_type=(cmsUInt32Number) TYPE_RGB_16;
1144 if ((source_colorspace == UndefinedColorspace) ||
1145 (target_colorspace == UndefinedColorspace))
1146 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1148 if ((source_colorspace == GRAYColorspace) &&
1149 (IsGrayImage(image,exception) == MagickFalse))
1150 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1152 if ((source_colorspace == CMYKColorspace) &&
1153 (image->colorspace != CMYKColorspace))
1154 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1156 if ((source_colorspace == XYZColorspace) &&
1157 (image->colorspace != XYZColorspace))
1158 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1160 if ((source_colorspace == YCbCrColorspace) &&
1161 (image->colorspace != YCbCrColorspace))
1162 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1164 if ((source_colorspace != CMYKColorspace) &&
1165 (source_colorspace != GRAYColorspace) &&
1166 (source_colorspace != LabColorspace) &&
1167 (source_colorspace != XYZColorspace) &&
1168 (source_colorspace != YCbCrColorspace) &&
1169 (image->colorspace != RGBColorspace))
1170 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1172 switch (image->rendering_intent)
1174 case AbsoluteIntent: intent=INTENT_ABSOLUTE_COLORIMETRIC; break;
1175 case PerceptualIntent: intent=INTENT_PERCEPTUAL; break;
1176 case RelativeIntent: intent=INTENT_RELATIVE_COLORIMETRIC; break;
1177 case SaturationIntent: intent=INTENT_SATURATION; break;
1178 default: intent=INTENT_PERCEPTUAL; break;
1180 flags=cmsFLAGS_HIGHRESPRECALC;
1181 #if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1182 if (image->black_point_compensation != MagickFalse)
1183 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1185 transform=AcquireTransformThreadSet(image,source_profile,
1186 source_type,target_profile,target_type,intent,flags);
1187 if (transform == (cmsHTRANSFORM *) NULL)
1188 ThrowProfileException(ImageError,"UnableToCreateColorTransform",
1191 Transform image as dictated by the source & target image profiles.
1193 source_pixels=AcquirePixelThreadSet(image->columns,source_channels);
1194 target_pixels=AcquirePixelThreadSet(image->columns,target_channels);
1195 if ((source_pixels == (unsigned short **) NULL) ||
1196 (target_pixels == (unsigned short **) NULL))
1198 transform=DestroyTransformThreadSet(transform);
1199 ThrowProfileException(ResourceLimitError,
1200 "MemoryAllocationFailed",image->filename);
1202 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1204 target_pixels=DestroyPixelThreadSet(target_pixels);
1205 source_pixels=DestroyPixelThreadSet(source_pixels);
1206 transform=DestroyTransformThreadSet(transform);
1207 if (source_profile != (cmsHPROFILE) NULL)
1208 (void) cmsCloseProfile(source_profile);
1209 if (target_profile != (cmsHPROFILE) NULL)
1210 (void) cmsCloseProfile(target_profile);
1211 return(MagickFalse);
1213 if (target_colorspace == CMYKColorspace)
1214 (void) SetImageColorspace(image,target_colorspace);
1217 image_view=AcquireCacheView(image);
1218 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1219 #pragma omp parallel for schedule(dynamic,4) shared(status)
1221 for (y=0; y < (ssize_t) image->rows; y++)
1224 id = GetOpenMPThreadId();
1229 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 p=source_pixels[id];
1252 for (x=0; x < (ssize_t) image->columns; x++)
1254 *p++=ScaleQuantumToShort(q->red);
1255 if (source_channels > 1)
1257 *p++=ScaleQuantumToShort(q->green);
1258 *p++=ScaleQuantumToShort(q->blue);
1260 if (source_channels > 3)
1261 *p++=ScaleQuantumToShort(indexes[x]);
1264 cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
1265 (unsigned int) image->columns);
1266 p=target_pixels[id];
1268 for (x=0; x < (ssize_t) image->columns; x++)
1270 q->red=ScaleShortToQuantum(*p);
1274 if (target_channels > 1)
1276 q->green=ScaleShortToQuantum(*p);
1278 q->blue=ScaleShortToQuantum(*p);
1281 if (target_channels > 3)
1283 indexes[x]=ScaleShortToQuantum(*p);
1288 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1289 if (sync == MagickFalse)
1291 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1296 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1297 #pragma omp critical (MagickCore_ProfileImage)
1299 proceed=SetImageProgress(image,ProfileImageTag,progress++,
1301 if (proceed == MagickFalse)
1305 image_view=DestroyCacheView(image_view);
1306 (void) SetImageColorspace(image,target_colorspace);
1311 image->type=image->matte == MagickFalse ? TrueColorType :
1315 case cmsSigCmykData:
1317 image->type=image->matte == MagickFalse ? ColorSeparationType :
1318 ColorSeparationMatteType;
1321 case cmsSigGrayData:
1323 image->type=image->matte == MagickFalse ? GrayscaleType :
1330 target_pixels=DestroyPixelThreadSet(target_pixels);
1331 source_pixels=DestroyPixelThreadSet(source_pixels);
1332 transform=DestroyTransformThreadSet(transform);
1333 if (cmsGetDeviceClass(source_profile) != cmsSigLinkClass)
1334 status=SetImageProfile(image,name,profile);
1335 if (target_profile != (cmsHPROFILE) NULL)
1336 (void) cmsCloseProfile(target_profile);
1338 (void) cmsCloseProfile(source_profile);
1342 profile=DestroyStringInfo(profile);
1347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1351 % R e m o v e I m a g e P r o f i l e %
1355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357 % RemoveImageProfile() removes a named profile from the image and returns its
1360 % The format of the RemoveImageProfile method is:
1362 % void *RemoveImageProfile(Image *image,const char *name)
1364 % A description of each parameter follows:
1366 % o image: the image.
1368 % o name: the profile name.
1371 MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
1376 assert(image != (Image *) NULL);
1377 assert(image->signature == MagickSignature);
1378 if (image->debug != MagickFalse)
1379 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1380 if (image->profiles == (SplayTreeInfo *) NULL)
1381 return((StringInfo *) NULL);
1382 if (LocaleCompare(name,"icc") == 0)
1385 Continue to support deprecated color profile for now.
1387 image->color_profile.length=0;
1388 image->color_profile.info=(unsigned char *) NULL;
1390 if (LocaleCompare(name,"iptc") == 0)
1393 Continue to support deprecated IPTC profile for now.
1395 image->iptc_profile.length=0;
1396 image->iptc_profile.info=(unsigned char *) NULL;
1398 profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
1399 image->profiles,name);
1404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1408 % R e s e t P r o f i l e I t e r a t o r %
1412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1414 % ResetImageProfileIterator() resets the image profile iterator. Use it in
1415 % conjunction with GetNextImageProfile() to iterate over all the profiles
1416 % associated with an image.
1418 % The format of the ResetImageProfileIterator method is:
1420 % ResetImageProfileIterator(Image *image)
1422 % A description of each parameter follows:
1424 % o image: the image.
1427 MagickExport void ResetImageProfileIterator(const Image *image)
1429 assert(image != (Image *) NULL);
1430 assert(image->signature == MagickSignature);
1431 if (image->debug != MagickFalse)
1432 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1433 if (image->profiles == (SplayTreeInfo *) NULL)
1435 ResetSplayTreeIterator((SplayTreeInfo *) image->profiles);
1439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1443 % S e t I m a g e P r o f i l e %
1447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1449 % SetImageProfile() adds a named profile to the image. If a profile with the
1450 % same name already exists, it is replaced. This method differs from the
1451 % ProfileImage() method in that it does not apply CMS color profiles.
1453 % The format of the SetImageProfile method is:
1455 % MagickBooleanType SetImageProfile(Image *image,const char *name,
1456 % const StringInfo *profile)
1458 % A description of each parameter follows:
1460 % o image: the image.
1462 % o name: the profile name, for example icc, exif, and 8bim (8bim is the
1463 % Photoshop wrapper for iptc profiles).
1465 % o profile: A StringInfo structure that contains the named profile.
1469 static void *DestroyProfile(void *profile)
1471 return((void *) DestroyStringInfo((StringInfo *) profile));
1474 static inline const unsigned char *ReadResourceByte(const unsigned char *p,
1475 unsigned char *quantum)
1481 static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
1482 const ssize_t count,unsigned char *quantum)
1487 for (i=0; i < count; i++)
1492 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
1495 *quantum=(size_t) (*p++ << 24);
1496 *quantum|=(size_t) (*p++ << 16);
1497 *quantum|=(size_t) (*p++ << 8);
1498 *quantum|=(size_t) (*p++ << 0);
1502 static inline const unsigned char *ReadResourceShort(const unsigned char *p,
1503 unsigned short *quantum)
1505 *quantum=(unsigned short) (*p++ << 8);
1506 *quantum|=(unsigned short) (*p++ << 0);
1510 static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
1511 const StringInfo *resource_block)
1516 register const unsigned char
1534 datum=GetStringInfoDatum(resource_block);
1535 length=GetStringInfoLength(resource_block);
1536 for (p=datum; p < (datum+length-16); )
1538 if (LocaleNCompare((char *) p,"8BIM",4) != 0)
1541 p=ReadResourceShort(p,&id);
1542 p=ReadResourceByte(p,&length_byte);
1544 if (((length_byte+1) & 0x01) != 0)
1546 if (p > (datum+length-4))
1548 p=ReadResourceLong(p,&count);
1549 if ((p > (datum+length-count)) || (count > length))
1561 p=ReadResourceShort(p,&resolution)+6;
1562 image->x_resolution=(double) resolution;
1563 p=ReadResourceShort(p,&resolution)+6;
1564 image->y_resolution=(double) resolution;
1572 profile=AcquireStringInfo(count);
1573 SetStringInfoDatum(profile,p);
1574 (void) SetImageProfile(image,"iptc",profile);
1575 profile=DestroyStringInfo(profile);
1592 profile=AcquireStringInfo(count);
1593 SetStringInfoDatum(profile,p);
1594 (void) SetImageProfile(image,"icc",profile);
1595 profile=DestroyStringInfo(profile);
1604 profile=AcquireStringInfo(count);
1605 SetStringInfoDatum(profile,p);
1606 (void) SetImageProfile(image,"exif",profile);
1607 profile=DestroyStringInfo(profile);
1616 profile=AcquireStringInfo(count);
1617 SetStringInfoDatum(profile,p);
1618 (void) SetImageProfile(image,"xmp",profile);
1619 profile=DestroyStringInfo(profile);
1629 if ((count & 0x01) != 0)
1635 MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
1636 const StringInfo *profile)
1640 property[MaxTextExtent];
1645 assert(image != (Image *) NULL);
1646 assert(image->signature == MagickSignature);
1647 if (image->debug != MagickFalse)
1648 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1649 if (image->profiles == (SplayTreeInfo *) NULL)
1650 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1652 (void) CopyMagickString(key,name,MaxTextExtent);
1653 status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
1654 ConstantString(key),CloneStringInfo(profile));
1655 if ((status != MagickFalse) &&
1656 ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0)))
1662 Continue to support deprecated color profile member.
1664 icc_profile=GetImageProfile(image,name);
1665 if (icc_profile != (const StringInfo *) NULL)
1667 image->color_profile.length=GetStringInfoLength(icc_profile);
1668 image->color_profile.info=GetStringInfoDatum(icc_profile);
1671 if ((status != MagickFalse) &&
1672 ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
1678 Continue to support deprecated IPTC profile member.
1680 iptc_profile=GetImageProfile(image,name);
1681 if (iptc_profile != (const StringInfo *) NULL)
1683 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1684 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1686 (void) GetProfilesFromResourceBlock(image,profile);
1689 Inject profile into image properties.
1691 (void) FormatMagickString(property,MaxTextExtent,"%s:sans",name);
1692 (void) GetImageProperty(image,property);
1697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1701 % S y n c I m a g e P r o f i l e s %
1705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1707 % SyncImageProfiles() synchronizes image properties with the image profiles.
1708 % Currently we only support updating the EXIF resolution and orientation.
1710 % The format of the SyncImageProfiles method is:
1712 % MagickBooleanType SyncImageProfiles(Image *image)
1714 % A description of each parameter follows:
1716 % o image: the image.
1720 static inline int ReadProfileByte(unsigned char **p,size_t *length)
1732 static inline unsigned short ReadProfileShort(const EndianType endian,
1733 unsigned char *buffer)
1738 if (endian == MSBEndian)
1740 value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
1741 ((unsigned char *) buffer)[1]);
1742 return((unsigned short) (value & 0xffff));
1744 value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
1745 return((unsigned short) (value & 0xffff));
1748 static inline size_t ReadProfileLong(const EndianType endian,
1749 unsigned char *buffer)
1754 if (endian == MSBEndian)
1756 value=(size_t) ((buffer[0] << 24) | (buffer[1] << 16) |
1757 (buffer[2] << 8) | buffer[3]);
1758 return((size_t) (value & 0xffffffff));
1760 value=(size_t) ((buffer[3] << 24) | (buffer[2] << 16) |
1761 (buffer[1] << 8 ) | (buffer[0]));
1762 return((size_t) (value & 0xffffffff));
1765 static inline void WriteProfileLong(const EndianType endian,
1766 const size_t value,unsigned char *p)
1771 if (endian == MSBEndian)
1773 buffer[0]=(unsigned char) (value >> 24);
1774 buffer[1]=(unsigned char) (value >> 16);
1775 buffer[2]=(unsigned char) (value >> 8);
1776 buffer[3]=(unsigned char) value;
1777 (void) CopyMagickMemory(p,buffer,4);
1780 buffer[0]=(unsigned char) value;
1781 buffer[1]=(unsigned char) (value >> 8);
1782 buffer[2]=(unsigned char) (value >> 16);
1783 buffer[3]=(unsigned char) (value >> 24);
1784 (void) CopyMagickMemory(p,buffer,4);
1787 static void WriteProfileShort(const EndianType endian,
1788 const unsigned short value,unsigned char *p)
1793 if (endian == MSBEndian)
1795 buffer[0]=(unsigned char) (value >> 8);
1796 buffer[1]=(unsigned char) value;
1797 (void) CopyMagickMemory(p,buffer,2);
1800 buffer[0]=(unsigned char) value;
1801 buffer[1]=(unsigned char) (value >> 8);
1802 (void) CopyMagickMemory(p,buffer,2);
1805 MagickExport MagickBooleanType SyncImageProfiles(Image *image)
1807 #define MaxDirectoryStack 16
1808 #define EXIF_DELIMITER "\n"
1809 #define EXIF_NUM_FORMATS 12
1810 #define TAG_EXIF_OFFSET 0x8769
1811 #define TAG_INTEROP_OFFSET 0xa005
1813 typedef struct _DirectoryInfo
1823 directory_stack[MaxDirectoryStack];
1841 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
1851 Set EXIF resolution tag.
1853 profile=(StringInfo *) GetImageProfile(image,"EXIF");
1854 if (profile == (StringInfo *) NULL)
1856 length=GetStringInfoLength(profile);
1857 exif=GetStringInfoDatum(profile);
1860 if (ReadProfileByte(&exif,&length) != 0x45)
1862 if (ReadProfileByte(&exif,&length) != 0x78)
1864 if (ReadProfileByte(&exif,&length) != 0x69)
1866 if (ReadProfileByte(&exif,&length) != 0x66)
1868 if (ReadProfileByte(&exif,&length) != 0x00)
1870 if (ReadProfileByte(&exif,&length) != 0x00)
1875 return(MagickFalse);
1876 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
1884 return(MagickFalse);
1885 if (ReadProfileShort(endian,exif+2) != 0x002a)
1886 return(MagickFalse);
1888 This the offset to the first IFD.
1890 offset=(int) ReadProfileLong(endian,exif+4);
1891 if ((size_t) offset >= length)
1892 return(MagickFalse);
1893 directory=exif+offset;
1901 directory=directory_stack[level].directory;
1902 entry=directory_stack[level].entry;
1905 Determine how many entries there are in the current IFD.
1907 number_entries=ReadProfileShort(endian,directory);
1908 for ( ; entry < number_entries; entry++)
1913 register unsigned char
1924 q=(unsigned char *) (directory+2+(12*entry));
1925 tag_value=(ssize_t) ReadProfileShort(endian,q);
1926 format=(ssize_t) ReadProfileShort(endian,q+2);
1927 if ((format-1) >= EXIF_NUM_FORMATS)
1929 components=(int) ReadProfileLong(endian,q+4);
1930 number_bytes=(size_t) components*format_bytes[format];
1931 if (number_bytes <= 4)
1939 The directory entry contains an offset.
1941 offset=(int) ReadProfileLong(endian,q+8);
1942 if ((size_t) (offset+number_bytes) > length)
1944 p=(unsigned char *) (exif+offset);
1950 (void) WriteProfileLong(endian,(size_t)
1951 (image->x_resolution+0.5),p);
1952 (void) WriteProfileLong(endian,1UL,p+4);
1957 (void) WriteProfileLong(endian,(size_t)
1958 (image->y_resolution+0.5),p);
1959 (void) WriteProfileLong(endian,1UL,p+4);
1964 (void) WriteProfileShort(endian,(unsigned short)
1965 image->orientation,p);
1970 (void) WriteProfileShort(endian,(unsigned short)
1971 (image->units+1),p);
1977 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
1982 offset=(size_t) ReadProfileLong(endian,p);
1983 if ((offset < length) && (level < (MaxDirectoryStack-2)))
1985 directory_stack[level].directory=directory;
1987 directory_stack[level].entry=entry;
1989 directory_stack[level].directory=exif+offset;
1990 directory_stack[level].entry=0;
1992 if ((directory+2+(12*number_entries)) > (exif+length))
1994 offset=(size_t) ReadProfileLong(endian,directory+2+(12*
1996 if ((offset != 0) && (offset < length) &&
1997 (level < (MaxDirectoryStack-2)))
1999 directory_stack[level].directory=exif+offset;
2000 directory_stack[level].entry=0;
2007 } while (level > 0);