// GP: mode = -1 will be automatically guessed from the file SEXP lib_readImages (SEXP files, SEXP mode) { SEXP res; int _mode, i, nappends; Image * image, * images; ImageInfo * image_info; ExceptionInfo exception; const char * file; ImageType it; if ( LENGTH(files) < 1 ) error ( "please supply at least one file name or URL" ); _mode = INTEGER (mode)[0]; if ( _mode < -1 || _mode > MODE_MAX) error ( "requested mode is not supported" ); // Special call for reading Cellomics image if (LENGTH(files)==1) { file = CHAR(STRING_ELT(files, 0)); i = strlen(file); if (i>4 && (strncmp(&file[i-4], ".c01", 4)==0 || strncmp(&file[i-4], ".C01", 4)==0)) { return (readCellomics(file)); } } image_info = (ImageInfo *) NULL; /* images loaded into image and moved into this list */ images = NewImageList (); GetExceptionInfo (&exception); image_info = CloneImageInfo ( (ImageInfo *)NULL ); nappends = 0; for ( i = 0; i < LENGTH (files); i++ ) { if ( LENGTH (files) > 1 ) file = CHAR ( STRING_ELT(files, i) ); else file = CHAR ( asChar(files) ); strcpy (image_info->filename, file); // Prevent an ImageMagick bug when file is an empty string or NULL if (file==NULL) image=NULL; else if (strlen(file)==0) image=NULL; else { image = ReadImage (image_info, &exception); CatchException (&exception); } if ( image == (Image *)NULL ) { warning ("requested image not found or could not be loaded" ); continue; } // Automatic color mode guess if (_mode==-1) { it = GetImageType(image,&exception); // Rprintf("it=%d G=%d P=%d PM=%d\n",it, GrayscaleType, PaletteType, PaletteMatteType); if (it==BilevelType || it==GrayscaleType || it==GrayscaleMatteType) _mode=MODE_GRAYSCALE; else _mode=MODE_COLOR; } /* do not destroy image here */ AppendImageToList (&images, image); if ( nappends == 0 ) { /* set all attributes from the first image */ strcpy (images->filename, image->filename); images->compression = image->compression; images->x_resolution = image->x_resolution; images->y_resolution = image->y_resolution; } nappends++; } /* do not update image properties here because if no image was added to the list it will cause segfault, or use GetImageListLength first to check size */ image_info = DestroyImageInfo (image_info); /* convert image list into R object */ res = PROTECT(magick2SEXP (images, _mode)); images = DestroyImageList (images); DestroyExceptionInfo(&exception); UNPROTECT(1); return res; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d M P E G I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadMPEGImage() reads an binary file in the MPEG video stream format % and returns it. It allocates the memory necessary for the new Image % structure and returns a pointer to the new image. This method differs from % the other decoder methods in that only the Photoshop resource (MPEG) % information is useful in the returned image. % % The format of the ReadMPEGImage method is: % % Image *ReadMPEGImage(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. % % */ static Image *ReadMPEGImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image, *images; ImageInfo *read_info; MagickBooleanType status; register long i; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } CloseBlob(image); DestroyImageList(image); /* Convert MPEG to PPM with delegate. */ image=AllocateImage(image_info); read_info=CloneImageInfo(image_info); (void) InvokeDelegate(read_info,image,"mpeg-decode",(char *) NULL,exception); image=DestroyImage(image); /* Read PPM files. */ images=NewImageList(); for (i=(long) read_info->scene; ; i++) { (void) FormatMagickString(read_info->filename,MaxTextExtent, "%s%ld.ppm",read_info->unique,i); if (IsAccessible(read_info->filename) == MagickFalse) break; image=ReadImage(read_info,exception); if (image == (Image *) NULL) break; (void) strcpy(image->magick,image_info->magick); image->scene=(unsigned long) i; AppendImageToList(&images,image); if (read_info->number_scenes != 0) if (i >= (long) (read_info->scene+read_info->number_scenes-1)) break; } /* Free resources. */ for (i=0; ; i++) { (void) FormatMagickString(read_info->filename,MaxTextExtent, "%s%ld.ppm",read_info->unique,i); if (IsAccessible(read_info->filename) == MagickFalse) break; (void) remove(read_info->filename); } read_info=DestroyImageInfo(read_info); return(images); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % C l o n e I m a g e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CloneImages() clones one or more images from an image sequence, using a % comma separated list of image numbers or ranges. % % The numbers start at 0 for the first image in the list, while negative % numbers refer to images starting counting from the end of the range. Images % may be refered to multiple times to clone them multiple times. Images % refered beyond the available number of images in list are ignored. % % Images referenced may be reversed, and results in a clone of those images % also being made with a reversed order. % % The format of the CloneImages method is: % % Image *CloneImages(const Image *images,const char *scenes, % ExceptionInfo *exception) % % A description of each parameter follows: % % o images: the image sequence. % % o scenes: This character string specifies which scenes to clone % (e.g. 1,3-5,7-3,2). % % o exception: return any errors or warnings in this structure. % */ MagickExport Image *CloneImages(const Image *images,const char *scenes, ExceptionInfo *exception) { char *p; const Image *next; Image *clone_images, *image; long first, last, step; register long i; size_t length; assert(images != (const Image *) NULL); assert(images->signature == MagickSignature); assert(scenes != (char *) NULL); if (images->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); clone_images=NewImageList(); images=GetFirstImageInList(images); length=GetImageListLength(images); for (p=(char *) scenes; *p != '\0';) { while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ',')) p++; first=strtol(p,&p,10); if (first < 0) first+=(long) length; last=first; while (isspace((int) ((unsigned char) *p)) != 0) p++; if (*p == '-') { last=strtol(p+1,&p,10); if (last < 0) last+=(long) length; } for (step=first > last ? -1 : 1; first != (last+step); first+=step) { i=0; for (next=images; next != (Image *) NULL; next=GetNextImageInList(next)) { if (i == first) { image=CloneImage(next,0,0,MagickTrue,exception); if (image == (Image *) NULL) break; AppendImageToList(&clone_images,image); } i++; } } } return(GetFirstImageInList(clone_images)); }
MagickExport Image *ForwardFourierTransformImage(const Image *image, const MagickBooleanType modulus,ExceptionInfo *exception) { Image *fourier_image; fourier_image=NewImageList(); #if !defined(MAGICKCORE_FFTW_DELEGATE) (void) modulus; (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","`%s' (FFTW)", image->filename); #else { Image *magnitude_image; size_t extent, width; width=image->columns; if ((image->columns != image->rows) || ((image->columns % 2) != 0) || ((image->rows % 2) != 0)) { extent=image->columns < image->rows ? image->rows : image->columns; width=(extent & 0x01) == 1 ? extent+1UL : extent; } magnitude_image=CloneImage(image,width,width,MagickFalse,exception); if (magnitude_image != (Image *) NULL) { Image *phase_image; magnitude_image->storage_class=DirectClass; magnitude_image->depth=32UL; phase_image=CloneImage(image,width,width,MagickFalse,exception); if (phase_image == (Image *) NULL) magnitude_image=DestroyImage(magnitude_image); else { MagickBooleanType is_gray, status; phase_image->storage_class=DirectClass; phase_image->depth=32UL; AppendImageToList(&fourier_image,magnitude_image); AppendImageToList(&fourier_image,phase_image); status=MagickTrue; is_gray=IsGrayImage(image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel sections #endif { #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp section #endif { MagickBooleanType thread_status; if (is_gray != MagickFalse) thread_status=ForwardFourierTransformChannel(image, GrayChannels,modulus,fourier_image,exception); else thread_status=ForwardFourierTransformChannel(image, RedChannel,modulus,fourier_image,exception); if (thread_status == MagickFalse) status=thread_status; } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp section #endif { MagickBooleanType thread_status; thread_status=MagickTrue; if (is_gray == MagickFalse) thread_status=ForwardFourierTransformChannel(image, GreenChannel,modulus,fourier_image,exception); if (thread_status == MagickFalse) status=thread_status; } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp section #endif { MagickBooleanType thread_status; thread_status=MagickTrue; if (is_gray == MagickFalse) thread_status=ForwardFourierTransformChannel(image, BlueChannel,modulus,fourier_image,exception); if (thread_status == MagickFalse) status=thread_status; } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp section #endif { MagickBooleanType thread_status; thread_status=MagickTrue; if (image->matte != MagickFalse) thread_status=ForwardFourierTransformChannel(image, OpacityChannel,modulus,fourier_image,exception); if (thread_status == MagickFalse) status=thread_status; } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp section #endif { MagickBooleanType thread_status; thread_status=MagickTrue; if (image->colorspace == CMYKColorspace) thread_status=ForwardFourierTransformChannel(image, IndexChannel,modulus,fourier_image,exception); if (thread_status == MagickFalse) status=thread_status; } } if (status == MagickFalse) fourier_image=DestroyImageList(fourier_image); fftw_cleanup(); } } } #endif return(fourier_image); }
WandExport MagickBooleanType CompareImagesCommand(ImageInfo *image_info, int argc,char **argv,char **metadata,ExceptionInfo *exception) { #define CompareEpsilon (1.0e-06) #define DefaultDissimilarityThreshold 0.31830988618379067154 #define DefaultSimilarityThreshold (-1.0) #define DestroyCompare() \ { \ if (similarity_image != (Image *) NULL) \ similarity_image=DestroyImageList(similarity_image); \ if (difference_image != (Image *) NULL) \ difference_image=DestroyImageList(difference_image); \ DestroyImageStack(); \ for (i=0; i < (ssize_t) argc; i++) \ argv[i]=DestroyString(argv[i]); \ argv=(char **) RelinquishMagickMemory(argv); \ } #define ThrowCompareException(asperity,tag,option) \ { \ if (exception->severity < (asperity)) \ (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag, \ "`%s'",option); \ DestroyCompare(); \ return(MagickFalse); \ } #define ThrowCompareInvalidArgumentException(option,argument) \ { \ (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \ "InvalidArgument","'%s': %s",option,argument); \ DestroyCompare(); \ return(MagickFalse); \ } char *filename, *option; const char *format; double dissimilarity_threshold, distortion, similarity_metric, similarity_threshold; Image *difference_image, *image, *reconstruct_image, *similarity_image; ImageStack image_stack[MaxImageStackDepth+1]; MagickBooleanType fire, pend, respect_parenthesis, subimage_search; MagickStatusType status; MetricType metric; RectangleInfo offset; register ssize_t i; ssize_t j, k; /* Set defaults. */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(exception != (ExceptionInfo *) NULL); if (argc == 2) { option=argv[1]; if ((LocaleCompare("version",option+1) == 0) || (LocaleCompare("-version",option+1) == 0)) { ListMagickVersion(stdout); return(MagickFalse); } } if (argc < 3) return(CompareUsage()); difference_image=NewImageList(); similarity_image=NewImageList(); dissimilarity_threshold=DefaultDissimilarityThreshold; similarity_threshold=DefaultSimilarityThreshold; distortion=0.0; format=(char *) NULL; j=1; k=0; metric=UndefinedErrorMetric; NewImageStack(); option=(char *) NULL; pend=MagickFalse; reconstruct_image=NewImageList(); respect_parenthesis=MagickFalse; status=MagickTrue; subimage_search=MagickFalse; /* Compare an image. */ ReadCommandlLine(argc,&argv); status=ExpandFilenames(&argc,&argv); if (status == MagickFalse) ThrowCompareException(ResourceLimitError,"MemoryAllocationFailed", GetExceptionMessage(errno)); for (i=1; i < (ssize_t) (argc-1); i++) { option=argv[i]; if (LocaleCompare(option,"(") == 0) { FireImageStack(MagickTrue,MagickTrue,pend); if (k == MaxImageStackDepth) ThrowCompareException(OptionError,"ParenthesisNestedTooDeeply", option); PushImageStack(); continue; } if (LocaleCompare(option,")") == 0) { FireImageStack(MagickTrue,MagickTrue,MagickTrue); if (k == 0) ThrowCompareException(OptionError,"UnableToParseExpression",option); PopImageStack(); continue; } if (IsCommandOption(option) == MagickFalse) { Image *images; /* Read input image. */ FireImageStack(MagickFalse,MagickFalse,pend); filename=argv[i]; if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1))) filename=argv[++i]; images=ReadImages(image_info,filename,exception); status&=(images != (Image *) NULL) && (exception->severity < ErrorException); if (images == (Image *) NULL) continue; AppendImageStack(images); continue; } pend=image != (Image *) NULL ? MagickTrue : MagickFalse; switch (*(option+1)) { case 'a': { if (LocaleCompare("alpha",option+1) == 0) { ssize_t type; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); type=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,argv[i]); if (type < 0) ThrowCompareException(OptionError,"UnrecognizedAlphaChannelOption", argv[i]); break; } if (LocaleCompare("authenticate",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option); } case 'c': { if (LocaleCompare("cache",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("channel",option+1) == 0) { ssize_t channel; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); channel=ParseChannelOption(argv[i]); if (channel < 0) ThrowCompareException(OptionError,"UnrecognizedChannelType", argv[i]); (void) SetPixelChannelMask(image,(ChannelType) channel); break; } if (LocaleCompare("colorspace",option+1) == 0) { ssize_t colorspace; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse, argv[i]); if (colorspace < 0) ThrowCompareException(OptionError,"UnrecognizedColorspace", argv[i]); break; } if (LocaleCompare("compose",option+1) == 0) { ssize_t compose; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); compose=ParseCommandOption(MagickComposeOptions,MagickFalse, argv[i]); if (compose < 0) ThrowCompareException(OptionError,"UnrecognizedComposeOperator", argv[i]); break; } if (LocaleCompare("compress",option+1) == 0) { ssize_t compress; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); compress=ParseCommandOption(MagickCompressOptions,MagickFalse, argv[i]); if (compress < 0) ThrowCompareException(OptionError,"UnrecognizedImageCompression", argv[i]); break; } if (LocaleCompare("concurrent",option+1) == 0) break; ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'd': { if (LocaleCompare("debug",option+1) == 0) { LogEventType event_mask; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); event_mask=SetLogEventMask(argv[i]); if (event_mask == UndefinedEvents) ThrowCompareException(OptionError,"UnrecognizedEventType", argv[i]); break; } if (LocaleCompare("decipher",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("define",option+1) == 0) { i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (*option == '+') { const char *define; define=GetImageOption(image_info,argv[i]); if (define == (const char *) NULL) ThrowCompareException(OptionError,"NoSuchOption",argv[i]); break; } break; } if (LocaleCompare("density",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("depth",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("dissimilarity-threshold",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); if (*option == '+') dissimilarity_threshold=DefaultDissimilarityThreshold; else dissimilarity_threshold=StringToDouble(argv[i],(char **) NULL); break; } if (LocaleCompare("duration",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'e': { if (LocaleCompare("encipher",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("extract",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'f': { if (LocaleCompare("format",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); format=argv[i]; break; } if (LocaleCompare("fuzz",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'h': { if ((LocaleCompare("help",option+1) == 0) || (LocaleCompare("-help",option+1) == 0)) return(CompareUsage()); if (LocaleCompare("highlight-color",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'i': { if (LocaleCompare("identify",option+1) == 0) break; if (LocaleCompare("interlace",option+1) == 0) { ssize_t interlace; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse, argv[i]); if (interlace < 0) ThrowCompareException(OptionError,"UnrecognizedInterlaceType", argv[i]); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'l': { if (LocaleCompare("limit",option+1) == 0) { char *p; double value; ssize_t resource; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); resource=ParseCommandOption(MagickResourceOptions,MagickFalse, argv[i]); if (resource < 0) ThrowCompareException(OptionError,"UnrecognizedResourceType", argv[i]); i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); value=StringToDouble(argv[i],&p); (void) value; if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0)) ThrowCompareInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("list",option+1) == 0) { ssize_t list; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]); if (list < 0) ThrowCompareException(OptionError,"UnrecognizedListType",argv[i]); status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **) argv+j,exception); DestroyCompare(); return(status == 0 ? MagickTrue : MagickFalse); } if (LocaleCompare("log",option+1) == 0) { if (*option == '+') break; i++; if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL)) ThrowCompareException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("lowlight-color",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'm': { if (LocaleCompare("matte",option+1) == 0) break; if (LocaleCompare("metric",option+1) == 0) { ssize_t type; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); type=ParseCommandOption(MagickMetricOptions,MagickTrue,argv[i]); if (type < 0) ThrowCompareException(OptionError,"UnrecognizedMetricType", argv[i]); metric=(MetricType) type; break; } if (LocaleCompare("monitor",option+1) == 0) break; ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'p': { if (LocaleCompare("profile",option+1) == 0) { i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'q': { if (LocaleCompare("quality",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("quantize",option+1) == 0) { ssize_t colorspace; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); colorspace=ParseCommandOption(MagickColorspaceOptions, MagickFalse,argv[i]); if (colorspace < 0) ThrowCompareException(OptionError,"UnrecognizedColorspace", argv[i]); break; } if (LocaleCompare("quiet",option+1) == 0) break; ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'r': { if (LocaleCompare("regard-warnings",option+1) == 0) break; if (LocaleNCompare("respect-parentheses",option+1,17) == 0) { respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse; break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 's': { if (LocaleCompare("sampling-factor",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("seed",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("set",option+1) == 0) { i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("similarity-threshold",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); if (*option == '+') similarity_threshold=DefaultSimilarityThreshold; else similarity_threshold=StringToDouble(argv[i],(char **) NULL); break; } if (LocaleCompare("size",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowCompareInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("subimage-search",option+1) == 0) { if (*option == '+') { subimage_search=MagickFalse; break; } subimage_search=MagickTrue; break; } if (LocaleCompare("synchronize",option+1) == 0) break; ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 't': { if (LocaleCompare("taint",option+1) == 0) break; if (LocaleCompare("transparent-color",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("type",option+1) == 0) { ssize_t type; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]); if (type < 0) ThrowCompareException(OptionError,"UnrecognizedImageType", argv[i]); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case 'v': { if (LocaleCompare("verbose",option+1) == 0) break; if ((LocaleCompare("version",option+1) == 0) || (LocaleCompare("-version",option+1) == 0)) { ListMagickVersion(stdout); break; } if (LocaleCompare("virtual-pixel",option+1) == 0) { ssize_t method; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowCompareException(OptionError,"MissingArgument",option); method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse, argv[i]); if (method < 0) ThrowCompareException(OptionError, "UnrecognizedVirtualPixelMethod",argv[i]); break; } ThrowCompareException(OptionError,"UnrecognizedOption",option) } case '?': break; default: ThrowCompareException(OptionError,"UnrecognizedOption",option) } fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) & FireOptionFlag) == 0 ? MagickFalse : MagickTrue; if (fire != MagickFalse) FireImageStack(MagickTrue,MagickTrue,MagickTrue); } if (k != 0) ThrowCompareException(OptionError,"UnbalancedParenthesis",argv[i]); if (i-- != (ssize_t) (argc-1)) ThrowCompareException(OptionError,"MissingAnImageFilename",argv[i]); if ((image == (Image *) NULL) || (GetImageListLength(image) < 2)) ThrowCompareException(OptionError,"MissingAnImageFilename",argv[i]); FinalizeImageSettings(image_info,image,MagickTrue); if ((image == (Image *) NULL) || (GetImageListLength(image) < 2)) ThrowCompareException(OptionError,"MissingAnImageFilename",argv[i]); image=GetImageFromList(image,0); reconstruct_image=GetImageFromList(image,1); offset.x=0; offset.y=0; if (subimage_search != MagickFalse) { similarity_image=SimilarityImage(image,reconstruct_image,metric, similarity_threshold,&offset,&similarity_metric,exception); if (similarity_metric > dissimilarity_threshold) ThrowCompareException(ImageError,"ImagesTooDissimilar",image->filename); } if ((reconstruct_image->columns == image->columns) && (reconstruct_image->rows == image->rows)) difference_image=CompareImages(image,reconstruct_image,metric,&distortion, exception); else if (similarity_image == (Image *) NULL) { if (metric == PerceptualHashErrorMetric) difference_image=CompareImages(image,reconstruct_image,metric, &distortion,exception); else ThrowCompareException(OptionError,"ImageWidthsOrHeightsDiffer", image->filename); } else { Image *composite_image; /* Determine if reconstructed image is a subimage of the image. */ composite_image=CloneImage(image,0,0,MagickTrue,exception); if (composite_image == (Image *) NULL) difference_image=CompareImages(image,reconstruct_image,metric, &distortion,exception); else { Image *distort_image; RectangleInfo page; (void) CompositeImage(composite_image,reconstruct_image, CopyCompositeOp,MagickTrue,offset.x,offset.y,exception); difference_image=CompareImages(image,composite_image,metric, &distortion,exception); if (difference_image != (Image *) NULL) { difference_image->page.x=offset.x; difference_image->page.y=offset.y; } composite_image=DestroyImage(composite_image); page.width=reconstruct_image->columns; page.height=reconstruct_image->rows; page.x=offset.x; page.y=offset.y; distort_image=CropImage(image,&page,exception); if (distort_image != (Image *) NULL) { Image *sans_image; sans_image=CompareImages(distort_image,reconstruct_image,metric, &distortion,exception); distort_image=DestroyImage(distort_image); if (sans_image != (Image *) NULL) sans_image=DestroyImage(sans_image); } } if (difference_image != (Image *) NULL) { AppendImageToList(&difference_image,similarity_image); similarity_image=(Image *) NULL; } } if (difference_image == (Image *) NULL) status=0; else { if (image_info->verbose != MagickFalse) (void) SetImageColorMetric(image,reconstruct_image,exception); if (*difference_image->magick == '\0') (void) CopyMagickString(difference_image->magick,image->magick, MagickPathExtent); if (image_info->verbose == MagickFalse) { switch (metric) { case FuzzErrorMetric: case MeanAbsoluteErrorMetric: case MeanSquaredErrorMetric: case PeakAbsoluteErrorMetric: case RootMeanSquaredErrorMetric: { (void) FormatLocaleFile(stderr,"%g (%g)",QuantumRange*distortion, (double) distortion); break; } case AbsoluteErrorMetric: case NormalizedCrossCorrelationErrorMetric: case PeakSignalToNoiseRatioErrorMetric: case PerceptualHashErrorMetric: { (void) FormatLocaleFile(stderr,"%g",distortion); break; } case MeanErrorPerPixelErrorMetric: { (void) FormatLocaleFile(stderr,"%g (%g, %g)",distortion, image->error.normalized_mean_error, image->error.normalized_maximum_error); break; } case UndefinedErrorMetric: break; } if (subimage_search != MagickFalse) (void) FormatLocaleFile(stderr," @ %.20g,%.20g",(double) difference_image->page.x,(double) difference_image->page.y); } else { double *channel_distortion; channel_distortion=GetImageDistortions(image,reconstruct_image, metric,exception); (void) FormatLocaleFile(stderr,"Image: %s\n",image->filename); if ((reconstruct_image->columns != image->columns) || (reconstruct_image->rows != image->rows)) (void) FormatLocaleFile(stderr,"Offset: %.20g,%.20g\n",(double) difference_image->page.x,(double) difference_image->page.y); (void) FormatLocaleFile(stderr," Channel distortion: %s\n", CommandOptionToMnemonic(MagickMetricOptions,(ssize_t) metric)); switch (metric) { case FuzzErrorMetric: case MeanAbsoluteErrorMetric: case MeanSquaredErrorMetric: case PeakAbsoluteErrorMetric: case RootMeanSquaredErrorMetric: { switch (image->colorspace) { case RGBColorspace: default: { (void) FormatLocaleFile(stderr," red: %g (%g)\n", QuantumRange*channel_distortion[RedPixelChannel], channel_distortion[RedPixelChannel]); (void) FormatLocaleFile(stderr," green: %g (%g)\n", QuantumRange*channel_distortion[GreenPixelChannel], channel_distortion[GreenPixelChannel]); (void) FormatLocaleFile(stderr," blue: %g (%g)\n", QuantumRange*channel_distortion[BluePixelChannel], channel_distortion[BluePixelChannel]); if (image->alpha_trait != UndefinedPixelTrait) (void) FormatLocaleFile(stderr," alpha: %g (%g)\n", QuantumRange*channel_distortion[AlphaPixelChannel], channel_distortion[AlphaPixelChannel]); break; } case CMYKColorspace: { (void) FormatLocaleFile(stderr," cyan: %g (%g)\n", QuantumRange*channel_distortion[CyanPixelChannel], channel_distortion[CyanPixelChannel]); (void) FormatLocaleFile(stderr," magenta: %g (%g)\n", QuantumRange*channel_distortion[MagentaPixelChannel], channel_distortion[MagentaPixelChannel]); (void) FormatLocaleFile(stderr," yellow: %g (%g)\n", QuantumRange*channel_distortion[YellowPixelChannel], channel_distortion[YellowPixelChannel]); (void) FormatLocaleFile(stderr," black: %g (%g)\n", QuantumRange*channel_distortion[BlackPixelChannel], channel_distortion[BlackPixelChannel]); if (image->alpha_trait != UndefinedPixelTrait) (void) FormatLocaleFile(stderr," alpha: %g (%g)\n", QuantumRange*channel_distortion[AlphaPixelChannel], channel_distortion[AlphaPixelChannel]); break; } case GRAYColorspace: { (void) FormatLocaleFile(stderr," gray: %g (%g)\n", QuantumRange*channel_distortion[GrayPixelChannel], channel_distortion[GrayPixelChannel]); if (image->alpha_trait != UndefinedPixelTrait) (void) FormatLocaleFile(stderr," alpha: %g (%g)\n", QuantumRange*channel_distortion[AlphaPixelChannel], channel_distortion[AlphaPixelChannel]); break; } } (void) FormatLocaleFile(stderr," all: %g (%g)\n", QuantumRange*channel_distortion[MaxPixelChannels], channel_distortion[MaxPixelChannels]); break; } case AbsoluteErrorMetric: case NormalizedCrossCorrelationErrorMetric: case PeakSignalToNoiseRatioErrorMetric: case PerceptualHashErrorMetric: { switch (image->colorspace) { case RGBColorspace: default: { (void) FormatLocaleFile(stderr," red: %g\n", channel_distortion[RedPixelChannel]); (void) FormatLocaleFile(stderr," green: %g\n", channel_distortion[GreenPixelChannel]); (void) FormatLocaleFile(stderr," blue: %g\n", channel_distortion[BluePixelChannel]); if (image->alpha_trait != UndefinedPixelTrait) (void) FormatLocaleFile(stderr," alpha: %g\n", channel_distortion[AlphaPixelChannel]); break; } case CMYKColorspace: { (void) FormatLocaleFile(stderr," cyan: %g\n", channel_distortion[CyanPixelChannel]); (void) FormatLocaleFile(stderr," magenta: %g\n", channel_distortion[MagentaPixelChannel]); (void) FormatLocaleFile(stderr," yellow: %g\n", channel_distortion[YellowPixelChannel]); (void) FormatLocaleFile(stderr," black: %g\n", channel_distortion[BlackPixelChannel]); if (image->alpha_trait != UndefinedPixelTrait) (void) FormatLocaleFile(stderr," alpha: %g\n", channel_distortion[AlphaPixelChannel]); break; } case GRAYColorspace: { (void) FormatLocaleFile(stderr," gray: %g\n", channel_distortion[GrayPixelChannel]); if (image->alpha_trait != UndefinedPixelTrait) (void) FormatLocaleFile(stderr," alpha: %g\n", channel_distortion[AlphaPixelChannel]); break; } } (void) FormatLocaleFile(stderr," all: %g\n", channel_distortion[MaxPixelChannels]); break; } case MeanErrorPerPixelErrorMetric: { (void) FormatLocaleFile(stderr," %g (%g, %g)\n", channel_distortion[MaxPixelChannels], image->error.normalized_mean_error, image->error.normalized_maximum_error); break; } case UndefinedErrorMetric: break; } channel_distortion=(double *) RelinquishMagickMemory( channel_distortion); if (subimage_search != MagickFalse) (void) FormatLocaleFile(stderr," Offset: %.20g,%.20g\n",(double) difference_image->page.x,(double) difference_image->page.y); } status&=WriteImages(image_info,difference_image,argv[argc-1],exception); if ((metadata != (char **) NULL) && (format != (char *) NULL)) { char *text; text=InterpretImageProperties(image_info,difference_image,format, exception); if (text == (char *) NULL) ThrowCompareException(ResourceLimitError,"MemoryAllocationFailed", GetExceptionMessage(errno)); (void) ConcatenateString(&(*metadata),text); text=DestroyString(text); } difference_image=DestroyImageList(difference_image); } DestroyCompare(); if ((metric == NormalizedCrossCorrelationErrorMetric) || (metric == UndefinedErrorMetric)) { if (fabs(distortion-1.0) > CompareEpsilon) (void) SetImageOption(image_info,"compare:dissimilar","true"); } else if (fabs(distortion) > CompareEpsilon) (void) SetImageOption(image_info,"compare:dissimilar","true"); return(status != 0 ? MagickTrue : MagickFalse); }
MagickExport Image *MontageImageList(const ImageInfo *image_info, const MontageInfo *montage_info,const Image *images,ExceptionInfo *exception) { #define MontageImageTag "Montage/Image" #define TileImageTag "Tile/Image" char tile_geometry[MagickPathExtent], *title; const char *value; DrawInfo *draw_info; FrameInfo frame_info; Image *image, **image_list, **master_list, *montage, *texture, *tile_image, *thumbnail; ImageInfo *clone_info; MagickBooleanType concatenate, proceed, status; MagickOffsetType tiles; MagickProgressMonitor progress_monitor; MagickStatusType flags; register ssize_t i; RectangleInfo bounds, geometry, extract_info; size_t bevel_width, border_width, extent, height, images_per_page, max_height, number_images, number_lines, sans, tiles_per_column, tiles_per_page, tiles_per_row, title_offset, total_tiles, width; ssize_t tile, x, x_offset, y, y_offset; TypeMetric metrics; /* Create image tiles. */ assert(images != (Image *) NULL); assert(images->signature == MagickCoreSignature); if (images->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); assert(montage_info != (MontageInfo *) NULL); assert(montage_info->signature == MagickCoreSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); number_images=GetImageListLength(images); master_list=ImageListToArray(images,exception); image_list=master_list; image=image_list[0]; if (master_list == (Image **) NULL) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); thumbnail=NewImageList(); for (i=0; i < (ssize_t) number_images; i++) { image=CloneImage(image_list[i],0,0,MagickTrue,exception); if (image == (Image *) NULL) break; (void) ParseAbsoluteGeometry("0x0+0+0",&image->page); progress_monitor=SetImageProgressMonitor(image,(MagickProgressMonitor) NULL, image->client_data); flags=ParseRegionGeometry(image,montage_info->geometry,&geometry,exception); thumbnail=ThumbnailImage(image,geometry.width,geometry.height,exception); if (thumbnail == (Image *) NULL) break; image_list[i]=thumbnail; (void) SetImageProgressMonitor(image,progress_monitor,image->client_data); proceed=SetImageProgress(image,TileImageTag,(MagickOffsetType) i, number_images); if (proceed == MagickFalse) break; image=DestroyImage(image); } if (i < (ssize_t) number_images) { if (thumbnail == (Image *) NULL) i--; for (tile=0; (ssize_t) tile <= i; tile++) if (image_list[tile] != (Image *) NULL) image_list[tile]=DestroyImage(image_list[tile]); master_list=(Image **) RelinquishMagickMemory(master_list); return((Image *) NULL); } /* Sort image list by increasing tile number. */ for (i=0; i < (ssize_t) number_images; i++) if (image_list[i]->scene == 0) break; if (i == (ssize_t) number_images) qsort((void *) image_list,(size_t) number_images,sizeof(*image_list), SceneCompare); /* Determine tiles per row and column. */ tiles_per_column=(size_t) sqrt((double) number_images); tiles_per_row=(size_t) ceil((double) number_images/tiles_per_column); x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &tiles_per_column,&tiles_per_row); /* Determine tile sizes. */ concatenate=MagickFalse; SetGeometry(image_list[0],&extract_info); extract_info.x=(ssize_t) montage_info->border_width; extract_info.y=(ssize_t) montage_info->border_width; if (montage_info->geometry != (char *) NULL) { /* Initialize tile geometry. */ flags=GetGeometry(montage_info->geometry,&extract_info.x,&extract_info.y, &extract_info.width,&extract_info.height); concatenate=((flags & RhoValue) == 0) && ((flags & SigmaValue) == 0) ? MagickTrue : MagickFalse; } border_width=montage_info->border_width; bevel_width=0; (void) ResetMagickMemory(&frame_info,0,sizeof(frame_info)); if (montage_info->frame != (char *) NULL) { char absolute_geometry[MagickPathExtent]; frame_info.width=extract_info.width; frame_info.height=extract_info.height; (void) FormatLocaleString(absolute_geometry,MagickPathExtent,"%s!", montage_info->frame); flags=ParseMetaGeometry(absolute_geometry,&frame_info.outer_bevel, &frame_info.inner_bevel,&frame_info.width,&frame_info.height); if ((flags & HeightValue) == 0) frame_info.height=frame_info.width; if ((flags & XiValue) == 0) frame_info.outer_bevel=(ssize_t) frame_info.width/2; if ((flags & PsiValue) == 0) frame_info.inner_bevel=frame_info.outer_bevel; frame_info.x=(ssize_t) frame_info.width; frame_info.y=(ssize_t) frame_info.height; bevel_width=(size_t) MagickMax(frame_info.inner_bevel, frame_info.outer_bevel); border_width=(size_t) MagickMax((ssize_t) frame_info.width, (ssize_t) frame_info.height); } for (i=0; i < (ssize_t) number_images; i++) { if (image_list[i]->columns > extract_info.width) extract_info.width=image_list[i]->columns; if (image_list[i]->rows > extract_info.height) extract_info.height=image_list[i]->rows; } /* Initialize draw attributes. */ clone_info=CloneImageInfo(image_info); clone_info->background_color=montage_info->background_color; clone_info->border_color=montage_info->border_color; draw_info=CloneDrawInfo(clone_info,(DrawInfo *) NULL); if (montage_info->font != (char *) NULL) (void) CloneString(&draw_info->font,montage_info->font); if (montage_info->pointsize != 0.0) draw_info->pointsize=montage_info->pointsize; draw_info->gravity=CenterGravity; draw_info->stroke=montage_info->stroke; draw_info->fill=montage_info->fill; draw_info->text=AcquireString(""); (void) GetTypeMetrics(image_list[0],draw_info,&metrics,exception); texture=NewImageList(); if (montage_info->texture != (char *) NULL) { (void) CopyMagickString(clone_info->filename,montage_info->texture, MagickPathExtent); texture=ReadImage(clone_info,exception); } /* Determine the number of lines in an next label. */ title=InterpretImageProperties(clone_info,image_list[0],montage_info->title, exception); title_offset=0; if (montage_info->title != (char *) NULL) title_offset=(size_t) (2*(metrics.ascent-metrics.descent)* MultilineCensus(title)+2*extract_info.y); number_lines=0; for (i=0; i < (ssize_t) number_images; i++) { value=GetImageProperty(image_list[i],"label",exception); if (value == (const char *) NULL) continue; if (MultilineCensus(value) > number_lines) number_lines=MultilineCensus(value); } /* Allocate next structure. */ tile_image=AcquireImage((ImageInfo *) NULL,exception); montage=AcquireImage(clone_info,exception); montage->background_color=montage_info->background_color; montage->scene=0; images_per_page=(number_images-1)/(tiles_per_row*tiles_per_column)+1; tiles=0; total_tiles=(size_t) number_images; for (i=0; i < (ssize_t) images_per_page; i++) { /* Determine bounding box. */ tiles_per_page=tiles_per_row*tiles_per_column; x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); tiles_per_page=tiles_per_row*tiles_per_column; y_offset+=(ssize_t) title_offset; max_height=0; bounds.width=0; bounds.height=0; width=0; for (tile=0; tile < (ssize_t) tiles_per_page; tile++) { if (tile < (ssize_t) number_images) { width=concatenate != MagickFalse ? image_list[tile]->columns : extract_info.width; if (image_list[tile]->rows > max_height) max_height=image_list[tile]->rows; } x_offset+=(ssize_t) (width+2*(extract_info.x+border_width)); if (x_offset > (ssize_t) bounds.width) bounds.width=(size_t) x_offset; if (((tile+1) == (ssize_t) tiles_per_page) || (((tile+1) % tiles_per_row) == 0)) { x_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y, &sans,&sans); height=concatenate != MagickFalse ? max_height : extract_info.height; y_offset+=(ssize_t) (height+(extract_info.y+(ssize_t) border_width)*2+ (metrics.ascent-metrics.descent+4)*number_lines+ (montage_info->shadow != MagickFalse ? 4 : 0)); if (y_offset > (ssize_t) bounds.height) bounds.height=(size_t) y_offset; max_height=0; } } if (montage_info->shadow != MagickFalse) bounds.width+=4; /* Initialize montage image. */ (void) CopyMagickString(montage->filename,montage_info->filename, MagickPathExtent); montage->columns=(size_t) MagickMax((ssize_t) bounds.width,1); montage->rows=(size_t) MagickMax((ssize_t) bounds.height,1); (void) SetImageBackgroundColor(montage,exception); /* Set montage geometry. */ montage->montage=AcquireString((char *) NULL); tile=0; extent=1; while (tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images)) { extent+=strlen(image_list[tile]->filename)+1; tile++; } montage->directory=(char *) AcquireQuantumMemory(extent, sizeof(*montage->directory)); if ((montage->montage == (char *) NULL) || (montage->directory == (char *) NULL)) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); y_offset+=(ssize_t) title_offset; (void) FormatLocaleString(montage->montage,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) (extract_info.width+ (extract_info.x+border_width)*2),(double) (extract_info.height+ (extract_info.y+border_width)*2+(double) ((metrics.ascent- metrics.descent+4)*number_lines+(montage_info->shadow != MagickFalse ? 4 : 0))),(double) x_offset,(double) y_offset); *montage->directory='\0'; tile=0; while (tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images)) { (void) ConcatenateMagickString(montage->directory, image_list[tile]->filename,extent); (void) ConcatenateMagickString(montage->directory,"\n",extent); tile++; } progress_monitor=SetImageProgressMonitor(montage,(MagickProgressMonitor) NULL,montage->client_data); if (texture != (Image *) NULL) (void) TextureImage(montage,texture,exception); if (montage_info->title != (char *) NULL) { char geometry[MagickPathExtent]; DrawInfo *clone_info; TypeMetric metrics; /* Annotate composite image with title. */ clone_info=CloneDrawInfo(image_info,draw_info); clone_info->gravity=CenterGravity; clone_info->pointsize*=2.0; (void) GetTypeMetrics(image_list[0],clone_info,&metrics,exception); (void) FormatLocaleString(geometry,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) montage->columns,(double) (metrics.ascent-metrics.descent),0.0,(double) extract_info.y+4); (void) CloneString(&clone_info->geometry,geometry); (void) CloneString(&clone_info->text,title); (void) AnnotateImage(montage,clone_info,exception); clone_info=DestroyDrawInfo(clone_info); } (void) SetImageProgressMonitor(montage,progress_monitor, montage->client_data); /* Copy tile to the composite. */ x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); x_offset+=extract_info.x; y_offset+=(ssize_t) title_offset+extract_info.y; max_height=0; status=MagickTrue; for (tile=0; tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images); tile++) { /* Copy this tile to the composite. */ image=CloneImage(image_list[tile],0,0,MagickTrue,exception); progress_monitor=SetImageProgressMonitor(image, (MagickProgressMonitor) NULL,image->client_data); width=concatenate != MagickFalse ? image->columns : extract_info.width; if (image->rows > max_height) max_height=image->rows; height=concatenate != MagickFalse ? max_height : extract_info.height; if (border_width != 0) { Image *border_image; RectangleInfo border_info; /* Put a border around the image. */ border_info.width=border_width; border_info.height=border_width; if (montage_info->frame != (char *) NULL) { border_info.width=(width-image->columns+1)/2; border_info.height=(height-image->rows+1)/2; } border_image=BorderImage(image,&border_info,image->compose,exception); if (border_image != (Image *) NULL) { image=DestroyImage(image); image=border_image; } if ((montage_info->frame != (char *) NULL) && (image->compose == DstOutCompositeOp)) { (void) SetPixelChannelMask(image,AlphaChannel); (void) NegateImage(image,MagickFalse,exception); (void) SetPixelChannelMask(image,DefaultChannels); } } /* Gravitate as specified by the tile gravity. */ tile_image->columns=width; tile_image->rows=height; tile_image->gravity=montage_info->gravity; if (image->gravity != UndefinedGravity) tile_image->gravity=image->gravity; (void) FormatLocaleString(tile_geometry,MagickPathExtent,"%.20gx%.20g+0+0", (double) image->columns,(double) image->rows); flags=ParseGravityGeometry(tile_image,tile_geometry,&geometry,exception); x=(ssize_t) (geometry.x+border_width); y=(ssize_t) (geometry.y+border_width); if ((montage_info->frame != (char *) NULL) && (bevel_width != 0)) { FrameInfo extract_info; Image *frame_image; /* Put an ornamental border around this tile. */ extract_info=frame_info; extract_info.width=width+2*frame_info.width; extract_info.height=height+2*frame_info.height; value=GetImageProperty(image,"label",exception); if (value != (const char *) NULL) extract_info.height+=(size_t) ((metrics.ascent-metrics.descent+4)* MultilineCensus(value)); frame_image=FrameImage(image,&extract_info,image->compose,exception); if (frame_image != (Image *) NULL) { image=DestroyImage(image); image=frame_image; } x=0; y=0; } if (LocaleCompare(image->magick,"NULL") != 0) { /* Composite background with tile. */ if (montage_info->shadow != MagickFalse) { Image *shadow_image; /* Shadow image. */ (void) QueryColorCompliance("#0000",AllCompliance, &image->background_color,exception); shadow_image=ShadowImage(image,80.0,2.0,5,5,exception); if (shadow_image != (Image *) NULL) { (void) CompositeImage(shadow_image,image,OverCompositeOp, MagickTrue,0,0,exception); image=DestroyImage(image); image=shadow_image; } } (void) CompositeImage(montage,image,image->compose,MagickTrue, x_offset+x,y_offset+y,exception); value=GetImageProperty(image,"label",exception); if (value != (const char *) NULL) { char geometry[MagickPathExtent]; /* Annotate composite tile with label. */ (void) FormatLocaleString(geometry,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) ((montage_info->frame ? image->columns : width)-2*border_width),(double) (metrics.ascent-metrics.descent+4)*MultilineCensus(value), (double) (x_offset+border_width),(double) ((montage_info->frame ? y_offset+height+border_width+4 : y_offset+extract_info.height+border_width+ (montage_info->shadow != MagickFalse ? 4 : 0))+bevel_width)); (void) CloneString(&draw_info->geometry,geometry); (void) CloneString(&draw_info->text,value); (void) AnnotateImage(montage,draw_info,exception); } } x_offset+=(ssize_t) (width+2*(extract_info.x+border_width)); if (((tile+1) == (ssize_t) tiles_per_page) || (((tile+1) % tiles_per_row) == 0)) { x_offset=extract_info.x; y_offset+=(ssize_t) (height+(extract_info.y+border_width)*2+ (metrics.ascent-metrics.descent+4)*number_lines+ (montage_info->shadow != MagickFalse ? 4 : 0)); max_height=0; } if (images->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; proceed=SetImageProgress(image,MontageImageTag,tiles,total_tiles); if (proceed == MagickFalse) status=MagickFalse; } image_list[tile]=DestroyImage(image_list[tile]); image=DestroyImage(image); tiles++; } (void) status; if ((i+1) < (ssize_t) images_per_page) { /* Allocate next image structure. */ AcquireNextImage(clone_info,montage,exception); if (GetNextImageInList(montage) == (Image *) NULL) { montage=DestroyImageList(montage); return((Image *) NULL); } montage=GetNextImageInList(montage); montage->background_color=montage_info->background_color; image_list+=tiles_per_page; number_images-=tiles_per_page; } } tile_image=DestroyImage(tile_image); if (texture != (Image *) NULL) texture=DestroyImage(texture); title=DestroyString(title); master_list=(Image **) RelinquishMagickMemory(master_list); draw_info=DestroyDrawInfo(draw_info); clone_info=DestroyImageInfo(clone_info); return(GetFirstImageInList(montage)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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,MagickFalse,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)) { unsigned long 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); (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) { if (IsPathAccessible(read_info->filename) != MagickFalse) (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); 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,MagickFalse,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 timestamp[MaxTextExtent]; const StringInfo *profile; next->taint=MagickFalse; if (next->magick_columns == 0) next->magick_columns=next->columns; if (next->magick_rows == 0) next->magick_rows=next->rows; if ((LocaleCompare(magick,"HTTP") != 0) && (LocaleCompare(magick,"FTP") != 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); value=GetImageProperty(next,"tiff:Orientation"); if (value == (char *) NULL) value=GetImageProperty(next,"exif:Orientation"); if (value != (char *) NULL) { next->orientation=(OrientationType) StringToLong(value); (void) DeleteImageProperty(next,"tiff:Orientation"); (void) DeleteImageProperty(next,"exif:Orientation"); } value=GetImageProperty(next,"tiff:XResolution"); if (value == (char *) NULL) value=GetImageProperty(next,"exif:XResolution"); if (value != (char *) NULL) { geometry_info.rho=next->x_resolution; geometry_info.sigma=1.0; flags=ParseGeometry(value,&geometry_info); if (geometry_info.sigma != 0) next->x_resolution=geometry_info.rho/geometry_info.sigma; (void) DeleteImageProperty(next,"exif:XResolution"); (void) DeleteImageProperty(next,"tiff:XResolution"); } value=GetImageProperty(next,"tiff:YResolution"); if (value == (char *) NULL) value=GetImageProperty(next,"exif:YResolution"); if (value != (char *) NULL) { geometry_info.rho=next->y_resolution; geometry_info.sigma=1.0; flags=ParseGeometry(value,&geometry_info); if (geometry_info.sigma != 0) next->y_resolution=geometry_info.rho/geometry_info.sigma; (void) DeleteImageProperty(next,"exif:YResolution"); (void) DeleteImageProperty(next,"tiff:YResolution"); } value=GetImageProperty(next,"tiff:ResolutionUnit"); if (value == (char *) NULL) value=GetImageProperty(next,"exif:ResolutionUnit"); 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; if (*read_info->filename != '\0') { char *property; const char *option; option=GetImageOption(read_info,"caption"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option); (void) SetImageProperty(next,"caption",property); property=DestroyString(property); } option=GetImageOption(read_info,"comment"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option); (void) SetImageProperty(next,"comment",property); property=DestroyString(property); } option=GetImageOption(read_info,"label"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option); (void) SetImageProperty(next,"label",property); 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"); if (profile != (const StringInfo *) NULL) { next->color_profile.length=GetStringInfoLength(profile); next->color_profile.info=GetStringInfoDatum(profile); } profile=GetImageProfile(next,"iptc"); if (profile == (const StringInfo *) NULL) profile=GetImageProfile(next,"8bim"); if (profile != (const StringInfo *) NULL) { next->iptc_profile.length=GetStringInfoLength(profile); next->iptc_profile.info=GetStringInfoDatum(profile); } (void) FormatMagickTime(GetBlobProperties(next)->st_mtime,MaxTextExtent, timestamp); (void) SetImageProperty(next,"date:modify",timestamp); (void) FormatMagickTime(GetBlobProperties(next)->st_ctime,MaxTextExtent, timestamp); (void) SetImageProperty(next,"date:create",timestamp); if (read_info->verbose != MagickFalse) (void) IdentifyImage(next,stdout,MagickFalse); image=next; } read_info=DestroyImageInfo(read_info); return(GetFirstImageInList(image)); }
WandExport MagickBooleanType ConjureImageCommand(ImageInfo *image_info, int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception) { #define DestroyConjure() \ { \ image=DestroyImageList(image); \ for (i=0; i < (ssize_t) argc; i++) \ argv[i]=DestroyString(argv[i]); \ argv=(char **) RelinquishMagickMemory(argv); \ } #define ThrowConjureException(asperity,tag,option) \ { \ (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \ option); \ DestroyConjure(); \ return(MagickFalse); \ } #define ThrowConjureInvalidArgumentException(option,argument) \ { \ (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \ "InvalidArgument","`%s': %s",option,argument); \ DestroyConjure(); \ return(MagickFalse); \ } char filename[MaxTextExtent], *option; Image *image; MagickStatusType status; register ssize_t i; ssize_t number_images; /* Set defaults. */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(exception != (ExceptionInfo *) NULL); if (argc < 2) return(ConjureUsage()); image=NewImageList(); number_images=0; option=(char *) NULL; /* Conjure an image. */ ReadCommandlLine(argc,&argv); status=ExpandFilenames(&argc,&argv); if (status == MagickFalse) ThrowConjureException(ResourceLimitError,"MemoryAllocationFailed", GetExceptionMessage(errno)); for (i=1; i < (ssize_t) argc; i++) { option=argv[i]; if (IsCommandOption(option) != MagickFalse) { if (LocaleCompare("concurrent",option+1) == 0) break; if (LocaleCompare("debug",option+1) == 0) { ssize_t event; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowConjureException(OptionError,"MissingArgument",option); event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]); if (event < 0) ThrowConjureException(OptionError,"UnrecognizedEventType", argv[i]); (void) SetLogEventMask(argv[i]); continue; } if (LocaleCompare("duration",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) (argc-1)) ThrowConjureException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowConjureInvalidArgumentException(option,argv[i]); continue; } if ((LocaleCompare("help",option+1) == 0) || (LocaleCompare("-help",option+1) == 0)) { if (*option == '-') return(ConjureUsage()); continue; } if (LocaleCompare("log",option+1) == 0) { if (*option == '-') { i++; if (i == (ssize_t) argc) ThrowConjureException(OptionError,"MissingLogFormat",option); (void) SetLogFormat(argv[i]); } continue; } if (LocaleCompare("monitor",option+1) == 0) continue; if (LocaleCompare("quiet",option+1) == 0) continue; if (LocaleCompare("regard-warnings",option+1) == 0) break; if (LocaleCompare("seed",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) (argc-1)) ThrowConjureException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowConjureInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("verbose",option+1) == 0) { image_info->verbose=(*option == '-') ? MagickTrue : MagickFalse; continue; } if ((LocaleCompare("version",option+1) == 0) || (LocaleCompare("-version",option+1) == 0)) { (void) FormatLocaleFile(stdout,"Version: %s\n", GetMagickVersion((size_t *) NULL)); (void) FormatLocaleFile(stdout,"Copyright: %s\n", GetMagickCopyright()); (void) FormatLocaleFile(stdout,"Features: %s\n\n", GetMagickFeatures()); return(MagickFalse); } /* Persist key/value pair. */ (void) DeleteImageOption(image_info,option+1); status=SetImageOption(image_info,option+1,argv[i+1]); if (status == MagickFalse) ThrowConjureException(ImageError,"UnableToPersistKey",option); i++; continue; } /* Interpret MSL script. */ (void) DeleteImageOption(image_info,"filename"); status=SetImageOption(image_info,"filename",argv[i]); if (status == MagickFalse) ThrowConjureException(ImageError,"UnableToPersistKey",argv[i]); (void) FormatLocaleString(filename,MaxTextExtent,"msl:%s",argv[i]); image=ReadImages(image_info,filename,exception); CatchException(exception); if (image != (Image *) NULL) image=DestroyImageList(image); status=image != (Image *) NULL ? MagickTrue : MagickFalse; number_images++; } if (i != (ssize_t) argc) ThrowConjureException(OptionError,"MissingAnImageFilename",argv[i]); if (number_images == 0) ThrowConjureException(OptionError,"MissingAnImageFilename",argv[argc-1]); if (image != (Image *) NULL) image=DestroyImageList(image); for (i=0; i < (ssize_t) argc; i++) argv[i]=DestroyString(argv[i]); argv=(char **) RelinquishMagickMemory(argv); return(status != 0 ? MagickTrue : MagickFalse); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e H T M L I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteHTMLImage() writes an image in the HTML encoded image format. % % The format of the WriteHTMLImage method is: % % MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % */ static MagickBooleanType WriteHTMLImage(const ImageInfo *image_info, Image *image) { char basename[MaxTextExtent], buffer[MaxTextExtent], filename[MaxTextExtent], mapname[MaxTextExtent], url[MaxTextExtent]; Image *next; ImageInfo *write_info; MagickBooleanType status; RectangleInfo geometry; register char *p; /* Open 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); (void) CloseBlob(image); if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace); *url='\0'; if ((LocaleCompare(image_info->magick,"FTP") == 0) || (LocaleCompare(image_info->magick,"HTTP") == 0)) { /* Extract URL base from filename. */ p=strrchr(image->filename,'/'); if (p != (char *) NULL) { p++; (void) CopyMagickString(url,image_info->magick,MaxTextExtent); (void) ConcatenateMagickString(url,":",MaxTextExtent); url[strlen(url)+p-image->filename]='\0'; (void) ConcatenateMagickString(url,image->filename, p-image->filename+2); (void) CopyMagickString(image->filename,p,MaxTextExtent); } } /* Refer to image map file. */ (void) CopyMagickString(filename,image->filename,MaxTextExtent); AppendImageFormat("map",filename); GetPathComponent(filename,BasePath,basename); (void) CopyMagickString(mapname,basename,MaxTextExtent); (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent); (void) CopyMagickString(filename,image->filename,MaxTextExtent); write_info=CloneImageInfo(image_info); write_info->adjoin=MagickTrue; status=MagickTrue; if (LocaleCompare(image_info->magick,"SHTML") != 0) { const char *value; /* Open output image file. */ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); /* Write the HTML image file. */ (void) WriteBlobString(image,"<?xml version=\"1.0\" " "encoding=\"US-ASCII\"?>\n"); (void) WriteBlobString(image,"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML " "1.0 Strict//EN\" " "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"); (void) WriteBlobString(image,"<html>\n"); (void) WriteBlobString(image,"<head>\n"); value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) FormatLocaleString(buffer,MaxTextExtent,"<title>%s</title>\n", value); else { GetPathComponent(filename,BasePath,basename); (void) FormatLocaleString(buffer,MaxTextExtent, "<title>%s</title>\n",basename); } (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"</head>\n"); (void) WriteBlobString(image,"<body style=\"text-align: center;\">\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"<h1>%s</h1>\n", image->filename); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<div>\n"); (void) CopyMagickString(filename,image->filename,MaxTextExtent); AppendImageFormat("png",filename); (void) FormatLocaleString(buffer,MaxTextExtent,"<img usemap=\"#%s\" " "src=\"%s\" style=\"border: 0;\" alt=\"Image map\" />\n",mapname, filename); (void) WriteBlobString(image,buffer); /* Determine the size and location of each image tile. */ SetGeometry(image,&geometry); if (image->montage != (char *) NULL) (void) ParseAbsoluteGeometry(image->montage,&geometry); /* Write an image map. */ (void) FormatLocaleString(buffer,MaxTextExtent, "<map id=\"%s\" name=\"%s\">\n",mapname,mapname); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent," <area href=\"%s",url); (void) WriteBlobString(image,buffer); if (image->directory == (char *) NULL) { (void) FormatLocaleString(buffer,MaxTextExtent, "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n", image->filename,(double) geometry.width-1,(double) geometry.height- 1); (void) WriteBlobString(image,buffer); } else for (p=image->directory; *p != '\0'; p++) if (*p != '\n') (void) WriteBlobByte(image,(unsigned char) *p); else { (void) FormatLocaleString(buffer,MaxTextExtent,"\" shape=" "\"rect\" coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n", (double) geometry.x,(double) geometry.y,(double) (geometry.x+ geometry.width-1),(double) (geometry.y+geometry.height-1)); (void) WriteBlobString(image,buffer); if (*(p+1) != '\0') { (void) FormatLocaleString(buffer,MaxTextExtent, " <area href=%s\"",url); (void) WriteBlobString(image,buffer); } geometry.x+=(ssize_t) geometry.width; if ((geometry.x+4) >= (ssize_t) image->columns) { geometry.x=0; geometry.y+=(ssize_t) geometry.height; } } (void) WriteBlobString(image,"</map>\n"); (void) CopyMagickString(filename,image->filename,MaxTextExtent); (void) WriteBlobString(image,"</div>\n"); (void) WriteBlobString(image,"</body>\n"); (void) WriteBlobString(image,"</html>\n"); (void) CloseBlob(image); /* Write the image as PNG. */ (void) CopyMagickString(image->filename,filename,MaxTextExtent); AppendImageFormat("png",image->filename); next=GetNextImageInList(image); image->next=NewImageList(); (void) CopyMagickString(image->magick,"PNG",MaxTextExtent); (void) WriteImage(write_info,image); image->next=next; /* Determine image map filename. */ GetPathComponent(image->filename,BasePath,filename); (void) ConcatenateMagickString(filename,"_map.shtml",MaxTextExtent); (void) CopyMagickString(image->filename,filename,MaxTextExtent); } /* Open image map. */ status=OpenBlob(write_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); write_info=DestroyImageInfo(write_info); /* Determine the size and location of each image tile. */ SetGeometry(image,&geometry); if (image->montage != (char *) NULL) (void) ParseAbsoluteGeometry(image->montage,&geometry); /* Write an image map. */ (void) FormatLocaleString(buffer,MaxTextExtent, "<map id=\"%s\" name=\"%s\">\n",mapname,mapname); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent," <area href=\"%s",url); (void) WriteBlobString(image,buffer); if (image->directory == (char *) NULL) { (void) FormatLocaleString(buffer,MaxTextExtent, "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n", image->filename,(double) geometry.width-1,(double) geometry.height-1); (void) WriteBlobString(image,buffer); } else for (p=image->directory; *p != '\0'; p++) if (*p != '\n') (void) WriteBlobByte(image,(unsigned char) *p); else { (void) FormatLocaleString(buffer,MaxTextExtent,"\" shape=\"rect\"" " coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n", (double) geometry.x,(double) geometry.y,geometry.x+(double) geometry.width-1,geometry.y+(double) geometry.height-1); (void) WriteBlobString(image,buffer); if (*(p+1) != '\0') { (void) FormatLocaleString(buffer,MaxTextExtent, " <area href=%s\"",url); (void) WriteBlobString(image,buffer); } geometry.x+=(ssize_t) geometry.width; if ((geometry.x+4) >= (ssize_t) image->columns) { geometry.x=0; geometry.y+=(ssize_t) geometry.height; } } (void) WriteBlobString(image,"</map>\n"); (void) CloseBlob(image); (void) CopyMagickString(image->filename,filename,MaxTextExtent); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + A c q u i r e W a n d C L I % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireMagickCLI() creates a new CLI wand (an expanded form of Magick % Wand). The given image_info and exception is included as is if provided. % % Use DestroyMagickCLI() to dispose of the CLI wand when it is no longer % needed. % % The format of the NewMagickWand method is: % % MagickCLI *AcquireMagickCLI(ImageInfo *image_info, % ExceptionInfo *exception) % */ WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info, ExceptionInfo *exception) { MagickCLI *cli_wand; /* precaution - as per NewMagickWand() */ { size_t depth = MAGICKCORE_QUANTUM_DEPTH; const char *quantum = GetMagickQuantumDepth(&depth); if (depth != MAGICKCORE_QUANTUM_DEPTH) ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum); } /* allocate memory for MgaickCLI */ cli_wand=(MagickCLI *) AcquireMagickMemory(sizeof(*cli_wand)); if (cli_wand == (MagickCLI *) NULL) { ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", GetExceptionMessage(errno)); return((MagickCLI *)NULL); } /* Initialize Wand Part of MagickCLI FUTURE: this is a repeat of code from NewMagickWand() However some parts may be given fro man external source! */ cli_wand->wand.id=AcquireWandId(); (void) FormatLocaleString(cli_wand->wand.name,MaxTextExtent, "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id); cli_wand->wand.images=NewImageList(); if ( image_info == (ImageInfo *)NULL) cli_wand->wand.image_info=AcquireImageInfo(); else cli_wand->wand.image_info=image_info; if ( exception == (ExceptionInfo *)NULL) cli_wand->wand.exception=AcquireExceptionInfo(); else cli_wand->wand.exception=exception; cli_wand->wand.debug=IsEventLogging(); cli_wand->wand.signature=WandSignature; /* Initialize CLI Part of MagickCLI */ cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL); cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info); cli_wand->process_flags=MagickCommandOptionFlags; /* assume "magick" CLI */ cli_wand->command=(const OptionInfo *)NULL; /* no option at this time */ cli_wand->image_list_stack=(Stack *)NULL; cli_wand->image_info_stack=(Stack *)NULL; /* default exception location... EG: sprintf(locaiton, filename, line, column); */ cli_wand->location="from \"%s\""; /* location format using arguments: */ /* filename, line, column */ cli_wand->filename="unknown"; /* script filename, unknown source */ cli_wand->line=0; /* line from script OR CLI argument */ cli_wand->column=0; /* column from script */ cli_wand->signature=WandSignature; if (IfMagickTrue(cli_wand->wand.debug)) (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); return(cli_wand); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d J N X I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadJNXImage() reads an image in the Garmin tile storage format and returns % it. It allocates the memory necessary for the new Image structure and % returns a pointer to the new image. % % The format of the ReadJNXImage method is: % % Image *ReadJNXImage(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. % */ static Image *ReadJNXImage(const ImageInfo *image_info,ExceptionInfo *exception) { #define JNXMaxLevels 20 Image *image, *images; JNXInfo jnx_info; JNXLevelInfo jnx_level_info[JNXMaxLevels]; MagickBooleanType status; register ssize_t i; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read JNX header. */ (void) ResetMagickMemory(&jnx_info,0,sizeof(jnx_info)); jnx_info.version=(int) ReadBlobLSBLong(image); if ((jnx_info.version != 3) && (jnx_info.version != 4)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); jnx_info.serial=(int) ReadBlobLSBLong(image); jnx_info.northeast.x=180.0*((int) ReadBlobLSBLong(image))/0x7fffffff; jnx_info.northeast.y=180.0*((int) ReadBlobLSBLong(image))/0x7fffffff; jnx_info.southwest.x=180.0*((int) ReadBlobLSBLong(image))/0x7fffffff; jnx_info.southwest.y=180.0*((int) ReadBlobLSBLong(image))/0x7fffffff; jnx_info.levels=(int) ReadBlobLSBLong(image); if (jnx_info.levels > JNXMaxLevels) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); jnx_info.expire=(int) ReadBlobLSBLong(image); jnx_info.id=(int) ReadBlobLSBLong(image); jnx_info.crc=(int) ReadBlobLSBLong(image); jnx_info.signature=(int) ReadBlobLSBLong(image); jnx_info.offset=ReadBlobLSBLong(image); if (jnx_info.version > 3) jnx_info.order=(int) ReadBlobLSBLong(image); else if (jnx_info.version == 3) jnx_info.order=30; /* Read JNX levels. */ (void) ResetMagickMemory(&jnx_level_info,0,sizeof(jnx_level_info)); for (i=0; i < (ssize_t) jnx_info.levels; i++) { jnx_level_info[i].count=(int) ReadBlobLSBLong(image); if (jnx_level_info[i].count > 50000) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); jnx_level_info[i].offset=(int) ReadBlobLSBLong(image); jnx_level_info[i].scale=ReadBlobLSBLong(image); if (jnx_info.version > 3) { register ssize_t j; unsigned short c; (void) ReadBlobLSBLong(image); j=0; while ((c=ReadBlobLSBShort(image)) != 0) if (j < (MagickPathExtent-1)) jnx_level_info[i].copyright[j++]=c; jnx_level_info[i].copyright[j]=0; } } /* Read JNX tiles. */ images=NewImageList(); for (i=0; i < (ssize_t) jnx_info.levels; i++) { MagickOffsetType offset; register ssize_t j; offset=SeekBlob(image,(MagickOffsetType) jnx_level_info[i].offset,SEEK_SET); if (offset != (MagickOffsetType) jnx_level_info[i].offset) continue; for (j=0; j < (ssize_t) jnx_level_info[i].count; j++) { Image *tile_image; ImageInfo *read_info; int tile_offset; MagickOffsetType restore_offset; PointInfo northeast, southwest; ssize_t count; unsigned char *blob; unsigned int tile_length; northeast.x=180.0*((int) ReadBlobLSBLong(image))/0x7fffffff; northeast.y=180.0*((int) ReadBlobLSBLong(image))/0x7fffffff; southwest.x=180.0*((int) ReadBlobLSBLong(image))/0x7fffffff; southwest.y=180.0*((int) ReadBlobLSBLong(image))/0x7fffffff; (void) ReadBlobLSBShort(image); /* width */ (void) ReadBlobLSBShort(image); /* height */ tile_length=ReadBlobLSBLong(image); tile_offset=(int) ReadBlobLSBLong(image); if (tile_offset == -1) continue; restore_offset=TellBlob(image); if (restore_offset < 0) continue; offset=SeekBlob(image,(MagickOffsetType) tile_offset,SEEK_SET); if (offset != (MagickOffsetType) tile_offset) continue; /* Read a tile. */ blob=(unsigned char *) AcquireQuantumMemory((size_t) tile_length+2, sizeof(*blob)); if (blob == (unsigned char *) NULL) { if (images != (Image *) NULL) images=DestroyImageList(images); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } blob[0]=0xFF; blob[1]=0xD8; count=ReadBlob(image,tile_length,blob+2); if (count != (ssize_t) tile_length) { if (images != (Image *) NULL) images=DestroyImageList(images); blob=(unsigned char *) RelinquishMagickMemory(blob); ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile"); } read_info=CloneImageInfo(image_info); (void) CopyMagickString(read_info->magick,"JPEG",MagickPathExtent); tile_image=BlobToImage(read_info,blob,tile_length+2,exception); read_info=DestroyImageInfo(read_info); blob=(unsigned char *) RelinquishMagickMemory(blob); offset=SeekBlob(image,restore_offset,SEEK_SET); if (tile_image == (Image *) NULL) continue; (void) CopyMagickString(tile_image->magick,image->magick,MagickPathExtent); (void) FormatImageProperty(tile_image,"jnx:northeast","%.20g,%.20g", northeast.x,northeast.y); (void) FormatImageProperty(tile_image,"jnx:southwest","%.20g,%.20g", southwest.x,southwest.y); AppendImageToList(&images,tile_image); } if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType) i, (MagickSizeType) jnx_info.levels); if (proceed == MagickFalse) status=MagickFalse; } } (void) CloseBlob(image); image=DestroyImage(image); if (images == (Image *) NULL) return((Image *) NULL); return(GetFirstImageInList(images)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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(ImageInfo *image_info,const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o filename: the image filename. % % o exception: return any errors or warnings in this structure. % */ MagickExport Image *ReadImages(ImageInfo *image_info,const char *filename, ExceptionInfo *exception) { char read_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) SetImageOption(image_info,"filename",filename); (void) CopyMagickString(image_info->filename,filename,MaxTextExtent); (void) InterpretImageFilename(image_info,(Image *) NULL,filename, (int) image_info->scene,read_filename,exception); if (LocaleCompare(read_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(read_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,read_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)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d V I D I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadVIDImage reads one of more images and creates a Visual Image % Directory file. It allocates the memory necessary for the new Image % structure and returns a pointer to the new image. % % The format of the ReadVIDImage method is: % % Image *ReadVIDImage(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. % */ static Image *ReadVIDImage(const ImageInfo *image_info,ExceptionInfo *exception) { #define ClientName "montage" char **filelist, *label; Image *image, *images, *montage_image, *next_image, *thumbnail_image; ImageInfo *read_info; int number_files; MagickBooleanType status; MontageInfo *montage_info; RectangleInfo geometry; register ssize_t i; /* Expand the filename. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); filelist=(char **) AcquireMagickMemory(sizeof(*filelist)); if (filelist == (char **) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); filelist[0]=ConstantString(image_info->filename); number_files=1; status=ExpandFilenames(&number_files,&filelist); if ((status == MagickFalse) || (number_files == 0)) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); image=DestroyImage(image); /* Read each image and convert them to a tile. */ images=NewImageList(); read_info=CloneImageInfo(image_info); SetImageInfoBlob(read_info,(void *) NULL,0); (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL, (void *) NULL); if (read_info->size == (char *) NULL) (void) CloneString(&read_info->size,DefaultTileGeometry); for (i=0; i < (ssize_t) number_files; i++) { if (image_info->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(),"name: %s", filelist[i]); (void) CopyMagickString(read_info->filename,filelist[i],MaxTextExtent); filelist[i]=DestroyString(filelist[i]); *read_info->magick='\0'; next_image=ReadImage(read_info,exception); CatchException(exception); if (next_image == (Image *) NULL) break; label=InterpretImageProperties(image_info,next_image,DefaultTileLabel); (void) SetImageProperty(next_image,"label",label); label=DestroyString(label); if (image_info->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "geometry: %.20gx%.20g",(double) next_image->columns,(double) next_image->rows); SetGeometry(next_image,&geometry); (void) ParseMetaGeometry(read_info->size,&geometry.x,&geometry.y, &geometry.width,&geometry.height); thumbnail_image=ThumbnailImage(next_image,geometry.width,geometry.height, exception); if (thumbnail_image != (Image *) NULL) { next_image=DestroyImage(next_image); next_image=thumbnail_image; } if (image_info->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "thumbnail geometry: %.20gx%.20g",(double) next_image->columns,(double) next_image->rows); AppendImageToList(&images,next_image); status=SetImageProgress(images,LoadImagesTag,i,number_files); if (status == MagickFalse) break; } read_info=DestroyImageInfo(read_info); filelist=(char **) RelinquishMagickMemory(filelist); if (images == (Image *) NULL) ThrowReaderException(CorruptImageError, "ImageFileDoesNotContainAnyImageData"); /* Create the visual image directory. */ montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL); if (image_info->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(),"creating montage"); montage_image=MontageImageList(image_info,montage_info, GetFirstImageInList(images),exception); montage_info=DestroyMontageInfo(montage_info); images=DestroyImageList(images); return(montage_image); }
int tc_filter(frame_list_t *ptr_, char *options) { vframe_list_t *ptr = (vframe_list_t *)ptr_; vob_t *vob = NULL; int instance = ptr->filter_id; MyFilterData *mfd = mfd_all[instance]; if (mfd != NULL) { vob = mfd->vob; } //---------------------------------- // // filter init // //---------------------------------- if (ptr->tag & TC_FILTER_GET_CONFIG) { optstr_filter_desc(options, MOD_NAME, MOD_CAP, MOD_VERSION, MOD_AUTHOR, "VRYO", "1"); // buf, name, comment, format, val, from, to optstr_param(options, "file", "Image filename", "%s", "logo.png"); optstr_param(options, "posdef", "Position (0=None, 1=TopL, 2=TopR, 3=BotL, 4=BotR, 5=Center)", "%d", "0", "0", "5"); optstr_param(options, "pos", "Position (0-width x 0-height)", "%dx%d", "0x0", "0", "width", "0", "height"); optstr_param(options, "range", "Restrict rendering to framerange", "%u-%u", "0-0", "0", "oo", "0", "oo"); optstr_param(options, "fade", "Fade image in/out (# of frames)", "%u-%u", "0-0", "0", "oo", "0", "oo"); // bools optstr_param(options, "ignoredelay", "Ignore delay specified in animations", "", "0"); optstr_param(options, "rgbswap", "Swap red/blue colors", "", "0"); optstr_param(options, "grayout", "YUV only: don't write Cb and Cr, makes a nice effect", "", "0"); optstr_param(options, "hqconv", "YUV only: do high quality rgb->yuv img conversion", "", "0"); optstr_param(options, "flip", "Mirror image", "", "0"); return 0; } if (ptr->tag & TC_FILTER_INIT) { Image *timg; Image *nimg; ImageInfo *image_info; ExceptionInfo exception_info; int rgb_off = 0; vob_t *tmpvob; tmpvob = tc_get_vob(); if (tmpvob == NULL) return -1; mfd_all[instance] = tc_zalloc(sizeof(MyFilterData)); if (mfd_all[instance] == NULL) return -1; mfd = mfd_all[instance]; strlcpy(mfd->file, "logo.png", PATH_MAX); mfd->end = (unsigned int)-1; mfd->vob = tmpvob; vob = mfd->vob; if (options != NULL) { if (verbose) tc_log_info(MOD_NAME, "options=%s", options); optstr_get(options, "file", "%[^:]", mfd->file); optstr_get(options, "posdef", "%d", (int *)&mfd->pos); optstr_get(options, "pos", "%dx%d", &mfd->posx, &mfd->posy); optstr_get(options, "range", "%u-%u", &mfd->start, &mfd->end); optstr_get(options, "fade", "%u-%u", &mfd->fadein, &mfd->fadeout); if (optstr_lookup(options, "ignoredelay") != NULL) mfd->ignoredelay = !mfd->ignoredelay; if (optstr_lookup(options, "flip") != NULL) mfd->flip = !mfd->flip; if (optstr_lookup(options, "rgbswap") != NULL) mfd->rgbswap = !mfd->rgbswap; if (optstr_lookup(options, "grayout") != NULL) mfd->grayout = !mfd->grayout; if (optstr_lookup(options, "hqconv") != NULL) mfd->hqconv = !mfd->hqconv; if (optstr_lookup (options, "help") != NULL) flogo_help_optstr(); } if (verbose > 1) { tc_log_info(MOD_NAME, " Logo renderer Settings:"); tc_log_info(MOD_NAME, " file = %s", mfd->file); tc_log_info(MOD_NAME, " posdef = %d", mfd->pos); tc_log_info(MOD_NAME, " pos = %dx%d", mfd->posx, mfd->posy); tc_log_info(MOD_NAME, " range = %u-%u", mfd->start, mfd->end); tc_log_info(MOD_NAME, " fade = %u-%u", mfd->fadein, mfd->fadeout); tc_log_info(MOD_NAME, " flip = %d", mfd->flip); tc_log_info(MOD_NAME, " ignoredelay = %d", mfd->ignoredelay); tc_log_info(MOD_NAME, " rgbswap = %d", mfd->rgbswap); tc_log_info(MOD_NAME, " grayout = %d", mfd->grayout); tc_log_info(MOD_NAME, " hqconv = %d", mfd->hqconv); } /* Transcode serializes module execution, so this does not need a * semaphore. */ magick_usecount++; if (!IsMagickInstantiated()) { InitializeMagick(""); } GetExceptionInfo(&exception_info); image_info = CloneImageInfo((ImageInfo *) NULL); strlcpy(image_info->filename, mfd->file, MaxTextExtent); mfd->image = ReadImage(image_info, &exception_info); if (mfd->image == (Image *) NULL) { MagickWarning(exception_info.severity, exception_info.reason, exception_info.description); strlcpy(mfd->file, "/dev/null", PATH_MAX); return 0; } DestroyImageInfo(image_info); if (mfd->image->columns > vob->ex_v_width || mfd->image->rows > vob->ex_v_height ) { tc_log_error(MOD_NAME, "\"%s\" is too large", mfd->file); return -1; } if (vob->im_v_codec == TC_CODEC_YUV420P) { if ((mfd->image->columns & 1) || (mfd->image->rows & 1)) { tc_log_error(MOD_NAME, "\"%s\" has odd sizes", mfd->file); return -1; } } mfd->images = (Image *)GetFirstImageInList(mfd->image); nimg = NewImageList(); while (mfd->images != (Image *)NULL) { if (mfd->flip || flip) { timg = FlipImage(mfd->images, &exception_info); if (timg == (Image *) NULL) { MagickError(exception_info.severity, exception_info.reason, exception_info.description); return -1; } AppendImageToList(&nimg, timg); } mfd->images = GetNextImageInList(mfd->images); mfd->nr_of_images++; } // check for memleaks; //DestroyImageList(image); if (mfd->flip || flip) { mfd->image = nimg; } /* initial delay. real delay = 1/100 sec * delay */ mfd->cur_delay = mfd->image->delay*vob->fps/100; if (verbose & TC_DEBUG) tc_log_info(MOD_NAME, "Nr: %d Delay: %d mfd->image->del %lu|", mfd->nr_of_images, mfd->cur_delay, mfd->image->delay); if (vob->im_v_codec == TC_CODEC_YUV420P) { /* convert Magick RGB image format to YUV */ /* todo: convert the magick image if it's not rgb! (e.g. cmyk) */ Image *image; uint8_t *yuv_hqbuf = NULL; /* Round up for odd-size images */ unsigned long width = mfd->image->columns; unsigned long height = mfd->image->rows; int do_rgbswap = (rgbswap || mfd->rgbswap); int i; /* Allocate buffers for the YUV420P frames. mfd->nr_of_images * will be 1 unless this is an animated GIF or MNG. * This buffer needs to be large enough to store a temporary * 24-bit RGB image (extracted from the ImageMagick handle). */ mfd->yuv = flogo_yuvbuf_alloc(width*height * 3, mfd->nr_of_images); if (mfd->yuv == NULL) { tc_log_error(MOD_NAME, "(%d) out of memory\n", __LINE__); return -1; } if (mfd->hqconv) { /* One temporary buffer, to hold full Y, U, and V planes. */ yuv_hqbuf = tc_malloc(width*height * 3); if (yuv_hqbuf == NULL) { tc_log_error(MOD_NAME, "(%d) out of memory\n", __LINE__); return -1; } } mfd->tcvhandle = tcv_init(); if (mfd->tcvhandle == NULL) { tc_log_error(MOD_NAME, "image conversion init failed"); return -1; } image = GetFirstImageInList(mfd->image); for (i = 0; i < mfd->nr_of_images; i++) { if (!mfd->hqconv) { flogo_convert_image(mfd->tcvhandle, image, mfd->yuv[i], IMG_YUV420P, do_rgbswap); } else { flogo_convert_image(mfd->tcvhandle, image, yuv_hqbuf, IMG_YUV444P, do_rgbswap); // Copy over Y data from the 444 image ac_memcpy(mfd->yuv[i], yuv_hqbuf, width * height); // Resize U plane by 1/2 in each dimension, into the // mfd YUV buffer tcv_zoom(mfd->tcvhandle, yuv_hqbuf + (width * height), mfd->yuv[i] + (width * height), width, height, 1, width / 2, height / 2, TCV_ZOOM_LANCZOS3 ); // Do the same with the V plane tcv_zoom(mfd->tcvhandle, yuv_hqbuf + 2*width*height, mfd->yuv[i] + width*height + (width/2)*(height/2), width, height, 1, width / 2, height / 2, TCV_ZOOM_LANCZOS3 ); } image = GetNextImageInList(image); } if (mfd->hqconv) tc_free(yuv_hqbuf); tcv_free(mfd->tcvhandle); } else { /* for RGB format is origin bottom left */ /* for RGB, rgbswap is done in the frame routine */ rgb_off = vob->ex_v_height - mfd->image->rows; mfd->posy = rgb_off - mfd->posy; } switch (mfd->pos) { case NONE: /* 0 */ break; case TOP_LEFT: mfd->posx = 0; mfd->posy = rgb_off; break; case TOP_RIGHT: mfd->posx = vob->ex_v_width - mfd->image->columns; break; case BOT_LEFT: mfd->posy = vob->ex_v_height - mfd->image->rows - rgb_off; break; case BOT_RIGHT: mfd->posx = vob->ex_v_width - mfd->image->columns; mfd->posy = vob->ex_v_height - mfd->image->rows - rgb_off; break; case CENTER: mfd->posx = (vob->ex_v_width - mfd->image->columns)/2; mfd->posy = (vob->ex_v_height- mfd->image->rows)/2; /* align to not cause color disruption */ if (mfd->posx & 1) mfd->posx++; if (mfd->posy & 1) mfd->posy++; break; } if (mfd->posy < 0 || mfd->posx < 0 || (mfd->posx + mfd->image->columns) > vob->ex_v_width || (mfd->posy + mfd->image->rows) > vob->ex_v_height) { tc_log_error(MOD_NAME, "invalid position"); return -1; } /* for running through image sequence */ mfd->images = mfd->image; /* Set up image/video coefficient lookup tables */ if (img_coeff_lookup[0] < 0) { int i; float maxrgbval = (float)MaxRGB; // from ImageMagick for (i = 0; i <= MAX_UINT8_VAL; i++) { float x = (float)ScaleCharToQuantum(i); /* Alternatively: * img_coeff = (maxrgbval - x) / maxrgbval; * vid_coeff = x / maxrgbval; */ img_coeff_lookup[i] = 1.0 - (x / maxrgbval); vid_coeff_lookup[i] = 1.0 - img_coeff_lookup[i]; } } // filter init ok. if (verbose) tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP); return 0; } //---------------------------------- // // filter close // //---------------------------------- if (ptr->tag & TC_FILTER_CLOSE) { if (mfd) { flogo_yuvbuf_free(mfd->yuv, mfd->nr_of_images); mfd->yuv = NULL; if (mfd->image) { DestroyImage(mfd->image); } tc_free(mfd); mfd = NULL; mfd_all[instance] = NULL; } magick_usecount--; if (magick_usecount == 0 && IsMagickInstantiated()) { DestroyMagick(); } return 0; } /* filter close */ //---------------------------------- // // filter frame routine // //---------------------------------- // tag variable indicates, if we are called before // transcodes internal video/audo frame processing routines // or after and determines video/audio context if ((ptr->tag & TC_POST_M_PROCESS) && (ptr->tag & TC_VIDEO) && !(ptr->attributes & TC_FRAME_IS_SKIPPED) ) { PixelPacket *pixel_packet; uint8_t *video_buf; int do_fade = 0; float fade_coeff = 0.0; float img_coeff, vid_coeff; /* Note: ImageMagick defines opacity = 0 as fully visible, and * opacity = MaxRGB as fully transparent. */ Quantum opacity; int row, col; if (ptr->id < mfd->start || ptr->id > mfd->end) return 0; if (strcmp(mfd->file, "/dev/null") == 0) return 0; if (ptr->id - mfd->start < mfd->fadein) { // fading-in fade_coeff = (float)(mfd->start - ptr->id + mfd->fadein) / (float)(mfd->fadein); do_fade = 1; } else if (mfd->end - ptr->id < mfd->fadeout) { // fading-out fade_coeff = (float)(ptr->id - mfd->end + mfd->fadeout) / (float)(mfd->fadeout); do_fade = 1; } mfd->cur_delay--; if (mfd->cur_delay < 0 || mfd->ignoredelay) { int seq; mfd->cur_seq = (mfd->cur_seq + 1) % mfd->nr_of_images; mfd->images = mfd->image; for (seq=0; seq<mfd->cur_seq; seq++) mfd->images = mfd->images->next; mfd->cur_delay = mfd->images->delay * vob->fps/100; } pixel_packet = GetImagePixels(mfd->images, 0, 0, mfd->images->columns, mfd->images->rows); if (vob->im_v_codec == TC_CODEC_RGB24) { unsigned long r_off, g_off, b_off; if (!(rgbswap || mfd->rgbswap)) { r_off = 0; b_off = 2; } else { r_off = 2; b_off = 0; } g_off = 1; for (row = 0; row < mfd->image->rows; row++) { video_buf = ptr->video_buf + 3 * ((row + mfd->posy) * vob->ex_v_width + mfd->posx); for (col = 0; col < mfd->image->columns; col++) { opacity = pixel_packet->opacity; if (do_fade) opacity += (Quantum)((MaxRGB - opacity) * fade_coeff); if (opacity == 0) { *(video_buf + r_off) = ScaleQuantumToChar(pixel_packet->red); *(video_buf + g_off) = ScaleQuantumToChar(pixel_packet->green); *(video_buf + b_off) = ScaleQuantumToChar(pixel_packet->blue); } else if (opacity < MaxRGB) { unsigned char opacity_uchar = ScaleQuantumToChar(opacity); img_coeff = img_coeff_lookup[opacity_uchar]; vid_coeff = vid_coeff_lookup[opacity_uchar]; *(video_buf + r_off) = (uint8_t)((*(video_buf + r_off)) * vid_coeff) + (uint8_t)(ScaleQuantumToChar(pixel_packet->red) * img_coeff); *(video_buf + g_off) = (uint8_t)((*(video_buf + g_off)) * vid_coeff) + (uint8_t)(ScaleQuantumToChar(pixel_packet->green) * img_coeff); *(video_buf + b_off) = (uint8_t)((*(video_buf + b_off)) * vid_coeff) + (uint8_t)(ScaleQuantumToChar(pixel_packet->blue) * img_coeff); } video_buf += 3; pixel_packet++; } } } else { /* !RGB */ unsigned long vid_size = vob->ex_v_width * vob->ex_v_height; unsigned long img_size = mfd->images->columns * mfd->images->rows; uint8_t *img_pixel_Y, *img_pixel_U, *img_pixel_V; uint8_t *vid_pixel_Y, *vid_pixel_U, *vid_pixel_V; img_pixel_Y = mfd->yuv[mfd->cur_seq]; img_pixel_U = img_pixel_Y + img_size; img_pixel_V = img_pixel_U + img_size/4; for (row = 0; row < mfd->images->rows; row++) { vid_pixel_Y = ptr->video_buf + (row + mfd->posy)*mfd->vob->ex_v_width + mfd->posx; vid_pixel_U = ptr->video_buf + vid_size + (row/2 + mfd->posy/2)*(mfd->vob->ex_v_width/2) + mfd->posx/2; vid_pixel_V = vid_pixel_U + vid_size/4; for (col = 0; col < mfd->images->columns; col++) { int do_UV_pixels = (mfd->grayout == 0 && !(row % 2) && !(col % 2)) ? 1 : 0; opacity = pixel_packet->opacity; if (do_fade) opacity += (Quantum)((MaxRGB - opacity) * fade_coeff); if (opacity == 0) { *vid_pixel_Y = *img_pixel_Y; if (do_UV_pixels) { *vid_pixel_U = *img_pixel_U; *vid_pixel_V = *img_pixel_V; } } else if (opacity < MaxRGB) { unsigned char opacity_uchar = ScaleQuantumToChar(opacity); img_coeff = img_coeff_lookup[opacity_uchar]; vid_coeff = vid_coeff_lookup[opacity_uchar]; *vid_pixel_Y = (uint8_t)(*vid_pixel_Y * vid_coeff) + (uint8_t)(*img_pixel_Y * img_coeff); if (do_UV_pixels) { *vid_pixel_U = (uint8_t)(*vid_pixel_U * vid_coeff) + (uint8_t)(*img_pixel_U * img_coeff); *vid_pixel_V = (uint8_t)(*vid_pixel_V * vid_coeff) + (uint8_t)(*img_pixel_V * img_coeff); } } vid_pixel_Y++; img_pixel_Y++; if (do_UV_pixels) { vid_pixel_U++; img_pixel_U++; vid_pixel_V++; img_pixel_V++; } pixel_packet++; } } } } return 0; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % I d e n t i f y I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % IdentifyImage() identifies an image by printing its attributes to the file. % Attributes include the image width, height, size, and others. % % The format of the IdentifyImage method is: % % MagickBooleanType IdentifyImage(Image *image,FILE *file, % const MagickBooleanType verbose) % % A description of each parameter follows: % % o image: The image. % % o file: The file, typically stdout. % % o verbose: A value other than zero prints more detailed information % about the image. % */ MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file, const MagickBooleanType verbose) { #define IdentifyFormat " %s:\n Min: " QuantumFormat \ " (%g)\n Max: " QuantumFormat " (%g)\n" \ " Mean: %g (%g)\n Standard deviation: %g (%g)\n" char color[MaxTextExtent], format[MaxTextExtent], key[MaxTextExtent]; ColorspaceType colorspace; const char *property, *value; const MagickInfo *magick_info; const PixelPacket *pixels; double elapsed_time, user_time; ExceptionInfo *exception; Image *p; ImageType type; long y; MagickBooleanType ping; register long i, x; unsigned long scale; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); if (file == (FILE *) NULL) file=stdout; *format='\0'; elapsed_time=GetElapsedTime(&image->timer); user_time=GetUserTime(&image->timer); GetTimerInfo(&image->timer); if (verbose == MagickFalse) { /* Display summary info about the image. */ if (*image->magick_filename != '\0') if (LocaleCompare(image->magick_filename,image->filename) != 0) (void) fprintf(file,"%s=>",image->magick_filename); if ((GetPreviousImageInList(image) == (Image *) NULL) && (GetNextImageInList(image) == (Image *) NULL) && (image->scene == 0)) (void) fprintf(file,"%s ",image->filename); else (void) fprintf(file,"%s[%lu] ",image->filename,image->scene); (void) fprintf(file,"%s ",image->magick); if ((image->magick_columns != 0) || (image->magick_rows != 0)) if ((image->magick_columns != image->columns) || (image->magick_rows != image->rows)) (void) fprintf(file,"%lux%lu=>",image->magick_columns, image->magick_rows); (void) fprintf(file,"%lux%lu ",image->columns,image->rows); if ((image->page.width != 0) || (image->page.height != 0) || (image->page.x != 0) || (image->page.y != 0)) (void) fprintf(file,"%lux%lu%+ld%+ld ",image->page.width, image->page.height,image->page.x,image->page.y); if (image->storage_class == DirectClass) { (void) fprintf(file,"DirectClass "); if (image->total_colors != 0) { (void) FormatMagickSize(image->total_colors,format); (void) fprintf(file,"%s ",format); } } else if (image->total_colors <= image->colors) (void) fprintf(file,"PseudoClass %luc ",image->colors); else (void) fprintf(file,"PseudoClass %lu=>%luc ",image->total_colors, image->colors); (void) fprintf(file,"%lu-bit ",image->depth); if (image->error.mean_error_per_pixel != 0.0) (void) fprintf(file,"%ld/%f/%fdb ", (long) (image->error.mean_error_per_pixel+0.5), image->error.normalized_mean_error, image->error.normalized_maximum_error); if (GetBlobSize(image) != 0) { (void) FormatMagickSize(GetBlobSize(image),format); (void) fprintf(file,"%s ",format); } if (elapsed_time > 0.06) (void) fprintf(file,"%0.3fu %ld:%02ld",user_time, (long) (elapsed_time/60.0+0.5),(long) ceil(fmod(elapsed_time,60.0))); (void) fprintf(file,"\n"); (void) fflush(file); return(ferror(file) != 0 ? MagickFalse : MagickTrue); } /* Display verbose info about the image. */ exception=AcquireExceptionInfo(); pixels=AcquireImagePixels(image,0,0,1,1,exception); exception=DestroyExceptionInfo(exception); ping=pixels == (const PixelPacket *) NULL ? MagickTrue : MagickFalse; type=GetImageType(image,&image->exception); (void) SignatureImage(image); (void) fprintf(file,"Image: %s\n",image->filename); if (*image->magick_filename != '\0') if (LocaleCompare(image->magick_filename,image->filename) != 0) { char filename[MaxTextExtent]; GetPathComponent(image->magick_filename,TailPath,filename); (void) fprintf(file," Base filename: %s\n",filename); } magick_info=GetMagickInfo(image->magick,&image->exception); if ((magick_info == (const MagickInfo *) NULL) || (*GetMagickDescription(magick_info) == '\0')) (void) fprintf(file," Format: %s\n",image->magick); else (void) fprintf(file," Format: %s (%s)\n",image->magick, GetMagickDescription(magick_info)); (void) fprintf(file," Class: %s\n", MagickOptionToMnemonic(MagickClassOptions,(long) image->storage_class)); (void) fprintf(file," Geometry: %lux%lu%+ld%+ld\n",image->columns, image->rows,image->tile_offset.x,image->tile_offset.y); if ((image->magick_columns != 0) || (image->magick_rows != 0)) if ((image->magick_columns != image->columns) || (image->magick_rows != image->rows)) (void) fprintf(file," Base geometry: %lux%lu\n",image->magick_columns, image->magick_rows); (void) fprintf(file," Type: %s\n",MagickOptionToMnemonic(MagickTypeOptions, (long) type)); (void) fprintf(file," Endianess: %s\n",MagickOptionToMnemonic( MagickEndianOptions,(long) image->endian)); /* Detail channel depth and extrema. */ colorspace=image->colorspace; if (IsGrayImage(image,&image->exception) != MagickFalse) colorspace=GRAYColorspace; (void) fprintf(file," Colorspace: %s\n", MagickOptionToMnemonic(MagickColorspaceOptions,(long) colorspace)); if (ping == MagickFalse) { ChannelStatistics *channel_statistics; (void) fprintf(file," Depth: %lu-bit\n",GetImageDepth(image, &image->exception)); channel_statistics=GetImageChannelStatistics(image,&image->exception); (void) fprintf(file," Channel depth:\n"); switch (colorspace) { case RGBColorspace: default: { (void) fprintf(file," Red: %lu-bit\n", channel_statistics[RedChannel].depth); (void) fprintf(file," Green: %lu-bit\n", channel_statistics[GreenChannel].depth); (void) fprintf(file," Blue: %lu-bit\n", channel_statistics[BlueChannel].depth); if (image->matte != MagickFalse) (void) fprintf(file," Alpha: %lu-bit\n", channel_statistics[OpacityChannel].depth); break; } case CMYKColorspace: { (void) fprintf(file," Cyan: %lu-bit\n", channel_statistics[CyanChannel].depth); (void) fprintf(file," Magenta: %lu-bit\n", channel_statistics[MagentaChannel].depth); (void) fprintf(file," Yellow: %lu-bit\n", channel_statistics[YellowChannel].depth); (void) fprintf(file," Black: %lu-bit\n", channel_statistics[BlackChannel].depth); if (image->matte != MagickFalse) (void) fprintf(file," Alpha: %lu-bit\n", channel_statistics[OpacityChannel].depth); break; } case GRAYColorspace: { (void) fprintf(file," Gray: %lu-bit\n", channel_statistics[GrayChannel].depth); if (image->matte != MagickFalse) (void) fprintf(file," Alpha: %lu-bit\n", channel_statistics[OpacityChannel].depth); break; } } scale=QuantumRange/((unsigned long) QuantumRange >> ((unsigned long) MAGICKCORE_QUANTUM_DEPTH-channel_statistics[AllChannels].depth)); (void) fprintf(file," Channel statistics:\n"); switch (colorspace) { case RGBColorspace: default: { (void) fprintf(file,IdentifyFormat,"Red",(Quantum) (channel_statistics[RedChannel].minima/scale),(double) channel_statistics[RedChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[RedChannel].maxima/scale),(double) channel_statistics[RedChannel].maxima/(double) QuantumRange, channel_statistics[RedChannel].mean/(double) scale, channel_statistics[RedChannel].mean/(double) QuantumRange, channel_statistics[RedChannel].standard_deviation/(double) scale, channel_statistics[RedChannel].standard_deviation/(double) QuantumRange); (void) fprintf(file,IdentifyFormat,"Green",(Quantum) (channel_statistics[GreenChannel].minima/scale),(double) channel_statistics[GreenChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[GreenChannel].maxima/scale),(double) channel_statistics[GreenChannel].maxima/(double) QuantumRange, channel_statistics[GreenChannel].mean/(double) scale, channel_statistics[GreenChannel].mean/(double) QuantumRange, channel_statistics[GreenChannel].standard_deviation/(double) scale, channel_statistics[GreenChannel].standard_deviation/(double) QuantumRange); (void) fprintf(file,IdentifyFormat,"Blue",(Quantum) (channel_statistics[BlueChannel].minima/scale),(double) channel_statistics[BlueChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[BlueChannel].maxima/scale),(double) channel_statistics[BlueChannel].maxima/(double) QuantumRange, channel_statistics[BlueChannel].mean/(double) scale, channel_statistics[BlueChannel].mean/(double) QuantumRange, channel_statistics[BlueChannel].standard_deviation/(double) scale, channel_statistics[BlueChannel].standard_deviation/(double) QuantumRange); break; } case CMYKColorspace: { (void) fprintf(file,IdentifyFormat,"Cyan",(Quantum) (channel_statistics[CyanChannel].minima/scale),(double) channel_statistics[CyanChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[CyanChannel].maxima/scale),(double) channel_statistics[CyanChannel].maxima/(double) QuantumRange, channel_statistics[CyanChannel].mean/(double) scale, channel_statistics[CyanChannel].mean/(double) QuantumRange, channel_statistics[CyanChannel].standard_deviation/(double) scale, channel_statistics[CyanChannel].standard_deviation/(double) QuantumRange); (void) fprintf(file,IdentifyFormat,"Magenta",(Quantum) (channel_statistics[MagentaChannel].minima/scale),(double) channel_statistics[MagentaChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[MagentaChannel].maxima/scale),(double) channel_statistics[MagentaChannel].maxima/(double) QuantumRange, channel_statistics[MagentaChannel].mean/(double) scale, channel_statistics[MagentaChannel].mean/(double) QuantumRange, channel_statistics[MagentaChannel].standard_deviation/(double) scale,channel_statistics[MagentaChannel].standard_deviation/(double) QuantumRange); (void) fprintf(file,IdentifyFormat,"Yellow",(Quantum) (channel_statistics[YellowChannel].minima/scale),(double) channel_statistics[YellowChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[YellowChannel].maxima/scale),(double) channel_statistics[YellowChannel].maxima/(double) QuantumRange, channel_statistics[YellowChannel].mean/(double) scale, channel_statistics[YellowChannel].mean/(double) QuantumRange, channel_statistics[YellowChannel].standard_deviation/(double) scale, channel_statistics[YellowChannel].standard_deviation/(double) QuantumRange); (void) fprintf(file,IdentifyFormat,"Black",(Quantum) (channel_statistics[BlackChannel].minima/scale),(double) channel_statistics[BlackChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[BlackChannel].maxima/scale),(double) channel_statistics[BlackChannel].maxima/(double) QuantumRange, channel_statistics[BlackChannel].mean/(double) scale, channel_statistics[BlackChannel].mean/(double) QuantumRange, channel_statistics[BlackChannel].standard_deviation/(double) scale, channel_statistics[BlackChannel].standard_deviation/(double) QuantumRange); break; } case GRAYColorspace: { (void) fprintf(file,IdentifyFormat,"Gray",(Quantum) (channel_statistics[GrayChannel].minima/scale),(double) channel_statistics[GrayChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[GrayChannel].maxima/scale),(double) channel_statistics[GrayChannel].maxima/(double) QuantumRange, channel_statistics[GrayChannel].mean/(double) scale, channel_statistics[GrayChannel].mean/(double) QuantumRange, channel_statistics[GrayChannel].standard_deviation/(double) scale, channel_statistics[GrayChannel].standard_deviation/(double) QuantumRange); break; } } if (image->matte != MagickFalse) (void) fprintf(file,IdentifyFormat,"Opacity",(Quantum) (channel_statistics[OpacityChannel].minima/scale),(double) channel_statistics[OpacityChannel].minima/(double) QuantumRange, (Quantum) (channel_statistics[OpacityChannel].maxima/scale),(double) channel_statistics[OpacityChannel].maxima/(double) QuantumRange, channel_statistics[OpacityChannel].mean/(double) scale, channel_statistics[OpacityChannel].mean/(double) QuantumRange, channel_statistics[OpacityChannel].standard_deviation/(double) scale, channel_statistics[OpacityChannel].standard_deviation/(double) QuantumRange); channel_statistics=(ChannelStatistics *) RelinquishMagickMemory( channel_statistics); if (colorspace == CMYKColorspace) (void) fprintf(file," Total ink density: %.0f%%\n",100.0* GetImageTotalInkDensity(image)/(double) QuantumRange); x=0; p=NewImageList(); if (image->matte != MagickFalse) { register const IndexPacket *indexes; register const PixelPacket *p; p=(PixelPacket *) NULL; indexes=(IndexPacket *) NULL; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=AcquireIndexes(image); for (x=0; x < (long) image->columns; x++) { if (p->opacity == (Quantum) TransparentOpacity) break; p++; } if (x < (long) image->columns) break; } if ((x < (long) image->columns) || (y < (long) image->rows)) { char tuple[MaxTextExtent]; MagickPixelPacket pixel; GetMagickPixelPacket(image,&pixel); SetMagickPixelPacket(image,p,indexes+x,&pixel); (void) QueryMagickColorname(image,&pixel,SVGCompliance, MagickFalse,tuple,&image->exception); (void) fprintf(file," Alpha: %s ",tuple); (void) QueryMagickColorname(image,&pixel,SVGCompliance,MagickTrue, tuple,&image->exception); (void) fprintf(file," %s\n",tuple); } } if ((ping == MagickFalse) && (IsHistogramImage(image,&image->exception) != MagickFalse)) { (void) fprintf(file," Histogram:\n"); (void) GetNumberColors(image,file,&image->exception); } }
WandExport MagickBooleanType ImportImageCommand(ImageInfo *image_info, int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception) { #if defined(HasX11) #define DestroyImport() \ { \ XDestroyResourceInfo(&resource_info); \ if (display != (Display *) NULL) \ { \ XCloseDisplay(display); \ display=(Display *) NULL; \ } \ for ( ; k >= 0; k--) \ image_stack[k]=DestroyImageList(image_stack[k]); \ for (i=0; i < (long) argc; i++) \ argv[i]=DestroyString(argv[i]); \ argv=(char **) RelinquishMagickMemory(argv); \ } #define ThrowImportException(asperity,tag,option) \ { \ (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \ option); \ DestroyImport(); \ return(MagickFalse); \ } #define ThrowImportInvalidArgumentException(option,argument) \ { \ (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \ "InvalidArgument","`%s': %s",argument,option); \ DestroyImport(); \ return(MagickFalse); \ } char *filename, *option, *resource_value, *server_name, *target_window; Display *display; Image *image_stack[MaxImageStackDepth+1]; long j, k, snapshots; MagickBooleanType fire, pend; MagickStatusType status; QuantizeInfo *quantize_info; register long i; XImportInfo ximage_info; XResourceInfo resource_info; XrmDatabase resource_database; /* Set defaults. */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(exception != (ExceptionInfo *) NULL); if (argc == 2) { option=argv[1]; if ((LocaleCompare("version",option+1) == 0) || (LocaleCompare("-version",option+1) == 0)) { (void) fprintf(stdout,"Version: %s\n", GetMagickVersion((unsigned long *) NULL)); (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright()); return(MagickTrue); } } display=(Display *) NULL; j=1; k=0; image_stack[k]=NewImageList(); option=(char *) NULL; pend=MagickFalse; resource_database=(XrmDatabase) NULL; (void) ResetMagickMemory(&resource_info,0,sizeof(resource_info)); server_name=(char *) NULL; status=MagickTrue; SetNotifyHandlers; /* Check for server name specified on the command line. */ ReadCommandlLine(argc,&argv); status=ExpandFilenames(&argc,&argv); if (status == MagickFalse) { char *message; message=GetExceptionMessage(errno); ThrowImportException(ResourceLimitError,"MemoryAllocationFailed", message); message=DestroyString(message); } for (i=1; i < (long) argc; i++) { /* Check command line for server name. */ option=argv[i]; if (IsMagickOption(option) == MagickFalse) continue; if (LocaleCompare("display",option+1) == 0) { /* User specified server name. */ i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); server_name=argv[i]; } if ((LocaleCompare("help",option+1) == 0) || (LocaleCompare("-help",option+1) == 0)) ImportUsage(); } /* Get user defaults from X resource database. */ display=XOpenDisplay(server_name); if (display == (Display *) NULL) ThrowImportException(XServerError,"UnableToOpenXServer", XDisplayName(server_name)); (void) XSetErrorHandler(XError); resource_database=XGetResourceDatabase(display,GetClientName()); XGetImportInfo(&ximage_info); XGetResourceInfo(resource_database,GetClientName(),&resource_info); image_info=resource_info.image_info; quantize_info=resource_info.quantize_info; resource_value=XGetResourceInstance(resource_database,GetClientName(), "border","False"); ximage_info.borders=IsMagickTrue(resource_value); resource_value=XGetResourceInstance(resource_database,GetClientName(), "delay","0"); resource_info.delay=(unsigned int) atoi(resource_value); image_info->density=XGetResourceInstance(resource_database,GetClientName(), "density",(char *) NULL); resource_value=XGetResourceInstance(resource_database,GetClientName(), "descend","True"); ximage_info.descend=IsMagickTrue(resource_value); resource_value=XGetResourceInstance(resource_database,GetClientName(), "frame","False"); ximage_info.frame=IsMagickTrue(resource_value); resource_value=XGetResourceInstance(resource_database,GetClientName(), "interlace","none"); image_info->interlace=UndefinedInterlace; if (LocaleCompare("None",resource_value) == 0) image_info->interlace=NoInterlace; if (LocaleCompare("Line",resource_value) == 0) image_info->interlace=LineInterlace; if (LocaleCompare("Plane",resource_value) == 0) image_info->interlace=PlaneInterlace; if (LocaleCompare("Partition",resource_value) == 0) image_info->interlace=PartitionInterlace; if (image_info->interlace == UndefinedInterlace) ThrowImportException(OptionError,"Unrecognized interlace type", resource_value); image_info->page=XGetResourceInstance(resource_database,GetClientName(), "pageGeometry",(char *) NULL); resource_value=XGetResourceInstance(resource_database,GetClientName(), "pause","0"); resource_info.pause=(unsigned int) atol(resource_value); resource_value=XGetResourceInstance(resource_database,GetClientName(), "quality","85"); image_info->quality=(unsigned long) atol(resource_value); resource_value=XGetResourceInstance(resource_database,GetClientName(), "screen","False"); ximage_info.screen=IsMagickTrue(resource_value); resource_value=XGetResourceInstance(resource_database,GetClientName(), "silent","False"); ximage_info.silent=IsMagickTrue(resource_value); resource_value=XGetResourceInstance(resource_database,GetClientName(), "verbose","False"); image_info->verbose=IsMagickTrue(resource_value); resource_value=XGetResourceInstance(resource_database,GetClientName(), "dither","True"); quantize_info->dither=IsMagickTrue(resource_value); snapshots=1; status=MagickTrue; filename=(char *) NULL; target_window=(char *) NULL; /* Check command syntax. */ for (i=1; i < (long) argc; i++) { option=argv[i]; if (LocaleCompare(option,"(") == 0) { if (k == MaxImageStackDepth) ThrowImportException(OptionError,"ParenthesisNestedTooDeeply", option); MogrifyImageStack(image_stack[k],MagickTrue,pend); k++; image_stack[k]=NewImageList(); continue; } if (LocaleCompare(option,")") == 0) { if (k == 0) ThrowImportException(OptionError,"UnableToParseExpression",option); if (image_stack[k] != (Image *) NULL) { MogrifyImageStack(image_stack[k],MagickTrue,MagickTrue); AppendImageToList(&image_stack[k-1],image_stack[k]); } k--; continue; } if (IsMagickOption(option) == MagickFalse) { Image *image; unsigned long scene; /* Read image from X server. */ MogrifyImageStack(image_stack[k],MagickFalse,pend); filename=argv[i]; if (target_window != (char *) NULL) (void) CopyMagickString(image_info->filename,target_window, MaxTextExtent); for (scene=0; scene < (unsigned long) MagickMax(snapshots,1); scene++) { (void) sleep(resource_info.pause); image=XImportImage(image_info,&ximage_info); status&=(image != (Image *) NULL) && (exception->severity < ErrorException); if (image == (Image *) NULL) continue; (void) CopyMagickString(image->filename,filename,MaxTextExtent); (void) CopyMagickString(image->magick,"PS",MaxTextExtent); image->scene=scene; AppendImageToList(&image_stack[k],image); MogrifyImageStack(image_stack[k],MagickFalse,MagickTrue); } continue; } pend=image_stack[k] != (Image *) NULL ? MagickTrue : MagickFalse; switch(*(option+1)) { case 'a': { if (LocaleCompare("adjoin",option+1) == 0) break; if (LocaleCompare("annotate",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) (argc-1)) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); if (i == (long) (argc-1)) ThrowImportException(OptionError,"MissingArgument",option); i++; break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'b': { if (LocaleCompare("border",option+1) == 0) { ximage_info.borders=(*option == '-') ? MagickTrue : MagickFalse; (void) CopyMagickString(argv[i]+1,"sans0",MaxTextExtent); break; } if (LocaleCompare("bordercolor",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'c': { if (LocaleCompare("cache",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("channel",option+1) == 0) { long channel; if (*option == '+') break; i++; if (i == (long) (argc-1)) ThrowImportException(OptionError,"MissingArgument",option); channel=ParseChannelOption(argv[i]); if (channel < 0) ThrowImportException(OptionError,"UnrecognizedChannelType", argv[i]); break; } if (LocaleCompare("colors",option+1) == 0) { quantize_info->number_colors=0; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); quantize_info->number_colors=(unsigned long) atol(argv[i]); break; } if (LocaleCompare("colorspace",option+1) == 0) { long colorspace; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); colorspace=ParseMagickOption(MagickColorspaceOptions,MagickFalse, argv[i]); if (colorspace < 0) ThrowImportException(OptionError,"UnrecognizedColorspace", argv[i]); break; } if (LocaleCompare("comment",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); status=SetImageOption(image_info,"Comment",argv[i]); if (status == MagickFalse) ThrowImportException(OptionError,"UnrecognizedOption",argv[i]); break; } if (LocaleCompare("compress",option+1) == 0) { long compress; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); compress=ParseMagickOption(MagickCompressOptions,MagickFalse, argv[i]); if (compress < 0) ThrowImportException(OptionError,"UnrecognizedImageCompression", argv[i]); break; } if (LocaleCompare("crop",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'd': { if (LocaleCompare("debug",option+1) == 0) { long event; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); event=ParseMagickOption(MagickLogEventOptions,MagickFalse,argv[i]); if (event < 0) ThrowImportException(OptionError,"UnrecognizedEventType",argv[i]); (void) SetLogEventMask(argv[i]); break; } if (LocaleCompare("define",option+1) == 0) { i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (*option == '+') { const char *define; define=GetImageOption(image_info,argv[i]); if (define == (char *) NULL) ThrowImportException(OptionError,"NoSuchOption",argv[i]); break; } break; } if (LocaleCompare("delay",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); status=SetImageOption(image_info,"delay",argv[i]); if (status == MagickFalse) ThrowImportException(OptionError,"UnrecognizedOption",argv[i]); break; } if (LocaleCompare("density",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("depth",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("descend",option+1) == 0) { ximage_info.descend=(*option == '-') ? MagickTrue : MagickFalse; break; } if (LocaleCompare("display",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("dispose",option+1) == 0) { long dispose; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse,argv[i]); if (dispose < 0) ThrowImportException(OptionError,"UnrecognizedDisposeMethod", argv[i]); break; } if (LocaleCompare("dither",option+1) == 0) { quantize_info->dither=(*option == '-') ? MagickTrue : MagickFalse; break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'e': { if (LocaleCompare("encoding",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("endian",option+1) == 0) { long endian; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); endian=ParseMagickOption(MagickEndianOptions,MagickFalse, argv[i]); if (endian < 0) ThrowImportException(OptionError,"UnrecognizedEndianType", argv[i]); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'f': { if (LocaleCompare("frame",option+1) == 0) { ximage_info.frame=(*option == '-') ? MagickTrue : MagickFalse; (void) CopyMagickString(argv[i]+1,"sans0",MaxTextExtent); break; } if (LocaleCompare("format",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) (argc-1)) ThrowImportException(OptionError,"MissingArgument",option); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'g': { if (LocaleCompare("geometry",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("gravity",option+1) == 0) { long gravity; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,argv[i]); if (gravity < 0) ThrowImportException(OptionError,"UnrecognizedGravityType", argv[i]); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'h': { if (LocaleCompare("help",option+1) == 0) break; ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'i': { if (LocaleCompare("identify",option+1) == 0) break; if (LocaleCompare("interlace",option+1) == 0) { long interlace; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); interlace=ParseMagickOption(MagickInterlaceOptions,MagickFalse, argv[i]); if (interlace < 0) ThrowImportException(OptionError,"UnrecognizedInterlaceType", argv[i]); break; } if (LocaleCompare("interpolate",option+1) == 0) { long interpolate; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); interpolate=ParseMagickOption(MagickInterpolateOptions,MagickFalse, argv[i]); if (interpolate < 0) ThrowImportException(OptionError,"UnrecognizedInterpolateMethod", argv[i]); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'l': { if (LocaleCompare("label",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); status=SetImageOption(image_info,"label",argv[i]); if (status == MagickFalse) ThrowImportException(OptionError,"UnrecognizedOption",argv[i]); break; } if (LocaleCompare("limit",option+1) == 0) { long resource; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); resource=ParseMagickOption(MagickResourceOptions,MagickFalse, argv[i]); if (resource < 0) ThrowImportException(OptionError,"UnrecognizedResourceType", argv[i]); i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if ((LocaleCompare("unlimited",argv[i]) != 0) && (IsGeometry(argv[i]) == MagickFalse)) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("log",option+1) == 0) { if (*option == '+') break; i++; if ((i == (long) argc) || (strchr(argv[i],'%') == (char *) NULL)) ThrowImportException(OptionError,"MissingArgument",option); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'm': { if (LocaleCompare("monitor",option+1) == 0) break; if (LocaleCompare("monochrome",option+1) == 0) { if (*option == '+') break; quantize_info->number_colors=2; quantize_info->colorspace=GRAYColorspace; break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'n': { if (LocaleCompare("negate",option+1) == 0) break; ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'p': { if (LocaleCompare("page",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); status=SetImageOption(image_info,"page",argv[i]); if (status == MagickFalse) ThrowImportException(OptionError,"UnrecognizedOption",argv[i]); break; } if (LocaleCompare("pause",option+1) == 0) { resource_info.pause=0; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); resource_info.pause=(unsigned int) atoi(argv[i]); break; } if (LocaleCompare("ping",option+1) == 0) break; /* deprecated option */ if (LocaleCompare("pointsize",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'q': { if (LocaleCompare("quality",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("quantize",option+1) == 0) { long colorspace; if (*option == '+') break; i++; if (i == (long) (argc-1)) ThrowImportException(OptionError,"MissingArgument",option); colorspace=ParseMagickOption(MagickColorspaceOptions, MagickFalse,argv[i]); if (colorspace < 0) ThrowImportException(OptionError,"UnrecognizedColorspace", argv[i]); break; } if (LocaleCompare("quiet",option+1) == 0) break; ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'r': { if (LocaleCompare("regard-warnings",option+1) == 0) break; if (LocaleCompare("repage",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) (argc-1)) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("resize",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("rotate",option+1) == 0) { i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 's': { if (LocaleCompare("sampling-factor",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("scene",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("set",option+1) == 0) { i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("screen",option+1) == 0) { ximage_info.screen=(*option == '-') ? MagickTrue : MagickFalse; break; } if (LocaleCompare("seed",option+1) == 0) { unsigned long seed; if (*option == '+') { seed=(unsigned long) time((time_t *) NULL); SeedRandomReservoir(seed); break; } i++; if (i == (long) (argc-1)) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); seed=(unsigned long) atol(argv[i]); SeedRandomReservoir(seed); break; } if (LocaleCompare("silent",option+1) == 0) { ximage_info.silent=(*option == '-') ? MagickTrue : MagickFalse; break; } if (LocaleCompare("snaps",option+1) == 0) { (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent); i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); snapshots=atol(argv[i]); break; } if (LocaleCompare("strip",option+1) == 0) break; if (LocaleCompare("support",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 't': { if (LocaleCompare("thumnail",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("transparent",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("transparent-color",option+1) == 0) { if (*option == '+') break; i++; if (i == (long) (argc-1)) ThrowImportException(OptionError,"MissingArgument",option); break; } if (LocaleCompare("treedepth",option+1) == 0) { quantize_info->tree_depth=0; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowImportInvalidArgumentException(option,argv[i]); quantize_info->tree_depth=(unsigned long) atol(argv[i]); break; } if (LocaleCompare("trim",option+1) == 0) break; if (LocaleCompare("type",option+1) == 0) { long type; if (*option == '+') break; i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); type=ParseMagickOption(MagickTypeOptions,MagickFalse,argv[i]); if (type < 0) ThrowImportException(OptionError,"UnrecognizedImageType",argv[i]); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case 'w': { i++; if (i == (long) argc) ThrowImportException(OptionError,"MissingArgument",option); (void) CloneString(&target_window,argv[i]); break; } case 'v': { if (LocaleCompare("verbose",option+1) == 0) break; if ((LocaleCompare("version",option+1) == 0) || (LocaleCompare("-version",option+1) == 0)) { (void) fprintf(stdout,"Version: %s\n", GetMagickVersion((unsigned long *) NULL)); (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright()); break; } ThrowImportException(OptionError,"UnrecognizedOption",option); } case '?': break; default: ThrowImportException(OptionError,"UnrecognizedOption",option); } fire=(MagickBooleanType) ParseMagickOption(MagickMogrifyOptions, MagickFalse,option+1); if (fire == MagickTrue) MogrifyImageStack(image_stack[k],MagickTrue,MagickTrue); } if (k != 0) ThrowImportException(OptionError,"UnbalancedParenthesis",argv[i]); if (i != argc) ThrowImportException(OptionError,"MissingAnImageFilename",argv[i]); if (image_stack[k] == (Image *) NULL) ThrowImportException(OptionError,"MissingAnImageFilename",argv[argc-1]); MogrifyImageStack(image_stack[k],MagickTrue,MagickTrue) GetImageException(image_stack[k],exception); status&=WriteImages(image_info,image_stack[k],filename,exception); DestroyImport(); return(status != 0 ? MagickTrue : MagickFalse); #else (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError, "XWindowLibraryIsNotAvailable","`%s'",image_info->filename); ImportUsage(); return(MagickFalse); #endif }