/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + C L I L o g E v e n t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CLILogEvent() is a wrapper around LogMagickEvent(), adding to it the % location of the option that is (about) to be executed. % */ WandExport MagickBooleanType CLILogEvent(MagickCLI *cli_wand, const LogEventType type,const char *module,const char *function, const size_t line,const char *format,...) { char new_format[MaxTextExtent]; MagickBooleanType status; va_list operands; /* HACK - prepend the CLI location to format string. The better way would be add more arguments to to the 'va' oparands list, but that does not appear to be possible! So we do some pre-formating of the location info here. */ (void) FormatLocaleString(new_format,MaxTextExtent,cli_wand->location, cli_wand->filename, cli_wand->line, cli_wand->column); (void) ConcatenateMagickString(new_format," ",MaxTextExtent); (void) ConcatenateMagickString(new_format,format,MaxTextExtent); va_start(operands,format); status=LogMagickEventList(type,module,function,line,new_format,operands); va_end(operands); return(status == MagickFalse ? 0 : 1); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t W a n d V i e w E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetWandViewException() returns the severity, reason, and description of any % error that occurs when utilizing a wand view. % % The format of the GetWandViewException method is: % % char *GetWandViewException(const WandView *wand_view, % ExceptionType *severity) % % A description of each parameter follows: % % o wand_view: the pixel wand_view. % % o severity: the severity of the error is returned here. % */ WandExport char *GetWandViewException(const WandView *wand_view, ExceptionType *severity) { char *description; assert(wand_view != (const WandView *) NULL); assert(wand_view->signature == WandSignature); if (wand_view->debug != MagickFalse) (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand_view->name); assert(severity != (ExceptionType *) NULL); *severity=wand_view->exception->severity; description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent, sizeof(*description)); if (description == (char *) NULL) ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", wand_view->name); *description='\0'; if (wand_view->exception->reason != (char *) NULL) (void) CopyMagickString(description,GetLocaleExceptionMessage( wand_view->exception->severity,wand_view->exception->reason), MaxTextExtent); if (wand_view->exception->description != (char *) NULL) { (void) ConcatenateMagickString(description," (",MaxTextExtent); (void) ConcatenateMagickString(description,GetLocaleExceptionMessage( wand_view->exception->severity,wand_view->exception->description), MaxTextExtent); (void) ConcatenateMagickString(description,")",MaxTextExtent); } return(description); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M a g i c k G e t E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MagickGetException() returns the severity, reason, and description of any % error that occurs when using other methods in this API. % % The format of the MagickGetException method is: % % char *MagickGetException(const MagickWand *wand,ExceptionType *severity) % % A description of each parameter follows: % % o wand: the magick wand. % % o severity: the severity of the error is returned here. % */ WandExport char *MagickGetException(const MagickWand *wand, ExceptionType *severity) { char *description; assert(wand != (const MagickWand *) NULL); assert(wand->signature == WandSignature); if (wand->debug != MagickFalse) (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); assert(severity != (ExceptionType *) NULL); *severity=wand->exception->severity; description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent, sizeof(*description)); if (description == (char *) NULL) { (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError, "MemoryAllocationFailed","`%s'",wand->name); return((char *) NULL); } *description='\0'; if (wand->exception->reason != (char *) NULL) (void) CopyMagickString(description,GetLocaleExceptionMessage( wand->exception->severity,wand->exception->reason),MaxTextExtent); if (wand->exception->description != (char *) NULL) { (void) ConcatenateMagickString(description," (",MaxTextExtent); (void) ConcatenateMagickString(description,GetLocaleExceptionMessage( wand->exception->severity,wand->exception->description),MaxTextExtent); (void) ConcatenateMagickString(description,")",MaxTextExtent); } return(description); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t I m a g e V i e w E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetImageViewException() returns the severity, reason, and description of any % error that occurs when utilizing a image view. % % The format of the GetImageViewException method is: % % char *GetImageViewException(const PixelImage *image_view, % ExceptionType *severity) % % A description of each parameter follows: % % o image_view: the pixel image_view. % % o severity: the severity of the error is returned here. % */ MagickExport char *GetImageViewException(const ImageView *image_view, ExceptionType *severity) { char *description; assert(image_view != (const ImageView *) NULL); assert(image_view->signature == MagickSignature); assert(severity != (ExceptionType *) NULL); *severity=image_view->exception->severity; description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent, sizeof(*description)); if (description == (char *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); *description='\0'; if (image_view->exception->reason != (char *) NULL) (void) CopyMagickString(description,GetLocaleExceptionMessage( image_view->exception->severity,image_view->exception->reason), MaxTextExtent); if (image_view->exception->description != (char *) NULL) { (void) ConcatenateMagickString(description," (",MaxTextExtent); (void) ConcatenateMagickString(description,GetLocaleExceptionMessage( image_view->exception->severity,image_view->exception->description), MaxTextExtent); (void) ConcatenateMagickString(description,")",MaxTextExtent); } return(description); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P i x e l G e t I t e r a t o r E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PixelGetIteratorException() returns the severity, reason, and description of % any error that occurs when using other methods in this API. % % The format of the PixelGetIteratorException method is: % % char *PixelGetIteratorException(const PixelIterator *iterator, % ExceptionType *severity) % % A description of each parameter follows: % % o iterator: the pixel iterator. % % o severity: the severity of the error is returned here. % */ WandExport char *PixelGetIteratorException(const PixelIterator *iterator, ExceptionType *severity) { char *description; assert(iterator != (const PixelIterator *) NULL); assert(iterator->signature == MagickWandSignature); if (iterator->debug != MagickFalse) (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name); assert(severity != (ExceptionType *) NULL); *severity=iterator->exception->severity; description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent, sizeof(*description)); if (description == (char *) NULL) ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", iterator->name); *description='\0'; if (iterator->exception->reason != (char *) NULL) (void) CopyMagickString(description,GetLocaleExceptionMessage( iterator->exception->severity,iterator->exception->reason),MagickPathExtent); if (iterator->exception->description != (char *) NULL) { (void) ConcatenateMagickString(description," (",MagickPathExtent); (void) ConcatenateMagickString(description,GetLocaleExceptionMessage( iterator->exception->severity,iterator->exception->description), MagickPathExtent); (void) ConcatenateMagickString(description,")",MagickPathExtent); } return(description); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + C L I T h r o w E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CLIThrowException() is a wrapper around ThrowMagickException(), adding to % it the location of the option that caused the exception to occur. */ WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand, const char *module,const char *function,const size_t line, const ExceptionType severity,const char *tag,const char *format,...) { char new_format[MaxTextExtent]; size_t len; MagickBooleanType status; va_list operands; /* HACK - append location to format string. The better way would be add more arguments to to the 'va' oparands list, but that does not appear to be possible! So we do some pre-formating of the location info here. */ (void) CopyMagickString(new_format,format,MaxTextExtent); (void) ConcatenateMagickString(new_format," ",MaxTextExtent); len=strlen(new_format); (void) FormatLocaleString(new_format+len,MaxTextExtent-len,cli_wand->location, cli_wand->filename, cli_wand->line, cli_wand->column); va_start(operands,format); status=ThrowMagickExceptionList(cli_wand->wand.exception, module,function,line, severity,tag,new_format,operands); va_end(operands); return(status == MagickFalse ? 0 : 1); }
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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + C L I T h r o w E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CLIThrowException() formats and records an exception condition, adding to % it the location of the option that caused the exception to occur. */ WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand, const char *module,const char *function,const size_t line, const ExceptionType severity,const char *tag,const char *format,...) { char new_format[MaxTextExtent]; size_t len; MagickBooleanType status; va_list operands; /* HACK - append location to format string. The better way would be append location formats and add more arguments to operands, but that does not appear to be posible! Note: ThrowMagickExceptionList() was exported specifically for the use of this function. */ (void) CopyMagickString(new_format,format,MaxTextExtent); (void) ConcatenateMagickString(new_format," ",MaxTextExtent); len=strlen(new_format); (void) FormatLocaleString(new_format+len,MaxTextExtent-len,cli_wand->location, cli_wand->filename, cli_wand->line, cli_wand->column); va_start(operands,format); status=ThrowMagickExceptionList(cli_wand->wand.exception, module,function,line, severity,tag,new_format,operands); va_end(operands); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d G R A D I E N T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadGRADIENTImage creates a gradient image and initializes it to % the color range as specified by the filename. It allocates the memory % necessary for the new Image structure and returns a pointer to the new % image. % % The format of the ReadGRADIENTImage method is: % % Image *ReadGRADIENTImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadGRADIENTImage(const ImageInfo *image_info, ExceptionInfo *exception) { char colorname[MaxTextExtent]; MagickBooleanType icc_color, status; MagickPixelPacket start_pixel, stop_pixel; PixelPacket start_color, stop_color; Image *image; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); (void) SetImageOpacity(image,(Quantum) TransparentOpacity); (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent); (void) CopyMagickString(colorname,image_info->filename,MaxTextExtent); (void) sscanf(image_info->filename,"%[^-]",colorname); icc_color=MagickFalse; if (LocaleCompare(colorname,"icc") == 0) { (void) ConcatenateMagickString(colorname,"-",MaxTextExtent); (void) sscanf(image_info->filename,"%*[^-]-%[^-]",colorname+4); icc_color=MagickTrue; } if (QueryColorDatabase(colorname,&start_color,exception) == MagickFalse) { image=DestroyImage(image); return((Image *) NULL); } (void) QueryMagickColor(colorname,&start_pixel,exception); (void) CopyMagickString(colorname,"white",MaxTextExtent); if (GetPixelLuma(image,&start_color) > (QuantumRange/2)) (void) CopyMagickString(colorname,"black",MaxTextExtent); if (icc_color == MagickFalse) (void) sscanf(image_info->filename,"%*[^-]-%s",colorname); else (void) sscanf(image_info->filename,"%*[^-]-%*[^-]-%s",colorname); if (QueryColorDatabase(colorname,&stop_color,exception) == MagickFalse) { image=DestroyImage(image); return((Image *) NULL); } (void) QueryMagickColor(colorname,&stop_pixel,exception); (void) SetImageColorspace(image,start_pixel.colorspace); status=GradientImage(image,LocaleCompare(image_info->magick,"GRADIENT") == 0 ? LinearGradient : RadialGradient,PadSpread,&start_color,&stop_color); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if ((start_pixel.matte == MagickFalse) && (stop_pixel.matte == MagickFalse)) (void) SetImageAlphaChannel(image,DeactivateAlphaChannel); return(GetFirstImageInList(image)); }
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 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e T X T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteTXTImage writes the pixel values as text numbers. % % The format of the WriteTXTImage method is: % % MagickBooleanType WriteTXTImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteTXTImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent], colorspace[MaxTextExtent], tuple[MaxTextExtent]; MagickBooleanType status; MagickOffsetType scene; MagickPixelPacket pixel; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t x; ssize_t 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,WriteBlobMode,&image->exception); if (status == MagickFalse) return(status); scene=0; do { ComplianceType compliance; (void) CopyMagickString(colorspace,CommandOptionToMnemonic( MagickColorspaceOptions,(ssize_t) image->colorspace),MaxTextExtent); LocaleLower(colorspace); image->depth=GetImageQuantumDepth(image,MagickTrue); if (image->matte != MagickFalse) (void) ConcatenateMagickString(colorspace,"a",MaxTextExtent); compliance=NoCompliance; if (LocaleCompare(image_info->magick,"SPARSE-COLOR") != 0) { (void) FormatLocaleString(buffer,MaxTextExtent, "# ImageMagick pixel enumeration: %.20g,%.20g,%.20g,%s\n",(double) image->columns,(double) image->rows,(double) ((MagickOffsetType) GetQuantumRange(image->depth)),colorspace); (void) WriteBlobString(image,buffer); compliance=SVGCompliance; } GetMagickPixelPacket(image,&pixel); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { SetMagickPixelPacket(image,p,indexes+x,&pixel); if (pixel.colorspace == LabColorspace) { pixel.green-=(QuantumRange+1)/2.0; pixel.blue-=(QuantumRange+1)/2.0; } if (LocaleCompare(image_info->magick,"SPARSE-COLOR") == 0) { /* Sparse-color format. */ if (GetPixelOpacity(p) == (Quantum) OpaqueOpacity) { GetColorTuple(&pixel,MagickFalse,tuple); (void) QueryMagickColorname(image,&pixel,SVGCompliance,tuple, &image->exception); (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g,%.20g,", (double) x,(double) y); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,tuple); (void) WriteBlobString(image," "); } p++; continue; } (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g,%.20g: ",(double) x,(double) y); (void) WriteBlobString(image,buffer); (void) CopyMagickString(tuple,"(",MaxTextExtent); ConcatenateColorComponent(&pixel,RedChannel,compliance,tuple); (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&pixel,GreenChannel,compliance,tuple); (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&pixel,BlueChannel,compliance,tuple); if (pixel.colorspace == CMYKColorspace) { (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&pixel,IndexChannel,compliance,tuple); } if (pixel.matte != MagickFalse) { (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&pixel,AlphaChannel,compliance,tuple); } (void) ConcatenateMagickString(tuple,")",MaxTextExtent); (void) WriteBlobString(image,tuple); (void) WriteBlobString(image," "); GetColorTuple(&pixel,MagickTrue,tuple); (void) FormatLocaleString(buffer,MaxTextExtent,"%s",tuple); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image," "); (void) QueryMagickColorname(image,&pixel,SVGCompliance,tuple, &image->exception); (void) WriteBlobString(image,tuple); (void) WriteBlobString(image,"\n"); p++; } status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(MagickTrue); }
MagickExport Image *MontageImageList(const ImageInfo *image_info, const MontageInfo *montage_info,const Image *images,ExceptionInfo *exception) { #define MontageImageTag "Montage/Image" #define TileImageTag "Tile/Image" char tile_geometry[MagickPathExtent], *title; const char *value; DrawInfo *draw_info; FrameInfo frame_info; Image *image, **image_list, **master_list, *montage, *texture, *tile_image, *thumbnail; ImageInfo *clone_info; MagickBooleanType concatenate, proceed, status; MagickOffsetType tiles; MagickProgressMonitor progress_monitor; MagickStatusType flags; register ssize_t i; RectangleInfo bounds, geometry, extract_info; size_t border_width, extent, height, images_per_page, max_height, number_images, number_lines, sans, tiles_per_column, tiles_per_page, tiles_per_row, title_offset, total_tiles, width; ssize_t bevel_width, tile, x, x_offset, y, y_offset; TypeMetric metrics; /* Create image tiles. */ assert(images != (Image *) NULL); assert(images->signature == MagickCoreSignature); if (images->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); assert(montage_info != (MontageInfo *) NULL); assert(montage_info->signature == MagickCoreSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); number_images=GetImageListLength(images); master_list=ImageListToArray(images,exception); image_list=master_list; image=image_list[0]; if (master_list == (Image **) NULL) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); thumbnail=NewImageList(); for (i=0; i < (ssize_t) number_images; i++) { image=CloneImage(image_list[i],0,0,MagickTrue,exception); if (image == (Image *) NULL) break; (void) ParseAbsoluteGeometry("0x0+0+0",&image->page); progress_monitor=SetImageProgressMonitor(image,(MagickProgressMonitor) NULL, image->client_data); flags=ParseRegionGeometry(image,montage_info->geometry,&geometry,exception); thumbnail=ThumbnailImage(image,geometry.width,geometry.height,exception); if (thumbnail == (Image *) NULL) break; image_list[i]=thumbnail; (void) SetImageProgressMonitor(image,progress_monitor,image->client_data); proceed=SetImageProgress(image,TileImageTag,(MagickOffsetType) i, number_images); if (proceed == MagickFalse) break; image=DestroyImage(image); } if (i < (ssize_t) number_images) { if (thumbnail == (Image *) NULL) i--; for (tile=0; (ssize_t) tile <= i; tile++) if (image_list[tile] != (Image *) NULL) image_list[tile]=DestroyImage(image_list[tile]); master_list=(Image **) RelinquishMagickMemory(master_list); return((Image *) NULL); } /* Sort image list by increasing tile number. */ for (i=0; i < (ssize_t) number_images; i++) if (image_list[i]->scene == 0) break; if (i == (ssize_t) number_images) qsort((void *) image_list,(size_t) number_images,sizeof(*image_list), SceneCompare); /* Determine tiles per row and column. */ tiles_per_column=(size_t) sqrt((double) number_images); tiles_per_row=(size_t) ceil((double) number_images/tiles_per_column); x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &tiles_per_column,&tiles_per_row); /* Determine tile sizes. */ concatenate=MagickFalse; SetGeometry(image_list[0],&extract_info); extract_info.x=(ssize_t) montage_info->border_width; extract_info.y=(ssize_t) montage_info->border_width; if (montage_info->geometry != (char *) NULL) { /* Initialize tile geometry. */ flags=GetGeometry(montage_info->geometry,&extract_info.x,&extract_info.y, &extract_info.width,&extract_info.height); concatenate=((flags & RhoValue) == 0) && ((flags & SigmaValue) == 0) ? MagickTrue : MagickFalse; } border_width=montage_info->border_width; bevel_width=0; (void) ResetMagickMemory(&frame_info,0,sizeof(frame_info)); if (montage_info->frame != (char *) NULL) { char absolute_geometry[MagickPathExtent]; frame_info.width=extract_info.width; frame_info.height=extract_info.height; (void) FormatLocaleString(absolute_geometry,MagickPathExtent,"%s!", montage_info->frame); flags=ParseMetaGeometry(absolute_geometry,&frame_info.outer_bevel, &frame_info.inner_bevel,&frame_info.width,&frame_info.height); if ((flags & HeightValue) == 0) frame_info.height=frame_info.width; if ((flags & XiValue) == 0) frame_info.outer_bevel=(ssize_t) frame_info.width/2-1; if ((flags & PsiValue) == 0) frame_info.inner_bevel=frame_info.outer_bevel; frame_info.x=(ssize_t) frame_info.width; frame_info.y=(ssize_t) frame_info.height; bevel_width=(ssize_t) MagickMax(frame_info.inner_bevel, frame_info.outer_bevel); border_width=(size_t) MagickMax((ssize_t) frame_info.width, (ssize_t) frame_info.height); } for (i=0; i < (ssize_t) number_images; i++) { if (image_list[i]->columns > extract_info.width) extract_info.width=image_list[i]->columns; if (image_list[i]->rows > extract_info.height) extract_info.height=image_list[i]->rows; } /* Initialize draw attributes. */ clone_info=CloneImageInfo(image_info); clone_info->background_color=montage_info->background_color; clone_info->border_color=montage_info->border_color; draw_info=CloneDrawInfo(clone_info,(DrawInfo *) NULL); if (montage_info->font != (char *) NULL) (void) CloneString(&draw_info->font,montage_info->font); if (montage_info->pointsize != 0.0) draw_info->pointsize=montage_info->pointsize; draw_info->gravity=CenterGravity; draw_info->stroke=montage_info->stroke; draw_info->fill=montage_info->fill; draw_info->text=AcquireString(""); (void) GetTypeMetrics(image_list[0],draw_info,&metrics,exception); texture=NewImageList(); if (montage_info->texture != (char *) NULL) { (void) CopyMagickString(clone_info->filename,montage_info->texture, MagickPathExtent); texture=ReadImage(clone_info,exception); } /* Determine the number of lines in an next label. */ title=InterpretImageProperties(clone_info,image_list[0],montage_info->title, exception); title_offset=0; if (montage_info->title != (char *) NULL) title_offset=(size_t) (2*(metrics.ascent-metrics.descent)* MultilineCensus(title)+2*extract_info.y); number_lines=0; for (i=0; i < (ssize_t) number_images; i++) { value=GetImageProperty(image_list[i],"label",exception); if (value == (const char *) NULL) continue; if (MultilineCensus(value) > number_lines) number_lines=MultilineCensus(value); } /* Allocate next structure. */ tile_image=AcquireImage((ImageInfo *) NULL,exception); montage=AcquireImage(clone_info,exception); montage->background_color=montage_info->background_color; montage->scene=0; images_per_page=(number_images-1)/(tiles_per_row*tiles_per_column)+1; tiles=0; total_tiles=(size_t) number_images; for (i=0; i < (ssize_t) images_per_page; i++) { /* Determine bounding box. */ tiles_per_page=tiles_per_row*tiles_per_column; x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); tiles_per_page=tiles_per_row*tiles_per_column; y_offset+=(ssize_t) title_offset; max_height=0; bounds.width=0; bounds.height=0; width=0; for (tile=0; tile < (ssize_t) tiles_per_page; tile++) { if (tile < (ssize_t) number_images) { width=concatenate != MagickFalse ? image_list[tile]->columns : extract_info.width; if (image_list[tile]->rows > max_height) max_height=image_list[tile]->rows; } x_offset+=(ssize_t) (width+2*(extract_info.x+border_width)); if (x_offset > (ssize_t) bounds.width) bounds.width=(size_t) x_offset; if (((tile+1) == (ssize_t) tiles_per_page) || (((tile+1) % tiles_per_row) == 0)) { x_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y, &sans,&sans); height=concatenate != MagickFalse ? max_height : extract_info.height; y_offset+=(ssize_t) (height+(extract_info.y+(ssize_t) border_width)*2+ (metrics.ascent-metrics.descent+4)*number_lines+ (montage_info->shadow != MagickFalse ? 4 : 0)); if (y_offset > (ssize_t) bounds.height) bounds.height=(size_t) y_offset; max_height=0; } } if (montage_info->shadow != MagickFalse) bounds.width+=4; /* Initialize montage image. */ (void) CopyMagickString(montage->filename,montage_info->filename, MagickPathExtent); montage->columns=(size_t) MagickMax((ssize_t) bounds.width,1); montage->rows=(size_t) MagickMax((ssize_t) bounds.height,1); (void) SetImageBackgroundColor(montage,exception); /* Set montage geometry. */ montage->montage=AcquireString((char *) NULL); tile=0; extent=1; while (tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images)) { extent+=strlen(image_list[tile]->filename)+1; tile++; } montage->directory=(char *) AcquireQuantumMemory(extent, sizeof(*montage->directory)); if ((montage->montage == (char *) NULL) || (montage->directory == (char *) NULL)) { if (montage->montage != (char *) NULL) montage->montage=(char *) RelinquishMagickMemory(montage->montage); if (montage->directory != (char *) NULL) montage->directory=(char *) RelinquishMagickMemory( montage->directory); ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); } x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); y_offset+=(ssize_t) title_offset; (void) FormatLocaleString(montage->montage,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) (extract_info.width+ (extract_info.x+border_width)*2),(double) (extract_info.height+ (extract_info.y+border_width)*2+(double) ((metrics.ascent- metrics.descent+4)*number_lines+(montage_info->shadow != MagickFalse ? 4 : 0))),(double) x_offset,(double) y_offset); *montage->directory='\0'; tile=0; while (tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images)) { (void) ConcatenateMagickString(montage->directory, image_list[tile]->filename,extent); (void) ConcatenateMagickString(montage->directory,"\n",extent); tile++; } progress_monitor=SetImageProgressMonitor(montage,(MagickProgressMonitor) NULL,montage->client_data); if (texture != (Image *) NULL) (void) TextureImage(montage,texture,exception); if (montage_info->title != (char *) NULL) { DrawInfo *draw_clone_info; TypeMetric tile_metrics; /* Annotate composite image with title. */ draw_clone_info=CloneDrawInfo(image_info,draw_info); draw_clone_info->gravity=CenterGravity; draw_clone_info->pointsize*=2.0; (void) GetTypeMetrics(image_list[0],draw_clone_info,&tile_metrics, exception); (void) FormatLocaleString(tile_geometry,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) montage->columns,(double) (tile_metrics.ascent-tile_metrics.descent),0.0, (double) extract_info.y+4); (void) CloneString(&draw_clone_info->geometry,tile_geometry); (void) CloneString(&draw_clone_info->text,title); (void) AnnotateImage(montage,draw_clone_info,exception); draw_clone_info=DestroyDrawInfo(draw_clone_info); } (void) SetImageProgressMonitor(montage,progress_monitor, montage->client_data); /* Copy tile to the composite. */ x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); x_offset+=extract_info.x; y_offset+=(ssize_t) title_offset+extract_info.y; max_height=0; status=MagickTrue; for (tile=0; tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images); tile++) { /* Copy this tile to the composite. */ image=CloneImage(image_list[tile],0,0,MagickTrue,exception); if (image == (Image *) NULL) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); progress_monitor=SetImageProgressMonitor(image, (MagickProgressMonitor) NULL,image->client_data); width=concatenate != MagickFalse ? image->columns : extract_info.width; if (image->rows > max_height) max_height=image->rows; height=concatenate != MagickFalse ? max_height : extract_info.height; if (border_width != 0) { Image *border_image; RectangleInfo border_info; /* Put a border around the image. */ border_info.width=border_width; border_info.height=border_width; if (montage_info->frame != (char *) NULL) { border_info.width=(width-image->columns+1)/2; border_info.height=(height-image->rows+1)/2; } border_image=BorderImage(image,&border_info,image->compose,exception); if (border_image != (Image *) NULL) { image=DestroyImage(image); image=border_image; } if ((montage_info->frame != (char *) NULL) && (image->compose == DstOutCompositeOp)) { (void) SetPixelChannelMask(image,AlphaChannel); (void) NegateImage(image,MagickFalse,exception); (void) SetPixelChannelMask(image,DefaultChannels); } } /* Gravitate as specified by the tile gravity. */ tile_image->columns=width; tile_image->rows=height; tile_image->gravity=montage_info->gravity; if (image->gravity != UndefinedGravity) tile_image->gravity=image->gravity; (void) FormatLocaleString(tile_geometry,MagickPathExtent, "%.20gx%.20g+0+0",(double) image->columns,(double) image->rows); flags=ParseGravityGeometry(tile_image,tile_geometry,&geometry,exception); x=(ssize_t) (geometry.x+border_width); y=(ssize_t) (geometry.y+border_width); if ((montage_info->frame != (char *) NULL) && (bevel_width > 0)) { FrameInfo frame_clone; Image *frame_image; /* Put an ornamental border around this tile. */ frame_clone=frame_info; frame_clone.width=width+2*frame_info.width; frame_clone.height=height+2*frame_info.height; value=GetImageProperty(image,"label",exception); if (value != (const char *) NULL) frame_clone.height+=(size_t) ((metrics.ascent-metrics.descent+4)* MultilineCensus(value)); frame_image=FrameImage(image,&frame_clone,image->compose,exception); if (frame_image != (Image *) NULL) { image=DestroyImage(image); image=frame_image; } x=0; y=0; } if (LocaleCompare(image->magick,"NULL") != 0) { /* Composite background with tile. */ if (montage_info->shadow != MagickFalse) { Image *shadow_image; /* Shadow image. */ (void) QueryColorCompliance("#0000",AllCompliance, &image->background_color,exception); shadow_image=ShadowImage(image,80.0,2.0,5,5,exception); if (shadow_image != (Image *) NULL) { (void) CompositeImage(shadow_image,image,OverCompositeOp, MagickTrue,0,0,exception); image=DestroyImage(image); image=shadow_image; } } (void) CompositeImage(montage,image,image->compose,MagickTrue, x_offset+x,y_offset+y,exception); value=GetImageProperty(image,"label",exception); if (value != (const char *) NULL) { /* Annotate composite tile with label. */ (void) FormatLocaleString(tile_geometry,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) ((montage_info->frame ? image->columns : width)-2*border_width),(double) (metrics.ascent-metrics.descent+4)*MultilineCensus(value), (double) (x_offset+border_width),(double) ((montage_info->frame ? y_offset+height+border_width+4 : y_offset+extract_info.height+border_width+ (montage_info->shadow != MagickFalse ? 4 : 0))+bevel_width)); (void) CloneString(&draw_info->geometry,tile_geometry); (void) CloneString(&draw_info->text,value); (void) AnnotateImage(montage,draw_info,exception); } } x_offset+=(ssize_t) (width+2*(extract_info.x+border_width)); if (((tile+1) == (ssize_t) tiles_per_page) || (((tile+1) % tiles_per_row) == 0)) { x_offset=extract_info.x; y_offset+=(ssize_t) (height+(extract_info.y+border_width)*2+ (metrics.ascent-metrics.descent+4)*number_lines+ (montage_info->shadow != MagickFalse ? 4 : 0)); max_height=0; } if (images->progress_monitor != (MagickProgressMonitor) NULL) { proceed=SetImageProgress(image,MontageImageTag,tiles,total_tiles); if (proceed == MagickFalse) status=MagickFalse; } image_list[tile]=DestroyImage(image_list[tile]); image=DestroyImage(image); tiles++; } (void) status; if ((i+1) < (ssize_t) images_per_page) { /* Allocate next image structure. */ AcquireNextImage(clone_info,montage,exception); if (GetNextImageInList(montage) == (Image *) NULL) { montage=DestroyImageList(montage); return((Image *) NULL); } montage=GetNextImageInList(montage); montage->background_color=montage_info->background_color; image_list+=tiles_per_page; number_images-=tiles_per_page; } } tile_image=DestroyImage(tile_image); if (texture != (Image *) NULL) texture=DestroyImage(texture); title=DestroyString(title); master_list=(Image **) RelinquishMagickMemory(master_list); draw_info=DestroyDrawInfo(draw_info); clone_info=DestroyImageInfo(clone_info); return(GetFirstImageInList(montage)); }
static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception) { #define MaxBufferExtent 8192 char filename[MaxTextExtent]; FILE *file; Image *image; ImageInfo *read_info; int unique_file; image=(Image *) NULL; read_info=CloneImageInfo(image_info); SetImageInfoBlob(read_info,(void *) NULL,0); file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(read_info->filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file == -1) || (file == (FILE *) NULL)) { read_info=DestroyImageInfo(read_info); (void) CopyMagickString(image->filename,read_info->filename, MaxTextExtent); ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile", image->filename); image=DestroyImageList(image); return((Image *) NULL); } (void) CopyMagickString(filename,image_info->magick,MaxTextExtent); (void) ConcatenateMagickString(filename,":",MaxTextExtent); LocaleLower(filename); (void) ConcatenateMagickString(filename,image_info->filename,MaxTextExtent); if (LocaleCompare(read_info->magick,"file") == 0) { (void) RelinquishUniqueFileResource(read_info->filename); unique_file=(-1); (void) CopyMagickString(read_info->filename,image_info->filename+2, MaxTextExtent); } #if defined(MAGICKCORE_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); xmlNanoHTTPClose(context); xmlFree(type); xmlNanoHTTPCleanup(); } } #endif (void) fclose(file); *read_info->magick='\0'; image=ReadImage(read_info,exception); if (unique_file != -1) (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); if (image == (Image *) NULL) (void) ThrowMagickException(exception,GetMagickModule(),CoderError, "NoDataReturned","`%s'",filename); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + 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 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d I N L I N E I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadINLINEImage() reads base64-encoded inlines images. % % The format of the ReadINLINEImage method is: % % Image *ReadINLINEImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadINLINEImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; MagickBooleanType status; register size_t i; size_t quantum; ssize_t count; unsigned char *inline_image; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); if (LocaleCompare(image_info->magick,"DATA") == 0) { char *filename; Image *data_image; filename=AcquireString("data:"); (void) ConcatenateMagickString(filename,image_info->filename, MagickPathExtent); data_image=ReadInlineImage(image_info,filename,exception); filename=DestroyString(filename); return(data_image); } image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } quantum=MagickMin((size_t) GetBlobSize(image),MagickMaxBufferExtent); if (quantum == 0) quantum=MagickMaxBufferExtent; inline_image=(unsigned char *) AcquireQuantumMemory(quantum, sizeof(*inline_image)); count=0; for (i=0; inline_image != (unsigned char *) NULL; i+=count) { count=(ssize_t) ReadBlob(image,quantum,inline_image+i); if (count <= 0) { count=0; if (errno != EINTR) break; } if (~((size_t) i) < (quantum+1)) { inline_image=(unsigned char *) RelinquishMagickMemory(inline_image); break; } inline_image=(unsigned char *) ResizeQuantumMemory(inline_image,i+count+ quantum+1,sizeof(*inline_image)); } if (inline_image == (unsigned char *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return((Image *) NULL); } inline_image[i+count]='\0'; image=DestroyImageList(image); image=ReadInlineImage(image_info,(char *) inline_image,exception); inline_image=(unsigned char *) RelinquishMagickMemory(inline_image); return(image); }
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 T X T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteTXTImage writes the pixel values as text numbers. % % The format of the WriteTXTImage method is: % % MagickBooleanType WriteTXTImage(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 WriteTXTImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { char buffer[MagickPathExtent], colorspace[MagickPathExtent], tuple[MagickPathExtent]; MagickBooleanType status; MagickOffsetType scene; PixelInfo pixel; register const Quantum *p; register ssize_t x; ssize_t y; /* 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); status=OpenBlob(image_info,image,WriteBlobMode,exception); if (status == MagickFalse) return(status); scene=0; do { ComplianceType compliance; const char *value; (void) CopyMagickString(colorspace,CommandOptionToMnemonic( MagickColorspaceOptions,(ssize_t) image->colorspace),MagickPathExtent); LocaleLower(colorspace); image->depth=GetImageQuantumDepth(image,MagickTrue); if (image->alpha_trait != UndefinedPixelTrait) (void) ConcatenateMagickString(colorspace,"a",MagickPathExtent); compliance=NoCompliance; value=GetImageOption(image_info,"txt:compliance"); if (value != (char *) NULL) compliance=(ComplianceType) ParseCommandOption(MagickComplianceOptions, MagickFalse,value); if (LocaleCompare(image_info->magick,"SPARSE-COLOR") != 0) { size_t depth; depth=compliance == SVGCompliance ? image->depth : MAGICKCORE_QUANTUM_DEPTH; (void) FormatLocaleString(buffer,MagickPathExtent, "# ImageMagick pixel enumeration: %.20g,%.20g,%.20g,%s\n",(double) image->columns,(double) image->rows,(double) ((MagickOffsetType) GetQuantumRange(depth)),colorspace); (void) WriteBlobString(image,buffer); } GetPixelInfo(image,&pixel); 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++) { GetPixelInfoPixel(image,p,&pixel); if (pixel.colorspace == LabColorspace) { pixel.green-=(QuantumRange+1)/2.0; pixel.blue-=(QuantumRange+1)/2.0; } if (LocaleCompare(image_info->magick,"SPARSE-COLOR") == 0) { /* Sparse-color format. */ if (GetPixelAlpha(image,p) == (Quantum) OpaqueAlpha) { GetColorTuple(&pixel,MagickFalse,tuple); (void) FormatLocaleString(buffer,MagickPathExtent, "%.20g,%.20g,",(double) x,(double) y); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,tuple); (void) WriteBlobString(image," "); } p+=GetPixelChannels(image); continue; } (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g,%.20g: ", (double) x,(double) y); (void) WriteBlobString(image,buffer); (void) CopyMagickString(tuple,"(",MagickPathExtent); if (pixel.colorspace == GRAYColorspace) ConcatenateColorComponent(&pixel,GrayPixelChannel,compliance, tuple); else { ConcatenateColorComponent(&pixel,RedPixelChannel,compliance,tuple); (void) ConcatenateMagickString(tuple,",",MagickPathExtent); ConcatenateColorComponent(&pixel,GreenPixelChannel,compliance, tuple); (void) ConcatenateMagickString(tuple,",",MagickPathExtent); ConcatenateColorComponent(&pixel,BluePixelChannel,compliance,tuple); } if (pixel.colorspace == CMYKColorspace) { (void) ConcatenateMagickString(tuple,",",MagickPathExtent); ConcatenateColorComponent(&pixel,BlackPixelChannel,compliance, tuple); } if (pixel.alpha_trait != UndefinedPixelTrait) { (void) ConcatenateMagickString(tuple,",",MagickPathExtent); ConcatenateColorComponent(&pixel,AlphaPixelChannel,compliance, tuple); } (void) ConcatenateMagickString(tuple,")",MagickPathExtent); (void) WriteBlobString(image,tuple); (void) WriteBlobString(image," "); GetColorTuple(&pixel,MagickTrue,tuple); (void) FormatLocaleString(buffer,MagickPathExtent,"%s",tuple); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image," "); (void) QueryColorname(image,&pixel,SVGCompliance,tuple,exception); (void) WriteBlobString(image,tuple); (void) WriteBlobString(image,"\n"); p+=GetPixelChannels(image); } status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(MagickTrue); }
static MagickBooleanType WritePS2Image(const ImageInfo *image_info,Image *image) { static const char *PostscriptProlog[]= { "%%%%BeginProlog", "%%", "%% Display a color image. The image is displayed in color on", "%% Postscript viewers or printers that support color, otherwise", "%% it is displayed as grayscale.", "%%", "/DirectClassImage", "{", " %%", " %% Display a DirectClass image.", " %%", " colorspace 0 eq", " {", " /DeviceRGB setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [0 1 0 1 0 1]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " }", " {", " /DeviceCMYK setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [1 0 1 0 1 0 1 0]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " } ifelse", "} bind def", "", "/PseudoClassImage", "{", " %%", " %% Display a PseudoClass image.", " %%", " %% Parameters:", " %% colors: number of colors in the colormap.", " %%", " currentfile buffer readline pop", " token pop /colors exch def pop", " colors 0 eq", " {", " %%", " %% Image is grayscale.", " %%", " currentfile buffer readline pop", " token pop /bits exch def pop", " /DeviceGray setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent bits", " /Decode [0 1]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " {", " /DataSource pixel_stream %s", " <<", " /K "CCITTParam, " /Columns columns", " /Rows rows", " >> /CCITTFaxDecode filter", " } ifelse", " >> image", " }", " {", " %%", " %% Parameters:", " %% colormap: red, green, blue color packets.", " %%", " /colormap colors 3 mul string def", " currentfile colormap readhexstring pop pop", " currentfile buffer readline pop", " [ /Indexed /DeviceRGB colors 1 sub colormap ] setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [0 255]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " } ifelse", "} bind def", "", "/DisplayImage", "{", " %%", " %% Display a DirectClass or PseudoClass image.", " %%", " %% Parameters:", " %% x & y translation.", " %% x & y scale.", " %% label pointsize.", " %% image label.", " %% image columns & rows.", " %% class: 0-DirectClass or 1-PseudoClass.", " %% colorspace: 0-RGB or 1-CMYK.", " %% compression: 0-RLECompression or 1-NoCompression.", " %% hex color packets.", " %%", " gsave", " /buffer 512 string def", " /pixel_stream currentfile def", "", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " x y translate", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " currentfile buffer readline pop", " token pop /pointsize exch def pop", " /Helvetica findfont pointsize scalefont setfont", (char *) NULL }, *PostscriptEpilog[]= { " x y scale", " currentfile buffer readline pop", " token pop /columns exch def", " token pop /rows exch def pop", " currentfile buffer readline pop", " token pop /class exch def pop", " currentfile buffer readline pop", " token pop /colorspace exch def pop", " currentfile buffer readline pop", " token pop /compression exch def pop", " class 0 gt { PseudoClassImage } { DirectClassImage } ifelse", (char *) NULL }; char buffer[MaxTextExtent], date[MaxTextExtent], page_geometry[MaxTextExtent], **labels; CompressionType compression; const char **q, *value; double pointsize; GeometryInfo geometry_info; MagickOffsetType scene, start, stop; MagickBooleanType progress, status; MagickOffsetType offset; MagickSizeType number_pixels; MagickStatusType flags; PointInfo delta, resolution, scale; RectangleInfo geometry, media_info, page_info; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t x; register ssize_t i; SegmentInfo bounds; size_t length, page, text_size; ssize_t j, y; time_t timer; unsigned char *pixels; /* 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); compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; switch (compression) { #if !defined(MAGICKCORE_JPEG_DELEGATE) case JPEGCompression: { compression=RLECompression; (void) ThrowMagickException(&image->exception,GetMagickModule(), MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (JPEG)", image->filename); break; } #endif default: break; } (void) ResetMagickMemory(&bounds,0,sizeof(bounds)); page=1; scene=0; do { /* Scale relative to dots-per-inch. */ delta.x=DefaultResolution; delta.y=DefaultResolution; resolution.x=image->x_resolution; resolution.y=image->y_resolution; if ((resolution.x == 0.0) || (resolution.y == 0.0)) { flags=ParseGeometry(PSDensityGeometry,&geometry_info); resolution.x=geometry_info.rho; resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } if (image_info->density != (char *) NULL) { flags=ParseGeometry(image_info->density,&geometry_info); resolution.x=geometry_info.rho; resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } if (image->units == PixelsPerCentimeterResolution) { resolution.x=(size_t) (100.0*2.54*resolution.x+0.5)/100.0; resolution.y=(size_t) (100.0*2.54*resolution.y+0.5)/100.0; } SetGeometry(image,&geometry); (void) FormatLocaleString(page_geometry,MaxTextExtent,"%.20gx%.20g", (double) image->columns,(double) image->rows); if (image_info->page != (char *) NULL) (void) CopyMagickString(page_geometry,image_info->page,MaxTextExtent); else if ((image->page.width != 0) && (image->page.height != 0)) (void) FormatLocaleString(page_geometry,MaxTextExtent, "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,(double) image->page.height,(double) image->page.x,(double) image->page.y); else if ((image->gravity != UndefinedGravity) && (LocaleCompare(image_info->magick,"PS") == 0)) (void) CopyMagickString(page_geometry,PSPageGeometry,MaxTextExtent); (void) ConcatenateMagickString(page_geometry,">",MaxTextExtent); (void) ParseMetaGeometry(page_geometry,&geometry.x,&geometry.y, &geometry.width,&geometry.height); scale.x=(double) (geometry.width*delta.x)/resolution.x; geometry.width=(size_t) floor(scale.x+0.5); scale.y=(double) (geometry.height*delta.y)/resolution.y; geometry.height=(size_t) floor(scale.y+0.5); (void) ParseAbsoluteGeometry(page_geometry,&media_info); (void) ParseGravityGeometry(image,page_geometry,&page_info, &image->exception); if (image->gravity != UndefinedGravity) { geometry.x=(-page_info.x); geometry.y=(ssize_t) (media_info.height+page_info.y-image->rows); } pointsize=12.0; if (image_info->pointsize != 0.0) pointsize=image_info->pointsize; text_size=0; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) text_size=(size_t) (MultilineCensus(value)*pointsize+12); if (page == 1) { /* Output Postscript header. */ if (LocaleCompare(image_info->magick,"PS2") == 0) (void) CopyMagickString(buffer,"%!PS-Adobe-3.0\n",MaxTextExtent); else (void) CopyMagickString(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n", MaxTextExtent); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"%%Creator: (ImageMagick)\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"%%%%Title: (%s)\n", image->filename); (void) WriteBlobString(image,buffer); timer=time((time_t *) NULL); (void) FormatMagickTime(timer,MaxTextExtent,date); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%CreationDate: (%s)\n",date); (void) WriteBlobString(image,buffer); bounds.x1=(double) geometry.x; bounds.y1=(double) geometry.y; bounds.x2=(double) geometry.x+geometry.width; bounds.y2=(double) geometry.y+geometry.height+text_size; if ((image_info->adjoin != MagickFalse) && (GetNextImageInList(image) != (Image *) NULL)) (void) CopyMagickString(buffer,"%%BoundingBox: (atend)\n", MaxTextExtent); else { (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BoundingBox: %.20g %.20g %.20g %.20g\n",ceil(bounds.x1-0.5), ceil(bounds.y1-0.5),floor(bounds.x2+0.5),floor(bounds.y2+0.5)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1, bounds.y1,bounds.x2,bounds.y2); } (void) WriteBlobString(image,buffer); value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image, "%%DocumentNeededResources: font Helvetica\n"); (void) WriteBlobString(image,"%%LanguageLevel: 2\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"%%Pages: 1\n"); else { (void) WriteBlobString(image,"%%Orientation: Portrait\n"); (void) WriteBlobString(image,"%%PageOrder: Ascend\n"); if (image_info->adjoin == MagickFalse) (void) CopyMagickString(buffer,"%%Pages: 1\n",MaxTextExtent); else (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%Pages: %.20g\n",(double) GetImageListLength(image)); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EndComments\n"); (void) WriteBlobString(image,"\n%%BeginDefaults\n"); (void) WriteBlobString(image,"%%EndDefaults\n\n"); /* Output Postscript commands. */ for (q=PostscriptProlog; *q; q++) { switch (compression) { case NoCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/ASCII85Decode filter"); break; } case JPEGCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/DCTDecode filter"); break; } case LZWCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/LZWDecode filter"); break; } case FaxCompression: case Group4Compression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q," "); break; } default: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/RunLengthDecode filter"); break; } } (void) WriteBlobString(image,buffer); (void) WriteBlobByte(image,'\n'); } value=GetImageProperty(image,"label"); if (value != (const char *) NULL) for (j=(ssize_t) MultilineCensus(value)-1; j >= 0; j--) { (void) WriteBlobString(image," /label 512 string def\n"); (void) WriteBlobString(image," currentfile label readline pop\n"); (void) FormatLocaleString(buffer,MaxTextExtent, " 0 y %g add moveto label show pop\n",j*pointsize+12); (void) WriteBlobString(image,buffer); } for (q=PostscriptEpilog; *q; q++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%s\n",*q); (void) WriteBlobString(image,buffer); } if (LocaleCompare(image_info->magick,"PS2") == 0) (void) WriteBlobString(image," showpage\n"); (void) WriteBlobString(image,"} bind def\n"); (void) WriteBlobString(image,"%%EndProlog\n"); } (void) FormatLocaleString(buffer,MaxTextExtent,"%%%%Page: 1 %.20g\n", (double) page++); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%PageBoundingBox: %.20g %.20g %.20g %.20g\n",(double) geometry.x, (double) geometry.y,geometry.x+(double) geometry.width,geometry.y+(double) (geometry.height+text_size)); (void) WriteBlobString(image,buffer); if ((double) geometry.x < bounds.x1) bounds.x1=(double) geometry.x; if ((double) geometry.y < bounds.y1) bounds.y1=(double) geometry.y; if ((double) (geometry.x+geometry.width-1) > bounds.x2) bounds.x2=(double) geometry.x+geometry.width-1; if ((double) (geometry.y+(geometry.height+text_size)-1) > bounds.y2) bounds.y2=(double) geometry.y+(geometry.height+text_size)-1; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image,"%%PageResources: font Times-Roman\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"userdict begin\n"); start=TellBlob(image); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",0L, compression == NoCompression ? "ASCII" : "Binary"); (void) WriteBlobString(image,buffer); stop=TellBlob(image); (void) WriteBlobString(image,"DisplayImage\n"); /* Output image data. */ (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n%g %g\n%g\n", (double) geometry.x,(double) geometry.y,scale.x,scale.y,pointsize); (void) WriteBlobString(image,buffer); labels=(char **) NULL; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) labels=StringToList(value); if (labels != (char **) NULL) { for (i=0; labels[i] != (char *) NULL; i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%s \n", labels[i]); (void) WriteBlobString(image,buffer); labels[i]=DestroyString(labels[i]); } labels=(char **) RelinquishMagickMemory(labels); } number_pixels=(MagickSizeType) image->columns*image->rows; if (number_pixels != (MagickSizeType) ((size_t) number_pixels)) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); if ((compression == FaxCompression) || (compression == Group4Compression) || ((image_info->type != TrueColorType) && (IsGrayImage(image,&image->exception) != MagickFalse))) { (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n1\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) ((compression != FaxCompression) && (compression != Group4Compression))); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"0\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (compression == FaxCompression) || (compression == Group4Compression) ? 1 : 8); (void) WriteBlobString(image,buffer); switch (compression) { case FaxCompression: case Group4Compression: { if (LocaleCompare(CCITTParam,"0") == 0) { (void) HuffmanEncodeImage(image_info,image,image); break; } (void) Huffman2DEncodeImage(image_info,image,image); break; } case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); if (status == MagickFalse) ThrowWriterException(CoderError,image->exception.reason); break; } case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Dump Runlength encoded pixels. */ q=pixels; for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p)); p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } break; } case NoCompression: { /* Dump uncompressed PseudoColor packets. */ Ascii85Initialize(image); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { Ascii85Encode(image,ScaleQuantumToChar( PixelIntensityToQuantum(p))); p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } else if ((image->storage_class == DirectClass) || (image->colors > 256) || (compression == JPEGCompression) || (image->matte != MagickFalse)) { (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n0\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) (compression == NoCompression)); (void) WriteBlobString(image,buffer); switch (compression) { case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); if (status == MagickFalse) ThrowWriterException(CoderError,image->exception.reason); break; } case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); /* Dump Packbit encoded pixels. */ q=pixels; for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { if ((image->matte != MagickFalse) && (GetPixelOpacity(p) == (Quantum) TransparentOpacity)) { *q++=ScaleQuantumToChar((Quantum) QuantumRange); *q++=ScaleQuantumToChar((Quantum) QuantumRange); *q++=ScaleQuantumToChar((Quantum) QuantumRange); } else if (image->colorspace != CMYKColorspace) { *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); } else { *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); *q++=ScaleQuantumToChar(GetPixelIndex( indexes+x)); } p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } pixels=(unsigned char *) RelinquishMagickMemory(pixels); break; } case NoCompression: { /* Dump uncompressed DirectColor packets. */ Ascii85Initialize(image); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { if ((image->matte != MagickFalse) && (GetPixelOpacity(p) == (Quantum) TransparentOpacity)) { Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); } else if (image->colorspace != CMYKColorspace) { Ascii85Encode(image,ScaleQuantumToChar( GetPixelRed(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelGreen(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlue(p))); } else { Ascii85Encode(image,ScaleQuantumToChar( GetPixelRed(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelGreen(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlue(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelIndex(indexes+x))); } p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } else { /* Dump number of colors and colormap. */ (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n1\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) (compression == NoCompression)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double) image->colors); (void) WriteBlobString(image,buffer); for (i=0; i < (ssize_t) image->colors; i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%02X%02X%02X\n", ScaleQuantumToChar(image->colormap[i].red), ScaleQuantumToChar(image->colormap[i].green), ScaleQuantumToChar(image->colormap[i].blue)); (void) WriteBlobString(image,buffer); } switch (compression) { case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); /* Dump Runlength encoded pixels. */ q=pixels; for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) *q++=(unsigned char) GetPixelIndex(indexes+x); progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } break; } case NoCompression: { /* Dump uncompressed PseudoColor packets. */ Ascii85Initialize(image); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) Ascii85Encode(image,(unsigned char) GetPixelIndex( indexes+x)); progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } (void) WriteBlobByte(image,'\n'); length=(size_t) (TellBlob(image)-stop); stop=TellBlob(image); offset=SeekBlob(image,start,SEEK_SET); if (offset < 0) ThrowWriterException(CorruptImageError,"ImproperImageHeader"); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",(long) length, compression == NoCompression ? "ASCII" : "Binary"); (void) WriteBlobString(image,buffer); offset=SeekBlob(image,stop,SEEK_SET); (void) WriteBlobString(image,"%%EndData\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"end\n"); (void) WriteBlobString(image,"%%PageTrailer\n"); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) WriteBlobString(image,"%%Trailer\n"); if (page > 1) { (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BoundingBox: %.20g %.20g %.20g %.20g\n",ceil(bounds.x1-0.5), ceil(bounds.y1-0.5),floor(bounds.x2+0.5),floor(bounds.y2+0.5)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1,bounds.y1, bounds.x2,bounds.y2); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EOF\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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e D E B U G I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteDEBUGImage writes the image pixel values with 20 places of precision. % % The format of the WriteDEBUGImage method is: % % MagickBooleanType WriteDEBUGImage(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 WriteDEBUGImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { char buffer[MaxTextExtent], colorspace[MaxTextExtent], tuple[MaxTextExtent]; ssize_t y; MagickBooleanType status; MagickOffsetType scene; PixelInfo pixel; register const Quantum *p; register ssize_t x; /* 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,WriteBlobMode,exception); if (status == MagickFalse) return(status); scene=0; do { (void) CopyMagickString(colorspace,CommandOptionToMnemonic( MagickColorspaceOptions,(ssize_t) image->colorspace),MaxTextExtent); LocaleLower(colorspace); image->depth=GetImageQuantumDepth(image,MagickTrue); if (image->alpha_trait == BlendPixelTrait) (void) ConcatenateMagickString(colorspace,"a",MaxTextExtent); (void) FormatLocaleString(buffer,MaxTextExtent, "# ImageMagick pixel debugging: %.20g,%.20g,%.20g,%s\n",(double) image->columns,(double) image->rows,(double) ((MagickOffsetType) GetQuantumRange(image->depth)),colorspace); (void) WriteBlobString(image,buffer); GetPixelInfo(image,&pixel); 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++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g,%.20g: ",(double) x,(double) y); (void) WriteBlobString(image,buffer); GetPixelInfoPixel(image,p,&pixel); (void) FormatLocaleString(tuple,MaxTextExtent,"%.20g,%.20g,%.20g ", (double) pixel.red,(double) pixel.green,(double) pixel.blue); if (pixel.colorspace == CMYKColorspace) { char black[MaxTextExtent]; (void) FormatLocaleString(black,MaxTextExtent,",%.20g ", (double) pixel.black); (void) ConcatenateMagickString(tuple,black,MaxTextExtent); } if (pixel.alpha_trait == BlendPixelTrait) { char alpha[MaxTextExtent]; (void) FormatLocaleString(alpha,MaxTextExtent,",%.20g ", (double) pixel.alpha); (void) ConcatenateMagickString(tuple,alpha,MaxTextExtent); } (void) WriteBlobString(image,tuple); (void) WriteBlobString(image,"\n"); p+=GetPixelChannels(image); } status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t C o n f i g u r e P a t h s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetConfigurePaths() returns any Magick configuration paths associated % with the specified filename. % % The format of the GetConfigurePaths method is: % % LinkedListInfo *GetConfigurePaths(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the configure file name. % % o exception: return any errors or warnings in this structure. % */ MagickExport LinkedListInfo *GetConfigurePaths(const char *filename, ExceptionInfo *exception) { #define RegistryKey "ConfigurePath" #define MagickCoreDLL "CORE_RL_magick_.dll" #define MagickCoreDebugDLL "CORE_DB_magick_.dll" char path[MaxTextExtent]; LinkedListInfo *paths; assert(filename != (const char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); assert(exception != (ExceptionInfo *) NULL); (void) CopyMagickString(path,filename,MaxTextExtent); paths=NewLinkedList(0); { char *configure_path; /* Search $MAGICK_CONFIGURE_PATH. */ configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH"); if (configure_path != (char *) NULL) { register char *p, *q; for (p=configure_path-1; p != (char *) NULL; ) { (void) CopyMagickString(path,p+1,MaxTextExtent); q=strchr(path,DirectoryListSeparator); if (q != (char *) NULL) *q='\0'; q=path+strlen(path)-1; if ((q >= path) && (*q != *DirectorySeparator)) (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); (void) AppendValueToLinkedList(paths,ConstantString(path)); p=strchr(p+1,DirectoryListSeparator); } configure_path=DestroyString(configure_path); } } #if defined(MAGICKCORE_INSTALLED_SUPPORT) #if defined(MAGICKCORE_SHARE_PATH) (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH)); #endif #if defined(MAGICKCORE_SHAREARCH_PATH) (void) AppendValueToLinkedList(paths,ConstantString( MAGICKCORE_SHAREARCH_PATH)); #endif #if defined(MAGICKCORE_CONFIGURE_PATH) (void) AppendValueToLinkedList(paths,ConstantString( MAGICKCORE_CONFIGURE_PATH)); #endif #if defined(MAGICKCORE_DOCUMENTATION_PATH) (void) AppendValueToLinkedList(paths,ConstantString( MAGICKCORE_DOCUMENTATION_PATH)); #endif #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH)) { unsigned char *key_value; /* Locate file via registry key. */ key_value=NTRegistryKeyLookup(RegistryKey); if (key_value != (unsigned char *) NULL) { (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value, DirectorySeparator); (void) AppendValueToLinkedList(paths,ConstantString(path)); key_value=(unsigned char *) RelinquishMagickMemory(key_value); } } #endif #else { char *home; /* Search under MAGICK_HOME. */ home=GetEnvironmentValue("MAGICK_HOME"); if (home != (char *) NULL) { #if !defined(MAGICKCORE_POSIX_SUPPORT) (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home, DirectorySeparator); (void) AppendValueToLinkedList(paths,ConstantString(path)); #else (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home, MAGICKCORE_CONFIGURE_RELATIVE_PATH); (void) AppendValueToLinkedList(paths,ConstantString(path)); (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home, MAGICKCORE_SHARE_RELATIVE_PATH); (void) AppendValueToLinkedList(paths,ConstantString(path)); #endif home=DestroyString(home); } } if (*GetClientPath() != '\0') { #if !defined(MAGICKCORE_POSIX_SUPPORT) (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(), DirectorySeparator); (void) AppendValueToLinkedList(paths,ConstantString(path)); #else char prefix[MaxTextExtent]; /* Search based on executable directory if directory is known. */ (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent); ChopPathComponents(prefix,1); (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix, MAGICKCORE_CONFIGURE_RELATIVE_PATH); (void) AppendValueToLinkedList(paths,ConstantString(path)); (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix, MAGICKCORE_SHARE_RELATIVE_PATH); (void) AppendValueToLinkedList(paths,ConstantString(path)); #endif } /* Search current directory. */ (void) AppendValueToLinkedList(paths,ConstantString("")); #endif { char *home; home=GetEnvironmentValue("HOME"); if (home == (char *) NULL) home=GetEnvironmentValue("USERPROFILE"); if (home != (char *) NULL) { /* Search $HOME/.magick. */ (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home, DirectorySeparator,DirectorySeparator); (void) AppendValueToLinkedList(paths,ConstantString(path)); home=DestroyString(home); } } #if defined(MAGICKCORE_WINDOWS_SUPPORT) { char module_path[MaxTextExtent]; if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) || (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse)) { unsigned char *key_value; /* Search module path. */ (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, DirectorySeparator); key_value=NTRegistryKeyLookup(RegistryKey); if (key_value == (unsigned char *) NULL) (void) AppendValueToLinkedList(paths,ConstantString(path)); else key_value=(unsigned char *) RelinquishMagickMemory(key_value); } if (NTGetModulePath("Magick.dll",module_path) != MagickFalse) { /* Search PerlMagick module path. */ (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, DirectorySeparator); (void) AppendValueToLinkedList(paths,ConstantString(path)); (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, "\\inc\\lib\\auto\\Image\\Magick\\"); (void) AppendValueToLinkedList(paths,ConstantString(path)); } } #endif return(paths); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t P a g e G e o m e t r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetPageGeometry() replaces any page mneumonic with the equivalent size in % picas. % % The format of the GetPageGeometry method is: % % char *GetPageGeometry(const char *page_geometry) % % A description of each parameter follows. % % o page_geometry: Specifies a pointer to an array of characters. % The string is either a Postscript page name (e.g. A4) or a postscript % page geometry (e.g. 612x792+36+36). % */ MagickExport char *GetPageGeometry(const char *page_geometry) { static const char *PageSizes[][2]= { { "4x6", "288x432" }, { "5x7", "360x504" }, { "7x9", "504x648" }, { "8x10", "576x720" }, { "9x11", "648x792" }, { "9x12", "648x864" }, { "10x13", "720x936" }, { "10x14", "720x1008" }, { "11x17", "792x1224" }, { "a0", "2384x3370" }, { "a1", "1684x2384" }, { "a10", "73x105" }, { "a2", "1191x1684" }, { "a3", "842x1191" }, { "a4", "595x842" }, { "a4smaLL", "595x842" }, { "a5", "420x595" }, { "a6", "297x420" }, { "a7", "210x297" }, { "a8", "148x210" }, { "a9", "105x148" }, { "archa", "648x864" }, { "archb", "864x1296" }, { "archC", "1296x1728" }, { "archd", "1728x2592" }, { "arche", "2592x3456" }, { "b0", "2920x4127" }, { "b1", "2064x2920" }, { "b10", "91x127" }, { "b2", "1460x2064" }, { "b3", "1032x1460" }, { "b4", "729x1032" }, { "b5", "516x729" }, { "b6", "363x516" }, { "b7", "258x363" }, { "b8", "181x258" }, { "b9", "127x181" }, { "c0", "2599x3676" }, { "c1", "1837x2599" }, { "c2", "1298x1837" }, { "c3", "918x1296" }, { "c4", "649x918" }, { "c5", "459x649" }, { "c6", "323x459" }, { "c7", "230x323" }, { "executive", "540x720" }, { "flsa", "612x936" }, { "flse", "612x936" }, { "folio", "612x936" }, { "halfletter", "396x612" }, { "isob0", "2835x4008" }, { "isob1", "2004x2835" }, { "isob10", "88x125" }, { "isob2", "1417x2004" }, { "isob3", "1001x1417" }, { "isob4", "709x1001" }, { "isob5", "499x709" }, { "isob6", "354x499" }, { "isob7", "249x354" }, { "isob8", "176x249" }, { "isob9", "125x176" }, { "jisb0", "1030x1456" }, { "jisb1", "728x1030" }, { "jisb2", "515x728" }, { "jisb3", "364x515" }, { "jisb4", "257x364" }, { "jisb5", "182x257" }, { "jisb6", "128x182" }, { "ledger", "1224x792" }, { "legal", "612x1008" }, { "letter", "612x792" }, { "lettersmaLL", "612x792" }, { "quarto", "610x780" }, { "statement", "396x612" }, { "tabloid", "792x1224" }, { (char *) NULL, (char *) NULL } }; char *page; register ssize_t i; assert(page_geometry != (char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",page_geometry); page=AcquireString(page_geometry); for (i=0; *PageSizes[i] != (char *) NULL; i++) if (LocaleNCompare(PageSizes[i][0],page,strlen(PageSizes[i][0])) == 0) { RectangleInfo geometry; MagickStatusType flags; /* Replace mneumonic with the equivalent size in dots-per-inch. */ (void) CopyMagickString(page,PageSizes[i][1],MaxTextExtent); (void) ConcatenateMagickString(page,page_geometry+ strlen(PageSizes[i][0]),MaxTextExtent); flags=GetGeometry(page,&geometry.x,&geometry.y,&geometry.width, &geometry.height); if ((flags & GreaterValue) == 0) (void) ConcatenateMagickString(page,">",MaxTextExtent); break; } return(page); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % N T A c q u i r e T y p e C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % NTAcquireTypeCache() loads a Windows TrueType fonts. % % The format of the NTAcquireTypeCache method is: % % MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *type_cache) % % A description of each parameter follows: % % o type_cache: A linked list of fonts. % */ MagickExport MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *type_cache, ExceptionInfo *exception) { HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE; LONG res; int list_entries = 0; char buffer[MaxTextExtent], system_root[MaxTextExtent], font_root[MaxTextExtent]; DWORD type, system_root_length; MagickBooleanType status; /* Try to find the right Windows*\CurrentVersion key, the SystemRoot and then the Fonts key */ res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, ®_key); if (res == ERROR_SUCCESS) { system_root_length=sizeof(system_root)-1; res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type, (BYTE*) system_root, &system_root_length); } if (res != ERROR_SUCCESS) { res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, ®_key); if (res == ERROR_SUCCESS) { system_root_length=sizeof(system_root)-1; res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type, (BYTE*)system_root, &system_root_length); } } if (res == ERROR_SUCCESS) res = RegOpenKeyExA (reg_key, "Fonts",0, KEY_READ, ®_key); if (res != ERROR_SUCCESS) return(MagickFalse); *font_root='\0'; (void) CopyMagickString(buffer,system_root,MaxTextExtent); (void) ConcatenateMagickString(buffer,"\\fonts\\arial.ttf",MaxTextExtent); if (IsPathAccessible(buffer) != MagickFalse) { (void) CopyMagickString(font_root,system_root,MaxTextExtent); (void) ConcatenateMagickString(font_root,"\\fonts\\",MaxTextExtent); } else { (void) CopyMagickString(font_root,system_root,MaxTextExtent); (void) ConcatenateMagickString(font_root,"\\",MaxTextExtent); } { TypeInfo *type_info; DWORD registry_index = 0, type, value_data_size, value_name_length; char value_data[MaxTextExtent], value_name[MaxTextExtent]; res = ERROR_SUCCESS; while (res != ERROR_NO_MORE_ITEMS) { char *family_extent, token[MaxTextExtent], *pos, *q; value_name_length = sizeof(value_name) - 1; value_data_size = sizeof(value_data) - 1; res=RegEnumValueA(reg_key,registry_index,value_name,&value_name_length, 0,&type,(BYTE *) value_data,&value_data_size); registry_index++; if (res != ERROR_SUCCESS) continue; if ((pos=strstr(value_name," (TrueType)")) == (char*) NULL) continue; *pos='\0'; /* Remove (TrueType) from string */ type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(type_info,0,sizeof(TypeInfo)); type_info->path=ConstantString("Windows Fonts"); type_info->signature=MagickSignature; (void) CopyMagickString(buffer,value_name,MaxTextExtent); /* name */ for (pos=buffer; *pos != 0; pos++) if (*pos == ' ') *pos='-'; type_info->name=ConstantString(buffer); type_info->description=ConstantString(value_name); /* fullname */ type_info->format=ConstantString("truetype"); /* format */ if (strchr(value_data,'\\') != (char *) NULL) /* glyphs */ (void) CopyMagickString(buffer,value_data,MaxTextExtent); else { (void) CopyMagickString(buffer,font_root,MaxTextExtent); (void) ConcatenateMagickString(buffer,value_data,MaxTextExtent); } LocaleLower(buffer); type_info->glyphs=ConstantString(buffer); type_info->stretch=NormalStretch; type_info->style=NormalStyle; type_info->weight=400; /* Some fonts are known to require special encodings. */ if ( (LocaleCompare(type_info->name, "Symbol") == 0 ) || (LocaleCompare(type_info->name, "Wingdings") == 0 ) || (LocaleCompare(type_info->name, "Wingdings-2") == 0 ) || (LocaleCompare(type_info->name, "Wingdings-3") == 0 ) ) type_info->encoding=ConstantString("AppleRoman"); family_extent=value_name; for (q=value_name; *q != '\0'; ) { GetMagickToken(q,(const char **) &q,token); if (*token == '\0') break; if (LocaleCompare(token,"Italic") == 0) { type_info->style=ItalicStyle; } else if (LocaleCompare(token,"Oblique") == 0) { type_info->style=ObliqueStyle; } else if (LocaleCompare(token,"Bold") == 0) { type_info->weight=700; } else if (LocaleCompare(token,"Thin") == 0) { type_info->weight=100; } else if ( (LocaleCompare(token,"ExtraLight") == 0) || (LocaleCompare(token,"UltraLight") == 0) ) { type_info->weight=200; } else if (LocaleCompare(token,"Light") == 0) { type_info->weight=300; } else if ( (LocaleCompare(token,"Normal") == 0) || (LocaleCompare(token,"Regular") == 0) ) { type_info->weight=400; } else if (LocaleCompare(token,"Medium") == 0) { type_info->weight=500; } else if ( (LocaleCompare(token,"SemiBold") == 0) || (LocaleCompare(token,"DemiBold") == 0) ) { type_info->weight=600; } else if ( (LocaleCompare(token,"ExtraBold") == 0) || (LocaleCompare(token,"UltraBold") == 0) ) { type_info->weight=800; } else if ( (LocaleCompare(token,"Heavy") == 0) || (LocaleCompare(token,"Black") == 0) ) { type_info->weight=900; } else if (LocaleCompare(token,"Condensed") == 0) { type_info->stretch = CondensedStretch; } else if (LocaleCompare(token,"Expanded") == 0) { type_info->stretch = ExpandedStretch; } else if (LocaleCompare(token,"ExtraCondensed") == 0) { type_info->stretch = ExtraCondensedStretch; } else if (LocaleCompare(token,"ExtraExpanded") == 0) { type_info->stretch = ExtraExpandedStretch; } else if (LocaleCompare(token,"SemiCondensed") == 0) { type_info->stretch = SemiCondensedStretch; } else if (LocaleCompare(token,"SemiExpanded") == 0) { type_info->stretch = SemiExpandedStretch; } else if (LocaleCompare(token,"UltraCondensed") == 0) { type_info->stretch = UltraCondensedStretch; } else if (LocaleCompare(token,"UltraExpanded") == 0) { type_info->stretch = UltraExpandedStretch; } else { family_extent=q; } } (void) CopyMagickString(buffer,value_name,family_extent-value_name+1); StripString(buffer); type_info->family=ConstantString(buffer); list_entries++; status=AddValueToSplayTree(type_cache,ConstantString(type_info->name), type_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name); } } RegCloseKey(reg_key); return(MagickTrue); }
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 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); }