MagickExport MagickBooleanType ThrowMagickExceptionList( ExceptionInfo *exception,const char *module,const char *function, const size_t line,const ExceptionType severity,const char *tag, const char *format,va_list operands) { char message[MaxTextExtent], path[MaxTextExtent], reason[MaxTextExtent]; const char *locale, *type; int n; MagickBooleanType status; size_t length; assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); locale=GetLocaleExceptionMessage(severity,tag); (void) CopyMagickString(reason,locale,MaxTextExtent); (void) ConcatenateMagickString(reason," ",MaxTextExtent); length=strlen(reason); #if defined(MAGICKCORE_HAVE_VSNPRINTF) n=vsnprintf(reason+length,MaxTextExtent-length,format,operands); #else n=vsprintf(reason+length,format,operands); #endif if (n < 0) reason[MaxTextExtent-1]='\0'; status=LogMagickEvent(ExceptionEvent,module,function,line,"%s",reason); GetPathComponent(module,TailPath,path); type="undefined"; if ((severity >= WarningException) && (severity < ErrorException)) type="warning"; if ((severity >= ErrorException) && (severity < FatalErrorException)) type="error"; if (severity >= FatalErrorException) type="fatal"; (void) FormatLocaleString(message,MaxTextExtent,"%s @ %s/%s/%s/%.20g",reason, type,path,function,(double) line); (void) ThrowException(exception,severity,message,(char *) NULL); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d T y p e C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadTypeCache() loads the type configurations which provides a mapping % between type attributes and a type name. % % The format of the LoadTypeCache method is: % % MagickBooleanType LoadTypeCache(SplayTreeInfo *type_cache, % const char *xml,const char *filename,const size_t depth, % ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The type list in XML format. % % o filename: The type list filename. % % o depth: depth of <include /> statements. % % o exception: return any errors or warnings in this structure. % */ static inline MagickBooleanType SetTypeNodePath(const char *filename, char *font_path,const char *token,char **target) { char *path; path=ConstantString(token); #if defined(MAGICKCORE_WINDOWS_SUPPORT) if (strchr(path,'@') != (char *) NULL) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif if (IsPathAccessible(path) == MagickFalse) { /* Relative path. */ path=DestroyString(path); GetPathComponent(filename,HeadPath,font_path); (void) ConcatenateMagickString(font_path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(font_path,token,MaxTextExtent); path=ConstantString(font_path); #if defined(MAGICKCORE_WINDOWS_SUPPORT) if (strchr(path,'@') != (char *) NULL) SubstituteString(&path,"@ghostscript_font_path@",""); #endif if (IsPathAccessible(path) == MagickFalse) { path=DestroyString(path); return(MagickFalse); } } *target=path; return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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); } }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e X P M I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteXPMImage() writes an image to a file in the X pixmap format. % % The format of the WriteXPMImage method is: % % MagickBooleanType WriteXPMImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteXPMImage(const ImageInfo *image_info,Image *image) { #define MaxCixels 92 static const char Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk" "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; char buffer[MaxTextExtent], basename[MaxTextExtent], name[MaxTextExtent], symbol[MaxTextExtent]; ExceptionInfo *exception; MagickBooleanType status; MagickPixelPacket pixel; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t i, x; size_t characters_per_pixel; ssize_t j, k, opacity, y; /* Open output image file. */ 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->filename); exception=(&image->exception); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace); opacity=(-1); if (image->matte == MagickFalse) { if ((image->storage_class == DirectClass) || (image->colors > 256)) (void) SetImageType(image,PaletteType); } else { MagickRealType alpha, beta; /* Identify transparent colormap index. */ if ((image->storage_class == DirectClass) || (image->colors > 256)) (void) SetImageType(image,PaletteBilevelMatteType); for (i=0; i < (ssize_t) image->colors; i++) if (image->colormap[i].opacity != OpaqueOpacity) { if (opacity < 0) { opacity=i; continue; } alpha=(Quantum) TransparentOpacity-(MagickRealType) image->colormap[i].opacity; beta=(Quantum) TransparentOpacity-(MagickRealType) image->colormap[opacity].opacity; if (alpha < beta) opacity=i; } if (opacity == -1) { (void) SetImageType(image,PaletteBilevelMatteType); for (i=0; i < (ssize_t) image->colors; i++) if (image->colormap[i].opacity != OpaqueOpacity) { if (opacity < 0) { opacity=i; continue; } alpha=(Quantum) TransparentOpacity-(MagickRealType) image->colormap[i].opacity; beta=(Quantum) TransparentOpacity-(MagickRealType) image->colormap[opacity].opacity; if (alpha < beta) opacity=i; } } if (opacity >= 0) { image->colormap[opacity].red=image->transparent_color.red; image->colormap[opacity].green=image->transparent_color.green; image->colormap[opacity].blue=image->transparent_color.blue; } } /* Compute the character per pixel. */ characters_per_pixel=1; for (k=MaxCixels; (ssize_t) image->colors > k; k*=MaxCixels) characters_per_pixel++; /* XPM header. */ (void) WriteBlobString(image,"/* XPM */\n"); GetPathComponent(image->filename,BasePath,basename); if (isalnum((int) ((unsigned char) *basename)) == 0) { (void) FormatLocaleString(buffer,MaxTextExtent,"xpm_%s",basename); (void) CopyMagickString(basename,buffer,MaxTextExtent); } if (isalpha((int) ((unsigned char) basename[0])) == 0) basename[0]='_'; for (i=1; basename[i] != '\0'; i++) if (isalnum((int) ((unsigned char) basename[i])) == 0) basename[i]='_'; (void) FormatLocaleString(buffer,MaxTextExtent, "static char *%s[] = {\n",basename); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n"); (void) FormatLocaleString(buffer,MaxTextExtent, "\"%.20g %.20g %.20g %.20g \",\n",(double) image->columns,(double) image->rows,(double) image->colors,(double) characters_per_pixel); (void) WriteBlobString(image,buffer); GetMagickPixelPacket(image,&pixel); for (i=0; i < (ssize_t) image->colors; i++) { /* Define XPM color. */ SetMagickPixelPacket(image,image->colormap+i,(IndexPacket *) NULL,&pixel); pixel.colorspace=sRGBColorspace; pixel.depth=8; pixel.opacity=(MagickRealType) OpaqueOpacity; (void) QueryMagickColorname(image,&pixel,XPMCompliance,name,exception); if (i == opacity) (void) CopyMagickString(name,"None",MaxTextExtent); /* Write XPM color. */ k=i % MaxCixels; symbol[0]=Cixel[k]; for (j=1; j < (ssize_t) characters_per_pixel; j++) { k=((i-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) FormatLocaleString(buffer,MaxTextExtent,"\"%s c %s\",\n",symbol, name); (void) WriteBlobString(image,buffer); } /* Define XPM pixels. */ (void) WriteBlobString(image,"/* pixels */\n"); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); (void) WriteBlobString(image,"\""); for (x=0; x < (ssize_t) image->columns; x++) { k=((ssize_t) GetPixelIndex(indexes+x) % MaxCixels); symbol[0]=Cixel[k]; for (j=1; j < (ssize_t) characters_per_pixel; j++) { k=(((int) GetPixelIndex(indexes+x)-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) CopyMagickString(buffer,symbol,MaxTextExtent); (void) WriteBlobString(image,buffer); } (void) FormatLocaleString(buffer,MaxTextExtent,"\"%s\n", (y == (ssize_t) (image->rows-1) ? "" : ",")); (void) WriteBlobString(image,buffer); if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } (void) WriteBlobString(image,"};\n"); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d C o n f i g u r e L i s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadConfigureList() loads the configure configuration file which provides a % mapping between configure attributes and a configure name. % % The format of the LoadConfigureList method is: % % MagickBooleanType LoadConfigureList(const char *xml,const char *filename, % const size_t depth,ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The configure list in XML format. % % o filename: The configure list filename. % % o depth: depth of <include /> statements. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadConfigureList(const char *xml,const char *filename, const size_t depth,ExceptionInfo *exception) { char keyword[MaxTextExtent], *token; ConfigureInfo *configure_info; const char *q; MagickBooleanType status; /* Load the configure map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading configure file \"%s\" ...",filename); if (configure_list == (LinkedListInfo *) NULL) { configure_list=NewLinkedList(0); if (configure_list == (LinkedListInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } status=MagickTrue; configure_info=(ConfigureInfo *) NULL; token=AcquireString((char *) xml); for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); else { char path[MaxTextExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MaxTextExtent); else (void) ConcatenateMagickString(path,token,MaxTextExtent); xml=FileToString(path,~0,exception); if (xml != (char *) NULL) { status=LoadConfigureList(xml,path,depth+1,exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<configure") == 0) { /* Configure element. */ configure_info=(ConfigureInfo *) AcquireMagickMemory( sizeof(*configure_info)); if (configure_info == (ConfigureInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info)); configure_info->path=ConstantString(filename); configure_info->exempt=MagickFalse; configure_info->signature=MagickSignature; continue; } if (configure_info == (ConfigureInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AppendValueToLinkedList(configure_list,configure_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", configure_info->name); configure_info=(ConfigureInfo *) NULL; } /* Parse configure element. */ GetMagickToken(q,(const char **) NULL,token); if (*token != '=') continue; GetMagickToken(q,&q,token); GetMagickToken(q,&q,token); switch (*keyword) { case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { configure_info->name=ConstantString(token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { configure_info->stealth=IsMagickTrue(token); break; } break; } case 'V': case 'v': { if (LocaleCompare((char *) keyword,"value") == 0) { configure_info->value=ConstantString(token); break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status); }
MagickExport MagickBooleanType LoadFontConfigFonts(SplayTreeInfo *type_list, ExceptionInfo *exception) { #if !defined(FC_FULLNAME) #define FC_FULLNAME "fullname" #endif char extension[MaxTextExtent], name[MaxTextExtent]; FcChar8 *family, *file, *fullname, *style; FcConfig *font_config; FcFontSet *font_set; FcObjectSet *object_set; FcPattern *pattern; FcResult status; int slant, width, weight; register ssize_t i; TypeInfo *type_info; /* Load system fonts. */ (void) exception; font_config=FcInitLoadConfigAndFonts(); if (font_config == (FcConfig *) NULL) return(MagickFalse); font_set=(FcFontSet *) NULL; object_set=FcObjectSetBuild(FC_FULLNAME,FC_FAMILY,FC_STYLE,FC_SLANT, FC_WIDTH,FC_WEIGHT,FC_FILE,(char *) NULL); if (object_set != (FcObjectSet *) NULL) { pattern=FcPatternCreate(); if (pattern != (FcPattern *) NULL) { font_set=FcFontList(0,pattern,object_set); FcPatternDestroy(pattern); } FcObjectSetDestroy(object_set); } if (font_set == (FcFontSet *) NULL) { FcConfigDestroy(font_config); return(MagickFalse); } for (i=0; i < (ssize_t) font_set->nfont; i++) { status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family); if (status != FcResultMatch) continue; status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file); if (status != FcResultMatch) continue; *extension='\0'; GetPathComponent((const char *) file,ExtensionPath,extension); if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0)) continue; type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) continue; (void) ResetMagickMemory(type_info,0,sizeof(*type_info)); type_info->path=ConstantString("System Fonts"); type_info->signature=MagickSignature; (void) CopyMagickString(name,"Unknown",MaxTextExtent); status=FcPatternGetString(font_set->fonts[i],FC_FULLNAME,0,&fullname); if ((status == FcResultMatch) && (fullname != (FcChar8 *) NULL)) (void) CopyMagickString(name,(const char *) fullname,MaxTextExtent); else { if (family != (FcChar8 *) NULL) (void) CopyMagickString(name,(const char *) family,MaxTextExtent); status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style); if ((status == FcResultMatch) && (style != (FcChar8 *) NULL) && (LocaleCompare((const char *) style,"Regular") != 0)) { (void) ConcatenateMagickString(name," ",MaxTextExtent); (void) ConcatenateMagickString(name,(const char *) style, MaxTextExtent); } } type_info->name=ConstantString(name); (void) SubstituteString(&type_info->name," ","-"); type_info->family=ConstantString((const char *) family); status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant); type_info->style=NormalStyle; if (slant == FC_SLANT_ITALIC) type_info->style=ItalicStyle; if (slant == FC_SLANT_OBLIQUE) type_info->style=ObliqueStyle; status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width); type_info->stretch=NormalStretch; if (width >= FC_WIDTH_ULTRACONDENSED) type_info->stretch=UltraCondensedStretch; if (width >= FC_WIDTH_EXTRACONDENSED) type_info->stretch=ExtraCondensedStretch; if (width >= FC_WIDTH_CONDENSED) type_info->stretch=CondensedStretch; if (width >= FC_WIDTH_SEMICONDENSED) type_info->stretch=SemiCondensedStretch; if (width >= FC_WIDTH_NORMAL) type_info->stretch=NormalStretch; if (width >= FC_WIDTH_SEMIEXPANDED) type_info->stretch=SemiExpandedStretch; if (width >= FC_WIDTH_EXPANDED) type_info->stretch=ExpandedStretch; if (width >= FC_WIDTH_EXTRAEXPANDED) type_info->stretch=ExtraExpandedStretch; if (width >= FC_WIDTH_ULTRAEXPANDED) type_info->stretch=UltraExpandedStretch; type_info->weight=400; status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight); if (weight >= FC_WEIGHT_THIN) type_info->weight=100; if (weight >= FC_WEIGHT_EXTRALIGHT) type_info->weight=200; if (weight >= FC_WEIGHT_LIGHT) type_info->weight=300; if (weight >= FC_WEIGHT_NORMAL) type_info->weight=400; if (weight >= FC_WEIGHT_MEDIUM) type_info->weight=500; if (weight >= FC_WEIGHT_DEMIBOLD) type_info->weight=600; if (weight >= FC_WEIGHT_BOLD) type_info->weight=700; if (weight >= FC_WEIGHT_EXTRABOLD) type_info->weight=800; if (weight >= FC_WEIGHT_BLACK) type_info->weight=900; type_info->glyphs=ConstantString((const char *) file); (void) AddValueToSplayTree(type_list,type_info->name,type_info); } FcFontSetDestroy(font_set); FcConfigDestroy(font_config); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadImage() reads an image or image sequence from a file or file handle. % The method returns a NULL if there is a memory shortage or if the image % cannot be read. On failure, a NULL image is returned and exception % describes the reason for the failure. % % The format of the ReadImage method is: % % Image *ReadImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: Read the image defined by the file or filename members of % this structure. % % o exception: return any errors or warnings in this structure. % */ MagickExport Image *ReadImage(const ImageInfo *image_info, ExceptionInfo *exception) { char filename[MaxTextExtent], magick[MaxTextExtent], magick_filename[MaxTextExtent]; const char *value; const DelegateInfo *delegate_info; const MagickInfo *magick_info; ExceptionInfo *sans_exception; GeometryInfo geometry_info; Image *image, *next; ImageInfo *read_info; MagickStatusType flags, thread_support; PolicyDomain domain; PolicyRights rights; /* Determine image type from filename prefix or suffix (e.g. image.jpg). */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image_info->filename != (char *) NULL); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); read_info=CloneImageInfo(image_info); (void) CopyMagickString(magick_filename,read_info->filename,MaxTextExtent); (void) SetImageInfo(read_info,0,exception); (void) CopyMagickString(filename,read_info->filename,MaxTextExtent); (void) CopyMagickString(magick,read_info->magick,MaxTextExtent); domain=CoderPolicyDomain; rights=ReadPolicyRights; if (IsRightsAuthorized(domain,rights,read_info->magick) == MagickFalse) { errno=EPERM; (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, "NotAuthorized","`%s'",read_info->filename); return((Image *) NULL); } /* Call appropriate image reader based on image type. */ sans_exception=AcquireExceptionInfo(); magick_info=GetMagickInfo(read_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (magick_info != (const MagickInfo *) NULL) { if (GetMagickEndianSupport(magick_info) == MagickFalse) read_info->endian=UndefinedEndian; else if ((image_info->endian == UndefinedEndian) && (GetMagickRawSupport(magick_info) != MagickFalse)) { size_t lsb_first; lsb_first=1; read_info->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian; } } if ((magick_info != (const MagickInfo *) NULL) && (GetMagickSeekableStream(magick_info) != MagickFalse)) { MagickBooleanType status; image=AcquireImage(read_info,exception); (void) CopyMagickString(image->filename,read_info->filename, MaxTextExtent); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { read_info=DestroyImageInfo(read_info); image=DestroyImage(image); return((Image *) NULL); } if (IsBlobSeekable(image) == MagickFalse) { /* Coder requires a seekable stream. */ *read_info->filename='\0'; status=ImageToFile(image,read_info->filename,exception); if (status == MagickFalse) { (void) CloseBlob(image); read_info=DestroyImageInfo(read_info); image=DestroyImage(image); return((Image *) NULL); } read_info->temporary=MagickTrue; } (void) CloseBlob(image); image=DestroyImage(image); } image=NewImageList(); if (constitute_semaphore == (SemaphoreInfo *) NULL) AcquireSemaphoreInfo(&constitute_semaphore); if ((magick_info != (const MagickInfo *) NULL) && (GetImageDecoder(magick_info) != (DecodeImageHandler *) NULL)) { thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & DecoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); image=GetImageDecoder(magick_info)(read_info,exception); if ((thread_support & DecoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } else { delegate_info=GetDelegateInfo(read_info->magick,(char *) NULL,exception); if (delegate_info == (const DelegateInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", read_info->filename); if (read_info->temporary != MagickFalse) (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } /* Let our decoding delegate process the image. */ image=AcquireImage(read_info,exception); if (image == (Image *) NULL) { read_info=DestroyImageInfo(read_info); return((Image *) NULL); } (void) CopyMagickString(image->filename,read_info->filename, MaxTextExtent); *read_info->filename='\0'; if (GetDelegateThreadSupport(delegate_info) == MagickFalse) LockSemaphoreInfo(constitute_semaphore); (void) InvokeDelegate(read_info,image,read_info->magick,(char *) NULL, exception); if (GetDelegateThreadSupport(delegate_info) == MagickFalse) UnlockSemaphoreInfo(constitute_semaphore); image=DestroyImageList(image); read_info->temporary=MagickTrue; (void) SetImageInfo(read_info,0,exception); magick_info=GetMagickInfo(read_info->magick,exception); if ((magick_info == (const MagickInfo *) NULL) || (GetImageDecoder(magick_info) == (DecodeImageHandler *) NULL)) { if (IsPathAccessible(read_info->filename) != MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", read_info->filename); else ThrowFileException(exception,FileOpenError,"UnableToOpenFile", read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & DecoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); image=(Image *) (GetImageDecoder(magick_info))(read_info,exception); if ((thread_support & DecoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } if (read_info->temporary != MagickFalse) { (void) RelinquishUniqueFileResource(read_info->filename); read_info->temporary=MagickFalse; if (image != (Image *) NULL) (void) CopyMagickString(image->filename,filename,MaxTextExtent); } if (image == (Image *) NULL) { read_info=DestroyImageInfo(read_info); return(image); } if (exception->severity >= ErrorException) (void) LogMagickEvent(ExceptionEvent,GetMagickModule(), "Coder (%s) generated an image despite an error (%d), " "notify the developers",image->magick,exception->severity); if (IsBlobTemporary(image) != MagickFalse) (void) RelinquishUniqueFileResource(read_info->filename); if ((GetNextImageInList(image) != (Image *) NULL) && (IsSceneGeometry(read_info->scenes,MagickFalse) != MagickFalse)) { Image *clones; clones=CloneImages(image,read_info->scenes,exception); if (clones == (Image *) NULL) (void) ThrowMagickException(exception,GetMagickModule(),OptionError, "SubimageSpecificationReturnsNoImages","`%s'",read_info->filename); else { image=DestroyImageList(image); image=GetFirstImageInList(clones); } } if (GetBlobError(image) != MagickFalse) { ThrowFileException(exception,FileOpenError, "AnErrorHasOccurredReadingFromFile",read_info->filename); image=DestroyImageList(image); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } for (next=image; next != (Image *) NULL; next=GetNextImageInList(next)) { char magick_path[MaxTextExtent], *property, timestamp[MaxTextExtent]; const char *option; const StringInfo *profile; next->taint=MagickFalse; GetPathComponent(magick_filename,MagickPath,magick_path); if (*magick_path == '\0') (void) CopyMagickString(next->magick,magick,MaxTextExtent); (void) CopyMagickString(next->magick_filename,magick_filename, MaxTextExtent); if (IsBlobTemporary(image) != MagickFalse) (void) CopyMagickString(next->filename,filename,MaxTextExtent); if (next->magick_columns == 0) next->magick_columns=next->columns; if (next->magick_rows == 0) next->magick_rows=next->rows; value=GetImageProperty(next,"tiff:Orientation",exception); if (value == (char *) NULL) value=GetImageProperty(next,"exif:Orientation",exception); if (value != (char *) NULL) { next->orientation=(OrientationType) StringToLong(value); (void) DeleteImageProperty(next,"tiff:Orientation"); (void) DeleteImageProperty(next,"exif:Orientation"); } value=GetImageProperty(next,"exif:XResolution",exception); if (value != (char *) NULL) { geometry_info.rho=next->resolution.x; geometry_info.sigma=1.0; flags=ParseGeometry(value,&geometry_info); if (geometry_info.sigma != 0) next->resolution.x=geometry_info.rho/geometry_info.sigma; (void) DeleteImageProperty(next,"exif:XResolution"); } value=GetImageProperty(next,"exif:YResolution",exception); if (value != (char *) NULL) { geometry_info.rho=next->resolution.y; geometry_info.sigma=1.0; flags=ParseGeometry(value,&geometry_info); if (geometry_info.sigma != 0) next->resolution.y=geometry_info.rho/geometry_info.sigma; (void) DeleteImageProperty(next,"exif:YResolution"); } value=GetImageProperty(next,"tiff:ResolutionUnit",exception); if (value == (char *) NULL) value=GetImageProperty(next,"exif:ResolutionUnit",exception); if (value != (char *) NULL) { next->units=(ResolutionType) (StringToLong(value)-1); (void) DeleteImageProperty(next,"exif:ResolutionUnit"); (void) DeleteImageProperty(next,"tiff:ResolutionUnit"); } if (next->page.width == 0) next->page.width=next->columns; if (next->page.height == 0) next->page.height=next->rows; option=GetImageOption(read_info,"caption"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"caption",property,exception); property=DestroyString(property); } option=GetImageOption(read_info,"comment"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"comment",property,exception); property=DestroyString(property); } option=GetImageOption(read_info,"label"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"label",property,exception); property=DestroyString(property); } if (LocaleCompare(next->magick,"TEXT") == 0) (void) ParseAbsoluteGeometry("0x0+0+0",&next->page); if ((read_info->extract != (char *) NULL) && (read_info->stream == (StreamHandler) NULL)) { RectangleInfo geometry; flags=ParseAbsoluteGeometry(read_info->extract,&geometry); if ((next->columns != geometry.width) || (next->rows != geometry.height)) { if (((flags & XValue) != 0) || ((flags & YValue) != 0)) { Image *crop_image; crop_image=CropImage(next,&geometry,exception); if (crop_image != (Image *) NULL) ReplaceImageInList(&next,crop_image); } else if (((flags & WidthValue) != 0) || ((flags & HeightValue) != 0)) { Image *size_image; flags=ParseRegionGeometry(next,read_info->extract,&geometry, exception); size_image=ResizeImage(next,geometry.width,geometry.height, next->filter,next->blur,exception); if (size_image != (Image *) NULL) ReplaceImageInList(&next,size_image); } } } profile=GetImageProfile(next,"icc"); if (profile == (const StringInfo *) NULL) profile=GetImageProfile(next,"icm"); profile=GetImageProfile(next,"iptc"); if (profile == (const StringInfo *) NULL) profile=GetImageProfile(next,"8bim"); (void) FormatMagickTime(GetBlobProperties(next)->st_mtime,MaxTextExtent, timestamp); (void) SetImageProperty(next,"date:modify",timestamp,exception); (void) FormatMagickTime(GetBlobProperties(next)->st_ctime,MaxTextExtent, timestamp); (void) SetImageProperty(next,"date:create",timestamp,exception); option=GetImageOption(image_info,"delay"); if (option != (const char *) NULL) { GeometryInfo geometry_info; flags=ParseGeometry(option,&geometry_info); if ((flags & GreaterValue) != 0) { if (next->delay > (size_t) floor(geometry_info.rho+0.5)) next->delay=(size_t) floor(geometry_info.rho+0.5); } else if ((flags & LessValue) != 0) { if (next->delay < (size_t) floor(geometry_info.rho+0.5)) next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5); } else next->delay=(size_t) floor(geometry_info.rho+0.5); if ((flags & SigmaValue) != 0) next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5); } option=GetImageOption(image_info,"dispose"); if (option != (const char *) NULL) next->dispose=(DisposeType) ParseCommandOption(MagickDisposeOptions, MagickFalse,option); if (read_info->verbose != MagickFalse) (void) IdentifyImage(next,stderr,MagickFalse,exception); image=next; } read_info=DestroyImageInfo(read_info); return(GetFirstImageInList(image)); }
static MagickBooleanType WriteMPEGImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { #define WriteMPEGIntermediateFormat "jpg" char basename[MagickPathExtent], filename[MagickPathExtent]; double delay; Image *coalesce_image; ImageInfo *write_info; int file; MagickBooleanType status; register Image *p; register ssize_t i; size_t count, length, scene; unsigned char *blob; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); (void) CloseBlob(image); /* Write intermediate files. */ coalesce_image=CoalesceImages(image,exception); if (coalesce_image == (Image *) NULL) return(MagickFalse); file=AcquireUniqueFileResource(basename); if (file != -1) file=close(file)-1; (void) FormatLocaleString(coalesce_image->filename,MagickPathExtent,"%s", basename); count=0; write_info=CloneImageInfo(image_info); *write_info->magick='\0'; for (p=coalesce_image; p != (Image *) NULL; p=GetNextImageInList(p)) { char previous_image[MagickPathExtent]; blob=(unsigned char *) NULL; length=0; scene=p->scene; delay=100.0*p->delay/MagickMax(1.0*p->ticks_per_second,1.0); for (i=0; i < (ssize_t) MagickMax((1.0*delay+1.0)/3.0,1.0); i++) { p->scene=count; count++; status=MagickFalse; switch (i) { case 0: { Image *frame; (void) FormatLocaleString(p->filename,MagickPathExtent,"%s%.20g.%s", basename,(double) p->scene,WriteMPEGIntermediateFormat); (void) FormatLocaleString(filename,MagickPathExtent,"%s%.20g.%s", basename,(double) p->scene,WriteMPEGIntermediateFormat); (void) FormatLocaleString(previous_image,MagickPathExtent, "%s%.20g.%s",basename,(double) p->scene, WriteMPEGIntermediateFormat); frame=CloneImage(p,0,0,MagickTrue,exception); if (frame == (Image *) NULL) break; status=WriteImage(write_info,frame,exception); frame=DestroyImage(frame); break; } case 1: { blob=(unsigned char *) FileToBlob(previous_image,~0UL,&length, exception); } default: { (void) FormatLocaleString(filename,MagickPathExtent,"%s%.20g.%s", basename,(double) p->scene,WriteMPEGIntermediateFormat); if (length > 0) status=BlobToFile(filename,blob,length,exception); break; } } if (image->debug != MagickFalse) { if (status != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "%.20g. Wrote %s file for scene %.20g:",(double) i, WriteMPEGIntermediateFormat,(double) p->scene); else (void) LogMagickEvent(CoderEvent,GetMagickModule(), "%.20g. Failed to write %s file for scene %.20g:",(double) i, WriteMPEGIntermediateFormat,(double) p->scene); (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%s",filename); } } p->scene=scene; if (blob != (unsigned char *) NULL) blob=(unsigned char *) RelinquishMagickMemory(blob); if (status == MagickFalse) break; } /* Convert JPEG to MPEG. */ (void) CopyMagickString(coalesce_image->magick_filename,basename, MagickPathExtent); (void) CopyMagickString(coalesce_image->filename,basename,MagickPathExtent); GetPathComponent(image_info->filename,ExtensionPath,coalesce_image->magick); if (*coalesce_image->magick == '\0') (void) CopyMagickString(coalesce_image->magick,image->magick, MagickPathExtent); status=InvokeDelegate(write_info,coalesce_image,(char *) NULL,"mpeg:encode", exception); (void) FormatLocaleString(write_info->filename,MagickPathExtent,"%s.%s", write_info->unique,coalesce_image->magick); status=CopyDelegateFile(write_info->filename,image->filename); (void) RelinquishUniqueFileResource(write_info->filename); write_info=DestroyImageInfo(write_info); /* Relinquish resources. */ count=0; for (p=coalesce_image; p != (Image *) NULL; p=GetNextImageInList(p)) { delay=100.0*p->delay/MagickMax(1.0*p->ticks_per_second,1.0); for (i=0; i < (ssize_t) MagickMax((1.0*delay+1.0)/3.0,1.0); i++) { (void) FormatLocaleString(p->filename,MagickPathExtent,"%s%.20g.%s", basename,(double) count++,WriteMPEGIntermediateFormat); (void) RelinquishUniqueFileResource(p->filename); } (void) CopyMagickString(p->filename,image_info->filename,MagickPathExtent); } (void) RelinquishUniqueFileResource(basename); coalesce_image=DestroyImageList(coalesce_image); if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit"); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d C o d e r C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadCoderCache() loads the coder configurations which provides a % mapping between coder attributes and a coder name. % % The format of the LoadCoderCache coder is: % % MagickBooleanType LoadCoderCache(SplayTreeInfo *coder_cache, % const char *xml,const char *filename,const size_t depth, % ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The coder list in XML format. % % o filename: The coder list filename. % % o depth: depth of <include /> statements. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadCoderCache(SplayTreeInfo *coder_cache, const char *xml,const char *filename,const size_t depth, ExceptionInfo *exception) { char keyword[MagickPathExtent], *token; const char *q; CoderInfo *coder_info; MagickStatusType status; size_t extent; /* Load the coder map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading coder configuration file \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); status=MagickTrue; coder_info=(CoderInfo *) NULL; token=AcquireString(xml); extent=strlen(token)+MagickPathExtent; for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetNextToken(q,&q,extent,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MagickPathExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetNextToken(q,&q,extent,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetNextToken(q,&q,extent,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MagickPathExtent); GetNextToken(q,&q,extent,token); if (*token != '=') continue; GetNextToken(q,&q,extent,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token); else { char path[MagickPathExtent], *file_xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MagickPathExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MagickPathExtent); else (void) ConcatenateMagickString(path,token,MagickPathExtent); file_xml=FileToXML(path,~0UL); if (file_xml != (char *) NULL) { status&=LoadCoderCache(coder_cache,file_xml,path,depth+1, exception); file_xml=DestroyString(file_xml); } } } } continue; } if (LocaleCompare(keyword,"<coder") == 0) { /* Coder element. */ coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); if (coder_info == (CoderInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); coder_info->path=ConstantString(filename); coder_info->exempt=MagickFalse; coder_info->signature=MagickCoreSignature; continue; } if (coder_info == (CoderInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AddValueToSplayTree(coder_cache,ConstantString( coder_info->magick),coder_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", coder_info->magick); coder_info=(CoderInfo *) NULL; continue; } GetNextToken(q,(const char **) NULL,extent,token); if (*token != '=') continue; GetNextToken(q,&q,extent,token); GetNextToken(q,&q,extent,token); switch (*keyword) { case 'M': case 'm': { if (LocaleCompare((char *) keyword,"magick") == 0) { coder_info->magick=ConstantString(token); break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { coder_info->name=ConstantString(token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { coder_info->stealth=IsStringTrue(token); break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status != 0 ? MagickTrue : MagickFalse); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + R e a d C o n f i g u r e F i l e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadConfigureFile reads the color configuration file which maps % color strings with a particular image format. % % The format of the ReadConfigureFile method is: % % unsigned int ReadConfigureFile(const char *basename, % const unsigned long depth,ExceptionInfo *exception) % % A description of each parameter follows: % % o status: Method ReadConfigureFile returns True if at least one color % is defined otherwise False. % % o basename: The color configuration filename. % % o depth: depth of <include /> statements. % % o exception: Return any errors or warnings in this structure. % % */ #if defined(MSWINDOWS) static void CatDelegatePath(char *path, const char *binpath, const char *command) { strcpy(path,binpath); strcat(path,command); if (IsAccessibleNoLogging(path)) return; strcpy(path,command); return; } #endif /* defined(MSWINDOWS) */ static unsigned int ReadConfigureFile(const char *basename, const unsigned long depth,ExceptionInfo *exception) { char keyword[MaxTextExtent], path[MaxTextExtent], *q, *token, *xml; size_t length; /* Read the delegates configure file. */ (void) strcpy(path,basename); if (depth == 0) xml=(char *) GetConfigureBlob(basename,path,&length,exception); else xml=(char *) FileToBlob(basename,&length,exception); if (xml == (char *) NULL) xml=AllocateString(DelegateMap); token=AllocateString(xml); for (q=xml; *q != '\0'; ) { /* Interpret XML. */ GetToken(q,&q,token); if (*token == '\0') break; (void) strlcpy(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetToken(q,&q,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while ((*token != '>') && (*q != '\0')) { (void) strlcpy(keyword,token,MaxTextExtent); GetToken(q,&q,token); if (*token != '=') continue; GetToken(q,&q,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) ThrowException(exception,ConfigureError,IncludeElementNestedTooDeeply,path); else { char filename[MaxTextExtent]; GetPathComponent(path,HeadPath,filename); if (*filename != '\0') (void) strlcat(filename,DirectorySeparator,MaxTextExtent); (void) strlcat(filename,token,MaxTextExtent); (void) ReadConfigureFile(filename,depth+1,exception); } if (delegate_list != (DelegateInfo *) NULL) while (delegate_list->next != (DelegateInfo *) NULL) delegate_list=delegate_list->next; } } continue; } if (LocaleCompare(keyword,"<delegate") == 0) { DelegateInfo *delegate_info; /* Allocate memory for the delegate list. */ delegate_info=MagickAllocateMemory(DelegateInfo *,sizeof(DelegateInfo)); if (delegate_info == (DelegateInfo *) NULL) MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed, UnableToAllocateDelegateInfo); (void) memset(delegate_info,0,sizeof(DelegateInfo)); delegate_info->path=AcquireString(path); delegate_info->signature=MagickSignature; if (delegate_list == (DelegateInfo *) NULL) { delegate_list=delegate_info; continue; } delegate_list->next=delegate_info; delegate_info->previous=delegate_list; delegate_list=delegate_list->next; continue; } if (delegate_list == (DelegateInfo *) NULL) continue; GetToken(q,(char **) NULL,token); if (*token != '=') continue; GetToken(q,&q,token); GetToken(q,&q,token); switch (*keyword) { case 'C': case 'c': { if (LocaleCompare((char *) keyword,"command") == 0) { delegate_list->commands=AllocateString(token); #if defined(MSWINDOWS) if (strchr(delegate_list->commands,'@') != (char *) NULL) { char BinPath[MaxTextExtent], path[MaxTextExtent]; BinPath[0]=0; /* Substitute @PSDelegate@ with path to Ghostscript */ NTGhostscriptEXE(path,MaxTextExtent-1); SubstituteString((char **) &delegate_list->commands, "@PSDelegate@",path); # if defined(UseInstalledMagick) # if defined(MagickBinPath) strcpy(BinPath,MagickBinPath); # else { char *key, *key_value; /* Obtain installation path from registry */ key="BinPath"; key_value=NTRegistryKeyLookup(key); if (!key_value) { ThrowException(exception,ConfigureError, RegistryKeyLookupFailed,key); } else { strcpy(BinPath,key_value); MagickFreeMemory(key_value); } } # endif /* defined(MagickBinPath) */ # else /* Base path off of client path */ strcpy(BinPath,SetClientPath(NULL)); # endif /* defined(UseInstalledMagick) */ if ((BinPath[0] != 0) && (BinPath[strlen(BinPath)-1] != *DirectorySeparator)) strcat(BinPath,DirectorySeparator); /* Substitute @GMDelegate@ with path to gm.exe */ CatDelegatePath(path,BinPath,"gm.exe"); SubstituteString((char **) &delegate_list->commands, "@GMDelegate@",path); /* Substitute @GMDisplayDelegate@ with path to gmdisplay.exe */ CatDelegatePath(path,BinPath,"gmdisplay.exe"); SubstituteString((char **) &delegate_list->commands, "@GMDisplayDelegate@",path); /* Substitute @MPEGDecodeDelegate@ with path to mpeg2dec.exe */ CatDelegatePath(path,BinPath,"mpeg2dec.exe"); SubstituteString((char **) &delegate_list->commands, "@MPEGDecodeDelegate@",path); /* Substitute @MPEGEncodeDelegate@ with path to mpeg2enc.exe */ CatDelegatePath(path,BinPath,"mpeg2enc.exe"); SubstituteString((char **) &delegate_list->commands, "@MPEGEncodeDelegate@",path); /* Substitute @HPGLDecodeDelegate@ with path to hp2xx.exe */ CatDelegatePath(path,BinPath,"hp2xx.exe"); SubstituteString((char **) &delegate_list->commands, "@HPGLDecodeDelegate@",path); } #endif /* defined(MSWINDOWS) */ } /* LocaleCompare */ break; } case 'D': case 'd': { if (LocaleCompare((char *) keyword,"decode") == 0) { delegate_list->decode=AcquireString(token); delegate_list->mode=1; break; } break; } case 'E': case 'e': { if (LocaleCompare((char *) keyword,"encode") == 0) { delegate_list->encode=AcquireString(token); delegate_list->mode=(-1); break; } break; } case 'M': case 'm': { if (LocaleCompare((char *) keyword,"mode") == 0) { delegate_list->mode=1; if (LocaleCompare(token,"bi") == 0) delegate_list->mode=0; else if (LocaleCompare(token,"encode") == 0) delegate_list->mode=(-1); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { delegate_list->stealth=LocaleCompare(token,"True") == 0; break; } break; } default: break; } }
static MagickBooleanType LoadCoderList(const char *xml,const char *filename, const unsigned long depth,ExceptionInfo *exception) { CoderInfo *coder_info = (CoderInfo *) NULL; const char *attribute; MagickBooleanType status; XMLTreeInfo *coder, *coder_map, *include; /* Load the coder map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading coder map \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (coder_list == (SplayTreeInfo *) NULL) { coder_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyCoderNode); if (coder_list == (SplayTreeInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); return(MagickFalse); } } coder_map=NewXMLTree(xml,exception); if (coder_map == (XMLTreeInfo *) NULL) return(MagickFalse); status=MagickTrue; include=GetXMLTreeChild(coder_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",attribute); else { char path[MaxTextExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(path,attribute,MaxTextExtent); xml=FileToString(path,~0,exception); if (xml != (char *) NULL) { status=LoadCoderList(xml,path,depth+1,exception); xml=DestroyString(xml); } } } include=GetNextXMLTreeTag(include); } coder=GetXMLTreeChild(coder_map,"coder"); while (coder != (XMLTreeInfo *) NULL) { /* Process coder element. */ coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); if (coder_info == (CoderInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); coder_info->path=ConstantString(filename); coder_info->signature=MagickSignature; attribute=GetXMLTreeAttribute(coder,"magick"); if (attribute != (const char *) NULL) coder_info->magick=ConstantString(attribute); attribute=GetXMLTreeAttribute(coder,"name"); if (attribute != (const char *) NULL) coder_info->name=ConstantString(attribute); attribute=GetXMLTreeAttribute(coder,"stealth"); if (attribute != (const char *) NULL) coder_info->stealth=IsMagickTrue(attribute); status=AddValueToSplayTree(coder_list,coder_info->magick,coder_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); coder=GetNextXMLTreeTag(coder); } coder_map=DestroyXMLTree(coder_map); return(status); }
static int MagickMain(int argc,char **argv) { #define MagickCommandSize(name,use_metadata,command) \ { (name), sizeof(name)-1, (use_metadata), (command) } typedef struct _CommandInfo { const char *client_name; size_t extent; MagickBooleanType use_metadata; MagickCommand command; } CommandInfo; const CommandInfo MagickCommands[] = { MagickCommandSize("magick", MagickFalse, MagickImageCommand), MagickCommandSize("convert", MagickFalse, ConvertImageCommand), MagickCommandSize("composite", MagickFalse, CompositeImageCommand), MagickCommandSize("identify", MagickTrue, IdentifyImageCommand), MagickCommandSize("animate", MagickFalse, AnimateImageCommand), MagickCommandSize("compare", MagickTrue, CompareImagesCommand), MagickCommandSize("conjure", MagickFalse, ConjureImageCommand), MagickCommandSize("display", MagickFalse, DisplayImageCommand), MagickCommandSize("import", MagickFalse, ImportImageCommand), MagickCommandSize("mogrify", MagickFalse, MogrifyImageCommand), MagickCommandSize("montage", MagickFalse, MontageImageCommand), MagickCommandSize("stream", MagickFalse, StreamImageCommand) }; char client_name[MagickPathExtent], *metadata; ExceptionInfo *exception; ImageInfo *image_info; int exit_code, offset; MagickBooleanType status; register ssize_t i; size_t number_commands; MagickCoreGenesis(*argv,MagickTrue); exception=AcquireExceptionInfo(); image_info=AcquireImageInfo(); GetPathComponent(argv[0],TailPath,client_name); number_commands=sizeof(MagickCommands)/sizeof(MagickCommands[0]); for (i=0; i < (ssize_t) number_commands; i++) { offset=LocaleNCompare(MagickCommands[i].client_name,client_name, MagickCommands[i].extent); if (offset == 0) break; } i%=(number_commands); if ((i == 0) && (argc > 1)) { for (i=1; i < (ssize_t) number_commands; i++) { offset=LocaleCompare(MagickCommands[i].client_name,argv[1]); if (offset == 0) { argc--; argv++; break; } } i%=number_commands; } metadata=(char *) NULL; status=MagickCommandGenesis(image_info,MagickCommands[i].command,argc,argv, MagickCommands[i].use_metadata ? &metadata : (char **) NULL,exception); if (metadata != (char *) NULL) { (void) fputs(metadata,stdout); metadata=DestroyString(metadata); } if (MagickCommands[i].command != CompareImagesCommand) exit_code=status != MagickFalse ? 0 : 1; else { if (status == MagickFalse) exit_code=2; else { const char *option; option=GetImageOption(image_info,"compare:dissimilar"); exit_code=IsStringTrue(option) ? 1 : 0; } } image_info=DestroyImageInfo(image_info); exception=DestroyExceptionInfo(exception); MagickCoreTerminus(); return(exit_code); }
WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,int argc, char **argv,char **metadata,ExceptionInfo *exception) { MagickCLI *cli_wand; size_t len; assert(image_info != (ImageInfo *) NULL); /* For specific OS command line requirements */ ReadCommandlLine(argc,&argv); /* Initialize special "CLI Wand" to hold images and settings (empty) */ cli_wand=AcquireMagickCLI(image_info,exception); cli_wand->location="Initializing"; cli_wand->filename=argv[0]; cli_wand->line=1; if (cli_wand->wand.debug != MagickFalse) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "\"%s\"",argv[0]); GetPathComponent(argv[0],TailPath,cli_wand->wand.name); SetClientName(cli_wand->wand.name); ConcatenateMagickString(cli_wand->wand.name,"-CLI",MagickPathExtent); len=strlen(argv[0]); /* precaution */ /* "convert" command - give a "deprecated" warning" */ if (len>=7 && LocaleCompare("convert",argv[0]+len-7) == 0) { cli_wand->process_flags = ConvertCommandOptionFlags; (void) FormatLocaleFile(stderr,"WARNING: %s\n", "The convert command is deprecated in IMv7, use \"magick\"\n"); } /* Special Case: If command name ends with "script" implied "-script" */ if (len>=6 && LocaleCompare("script",argv[0]+len-6) == 0) { if (argc >= 2 && ( (*(argv[1]) != '-') || (strlen(argv[1]) == 1) )) { GetPathComponent(argv[1],TailPath,cli_wand->wand.name); ProcessScriptOptions(cli_wand,argv[1],argc,argv,2); goto Magick_Command_Cleanup; } } /* Special Case: Version Information and Abort */ if (argc == 2) { if ((LocaleCompare("-version",argv[1]) == 0) || /* GNU standard option */ (LocaleCompare("--version",argv[1]) == 0) ) { /* just version */ CLIOption(cli_wand, "-version"); goto Magick_Command_Exit; } if ((LocaleCompare("-help",argv[1]) == 0) || /* GNU standard option */ (LocaleCompare("--help",argv[1]) == 0) ) { /* just a brief summary */ if (cli_wand->wand.debug != MagickFalse) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "- Special Option \"%s\"", argv[1]); MagickUsage(MagickFalse); goto Magick_Command_Exit; } if (LocaleCompare("-usage",argv[1]) == 0) { /* both version & usage */ if (cli_wand->wand.debug != MagickFalse) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "- Special Option \"%s\"", argv[1]); CLIOption(cli_wand, "-version" ); MagickUsage(MagickTrue); goto Magick_Command_Exit; } } /* not enough arguments -- including -help */ if (argc < 3) { (void) FormatLocaleFile(stderr, "Error: Invalid argument or not enough arguments\n\n"); MagickUsage(MagickFalse); goto Magick_Command_Exit; } /* Special "concatenate option (hidden) for delegate usage */ if (LocaleCompare("-concatenate",argv[1]) == 0) { if (cli_wand->wand.debug != MagickFalse) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "- Special Option \"%s\"", argv[1]); ConcatenateImages(argc,argv,exception); goto Magick_Command_Exit; } /* List Information and Abort */ if (argc == 3 && LocaleCompare("-list",argv[1]) == 0) { CLIOption(cli_wand, argv[1], argv[2]); goto Magick_Command_Exit; } /* ------------- */ /* The Main Call */ if (LocaleCompare("-script",argv[1]) == 0) { /* Start processing directly from script, no pre-script options Replace wand command name with script name First argument in the argv array is the script name to read. */ GetPathComponent(argv[2],TailPath,cli_wand->wand.name); ProcessScriptOptions(cli_wand,argv[2],argc,argv,3); } else { /* Normal Command Line, assumes output file as last option */ ProcessCommandOptions(cli_wand,argc,argv,1); } /* ------------- */ Magick_Command_Cleanup: cli_wand->location="Cleanup"; cli_wand->filename=argv[0]; if (cli_wand->wand.debug != MagickFalse) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "\"%s\"",argv[0]); /* recover original image_info and clean up stacks FUTURE: "-reset stacks" option */ while ((cli_wand->image_list_stack != (Stack *) NULL) && (cli_wand->image_list_stack->next != (Stack *) NULL)) CLIOption(cli_wand,")"); while ((cli_wand->image_info_stack != (Stack *) NULL) && (cli_wand->image_info_stack->next != (Stack *) NULL)) CLIOption(cli_wand,"}"); /* assert we have recovered the original structures */ assert(cli_wand->wand.image_info == image_info); assert(cli_wand->wand.exception == exception); /* Handle metadata for ImageMagickObject COM object for Windows VBS */ if (metadata != (char **) NULL) { const char *format; char *text; format="%w,%h,%m"; // Get this from image_info Option splaytree text=InterpretImageProperties(image_info,cli_wand->wand.images,format, exception); if (text == (char *) NULL) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError, "MemoryAllocationFailed","`%s'", GetExceptionMessage(errno)); else { (void) ConcatenateString(&(*metadata),text); text=DestroyString(text); } } Magick_Command_Exit: cli_wand->location="Exiting"; cli_wand->filename=argv[0]; if (cli_wand->wand.debug != MagickFalse) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "\"%s\"",argv[0]); /* Destroy the special CLI Wand */ cli_wand->wand.image_info = (ImageInfo *) NULL; /* not these */ cli_wand->wand.exception = (ExceptionInfo *) NULL; cli_wand=DestroyMagickCLI(cli_wand); return(exception->severity < ErrorException ? MagickTrue : MagickFalse); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e C I P I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Procedure WriteCIPImage() writes an image to a file in the Cisco IP phone % image format. % % The format of the WriteCIPImage method is: % % MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % % */ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent]; const ImageAttribute *attribute; long y; MagickBooleanType status; register const PixelPacket *p; register long i, x; unsigned char byte; /* Open output image file. */ 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->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); (void) WriteBlobString(image,"<CiscoIPPhoneImage>\n"); attribute=GetImageAttribute(image,"Label"); if (attribute != (const ImageAttribute *) NULL) (void) FormatMagickString(buffer,MaxTextExtent,"<Title>%s</Title>\n", attribute->value); else { char basename[MaxTextExtent]; GetPathComponent(image->filename,BasePath,basename); (void) FormatMagickString(buffer,MaxTextExtent,"<Title>%s</Title>\n", basename); } (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<LocationX>%ld</LocationX>\n", image->page.x); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<LocationY>%ld</LocationY>\n", image->page.y); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<Width>%lu</Width>\n", image->columns+(image->columns % 2)); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<Height>%lu</Height>\n", image->rows); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<Depth>2</Depth>\n"); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<Data>"); (void) SetImageColorspace(image,RGBColorspace); for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < ((long) image->columns-3); x+=4) { byte=(unsigned char) (((4*PixelIntensityToQuantum(p+3)/QuantumRange) & 0x03) << 6) | (((4*PixelIntensityToQuantum(p+2)/QuantumRange) & 0x03) << 4) | (((4*PixelIntensityToQuantum(p+1)/QuantumRange) & 0x03) << 2) | (((4*PixelIntensityToQuantum(p+0)/QuantumRange) & 0x03) << 0); (void) FormatMagickString(buffer,MaxTextExtent,"%02x",byte); (void) WriteBlobString(image,buffer); p+=4; } if ((image->columns % 4) != 0) { i=(long) image->columns % 4; byte=(unsigned char) ((((4*PixelIntensityToQuantum(p+Min(i,3))/QuantumRange) & 0x03) << 6) | (((4*PixelIntensityToQuantum(p+Min(i,2))/QuantumRange) & 0x03) << 4) | (((4*PixelIntensityToQuantum(p+Min(i,1))/QuantumRange) & 0x03) << 2) | (((4*PixelIntensityToQuantum(p+Min(i,0))/QuantumRange) & 0x03) << 0)); (void) FormatMagickString(buffer,MaxTextExtent,"%02x",~byte); (void) WriteBlobString(image,buffer); } if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(SaveImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } (void) WriteBlobString(image,"</Data>\n"); (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n"); CloseBlob(image); return(MagickTrue); }
static MagickBooleanType LoadLocaleList(const char *xml,const char *filename, const char *locale,const unsigned long depth,ExceptionInfo *exception) { const char *attribute; MagickBooleanType status; XMLTreeInfo *include, **components, *locale_map; /* Load the locale map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading locale map \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (locale_list == (SplayTreeInfo *) NULL) { locale_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyLocaleNode); if (locale_list == (SplayTreeInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } locale_map=NewXMLTree(xml,exception); if (locale_map == (XMLTreeInfo *) NULL) return(MagickFalse); include=GetXMLTreeChild(locale_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"locale"); if ((attribute != (const char *) NULL) && (LocaleCompare(locale,attribute) != 0)) { include=GetNextXMLTreeTag(include); continue; } attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > MaxRecursionDepth) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",filename); else { char path[MaxTextExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(path,attribute,MaxTextExtent); xml=FileToString(path,~0,exception); if (xml != (char *) NULL) { status=LoadLocaleList(xml,path,locale,depth+1,exception); xml=DestroyString(xml); } } } include=GetNextXMLTreeTag(include); } components=(XMLTreeInfo **) AcquireQuantumMemory(MaxRecursionDepth, sizeof(*components)); if (components == (XMLTreeInfo **) NULL) { locale_map=DestroyXMLTree(locale_map); ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } status=TraverseLocaleMap(filename,components,locale_map,0,exception); components=(XMLTreeInfo **) RelinquishMagickMemory(components); locale_map=DestroyXMLTree(locale_map); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d M a g i c L i s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadMagicList() loads the magic configuration file which provides a mapping % between magic attributes and a magic name. % % The format of the LoadMagicList method is: % % MagickBooleanType LoadMagicList(const char *xml,const char *filename, % const unsigned long depth,ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The magic list in XML format. % % o filename: The magic list filename. % % o depth: depth of <include /> statements. % % o exception: Return any errors or warnings in this structure. % */ static MagickBooleanType LoadMagicList(const char *xml,const char *filename, const unsigned long depth,ExceptionInfo *exception) { const char *attribute; MagicInfo *magic_info = (MagicInfo *) NULL; MagickBooleanType status; XMLTreeInfo *magic, *magic_map, *include; /* Load the magic map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading magic map \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (magic_list == (LinkedListInfo *) NULL) { magic_list=NewLinkedList(0); if (magic_list == (LinkedListInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } magic_map=NewXMLTree(xml,exception); if (magic_map == (XMLTreeInfo *) NULL) return(MagickFalse); status=MagickTrue; include=GetXMLTreeChild(magic_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",filename); else { char path[MaxTextExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(path,attribute,MaxTextExtent); xml=FileToString(path,~0,exception); if (xml != (char *) NULL) { status=LoadMagicList(xml,path,depth+1,exception); xml=DestroyString(xml); } } } include=GetNextXMLTreeTag(include); } magic=GetXMLTreeChild(magic_map,"magic"); while (magic != (XMLTreeInfo *) NULL) { const char *attribute; /* Process magic element. */ magic_info=(MagicInfo *) AcquireMagickMemory(sizeof(*magic_info)); if (magic_info == (MagicInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(magic_info,0,sizeof(*magic_info)); magic_info->path=ConstantString(filename); magic_info->signature=MagickSignature; attribute=GetXMLTreeAttribute(magic,"name"); if (attribute != (const char *) NULL) magic_info->name=ConstantString(attribute); attribute=GetXMLTreeAttribute(magic,"offset"); if (attribute != (const char *) NULL) magic_info->offset=(MagickOffsetType) atol(attribute); attribute=GetXMLTreeAttribute(magic,"stealth"); if (attribute != (const char *) NULL) magic_info->stealth=IsMagickTrue(attribute); attribute=GetXMLTreeAttribute(magic,"target"); if (attribute != (const char *) NULL) { const char *p; register unsigned char *q; magic_info->target=ConstantString(attribute); magic_info->magic=(unsigned char *) ConstantString(attribute); q=magic_info->magic; for (p=magic_info->target; *p != '\0'; ) { if (*p == '\\') { p++; if (isdigit((int) ((unsigned char) *p)) != 0) { char *end; *q++=(unsigned char) strtol(p,&end,8); p+=(end-p); magic_info->length++; continue; } switch (*p) { case 'b': *q='\b'; break; case 'f': *q='\f'; break; case 'n': *q='\n'; break; case 'r': *q='\r'; break; case 't': *q='\t'; break; case 'v': *q='\v'; break; case 'a': *q='a'; break; case '?': *q='\?'; break; default: *q=(unsigned char) (*p); break; } p++; q++; magic_info->length++; continue; } *q++=(unsigned char) (*p++); magic_info->length++; } } status=AppendValueToLinkedList(magic_list,magic_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); magic=GetNextXMLTreeTag(magic); } magic_map=DestroyXMLTree(magic_map); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d M i m e C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadMimeCache() loads the mime configurations which provides a mapping % between mime attributes and a mime name. % % The format of the LoadMimeCache method is: % % MagickBooleanType LoadMimeCache(LinkedListInfo *cache,const char *xml, % const char *filename,const size_t depth,ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The mime list in XML format. % % o filename: The mime list filename. % % o depth: depth of <include /> statements. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadMimeCache(LinkedListInfo *cache,const char *xml, const char *filename,const size_t depth,ExceptionInfo *exception) { const char *attribute; MimeInfo *mime_info = (MimeInfo *) NULL; MagickStatusType status; XMLTreeInfo *mime, *mime_map, *include; /* Load the mime map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading mime map \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); mime_map=NewXMLTree(xml,exception); if (mime_map == (XMLTreeInfo *) NULL) return(MagickFalse); status=MagickTrue; include=GetXMLTreeChild(mime_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",filename); else { char path[MagickPathExtent], *file_xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MagickPathExtent); if (*attribute == *DirectorySeparator) (void) CopyMagickString(path,attribute,MagickPathExtent); else (void) ConcatenateMagickString(path,attribute,MagickPathExtent); file_xml=FileToXML(path,~0UL); if (file_xml != (char *) NULL) { status&=LoadMimeCache(cache,file_xml,path,depth+1,exception); file_xml=DestroyString(file_xml); } } } include=GetNextXMLTreeTag(include); } mime=GetXMLTreeChild(mime_map,"mime"); while (mime != (XMLTreeInfo *) NULL) { /* Process mime element. */ mime_info=(MimeInfo *) AcquireCriticalMemory(sizeof(*mime_info)); (void) ResetMagickMemory(mime_info,0,sizeof(*mime_info)); mime_info->path=ConstantString(filename); mime_info->signature=MagickCoreSignature; attribute=GetXMLTreeAttribute(mime,"data-type"); if (attribute != (const char *) NULL) mime_info->data_type=(DataType) ParseCommandOption(MagickDataTypeOptions, MagickTrue,attribute); attribute=GetXMLTreeAttribute(mime,"description"); if (attribute != (const char *) NULL) mime_info->description=ConstantString(attribute); attribute=GetXMLTreeAttribute(mime,"endian"); if (attribute != (const char *) NULL) mime_info->endian=(EndianType) ParseCommandOption(MagickEndianOptions, MagickTrue,attribute); attribute=GetXMLTreeAttribute(mime,"magic"); if (attribute != (const char *) NULL) { char *token; const char *p; register unsigned char *q; token=AcquireString(attribute); (void) SubstituteString((char **) &token,"<","<"); (void) SubstituteString((char **) &token,"&","&"); (void) SubstituteString((char **) &token,""","\""); mime_info->magic=(unsigned char *) AcquireString(token); q=mime_info->magic; for (p=token; *p != '\0'; ) { if (*p == '\\') { p++; if (isdigit((int) ((unsigned char) *p)) != 0) { char *end; *q++=(unsigned char) strtol(p,&end,8); p+=(end-p); mime_info->length++; continue; } switch (*p) { case 'b': *q='\b'; break; case 'f': *q='\f'; break; case 'n': *q='\n'; break; case 'r': *q='\r'; break; case 't': *q='\t'; break; case 'v': *q='\v'; break; case 'a': *q='a'; break; case '?': *q='\?'; break; default: *q=(unsigned char) (*p); break; } p++; q++; mime_info->length++; continue; } *q++=(unsigned char) (*p++); mime_info->length++; } token=DestroyString(token); if (mime_info->data_type != StringData) mime_info->value=(ssize_t) strtoul((char *) mime_info->magic, (char **) NULL,0); } attribute=GetXMLTreeAttribute(mime,"mask"); if (attribute != (const char *) NULL) mime_info->mask=(ssize_t) strtoul(attribute,(char **) NULL,0); attribute=GetXMLTreeAttribute(mime,"offset"); if (attribute != (const char *) NULL) { char *c; mime_info->offset=(MagickOffsetType) strtol(attribute,&c,0); if (*c == ':') mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0); } attribute=GetXMLTreeAttribute(mime,"pattern"); if (attribute != (const char *) NULL) mime_info->pattern=ConstantString(attribute); attribute=GetXMLTreeAttribute(mime,"priority"); if (attribute != (const char *) NULL) mime_info->priority=(ssize_t) strtol(attribute,(char **) NULL,0); attribute=GetXMLTreeAttribute(mime,"stealth"); if (attribute != (const char *) NULL) mime_info->stealth=IsStringTrue(attribute); attribute=GetXMLTreeAttribute(mime,"type"); if (attribute != (const char *) NULL) mime_info->type=ConstantString(attribute); status=AppendValueToLinkedList(cache,mime_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); mime=GetNextXMLTreeTag(mime); } mime_map=DestroyXMLTree(mime_map); 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e U I L I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Procedure WriteUILImage() writes an image to a file in the X-Motif UIL table % format. % % The format of the WriteUILImage method is: % % MagickBooleanType WriteUILImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteUILImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { #define MaxCixels 92 char basename[MagickPathExtent], buffer[MagickPathExtent], name[MagickPathExtent], *symbol; int j; MagickBooleanType status, transparent; MagickSizeType number_pixels; PixelInfo pixel; register const Quantum *p; register ssize_t i, x; size_t characters_per_pixel, colors; ssize_t k, y; static const char Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk" "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); (void) TransformImageColorspace(image,sRGBColorspace,exception); transparent=MagickFalse; i=0; p=(const Quantum *) NULL; if (image->storage_class == PseudoClass) colors=image->colors; else { unsigned char *matte_image; /* Convert DirectClass to PseudoClass image. */ matte_image=(unsigned char *) NULL; if (image->alpha_trait != UndefinedPixelTrait) { /* Map all the transparent pixels. */ number_pixels=(MagickSizeType) image->columns*image->rows; if (number_pixels != ((MagickSizeType) (size_t) number_pixels)) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); matte_image=(unsigned char *) AcquireQuantumMemory(image->columns, image->rows*sizeof(*matte_image)); if (matte_image == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { matte_image[i]=(unsigned char) (GetPixelAlpha(image,p) == (Quantum) TransparentAlpha ? 1 : 0); if (matte_image[i] != 0) transparent=MagickTrue; i++; p+=GetPixelChannels(image); } } } (void) SetImageType(image,PaletteType,exception); colors=image->colors; if (transparent != MagickFalse) { register Quantum *q; colors++; for (y=0; y < (ssize_t) image->rows; y++) { q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { if (matte_image[i] != 0) SetPixelIndex(image,(Quantum) image->colors,q); q+=GetPixelChannels(image); } } } if (matte_image != (unsigned char *) NULL) matte_image=(unsigned char *) RelinquishMagickMemory(matte_image); } /* Compute the character per pixel. */ characters_per_pixel=1; for (k=MaxCixels; (ssize_t) colors > k; k*=MaxCixels) characters_per_pixel++; /* UIL header. */ symbol=AcquireString(""); (void) WriteBlobString(image,"/* UIL */\n"); GetPathComponent(image->filename,BasePath,basename); (void) FormatLocaleString(buffer,MagickPathExtent, "value\n %s_ct : color_table(\n",basename); (void) WriteBlobString(image,buffer); GetPixelInfo(image,&pixel); for (i=0; i < (ssize_t) colors; i++) { /* Define UIL color. */ pixel=image->colormap[i]; pixel.colorspace=sRGBColorspace; pixel.depth=8; pixel.alpha=(double) OpaqueAlpha; GetColorTuple(&pixel,MagickTrue,name); if (transparent != MagickFalse) if (i == (ssize_t) (colors-1)) (void) CopyMagickString(name,"None",MagickPathExtent); /* Write UIL color. */ k=i % MaxCixels; symbol[0]=Cixel[k]; for (j=1; j < (int) characters_per_pixel; j++) { k=((i-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) SubstituteString(&symbol,"'","''"); if (LocaleCompare(name,"None") == 0) (void) FormatLocaleString(buffer,MagickPathExtent, " background color = '%s'",symbol); else (void) FormatLocaleString(buffer,MagickPathExtent, " color('%s',%s) = '%s'",name, GetPixelInfoIntensity(image,image->colormap+i) < (QuantumRange/2.0) ? "background" : "foreground",symbol); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent,"%s", (i == (ssize_t) (colors-1) ? ");\n" : ",\n")); (void) WriteBlobString(image,buffer); } /* Define UIL pixels. */ GetPathComponent(image->filename,BasePath,basename); (void) FormatLocaleString(buffer,MagickPathExtent, " %s_icon : icon(color_table = %s_ct,\n",basename,basename); (void) WriteBlobString(image,buffer); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; (void) WriteBlobString(image," \""); for (x=0; x < (ssize_t) image->columns; x++) { k=((ssize_t) GetPixelIndex(image,p) % MaxCixels); symbol[0]=Cixel[k]; for (j=1; j < (int) characters_per_pixel; j++) { k=(((int) GetPixelIndex(image,p)-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) CopyMagickString(buffer,symbol,MagickPathExtent); (void) WriteBlobString(image,buffer); p+=GetPixelChannels(image); } (void) FormatLocaleString(buffer,MagickPathExtent,"\"%s\n", (y == (ssize_t) (image->rows-1) ? ");" : ",")); (void) WriteBlobString(image,buffer); status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } symbol=DestroyString(symbol); (void) CloseBlob(image); return(MagickTrue); }
static MagickBooleanType LoadLocaleList(const char *xml,const char *filename, const char *locale,const size_t depth,ExceptionInfo *exception) { char keyword[MaxTextExtent], message[MaxTextExtent], tag[MaxTextExtent], *token; const char *q; FatalErrorHandler fatal_handler; LocaleInfo *locale_info; MagickBooleanType status; register char *p; /* Read the locale configure file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading locale configure file \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (locale_list == (SplayTreeInfo *) NULL) { locale_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyLocaleNode); if (locale_list == (SplayTreeInfo *) NULL) return(MagickFalse); } status=MagickTrue; locale_info=(LocaleInfo *) NULL; *tag='\0'; *message='\0'; *keyword='\0'; fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler); token=AcquireString(xml); for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) { GetMagickToken(q,&q,token); while (isspace((int) ((unsigned char) *q)) != 0) q++; } continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) { GetMagickToken(q,&q,token); while (isspace((int) ((unsigned char) *q)) != 0) q++; } continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"locale") == 0) { if (LocaleCompare(locale,token) != 0) break; continue; } if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); else { char path[MaxTextExtent], *xml; *path='\0'; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MaxTextExtent); else (void) ConcatenateMagickString(path,token,MaxTextExtent); xml=FileToString(path,~0,exception); if (xml != (char *) NULL) { status=LoadLocaleList(xml,path,locale,depth+1,exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<locale") == 0) { /* Locale element. */ while ((*token != '>') && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); } continue; } if (LocaleCompare(keyword,"</locale>") == 0) { ChopLocaleComponents(tag,1); (void) ConcatenateMagickString(tag,"/",MaxTextExtent); continue; } if (LocaleCompare(keyword,"<localemap>") == 0) continue; if (LocaleCompare(keyword,"</localemap>") == 0) continue; if (LocaleCompare(keyword,"<message") == 0) { /* Message element. */ while ((*token != '>') && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"name") == 0) { (void) ConcatenateMagickString(tag,token,MaxTextExtent); (void) ConcatenateMagickString(tag,"/",MaxTextExtent); } } for (p=(char *) q; (*q != '<') && (*q != '\0'); q++) ; while (isspace((int) ((unsigned char) *p)) != 0) p++; q--; while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p)) q--; (void) CopyMagickString(message,p,(size_t) (q-p+2)); locale_info=(LocaleInfo *) AcquireMagickMemory(sizeof(*locale_info)); if (locale_info == (LocaleInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(locale_info,0,sizeof(*locale_info)); locale_info->path=ConstantString(filename); locale_info->tag=ConstantString(tag); locale_info->message=ConstantString(message); locale_info->signature=MagickSignature; status=AddValueToSplayTree(locale_list,locale_info->tag,locale_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", locale_info->tag); (void) ConcatenateMagickString(tag,message,MaxTextExtent); (void) ConcatenateMagickString(tag,"\n",MaxTextExtent); q++; continue; } if (LocaleCompare(keyword,"</message>") == 0) { ChopLocaleComponents(tag,2); (void) ConcatenateMagickString(tag,"/",MaxTextExtent); continue; } if (*keyword == '<') { /* Subpath element. */ if (*(keyword+1) == '?') continue; if (*(keyword+1) == '/') { ChopLocaleComponents(tag,1); if (*tag != '\0') (void) ConcatenateMagickString(tag,"/",MaxTextExtent); continue; } token[strlen(token)-1]='\0'; (void) CopyMagickString(token,token+1,MaxTextExtent); (void) ConcatenateMagickString(tag,token,MaxTextExtent); (void) ConcatenateMagickString(tag,"/",MaxTextExtent); continue; } GetMagickToken(q,(const char **) NULL,token); if (*token != '=') continue; } token=(char *) RelinquishMagickMemory(token); (void) SetFatalErrorHandler(fatal_handler); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteImage() writes an image or an image sequence to a file or file handle. % If writing to a file is on disk, the name is defined by the filename member % of the image structure. WriteImage() returns MagickFalse is there is a % memory shortage or if the image cannot be written. Check the exception % member of image to determine the cause for any failure. % % The format of the WriteImage method is: % % MagickBooleanType WriteImage(const ImageInfo *image_info,Image *image, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o image: the image. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { char filename[MaxTextExtent]; const char *option; const DelegateInfo *delegate_info; const MagickInfo *magick_info; ExceptionInfo *sans_exception; ImageInfo *write_info; MagickBooleanType status, temporary; MagickStatusType thread_support; PolicyDomain domain; PolicyRights rights; /* Determine image type from filename prefix or suffix (e.g. image.jpg). */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); sans_exception=AcquireExceptionInfo(); write_info=CloneImageInfo(image_info); (void) CopyMagickString(write_info->filename,image->filename,MaxTextExtent); if (*write_info->magick == '\0') (void) CopyMagickString(write_info->magick,image->magick,MaxTextExtent); (void) SetImageInfo(write_info,1,sans_exception); if (LocaleCompare(write_info->magick,"clipmask") == 0) { if (image->clip_mask == (Image *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), OptionError,"NoClipPathDefined","`%s'",image->filename); return(MagickFalse); } image=image->clip_mask; (void) SetImageInfo(write_info,1,sans_exception); } (void) CopyMagickString(filename,image->filename,MaxTextExtent); (void) CopyMagickString(image->filename,write_info->filename,MaxTextExtent); domain=CoderPolicyDomain; rights=WritePolicyRights; if (IsRightsAuthorized(domain,rights,write_info->magick) == MagickFalse) { sans_exception=DestroyExceptionInfo(sans_exception); errno=EPERM; ThrowBinaryException(PolicyError,"NotAuthorized",filename); } magick_info=GetMagickInfo(write_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (magick_info != (const MagickInfo *) NULL) { if (GetMagickEndianSupport(magick_info) == MagickFalse) image->endian=UndefinedEndian; else if ((image_info->endian == UndefinedEndian) && (GetMagickRawSupport(magick_info) != MagickFalse)) { size_t lsb_first; lsb_first=1; image->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian; } } (void) SyncImageProfiles(image); option=GetImageOption(image_info,"delegate:bimodal"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse) && (write_info->page == (char *) NULL) && (GetPreviousImageInList(image) == (Image *) NULL) && (GetNextImageInList(image) == (Image *) NULL) && (IsTaintImage(image) == MagickFalse)) { delegate_info=GetDelegateInfo(image->magick,write_info->magick,exception); if ((delegate_info != (const DelegateInfo *) NULL) && (GetDelegateMode(delegate_info) == 0) && (IsPathAccessible(image->magick_filename) != MagickFalse)) { /* Process image with bi-modal delegate. */ (void) CopyMagickString(image->filename,image->magick_filename, MaxTextExtent); status=InvokeDelegate(write_info,image,image->magick, write_info->magick,exception); write_info=DestroyImageInfo(write_info); (void) CopyMagickString(image->filename,filename,MaxTextExtent); return(status); } } status=MagickFalse; temporary=MagickFalse; if ((magick_info != (const MagickInfo *) NULL) && (GetMagickSeekableStream(magick_info) != MagickFalse)) { char filename[MaxTextExtent]; (void) CopyMagickString(filename,image->filename,MaxTextExtent); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); (void) CopyMagickString(image->filename,filename,MaxTextExtent); if (status != MagickFalse) { if (IsBlobSeekable(image) == MagickFalse) { /* A seekable stream is required by the encoder. */ write_info->adjoin=MagickTrue; (void) CopyMagickString(write_info->filename,image->filename, MaxTextExtent); (void) AcquireUniqueFilename(image->filename); temporary=MagickTrue; } (void) CloseBlob(image); } } if (constitute_semaphore == (SemaphoreInfo *) NULL) AcquireSemaphoreInfo(&constitute_semaphore); if ((magick_info != (const MagickInfo *) NULL) && (GetImageEncoder(magick_info) != (EncodeImageHandler *) NULL)) { /* Call appropriate image writer based on image type. */ thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & EncoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); status=GetImageEncoder(magick_info)(write_info,image,exception); if ((thread_support & EncoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } else { delegate_info=GetDelegateInfo((char *) NULL,write_info->magick,exception); if (delegate_info != (DelegateInfo *) NULL) { /* Process the image with delegate. */ *write_info->filename='\0'; if (GetDelegateThreadSupport(delegate_info) == MagickFalse) LockSemaphoreInfo(constitute_semaphore); status=InvokeDelegate(write_info,image,(char *) NULL, write_info->magick,exception); if (GetDelegateThreadSupport(delegate_info) == MagickFalse) UnlockSemaphoreInfo(constitute_semaphore); (void) CopyMagickString(image->filename,filename,MaxTextExtent); } else { sans_exception=AcquireExceptionInfo(); magick_info=GetMagickInfo(write_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if ((write_info->affirm == MagickFalse) && (magick_info == (const MagickInfo *) NULL)) { (void) CopyMagickString(write_info->magick,image->magick, MaxTextExtent); magick_info=GetMagickInfo(write_info->magick,exception); } if ((magick_info == (const MagickInfo *) NULL) || (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL)) { char extension[MaxTextExtent]; GetPathComponent(image->filename,ExtensionPath,extension); if (*extension != '\0') magick_info=GetMagickInfo(extension,exception); else magick_info=GetMagickInfo(image->magick,exception); (void) CopyMagickString(image->filename,filename,MaxTextExtent); } if ((magick_info == (const MagickInfo *) NULL) || (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL)) (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'", image->filename); else { /* Call appropriate image writer based on image type. */ thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & EncoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); status=GetImageEncoder(magick_info)(write_info,image,exception); if ((thread_support & EncoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } } } if (GetBlobError(image) != MagickFalse) ThrowFileException(exception,FileOpenError, "AnErrorHasOccurredWritingToFile",image->filename); if (temporary == MagickTrue) { /* Copy temporary image file to permanent. */ status=OpenBlob(write_info,image,ReadBinaryBlobMode,exception); if (status != MagickFalse) status=ImageToFile(image,write_info->filename,exception); (void) CloseBlob(image); (void) RelinquishUniqueFileResource(image->filename); (void) CopyMagickString(image->filename,write_info->filename, MaxTextExtent); } if ((LocaleCompare(write_info->magick,"info") != 0) && (write_info->verbose != MagickFalse)) (void) IdentifyImage(image,stdout,MagickFalse,exception); write_info=DestroyImageInfo(write_info); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e C I P I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Procedure WriteCIPImage() writes an image to a file in the Cisco IP phone % image format. % % The format of the WriteCIPImage method is: % % MagickBooleanType WriteCIPImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { char buffer[MagickPathExtent]; const char *value; MagickBooleanType status; register const Quantum *p; register ssize_t i, x; ssize_t y; unsigned char byte; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); (void) WriteBlobString(image,"<CiscoIPPhoneImage>\n"); value=GetImageProperty(image,"label",exception); if (value != (const char *) NULL) (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",value); else { char basename[MagickPathExtent]; GetPathComponent(image->filename,BasePath,basename); (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n", basename); } (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent, "<LocationX>%.20g</LocationX>\n",(double) image->page.x); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent, "<LocationY>%.20g</LocationY>\n",(double) image->page.y); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent,"<Width>%.20g</Width>\n", (double) (image->columns+(image->columns % 2))); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent,"<Height>%.20g</Height>\n", (double) image->rows); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent,"<Depth>2</Depth>\n"); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<Data>"); (void) TransformImageColorspace(image,sRGBColorspace,exception); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; for (x=0; x < ((ssize_t) image->columns-3); x+=4) { byte=(unsigned char) ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+3))/QuantumRange) & 0x03) << 6) | (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+2))/QuantumRange) & 0x03) << 4) | (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+1))/QuantumRange) & 0x03) << 2) | (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+0))/QuantumRange) & 0x03) << 0)); (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",byte); (void) WriteBlobString(image,buffer); p+=4; } if ((image->columns % 4) != 0) { i=(ssize_t) image->columns % 4; byte=(unsigned char) ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,3)))/QuantumRange) & 0x03) << 6) | (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,2)))/QuantumRange) & 0x03) << 4) | (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,1)))/QuantumRange) & 0x03) << 2) | (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,0)))/QuantumRange) & 0x03) << 0)); (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",~byte); (void) WriteBlobString(image,buffer); } status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } (void) WriteBlobString(image,"</Data>\n"); (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n"); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d M a g i c L i s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadMagicCache() loads the magic configurations which provides a mapping % between magic attributes and a magic name. % % The format of the LoadMagicCache method is: % % MagickBooleanType LoadMagicCache(LinkedListInfo *magic_cache, % const char *xml,const char *filename,const size_t depth, % ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The magic list in XML format. % % o filename: The magic list filename. % % o depth: depth of <include /> statements. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadMagicCache(LinkedListInfo *magic_cache, const char *xml,const char *filename,const size_t depth, ExceptionInfo *exception) { char keyword[MaxTextExtent], *token; const char *q; MagicInfo *magic_info; MagickStatusType status; /* Load the magic map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading magic configure file \"%s\" ...",filename); if (xml == (char *) NULL) return(MagickFalse); status=MagickTrue; magic_info=(MagicInfo *) NULL; token=AcquireString(xml); for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); else { char path[MaxTextExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MaxTextExtent); else (void) ConcatenateMagickString(path,token,MaxTextExtent); xml=FileToXML(path,~0UL); if (xml != (char *) NULL) { status&=LoadMagicCache(magic_cache,xml,path,depth+1, exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<magic") == 0) { /* Magic element. */ magic_info=(MagicInfo *) AcquireMagickMemory(sizeof(*magic_info)); if (magic_info == (MagicInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(magic_info,0,sizeof(*magic_info)); magic_info->path=ConstantString(filename); magic_info->exempt=MagickFalse; magic_info->signature=MagickSignature; continue; } if (magic_info == (MagicInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AppendValueToLinkedList(magic_cache,magic_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", magic_info->name); magic_info=(MagicInfo *) NULL; continue; } GetMagickToken(q,(const char **) NULL,token); if (*token != '=') continue; GetMagickToken(q,&q,token); GetMagickToken(q,&q,token); switch (*keyword) { case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { magic_info->name=ConstantString(token); break; } break; } case 'O': case 'o': { if (LocaleCompare((char *) keyword,"offset") == 0) { magic_info->offset=(MagickOffsetType) StringToLong(token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { magic_info->stealth=IsMagickTrue(token); break; } break; } case 'T': case 't': { if (LocaleCompare((char *) keyword,"target") == 0) { char *p; register unsigned char *q; size_t length; length=strlen(token); magic_info->target=ConstantString(token); magic_info->magic=(unsigned char *) ConstantString(token); q=magic_info->magic; for (p=magic_info->target; *p != '\0'; ) { if (*p == '\\') { p++; if (isdigit((int) ((unsigned char) *p)) != 0) { char *end; *q++=(unsigned char) strtol(p,&end,8); p+=(end-p); magic_info->length++; continue; } switch (*p) { case 'b': *q='\b'; break; case 'f': *q='\f'; break; case 'n': *q='\n'; break; case 'r': *q='\r'; break; case 't': *q='\t'; break; case 'v': *q='\v'; break; case 'a': *q='a'; break; case '?': *q='\?'; break; default: *q=(unsigned char) (*p); break; } p++; q++; magic_info->length++; continue; } else if (LocaleNCompare(p,"&",5) == 0) (void) CopyMagickString(p+1,p+5,length-magic_info->length); *q++=(unsigned char) (*p++); magic_info->length++; } break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status != 0 ? MagickTrue : MagickFalse); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d P o l i c y C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadPolicyCache() loads the policy configurations which provides a mapping % between policy attributes and a policy domain. % % The format of the LoadPolicyCache method is: % % MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml, % const char *filename,const size_t depth,ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The policy list in XML format. % % o filename: The policy list filename. % % o depth: depth of <include /> statements. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml, const char *filename,const size_t depth,ExceptionInfo *exception) { char keyword[MagickPathExtent], *token; const char *q; MagickStatusType status; PolicyInfo *policy_info; size_t extent; /* Load the policy map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading policy file \"%s\" ...",filename); if (xml == (char *) NULL) return(MagickFalse); status=MagickTrue; policy_info=(PolicyInfo *) NULL; token=AcquireString(xml); extent=strlen(token)+MagickPathExtent; for (q=(const char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetNextToken(q,&q,extent,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MagickPathExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Docdomain element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetNextToken(q,&q,extent,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetNextToken(q,&q,extent,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MagickPathExtent); GetNextToken(q,&q,extent,token); if (*token != '=') continue; GetNextToken(q,&q,extent,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > MagickMaxRecursionDepth) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); else { char path[MagickPathExtent], *file_xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MagickPathExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MagickPathExtent); else (void) ConcatenateMagickString(path,token,MagickPathExtent); file_xml=FileToXML(path,~0UL); if (file_xml != (char *) NULL) { status&=LoadPolicyCache(cache,file_xml,path, depth+1,exception); file_xml=DestroyString(file_xml); } } } } continue; } if (LocaleCompare(keyword,"<policy") == 0) { /* Policy element. */ policy_info=(PolicyInfo *) AcquireCriticalMemory(sizeof(*policy_info)); (void) memset(policy_info,0,sizeof(*policy_info)); policy_info->path=ConstantString(filename); policy_info->exempt=MagickFalse; policy_info->signature=MagickCoreSignature; continue; } if (policy_info == (PolicyInfo *) NULL) continue; if ((LocaleCompare(keyword,"/>") == 0) || (LocaleCompare(keyword,"</policy>") == 0)) { status=AppendValueToLinkedList(cache,policy_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", policy_info->name); policy_info=(PolicyInfo *) NULL; continue; } GetNextToken(q,(const char **) NULL,extent,token); if (*token != '=') continue; GetNextToken(q,&q,extent,token); GetNextToken(q,&q,extent,token); switch (*keyword) { case 'D': case 'd': { if (LocaleCompare((char *) keyword,"domain") == 0) { policy_info->domain=(PolicyDomain) ParseCommandOption( MagickPolicyDomainOptions,MagickTrue,token); break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { policy_info->name=ConstantString(token); break; } break; } case 'P': case 'p': { if (LocaleCompare((char *) keyword,"pattern") == 0) { policy_info->pattern=ConstantString(token); break; } break; } case 'R': case 'r': { if (LocaleCompare((char *) keyword,"rights") == 0) { policy_info->rights=(PolicyRights) ParseCommandOption( MagickPolicyRightsOptions,MagickTrue,token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { policy_info->stealth=IsStringTrue(token); break; } break; } case 'V': case 'v': { if (LocaleCompare((char *) keyword,"value") == 0) { policy_info->value=ConstantString(token); break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status != 0 ? MagickTrue : MagickFalse); }
static MagickBooleanType LoadTypeList(const char *xml,const char *filename, const size_t depth,ExceptionInfo *exception) { char font_path[MaxTextExtent], keyword[MaxTextExtent], *token; const char *q; MagickBooleanType status; TypeInfo *type_info; /* Load the type map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading type configure file \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (type_list == (SplayTreeInfo *) NULL) { type_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyTypeNode); if (type_list == (SplayTreeInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } status=MagickTrue; type_info=(TypeInfo *) NULL; token=AcquireString(xml); #if defined(MAGICKCORE_WINDOWS_SUPPORT) /* Determine the Ghostscript font path. */ *font_path='\0'; if (NTGhostscriptFonts(font_path,MaxTextExtent-2)) (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent); #endif for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token); else { char path[MaxTextExtent], *xml; ExceptionInfo *sans_exception; *path='\0'; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MaxTextExtent); else (void) ConcatenateMagickString(path,token,MaxTextExtent); sans_exception=AcquireExceptionInfo(); xml=FileToString(path,~0UL,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (xml != (char *) NULL) { status=LoadTypeList(xml,path,depth+1,exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<type") == 0) { /* Type element. */ type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(type_info,0,sizeof(*type_info)); type_info->path=ConstantString(filename); type_info->signature=MagickSignature; continue; } if (type_info == (TypeInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AddValueToSplayTree(type_list,type_info->name,type_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name); type_info=(TypeInfo *) NULL; } GetMagickToken(q,(const char **) NULL,token); if (*token != '=') continue; GetMagickToken(q,&q,token); GetMagickToken(q,&q,token); switch (*keyword) { case 'E': case 'e': { if (LocaleCompare((char *) keyword,"encoding") == 0) { type_info->encoding=ConstantString(token); break; } break; } case 'F': case 'f': { if (LocaleCompare((char *) keyword,"face") == 0) { type_info->face=StringToUnsignedLong(token); break; } if (LocaleCompare((char *) keyword,"family") == 0) { type_info->family=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"format") == 0) { type_info->format=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"foundry") == 0) { type_info->foundry=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"fullname") == 0) { type_info->description=ConstantString(token); break; } break; } case 'G': case 'g': { if (LocaleCompare((char *) keyword,"glyphs") == 0) { char *path; path=ConstantString(token); #if defined(MAGICKCORE_WINDOWS_SUPPORT) if (strchr(path,'@') != (char *) NULL) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif if (IsPathAccessible(path) == MagickFalse) { /* Relative path. */ path=DestroyString(path); GetPathComponent(filename,HeadPath,font_path); (void) ConcatenateMagickString(font_path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(font_path,token,MaxTextExtent); path=ConstantString(font_path); if (IsPathAccessible(path) == MagickFalse) { path=DestroyString(path); path=ConstantString(token); } } type_info->glyphs=path; break; } break; } case 'M': case 'm': { if (LocaleCompare((char *) keyword,"metrics") == 0) { char *path; path=ConstantString(token); #if defined(MAGICKCORE_WINDOWS_SUPPORT) if (strchr(path,'@') != (char *) NULL) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif if (IsPathAccessible(path) == MagickFalse) { /* Relative path. */ path=DestroyString(path); GetPathComponent(filename,HeadPath,font_path); (void) ConcatenateMagickString(font_path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(font_path,token,MaxTextExtent); path=ConstantString(font_path); } type_info->metrics=path; break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { type_info->name=ConstantString(token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { type_info->stealth=IsStringTrue(token); break; } if (LocaleCompare((char *) keyword,"stretch") == 0) { type_info->stretch=(StretchType) ParseCommandOption( MagickStretchOptions,MagickFalse,token); break; } if (LocaleCompare((char *) keyword,"style") == 0) { type_info->style=(StyleType) ParseCommandOption(MagickStyleOptions, MagickFalse,token); break; } break; } case 'W': case 'w': { if (LocaleCompare((char *) keyword,"weight") == 0) { type_info->weight=StringToUnsignedLong(token); if (LocaleCompare(token,"bold") == 0) type_info->weight=700; if (LocaleCompare(token,"normal") == 0) type_info->weight=400; break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status); }
MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file, const MagickBooleanType verbose,ExceptionInfo *exception) { char color[MaxTextExtent], format[MaxTextExtent], key[MaxTextExtent]; ChannelFeatures *channel_features; ChannelStatistics *channel_statistics; ColorspaceType colorspace; const char *artifact, *name, *property, *registry, *value; const MagickInfo *magick_info; double elapsed_time, user_time; ImageType type; MagickBooleanType ping; register const Quantum *p; register ssize_t i, x; size_t distance, scale; ssize_t y; 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) FormatLocaleFile(file,"%s=>",image->magick_filename); if ((GetPreviousImageInList(image) == (Image *) NULL) && (GetNextImageInList(image) == (Image *) NULL) && (image->scene == 0)) (void) FormatLocaleFile(file,"%s ",image->filename); else (void) FormatLocaleFile(file,"%s[%.20g] ",image->filename,(double) image->scene); (void) FormatLocaleFile(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) FormatLocaleFile(file,"%.20gx%.20g=>",(double) image->magick_columns,(double) image->magick_rows); (void) FormatLocaleFile(file,"%.20gx%.20g ",(double) image->columns, (double) image->rows); if ((image->page.width != 0) || (image->page.height != 0) || (image->page.x != 0) || (image->page.y != 0)) (void) FormatLocaleFile(file,"%.20gx%.20g%+.20g%+.20g ",(double) image->page.width,(double) image->page.height,(double) image->page.x, (double) image->page.y); (void) FormatLocaleFile(file,"%.20g-bit ",(double) image->depth); if (image->type != UndefinedType) (void) FormatLocaleFile(file,"%s ",CommandOptionToMnemonic( MagickTypeOptions,(ssize_t) image->type)); if (image->storage_class == DirectClass) { (void) FormatLocaleFile(file,"DirectClass "); if (image->total_colors != 0) { (void) FormatMagickSize(image->total_colors,MagickFalse,format); (void) FormatLocaleFile(file,"%s ",format); } } else if (image->total_colors <= image->colors) (void) FormatLocaleFile(file,"PseudoClass %.20gc ",(double) image->colors); else (void) FormatLocaleFile(file,"PseudoClass %.20g=>%.20gc ",(double) image->total_colors,(double) image->colors); if (image->error.mean_error_per_pixel != 0.0) (void) FormatLocaleFile(file,"%.20g/%f/%fdb ",(double) (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),MagickFalse,format); (void) FormatLocaleFile(file,"%s ",format); } (void) FormatLocaleFile(file,"%0.3fu %lu:%02lu.%03lu",user_time, (unsigned long) (elapsed_time/60.0),(unsigned long) floor(fmod( elapsed_time,60.0)),(unsigned long) (1000.0*(elapsed_time- floor(elapsed_time)))); (void) FormatLocaleFile(file,"\n"); (void) fflush(file); return(ferror(file) != 0 ? MagickFalse : MagickTrue); } /* Display verbose info about the image. */ p=GetVirtualPixels(image,0,0,1,1,exception); ping=p == (const Quantum *) NULL ? MagickTrue : MagickFalse; type=GetImageType(image,exception); (void) SignatureImage(image,exception); (void) FormatLocaleFile(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) FormatLocaleFile(file," Base filename: %s\n",filename); } magick_info=GetMagickInfo(image->magick,exception); if ((magick_info == (const MagickInfo *) NULL) || (*GetMagickDescription(magick_info) == '\0')) (void) FormatLocaleFile(file," Format: %s\n",image->magick); else (void) FormatLocaleFile(file," Format: %s (%s)\n",image->magick, GetMagickDescription(magick_info)); (void) FormatLocaleFile(file," Class: %s\n",CommandOptionToMnemonic( MagickClassOptions,(ssize_t) image->storage_class)); (void) FormatLocaleFile(file," Geometry: %.20gx%.20g%+.20g%+.20g\n",(double) image->columns,(double) image->rows,(double) image->tile_offset.x,(double) 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) FormatLocaleFile(file," Base geometry: %.20gx%.20g\n",(double) image->magick_columns,(double) image->magick_rows); if ((image->resolution.x != 0.0) && (image->resolution.y != 0.0)) { (void) FormatLocaleFile(file," Resolution: %gx%g\n",image->resolution.x, image->resolution.y); (void) FormatLocaleFile(file," Print size: %gx%g\n",(double) image->columns/image->resolution.x,(double) image->rows/ image->resolution.y); } (void) FormatLocaleFile(file," Units: %s\n",CommandOptionToMnemonic( MagickResolutionOptions,(ssize_t) image->units)); (void) FormatLocaleFile(file," Type: %s\n",CommandOptionToMnemonic( MagickTypeOptions,(ssize_t) type)); if (image->type != UndefinedType) (void) FormatLocaleFile(file," Base type: %s\n",CommandOptionToMnemonic( MagickTypeOptions,(ssize_t) image->type)); (void) FormatLocaleFile(file," Endianess: %s\n",CommandOptionToMnemonic( MagickEndianOptions,(ssize_t) image->endian)); /* Detail channel depth and extrema. */ (void) FormatLocaleFile(file," Colorspace: %s\n",CommandOptionToMnemonic( MagickColorspaceOptions,(ssize_t) image->colorspace)); channel_statistics=(ChannelStatistics *) NULL; channel_features=(ChannelFeatures *) NULL; colorspace=image->colorspace; scale=1; if (ping == MagickFalse) { size_t depth; channel_statistics=GetImageStatistics(image,exception); artifact=GetImageArtifact(image,"identify:features"); if (artifact != (const char *) NULL) { distance=StringToUnsignedLong(artifact); channel_features=GetImageFeatures(image,distance,exception); } depth=GetImageDepth(image,exception); if (image->depth == depth) (void) FormatLocaleFile(file," Depth: %.20g-bit\n",(double) image->depth); else (void) FormatLocaleFile(file," Depth: %.20g/%.20g-bit\n",(double) image->depth,(double) depth); (void) FormatLocaleFile(file," Channel depth:\n"); if (IsImageGray(image,exception) != MagickFalse) colorspace=GRAYColorspace; switch (colorspace) { case RGBColorspace: default: { (void) FormatLocaleFile(file," red: %.20g-bit\n",(double) channel_statistics[RedPixelChannel].depth); (void) FormatLocaleFile(file," green: %.20g-bit\n",(double) channel_statistics[GreenPixelChannel].depth); (void) FormatLocaleFile(file," blue: %.20g-bit\n",(double) channel_statistics[BluePixelChannel].depth); break; } case CMYKColorspace: { (void) FormatLocaleFile(file," cyan: %.20g-bit\n",(double) channel_statistics[CyanPixelChannel].depth); (void) FormatLocaleFile(file," magenta: %.20g-bit\n",(double) channel_statistics[MagentaPixelChannel].depth); (void) FormatLocaleFile(file," yellow: %.20g-bit\n",(double) channel_statistics[YellowPixelChannel].depth); (void) FormatLocaleFile(file," black: %.20g-bit\n",(double) channel_statistics[BlackPixelChannel].depth); break; } case GRAYColorspace: { (void) FormatLocaleFile(file," gray: %.20g-bit\n",(double) channel_statistics[GrayPixelChannel].depth); break; } } if (image->matte != MagickFalse) (void) FormatLocaleFile(file," alpha: %.20g-bit\n",(double) channel_statistics[AlphaPixelChannel].depth); scale=1; if (image->depth <= MAGICKCORE_QUANTUM_DEPTH) scale=QuantumRange/((size_t) QuantumRange >> ((size_t) MAGICKCORE_QUANTUM_DEPTH-image->depth)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e P I C O N I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WritePICONImage() writes an image to a file in the Personal Icon format. % % The format of the WritePICONImage method is: % % MagickBooleanType WritePICONImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WritePICONImage(const ImageInfo *image_info, Image *image) { #define ColormapExtent 155 #define GraymapExtent 95 #define PiconGeometry "48x48>" static unsigned char Colormap[]= { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x06, 0x00, 0x05, 0x00, 0xf4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x4f, 0x4f, 0x70, 0x80, 0x90, 0x7e, 0x7e, 0x7e, 0xdc, 0xdc, 0xdc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0xff, 0x1e, 0x90, 0xff, 0x87, 0xce, 0xeb, 0xe6, 0xe6, 0xfa, 0x00, 0xff, 0xff, 0x80, 0x00, 0x80, 0xb2, 0x22, 0x22, 0x2e, 0x8b, 0x57, 0x32, 0xcd, 0x32, 0x00, 0xff, 0x00, 0x98, 0xfb, 0x98, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x63, 0x47, 0xff, 0xa5, 0x00, 0xff, 0xd7, 0x00, 0xff, 0xff, 0x00, 0xee, 0x82, 0xee, 0xa0, 0x52, 0x2d, 0xcd, 0x85, 0x3f, 0xd2, 0xb4, 0x8c, 0xf5, 0xde, 0xb3, 0xff, 0xfa, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x05, 0x18, 0x20, 0x10, 0x08, 0x03, 0x51, 0x18, 0x07, 0x92, 0x28, 0x0b, 0xd3, 0x38, 0x0f, 0x14, 0x49, 0x13, 0x55, 0x59, 0x17, 0x96, 0x69, 0x1b, 0xd7, 0x85, 0x00, 0x3b, }, Graymap[]= { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x04, 0x00, 0x04, 0x00, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x21, 0x21, 0x21, 0x33, 0x33, 0x33, 0x45, 0x45, 0x45, 0x54, 0x54, 0x54, 0x66, 0x66, 0x66, 0x78, 0x78, 0x78, 0x87, 0x87, 0x87, 0x99, 0x99, 0x99, 0xab, 0xab, 0xab, 0xba, 0xba, 0xba, 0xcc, 0xcc, 0xcc, 0xde, 0xde, 0xde, 0xed, 0xed, 0xed, 0xff, 0xff, 0xff, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x0c, 0x10, 0x04, 0x31, 0x48, 0x31, 0x07, 0x25, 0xb5, 0x58, 0x73, 0x4f, 0x04, 0x00, 0x3b, }; #define MaxCixels 92 static const char Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk" "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; char buffer[MaxTextExtent], basename[MaxTextExtent], name[MaxTextExtent], symbol[MaxTextExtent]; ExceptionInfo *exception; Image *affinity_image, *picon; ImageInfo *blob_info; MagickBooleanType status, transparent; MagickPixelPacket pixel; QuantizeInfo *quantize_info; RectangleInfo geometry; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t i, x; register PixelPacket *q; size_t characters_per_pixel, colors; ssize_t j, k, y; /* Open output image file. */ 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->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); (void) TransformImageColorspace(image,sRGBColorspace); SetGeometry(image,&geometry); (void) ParseMetaGeometry(PiconGeometry,&geometry.x,&geometry.y, &geometry.width,&geometry.height); picon=ResizeImage(image,geometry.width,geometry.height,TriangleFilter,1.0, &image->exception); blob_info=CloneImageInfo(image_info); (void) AcquireUniqueFilename(blob_info->filename); if ((image_info->type != TrueColorType) && (SetImageGray(image,&image->exception) != MagickFalse)) affinity_image=BlobToImage(blob_info,Graymap,GraymapExtent, &image->exception); else affinity_image=BlobToImage(blob_info,Colormap,ColormapExtent, &image->exception); (void) RelinquishUniqueFileResource(blob_info->filename); blob_info=DestroyImageInfo(blob_info); if ((picon == (Image *) NULL) || (affinity_image == (Image *) NULL)) return(MagickFalse); quantize_info=AcquireQuantizeInfo(image_info); status=RemapImage(quantize_info,picon,affinity_image); quantize_info=DestroyQuantizeInfo(quantize_info); affinity_image=DestroyImage(affinity_image); transparent=MagickFalse; exception=(&image->exception); if (picon->storage_class == PseudoClass) { (void) CompressImageColormap(picon); if (picon->matte != MagickFalse) transparent=MagickTrue; } else { /* Convert DirectClass to PseudoClass picon. */ if (picon->matte != MagickFalse) { /* Map all the transparent pixels. */ for (y=0; y < (ssize_t) picon->rows; y++) { q=GetAuthenticPixels(picon,0,y,picon->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) picon->columns; x++) { if (q->opacity == (Quantum) TransparentOpacity) transparent=MagickTrue; else SetPixelOpacity(q,OpaqueOpacity); q++; } if (SyncAuthenticPixels(picon,exception) == MagickFalse) break; } } (void) SetImageType(picon,PaletteType); } colors=picon->colors; if (transparent != MagickFalse) { register IndexPacket *indexes; colors++; picon->colormap=(PixelPacket *) ResizeQuantumMemory((void **) picon->colormap,(size_t) colors,sizeof(*picon->colormap)); if (picon->colormap == (PixelPacket *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationError"); for (y=0; y < (ssize_t) picon->rows; y++) { q=GetAuthenticPixels(picon,0,y,picon->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(picon); for (x=0; x < (ssize_t) picon->columns; x++) { if (q->opacity == (Quantum) TransparentOpacity) SetPixelIndex(indexes+x,picon->colors); q++; } if (SyncAuthenticPixels(picon,exception) == MagickFalse) break; } } /* Compute the character per pixel. */ characters_per_pixel=1; for (k=MaxCixels; (ssize_t) colors > k; k*=MaxCixels) characters_per_pixel++; /* XPM header. */ (void) WriteBlobString(image,"/* XPM */\n"); GetPathComponent(picon->filename,BasePath,basename); (void) FormatLocaleString(buffer,MaxTextExtent, "static char *%s[] = {\n",basename); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n"); (void) FormatLocaleString(buffer,MaxTextExtent, "\"%.20g %.20g %.20g %.20g\",\n",(double) picon->columns,(double) picon->rows,(double) colors,(double) characters_per_pixel); (void) WriteBlobString(image,buffer); GetMagickPixelPacket(image,&pixel); for (i=0; i < (ssize_t) colors; i++) { /* Define XPM color. */ SetMagickPixelPacket(image,picon->colormap+i,(IndexPacket *) NULL,&pixel); pixel.colorspace=sRGBColorspace; pixel.depth=8; pixel.opacity=(MagickRealType) OpaqueOpacity; (void) QueryMagickColorname(image,&pixel,XPMCompliance,name, &image->exception); if (transparent != MagickFalse) { if (i == (ssize_t) (colors-1)) (void) CopyMagickString(name,"grey75",MaxTextExtent); } /* Write XPM color. */ k=i % MaxCixels; symbol[0]=Cixel[k]; for (j=1; j < (ssize_t) characters_per_pixel; j++) { k=((i-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) FormatLocaleString(buffer,MaxTextExtent,"\"%s c %s\",\n", symbol,name); (void) WriteBlobString(image,buffer); } /* Define XPM pixels. */ (void) WriteBlobString(image,"/* pixels */\n"); for (y=0; y < (ssize_t) picon->rows; y++) { p=GetVirtualPixels(picon,0,y,picon->columns,1,&picon->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(picon); (void) WriteBlobString(image,"\""); for (x=0; x < (ssize_t) picon->columns; x++) { k=((ssize_t) GetPixelIndex(indexes+x) % MaxCixels); symbol[0]=Cixel[k]; for (j=1; j < (ssize_t) characters_per_pixel; j++) { k=(((int) GetPixelIndex(indexes+x)-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) CopyMagickString(buffer,symbol,MaxTextExtent); (void) WriteBlobString(image,buffer); } (void) FormatLocaleString(buffer,MaxTextExtent,"\"%s\n", y == (ssize_t) (picon->rows-1) ? "" : ","); (void) WriteBlobString(image,buffer); status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, picon->rows); if (status == MagickFalse) break; } picon=DestroyImage(picon); (void) WriteBlobString(image,"};\n"); (void) CloseBlob(image); return(MagickTrue); }
static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception) { #define MaxBufferExtent 8192 char filename[MagickPathExtent]; FILE *file; Image *image; ImageInfo *read_info; int unique_file; read_info=CloneImageInfo(image_info); SetImageInfoBlob(read_info,(void *) NULL,0); if (LocaleCompare(read_info->magick,"file") == 0) { (void) CopyMagickString(read_info->filename,image_info->filename+2, MagickPathExtent); *read_info->magick='\0'; image=ReadImage(read_info,exception); read_info=DestroyImageInfo(read_info); return(GetFirstImageInList(image)); } file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(read_info->filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file == -1) || (file == (FILE *) NULL)) { ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile", read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } (void) CopyMagickString(filename,image_info->magick,MagickPathExtent); (void) ConcatenateMagickString(filename,":",MagickPathExtent); LocaleLower(filename); (void) ConcatenateMagickString(filename,image_info->filename, MagickPathExtent); #if defined(MAGICKCORE_WINDOWS_SUPPORT) && \ !(defined(__MINGW32__) || defined(__MINGW64__)) (void) fclose(file); if (URLDownloadToFile(NULL,filename,read_info->filename,0,NULL) != S_OK) { ThrowFileException(exception,FileOpenError,"UnableToOpenFile", filename); (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } #else #if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED) if (LocaleCompare(read_info->magick,"ftp") == 0) { void *context; xmlNanoFTPInit(); context=xmlNanoFTPNewCtxt(filename); if (context != (void *) NULL) { if (xmlNanoFTPConnect(context) >= 0) (void) xmlNanoFTPGet(context,GetFTPData,(void *) file, (char *) NULL); (void) xmlNanoFTPClose(context); } } #endif #if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED) if (LocaleCompare(read_info->magick,"http") == 0) { char buffer[MaxBufferExtent], *type; int bytes; void *context; type=(char *) NULL; context=xmlNanoHTTPMethod(filename,(const char *) NULL, (const char *) NULL,&type,(const char *) NULL,0); if (context != (void *) NULL) { ssize_t count; while ((bytes=xmlNanoHTTPRead(context,buffer,MaxBufferExtent)) > 0) count=(ssize_t) fwrite(buffer,bytes,1,file); (void) count; xmlNanoHTTPClose(context); xmlFree(type); xmlNanoHTTPCleanup(); } } #endif (void) fclose(file); #endif *read_info->magick='\0'; image=ReadImage(read_info,exception); (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); if (image != (Image *) NULL) GetPathComponent(image_info->filename,TailPath,image->filename); else { (void) ThrowMagickException(exception,GetMagickModule(),CoderError, "NoDataReturned","`%s'",filename); return((Image *) NULL); } return(GetFirstImageInList(image)); }
static MagickBooleanType LoadCoderList(const char *xml,const char *filename, const unsigned long depth,ExceptionInfo *exception) { char keyword[MaxTextExtent], *q, *token; CoderInfo *coder_info = (CoderInfo *) NULL; MagickBooleanType status; /* Load the coder map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading coder file \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (coder_list == (SplayTreeInfo *) NULL) { coder_list=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, DestroyCoderNode); if (coder_list == (SplayTreeInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } status=MagickTrue; token=AcquireString(xml); for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token); else { char path[MaxTextExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(path,token,MaxTextExtent); xml=FileToString(path,~0,exception); if (LoadCoderList(xml,path,depth+1,exception) == MagickFalse) status=MagickFalse; xml=(char *) RelinquishMagickMemory(xml); } } } continue; } if (LocaleCompare(keyword,"<coder") == 0) { /* Allocate memory for the coder list. */ coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); if (coder_info == (CoderInfo *) NULL) ThrowMagickFatalException(ResourceLimitFatalError, "MemoryAllocationFailed",filename); (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); coder_info->path=ConstantString(AcquireString(filename)); coder_info->signature=MagickSignature; continue; } if (coder_info == (CoderInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AddValueToSplayTree(coder_list, ConstantString(AcquireString(coder_info->magick)),coder_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", coder_info->magick); coder_info=(CoderInfo *) NULL; } GetMagickToken(q,(char **) NULL,token); if (*token != '=') continue; GetMagickToken(q,&q,token); GetMagickToken(q,&q,token); switch (*keyword) { case 'M': case 'm': { if (LocaleCompare((char *) keyword,"magick") == 0) { coder_info->magick=ConstantString(AcquireString(token)); break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { coder_info->name=ConstantString(AcquireString(token)); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { coder_info->stealth=(MagickBooleanType) (LocaleCompare(token,"True") == 0); break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); if (coder_list == (SplayTreeInfo *) NULL) return(MagickFalse); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d C o n f i g u r e L i s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadConfigureCache() loads the configure configurations which provides a % mapping between configure attributes and a configure name. % % The format of the LoadConfigureCache method is: % % WizardBooleanType LoadConfigureCache(LinkedListInfo *configure_cache, % const char *xml,const char *filename,const size_t depth, % ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The configure list in XML format. % % o filename: The configure list filename. % % o depth: depth of <include /> statements. % % o exception: Return any errors or warnings in this structure. % */ static WizardBooleanType LoadConfigureCache(LinkedListInfo *configure_cache, const char *xml,const char *filename,const size_t depth, ExceptionInfo *exception) { const char *attribute; ConfigureInfo *configure_info = (ConfigureInfo *) NULL; WizardStatusType status; XMLTreeInfo *configure, *configure_map, *include; /* Load the configure map file. */ (void) LogWizardEvent(ConfigureEvent,GetWizardModule(), "Loading configure map \"%s\" ...",filename); if (xml == (const char *) NULL) return(WizardFalse); configure_map=NewXMLTree(xml,exception); if (configure_map == (XMLTreeInfo *) NULL) return(WizardFalse); status=WizardFalse; include=GetXMLTreeChild(configure_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowWizardException(exception,GetWizardModule(), ConfigureError,"include element nested too deeply `%s'",filename); else { char path[WizardPathExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateWizardString(path,DirectorySeparator, WizardPathExtent); (void) ConcatenateWizardString(path,attribute,WizardPathExtent); xml=FileToXML(path,~0UL); status&=LoadConfigureCache(configure_cache,xml,path,depth+1, exception); xml=(char *) RelinquishWizardMemory(xml); } } include=GetNextXMLTreeTag(include); } configure=GetXMLTreeChild(configure_map,"configure"); while (configure != (XMLTreeInfo *) NULL) { const char *attribute; /* Process configure element. */ configure_info=(ConfigureInfo *) AcquireWizardMemory( sizeof(*configure_info)); if (configure_info == (ConfigureInfo *) NULL) ThrowFatalException(ResourceFatalError,"memory allocation failed `%s`"); (void) ResetWizardMemory(configure_info,0,sizeof(*configure_info)); configure_info->path=ConstantString(filename); configure_info->exempt=WizardFalse; configure_info->signature=WizardSignature; attribute=GetXMLTreeAttribute(configure,"name"); if (attribute != (const char *) NULL) configure_info->name=ConstantString(attribute); attribute=GetXMLTreeAttribute(configure,"stealth"); if (attribute != (const char *) NULL) configure_info->stealth=IsWizardTrue(attribute); attribute=GetXMLTreeAttribute(configure,"value"); if (attribute != (const char *) NULL) configure_info->value=ConstantString(attribute); status=AppendValueToLinkedList(configure_cache,configure_info); if (status == WizardFalse) (void) ThrowWizardException(exception,GetWizardModule(), ResourceFatalError,"memory allocation failed `%s`",strerror(errno)); configure=GetNextXMLTreeTag(configure); } configure_map=DestroyXMLTree(configure_map); return(status != 0 ? WizardTrue : WizardFalse); }