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>
78 * Define declarations.
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
94 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98 % C l o n e I m a g e P r o f i l e s %
102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 % CloneImageProfiles() clones one or more image profiles.
106 % The format of the CloneImageProfiles method is:
108 % MagickBooleanType CloneImageProfiles(Image *image,
109 % const Image *clone_image)
111 % A description of each parameter follows:
113 % o image: the image.
115 % o clone_image: the clone image.
118 MagickExport MagickBooleanType CloneImageProfiles(Image *image,
119 const Image *clone_image)
121 assert(image != (Image *) NULL);
122 assert(image->signature == MagickSignature);
123 if (image->debug != MagickFalse)
124 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
125 assert(clone_image != (const Image *) NULL);
126 assert(clone_image->signature == MagickSignature);
127 image->color_profile.length=clone_image->color_profile.length;
128 image->color_profile.info=clone_image->color_profile.info;
129 image->iptc_profile.length=clone_image->iptc_profile.length;
130 image->iptc_profile.info=clone_image->iptc_profile.info;
131 if (clone_image->profiles != (void *) NULL)
132 image->profiles=CloneSplayTree((SplayTreeInfo *) clone_image->profiles,
133 (void *(*)(void *)) ConstantString,(void *(*)(void *)) CloneStringInfo);
138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 % D e l e t e I m a g e P r o f i l e %
146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
148 % DeleteImageProfile() deletes a profile from the image by its name.
150 % The format of the DeleteImageProfile method is:
152 % MagickBooleanTyupe DeleteImageProfile(Image *image,const char *name)
154 % A description of each parameter follows:
156 % o image: the image.
158 % o name: the profile name.
161 MagickExport MagickBooleanType DeleteImageProfile(Image *image,const char *name)
163 assert(image != (Image *) NULL);
164 assert(image->signature == MagickSignature);
165 if (image->debug != MagickFalse)
166 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
167 if (image->profiles == (SplayTreeInfo *) NULL)
169 if (LocaleCompare(name,"icc") == 0)
172 Continue to support deprecated color profile for now.
174 image->color_profile.length=0;
175 image->color_profile.info=(unsigned char *) NULL;
177 if (LocaleCompare(name,"iptc") == 0)
180 Continue to support deprecated IPTC profile for now.
182 image->iptc_profile.length=0;
183 image->iptc_profile.info=(unsigned char *) NULL;
185 return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->profiles,name));
189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193 % D e s t r o y I m a g e P r o f i l e s %
197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199 % DestroyImageProfiles() releases memory associated with an image profile map.
201 % The format of the DestroyProfiles method is:
203 % void DestroyImageProfiles(Image *image)
205 % A description of each parameter follows:
207 % o image: the image.
210 MagickExport void DestroyImageProfiles(Image *image)
212 if (image->profiles != (SplayTreeInfo *) NULL)
213 image->profiles=DestroySplayTree((SplayTreeInfo *) image->profiles);
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 % G e t I m a g e P r o f i l e %
225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 % GetImageProfile() gets a profile associated with an image by name.
229 % The format of the GetImageProfile method is:
231 % const StringInfo *GetImageProfile(const Image *image,const char *name)
233 % A description of each parameter follows:
235 % o image: the image.
237 % o name: the profile name.
240 MagickExport const StringInfo *GetImageProfile(const Image *image,
249 assert(image != (Image *) NULL);
250 assert(image->signature == MagickSignature);
251 if (image->debug != MagickFalse)
252 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
253 if (image->profiles == (SplayTreeInfo *) NULL)
254 return((StringInfo *) NULL);
255 (void) CopyMagickString(key,name,MaxTextExtent);
256 profile=(const StringInfo *) GetValueFromSplayTree((SplayTreeInfo *)
257 image->profiles,key);
262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 % G e t N e x t I m a g e P r o f i l e %
270 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272 % GetNextImageProfile() gets the next profile name for an image.
274 % The format of the GetNextImageProfile method is:
276 % char *GetNextImageProfile(const Image *image)
278 % A description of each parameter follows:
280 % o hash_info: the hash info.
283 MagickExport char *GetNextImageProfile(const Image *image)
285 assert(image != (Image *) NULL);
286 assert(image->signature == MagickSignature);
287 if (image->debug != MagickFalse)
288 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
289 if (image->profiles == (SplayTreeInfo *) NULL)
290 return((char *) NULL);
291 return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->profiles));
295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299 % P r o f i l e I m a g e %
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 % ProfileImage() associates, applies, or removes an ICM, IPTC, or generic
306 % profile with / to / from an image. If the profile is NULL, it is removed
307 % from the image otherwise added or applied. Use a name of '*' and a profile
308 % of NULL to remove all profiles from the image.
310 % ICC and ICM profiles are handled as follows: If the image does not have
311 % an associated color profile, the one you provide is associated with the
312 % image and the image pixels are not transformed. Otherwise, the colorspace
313 % transform defined by the existing and new profile are applied to the image
314 % pixels and the new profile is associated with the image.
316 % The format of the ProfileImage method is:
318 % MagickBooleanType ProfileImage(Image *image,const char *name,
319 % const void *datum,const size_t length,const MagickBooleanType clone)
321 % A description of each parameter follows:
323 % o image: the image.
325 % o name: Name of profile to add or remove: ICC, IPTC, or generic profile.
327 % o datum: the profile data.
329 % o length: the length of the profile.
331 % o clone: should be MagickFalse.
335 #if defined(MAGICKCORE_LCMS_DELEGATE)
337 static unsigned short **DestroyPixelThreadSet(unsigned short **pixels)
342 assert(pixels != (unsigned short **) NULL);
343 for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
344 if (pixels[i] != (unsigned short *) NULL)
345 pixels[i]=(unsigned short *) RelinquishMagickMemory(pixels[i]);
346 pixels=(unsigned short **) RelinquishAlignedMemory(pixels);
350 static unsigned short **AcquirePixelThreadSet(const size_t columns,
351 const size_t channels)
362 number_threads=GetOpenMPMaximumThreads();
363 pixels=(unsigned short **) AcquireAlignedMemory(number_threads,
365 if (pixels == (unsigned short **) NULL)
366 return((unsigned short **) NULL);
367 (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels));
368 for (i=0; i < (long) number_threads; i++)
370 pixels[i]=(unsigned short *) AcquireQuantumMemory(columns,channels*
372 if (pixels[i] == (unsigned short *) NULL)
373 return(DestroyPixelThreadSet(pixels));
378 static cmsHTRANSFORM *DestroyTransformThreadSet(cmsHTRANSFORM *transform)
383 assert(transform != (cmsHTRANSFORM *) NULL);
384 for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
385 if (transform[i] != (cmsHTRANSFORM) NULL)
386 cmsDeleteTransform(transform[i]);
387 transform=(cmsHTRANSFORM *) RelinquishAlignedMemory(transform);
391 static cmsHTRANSFORM *AcquireTransformThreadSet(
392 const cmsHPROFILE source_profile,const cmsUInt32Number source_type,
393 const cmsHPROFILE target_profile,const cmsUInt32Number target_type,
394 const int intent,const cmsUInt32Number flags)
405 number_threads=GetOpenMPMaximumThreads();
406 transform=(cmsHTRANSFORM *) AcquireAlignedMemory(number_threads,
408 if (transform == (cmsHTRANSFORM *) NULL)
409 return((cmsHTRANSFORM *) NULL);
410 (void) ResetMagickMemory(transform,0,number_threads*sizeof(*transform));
411 for (i=0; i < (long) number_threads; i++)
413 transform[i]=cmsCreateTransform(source_profile,source_type,target_profile,
414 target_type,intent,flags);
415 if (transform[i] == (cmsHTRANSFORM) NULL)
416 return(DestroyTransformThreadSet(transform));
422 static MagickBooleanType SetAdobeRGB1998ImageProfile(Image *image)
425 AdobeRGB1998Profile[] =
427 0x00, 0x00, 0x02, 0x30, 0x41, 0x44, 0x42, 0x45, 0x02, 0x10, 0x00,
428 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
429 0x5a, 0x20, 0x07, 0xd0, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x13, 0x00,
430 0x33, 0x00, 0x3b, 0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c,
431 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
434 0x00, 0xd3, 0x2d, 0x41, 0x44, 0x42, 0x45, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x0a,
439 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
440 0x32, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00,
441 0x00, 0x6b, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x9c, 0x00,
442 0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x01, 0xb0,
443 0x00, 0x00, 0x00, 0x14, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01,
444 0xc4, 0x00, 0x00, 0x00, 0x0e, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00,
445 0x01, 0xd4, 0x00, 0x00, 0x00, 0x0e, 0x62, 0x54, 0x52, 0x43, 0x00,
446 0x00, 0x01, 0xe4, 0x00, 0x00, 0x00, 0x0e, 0x72, 0x58, 0x59, 0x5a,
447 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59,
448 0x5a, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58,
449 0x59, 0x5a, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x14, 0x74,
450 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79,
451 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20,
452 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65,
453 0x6d, 0x73, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72,
454 0x61, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63,
455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x41, 0x64, 0x6f,
456 0x62, 0x65, 0x20, 0x52, 0x47, 0x42, 0x20, 0x28, 0x31, 0x39, 0x39,
457 0x38, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459 0x00, 0x00, 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, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00,
466 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x00, 0x01, 0x02, 0x33, 0x00, 0x00, 0x63, 0x75, 0x72, 0x76, 0x00,
470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33, 0x00, 0x00,
471 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472 0x01, 0x02, 0x33, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, 0x00, 0x00, 0x4f, 0xa5, 0x00,
474 0x00, 0x04, 0xfc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
475 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, 0x00, 0x00, 0x0f,
476 0x95, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x26, 0x31, 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9c
486 assert(image != (Image *) NULL);
487 assert(image->signature == MagickSignature);
488 if (GetImageProfile(image,"icm") != (const StringInfo *) NULL)
490 profile=AcquireStringInfo(sizeof(AdobeRGB1998Profile));
491 SetStringInfoDatum(profile,AdobeRGB1998Profile);
492 status=SetImageProfile(image,"icm",profile);
493 profile=DestroyStringInfo(profile);
497 static MagickBooleanType SetsRGBImageProfile(Image *image)
502 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
503 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
504 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
505 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
506 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
507 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
509 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x11,
514 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00,
515 0x33, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00,
516 0x00, 0x6c, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0xf0, 0x00,
517 0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04,
518 0x00, 0x00, 0x00, 0x14, 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02,
519 0x18, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00,
520 0x02, 0x2c, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58, 0x59, 0x5a, 0x00,
521 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, 0x64, 0x6d, 0x6e, 0x64,
522 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70, 0x64, 0x6d, 0x64,
523 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, 0x76, 0x75,
524 0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x76,
525 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24,
526 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00,
527 0x14, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00,
528 0x00, 0x24, 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, 0x00,
529 0x00, 0x00, 0x0c, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c,
530 0x00, 0x00, 0x08, 0x0c, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04,
531 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x62, 0x54, 0x52, 0x43, 0x00, 0x00,
532 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x74, 0x65, 0x78, 0x74, 0x00,
533 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
534 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20,
535 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74, 0x74, 0x2d, 0x50, 0x61, 0x63,
536 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e,
537 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45,
539 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
541 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39,
542 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58,
549 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a,
551 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00,
552 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, 0x00,
553 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, 0x00, 0x00, 0xb7, 0x85,
554 0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00,
556 0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
558 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
559 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
561 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
562 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 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, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31,
568 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, 0x65, 0x66,
569 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, 0x6f,
570 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
571 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20,
573 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
574 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20,
575 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63,
576 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73,
579 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
580 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
581 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
582 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
583 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
585 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
586 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
587 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
588 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
592 0xa4, 0xfe, 0x00, 0x14, 0x5f, 0x2e, 0x00, 0x10, 0xcf, 0x14, 0x00,
593 0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, 0x00, 0x03, 0x5c, 0x9e,
594 0x00, 0x00, 0x00, 0x01, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, 0x00, 0x57,
596 0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
599 0x8f, 0x00, 0x00, 0x00, 0x02, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00,
600 0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05,
602 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00,
603 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b,
604 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54, 0x00,
605 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
606 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00,
607 0x90, 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9,
608 0x00, 0xae, 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00,
609 0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0,
610 0x00, 0xe5, 0x00, 0xeb, 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01,
611 0x01, 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f,
612 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, 0x01, 0x38, 0x01, 0x3e, 0x01,
613 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67,
614 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, 0x01, 0x8b, 0x01,
615 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9,
616 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, 0x01,
617 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
618 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02,
619 0x4b, 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a,
620 0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02,
621 0xb6, 0x02, 0xc1, 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb,
622 0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03,
623 0x2d, 0x03, 0x38, 0x03, 0x43, 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66,
624 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, 0x03,
625 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, 0x03, 0xe0, 0x03, 0xec,
626 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04,
627 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, 0x04, 0x7e,
628 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4, 0x04,
629 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
630 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05,
631 0x77, 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5,
632 0x05, 0xd5, 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06,
633 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b,
634 0x06, 0x8c, 0x06, 0x9d, 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06,
635 0xe3, 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d,
636 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, 0x07, 0x86, 0x07, 0x99, 0x07,
637 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b,
638 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, 0x08, 0x6e, 0x08,
639 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7,
640 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, 0x09,
641 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
642 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a,
643 0x54, 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5,
644 0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b,
645 0x51, 0x0b, 0x69, 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8,
646 0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c,
647 0x5c, 0x0c, 0x75, 0x0c, 0x8e, 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9,
648 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, 0x0d,
649 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, 0x0d, 0xde, 0x0d, 0xf8,
650 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e,
651 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, 0x0f, 0x25,
652 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3, 0x0f,
653 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
654 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11,
655 0x13, 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa,
656 0x11, 0xc9, 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12,
657 0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03,
658 0x13, 0x23, 0x13, 0x43, 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13,
659 0xc5, 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a,
660 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, 0x14, 0xf0, 0x15, 0x12, 0x15,
661 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0,
662 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, 0x16, 0x8f, 0x16,
663 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65,
664 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, 0x18,
665 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
666 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19,
667 0xdd, 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e,
668 0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b,
669 0x8a, 0x1b, 0xb2, 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52,
670 0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d,
671 0x47, 0x1d, 0x70, 0x1d, 0x99, 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16,
672 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, 0x1f,
673 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, 0x1f, 0xbf, 0x1f, 0xea,
674 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20,
675 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, 0x21, 0xce,
676 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf, 0x22,
677 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
678 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24,
679 0xda, 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7,
680 0x25, 0xf7, 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26,
681 0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc,
682 0x28, 0x0d, 0x28, 0x3f, 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29,
683 0x06, 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02,
684 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, 0x2a, 0xcf, 0x2b, 0x02, 0x2b,
685 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39,
686 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, 0x2d, 0x41, 0x2d,
687 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82,
688 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, 0x2f,
689 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
690 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32,
691 0x2a, 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46,
692 0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34,
693 0x9e, 0x34, 0xd8, 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2,
694 0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37,
695 0x24, 0x37, 0x60, 0x37, 0x9c, 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50,
696 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, 0x39,
697 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, 0x3a, 0xb2, 0x3a, 0xef,
698 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c,
699 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, 0x3d, 0xa1,
700 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0, 0x3f,
701 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
702 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41,
703 0xee, 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a,
704 0x43, 0x7d, 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44,
705 0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22,
706 0x46, 0x67, 0x46, 0xab, 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47,
707 0xc0, 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d,
708 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, 0x4a, 0x37, 0x4a, 0x7d, 0x4a,
709 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a,
710 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, 0x4d, 0x93, 0x4d,
711 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49,
712 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, 0x51,
713 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
714 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54,
715 0x42, 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2,
716 0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57,
717 0x92, 0x57, 0xe0, 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a,
718 0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a,
719 0xf5, 0x5b, 0x45, 0x5b, 0x95, 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86,
720 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, 0x5e,
721 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, 0x5f, 0xb3, 0x60, 0x05,
722 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61,
723 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, 0x63, 0x97,
724 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d, 0x65,
725 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
726 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69,
727 0x43, 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7,
728 0x6b, 0x4f, 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d,
729 0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4,
730 0x6f, 0x1e, 0x6f, 0x78, 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70,
731 0xe0, 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6,
732 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, 0x74, 0x14, 0x74, 0x70, 0x74,
733 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b,
734 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, 0x78, 0x6e, 0x78,
735 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5,
736 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, 0x7c,
737 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
738 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81,
739 0x0a, 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4,
740 0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85,
741 0x47, 0x85, 0xab, 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b,
742 0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89,
743 0x99, 0x89, 0xfe, 0x8a, 0x64, 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96,
744 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, 0x8d,
745 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, 0x8f, 0x9e, 0x90, 0x06,
746 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92,
747 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, 0x94, 0x8a,
748 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f, 0x97,
749 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
750 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b,
751 0xaf, 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2,
752 0x9e, 0x40, 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0,
753 0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96,
754 0xa3, 0x06, 0xa3, 0x76, 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5,
755 0x38, 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e,
756 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, 0xa9, 0x37, 0xa9, 0xa9, 0xaa,
757 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c,
758 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, 0xae, 0xa1, 0xaf,
759 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60,
760 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, 0xb4,
761 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
762 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9,
763 0x4a, 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7,
764 0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe,
765 0x84, 0xbe, 0xff, 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec,
766 0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3,
767 0xd4, 0xc4, 0x51, 0xc4, 0xce, 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46,
768 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, 0xc9,
769 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, 0xcb, 0x36, 0xcb, 0xb6,
770 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce,
771 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, 0xd1, 0x3c,
772 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6, 0xd4,
773 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
774 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9,
775 0xf1, 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a,
776 0xdd, 0x10, 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf,
777 0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53,
778 0xe2, 0xdb, 0xe3, 0x63, 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5,
779 0x84, 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32,
780 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, 0xea, 0x5b, 0xea, 0xe5, 0xeb,
781 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28,
782 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, 0xf0, 0xe5, 0xf1,
783 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34,
784 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, 0xf7,
785 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
786 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd,
787 0xba, 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
796 assert(image != (Image *) NULL);
797 assert(image->signature == MagickSignature);
798 if (GetImageProfile(image,"icm") != (const StringInfo *) NULL)
800 profile=AcquireStringInfo(sizeof(sRGBProfile));
801 SetStringInfoDatum(profile,sRGBProfile);
802 status=SetImageProfile(image,"icm",profile);
803 profile=DestroyStringInfo(profile);
806 #if defined(MAGICKCORE_LCMS_DELEGATE)
807 #if defined(LCMS_VERSION) && (LCMS_VERSION >= 2000)
808 static void LCMSErrorHandler(cmsContext context,int severity,
811 (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%d, %s",
812 severity,message != (char *) NULL ? message : "no message");
815 #if defined(LCMS_VERSION) && (LCMS_VERSION < 2000)
816 #if defined(LCMS_VERSION) && (LCMS_VERSION > 1010)
817 static int LCMSErrorHandler(int severity,const char *message)
819 (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%d, %s",
820 severity,message != (char *) NULL ? message : "no message");
827 MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
828 const void *datum,const size_t length,
829 const MagickBooleanType magick_unused(clone))
831 #define ProfileImageTag "Profile/Image"
832 #define ThrowProfileException(severity,tag,context) \
834 (void) cmsCloseProfile(source_profile); \
835 (void) cmsCloseProfile(target_profile); \
836 ThrowBinaryException(severity,tag,context); \
845 assert(image != (Image *) NULL);
846 assert(image->signature == MagickSignature);
847 if (image->debug != MagickFalse)
848 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
849 assert(name != (const char *) NULL);
850 if ((datum == (const void *) NULL) || (length == 0))
863 Delete image profile(s).
865 names=ConstantString(name);
866 (void) SubstituteString(&names,","," ");
867 arguments=StringToArgv(names,&number_arguments);
868 names=DestroyString(names);
869 if (arguments == (char **) NULL)
871 ResetImageProfileIterator(image);
872 for (name=GetNextImageProfile(image); name != (const char *) NULL; )
874 for (i=1; i < number_arguments; i++)
876 if ((*arguments[i] == '!') &&
877 (LocaleCompare(name,arguments[i]+1) == 0))
879 if (GlobExpression(name,arguments[i],MagickTrue) != MagickFalse)
881 (void) DeleteImageProfile(image,name);
882 ResetImageProfileIterator(image);
886 name=GetNextImageProfile(image);
888 for (i=0; i < number_arguments; i++)
889 arguments[i]=DestroyString(arguments[i]);
890 arguments=(char **) RelinquishMagickMemory(arguments);
894 Add a ICC, IPTC, or generic profile to the image.
896 profile=AcquireStringInfo((size_t) length);
897 SetStringInfoDatum(profile,(unsigned char *) datum);
898 if ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0))
903 icc_profile=GetImageProfile(image,"icc");
904 if ((icc_profile != (const StringInfo *) NULL) &&
905 (CompareStringInfo(icc_profile,profile) == 0))
910 value=GetImageProperty(image,"exif:ColorSpace");
911 if (LocaleCompare(value,"1") != 0)
912 (void) SetsRGBImageProfile(image);
913 value=GetImageProperty(image,"exif:InteroperabilityIndex");
914 if (LocaleCompare(value,"R98.") != 0)
915 (void) SetsRGBImageProfile(image);
916 value=GetImageProperty(image,"exif:InteroperabilityIndex");
917 if (LocaleCompare(value,"R03.") != 0)
918 (void) SetAdobeRGB1998ImageProfile(image);
919 icc_profile=GetImageProfile(image,"icc");
921 if ((icc_profile != (const StringInfo *) NULL) &&
922 (CompareStringInfo(icc_profile,profile) == 0))
924 profile=DestroyStringInfo(profile);
927 #if !defined(MAGICKCORE_LCMS_DELEGATE)
928 (void) ThrowMagickException(&image->exception,GetMagickModule(),
929 MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","`%s' (LCMS)",
932 if (icc_profile != (StringInfo *) NULL)
972 **restrict source_pixels,
973 **restrict target_pixels;
976 Transform pixel colors as defined by the color profiles.
978 #if defined(LCMS_VERSION) && (LCMS_VERSION >= 2000)
979 cmsSetLogErrorHandler(LCMSErrorHandler);
981 #if defined(LCMS_VERSION) && (LCMS_VERSION < 2000)
982 #if defined(LCMS_VERSION) && (LCMS_VERSION > 1010)
983 cmsSetErrorHandler(LCMSErrorHandler);
985 (void) cmsErrorAction(LCMS_ERROR_SHOW);
988 source_profile=cmsOpenProfileFromMem(GetStringInfoDatum(icc_profile),
989 (cmsUInt32Number) GetStringInfoLength(icc_profile));
990 target_profile=cmsOpenProfileFromMem(GetStringInfoDatum(profile),
991 (cmsUInt32Number) GetStringInfoLength(profile));
992 if ((source_profile == (cmsHPROFILE) NULL) ||
993 (target_profile == (cmsHPROFILE) NULL))
994 ThrowBinaryException(ResourceLimitError,
995 "ColorspaceColorProfileMismatch",name);
996 switch (cmsGetColorSpace(source_profile))
1000 source_colorspace=CMYKColorspace;
1001 source_type=(cmsUInt32Number) TYPE_CMYK_16;
1005 case cmsSigGrayData:
1007 source_colorspace=GRAYColorspace;
1008 source_type=(cmsUInt32Number) TYPE_GRAY_16;
1014 source_colorspace=LabColorspace;
1015 source_type=(cmsUInt32Number) TYPE_Lab_16;
1021 source_colorspace=YUVColorspace;
1022 source_type=(cmsUInt32Number) TYPE_YUV_16;
1028 source_colorspace=RGBColorspace;
1029 source_type=(cmsUInt32Number) TYPE_RGB_16;
1035 source_colorspace=XYZColorspace;
1036 source_type=(cmsUInt32Number) TYPE_XYZ_16;
1040 case cmsSigYCbCrData:
1042 source_colorspace=YCbCrColorspace;
1043 source_type=(cmsUInt32Number) TYPE_YCbCr_16;
1049 source_colorspace=UndefinedColorspace;
1050 source_type=(cmsUInt32Number) TYPE_RGB_16;
1055 switch (cmsGetColorSpace(target_profile))
1057 case cmsSigCmykData:
1059 target_colorspace=CMYKColorspace;
1060 target_type=(cmsUInt32Number) TYPE_CMYK_16;
1066 target_colorspace=LabColorspace;
1067 target_type=(cmsUInt32Number) TYPE_Lab_16;
1071 case cmsSigGrayData:
1073 target_colorspace=GRAYColorspace;
1074 target_type=(cmsUInt32Number) TYPE_GRAY_16;
1080 target_colorspace=YUVColorspace;
1081 target_type=(cmsUInt32Number) TYPE_YUV_16;
1087 target_colorspace=RGBColorspace;
1088 target_type=(cmsUInt32Number) TYPE_RGB_16;
1094 target_colorspace=XYZColorspace;
1095 target_type=(cmsUInt32Number) TYPE_XYZ_16;
1099 case cmsSigYCbCrData:
1101 target_colorspace=YCbCrColorspace;
1102 target_type=(cmsUInt32Number) TYPE_YCbCr_16;
1108 target_colorspace=UndefinedColorspace;
1109 target_type=(cmsUInt32Number) TYPE_RGB_16;
1114 exception=(&image->exception);
1115 if ((source_colorspace == UndefinedColorspace) ||
1116 (target_colorspace == UndefinedColorspace))
1117 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1119 if ((source_colorspace == GRAYColorspace) &&
1120 (IsGrayImage(image,exception) == MagickFalse))
1121 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1123 if ((source_colorspace == CMYKColorspace) &&
1124 (image->colorspace != CMYKColorspace))
1125 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1127 if ((source_colorspace == XYZColorspace) &&
1128 (image->colorspace != XYZColorspace))
1129 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1131 if ((source_colorspace == YCbCrColorspace) &&
1132 (image->colorspace != YCbCrColorspace))
1133 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1135 if ((source_colorspace != CMYKColorspace) &&
1136 (source_colorspace != GRAYColorspace) &&
1137 (source_colorspace != LabColorspace) &&
1138 (source_colorspace != XYZColorspace) &&
1139 (source_colorspace != YCbCrColorspace) &&
1140 (image->colorspace != RGBColorspace))
1141 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
1143 switch (image->rendering_intent)
1145 case AbsoluteIntent: intent=INTENT_ABSOLUTE_COLORIMETRIC; break;
1146 case PerceptualIntent: intent=INTENT_PERCEPTUAL; break;
1147 case RelativeIntent: intent=INTENT_RELATIVE_COLORIMETRIC; break;
1148 case SaturationIntent: intent=INTENT_SATURATION; break;
1149 default: intent=INTENT_PERCEPTUAL; break;
1151 flags=cmsFLAGS_HIGHRESPRECALC;
1152 #if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1153 if (image->black_point_compensation != MagickFalse)
1154 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1156 transform=AcquireTransformThreadSet(source_profile,source_type,
1157 target_profile,target_type,intent,flags);
1158 (void) cmsCloseProfile(source_profile);
1159 if (transform == (cmsHTRANSFORM *) NULL)
1160 ThrowBinaryException(ImageError,"UnableToCreateColorTransform",
1163 Transform image as dictated by the source and target image profiles.
1165 length=(size_t) image->columns;
1166 source_pixels=AcquirePixelThreadSet(image->columns,source_channels);
1167 target_pixels=AcquirePixelThreadSet(image->columns,target_channels);
1168 if ((source_pixels == (unsigned short **) NULL) ||
1169 (target_pixels == (unsigned short **) NULL))
1171 transform=DestroyTransformThreadSet(transform);
1172 (void) cmsCloseProfile(target_profile);
1173 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1176 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1178 target_pixels=DestroyPixelThreadSet(target_pixels);
1179 source_pixels=DestroyPixelThreadSet(source_pixels);
1180 transform=DestroyTransformThreadSet(transform);
1181 (void) cmsCloseProfile(target_profile);
1182 return(MagickFalse);
1184 if (target_colorspace == CMYKColorspace)
1185 (void) SetImageColorspace(image,target_colorspace);
1188 image_view=AcquireCacheView(image);
1189 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1190 #pragma omp parallel for schedule(dynamic,4) shared(status)
1192 for (y=0; y < (long) image->rows; y++)
1197 register IndexPacket
1204 register PixelPacket
1207 register unsigned short
1210 if (status == MagickFalse)
1212 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1214 if (q == (PixelPacket *) NULL)
1219 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1220 id=GetOpenMPThreadId();
1221 p=source_pixels[id];
1222 for (x=0; x < (long) image->columns; x++)
1224 *p++=ScaleQuantumToShort(q->red);
1225 if (source_channels > 1)
1227 *p++=ScaleQuantumToShort(q->green);
1228 *p++=ScaleQuantumToShort(q->blue);
1230 if (source_channels > 3)
1231 *p++=ScaleQuantumToShort(indexes[x]);
1234 cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
1235 (unsigned int) image->columns);
1236 p=target_pixels[id];
1238 for (x=0; x < (long) image->columns; x++)
1240 q->red=ScaleShortToQuantum(*p);
1244 if (target_channels > 1)
1246 q->green=ScaleShortToQuantum(*p);
1248 q->blue=ScaleShortToQuantum(*p);
1251 if (target_channels > 3)
1253 indexes[x]=ScaleShortToQuantum(*p);
1258 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1259 if (sync == MagickFalse)
1261 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1266 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1267 #pragma omp critical (MagickCore_ProfileImage)
1269 proceed=SetImageProgress(image,ProfileImageTag,progress++,
1271 if (proceed == MagickFalse)
1275 image_view=DestroyCacheView(image_view);
1276 (void) SetImageColorspace(image,target_colorspace);
1277 switch (cmsGetColorSpace(target_profile))
1281 image->type=image->matte == MagickFalse ? TrueColorType :
1285 case cmsSigCmykData:
1287 image->type=image->matte == MagickFalse ? ColorSeparationType :
1288 ColorSeparationMatteType;
1291 case cmsSigGrayData:
1293 image->type=image->matte == MagickFalse ? GrayscaleType :
1300 target_pixels=DestroyPixelThreadSet(target_pixels);
1301 source_pixels=DestroyPixelThreadSet(source_pixels);
1302 transform=DestroyTransformThreadSet(transform);
1303 (void) cmsCloseProfile(target_profile);
1307 status=SetImageProfile(image,name,profile);
1308 profile=DestroyStringInfo(profile);
1313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1317 % R e m o v e I m a g e P r o f i l e %
1321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1323 % RemoveImageProfile() removes a named profile from the image and returns its
1326 % The format of the RemoveImageProfile method is:
1328 % void *RemoveImageProfile(Image *image,const char *name)
1330 % A description of each parameter follows:
1332 % o image: the image.
1334 % o name: the profile name.
1337 MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
1342 assert(image != (Image *) NULL);
1343 assert(image->signature == MagickSignature);
1344 if (image->debug != MagickFalse)
1345 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1346 if (image->profiles == (SplayTreeInfo *) NULL)
1347 return((StringInfo *) NULL);
1348 if (LocaleCompare(name,"icc") == 0)
1351 Continue to support deprecated color profile for now.
1353 image->color_profile.length=0;
1354 image->color_profile.info=(unsigned char *) NULL;
1356 if (LocaleCompare(name,"iptc") == 0)
1359 Continue to support deprecated IPTC profile for now.
1361 image->iptc_profile.length=0;
1362 image->iptc_profile.info=(unsigned char *) NULL;
1364 profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
1365 image->profiles,name);
1370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1374 % R e s e t P r o f i l e I t e r a t o r %
1378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1380 % ResetImageProfileIterator() resets the image profile iterator. Use it in
1381 % conjunction with GetNextImageProfile() to iterate over all the profiles
1382 % associated with an image.
1384 % The format of the ResetImageProfileIterator method is:
1386 % ResetImageProfileIterator(Image *image)
1388 % A description of each parameter follows:
1390 % o image: the image.
1393 MagickExport void ResetImageProfileIterator(const Image *image)
1395 assert(image != (Image *) NULL);
1396 assert(image->signature == MagickSignature);
1397 if (image->debug != MagickFalse)
1398 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1399 if (image->profiles == (SplayTreeInfo *) NULL)
1401 ResetSplayTreeIterator((SplayTreeInfo *) image->profiles);
1405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409 % S e t I m a g e P r o f i l e %
1413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415 % SetImageProfile() adds a named profile to the image. If a profile with the
1416 % same name already exists, it is replaced. This method differs from the
1417 % ProfileImage() method in that it does not apply CMS color profiles.
1419 % The format of the SetImageProfile method is:
1421 % MagickBooleanType SetImageProfile(Image *image,const char *name,
1422 % const StringInfo *profile)
1424 % A description of each parameter follows:
1426 % o image: the image.
1428 % o name: the profile name, for example icc, exif, and 8bim (8bim is the
1429 % Photoshop wrapper for iptc profiles).
1431 % o profile: A StringInfo structure that contains the named profile.
1435 static void *DestroyProfile(void *profile)
1437 return((void *) DestroyStringInfo((StringInfo *) profile));
1440 static inline const unsigned char *ReadResourceByte(const unsigned char *p,
1441 unsigned char *quantum)
1447 static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
1448 const ssize_t count,unsigned char *quantum)
1453 for (i=0; i < count; i++)
1458 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
1459 unsigned long *quantum)
1461 *quantum=(unsigned long) (*p++ << 24);
1462 *quantum|=(unsigned long) (*p++ << 16);
1463 *quantum|=(unsigned long) (*p++ << 8);
1464 *quantum|=(unsigned long) (*p++ << 0);
1468 static inline const unsigned char *ReadResourceShort(const unsigned char *p,
1469 unsigned short *quantum)
1471 *quantum=(unsigned short) (*p++ << 8);
1472 *quantum|=(unsigned short) (*p++ << 0);
1476 static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
1477 const StringInfo *resource_block)
1482 register const unsigned char
1500 datum=GetStringInfoDatum(resource_block);
1501 length=GetStringInfoLength(resource_block);
1502 for (p=datum; p < (datum+length-16); )
1504 if (LocaleNCompare((char *) p,"8BIM",4) != 0)
1507 p=ReadResourceShort(p,&id);
1508 p=ReadResourceByte(p,&length_byte);
1510 if (((length_byte+1) & 0x01) != 0)
1512 if (p > (datum+length-4))
1514 p=ReadResourceLong(p,&count);
1515 if ((p > (datum+length-count)) || (count > length))
1527 p=ReadResourceShort(p,&resolution)+6;
1528 image->x_resolution=(double) resolution;
1529 p=ReadResourceShort(p,&resolution)+6;
1530 image->y_resolution=(double) resolution;
1538 profile=AcquireStringInfo(count);
1539 SetStringInfoDatum(profile,p);
1540 (void) SetImageProfile(image,"iptc",profile);
1541 profile=DestroyStringInfo(profile);
1558 profile=AcquireStringInfo(count);
1559 SetStringInfoDatum(profile,p);
1560 (void) SetImageProfile(image,"icc",profile);
1561 profile=DestroyStringInfo(profile);
1570 profile=AcquireStringInfo(count);
1571 SetStringInfoDatum(profile,p);
1572 (void) SetImageProfile(image,"exif",profile);
1573 profile=DestroyStringInfo(profile);
1582 profile=AcquireStringInfo(count);
1583 SetStringInfoDatum(profile,p);
1584 (void) SetImageProfile(image,"xmp",profile);
1585 profile=DestroyStringInfo(profile);
1595 if ((count & 0x01) != 0)
1601 MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
1602 const StringInfo *profile)
1606 property[MaxTextExtent];
1611 assert(image != (Image *) NULL);
1612 assert(image->signature == MagickSignature);
1613 if (image->debug != MagickFalse)
1614 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1615 if (image->profiles == (SplayTreeInfo *) NULL)
1616 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1618 (void) CopyMagickString(key,name,MaxTextExtent);
1619 status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
1620 ConstantString(key),CloneStringInfo(profile));
1621 if ((status != MagickFalse) &&
1622 ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0)))
1628 Continue to support deprecated color profile member.
1630 icc_profile=GetImageProfile(image,name);
1631 if (icc_profile != (const StringInfo *) NULL)
1633 image->color_profile.length=GetStringInfoLength(icc_profile);
1634 image->color_profile.info=GetStringInfoDatum(icc_profile);
1637 if ((status != MagickFalse) &&
1638 ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
1644 Continue to support deprecated IPTC profile member.
1646 iptc_profile=GetImageProfile(image,name);
1647 if (iptc_profile != (const StringInfo *) NULL)
1649 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1650 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1652 (void) GetProfilesFromResourceBlock(image,profile);
1655 Inject profile into image properties.
1657 (void) FormatMagickString(property,MaxTextExtent,"%s:sans",name);
1658 (void) GetImageProperty(image,property);
1663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1667 % S y n c I m a g e P r o f i l e s %
1671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673 % SyncImageProfiles() synchronizes image properties with the image profiles.
1674 % Currently we only support updating the EXIF resolution and orientation.
1676 % The format of the SyncImageProfiles method is:
1678 % MagickBooleanType SyncImageProfiles(Image *image)
1680 % A description of each parameter follows:
1682 % o image: the image.
1686 static inline int ReadProfileByte(unsigned char **p,size_t *length)
1698 static inline unsigned short ReadProfileShort(const EndianType endian,
1699 unsigned char *buffer)
1704 if (endian == MSBEndian)
1706 value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
1707 ((unsigned char *) buffer)[1]);
1708 return((unsigned short) (value & 0xffff));
1710 value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
1711 return((unsigned short) (value & 0xffff));
1714 static inline unsigned long ReadProfileLong(const EndianType endian,
1715 unsigned char *buffer)
1720 if (endian == MSBEndian)
1722 value=(unsigned long) ((buffer[0] << 24) | (buffer[1] << 16) |
1723 (buffer[2] << 8) | buffer[3]);
1724 return((unsigned long) (value & 0xffffffff));
1726 value=(unsigned long) ((buffer[3] << 24) | (buffer[2] << 16) |
1727 (buffer[1] << 8 ) | (buffer[0]));
1728 return((unsigned long) (value & 0xffffffff));
1731 static inline void WriteProfileLong(const EndianType endian,
1732 const unsigned long value,unsigned char *p)
1737 if (endian == MSBEndian)
1739 buffer[0]=(unsigned char) (value >> 24);
1740 buffer[1]=(unsigned char) (value >> 16);
1741 buffer[2]=(unsigned char) (value >> 8);
1742 buffer[3]=(unsigned char) value;
1743 (void) CopyMagickMemory(p,buffer,4);
1746 buffer[0]=(unsigned char) value;
1747 buffer[1]=(unsigned char) (value >> 8);
1748 buffer[2]=(unsigned char) (value >> 16);
1749 buffer[3]=(unsigned char) (value >> 24);
1750 (void) CopyMagickMemory(p,buffer,4);
1753 static void WriteProfileShort(const EndianType endian,
1754 const unsigned short value,unsigned char *p)
1759 if (endian == MSBEndian)
1761 buffer[0]=(unsigned char) (value >> 8);
1762 buffer[1]=(unsigned char) value;
1763 (void) CopyMagickMemory(p,buffer,2);
1766 buffer[0]=(unsigned char) value;
1767 buffer[1]=(unsigned char) (value >> 8);
1768 (void) CopyMagickMemory(p,buffer,2);
1771 MagickExport MagickBooleanType SyncImageProfiles(Image *image)
1773 #define MaxDirectoryStack 16
1774 #define EXIF_DELIMITER "\n"
1775 #define EXIF_NUM_FORMATS 12
1776 #define TAG_EXIF_OFFSET 0x8769
1777 #define TAG_INTEROP_OFFSET 0xa005
1779 typedef struct _DirectoryInfo
1789 directory_stack[MaxDirectoryStack];
1805 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
1819 Set EXIF resolution tag.
1821 profile=(StringInfo *) GetImageProfile(image,"EXIF");
1822 if (profile == (StringInfo *) NULL)
1824 length=GetStringInfoLength(profile);
1825 exif=GetStringInfoDatum(profile);
1828 if (ReadProfileByte(&exif,&length) != 0x45)
1830 if (ReadProfileByte(&exif,&length) != 0x78)
1832 if (ReadProfileByte(&exif,&length) != 0x69)
1834 if (ReadProfileByte(&exif,&length) != 0x66)
1836 if (ReadProfileByte(&exif,&length) != 0x00)
1838 if (ReadProfileByte(&exif,&length) != 0x00)
1843 return(MagickFalse);
1844 id=(int) ReadProfileShort(LSBEndian,exif);
1852 return(MagickFalse);
1853 if (ReadProfileShort(endian,exif+2) != 0x002a)
1854 return(MagickFalse);
1856 This the offset to the first IFD.
1858 offset=(ssize_t) ReadProfileLong(endian,exif+4);
1859 if ((size_t) offset >= length)
1860 return(MagickFalse);
1861 directory=exif+offset;
1869 directory=directory_stack[level].directory;
1870 entry=directory_stack[level].entry;
1873 Determine how many entries there are in the current IFD.
1875 number_entries=ReadProfileShort(endian,directory);
1876 for ( ; entry < number_entries; entry++)
1883 register unsigned char
1890 q=(unsigned char *) (directory+2+(12*entry));
1891 tag_value=(long) ReadProfileShort(endian,q);
1892 format=(long) ReadProfileShort(endian,q+2);
1893 if ((format-1) >= EXIF_NUM_FORMATS)
1895 components=(long) ReadProfileLong(endian,q+4);
1896 number_bytes=(size_t) components*format_bytes[format];
1897 if (number_bytes <= 4)
1905 The directory entry contains an offset.
1907 offset=(ssize_t) ReadProfileLong(endian,q+8);
1908 if ((size_t) (offset+number_bytes) > length)
1910 p=(unsigned char *) (exif+offset);
1916 (void) WriteProfileLong(endian,(unsigned long)
1917 (image->x_resolution+0.5),p);
1918 (void) WriteProfileLong(endian,1UL,p+4);
1923 (void) WriteProfileLong(endian,(unsigned long)
1924 (image->y_resolution+0.5),p);
1925 (void) WriteProfileLong(endian,1UL,p+4);
1930 (void) WriteProfileShort(endian,(unsigned short)
1931 image->orientation,p);
1936 (void) WriteProfileShort(endian,(unsigned short)
1937 (image->units+1),p);
1943 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
1948 offset=(size_t) ReadProfileLong(endian,p);
1949 if ((offset < length) && (level < (MaxDirectoryStack-2)))
1951 directory_stack[level].directory=directory;
1953 directory_stack[level].entry=entry;
1955 directory_stack[level].directory=exif+offset;
1956 directory_stack[level].entry=0;
1958 if ((directory+2+(12*number_entries)) > (exif+length))
1960 offset=(size_t) ReadProfileLong(endian,directory+2+(12*
1962 if ((offset != 0) && (offset < length) &&
1963 (level < (MaxDirectoryStack-2)))
1965 directory_stack[level].directory=exif+offset;
1966 directory_stack[level].entry=0;
1973 } while (level > 0);