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#if !defined(MAGICKCORE_HDRI_SUPPORT)
990 source_info.translate[1]=(-0.5);
991 source_info.translate[2]=(-0.5);
997 source_info.colorspace=sRGBColorspace;
998 source_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1003 source_info.colorspace=XYZColorspace;
1004 source_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1008 ThrowProfileException(ImageError,
1009 "ColorspaceColorProfileMismatch",name);
1011 signature=cmsGetPCS(source_info.profile);
1012 if (target_info.profile != (cmsHPROFILE) NULL)
1013 signature=cmsGetColorSpace(target_info.profile);
1014 SetLCMSInfoScale(&target_info,1.0);
1015 SetLCMSInfoTranslate(&target_info,0.0);
1016 target_info.channels=3;
1019 case cmsSigCmykData:
1021 target_info.colorspace=CMYKColorspace;
1022 target_info.channels=4;
1023 target_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
1024 SetLCMSInfoScale(&target_info,0.01);
1027 case cmsSigGrayData:
1029 target_info.colorspace=GRAYColorspace;
1030 target_info.channels=1;
1031 target_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
1036 target_info.colorspace=LabColorspace;
1037 target_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
1038 target_info.scale[0]=0.01;
1039 target_info.scale[1]=1/255.0;
1040 target_info.scale[2]=1/255.0;
1041#if !defined(MAGICKCORE_HDRI_SUPPORT)
1042 target_info.translate[1]=0.5;
1043 target_info.translate[2]=0.5;
1049 target_info.colorspace=sRGBColorspace;
1050 target_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1055 target_info.colorspace=XYZColorspace;
1056 target_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1060 ThrowProfileException(ImageError,
1061 "ColorspaceColorProfileMismatch",name);
1063 switch (image->rendering_intent)
1065 case AbsoluteIntent:
1067 target_info.intent=INTENT_ABSOLUTE_COLORIMETRIC;
1070 case PerceptualIntent:
1072 target_info.intent=INTENT_PERCEPTUAL;
1075 case RelativeIntent:
1077 target_info.intent=INTENT_RELATIVE_COLORIMETRIC;
1080 case SaturationIntent:
1082 target_info.intent=INTENT_SATURATION;
1087 target_info.intent=INTENT_PERCEPTUAL;
1091 flags=cmsFLAGS_HIGHRESPRECALC;
1092#if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1093 if (image->black_point_compensation != MagickFalse)
1094 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1096 transform=AcquireTransformTLS(&source_info,&target_info,
1098 if (transform == (cmsHTRANSFORM *) NULL)
1099 ThrowProfileException(ImageError,
"UnableToCreateColorTransform",
1104 source_info.pixels=AcquirePixelTLS(image->columns,
1105 source_info.channels);
1106 target_info.pixels=AcquirePixelTLS(image->columns,
1107 target_info.channels);
1108 if ((source_info.pixels == (
double **) NULL) ||
1109 (target_info.pixels == (
double **) NULL))
1111 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1112 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1113 transform=DestroyTransformTLS(transform);
1114 ThrowProfileException(ResourceLimitError,
1115 "MemoryAllocationFailed",image->filename);
1117 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1119 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1120 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1121 transform=DestroyTransformTLS(transform);
1122 profile=DestroyStringInfo(profile);
1123 if (source_info.profile != (cmsHPROFILE) NULL)
1124 (void) cmsCloseProfile(source_info.profile);
1125 if (target_info.profile != (cmsHPROFILE) NULL)
1126 (void) cmsCloseProfile(target_info.profile);
1127 return(MagickFalse);
1129 if (target_info.colorspace == CMYKColorspace)
1130 (void) SetImageColorspace(image,target_info.colorspace);
1132 image_view=AcquireAuthenticCacheView(image,exception);
1133#if defined(MAGICKCORE_OPENMP_SUPPORT)
1134 #pragma omp parallel for schedule(static) shared(status) \
1135 magick_number_threads(image,image,image->rows,1)
1137 for (y=0; y < (ssize_t) image->rows; y++)
1140 id = GetOpenMPThreadId();
1146 *magick_restrict indexes;
1157 if (status == MagickFalse)
1159 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1166 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1167 p=source_info.pixels[id];
1168 for (x=0; x < (ssize_t) image->columns; x++)
1170 *p++=GetLCMSPixel(source_info,GetPixelRed(q),0);
1171 if (source_info.channels > 1)
1173 *p++=GetLCMSPixel(source_info,GetPixelGreen(q),1);
1174 *p++=GetLCMSPixel(source_info,GetPixelBlue(q),2);
1176 if (source_info.channels > 3)
1178 *p=GetLCMSPixel(source_info,0,3);
1179 if (indexes != (IndexPacket *) NULL)
1180 *p=GetLCMSPixel(source_info,GetPixelIndex(indexes+x),3);
1185 cmsDoTransform(transform[
id],source_info.pixels[
id],
1186 target_info.pixels[
id],(
unsigned int) image->columns);
1187 p=target_info.pixels[id];
1189 for (x=0; x < (ssize_t) image->columns; x++)
1191 SetPixelRed(q,SetLCMSPixel(target_info,*p,0));
1192 SetPixelGreen(q,GetPixelRed(q));
1193 SetPixelBlue(q,GetPixelRed(q));
1195 if (target_info.channels > 1)
1197 SetPixelGreen(q,SetLCMSPixel(target_info,*p,1));
1199 SetPixelBlue(q,SetLCMSPixel(target_info,*p,2));
1202 if (target_info.channels > 3)
1204 if (indexes != (IndexPacket *) NULL)
1205 SetPixelIndex(indexes+x,SetLCMSPixel(target_info,*p,3));
1210 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1211 if (sync == MagickFalse)
1213 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1218#if defined(MAGICKCORE_OPENMP_SUPPORT)
1222 proceed=SetImageProgress(image,ProfileImageTag,progress,
1224 if (proceed == MagickFalse)
1228 image_view=DestroyCacheView(image_view);
1229 (void) SetImageColorspace(image,target_info.colorspace);
1234 image->type=image->matte == MagickFalse ? TrueColorType :
1238 case cmsSigCmykData:
1240 image->type=image->matte == MagickFalse ? ColorSeparationType :
1241 ColorSeparationMatteType;
1244 case cmsSigGrayData:
1246 image->type=image->matte == MagickFalse ? GrayscaleType :
1253 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1254 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1255 transform=DestroyTransformTLS(transform);
1256 if ((status != MagickFalse) &&
1257 (cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass))
1258 status=SetImageProfile(image,name,profile);
1259 if (target_info.profile != (cmsHPROFILE) NULL)
1260 (void) cmsCloseProfile(target_info.profile);
1262 (void) cmsCloseProfile(source_info.profile);
1263 cmsDeleteContext(cms_context);
1267 profile=DestroyStringInfo(profile);
1296MagickExport
StringInfo *RemoveImageProfile(
Image *image,
const char *name)
1301 assert(image != (
Image *) NULL);
1302 assert(image->signature == MagickCoreSignature);
1303 if (IsEventLogging() != MagickFalse)
1304 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1307 if (LocaleCompare(name,
"icc") == 0)
1312 image->color_profile.length=0;
1313 image->color_profile.info=(
unsigned char *) NULL;
1315 if (LocaleCompare(name,
"iptc") == 0)
1320 image->iptc_profile.length=0;
1321 image->iptc_profile.info=(
unsigned char *) NULL;
1323 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
1325 image->profiles,name);
1353MagickExport
void ResetImageProfileIterator(
const Image *image)
1355 assert(image != (
Image *) NULL);
1356 assert(image->signature == MagickCoreSignature);
1357 if (IsEventLogging() != MagickFalse)
1358 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1395static void *DestroyProfile(
void *profile)
1397 return((
void *) DestroyStringInfo((
StringInfo *) profile));
1400static inline const unsigned char *ReadResourceByte(
const unsigned char *p,
1401 unsigned char *quantum)
1407static inline const unsigned char *ReadResourceLong(
const unsigned char *p,
1408 unsigned int *quantum)
1410 *quantum=(
unsigned int) (*p++) << 24;
1411 *quantum|=(
unsigned int) (*p++) << 16;
1412 *quantum|=(
unsigned int) (*p++) << 8;
1413 *quantum|=(
unsigned int) (*p++);
1417static inline const unsigned char *ReadResourceShort(
const unsigned char *p,
1418 unsigned short *quantum)
1420 *quantum=(
unsigned short) (*p++) << 8;
1421 *quantum|=(
unsigned short) (*p++);
1425static inline void WriteResourceLong(
unsigned char *p,
1426 const unsigned int quantum)
1431 buffer[0]=(
unsigned char) (quantum >> 24);
1432 buffer[1]=(
unsigned char) (quantum >> 16);
1433 buffer[2]=(
unsigned char) (quantum >> 8);
1434 buffer[3]=(
unsigned char) quantum;
1435 (void) memcpy(p,buffer,4);
1438static void WriteTo8BimProfile(
Image *image,
const char *name,
1468 if (LocaleCompare(name,
"icc") == 0)
1471 if (LocaleCompare(name,
"iptc") == 0)
1474 if (LocaleCompare(name,
"xmp") == 0)
1479 image->profiles,
"8bim");
1482 datum=GetStringInfoDatum(profile_8bim);
1483 length=GetStringInfoLength(profile_8bim);
1484 for (p=datum; p < (datum+length-16); )
1487 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1490 p=ReadResourceShort(p,&
id);
1491 p=ReadResourceByte(p,&length_byte);
1492 p+=(ptrdiff_t) length_byte;
1493 if (((length_byte+1) & 0x01) != 0)
1495 if (p > (datum+length-4))
1497 p=ReadResourceLong(p,&value);
1498 count=(ssize_t) value;
1499 if ((count & 0x01) != 0)
1501 if ((count < 0) || (p > (datum+length-count)) || (count > (ssize_t) length))
1503 if (
id != profile_id)
1504 p+=(ptrdiff_t) count;
1518 extent=(datum+length)-(p+count);
1522 extract_profile=AcquireStringInfo(offset+extent);
1523 (void) memcpy(extract_profile->datum,datum,offset);
1528 extract_extent=profile->length;
1529 if ((extract_extent & 0x01) != 0)
1531 extract_profile=AcquireStringInfo(offset+extract_extent+extent);
1532 (void) memcpy(extract_profile->datum,datum,offset-4);
1533 WriteResourceLong(extract_profile->datum+offset-4,(
unsigned int)
1535 (void) memcpy(extract_profile->datum+offset,
1536 profile->datum,profile->length);
1538 (void) memcpy(extract_profile->datum+offset+extract_extent,
1540 (void) AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1541 ConstantString(
"8bim"),CloneStringInfo(extract_profile));
1542 extract_profile=DestroyStringInfo(extract_profile);
1548static void GetProfilesFromResourceBlock(
Image *image,
1575 datum=GetStringInfoDatum(resource_block);
1576 length=GetStringInfoLength(resource_block);
1577 for (p=datum; p < (datum+length-16); )
1579 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1582 p=ReadResourceShort(p,&
id);
1583 p=ReadResourceByte(p,&length_byte);
1584 p+=(ptrdiff_t) length_byte;
1585 if (((length_byte+1) & 0x01) != 0)
1587 if (p > (datum+length-4))
1589 p=ReadResourceLong(p,&value);
1590 count=(ssize_t) value;
1591 if ((p > (datum+length-count)) || (count > (ssize_t) length) ||
1609 p=ReadResourceLong(p,&resolution);
1610 image->x_resolution=((double) resolution)/65536.0;
1611 p=ReadResourceShort(p,&units)+2;
1612 p=ReadResourceLong(p,&resolution)+4;
1613 image->y_resolution=((double) resolution)/65536.0;
1617 if ((ResolutionType) units != PixelsPerCentimeterResolution)
1618 image->units=PixelsPerInchResolution;
1621 image->units=PixelsPerCentimeterResolution;
1622 image->x_resolution/=2.54;
1623 image->y_resolution/=2.54;
1632 profile=AcquireStringInfo(count);
1633 SetStringInfoDatum(profile,p);
1634 (void) SetImageProfileInternal(image,
"iptc",profile,MagickTrue);
1635 profile=DestroyStringInfo(profile);
1636 p+=(ptrdiff_t) count;
1644 p+=(ptrdiff_t) count;
1652 profile=AcquireStringInfo(count);
1653 SetStringInfoDatum(profile,p);
1654 (void) SetImageProfileInternal(image,
"icc",profile,MagickTrue);
1655 profile=DestroyStringInfo(profile);
1656 p+=(ptrdiff_t) count;
1664 profile=AcquireStringInfo(count);
1665 SetStringInfoDatum(profile,p);
1666 (void) SetImageProfileInternal(image,
"exif",profile,MagickTrue);
1667 profile=DestroyStringInfo(profile);
1668 p+=(ptrdiff_t) count;
1676 profile=AcquireStringInfo(count);
1677 SetStringInfoDatum(profile,p);
1678 (void) SetImageProfileInternal(image,
"xmp",profile,MagickTrue);
1679 profile=DestroyStringInfo(profile);
1680 p+=(ptrdiff_t) count;
1685 p+=(ptrdiff_t) count;
1689 if ((count & 0x01) != 0)
1694#if defined(MAGICKCORE_XML_DELEGATE)
1695static MagickBooleanType ValidateXMPProfile(
Image *image,
1704 const char *artifact=GetImageArtifact(image,
"xmp:validate");
1705 if (IsStringTrue(artifact) == MagickFalse)
1707 document=xmlReadMemory((
const char *) GetStringInfoDatum(profile),(
int)
1708 GetStringInfoLength(profile),
"xmp.xml",NULL,XML_PARSE_NOERROR |
1709 XML_PARSE_NOWARNING);
1710 if (document == (xmlDocPtr) NULL)
1712 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1713 ImageWarning,
"CorruptImageProfile",
"`%s' (XMP)",image->filename);
1714 return(MagickFalse);
1716 xmlFreeDoc(document);
1720static MagickBooleanType ValidateXMPProfile(
Image *image,
1723 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1724 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
"'%s' (XML)",
1726 return(MagickFalse);
1730static MagickBooleanType SetImageProfileInternal(
Image *image,
const char *name,
1731 const StringInfo *profile,
const MagickBooleanType recursive)
1739 assert(image != (
Image *) NULL);
1740 assert(image->signature == MagickCoreSignature);
1741 if (IsEventLogging() != MagickFalse)
1742 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1743 if ((LocaleCompare(name,
"xmp") == 0) &&
1744 (ValidateXMPProfile(image,profile) == MagickFalse))
1747 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1749 (void) CopyMagickString(key,name,MaxTextExtent);
1751 status=AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1752 ConstantString(key),CloneStringInfo(profile));
1753 if ((status != MagickFalse) &&
1754 ((LocaleCompare(name,
"icc") == 0) || (LocaleCompare(name,
"icm") == 0)))
1762 icc_profile=GetImageProfile(image,name);
1763 if (icc_profile != (
const StringInfo *) NULL)
1765 image->color_profile.length=GetStringInfoLength(icc_profile);
1766 image->color_profile.info=GetStringInfoDatum(icc_profile);
1769 if ((status != MagickFalse) &&
1770 ((LocaleCompare(name,
"iptc") == 0) || (LocaleCompare(name,
"8bim") == 0)))
1778 iptc_profile=GetImageProfile(image,name);
1779 if (iptc_profile != (
const StringInfo *) NULL)
1781 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
1782 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
1785 if (status != MagickFalse)
1787 if (LocaleCompare(name,
"8bim") == 0)
1788 GetProfilesFromResourceBlock(image,profile);
1790 if (recursive == MagickFalse)
1791 WriteTo8BimProfile(image,name,profile);
1796MagickExport MagickBooleanType SetImageProfile(
Image *image,
const char *name,
1799 return(SetImageProfileInternal(image,name,profile,MagickFalse));
1826static inline int ReadProfileByte(
unsigned char **p,
size_t *length)
1838static inline signed short ReadProfileShort(
const EndianType endian,
1839 unsigned char *buffer)
1853 if (endian == LSBEndian)
1855 value=(
unsigned short) buffer[1] << 8;
1856 value|=(
unsigned short) buffer[0];
1857 quantum.unsigned_value=value & 0xffff;
1858 return(quantum.signed_value);
1860 value=(
unsigned short) buffer[0] << 8;
1861 value|=(
unsigned short) buffer[1];
1862 quantum.unsigned_value=value & 0xffff;
1863 return(quantum.signed_value);
1866static inline signed int ReadProfileLong(
const EndianType endian,
1867 unsigned char *buffer)
1881 if (endian == LSBEndian)
1883 value=(
unsigned int) buffer[3] << 24;
1884 value|=(
unsigned int) buffer[2] << 16;
1885 value|=(
unsigned int) buffer[1] << 8;
1886 value|=(
unsigned int) buffer[0];
1887 quantum.unsigned_value=value & 0xffffffff;
1888 return(quantum.signed_value);
1890 value=(
unsigned int) buffer[0] << 24;
1891 value|=(
unsigned int) buffer[1] << 16;
1892 value|=(
unsigned int) buffer[2] << 8;
1893 value|=(
unsigned int) buffer[3];
1894 quantum.unsigned_value=value & 0xffffffff;
1895 return(quantum.signed_value);
1898static inline signed int ReadProfileMSBLong(
unsigned char **p,
size_t *length)
1905 value=ReadProfileLong(MSBEndian,*p);
1911static inline signed short ReadProfileMSBShort(
unsigned char **p,
1919 value=ReadProfileShort(MSBEndian,*p);
1925static inline void WriteProfileLong(
const EndianType endian,
1926 const size_t value,
unsigned char *p)
1931 if (endian == LSBEndian)
1933 buffer[0]=(
unsigned char) value;
1934 buffer[1]=(
unsigned char) (value >> 8);
1935 buffer[2]=(
unsigned char) (value >> 16);
1936 buffer[3]=(
unsigned char) (value >> 24);
1937 (void) memcpy(p,buffer,4);
1940 buffer[0]=(
unsigned char) (value >> 24);
1941 buffer[1]=(
unsigned char) (value >> 16);
1942 buffer[2]=(
unsigned char) (value >> 8);
1943 buffer[3]=(
unsigned char) value;
1944 (void) memcpy(p,buffer,4);
1947static void WriteProfileShort(
const EndianType endian,
1948 const unsigned short value,
unsigned char *p)
1953 if (endian == LSBEndian)
1955 buffer[0]=(
unsigned char) value;
1956 buffer[1]=(
unsigned char) (value >> 8);
1957 (void) memcpy(p,buffer,2);
1960 buffer[0]=(
unsigned char) (value >> 8);
1961 buffer[1]=(
unsigned char) value;
1962 (void) memcpy(p,buffer,2);
1965static MagickBooleanType SyncExifProfile(
const Image *image,
unsigned char *exif,
1968#define MaxDirectoryStack 16
1969#define EXIF_DELIMITER "\n"
1970#define EXIF_NUM_FORMATS 12
1971#define TAG_EXIF_OFFSET 0x8769
1972#define TAG_INTEROP_OFFSET 0xa005
1974 typedef struct _DirectoryInfo
1984 directory_stack[MaxDirectoryStack] = { { 0, 0 } };
2002 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
2008 return(MagickFalse);
2009 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2010 if ((
id != 0x4949) && (
id != 0x4D4D))
2014 if (ReadProfileByte(&exif,&length) != 0x45)
2016 if (ReadProfileByte(&exif,&length) != 0x78)
2018 if (ReadProfileByte(&exif,&length) != 0x69)
2020 if (ReadProfileByte(&exif,&length) != 0x66)
2022 if (ReadProfileByte(&exif,&length) != 0x00)
2024 if (ReadProfileByte(&exif,&length) != 0x00)
2029 return(MagickFalse);
2030 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2039 return(MagickFalse);
2040 if (ReadProfileShort(endian,exif+2) != 0x002a)
2041 return(MagickFalse);
2045 offset=(ssize_t) ReadProfileLong(endian,exif+4);
2046 if ((offset < 0) || ((
size_t) offset >= length))
2047 return(MagickFalse);
2048 directory=exif+offset;
2051 exif_resources=NewSplayTree((
int (*)(
const void *,
const void *)) NULL,
2052 (
void *(*)(
void *)) NULL,(
void *(*)(
void *)) NULL);
2058 directory=directory_stack[level].directory;
2059 entry=directory_stack[level].entry;
2061 if ((directory < exif) || (directory > (exif+length-2)))
2066 number_entries=ReadProfileShort(endian,directory);
2067 for ( ; entry < number_entries; entry++)
2083 q=(
unsigned char *) (directory+2+(12*entry));
2084 if (q > (exif+length-12))
2086 if (GetValueFromSplayTree(exif_resources,q) == q)
2088 (void) AddValueToSplayTree(exif_resources,q,q);
2089 tag_value=(ssize_t) ReadProfileShort(endian,q);
2090 format=(ssize_t) ReadProfileShort(endian,q+2);
2091 if ((format < 0) || ((format-1) >= EXIF_NUM_FORMATS))
2093 components=(int) ReadProfileLong(endian,q+4);
2096 number_bytes=(size_t) components*format_bytes[format];
2097 if ((ssize_t) number_bytes < components)
2099 if (number_bytes <= 4)
2106 offset=(ssize_t) ReadProfileLong(endian,q+8);
2107 if ((offset < 0) || ((
size_t) (offset+number_bytes) > length))
2109 if (~length < number_bytes)
2111 p=(
unsigned char *) (exif+offset);
2117 (void) WriteProfileLong(endian,(
size_t) (image->x_resolution+0.5),p);
2118 if (number_bytes == 8)
2119 (void) WriteProfileLong(endian,1UL,p+4);
2124 (void) WriteProfileLong(endian,(
size_t) (image->y_resolution+0.5),p);
2125 if (number_bytes == 8)
2126 (void) WriteProfileLong(endian,1UL,p+4);
2131 if (number_bytes == 4)
2133 (void) WriteProfileLong(endian,(
size_t) image->orientation,p);
2136 (void) WriteProfileShort(endian,(
unsigned short) image->orientation,
2142 if (number_bytes == 4)
2144 (void) WriteProfileLong(endian,((
size_t) image->units)+1,p);
2147 (void) WriteProfileShort(endian,(
unsigned short) (image->units+1),p);
2153 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
2155 offset=(ssize_t) ReadProfileLong(endian,p);
2156 if (((
size_t) offset < length) && (level < (MaxDirectoryStack-2)))
2158 directory_stack[level].directory=directory;
2160 directory_stack[level].entry=entry;
2162 directory_stack[level].directory=exif+offset;
2163 directory_stack[level].entry=0;
2165 if ((directory+2+(12*number_entries)) > (exif+length))
2167 offset=(ssize_t) ReadProfileLong(endian,directory+2+(12*
2169 if ((offset != 0) && ((
size_t) offset < length) &&
2170 (level < (MaxDirectoryStack-2)))
2172 directory_stack[level].directory=exif+offset;
2173 directory_stack[level].entry=0;
2180 }
while (level > 0);
2181 exif_resources=DestroySplayTree(exif_resources);
2185static MagickBooleanType Sync8BimProfile(
const Image *image,
2200 length=GetStringInfoLength(profile);
2201 p=GetStringInfoDatum(profile);
2204 if (ReadProfileByte(&p,&length) != 0x38)
2206 if (ReadProfileByte(&p,&length) != 0x42)
2208 if (ReadProfileByte(&p,&length) != 0x49)
2210 if (ReadProfileByte(&p,&length) != 0x4D)
2213 return(MagickFalse);
2214 id=ReadProfileMSBShort(&p,&length);
2215 count=(ssize_t) ReadProfileByte(&p,&length);
2216 if ((count >= (ssize_t) length) || (count < 0))
2217 return(MagickFalse);
2218 p+=(ptrdiff_t) count;
2220 if ((*p & 0x01) == 0)
2221 (void) ReadProfileByte(&p,&length);
2222 count=(ssize_t) ReadProfileMSBLong(&p,&length);
2223 if ((count > (ssize_t) length) || (count < 0))
2224 return(MagickFalse);
2225 if ((
id == 0x3ED) && (count == 16))
2227 if (image->units == PixelsPerCentimeterResolution)
2228 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2229 image->x_resolution*2.54*65536.0),p);
2231 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2232 image->x_resolution*65536.0),p);
2233 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+4);
2234 if (image->units == PixelsPerCentimeterResolution)
2235 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2236 image->y_resolution*2.54*65536.0),p+8);
2238 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2239 image->y_resolution*65536.0),p+8);
2240 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+12);
2243 (void) SyncExifProfile(image,p,count);
2244 p+=(ptrdiff_t) count;
2250MagickExport MagickBooleanType SyncImageProfiles(
Image *image)
2259 profile=(
StringInfo *) GetImageProfile(image,
"8BIM");
2261 if (Sync8BimProfile(image,profile) == MagickFalse)
2263 profile=(
StringInfo *) GetImageProfile(image,
"EXIF");
2265 if (SyncExifProfile(image,GetStringInfoDatum(profile),
2266 GetStringInfoLength(profile)) == MagickFalse)