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
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++)
1226 id = GetOpenMPThreadId();
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 p=source_pixels[id];
1254 for (x=0; x < (ssize_t) image->columns; x++)
1256 *p++=ScaleQuantumToShort(q->red);
1257 if (source_channels > 1)
1259 *p++=ScaleQuantumToShort(q->green);
1260 *p++=ScaleQuantumToShort(q->blue);
1262 if (source_channels > 3)
1263 *p++=ScaleQuantumToShort(indexes[x]);
1266 cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
1267 (unsigned int) image->columns);
1268 p=target_pixels[id];
1270 for (x=0; x < (ssize_t) image->columns; x++)
1272 q->red=ScaleShortToQuantum(*p);
1276 if (target_channels > 1)
1278 q->green=ScaleShortToQuantum(*p);
1280 q->blue=ScaleShortToQuantum(*p);
1283 if (target_channels > 3)
1285 indexes[x]=ScaleShortToQuantum(*p);
1290 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1291 if (sync == MagickFalse)
1293 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1298 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1299 #pragma omp critical (MagickCore_ProfileImage)
1301 proceed=SetImageProgress(image,ProfileImageTag,progress++,
1303 if (proceed == MagickFalse)
1307 image_view=DestroyCacheView(image_view);
1308 (void) SetImageColorspace(image,target_colorspace);
1313 image->type=image->matte == MagickFalse ? TrueColorType :
1317 case cmsSigCmykData:
1319 image->type=image->matte == MagickFalse ? ColorSeparationType :
1320 ColorSeparationMatteType;
1323 case cmsSigGrayData:
1325 image->type=image->matte == MagickFalse ? GrayscaleType :
1332 target_pixels=DestroyPixelThreadSet(target_pixels);
1333 source_pixels=DestroyPixelThreadSet(source_pixels);
1334 transform=DestroyTransformThreadSet(transform);
1335 if (cmsGetDeviceClass(source_profile) != cmsSigLinkClass)
1336 status=SetImageProfile(image,name,profile);
1337 if (target_profile != (cmsHPROFILE) NULL)
1338 (void) cmsCloseProfile(target_profile);
1340 (void) cmsCloseProfile(source_profile);
1344 profile=DestroyStringInfo(profile);
1349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1353 % R e m o v e I m a g e P r o f i l e %
1357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1359 % RemoveImageProfile() removes a named profile from the image and returns its
1362 % The format of the RemoveImageProfile method is:
1364 % void *RemoveImageProfile(Image *image,const char *name)
1366 % A description of each parameter follows:
1368 % o image: the image.
1370 % o name: the profile name.
1373 MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
1378 assert(image != (Image *) NULL);
1379 assert(image->signature == MagickSignature);
1380 if (image->debug != MagickFalse)
1381 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1382 if (image->profiles == (SplayTreeInfo *) NULL)
1383 return((StringInfo *) NULL);
1384 if (LocaleCompare(name,"icc") == 0)
1387 Continue to support deprecated color profile for now.
1389 image->color_profile.length=0;
1390 image->color_profile.info=(unsigned char *) NULL;
1392 if (LocaleCompare(name,"iptc") == 0)
1395 Continue to support deprecated IPTC profile for now.
1397 image->iptc_profile.length=0;
1398 image->iptc_profile.info=(unsigned char *) NULL;
1400 profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
1401 image->profiles,name);
1406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410 % R e s e t P r o f i l e I t e r a t o r %
1414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1416 % ResetImageProfileIterator() resets the image profile iterator. Use it in
1417 % conjunction with GetNextImageProfile() to iterate over all the profiles
1418 % associated with an image.
1420 % The format of the ResetImageProfileIterator method is:
1422 % ResetImageProfileIterator(Image *image)
1424 % A description of each parameter follows:
1426 % o image: the image.
1429 MagickExport void ResetImageProfileIterator(const Image *image)
1431 assert(image != (Image *) NULL);
1432 assert(image->signature == MagickSignature);
1433 if (image->debug != MagickFalse)
1434 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1435 if (image->profiles == (SplayTreeInfo *) NULL)
1437 ResetSplayTreeIterator((SplayTreeInfo *) image->profiles);
1441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1445 % S e t I m a g e P r o f i l e %
1449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1451 % SetImageProfile() adds a named profile to the image. If a profile with the
1452 % same name already exists, it is replaced. This method differs from the
1453 % ProfileImage() method in that it does not apply CMS color profiles.
1455 % The format of the SetImageProfile method is:
1457 % MagickBooleanType SetImageProfile(Image *image,const char *name,
1458 % const StringInfo *profile)
1460 % A description of each parameter follows:
1462 % o image: the image.
1464 % o name: the profile name, for example icc, exif, and 8bim (8bim is the
1465 % Photoshop wrapper for iptc profiles).
1467 % o profile: A StringInfo structure that contains the named profile.
1471 static void *DestroyProfile(void *profile)
1473 return((void *) DestroyStringInfo((StringInfo *) profile));
1476 static inline const unsigned char *ReadResourceByte(const unsigned char *p,
1477 unsigned char *quantum)
1483 static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
1484 const ssize_t count,unsigned char *quantum)
1489 for (i=0; i < count; i++)
1494 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
1497 *quantum=(size_t) (*p++ << 24);
1498 *quantum|=(size_t) (*p++ << 16);
1499 *quantum|=(size_t) (*p++ << 8);
1500 *quantum|=(size_t) (*p++ << 0);
1504 static inline const unsigned char *ReadResourceShort(const unsigned char *p,
1505 unsigned short *quantum)
1507 *quantum=(unsigned short) (*p++ << 8);
1508 *quantum|=(unsigned short) (*p++ << 0);
1512 static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
1513 const StringInfo *resource_block)
1518 register const unsigned char
1536 datum=GetStringInfoDatum(resource_block);
1537 length=GetStringInfoLength(resource_block);
1538 for (p=datum; p < (datum+length-16); )
1540 if (LocaleNCompare((char *) p,"8BIM",4) != 0)
1543 p=ReadResourceShort(p,&id);
1544 p=ReadResourceByte(p,&length_byte);
1546 if (((length_byte+1) & 0x01) != 0)
1548 if (p > (datum+length-4))
1550 p=ReadResourceLong(p,&count);
1551 if ((p > (datum+length-count)) || (count > length))
1563 p=ReadResourceShort(p,&resolution)+6;
1564 image->x_resolution=(double) resolution;
1565 p=ReadResourceShort(p,&resolution)+6;
1566 image->y_resolution=(double) resolution;
1574 profile=AcquireStringInfo(count);
1575 SetStringInfoDatum(profile,p);
1576 (void) SetImageProfile(image,"iptc",profile);
1577 profile=DestroyStringInfo(profile);
1594 profile=AcquireStringInfo(count);
1595 SetStringInfoDatum(profile,p);
1596 (void) SetImageProfile(image,"icc",profile);
1597 profile=DestroyStringInfo(profile);
1606 profile=AcquireStringInfo(count);
1607 SetStringInfoDatum(profile,p);
1608 (void) SetImageProfile(image,"exif",profile);
1609 profile=DestroyStringInfo(profile);
1618 profile=AcquireStringInfo(count);
1619 SetStringInfoDatum(profile,p);
1620 (void) SetImageProfile(image,"xmp",profile);
1621 profile=DestroyStringInfo(profile);
1631 if ((count & 0x01) != 0)
1637 MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
1638 const StringInfo *profile)
1642 property[MaxTextExtent];
1647 assert(image != (Image *) NULL);
1648 assert(image->signature == MagickSignature);
1649 if (image->debug != MagickFalse)
1650 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1651 if (image->profiles == (SplayTreeInfo *) NULL)
1652 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1654 (void) CopyMagickString(key,name,MaxTextExtent);
1655 status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
1656 ConstantString(key),CloneStringInfo(profile));
1657 if ((status != MagickFalse) &&
1658 ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0)))
1664 Continue to support deprecated color profile member.
1666 icc_profile=GetImageProfile(image,name);
1667 if (icc_profile != (const StringInfo *) NULL)
1669 image->color_profile.length=GetStringInfoLength(icc_profile);
1670 image->color_profile.info=GetStringInfoDatum(icc_profile);
1673 if ((status != MagickFalse) &&
1674 ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
1680 Continue to support deprecated IPTC profile member.
1682 iptc_profile=GetImageProfile(image,name);
1683 if (iptc_profile != (const StringInfo *) NULL)
1685 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1686 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1688 (void) GetProfilesFromResourceBlock(image,profile);
1691 Inject profile into image properties.
1693 (void) FormatMagickString(property,MaxTextExtent,"%s:sans",name);
1694 (void) GetImageProperty(image,property);
1699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1703 % S y n c I m a g e P r o f i l e s %
1707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1709 % SyncImageProfiles() synchronizes image properties with the image profiles.
1710 % Currently we only support updating the EXIF resolution and orientation.
1712 % The format of the SyncImageProfiles method is:
1714 % MagickBooleanType SyncImageProfiles(Image *image)
1716 % A description of each parameter follows:
1718 % o image: the image.
1722 static inline int ReadProfileByte(unsigned char **p,size_t *length)
1734 static inline unsigned short ReadProfileShort(const EndianType endian,
1735 unsigned char *buffer)
1740 if (endian == MSBEndian)
1742 value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
1743 ((unsigned char *) buffer)[1]);
1744 return((unsigned short) (value & 0xffff));
1746 value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
1747 return((unsigned short) (value & 0xffff));
1750 static inline size_t ReadProfileLong(const EndianType endian,
1751 unsigned char *buffer)
1756 if (endian == MSBEndian)
1758 value=(size_t) ((buffer[0] << 24) | (buffer[1] << 16) |
1759 (buffer[2] << 8) | buffer[3]);
1760 return((size_t) (value & 0xffffffff));
1762 value=(size_t) ((buffer[3] << 24) | (buffer[2] << 16) |
1763 (buffer[1] << 8 ) | (buffer[0]));
1764 return((size_t) (value & 0xffffffff));
1767 static inline void WriteProfileLong(const EndianType endian,
1768 const size_t value,unsigned char *p)
1773 if (endian == MSBEndian)
1775 buffer[0]=(unsigned char) (value >> 24);
1776 buffer[1]=(unsigned char) (value >> 16);
1777 buffer[2]=(unsigned char) (value >> 8);
1778 buffer[3]=(unsigned char) value;
1779 (void) CopyMagickMemory(p,buffer,4);
1782 buffer[0]=(unsigned char) value;
1783 buffer[1]=(unsigned char) (value >> 8);
1784 buffer[2]=(unsigned char) (value >> 16);
1785 buffer[3]=(unsigned char) (value >> 24);
1786 (void) CopyMagickMemory(p,buffer,4);
1789 static void WriteProfileShort(const EndianType endian,
1790 const unsigned short value,unsigned char *p)
1795 if (endian == MSBEndian)
1797 buffer[0]=(unsigned char) (value >> 8);
1798 buffer[1]=(unsigned char) value;
1799 (void) CopyMagickMemory(p,buffer,2);
1802 buffer[0]=(unsigned char) value;
1803 buffer[1]=(unsigned char) (value >> 8);
1804 (void) CopyMagickMemory(p,buffer,2);
1807 MagickExport MagickBooleanType SyncImageProfiles(Image *image)
1809 #define MaxDirectoryStack 16
1810 #define EXIF_DELIMITER "\n"
1811 #define EXIF_NUM_FORMATS 12
1812 #define TAG_EXIF_OFFSET 0x8769
1813 #define TAG_INTEROP_OFFSET 0xa005
1815 typedef struct _DirectoryInfo
1825 directory_stack[MaxDirectoryStack];
1843 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
1853 Set EXIF resolution tag.
1855 profile=(StringInfo *) GetImageProfile(image,"EXIF");
1856 if (profile == (StringInfo *) NULL)
1858 length=GetStringInfoLength(profile);
1859 exif=GetStringInfoDatum(profile);
1862 if (ReadProfileByte(&exif,&length) != 0x45)
1864 if (ReadProfileByte(&exif,&length) != 0x78)
1866 if (ReadProfileByte(&exif,&length) != 0x69)
1868 if (ReadProfileByte(&exif,&length) != 0x66)
1870 if (ReadProfileByte(&exif,&length) != 0x00)
1872 if (ReadProfileByte(&exif,&length) != 0x00)
1877 return(MagickFalse);
1878 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
1886 return(MagickFalse);
1887 if (ReadProfileShort(endian,exif+2) != 0x002a)
1888 return(MagickFalse);
1890 This the offset to the first IFD.
1892 offset=(int) ReadProfileLong(endian,exif+4);
1893 if ((size_t) offset >= length)
1894 return(MagickFalse);
1895 directory=exif+offset;
1903 directory=directory_stack[level].directory;
1904 entry=directory_stack[level].entry;
1907 Determine how many entries there are in the current IFD.
1909 number_entries=ReadProfileShort(endian,directory);
1910 for ( ; entry < number_entries; entry++)
1919 register unsigned char
1926 q=(unsigned char *) (directory+2+(12*entry));
1927 tag_value=(ssize_t) ReadProfileShort(endian,q);
1928 format=(ssize_t) ReadProfileShort(endian,q+2);
1929 if ((format-1) >= EXIF_NUM_FORMATS)
1931 components=(int) ReadProfileLong(endian,q+4);
1932 number_bytes=(size_t) components*format_bytes[format];
1933 if (number_bytes <= 4)
1941 The directory entry contains an offset.
1943 offset=(int) ReadProfileLong(endian,q+8);
1944 if ((size_t) (offset+number_bytes) > length)
1946 p=(unsigned char *) (exif+offset);
1952 (void) WriteProfileLong(endian,(size_t)
1953 (image->x_resolution+0.5),p);
1954 (void) WriteProfileLong(endian,1UL,p+4);
1959 (void) WriteProfileLong(endian,(size_t)
1960 (image->y_resolution+0.5),p);
1961 (void) WriteProfileLong(endian,1UL,p+4);
1966 (void) WriteProfileShort(endian,(unsigned short)
1967 image->orientation,p);
1972 (void) WriteProfileShort(endian,(unsigned short)
1973 (image->units+1),p);
1979 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
1984 offset=(size_t) ReadProfileLong(endian,p);
1985 if ((offset < length) && (level < (MaxDirectoryStack-2)))
1987 directory_stack[level].directory=directory;
1989 directory_stack[level].entry=entry;
1991 directory_stack[level].directory=exif+offset;
1992 directory_stack[level].entry=0;
1994 if ((directory+2+(12*number_entries)) > (exif+length))
1996 offset=(size_t) ReadProfileLong(endian,directory+2+(12*
1998 if ((offset != 0) && (offset < length) &&
1999 (level < (MaxDirectoryStack-2)))
2001 directory_stack[level].directory=exif+offset;
2002 directory_stack[level].entry=0;
2009 } while (level > 0);