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 "MagickCore/studio.h"
43 #include "MagickCore/attribute.h"
44 #include "MagickCore/cache.h"
45 #include "MagickCore/color.h"
46 #include "MagickCore/colorspace-private.h"
47 #include "MagickCore/configure.h"
48 #include "MagickCore/exception.h"
49 #include "MagickCore/exception-private.h"
50 #include "MagickCore/hashmap.h"
51 #include "MagickCore/image.h"
52 #include "MagickCore/memory_.h"
53 #include "MagickCore/monitor.h"
54 #include "MagickCore/monitor-private.h"
55 #include "MagickCore/option.h"
56 #include "MagickCore/pixel-accessor.h"
57 #include "MagickCore/profile.h"
58 #include "MagickCore/property.h"
59 #include "MagickCore/quantum.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/splay-tree.h"
62 #include "MagickCore/string_.h"
63 #include "MagickCore/thread-private.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/utility.h"
66 #if defined(MAGICKCORE_LCMS_DELEGATE)
67 #if defined(MAGICKCORE_HAVE_LCMS_LCMS2_H)
69 #include <lcms/lcms2.h>
70 #elif defined(MAGICKCORE_HAVE_LCMS2_H)
73 #elif defined(MAGICKCORE_HAVE_LCMS_LCMS_H)
74 #include <lcms/lcms.h>
83 #if !defined(LCMS_VERSION) || (LCMS_VERSION < 2000)
84 #define cmsSigCmykData icSigCmykData
85 #define cmsSigGrayData icSigGrayData
86 #define cmsSigLabData icSigLabData
87 #define cmsSigLuvData icSigLuvData
88 #define cmsSigRgbData icSigRgbData
89 #define cmsSigXYZData icSigXYZData
90 #define cmsSigYCbCrData icSigYCbCrData
91 #define cmsSigLinkClass icSigLinkClass
92 #define cmsColorSpaceSignature icColorSpaceSignature
93 #define cmsUInt32Number DWORD
94 #define cmsSetLogErrorHandler(handler) cmsSetErrorHandler(handler)
95 #define cmsCreateTransformTHR(context,source_profile,source_type, \
96 target_profile,target_type,intent,flags) cmsCreateTransform(source_profile, \
97 source_type,target_profile,target_type,intent,flags);
98 #define cmsOpenProfileFromMemTHR(context,profile,length) \
99 cmsOpenProfileFromMem(profile,length)
103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107 % C l o n e I m a g e P r o f i l e s %
111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 % CloneImageProfiles() clones one or more image profiles.
115 % The format of the CloneImageProfiles method is:
117 % MagickBooleanType CloneImageProfiles(Image *image,
118 % const Image *clone_image)
120 % A description of each parameter follows:
122 % o image: the image.
124 % o clone_image: the clone image.
127 MagickExport MagickBooleanType CloneImageProfiles(Image *image,
128 const Image *clone_image)
130 assert(image != (Image *) NULL);
131 assert(image->signature == MagickSignature);
132 if (image->debug != MagickFalse)
133 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
134 assert(clone_image != (const Image *) NULL);
135 assert(clone_image->signature == MagickSignature);
136 image->color_profile.length=clone_image->color_profile.length;
137 image->color_profile.info=clone_image->color_profile.info;
138 image->iptc_profile.length=clone_image->iptc_profile.length;
139 image->iptc_profile.info=clone_image->iptc_profile.info;
140 if (clone_image->profiles != (void *) NULL)
141 image->profiles=CloneSplayTree((SplayTreeInfo *) clone_image->profiles,
142 (void *(*)(void *)) ConstantString,(void *(*)(void *)) CloneStringInfo);
147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151 % D e l e t e I m a g e P r o f i l e %
155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157 % DeleteImageProfile() deletes a profile from the image by its name.
159 % The format of the DeleteImageProfile method is:
161 % MagickBooleanTyupe DeleteImageProfile(Image *image,const char *name)
163 % A description of each parameter follows:
165 % o image: the image.
167 % o name: the profile name.
170 MagickExport MagickBooleanType DeleteImageProfile(Image *image,const char *name)
172 assert(image != (Image *) NULL);
173 assert(image->signature == MagickSignature);
174 if (image->debug != MagickFalse)
175 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
176 if (image->profiles == (SplayTreeInfo *) NULL)
178 return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->profiles,name));
182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 % D e s t r o y I m a g e P r o f i l e s %
190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192 % DestroyImageProfiles() releases memory associated with an image profile map.
194 % The format of the DestroyProfiles method is:
196 % void DestroyImageProfiles(Image *image)
198 % A description of each parameter follows:
200 % o image: the image.
203 MagickExport void DestroyImageProfiles(Image *image)
205 if (image->profiles != (SplayTreeInfo *) NULL)
206 image->profiles=DestroySplayTree((SplayTreeInfo *) image->profiles);
210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214 % G e t I m a g e P r o f i l e %
218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 % GetImageProfile() gets a profile associated with an image by name.
222 % The format of the GetImageProfile method is:
224 % const StringInfo *GetImageProfile(const Image *image,const char *name)
226 % A description of each parameter follows:
228 % o image: the image.
230 % o name: the profile name.
233 MagickExport const StringInfo *GetImageProfile(const Image *image,
242 assert(image != (Image *) NULL);
243 assert(image->signature == MagickSignature);
244 if (image->debug != MagickFalse)
245 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
246 if (image->profiles == (SplayTreeInfo *) NULL)
247 return((StringInfo *) NULL);
248 (void) CopyMagickString(key,name,MaxTextExtent);
249 profile=(const StringInfo *) GetValueFromSplayTree((SplayTreeInfo *)
250 image->profiles,key);
255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259 % G e t N e x t I m a g e P r o f i l e %
263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265 % GetNextImageProfile() gets the next profile name for an image.
267 % The format of the GetNextImageProfile method is:
269 % char *GetNextImageProfile(const Image *image)
271 % A description of each parameter follows:
273 % o hash_info: the hash info.
276 MagickExport char *GetNextImageProfile(const Image *image)
278 assert(image != (Image *) NULL);
279 assert(image->signature == MagickSignature);
280 if (image->debug != MagickFalse)
281 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
282 if (image->profiles == (SplayTreeInfo *) NULL)
283 return((char *) NULL);
284 return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->profiles));
288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292 % P r o f i l e I m a g e %
296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298 % ProfileImage() associates, applies, or removes an ICM, IPTC, or generic
299 % profile with / to / from an image. If the profile is NULL, it is removed
300 % from the image otherwise added or applied. Use a name of '*' and a profile
301 % of NULL to remove all profiles from the image.
303 % ICC and ICM profiles are handled as follows: If the image does not have
304 % an associated color profile, the one you provide is associated with the
305 % image and the image pixels are not transformed. Otherwise, the colorspace
306 % transform defined by the existing and new profile are applied to the image
307 % pixels and the new profile is associated with the image.
309 % The format of the ProfileImage method is:
311 % MagickBooleanType ProfileImage(Image *image,const char *name,
312 % const void *datum,const size_t length,const MagickBooleanType clone)
314 % A description of each parameter follows:
316 % o image: the image.
318 % o name: Name of profile to add or remove: ICC, IPTC, or generic profile.
320 % o datum: the profile data.
322 % o length: the length of the profile.
324 % o clone: should be MagickFalse.
328 #if defined(MAGICKCORE_LCMS_DELEGATE)
330 static unsigned short **DestroyPixelThreadSet(unsigned short **pixels)
335 assert(pixels != (unsigned short **) NULL);
336 for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
337 if (pixels[i] != (unsigned short *) NULL)
338 pixels[i]=(unsigned short *) RelinquishMagickMemory(pixels[i]);
339 pixels=(unsigned short **) RelinquishMagickMemory(pixels);
343 static unsigned short **AcquirePixelThreadSet(const size_t columns,
344 const size_t channels)
355 number_threads=GetOpenMPMaximumThreads();
356 pixels=(unsigned short **) AcquireQuantumMemory(number_threads,
358 if (pixels == (unsigned short **) NULL)
359 return((unsigned short **) NULL);
360 (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels));
361 for (i=0; i < (ssize_t) number_threads; i++)
363 pixels[i]=(unsigned short *) AcquireQuantumMemory(columns,channels*
365 if (pixels[i] == (unsigned short *) NULL)
366 return(DestroyPixelThreadSet(pixels));
371 static cmsHTRANSFORM *DestroyTransformThreadSet(cmsHTRANSFORM *transform)
376 assert(transform != (cmsHTRANSFORM *) NULL);
377 for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
378 if (transform[i] != (cmsHTRANSFORM) NULL)
379 cmsDeleteTransform(transform[i]);
380 transform=(cmsHTRANSFORM *) RelinquishMagickMemory(transform);
384 static cmsHTRANSFORM *AcquireTransformThreadSet(Image *image,
385 const cmsHPROFILE source_profile,const cmsUInt32Number source_type,
386 const cmsHPROFILE target_profile,const cmsUInt32Number target_type,
387 const int intent,const cmsUInt32Number flags)
398 number_threads=GetOpenMPMaximumThreads();
399 transform=(cmsHTRANSFORM *) AcquireQuantumMemory(number_threads,
401 if (transform == (cmsHTRANSFORM *) NULL)
402 return((cmsHTRANSFORM *) NULL);
403 (void) ResetMagickMemory(transform,0,number_threads*sizeof(*transform));
404 for (i=0; i < (ssize_t) number_threads; i++)
406 transform[i]=cmsCreateTransformTHR(image,source_profile,source_type,
407 target_profile,target_type,intent,flags);
408 if (transform[i] == (cmsHTRANSFORM) NULL)
409 return(DestroyTransformThreadSet(transform));
415 static MagickBooleanType SetAdobeRGB1998ImageProfile(Image *image)
418 AdobeRGB1998Profile[] =
420 0x00, 0x00, 0x02, 0x30, 0x41, 0x44, 0x42, 0x45, 0x02, 0x10, 0x00,
421 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
422 0x5a, 0x20, 0x07, 0xd0, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x13, 0x00,
423 0x33, 0x00, 0x3b, 0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c,
424 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
427 0x00, 0xd3, 0x2d, 0x41, 0x44, 0x42, 0x45, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
432 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
433 0x32, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00,
434 0x00, 0x6b, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x9c, 0x00,
435 0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x01, 0xb0,
436 0x00, 0x00, 0x00, 0x14, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01,
437 0xc4, 0x00, 0x00, 0x00, 0x0e, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00,
438 0x01, 0xd4, 0x00, 0x00, 0x00, 0x0e, 0x62, 0x54, 0x52, 0x43, 0x00,
439 0x00, 0x01, 0xe4, 0x00, 0x00, 0x00, 0x0e, 0x72, 0x58, 0x59, 0x5a,
440 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59,
441 0x5a, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58,
442 0x59, 0x5a, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x14, 0x74,
443 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79,
444 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20,
445 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65,
446 0x6d, 0x73, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72,
447 0x61, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63,
448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x41, 0x64, 0x6f,
449 0x62, 0x65, 0x20, 0x52, 0x47, 0x42, 0x20, 0x28, 0x31, 0x39, 0x39,
450 0x38, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00,
459 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x01, 0x02, 0x33, 0x00, 0x00, 0x63, 0x75, 0x72, 0x76, 0x00,
463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33, 0x00, 0x00,
464 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x01, 0x02, 0x33, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, 0x00, 0x00, 0x4f, 0xa5, 0x00,
467 0x00, 0x04, 0xfc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, 0x00, 0x00, 0x0f,
469 0x95, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0x26, 0x31, 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9c
479 assert(image != (Image *) NULL);
480 assert(image->signature == MagickSignature);
481 if (GetImageProfile(image,"icm") != (const StringInfo *) NULL)
483 profile=AcquireStringInfo(sizeof(AdobeRGB1998Profile));
484 SetStringInfoDatum(profile,AdobeRGB1998Profile);
485 status=SetImageProfile(image,"icm",profile);
486 profile=DestroyStringInfo(profile);
490 static MagickBooleanType SetsRGBImageProfile(Image *image)
495 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
496 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
497 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
498 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
499 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
500 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
502 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
507 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00,
508 0x33, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00,
509 0x00, 0x6c, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0xf0, 0x00,
510 0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04,
511 0x00, 0x00, 0x00, 0x14, 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02,
512 0x18, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00,
513 0x02, 0x2c, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58, 0x59, 0x5a, 0x00,
514 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, 0x64, 0x6d, 0x6e, 0x64,
515 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70, 0x64, 0x6d, 0x64,
516 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, 0x76, 0x75,
517 0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x76,
518 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24,
519 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00,
520 0x14, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00,
521 0x00, 0x24, 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, 0x00,
522 0x00, 0x00, 0x0c, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c,
523 0x00, 0x00, 0x08, 0x0c, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04,
524 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x62, 0x54, 0x52, 0x43, 0x00, 0x00,
525 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x74, 0x65, 0x78, 0x74, 0x00,
526 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
527 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20,
528 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74, 0x74, 0x2d, 0x50, 0x61, 0x63,
529 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e,
530 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
531 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45,
532 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00,
533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
534 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39,
535 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58,
542 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a,
544 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00,
545 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, 0x00, 0x00, 0xb7, 0x85,
547 0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
548 0x00, 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00,
549 0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
551 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
552 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
554 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
555 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31,
561 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, 0x65, 0x66,
562 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, 0x6f,
563 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
564 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20,
566 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
567 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20,
568 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63,
569 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73,
572 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
573 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
574 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
575 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
576 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
578 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
579 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
580 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
581 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
585 0xa4, 0xfe, 0x00, 0x14, 0x5f, 0x2e, 0x00, 0x10, 0xcf, 0x14, 0x00,
586 0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, 0x00, 0x03, 0x5c, 0x9e,
587 0x00, 0x00, 0x00, 0x01, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, 0x00, 0x57,
589 0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
592 0x8f, 0x00, 0x00, 0x00, 0x02, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00,
593 0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05,
595 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00,
596 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b,
597 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54, 0x00,
598 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
599 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00,
600 0x90, 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9,
601 0x00, 0xae, 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00,
602 0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0,
603 0x00, 0xe5, 0x00, 0xeb, 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01,
604 0x01, 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f,
605 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, 0x01, 0x38, 0x01, 0x3e, 0x01,
606 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67,
607 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, 0x01, 0x8b, 0x01,
608 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9,
609 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, 0x01,
610 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
611 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02,
612 0x4b, 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a,
613 0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02,
614 0xb6, 0x02, 0xc1, 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb,
615 0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03,
616 0x2d, 0x03, 0x38, 0x03, 0x43, 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66,
617 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, 0x03,
618 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, 0x03, 0xe0, 0x03, 0xec,
619 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04,
620 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, 0x04, 0x7e,
621 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4, 0x04,
622 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
623 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05,
624 0x77, 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5,
625 0x05, 0xd5, 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06,
626 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b,
627 0x06, 0x8c, 0x06, 0x9d, 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06,
628 0xe3, 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d,
629 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, 0x07, 0x86, 0x07, 0x99, 0x07,
630 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b,
631 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, 0x08, 0x6e, 0x08,
632 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7,
633 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, 0x09,
634 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
635 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a,
636 0x54, 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5,
637 0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b,
638 0x51, 0x0b, 0x69, 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8,
639 0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c,
640 0x5c, 0x0c, 0x75, 0x0c, 0x8e, 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9,
641 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, 0x0d,
642 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, 0x0d, 0xde, 0x0d, 0xf8,
643 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e,
644 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, 0x0f, 0x25,
645 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3, 0x0f,
646 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
647 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11,
648 0x13, 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa,
649 0x11, 0xc9, 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12,
650 0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03,
651 0x13, 0x23, 0x13, 0x43, 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13,
652 0xc5, 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a,
653 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, 0x14, 0xf0, 0x15, 0x12, 0x15,
654 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0,
655 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, 0x16, 0x8f, 0x16,
656 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65,
657 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, 0x18,
658 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
659 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19,
660 0xdd, 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e,
661 0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b,
662 0x8a, 0x1b, 0xb2, 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52,
663 0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d,
664 0x47, 0x1d, 0x70, 0x1d, 0x99, 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16,
665 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, 0x1f,
666 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, 0x1f, 0xbf, 0x1f, 0xea,
667 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20,
668 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, 0x21, 0xce,
669 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf, 0x22,
670 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
671 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24,
672 0xda, 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7,
673 0x25, 0xf7, 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26,
674 0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc,
675 0x28, 0x0d, 0x28, 0x3f, 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29,
676 0x06, 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02,
677 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, 0x2a, 0xcf, 0x2b, 0x02, 0x2b,
678 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39,
679 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, 0x2d, 0x41, 0x2d,
680 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82,
681 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, 0x2f,
682 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
683 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32,
684 0x2a, 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46,
685 0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34,
686 0x9e, 0x34, 0xd8, 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2,
687 0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37,
688 0x24, 0x37, 0x60, 0x37, 0x9c, 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50,
689 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, 0x39,
690 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, 0x3a, 0xb2, 0x3a, 0xef,
691 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c,
692 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, 0x3d, 0xa1,
693 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0, 0x3f,
694 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
695 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41,
696 0xee, 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a,
697 0x43, 0x7d, 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44,
698 0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22,
699 0x46, 0x67, 0x46, 0xab, 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47,
700 0xc0, 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d,
701 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, 0x4a, 0x37, 0x4a, 0x7d, 0x4a,
702 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a,
703 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, 0x4d, 0x93, 0x4d,
704 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49,
705 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, 0x51,
706 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
707 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54,
708 0x42, 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2,
709 0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57,
710 0x92, 0x57, 0xe0, 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a,
711 0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a,
712 0xf5, 0x5b, 0x45, 0x5b, 0x95, 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86,
713 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, 0x5e,
714 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, 0x5f, 0xb3, 0x60, 0x05,
715 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61,
716 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, 0x63, 0x97,
717 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d, 0x65,
718 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
719 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69,
720 0x43, 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7,
721 0x6b, 0x4f, 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d,
722 0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4,
723 0x6f, 0x1e, 0x6f, 0x78, 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70,
724 0xe0, 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6,
725 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, 0x74, 0x14, 0x74, 0x70, 0x74,
726 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b,
727 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, 0x78, 0x6e, 0x78,
728 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5,
729 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, 0x7c,
730 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
731 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81,
732 0x0a, 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4,
733 0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85,
734 0x47, 0x85, 0xab, 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b,
735 0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89,
736 0x99, 0x89, 0xfe, 0x8a, 0x64, 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96,
737 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, 0x8d,
738 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, 0x8f, 0x9e, 0x90, 0x06,
739 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92,
740 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, 0x94, 0x8a,
741 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f, 0x97,
742 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
743 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b,
744 0xaf, 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2,
745 0x9e, 0x40, 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0,
746 0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96,
747 0xa3, 0x06, 0xa3, 0x76, 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5,
748 0x38, 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e,
749 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, 0xa9, 0x37, 0xa9, 0xa9, 0xaa,
750 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c,
751 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, 0xae, 0xa1, 0xaf,
752 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60,
753 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, 0xb4,
754 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
755 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9,
756 0x4a, 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7,
757 0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe,
758 0x84, 0xbe, 0xff, 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec,
759 0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3,
760 0xd4, 0xc4, 0x51, 0xc4, 0xce, 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46,
761 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, 0xc9,
762 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, 0xcb, 0x36, 0xcb, 0xb6,
763 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce,
764 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, 0xd1, 0x3c,
765 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6, 0xd4,
766 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
767 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9,
768 0xf1, 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a,
769 0xdd, 0x10, 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf,
770 0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53,
771 0xe2, 0xdb, 0xe3, 0x63, 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5,
772 0x84, 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32,
773 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, 0xea, 0x5b, 0xea, 0xe5, 0xeb,
774 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28,
775 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, 0xf0, 0xe5, 0xf1,
776 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34,
777 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, 0xf7,
778 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
779 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd,
780 0xba, 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
789 assert(image != (Image *) NULL);
790 assert(image->signature == MagickSignature);
791 if (GetImageProfile(image,"icm") != (const StringInfo *) NULL)
793 profile=AcquireStringInfo(sizeof(sRGBProfile));
794 SetStringInfoDatum(profile,sRGBProfile);
795 status=SetImageProfile(image,"icm",profile);
796 profile=DestroyStringInfo(profile);
799 #if defined(MAGICKCORE_LCMS_DELEGATE)
800 #if defined(LCMS_VERSION) && (LCMS_VERSION >= 2000)
801 static void LCMSExceptionHandler(cmsContext context,cmsUInt32Number severity,
807 (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%u, %s",
808 severity,message != (char *) NULL ? message : "no message");
809 image=(Image *) context;
810 if (image != (Image *) NULL)
811 (void) ThrowMagickException(&image->exception,GetMagickModule(),
812 ImageWarning,"UnableToTransformColorspace","`%s'",image->filename);
816 static int LCMSExceptionHandler(int severity,const char *message)
818 (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%d, %s",
819 severity,message != (char *) NULL ? message : "no message");
825 MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
826 const void *datum,const size_t length,
827 const MagickBooleanType magick_unused(clone))
829 #define ProfileImageTag "Profile/Image"
830 #define ThrowProfileException(severity,tag,context) \
832 if (source_profile != (cmsHPROFILE) NULL) \
833 (void) cmsCloseProfile(source_profile); \
834 if (target_profile != (cmsHPROFILE) NULL) \
835 (void) cmsCloseProfile(target_profile); \
836 ThrowBinaryException(severity,tag,context); \
848 assert(image != (Image *) NULL);
849 assert(image->signature == MagickSignature);
850 if (image->debug != MagickFalse)
851 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
852 assert(name != (const char *) NULL);
853 exception=(&image->exception);
854 if ((datum == (const void *) NULL) || (length == 0))
867 Delete image profile(s).
869 names=ConstantString(name);
870 (void) SubstituteString(&names,","," ");
871 arguments=StringToArgv(names,&number_arguments);
872 names=DestroyString(names);
873 if (arguments == (char **) NULL)
875 ResetImageProfileIterator(image);
876 for (name=GetNextImageProfile(image); name != (const char *) NULL; )
878 for (i=1; i < (ssize_t) number_arguments; i++)
880 if ((*arguments[i] == '!') &&
881 (LocaleCompare(name,arguments[i]+1) == 0))
883 if (GlobExpression(name,arguments[i],MagickTrue) != MagickFalse)
885 (void) DeleteImageProfile(image,name);
886 ResetImageProfileIterator(image);
890 name=GetNextImageProfile(image);
892 for (i=0; i < (ssize_t) number_arguments; i++)
893 arguments[i]=DestroyString(arguments[i]);
894 arguments=(char **) RelinquishMagickMemory(arguments);
898 Add a ICC, IPTC, or generic profile to the image.
901 profile=AcquireStringInfo((size_t) length);
902 SetStringInfoDatum(profile,(unsigned char *) datum);
903 if ((LocaleCompare(name,"icc") != 0) && (LocaleCompare(name,"icm") != 0))
904 status=SetImageProfile(image,name,profile);
910 icc_profile=GetImageProfile(image,"icc");
911 if ((icc_profile != (const StringInfo *) NULL) &&
912 (CompareStringInfo(icc_profile,profile) == 0))
917 value=GetImageProperty(image,"exif:ColorSpace");
918 if (LocaleCompare(value,"1") != 0)
919 (void) SetsRGBImageProfile(image);
920 value=GetImageProperty(image,"exif:InteroperabilityIndex");
921 if (LocaleCompare(value,"R98.") != 0)
922 (void) SetsRGBImageProfile(image);
923 value=GetImageProperty(image,"exif:InteroperabilityIndex");
924 if (LocaleCompare(value,"R03.") != 0)
925 (void) SetAdobeRGB1998ImageProfile(image);
926 icc_profile=GetImageProfile(image,"icc");
928 if ((icc_profile != (const StringInfo *) NULL) &&
929 (CompareStringInfo(icc_profile,profile) == 0))
931 profile=DestroyStringInfo(profile);
934 #if !defined(MAGICKCORE_LCMS_DELEGATE)
935 (void) ThrowMagickException(&image->exception,GetMagickModule(),
936 MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn",
937 "`%s' (LCMS)",image->filename);
944 Transform pixel colors as defined by the color profiles.
946 cmsSetLogErrorHandler(LCMSExceptionHandler);
947 source_profile=cmsOpenProfileFromMemTHR(image,
948 GetStringInfoDatum(profile),(cmsUInt32Number)
949 GetStringInfoLength(profile));
950 if (source_profile == (cmsHPROFILE) NULL)
951 ThrowBinaryException(ResourceLimitError,
952 "ColorspaceColorProfileMismatch",name);
953 if ((cmsGetDeviceClass(source_profile) != cmsSigLinkClass) &&
954 (icc_profile == (StringInfo *) NULL))
955 status=SetImageProfile(image,name,profile);
965 cmsColorSpaceSignature
996 **restrict source_pixels,
997 **restrict target_pixels;
999 target_profile=(cmsHPROFILE) NULL;
1000 if (icc_profile != (StringInfo *) NULL)
1002 target_profile=source_profile;
1003 source_profile=cmsOpenProfileFromMemTHR(image,
1004 GetStringInfoDatum(icc_profile),(cmsUInt32Number)
1005 GetStringInfoLength(icc_profile));
1006 if (source_profile == (cmsHPROFILE) NULL)
1007 ThrowProfileException(ResourceLimitError,
1008 "ColorspaceColorProfileMismatch",name);
1010 switch (cmsGetColorSpace(source_profile))
1012 case cmsSigCmykData:
1014 source_colorspace=CMYKColorspace;
1015 source_type=(cmsUInt32Number) TYPE_CMYK_16;
1019 case cmsSigGrayData:
1021 source_colorspace=GRAYColorspace;
1022 source_type=(cmsUInt32Number) TYPE_GRAY_16;
1028 source_colorspace=LabColorspace;
1029 source_type=(cmsUInt32Number) TYPE_Lab_16;
1035 source_colorspace=YUVColorspace;
1036 source_type=(cmsUInt32Number) TYPE_YUV_16;
1042 source_colorspace=RGBColorspace;
1043 source_type=(cmsUInt32Number) TYPE_RGB_16;
1049 source_colorspace=XYZColorspace;
1050 source_type=(cmsUInt32Number) TYPE_XYZ_16;
1054 case cmsSigYCbCrData:
1056 source_colorspace=YCbCrColorspace;
1057 source_type=(cmsUInt32Number) TYPE_YCbCr_16;
1063 source_colorspace=UndefinedColorspace;
1064 source_type=(cmsUInt32Number) TYPE_RGB_16;
1069 signature=cmsGetPCS(source_profile);
1070 if (target_profile != (cmsHPROFILE) NULL)
1071 signature=cmsGetColorSpace(target_profile);
1074 case cmsSigCmykData:
1076 target_colorspace=CMYKColorspace;
1077 target_type=(cmsUInt32Number) TYPE_CMYK_16;
1083 target_colorspace=LabColorspace;
1084 target_type=(cmsUInt32Number) TYPE_Lab_16;
1088 case cmsSigGrayData:
1090 target_colorspace=GRAYColorspace;
1091 target_type=(cmsUInt32Number) TYPE_GRAY_16;
1097 target_colorspace=YUVColorspace;
1098 target_type=(cmsUInt32Number) TYPE_YUV_16;
1104 target_colorspace=RGBColorspace;
1105 target_type=(cmsUInt32Number) TYPE_RGB_16;
1111 target_colorspace=XYZColorspace;
1112 target_type=(cmsUInt32Number) TYPE_XYZ_16;
1116 case cmsSigYCbCrData:
1118 target_colorspace=YCbCrColorspace;
1119 target_type=(cmsUInt32Number) TYPE_YCbCr_16;
1125 target_colorspace=UndefinedColorspace;
1126 target_type=(cmsUInt32Number) TYPE_RGB_16;
1131 if ((source_colorspace == UndefinedColorspace) ||
1132 (target_colorspace == UndefinedColorspace))
1133 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1135 if ((source_colorspace == GRAYColorspace) &&
1136 (IsImageGray(image,exception) == MagickFalse))
1137 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1139 if ((source_colorspace == CMYKColorspace) &&
1140 (image->colorspace != CMYKColorspace))
1141 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1143 if ((source_colorspace == XYZColorspace) &&
1144 (image->colorspace != XYZColorspace))
1145 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1147 if ((source_colorspace == YCbCrColorspace) &&
1148 (image->colorspace != YCbCrColorspace))
1149 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1151 if ((source_colorspace != CMYKColorspace) &&
1152 (source_colorspace != GRAYColorspace) &&
1153 (source_colorspace != LabColorspace) &&
1154 (source_colorspace != XYZColorspace) &&
1155 (source_colorspace != YCbCrColorspace) &&
1156 (IsRGBColorspace(image->colorspace) == MagickFalse))
1157 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1159 switch (image->rendering_intent)
1161 case AbsoluteIntent: intent=INTENT_ABSOLUTE_COLORIMETRIC; break;
1162 case PerceptualIntent: intent=INTENT_PERCEPTUAL; break;
1163 case RelativeIntent: intent=INTENT_RELATIVE_COLORIMETRIC; break;
1164 case SaturationIntent: intent=INTENT_SATURATION; break;
1165 default: intent=INTENT_PERCEPTUAL; break;
1167 flags=cmsFLAGS_HIGHRESPRECALC;
1168 #if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1169 if (image->black_point_compensation != MagickFalse)
1170 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1172 transform=AcquireTransformThreadSet(image,source_profile,
1173 source_type,target_profile,target_type,intent,flags);
1174 if (transform == (cmsHTRANSFORM *) NULL)
1175 ThrowProfileException(ImageError,"UnableToCreateColorTransform",
1178 Transform image as dictated by the source & target image profiles.
1180 source_pixels=AcquirePixelThreadSet(image->columns,source_channels);
1181 target_pixels=AcquirePixelThreadSet(image->columns,target_channels);
1182 if ((source_pixels == (unsigned short **) NULL) ||
1183 (target_pixels == (unsigned short **) NULL))
1185 transform=DestroyTransformThreadSet(transform);
1186 ThrowProfileException(ResourceLimitError,
1187 "MemoryAllocationFailed",image->filename);
1189 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1191 target_pixels=DestroyPixelThreadSet(target_pixels);
1192 source_pixels=DestroyPixelThreadSet(source_pixels);
1193 transform=DestroyTransformThreadSet(transform);
1194 if (source_profile != (cmsHPROFILE) NULL)
1195 (void) cmsCloseProfile(source_profile);
1196 if (target_profile != (cmsHPROFILE) NULL)
1197 (void) cmsCloseProfile(target_profile);
1198 return(MagickFalse);
1200 if (target_colorspace == CMYKColorspace)
1201 (void) SetImageColorspace(image,target_colorspace,exception);
1204 image_view=AcquireCacheView(image);
1205 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1206 #pragma omp parallel for schedule(dynamic,4) shared(status)
1208 for (y=0; y < (ssize_t) image->rows; y++)
1211 id = GetOpenMPThreadId();
1222 register unsigned short
1225 if (status == MagickFalse)
1227 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1229 if (q == (const Quantum *) NULL)
1234 p=source_pixels[id];
1235 for (x=0; x < (ssize_t) image->columns; x++)
1237 *p++=ScaleQuantumToShort(GetPixelRed(image,q));
1238 if (source_channels > 1)
1240 *p++=ScaleQuantumToShort(GetPixelGreen(image,q));
1241 *p++=ScaleQuantumToShort(GetPixelBlue(image,q));
1243 if (source_channels > 3)
1244 *p++=ScaleQuantumToShort(GetPixelBlack(image,q));
1245 q+=GetPixelChannels(image);
1247 cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
1248 (unsigned int) image->columns);
1249 p=target_pixels[id];
1250 q-=image->columns*GetPixelChannels(image);
1251 for (x=0; x < (ssize_t) image->columns; x++)
1253 SetPixelRed(image,ScaleShortToQuantum(*p),q);
1254 SetPixelGreen(image,GetPixelRed(image,q),q);
1255 SetPixelBlue(image,GetPixelRed(image,q),q);
1257 if (target_channels > 1)
1259 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
1261 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
1264 if (target_channels > 3)
1266 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
1269 q+=GetPixelChannels(image);
1271 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1272 if (sync == MagickFalse)
1274 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1279 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1280 #pragma omp critical (MagickCore_ProfileImage)
1282 proceed=SetImageProgress(image,ProfileImageTag,progress++,
1284 if (proceed == MagickFalse)
1288 image_view=DestroyCacheView(image_view);
1289 (void) SetImageColorspace(image,target_colorspace,exception);
1294 image->type=image->matte == MagickFalse ? TrueColorType :
1298 case cmsSigCmykData:
1300 image->type=image->matte == MagickFalse ? ColorSeparationType :
1301 ColorSeparationMatteType;
1304 case cmsSigGrayData:
1306 image->type=image->matte == MagickFalse ? GrayscaleType :
1313 target_pixels=DestroyPixelThreadSet(target_pixels);
1314 source_pixels=DestroyPixelThreadSet(source_pixels);
1315 transform=DestroyTransformThreadSet(transform);
1316 if (cmsGetDeviceClass(source_profile) != cmsSigLinkClass)
1317 status=SetImageProfile(image,name,profile);
1318 if (target_profile != (cmsHPROFILE) NULL)
1319 (void) cmsCloseProfile(target_profile);
1321 (void) cmsCloseProfile(source_profile);
1325 profile=DestroyStringInfo(profile);
1330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1334 % R e m o v e I m a g e P r o f i l e %
1338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1340 % RemoveImageProfile() removes a named profile from the image and returns its
1343 % The format of the RemoveImageProfile method is:
1345 % void *RemoveImageProfile(Image *image,const char *name)
1347 % A description of each parameter follows:
1349 % o image: the image.
1351 % o name: the profile name.
1354 MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
1359 assert(image != (Image *) NULL);
1360 assert(image->signature == MagickSignature);
1361 if (image->debug != MagickFalse)
1362 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1363 if (image->profiles == (SplayTreeInfo *) NULL)
1364 return((StringInfo *) NULL);
1365 profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
1366 image->profiles,name);
1371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1375 % R e s e t P r o f i l e I t e r a t o r %
1379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1381 % ResetImageProfileIterator() resets the image profile iterator. Use it in
1382 % conjunction with GetNextImageProfile() to iterate over all the profiles
1383 % associated with an image.
1385 % The format of the ResetImageProfileIterator method is:
1387 % ResetImageProfileIterator(Image *image)
1389 % A description of each parameter follows:
1391 % o image: the image.
1394 MagickExport void ResetImageProfileIterator(const Image *image)
1396 assert(image != (Image *) NULL);
1397 assert(image->signature == MagickSignature);
1398 if (image->debug != MagickFalse)
1399 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1400 if (image->profiles == (SplayTreeInfo *) NULL)
1402 ResetSplayTreeIterator((SplayTreeInfo *) image->profiles);
1406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410 % S e t I m a g e P r o f i l e %
1414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1416 % SetImageProfile() adds a named profile to the image. If a profile with the
1417 % same name already exists, it is replaced. This method differs from the
1418 % ProfileImage() method in that it does not apply CMS color profiles.
1420 % The format of the SetImageProfile method is:
1422 % MagickBooleanType SetImageProfile(Image *image,const char *name,
1423 % const StringInfo *profile)
1425 % A description of each parameter follows:
1427 % o image: the image.
1429 % o name: the profile name, for example icc, exif, and 8bim (8bim is the
1430 % Photoshop wrapper for iptc profiles).
1432 % o profile: A StringInfo structure that contains the named profile.
1436 static void *DestroyProfile(void *profile)
1438 return((void *) DestroyStringInfo((StringInfo *) profile));
1441 static inline const unsigned char *ReadResourceByte(const unsigned char *p,
1442 unsigned char *quantum)
1448 static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
1449 const ssize_t count,unsigned char *quantum)
1454 for (i=0; i < count; i++)
1459 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
1462 *quantum=(size_t) (*p++ << 24);
1463 *quantum|=(size_t) (*p++ << 16);
1464 *quantum|=(size_t) (*p++ << 8);
1465 *quantum|=(size_t) (*p++ << 0);
1469 static inline const unsigned char *ReadResourceShort(const unsigned char *p,
1470 unsigned short *quantum)
1472 *quantum=(unsigned short) (*p++ << 8);
1473 *quantum|=(unsigned short) (*p++ << 0);
1477 static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
1478 const StringInfo *resource_block)
1483 register const unsigned char
1501 datum=GetStringInfoDatum(resource_block);
1502 length=GetStringInfoLength(resource_block);
1503 for (p=datum; p < (datum+length-16); )
1505 if (LocaleNCompare((char *) p,"8BIM",4) != 0)
1508 p=ReadResourceShort(p,&id);
1509 p=ReadResourceByte(p,&length_byte);
1511 if (((length_byte+1) & 0x01) != 0)
1513 if (p > (datum+length-4))
1515 p=ReadResourceLong(p,&count);
1516 if ((p > (datum+length-count)) || (count > length))
1528 p=ReadResourceShort(p,&resolution)+6;
1529 image->x_resolution=(double) resolution;
1530 p=ReadResourceShort(p,&resolution)+6;
1531 image->y_resolution=(double) resolution;
1539 profile=AcquireStringInfo(count);
1540 SetStringInfoDatum(profile,p);
1541 (void) SetImageProfile(image,"iptc",profile);
1542 profile=DestroyStringInfo(profile);
1559 profile=AcquireStringInfo(count);
1560 SetStringInfoDatum(profile,p);
1561 (void) SetImageProfile(image,"icc",profile);
1562 profile=DestroyStringInfo(profile);
1571 profile=AcquireStringInfo(count);
1572 SetStringInfoDatum(profile,p);
1573 (void) SetImageProfile(image,"exif",profile);
1574 profile=DestroyStringInfo(profile);
1583 profile=AcquireStringInfo(count);
1584 SetStringInfoDatum(profile,p);
1585 (void) SetImageProfile(image,"xmp",profile);
1586 profile=DestroyStringInfo(profile);
1596 if ((count & 0x01) != 0)
1602 MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
1603 const StringInfo *profile)
1607 property[MaxTextExtent];
1612 assert(image != (Image *) NULL);
1613 assert(image->signature == MagickSignature);
1614 if (image->debug != MagickFalse)
1615 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1616 if (image->profiles == (SplayTreeInfo *) NULL)
1617 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1619 (void) CopyMagickString(key,name,MaxTextExtent);
1620 status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
1621 ConstantString(key),CloneStringInfo(profile));
1622 if ((status != MagickFalse) &&
1623 ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
1624 (void) GetProfilesFromResourceBlock(image,profile);
1626 Inject profile into image properties.
1628 (void) FormatLocaleString(property,MaxTextExtent,"%s:sans",name);
1629 (void) GetImageProperty(image,property);
1634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1638 % S y n c I m a g e P r o f i l e s %
1642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1644 % SyncImageProfiles() synchronizes image properties with the image profiles.
1645 % Currently we only support updating the EXIF resolution and orientation.
1647 % The format of the SyncImageProfiles method is:
1649 % MagickBooleanType SyncImageProfiles(Image *image)
1651 % A description of each parameter follows:
1653 % o image: the image.
1657 static inline int ReadProfileByte(unsigned char **p,size_t *length)
1669 static inline unsigned short ReadProfileShort(const EndianType endian,
1670 unsigned char *buffer)
1675 if (endian == MSBEndian)
1677 value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
1678 ((unsigned char *) buffer)[1]);
1679 return((unsigned short) (value & 0xffff));
1681 value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
1682 return((unsigned short) (value & 0xffff));
1685 static inline size_t ReadProfileLong(const EndianType endian,
1686 unsigned char *buffer)
1691 if (endian == MSBEndian)
1693 value=(size_t) ((buffer[0] << 24) | (buffer[1] << 16) |
1694 (buffer[2] << 8) | buffer[3]);
1695 return((size_t) (value & 0xffffffff));
1697 value=(size_t) ((buffer[3] << 24) | (buffer[2] << 16) |
1698 (buffer[1] << 8 ) | (buffer[0]));
1699 return((size_t) (value & 0xffffffff));
1702 static inline void WriteProfileLong(const EndianType endian,
1703 const size_t value,unsigned char *p)
1708 if (endian == MSBEndian)
1710 buffer[0]=(unsigned char) (value >> 24);
1711 buffer[1]=(unsigned char) (value >> 16);
1712 buffer[2]=(unsigned char) (value >> 8);
1713 buffer[3]=(unsigned char) value;
1714 (void) CopyMagickMemory(p,buffer,4);
1717 buffer[0]=(unsigned char) value;
1718 buffer[1]=(unsigned char) (value >> 8);
1719 buffer[2]=(unsigned char) (value >> 16);
1720 buffer[3]=(unsigned char) (value >> 24);
1721 (void) CopyMagickMemory(p,buffer,4);
1724 static void WriteProfileShort(const EndianType endian,
1725 const unsigned short value,unsigned char *p)
1730 if (endian == MSBEndian)
1732 buffer[0]=(unsigned char) (value >> 8);
1733 buffer[1]=(unsigned char) value;
1734 (void) CopyMagickMemory(p,buffer,2);
1737 buffer[0]=(unsigned char) value;
1738 buffer[1]=(unsigned char) (value >> 8);
1739 (void) CopyMagickMemory(p,buffer,2);
1742 MagickExport MagickBooleanType SyncImageProfiles(Image *image)
1744 #define MaxDirectoryStack 16
1745 #define EXIF_DELIMITER "\n"
1746 #define EXIF_NUM_FORMATS 12
1747 #define TAG_EXIF_OFFSET 0x8769
1748 #define TAG_INTEROP_OFFSET 0xa005
1750 typedef struct _DirectoryInfo
1760 directory_stack[MaxDirectoryStack];
1778 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
1788 Set EXIF resolution tag.
1790 profile=(StringInfo *) GetImageProfile(image,"EXIF");
1791 if (profile == (StringInfo *) NULL)
1793 length=GetStringInfoLength(profile);
1794 exif=GetStringInfoDatum(profile);
1797 if (ReadProfileByte(&exif,&length) != 0x45)
1799 if (ReadProfileByte(&exif,&length) != 0x78)
1801 if (ReadProfileByte(&exif,&length) != 0x69)
1803 if (ReadProfileByte(&exif,&length) != 0x66)
1805 if (ReadProfileByte(&exif,&length) != 0x00)
1807 if (ReadProfileByte(&exif,&length) != 0x00)
1812 return(MagickFalse);
1813 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
1821 return(MagickFalse);
1822 if (ReadProfileShort(endian,exif+2) != 0x002a)
1823 return(MagickFalse);
1825 This the offset to the first IFD.
1827 offset=(int) ReadProfileLong(endian,exif+4);
1828 if ((size_t) offset >= length)
1829 return(MagickFalse);
1830 directory=exif+offset;
1838 directory=directory_stack[level].directory;
1839 entry=directory_stack[level].entry;
1842 Determine how many entries there are in the current IFD.
1844 number_entries=ReadProfileShort(endian,directory);
1845 for ( ; entry < number_entries; entry++)
1850 register unsigned char
1861 q=(unsigned char *) (directory+2+(12*entry));
1862 tag_value=(ssize_t) ReadProfileShort(endian,q);
1863 format=(ssize_t) ReadProfileShort(endian,q+2);
1864 if ((format-1) >= EXIF_NUM_FORMATS)
1866 components=(int) ReadProfileLong(endian,q+4);
1867 number_bytes=(size_t) components*format_bytes[format];
1868 if (number_bytes <= 4)
1876 The directory entry contains an offset.
1878 offset=(int) ReadProfileLong(endian,q+8);
1879 if ((size_t) (offset+number_bytes) > length)
1881 p=(unsigned char *) (exif+offset);
1887 (void) WriteProfileLong(endian,(size_t)
1888 (image->x_resolution+0.5),p);
1889 (void) WriteProfileLong(endian,1UL,p+4);
1894 (void) WriteProfileLong(endian,(size_t)
1895 (image->y_resolution+0.5),p);
1896 (void) WriteProfileLong(endian,1UL,p+4);
1901 (void) WriteProfileShort(endian,(unsigned short)
1902 image->orientation,p);
1907 (void) WriteProfileShort(endian,(unsigned short)
1908 (image->units+1),p);
1914 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
1919 offset=(size_t) ReadProfileLong(endian,p);
1920 if ((offset < length) && (level < (MaxDirectoryStack-2)))
1922 directory_stack[level].directory=directory;
1924 directory_stack[level].entry=entry;
1926 directory_stack[level].directory=exif+offset;
1927 directory_stack[level].entry=0;
1929 if ((directory+2+(12*number_entries)) > (exif+length))
1931 offset=(size_t) ReadProfileLong(endian,directory+2+(12*
1933 if ((offset != 0) && (offset < length) &&
1934 (level < (MaxDirectoryStack-2)))
1936 directory_stack[level].directory=exif+offset;
1937 directory_stack[level].entry=0;
1944 } while (level > 0);