42#include "magick/studio.h"
43#include "magick/attribute.h"
44#include "magick/blob.h"
45#include "magick/blob-private.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/cache.h"
49#include "magick/cache-private.h"
50#include "magick/client.h"
51#include "magick/coder.h"
52#include "magick/colorspace-private.h"
53#include "magick/constitute.h"
54#include "magick/delegate.h"
55#include "magick/geometry.h"
56#include "magick/identify.h"
57#include "magick/image-private.h"
58#include "magick/list.h"
59#include "magick/magick.h"
60#include "magick/memory_.h"
61#include "magick/monitor.h"
62#include "magick/monitor-private.h"
63#include "magick/option.h"
64#include "magick/pixel.h"
65#include "magick/policy.h"
66#include "magick/profile.h"
67#include "magick/property.h"
68#include "magick/quantum.h"
69#include "magick/resize.h"
70#include "magick/resource_.h"
71#include "magick/semaphore.h"
72#include "magick/statistic.h"
73#include "magick/stream.h"
74#include "magick/string_.h"
75#include "magick/string-private.h"
76#include "magick/timer.h"
77#include "magick/token.h"
78#include "magick/transform.h"
79#include "magick/utility.h"
84#define MaxReadRecursionDepth 100
135MagickExport Image *ConstituteImage(
const size_t columns,
136 const size_t rows,
const char *map,
const StorageType storage,
137 const void *pixels,ExceptionInfo *exception)
154 assert(map != (
const char *) NULL);
155 assert(pixels != (
void *) NULL);
156 assert(exception != (ExceptionInfo *) NULL);
157 assert(exception->signature == MagickCoreSignature);
158 if (IsEventLogging() != MagickFalse)
159 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",map);
160 image=AcquireImage((ImageInfo *) NULL);
161 if (image == (Image *) NULL)
162 return((Image *) NULL);
165 case CharPixel: image->depth=8*
sizeof(
unsigned char);
break;
166 case DoublePixel: image->depth=8*
sizeof(double);
break;
167 case FloatPixel: image->depth=8*
sizeof(float);
break;
168 case LongPixel: image->depth=8*
sizeof(
unsigned long);
break;
169 case ShortPixel: image->depth=8*
sizeof(
unsigned short);
break;
173 for (i=0; i < (ssize_t) length; i++)
182 image->matte=MagickTrue;
194 image->colorspace=CMYKColorspace;
200 image->colorspace=GRAYColorspace;
206 image->colorspace=GRAYColorspace;
211 status=SetImageExtent(image,columns,rows);
212 if (status == MagickFalse)
214 InheritException(exception,&image->exception);
215 image=DestroyImage(image);
217 status=ResetImagePixels(image,exception);
218 if (status == MagickFalse)
220 InheritException(exception,&image->exception);
221 image=DestroyImage(image);
223 status=ImportImagePixels(image,0,0,columns,rows,map,storage,pixels);
224 if (status == MagickFalse)
226 InheritException(exception,&image->exception);
227 image=DestroyImage(image);
261#if defined(__cplusplus) || defined(c_plusplus)
265static size_t PingStream(
const Image *magick_unused(image),
266 const void *magick_unused(pixels),
const size_t columns)
268 magick_unreferenced(image);
269 magick_unreferenced(pixels);
274#if defined(__cplusplus) || defined(c_plusplus)
278MagickExport Image *PingImage(
const ImageInfo *image_info,
279 ExceptionInfo *exception)
287 assert(image_info != (ImageInfo *) NULL);
288 assert(image_info->signature == MagickCoreSignature);
289 assert(exception != (ExceptionInfo *) NULL);
290 if (IsEventLogging() != MagickFalse)
291 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
292 image_info->filename);
293 ping_info=CloneImageInfo(image_info);
294 ping_info->ping=MagickTrue;
295 image=ReadStream(ping_info,&PingStream,exception);
296 if (image != (Image *) NULL)
298 if ((image->columns == 0) || (image->rows == 0))
299 ThrowReaderException(CorruptImageError,
"ImproperImageHeader");
300 ResetTimer(&image->timer);
301 if (ping_info->verbose != MagickFalse)
302 (void) IdentifyImage(image,stdout,MagickFalse);
304 ping_info=DestroyImageInfo(ping_info);
332MagickExport Image *PingImages(
const ImageInfo *image_info,
333 ExceptionInfo *exception)
336 filename[MaxTextExtent];
348 assert(image_info != (ImageInfo *) NULL);
349 assert(image_info->signature == MagickCoreSignature);
350 assert(exception != (ExceptionInfo *) NULL);
351 if (IsEventLogging() != MagickFalse)
352 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
353 image_info->filename);
354 (void) InterpretImageFilename(image_info,(Image *) NULL,image_info->filename,
355 (
int) image_info->scene,filename);
356 if (LocaleCompare(filename,image_info->filename) != 0)
368 read_info=CloneImageInfo(image_info);
369 sans=AcquireExceptionInfo();
370 (void) SetImageInfo(read_info,0,sans);
371 sans=DestroyExceptionInfo(sans);
372 if (read_info->number_scenes == 0)
374 read_info=DestroyImageInfo(read_info);
375 return(PingImage(image_info,exception));
377 (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
378 images=NewImageList();
379 extent=(ssize_t) (read_info->scene+read_info->number_scenes);
380 for (scene=(ssize_t) read_info->scene; scene < (ssize_t) extent; scene++)
382 (void) InterpretImageFilename(image_info,(Image *) NULL,filename,(
int)
383 scene,read_info->filename);
384 image=PingImage(read_info,exception);
385 if (image == (Image *) NULL)
387 AppendImageToList(&images,image);
389 read_info=DestroyImageInfo(read_info);
392 return(PingImage(image_info,exception));
424static MagickBooleanType IsCoderAuthorized(
const char *module,
425 const char *coder,
const PolicyRights rights,ExceptionInfo *exception)
427 if (IsRightsAuthorized(CoderPolicyDomain,rights,coder) == MagickFalse)
430 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
431 "NotAuthorized",
"`%s'",coder);
434 if (IsRightsAuthorized(ModulePolicyDomain,rights,module) == MagickFalse)
437 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
438 "NotAuthorized",
"`%s'",module);
444MagickExport Image *ReadImage(
const ImageInfo *image_info,
445 ExceptionInfo *exception)
448 filename[MaxTextExtent],
449 magick[MaxTextExtent],
450 magick_filename[MaxTextExtent];
484 assert(image_info != (ImageInfo *) NULL);
485 assert(image_info->signature == MagickCoreSignature);
486 assert(image_info->filename != (
char *) NULL);
487 assert(exception != (ExceptionInfo *) NULL);
488 if (IsEventLogging() != MagickFalse)
489 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
490 image_info->filename);
491 read_info=CloneImageInfo(image_info);
492 (void) CopyMagickString(magick_filename,read_info->filename,MaxTextExtent);
493 (void) SetImageInfo(read_info,0,exception);
494 (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
495 (void) CopyMagickString(magick,read_info->magick,MaxTextExtent);
499 sans_exception=AcquireExceptionInfo();
500 magick_info=GetMagickInfo(read_info->magick,sans_exception);
501 if (sans_exception->severity == PolicyError)
502 magick_info=GetMagickInfo(read_info->magick,exception);
503 sans_exception=DestroyExceptionInfo(sans_exception);
504 if ((magick_info != (
const MagickInfo *) NULL) &&
505 (GetMagickRawSupport(magick_info) != MagickFalse))
507 if (GetMagickEndianSupport(magick_info) == MagickFalse)
508 read_info->endian=UndefinedEndian;
510 if (image_info->endian == UndefinedEndian)
516 read_info->endian=(*(
char *) &lsb_first) == 1 ? LSBEndian :
520 if ((magick_info != (
const MagickInfo *) NULL) &&
521 (GetMagickSeekableStream(magick_info) != MagickFalse))
526 image=AcquireImage(read_info);
527 (void) CopyMagickString(image->filename,read_info->filename,
529 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
530 if (status == MagickFalse)
532 read_info=DestroyImageInfo(read_info);
533 image=DestroyImage(image);
534 return((Image *) NULL);
536 if (IsBlobSeekable(image) == MagickFalse)
541 *read_info->filename=
'\0';
542 status=ImageToFile(image,read_info->filename,exception);
543 if (status == MagickFalse)
545 (void) CloseBlob(image);
546 read_info=DestroyImageInfo(read_info);
547 image=DestroyImage(image);
548 return((Image *) NULL);
550 read_info->temporary=MagickTrue;
552 (void) CloseBlob(image);
553 image=DestroyImage(image);
555 image=NewImageList();
556 if ((magick_info == (
const MagickInfo *) NULL) ||
557 (GetImageDecoder(magick_info) == (DecodeImageHandler *) NULL))
559 delegate_info=GetDelegateInfo(read_info->magick,(
char *) NULL,exception);
560 if (delegate_info == (
const DelegateInfo *) NULL)
562 (void) SetImageInfo(read_info,0,exception);
563 (void) CopyMagickString(read_info->filename,filename,MaxTextExtent);
564 magick_info=GetMagickInfo(read_info->magick,exception);
567 if ((magick_info != (
const MagickInfo *) NULL) &&
568 (GetImageDecoder(magick_info) != (DecodeImageHandler *) NULL))
573 thread_support=GetMagickThreadSupport(magick_info);
574 if ((thread_support & DecoderThreadSupport) == 0)
575 LockSemaphoreInfo(magick_info->semaphore);
576 status=IsCoderAuthorized(magick_info->magick_module,read_info->magick,
577 ReadPolicyRights,exception);
578 image=(Image *) NULL;
579 if (status != MagickFalse)
580 image=GetImageDecoder(magick_info)(read_info,exception);
581 if ((thread_support & DecoderThreadSupport) == 0)
582 UnlockSemaphoreInfo(magick_info->semaphore);
589 delegate_info=GetDelegateInfo(read_info->magick,(
char *) NULL,exception);
590 if (delegate_info == (
const DelegateInfo *) NULL)
592 (void) ThrowMagickException(exception,GetMagickModule(),
593 MissingDelegateError,
"NoDecodeDelegateForThisImageFormat",
"`%s'",
594 read_info->filename);
595 if (read_info->temporary != MagickFalse)
596 (void) RelinquishUniqueFileResource(read_info->filename);
597 read_info=DestroyImageInfo(read_info);
598 return((Image *) NULL);
603 image=AcquireImage(read_info);
604 if (image == (Image *) NULL)
606 read_info=DestroyImageInfo(read_info);
607 return((Image *) NULL);
609 (void) CopyMagickString(image->filename,read_info->filename,
611 *read_info->filename=
'\0';
612 if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
613 LockSemaphoreInfo(delegate_info->semaphore);
614 status=InvokeDelegate(read_info,image,read_info->magick,(
char *) NULL,
616 if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
617 UnlockSemaphoreInfo(delegate_info->semaphore);
618 image=DestroyImageList(image);
619 read_info->temporary=MagickTrue;
620 if (status != MagickFalse)
621 (void) SetImageInfo(read_info,0,exception);
622 magick_info=GetMagickInfo(read_info->magick,exception);
623 if ((magick_info == (
const MagickInfo *) NULL) ||
624 (GetImageDecoder(magick_info) == (DecodeImageHandler *) NULL))
626 if (IsPathAccessible(read_info->filename) != MagickFalse)
627 (void) ThrowMagickException(exception,GetMagickModule(),
628 MissingDelegateError,
"NoDecodeDelegateForThisImageFormat",
"`%s'",
631 ThrowFileException(exception,FileOpenError,
"UnableToOpenFile",
632 read_info->filename);
633 read_info=DestroyImageInfo(read_info);
634 return((Image *) NULL);
639 thread_support=GetMagickThreadSupport(magick_info);
640 if ((thread_support & DecoderThreadSupport) == 0)
641 LockSemaphoreInfo(magick_info->semaphore);
642 status=IsCoderAuthorized(magick_info->magick_module,read_info->magick,
643 ReadPolicyRights,exception);
644 image=(Image *) NULL;
645 if (status != MagickFalse)
646 image=(Image *) (GetImageDecoder(magick_info))(read_info,exception);
647 if ((thread_support & DecoderThreadSupport) == 0)
648 UnlockSemaphoreInfo(magick_info->semaphore);
650 if (read_info->temporary != MagickFalse)
652 (void) RelinquishUniqueFileResource(read_info->filename);
653 read_info->temporary=MagickFalse;
654 if (image != (Image *) NULL)
655 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
657 if (image == (Image *) NULL)
659 read_info=DestroyImageInfo(read_info);
662 if (exception->severity >= ErrorException)
663 (void) LogMagickEvent(ExceptionEvent,GetMagickModule(),
664 "Coder (%s) generated an image despite an error (%d), "
665 "notify the developers",image->magick,exception->severity);
666 if (IsBlobTemporary(image) != MagickFalse)
667 (void) RelinquishUniqueFileResource(read_info->filename);
668 if (read_info->ping != MagickFalse)
670 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
672 if ((image->columns == 0) || (image->rows == 0))
674 read_info=DestroyImageInfo(read_info);
675 ThrowReaderException(ImageError,
"NegativeOrZeroImageSize");
679 if ((IsSceneGeometry(read_info->scenes,MagickFalse) != MagickFalse) &&
680 (GetImageListLength(image) != 1))
685 clones=CloneImages(image,read_info->scenes,exception);
686 image=DestroyImageList(image);
687 if (clones != (Image *) NULL)
688 image=GetFirstImageInList(clones);
689 if (image == (Image *) NULL)
691 read_info=DestroyImageInfo(read_info);
695 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
698 magick_path[MaxTextExtent],
700 timestamp[MaxTextExtent];
712 *source_date_epoch = (
const char *) NULL;
714 static MagickBooleanType
715 epoch_initialized = MagickFalse;
717 next->taint=MagickFalse;
718 GetPathComponent(magick_filename,MagickPath,magick_path);
719 if ((*magick_path ==
'\0') && (*next->magick ==
'\0'))
720 (void) CopyMagickString(next->magick,magick,MaxTextExtent);
721 (void) CopyMagickString(next->magick_filename,magick_filename,
723 if (IsBlobTemporary(image) != MagickFalse)
724 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
725 if (next->magick_columns == 0)
726 next->magick_columns=next->columns;
727 if (next->magick_rows == 0)
728 next->magick_rows=next->rows;
729 (void) GetImageProperty(next,
"exif:*");
730 (void) GetImageProperty(next,
"icc:*");
731 (void) GetImageProperty(next,
"iptc:*");
732 (void) GetImageProperty(next,
"xmp:*");
733 value=GetImageProperty(next,
"exif:Orientation");
734 if (value == (
char *) NULL)
735 value=GetImageProperty(next,
"tiff:Orientation");
736 if (value != (
char *) NULL)
738 next->orientation=(OrientationType) StringToLong(value);
739 (void) DeleteImageProperty(next,
"tiff:Orientation");
740 (void) DeleteImageProperty(next,
"exif:Orientation");
742 value=GetImageProperty(next,
"exif:XResolution");
743 if (value != (
char *) NULL)
745 geometry_info.rho=next->x_resolution;
746 geometry_info.sigma=1.0;
747 (void) ParseGeometry(value,&geometry_info);
748 if (geometry_info.sigma != 0)
749 next->x_resolution=geometry_info.rho/geometry_info.sigma;
750 if (strchr(value,
',') != (
char *) NULL)
751 next->x_resolution=geometry_info.rho+geometry_info.sigma/1000.0;
752 (void) DeleteImageProperty(next,
"exif:XResolution");
754 value=GetImageProperty(next,
"exif:YResolution");
755 if (value != (
char *) NULL)
757 geometry_info.rho=next->y_resolution;
758 geometry_info.sigma=1.0;
759 (void) ParseGeometry(value,&geometry_info);
760 if (geometry_info.sigma != 0)
761 next->y_resolution=geometry_info.rho/geometry_info.sigma;
762 if (strchr(value,
',') != (
char *) NULL)
763 next->y_resolution=geometry_info.rho+geometry_info.sigma/1000.0;
764 (void) DeleteImageProperty(next,
"exif:YResolution");
766 value=GetImageProperty(next,
"exif:ResolutionUnit");
767 if (value == (
char *) NULL)
768 value=GetImageProperty(next,
"tiff:ResolutionUnit");
769 if (value != (
char *) NULL)
771 option_type=ParseCommandOption(MagickResolutionOptions,MagickFalse,
773 if (option_type >= 0)
774 next->units=(ResolutionType) option_type;
775 (void) DeleteImageProperty(next,
"exif:ResolutionUnit");
776 (void) DeleteImageProperty(next,
"tiff:ResolutionUnit");
778 if (next->page.width == 0)
779 next->page.width=next->columns;
780 if (next->page.height == 0)
781 next->page.height=next->rows;
782 option=GetImageOption(read_info,
"caption");
783 if (option != (
const char *) NULL)
785 property=InterpretImageProperties(read_info,next,option);
786 (void) SetImageProperty(next,
"caption",property);
787 property=DestroyString(property);
789 option=GetImageOption(read_info,
"comment");
790 if (option != (
const char *) NULL)
792 property=InterpretImageProperties(read_info,next,option);
793 (void) SetImageProperty(next,
"comment",property);
794 property=DestroyString(property);
796 option=GetImageOption(read_info,
"label");
797 if (option != (
const char *) NULL)
799 property=InterpretImageProperties(read_info,next,option);
800 (void) SetImageProperty(next,
"label",property);
801 property=DestroyString(property);
803 if (LocaleCompare(next->magick,
"TEXT") == 0)
804 (void) ParseAbsoluteGeometry(
"0x0+0+0",&next->page);
805 if ((read_info->extract != (
char *) NULL) &&
806 (read_info->stream == (StreamHandler) NULL))
811 SetGeometry(next,&geometry);
812 flags=ParseAbsoluteGeometry(read_info->extract,&geometry);
813 if ((next->columns != geometry.width) ||
814 (next->rows != geometry.height))
816 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
821 crop_image=CropImage(next,&geometry,exception);
822 if (crop_image != (Image *) NULL)
823 ReplaceImageInList(&next,crop_image);
826 if (((flags & WidthValue) != 0) || ((flags & HeightValue) != 0))
828 (void) ParseRegionGeometry(next,read_info->extract,&geometry,
830 if ((geometry.width != 0) && (geometry.height != 0))
832 Image *resize_image=ResizeImage(next,geometry.width,
833 geometry.height,next->filter,next->blur,exception);
834 if (resize_image != (Image *) NULL)
835 ReplaceImageInList(&next,resize_image);
840 profile=GetImageProfile(next,
"icc");
841 if (profile == (
const StringInfo *) NULL)
842 profile=GetImageProfile(next,
"icm");
843 if (profile != (
const StringInfo *) NULL)
845 next->color_profile.length=GetStringInfoLength(profile);
846 next->color_profile.info=GetStringInfoDatum(profile);
848 profile=GetImageProfile(next,
"iptc");
849 if (profile == (
const StringInfo *) NULL)
850 profile=GetImageProfile(next,
"8bim");
851 if (profile != (
const StringInfo *) NULL)
853 next->iptc_profile.length=GetStringInfoLength(profile);
854 next->iptc_profile.info=GetStringInfoDatum(profile);
856 if (epoch_initialized == MagickFalse)
858 source_date_epoch=getenv(
"SOURCE_DATE_EPOCH");
859 epoch_initialized=MagickTrue;
861 if (source_date_epoch == (
const char *) NULL)
863 (void) FormatMagickTime(image->timestamp,MaxTextExtent,timestamp);
864 (void) SetImageProperty(next,
"date:timestamp",timestamp);
865 (void) FormatMagickTime((time_t) GetBlobProperties(next)->st_mtime,
866 MaxTextExtent,timestamp);
867 (void) SetImageProperty(next,
"date:modify",timestamp);
868 (void) FormatMagickTime((time_t) GetBlobProperties(next)->st_ctime,
869 MaxTextExtent,timestamp);
870 (void) SetImageProperty(next,
"date:create",timestamp);
872 option=GetImageOption(image_info,
"delay");
873 if (option != (
const char *) NULL)
878 flags=ParseGeometry(option,&geometry_info);
879 if ((flags & GreaterValue) != 0)
881 if (next->delay > (
size_t) floor(geometry_info.rho+0.5))
882 next->delay=(size_t) floor(geometry_info.rho+0.5);
885 if ((flags & LessValue) != 0)
887 if (next->delay < (
size_t) floor(geometry_info.rho+0.5))
888 next->delay=(size_t) floor(geometry_info.rho+0.5);
891 next->delay=(size_t) floor(geometry_info.rho+0.5);
892 if ((flags & SigmaValue) != 0)
893 next->ticks_per_second=CastDoubleToLong(floor(
894 geometry_info.sigma+0.5));
896 option=GetImageOption(image_info,
"dispose");
897 if (option != (
const char *) NULL)
899 option_type=ParseCommandOption(MagickDisposeOptions,MagickFalse,
901 if (option_type >= 0)
902 next->dispose=(DisposeType) option_type;
904 if (read_info->verbose != MagickFalse)
905 (void) IdentifyImage(next,stderr,MagickFalse);
908 read_info=DestroyImageInfo(read_info);
909 if (GetBlobError(image) != MagickFalse)
910 ThrowReaderException(CorruptImageError,
"UnableToReadImageData");
911 return(GetFirstImageInList(image));
938MagickExport Image *ReadImages(
const ImageInfo *image_info,
939 ExceptionInfo *exception)
942 filename[MaxTextExtent];
954 assert(image_info != (ImageInfo *) NULL);
955 assert(image_info->signature == MagickCoreSignature);
956 assert(exception != (ExceptionInfo *) NULL);
957 if (IsEventLogging() != MagickFalse)
958 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
959 image_info->filename);
960 read_info=CloneImageInfo(image_info);
961 *read_info->magick=
'\0';
962 (void) InterpretImageFilename(read_info,(Image *) NULL,read_info->filename,
963 (
int) read_info->scene,filename);
964 if (LocaleCompare(filename,read_info->filename) != 0)
976 sans=AcquireExceptionInfo();
977 (void) SetImageInfo(read_info,0,sans);
978 sans=DestroyExceptionInfo(sans);
979 if (read_info->number_scenes == 0)
981 read_info=DestroyImageInfo(read_info);
982 return(ReadImage(image_info,exception));
984 (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
985 images=NewImageList();
986 extent=(ssize_t) (read_info->scene+read_info->number_scenes);
987 for (scene=(ssize_t) read_info->scene; scene < (ssize_t) extent; scene++)
989 (void) InterpretImageFilename(image_info,(Image *) NULL,filename,(
int)
990 scene,read_info->filename);
991 image=ReadImage(read_info,exception);
992 if (image == (Image *) NULL)
994 AppendImageToList(&images,image);
996 read_info=DestroyImageInfo(read_info);
999 image=ReadImage(read_info,exception);
1000 read_info=DestroyImageInfo(read_info);
1034MagickExport Image *ReadInlineImage(
const ImageInfo *image_info,
1035 const char *content,ExceptionInfo *exception)
1055 image=NewImageList();
1056 for (p=content; (*p !=
',') && (*p !=
'\0'); p++) ;
1058 ThrowReaderException(CorruptImageError,
"CorruptImage");
1059 blob=Base64Decode(++p,&length);
1062 blob=(
unsigned char *) RelinquishMagickMemory(blob);
1063 ThrowReaderException(CorruptImageError,
"CorruptImage");
1065 read_info=CloneImageInfo(image_info);
1066 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
1068 *read_info->filename=
'\0';
1069 *read_info->magick=
'\0';
1070 for (p=content; (*p !=
'/') && (*p !=
'\0'); p++) ;
1082 if (LocaleNCompare(++p,
"x-",2) == 0)
1084 (void) CopyMagickString(read_info->filename,
"data.",MagickPathExtent);
1085 q=read_info->filename+5;
1086 for (i=0; (*p !=
';') && (*p !=
'\0') && (i < (MagickPathExtent-6)); i++)
1090 image=BlobToImage(read_info,blob,length,exception);
1091 blob=(
unsigned char *) RelinquishMagickMemory(blob);
1092 read_info=DestroyImageInfo(read_info);
1124MagickExport MagickBooleanType WriteImage(
const ImageInfo *image_info,
1128 filename[MaxTextExtent];
1156 assert(image_info != (ImageInfo *) NULL);
1157 assert(image_info->signature == MagickCoreSignature);
1158 assert(image != (Image *) NULL);
1159 assert(image->signature == MagickCoreSignature);
1160 if (IsEventLogging() != MagickFalse)
1161 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1162 image_info->filename);
1163 exception=(&image->exception);
1164 sans_exception=AcquireExceptionInfo();
1165 write_info=CloneImageInfo(image_info);
1166 (void) CopyMagickString(write_info->filename,image->filename,MaxTextExtent);
1167 (void) SetImageInfo(write_info,1,sans_exception);
1168 if (*write_info->magick ==
'\0')
1169 (void) CopyMagickString(write_info->magick,image->magick,MaxTextExtent);
1170 if (LocaleCompare(write_info->magick,
"clipmask") == 0)
1172 if (image->clip_mask == (Image *) NULL)
1174 (void) ThrowMagickException(exception,GetMagickModule(),
1175 OptionError,
"NoClipPathDefined",
"`%s'",image->filename);
1176 write_info=DestroyImageInfo(write_info);
1177 return(MagickFalse);
1179 image=image->clip_mask;
1180 (void) SetImageInfo(write_info,1,sans_exception);
1182 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
1183 (void) CopyMagickString(image->filename,write_info->filename,MaxTextExtent);
1187 magick_info=GetMagickInfo(write_info->magick,sans_exception);
1188 if (sans_exception->severity == PolicyError)
1189 magick_info=GetMagickInfo(write_info->magick,exception);
1190 sans_exception=DestroyExceptionInfo(sans_exception);
1191 if (magick_info != (
const MagickInfo *) NULL)
1193 if (GetMagickEndianSupport(magick_info) == MagickFalse)
1194 image->endian=UndefinedEndian;
1196 if ((image_info->endian == UndefinedEndian) &&
1197 (GetMagickRawSupport(magick_info) != MagickFalse))
1203 image->endian=(*(
char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
1206 if ((image->ping != MagickFalse) &&
1207 (SyncImagePixelCache(image,exception) == MagickFalse))
1208 return(MagickFalse);
1209 if (SyncImageProfiles(image) == MagickFalse)
1210 return(MagickFalse);
1211 DisassociateImageStream(image);
1212 option=GetImageOption(image_info,
"delegate:bimodal");
1213 if ((option != (
const char *) NULL) &&
1214 (IsMagickTrue(option) != MagickFalse) &&
1215 (write_info->page == (
char *) NULL) &&
1216 (GetPreviousImageInList(image) == (Image *) NULL) &&
1217 (GetNextImageInList(image) == (Image *) NULL) &&
1218 (IsTaintImage(image) == MagickFalse))
1220 delegate_info=GetDelegateInfo(image->magick,write_info->magick,
1222 if ((delegate_info != (
const DelegateInfo *) NULL) &&
1223 (GetDelegateMode(delegate_info) == 0) &&
1224 (IsPathAccessible(image->magick_filename) != MagickFalse))
1229 (void) CopyMagickString(image->filename,image->magick_filename,
1231 status=InvokeDelegate(write_info,image,image->magick,
1232 write_info->magick,exception);
1233 write_info=DestroyImageInfo(write_info);
1234 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1239 temporary=MagickFalse;
1240 if ((magick_info != (
const MagickInfo *) NULL) &&
1241 (GetMagickSeekableStream(magick_info) != MagickFalse))
1244 filename[MaxTextExtent];
1246 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
1247 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1248 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1249 if (status != MagickFalse)
1251 if (IsBlobSeekable(image) == MagickFalse)
1256 write_info->adjoin=MagickTrue;
1257 (void) CopyMagickString(write_info->filename,image->filename,
1259 (void) AcquireUniqueFilename(image->filename);
1260 temporary=MagickTrue;
1262 if (CloseBlob(image) == MagickFalse)
1266 if ((magick_info != (
const MagickInfo *) NULL) &&
1267 (GetImageEncoder(magick_info) != (EncodeImageHandler *) NULL))
1272 thread_support=GetMagickThreadSupport(magick_info);
1273 if ((thread_support & EncoderThreadSupport) == 0)
1274 LockSemaphoreInfo(magick_info->semaphore);
1275 status=IsCoderAuthorized(magick_info->magick_module,write_info->magick,
1276 WritePolicyRights,exception);
1277 if (status != MagickFalse)
1278 status=GetImageEncoder(magick_info)(write_info,image);
1279 if ((thread_support & EncoderThreadSupport) == 0)
1280 UnlockSemaphoreInfo(magick_info->semaphore);
1284 delegate_info=GetDelegateInfo((
char *) NULL,write_info->magick,
1286 if (delegate_info != (DelegateInfo *) NULL)
1291 *write_info->filename=
'\0';
1292 if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
1293 LockSemaphoreInfo(delegate_info->semaphore);
1294 status=InvokeDelegate(write_info,image,(
char *) NULL,
1295 write_info->magick,exception);
1296 if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
1297 UnlockSemaphoreInfo(delegate_info->semaphore);
1298 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1302 sans_exception=AcquireExceptionInfo();
1303 magick_info=GetMagickInfo(write_info->magick,sans_exception);
1304 if (sans_exception->severity == PolicyError)
1305 magick_info=GetMagickInfo(write_info->magick,exception);
1306 sans_exception=DestroyExceptionInfo(sans_exception);
1307 if ((write_info->affirm == MagickFalse) &&
1308 (magick_info == (
const MagickInfo *) NULL))
1310 (void) CopyMagickString(write_info->magick,image->magick,
1312 magick_info=GetMagickInfo(write_info->magick,exception);
1314 if ((magick_info == (
const MagickInfo *) NULL) ||
1315 (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL))
1318 extension[MaxTextExtent];
1320 GetPathComponent(image->filename,ExtensionPath,extension);
1321 if (*extension !=
'\0')
1322 magick_info=GetMagickInfo(extension,exception);
1324 magick_info=GetMagickInfo(image->magick,exception);
1325 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1327 if ((magick_info == (
const MagickInfo *) NULL) ||
1328 (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL))
1330 magick_info=GetMagickInfo(image->magick,exception);
1331 if ((magick_info == (
const MagickInfo *) NULL) ||
1332 (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL))
1333 (void) ThrowMagickException(exception,GetMagickModule(),
1334 MissingDelegateError,
"NoEncodeDelegateForThisImageFormat",
1335 "`%s'",write_info->magick);
1337 (
void) ThrowMagickException(exception,GetMagickModule(),
1338 MissingDelegateWarning,
"NoEncodeDelegateForThisImageFormat",
1339 "`%s'",write_info->magick);
1341 if ((magick_info != (
const MagickInfo *) NULL) &&
1342 (GetImageEncoder(magick_info) != (EncodeImageHandler *) NULL))
1347 thread_support=GetMagickThreadSupport(magick_info);
1348 if ((thread_support & EncoderThreadSupport) == 0)
1349 LockSemaphoreInfo(magick_info->semaphore);
1350 status=IsCoderAuthorized(magick_info->magick_module,write_info->magick,
1351 WritePolicyRights,exception);
1352 if (status != MagickFalse)
1353 status=GetImageEncoder(magick_info)(write_info,image);
1354 if ((thread_support & EncoderThreadSupport) == 0)
1355 UnlockSemaphoreInfo(magick_info->semaphore);
1359 if (temporary != MagickFalse)
1364 status=OpenBlob(write_info,image,ReadBinaryBlobMode,exception);
1365 if (status != MagickFalse)
1367 (void) RelinquishUniqueFileResource(write_info->filename);
1368 status=ImageToFile(image,write_info->filename,exception);
1370 if (CloseBlob(image) == MagickFalse)
1372 (void) RelinquishUniqueFileResource(image->filename);
1373 (void) CopyMagickString(image->filename,write_info->filename,
1376 if ((LocaleCompare(write_info->magick,
"info") != 0) &&
1377 (write_info->verbose != MagickFalse))
1378 (void) IdentifyImage(image,stderr,MagickFalse);
1379 write_info=DestroyImageInfo(write_info);
1380 if (GetBlobError(image) != MagickFalse)
1381 ThrowWriterException(FileOpenError,
"UnableToWriteFile");
1421MagickExport MagickBooleanType WriteImages(
const ImageInfo *image_info,
1422 Image *images,
const char *filename,ExceptionInfo *exception)
1424#define WriteImageTag "Write/Image"
1438 MagickProgressMonitor
1450 assert(image_info != (
const ImageInfo *) NULL);
1451 assert(image_info->signature == MagickCoreSignature);
1452 assert(images != (Image *) NULL);
1453 assert(images->signature == MagickCoreSignature);
1454 assert(exception != (ExceptionInfo *) NULL);
1455 if (IsEventLogging() != MagickFalse)
1456 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
1457 write_info=CloneImageInfo(image_info);
1458 *write_info->magick=
'\0';
1459 images=GetFirstImageInList(images);
1460 if (images == (Image *) NULL)
1461 return(MagickFalse);
1462 if (filename != (
const char *) NULL)
1463 for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
1464 (
void) CopyMagickString(p->filename,filename,MaxTextExtent);
1465 (void) CopyMagickString(write_info->filename,images->filename,MaxTextExtent);
1466 sans_exception=AcquireExceptionInfo();
1467 (void) SetImageInfo(write_info,(
unsigned int) GetImageListLength(images),
1469 sans_exception=DestroyExceptionInfo(sans_exception);
1470 if (*write_info->magick ==
'\0')
1471 (void) CopyMagickString(write_info->magick,images->magick,MaxTextExtent);
1473 for ( ; GetNextImageInList(p) != (Image *) NULL; p=GetNextImageInList(p))
1475 if (p->scene >= GetNextImageInList(p)->scene)
1483 i=(ssize_t) images->scene;
1484 for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
1485 p->scene=(
size_t) i++;
1493 progress_monitor=(MagickProgressMonitor) NULL;
1495 number_images=GetImageListLength(images);
1496 for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
1498 if (number_images != 1)
1499 progress_monitor=SetImageProgressMonitor(p,(MagickProgressMonitor) NULL,
1501 status&=WriteImage(write_info,p);
1502 GetImageException(p,exception);
1503 if (number_images != 1)
1504 (void) SetImageProgressMonitor(p,progress_monitor,p->client_data);
1505 if (write_info->adjoin != MagickFalse)
1507 if (number_images != 1)
1509 proceed=SetImageProgress(p,WriteImageTag,i++,number_images);
1510 if (proceed == MagickFalse)
1514 write_info=DestroyImageInfo(write_info);
1515 return(status != 0 ? MagickTrue : MagickFalse);