42#include "magick/studio.h"
43#include "magick/artifact.h"
44#include "magick/attribute.h"
45#include "magick/cache.h"
46#include "magick/color.h"
47#include "magick/colorspace-private.h"
48#include "magick/configure.h"
49#include "magick/exception.h"
50#include "magick/exception-private.h"
51#include "magick/hashmap.h"
52#include "magick/image.h"
53#include "magick/memory_.h"
54#include "magick/monitor.h"
55#include "magick/monitor-private.h"
56#include "magick/option.h"
57#include "magick/option-private.h"
58#include "magick/profile.h"
59#include "magick/property.h"
60#include "magick/quantum.h"
61#include "magick/quantum-private.h"
62#include "magick/resource_.h"
63#include "magick/splay-tree.h"
64#include "magick/string_.h"
65#include "magick/string-private.h"
66#include "magick/thread-private.h"
67#include "magick/token.h"
68#include "magick/utility.h"
69#if defined(MAGICKCORE_LCMS_DELEGATE)
70#if defined(MAGICKCORE_HAVE_LCMS_LCMS2_H)
72#include <lcms/lcms2.h>
78#if defined(MAGICKCORE_XML_DELEGATE)
79# if defined(MAGICKCORE_WINDOWS_SUPPORT)
80# if !defined(__MINGW32__)
81# include <win32config.h>
84# include <libxml/parser.h>
85# include <libxml/tree.h>
91static MagickBooleanType
93 const MagickBooleanType);
125 *(*CloneKeyFunc)(
const char *);
130static inline void *CloneProfileKey(
void *key)
132 return((
void *) ((CloneKeyFunc) ConstantString)((
const char *) key));
135static inline void *CloneProfileValue(
void *value)
137 return((
void *) ((CloneValueFunc) CloneStringInfo)((
const StringInfo *) value));
140MagickExport MagickBooleanType CloneImageProfiles(
Image *image,
141 const Image *clone_image)
143 assert(image != (
Image *) NULL);
144 assert(image->signature == MagickCoreSignature);
145 assert(clone_image != (
const Image *) NULL);
146 assert(clone_image->signature == MagickCoreSignature);
147 if (IsEventLogging() != MagickFalse)
148 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
149 image->color_profile.length=clone_image->color_profile.length;
150 image->color_profile.info=clone_image->color_profile.info;
151 image->iptc_profile.length=clone_image->iptc_profile.length;
152 image->iptc_profile.info=clone_image->iptc_profile.info;
153 if (clone_image->profiles != (
void *) NULL)
155 if (image->profiles != (
void *) NULL)
156 DestroyImageProfiles(image);
157 image->profiles=CloneSplayTree((
SplayTreeInfo *) clone_image->profiles,
158 CloneProfileKey,CloneProfileValue);
187MagickExport MagickBooleanType DeleteImageProfile(
Image *image,
const char *name)
189 assert(image != (
Image *) NULL);
190 assert(image->signature == MagickCoreSignature);
191 if (image->debug != MagickFalse)
192 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
195 if (LocaleCompare(name,
"icc") == 0)
200 image->color_profile.length=0;
201 image->color_profile.info=(
unsigned char *) NULL;
203 if (LocaleCompare(name,
"iptc") == 0)
208 image->iptc_profile.length=0;
209 image->iptc_profile.info=(
unsigned char *) NULL;
211 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
212 return(DeleteNodeFromSplayTree((
SplayTreeInfo *) image->profiles,name));
237MagickExport
void DestroyImageProfiles(
Image *image)
240 image->profiles=DestroySplayTree((
SplayTreeInfo *) image->profiles);
273 assert(image != (
Image *) NULL);
274 assert(image->signature == MagickCoreSignature);
275 if (image->debug != MagickFalse)
276 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
280 image->profiles,name);
306MagickExport
char *GetNextImageProfile(
const Image *image)
308 assert(image != (
Image *) NULL);
309 assert(image->signature == MagickCoreSignature);
310 if (IsEventLogging() != MagickFalse)
311 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
313 return((
char *) NULL);
314 return((
char *) GetNextKeyInSplayTree((
SplayTreeInfo *) image->profiles));
358#if defined(MAGICKCORE_LCMS_DELEGATE)
360typedef struct _LCMSInfo
378 **magick_restrict pixels,
383#if LCMS_VERSION < 2060
384static void* cmsGetContextUserData(cmsContext ContextID)
389static cmsContext cmsCreateContext(
void *magick_unused(Plugin),
void *UserData)
391 magick_unreferenced(Plugin);
392 return((cmsContext) UserData);
395static void cmsSetLogErrorHandlerTHR(cmsContext magick_unused(ContextID),
396 cmsLogErrorHandlerFunction Fn)
398 magick_unreferenced(ContextID);
399 cmsSetLogErrorHandler(Fn);
402static void cmsDeleteContext(cmsContext magick_unused(ContextID))
404 magick_unreferenced(ContextID);
408static double **DestroyPixelTLS(
double **pixels)
413 if (pixels == (
double **) NULL)
414 return((
double **) NULL);
415 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
416 if (pixels[i] != (
double *) NULL)
417 pixels[i]=(
double *) RelinquishMagickMemory(pixels[i]);
418 pixels=(
double **) RelinquishMagickMemory(pixels);
422static double **AcquirePixelTLS(
const size_t columns,
423 const size_t channels)
434 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
435 pixels=(
double **) AcquireQuantumMemory(number_threads,
sizeof(*pixels));
436 if (pixels == (
double **) NULL)
437 return((
double **) NULL);
438 (void) memset(pixels,0,number_threads*
sizeof(*pixels));
439 for (i=0; i < (ssize_t) number_threads; i++)
441 pixels[i]=(
double *) AcquireQuantumMemory(columns,channels*
sizeof(**pixels));
442 if (pixels[i] == (
double *) NULL)
443 return(DestroyPixelTLS(pixels));
448static cmsHTRANSFORM *DestroyTransformTLS(cmsHTRANSFORM *transform)
453 assert(transform != (cmsHTRANSFORM *) NULL);
454 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
455 if (transform[i] != (cmsHTRANSFORM) NULL)
456 cmsDeleteTransform(transform[i]);
457 transform=(cmsHTRANSFORM *) RelinquishMagickMemory(transform);
461static cmsHTRANSFORM *AcquireTransformTLS(
const LCMSInfo *source_info,
462 const LCMSInfo *target_info,
const cmsUInt32Number flags,
463 cmsContext cms_context)
474 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
475 transform=(cmsHTRANSFORM *) AcquireQuantumMemory(number_threads,
477 if (transform == (cmsHTRANSFORM *) NULL)
478 return((cmsHTRANSFORM *) NULL);
479 (void) memset(transform,0,number_threads*
sizeof(*transform));
480 for (i=0; i < (ssize_t) number_threads; i++)
482 transform[i]=cmsCreateTransformTHR(cms_context,source_info->profile,
483 source_info->type,target_info->profile,target_info->type,
484 target_info->intent,flags);
485 if (transform[i] == (cmsHTRANSFORM) NULL)
486 return(DestroyTransformTLS(transform));
491static void LCMSExceptionHandler(cmsContext context,cmsUInt32Number severity,
497 if (IsEventLogging() != MagickFalse)
498 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
"lcms: #%u, %s",
499 severity,message != (
char *) NULL ? message :
"no message");
500 image=(
Image *) cmsGetContextUserData(context);
501 if (image != (
Image *) NULL)
502 (
void) ThrowMagickException(&image->exception,GetMagickModule(),
503 ImageWarning,
"UnableToTransformColorspace",
"`%s'",image->filename);
506static inline void SetLCMSInfoTranslate(LCMSInfo *info,
const double translate)
508 info->translate[0]=translate;
509 info->translate[1]=translate;
510 info->translate[2]=translate;
511 info->translate[3]=translate;
514static inline void SetLCMSInfoScale(LCMSInfo *info,
const double scale)
516 info->scale[0]=scale;
517 info->scale[1]=scale;
518 info->scale[2]=scale;
519 info->scale[3]=scale;
523static MagickBooleanType SetsRGBImageProfile(
Image *image)
528 0x00, 0x00, 0x0c, 0x8c, 0x61, 0x72, 0x67, 0x6c, 0x02, 0x20, 0x00, 0x00,
529 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20,
530 0x07, 0xde, 0x00, 0x01, 0x00, 0x06, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x3a,
531 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00,
532 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00,
533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
534 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x61, 0x72, 0x67, 0x6c,
535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
539 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x99,
540 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0xec, 0x00, 0x00, 0x00, 0x67,
541 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70,
542 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88,
543 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x0c,
544 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x00, 0x67,
545 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x24,
546 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xe4, 0x00, 0x00, 0x00, 0x14,
547 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x24,
548 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x04, 0x1c, 0x00, 0x00, 0x00, 0x14,
549 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x14,
550 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x00, 0x14,
551 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x58, 0x00, 0x00, 0x00, 0x14,
552 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x6c, 0x00, 0x00, 0x00, 0x14,
553 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
554 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
555 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
556 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
557 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36,
558 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x28, 0x45, 0x71, 0x75, 0x69, 0x76,
559 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x77, 0x77,
560 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x31, 0x39,
561 0x39, 0x38, 0x20, 0x48, 0x50, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c,
562 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x3f, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31,
564 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x28, 0x45, 0x71, 0x75,
565 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x77,
566 0x77, 0x77, 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x20,
567 0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x50, 0x20, 0x70, 0x72, 0x6f, 0x66,
568 0x69, 0x6c, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x72, 0x65, 0x61,
570 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x72, 0x61, 0x65, 0x6d,
571 0x65, 0x20, 0x57, 0x2e, 0x20, 0x47, 0x69, 0x6c, 0x6c, 0x2e, 0x20, 0x52,
572 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f,
573 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
574 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x20, 0x4e, 0x6f, 0x20, 0x57,
575 0x61, 0x72, 0x72, 0x61, 0x6e, 0x74, 0x79, 0x2c, 0x20, 0x55, 0x73, 0x65,
576 0x20, 0x61, 0x74, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x6f, 0x77, 0x6e,
577 0x20, 0x72, 0x69, 0x73, 0x6b, 0x2e, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20,
579 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
580 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74,
582 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
583 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
588 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e,
589 0x31, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47,
590 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61,
591 0x63, 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43,
593 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
594 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63,
595 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
596 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00,
599 0x43, 0x52, 0x54, 0x20, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x0d, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36,
601 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x0d, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36,
603 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa4, 0x7c,
609 0x00, 0x14, 0x5f, 0x30, 0x00, 0x10, 0xce, 0x02, 0x00, 0x03, 0xed, 0xb2,
610 0x00, 0x04, 0x13, 0x0a, 0x00, 0x03, 0x5c, 0x67, 0x00, 0x00, 0x00, 0x01,
611 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x0a, 0x3d,
612 0x00, 0x50, 0x00, 0x00, 0x00, 0x57, 0x1e, 0xb8, 0x6d, 0x65, 0x61, 0x73,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x00, 0x00, 0x02, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x58, 0x59, 0x5a, 0x20,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00,
617 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa0,
620 0x00, 0x00, 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x97, 0x00, 0x00, 0xb7, 0x87,
622 0x00, 0x00, 0x18, 0xd9, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
623 0x00, 0x00, 0x24, 0x9f, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xc4,
624 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
625 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19,
626 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37,
627 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54,
628 0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
629 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00, 0x90,
630 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae,
631 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00, 0xc6, 0x00, 0xcb,
632 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb,
633 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0d,
634 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32,
635 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59,
636 0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83,
637 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1,
638 0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1,
639 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
640 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b,
641 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x84,
642 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1,
643 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, 0x02, 0xf5, 0x03, 0x00,
644 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43,
645 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a,
646 0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3,
647 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20,
648 0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71,
649 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4,
650 0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
651 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77,
652 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5,
653 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37,
654 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d,
655 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, 0x06, 0xf5, 0x07, 0x07,
656 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74,
657 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5,
658 0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a,
659 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2,
660 0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f,
661 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
662 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54,
663 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5, 0x0a, 0xdc,
664 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69,
665 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, 0x0b, 0xe1, 0x0b, 0xf9,
666 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e,
667 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26,
668 0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3,
669 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64,
670 0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09,
671 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3,
672 0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
673 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11, 0x13,
674 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9,
675 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84,
676 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43,
677 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, 0x13, 0xe5, 0x14, 0x06,
678 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce,
679 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b,
680 0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c,
681 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41,
682 0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b,
683 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
684 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd,
685 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e, 0x1a, 0xc5,
686 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2,
687 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, 0x1c, 0x7b, 0x1c, 0xa3,
688 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99,
689 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94,
690 0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94,
691 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98,
692 0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1,
693 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf,
694 0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
695 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24, 0xda,
696 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7,
697 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26, 0xe8, 0x27, 0x18,
698 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f,
699 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6b,
700 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b,
701 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1,
702 0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c,
703 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c,
704 0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91,
705 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
706 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a,
707 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46, 0x33, 0x7f,
708 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8,
709 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, 0x35, 0xfd, 0x36, 0x37,
710 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c,
711 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05,
712 0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74,
713 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8,
714 0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61,
715 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0,
716 0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
717 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41, 0xee,
718 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d,
719 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44, 0xce, 0x45, 0x12,
720 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab,
721 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, 0x48, 0x05, 0x48, 0x4b,
722 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0,
723 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a,
724 0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a,
725 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00,
726 0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb,
727 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
728 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42,
729 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2, 0x56, 0x0f,
730 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0,
731 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, 0x59, 0x69, 0x59, 0xb8,
732 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95,
733 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78,
734 0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61,
735 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f,
736 0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43,
737 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d,
738 0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
739 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69, 0x43,
740 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f,
741 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d, 0x08, 0x6d, 0x60,
742 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78,
743 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, 0x71, 0x3a, 0x71, 0x95,
744 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8,
745 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1,
746 0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11,
747 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46,
748 0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81,
749 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
750 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a,
751 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4, 0x83, 0x57,
752 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab,
753 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, 0x87, 0x9f, 0x88, 0x04,
754 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64,
755 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca,
756 0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36,
757 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8,
758 0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20,
759 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f,
760 0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
761 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b, 0xaf,
762 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40,
763 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0, 0x69, 0xa0, 0xd8,
764 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76,
765 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, 0xa5, 0xa9, 0xa6, 0x1a,
766 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4,
767 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75,
768 0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d,
769 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea,
770 0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae,
771 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
772 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a,
773 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7, 0xbc, 0x21,
774 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff,
775 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, 0xc1, 0x67, 0xc1, 0xe3,
776 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce,
777 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf,
778 0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7,
779 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5,
780 0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba,
781 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6,
782 0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
783 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9, 0xf1,
784 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10,
785 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf, 0xaf, 0xe0, 0x36,
786 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63,
787 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, 0xe6, 0x0d, 0xe6, 0x96,
788 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0,
789 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11,
790 0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58,
791 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7,
792 0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb,
793 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
794 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba,
795 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
804 assert(image != (
Image *) NULL);
805 assert(image->signature == MagickCoreSignature);
806 if (GetImageProfile(image,
"icc") != (
const StringInfo *) NULL)
808 profile=AcquireStringInfo(
sizeof(sRGBProfile));
809 SetStringInfoDatum(profile,sRGBProfile);
810 status=SetImageProfile(image,
"icc",profile);
811 profile=DestroyStringInfo(profile);
815MagickExport MagickBooleanType ProfileImage(
Image *image,
const char *name,
816 const void *datum,
const size_t length,
817 const MagickBooleanType magick_unused(clone))
819#define GetLCMSPixel(source_info,pixel,index) (source_info.scale[index]* \
820 ((QuantumScale*(MagickRealType) (pixel))+source_info.translate[index]))
821#define ProfileImageTag "Profile/Image"
822#define SetLCMSPixel(target_info,pixel,index) ClampToQuantum( \
823 target_info.scale[index]*(((MagickRealType) QuantumRange*pixel)+ \
824 target_info.translate[index]))
825#define ThrowProfileException(severity,tag,context) \
827 if (profile != (StringInfo *) NULL) \
828 profile=DestroyStringInfo(profile); \
829 if (cms_context != (cmsContext) NULL) \
830 cmsDeleteContext(cms_context); \
831 if (source_info.profile != (cmsHPROFILE) NULL) \
832 (void) cmsCloseProfile(source_info.profile); \
833 if (target_info.profile != (cmsHPROFILE) NULL) \
834 (void) cmsCloseProfile(target_info.profile); \
835 ThrowBinaryException(severity,tag,context); \
844 magick_unreferenced(clone);
846 assert(image != (
Image *) NULL);
847 assert(image->signature == MagickCoreSignature);
848 assert(name != (
const char *) NULL);
849 if (IsEventLogging() != MagickFalse)
850 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
851 if ((datum == (
const void *) NULL) || (length == 0))
859 ResetImageProfileIterator(image);
860 for (next=GetNextImageProfile(image); next != (
const char *) NULL; )
862 if (IsOptionMember(next,name) != MagickFalse)
864 (void) DeleteImageProfile(image,next);
865 ResetImageProfileIterator(image);
867 next=GetNextImageProfile(image);
875 profile=AcquireStringInfo((
size_t) length);
876 SetStringInfoDatum(profile,(
unsigned char *) datum);
877 if ((LocaleCompare(name,
"icc") != 0) && (LocaleCompare(name,
"icm") != 0))
878 status=SetImageProfile(image,name,profile);
884 icc_profile=GetImageProfile(image,
"icc");
885 if ((icc_profile != (
const StringInfo *) NULL) &&
886 (CompareStringInfo(icc_profile,profile) == 0))
891 value=GetImageProperty(image,
"exif:ColorSpace");
893 if (LocaleCompare(value,
"1") != 0)
894 (
void) SetsRGBImageProfile(image);
895 value=GetImageProperty(image,
"exif:InteroperabilityIndex");
896 if (LocaleCompare(value,
"R98.") != 0)
897 (void) SetsRGBImageProfile(image);
898 icc_profile=GetImageProfile(image,
"icc");
900 if ((icc_profile != (
const StringInfo *) NULL) &&
901 (CompareStringInfo(icc_profile,profile) == 0))
903 profile=DestroyStringInfo(profile);
906#if !defined(MAGICKCORE_LCMS_DELEGATE)
907 (void) ThrowMagickException(&image->exception,GetMagickModule(),
908 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
"`%s' (LCMS)",
922 cms_context=cmsCreateContext(NULL,image);
923 if (cms_context == (cmsContext) NULL)
925 profile=DestroyStringInfo(profile);
926 ThrowBinaryImageException(ResourceLimitError,
927 "ColorspaceColorProfileMismatch",name);
929 cmsSetLogErrorHandlerTHR(cms_context,LCMSExceptionHandler);
930 source_info.profile=cmsOpenProfileFromMemTHR(cms_context,
931 GetStringInfoDatum(profile),(cmsUInt32Number)
932 GetStringInfoLength(profile));
933 if (source_info.profile == (cmsHPROFILE) NULL)
935 profile=DestroyStringInfo(profile);
936 cmsDeleteContext(cms_context);
937 ThrowBinaryImageException(ResourceLimitError,
938 "ColorspaceColorProfileMismatch",name);
940 if ((cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass) &&
942 status=SetImageProfile(image,name,profile);
948 cmsColorSpaceSignature
952 *magick_restrict transform;
966 exception=(&image->exception);
967 target_info.profile=(cmsHPROFILE) NULL;
970 target_info.profile=source_info.profile;
971 source_info.profile=cmsOpenProfileFromMemTHR(cms_context,
972 GetStringInfoDatum(icc_profile),(cmsUInt32Number)
973 GetStringInfoLength(icc_profile));
974 if (source_info.profile == (cmsHPROFILE) NULL)
975 ThrowProfileException(ResourceLimitError,
976 "ColorspaceColorProfileMismatch",name);
978 SetLCMSInfoScale(&source_info,1.0);
979 SetLCMSInfoTranslate(&source_info,0.0);
980 source_info.colorspace=sRGBColorspace;
981 source_info.channels=3;
982 switch (cmsGetColorSpace(source_info.profile))
986 source_info.colorspace=CMYKColorspace;
987 source_info.channels=4;
988 source_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
989 SetLCMSInfoScale(&source_info,100.0);
994 source_info.colorspace=GRAYColorspace;
995 source_info.channels=1;
996 source_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
1001 source_info.colorspace=LabColorspace;
1002 source_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
1003 source_info.scale[0]=100.0;
1004 source_info.scale[1]=255.0;
1005 source_info.scale[2]=255.0;
1006 source_info.translate[1]=(-0.5);
1007 source_info.translate[2]=(-0.5);
1012 source_info.colorspace=sRGBColorspace;
1013 source_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1018 source_info.colorspace=XYZColorspace;
1019 source_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1023 ThrowProfileException(ImageError,
1024 "ColorspaceColorProfileMismatch",name);
1026 signature=cmsGetPCS(source_info.profile);
1027 if (target_info.profile != (cmsHPROFILE) NULL)
1028 signature=cmsGetColorSpace(target_info.profile);
1029 SetLCMSInfoScale(&target_info,1.0);
1030 SetLCMSInfoTranslate(&target_info,0.0);
1031 target_info.channels=3;
1034 case cmsSigCmykData:
1036 target_info.colorspace=CMYKColorspace;
1037 target_info.channels=4;
1038 target_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
1039 SetLCMSInfoScale(&target_info,0.01);
1042 case cmsSigGrayData:
1044 target_info.colorspace=GRAYColorspace;
1045 target_info.channels=1;
1046 target_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
1051 target_info.colorspace=LabColorspace;
1052 target_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
1053 target_info.scale[0]=0.01;
1054 target_info.scale[1]=1/255.0;
1055 target_info.scale[2]=1/255.0;
1056 target_info.translate[1]=0.5;
1057 target_info.translate[2]=0.5;
1062 target_info.colorspace=sRGBColorspace;
1063 target_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1068 target_info.colorspace=XYZColorspace;
1069 target_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1073 ThrowProfileException(ImageError,
1074 "ColorspaceColorProfileMismatch",name);
1076 switch (image->rendering_intent)
1078 case AbsoluteIntent:
1080 target_info.intent=INTENT_ABSOLUTE_COLORIMETRIC;
1083 case PerceptualIntent:
1085 target_info.intent=INTENT_PERCEPTUAL;
1088 case RelativeIntent:
1090 target_info.intent=INTENT_RELATIVE_COLORIMETRIC;
1093 case SaturationIntent:
1095 target_info.intent=INTENT_SATURATION;
1100 target_info.intent=INTENT_PERCEPTUAL;
1104 flags=cmsFLAGS_HIGHRESPRECALC;
1105#if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1106 if (image->black_point_compensation != MagickFalse)
1107 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1109 transform=AcquireTransformTLS(&source_info,&target_info,
1111 if (transform == (cmsHTRANSFORM *) NULL)
1112 ThrowProfileException(ImageError,
"UnableToCreateColorTransform",
1117 source_info.pixels=AcquirePixelTLS(image->columns,
1118 source_info.channels);
1119 target_info.pixels=AcquirePixelTLS(image->columns,
1120 target_info.channels);
1121 if ((source_info.pixels == (
double **) NULL) ||
1122 (target_info.pixels == (
double **) NULL))
1124 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1125 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1126 transform=DestroyTransformTLS(transform);
1127 ThrowProfileException(ResourceLimitError,
1128 "MemoryAllocationFailed",image->filename);
1130 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1132 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1133 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1134 transform=DestroyTransformTLS(transform);
1135 profile=DestroyStringInfo(profile);
1136 if (source_info.profile != (cmsHPROFILE) NULL)
1137 (void) cmsCloseProfile(source_info.profile);
1138 if (target_info.profile != (cmsHPROFILE) NULL)
1139 (
void) cmsCloseProfile(target_info.profile);
1140 return(MagickFalse);
1142 if (target_info.colorspace == CMYKColorspace)
1143 (void) SetImageColorspace(image,target_info.colorspace);
1145 image_view=AcquireAuthenticCacheView(image,exception);
1146#if defined(MAGICKCORE_OPENMP_SUPPORT)
1147 #pragma omp parallel for schedule(static) shared(status) \
1148 magick_number_threads(image,image,image->rows,1)
1150 for (y=0; y < (ssize_t) image->rows; y++)
1153 id = GetOpenMPThreadId();
1159 *magick_restrict indexes;
1170 if (status == MagickFalse)
1172 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1179 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1180 p=source_info.pixels[id];
1181 for (x=0; x < (ssize_t) image->columns; x++)
1183 *p++=GetLCMSPixel(source_info,GetPixelRed(q),0);
1184 if (source_info.channels > 1)
1186 *p++=GetLCMSPixel(source_info,GetPixelGreen(q),1);
1187 *p++=GetLCMSPixel(source_info,GetPixelBlue(q),2);
1189 if (source_info.channels > 3)
1191 *p=GetLCMSPixel(source_info,0,3);
1192 if (indexes != (IndexPacket *) NULL)
1193 *p=GetLCMSPixel(source_info,GetPixelIndex(indexes+x),3);
1198 cmsDoTransform(transform[
id],source_info.pixels[
id],
1199 target_info.pixels[
id],(
unsigned int) image->columns);
1200 p=target_info.pixels[id];
1202 for (x=0; x < (ssize_t) image->columns; x++)
1204 SetPixelRed(q,SetLCMSPixel(target_info,*p,0));
1205 SetPixelGreen(q,GetPixelRed(q));
1206 SetPixelBlue(q,GetPixelRed(q));
1208 if (target_info.channels > 1)
1210 SetPixelGreen(q,SetLCMSPixel(target_info,*p,1));
1212 SetPixelBlue(q,SetLCMSPixel(target_info,*p,2));
1215 if (target_info.channels > 3)
1217 if (indexes != (IndexPacket *) NULL)
1218 SetPixelIndex(indexes+x,SetLCMSPixel(target_info,*p,3));
1223 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1224 if (sync == MagickFalse)
1226 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1231#if defined(MAGICKCORE_OPENMP_SUPPORT)
1235 proceed=SetImageProgress(image,ProfileImageTag,progress,
1237 if (proceed == MagickFalse)
1241 image_view=DestroyCacheView(image_view);
1242 (void) SetImageColorspace(image,target_info.colorspace);
1247 image->type=image->matte == MagickFalse ? TrueColorType :
1251 case cmsSigCmykData:
1253 image->type=image->matte == MagickFalse ? ColorSeparationType :
1254 ColorSeparationMatteType;
1257 case cmsSigGrayData:
1259 image->type=image->matte == MagickFalse ? GrayscaleType :
1266 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1267 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1268 transform=DestroyTransformTLS(transform);
1269 if ((status != MagickFalse) &&
1270 (cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass))
1271 status=SetImageProfile(image,name,profile);
1272 if (target_info.profile != (cmsHPROFILE) NULL)
1273 (void) cmsCloseProfile(target_info.profile);
1275 (void) cmsCloseProfile(source_info.profile);
1276 cmsDeleteContext(cms_context);
1280 profile=DestroyStringInfo(profile);
1309MagickExport
StringInfo *RemoveImageProfile(
Image *image,
const char *name)
1314 assert(image != (
Image *) NULL);
1315 assert(image->signature == MagickCoreSignature);
1316 if (IsEventLogging() != MagickFalse)
1317 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1320 if (LocaleCompare(name,
"icc") == 0)
1325 image->color_profile.length=0;
1326 image->color_profile.info=(
unsigned char *) NULL;
1328 if (LocaleCompare(name,
"iptc") == 0)
1333 image->iptc_profile.length=0;
1334 image->iptc_profile.info=(
unsigned char *) NULL;
1336 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
1338 image->profiles,name);
1366MagickExport
void ResetImageProfileIterator(
const Image *image)
1368 assert(image != (
Image *) NULL);
1369 assert(image->signature == MagickCoreSignature);
1370 if (IsEventLogging() != MagickFalse)
1371 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1408static void *DestroyProfile(
void *profile)
1410 return((
void *) DestroyStringInfo((
StringInfo *) profile));
1413static inline const unsigned char *ReadResourceByte(
const unsigned char *p,
1414 unsigned char *quantum)
1420static inline const unsigned char *ReadResourceLong(
const unsigned char *p,
1421 unsigned int *quantum)
1423 *quantum=(
unsigned int) (*p++) << 24;
1424 *quantum|=(
unsigned int) (*p++) << 16;
1425 *quantum|=(
unsigned int) (*p++) << 8;
1426 *quantum|=(
unsigned int) (*p++);
1430static inline const unsigned char *ReadResourceShort(
const unsigned char *p,
1431 unsigned short *quantum)
1433 *quantum=(
unsigned short) (*p++) << 8;
1434 *quantum|=(
unsigned short) (*p++);
1438static inline void WriteResourceLong(
unsigned char *p,
1439 const unsigned int quantum)
1444 buffer[0]=(
unsigned char) (quantum >> 24);
1445 buffer[1]=(
unsigned char) (quantum >> 16);
1446 buffer[2]=(
unsigned char) (quantum >> 8);
1447 buffer[3]=(
unsigned char) quantum;
1448 (void) memcpy(p,buffer,4);
1451static void WriteTo8BimProfile(
Image *image,
const char *name,
1481 if (LocaleCompare(name,
"icc") == 0)
1484 if (LocaleCompare(name,
"iptc") == 0)
1487 if (LocaleCompare(name,
"xmp") == 0)
1492 image->profiles,
"8bim");
1495 datum=GetStringInfoDatum(profile_8bim);
1496 length=GetStringInfoLength(profile_8bim);
1497 for (p=datum; p < (datum+length-16); )
1500 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1503 p=ReadResourceShort(p,&
id);
1504 p=ReadResourceByte(p,&length_byte);
1506 if (((length_byte+1) & 0x01) != 0)
1508 if (p > (datum+length-4))
1510 p=ReadResourceLong(p,&value);
1511 count=(ssize_t) value;
1512 if ((count & 0x01) != 0)
1514 if ((count < 0) || (p > (datum+length-count)) || (count > (ssize_t) length))
1516 if (
id != profile_id)
1531 extent=(datum+length)-(p+count);
1535 extract_profile=AcquireStringInfo(offset+extent);
1536 (void) memcpy(extract_profile->datum,datum,offset);
1541 extract_extent=profile->length;
1542 if ((extract_extent & 0x01) != 0)
1544 extract_profile=AcquireStringInfo(offset+extract_extent+extent);
1545 (void) memcpy(extract_profile->datum,datum,offset-4);
1546 WriteResourceLong(extract_profile->datum+offset-4,(
unsigned int)
1548 (void) memcpy(extract_profile->datum+offset,
1549 profile->datum,profile->length);
1551 (void) memcpy(extract_profile->datum+offset+extract_extent,
1553 (void) AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1554 ConstantString(
"8bim"),CloneStringInfo(extract_profile));
1555 extract_profile=DestroyStringInfo(extract_profile);
1561static void GetProfilesFromResourceBlock(
Image *image,
1588 datum=GetStringInfoDatum(resource_block);
1589 length=GetStringInfoLength(resource_block);
1590 for (p=datum; p < (datum+length-16); )
1592 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1595 p=ReadResourceShort(p,&
id);
1596 p=ReadResourceByte(p,&length_byte);
1598 if (((length_byte+1) & 0x01) != 0)
1600 if (p > (datum+length-4))
1602 p=ReadResourceLong(p,&value);
1603 count=(ssize_t) value;
1604 if ((p > (datum+length-count)) || (count > (ssize_t) length) ||
1622 p=ReadResourceLong(p,&resolution);
1623 image->x_resolution=((double) resolution)/65536.0;
1624 p=ReadResourceShort(p,&units)+2;
1625 p=ReadResourceLong(p,&resolution)+4;
1626 image->y_resolution=((double) resolution)/65536.0;
1630 if ((ResolutionType) units != PixelsPerCentimeterResolution)
1631 image->units=PixelsPerInchResolution;
1634 image->units=PixelsPerCentimeterResolution;
1635 image->x_resolution/=2.54;
1636 image->y_resolution/=2.54;
1645 profile=AcquireStringInfo(count);
1646 SetStringInfoDatum(profile,p);
1647 (void) SetImageProfileInternal(image,
"iptc",profile,MagickTrue);
1648 profile=DestroyStringInfo(profile);
1665 profile=AcquireStringInfo(count);
1666 SetStringInfoDatum(profile,p);
1667 (void) SetImageProfileInternal(image,
"icc",profile,MagickTrue);
1668 profile=DestroyStringInfo(profile);
1677 profile=AcquireStringInfo(count);
1678 SetStringInfoDatum(profile,p);
1679 (void) SetImageProfileInternal(image,
"exif",profile,MagickTrue);
1680 profile=DestroyStringInfo(profile);
1689 profile=AcquireStringInfo(count);
1690 SetStringInfoDatum(profile,p);
1691 (void) SetImageProfileInternal(image,
"xmp",profile,MagickTrue);
1692 profile=DestroyStringInfo(profile);
1702 if ((count & 0x01) != 0)
1707#if defined(MAGICKCORE_XML_DELEGATE)
1708static MagickBooleanType ValidateXMPProfile(
Image *image,
1717 const char *artifact=GetImageArtifact(image,
"xmp:validate");
1718 if (IsStringTrue(artifact) == MagickFalse)
1720 document=xmlReadMemory((
const char *) GetStringInfoDatum(profile),(
int)
1721 GetStringInfoLength(profile),
"xmp.xml",NULL,XML_PARSE_NOERROR |
1722 XML_PARSE_NOWARNING);
1723 if (document == (xmlDocPtr) NULL)
1725 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1726 ImageWarning,
"CorruptImageProfile",
"`%s' (XMP)",image->filename);
1727 return(MagickFalse);
1729 xmlFreeDoc(document);
1733static MagickBooleanType ValidateXMPProfile(
Image *image,
1736 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1737 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
"'%s' (XML)",
1739 return(MagickFalse);
1743static MagickBooleanType SetImageProfileInternal(
Image *image,
const char *name,
1744 const StringInfo *profile,
const MagickBooleanType recursive)
1752 assert(image != (
Image *) NULL);
1753 assert(image->signature == MagickCoreSignature);
1754 if (IsEventLogging() != MagickFalse)
1755 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1756 if ((LocaleCompare(name,
"xmp") == 0) &&
1757 (ValidateXMPProfile(image,profile) == MagickFalse))
1760 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1762 (void) CopyMagickString(key,name,MaxTextExtent);
1764 status=AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1765 ConstantString(key),CloneStringInfo(profile));
1766 if ((status != MagickFalse) &&
1767 ((LocaleCompare(name,
"icc") == 0) || (LocaleCompare(name,
"icm") == 0)))
1775 icc_profile=GetImageProfile(image,name);
1776 if (icc_profile != (
const StringInfo *) NULL)
1778 image->color_profile.length=GetStringInfoLength(icc_profile);
1779 image->color_profile.info=GetStringInfoDatum(icc_profile);
1782 if ((status != MagickFalse) &&
1783 ((LocaleCompare(name,
"iptc") == 0) || (LocaleCompare(name,
"8bim") == 0)))
1791 iptc_profile=GetImageProfile(image,name);
1792 if (iptc_profile != (
const StringInfo *) NULL)
1794 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1795 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1798 if (status != MagickFalse)
1800 if (LocaleCompare(name,
"8bim") == 0)
1801 GetProfilesFromResourceBlock(image,profile);
1803 if (recursive == MagickFalse)
1804 WriteTo8BimProfile(image,name,profile);
1809MagickExport MagickBooleanType SetImageProfile(
Image *image,
const char *name,
1812 return(SetImageProfileInternal(image,name,profile,MagickFalse));
1839static inline int ReadProfileByte(
unsigned char **p,
size_t *length)
1851static inline signed short ReadProfileShort(
const EndianType endian,
1852 unsigned char *buffer)
1866 if (endian == LSBEndian)
1868 value=(
unsigned short) buffer[1] << 8;
1869 value|=(
unsigned short) buffer[0];
1870 quantum.unsigned_value=value & 0xffff;
1871 return(quantum.signed_value);
1873 value=(
unsigned short) buffer[0] << 8;
1874 value|=(
unsigned short) buffer[1];
1875 quantum.unsigned_value=value & 0xffff;
1876 return(quantum.signed_value);
1879static inline signed int ReadProfileLong(
const EndianType endian,
1880 unsigned char *buffer)
1894 if (endian == LSBEndian)
1896 value=(
unsigned int) buffer[3] << 24;
1897 value|=(
unsigned int) buffer[2] << 16;
1898 value|=(
unsigned int) buffer[1] << 8;
1899 value|=(
unsigned int) buffer[0];
1900 quantum.unsigned_value=value & 0xffffffff;
1901 return(quantum.signed_value);
1903 value=(
unsigned int) buffer[0] << 24;
1904 value|=(
unsigned int) buffer[1] << 16;
1905 value|=(
unsigned int) buffer[2] << 8;
1906 value|=(
unsigned int) buffer[3];
1907 quantum.unsigned_value=value & 0xffffffff;
1908 return(quantum.signed_value);
1911static inline signed int ReadProfileMSBLong(
unsigned char **p,
size_t *length)
1918 value=ReadProfileLong(MSBEndian,*p);
1924static inline signed short ReadProfileMSBShort(
unsigned char **p,
1932 value=ReadProfileShort(MSBEndian,*p);
1938static inline void WriteProfileLong(
const EndianType endian,
1939 const size_t value,
unsigned char *p)
1944 if (endian == LSBEndian)
1946 buffer[0]=(
unsigned char) value;
1947 buffer[1]=(
unsigned char) (value >> 8);
1948 buffer[2]=(
unsigned char) (value >> 16);
1949 buffer[3]=(
unsigned char) (value >> 24);
1950 (void) memcpy(p,buffer,4);
1953 buffer[0]=(
unsigned char) (value >> 24);
1954 buffer[1]=(
unsigned char) (value >> 16);
1955 buffer[2]=(
unsigned char) (value >> 8);
1956 buffer[3]=(
unsigned char) value;
1957 (void) memcpy(p,buffer,4);
1960static void WriteProfileShort(
const EndianType endian,
1961 const unsigned short value,
unsigned char *p)
1966 if (endian == LSBEndian)
1968 buffer[0]=(
unsigned char) value;
1969 buffer[1]=(
unsigned char) (value >> 8);
1970 (void) memcpy(p,buffer,2);
1973 buffer[0]=(
unsigned char) (value >> 8);
1974 buffer[1]=(
unsigned char) value;
1975 (void) memcpy(p,buffer,2);
1978static MagickBooleanType SyncExifProfile(
const Image *image,
unsigned char *exif,
1981#define MaxDirectoryStack 16
1982#define EXIF_DELIMITER "\n"
1983#define EXIF_NUM_FORMATS 12
1984#define TAG_EXIF_OFFSET 0x8769
1985#define TAG_INTEROP_OFFSET 0xa005
1987 typedef struct _DirectoryInfo
1997 directory_stack[MaxDirectoryStack] = { { 0, 0 } };
2015 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
2021 return(MagickFalse);
2022 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2023 if ((
id != 0x4949) && (
id != 0x4D4D))
2027 if (ReadProfileByte(&exif,&length) != 0x45)
2029 if (ReadProfileByte(&exif,&length) != 0x78)
2031 if (ReadProfileByte(&exif,&length) != 0x69)
2033 if (ReadProfileByte(&exif,&length) != 0x66)
2035 if (ReadProfileByte(&exif,&length) != 0x00)
2037 if (ReadProfileByte(&exif,&length) != 0x00)
2042 return(MagickFalse);
2043 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2052 return(MagickFalse);
2053 if (ReadProfileShort(endian,exif+2) != 0x002a)
2054 return(MagickFalse);
2058 offset=(ssize_t) ReadProfileLong(endian,exif+4);
2059 if ((offset < 0) || ((size_t) offset >= length))
2060 return(MagickFalse);
2061 directory=exif+offset;
2064 exif_resources=NewSplayTree((
int (*)(
const void *,
const void *)) NULL,
2065 (
void *(*)(
void *)) NULL,(
void *(*)(
void *)) NULL);
2071 directory=directory_stack[level].directory;
2072 entry=directory_stack[level].entry;
2074 if ((directory < exif) || (directory > (exif+length-2)))
2079 number_entries=ReadProfileShort(endian,directory);
2080 for ( ; entry < number_entries; entry++)
2096 q=(
unsigned char *) (directory+2+(12*entry));
2097 if (q > (exif+length-12))
2099 if (GetValueFromSplayTree(exif_resources,q) == q)
2101 (void) AddValueToSplayTree(exif_resources,q,q);
2102 tag_value=(ssize_t) ReadProfileShort(endian,q);
2103 format=(ssize_t) ReadProfileShort(endian,q+2);
2104 if ((format < 0) || ((format-1) >= EXIF_NUM_FORMATS))
2106 components=(int) ReadProfileLong(endian,q+4);
2109 number_bytes=(size_t) components*format_bytes[format];
2110 if ((ssize_t) number_bytes < components)
2112 if (number_bytes <= 4)
2119 offset=(ssize_t) ReadProfileLong(endian,q+8);
2120 if ((offset < 0) || ((size_t) (offset+number_bytes) > length))
2122 if (~length < number_bytes)
2124 p=(
unsigned char *) (exif+offset);
2130 (void) WriteProfileLong(endian,(
size_t) (image->x_resolution+0.5),p);
2131 if (number_bytes == 8)
2132 (void) WriteProfileLong(endian,1UL,p+4);
2137 (void) WriteProfileLong(endian,(
size_t) (image->y_resolution+0.5),p);
2138 if (number_bytes == 8)
2139 (void) WriteProfileLong(endian,1UL,p+4);
2144 if (number_bytes == 4)
2146 (void) WriteProfileLong(endian,(
size_t) image->orientation,p);
2149 (void) WriteProfileShort(endian,(
unsigned short) image->orientation,
2155 if (number_bytes == 4)
2157 (void) WriteProfileLong(endian,((
size_t) image->units)+1,p);
2160 (void) WriteProfileShort(endian,(
unsigned short) (image->units+1),p);
2166 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
2168 offset=(ssize_t) ReadProfileLong(endian,p);
2169 if (((
size_t) offset < length) && (level < (MaxDirectoryStack-2)))
2171 directory_stack[level].directory=directory;
2173 directory_stack[level].entry=entry;
2175 directory_stack[level].directory=exif+offset;
2176 directory_stack[level].entry=0;
2178 if ((directory+2+(12*number_entries)) > (exif+length))
2180 offset=(ssize_t) ReadProfileLong(endian,directory+2+(12*
2182 if ((offset != 0) && ((size_t) offset < length) &&
2183 (level < (MaxDirectoryStack-2)))
2185 directory_stack[level].directory=exif+offset;
2186 directory_stack[level].entry=0;
2193 }
while (level > 0);
2194 exif_resources=DestroySplayTree(exif_resources);
2198static MagickBooleanType Sync8BimProfile(
const Image *image,
2213 length=GetStringInfoLength(profile);
2214 p=GetStringInfoDatum(profile);
2217 if (ReadProfileByte(&p,&length) != 0x38)
2219 if (ReadProfileByte(&p,&length) != 0x42)
2221 if (ReadProfileByte(&p,&length) != 0x49)
2223 if (ReadProfileByte(&p,&length) != 0x4D)
2226 return(MagickFalse);
2227 id=ReadProfileMSBShort(&p,&length);
2228 count=(ssize_t) ReadProfileByte(&p,&length);
2229 if ((count >= (ssize_t) length) || (count < 0))
2230 return(MagickFalse);
2233 if ((*p & 0x01) == 0)
2234 (
void) ReadProfileByte(&p,&length);
2235 count=(ssize_t) ReadProfileMSBLong(&p,&length);
2236 if ((count > (ssize_t) length) || (count < 0))
2237 return(MagickFalse);
2238 if ((
id == 0x3ED) && (count == 16))
2240 if (image->units == PixelsPerCentimeterResolution)
2241 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2242 image->x_resolution*2.54*65536.0),p);
2244 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2245 image->x_resolution*65536.0),p);
2246 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+4);
2247 if (image->units == PixelsPerCentimeterResolution)
2248 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2249 image->y_resolution*2.54*65536.0),p+8);
2251 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2252 image->y_resolution*65536.0),p+8);
2253 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+12);
2256 (void) SyncExifProfile(image,p,count);
2263MagickExport MagickBooleanType SyncImageProfiles(
Image *image)
2272 profile=(
StringInfo *) GetImageProfile(image,
"8BIM");
2274 if (Sync8BimProfile(image,profile) == MagickFalse)
2276 profile=(
StringInfo *) GetImageProfile(image,
"EXIF");
2278 if (SyncExifProfile(image,GetStringInfoDatum(profile),
2279 GetStringInfoLength(profile)) == MagickFalse)