void Magick::Options::magick(const std::string &magick_) { if (magick_.empty()) { _imageInfo->magick[0] = '\0'; return; } FormatLocaleString(_imageInfo->filename,MagickPathExtent,"%.1024s:", magick_.c_str()); GetPPException; SetImageInfo(_imageInfo,1,exceptionInfo); if ( _imageInfo->magick[0] == '\0' ) throwExceptionExplicit(MagickCore::OptionError,"Unrecognized image format", magick_.c_str()); ThrowPPException(_quiet); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e V I D I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteVIDImage() writes an image to a file in VID X image format. % % The format of the WriteVIDImage method is: % % MagickBooleanType WriteVIDImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteVIDImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { Image *montage_image; ImageInfo *write_info; MagickBooleanType status; MontageInfo *montage_info; register Image *p; /* Create the visual image directory. */ for (p=image; p != (Image *) NULL; p=GetNextImageInList(p)) (void) SetImageProperty(p,"label",DefaultTileLabel,exception); montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL); montage_image=MontageImageList(image_info,montage_info,image,exception); montage_info=DestroyMontageInfo(montage_info); if (montage_image == (Image *) NULL) return(MagickFalse); (void) CopyMagickString(montage_image->filename,image_info->filename, MagickPathExtent); write_info=CloneImageInfo(image_info); *write_info->magick='\0'; (void) SetImageInfo(write_info,1,exception); if ((*write_info->magick == '\0') || (LocaleCompare(write_info->magick,"VID") == 0)) (void) FormatLocaleString(montage_image->filename,MagickPathExtent, "miff:%s",write_info->filename); status=WriteImage(write_info,montage_image,exception); montage_image=DestroyImage(montage_image); write_info=DestroyImageInfo(write_info); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e V I D I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteVIDImage() writes an image to a file in VID X image format. % % The format of the WriteVIDImage method is: % % MagickBooleanType WriteVIDImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteVIDImage(const ImageInfo *image_info,Image *image) { Image *montage_image; ImageInfo *write_info; MagickBooleanType status; MontageInfo *montage_info; register Image *p; /* Create the visual image directory. */ for (p=image; p != (Image *) NULL; p=GetNextImageInList(p)) (void) SetImageProperty(p,"label",DefaultTileLabel); montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL); montage_image=MontageImageList(image_info,montage_info,image, &image->exception); montage_info=DestroyMontageInfo(montage_info); if (montage_image == (Image *) NULL) ThrowWriterException(CorruptImageError,image->exception.reason); (void) CopyMagickString(montage_image->filename,image_info->filename, MaxTextExtent); write_info=CloneImageInfo(image_info); (void) SetImageInfo(write_info,1,&image->exception); if (LocaleCompare(write_info->magick,"VID") == 0) (void) FormatMagickString(montage_image->filename,MaxTextExtent, "miff:%s",write_info->filename); status=WriteImage(write_info,montage_image); montage_image=DestroyImage(montage_image); write_info=DestroyImageInfo(write_info); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e P R E V I E W I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WritePreviewImage creates several tiles each with a varying % stength of an image enhancement function (e.g. gamma). The image is written % in the MIFF format. % % The format of the WritePreviewImage method is: % % MagickBooleanType WritePreviewImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WritePreviewImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { Image *preview_image; ImageInfo *write_info; MagickBooleanType status; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); preview_image=PreviewImage(image,image_info->preview_type,exception); if (preview_image == (Image *) NULL) return(MagickFalse); (void) CopyMagickString(preview_image->filename,image_info->filename, MagickPathExtent); write_info=CloneImageInfo(image_info); *write_info->magick='\0'; (void) SetImageInfo(write_info,1,exception); if (LocaleCompare(write_info->magick,"PREVIEW") == 0) (void) FormatLocaleString(preview_image->filename,MagickPathExtent, "miff:%s",image_info->filename); status=WriteImage(write_info,preview_image,exception); preview_image=DestroyImage(preview_image); write_info=DestroyImageInfo(write_info); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G l o b E x p r e s s i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GlobExpression() returns MagickTrue if the expression matches the pattern. % % The format of the GlobExpression function is: % % MagickBooleanType GlobExpression(const char *expression, % const char *pattern,const MagickBooleanType case_insensitive) % % A description of each parameter follows: % % o expression: Specifies a pointer to a text string containing a file name. % % o pattern: Specifies a pointer to a text string containing a pattern. % % o case_insensitive: set to MagickTrue to ignore the case when matching % an expression. % */ MagickExport MagickBooleanType GlobExpression(const char *expression, const char *pattern,const MagickBooleanType case_insensitive) { MagickBooleanType done, match; register const char *p; /* Return on empty pattern or '*'. */ if (pattern == (char *) NULL) return(MagickTrue); if (GetUTFCode(pattern) == 0) return(MagickTrue); if (LocaleCompare(pattern,"*") == 0) return(MagickTrue); p=pattern+strlen(pattern)-1; if ((GetUTFCode(p) == ']') && (strchr(pattern,'[') != (char *) NULL)) { ExceptionInfo *exception; ImageInfo *image_info; /* Determine if pattern is a scene, i.e. img0001.pcd[2]. */ image_info=AcquireImageInfo(); (void) CopyMagickString(image_info->filename,pattern,MaxTextExtent); exception=AcquireExceptionInfo(); (void) SetImageInfo(image_info,MagickTrue,exception); exception=DestroyExceptionInfo(exception); if (LocaleCompare(image_info->filename,pattern) != 0) { image_info=DestroyImageInfo(image_info); return(MagickFalse); } image_info=DestroyImageInfo(image_info); } /* Evaluate glob expression. */ done=MagickFalse; while ((GetUTFCode(pattern) != 0) && (done == MagickFalse)) { if (GetUTFCode(expression) == 0) if ((GetUTFCode(pattern) != '{') && (GetUTFCode(pattern) != '*')) break; switch (GetUTFCode(pattern)) { case '\\': { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) != 0) pattern+=GetUTFOctets(pattern); break; } case '*': { MagickBooleanType status; status=MagickFalse; pattern+=GetUTFOctets(pattern); while ((GetUTFCode(expression) != 0) && (status == MagickFalse)) { status=GlobExpression(expression,pattern,case_insensitive); expression+=GetUTFOctets(expression); } if (status != MagickFalse) { while (GetUTFCode(expression) != 0) expression+=GetUTFOctets(expression); while (GetUTFCode(pattern) != 0) pattern+=GetUTFOctets(pattern); } break; } case '[': { long c; pattern+=GetUTFOctets(pattern); for ( ; ; ) { if ((GetUTFCode(pattern) == 0) || (GetUTFCode(pattern) == ']')) { done=MagickTrue; break; } if (GetUTFCode(pattern) == '\\') { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == 0) { done=MagickTrue; break; } } if (GetUTFCode(pattern+GetUTFOctets(pattern)) == '-') { c=GetUTFCode(pattern); pattern+=GetUTFOctets(pattern); pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == ']') { done=MagickTrue; break; } if (GetUTFCode(pattern) == '\\') { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == 0) { done=MagickTrue; break; } } if ((GetUTFCode(expression) < c) || (GetUTFCode(expression) > GetUTFCode(pattern))) { pattern+=GetUTFOctets(pattern); continue; } } else if (GetUTFCode(pattern) != GetUTFCode(expression)) { pattern+=GetUTFOctets(pattern); continue; } pattern+=GetUTFOctets(pattern); while ((GetUTFCode(pattern) != ']') && (GetUTFCode(pattern) != 0)) { if ((GetUTFCode(pattern) == '\\') && (GetUTFCode(pattern+GetUTFOctets(pattern)) > 0)) pattern+=GetUTFOctets(pattern); pattern+=GetUTFOctets(pattern); } if (GetUTFCode(pattern) != 0) { pattern+=GetUTFOctets(pattern); expression+=GetUTFOctets(expression); } break; } break; } case '?': { pattern+=GetUTFOctets(pattern); expression+=GetUTFOctets(expression); break; } case '{': { register const char *p; pattern+=GetUTFOctets(pattern); while ((GetUTFCode(pattern) != '}') && (GetUTFCode(pattern) != 0)) { p=expression; match=MagickTrue; while ((GetUTFCode(p) != 0) && (GetUTFCode(pattern) != 0) && (GetUTFCode(pattern) != ',') && (GetUTFCode(pattern) != '}') && (match != MagickFalse)) { if (GetUTFCode(pattern) == '\\') pattern+=GetUTFOctets(pattern); match=(GetUTFCode(pattern) == GetUTFCode(p)) ? MagickTrue : MagickFalse; p+=GetUTFOctets(p); pattern+=GetUTFOctets(pattern); } if (GetUTFCode(pattern) == 0) { match=MagickFalse; done=MagickTrue; break; } else if (match != MagickFalse) { expression=p; while ((GetUTFCode(pattern) != '}') && (GetUTFCode(pattern) != 0)) { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == '\\') { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == '}') pattern+=GetUTFOctets(pattern); } } } else { while ((GetUTFCode(pattern) != '}') && (GetUTFCode(pattern) != ',') && (GetUTFCode(pattern) != 0)) { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == '\\') { pattern+=GetUTFOctets(pattern); if ((GetUTFCode(pattern) == '}') || (GetUTFCode(pattern) == ',')) pattern+=GetUTFOctets(pattern); } } } if (GetUTFCode(pattern) != 0) pattern+=GetUTFOctets(pattern); } break; } default: { if (case_insensitive != MagickFalse) { if (tolower((int) GetUTFCode(expression)) != tolower((int) GetUTFCode(pattern))) { done=MagickTrue; break; } } else if (GetUTFCode(expression) != GetUTFCode(pattern)) { done=MagickTrue; break; } expression+=GetUTFOctets(expression); pattern+=GetUTFOctets(pattern); } } } while (GetUTFCode(pattern) == '*') pattern+=GetUTFOctets(pattern); match=(GetUTFCode(expression) == 0) && (GetUTFCode(pattern) == 0) ? MagickTrue : MagickFalse; return(match); }
static unsigned int WriteXTRNImage(const ImageInfo *image_info,Image *image) { Image * p; ImageInfo *clone_info; int scene; void *param1, *param2, *param3; unsigned int status; param1 = param2 = param3 = (void *) NULL; if (LocaleCompare(image_info->magick,"XTRNFILE") == 0) { clone_info=CloneImageInfo(image_info); status=WriteImage(image_info,image); if (status == False) CatchImageException(image); DestroyImageInfo(clone_info); } else if (LocaleCompare(image_info->magick,"XTRNIMAGE") == 0) { Image **image_ptr; ImageInfo **image_info_ptr; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%lx",¶m1,¶m2); image_info_ptr=(ImageInfo **) param1; image_ptr=(Image **) param2; if ((image_info_ptr != (ImageInfo **) NULL) && (image_ptr != (Image **) NULL)) { *image_ptr=CloneImage(image,0,0,False,&(image->exception)); *image_info_ptr=clone_info; } } } else if (LocaleCompare(image_info->magick,"XTRNBLOB") == 0) { char **blob_data; ExceptionInfo exception; size_t *blob_length; char filename[MaxTextExtent]; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%lx,%s", ¶m1,¶m2,&filename); blob_data=(char **) param1; blob_length=(size_t *) param2; scene = 0; (void) strcpy(clone_info->filename, filename); for (p=image; p != (Image *) NULL; p=p->next) { (void) strcpy(p->filename, filename); p->scene=scene++; } SetImageInfo(clone_info,SETMAGICK_WRITE,&image->exception); (void) strcpy(image->magick,clone_info->magick); GetExceptionInfo(&exception); if (*blob_length == 0) *blob_length=8192; *blob_data=(char *) ImageToBlob(clone_info,image,blob_length,&exception); if (*blob_data == NULL) status=False; if (status == False) CatchImageException(image); } DestroyImageInfo(clone_info); } else if (LocaleCompare(image_info->magick,"XTRNARRAY") == 0) { char *blob_data; ExceptionInfo exception; size_t blob_length; char filename[MaxTextExtent]; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%s", ¶m1,&filename); image->client_data=param1; scene = 0; blob_length = 0; (void) strcpy(clone_info->filename, filename); for (p=image; p != (Image *) NULL; p=p->next) { (void) strcpy(p->filename, filename); p->scene=scene++; } SetImageInfo(clone_info,SETMAGICK_WRITE,&image->exception); (void) strcpy(image->magick,clone_info->magick); GetExceptionInfo(&exception); blob_data=(char *) ImageToBlob(clone_info,image,&blob_length,&exception); if (blob_data == NULL) status=False; else SafeArrayFifo(image,blob_data,blob_length); if (status == False) CatchImageException(image); } DestroyImageInfo(clone_info); } return(True); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e I m a g e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteImages() writes an image sequence. % % The format of the WriteImages method is: % % MagickBooleanType WriteImages(const ImageInfo *image_info,Image *images, % const char *filename,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o images: the image list. % % o filename: the image filename. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType WriteImages(const ImageInfo *image_info, Image *images,const char *filename,ExceptionInfo *exception) { BlobInfo *blob; ExceptionInfo *sans_exception; ImageInfo *write_info; MagickStatusType status; register Image *p; assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(images != (Image *) NULL); assert(images->signature == MagickSignature); if (images->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); assert(exception != (ExceptionInfo *) NULL); write_info=CloneImageInfo(image_info); images=GetFirstImageInList(images); blob=CloneBlobInfo(images->blob); /* thread specific I/O handler */ DestroyBlob(images); images->blob=blob; if (filename != (const char *) NULL) for (p=images; p != (Image *) NULL; p=GetNextImageInList(p)) (void) CopyMagickString(p->filename,filename,MaxTextExtent); (void) CopyMagickString(write_info->filename,images->filename,MaxTextExtent); if (*write_info->magick == '\0') (void) CopyMagickString(write_info->magick,images->magick,MaxTextExtent); sans_exception=AcquireExceptionInfo(); (void) SetImageInfo(write_info,MagickTrue,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); p=images; for ( ; GetNextImageInList(p) != (Image *) NULL; p=GetNextImageInList(p)) if (p->scene >= GetNextImageInList(p)->scene) { register long i; /* Generate consistent scene numbers. */ i=(long) images->scene; for (p=images; p != (Image *) NULL; p=GetNextImageInList(p)) p->scene=(unsigned long) i++; break; } /* Write images. */ status=MagickTrue; for (p=images; p != (Image *) NULL; p=GetNextImageInList(p)) { status&=WriteImage(write_info,p); GetImageException(p,exception); if (write_info->adjoin != MagickFalse) break; } write_info=DestroyImageInfo(write_info); return(status != 0 ? MagickTrue : MagickFalse); }
static MagickBooleanType WriteXTRNImage(const ImageInfo *image_info,Image *image) { Image * p; ImageInfo *clone_info; int scene; MagickBooleanType status; void *param1, *param2, *param3; param1 = param2 = param3 = (void *) NULL; if (LocaleCompare(image_info->magick,"XTRNFILE") == 0) { clone_info=CloneImageInfo(image_info); status=WriteImage(image_info,image); if (status == MagickFalse) CatchImageException(image); clone_info=DestroyImageInfo(clone_info); } else if (LocaleCompare(image_info->magick,"XTRNIMAGE") == 0) { Image **image_ptr; ImageInfo **image_info_ptr; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%lx",¶m1,¶m2); image_info_ptr=(ImageInfo **) param1; image_ptr=(Image **) param2; if ((image_info_ptr != (ImageInfo **) NULL) && (image_ptr != (Image **) NULL)) { *image_ptr=CloneImage(image,0,0,MagickFalse,&(image->exception)); *image_info_ptr=clone_info; } } } else if (LocaleCompare(image_info->magick,"XTRNBLOB") == 0) { char **blob_data; ExceptionInfo exception; size_t *blob_length; char filename[MaxTextExtent]; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%lx,%s", ¶m1,¶m2,&filename); blob_data=(char **) param1; blob_length=(size_t *) param2; scene = 0; (void) CopyMagickString(clone_info->filename,filename,MaxTextExtent); for (p=image; p != (Image *) NULL; p=GetNextImageInList(p)) { (void) CopyMagickString(p->filename,filename,MaxTextExtent); p->scene=scene++; } SetImageInfo(clone_info,MagickTrue,&image->exception); (void) CopyMagickString(image->magick,clone_info->magick, MaxTextExtent); GetExceptionInfo(&exception); if (*blob_length == 0) *blob_length=8192; *blob_data=(char *) ImageToBlob(clone_info,image,blob_length, &exception); if (*blob_data == NULL) status=MagickFalse; if (status == MagickFalse) CatchImageException(image); } clone_info=DestroyImageInfo(clone_info); } else if (LocaleCompare(image_info->magick,"XTRNSTREAM") == 0) { size_t (*fifo)(const Image *,const void *,const size_t); char filename[MaxTextExtent]; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%lx,%s", ¶m1,¶m2,&filename); fifo=(size_t (*)(const Image *,const void *,const size_t)) param1; image->client_data=param2; scene=0; (void) CopyMagickString(clone_info->filename,filename,MaxTextExtent); for (p=image; p != (Image *) NULL; p=GetNextImageInList(p)) { (void) CopyMagickString(p->filename,filename,MaxTextExtent); p->scene=scene++; } SetImageInfo(clone_info,MagickTrue,&image->exception); (void) CopyMagickString(image->magick,clone_info->magick, MaxTextExtent); status=WriteStream(clone_info,image,fifo); if (status == MagickFalse) CatchImageException(image); } clone_info=DestroyImageInfo(clone_info); } else if (LocaleCompare(image_info->magick,"XTRNARRAY") == 0) { char filename[MaxTextExtent]; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%s", ¶m1,&filename); image->client_data=param1; scene = 0; (void) CopyMagickString(clone_info->filename,filename,MaxTextExtent); for (p=image; p != (Image *) NULL; p=GetNextImageInList(p)) { (void) CopyMagickString(p->filename,filename,MaxTextExtent); p->scene=scene++; } SetImageInfo(clone_info,MagickTrue,&image->exception); (void) CopyMagickString(image->magick,clone_info->magick, MaxTextExtent); status=WriteStream(clone_info,image,SafeArrayFifo); if (status == MagickFalse) CatchImageException(image); } clone_info=DestroyImageInfo(clone_info); } return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d I m a g e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadImages() reads one or more images and returns them as an image list. % % The format of the ReadImage method is: % % Image *ReadImages(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ MagickExport Image *ReadImages(const ImageInfo *image_info, ExceptionInfo *exception) { char filename[MaxTextExtent]; Image *image, *images; ImageInfo *read_info; /* Read image list from a file. */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); (void) InterpretImageFilename(image_info,(Image *) NULL,image_info->filename, (int) image_info->scene,filename,exception); if (LocaleCompare(filename,image_info->filename) != 0) { ExceptionInfo *sans; ssize_t extent, scene; /* Images of the form image-%d.png[1-5]. */ read_info=CloneImageInfo(image_info); sans=AcquireExceptionInfo(); (void) SetImageInfo(read_info,0,sans); sans=DestroyExceptionInfo(sans); if (read_info->number_scenes == 0) { read_info=DestroyImageInfo(read_info); return(ReadImage(image_info,exception)); } (void) CopyMagickString(filename,read_info->filename,MaxTextExtent); images=NewImageList(); extent=(ssize_t) (read_info->scene+read_info->number_scenes); for (scene=(ssize_t) read_info->scene; scene < (ssize_t) extent; scene++) { (void) InterpretImageFilename(image_info,(Image *) NULL,filename,(int) scene,read_info->filename,exception); image=ReadImage(read_info,exception); if (image == (Image *) NULL) continue; AppendImageToList(&images,image); } read_info=DestroyImageInfo(read_info); return(images); } return(ReadImage(image_info,exception)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G l o b E x p r e s s i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GlobExpression() returns MagickTrue if the expression matches the pattern. % % The format of the GlobExpression function is: % % MagickBooleanType GlobExpression(const char *expression, % const char *pattern) % % A description of each parameter follows: % % o expression: Specifies a pointer to a text string containing a file name. % % o pattern: Specifies a pointer to a text string containing a pattern. % % */ MagickExport MagickBooleanType GlobExpression(const char *expression, const char *pattern) { MagickBooleanType done; register const char *p; /* Return on empty pattern or '*'. */ if (pattern == (char *) NULL) return(MagickTrue); if (*pattern == '\0') return(MagickTrue); if (LocaleCompare(pattern,"*") == 0) return(MagickTrue); p=pattern+strlen(pattern)-1; if ((*p == ']') && (strchr(pattern,'[') != (char *) NULL)) { ExceptionInfo exception; ImageInfo *image_info; /* Determine if pattern is a scene, i.e. img0001.pcd[2]. */ image_info=CloneImageInfo((ImageInfo *) NULL); (void) CopyMagickString(image_info->filename,pattern,MaxTextExtent); GetExceptionInfo(&exception); (void) SetImageInfo(image_info,MagickTrue,&exception); DestroyExceptionInfo(&exception); if (LocaleCompare(image_info->filename,pattern) != 0) { image_info=DestroyImageInfo(image_info); return(MagickFalse); } image_info=DestroyImageInfo(image_info); } /* Evaluate glob expression. */ done=MagickFalse; while ((*pattern != '\0') && (done == MagickFalse)) { if (*expression == '\0') if ((*pattern != '{') && (*pattern != '*')) break; switch (*pattern) { case '\\': { pattern++; if (*pattern != '\0') pattern++; break; } case '*': { MagickBooleanType status; pattern++; status=MagickFalse; while ((*expression != '\0') && (status == MagickFalse)) status=GlobExpression(expression++,pattern); if (status != MagickFalse) { while (*expression != '\0') expression++; while (*pattern != '\0') pattern++; } break; } case '[': { char c; pattern++; for ( ; ; ) { if ((*pattern == '\0') || (*pattern == ']')) { done=MagickTrue; break; } if (*pattern == '\\') { pattern++; if (*pattern == '\0') { done=MagickTrue; break; } } if (*(pattern+1) == '-') { c=(*pattern); pattern+=2; if (*pattern == ']') { done=MagickTrue; break; } if (*pattern == '\\') { pattern++; if (*pattern == '\0') { done=MagickTrue; break; } } if ((*expression < c) || (*expression > *pattern)) { pattern++; continue; } } else if (*pattern != *expression) { pattern++; continue; } pattern++; while ((*pattern != ']') && (*pattern != '\0')) { if ((*pattern == '\\') && (*(pattern+1) != '\0')) pattern++; pattern++; } if (*pattern != '\0') { pattern++; expression++; } break; } break; } case '?': { pattern++; expression++; break; } case '{': { MagickBooleanType match; register const char *p; pattern++; while ((*pattern != '}') && (*pattern != '\0')) { p=expression; match=MagickTrue; while ((*p != '\0') && (*pattern != '\0') && (*pattern != ',') && (*pattern != '}') && (match != MagickFalse)) { if (*pattern == '\\') pattern++; match=(MagickBooleanType) (*pattern == *p); p++; pattern++; } if (*pattern == '\0') { match=MagickFalse; done=MagickTrue; break; } else if (match != MagickFalse) { expression=p; while ((*pattern != '}') && (*pattern != '\0')) { pattern++; if (*pattern == '\\') { pattern++; if (*pattern == '}') pattern++; } } } else { while ((*pattern != '}') && (*pattern != ',') && (*pattern != '\0')) { pattern++; if (*pattern == '\\') { pattern++; if ((*pattern == '}') || (*pattern == ',')) pattern++; } } } if (*pattern != '\0') pattern++; } break; } default: { if (*expression != *pattern) done=MagickTrue; else { expression++; pattern++; } } } } while (*pattern == '*') pattern++; return((MagickBooleanType) ((*expression == '\0') && (*pattern == '\0'))); }
static MagickBooleanType WriteXTRNImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { Image * p; ImageInfo *clone_info; int scene; MagickBooleanType status; void *param1, *param2, *param3; param1 = param2 = param3 = (void *) NULL; status=MagickTrue; if (LocaleCompare(image_info->magick,"XTRNFILE") == 0) { clone_info=CloneImageInfo(image_info); *clone_info->magick='\0'; status=WriteImage(clone_info,image,exception); if (status == MagickFalse) CatchImageException(image); clone_info=DestroyImageInfo(clone_info); } else if (LocaleCompare(image_info->magick,"XTRNIMAGE") == 0) { Image **image_ptr; ImageInfo **image_info_ptr; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%lx",¶m1,¶m2); image_info_ptr=(ImageInfo **) param1; image_ptr=(Image **) param2; if ((image_info_ptr != (ImageInfo **) NULL) && (image_ptr != (Image **) NULL)) { *image_ptr=CloneImage(image,0,0,MagickFalse,exception); *image_info_ptr=clone_info; } } } else if (LocaleCompare(image_info->magick,"XTRNBLOB") == 0) { char **blob_data; size_t *blob_length; char filename[MagickPathExtent]; clone_info=CloneImageInfo(image_info); if (clone_info->filename[0]) { (void) sscanf(clone_info->filename,"%lx,%lx,%2048s", ¶m1,¶m2,filename); blob_data=(char **) param1; blob_length=(size_t *) param2; scene = 0; (void) CopyMagickString(clone_info->filename,filename, MagickPathExtent); for (p=image; p != (Image *) NULL; p=GetNextImageInList(p)) { (void) CopyMagickString(p->filename,filename,MagickPathExtent); p->scene=scene++; } SetImageInfo(clone_info,1,exception); (void) CopyMagickString(image->magick,clone_info->magick, MagickPathExtent); if (*blob_length == 0) *blob_length=8192; *blob_data=(char *) ImageToBlob(clone_info,image,blob_length, exception); if (*blob_data == NULL) status=MagickFalse; if (status == MagickFalse) CatchImageException(image); } clone_info=DestroyImageInfo(clone_info); } else if (LocaleCompare(image_info->magick,"XTRNARRAY") == 0) { char filename[MagickPathExtent]; size_t blob_length; unsigned char *blob_data; clone_info=CloneImageInfo(image_info); if (*clone_info->filename != '\0') { (void) sscanf(clone_info->filename,"%lx,%2048s",¶m1,filename); image->client_data=param1; scene=0; (void) CopyMagickString(clone_info->filename,filename, MagickPathExtent); for (p=image; p != (Image *) NULL; p=GetNextImageInList(p)) { (void) CopyMagickString(p->filename,filename,MagickPathExtent); p->scene=scene++; } SetImageInfo(clone_info,1,exception); (void) CopyMagickString(image->magick,clone_info->magick, MagickPathExtent); blob_data=ImageToBlob(clone_info,image,&blob_length, exception); if (blob_data == (unsigned char *) NULL) status=MagickFalse; else SafeArrayFifo(image,blob_data,blob_length); if (status == MagickFalse) CatchImageException(image); } clone_info=DestroyImageInfo(clone_info); } return(MagickTrue); }
static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception) { #define MaxBufferExtent 8192 char filename[MaxTextExtent]; FILE *file; Image *image; ImageInfo *read_info; int unique_file; image=(Image *) NULL; read_info=CloneImageInfo(image_info); SetImageInfoBlob(read_info,(void *) NULL,0); file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(read_info->filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file == -1) || (file == (FILE *) NULL)) { ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile", read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } (void) CopyMagickString(filename,image_info->magick,MaxTextExtent); (void) ConcatenateMagickString(filename,":",MaxTextExtent); LocaleLower(filename); (void) ConcatenateMagickString(filename,image_info->filename,MaxTextExtent); if (LocaleCompare(read_info->magick,"file") == 0) { (void) RelinquishUniqueFileResource(read_info->filename); unique_file=(-1); (void) CopyMagickString(read_info->filename,image_info->filename+2, MaxTextExtent); } #if defined(MAGICKCORE_WINDOWS_SUPPORT) && \ !(defined(__MINGW32__) || defined(__MINGW64__)) (void) fclose(file); if (URLDownloadToFile(NULL,filename,read_info->filename,0,NULL) != S_OK) { ThrowFileException(exception,FileOpenError,"UnableToOpenFile", filename); (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } #else #if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED) if (LocaleCompare(read_info->magick,"ftp") == 0) { void *context; xmlNanoFTPInit(); context=xmlNanoFTPNewCtxt(filename); if (context != (void *) NULL) { if (xmlNanoFTPConnect(context) >= 0) (void) xmlNanoFTPGet(context,GetFTPData,(void *) file, (char *) NULL); (void) xmlNanoFTPClose(context); } } #endif #if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED) if (LocaleCompare(read_info->magick,"http") == 0) { char buffer[MaxBufferExtent], *type; int bytes; void *context; type=(char *) NULL; context=xmlNanoHTTPMethod(filename,(const char *) NULL, (const char *) NULL,&type,(const char *) NULL,0); if (context != (void *) NULL) { ssize_t count; while ((bytes=xmlNanoHTTPRead(context,buffer,MaxBufferExtent)) > 0) count=(ssize_t) fwrite(buffer,bytes,1,file); (void) count; xmlNanoHTTPClose(context); xmlFree(type); xmlNanoHTTPCleanup(); } } #endif (void) fclose(file); #endif { ExceptionInfo *sans; ImageInfo *clone_info; /* Guess image format from URL. */ clone_info=CloneImageInfo(image_info); sans=AcquireExceptionInfo(); (void) SetImageInfo(clone_info,0,sans); (void) CopyMagickString(read_info->magick,clone_info->magick,MaxTextExtent); clone_info=DestroyImageInfo(clone_info); sans=DestroyExceptionInfo(sans); } image=ReadImage(read_info,exception); if (unique_file != -1) (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); if (image != (Image *) NULL) GetPathComponent(image_info->filename,TailPath,image->filename); else { (void) ThrowMagickException(exception,GetMagickModule(),CoderError, "NoDataReturned","`%s'",filename); return((Image *) NULL); } return(GetFirstImageInList(image)); }
static MagickBooleanType WriteHISTOGRAMImage(const ImageInfo *image_info, Image *image) { #define HistogramDensity "256x200" ChannelType channel; char filename[MaxTextExtent]; ExceptionInfo *exception; FILE *file; Image *histogram_image; ImageInfo *write_info; int unique_file; long y; MagickBooleanType status; MagickPixelPacket *histogram; MagickRealType maximum, scale; RectangleInfo geometry; register const PixelPacket *p; register long x; register PixelPacket *q, *r; size_t length; /* Allocate histogram image. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); SetGeometry(image,&geometry); if (image_info->density == (char *) NULL) (void) ParseAbsoluteGeometry(HistogramDensity,&geometry); else (void) ParseAbsoluteGeometry(image_info->density,&geometry); histogram_image=CloneImage(image,geometry.width,geometry.height,MagickTrue, &image->exception); if (histogram_image == (Image *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) SetImageStorageClass(histogram_image,DirectClass); /* Allocate histogram count arrays. */ length=MagickMax((size_t) ScaleQuantumToChar((Quantum) QuantumRange)+1UL, histogram_image->columns); histogram=(MagickPixelPacket *) AcquireQuantumMemory(length, sizeof(*histogram)); if (histogram == (MagickPixelPacket *) NULL) { histogram_image=DestroyImage(histogram_image); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } /* Initialize histogram count arrays. */ channel=image_info->channel; (void) ResetMagickMemory(histogram,0,length*sizeof(*histogram)); for (y=0; y < (long) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if ((channel & RedChannel) != 0) histogram[ScaleQuantumToChar(p->red)].red++; if ((channel & GreenChannel) != 0) histogram[ScaleQuantumToChar(p->green)].green++; if ((channel & BlueChannel) != 0) histogram[ScaleQuantumToChar(p->blue)].blue++; p++; } } maximum=histogram[0].red; for (x=0; x < (long) histogram_image->columns; x++) { if (((channel & RedChannel) != 0) && (maximum < histogram[x].red)) maximum=histogram[x].red; if (((channel & GreenChannel) != 0) && (maximum < histogram[x].green)) maximum=histogram[x].green; if (((channel & BlueChannel) != 0) && (maximum < histogram[x].blue)) maximum=histogram[x].blue; } scale=(MagickRealType) histogram_image->rows/maximum; /* Initialize histogram image. */ exception=(&image->exception); (void) QueryColorDatabase("#000000",&histogram_image->background_color, &image->exception); (void) SetImageBackgroundColor(histogram_image); for (x=0; x < (long) histogram_image->columns; x++) { q=GetAuthenticPixels(histogram_image,x,0,1,histogram_image->rows,exception); if (q == (PixelPacket *) NULL) break; if ((channel & RedChannel) != 0) { y=(long) (histogram_image->rows-scale*histogram[x].red+0.5); r=q+y; for ( ; y < (long) histogram_image->rows; y++) { r->red=(Quantum) QuantumRange; r++; } } if ((channel & GreenChannel) != 0) { y=(long) (histogram_image->rows-scale*histogram[x].green+0.5); r=q+y; for ( ; y < (long) histogram_image->rows; y++) { r->green=(Quantum) QuantumRange; r++; } } if ((channel & BlueChannel) != 0) { y=(long) (histogram_image->rows-scale*histogram[x].blue+0.5); r=q+y; for ( ; y < (long) histogram_image->rows; y++) { r->blue=(Quantum) QuantumRange; r++; } } if (SyncAuthenticPixels(histogram_image,exception) == MagickFalse) break; status=SetImageProgress(image,SaveImageTag,y,histogram_image->rows); if (status == MagickFalse) break; } /* Relinquish resources. */ histogram=(MagickPixelPacket *) RelinquishMagickMemory(histogram); file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file != -1) && (file != (FILE *) NULL)) { char *property; /* Add a histogram as an image comment. */ (void) GetNumberColors(image,file,&image->exception); (void) fclose(file); property=FileToString(filename,~0UL,&image->exception); if (property != (char *) NULL) { (void) SetImageProperty(histogram_image,"comment",property); property=DestroyString(property); } } (void) RelinquishUniqueFileResource(filename); /* Write Histogram image. */ (void) CopyMagickString(histogram_image->filename,image_info->filename, MaxTextExtent); write_info=CloneImageInfo(image_info); (void) SetImageInfo(write_info,MagickTrue,&image->exception); if (LocaleCompare(write_info->magick,"HISTOGRAM") == 0) (void) FormatMagickString(histogram_image->filename,MaxTextExtent, "miff:%s",write_info->filename); status=WriteImage(write_info,histogram_image); histogram_image=DestroyImage(histogram_image); write_info=DestroyImageInfo(write_info); return(status); }
MagickExport unsigned int InvokeDelegate(ImageInfo *image_info,Image *image, const char *decode,const char *encode,ExceptionInfo *exception) { char *command, **commands, filename[MaxTextExtent]; const DelegateInfo *delegate_info; register long i; unsigned int status, temporary_image_filename; /* Get delegate. */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); temporary_image_filename=(*image->filename == '\0'); if (temporary_image_filename) { /* Allocate a temporary filename if image is unnamed. */ if(!AcquireTemporaryFileName(image->filename)) { (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image->filename); return(False); } } (void) strlcpy(filename,image->filename,MaxTextExtent); delegate_info=GetDelegateInfo(decode,encode,exception); if (delegate_info == (DelegateInfo *) NULL) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,DelegateError,NoTagFound, decode ? decode : encode); return(False); } if (*image_info->filename == '\0') { /* ReadImage will normally have already set image_info->filename to the name of a temporary file. If not, then assign one. Setting image_info->temporary to True indicates that there is a temporary file to be removed later. */ if(!AcquireTemporaryFileName(image_info->filename)) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->filename); return(False); } image_info->temporary=True; } if (delegate_info->mode != 0) if ((decode && (delegate_info->encode != (char *) NULL)) || (encode && (delegate_info->decode != (char *) NULL))) { char decode_filename[MaxTextExtent], *magick; ImageInfo *clone_info; register Image *p; /* Delegate requires a particular image format. */ if (!AcquireTemporaryFileName(image_info->unique)) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->unique); return(False); } if (!AcquireTemporaryFileName(image_info->zero)) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) LiberateTemporaryFile(image_info->unique); (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->zero); return(False); } /* Expand sprintf-style codes in delegate command to command string */ magick=TranslateText(image_info,image,decode != (char *) NULL ? delegate_info->encode : delegate_info->decode); if (magick == (char *) NULL) { (void) LiberateTemporaryFile(image_info->unique); (void) LiberateTemporaryFile(image_info->zero); if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,DelegateError,DelegateFailed, decode ? decode : encode); return(False); } LocaleUpper(magick); clone_info=CloneImageInfo(image_info); (void) strlcpy((char *) clone_info->magick,magick,MaxTextExtent); (void) strlcpy(image->magick,magick,MaxTextExtent); MagickFreeMemory(magick); (void) strlcpy(decode_filename,image->filename,MaxTextExtent); FormatString(clone_info->filename,"%.1024s:",delegate_info->decode); (void) SetImageInfo(clone_info,True,exception); (void) strlcpy(clone_info->filename,image_info->filename, MaxTextExtent); for (p=image; p != (Image *) NULL; p=p->next) { FormatString(p->filename,"%.1024s:%.1024s",delegate_info->decode, decode_filename); status=WriteImage(clone_info,p); if (status == False) { (void) LiberateTemporaryFile(image_info->unique); (void) LiberateTemporaryFile(image_info->zero); if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); DestroyImageInfo(clone_info); (void) ThrowException(exception,DelegateError,DelegateFailed, decode ? decode : encode); return(False); } if (clone_info->adjoin) break; } (void) LiberateTemporaryFile(image_info->unique); (void) LiberateTemporaryFile(image_info->zero); DestroyImageInfo(clone_info); } /* Invoke delegate. */ (void) strlcpy(image->filename,filename,MaxTextExtent); commands=StringToList(delegate_info->commands); if (commands == (char **) NULL) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,decode ? decode : encode); return(False); } command=(char *) NULL; status=True; /* For each delegate command ... */ for (i=0; commands[i] != (char *) NULL; i++) { status=True; /* Allocate convenience temporary files */ if (!AcquireTemporaryFileName(image_info->unique)) { (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->unique); status=False; goto error_exit; } if (!AcquireTemporaryFileName(image_info->zero)) { (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->zero); (void) LiberateTemporaryFile(image_info->unique); status=False; goto error_exit; } #if defined(POSIX) { MagickBool needs_shell; /* Check to see if command template must be executed via shell due to using constructs requiring multiple processes or I/O redirection. */ needs_shell = MagickFalse; { char * p; p = commands[i]; for (p = commands[i]; *p; p++) { if (('&' == *p) || (';' == *p) || ('<' == *p) || ('>' == *p) || ('|' == *p)) { needs_shell = MagickTrue; break; } } } if (MagickFalse == needs_shell) { int arg_count, j; char **arg_array; /* Convert command template into an argument array. Translate each argument array element individually in order to absolutely avoid any possibility that the number of arguments may be altered due to substituted data. */ arg_array = StringToArgv(commands[i],&arg_count); for (j = 0; arg_array[j] != (const char*) NULL; j++) { if (strchr(arg_array[j], '%') != (const char*) NULL) { char *expanded = TranslateText(image_info,image,arg_array[j]); if (expanded != (char *) NULL) { MagickFreeMemory(arg_array[j]); arg_array[j] = expanded; } } } /* Execute delegate using our secure "spawn" facility. */ status = MagickSpawnVP(image_info->verbose,arg_array[1],arg_array+1); } else { /* Expand sprintf-style codes in delegate command to command string, escaping replacement text appropriately */ command=TranslateTextEx(image_info,image,commands[i],UnixShellTextEscape); if (command == (char *) NULL) break; /* Execute delegate using command shell. */ status=SystemCommand(image_info->verbose,command); } } #else { /* Expand sprintf-style codes in delegate command to command string */ command=TranslateText(image_info,image,commands[i]); if (command == (char *) NULL) break; /* Execute delegate using command shell. */ status=SystemCommand(image_info->verbose,command); } #endif MagickFreeMemory(command); /* Liberate convenience temporary files */ (void) LiberateTemporaryFile(image_info->unique); (void) LiberateTemporaryFile(image_info->zero); if (status != False) { (void) ThrowException(exception,DelegateError,DelegateFailed, commands[i]); goto error_exit; } MagickFreeMemory(commands[i]); } /* Free resources. */ error_exit: if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); for ( ; commands[i] != (char *) NULL; i++) MagickFreeMemory(commands[i]); MagickFreeMemory(commands); return(status != False); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e I m a g e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteImages() writes an image sequence into one or more files. While % WriteImage() can write an image sequence, it is limited to writing % the sequence into a single file using a format which supports multiple % frames. WriteImages(), however, does not have this limitation, instead it % generates multiple output files if necessary (or when requested). When % ImageInfo's adjoin flag is set to MagickFalse, the file name is expected % to include a printf-style formatting string for the frame number (e.g. % "image%02d.png"). % % The format of the WriteImages method is: % % MagickBooleanType WriteImages(const ImageInfo *image_info,Image *images, % const char *filename,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o images: the image list. % % o filename: the image filename. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType WriteImages(const ImageInfo *image_info, Image *images,const char *filename,ExceptionInfo *exception) { #define WriteImageTag "Write/Image" BlobInfo *blob; ExceptionInfo *sans_exception; ImageInfo *write_info; MagickBooleanType proceed; MagickOffsetType i; MagickProgressMonitor progress_monitor; MagickSizeType number_images; MagickStatusType status; register Image *p; assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(images != (Image *) NULL); assert(images->signature == MagickSignature); if (images->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); assert(exception != (ExceptionInfo *) NULL); write_info=CloneImageInfo(image_info); images=GetFirstImageInList(images); blob=CloneBlobInfo(images->blob); /* thread specific I/O handler */ DestroyBlob(images); images->blob=blob; if (filename != (const char *) NULL) for (p=images; p != (Image *) NULL; p=GetNextImageInList(p)) (void) CopyMagickString(p->filename,filename,MaxTextExtent); (void) CopyMagickString(write_info->filename,images->filename,MaxTextExtent); if (*write_info->magick == '\0') (void) CopyMagickString(write_info->magick,images->magick,MaxTextExtent); sans_exception=AcquireExceptionInfo(); (void) SetImageInfo(write_info,(unsigned int) GetImageListLength(images), sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); p=images; for ( ; GetNextImageInList(p) != (Image *) NULL; p=GetNextImageInList(p)) if (p->scene >= GetNextImageInList(p)->scene) { register ssize_t i; /* Generate consistent scene numbers. */ i=(ssize_t) images->scene; for (p=images; p != (Image *) NULL; p=GetNextImageInList(p)) p->scene=(size_t) i++; break; } /* Write images. */ status=MagickTrue; progress_monitor=(MagickProgressMonitor) NULL; i=0; number_images=GetImageListLength(images); for (p=images; p != (Image *) NULL; p=GetNextImageInList(p)) { if (number_images != 1) progress_monitor=SetImageProgressMonitor(p,(MagickProgressMonitor) NULL, p->client_data); status&=WriteImage(write_info,p,exception); if (number_images != 1) (void) SetImageProgressMonitor(p,progress_monitor,p->client_data); if (write_info->adjoin != MagickFalse) break; if (number_images != 1) { proceed=SetImageProgress(p,WriteImageTag,i++,number_images); if (proceed == MagickFalse) break; } } write_info=DestroyImageInfo(write_info); return(status != 0 ? MagickTrue : MagickFalse); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadImage() reads an image or image sequence from a file or file handle. % The method returns a NULL if there is a memory shortage or if the image % cannot be read. On failure, a NULL image is returned and exception % describes the reason for the failure. % % The format of the ReadImage method is: % % Image *ReadImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: Read the image defined by the file or filename members of % this structure. % % o exception: return any errors or warnings in this structure. % */ MagickExport Image *ReadImage(const ImageInfo *image_info, ExceptionInfo *exception) { char filename[MaxTextExtent], magick[MaxTextExtent], magick_filename[MaxTextExtent]; const char *value; const DelegateInfo *delegate_info; const MagickInfo *magick_info; ExceptionInfo *sans_exception; GeometryInfo geometry_info; Image *image, *next; ImageInfo *read_info; MagickStatusType flags, thread_support; PolicyDomain domain; PolicyRights rights; /* Determine image type from filename prefix or suffix (e.g. image.jpg). */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image_info->filename != (char *) NULL); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); read_info=CloneImageInfo(image_info); (void) CopyMagickString(magick_filename,read_info->filename,MaxTextExtent); (void) SetImageInfo(read_info,0,exception); (void) CopyMagickString(filename,read_info->filename,MaxTextExtent); (void) CopyMagickString(magick,read_info->magick,MaxTextExtent); domain=CoderPolicyDomain; rights=ReadPolicyRights; if (IsRightsAuthorized(domain,rights,read_info->magick) == MagickFalse) { errno=EPERM; (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, "NotAuthorized","`%s'",read_info->filename); return((Image *) NULL); } /* Call appropriate image reader based on image type. */ sans_exception=AcquireExceptionInfo(); magick_info=GetMagickInfo(read_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (magick_info != (const MagickInfo *) NULL) { if (GetMagickEndianSupport(magick_info) == MagickFalse) read_info->endian=UndefinedEndian; else if ((image_info->endian == UndefinedEndian) && (GetMagickRawSupport(magick_info) != MagickFalse)) { size_t lsb_first; lsb_first=1; read_info->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian; } } if ((magick_info != (const MagickInfo *) NULL) && (GetMagickSeekableStream(magick_info) != MagickFalse)) { MagickBooleanType status; image=AcquireImage(read_info,exception); (void) CopyMagickString(image->filename,read_info->filename, MaxTextExtent); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { read_info=DestroyImageInfo(read_info); image=DestroyImage(image); return((Image *) NULL); } if (IsBlobSeekable(image) == MagickFalse) { /* Coder requires a seekable stream. */ *read_info->filename='\0'; status=ImageToFile(image,read_info->filename,exception); if (status == MagickFalse) { (void) CloseBlob(image); read_info=DestroyImageInfo(read_info); image=DestroyImage(image); return((Image *) NULL); } read_info->temporary=MagickTrue; } (void) CloseBlob(image); image=DestroyImage(image); } image=NewImageList(); if (constitute_semaphore == (SemaphoreInfo *) NULL) AcquireSemaphoreInfo(&constitute_semaphore); if ((magick_info != (const MagickInfo *) NULL) && (GetImageDecoder(magick_info) != (DecodeImageHandler *) NULL)) { thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & DecoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); image=GetImageDecoder(magick_info)(read_info,exception); if ((thread_support & DecoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } else { delegate_info=GetDelegateInfo(read_info->magick,(char *) NULL,exception); if (delegate_info == (const DelegateInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", read_info->filename); if (read_info->temporary != MagickFalse) (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } /* Let our decoding delegate process the image. */ image=AcquireImage(read_info,exception); if (image == (Image *) NULL) { read_info=DestroyImageInfo(read_info); return((Image *) NULL); } (void) CopyMagickString(image->filename,read_info->filename, MaxTextExtent); *read_info->filename='\0'; if (GetDelegateThreadSupport(delegate_info) == MagickFalse) LockSemaphoreInfo(constitute_semaphore); (void) InvokeDelegate(read_info,image,read_info->magick,(char *) NULL, exception); if (GetDelegateThreadSupport(delegate_info) == MagickFalse) UnlockSemaphoreInfo(constitute_semaphore); image=DestroyImageList(image); read_info->temporary=MagickTrue; (void) SetImageInfo(read_info,0,exception); magick_info=GetMagickInfo(read_info->magick,exception); if ((magick_info == (const MagickInfo *) NULL) || (GetImageDecoder(magick_info) == (DecodeImageHandler *) NULL)) { if (IsPathAccessible(read_info->filename) != MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", read_info->filename); else ThrowFileException(exception,FileOpenError,"UnableToOpenFile", read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & DecoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); image=(Image *) (GetImageDecoder(magick_info))(read_info,exception); if ((thread_support & DecoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } if (read_info->temporary != MagickFalse) { (void) RelinquishUniqueFileResource(read_info->filename); read_info->temporary=MagickFalse; if (image != (Image *) NULL) (void) CopyMagickString(image->filename,filename,MaxTextExtent); } if (image == (Image *) NULL) { read_info=DestroyImageInfo(read_info); return(image); } if (exception->severity >= ErrorException) (void) LogMagickEvent(ExceptionEvent,GetMagickModule(), "Coder (%s) generated an image despite an error (%d), " "notify the developers",image->magick,exception->severity); if (IsBlobTemporary(image) != MagickFalse) (void) RelinquishUniqueFileResource(read_info->filename); if ((GetNextImageInList(image) != (Image *) NULL) && (IsSceneGeometry(read_info->scenes,MagickFalse) != MagickFalse)) { Image *clones; clones=CloneImages(image,read_info->scenes,exception); if (clones == (Image *) NULL) (void) ThrowMagickException(exception,GetMagickModule(),OptionError, "SubimageSpecificationReturnsNoImages","`%s'",read_info->filename); else { image=DestroyImageList(image); image=GetFirstImageInList(clones); } } if (GetBlobError(image) != MagickFalse) { ThrowFileException(exception,FileOpenError, "AnErrorHasOccurredReadingFromFile",read_info->filename); image=DestroyImageList(image); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } for (next=image; next != (Image *) NULL; next=GetNextImageInList(next)) { char magick_path[MaxTextExtent], *property, timestamp[MaxTextExtent]; const char *option; const StringInfo *profile; next->taint=MagickFalse; GetPathComponent(magick_filename,MagickPath,magick_path); if (*magick_path == '\0') (void) CopyMagickString(next->magick,magick,MaxTextExtent); (void) CopyMagickString(next->magick_filename,magick_filename, MaxTextExtent); if (IsBlobTemporary(image) != MagickFalse) (void) CopyMagickString(next->filename,filename,MaxTextExtent); if (next->magick_columns == 0) next->magick_columns=next->columns; if (next->magick_rows == 0) next->magick_rows=next->rows; value=GetImageProperty(next,"tiff:Orientation",exception); if (value == (char *) NULL) value=GetImageProperty(next,"exif:Orientation",exception); if (value != (char *) NULL) { next->orientation=(OrientationType) StringToLong(value); (void) DeleteImageProperty(next,"tiff:Orientation"); (void) DeleteImageProperty(next,"exif:Orientation"); } value=GetImageProperty(next,"exif:XResolution",exception); if (value != (char *) NULL) { geometry_info.rho=next->resolution.x; geometry_info.sigma=1.0; flags=ParseGeometry(value,&geometry_info); if (geometry_info.sigma != 0) next->resolution.x=geometry_info.rho/geometry_info.sigma; (void) DeleteImageProperty(next,"exif:XResolution"); } value=GetImageProperty(next,"exif:YResolution",exception); if (value != (char *) NULL) { geometry_info.rho=next->resolution.y; geometry_info.sigma=1.0; flags=ParseGeometry(value,&geometry_info); if (geometry_info.sigma != 0) next->resolution.y=geometry_info.rho/geometry_info.sigma; (void) DeleteImageProperty(next,"exif:YResolution"); } value=GetImageProperty(next,"tiff:ResolutionUnit",exception); if (value == (char *) NULL) value=GetImageProperty(next,"exif:ResolutionUnit",exception); if (value != (char *) NULL) { next->units=(ResolutionType) (StringToLong(value)-1); (void) DeleteImageProperty(next,"exif:ResolutionUnit"); (void) DeleteImageProperty(next,"tiff:ResolutionUnit"); } if (next->page.width == 0) next->page.width=next->columns; if (next->page.height == 0) next->page.height=next->rows; option=GetImageOption(read_info,"caption"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"caption",property,exception); property=DestroyString(property); } option=GetImageOption(read_info,"comment"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"comment",property,exception); property=DestroyString(property); } option=GetImageOption(read_info,"label"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"label",property,exception); property=DestroyString(property); } if (LocaleCompare(next->magick,"TEXT") == 0) (void) ParseAbsoluteGeometry("0x0+0+0",&next->page); if ((read_info->extract != (char *) NULL) && (read_info->stream == (StreamHandler) NULL)) { RectangleInfo geometry; flags=ParseAbsoluteGeometry(read_info->extract,&geometry); if ((next->columns != geometry.width) || (next->rows != geometry.height)) { if (((flags & XValue) != 0) || ((flags & YValue) != 0)) { Image *crop_image; crop_image=CropImage(next,&geometry,exception); if (crop_image != (Image *) NULL) ReplaceImageInList(&next,crop_image); } else if (((flags & WidthValue) != 0) || ((flags & HeightValue) != 0)) { Image *size_image; flags=ParseRegionGeometry(next,read_info->extract,&geometry, exception); size_image=ResizeImage(next,geometry.width,geometry.height, next->filter,next->blur,exception); if (size_image != (Image *) NULL) ReplaceImageInList(&next,size_image); } } } profile=GetImageProfile(next,"icc"); if (profile == (const StringInfo *) NULL) profile=GetImageProfile(next,"icm"); profile=GetImageProfile(next,"iptc"); if (profile == (const StringInfo *) NULL) profile=GetImageProfile(next,"8bim"); (void) FormatMagickTime(GetBlobProperties(next)->st_mtime,MaxTextExtent, timestamp); (void) SetImageProperty(next,"date:modify",timestamp,exception); (void) FormatMagickTime(GetBlobProperties(next)->st_ctime,MaxTextExtent, timestamp); (void) SetImageProperty(next,"date:create",timestamp,exception); option=GetImageOption(image_info,"delay"); if (option != (const char *) NULL) { GeometryInfo geometry_info; flags=ParseGeometry(option,&geometry_info); if ((flags & GreaterValue) != 0) { if (next->delay > (size_t) floor(geometry_info.rho+0.5)) next->delay=(size_t) floor(geometry_info.rho+0.5); } else if ((flags & LessValue) != 0) { if (next->delay < (size_t) floor(geometry_info.rho+0.5)) next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5); } else next->delay=(size_t) floor(geometry_info.rho+0.5); if ((flags & SigmaValue) != 0) next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5); } option=GetImageOption(image_info,"dispose"); if (option != (const char *) NULL) next->dispose=(DisposeType) ParseCommandOption(MagickDisposeOptions, MagickFalse,option); if (read_info->verbose != MagickFalse) (void) IdentifyImage(next,stderr,MagickFalse,exception); image=next; } read_info=DestroyImageInfo(read_info); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e I N L I N E I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteINLINEImage() writes an image to a file in INLINE format (Base64). % % The format of the WriteINLINEImage method is: % % MagickBooleanType WriteINLINEImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteINLINEImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { char *base64, message[MagickPathExtent]; const MagickInfo *magick_info; Image *write_image; ImageInfo *write_info; MagickBooleanType status; size_t blob_length, encode_length; unsigned char *blob; /* Convert image to base64-encoding. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); write_info=CloneImageInfo(image_info); (void) SetImageInfo(write_info,1,exception); if (LocaleCompare(write_info->magick,"INLINE") == 0) (void) CopyMagickString(write_info->magick,image->magick,MagickPathExtent); magick_info=GetMagickInfo(write_info->magick,exception); if ((magick_info == (const MagickInfo *) NULL) || (GetMagickMimeType(magick_info) == (const char *) NULL)) ThrowWriterException(CorruptImageError,"ImageTypeNotSupported"); (void) CopyMagickString(image->filename,write_info->filename, MagickPathExtent); blob_length=2048; write_image=CloneImage(image,0,0,MagickTrue,exception); if (write_image == (Image *) NULL) { write_info=DestroyImageInfo(write_info); return(MagickTrue); } blob=(unsigned char *) ImageToBlob(write_info,write_image,&blob_length, exception); write_image=DestroyImage(write_image); write_info=DestroyImageInfo(write_info); if (blob == (unsigned char *) NULL) return(MagickFalse); encode_length=0; base64=Base64Encode(blob,blob_length,&encode_length); blob=(unsigned char *) RelinquishMagickMemory(blob); if (base64 == (char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Write base64-encoded image. */ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) { base64=DestroyString(base64); return(status); } (void) FormatLocaleString(message,MagickPathExtent,"data:%s;base64,", GetMagickMimeType(magick_info)); (void) WriteBlobString(image,message); (void) WriteBlobString(image,base64); base64=DestroyString(base64); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteImage() writes an image or an image sequence to a file or file handle. % If writing to a file is on disk, the name is defined by the filename member % of the image structure. WriteImage() returns MagickFalse is there is a % memory shortage or if the image cannot be written. Check the exception % member of image to determine the cause for any failure. % % The format of the WriteImage method is: % % MagickBooleanType WriteImage(const ImageInfo *image_info,Image *image, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o image: the image. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { char filename[MaxTextExtent]; const char *option; const DelegateInfo *delegate_info; const MagickInfo *magick_info; ExceptionInfo *sans_exception; ImageInfo *write_info; MagickBooleanType status, temporary; MagickStatusType thread_support; PolicyDomain domain; PolicyRights rights; /* Determine image type from filename prefix or suffix (e.g. image.jpg). */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); sans_exception=AcquireExceptionInfo(); write_info=CloneImageInfo(image_info); (void) CopyMagickString(write_info->filename,image->filename,MaxTextExtent); if (*write_info->magick == '\0') (void) CopyMagickString(write_info->magick,image->magick,MaxTextExtent); (void) SetImageInfo(write_info,1,sans_exception); if (LocaleCompare(write_info->magick,"clipmask") == 0) { if (image->clip_mask == (Image *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), OptionError,"NoClipPathDefined","`%s'",image->filename); return(MagickFalse); } image=image->clip_mask; (void) SetImageInfo(write_info,1,sans_exception); } (void) CopyMagickString(filename,image->filename,MaxTextExtent); (void) CopyMagickString(image->filename,write_info->filename,MaxTextExtent); domain=CoderPolicyDomain; rights=WritePolicyRights; if (IsRightsAuthorized(domain,rights,write_info->magick) == MagickFalse) { sans_exception=DestroyExceptionInfo(sans_exception); errno=EPERM; ThrowBinaryException(PolicyError,"NotAuthorized",filename); } magick_info=GetMagickInfo(write_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (magick_info != (const MagickInfo *) NULL) { if (GetMagickEndianSupport(magick_info) == MagickFalse) image->endian=UndefinedEndian; else if ((image_info->endian == UndefinedEndian) && (GetMagickRawSupport(magick_info) != MagickFalse)) { size_t lsb_first; lsb_first=1; image->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian; } } (void) SyncImageProfiles(image); option=GetImageOption(image_info,"delegate:bimodal"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse) && (write_info->page == (char *) NULL) && (GetPreviousImageInList(image) == (Image *) NULL) && (GetNextImageInList(image) == (Image *) NULL) && (IsTaintImage(image) == MagickFalse)) { delegate_info=GetDelegateInfo(image->magick,write_info->magick,exception); if ((delegate_info != (const DelegateInfo *) NULL) && (GetDelegateMode(delegate_info) == 0) && (IsPathAccessible(image->magick_filename) != MagickFalse)) { /* Process image with bi-modal delegate. */ (void) CopyMagickString(image->filename,image->magick_filename, MaxTextExtent); status=InvokeDelegate(write_info,image,image->magick, write_info->magick,exception); write_info=DestroyImageInfo(write_info); (void) CopyMagickString(image->filename,filename,MaxTextExtent); return(status); } } status=MagickFalse; temporary=MagickFalse; if ((magick_info != (const MagickInfo *) NULL) && (GetMagickSeekableStream(magick_info) != MagickFalse)) { char filename[MaxTextExtent]; (void) CopyMagickString(filename,image->filename,MaxTextExtent); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); (void) CopyMagickString(image->filename,filename,MaxTextExtent); if (status != MagickFalse) { if (IsBlobSeekable(image) == MagickFalse) { /* A seekable stream is required by the encoder. */ write_info->adjoin=MagickTrue; (void) CopyMagickString(write_info->filename,image->filename, MaxTextExtent); (void) AcquireUniqueFilename(image->filename); temporary=MagickTrue; } (void) CloseBlob(image); } } if (constitute_semaphore == (SemaphoreInfo *) NULL) AcquireSemaphoreInfo(&constitute_semaphore); if ((magick_info != (const MagickInfo *) NULL) && (GetImageEncoder(magick_info) != (EncodeImageHandler *) NULL)) { /* Call appropriate image writer based on image type. */ thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & EncoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); status=GetImageEncoder(magick_info)(write_info,image,exception); if ((thread_support & EncoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } else { delegate_info=GetDelegateInfo((char *) NULL,write_info->magick,exception); if (delegate_info != (DelegateInfo *) NULL) { /* Process the image with delegate. */ *write_info->filename='\0'; if (GetDelegateThreadSupport(delegate_info) == MagickFalse) LockSemaphoreInfo(constitute_semaphore); status=InvokeDelegate(write_info,image,(char *) NULL, write_info->magick,exception); if (GetDelegateThreadSupport(delegate_info) == MagickFalse) UnlockSemaphoreInfo(constitute_semaphore); (void) CopyMagickString(image->filename,filename,MaxTextExtent); } else { sans_exception=AcquireExceptionInfo(); magick_info=GetMagickInfo(write_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if ((write_info->affirm == MagickFalse) && (magick_info == (const MagickInfo *) NULL)) { (void) CopyMagickString(write_info->magick,image->magick, MaxTextExtent); magick_info=GetMagickInfo(write_info->magick,exception); } if ((magick_info == (const MagickInfo *) NULL) || (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL)) { char extension[MaxTextExtent]; GetPathComponent(image->filename,ExtensionPath,extension); if (*extension != '\0') magick_info=GetMagickInfo(extension,exception); else magick_info=GetMagickInfo(image->magick,exception); (void) CopyMagickString(image->filename,filename,MaxTextExtent); } if ((magick_info == (const MagickInfo *) NULL) || (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL)) (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'", image->filename); else { /* Call appropriate image writer based on image type. */ thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & EncoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); status=GetImageEncoder(magick_info)(write_info,image,exception); if ((thread_support & EncoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } } } if (GetBlobError(image) != MagickFalse) ThrowFileException(exception,FileOpenError, "AnErrorHasOccurredWritingToFile",image->filename); if (temporary == MagickTrue) { /* Copy temporary image file to permanent. */ status=OpenBlob(write_info,image,ReadBinaryBlobMode,exception); if (status != MagickFalse) status=ImageToFile(image,write_info->filename,exception); (void) CloseBlob(image); (void) RelinquishUniqueFileResource(image->filename); (void) CopyMagickString(image->filename,write_info->filename, MaxTextExtent); } if ((LocaleCompare(write_info->magick,"info") != 0) && (write_info->verbose != MagickFalse)) (void) IdentifyImage(image,stdout,MagickFalse,exception); write_info=DestroyImageInfo(write_info); return(status); }
/** * Return the imagelist as a blob (a String). * * Ruby usage: * - @verbatim ImageList#to_blob @endverbatim * * Notes: * - Runs an info parm block if present - the user can specify the image * format and depth * * @param self this object * @return the blob */ VALUE ImageList_to_blob(VALUE self) { Image *images, *image; Info *info; VALUE info_obj; VALUE blob_str; void *blob = NULL; size_t length = 0; ExceptionInfo *exception; info_obj = rm_info_new(); Data_Get_Struct(info_obj, Info, info); // Convert the images array to an images sequence. images = images_from_imagelist(self); exception = AcquireExceptionInfo(); (void) SetImageInfo(info, MagickTrue, exception); rm_check_exception(exception, images, RetainOnError); if (*info->magick != '\0') { Image *img; for (img = images; img; img = GetNextImageInList(img)) { strncpy(img->magick, info->magick, sizeof(info->magick)-1); } } for (image = images; image; image = GetNextImageInList(image)) { rm_sync_image_options(image, info); } // Unconditionally request multi-images support. The worst that // can happen is that there's only one image or the format // doesn't support multi-image files. info->adjoin = MagickTrue; blob = ImagesToBlob(info, images, &length, exception); if (blob && exception->severity >= ErrorException) { magick_free((void*)blob); blob = NULL; length = 0; } rm_split(images); CHECK_EXCEPTION() (void) DestroyExceptionInfo(exception); if (length == 0 || !blob) { return Qnil; } blob_str = rb_str_new(blob, (long)length); magick_free((void*)blob); RB_GC_GUARD(info_obj); RB_GC_GUARD(blob_str); return blob_str; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e T H U M B N A I L I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteTHUMBNAILImage() extracts the EXIF thumbnail image and writes it. % % The format of the WriteTHUMBNAILImage method is: % % MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { const char *property; const StringInfo *profile; Image *thumbnail_image; ImageInfo *write_info; MagickBooleanType status; register ssize_t i; size_t length; ssize_t offset; unsigned char magick[MaxTextExtent]; profile=GetImageProfile(image,"exif"); if (profile == (const StringInfo *) NULL) ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); property=GetImageProperty(image,"exif:JPEGInterchangeFormat",exception); if (property == (const char *) NULL) ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); offset=(ssize_t) StringToLong(property); property=GetImageProperty(image,"exif:JPEGInterchangeFormatLength",exception); if (property == (const char *) NULL) ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); length=(size_t) StringToLong(property); (void) ResetMagickMemory(magick,0,sizeof(magick)); for (i=0; i < (ssize_t) length; i++) { magick[0]=magick[1]; magick[1]=magick[2]; magick[2]=GetStringInfoDatum(profile)[offset+i]; if (memcmp(magick,"\377\330\377",3) == 0) break; } thumbnail_image=BlobToImage(image_info,GetStringInfoDatum(profile)+offset+i-2, length,exception); if (thumbnail_image == (Image *) NULL) return(MagickFalse); (void) SetImageType(thumbnail_image,thumbnail_image->alpha_trait != BlendPixelTrait ? TrueColorType : TrueColorMatteType,exception); (void) CopyMagickString(thumbnail_image->filename,image->filename, MaxTextExtent); write_info=CloneImageInfo(image_info); (void) SetImageInfo(write_info,1,exception); if (LocaleCompare(write_info->magick,"THUMBNAIL") == 0) (void) FormatLocaleString(thumbnail_image->filename,MaxTextExtent, "miff:%s",write_info->filename); status=WriteImage(write_info,thumbnail_image,exception); thumbnail_image=DestroyImage(thumbnail_image); write_info=DestroyImageInfo(write_info); return(status); }
/** * Write all the images to the specified file. If the file format supports * multi-image files, and the 'images' array contains more than one image, then * the images will be written as a single multi-image file. Otherwise each image * will be written to a separate file. * * Ruby usage: * - @verbatim ImageList#write(file) @endverbatim * * @param self this object * @param file the file * @return self */ VALUE ImageList_write(VALUE self, VALUE file) { Image *images, *img; Info *info; const MagickInfo *m; VALUE info_obj; unsigned long scene; ExceptionInfo *exception; info_obj = rm_info_new(); Data_Get_Struct(info_obj, Info, info); if (TYPE(file) == T_FILE) { OpenFile *fptr; // Ensure file is open - raise error if not GetOpenFile(file, fptr); #if defined(_WIN32) add_format_prefix(info, fptr->pathv); SetImageInfoFile(info, NULL); #else SetImageInfoFile(info, GetReadFile(fptr)); #endif } else { add_format_prefix(info, file); SetImageInfoFile(info, NULL); } // Convert the images array to an images sequence. images = images_from_imagelist(self); // Copy the filename into each image. Set a scene number to be used if // writing multiple files. (Ref: ImageMagick's utilities/convert.c for (scene = 0, img = images; img; img = GetNextImageInList(img)) { img->scene = scene++; strcpy(img->filename, info->filename); } // Find out if the format supports multi-images files. exception = AcquireExceptionInfo(); (void) SetImageInfo(info, MagickTrue, exception); rm_check_exception(exception, images, RetainOnError); m = GetMagickInfo(info->magick, exception); rm_check_exception(exception, images, RetainOnError); (void) DestroyExceptionInfo(exception); // Tell WriteImage if we want a multi-images file. if (imagelist_length(self) > 1L && m->adjoin) { info->adjoin = MagickTrue; } for (img = images; img; img = GetNextImageInList(img)) { rm_sync_image_options(img, info); (void) WriteImage(info, img); // images will be split before raising an exception rm_check_image_exception(images, RetainOnError); if (info->adjoin) { break; } } rm_split(images); RB_GC_GUARD(info_obj); return self; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e H I S T O G R A M I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteHISTOGRAMImage() writes an image to a file in Histogram format. % The image shows a histogram of the color (or gray) values in the image. The % image consists of three overlaid histograms: a red one for the red channel, % a green one for the green channel, and a blue one for the blue channel. The % image comment contains a list of unique pixel values and the number of times % each occurs in the image. % % This method is strongly based on a similar one written by % [email protected] which in turn is based on ppmhistmap of netpbm. % % The format of the WriteHISTOGRAMImage method is: % % MagickBooleanType WriteHISTOGRAMImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteHISTOGRAMImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { #define HistogramDensity "256x200" char filename[MagickPathExtent]; const char *option; Image *histogram_image; ImageInfo *write_info; MagickBooleanType status; PixelInfo *histogram; double maximum, scale; RectangleInfo geometry; register const Quantum *p; register Quantum *q, *r; register ssize_t x; size_t length; ssize_t y; /* Allocate histogram image. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); SetGeometry(image,&geometry); if (image_info->density == (char *) NULL) (void) ParseAbsoluteGeometry(HistogramDensity,&geometry); else (void) ParseAbsoluteGeometry(image_info->density,&geometry); histogram_image=CloneImage(image,geometry.width,geometry.height,MagickTrue, exception); if (histogram_image == (Image *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) SetImageStorageClass(histogram_image,DirectClass,exception); /* Allocate histogram count arrays. */ length=MagickMax((size_t) ScaleQuantumToChar(QuantumRange)+1UL, histogram_image->columns); histogram=(PixelInfo *) AcquireQuantumMemory(length,sizeof(*histogram)); if (histogram == (PixelInfo *) NULL) { histogram_image=DestroyImage(histogram_image); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } /* Initialize histogram count arrays. */ (void) ResetMagickMemory(histogram,0,length*sizeof(*histogram)); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) histogram[ScaleQuantumToChar(GetPixelRed(image,p))].red++; if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) histogram[ScaleQuantumToChar(GetPixelGreen(image,p))].green++; if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) histogram[ScaleQuantumToChar(GetPixelBlue(image,p))].blue++; p+=GetPixelChannels(image); } } maximum=histogram[0].red; for (x=0; x < (ssize_t) histogram_image->columns; x++) { if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) && (maximum < histogram[x].red)) maximum=histogram[x].red; if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) && (maximum < histogram[x].green)) maximum=histogram[x].green; if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) && (maximum < histogram[x].blue)) maximum=histogram[x].blue; } scale=0.0; if (fabs(maximum) >= MagickEpsilon) scale=(double) histogram_image->rows/maximum; /* Initialize histogram image. */ (void) QueryColorCompliance("#000000",AllCompliance, &histogram_image->background_color,exception); (void) SetImageBackgroundColor(histogram_image,exception); for (x=0; x < (ssize_t) histogram_image->columns; x++) { q=GetAuthenticPixels(histogram_image,x,0,1,histogram_image->rows,exception); if (q == (Quantum *) NULL) break; if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) { y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].red-0.5); r=q+y*GetPixelChannels(histogram_image); for ( ; y < (ssize_t) histogram_image->rows; y++) { SetPixelRed(histogram_image,QuantumRange,r); r+=GetPixelChannels(histogram_image); } } if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) { y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].green-0.5); r=q+y*GetPixelChannels(histogram_image); for ( ; y < (ssize_t) histogram_image->rows; y++) { SetPixelGreen(histogram_image,QuantumRange,r); r+=GetPixelChannels(histogram_image); } } if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) { y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].blue-0.5); r=q+y*GetPixelChannels(histogram_image); for ( ; y < (ssize_t) histogram_image->rows; y++) { SetPixelBlue(histogram_image,QuantumRange,r); r+=GetPixelChannels(histogram_image); } } if (SyncAuthenticPixels(histogram_image,exception) == MagickFalse) break; status=SetImageProgress(image,SaveImageTag,y,histogram_image->rows); if (status == MagickFalse) break; } histogram=(PixelInfo *) RelinquishMagickMemory(histogram); option=GetImageOption(image_info,"histogram:unique-colors"); if ((option == (const char *) NULL) || (IsStringTrue(option) != MagickFalse)) { FILE *file; int unique_file; /* Add a unique colors as an image comment. */ file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file != -1) && (file != (FILE *) NULL)) { char *property; (void) GetNumberColors(image,file,exception); (void) fclose(file); property=FileToString(filename,~0UL,exception); if (property != (char *) NULL) { (void) SetImageProperty(histogram_image,"comment",property, exception); property=DestroyString(property); } } (void) RelinquishUniqueFileResource(filename); } /* Write Histogram image. */ (void) CopyMagickString(histogram_image->filename,image_info->filename, MagickPathExtent); write_info=CloneImageInfo(image_info); *write_info->magick='\0'; (void) SetImageInfo(write_info,1,exception); if ((*write_info->magick == '\0') || (LocaleCompare(write_info->magick,"HISTOGRAM") == 0)) (void) FormatLocaleString(histogram_image->filename,MagickPathExtent, "miff:%s",write_info->filename); histogram_image->blob=DetachBlob(histogram_image->blob); histogram_image->blob=CloneBlobInfo(image->blob); status=WriteImage(write_info,histogram_image,exception); image->blob=DetachBlob(image->blob); image->blob=CloneBlobInfo(histogram_image->blob); histogram_image=DestroyImage(histogram_image); write_info=DestroyImageInfo(write_info); return(status); }
/* Method: ImageList#write(file) Purpose: Write all the images to the specified file. If the file format supports multi-image files, and the @images array contains more than one image, then the images will be written as a single multi-image file. Otherwise each image will be written to a separate file. Returns self. */ VALUE ImageList_write(VALUE self, VALUE file) { Image *images, *img; Info *info; const MagickInfo *m; volatile VALUE info_obj; char *filename; long filenameL; unsigned long scene; ExceptionInfo exception; info_obj = rm_info_new(); Data_Get_Struct(info_obj, Info, info); if (TYPE(file) == T_FILE) { OpenFile *fptr; // Ensure file is open - raise error if not GetOpenFile(file, fptr); SetImageInfoFile(info, GetReadFile(fptr)); } else { // Convert arg to string. Catch exceptions. file = rb_rescue(rb_String, file, file_arg_rescue, file); // Copy the filename to the Info and to the Image. filename = rb_str2cstr(file, &filenameL); filenameL = min(filenameL, MaxTextExtent-1); memcpy(info->filename, filename, (size_t)filenameL); info->filename[filenameL] = '\0'; SetImageInfoFile(info, NULL); } // Convert the images array to an images sequence. images = images_from_imagelist(self); // Copy the filename into each images. Set a scene number to be used if // writing multiple files. (Ref: ImageMagick's utilities/convert.c for (scene = 0, img = images; img; img = GetNextImageInList(img)) { img->scene = scene++; strcpy(img->filename, info->filename); } GetExceptionInfo(&exception); (void) SetImageInfo(info, MagickTrue, &exception); rm_check_exception(&exception, images, RetainOnError); (void) DestroyExceptionInfo(&exception); // Find out if the format supports multi-images files. GetExceptionInfo(&exception); m = GetMagickInfo(info->magick, &exception); rm_check_exception(&exception, images, RetainOnError); (void) DestroyExceptionInfo(&exception); // Tell WriteImage if we want a multi-images file. if (imagelist_length(self) > 1L && m->adjoin) { info->adjoin = MagickTrue; } for (img = images; img; img = GetNextImageInList(img)) { (void) WriteImage(info, img); // images will be split before raising an exception rm_check_image_exception(images, RetainOnError); if (info->adjoin) { break; } } rm_split(images); return self; }