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);
123MagickExport MagickBooleanType CloneImageProfiles(
Image *image,
124 const Image *clone_image)
126 assert(image != (
Image *) NULL);
127 assert(image->signature == MagickCoreSignature);
128 assert(clone_image != (
const Image *) NULL);
129 assert(clone_image->signature == MagickCoreSignature);
130 if (IsEventLogging() != MagickFalse)
131 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
132 image->color_profile.length=clone_image->color_profile.length;
133 image->color_profile.info=clone_image->color_profile.info;
134 image->iptc_profile.length=clone_image->iptc_profile.length;
135 image->iptc_profile.info=clone_image->iptc_profile.info;
136 if (clone_image->profiles != (
void *) NULL)
138 if (image->profiles != (
void *) NULL)
139 DestroyImageProfiles(image);
140 image->profiles=CloneSplayTree((
SplayTreeInfo *) clone_image->profiles,
141 (
void *(*)(
void *)) ConstantString,(
void *(*)(
void *)) CloneStringInfo);
170MagickExport MagickBooleanType DeleteImageProfile(
Image *image,
const char *name)
172 assert(image != (
Image *) NULL);
173 assert(image->signature == MagickCoreSignature);
174 if (image->debug != MagickFalse)
175 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
178 if (LocaleCompare(name,
"icc") == 0)
183 image->color_profile.length=0;
184 image->color_profile.info=(
unsigned char *) NULL;
186 if (LocaleCompare(name,
"iptc") == 0)
191 image->iptc_profile.length=0;
192 image->iptc_profile.info=(
unsigned char *) NULL;
194 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
195 return(DeleteNodeFromSplayTree((
SplayTreeInfo *) image->profiles,name));
220MagickExport
void DestroyImageProfiles(
Image *image)
223 image->profiles=DestroySplayTree((
SplayTreeInfo *) image->profiles);
256 assert(image != (
Image *) NULL);
257 assert(image->signature == MagickCoreSignature);
258 if (image->debug != MagickFalse)
259 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
263 image->profiles,name);
289MagickExport
char *GetNextImageProfile(
const Image *image)
291 assert(image != (
Image *) NULL);
292 assert(image->signature == MagickCoreSignature);
293 if (IsEventLogging() != MagickFalse)
294 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
296 return((
char *) NULL);
297 return((
char *) GetNextKeyInSplayTree((
SplayTreeInfo *) image->profiles));
341#if defined(MAGICKCORE_LCMS_DELEGATE)
343typedef struct _LCMSInfo
361 **magick_restrict pixels,
366#if LCMS_VERSION < 2060
367static void* cmsGetContextUserData(cmsContext ContextID)
372static cmsContext cmsCreateContext(
void *magick_unused(Plugin),
void *UserData)
374 magick_unreferenced(Plugin);
375 return((cmsContext) UserData);
378static void cmsSetLogErrorHandlerTHR(cmsContext magick_unused(ContextID),
379 cmsLogErrorHandlerFunction Fn)
381 magick_unreferenced(ContextID);
382 cmsSetLogErrorHandler(Fn);
385static void cmsDeleteContext(cmsContext magick_unused(ContextID))
387 magick_unreferenced(ContextID);
391static double **DestroyPixelTLS(
double **pixels)
396 if (pixels == (
double **) NULL)
397 return((
double **) NULL);
398 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
399 if (pixels[i] != (
double *) NULL)
400 pixels[i]=(
double *) RelinquishMagickMemory(pixels[i]);
401 pixels=(
double **) RelinquishMagickMemory(pixels);
405static double **AcquirePixelTLS(
const size_t columns,
406 const size_t channels)
417 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
418 pixels=(
double **) AcquireQuantumMemory(number_threads,
sizeof(*pixels));
419 if (pixels == (
double **) NULL)
420 return((
double **) NULL);
421 (void) memset(pixels,0,number_threads*
sizeof(*pixels));
422 for (i=0; i < (ssize_t) number_threads; i++)
424 pixels[i]=(
double *) AcquireQuantumMemory(columns,channels*
sizeof(**pixels));
425 if (pixels[i] == (
double *) NULL)
426 return(DestroyPixelTLS(pixels));
431static cmsHTRANSFORM *DestroyTransformTLS(cmsHTRANSFORM *transform)
436 assert(transform != (cmsHTRANSFORM *) NULL);
437 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
438 if (transform[i] != (cmsHTRANSFORM) NULL)
439 cmsDeleteTransform(transform[i]);
440 transform=(cmsHTRANSFORM *) RelinquishMagickMemory(transform);
444static cmsHTRANSFORM *AcquireTransformTLS(
const LCMSInfo *source_info,
445 const LCMSInfo *target_info,
const cmsUInt32Number flags,
446 cmsContext cms_context)
457 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
458 transform=(cmsHTRANSFORM *) AcquireQuantumMemory(number_threads,
460 if (transform == (cmsHTRANSFORM *) NULL)
461 return((cmsHTRANSFORM *) NULL);
462 (void) memset(transform,0,number_threads*
sizeof(*transform));
463 for (i=0; i < (ssize_t) number_threads; i++)
465 transform[i]=cmsCreateTransformTHR(cms_context,source_info->profile,
466 source_info->type,target_info->profile,target_info->type,
467 target_info->intent,flags);
468 if (transform[i] == (cmsHTRANSFORM) NULL)
469 return(DestroyTransformTLS(transform));
474static void LCMSExceptionHandler(cmsContext context,cmsUInt32Number severity,
480 if (IsEventLogging() != MagickFalse)
481 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
"lcms: #%u, %s",
482 severity,message != (
char *) NULL ? message :
"no message");
483 image=(
Image *) cmsGetContextUserData(context);
484 if (image != (
Image *) NULL)
485 (
void) ThrowMagickException(&image->exception,GetMagickModule(),
486 ImageWarning,
"UnableToTransformColorspace",
"`%s'",image->filename);
489static inline void SetLCMSInfoTranslate(LCMSInfo *info,
const double translate)
491 info->translate[0]=translate;
492 info->translate[1]=translate;
493 info->translate[2]=translate;
494 info->translate[3]=translate;
497static inline void SetLCMSInfoScale(LCMSInfo *info,
const double scale)
499 info->scale[0]=scale;
500 info->scale[1]=scale;
501 info->scale[2]=scale;
502 info->scale[3]=scale;
506static MagickBooleanType SetsRGBImageProfile(
Image *image)
511 0x00, 0x00, 0x0c, 0x8c, 0x61, 0x72, 0x67, 0x6c, 0x02, 0x20, 0x00, 0x00,
512 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20,
513 0x07, 0xde, 0x00, 0x01, 0x00, 0x06, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x3a,
514 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00,
515 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
517 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x61, 0x72, 0x67, 0x6c,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
522 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x99,
523 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0xec, 0x00, 0x00, 0x00, 0x67,
524 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70,
525 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88,
526 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x0c,
527 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x00, 0x67,
528 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x24,
529 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xe4, 0x00, 0x00, 0x00, 0x14,
530 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x24,
531 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x04, 0x1c, 0x00, 0x00, 0x00, 0x14,
532 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x14,
533 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x00, 0x14,
534 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x58, 0x00, 0x00, 0x00, 0x14,
535 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x6c, 0x00, 0x00, 0x00, 0x14,
536 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
537 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
538 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
539 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
540 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36,
541 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x28, 0x45, 0x71, 0x75, 0x69, 0x76,
542 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x77, 0x77,
543 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x31, 0x39,
544 0x39, 0x38, 0x20, 0x48, 0x50, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c,
545 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x3f, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31,
547 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x28, 0x45, 0x71, 0x75,
548 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x77,
549 0x77, 0x77, 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x20,
550 0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x50, 0x20, 0x70, 0x72, 0x6f, 0x66,
551 0x69, 0x6c, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x72, 0x65, 0x61,
553 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x72, 0x61, 0x65, 0x6d,
554 0x65, 0x20, 0x57, 0x2e, 0x20, 0x47, 0x69, 0x6c, 0x6c, 0x2e, 0x20, 0x52,
555 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f,
556 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
557 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x20, 0x4e, 0x6f, 0x20, 0x57,
558 0x61, 0x72, 0x72, 0x61, 0x6e, 0x74, 0x79, 0x2c, 0x20, 0x55, 0x73, 0x65,
559 0x20, 0x61, 0x74, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x6f, 0x77, 0x6e,
560 0x20, 0x72, 0x69, 0x73, 0x6b, 0x2e, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20,
562 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
563 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74,
565 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
566 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
571 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e,
572 0x31, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47,
573 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61,
574 0x63, 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43,
576 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
577 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63,
578 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
579 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00,
582 0x43, 0x52, 0x54, 0x20, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x0d, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36,
584 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x0d, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36,
586 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa4, 0x7c,
592 0x00, 0x14, 0x5f, 0x30, 0x00, 0x10, 0xce, 0x02, 0x00, 0x03, 0xed, 0xb2,
593 0x00, 0x04, 0x13, 0x0a, 0x00, 0x03, 0x5c, 0x67, 0x00, 0x00, 0x00, 0x01,
594 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x0a, 0x3d,
595 0x00, 0x50, 0x00, 0x00, 0x00, 0x57, 0x1e, 0xb8, 0x6d, 0x65, 0x61, 0x73,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x02, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x58, 0x59, 0x5a, 0x20,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00,
600 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa0,
603 0x00, 0x00, 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x97, 0x00, 0x00, 0xb7, 0x87,
605 0x00, 0x00, 0x18, 0xd9, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x24, 0x9f, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xc4,
607 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
608 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19,
609 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37,
610 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54,
611 0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
612 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00, 0x90,
613 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae,
614 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00, 0xc6, 0x00, 0xcb,
615 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb,
616 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0d,
617 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32,
618 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59,
619 0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83,
620 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1,
621 0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1,
622 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
623 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b,
624 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x84,
625 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1,
626 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, 0x02, 0xf5, 0x03, 0x00,
627 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43,
628 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a,
629 0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3,
630 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20,
631 0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71,
632 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4,
633 0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
634 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77,
635 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5,
636 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37,
637 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d,
638 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, 0x06, 0xf5, 0x07, 0x07,
639 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74,
640 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5,
641 0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a,
642 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2,
643 0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f,
644 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
645 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54,
646 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5, 0x0a, 0xdc,
647 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69,
648 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, 0x0b, 0xe1, 0x0b, 0xf9,
649 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e,
650 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26,
651 0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3,
652 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64,
653 0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09,
654 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3,
655 0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
656 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11, 0x13,
657 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9,
658 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84,
659 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43,
660 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, 0x13, 0xe5, 0x14, 0x06,
661 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce,
662 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b,
663 0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c,
664 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41,
665 0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b,
666 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
667 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd,
668 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e, 0x1a, 0xc5,
669 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2,
670 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, 0x1c, 0x7b, 0x1c, 0xa3,
671 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99,
672 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94,
673 0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94,
674 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98,
675 0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1,
676 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf,
677 0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
678 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24, 0xda,
679 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7,
680 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26, 0xe8, 0x27, 0x18,
681 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f,
682 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6b,
683 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b,
684 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1,
685 0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c,
686 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c,
687 0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91,
688 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
689 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a,
690 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46, 0x33, 0x7f,
691 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8,
692 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, 0x35, 0xfd, 0x36, 0x37,
693 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c,
694 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05,
695 0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74,
696 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8,
697 0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61,
698 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0,
699 0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
700 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41, 0xee,
701 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d,
702 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44, 0xce, 0x45, 0x12,
703 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab,
704 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, 0x48, 0x05, 0x48, 0x4b,
705 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0,
706 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a,
707 0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a,
708 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00,
709 0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb,
710 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
711 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42,
712 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2, 0x56, 0x0f,
713 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0,
714 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, 0x59, 0x69, 0x59, 0xb8,
715 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95,
716 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78,
717 0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61,
718 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f,
719 0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43,
720 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d,
721 0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
722 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69, 0x43,
723 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f,
724 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d, 0x08, 0x6d, 0x60,
725 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78,
726 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, 0x71, 0x3a, 0x71, 0x95,
727 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8,
728 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1,
729 0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11,
730 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46,
731 0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81,
732 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
733 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a,
734 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4, 0x83, 0x57,
735 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab,
736 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, 0x87, 0x9f, 0x88, 0x04,
737 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64,
738 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca,
739 0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36,
740 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8,
741 0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20,
742 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f,
743 0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
744 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b, 0xaf,
745 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40,
746 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0, 0x69, 0xa0, 0xd8,
747 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76,
748 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, 0xa5, 0xa9, 0xa6, 0x1a,
749 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4,
750 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75,
751 0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d,
752 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea,
753 0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae,
754 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
755 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a,
756 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7, 0xbc, 0x21,
757 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff,
758 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, 0xc1, 0x67, 0xc1, 0xe3,
759 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce,
760 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf,
761 0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7,
762 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5,
763 0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba,
764 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6,
765 0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
766 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9, 0xf1,
767 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10,
768 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf, 0xaf, 0xe0, 0x36,
769 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63,
770 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, 0xe6, 0x0d, 0xe6, 0x96,
771 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0,
772 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11,
773 0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58,
774 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7,
775 0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb,
776 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
777 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba,
778 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
787 assert(image != (
Image *) NULL);
788 assert(image->signature == MagickCoreSignature);
789 if (GetImageProfile(image,
"icc") != (
const StringInfo *) NULL)
791 profile=AcquireStringInfo(
sizeof(sRGBProfile));
792 SetStringInfoDatum(profile,sRGBProfile);
793 status=SetImageProfile(image,
"icc",profile);
794 profile=DestroyStringInfo(profile);
798MagickExport MagickBooleanType ProfileImage(
Image *image,
const char *name,
799 const void *datum,
const size_t length,
800 const MagickBooleanType magick_unused(clone))
802#define GetLCMSPixel(source_info,pixel,index) (source_info.scale[index]* \
803 ((QuantumScale*(MagickRealType) (pixel))+source_info.translate[index]))
804#define ProfileImageTag "Profile/Image"
805#define SetLCMSPixel(target_info,pixel,index) ClampToQuantum( \
806 target_info.scale[index]*(((MagickRealType) QuantumRange*pixel)+ \
807 target_info.translate[index]))
808#define ThrowProfileException(severity,tag,context) \
810 if (profile != (StringInfo *) NULL) \
811 profile=DestroyStringInfo(profile); \
812 if (cms_context != (cmsContext) NULL) \
813 cmsDeleteContext(cms_context); \
814 if (source_info.profile != (cmsHPROFILE) NULL) \
815 (void) cmsCloseProfile(source_info.profile); \
816 if (target_info.profile != (cmsHPROFILE) NULL) \
817 (void) cmsCloseProfile(target_info.profile); \
818 ThrowBinaryException(severity,tag,context); \
827 magick_unreferenced(clone);
829 assert(image != (
Image *) NULL);
830 assert(image->signature == MagickCoreSignature);
831 assert(name != (
const char *) NULL);
832 if (IsEventLogging() != MagickFalse)
833 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
834 if ((datum == (
const void *) NULL) || (length == 0))
842 ResetImageProfileIterator(image);
843 for (next=GetNextImageProfile(image); next != (
const char *) NULL; )
845 if (IsOptionMember(next,name) != MagickFalse)
847 (void) DeleteImageProfile(image,next);
848 ResetImageProfileIterator(image);
850 next=GetNextImageProfile(image);
858 profile=AcquireStringInfo((
size_t) length);
859 SetStringInfoDatum(profile,(
unsigned char *) datum);
860 if ((LocaleCompare(name,
"icc") != 0) && (LocaleCompare(name,
"icm") != 0))
861 status=SetImageProfile(image,name,profile);
867 icc_profile=GetImageProfile(image,
"icc");
868 if ((icc_profile != (
const StringInfo *) NULL) &&
869 (CompareStringInfo(icc_profile,profile) == 0))
874 value=GetImageProperty(image,
"exif:ColorSpace");
876 if (LocaleCompare(value,
"1") != 0)
877 (
void) SetsRGBImageProfile(image);
878 value=GetImageProperty(image,
"exif:InteroperabilityIndex");
879 if (LocaleCompare(value,
"R98.") != 0)
880 (void) SetsRGBImageProfile(image);
881 icc_profile=GetImageProfile(image,
"icc");
883 if ((icc_profile != (
const StringInfo *) NULL) &&
884 (CompareStringInfo(icc_profile,profile) == 0))
886 profile=DestroyStringInfo(profile);
889#if !defined(MAGICKCORE_LCMS_DELEGATE)
890 (void) ThrowMagickException(&image->exception,GetMagickModule(),
891 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
"`%s' (LCMS)",
905 cms_context=cmsCreateContext(NULL,image);
906 if (cms_context == (cmsContext) NULL)
908 profile=DestroyStringInfo(profile);
909 ThrowBinaryImageException(ResourceLimitError,
910 "ColorspaceColorProfileMismatch",name);
912 cmsSetLogErrorHandlerTHR(cms_context,LCMSExceptionHandler);
913 source_info.profile=cmsOpenProfileFromMemTHR(cms_context,
914 GetStringInfoDatum(profile),(cmsUInt32Number)
915 GetStringInfoLength(profile));
916 if (source_info.profile == (cmsHPROFILE) NULL)
918 profile=DestroyStringInfo(profile);
919 cmsDeleteContext(cms_context);
920 ThrowBinaryImageException(ResourceLimitError,
921 "ColorspaceColorProfileMismatch",name);
923 if ((cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass) &&
925 status=SetImageProfile(image,name,profile);
931 cmsColorSpaceSignature
935 *magick_restrict transform;
949 exception=(&image->exception);
950 target_info.profile=(cmsHPROFILE) NULL;
953 target_info.profile=source_info.profile;
954 source_info.profile=cmsOpenProfileFromMemTHR(cms_context,
955 GetStringInfoDatum(icc_profile),(cmsUInt32Number)
956 GetStringInfoLength(icc_profile));
957 if (source_info.profile == (cmsHPROFILE) NULL)
958 ThrowProfileException(ResourceLimitError,
959 "ColorspaceColorProfileMismatch",name);
961 SetLCMSInfoScale(&source_info,1.0);
962 SetLCMSInfoTranslate(&source_info,0.0);
963 source_info.colorspace=sRGBColorspace;
964 source_info.channels=3;
965 switch (cmsGetColorSpace(source_info.profile))
969 source_info.colorspace=CMYKColorspace;
970 source_info.channels=4;
971 source_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
972 SetLCMSInfoScale(&source_info,100.0);
977 source_info.colorspace=GRAYColorspace;
978 source_info.channels=1;
979 source_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
984 source_info.colorspace=LabColorspace;
985 source_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
986 source_info.scale[0]=100.0;
987 source_info.scale[1]=255.0;
988 source_info.scale[2]=255.0;
989 source_info.translate[1]=(-0.5);
990 source_info.translate[2]=(-0.5);
995 source_info.colorspace=sRGBColorspace;
996 source_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1001 source_info.colorspace=XYZColorspace;
1002 source_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1006 ThrowProfileException(ImageError,
1007 "ColorspaceColorProfileMismatch",name);
1009 signature=cmsGetPCS(source_info.profile);
1010 if (target_info.profile != (cmsHPROFILE) NULL)
1011 signature=cmsGetColorSpace(target_info.profile);
1012 SetLCMSInfoScale(&target_info,1.0);
1013 SetLCMSInfoTranslate(&target_info,0.0);
1014 target_info.channels=3;
1017 case cmsSigCmykData:
1019 target_info.colorspace=CMYKColorspace;
1020 target_info.channels=4;
1021 target_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
1022 SetLCMSInfoScale(&target_info,0.01);
1025 case cmsSigGrayData:
1027 target_info.colorspace=GRAYColorspace;
1028 target_info.channels=1;
1029 target_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
1034 target_info.colorspace=LabColorspace;
1035 target_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
1036 target_info.scale[0]=0.01;
1037 target_info.scale[1]=1/255.0;
1038 target_info.scale[2]=1/255.0;
1039 target_info.translate[1]=0.5;
1040 target_info.translate[2]=0.5;
1045 target_info.colorspace=sRGBColorspace;
1046 target_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1051 target_info.colorspace=XYZColorspace;
1052 target_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1056 ThrowProfileException(ImageError,
1057 "ColorspaceColorProfileMismatch",name);
1059 switch (image->rendering_intent)
1061 case AbsoluteIntent:
1063 target_info.intent=INTENT_ABSOLUTE_COLORIMETRIC;
1066 case PerceptualIntent:
1068 target_info.intent=INTENT_PERCEPTUAL;
1071 case RelativeIntent:
1073 target_info.intent=INTENT_RELATIVE_COLORIMETRIC;
1076 case SaturationIntent:
1078 target_info.intent=INTENT_SATURATION;
1083 target_info.intent=INTENT_PERCEPTUAL;
1087 flags=cmsFLAGS_HIGHRESPRECALC;
1088#if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1089 if (image->black_point_compensation != MagickFalse)
1090 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1092 transform=AcquireTransformTLS(&source_info,&target_info,
1094 if (transform == (cmsHTRANSFORM *) NULL)
1095 ThrowProfileException(ImageError,
"UnableToCreateColorTransform",
1100 source_info.pixels=AcquirePixelTLS(image->columns,
1101 source_info.channels);
1102 target_info.pixels=AcquirePixelTLS(image->columns,
1103 target_info.channels);
1104 if ((source_info.pixels == (
double **) NULL) ||
1105 (target_info.pixels == (
double **) NULL))
1107 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1108 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1109 transform=DestroyTransformTLS(transform);
1110 ThrowProfileException(ResourceLimitError,
1111 "MemoryAllocationFailed",image->filename);
1113 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1115 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1116 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1117 transform=DestroyTransformTLS(transform);
1118 profile=DestroyStringInfo(profile);
1119 if (source_info.profile != (cmsHPROFILE) NULL)
1120 (void) cmsCloseProfile(source_info.profile);
1121 if (target_info.profile != (cmsHPROFILE) NULL)
1122 (
void) cmsCloseProfile(target_info.profile);
1123 return(MagickFalse);
1125 if (target_info.colorspace == CMYKColorspace)
1126 (void) SetImageColorspace(image,target_info.colorspace);
1128 image_view=AcquireAuthenticCacheView(image,exception);
1129#if defined(MAGICKCORE_OPENMP_SUPPORT)
1130 #pragma omp parallel for schedule(static) shared(status) \
1131 magick_number_threads(image,image,image->rows,1)
1133 for (y=0; y < (ssize_t) image->rows; y++)
1136 id = GetOpenMPThreadId();
1142 *magick_restrict indexes;
1153 if (status == MagickFalse)
1155 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1162 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1163 p=source_info.pixels[id];
1164 for (x=0; x < (ssize_t) image->columns; x++)
1166 *p++=GetLCMSPixel(source_info,GetPixelRed(q),0);
1167 if (source_info.channels > 1)
1169 *p++=GetLCMSPixel(source_info,GetPixelGreen(q),1);
1170 *p++=GetLCMSPixel(source_info,GetPixelBlue(q),2);
1172 if (source_info.channels > 3)
1174 *p=GetLCMSPixel(source_info,0,3);
1175 if (indexes != (IndexPacket *) NULL)
1176 *p=GetLCMSPixel(source_info,GetPixelIndex(indexes+x),3);
1181 cmsDoTransform(transform[
id],source_info.pixels[
id],
1182 target_info.pixels[
id],(
unsigned int) image->columns);
1183 p=target_info.pixels[id];
1185 for (x=0; x < (ssize_t) image->columns; x++)
1187 SetPixelRed(q,SetLCMSPixel(target_info,*p,0));
1188 SetPixelGreen(q,GetPixelRed(q));
1189 SetPixelBlue(q,GetPixelRed(q));
1191 if (target_info.channels > 1)
1193 SetPixelGreen(q,SetLCMSPixel(target_info,*p,1));
1195 SetPixelBlue(q,SetLCMSPixel(target_info,*p,2));
1198 if (target_info.channels > 3)
1200 if (indexes != (IndexPacket *) NULL)
1201 SetPixelIndex(indexes+x,SetLCMSPixel(target_info,*p,3));
1206 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1207 if (sync == MagickFalse)
1209 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1214#if defined(MAGICKCORE_OPENMP_SUPPORT)
1218 proceed=SetImageProgress(image,ProfileImageTag,progress,
1220 if (proceed == MagickFalse)
1224 image_view=DestroyCacheView(image_view);
1225 (void) SetImageColorspace(image,target_info.colorspace);
1230 image->type=image->matte == MagickFalse ? TrueColorType :
1234 case cmsSigCmykData:
1236 image->type=image->matte == MagickFalse ? ColorSeparationType :
1237 ColorSeparationMatteType;
1240 case cmsSigGrayData:
1242 image->type=image->matte == MagickFalse ? GrayscaleType :
1249 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1250 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1251 transform=DestroyTransformTLS(transform);
1252 if ((status != MagickFalse) &&
1253 (cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass))
1254 status=SetImageProfile(image,name,profile);
1255 if (target_info.profile != (cmsHPROFILE) NULL)
1256 (void) cmsCloseProfile(target_info.profile);
1258 (void) cmsCloseProfile(source_info.profile);
1259 cmsDeleteContext(cms_context);
1263 profile=DestroyStringInfo(profile);
1292MagickExport
StringInfo *RemoveImageProfile(
Image *image,
const char *name)
1297 assert(image != (
Image *) NULL);
1298 assert(image->signature == MagickCoreSignature);
1299 if (IsEventLogging() != MagickFalse)
1300 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1303 if (LocaleCompare(name,
"icc") == 0)
1308 image->color_profile.length=0;
1309 image->color_profile.info=(
unsigned char *) NULL;
1311 if (LocaleCompare(name,
"iptc") == 0)
1316 image->iptc_profile.length=0;
1317 image->iptc_profile.info=(
unsigned char *) NULL;
1319 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
1321 image->profiles,name);
1349MagickExport
void ResetImageProfileIterator(
const Image *image)
1351 assert(image != (
Image *) NULL);
1352 assert(image->signature == MagickCoreSignature);
1353 if (IsEventLogging() != MagickFalse)
1354 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1391static void *DestroyProfile(
void *profile)
1393 return((
void *) DestroyStringInfo((
StringInfo *) profile));
1396static inline const unsigned char *ReadResourceByte(
const unsigned char *p,
1397 unsigned char *quantum)
1403static inline const unsigned char *ReadResourceLong(
const unsigned char *p,
1404 unsigned int *quantum)
1406 *quantum=(
unsigned int) (*p++) << 24;
1407 *quantum|=(
unsigned int) (*p++) << 16;
1408 *quantum|=(
unsigned int) (*p++) << 8;
1409 *quantum|=(
unsigned int) (*p++);
1413static inline const unsigned char *ReadResourceShort(
const unsigned char *p,
1414 unsigned short *quantum)
1416 *quantum=(
unsigned short) (*p++) << 8;
1417 *quantum|=(
unsigned short) (*p++);
1421static inline void WriteResourceLong(
unsigned char *p,
1422 const unsigned int quantum)
1427 buffer[0]=(
unsigned char) (quantum >> 24);
1428 buffer[1]=(
unsigned char) (quantum >> 16);
1429 buffer[2]=(
unsigned char) (quantum >> 8);
1430 buffer[3]=(
unsigned char) quantum;
1431 (void) memcpy(p,buffer,4);
1434static void WriteTo8BimProfile(
Image *image,
const char *name,
1464 if (LocaleCompare(name,
"icc") == 0)
1467 if (LocaleCompare(name,
"iptc") == 0)
1470 if (LocaleCompare(name,
"xmp") == 0)
1475 image->profiles,
"8bim");
1478 datum=GetStringInfoDatum(profile_8bim);
1479 length=GetStringInfoLength(profile_8bim);
1480 for (p=datum; p < (datum+length-16); )
1483 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1486 p=ReadResourceShort(p,&
id);
1487 p=ReadResourceByte(p,&length_byte);
1489 if (((length_byte+1) & 0x01) != 0)
1491 if (p > (datum+length-4))
1493 p=ReadResourceLong(p,&value);
1494 count=(ssize_t) value;
1495 if ((count & 0x01) != 0)
1497 if ((count < 0) || (p > (datum+length-count)) || (count > (ssize_t) length))
1499 if (
id != profile_id)
1514 extent=(datum+length)-(p+count);
1518 extract_profile=AcquireStringInfo(offset+extent);
1519 (void) memcpy(extract_profile->datum,datum,offset);
1524 extract_extent=profile->length;
1525 if ((extract_extent & 0x01) != 0)
1527 extract_profile=AcquireStringInfo(offset+extract_extent+extent);
1528 (void) memcpy(extract_profile->datum,datum,offset-4);
1529 WriteResourceLong(extract_profile->datum+offset-4,(
unsigned int)
1531 (void) memcpy(extract_profile->datum+offset,
1532 profile->datum,profile->length);
1534 (void) memcpy(extract_profile->datum+offset+extract_extent,
1536 (void) AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1537 ConstantString(
"8bim"),CloneStringInfo(extract_profile));
1538 extract_profile=DestroyStringInfo(extract_profile);
1544static void GetProfilesFromResourceBlock(
Image *image,
1571 datum=GetStringInfoDatum(resource_block);
1572 length=GetStringInfoLength(resource_block);
1573 for (p=datum; p < (datum+length-16); )
1575 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1578 p=ReadResourceShort(p,&
id);
1579 p=ReadResourceByte(p,&length_byte);
1581 if (((length_byte+1) & 0x01) != 0)
1583 if (p > (datum+length-4))
1585 p=ReadResourceLong(p,&value);
1586 count=(ssize_t) value;
1587 if ((p > (datum+length-count)) || (count > (ssize_t) length) ||
1605 p=ReadResourceLong(p,&resolution);
1606 image->x_resolution=((double) resolution)/65536.0;
1607 p=ReadResourceShort(p,&units)+2;
1608 p=ReadResourceLong(p,&resolution)+4;
1609 image->y_resolution=((double) resolution)/65536.0;
1613 if ((ResolutionType) units != PixelsPerCentimeterResolution)
1614 image->units=PixelsPerInchResolution;
1617 image->units=PixelsPerCentimeterResolution;
1618 image->x_resolution/=2.54;
1619 image->y_resolution/=2.54;
1628 profile=AcquireStringInfo(count);
1629 SetStringInfoDatum(profile,p);
1630 (void) SetImageProfileInternal(image,
"iptc",profile,MagickTrue);
1631 profile=DestroyStringInfo(profile);
1648 profile=AcquireStringInfo(count);
1649 SetStringInfoDatum(profile,p);
1650 (void) SetImageProfileInternal(image,
"icc",profile,MagickTrue);
1651 profile=DestroyStringInfo(profile);
1660 profile=AcquireStringInfo(count);
1661 SetStringInfoDatum(profile,p);
1662 (void) SetImageProfileInternal(image,
"exif",profile,MagickTrue);
1663 profile=DestroyStringInfo(profile);
1672 profile=AcquireStringInfo(count);
1673 SetStringInfoDatum(profile,p);
1674 (void) SetImageProfileInternal(image,
"xmp",profile,MagickTrue);
1675 profile=DestroyStringInfo(profile);
1685 if ((count & 0x01) != 0)
1690#if defined(MAGICKCORE_XML_DELEGATE)
1691static MagickBooleanType ValidateXMPProfile(
Image *image,
1700 const char *artifact=GetImageArtifact(image,
"xmp:validate");
1701 if (IsStringTrue(artifact) == MagickFalse)
1703 document=xmlReadMemory((
const char *) GetStringInfoDatum(profile),(
int)
1704 GetStringInfoLength(profile),
"xmp.xml",NULL,XML_PARSE_NOERROR |
1705 XML_PARSE_NOWARNING);
1706 if (document == (xmlDocPtr) NULL)
1708 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1709 ImageWarning,
"CorruptImageProfile",
"`%s' (XMP)",image->filename);
1710 return(MagickFalse);
1712 xmlFreeDoc(document);
1716static MagickBooleanType ValidateXMPProfile(
Image *image,
1719 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1720 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
"'%s' (XML)",
1722 return(MagickFalse);
1726static MagickBooleanType SetImageProfileInternal(
Image *image,
const char *name,
1727 const StringInfo *profile,
const MagickBooleanType recursive)
1735 assert(image != (
Image *) NULL);
1736 assert(image->signature == MagickCoreSignature);
1737 if (IsEventLogging() != MagickFalse)
1738 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1739 if ((LocaleCompare(name,
"xmp") == 0) &&
1740 (ValidateXMPProfile(image,profile) == MagickFalse))
1743 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1745 (void) CopyMagickString(key,name,MaxTextExtent);
1747 status=AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1748 ConstantString(key),CloneStringInfo(profile));
1749 if ((status != MagickFalse) &&
1750 ((LocaleCompare(name,
"icc") == 0) || (LocaleCompare(name,
"icm") == 0)))
1758 icc_profile=GetImageProfile(image,name);
1759 if (icc_profile != (
const StringInfo *) NULL)
1761 image->color_profile.length=GetStringInfoLength(icc_profile);
1762 image->color_profile.info=GetStringInfoDatum(icc_profile);
1765 if ((status != MagickFalse) &&
1766 ((LocaleCompare(name,
"iptc") == 0) || (LocaleCompare(name,
"8bim") == 0)))
1774 iptc_profile=GetImageProfile(image,name);
1775 if (iptc_profile != (
const StringInfo *) NULL)
1777 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1778 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1781 if (status != MagickFalse)
1783 if (LocaleCompare(name,
"8bim") == 0)
1784 GetProfilesFromResourceBlock(image,profile);
1786 if (recursive == MagickFalse)
1787 WriteTo8BimProfile(image,name,profile);
1792MagickExport MagickBooleanType SetImageProfile(
Image *image,
const char *name,
1795 return(SetImageProfileInternal(image,name,profile,MagickFalse));
1822static inline int ReadProfileByte(
unsigned char **p,
size_t *length)
1834static inline signed short ReadProfileShort(
const EndianType endian,
1835 unsigned char *buffer)
1849 if (endian == LSBEndian)
1851 value=(
unsigned short) buffer[1] << 8;
1852 value|=(
unsigned short) buffer[0];
1853 quantum.unsigned_value=value & 0xffff;
1854 return(quantum.signed_value);
1856 value=(
unsigned short) buffer[0] << 8;
1857 value|=(
unsigned short) buffer[1];
1858 quantum.unsigned_value=value & 0xffff;
1859 return(quantum.signed_value);
1862static inline signed int ReadProfileLong(
const EndianType endian,
1863 unsigned char *buffer)
1877 if (endian == LSBEndian)
1879 value=(
unsigned int) buffer[3] << 24;
1880 value|=(
unsigned int) buffer[2] << 16;
1881 value|=(
unsigned int) buffer[1] << 8;
1882 value|=(
unsigned int) buffer[0];
1883 quantum.unsigned_value=value & 0xffffffff;
1884 return(quantum.signed_value);
1886 value=(
unsigned int) buffer[0] << 24;
1887 value|=(
unsigned int) buffer[1] << 16;
1888 value|=(
unsigned int) buffer[2] << 8;
1889 value|=(
unsigned int) buffer[3];
1890 quantum.unsigned_value=value & 0xffffffff;
1891 return(quantum.signed_value);
1894static inline signed int ReadProfileMSBLong(
unsigned char **p,
size_t *length)
1901 value=ReadProfileLong(MSBEndian,*p);
1907static inline signed short ReadProfileMSBShort(
unsigned char **p,
1915 value=ReadProfileShort(MSBEndian,*p);
1921static inline void WriteProfileLong(
const EndianType endian,
1922 const size_t value,
unsigned char *p)
1927 if (endian == LSBEndian)
1929 buffer[0]=(
unsigned char) value;
1930 buffer[1]=(
unsigned char) (value >> 8);
1931 buffer[2]=(
unsigned char) (value >> 16);
1932 buffer[3]=(
unsigned char) (value >> 24);
1933 (void) memcpy(p,buffer,4);
1936 buffer[0]=(
unsigned char) (value >> 24);
1937 buffer[1]=(
unsigned char) (value >> 16);
1938 buffer[2]=(
unsigned char) (value >> 8);
1939 buffer[3]=(
unsigned char) value;
1940 (void) memcpy(p,buffer,4);
1943static void WriteProfileShort(
const EndianType endian,
1944 const unsigned short value,
unsigned char *p)
1949 if (endian == LSBEndian)
1951 buffer[0]=(
unsigned char) value;
1952 buffer[1]=(
unsigned char) (value >> 8);
1953 (void) memcpy(p,buffer,2);
1956 buffer[0]=(
unsigned char) (value >> 8);
1957 buffer[1]=(
unsigned char) value;
1958 (void) memcpy(p,buffer,2);
1961static MagickBooleanType SyncExifProfile(
const Image *image,
unsigned char *exif,
1964#define MaxDirectoryStack 16
1965#define EXIF_DELIMITER "\n"
1966#define EXIF_NUM_FORMATS 12
1967#define TAG_EXIF_OFFSET 0x8769
1968#define TAG_INTEROP_OFFSET 0xa005
1970 typedef struct _DirectoryInfo
1980 directory_stack[MaxDirectoryStack] = { { 0, 0 } };
1998 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
2004 return(MagickFalse);
2005 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2006 if ((
id != 0x4949) && (
id != 0x4D4D))
2010 if (ReadProfileByte(&exif,&length) != 0x45)
2012 if (ReadProfileByte(&exif,&length) != 0x78)
2014 if (ReadProfileByte(&exif,&length) != 0x69)
2016 if (ReadProfileByte(&exif,&length) != 0x66)
2018 if (ReadProfileByte(&exif,&length) != 0x00)
2020 if (ReadProfileByte(&exif,&length) != 0x00)
2025 return(MagickFalse);
2026 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2035 return(MagickFalse);
2036 if (ReadProfileShort(endian,exif+2) != 0x002a)
2037 return(MagickFalse);
2041 offset=(ssize_t) ReadProfileLong(endian,exif+4);
2042 if ((offset < 0) || ((size_t) offset >= length))
2043 return(MagickFalse);
2044 directory=exif+offset;
2047 exif_resources=NewSplayTree((
int (*)(
const void *,
const void *)) NULL,
2048 (
void *(*)(
void *)) NULL,(
void *(*)(
void *)) NULL);
2054 directory=directory_stack[level].directory;
2055 entry=directory_stack[level].entry;
2057 if ((directory < exif) || (directory > (exif+length-2)))
2062 number_entries=ReadProfileShort(endian,directory);
2063 for ( ; entry < number_entries; entry++)
2079 q=(
unsigned char *) (directory+2+(12*entry));
2080 if (q > (exif+length-12))
2082 if (GetValueFromSplayTree(exif_resources,q) == q)
2084 (void) AddValueToSplayTree(exif_resources,q,q);
2085 tag_value=(ssize_t) ReadProfileShort(endian,q);
2086 format=(ssize_t) ReadProfileShort(endian,q+2);
2087 if ((format < 0) || ((format-1) >= EXIF_NUM_FORMATS))
2089 components=(int) ReadProfileLong(endian,q+4);
2092 number_bytes=(size_t) components*format_bytes[format];
2093 if ((ssize_t) number_bytes < components)
2095 if (number_bytes <= 4)
2102 offset=(ssize_t) ReadProfileLong(endian,q+8);
2103 if ((offset < 0) || ((size_t) (offset+number_bytes) > length))
2105 if (~length < number_bytes)
2107 p=(
unsigned char *) (exif+offset);
2113 (void) WriteProfileLong(endian,(
size_t) (image->x_resolution+0.5),p);
2114 if (number_bytes == 8)
2115 (void) WriteProfileLong(endian,1UL,p+4);
2120 (void) WriteProfileLong(endian,(
size_t) (image->y_resolution+0.5),p);
2121 if (number_bytes == 8)
2122 (void) WriteProfileLong(endian,1UL,p+4);
2127 if (number_bytes == 4)
2129 (void) WriteProfileLong(endian,(
size_t) image->orientation,p);
2132 (void) WriteProfileShort(endian,(
unsigned short) image->orientation,
2138 if (number_bytes == 4)
2140 (void) WriteProfileLong(endian,((
size_t) image->units)+1,p);
2143 (void) WriteProfileShort(endian,(
unsigned short) (image->units+1),p);
2149 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
2151 offset=(ssize_t) ReadProfileLong(endian,p);
2152 if (((
size_t) offset < length) && (level < (MaxDirectoryStack-2)))
2154 directory_stack[level].directory=directory;
2156 directory_stack[level].entry=entry;
2158 directory_stack[level].directory=exif+offset;
2159 directory_stack[level].entry=0;
2161 if ((directory+2+(12*number_entries)) > (exif+length))
2163 offset=(ssize_t) ReadProfileLong(endian,directory+2+(12*
2165 if ((offset != 0) && ((size_t) offset < length) &&
2166 (level < (MaxDirectoryStack-2)))
2168 directory_stack[level].directory=exif+offset;
2169 directory_stack[level].entry=0;
2176 }
while (level > 0);
2177 exif_resources=DestroySplayTree(exif_resources);
2181static MagickBooleanType Sync8BimProfile(
const Image *image,
2196 length=GetStringInfoLength(profile);
2197 p=GetStringInfoDatum(profile);
2200 if (ReadProfileByte(&p,&length) != 0x38)
2202 if (ReadProfileByte(&p,&length) != 0x42)
2204 if (ReadProfileByte(&p,&length) != 0x49)
2206 if (ReadProfileByte(&p,&length) != 0x4D)
2209 return(MagickFalse);
2210 id=ReadProfileMSBShort(&p,&length);
2211 count=(ssize_t) ReadProfileByte(&p,&length);
2212 if ((count >= (ssize_t) length) || (count < 0))
2213 return(MagickFalse);
2216 if ((*p & 0x01) == 0)
2217 (
void) ReadProfileByte(&p,&length);
2218 count=(ssize_t) ReadProfileMSBLong(&p,&length);
2219 if ((count > (ssize_t) length) || (count < 0))
2220 return(MagickFalse);
2221 if ((
id == 0x3ED) && (count == 16))
2223 if (image->units == PixelsPerCentimeterResolution)
2224 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2225 image->x_resolution*2.54*65536.0),p);
2227 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2228 image->x_resolution*65536.0),p);
2229 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+4);
2230 if (image->units == PixelsPerCentimeterResolution)
2231 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2232 image->y_resolution*2.54*65536.0),p+8);
2234 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2235 image->y_resolution*65536.0),p+8);
2236 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+12);
2239 (void) SyncExifProfile(image,p,count);
2246MagickExport MagickBooleanType SyncImageProfiles(
Image *image)
2255 profile=(
StringInfo *) GetImageProfile(image,
"8BIM");
2257 if (Sync8BimProfile(image,profile) == MagickFalse)
2259 profile=(
StringInfo *) GetImageProfile(image,
"EXIF");
2261 if (SyncExifProfile(image,GetStringInfoDatum(profile),
2262 GetStringInfoLength(profile)) == MagickFalse)