42#include "MagickCore/studio.h"
43#include "MagickCore/artifact.h"
44#include "MagickCore/attribute.h"
45#include "MagickCore/cache.h"
46#include "MagickCore/color.h"
47#include "MagickCore/colorspace-private.h"
48#include "MagickCore/configure.h"
49#include "MagickCore/exception.h"
50#include "MagickCore/exception-private.h"
51#include "MagickCore/image.h"
52#include "MagickCore/linked-list.h"
53#include "MagickCore/memory_.h"
54#include "MagickCore/monitor.h"
55#include "MagickCore/monitor-private.h"
56#include "MagickCore/option.h"
57#include "MagickCore/option-private.h"
58#include "MagickCore/pixel-accessor.h"
59#include "MagickCore/profile.h"
60#include "MagickCore/profile-private.h"
61#include "MagickCore/property.h"
62#include "MagickCore/quantum.h"
63#include "MagickCore/quantum-private.h"
64#include "MagickCore/resource_.h"
65#include "MagickCore/splay-tree.h"
66#include "MagickCore/string_.h"
67#include "MagickCore/string-private.h"
68#include "MagickCore/thread-private.h"
69#include "MagickCore/token.h"
70#include "MagickCore/utility.h"
71#if defined(MAGICKCORE_LCMS_DELEGATE)
73#if defined(MAGICKCORE_HAVE_LCMS_LCMS2_H)
74#include <lcms/lcms2.h>
79#if defined(MAGICKCORE_XML_DELEGATE)
80# include <libxml/parser.h>
81# include <libxml/tree.h>
87static MagickBooleanType
146MagickExport MagickBooleanType CloneImageProfiles(
Image *image,
147 const Image *clone_image)
149 assert(image != (
Image *) NULL);
150 assert(image->signature == MagickCoreSignature);
151 assert(clone_image != (
const Image *) NULL);
152 assert(clone_image->signature == MagickCoreSignature);
153 if (IsEventLogging() != MagickFalse)
154 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
155 if (clone_image->profiles != (
void *) NULL)
157 if (image->profiles != (
void *) NULL)
158 DestroyImageProfiles(image);
159 image->profiles=CloneSplayTree((
SplayTreeInfo *) clone_image->profiles,
160 (
void *(*)(
void *)) ConstantString,(
void *(*)(
void *)) CloneStringInfo);
189MagickExport MagickBooleanType DeleteImageProfile(
Image *image,
const char *name)
191 assert(image != (
Image *) NULL);
192 assert(image->signature == MagickCoreSignature);
193 if (IsEventLogging() != MagickFalse)
194 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
197 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
198 return(DeleteNodeFromSplayTree((
SplayTreeInfo *) image->profiles,name));
223MagickExport
void DestroyImageProfiles(
Image *image)
226 image->profiles=DestroySplayTree((
SplayTreeInfo *) image->profiles);
259 assert(image != (
Image *) NULL);
260 assert(image->signature == MagickCoreSignature);
261 if (IsEventLogging() != MagickFalse)
262 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
266 image->profiles,name);
292MagickExport
char *GetNextImageProfile(
const Image *image)
294 assert(image != (
Image *) NULL);
295 assert(image->signature == MagickCoreSignature);
296 if (IsEventLogging() != MagickFalse)
297 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
299 return((
char *) NULL);
300 return((
char *) GetNextKeyInSplayTree((
SplayTreeInfo *) image->profiles));
344#if defined(MAGICKCORE_LCMS_DELEGATE)
346typedef struct _LCMSInfo
368 **magick_restrict pixels;
371#if LCMS_VERSION < 2060
372static void* cmsGetContextUserData(cmsContext ContextID)
377static cmsContext cmsCreateContext(
void *magick_unused(Plugin),
void *UserData)
379 magick_unreferenced(Plugin);
380 return((cmsContext) UserData);
383static void cmsSetLogErrorHandlerTHR(cmsContext magick_unused(ContextID),
384 cmsLogErrorHandlerFunction Fn)
386 magick_unreferenced(ContextID);
387 cmsSetLogErrorHandler(Fn);
390static void cmsDeleteContext(cmsContext magick_unused(ContextID))
392 magick_unreferenced(ContextID);
396static void **DestroyPixelTLS(
void **pixels)
401 if (pixels == (
void **) NULL)
402 return((
void **) NULL);
403 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
404 if (pixels[i] != (
void *) NULL)
405 pixels[i]=RelinquishMagickMemory(pixels[i]);
406 pixels=(
void **) RelinquishMagickMemory(pixels);
410static void **AcquirePixelTLS(
const size_t columns,
const size_t channels,
411 MagickBooleanType highres)
425 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
426 pixels=(
void **) AcquireQuantumMemory(number_threads,
sizeof(*pixels));
427 if (pixels == (
void **) NULL)
428 return((
void **) NULL);
429 (void) memset(pixels,0,number_threads*
sizeof(*pixels));
431 if (highres == MagickFalse)
432 size=
sizeof(Quantum);
433 for (i=0; i < (ssize_t) number_threads; i++)
435 pixels[i]=AcquireQuantumMemory(columns,channels*size);
436 if (pixels[i] == (
void *) NULL)
437 return(DestroyPixelTLS(pixels));
442static cmsHTRANSFORM *DestroyTransformTLS(cmsHTRANSFORM *transform)
447 assert(transform != (cmsHTRANSFORM *) NULL);
448 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
449 if (transform[i] != (cmsHTRANSFORM) NULL)
450 cmsDeleteTransform(transform[i]);
451 transform=(cmsHTRANSFORM *) RelinquishMagickMemory(transform);
455static cmsHTRANSFORM *AcquireTransformTLS(
const LCMSInfo *source_info,
456 const LCMSInfo *target_info,
const cmsUInt32Number flags,
457 cmsContext cms_context)
468 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
469 transform=(cmsHTRANSFORM *) AcquireQuantumMemory(number_threads,
471 if (transform == (cmsHTRANSFORM *) NULL)
472 return((cmsHTRANSFORM *) NULL);
473 (void) memset(transform,0,number_threads*
sizeof(*transform));
474 for (i=0; i < (ssize_t) number_threads; i++)
476 transform[i]=cmsCreateTransformTHR(cms_context,source_info->profile,
477 source_info->type,target_info->profile,target_info->type,
478 (cmsUInt32Number) target_info->intent,flags);
479 if (transform[i] == (cmsHTRANSFORM) NULL)
480 return(DestroyTransformTLS(transform));
485static void CMSExceptionHandler(cmsContext context,cmsUInt32Number severity,
500 exception=cms_exception->exception;
503 image=cms_exception->image;
504 if (image == (
Image *) NULL)
506 (void) ThrowMagickException(exception,GetMagickModule(),ImageWarning,
507 "UnableToTransformColorspace",
"`%s'",
"unknown context");
510 if (image->debug != MagickFalse)
511 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
"lcms: #%u, %s",
512 severity,message != (
char *) NULL ? message :
"no message");
513 (void) ThrowMagickException(exception,GetMagickModule(),ImageWarning,
514 "UnableToTransformColorspace",
"`%s', %s (#%u)",image->filename,
515 message != (
char *) NULL ? message :
"no message",severity);
518static void TransformDoublePixels(
const int id,
const Image* image,
519 const LCMSInfo *source_info,
const LCMSInfo *target_info,
520 const cmsHTRANSFORM *transform,Quantum *q)
522#define GetLCMSPixel(source_info,pixel,index) \
523 (source_info->scale[index]*(((double) QuantumScale*(double) pixel)+ \
524 source_info->translate[index]))
525#define SetLCMSPixel(target_info,pixel,index) ClampToQuantum( \
526 target_info->scale[index]*(((double) QuantumRange*(double) pixel)+ \
527 target_info->translate[index]))
535 p=(
double *) source_info->pixels[
id];
536 for (x=0; x < (ssize_t) image->columns; x++)
538 *p++=GetLCMSPixel(source_info,GetPixelRed(image,q),0);
539 if (source_info->channels > 1)
541 *p++=GetLCMSPixel(source_info,GetPixelGreen(image,q),1);
542 *p++=GetLCMSPixel(source_info,GetPixelBlue(image,q),2);
544 if (source_info->channels > 3)
545 *p++=GetLCMSPixel(source_info,GetPixelBlack(image,q),3);
546 q+=GetPixelChannels(image);
548 cmsDoTransform(transform[
id],source_info->pixels[
id],target_info->pixels[
id],
549 (
unsigned int) image->columns);
550 p=(
double *) target_info->pixels[
id];
551 q-=GetPixelChannels(image)*image->columns;
552 for (x=0; x < (ssize_t) image->columns; x++)
554 if (target_info->channels == 1)
555 SetPixelGray(image,SetLCMSPixel(target_info,*p,0),q);
557 SetPixelRed(image,SetLCMSPixel(target_info,*p,0),q);
559 if (target_info->channels > 1)
561 SetPixelGreen(image,SetLCMSPixel(target_info,*p,1),q);
563 SetPixelBlue(image,SetLCMSPixel(target_info,*p,2),q);
566 if (target_info->channels > 3)
568 SetPixelBlack(image,SetLCMSPixel(target_info,*p,3),q);
571 q+=GetPixelChannels(image);
575static void TransformQuantumPixels(
const int id,
const Image* image,
576 const LCMSInfo *source_info,
const LCMSInfo *target_info,
577 const cmsHTRANSFORM *transform,Quantum *q)
585 p=(Quantum *) source_info->pixels[
id];
586 for (x=0; x < (ssize_t) image->columns; x++)
588 *p++=GetPixelRed(image,q);
589 if (source_info->channels > 1)
591 *p++=GetPixelGreen(image,q);
592 *p++=GetPixelBlue(image,q);
594 if (source_info->channels > 3)
595 *p++=GetPixelBlack(image,q);
596 q+=GetPixelChannels(image);
598 cmsDoTransform(transform[
id],source_info->pixels[
id],target_info->pixels[
id],
599 (
unsigned int) image->columns);
600 p=(Quantum *) target_info->pixels[
id];
601 q-=GetPixelChannels(image)*image->columns;
602 for (x=0; x < (ssize_t) image->columns; x++)
604 if (target_info->channels == 1)
605 SetPixelGray(image,*p++,q);
607 SetPixelRed(image,*p++,q);
608 if (target_info->channels > 1)
610 SetPixelGreen(image,*p++,q);
611 SetPixelBlue(image,*p++,q);
613 if (target_info->channels > 3)
614 SetPixelBlack(image,*p++,q);
615 q+=GetPixelChannels(image);
619static inline void SetLCMSInfoTranslate(LCMSInfo *info,
const double translate)
621 info->translate[0]=translate;
622 info->translate[1]=translate;
623 info->translate[2]=translate;
624 info->translate[3]=translate;
627static inline void SetLCMSInfoScale(LCMSInfo *info,
const double scale)
629 info->scale[0]=scale;
630 info->scale[1]=scale;
631 info->scale[2]=scale;
632 info->scale[3]=scale;
641 0x00, 0x00, 0x0c, 0x8c, 0x61, 0x72, 0x67, 0x6c, 0x02, 0x20, 0x00, 0x00,
642 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20,
643 0x07, 0xde, 0x00, 0x01, 0x00, 0x06, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x3a,
644 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00,
645 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
647 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x61, 0x72, 0x67, 0x6c,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
652 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x99,
653 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0xec, 0x00, 0x00, 0x00, 0x67,
654 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70,
655 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88,
656 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x0c,
657 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x00, 0x67,
658 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x24,
659 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xe4, 0x00, 0x00, 0x00, 0x14,
660 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x24,
661 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x04, 0x1c, 0x00, 0x00, 0x00, 0x14,
662 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x14,
663 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x00, 0x14,
664 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x58, 0x00, 0x00, 0x00, 0x14,
665 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x6c, 0x00, 0x00, 0x00, 0x14,
666 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
667 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
668 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
669 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
670 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36,
671 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x28, 0x45, 0x71, 0x75, 0x69, 0x76,
672 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x77, 0x77,
673 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x31, 0x39,
674 0x39, 0x38, 0x20, 0x48, 0x50, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c,
675 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676 0x00, 0x3f, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31,
677 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x28, 0x45, 0x71, 0x75,
678 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x77,
679 0x77, 0x77, 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x20,
680 0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x50, 0x20, 0x70, 0x72, 0x6f, 0x66,
681 0x69, 0x6c, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x72, 0x65, 0x61,
683 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x72, 0x61, 0x65, 0x6d,
684 0x65, 0x20, 0x57, 0x2e, 0x20, 0x47, 0x69, 0x6c, 0x6c, 0x2e, 0x20, 0x52,
685 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f,
686 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
687 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x20, 0x4e, 0x6f, 0x20, 0x57,
688 0x61, 0x72, 0x72, 0x61, 0x6e, 0x74, 0x79, 0x2c, 0x20, 0x55, 0x73, 0x65,
689 0x20, 0x61, 0x74, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x6f, 0x77, 0x6e,
690 0x20, 0x72, 0x69, 0x73, 0x6b, 0x2e, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63,
691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20,
692 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
693 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74,
695 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
696 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
701 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e,
702 0x31, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47,
703 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61,
704 0x63, 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43,
706 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
707 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63,
708 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
709 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x00, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00,
712 0x43, 0x52, 0x54, 0x20, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
713 0x00, 0x00, 0x00, 0x0d, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36,
714 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715 0x00, 0x00, 0x00, 0x0d, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36,
716 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa4, 0x7c,
722 0x00, 0x14, 0x5f, 0x30, 0x00, 0x10, 0xce, 0x02, 0x00, 0x03, 0xed, 0xb2,
723 0x00, 0x04, 0x13, 0x0a, 0x00, 0x03, 0x5c, 0x67, 0x00, 0x00, 0x00, 0x01,
724 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x0a, 0x3d,
725 0x00, 0x50, 0x00, 0x00, 0x00, 0x57, 0x1e, 0xb8, 0x6d, 0x65, 0x61, 0x73,
726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 0x00, 0x00, 0x02, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x58, 0x59, 0x5a, 0x20,
729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00,
730 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa0,
733 0x00, 0x00, 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20,
734 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x97, 0x00, 0x00, 0xb7, 0x87,
735 0x00, 0x00, 0x18, 0xd9, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
736 0x00, 0x00, 0x24, 0x9f, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xc4,
737 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
738 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19,
739 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37,
740 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54,
741 0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
742 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00, 0x90,
743 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae,
744 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00, 0xc6, 0x00, 0xcb,
745 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb,
746 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0d,
747 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32,
748 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59,
749 0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83,
750 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1,
751 0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1,
752 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
753 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b,
754 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x84,
755 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1,
756 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, 0x02, 0xf5, 0x03, 0x00,
757 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43,
758 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a,
759 0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3,
760 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20,
761 0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71,
762 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4,
763 0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
764 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77,
765 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5,
766 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37,
767 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d,
768 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, 0x06, 0xf5, 0x07, 0x07,
769 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74,
770 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5,
771 0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a,
772 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2,
773 0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f,
774 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
775 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54,
776 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5, 0x0a, 0xdc,
777 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69,
778 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, 0x0b, 0xe1, 0x0b, 0xf9,
779 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e,
780 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26,
781 0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3,
782 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64,
783 0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09,
784 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3,
785 0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
786 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11, 0x13,
787 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9,
788 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84,
789 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43,
790 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, 0x13, 0xe5, 0x14, 0x06,
791 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce,
792 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b,
793 0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c,
794 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41,
795 0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b,
796 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
797 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd,
798 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e, 0x1a, 0xc5,
799 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2,
800 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, 0x1c, 0x7b, 0x1c, 0xa3,
801 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99,
802 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94,
803 0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94,
804 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98,
805 0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1,
806 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf,
807 0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
808 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24, 0xda,
809 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7,
810 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26, 0xe8, 0x27, 0x18,
811 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f,
812 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6b,
813 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b,
814 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1,
815 0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c,
816 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c,
817 0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91,
818 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
819 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a,
820 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46, 0x33, 0x7f,
821 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8,
822 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, 0x35, 0xfd, 0x36, 0x37,
823 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c,
824 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05,
825 0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74,
826 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8,
827 0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61,
828 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0,
829 0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
830 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41, 0xee,
831 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d,
832 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44, 0xce, 0x45, 0x12,
833 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab,
834 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, 0x48, 0x05, 0x48, 0x4b,
835 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0,
836 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a,
837 0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a,
838 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00,
839 0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb,
840 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
841 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42,
842 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2, 0x56, 0x0f,
843 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0,
844 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, 0x59, 0x69, 0x59, 0xb8,
845 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95,
846 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78,
847 0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61,
848 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f,
849 0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43,
850 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d,
851 0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
852 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69, 0x43,
853 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f,
854 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d, 0x08, 0x6d, 0x60,
855 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78,
856 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, 0x71, 0x3a, 0x71, 0x95,
857 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8,
858 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1,
859 0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11,
860 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46,
861 0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81,
862 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
863 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a,
864 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4, 0x83, 0x57,
865 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab,
866 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, 0x87, 0x9f, 0x88, 0x04,
867 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64,
868 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca,
869 0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36,
870 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8,
871 0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20,
872 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f,
873 0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
874 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b, 0xaf,
875 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40,
876 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0, 0x69, 0xa0, 0xd8,
877 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76,
878 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, 0xa5, 0xa9, 0xa6, 0x1a,
879 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4,
880 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75,
881 0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d,
882 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea,
883 0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae,
884 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
885 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a,
886 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7, 0xbc, 0x21,
887 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff,
888 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, 0xc1, 0x67, 0xc1, 0xe3,
889 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce,
890 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf,
891 0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7,
892 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5,
893 0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba,
894 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6,
895 0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
896 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9, 0xf1,
897 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10,
898 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf, 0xaf, 0xe0, 0x36,
899 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63,
900 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, 0xe6, 0x0d, 0xe6, 0x96,
901 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0,
902 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11,
903 0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58,
904 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7,
905 0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb,
906 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
907 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba,
908 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
914 assert(image != (
Image *) NULL);
915 assert(image->signature == MagickCoreSignature);
916 if (GetImageProfile(image,
"icc") != (
const StringInfo *) NULL)
918 profile=BlobToProfileStringInfo(
"icc",sRGBProfile,
sizeof(sRGBProfile),
920 (void) SetImageProfilePrivate(image,profile,exception);
923MagickExport MagickBooleanType ProfileImage(
Image *image,
const char *name,
924 const void *datum,
const size_t length,
ExceptionInfo *exception)
926#define ProfileImageTag "Profile/Image"
928 #define TYPE_XYZ_8 (COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(1))
930#define ThrowProfileException(severity,tag,context) \
932 if (profile != (StringInfo *) NULL) \
933 profile=DestroyStringInfo(profile); \
934 if (cms_context != (cmsContext) NULL) \
935 cmsDeleteContext(cms_context); \
936 if (source_info.profile != (cmsHPROFILE) NULL) \
937 (void) cmsCloseProfile(source_info.profile); \
938 if (target_info.profile != (cmsHPROFILE) NULL) \
939 (void) cmsCloseProfile(target_info.profile); \
940 ThrowBinaryException(severity,tag,context); \
949 assert(image != (
Image *) NULL);
950 assert(image->signature == MagickCoreSignature);
951 assert(name != (
const char *) NULL);
952 if (IsEventLogging() != MagickFalse)
953 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
954 if ((datum == (
const void *) NULL) || (length == 0))
962 ResetImageProfileIterator(image);
963 for (next=GetNextImageProfile(image); next != (
const char *) NULL; )
965 if (IsOptionMember(next,name) != MagickFalse)
967 (void) DeleteImageProfile(image,next);
968 ResetImageProfileIterator(image);
970 next=GetNextImageProfile(image);
978 profile=AcquireProfileStringInfo(name,(
size_t) length,exception);
981 SetStringInfoDatum(profile,(
unsigned char *) datum);
982 if ((LocaleCompare(name,
"icc") != 0) && (LocaleCompare(name,
"icm") != 0))
983 status=SetImageProfilePrivate(image,profile,exception);
989 icc_profile=GetImageProfile(image,
"icc");
990 if ((icc_profile != (
const StringInfo *) NULL) &&
991 (CompareStringInfo(icc_profile,profile) == 0))
996 value=GetImageProperty(image,
"exif:ColorSpace",exception);
998 if (LocaleCompare(value,
"1") != 0)
999 SetsRGBImageProfile(image,exception);
1000 value=GetImageProperty(image,
"exif:InteroperabilityIndex",exception);
1001 if (LocaleCompare(value,
"R98.") != 0)
1002 SetsRGBImageProfile(image,exception);
1003 icc_profile=GetImageProfile(image,
"icc");
1005 if ((icc_profile != (
const StringInfo *) NULL) &&
1006 (CompareStringInfo(icc_profile,profile) == 0))
1008 profile=DestroyStringInfo(profile);
1011#if !defined(MAGICKCORE_LCMS_DELEGATE)
1012 (void) ThrowMagickException(exception,GetMagickModule(),
1013 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
1014 "'%s' (LCMS)",image->filename);
1030 cms_exception.image=image;
1031 cms_exception.exception=exception;
1032 cms_context=cmsCreateContext(NULL,&cms_exception);
1033 if (cms_context == (cmsContext) NULL)
1035 profile=DestroyStringInfo(profile);
1036 ThrowBinaryException(ResourceLimitError,
1037 "ColorspaceColorProfileMismatch",name);
1039 cmsSetLogErrorHandlerTHR(cms_context,CMSExceptionHandler);
1040 source_info.profile=cmsOpenProfileFromMemTHR(cms_context,
1041 GetStringInfoDatum(profile),(cmsUInt32Number)
1042 GetStringInfoLength(profile));
1043 if (source_info.profile == (cmsHPROFILE) NULL)
1045 profile=DestroyStringInfo(profile);
1046 cmsDeleteContext(cms_context);
1047 ThrowBinaryException(ResourceLimitError,
1048 "ColorspaceColorProfileMismatch",name);
1050 if ((cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass) &&
1052 status=SetImageProfilePrivate(image,profile,exception);
1058 cmsColorSpaceSignature
1062 *magick_restrict transform;
1076 target_info.profile=(cmsHPROFILE) NULL;
1079 target_info.profile=source_info.profile;
1080 source_info.profile=cmsOpenProfileFromMemTHR(cms_context,
1081 GetStringInfoDatum(icc_profile),(cmsUInt32Number)
1082 GetStringInfoLength(icc_profile));
1083 if (source_info.profile == (cmsHPROFILE) NULL)
1084 ThrowProfileException(ResourceLimitError,
1085 "ColorspaceColorProfileMismatch",name);
1088#if !defined(MAGICKCORE_HDRI_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH > 16)
1093 artifact=GetImageArtifact(image,
"profile:highres-transform");
1094 if (IsStringFalse(artifact) != MagickFalse)
1095 highres=MagickFalse;
1098 SetLCMSInfoScale(&source_info,1.0);
1099 SetLCMSInfoTranslate(&source_info,0.0);
1100 source_info.colorspace=sRGBColorspace;
1101 source_info.channels=3;
1102 switch (cmsGetColorSpace(source_info.profile))
1104 case cmsSigCmykData:
1106 source_info.colorspace=CMYKColorspace;
1107 source_info.channels=4;
1108 if (highres != MagickFalse)
1110 source_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
1111 SetLCMSInfoScale(&source_info,100.0);
1113#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1115 source_info.type=(cmsUInt32Number) TYPE_CMYK_8;
1116#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1118 source_info.type=(cmsUInt32Number) TYPE_CMYK_16;
1122 case cmsSigGrayData:
1124 source_info.colorspace=GRAYColorspace;
1125 source_info.channels=1;
1126 if (highres != MagickFalse)
1127 source_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
1128#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1130 source_info.type=(cmsUInt32Number) TYPE_GRAY_8;
1131#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1133 source_info.type=(cmsUInt32Number) TYPE_GRAY_16;
1139 source_info.colorspace=LabColorspace;
1140 if (highres != MagickFalse)
1142 source_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
1143 source_info.scale[0]=100.0;
1144 source_info.scale[1]=255.0;
1145 source_info.scale[2]=255.0;
1146#if !defined(MAGICKCORE_HDRI_SUPPORT)
1147 source_info.translate[1]=(-0.5);
1148 source_info.translate[2]=(-0.5);
1151#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1153 source_info.type=(cmsUInt32Number) TYPE_Lab_8;
1154#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1156 source_info.type=(cmsUInt32Number) TYPE_Lab_16;
1162 source_info.colorspace=sRGBColorspace;
1163 if (highres != MagickFalse)
1164 source_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1165#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1167 source_info.type=(cmsUInt32Number) TYPE_RGB_8;
1168#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1170 source_info.type=(cmsUInt32Number) TYPE_RGB_16;
1176 source_info.colorspace=XYZColorspace;
1177 if (highres != MagickFalse)
1178 source_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1179#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1181 source_info.type=(cmsUInt32Number) TYPE_XYZ_8;
1182#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1184 source_info.type=(cmsUInt32Number) TYPE_XYZ_16;
1189 ThrowProfileException(ImageError,
1190 "ColorspaceColorProfileMismatch",name);
1192 signature=cmsGetPCS(source_info.profile);
1193 if (target_info.profile != (cmsHPROFILE) NULL)
1194 signature=cmsGetColorSpace(target_info.profile);
1195 SetLCMSInfoScale(&target_info,1.0);
1196 SetLCMSInfoTranslate(&target_info,0.0);
1197 target_info.channels=3;
1200 case cmsSigCmykData:
1202 target_info.colorspace=CMYKColorspace;
1203 target_info.channels=4;
1204 if (highres != MagickFalse)
1206 target_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
1207 SetLCMSInfoScale(&target_info,0.01);
1209#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1211 target_info.type=(cmsUInt32Number) TYPE_CMYK_8;
1212#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1214 target_info.type=(cmsUInt32Number) TYPE_CMYK_16;
1218 case cmsSigGrayData:
1220 target_info.colorspace=GRAYColorspace;
1221 target_info.channels=1;
1222 if (highres != MagickFalse)
1223 target_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
1224#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1226 target_info.type=(cmsUInt32Number) TYPE_GRAY_8;
1227#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1229 target_info.type=(cmsUInt32Number) TYPE_GRAY_16;
1235 target_info.colorspace=LabColorspace;
1236 if (highres != MagickFalse)
1238 target_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
1239 target_info.scale[0]=0.01;
1240 target_info.scale[1]=1/255.0;
1241 target_info.scale[2]=1/255.0;
1242#if !defined(MAGICKCORE_HDRI_SUPPORT)
1243 target_info.translate[1]=0.5;
1244 target_info.translate[2]=0.5;
1247#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1249 target_info.type=(cmsUInt32Number) TYPE_Lab_8;
1250#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1252 target_info.type=(cmsUInt32Number) TYPE_Lab_16;
1258 target_info.colorspace=sRGBColorspace;
1259 if (highres != MagickFalse)
1260 target_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1261#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1263 target_info.type=(cmsUInt32Number) TYPE_RGB_8;
1264#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1266 target_info.type=(cmsUInt32Number) TYPE_RGB_16;
1272 target_info.colorspace=XYZColorspace;
1273 if (highres != MagickFalse)
1274 target_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1275#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1277 target_info.type=(cmsUInt32Number) TYPE_XYZ_8;
1278#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1280 source_info.type=(cmsUInt32Number) TYPE_XYZ_16;
1285 ThrowProfileException(ImageError,
1286 "ColorspaceColorProfileMismatch",name);
1288 switch (image->rendering_intent)
1290 case AbsoluteIntent:
1292 target_info.intent=INTENT_ABSOLUTE_COLORIMETRIC;
1295 case PerceptualIntent:
1297 target_info.intent=INTENT_PERCEPTUAL;
1300 case RelativeIntent:
1302 target_info.intent=INTENT_RELATIVE_COLORIMETRIC;
1305 case SaturationIntent:
1307 target_info.intent=INTENT_SATURATION;
1312 target_info.intent=INTENT_PERCEPTUAL;
1316 flags=cmsFLAGS_HIGHRESPRECALC;
1317#if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1318 if (image->black_point_compensation != MagickFalse)
1319 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1321 transform=AcquireTransformTLS(&source_info,&target_info,flags,
1323 if (transform == (cmsHTRANSFORM *) NULL)
1324 ThrowProfileException(ImageError,
"UnableToCreateColorTransform",
1329 source_info.pixels=AcquirePixelTLS(image->columns,
1330 source_info.channels,highres);
1331 target_info.pixels=AcquirePixelTLS(image->columns,
1332 target_info.channels,highres);
1333 if ((source_info.pixels == (
void **) NULL) ||
1334 (target_info.pixels == (
void **) NULL))
1336 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1337 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1338 transform=DestroyTransformTLS(transform);
1339 ThrowProfileException(ResourceLimitError,
1340 "MemoryAllocationFailed",image->filename);
1342 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1344 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1345 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1346 transform=DestroyTransformTLS(transform);
1347 if (source_info.profile != (cmsHPROFILE) NULL)
1348 (void) cmsCloseProfile(source_info.profile);
1349 if (target_info.profile != (cmsHPROFILE) NULL)
1350 (void) cmsCloseProfile(target_info.profile);
1351 return(MagickFalse);
1353 if (target_info.colorspace == CMYKColorspace)
1354 (void) SetImageColorspace(image,target_info.colorspace,exception);
1356 image_view=AcquireAuthenticCacheView(image,exception);
1357#if defined(MAGICKCORE_OPENMP_SUPPORT)
1358 #pragma omp parallel for schedule(static) shared(status) \
1359 magick_number_threads(image,image,image->rows,1)
1361 for (y=0; y < (ssize_t) image->rows; y++)
1364 id = GetOpenMPThreadId();
1372 if (status == MagickFalse)
1374 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1376 if (q == (Quantum *) NULL)
1381 if (highres != MagickFalse)
1382 TransformDoublePixels(
id,image,&source_info,&target_info,
1385 TransformQuantumPixels(
id,image,&source_info,&target_info,
1387 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1388 if (sync == MagickFalse)
1390 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1395#if defined(MAGICKCORE_OPENMP_SUPPORT)
1399 proceed=SetImageProgress(image,ProfileImageTag,progress,
1401 if (proceed == MagickFalse)
1405 image_view=DestroyCacheView(image_view);
1406 (void) SetImageColorspace(image,target_info.colorspace,exception);
1411 image->type=image->alpha_trait == UndefinedPixelTrait ?
1412 TrueColorType : TrueColorAlphaType;
1415 case cmsSigCmykData:
1417 image->type=image->alpha_trait == UndefinedPixelTrait ?
1418 ColorSeparationType : ColorSeparationAlphaType;
1421 case cmsSigGrayData:
1423 image->type=image->alpha_trait == UndefinedPixelTrait ?
1424 GrayscaleType : GrayscaleAlphaType;
1430 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1431 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1432 transform=DestroyTransformTLS(transform);
1433 if ((status != MagickFalse) &&
1434 (cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass))
1435 status=SetImageProfilePrivate(image,profile,exception);
1436 if (target_info.profile != (cmsHPROFILE) NULL)
1437 (void) cmsCloseProfile(target_info.profile);
1439 (void) cmsCloseProfile(source_info.profile);
1440 cmsDeleteContext(cms_context);
1472MagickExport
StringInfo *RemoveImageProfile(
Image *image,
const char *name)
1477 assert(image != (
Image *) NULL);
1478 assert(image->signature == MagickCoreSignature);
1479 if (IsEventLogging() != MagickFalse)
1480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1483 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
1485 image->profiles,name);
1513MagickExport
void ResetImageProfileIterator(
const Image *image)
1515 assert(image != (
Image *) NULL);
1516 assert(image->signature == MagickCoreSignature);
1517 if (IsEventLogging() != MagickFalse)
1518 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1555static void *DestroyProfile(
void *profile)
1557 return((
void *) DestroyStringInfo((
StringInfo *) profile));
1560static inline const unsigned char *ReadResourceByte(
const unsigned char *p,
1561 unsigned char *quantum)
1567static inline const unsigned char *ReadResourceLong(
const unsigned char *p,
1568 unsigned int *quantum)
1570 *quantum=(
unsigned int) (*p++) << 24;
1571 *quantum|=(
unsigned int) (*p++) << 16;
1572 *quantum|=(
unsigned int) (*p++) << 8;
1573 *quantum|=(
unsigned int) (*p++);
1577static inline const unsigned char *ReadResourceShort(
const unsigned char *p,
1578 unsigned short *quantum)
1580 *quantum=(
unsigned short) (*p++) << 8;
1581 *quantum|=(
unsigned short) (*p++);
1585static inline void WriteResourceLong(
unsigned char *p,
1586 const unsigned int quantum)
1591 buffer[0]=(
unsigned char) (quantum >> 24);
1592 buffer[1]=(
unsigned char) (quantum >> 16);
1593 buffer[2]=(
unsigned char) (quantum >> 8);
1594 buffer[3]=(
unsigned char) quantum;
1595 (void) memcpy(p,buffer,4);
1598static void WriteTo8BimProfile(
Image *image,
const char *name,
1627 if (LocaleCompare(name,
"icc") == 0)
1630 if (LocaleCompare(name,
"iptc") == 0)
1633 if (LocaleCompare(name,
"xmp") == 0)
1638 image->profiles,
"8bim");
1641 datum=GetStringInfoDatum(profile_8bim);
1642 length=GetStringInfoLength(profile_8bim);
1643 for (p=datum; p < (datum+length-16); )
1646 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1649 p=ReadResourceShort(p,&
id);
1650 p=ReadResourceByte(p,&length_byte);
1652 if (((length_byte+1) & 0x01) != 0)
1654 if (p > (datum+length-4))
1656 p=ReadResourceLong(p,&value);
1657 count=(ssize_t) value;
1658 if ((count & 0x01) != 0)
1660 if ((count < 0) || (p > (datum+length-count)) || (count > (ssize_t) length))
1662 if (
id != profile_id)
1677 extent=(size_t) ((datum+length)-(p+count));
1680 offset=(size_t) (q-datum);
1681 extract_profile=AcquireStringInfo(offset+extent);
1682 (void) memcpy(extract_profile->datum,datum,offset);
1686 offset=(size_t) (p-datum);
1687 extract_extent=(ssize_t) profile->length;
1688 if ((extract_extent & 0x01) != 0)
1690 extract_profile=AcquireStringInfo(offset+(
size_t) extract_extent+
1692 (void) memcpy(extract_profile->datum,datum,offset-4);
1693 WriteResourceLong(extract_profile->datum+offset-4,(
unsigned int)
1695 (void) memcpy(extract_profile->datum+offset,
1696 profile->datum,profile->length);
1698 (void) memcpy(extract_profile->datum+offset+extract_extent,
1700 (void) AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1701 ConstantString(
"8bim"),CloneStringInfo(extract_profile));
1702 extract_profile=DestroyStringInfo(extract_profile);
1708static void GetProfilesFromResourceBlock(
Image *image,
1735 datum=GetStringInfoDatum(resource_block);
1736 length=GetStringInfoLength(resource_block);
1737 for (p=datum; p < (datum+length-16); )
1739 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1742 p=ReadResourceShort(p,&
id);
1743 p=ReadResourceByte(p,&length_byte);
1745 if (((length_byte+1) & 0x01) != 0)
1747 if (p > (datum+length-4))
1749 p=ReadResourceLong(p,&value);
1750 count=(ssize_t) value;
1751 if ((p > (datum+length-count)) || (count > (ssize_t) length) ||
1769 p=ReadResourceLong(p,&resolution);
1770 image->resolution.x=((double) resolution)/65536.0;
1771 p=ReadResourceShort(p,&units)+2;
1772 p=ReadResourceLong(p,&resolution)+4;
1773 image->resolution.y=((double) resolution)/65536.0;
1777 if ((ResolutionType) units != PixelsPerCentimeterResolution)
1778 image->units=PixelsPerInchResolution;
1781 image->units=PixelsPerCentimeterResolution;
1782 image->resolution.x/=2.54;
1783 image->resolution.y/=2.54;
1792 profile=BlobToProfileStringInfo(
"iptc",p,(
size_t) count,exception);
1794 (void) SetImageProfileInternal(image,GetStringInfoName(profile),
1795 profile,MagickTrue,exception);
1812 profile=BlobToProfileStringInfo(
"icc",p,(
size_t) count,exception);
1814 (void) SetImageProfileInternal(image,GetStringInfoName(profile),
1815 profile,MagickTrue,exception);
1824 profile=BlobToProfileStringInfo(
"exif",p,(
size_t) count,exception);
1826 (void) SetImageProfileInternal(image,GetStringInfoName(profile),
1827 profile,MagickTrue,exception);
1836 profile=BlobToProfileStringInfo(
"xmp",p,(
size_t) count,exception);
1838 (void) SetImageProfileInternal(image,GetStringInfoName(profile),
1839 profile,MagickTrue,exception);
1849 if ((count & 0x01) != 0)
1854static void PatchCorruptProfile(
const char *name,
StringInfo *profile)
1865 if (LocaleCompare(name,
"xmp") == 0)
1870 p=GetStringInfoDatum(profile);
1871 p=(
unsigned char *) strstr((
const char *) p,
"<?xpacket end=\"w\"?>");
1872 if (p != (
unsigned char *) NULL)
1875 length=(size_t) (p-GetStringInfoDatum(profile));
1876 if (length != GetStringInfoLength(profile))
1879 SetStringInfoLength(profile,length);
1884 if (LocaleCompare(name,
"exif") == 0)
1889 p=GetStringInfoDatum(profile);
1890 if ((LocaleNCompare((
const char *) p,
"MM",2) == 0) ||
1891 (LocaleNCompare((
const char *) p,
"II",2) == 0))
1894 profile_start[] =
"Exif\0\0";
1899 exif_profile=AcquireStringInfo(6);
1902 SetStringInfoDatum(exif_profile,profile_start);
1903 ConcatenateStringInfo(exif_profile,profile);
1904 SetStringInfoLength(profile,GetStringInfoLength(exif_profile));
1905 SetStringInfo(profile,exif_profile);
1906 exif_profile=DestroyStringInfo(exif_profile);
1912static MagickBooleanType ValidateXMPProfile(
Image *image,
1915#if defined(MAGICKCORE_XML_DELEGATE)
1922 const char *artifact=GetImageArtifact(image,
"xmp:validate");
1923 if (IsStringTrue(artifact) == MagickFalse)
1925 document=xmlReadMemory((
const char *) GetStringInfoDatum(profile),(
int)
1926 GetStringInfoLength(profile),
"xmp.xml",NULL,XML_PARSE_NOERROR |
1927 XML_PARSE_NOWARNING);
1928 if (document == (xmlDocPtr) NULL)
1930 (void) ThrowMagickException(exception,GetMagickModule(),ImageWarning,
1931 "CorruptImageProfile",
"`%s' (XMP)",image->filename);
1932 return(MagickFalse);
1934 xmlFreeDoc(document);
1938 (void) ThrowMagickException(exception,GetMagickModule(),
1939 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
"`%s' (XML)",
1941 return(MagickFalse);
1945static MagickBooleanType SetImageProfileInternal(
Image *image,
const char *name,
1946 StringInfo *profile,
const MagickBooleanType recursive,
1950 key[MagickPathExtent];
1958 assert(image != (
Image *) NULL);
1959 assert(image->signature == MagickCoreSignature);
1961 assert(name != (
const char *) NULL);
1962 if (IsEventLogging() != MagickFalse)
1963 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1964 length=GetStringInfoLength(profile);
1965 if ((length == 0) || (length > GetMaxProfileSize()))
1968 (void) ThrowMagickException(exception,GetMagickModule(),
1969 ResourceLimitWarning,
"ProfileSizeExceedsLimit",
"`%llu'",
1970 (
unsigned long long) length);
1971 profile=DestroyStringInfo(profile);
1974 PatchCorruptProfile(name,profile);
1975 if ((LocaleCompare(name,
"xmp") == 0) &&
1976 (ValidateXMPProfile(image,profile,exception) == MagickFalse))
1978 profile=DestroyStringInfo(profile);
1982 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1984 (void) CopyMagickString(key,name,MagickPathExtent);
1986 status=AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1987 ConstantString(key),profile);
1988 if (status == MagickFalse)
1989 profile=DestroyStringInfo(profile);
1992 if (LocaleCompare(name,
"8bim") == 0)
1993 GetProfilesFromResourceBlock(image,profile,exception);
1995 if (recursive == MagickFalse)
1996 WriteTo8BimProfile(image,name,profile);
2001MagickExport
StringInfo *AcquireProfileStringInfo(
const char *name,
2007 if (length > GetMaxProfileSize())
2008 (void) ThrowMagickException(exception,GetMagickModule(),
2009 ResourceLimitWarning,
"ProfileSizeExceedsLimit",
"`%llu'",
2010 (
unsigned long long) length);
2013 profile=AcquireStringInfo(length);
2014 SetStringInfoName(profile,name);
2019MagickExport
StringInfo *BlobToProfileStringInfo(
const char *name,
2020 const void *blob,
const size_t length,
ExceptionInfo *exception)
2025 profile=AcquireProfileStringInfo(name,length,exception);
2027 (void) memcpy(profile->datum,blob,length);
2031MagickExport MagickBooleanType SetImageProfile(
Image *image,
const char *name,
2038 return(MagickFalse);
2039 clone_profile=CloneStringInfo(profile);
2040 return(SetImageProfileInternal(image,name,clone_profile,MagickFalse,
2044MagickExport MagickBooleanType SetImageProfilePrivate(
Image *image,
2048 return(MagickFalse);
2049 return(SetImageProfileInternal(image,GetStringInfoName(profile),profile,
2050 MagickFalse,exception));
2076static inline int ReadProfileByte(
unsigned char **p,
size_t *length)
2088static inline signed short ReadProfileShort(
const EndianType endian,
2089 unsigned char *buffer)
2103 if (endian == LSBEndian)
2105 value=(
unsigned short) buffer[1] << 8;
2106 value|=(
unsigned short) buffer[0];
2107 quantum.unsigned_value=value & 0xffff;
2108 return(quantum.signed_value);
2110 value=(
unsigned short) buffer[0] << 8;
2111 value|=(
unsigned short) buffer[1];
2112 quantum.unsigned_value=value & 0xffff;
2113 return(quantum.signed_value);
2116static inline signed int ReadProfileLong(
const EndianType endian,
2117 unsigned char *buffer)
2131 if (endian == LSBEndian)
2133 value=(
unsigned int) buffer[3] << 24;
2134 value|=(
unsigned int) buffer[2] << 16;
2135 value|=(
unsigned int) buffer[1] << 8;
2136 value|=(
unsigned int) buffer[0];
2137 quantum.unsigned_value=value & 0xffffffff;
2138 return(quantum.signed_value);
2140 value=(
unsigned int) buffer[0] << 24;
2141 value|=(
unsigned int) buffer[1] << 16;
2142 value|=(
unsigned int) buffer[2] << 8;
2143 value|=(
unsigned int) buffer[3];
2144 quantum.unsigned_value=value & 0xffffffff;
2145 return(quantum.signed_value);
2148static inline signed int ReadProfileMSBLong(
unsigned char **p,
size_t *length)
2155 value=ReadProfileLong(MSBEndian,*p);
2161static inline signed short ReadProfileMSBShort(
unsigned char **p,
2169 value=ReadProfileShort(MSBEndian,*p);
2175static inline void WriteProfileLong(
const EndianType endian,
2176 const size_t value,
unsigned char *p)
2181 if (endian == LSBEndian)
2183 buffer[0]=(
unsigned char) value;
2184 buffer[1]=(
unsigned char) (value >> 8);
2185 buffer[2]=(
unsigned char) (value >> 16);
2186 buffer[3]=(
unsigned char) (value >> 24);
2187 (void) memcpy(p,buffer,4);
2190 buffer[0]=(
unsigned char) (value >> 24);
2191 buffer[1]=(
unsigned char) (value >> 16);
2192 buffer[2]=(
unsigned char) (value >> 8);
2193 buffer[3]=(
unsigned char) value;
2194 (void) memcpy(p,buffer,4);
2197static void WriteProfileShort(
const EndianType endian,
2198 const unsigned short value,
unsigned char *p)
2203 if (endian == LSBEndian)
2205 buffer[0]=(
unsigned char) value;
2206 buffer[1]=(
unsigned char) (value >> 8);
2207 (void) memcpy(p,buffer,2);
2210 buffer[0]=(
unsigned char) (value >> 8);
2211 buffer[1]=(
unsigned char) value;
2212 (void) memcpy(p,buffer,2);
2215static void SyncExifProfile(
const Image *image,
unsigned char *exif,
2218#define MaxDirectoryStack 16
2219#define EXIF_DELIMITER "\n"
2220#define EXIF_NUM_FORMATS 12
2221#define TAG_EXIF_OFFSET 0x8769
2222#define TAG_INTEROP_OFFSET 0xa005
2224 typedef struct _DirectoryInfo
2234 directory_stack[MaxDirectoryStack] = { { 0, 0 } };
2252 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
2259 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2260 if ((
id != 0x4949) && (
id != 0x4D4D))
2264 if (ReadProfileByte(&exif,&length) != 0x45)
2266 if (ReadProfileByte(&exif,&length) != 0x78)
2268 if (ReadProfileByte(&exif,&length) != 0x69)
2270 if (ReadProfileByte(&exif,&length) != 0x66)
2272 if (ReadProfileByte(&exif,&length) != 0x00)
2274 if (ReadProfileByte(&exif,&length) != 0x00)
2280 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2290 if (ReadProfileShort(endian,exif+2) != 0x002a)
2295 offset=(ssize_t) ReadProfileLong(endian,exif+4);
2296 if ((offset < 0) || ((
size_t) offset >= length))
2298 directory=exif+offset;
2301 exif_resources=NewSplayTree((
int (*)(
const void *,
const void *)) NULL,
2302 (
void *(*)(
void *)) NULL,(
void *(*)(
void *)) NULL);
2308 directory=directory_stack[level].directory;
2309 entry=directory_stack[level].entry;
2311 if ((directory < exif) || (directory > (exif+length-2)))
2316 number_entries=(size_t) ReadProfileShort(endian,directory);
2317 for ( ; entry < number_entries; entry++)
2333 q=(
unsigned char *) (directory+2+(12*entry));
2334 if (q > (exif+length-12))
2336 if (GetValueFromSplayTree(exif_resources,q) == q)
2338 (void) AddValueToSplayTree(exif_resources,q,q);
2339 tag_value=(ssize_t) ReadProfileShort(endian,q);
2340 format=(ssize_t) ReadProfileShort(endian,q+2);
2341 if ((format < 0) || ((format-1) >= EXIF_NUM_FORMATS))
2343 components=(int) ReadProfileLong(endian,q+4);
2346 number_bytes=(size_t) components*(
size_t) format_bytes[format];
2347 if ((ssize_t) number_bytes < components)
2349 if (number_bytes <= 4)
2356 offset=(ssize_t) ReadProfileLong(endian,q+8);
2358 ((
size_t) (offset+(ssize_t) number_bytes) > length))
2360 if (~length < number_bytes)
2362 p=(
unsigned char *) (exif+offset);
2368 (void) WriteProfileLong(endian,(
size_t) (image->resolution.x+0.5),p);
2369 if (number_bytes == 8)
2370 (void) WriteProfileLong(endian,1UL,p+4);
2375 (void) WriteProfileLong(endian,(
size_t) (image->resolution.y+0.5),p);
2376 if (number_bytes == 8)
2377 (void) WriteProfileLong(endian,1UL,p+4);
2382 if (number_bytes == 4)
2384 (void) WriteProfileLong(endian,(
size_t) image->orientation,p);
2387 (void) WriteProfileShort(endian,(
unsigned short) image->orientation,
2393 if (number_bytes == 4)
2395 (void) WriteProfileLong(endian,((
size_t) image->units)+1,p);
2398 (void) WriteProfileShort(endian,(
unsigned short) (image->units+1),p);
2404 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
2406 offset=(ssize_t) ReadProfileLong(endian,p);
2407 if (((
size_t) offset < length) && (level < (MaxDirectoryStack-2)))
2409 directory_stack[level].directory=directory;
2411 directory_stack[level].entry=entry;
2413 directory_stack[level].directory=exif+offset;
2414 directory_stack[level].entry=0;
2416 if ((directory+2+(12*number_entries)) > (exif+length))
2418 offset=(ssize_t) ReadProfileLong(endian,directory+2+(12*
2420 if ((offset != 0) && ((
size_t) offset < length) &&
2421 (level < (MaxDirectoryStack-2)))
2423 directory_stack[level].directory=exif+offset;
2424 directory_stack[level].entry=0;
2431 }
while (level > 0);
2432 exif_resources=DestroySplayTree(exif_resources);
2436static void Sync8BimProfile(
const Image *image,
const StringInfo *profile)
2450 length=GetStringInfoLength(profile);
2451 p=GetStringInfoDatum(profile);
2454 if (ReadProfileByte(&p,&length) != 0x38)
2456 if (ReadProfileByte(&p,&length) != 0x42)
2458 if (ReadProfileByte(&p,&length) != 0x49)
2460 if (ReadProfileByte(&p,&length) != 0x4D)
2464 id=(
unsigned short) ReadProfileMSBShort(&p,&length);
2465 count=(ssize_t) ReadProfileByte(&p,&length);
2466 if ((count >= (ssize_t) length) || (count < 0))
2469 length-=(size_t) count;
2470 if ((*p & 0x01) == 0)
2471 (void) ReadProfileByte(&p,&length);
2472 count=(ssize_t) ReadProfileMSBLong(&p,&length);
2473 if ((count > (ssize_t) length) || (count < 0))
2475 if ((
id == 0x3ED) && (count == 16))
2477 if (image->units == PixelsPerCentimeterResolution)
2478 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2479 image->resolution.x*2.54*65536.0),p);
2481 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2482 image->resolution.x*65536.0),p);
2483 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+4);
2484 if (image->units == PixelsPerCentimeterResolution)
2485 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2486 image->resolution.y*2.54*65536.0),p+8);
2488 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2489 image->resolution.y*65536.0),p+8);
2490 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+12);
2493 SyncExifProfile(image,p,(
size_t) count);
2495 length-=(size_t) count;
2500static void ReplaceXmpValue(
StringInfo *profile,
size_t start,
size_t end,
2511 length=GetStringInfoLength(profile);
2512 value_length=strlen(value);
2513 new_length=length-(end-start)+value_length;
2514 if (new_length > length)
2515 SetStringInfoLength(profile,new_length);
2516 datum=(
char *) GetStringInfoDatum(profile);
2517 (void) memmove(datum+start+value_length,datum+end,length-end);
2518 (void) memcpy(datum+start,value,value_length);
2519 if (new_length < length)
2521 SetStringInfoLength(profile,new_length);
2522 datum=(
char *) GetStringInfoDatum(profile);
2523 *(datum+new_length)=
'\0';
2527static MagickBooleanType GetXmpOffsets(
const StringInfo *profile,
2528 const char *tag,
size_t *start,
size_t *end)
2538 datum=(
char *) GetStringInfoDatum(profile);
2539 length=GetStringInfoLength(profile);
2540 pos=strstr(datum,tag);
2541 tag_length=strlen(tag);
2542 if ((pos == (
char *) NULL) || ((pos-datum) < 1) || (*(pos-1) !=
'<') ||
2543 (((
size_t) (pos-datum)+tag_length) > length) ||
2544 (*(pos+tag_length) !=
'>'))
2545 return(MagickFalse);
2546 *start=(size_t) (pos-datum)+tag_length+1;
2547 pos=strstr(datum+*start,
"<");
2548 if (pos == (
char *) NULL)
2549 return(MagickFalse);
2550 *end=(size_t) (pos-datum);
2554static void GetXmpNumeratorAndDenominator(
double value,
2555 unsigned long *numerator,
unsigned long *denominator)
2562 if (value <= MagickEpsilon)
2566 while(fabs(df - value) > MagickEpsilon)
2573 *numerator=(
unsigned long) (value*(*denominator));
2575 df=*numerator/(double)*denominator;
2582 value[MagickPathExtent];
2593 if (GetXmpOffsets(profile,
"tiff:XResolution",&start,&end) != MagickFalse)
2595 GetXmpNumeratorAndDenominator(image->resolution.x,&numerator,
2597 (void) FormatLocaleString(value,MagickPathExtent,
"%lu/%lu",numerator,
2599 ReplaceXmpValue(profile,start,end,value);
2601 if (GetXmpOffsets(profile,
"tiff:YResolution",&start,&end) != MagickFalse)
2603 if ((fabs(image->resolution.x-image->resolution.y) > MagickEpsilon) ||
2606 GetXmpNumeratorAndDenominator(image->resolution.y,&numerator,
2608 (void) FormatLocaleString(value,MagickPathExtent,
"%lu/%lu",
2609 numerator,denominator);
2611 ReplaceXmpValue(profile,start,end,value);
2613 if (GetXmpOffsets(profile,
"tiff:ResolutionUnit",&start,&end) != MagickFalse)
2615 (void) FormatLocaleString(value,MagickPathExtent,
"%d",
2616 ((
int) image->units)+1);
2617 ReplaceXmpValue(profile,start,end,value);
2619 if (GetXmpOffsets(profile,
"tiff:Orientation",&start,&end) != MagickFalse)
2621 (void) FormatLocaleString(value,MagickPathExtent,
"%d",
2622 (
int) image->orientation);
2623 ReplaceXmpValue(profile,start,end,value);
2627MagickPrivate
void SyncImageProfiles(
Image *image)
2632 profile=(
StringInfo *) GetImageProfile(image,
"8BIM");
2634 Sync8BimProfile(image,profile);
2635 profile=(
StringInfo *) GetImageProfile(image,
"EXIF");
2637 SyncExifProfile(image,GetStringInfoDatum(profile),GetStringInfoLength(
2639 profile=(
StringInfo *) GetImageProfile(image,
"XMP");
2641 SyncXmpProfile(image,profile);
2644static void UpdateClipPath(
unsigned char *blob,
size_t length,
2645 const size_t old_columns,
const size_t old_rows,
2656 selector=(ssize_t) ReadProfileMSBShort(&blob,&length);
2662 if (knot_count != 0)
2665 length-=(size_t) MagickMin(length,24U);
2671 knot_count=(ssize_t) ReadProfileMSBShort(&blob,&length);
2673 length-=(size_t) MagickMin(length,22);
2681 if (knot_count == 0)
2687 length-=(size_t) MagickMin(length,24);
2693 for (i=0; i < 3; i++)
2703 y=(double) ReadProfileMSBLong(&blob,&length);
2704 y=y*old_rows/4096.0/4096.0;
2706 yy=(
signed int) ((y*4096*4096)/new_geometry->height);
2707 WriteProfileLong(MSBEndian,(
size_t) yy,blob-4);
2708 x=(double) ReadProfileMSBLong(&blob,&length);
2709 x=x*old_columns/4096.0/4096.0;
2711 xx=(
signed int) ((x*4096*4096)/new_geometry->width);
2712 WriteProfileLong(MSBEndian,(
size_t) xx,blob-4);
2723 length-=(size_t) MagickMin(length,24);
2730MagickPrivate
void Update8BIMClipPath(
const Image *image,
2731 const size_t old_columns,
const size_t old_rows,
2747 assert(image != (
Image *) NULL);
2749 profile=GetImageProfile(image,
"8bim");
2752 length=GetStringInfoLength(profile);
2753 info=GetStringInfoDatum(profile);
2756 if (ReadProfileByte(&info,&length) != (
unsigned char)
'8')
2758 if (ReadProfileByte(&info,&length) != (
unsigned char)
'B')
2760 if (ReadProfileByte(&info,&length) != (
unsigned char)
'I')
2762 if (ReadProfileByte(&info,&length) != (
unsigned char)
'M')
2764 id=(ssize_t) ReadProfileMSBShort(&info,&length);
2765 count=(ssize_t) ReadProfileByte(&info,&length);
2766 if ((count != 0) && ((
size_t) count <= length))
2769 length-=(size_t) count;
2771 if ((count & 0x01) == 0)
2772 (void) ReadProfileByte(&info,&length);
2773 count=(ssize_t) ReadProfileMSBLong(&info,&length);
2774 if ((count < 0) || ((
size_t) count > length))
2779 if ((
id > 1999) && (
id < 2999))
2780 UpdateClipPath(info,(
size_t) count,old_columns,old_rows,new_geometry);
2782 length-=(size_t) MagickMin(length,(
size_t) count);