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