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)
72#if defined(MAGICKCORE_HAVE_LCMS_LCMS2_H)
74#include <lcms/lcms2.h>
80#if defined(MAGICKCORE_XML_DELEGATE)
81# if defined(MAGICKCORE_WINDOWS_SUPPORT)
82# if !defined(__MINGW32__)
83# include <win32config.h>
86# include <libxml/parser.h>
87# include <libxml/tree.h>
93static MagickBooleanType
152MagickExport MagickBooleanType CloneImageProfiles(
Image *image,
153 const Image *clone_image)
155 assert(image != (
Image *) NULL);
156 assert(image->signature == MagickCoreSignature);
157 assert(clone_image != (
const Image *) NULL);
158 assert(clone_image->signature == MagickCoreSignature);
159 if (IsEventLogging() != MagickFalse)
160 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
161 if (clone_image->profiles != (
void *) NULL)
163 if (image->profiles != (
void *) NULL)
164 DestroyImageProfiles(image);
165 image->profiles=CloneSplayTree((
SplayTreeInfo *) clone_image->profiles,
166 (
void *(*)(
void *)) ConstantString,(
void *(*)(
void *)) CloneStringInfo);
195MagickExport MagickBooleanType DeleteImageProfile(
Image *image,
const char *name)
197 assert(image != (
Image *) NULL);
198 assert(image->signature == MagickCoreSignature);
199 if (IsEventLogging() != MagickFalse)
200 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
203 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
204 return(DeleteNodeFromSplayTree((
SplayTreeInfo *) image->profiles,name));
229MagickExport
void DestroyImageProfiles(
Image *image)
232 image->profiles=DestroySplayTree((
SplayTreeInfo *) image->profiles);
265 assert(image != (
Image *) NULL);
266 assert(image->signature == MagickCoreSignature);
267 if (IsEventLogging() != MagickFalse)
268 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
272 image->profiles,name);
298MagickExport
char *GetNextImageProfile(
const Image *image)
300 assert(image != (
Image *) NULL);
301 assert(image->signature == MagickCoreSignature);
302 if (IsEventLogging() != MagickFalse)
303 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
305 return((
char *) NULL);
306 return((
char *) GetNextKeyInSplayTree((
SplayTreeInfo *) image->profiles));
350#if defined(MAGICKCORE_LCMS_DELEGATE)
352typedef struct _LCMSInfo
374 **magick_restrict pixels;
377#if LCMS_VERSION < 2060
378static void* cmsGetContextUserData(cmsContext ContextID)
383static cmsContext cmsCreateContext(
void *magick_unused(Plugin),
void *UserData)
385 magick_unreferenced(Plugin);
386 return((cmsContext) UserData);
389static void cmsSetLogErrorHandlerTHR(cmsContext magick_unused(ContextID),
390 cmsLogErrorHandlerFunction Fn)
392 magick_unreferenced(ContextID);
393 cmsSetLogErrorHandler(Fn);
396static void cmsDeleteContext(cmsContext magick_unused(ContextID))
398 magick_unreferenced(ContextID);
402static void **DestroyPixelTLS(
void **pixels)
407 if (pixels == (
void **) NULL)
408 return((
void **) NULL);
409 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
410 if (pixels[i] != (
void *) NULL)
411 pixels[i]=RelinquishMagickMemory(pixels[i]);
412 pixels=(
void **) RelinquishMagickMemory(pixels);
416static void **AcquirePixelTLS(
const size_t columns,
const size_t channels,
417 MagickBooleanType highres)
431 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
432 pixels=(
void **) AcquireQuantumMemory(number_threads,
sizeof(*pixels));
433 if (pixels == (
void **) NULL)
434 return((
void **) NULL);
435 (void) memset(pixels,0,number_threads*
sizeof(*pixels));
437 if (highres == MagickFalse)
438 size=
sizeof(Quantum);
439 for (i=0; i < (ssize_t) number_threads; i++)
441 pixels[i]=AcquireQuantumMemory(columns,channels*size);
442 if (pixels[i] == (
void *) NULL)
443 return(DestroyPixelTLS(pixels));
448static cmsHTRANSFORM *DestroyTransformTLS(cmsHTRANSFORM *transform)
453 assert(transform != (cmsHTRANSFORM *) NULL);
454 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
455 if (transform[i] != (cmsHTRANSFORM) NULL)
456 cmsDeleteTransform(transform[i]);
457 transform=(cmsHTRANSFORM *) RelinquishMagickMemory(transform);
461static cmsHTRANSFORM *AcquireTransformTLS(
const LCMSInfo *source_info,
462 const LCMSInfo *target_info,
const cmsUInt32Number flags,
463 cmsContext cms_context)
474 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
475 transform=(cmsHTRANSFORM *) AcquireQuantumMemory(number_threads,
477 if (transform == (cmsHTRANSFORM *) NULL)
478 return((cmsHTRANSFORM *) NULL);
479 (void) memset(transform,0,number_threads*
sizeof(*transform));
480 for (i=0; i < (ssize_t) number_threads; i++)
482 transform[i]=cmsCreateTransformTHR(cms_context,source_info->profile,
483 source_info->type,target_info->profile,target_info->type,
484 target_info->intent,flags);
485 if (transform[i] == (cmsHTRANSFORM) NULL)
486 return(DestroyTransformTLS(transform));
491static void CMSExceptionHandler(cmsContext context,cmsUInt32Number severity,
506 exception=cms_exception->exception;
509 image=cms_exception->image;
510 if (image == (
Image *) NULL)
512 (void) ThrowMagickException(exception,GetMagickModule(),ImageWarning,
513 "UnableToTransformColorspace",
"`%s'",
"unknown context");
516 if (image->debug != MagickFalse)
517 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
"lcms: #%u, %s",
518 severity,message != (
char *) NULL ? message :
"no message");
519 (void) ThrowMagickException(exception,GetMagickModule(),ImageWarning,
520 "UnableToTransformColorspace",
"`%s', %s (#%u)",image->filename,
521 message != (
char *) NULL ? message :
"no message",severity);
524static void TransformDoublePixels(
const int id,
const Image* image,
525 const LCMSInfo *source_info,
const LCMSInfo *target_info,
526 const cmsHTRANSFORM *transform,Quantum *q)
528#define GetLCMSPixel(source_info,pixel,index) \
529 (source_info->scale[index]*((QuantumScale*pixel)+source_info->translate[index]))
530#define SetLCMSPixel(target_info,pixel,index) \
531 ClampToQuantum(target_info->scale[index]*((QuantumRange*pixel)+target_info->translate[index]))
539 p=(
double *) source_info->pixels[
id];
540 for (x=0; x < (ssize_t) image->columns; x++)
542 *p++=GetLCMSPixel(source_info,GetPixelRed(image,q),0);
543 if (source_info->channels > 1)
545 *p++=GetLCMSPixel(source_info,GetPixelGreen(image,q),1);
546 *p++=GetLCMSPixel(source_info,GetPixelBlue(image,q),2);
548 if (source_info->channels > 3)
549 *p++=GetLCMSPixel(source_info,GetPixelBlack(image,q),3);
550 q+=GetPixelChannels(image);
552 cmsDoTransform(transform[
id],source_info->pixels[
id],target_info->pixels[
id],
553 (
unsigned int) image->columns);
554 p=(
double *) target_info->pixels[
id];
555 q-=GetPixelChannels(image)*image->columns;
556 for (x=0; x < (ssize_t) image->columns; x++)
558 if (target_info->channels == 1)
559 SetPixelGray(image,SetLCMSPixel(target_info,*p,0),q);
561 SetPixelRed(image,SetLCMSPixel(target_info,*p,0),q);
563 if (target_info->channels > 1)
565 SetPixelGreen(image,SetLCMSPixel(target_info,*p,1),q);
567 SetPixelBlue(image,SetLCMSPixel(target_info,*p,2),q);
570 if (target_info->channels > 3)
572 SetPixelBlack(image,SetLCMSPixel(target_info,*p,3),q);
575 q+=GetPixelChannels(image);
579static void TransformQuantumPixels(
const int id,
const Image* image,
580 const LCMSInfo *source_info,
const LCMSInfo *target_info,
581 const cmsHTRANSFORM *transform,Quantum *q)
589 p=(Quantum *) source_info->pixels[
id];
590 for (x=0; x < (ssize_t) image->columns; x++)
592 *p++=GetPixelRed(image,q);
593 if (source_info->channels > 1)
595 *p++=GetPixelGreen(image,q);
596 *p++=GetPixelBlue(image,q);
598 if (source_info->channels > 3)
599 *p++=GetPixelBlack(image,q);
600 q+=GetPixelChannels(image);
602 cmsDoTransform(transform[
id],source_info->pixels[
id],target_info->pixels[
id],
603 (
unsigned int) image->columns);
604 p=(Quantum *) target_info->pixels[
id];
605 q-=GetPixelChannels(image)*image->columns;
606 for (x=0; x < (ssize_t) image->columns; x++)
608 if (target_info->channels == 1)
609 SetPixelGray(image,*p++,q);
611 SetPixelRed(image,*p++,q);
612 if (target_info->channels > 1)
614 SetPixelGreen(image,*p++,q);
615 SetPixelBlue(image,*p++,q);
617 if (target_info->channels > 3)
618 SetPixelBlack(image,*p++,q);
619 q+=GetPixelChannels(image);
623static inline void SetLCMSInfoTranslate(LCMSInfo *info,
const double translate)
625 info->translate[0]=translate;
626 info->translate[1]=translate;
627 info->translate[2]=translate;
628 info->translate[3]=translate;
631static inline void SetLCMSInfoScale(LCMSInfo *info,
const double scale)
633 info->scale[0]=scale;
634 info->scale[1]=scale;
635 info->scale[2]=scale;
636 info->scale[3]=scale;
640static MagickBooleanType SetsRGBImageProfile(
Image *image,
646 0x00, 0x00, 0x0c, 0x8c, 0x61, 0x72, 0x67, 0x6c, 0x02, 0x20, 0x00, 0x00,
647 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20,
648 0x07, 0xde, 0x00, 0x01, 0x00, 0x06, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x3a,
649 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00,
650 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
652 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x61, 0x72, 0x67, 0x6c,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
657 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x99,
658 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0xec, 0x00, 0x00, 0x00, 0x67,
659 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70,
660 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88,
661 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x0c,
662 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x00, 0x67,
663 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x24,
664 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xe4, 0x00, 0x00, 0x00, 0x14,
665 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x24,
666 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x04, 0x1c, 0x00, 0x00, 0x00, 0x14,
667 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x14,
668 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x00, 0x14,
669 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x58, 0x00, 0x00, 0x00, 0x14,
670 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x04, 0x6c, 0x00, 0x00, 0x00, 0x14,
671 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
672 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
673 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x08, 0x0c,
674 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
675 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36,
676 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x28, 0x45, 0x71, 0x75, 0x69, 0x76,
677 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x77, 0x77,
678 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x31, 0x39,
679 0x39, 0x38, 0x20, 0x48, 0x50, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c,
680 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x3f, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31,
682 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x28, 0x45, 0x71, 0x75,
683 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x77,
684 0x77, 0x77, 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x20,
685 0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x50, 0x20, 0x70, 0x72, 0x6f, 0x66,
686 0x69, 0x6c, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x72, 0x65, 0x61,
688 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x72, 0x61, 0x65, 0x6d,
689 0x65, 0x20, 0x57, 0x2e, 0x20, 0x47, 0x69, 0x6c, 0x6c, 0x2e, 0x20, 0x52,
690 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f,
691 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
692 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x20, 0x4e, 0x6f, 0x20, 0x57,
693 0x61, 0x72, 0x72, 0x61, 0x6e, 0x74, 0x79, 0x2c, 0x20, 0x55, 0x73, 0x65,
694 0x20, 0x61, 0x74, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x6f, 0x77, 0x6e,
695 0x20, 0x72, 0x69, 0x73, 0x6b, 0x2e, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20,
697 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
698 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74,
700 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
701 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
706 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e,
707 0x31, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47,
708 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61,
709 0x63, 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43,
711 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
712 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63,
713 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
714 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00,
717 0x43, 0x52, 0x54, 0x20, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x0d, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36,
719 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 0x00, 0x00, 0x00, 0x0d, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36,
721 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa4, 0x7c,
727 0x00, 0x14, 0x5f, 0x30, 0x00, 0x10, 0xce, 0x02, 0x00, 0x03, 0xed, 0xb2,
728 0x00, 0x04, 0x13, 0x0a, 0x00, 0x03, 0x5c, 0x67, 0x00, 0x00, 0x00, 0x01,
729 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x0a, 0x3d,
730 0x00, 0x50, 0x00, 0x00, 0x00, 0x57, 0x1e, 0xb8, 0x6d, 0x65, 0x61, 0x73,
731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733 0x00, 0x00, 0x02, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x58, 0x59, 0x5a, 0x20,
734 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00,
735 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa0,
738 0x00, 0x00, 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x97, 0x00, 0x00, 0xb7, 0x87,
740 0x00, 0x00, 0x18, 0xd9, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
741 0x00, 0x00, 0x24, 0x9f, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xc4,
742 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
743 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19,
744 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37,
745 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54,
746 0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
747 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00, 0x90,
748 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae,
749 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00, 0xc6, 0x00, 0xcb,
750 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb,
751 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0d,
752 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32,
753 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59,
754 0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83,
755 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1,
756 0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1,
757 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
758 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b,
759 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x84,
760 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1,
761 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, 0x02, 0xf5, 0x03, 0x00,
762 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43,
763 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a,
764 0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3,
765 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20,
766 0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71,
767 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4,
768 0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
769 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77,
770 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5,
771 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37,
772 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d,
773 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, 0x06, 0xf5, 0x07, 0x07,
774 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74,
775 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5,
776 0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a,
777 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2,
778 0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f,
779 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
780 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54,
781 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5, 0x0a, 0xdc,
782 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69,
783 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, 0x0b, 0xe1, 0x0b, 0xf9,
784 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e,
785 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26,
786 0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3,
787 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64,
788 0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09,
789 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3,
790 0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
791 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11, 0x13,
792 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9,
793 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84,
794 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43,
795 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, 0x13, 0xe5, 0x14, 0x06,
796 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce,
797 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b,
798 0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c,
799 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41,
800 0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b,
801 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
802 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd,
803 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e, 0x1a, 0xc5,
804 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2,
805 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, 0x1c, 0x7b, 0x1c, 0xa3,
806 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99,
807 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94,
808 0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94,
809 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98,
810 0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1,
811 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf,
812 0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
813 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24, 0xda,
814 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7,
815 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26, 0xe8, 0x27, 0x18,
816 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f,
817 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6b,
818 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b,
819 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1,
820 0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c,
821 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c,
822 0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91,
823 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
824 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a,
825 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46, 0x33, 0x7f,
826 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8,
827 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, 0x35, 0xfd, 0x36, 0x37,
828 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c,
829 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05,
830 0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74,
831 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8,
832 0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61,
833 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0,
834 0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
835 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41, 0xee,
836 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d,
837 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44, 0xce, 0x45, 0x12,
838 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab,
839 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, 0x48, 0x05, 0x48, 0x4b,
840 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0,
841 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a,
842 0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a,
843 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00,
844 0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb,
845 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
846 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42,
847 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2, 0x56, 0x0f,
848 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0,
849 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, 0x59, 0x69, 0x59, 0xb8,
850 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95,
851 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78,
852 0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61,
853 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f,
854 0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43,
855 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d,
856 0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
857 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69, 0x43,
858 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f,
859 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d, 0x08, 0x6d, 0x60,
860 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78,
861 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, 0x71, 0x3a, 0x71, 0x95,
862 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8,
863 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1,
864 0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11,
865 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46,
866 0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81,
867 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
868 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a,
869 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4, 0x83, 0x57,
870 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab,
871 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, 0x87, 0x9f, 0x88, 0x04,
872 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64,
873 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca,
874 0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36,
875 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8,
876 0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20,
877 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f,
878 0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
879 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b, 0xaf,
880 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40,
881 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0, 0x69, 0xa0, 0xd8,
882 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76,
883 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, 0xa5, 0xa9, 0xa6, 0x1a,
884 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4,
885 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75,
886 0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d,
887 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea,
888 0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae,
889 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
890 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a,
891 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7, 0xbc, 0x21,
892 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff,
893 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, 0xc1, 0x67, 0xc1, 0xe3,
894 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce,
895 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf,
896 0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7,
897 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5,
898 0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba,
899 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6,
900 0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
901 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9, 0xf1,
902 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10,
903 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf, 0xaf, 0xe0, 0x36,
904 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63,
905 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, 0xe6, 0x0d, 0xe6, 0x96,
906 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0,
907 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11,
908 0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58,
909 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7,
910 0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb,
911 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
912 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba,
913 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
922 assert(image != (
Image *) NULL);
923 assert(image->signature == MagickCoreSignature);
924 if (GetImageProfile(image,
"icc") != (
const StringInfo *) NULL)
926 profile=AcquireStringInfo(
sizeof(sRGBProfile));
927 SetStringInfoDatum(profile,sRGBProfile);
928 status=SetImageProfile(image,
"icc",profile,exception);
929 profile=DestroyStringInfo(profile);
933MagickExport MagickBooleanType ProfileImage(
Image *image,
const char *name,
934 const void *datum,
const size_t length,
ExceptionInfo *exception)
936#define ProfileImageTag "Profile/Image"
938 #define TYPE_XYZ_8 (COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(1))
940#define ThrowProfileException(severity,tag,context) \
942 if (profile != (StringInfo *) NULL) \
943 profile=DestroyStringInfo(profile); \
944 if (cms_context != (cmsContext) NULL) \
945 cmsDeleteContext(cms_context); \
946 if (source_info.profile != (cmsHPROFILE) NULL) \
947 (void) cmsCloseProfile(source_info.profile); \
948 if (target_info.profile != (cmsHPROFILE) NULL) \
949 (void) cmsCloseProfile(target_info.profile); \
950 ThrowBinaryException(severity,tag,context); \
959 assert(image != (
Image *) NULL);
960 assert(image->signature == MagickCoreSignature);
961 assert(name != (
const char *) NULL);
962 if (IsEventLogging() != MagickFalse)
963 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
964 if ((datum == (
const void *) NULL) || (length == 0))
972 ResetImageProfileIterator(image);
973 for (next=GetNextImageProfile(image); next != (
const char *) NULL; )
975 if (IsOptionMember(next,name) != MagickFalse)
977 (void) DeleteImageProfile(image,next);
978 ResetImageProfileIterator(image);
980 next=GetNextImageProfile(image);
988 profile=AcquireStringInfo((
size_t) length);
989 SetStringInfoDatum(profile,(
unsigned char *) datum);
990 if ((LocaleCompare(name,
"icc") != 0) && (LocaleCompare(name,
"icm") != 0))
991 status=SetImageProfile(image,name,profile,exception);
997 icc_profile=GetImageProfile(image,
"icc");
998 if ((icc_profile != (
const StringInfo *) NULL) &&
999 (CompareStringInfo(icc_profile,profile) == 0))
1004 value=GetImageProperty(image,
"exif:ColorSpace",exception);
1006 if (LocaleCompare(value,
"1") != 0)
1007 (
void) SetsRGBImageProfile(image,exception);
1008 value=GetImageProperty(image,
"exif:InteroperabilityIndex",exception);
1009 if (LocaleCompare(value,
"R98.") != 0)
1010 (void) SetsRGBImageProfile(image,exception);
1011 icc_profile=GetImageProfile(image,
"icc");
1013 if ((icc_profile != (
const StringInfo *) NULL) &&
1014 (CompareStringInfo(icc_profile,profile) == 0))
1016 profile=DestroyStringInfo(profile);
1019#if !defined(MAGICKCORE_LCMS_DELEGATE)
1020 (void) ThrowMagickException(exception,GetMagickModule(),
1021 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
1022 "'%s' (LCMS)",image->filename);
1038 cms_exception.image=image;
1039 cms_exception.exception=exception;
1040 cms_context=cmsCreateContext(NULL,&cms_exception);
1041 if (cms_context == (cmsContext) NULL)
1043 profile=DestroyStringInfo(profile);
1044 ThrowBinaryException(ResourceLimitError,
1045 "ColorspaceColorProfileMismatch",name);
1047 cmsSetLogErrorHandlerTHR(cms_context,CMSExceptionHandler);
1048 source_info.profile=cmsOpenProfileFromMemTHR(cms_context,
1049 GetStringInfoDatum(profile),(cmsUInt32Number)
1050 GetStringInfoLength(profile));
1051 if (source_info.profile == (cmsHPROFILE) NULL)
1053 profile=DestroyStringInfo(profile);
1054 cmsDeleteContext(cms_context);
1055 ThrowBinaryException(ResourceLimitError,
1056 "ColorspaceColorProfileMismatch",name);
1058 if ((cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass) &&
1060 status=SetImageProfile(image,name,profile,exception);
1066 cmsColorSpaceSignature
1070 *magick_restrict transform;
1084 target_info.profile=(cmsHPROFILE) NULL;
1087 target_info.profile=source_info.profile;
1088 source_info.profile=cmsOpenProfileFromMemTHR(cms_context,
1089 GetStringInfoDatum(icc_profile),(cmsUInt32Number)
1090 GetStringInfoLength(icc_profile));
1091 if (source_info.profile == (cmsHPROFILE) NULL)
1092 ThrowProfileException(ResourceLimitError,
1093 "ColorspaceColorProfileMismatch",name);
1096#if !defined(MAGICKCORE_HDRI_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH > 16)
1101 artifact=GetImageArtifact(image,
"profile:highres-transform");
1102 if (IsStringFalse(artifact) != MagickFalse)
1103 highres=MagickFalse;
1106 SetLCMSInfoScale(&source_info,1.0);
1107 SetLCMSInfoTranslate(&source_info,0.0);
1108 source_info.colorspace=sRGBColorspace;
1109 source_info.channels=3;
1110 switch (cmsGetColorSpace(source_info.profile))
1112 case cmsSigCmykData:
1114 source_info.colorspace=CMYKColorspace;
1115 source_info.channels=4;
1116 if (highres != MagickFalse)
1118 source_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
1119 SetLCMSInfoScale(&source_info,100.0);
1121#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1123 source_info.type=(cmsUInt32Number) TYPE_CMYK_8;
1124#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1126 source_info.type=(cmsUInt32Number) TYPE_CMYK_16;
1130 case cmsSigGrayData:
1132 source_info.colorspace=GRAYColorspace;
1133 source_info.channels=1;
1134 if (highres != MagickFalse)
1135 source_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
1136#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1138 source_info.type=(cmsUInt32Number) TYPE_GRAY_8;
1139#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1141 source_info.type=(cmsUInt32Number) TYPE_GRAY_16;
1147 source_info.colorspace=LabColorspace;
1148 if (highres != MagickFalse)
1150 source_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
1151 source_info.scale[0]=100.0;
1152 source_info.scale[1]=255.0;
1153 source_info.scale[2]=255.0;
1154 source_info.translate[1]=(-0.5);
1155 source_info.translate[2]=(-0.5);
1157#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1159 source_info.type=(cmsUInt32Number) TYPE_Lab_8;
1160#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1162 source_info.type=(cmsUInt32Number) TYPE_Lab_16;
1168 source_info.colorspace=sRGBColorspace;
1169 if (highres != MagickFalse)
1170 source_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1171#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1173 source_info.type=(cmsUInt32Number) TYPE_RGB_8;
1174#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1176 source_info.type=(cmsUInt32Number) TYPE_RGB_16;
1182 source_info.colorspace=XYZColorspace;
1183 if (highres != MagickFalse)
1184 source_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1185#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1187 source_info.type=(cmsUInt32Number) TYPE_XYZ_8;
1188#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1190 source_info.type=(cmsUInt32Number) TYPE_XYZ_16;
1195 ThrowProfileException(ImageError,
1196 "ColorspaceColorProfileMismatch",name);
1198 signature=cmsGetPCS(source_info.profile);
1199 if (target_info.profile != (cmsHPROFILE) NULL)
1200 signature=cmsGetColorSpace(target_info.profile);
1201 SetLCMSInfoScale(&target_info,1.0);
1202 SetLCMSInfoTranslate(&target_info,0.0);
1203 target_info.channels=3;
1206 case cmsSigCmykData:
1208 target_info.colorspace=CMYKColorspace;
1209 target_info.channels=4;
1210 if (highres != MagickFalse)
1212 target_info.type=(cmsUInt32Number) TYPE_CMYK_DBL;
1213 SetLCMSInfoScale(&target_info,0.01);
1215#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1217 target_info.type=(cmsUInt32Number) TYPE_CMYK_8;
1218#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1220 target_info.type=(cmsUInt32Number) TYPE_CMYK_16;
1224 case cmsSigGrayData:
1226 target_info.colorspace=GRAYColorspace;
1227 target_info.channels=1;
1228 if (highres != MagickFalse)
1229 target_info.type=(cmsUInt32Number) TYPE_GRAY_DBL;
1230#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1232 target_info.type=(cmsUInt32Number) TYPE_GRAY_8;
1233#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1235 target_info.type=(cmsUInt32Number) TYPE_GRAY_16;
1241 target_info.colorspace=LabColorspace;
1242 if (highres != MagickFalse)
1244 target_info.type=(cmsUInt32Number) TYPE_Lab_DBL;
1245 target_info.scale[0]=0.01;
1246 target_info.scale[1]=1/255.0;
1247 target_info.scale[2]=1/255.0;
1248 target_info.translate[1]=0.5;
1249 target_info.translate[2]=0.5;
1251#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1253 target_info.type=(cmsUInt32Number) TYPE_Lab_8;
1254#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1256 target_info.type=(cmsUInt32Number) TYPE_Lab_16;
1262 target_info.colorspace=sRGBColorspace;
1263 if (highres != MagickFalse)
1264 target_info.type=(cmsUInt32Number) TYPE_RGB_DBL;
1265#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1267 target_info.type=(cmsUInt32Number) TYPE_RGB_8;
1268#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1270 target_info.type=(cmsUInt32Number) TYPE_RGB_16;
1276 target_info.colorspace=XYZColorspace;
1277 if (highres != MagickFalse)
1278 target_info.type=(cmsUInt32Number) TYPE_XYZ_DBL;
1279#if (MAGICKCORE_QUANTUM_DEPTH == 8)
1281 target_info.type=(cmsUInt32Number) TYPE_XYZ_8;
1282#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
1284 source_info.type=(cmsUInt32Number) TYPE_XYZ_16;
1289 ThrowProfileException(ImageError,
1290 "ColorspaceColorProfileMismatch",name);
1292 switch (image->rendering_intent)
1294 case AbsoluteIntent:
1296 target_info.intent=INTENT_ABSOLUTE_COLORIMETRIC;
1299 case PerceptualIntent:
1301 target_info.intent=INTENT_PERCEPTUAL;
1304 case RelativeIntent:
1306 target_info.intent=INTENT_RELATIVE_COLORIMETRIC;
1309 case SaturationIntent:
1311 target_info.intent=INTENT_SATURATION;
1316 target_info.intent=INTENT_PERCEPTUAL;
1320 flags=cmsFLAGS_HIGHRESPRECALC;
1321#if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
1322 if (image->black_point_compensation != MagickFalse)
1323 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
1325 transform=AcquireTransformTLS(&source_info,&target_info,flags,
1327 if (transform == (cmsHTRANSFORM *) NULL)
1328 ThrowProfileException(ImageError,
"UnableToCreateColorTransform",
1333 source_info.pixels=AcquirePixelTLS(image->columns,
1334 source_info.channels,highres);
1335 target_info.pixels=AcquirePixelTLS(image->columns,
1336 target_info.channels,highres);
1337 if ((source_info.pixels == (
void **) NULL) ||
1338 (target_info.pixels == (
void **) NULL))
1340 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1341 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1342 transform=DestroyTransformTLS(transform);
1343 ThrowProfileException(ResourceLimitError,
1344 "MemoryAllocationFailed",image->filename);
1346 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1348 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1349 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1350 transform=DestroyTransformTLS(transform);
1351 if (source_info.profile != (cmsHPROFILE) NULL)
1352 (void) cmsCloseProfile(source_info.profile);
1353 if (target_info.profile != (cmsHPROFILE) NULL)
1354 (
void) cmsCloseProfile(target_info.profile);
1355 return(MagickFalse);
1357 if (target_info.colorspace == CMYKColorspace)
1358 (void) SetImageColorspace(image,target_info.colorspace,exception);
1360 image_view=AcquireAuthenticCacheView(image,exception);
1361#if defined(MAGICKCORE_OPENMP_SUPPORT)
1362 #pragma omp parallel for schedule(static) shared(status) \
1363 magick_number_threads(image,image,image->rows,1)
1365 for (y=0; y < (ssize_t) image->rows; y++)
1368 id = GetOpenMPThreadId();
1376 if (status == MagickFalse)
1378 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1380 if (q == (Quantum *) NULL)
1385 if (highres != MagickFalse)
1386 TransformDoublePixels(
id,image,&source_info,&target_info,
1389 TransformQuantumPixels(
id,image,&source_info,&target_info,
1391 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1392 if (sync == MagickFalse)
1394 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1399#if defined(MAGICKCORE_OPENMP_SUPPORT)
1403 proceed=SetImageProgress(image,ProfileImageTag,progress,
1405 if (proceed == MagickFalse)
1409 image_view=DestroyCacheView(image_view);
1410 (void) SetImageColorspace(image,target_info.colorspace,exception);
1415 image->type=image->alpha_trait == UndefinedPixelTrait ?
1416 TrueColorType : TrueColorAlphaType;
1419 case cmsSigCmykData:
1421 image->type=image->alpha_trait == UndefinedPixelTrait ?
1422 ColorSeparationType : ColorSeparationAlphaType;
1425 case cmsSigGrayData:
1427 image->type=image->alpha_trait == UndefinedPixelTrait ?
1428 GrayscaleType : GrayscaleAlphaType;
1434 target_info.pixels=DestroyPixelTLS(target_info.pixels);
1435 source_info.pixels=DestroyPixelTLS(source_info.pixels);
1436 transform=DestroyTransformTLS(transform);
1437 if ((status != MagickFalse) &&
1438 (cmsGetDeviceClass(source_info.profile) != cmsSigLinkClass))
1439 status=SetImageProfile(image,name,profile,exception);
1440 if (target_info.profile != (cmsHPROFILE) NULL)
1441 (void) cmsCloseProfile(target_info.profile);
1443 (void) cmsCloseProfile(source_info.profile);
1444 cmsDeleteContext(cms_context);
1448 profile=DestroyStringInfo(profile);
1477MagickExport
StringInfo *RemoveImageProfile(
Image *image,
const char *name)
1482 assert(image != (
Image *) NULL);
1483 assert(image->signature == MagickCoreSignature);
1484 if (IsEventLogging() != MagickFalse)
1485 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1488 WriteTo8BimProfile(image,name,(
StringInfo *) NULL);
1490 image->profiles,name);
1518MagickExport
void ResetImageProfileIterator(
const Image *image)
1520 assert(image != (
Image *) NULL);
1521 assert(image->signature == MagickCoreSignature);
1522 if (IsEventLogging() != MagickFalse)
1523 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1560static void *DestroyProfile(
void *profile)
1562 return((
void *) DestroyStringInfo((
StringInfo *) profile));
1565static inline const unsigned char *ReadResourceByte(
const unsigned char *p,
1566 unsigned char *quantum)
1572static inline const unsigned char *ReadResourceLong(
const unsigned char *p,
1573 unsigned int *quantum)
1575 *quantum=(
unsigned int) (*p++) << 24;
1576 *quantum|=(
unsigned int) (*p++) << 16;
1577 *quantum|=(
unsigned int) (*p++) << 8;
1578 *quantum|=(
unsigned int) (*p++);
1582static inline const unsigned char *ReadResourceShort(
const unsigned char *p,
1583 unsigned short *quantum)
1585 *quantum=(
unsigned short) (*p++) << 8;
1586 *quantum|=(
unsigned short) (*p++);
1590static inline void WriteResourceLong(
unsigned char *p,
1591 const unsigned int quantum)
1596 buffer[0]=(
unsigned char) (quantum >> 24);
1597 buffer[1]=(
unsigned char) (quantum >> 16);
1598 buffer[2]=(
unsigned char) (quantum >> 8);
1599 buffer[3]=(
unsigned char) quantum;
1600 (void) memcpy(p,buffer,4);
1603static void WriteTo8BimProfile(
Image *image,
const char *name,
1632 if (LocaleCompare(name,
"icc") == 0)
1635 if (LocaleCompare(name,
"iptc") == 0)
1638 if (LocaleCompare(name,
"xmp") == 0)
1643 image->profiles,
"8bim");
1646 datum=GetStringInfoDatum(profile_8bim);
1647 length=GetStringInfoLength(profile_8bim);
1648 for (p=datum; p < (datum+length-16); )
1651 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1654 p=ReadResourceShort(p,&
id);
1655 p=ReadResourceByte(p,&length_byte);
1657 if (((length_byte+1) & 0x01) != 0)
1659 if (p > (datum+length-4))
1661 p=ReadResourceLong(p,&value);
1662 count=(ssize_t) value;
1663 if ((count & 0x01) != 0)
1665 if ((count < 0) || (p > (datum+length-count)) || (count > (ssize_t) length))
1667 if (
id != profile_id)
1682 extent=(datum+length)-(p+count);
1686 extract_profile=AcquireStringInfo(offset+extent);
1687 (void) memcpy(extract_profile->datum,datum,offset);
1692 extract_extent=profile->length;
1693 if ((extract_extent & 0x01) != 0)
1695 extract_profile=AcquireStringInfo(offset+extract_extent+extent);
1696 (void) memcpy(extract_profile->datum,datum,offset-4);
1697 WriteResourceLong(extract_profile->datum+offset-4,(
unsigned int)
1699 (void) memcpy(extract_profile->datum+offset,
1700 profile->datum,profile->length);
1702 (void) memcpy(extract_profile->datum+offset+extract_extent,
1704 (void) AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1705 ConstantString(
"8bim"),CloneStringInfo(extract_profile));
1706 extract_profile=DestroyStringInfo(extract_profile);
1712static void GetProfilesFromResourceBlock(
Image *image,
1739 datum=GetStringInfoDatum(resource_block);
1740 length=GetStringInfoLength(resource_block);
1741 for (p=datum; p < (datum+length-16); )
1743 if (LocaleNCompare((
char *) p,
"8BIM",4) != 0)
1746 p=ReadResourceShort(p,&
id);
1747 p=ReadResourceByte(p,&length_byte);
1749 if (((length_byte+1) & 0x01) != 0)
1751 if (p > (datum+length-4))
1753 p=ReadResourceLong(p,&value);
1754 count=(ssize_t) value;
1755 if ((p > (datum+length-count)) || (count > (ssize_t) length) ||
1773 p=ReadResourceLong(p,&resolution);
1774 image->resolution.x=((double) resolution)/65536.0;
1775 p=ReadResourceShort(p,&units)+2;
1776 p=ReadResourceLong(p,&resolution)+4;
1777 image->resolution.y=((double) resolution)/65536.0;
1781 if ((ResolutionType) units != PixelsPerCentimeterResolution)
1782 image->units=PixelsPerInchResolution;
1785 image->units=PixelsPerCentimeterResolution;
1786 image->resolution.x/=2.54;
1787 image->resolution.y/=2.54;
1796 profile=AcquireStringInfo(count);
1797 SetStringInfoDatum(profile,p);
1798 (void) SetImageProfileInternal(image,
"iptc",profile,MagickTrue,
1800 profile=DestroyStringInfo(profile);
1817 profile=AcquireStringInfo(count);
1818 SetStringInfoDatum(profile,p);
1819 (void) SetImageProfileInternal(image,
"icc",profile,MagickTrue,
1821 profile=DestroyStringInfo(profile);
1830 profile=AcquireStringInfo(count);
1831 SetStringInfoDatum(profile,p);
1832 (void) SetImageProfileInternal(image,
"exif",profile,MagickTrue,
1834 profile=DestroyStringInfo(profile);
1843 profile=AcquireStringInfo(count);
1844 SetStringInfoDatum(profile,p);
1845 (void) SetImageProfileInternal(image,
"xmp",profile,MagickTrue,
1847 profile=DestroyStringInfo(profile);
1857 if ((count & 0x01) != 0)
1862static void PatchCorruptProfile(
const char *name,
StringInfo *profile)
1873 if (LocaleCompare(name,
"xmp") == 0)
1878 p=GetStringInfoDatum(profile);
1879 p=(
unsigned char *) strstr((
const char *) p,
"<?xpacket end=\"w\"?>");
1880 if (p != (
unsigned char *) NULL)
1883 length=p-GetStringInfoDatum(profile);
1884 if (length != GetStringInfoLength(profile))
1887 SetStringInfoLength(profile,length);
1892 if (LocaleCompare(name,
"exif") == 0)
1897 p=GetStringInfoDatum(profile);
1898 if ((LocaleNCompare((
const char *) p,
"MM",2) == 0) ||
1899 (LocaleNCompare((
const char *) p,
"II",2) == 0))
1902 profile_start[] =
"Exif\0\0";
1907 exif_profile=AcquireStringInfo(6);
1910 SetStringInfoDatum(exif_profile,profile_start);
1911 ConcatenateStringInfo(exif_profile,profile);
1912 SetStringInfoLength(profile,GetStringInfoLength(exif_profile));
1913 SetStringInfo(profile,exif_profile);
1914 exif_profile=DestroyStringInfo(exif_profile);
1920#if defined(MAGICKCORE_XML_DELEGATE)
1921static MagickBooleanType ValidateXMPProfile(
Image *image,
1930 document=xmlReadMemory((
const char *) GetStringInfoDatum(profile),(
int)
1931 GetStringInfoLength(profile),
"xmp.xml",NULL,XML_PARSE_NOERROR |
1932 XML_PARSE_NOWARNING);
1933 if (document == (xmlDocPtr) NULL)
1935 (void) ThrowMagickException(exception,GetMagickModule(),ImageWarning,
1936 "CorruptImageProfile",
"`%s' (XMP)",image->filename);
1937 return(MagickFalse);
1939 xmlFreeDoc(document);
1943static MagickBooleanType ValidateXMPProfile(
Image *image,
1946 (void) ThrowMagickException(exception,GetMagickModule(),
1947 MissingDelegateWarning,
"DelegateLibrarySupportNotBuiltIn",
"'%s' (XML)",
1949 return(MagickFalse);
1953static MagickBooleanType SetImageProfileInternal(
Image *image,
const char *name,
1954 const StringInfo *profile,
const MagickBooleanType recursive,
1958 key[MagickPathExtent];
1966 assert(image != (
Image *) NULL);
1967 assert(image->signature == MagickCoreSignature);
1968 if (IsEventLogging() != MagickFalse)
1969 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1970 clone_profile=CloneStringInfo(profile);
1971 PatchCorruptProfile(name,clone_profile);
1972 if ((LocaleCompare(name,
"xmp") == 0) &&
1973 (ValidateXMPProfile(image,clone_profile,exception) == MagickFalse))
1975 clone_profile=DestroyStringInfo(clone_profile);
1979 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
1981 (void) CopyMagickString(key,name,MagickPathExtent);
1983 status=AddValueToSplayTree((
SplayTreeInfo *) image->profiles,
1984 ConstantString(key),clone_profile);
1985 if (status != MagickFalse)
1987 if (LocaleCompare(name,
"8bim") == 0)
1988 GetProfilesFromResourceBlock(image,clone_profile,exception);
1990 if (recursive == MagickFalse)
1991 WriteTo8BimProfile(image,name,clone_profile);
1996MagickExport MagickBooleanType SetImageProfile(
Image *image,
const char *name,
1999 return(SetImageProfileInternal(image,name,profile,MagickFalse,exception));
2026static inline int ReadProfileByte(
unsigned char **p,
size_t *length)
2038static inline signed short ReadProfileShort(
const EndianType endian,
2039 unsigned char *buffer)
2053 if (endian == LSBEndian)
2055 value=(
unsigned short) buffer[1] << 8;
2056 value|=(
unsigned short) buffer[0];
2057 quantum.unsigned_value=value & 0xffff;
2058 return(quantum.signed_value);
2060 value=(
unsigned short) buffer[0] << 8;
2061 value|=(
unsigned short) buffer[1];
2062 quantum.unsigned_value=value & 0xffff;
2063 return(quantum.signed_value);
2066static inline signed int ReadProfileLong(
const EndianType endian,
2067 unsigned char *buffer)
2081 if (endian == LSBEndian)
2083 value=(
unsigned int) buffer[3] << 24;
2084 value|=(
unsigned int) buffer[2] << 16;
2085 value|=(
unsigned int) buffer[1] << 8;
2086 value|=(
unsigned int) buffer[0];
2087 quantum.unsigned_value=value & 0xffffffff;
2088 return(quantum.signed_value);
2090 value=(
unsigned int) buffer[0] << 24;
2091 value|=(
unsigned int) buffer[1] << 16;
2092 value|=(
unsigned int) buffer[2] << 8;
2093 value|=(
unsigned int) buffer[3];
2094 quantum.unsigned_value=value & 0xffffffff;
2095 return(quantum.signed_value);
2098static inline signed int ReadProfileMSBLong(
unsigned char **p,
size_t *length)
2105 value=ReadProfileLong(MSBEndian,*p);
2111static inline signed short ReadProfileMSBShort(
unsigned char **p,
2119 value=ReadProfileShort(MSBEndian,*p);
2125static inline void WriteProfileLong(
const EndianType endian,
2126 const size_t value,
unsigned char *p)
2131 if (endian == LSBEndian)
2133 buffer[0]=(
unsigned char) value;
2134 buffer[1]=(
unsigned char) (value >> 8);
2135 buffer[2]=(
unsigned char) (value >> 16);
2136 buffer[3]=(
unsigned char) (value >> 24);
2137 (void) memcpy(p,buffer,4);
2140 buffer[0]=(
unsigned char) (value >> 24);
2141 buffer[1]=(
unsigned char) (value >> 16);
2142 buffer[2]=(
unsigned char) (value >> 8);
2143 buffer[3]=(
unsigned char) value;
2144 (void) memcpy(p,buffer,4);
2147static void WriteProfileShort(
const EndianType endian,
2148 const unsigned short value,
unsigned char *p)
2153 if (endian == LSBEndian)
2155 buffer[0]=(
unsigned char) value;
2156 buffer[1]=(
unsigned char) (value >> 8);
2157 (void) memcpy(p,buffer,2);
2160 buffer[0]=(
unsigned char) (value >> 8);
2161 buffer[1]=(
unsigned char) value;
2162 (void) memcpy(p,buffer,2);
2165static MagickBooleanType SyncExifProfile(
const Image *image,
unsigned char *exif,
2168#define MaxDirectoryStack 16
2169#define EXIF_DELIMITER "\n"
2170#define EXIF_NUM_FORMATS 12
2171#define TAG_EXIF_OFFSET 0x8769
2172#define TAG_INTEROP_OFFSET 0xa005
2174 typedef struct _DirectoryInfo
2184 directory_stack[MaxDirectoryStack] = {{ 0 }};
2202 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
2208 return(MagickFalse);
2209 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2210 if ((
id != 0x4949) && (
id != 0x4D4D))
2214 if (ReadProfileByte(&exif,&length) != 0x45)
2216 if (ReadProfileByte(&exif,&length) != 0x78)
2218 if (ReadProfileByte(&exif,&length) != 0x69)
2220 if (ReadProfileByte(&exif,&length) != 0x66)
2222 if (ReadProfileByte(&exif,&length) != 0x00)
2224 if (ReadProfileByte(&exif,&length) != 0x00)
2229 return(MagickFalse);
2230 id=(ssize_t) ReadProfileShort(LSBEndian,exif);
2239 return(MagickFalse);
2240 if (ReadProfileShort(endian,exif+2) != 0x002a)
2241 return(MagickFalse);
2245 offset=(ssize_t) ReadProfileLong(endian,exif+4);
2246 if ((offset < 0) || ((size_t) offset >= length))
2247 return(MagickFalse);
2248 directory=exif+offset;
2251 exif_resources=NewSplayTree((
int (*)(
const void *,
const void *)) NULL,
2252 (
void *(*)(
void *)) NULL,(
void *(*)(
void *)) NULL);
2258 directory=directory_stack[level].directory;
2259 entry=directory_stack[level].entry;
2261 if ((directory < exif) || (directory > (exif+length-2)))
2266 number_entries=ReadProfileShort(endian,directory);
2267 for ( ; entry < number_entries; entry++)
2283 q=(
unsigned char *) (directory+2+(12*entry));
2284 if (q > (exif+length-12))
2286 if (GetValueFromSplayTree(exif_resources,q) == q)
2288 (void) AddValueToSplayTree(exif_resources,q,q);
2289 tag_value=(ssize_t) ReadProfileShort(endian,q);
2290 format=(ssize_t) ReadProfileShort(endian,q+2);
2291 if ((format < 0) || ((format-1) >= EXIF_NUM_FORMATS))
2293 components=(int) ReadProfileLong(endian,q+4);
2296 number_bytes=(size_t) components*format_bytes[format];
2297 if ((ssize_t) number_bytes < components)
2299 if (number_bytes <= 4)
2306 offset=(ssize_t) ReadProfileLong(endian,q+8);
2307 if ((offset < 0) || ((size_t) (offset+number_bytes) > length))
2309 if (~length < number_bytes)
2311 p=(
unsigned char *) (exif+offset);
2317 (void) WriteProfileLong(endian,(
size_t) (image->resolution.x+0.5),p);
2318 if (number_bytes == 8)
2319 (void) WriteProfileLong(endian,1UL,p+4);
2324 (void) WriteProfileLong(endian,(
size_t) (image->resolution.y+0.5),p);
2325 if (number_bytes == 8)
2326 (void) WriteProfileLong(endian,1UL,p+4);
2331 if (number_bytes == 4)
2333 (void) WriteProfileLong(endian,(
size_t) image->orientation,p);
2336 (void) WriteProfileShort(endian,(
unsigned short) image->orientation,
2342 if (number_bytes == 4)
2344 (void) WriteProfileLong(endian,((
size_t) image->units)+1,p);
2347 (void) WriteProfileShort(endian,(
unsigned short) (image->units+1),p);
2353 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
2355 offset=(ssize_t) ReadProfileLong(endian,p);
2356 if (((
size_t) offset < length) && (level < (MaxDirectoryStack-2)))
2358 directory_stack[level].directory=directory;
2360 directory_stack[level].entry=entry;
2362 directory_stack[level].directory=exif+offset;
2363 directory_stack[level].entry=0;
2365 if ((directory+2+(12*number_entries)) > (exif+length))
2367 offset=(ssize_t) ReadProfileLong(endian,directory+2+(12*
2369 if ((offset != 0) && ((size_t) offset < length) &&
2370 (level < (MaxDirectoryStack-2)))
2372 directory_stack[level].directory=exif+offset;
2373 directory_stack[level].entry=0;
2380 }
while (level > 0);
2381 exif_resources=DestroySplayTree(exif_resources);
2385static MagickBooleanType Sync8BimProfile(
const Image *image,
2400 length=GetStringInfoLength(profile);
2401 p=GetStringInfoDatum(profile);
2404 if (ReadProfileByte(&p,&length) != 0x38)
2406 if (ReadProfileByte(&p,&length) != 0x42)
2408 if (ReadProfileByte(&p,&length) != 0x49)
2410 if (ReadProfileByte(&p,&length) != 0x4D)
2413 return(MagickFalse);
2414 id=ReadProfileMSBShort(&p,&length);
2415 count=(ssize_t) ReadProfileByte(&p,&length);
2416 if ((count >= (ssize_t) length) || (count < 0))
2417 return(MagickFalse);
2420 if ((*p & 0x01) == 0)
2421 (
void) ReadProfileByte(&p,&length);
2422 count=(ssize_t) ReadProfileMSBLong(&p,&length);
2423 if ((count > (ssize_t) length) || (count < 0))
2424 return(MagickFalse);
2425 if ((
id == 0x3ED) && (count == 16))
2427 if (image->units == PixelsPerCentimeterResolution)
2428 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2429 image->resolution.x*2.54*65536.0),p);
2431 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2432 image->resolution.x*65536.0),p);
2433 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+4);
2434 if (image->units == PixelsPerCentimeterResolution)
2435 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2436 image->resolution.y*2.54*65536.0),p+8);
2438 WriteProfileLong(MSBEndian,(
unsigned int) CastDoubleToLong(
2439 image->resolution.y*65536.0),p+8);
2440 WriteProfileShort(MSBEndian,(
unsigned short) image->units,p+12);
2443 (void) SyncExifProfile(image,p,count);
2450MagickPrivate MagickBooleanType SyncImageProfiles(
Image *image)
2459 profile=(
StringInfo *) GetImageProfile(image,
"8BIM");
2461 if (Sync8BimProfile(image,profile) == MagickFalse)
2463 profile=(
StringInfo *) GetImageProfile(image,
"EXIF");
2465 if (SyncExifProfile(image,GetStringInfoDatum(profile),
2466 GetStringInfoLength(profile)) == MagickFalse)
2471static void UpdateClipPath(
unsigned char *blob,
size_t length,
2472 const size_t old_columns,
const size_t old_rows,
2485 selector=(ssize_t) ReadProfileMSBShort(&blob,&length);
2491 if (knot_count != 0)
2494 length-=MagickMin(24,(ssize_t) length);
2500 knot_count=(ssize_t) ReadProfileMSBShort(&blob,&length);
2502 length-=MagickMin(22,(ssize_t) length);
2510 if (knot_count == 0)
2516 length-=MagickMin(24,(ssize_t) length);
2522 for (i=0; i < 3; i++)
2532 y=(double) ReadProfileMSBLong(&blob,&length);
2533 y=y*old_rows/4096.0/4096.0;
2535 yy=(
signed int) ((y*4096*4096)/new_geometry->height);
2536 WriteProfileLong(MSBEndian,(
size_t) yy,blob-4);
2537 x=(double) ReadProfileMSBLong(&blob,&length);
2538 x=x*old_columns/4096.0/4096.0;
2540 xx=(
signed int) ((x*4096*4096)/new_geometry->width);
2541 WriteProfileLong(MSBEndian,(
size_t) xx,blob-4);
2552 length-=MagickMin(24,(ssize_t) length);
2559MagickPrivate
void Update8BIMClipPath(
const Image *image,
2560 const size_t old_columns,
const size_t old_rows,
2576 assert(image != (
Image *) NULL);
2578 profile=GetImageProfile(image,
"8bim");
2581 length=GetStringInfoLength(profile);
2582 info=GetStringInfoDatum(profile);
2585 if (ReadProfileByte(&info,&length) != (
unsigned char)
'8')
2587 if (ReadProfileByte(&info,&length) != (
unsigned char)
'B')
2589 if (ReadProfileByte(&info,&length) != (
unsigned char)
'I')
2591 if (ReadProfileByte(&info,&length) != (
unsigned char)
'M')
2593 id=(ssize_t) ReadProfileMSBShort(&info,&length);
2594 count=(ssize_t) ReadProfileByte(&info,&length);
2595 if ((count != 0) && ((size_t) count <= length))
2600 if ((count & 0x01) == 0)
2601 (
void) ReadProfileByte(&info,&length);
2602 count=(ssize_t) ReadProfileMSBLong(&info,&length);
2603 if ((count < 0) || ((size_t) count > length))
2608 if ((
id > 1999) && (
id < 2999))
2609 UpdateClipPath(info,(
size_t) count,old_columns,old_rows,new_geometry);
2611 length-=MagickMin(count,(ssize_t) length);