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 < (long) 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 < (long) 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 < (long) 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 < (long) 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 < 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 < 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
1007 **restrict source_pixels,
1008 **restrict target_pixels;
1010 exception=(&image->exception);
1011 target_profile=(cmsHPROFILE) NULL;
1012 if (icc_profile != (StringInfo *) NULL)
1014 target_profile=source_profile;
1015 source_profile=cmsOpenProfileFromMem(
1016 GetStringInfoDatum(icc_profile),(cmsUInt32Number)
1017 GetStringInfoLength(icc_profile));
1018 if (source_profile == (cmsHPROFILE) NULL)
1019 ThrowProfileException(ResourceLimitError,
1020 "ColorspaceColorProfileMismatch",name);
1022 switch (cmsGetColorSpace(source_profile))
1024 case cmsSigCmykData:
1026 source_colorspace=CMYKColorspace;
1027 source_type=(cmsUInt32Number) TYPE_CMYK_16;
1031 case cmsSigGrayData:
1033 source_colorspace=GRAYColorspace;
1034 source_type=(cmsUInt32Number) TYPE_GRAY_16;
1040 source_colorspace=LabColorspace;
1041 source_type=(cmsUInt32Number) TYPE_Lab_16;
1047 source_colorspace=YUVColorspace;
1048 source_type=(cmsUInt32Number) TYPE_YUV_16;
1054 source_colorspace=RGBColorspace;
1055 source_type=(cmsUInt32Number) TYPE_RGB_16;
1061 source_colorspace=XYZColorspace;
1062 source_type=(cmsUInt32Number) TYPE_XYZ_16;
1066 case cmsSigYCbCrData:
1068 source_colorspace=YCbCrColorspace;
1069 source_type=(cmsUInt32Number) TYPE_YCbCr_16;
1075 source_colorspace=UndefinedColorspace;
1076 source_type=(cmsUInt32Number) TYPE_RGB_16;
1081 signature=cmsGetPCS(source_profile);
1082 if (target_profile != (cmsHPROFILE) NULL)
1083 signature=cmsGetColorSpace(target_profile);
1086 case cmsSigCmykData:
1088 target_colorspace=CMYKColorspace;
1089 target_type=(cmsUInt32Number) TYPE_CMYK_16;
1095 target_colorspace=LabColorspace;
1096 target_type=(cmsUInt32Number) TYPE_Lab_16;
1100 case cmsSigGrayData:
1102 target_colorspace=GRAYColorspace;
1103 target_type=(cmsUInt32Number) TYPE_GRAY_16;
1109 target_colorspace=YUVColorspace;
1110 target_type=(cmsUInt32Number) TYPE_YUV_16;
1116 target_colorspace=RGBColorspace;
1117 target_type=(cmsUInt32Number) TYPE_RGB_16;
1123 target_colorspace=XYZColorspace;
1124 target_type=(cmsUInt32Number) TYPE_XYZ_16;
1128 case cmsSigYCbCrData:
1130 target_colorspace=YCbCrColorspace;
1131 target_type=(cmsUInt32Number) TYPE_YCbCr_16;
1137 target_colorspace=UndefinedColorspace;
1138 target_type=(cmsUInt32Number) TYPE_RGB_16;
1143 if ((source_colorspace == UndefinedColorspace) ||
1144 (target_colorspace == UndefinedColorspace))
1145 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1147 if ((source_colorspace == GRAYColorspace) &&
1148 (IsGrayImage(image,exception) == MagickFalse))
1149 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1151 if ((source_colorspace == CMYKColorspace) &&
1152 (image->colorspace != CMYKColorspace))
1153 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1155 if ((source_colorspace == XYZColorspace) &&
1156 (image->colorspace != XYZColorspace))
1157 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1159 if ((source_colorspace == YCbCrColorspace) &&
1160 (image->colorspace != YCbCrColorspace))
1161 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1163 if ((source_colorspace != CMYKColorspace) &&
1164 (source_colorspace != GRAYColorspace) &&
1165 (source_colorspace != LabColorspace) &&
1166 (source_colorspace != XYZColorspace) &&
1167 (source_colorspace != YCbCrColorspace) &&
1168 (image->colorspace != RGBColorspace))
1169 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1171 switch (image->rendering_intent)
1173 case AbsoluteIntent: intent=INTENT_ABSOLUTE_COLORIMETRIC; break;
1174 case PerceptualIntent: intent=INTENT_PERCEPTUAL; break;
1175 case RelativeIntent: intent=INTENT_RELATIVE_COLORIMETRIC; break;
1176 case SaturationIntent: intent=INTENT_SATURATION; break;
1177 default: intent=INTENT_PERCEPTUAL; break;
1179 flags=cmsFLAGS_HIGHRESPRECALC;
1180 #if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1181 if (image->black_point_compensation != MagickFalse)
1182 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1184 transform=AcquireTransformThreadSet(source_profile,source_type,
1185 target_profile,target_type,intent,flags);
1186 if (transform == (cmsHTRANSFORM *) NULL)
1187 ThrowProfileException(ImageError,"UnableToCreateColorTransform",
1190 Transform image as dictated by the source & target image profiles.
1192 length=(size_t) image->columns;
1193 source_pixels=AcquirePixelThreadSet(image->columns,source_channels);
1194 target_pixels=AcquirePixelThreadSet(image->columns,target_channels);
1195 if ((source_pixels == (unsigned short **) NULL) ||
1196 (target_pixels == (unsigned short **) NULL))
1198 transform=DestroyTransformThreadSet(transform);
1199 ThrowProfileException(ResourceLimitError,
1200 "MemoryAllocationFailed",image->filename);
1202 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1204 target_pixels=DestroyPixelThreadSet(target_pixels);
1205 source_pixels=DestroyPixelThreadSet(source_pixels);
1206 transform=DestroyTransformThreadSet(transform);
1207 if (source_profile != (cmsHPROFILE) NULL)
1208 (void) cmsCloseProfile(source_profile);
1209 if (target_profile != (cmsHPROFILE) NULL)
1210 (void) cmsCloseProfile(target_profile);
1211 return(MagickFalse);
1213 if (target_colorspace == CMYKColorspace)
1214 (void) SetImageColorspace(image,target_colorspace);
1217 image_view=AcquireCacheView(image);
1218 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1219 #pragma omp parallel for schedule(dynamic,4) shared(status)
1221 for (y=0; y < (long) image->rows; y++)
1226 register IndexPacket
1233 register PixelPacket
1236 register unsigned short
1239 if (status == MagickFalse)
1241 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1243 if (q == (PixelPacket *) NULL)
1248 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1249 id=GetOpenMPThreadId();
1250 p=source_pixels[id];
1251 for (x=0; x < (long) image->columns; x++)
1253 *p++=ScaleQuantumToShort(q->red);
1254 if (source_channels > 1)
1256 *p++=ScaleQuantumToShort(q->green);
1257 *p++=ScaleQuantumToShort(q->blue);
1259 if (source_channels > 3)
1260 *p++=ScaleQuantumToShort(indexes[x]);
1263 cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
1264 (unsigned int) image->columns);
1265 p=target_pixels[id];
1267 for (x=0; x < (long) image->columns; x++)
1269 q->red=ScaleShortToQuantum(*p);
1273 if (target_channels > 1)
1275 q->green=ScaleShortToQuantum(*p);
1277 q->blue=ScaleShortToQuantum(*p);
1280 if (target_channels > 3)
1282 indexes[x]=ScaleShortToQuantum(*p);
1287 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1288 if (sync == MagickFalse)
1290 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1295 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1296 #pragma omp critical (MagickCore_ProfileImage)
1298 proceed=SetImageProgress(image,ProfileImageTag,progress++,
1300 if (proceed == MagickFalse)
1304 image_view=DestroyCacheView(image_view);
1305 (void) SetImageColorspace(image,target_colorspace);
1310 image->type=image->matte == MagickFalse ? TrueColorType :
1314 case cmsSigCmykData:
1316 image->type=image->matte == MagickFalse ? ColorSeparationType :
1317 ColorSeparationMatteType;
1320 case cmsSigGrayData:
1322 image->type=image->matte == MagickFalse ? GrayscaleType :
1329 target_pixels=DestroyPixelThreadSet(target_pixels);
1330 source_pixels=DestroyPixelThreadSet(source_pixels);
1331 transform=DestroyTransformThreadSet(transform);
1332 if (cmsGetDeviceClass(source_profile) != cmsSigLinkClass)
1333 status=SetImageProfile(image,name,profile);
1334 if (target_profile != (cmsHPROFILE) NULL)
1335 (void) cmsCloseProfile(target_profile);
1337 (void) cmsCloseProfile(source_profile);
1341 profile=DestroyStringInfo(profile);
1346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1350 % R e m o v e I m a g e P r o f i l e %
1354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1356 % RemoveImageProfile() removes a named profile from the image and returns its
1359 % The format of the RemoveImageProfile method is:
1361 % void *RemoveImageProfile(Image *image,const char *name)
1363 % A description of each parameter follows:
1365 % o image: the image.
1367 % o name: the profile name.
1370 MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
1375 assert(image != (Image *) NULL);
1376 assert(image->signature == MagickSignature);
1377 if (image->debug != MagickFalse)
1378 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1379 if (image->profiles == (SplayTreeInfo *) NULL)
1380 return((StringInfo *) NULL);
1381 if (LocaleCompare(name,"icc") == 0)
1384 Continue to support deprecated color profile for now.
1386 image->color_profile.length=0;
1387 image->color_profile.info=(unsigned char *) NULL;
1389 if (LocaleCompare(name,"iptc") == 0)
1392 Continue to support deprecated IPTC profile for now.
1394 image->iptc_profile.length=0;
1395 image->iptc_profile.info=(unsigned char *) NULL;
1397 profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
1398 image->profiles,name);
1403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1407 % R e s e t P r o f i l e I t e r a t o r %
1411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1413 % ResetImageProfileIterator() resets the image profile iterator. Use it in
1414 % conjunction with GetNextImageProfile() to iterate over all the profiles
1415 % associated with an image.
1417 % The format of the ResetImageProfileIterator method is:
1419 % ResetImageProfileIterator(Image *image)
1421 % A description of each parameter follows:
1423 % o image: the image.
1426 MagickExport void ResetImageProfileIterator(const Image *image)
1428 assert(image != (Image *) NULL);
1429 assert(image->signature == MagickSignature);
1430 if (image->debug != MagickFalse)
1431 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1432 if (image->profiles == (SplayTreeInfo *) NULL)
1434 ResetSplayTreeIterator((SplayTreeInfo *) image->profiles);
1438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1442 % S e t I m a g e P r o f i l e %
1446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1448 % SetImageProfile() adds a named profile to the image. If a profile with the
1449 % same name already exists, it is replaced. This method differs from the
1450 % ProfileImage() method in that it does not apply CMS color profiles.
1452 % The format of the SetImageProfile method is:
1454 % MagickBooleanType SetImageProfile(Image *image,const char *name,
1455 % const StringInfo *profile)
1457 % A description of each parameter follows:
1459 % o image: the image.
1461 % o name: the profile name, for example icc, exif, and 8bim (8bim is the
1462 % Photoshop wrapper for iptc profiles).
1464 % o profile: A StringInfo structure that contains the named profile.
1468 static void *DestroyProfile(void *profile)
1470 return((void *) DestroyStringInfo((StringInfo *) profile));
1473 static inline const unsigned char *ReadResourceByte(const unsigned char *p,
1474 unsigned char *quantum)
1480 static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
1481 const ssize_t count,unsigned char *quantum)
1486 for (i=0; i < count; i++)
1491 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
1492 unsigned long *quantum)
1494 *quantum=(unsigned long) (*p++ << 24);
1495 *quantum|=(unsigned long) (*p++ << 16);
1496 *quantum|=(unsigned long) (*p++ << 8);
1497 *quantum|=(unsigned long) (*p++ << 0);
1501 static inline const unsigned char *ReadResourceShort(const unsigned char *p,
1502 unsigned short *quantum)
1504 *quantum=(unsigned short) (*p++ << 8);
1505 *quantum|=(unsigned short) (*p++ << 0);
1509 static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
1510 const StringInfo *resource_block)
1515 register const unsigned char
1533 datum=GetStringInfoDatum(resource_block);
1534 length=GetStringInfoLength(resource_block);
1535 for (p=datum; p < (datum+length-16); )
1537 if (LocaleNCompare((char *) p,"8BIM",4) != 0)
1540 p=ReadResourceShort(p,&id);
1541 p=ReadResourceByte(p,&length_byte);
1543 if (((length_byte+1) & 0x01) != 0)
1545 if (p > (datum+length-4))
1547 p=ReadResourceLong(p,&count);
1548 if ((p > (datum+length-count)) || (count > length))
1560 p=ReadResourceShort(p,&resolution)+6;
1561 image->x_resolution=(double) resolution;
1562 p=ReadResourceShort(p,&resolution)+6;
1563 image->y_resolution=(double) resolution;
1571 profile=AcquireStringInfo(count);
1572 SetStringInfoDatum(profile,p);
1573 (void) SetImageProfile(image,"iptc",profile);
1574 profile=DestroyStringInfo(profile);
1591 profile=AcquireStringInfo(count);
1592 SetStringInfoDatum(profile,p);
1593 (void) SetImageProfile(image,"icc",profile);
1594 profile=DestroyStringInfo(profile);
1603 profile=AcquireStringInfo(count);
1604 SetStringInfoDatum(profile,p);
1605 (void) SetImageProfile(image,"exif",profile);
1606 profile=DestroyStringInfo(profile);
1615 profile=AcquireStringInfo(count);
1616 SetStringInfoDatum(profile,p);
1617 (void) SetImageProfile(image,"xmp",profile);
1618 profile=DestroyStringInfo(profile);
1628 if ((count & 0x01) != 0)
1634 MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
1635 const StringInfo *profile)
1639 property[MaxTextExtent];
1644 assert(image != (Image *) NULL);
1645 assert(image->signature == MagickSignature);
1646 if (image->debug != MagickFalse)
1647 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1648 if (image->profiles == (SplayTreeInfo *) NULL)
1649 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1651 (void) CopyMagickString(key,name,MaxTextExtent);
1652 status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
1653 ConstantString(key),CloneStringInfo(profile));
1654 if ((status != MagickFalse) &&
1655 ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0)))
1661 Continue to support deprecated color profile member.
1663 icc_profile=GetImageProfile(image,name);
1664 if (icc_profile != (const StringInfo *) NULL)
1666 image->color_profile.length=GetStringInfoLength(icc_profile);
1667 image->color_profile.info=GetStringInfoDatum(icc_profile);
1670 if ((status != MagickFalse) &&
1671 ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
1677 Continue to support deprecated IPTC profile member.
1679 iptc_profile=GetImageProfile(image,name);
1680 if (iptc_profile != (const StringInfo *) NULL)
1682 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1683 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1685 (void) GetProfilesFromResourceBlock(image,profile);
1688 Inject profile into image properties.
1690 (void) FormatMagickString(property,MaxTextExtent,"%s:sans",name);
1691 (void) GetImageProperty(image,property);
1696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1700 % S y n c I m a g e P r o f i l e s %
1704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1706 % SyncImageProfiles() synchronizes image properties with the image profiles.
1707 % Currently we only support updating the EXIF resolution and orientation.
1709 % The format of the SyncImageProfiles method is:
1711 % MagickBooleanType SyncImageProfiles(Image *image)
1713 % A description of each parameter follows:
1715 % o image: the image.
1719 static inline int ReadProfileByte(unsigned char **p,size_t *length)
1731 static inline unsigned short ReadProfileShort(const EndianType endian,
1732 unsigned char *buffer)
1737 if (endian == MSBEndian)
1739 value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
1740 ((unsigned char *) buffer)[1]);
1741 return((unsigned short) (value & 0xffff));
1743 value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
1744 return((unsigned short) (value & 0xffff));
1747 static inline unsigned long ReadProfileLong(const EndianType endian,
1748 unsigned char *buffer)
1753 if (endian == MSBEndian)
1755 value=(unsigned long) ((buffer[0] << 24) | (buffer[1] << 16) |
1756 (buffer[2] << 8) | buffer[3]);
1757 return((unsigned long) (value & 0xffffffff));
1759 value=(unsigned long) ((buffer[3] << 24) | (buffer[2] << 16) |
1760 (buffer[1] << 8 ) | (buffer[0]));
1761 return((unsigned long) (value & 0xffffffff));
1764 static inline void WriteProfileLong(const EndianType endian,
1765 const unsigned long value,unsigned char *p)
1770 if (endian == MSBEndian)
1772 buffer[0]=(unsigned char) (value >> 24);
1773 buffer[1]=(unsigned char) (value >> 16);
1774 buffer[2]=(unsigned char) (value >> 8);
1775 buffer[3]=(unsigned char) value;
1776 (void) CopyMagickMemory(p,buffer,4);
1779 buffer[0]=(unsigned char) value;
1780 buffer[1]=(unsigned char) (value >> 8);
1781 buffer[2]=(unsigned char) (value >> 16);
1782 buffer[3]=(unsigned char) (value >> 24);
1783 (void) CopyMagickMemory(p,buffer,4);
1786 static void WriteProfileShort(const EndianType endian,
1787 const unsigned short value,unsigned char *p)
1792 if (endian == MSBEndian)
1794 buffer[0]=(unsigned char) (value >> 8);
1795 buffer[1]=(unsigned char) value;
1796 (void) CopyMagickMemory(p,buffer,2);
1799 buffer[0]=(unsigned char) value;
1800 buffer[1]=(unsigned char) (value >> 8);
1801 (void) CopyMagickMemory(p,buffer,2);
1804 MagickExport MagickBooleanType SyncImageProfiles(Image *image)
1806 #define MaxDirectoryStack 16
1807 #define EXIF_DELIMITER "\n"
1808 #define EXIF_NUM_FORMATS 12
1809 #define TAG_EXIF_OFFSET 0x8769
1810 #define TAG_INTEROP_OFFSET 0xa005
1812 typedef struct _DirectoryInfo
1822 directory_stack[MaxDirectoryStack];
1838 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
1852 Set EXIF resolution tag.
1854 profile=(StringInfo *) GetImageProfile(image,"EXIF");
1855 if (profile == (StringInfo *) NULL)
1857 length=GetStringInfoLength(profile);
1858 exif=GetStringInfoDatum(profile);
1861 if (ReadProfileByte(&exif,&length) != 0x45)
1863 if (ReadProfileByte(&exif,&length) != 0x78)
1865 if (ReadProfileByte(&exif,&length) != 0x69)
1867 if (ReadProfileByte(&exif,&length) != 0x66)
1869 if (ReadProfileByte(&exif,&length) != 0x00)
1871 if (ReadProfileByte(&exif,&length) != 0x00)
1876 return(MagickFalse);
1877 id=(int) ReadProfileShort(LSBEndian,exif);
1885 return(MagickFalse);
1886 if (ReadProfileShort(endian,exif+2) != 0x002a)
1887 return(MagickFalse);
1889 This the offset to the first IFD.
1891 offset=(ssize_t) ReadProfileLong(endian,exif+4);
1892 if ((size_t) offset >= length)
1893 return(MagickFalse);
1894 directory=exif+offset;
1902 directory=directory_stack[level].directory;
1903 entry=directory_stack[level].entry;
1906 Determine how many entries there are in the current IFD.
1908 number_entries=ReadProfileShort(endian,directory);
1909 for ( ; entry < number_entries; entry++)
1916 register unsigned char
1923 q=(unsigned char *) (directory+2+(12*entry));
1924 tag_value=(long) ReadProfileShort(endian,q);
1925 format=(long) ReadProfileShort(endian,q+2);
1926 if ((format-1) >= EXIF_NUM_FORMATS)
1928 components=(long) ReadProfileLong(endian,q+4);
1929 number_bytes=(size_t) components*format_bytes[format];
1930 if (number_bytes <= 4)
1938 The directory entry contains an offset.
1940 offset=(ssize_t) ReadProfileLong(endian,q+8);
1941 if ((size_t) (offset+number_bytes) > length)
1943 p=(unsigned char *) (exif+offset);
1949 (void) WriteProfileLong(endian,(unsigned long)
1950 (image->x_resolution+0.5),p);
1951 (void) WriteProfileLong(endian,1UL,p+4);
1956 (void) WriteProfileLong(endian,(unsigned long)
1957 (image->y_resolution+0.5),p);
1958 (void) WriteProfileLong(endian,1UL,p+4);
1963 (void) WriteProfileShort(endian,(unsigned short)
1964 image->orientation,p);
1969 (void) WriteProfileShort(endian,(unsigned short)
1970 (image->units+1),p);
1976 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
1981 offset=(size_t) ReadProfileLong(endian,p);
1982 if ((offset < length) && (level < (MaxDirectoryStack-2)))
1984 directory_stack[level].directory=directory;
1986 directory_stack[level].entry=entry;
1988 directory_stack[level].directory=exif+offset;
1989 directory_stack[level].entry=0;
1991 if ((directory+2+(12*number_entries)) > (exif+length))
1993 offset=(size_t) ReadProfileLong(endian,directory+2+(12*
1995 if ((offset != 0) && (offset < length) &&
1996 (level < (MaxDirectoryStack-2)))
1998 directory_stack[level].directory=exif+offset;
1999 directory_stack[level].entry=0;
2006 } while (level > 0);