/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S e t I m a g e D e p t h % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SetImageDepth() sets the depth of the image. % % The format of the SetImageDepth method is: % % MagickBooleanType SetImageDepth(Image *image,const size_t depth, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o channel: the channel. % % o depth: the image depth. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType SetImageDepth(Image *image, const size_t depth,ExceptionInfo *exception) { CacheView *image_view; MagickBooleanType status; QuantumAny range; ssize_t y; assert(image != (Image *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(image->signature == MagickSignature); if (depth >= MAGICKCORE_QUANTUM_DEPTH) { image->depth=depth; return(MagickTrue); } range=GetQuantumRange(depth); if (image->storage_class == PseudoClass) { register ssize_t i; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(status) \ dynamic_number_threads(image,image->columns,1,1) #endif for (i=0; i < (ssize_t) image->colors; i++) { if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) image->colormap[i].red=(double) ScaleAnyToQuantum(ScaleQuantumToAny( ClampToQuantum(image->colormap[i].red),range),range); if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) image->colormap[i].green=(double) ScaleAnyToQuantum(ScaleQuantumToAny( ClampToQuantum(image->colormap[i].green),range),range); if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) image->colormap[i].blue=(double) ScaleAnyToQuantum(ScaleQuantumToAny( ClampToQuantum(image->colormap[i].blue),range),range); if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) image->colormap[i].alpha=(double) ScaleAnyToQuantum(ScaleQuantumToAny( ClampToQuantum(image->colormap[i].alpha),range),range); } } status=MagickTrue; image_view=AcquireAuthenticCacheView(image,exception); #if !defined(MAGICKCORE_HDRI_SUPPORT) if (QuantumRange <= MaxMap) { Quantum *depth_map; register ssize_t i; /* Scale pixels to desired (optimized with depth map). */ depth_map=(Quantum *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map)); if (depth_map == (Quantum *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); for (i=0; i <= (ssize_t) MaxMap; i++) depth_map[i]=ScaleAnyToQuantum(ScaleQuantumToAny((Quantum) i,range), range); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(status) \ dynamic_number_threads(image,image->columns,image->rows,1) #endif for (y=0; y < (ssize_t) image->rows; y++) { register ssize_t x; register Quantum *restrict q; if (status == MagickFalse) continue; q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, exception); if (q == (Quantum *) NULL) { status=MagickFalse; continue; } for (x=0; x < (ssize_t) image->columns; x++) { register ssize_t i; if (GetPixelMask(image,q) != 0) { q+=GetPixelChannels(image); continue; } for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel; PixelTrait traits; channel=GetPixelChannelChannel(image,i); traits=GetPixelChannelTraits(image,channel); if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) || (channel == MaskPixelChannel)) continue; q[i]=depth_map[ScaleQuantumToMap(q[i])]; } q+=GetPixelChannels(image); } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) { status=MagickFalse; continue; } } image_view=DestroyCacheView(image_view); depth_map=(Quantum *) RelinquishMagickMemory(depth_map); if (status != MagickFalse) image->depth=depth; 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 *policy_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 *policy_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 > 200) (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(policy_cache,file_xml,path,depth+1, exception); file_xml=DestroyString(file_xml); } } } } continue; } if (LocaleCompare(keyword,"<policy") == 0) { /* Policy element. */ policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info)); if (policy_info == (PolicyInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(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) { status=AppendValueToLinkedList(policy_cache,policy_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", policy_info->name); policy_info=(PolicyInfo *) NULL; continue; } GetNextToken(q,(const char **) NULL,extent,token); if (*token != '=') continue; GetNextToken(q,&q,extent,token); GetNextToken(q,&q,extent,token); switch (*keyword) { case 'D': case 'd': { if (LocaleCompare((char *) keyword,"domain") == 0) { policy_info->domain=(PolicyDomain) ParseCommandOption( MagickPolicyDomainOptions,MagickTrue,token); break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { policy_info->name=ConstantString(token); break; } break; } case 'P': case 'p': { if (LocaleCompare((char *) keyword,"pattern") == 0) { policy_info->pattern=ConstantString(token); break; } break; } case 'R': case 'r': { if (LocaleCompare((char *) keyword,"rights") == 0) { policy_info->rights=(PolicyRights) ParseCommandOption( MagickPolicyRightsOptions,MagickTrue,token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { policy_info->stealth=IsStringTrue(token); break; } break; } case 'V': case 'v': { if (LocaleCompare((char *) keyword,"value") == 0) { policy_info->value=ConstantString(token); break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status != 0 ? MagickTrue : MagickFalse); }
static SplayTreeInfo *AcquireTypeCache(const char *filename, ExceptionInfo *exception) { MagickStatusType status; SplayTreeInfo *type_cache; type_cache=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyTypeNode); if (type_cache == (SplayTreeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); status=MagickTrue; #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT) { char *font_path, path[MagickPathExtent]; const StringInfo *option; LinkedListInfo *options; *path='\0'; options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { (void) CopyMagickString(path,GetStringInfoPath(option),MagickPathExtent); status&=LoadTypeCache(type_cache,(const char *) GetStringInfoDatum(option),GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); font_path=GetEnvironmentValue("MAGICK_FONT_PATH"); if (font_path != (char *) NULL) { char *option; /* Search MAGICK_FONT_PATH. */ (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",font_path, DirectorySeparator,filename); option=FileToString(path,~0UL,exception); if (option != (void *) NULL) { status&=LoadTypeCache(type_cache,option,path,0,exception); option=DestroyString(option); } font_path=DestroyString(font_path); } } #endif if (GetNumberOfNodesInSplayTree(type_cache) == 0) status&=LoadTypeCache(type_cache,TypeMap,"built-in",0,exception); return(type_cache); }
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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + 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 G e t T y pe L i s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % NTLoadTypeLists() loads a Windows TrueType fonts. % % The format of the NTLoadTypeLists method is: % % MagickBooleanType NTLoadTypeLists(SplayTreeInfo *type_list) % % A description of each parameter follows: % % o type_list: A linked list of fonts. % */ MagickExport MagickBooleanType NTLoadTypeLists(SplayTreeInfo *type_list, 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; /* Name */ (void) CopyMagickString(buffer,value_name,MaxTextExtent); for(pos = buffer; *pos != 0 ; pos++) if (*pos == ' ') *pos = '-'; type_info->name=ConstantString(buffer); /* Fullname */ type_info->description=ConstantString(value_name); /* Format */ type_info->format=ConstantString("truetype"); /* Glyphs */ if (strchr(value_data,'\\') != (char *) NULL) (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_list,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) { CoderInfo *coder_info = (CoderInfo *) NULL; const char *attribute; MagickBooleanType status; XMLTreeInfo *coder, *coder_map, *include; /* Load the coder map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading coder map \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (coder_list == (SplayTreeInfo *) NULL) { coder_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyCoderNode); if (coder_list == (SplayTreeInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); return(MagickFalse); } } coder_map=NewXMLTree(xml,exception); if (coder_map == (XMLTreeInfo *) NULL) return(MagickFalse); status=MagickTrue; include=GetXMLTreeChild(coder_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",attribute); else { char path[MaxTextExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(path,attribute,MaxTextExtent); xml=FileToString(path,~0,exception); if (xml != (char *) NULL) { status=LoadCoderList(xml,path,depth+1,exception); xml=DestroyString(xml); } } } include=GetNextXMLTreeTag(include); } coder=GetXMLTreeChild(coder_map,"coder"); while (coder != (XMLTreeInfo *) NULL) { /* Process coder element. */ coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); if (coder_info == (CoderInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); coder_info->path=ConstantString(filename); coder_info->signature=MagickSignature; attribute=GetXMLTreeAttribute(coder,"magick"); if (attribute != (const char *) NULL) coder_info->magick=ConstantString(attribute); attribute=GetXMLTreeAttribute(coder,"name"); if (attribute != (const char *) NULL) coder_info->name=ConstantString(attribute); attribute=GetXMLTreeAttribute(coder,"stealth"); if (attribute != (const char *) NULL) coder_info->stealth=IsMagickTrue(attribute); status=AddValueToSplayTree(coder_list,coder_info->magick,coder_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); coder=GetNextXMLTreeTag(coder); } coder_map=DestroyXMLTree(coder_map); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A l l o c a t e S e m a p h o r e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AllocateSemaphoreInfo() initializes the SemaphoreInfo structure. % % The format of the AllocateSemaphoreInfo method is: % % SemaphoreInfo *AllocateSemaphoreInfo(void) % */ MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void) { SemaphoreInfo *semaphore_info; /* Allocate semaphore. */ semaphore_info=(SemaphoreInfo *) malloc(sizeof(SemaphoreInfo)); if (semaphore_info == (SemaphoreInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(semaphore_info,0,sizeof(SemaphoreInfo)); /* Initialize the semaphore. */ #if defined(MAGICKCORE_THREAD_SUPPORT) { int status; pthread_mutexattr_t mutex_info; status=pthread_mutexattr_init(&mutex_info); if (status != 0) { errno=status; ThrowFatalException(ResourceLimitFatalError, "UnableToInitializeSemaphore"); } status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info); if (status != 0) { errno=status; ThrowFatalException(ResourceLimitFatalError, "UnableToInitializeSemaphore"); } status=pthread_mutexattr_destroy(&mutex_info); if (status != 0) { errno=status; ThrowFatalException(ResourceLimitFatalError, "UnableToInitializeSemaphore"); } } #elif defined(MAGICKCORE_HAVE_WINTHREADS) { int status; status=InitializeCriticalSectionAndSpinCount(&semaphore_info->mutex,0x0400); if (status == 0) { errno=status; ThrowFatalException(ResourceLimitFatalError, "UnableToInitializeSemaphore"); } } #endif semaphore_info->id=GetMagickThreadId(); semaphore_info->reference_count=0; semaphore_info->signature=MagickSignature; return(semaphore_info); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A c q u i r e C o n f i g u r e C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireConfigureCache() caches one or more configure configurations which % provides a mapping between configure attributes and a configure name. % % The format of the AcquireConfigureCache method is: % % LinkedListInfo *AcquireConfigureCache(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: The font file name. % % o exception: Return any errors or warnings in this structure. % */ static LinkedListInfo *AcquireConfigureCache(const char *filename, ExceptionInfo *exception) { char path[WizardPathExtent]; const StringInfo *option; LinkedListInfo *configure_cache, *options; register ssize_t i; WizardStatusType status; /* Load built-in configure map. */ configure_cache=NewLinkedList(0); if (configure_cache == (LinkedListInfo *) NULL) ThrowFatalException(ResourceFatalError,"memory allocation failed `%s`"); status=WizardTrue; for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++) { ConfigureInfo *configure_info; register const ConfigureMapInfo *p; p=ConfigureMap+i; configure_info=(ConfigureInfo *) AcquireWizardMemory( sizeof(*configure_info)); if (configure_info == (ConfigureInfo *) NULL) { (void) ThrowWizardException(exception,GetWizardModule(),ResourceError, "memory allocation failed `%s'",strerror(errno)); continue; } (void) ResetWizardMemory(configure_info,0,sizeof(*configure_info)); configure_info->path=(char *) "[built-in]"; configure_info->name=(char *) p->name; configure_info->value=(char *) p->value; configure_info->exempt=WizardTrue; configure_info->signature=WizardSignature; status=AppendValueToLinkedList(configure_cache,configure_info); if (status == WizardFalse) (void) ThrowWizardException(exception,GetWizardModule(),ResourceError, "memory allocation failed `%s'",strerror(errno)); } /* Load external configure map. */ *path='\0'; options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { (void) CopyWizardString(path,GetStringInfoPath(option),WizardPathExtent); status&=LoadConfigureCache(configure_cache,(const char *) GetStringInfoDatum(option),GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); return(configure_cache); }
static MagickBooleanType TraverseLocaleMap(const char *filename, XMLTreeInfo **components,XMLTreeInfo *node,const unsigned long depth, ExceptionInfo *exception) { MagickBooleanType status; status=MagickTrue; if (depth >= MaxRecursionDepth) (void) ThrowMagickException(exception,GetMagickModule(),ConfigureError, "IncludeElementNestedTooDeeply","`%s'",filename); else if (node != (XMLTreeInfo *) NULL) { XMLTreeInfo *child, *sibling; components[depth]=node; if (strcmp(GetXMLTreeTag(node),"message") == 0) { char *message, *tag; const char *attribute, *content; LocaleInfo *locale_info; register long i; 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->signature=MagickSignature; tag=AcquireString((char *) NULL); for (i=1; i < (long) depth; i++) { (void) ConcatenateString(&tag,GetXMLTreeTag(components[i])); (void) ConcatenateString(&tag,"/"); } attribute=GetXMLTreeAttribute(node,"name"); if (attribute != (const char *) NULL) { (void) ConcatenateString(&tag,attribute); (void) ConcatenateString(&tag,"/"); } locale_info->tag=ConstantString(tag); tag=DestroyString(tag); message=AcquireString((char *) NULL); content=GetXMLTreeContent(node); if (content != (const char *) NULL) { (void) ConcatenateString(&message,content); StripString(message); } locale_info->message=ConstantString(message); message=DestroyString(message); status=AddValueToSplayTree(locale_list,locale_info->tag, locale_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); } child=GetXMLTreeChild(node,(const char *) NULL); if (child != (XMLTreeInfo *) NULL) status=TraverseLocaleMap(filename,components,child,depth+1,exception); sibling=GetXMLTreeOrdered(node); if (sibling != (XMLTreeInfo *) NULL) status=TraverseLocaleMap(filename,components,sibling,depth,exception); } return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d C o n f i g u r e L i s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadConfigureCache() loads the configure configurations which provides a % mapping between configure attributes and a configure name. % % The format of the LoadConfigureCache method is: % % WizardBooleanType LoadConfigureCache(LinkedListInfo *configure_cache, % const char *xml,const char *filename,const size_t depth, % ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The configure list in XML format. % % o filename: The configure list filename. % % o depth: depth of <include /> statements. % % o exception: Return any errors or warnings in this structure. % */ static WizardBooleanType LoadConfigureCache(LinkedListInfo *configure_cache, const char *xml,const char *filename,const size_t depth, ExceptionInfo *exception) { const char *attribute; ConfigureInfo *configure_info = (ConfigureInfo *) NULL; WizardStatusType status; XMLTreeInfo *configure, *configure_map, *include; /* Load the configure map file. */ (void) LogWizardEvent(ConfigureEvent,GetWizardModule(), "Loading configure map \"%s\" ...",filename); if (xml == (const char *) NULL) return(WizardFalse); configure_map=NewXMLTree(xml,exception); if (configure_map == (XMLTreeInfo *) NULL) return(WizardFalse); status=WizardFalse; include=GetXMLTreeChild(configure_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowWizardException(exception,GetWizardModule(), ConfigureError,"include element nested too deeply `%s'",filename); else { char path[WizardPathExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateWizardString(path,DirectorySeparator, WizardPathExtent); (void) ConcatenateWizardString(path,attribute,WizardPathExtent); xml=FileToXML(path,~0UL); status&=LoadConfigureCache(configure_cache,xml,path,depth+1, exception); xml=(char *) RelinquishWizardMemory(xml); } } include=GetNextXMLTreeTag(include); } configure=GetXMLTreeChild(configure_map,"configure"); while (configure != (XMLTreeInfo *) NULL) { const char *attribute; /* Process configure element. */ configure_info=(ConfigureInfo *) AcquireWizardMemory( sizeof(*configure_info)); if (configure_info == (ConfigureInfo *) NULL) ThrowFatalException(ResourceFatalError,"memory allocation failed `%s`"); (void) ResetWizardMemory(configure_info,0,sizeof(*configure_info)); configure_info->path=ConstantString(filename); configure_info->exempt=WizardFalse; configure_info->signature=WizardSignature; attribute=GetXMLTreeAttribute(configure,"name"); if (attribute != (const char *) NULL) configure_info->name=ConstantString(attribute); attribute=GetXMLTreeAttribute(configure,"stealth"); if (attribute != (const char *) NULL) configure_info->stealth=IsWizardTrue(attribute); attribute=GetXMLTreeAttribute(configure,"value"); if (attribute != (const char *) NULL) configure_info->value=ConstantString(attribute); status=AppendValueToLinkedList(configure_cache,configure_info); if (status == WizardFalse) (void) ThrowWizardException(exception,GetWizardModule(), ResourceFatalError,"memory allocation failed `%s`",strerror(errno)); configure=GetNextXMLTreeTag(configure); } configure_map=DestroyXMLTree(configure_map); return(status != 0 ? WizardTrue : WizardFalse); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A c q u i r e C o n f i g u r e C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireConfigureCache() caches one or more configure configurations which % provides a mapping between configure attributes and a configure name. % % The format of the AcquireConfigureCache method is: % % LinkedListInfo *AcquireConfigureCache(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the font file name. % % o exception: return any errors or warnings in this structure. % */ static LinkedListInfo *AcquireConfigureCache(const char *filename, ExceptionInfo *exception) { LinkedListInfo *cache; MagickStatusType status; register ssize_t i; /* Load external configure map. */ cache=NewLinkedList(0); if (cache == (LinkedListInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); status=MagickTrue; #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT) { const StringInfo *option; LinkedListInfo *options; options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { status&=LoadConfigureCache(cache,(const char *) GetStringInfoDatum(option),GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); } #endif /* Load built-in configure map. */ for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++) { ConfigureInfo *configure_info; register const ConfigureMapInfo *p; p=ConfigureMap+i; configure_info=(ConfigureInfo *) AcquireMagickMemory( sizeof(*configure_info)); if (configure_info == (ConfigureInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name); continue; } (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info)); configure_info->path=(char *) "[built-in]"; configure_info->name=(char *) p->name; configure_info->value=(char *) p->value; configure_info->exempt=MagickTrue; configure_info->signature=MagickCoreSignature; status&=AppendValueToLinkedList(cache,configure_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", configure_info->name); } return(cache); }
static MagickBooleanType LoadTypeList(const char *xml,const char *filename, const unsigned long depth,ExceptionInfo *exception) { char font_path[MaxTextExtent]; const char *attribute; TypeInfo *type_info = (TypeInfo *) NULL; MagickBooleanType status; XMLTreeInfo *type, *type_map, *include; /* Load the type map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading type map \"%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); } } type_map=NewXMLTree(xml,exception); if (type_map == (XMLTreeInfo *) NULL) return(MagickFalse); status=MagickTrue; include=GetXMLTreeChild(type_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",attribute); else { char path[MaxTextExtent], *xml; ExceptionInfo *sans_exception; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(path,attribute,MaxTextExtent); sans_exception=AcquireExceptionInfo(); xml=FileToString(path,~0,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (xml != (char *) NULL) { status=LoadTypeList(xml,path,depth+1,exception); xml=DestroyString(xml); } } } include=GetNextXMLTreeTag(include); } *font_path='\0'; #if defined(__WINDOWS__) if (NTGhostscriptFonts(font_path,MaxTextExtent-2)) (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent); #endif type=GetXMLTreeChild(type_map,"type"); while (type != (XMLTreeInfo *) NULL) { /* Process 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; attribute=GetXMLTreeAttribute(type,"encoding"); if (attribute != (const char *) NULL) type_info->encoding=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"face"); if (attribute != (const char *) NULL) type_info->face=(unsigned long) atol(attribute); attribute=GetXMLTreeAttribute(type,"family"); if (attribute != (const char *) NULL) type_info->family=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"format"); if (attribute != (const char *) NULL) type_info->format=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"foundry"); if (attribute != (const char *) NULL) type_info->foundry=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"fullname"); if (attribute != (const char *) NULL) type_info->description=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"glyphs"); if (attribute != (const char *) NULL) { char *path; path=ConstantString(attribute); #if defined(__WINDOWS__) if (strchr(path,'@') != (char *) NULL) (void) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif type_info->glyphs=path; } attribute=GetXMLTreeAttribute(type,"metrics"); if (attribute != (const char *) NULL) { char *path; path=ConstantString(attribute); #if defined(__WINDOWS__) if (strchr(path,'@') != (char *) NULL) (void) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif type_info->metrics=path; } attribute=GetXMLTreeAttribute(type,"name"); if (attribute != (const char *) NULL) type_info->name=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"stealth"); if (attribute != (const char *) NULL) type_info->stealth=IsMagickTrue(attribute); attribute=GetXMLTreeAttribute(type,"stretch"); if (attribute != (const char *) NULL) type_info->stretch=(StretchType) ParseMagickOption(MagickStretchOptions, MagickFalse,attribute); attribute=GetXMLTreeAttribute(type,"style"); if (attribute != (const char *) NULL) type_info->style=(StyleType) ParseMagickOption(MagickStyleOptions, MagickFalse,attribute); attribute=GetXMLTreeAttribute(type,"weight"); if (attribute != (const char *) NULL) { type_info->weight=(unsigned long) atol(attribute); if (LocaleCompare(attribute,"bold") == 0) type_info->weight=700; if (LocaleCompare(attribute,"normal") == 0) type_info->weight=400; } status=AddValueToSplayTree(type_list,type_info->name,type_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); type=GetNextXMLTreeTag(type); } type_map=DestroyXMLTree(type_map); return(status); }
MagickExport size_t GetImageChannelDepth(const Image *image, const ChannelType channel,ExceptionInfo *exception) { CacheView *image_view; ssize_t y; MagickBooleanType status; register ssize_t id; size_t *current_depth, depth, number_threads; /* Compute image depth. */ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); number_threads=GetOpenMPMaximumThreads(); current_depth=(size_t *) AcquireQuantumMemory(number_threads, sizeof(*current_depth)); if (current_depth == (size_t *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); status=MagickTrue; for (id=0; id < (ssize_t) number_threads; id++) current_depth[id]=1; if ((image->storage_class == PseudoClass) && (image->matte == MagickFalse)) { register const PixelPacket *restrict p; register ssize_t i; p=image->colormap; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (i=0; i < (ssize_t) image->colors; i++) { const int id = GetOpenMPThreadId(); if (status == MagickFalse) continue; while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH) { MagickStatusType status; QuantumAny range; status=0; range=GetQuantumRange(current_depth[id]); if ((channel & RedChannel) != 0) status|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red, range),range); if ((channel & GreenChannel) != 0) status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green, range),range); if ((channel & BlueChannel) != 0) status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue, range),range); if (status == 0) break; current_depth[id]++; } p++; } depth=current_depth[0]; for (id=1; id < (ssize_t) number_threads; id++) if (depth < current_depth[id]) depth=current_depth[id]; current_depth=(size_t *) RelinquishMagickMemory(current_depth); return(depth); } image_view=AcquireCacheView(image); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (y=0; y < (ssize_t) image->rows; y++) { const int id = GetOpenMPThreadId(); register const IndexPacket *restrict indexes; register const PixelPacket *restrict p; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); if (p == (const PixelPacket *) NULL) continue; indexes=GetCacheViewVirtualIndexQueue(image_view); for (x=0; x < (ssize_t) image->columns; x++) { while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH) { MagickStatusType status; QuantumAny range; status=0; range=GetQuantumRange(current_depth[id]); if ((channel & RedChannel) != 0) status|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red,range), range); if ((channel & GreenChannel) != 0) status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green, range),range); if ((channel & BlueChannel) != 0) status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,range), range); if (((channel & OpacityChannel) != 0) && (image->matte != MagickFalse)) status|=p->opacity != ScaleAnyToQuantum(ScaleQuantumToAny(p->opacity, range),range); if (((channel & IndexChannel) != 0) && (image->colorspace == CMYKColorspace)) status|=indexes[x] != ScaleAnyToQuantum(ScaleQuantumToAny(indexes[x], range),range); if (status == 0) break; current_depth[id]++; } p++; } if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH) status=MagickFalse; } image_view=DestroyCacheView(image_view); depth=current_depth[0]; for (id=1; id < (ssize_t) number_threads; id++) if (depth < current_depth[id]) depth=current_depth[id]; current_depth=(size_t *) RelinquishMagickMemory(current_depth); return(depth); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A c q u i r e V i r t u a l M e m o r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireVirtualMemory() allocates a pointer to a block of memory at least size % bytes suitably aligned for any use. % % The format of the AcquireVirtualMemory method is: % % MemoryInfo *AcquireVirtualMemory(const size_t count,const size_t quantum) % % A description of each parameter follows: % % o count: the number of quantum elements to allocate. % % o quantum: the number of bytes in each quantum. % */ MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count, const size_t quantum) { MemoryInfo *memory_info; size_t length; length=count*quantum; if ((count == 0) || (quantum != (length/count))) { errno=ENOMEM; return((MemoryInfo *) NULL); } memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, sizeof(*memory_info))); if (memory_info == (MemoryInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(memory_info,0,sizeof(*memory_info)); memory_info->length=length; memory_info->signature=MagickCoreSignature; if (AcquireMagickResource(MemoryResource,length) != MagickFalse) { memory_info->blob=AcquireAlignedMemory(1,length); if (memory_info->blob != NULL) memory_info->type=AlignedVirtualMemory; else RelinquishMagickResource(MemoryResource,length); } if ((memory_info->blob == NULL) && (AcquireMagickResource(MapResource,length) != MagickFalse)) { /* Heap memory failed, try anonymous memory mapping. */ memory_info->blob=MapBlob(-1,IOMode,0,length); if (memory_info->blob != NULL) memory_info->type=MapVirtualMemory; else RelinquishMagickResource(MapResource,length); } if ((memory_info->blob == NULL) && (AcquireMagickResource(DiskResource,length) != MagickFalse)) { int file; /* Anonymous memory mapping failed, try file-backed memory mapping. */ file=AcquireUniqueFileResource(memory_info->filename); if (file == -1) RelinquishMagickResource(DiskResource,length); else { if ((lseek(file,length-1,SEEK_SET) < 0) || (write(file,"",1) != 1)) RelinquishMagickResource(DiskResource,length); else { if (AcquireMagickResource(MapResource,length) == MagickFalse) RelinquishMagickResource(DiskResource,length); else { memory_info->blob=MapBlob(file,IOMode,0,length); if (memory_info->blob != NULL) memory_info->type=MapVirtualMemory; else { RelinquishMagickResource(MapResource,length); RelinquishMagickResource(DiskResource,length); } } } (void) close(file); } } if (memory_info->blob == NULL) { memory_info->blob=AcquireMagickMemory(length); if (memory_info->blob != NULL) memory_info->type=UnalignedVirtualMemory; } if (memory_info->blob == NULL) memory_info=RelinquishVirtualMemory(memory_info); return(memory_info); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A c q u i r e V i r t u a l M e m o r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireVirtualMemory() allocates a pointer to a block of memory at least size % bytes suitably aligned for any use. % % The format of the AcquireVirtualMemory method is: % % MemoryInfo *AcquireVirtualMemory(const size_t count,const size_t quantum) % % A description of each parameter follows: % % o count: the number of quantum elements to allocate. % % o quantum: the number of bytes in each quantum. % */ MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count, const size_t quantum) { MemoryInfo *memory_info; size_t extent; if (CheckMemoryOverflow(count,quantum) != MagickFalse) return((MemoryInfo *) NULL); memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, sizeof(*memory_info))); if (memory_info == (MemoryInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(memory_info,0,sizeof(*memory_info)); extent=count*quantum; memory_info->length=extent; memory_info->signature=MagickCoreSignature; if (AcquireMagickResource(MemoryResource,extent) != MagickFalse) { memory_info->blob=AcquireAlignedMemory(1,extent); if (memory_info->blob != NULL) { memory_info->type=AlignedVirtualMemory; return(memory_info); } } RelinquishMagickResource(MemoryResource,extent); if (AcquireMagickResource(MapResource,extent) != MagickFalse) { /* Heap memory failed, try anonymous memory mapping. */ memory_info->blob=MapBlob(-1,IOMode,0,extent); if (memory_info->blob != NULL) { memory_info->type=MapVirtualMemory; return(memory_info); } if (AcquireMagickResource(DiskResource,extent) != MagickFalse) { int file; /* Anonymous memory mapping failed, try file-backed memory mapping. If the MapResource request failed, there is no point in trying file-backed memory mapping. */ file=AcquireUniqueFileResource(memory_info->filename); if (file != -1) { if ((lseek(file,extent-1,SEEK_SET) == (extent-1)) && (write(file,"",1) == 1)) { memory_info->blob=MapBlob(file,IOMode,0,extent); if (memory_info->blob != NULL) { (void) close(file); memory_info->type=MapVirtualMemory; return(memory_info); } } /* File-backed memory mapping failed, delete the temporary file. */ (void) close(file); (void) RelinquishUniqueFileResource(memory_info->filename); *memory_info->filename = '\0'; } } RelinquishMagickResource(DiskResource,extent); } RelinquishMagickResource(MapResource,extent); if (memory_info->blob == NULL) { memory_info->blob=AcquireMagickMemory(extent); if (memory_info->blob != NULL) memory_info->type=UnalignedVirtualMemory; } if (memory_info->blob == NULL) memory_info=RelinquishVirtualMemory(memory_info); return(memory_info); }
static MagickBooleanType LoadCoderList(const char *xml,const char *filename, const unsigned long depth,ExceptionInfo *exception) { char keyword[MaxTextExtent], *token; const char *q; CoderInfo *coder_info; MagickBooleanType status; /* Load the coder map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading coder configuration 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; coder_info=(CoderInfo *) 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,"IncludeNodeNestedTooDeeply","`%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=LoadCoderList(xml,path,depth+1,exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<coder") == 0) { /* Coder element. */ coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); if (coder_info == (CoderInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); coder_info->path=ConstantString(filename); coder_info->signature=MagickSignature; continue; } if (coder_info == (CoderInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AddValueToSplayTree(coder_list,ConstantString( coder_info->magick),coder_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", coder_info->magick); coder_info=(CoderInfo *) NULL; } GetMagickToken(q,(const 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(token); break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { coder_info->name=ConstantString(token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { coder_info->stealth=IsMagickTrue(token); break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status); }
static SplayTreeInfo *AcquireCoderCache(const char *filename, ExceptionInfo *exception) { const StringInfo *option; LinkedListInfo *options; MagickStatusType status; register ssize_t i; SplayTreeInfo *coder_cache; /* Load external coder map. */ coder_cache=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, DestroyCoderNode); if (coder_cache == (SplayTreeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); status=MagickTrue; options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { status&=LoadCoderCache(coder_cache,(const char *) GetStringInfoDatum(option),GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); /* Load built-in coder map. */ for (i=0; i < (ssize_t) (sizeof(CoderMap)/sizeof(*CoderMap)); i++) { CoderInfo *coder_info; register const CoderMapInfo *p; p=CoderMap+i; coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); if (coder_info == (CoderInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name); continue; } (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); coder_info->path=(char *) "[built-in]"; coder_info->magick=(char *) p->magick; coder_info->name=(char *) p->name; coder_info->exempt=MagickTrue; coder_info->signature=MagickCoreSignature; status&=AddValueToSplayTree(coder_cache,ConstantString(coder_info->magick), coder_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",coder_info->name); } return(coder_cache); }
static LinkedListInfo *AcquireMagicCache(const char *filename, ExceptionInfo *exception) { char path[MagickPathExtent]; const StringInfo *option; LinkedListInfo *magic_cache, *options; MagickStatusType status; register ssize_t i; /* Load external magic map. */ magic_cache=NewLinkedList(0); if (magic_cache == (LinkedListInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); status=MagickTrue; *path='\0'; options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { (void) CopyMagickString(path,GetStringInfoPath(option),MagickPathExtent); status&=LoadMagicCache(magic_cache,(const char *) GetStringInfoDatum(option),GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); /* Load built-in magic map. */ for (i=0; i < (ssize_t) (sizeof(MagicMap)/sizeof(*MagicMap)); i++) { MagicInfo *magic_info; register const MagicMapInfo *p; p=MagicMap+i; magic_info=(MagicInfo *) AcquireMagickMemory(sizeof(*magic_info)); if (magic_info == (MagicInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name); continue; } (void) ResetMagickMemory(magic_info,0,sizeof(*magic_info)); magic_info->path=(char *) "[built-in]"; magic_info->name=(char *) p->name; magic_info->offset=p->offset; magic_info->target=(char *) p->magic; magic_info->magic=(unsigned char *) p->magic; magic_info->length=p->length; magic_info->exempt=MagickTrue; magic_info->signature=MagickCoreSignature; status&=InsertValueInSortedLinkedList(magic_cache,CompareMagickInfoSize, NULL,magic_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",magic_info->name); } return(magic_cache); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + 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 *mime_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 *mime_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], *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); xml=FileToXML(path,~0UL); if (xml != (char *) NULL) { status&=LoadMimeCache(mime_cache,xml,path,depth+1,exception); xml=DestroyString(xml); } } } include=GetNextXMLTreeTag(include); } mime=GetXMLTreeChild(mime_map,"mime"); while (mime != (XMLTreeInfo *) NULL) { const char *attribute; /* Process mime element. */ mime_info=(MimeInfo *) AcquireMagickMemory(sizeof(*mime_info)); if (mime_info == (MimeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(mime_info,0,sizeof(*mime_info)); mime_info->path=ConstantString(filename); mime_info->signature=MagickSignature; 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(mime_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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d M a g i c C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % 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[MagickPathExtent], *token; const char *q; MagicInfo *magic_info; MagickStatusType status; size_t extent; /* 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); extent=strlen(token)+MagickPathExtent; for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetNextToken(q,&q,extent,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MagickPathExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetNextToken(q,&q,extent,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetNextToken(q,&q,extent,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MagickPathExtent); GetNextToken(q,&q,extent,token); if (*token != '=') continue; GetNextToken(q,&q,extent,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"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 (xml != (char *) NULL) { status&=LoadMagicCache(magic_cache,file_xml,path,depth+1, exception); file_xml=DestroyString(file_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=MagickCoreSignature; continue; } if (magic_info == (MagicInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=InsertValueInSortedLinkedList(magic_cache,CompareMagickInfoSize, NULL,magic_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", magic_info->name); magic_info=(MagicInfo *) 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 '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=IsStringTrue(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); }
static MagickBooleanType LoadTypeCache(SplayTreeInfo *type_cache, const char *xml,const char *filename,const size_t depth, ExceptionInfo *exception) { char font_path[MagickPathExtent], keyword[MagickPathExtent], *token; const char *q; MagickStatusType 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); 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,MagickPathExtent-2)) (void) ConcatenateMagickString(font_path,DirectorySeparator,MagickPathExtent); #endif for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MagickPathExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) 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,MagickPathExtent); 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[MagickPathExtent], *xml; ExceptionInfo *sans_exception; *path='\0'; 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); sans_exception=AcquireExceptionInfo(); xml=FileToString(path,~0UL,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (xml != (char *) NULL) { status&=LoadTypeCache(type_cache,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=MagickCoreSignature; continue; } if (type_info == (TypeInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AddValueToSplayTree(type_cache,type_info->name,type_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name); type_info=(TypeInfo *) NULL; continue; } 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) { if (SetTypeNodePath(filename,font_path,token,&type_info->glyphs) == MagickFalse) type_info=(TypeInfo *) DestroyTypeNode(type_info); break; } break; } case 'M': case 'm': { if (LocaleCompare((char *) keyword,"metrics") == 0) { if (SetTypeNodePath(filename,font_path,token,&type_info->metrics) == MagickFalse) type_info=(TypeInfo *) DestroyTypeNode(type_info); 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) { ssize_t weight; weight=ParseCommandOption(MagickWeightOptions,MagickFalse,token); if (weight == -1) weight=StringToUnsignedLong(token); type_info->weight=(size_t) weight; break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status != 0 ? MagickTrue : MagickFalse); }
MagickExport MagickBooleanType SetImageRegistry(const RegistryType type, const char *key,const void *value,ExceptionInfo *exception) { MagickBooleanType status; RegistryInfo *registry_info; void *clone_value; if (IsEventLogging() != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); if (value == (const void *) NULL) return(MagickFalse); clone_value=(void *) NULL; switch (type) { case StringRegistryType: default: { const char *string; string=(const char *) value; clone_value=(void *) ConstantString(string); break; } case ImageRegistryType: { const Image *image; image=(const Image *) value; if (image->signature != MagickSignature) { (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, "UnableToSetRegistry","%s",key); return(MagickFalse); } clone_value=(void *) CloneImageList(image,exception); break; } case ImageInfoRegistryType: { const ImageInfo *image_info; image_info=(const ImageInfo *) value; if (image_info->signature != MagickSignature) { (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, "UnableToSetRegistry","%s",key); return(MagickFalse); } clone_value=(void *) CloneImageInfo(image_info); break; } } if (clone_value == (void *) NULL) return(MagickFalse); registry_info=(RegistryInfo *) AcquireMagickMemory(sizeof(*registry_info)); if (registry_info == (RegistryInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(registry_info,0,sizeof(*registry_info)); registry_info->type=type; registry_info->value=clone_value; registry_info->signature=MagickSignature; if (registry == (SplayTreeInfo *) NULL) { if (registry_semaphore == (SemaphoreInfo *) NULL) ActivateSemaphoreInfo(®istry_semaphore); LockSemaphoreInfo(registry_semaphore); if (registry == (SplayTreeInfo *) NULL) registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, DestroyRegistryNode); UnlockSemaphoreInfo(registry_semaphore); } status=AddValueToSplayTree(registry,ConstantString(key),registry_info); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t I m a g e D e p t h % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetImageDepth() returns the depth of a particular image channel. % % The format of the GetImageDepth method is: % % size_t GetImageDepth(const Image *image,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o exception: return any errors or warnings in this structure. % */ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception) { CacheView *image_view; MagickBooleanType status; register ssize_t i; size_t *current_depth, depth, number_threads; ssize_t y; /* Compute image depth. */ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); number_threads=(size_t) GetMagickResourceLimit(ThreadResource); current_depth=(size_t *) AcquireQuantumMemory(number_threads, sizeof(*current_depth)); if (current_depth == (size_t *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); status=MagickTrue; for (i=0; i < (ssize_t) number_threads; i++) current_depth[i]=1; if ((image->storage_class == PseudoClass) && (image->alpha_trait != BlendPixelTrait)) { #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(status) \ if ((image->colors) > 256) \ num_threads(GetMagickResourceLimit(ThreadResource)) #endif for (i=0; i < (ssize_t) image->colors; i++) { const int id = GetOpenMPThreadId(); while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH) { MagickBooleanType atDepth; QuantumAny range; atDepth=MagickTrue; range=GetQuantumRange(current_depth[id]); if ((atDepth != MagickFalse) && (GetPixelRedTraits(image) & UpdatePixelTrait) != 0) if (IsPixelAtDepth(image->colormap[i].red,range) == MagickFalse) atDepth=MagickFalse; if ((atDepth != MagickFalse) && (GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) if (IsPixelAtDepth(image->colormap[i].green,range) == MagickFalse) atDepth=MagickFalse; if ((atDepth != MagickFalse) && (GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) if (IsPixelAtDepth(image->colormap[i].blue,range) == MagickFalse) atDepth=MagickFalse; if ((atDepth != MagickFalse)) break; current_depth[id]++; } } depth=current_depth[0]; for (i=1; i < (ssize_t) number_threads; i++) if (depth < current_depth[i]) depth=current_depth[i]; current_depth=(size_t *) RelinquishMagickMemory(current_depth); return(depth); } image_view=AcquireVirtualCacheView(image,exception); #if !defined(MAGICKCORE_HDRI_SUPPORT) if (QuantumRange <= MaxMap) { size_t *depth_map; /* Scale pixels to desired (optimized with depth map). */ depth_map=(size_t *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map)); if (depth_map == (size_t *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); for (i=0; i <= (ssize_t) MaxMap; i++) { unsigned int depth; for (depth=1; depth < MAGICKCORE_QUANTUM_DEPTH; depth++) { Quantum pixel; QuantumAny range; range=GetQuantumRange(depth); pixel=(Quantum) i; if (pixel == ScaleAnyToQuantum(ScaleQuantumToAny(pixel,range),range)) break; } depth_map[i]=depth; } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(status) \ magick_threads(image,image,image->rows,1) #endif for (y=0; y < (ssize_t) image->rows; y++) { const int id = GetOpenMPThreadId(); register const Quantum *restrict p; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) continue; for (x=0; x < (ssize_t) image->columns; x++) { if (GetPixelReadMask(image,p) == 0) { p+=GetPixelChannels(image); continue; } for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel=GetPixelChannelChannel(image,i); PixelTrait traits=GetPixelChannelTraits(image,channel); if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) || (channel == ReadMaskPixelChannel) || (channel == MetaPixelChannel)) continue; if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id]) current_depth[id]=depth_map[ScaleQuantumToMap(p[i])]; } p+=GetPixelChannels(image); } if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH) status=MagickFalse; } image_view=DestroyCacheView(image_view); depth=current_depth[0]; for (i=1; i < (ssize_t) number_threads; i++) if (depth < current_depth[i]) depth=current_depth[i]; depth_map=(size_t *) RelinquishMagickMemory(depth_map); current_depth=(size_t *) RelinquishMagickMemory(current_depth); return(depth); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A c q u i r e P o l i c y C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquirePolicyCache() caches one or more policy configurations which provides % a mapping between policy attributes and a policy name. % % The format of the AcquirePolicyCache method is: % % LinkedListInfo *AcquirePolicyCache(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the font file name. % % o exception: return any errors or warnings in this structure. % */ static LinkedListInfo *AcquirePolicyCache(const char *filename, ExceptionInfo *exception) { const StringInfo *option; LinkedListInfo *options, *policy_cache; MagickStatusType status; register ssize_t i; /* Load external policy map. */ policy_cache=NewLinkedList(0); if (policy_cache == (LinkedListInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); status=MagickTrue; options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { status&=LoadPolicyCache(policy_cache,(const char *) GetStringInfoDatum(option),GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); /* Load built-in policy map. */ for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++) { PolicyInfo *policy_info; register const PolicyMapInfo *p; p=PolicyMap+i; policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info)); if (policy_info == (PolicyInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name); continue; } (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info)); policy_info->path=(char *) "[built-in]"; policy_info->domain=p->domain; policy_info->rights=p->rights; policy_info->name=(char *) p->name; policy_info->pattern=(char *) p->pattern; policy_info->value=(char *) p->value; policy_info->exempt=MagickTrue; policy_info->signature=MagickCoreSignature; status&=AppendValueToLinkedList(policy_cache,policy_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name); } return(policy_cache); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d C o n f i g u r e L i s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadConfigureCache() loads the configure configurations which provides a % mapping between configure attributes and a configure name. % % The format of the LoadConfigureCache method is: % % MagickBooleanType LoadConfigureCache(LinkedListInfo *configure_cache, % const char *xml,const char *filename,const size_t depth, % ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The configure list in XML format. % % o filename: The configure list filename. % % o depth: depth of <include /> statements. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadConfigureCache(LinkedListInfo *configure_cache, const char *xml,const char *filename,const size_t depth, ExceptionInfo *exception) { char keyword[MaxTextExtent], *token; ConfigureInfo *configure_info; const char *q; MagickStatusType status; /* Load the configure map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading configure file \"%s\" ...",filename); 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=FileToXML(path,~0UL); if (xml != (char *) NULL) { status&=LoadConfigureCache(configure_cache,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_cache,configure_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", configure_info->name); configure_info=(ConfigureInfo *) NULL; continue; } /* 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 != 0 ? MagickTrue : MagickFalse); }
MagickExport ChannelFeatures *GetImageChannelFeatures(const Image *image, const size_t distance,ExceptionInfo *exception) { typedef struct _ChannelStatistics { DoublePixelPacket direction[4]; /* horizontal, vertical, left and right diagonals */ } ChannelStatistics; CacheView *image_view; ChannelFeatures *channel_features; ChannelStatistics **cooccurrence, correlation, *density_x, *density_xy, *density_y, entropy_x, entropy_xy, entropy_xy1, entropy_xy2, entropy_y, mean, **Q, *sum, sum_squares, variance; LongPixelPacket gray, *grays; MagickBooleanType status; register ssize_t i; size_t length; ssize_t y, z; unsigned int number_grays; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); if ((image->columns < (distance+1)) || (image->rows < (distance+1))) return((ChannelFeatures *) NULL); length=CompositeChannels+1UL; channel_features=(ChannelFeatures *) AcquireQuantumMemory(length, sizeof(*channel_features)); if (channel_features == (ChannelFeatures *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(channel_features,0,length* sizeof(*channel_features)); /* Form grays. */ grays=(LongPixelPacket *) AcquireQuantumMemory(MaxMap+1UL,sizeof(*grays)); if (grays == (LongPixelPacket *) NULL) { channel_features=(ChannelFeatures *) RelinquishMagickMemory( channel_features); (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(channel_features); } for (i=0; i <= (ssize_t) MaxMap; i++) { grays[i].red=(~0U); grays[i].green=(~0U); grays[i].blue=(~0U); grays[i].opacity=(~0U); grays[i].index=(~0U); } status=MagickTrue; image_view=AcquireCacheView(image); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (y=0; y < (ssize_t) image->rows; y++) { register const IndexPacket *restrict indexes; register const PixelPacket *restrict p; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); if (p == (const PixelPacket *) NULL) { status=MagickFalse; continue; } indexes=GetCacheViewVirtualIndexQueue(image_view); for (x=0; x < (ssize_t) image->columns; x++) { grays[ScaleQuantumToMap(GetPixelRed(p))].red= ScaleQuantumToMap(GetPixelRed(p)); grays[ScaleQuantumToMap(GetPixelGreen(p))].green= ScaleQuantumToMap(GetPixelGreen(p)); grays[ScaleQuantumToMap(GetPixelBlue(p))].blue= ScaleQuantumToMap(GetPixelBlue(p)); if (image->colorspace == CMYKColorspace) grays[ScaleQuantumToMap(GetPixelIndex(indexes+x))].index= ScaleQuantumToMap(GetPixelIndex(indexes+x)); if (image->matte != MagickFalse) grays[ScaleQuantumToMap(GetPixelOpacity(p))].opacity= ScaleQuantumToMap(GetPixelOpacity(p)); p++; } } image_view=DestroyCacheView(image_view); if (status == MagickFalse) { grays=(LongPixelPacket *) RelinquishMagickMemory(grays); channel_features=(ChannelFeatures *) RelinquishMagickMemory( channel_features); return(channel_features); } (void) ResetMagickMemory(&gray,0,sizeof(gray)); for (i=0; i <= (ssize_t) MaxMap; i++) { if (grays[i].red != ~0U) grays[(ssize_t) gray.red++].red=grays[i].red; if (grays[i].green != ~0U) grays[(ssize_t) gray.green++].green=grays[i].green; if (grays[i].blue != ~0U) grays[(ssize_t) gray.blue++].blue=grays[i].blue; if (image->colorspace == CMYKColorspace) if (grays[i].index != ~0U) grays[(ssize_t) gray.index++].index=grays[i].index; if (image->matte != MagickFalse) if (grays[i].opacity != ~0U) grays[(ssize_t) gray.opacity++].opacity=grays[i].opacity; } /* Allocate spatial dependence matrix. */ number_grays=gray.red; if (gray.green > number_grays) number_grays=gray.green; if (gray.blue > number_grays) number_grays=gray.blue; if (image->colorspace == CMYKColorspace) if (gray.index > number_grays) number_grays=gray.index; if (image->matte != MagickFalse) if (gray.opacity > number_grays) number_grays=gray.opacity; cooccurrence=(ChannelStatistics **) AcquireQuantumMemory(number_grays, sizeof(*cooccurrence)); density_x=(ChannelStatistics *) AcquireQuantumMemory(2*(number_grays+1), sizeof(*density_x)); density_xy=(ChannelStatistics *) AcquireQuantumMemory(2*(number_grays+1), sizeof(*density_xy)); density_y=(ChannelStatistics *) AcquireQuantumMemory(2*(number_grays+1), sizeof(*density_y)); Q=(ChannelStatistics **) AcquireQuantumMemory(number_grays,sizeof(*Q)); sum=(ChannelStatistics *) AcquireQuantumMemory(number_grays,sizeof(*sum)); if ((cooccurrence == (ChannelStatistics **) NULL) || (density_x == (ChannelStatistics *) NULL) || (density_xy == (ChannelStatistics *) NULL) || (density_y == (ChannelStatistics *) NULL) || (Q == (ChannelStatistics **) NULL) || (sum == (ChannelStatistics *) NULL)) { if (Q != (ChannelStatistics **) NULL) { for (i=0; i < (ssize_t) number_grays; i++) Q[i]=(ChannelStatistics *) RelinquishMagickMemory(Q[i]); Q=(ChannelStatistics **) RelinquishMagickMemory(Q); } if (sum != (ChannelStatistics *) NULL) sum=(ChannelStatistics *) RelinquishMagickMemory(sum); if (density_y != (ChannelStatistics *) NULL) density_y=(ChannelStatistics *) RelinquishMagickMemory(density_y); if (density_xy != (ChannelStatistics *) NULL) density_xy=(ChannelStatistics *) RelinquishMagickMemory(density_xy); if (density_x != (ChannelStatistics *) NULL) density_x=(ChannelStatistics *) RelinquishMagickMemory(density_x); if (cooccurrence != (ChannelStatistics **) NULL) { for (i=0; i < (ssize_t) number_grays; i++) cooccurrence[i]=(ChannelStatistics *) RelinquishMagickMemory(cooccurrence[i]); cooccurrence=(ChannelStatistics **) RelinquishMagickMemory( cooccurrence); } grays=(LongPixelPacket *) RelinquishMagickMemory(grays); channel_features=(ChannelFeatures *) RelinquishMagickMemory( channel_features); (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(channel_features); } (void) ResetMagickMemory(&correlation,0,sizeof(correlation)); (void) ResetMagickMemory(density_x,0,2*(number_grays+1)*sizeof(*density_x)); (void) ResetMagickMemory(density_xy,0,2*(number_grays+1)*sizeof(*density_xy)); (void) ResetMagickMemory(density_y,0,2*(number_grays+1)*sizeof(*density_y)); (void) ResetMagickMemory(&mean,0,sizeof(mean)); (void) ResetMagickMemory(sum,0,number_grays*sizeof(*sum)); (void) ResetMagickMemory(&sum_squares,0,sizeof(sum_squares)); (void) ResetMagickMemory(density_xy,0,2*number_grays*sizeof(*density_xy)); (void) ResetMagickMemory(&entropy_x,0,sizeof(entropy_x)); (void) ResetMagickMemory(&entropy_xy,0,sizeof(entropy_xy)); (void) ResetMagickMemory(&entropy_xy1,0,sizeof(entropy_xy1)); (void) ResetMagickMemory(&entropy_xy2,0,sizeof(entropy_xy2)); (void) ResetMagickMemory(&entropy_y,0,sizeof(entropy_y)); (void) ResetMagickMemory(&variance,0,sizeof(variance)); for (i=0; i < (ssize_t) number_grays; i++) { cooccurrence[i]=(ChannelStatistics *) AcquireQuantumMemory(number_grays, sizeof(**cooccurrence)); Q[i]=(ChannelStatistics *) AcquireQuantumMemory(number_grays,sizeof(**Q)); if ((cooccurrence[i] == (ChannelStatistics *) NULL) || (Q[i] == (ChannelStatistics *) NULL)) break; (void) ResetMagickMemory(cooccurrence[i],0,number_grays* sizeof(**cooccurrence)); (void) ResetMagickMemory(Q[i],0,number_grays*sizeof(**Q)); } if (i < (ssize_t) number_grays) { for (i--; i >= 0; i--) { if (Q[i] != (ChannelStatistics *) NULL) Q[i]=(ChannelStatistics *) RelinquishMagickMemory(Q[i]); if (cooccurrence[i] != (ChannelStatistics *) NULL) cooccurrence[i]=(ChannelStatistics *) RelinquishMagickMemory(cooccurrence[i]); } Q=(ChannelStatistics **) RelinquishMagickMemory(Q); cooccurrence=(ChannelStatistics **) RelinquishMagickMemory(cooccurrence); sum=(ChannelStatistics *) RelinquishMagickMemory(sum); density_y=(ChannelStatistics *) RelinquishMagickMemory(density_y); density_xy=(ChannelStatistics *) RelinquishMagickMemory(density_xy); density_x=(ChannelStatistics *) RelinquishMagickMemory(density_x); grays=(LongPixelPacket *) RelinquishMagickMemory(grays); channel_features=(ChannelFeatures *) RelinquishMagickMemory( channel_features); (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(channel_features); } /* Initialize spatial dependence matrix. */ status=MagickTrue; image_view=AcquireCacheView(image); for (y=0; y < (ssize_t) image->rows; y++) { register const IndexPacket *restrict indexes; register const PixelPacket *restrict p; register ssize_t x; ssize_t i, offset, u, v; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,-(ssize_t) distance,y,image->columns+ 2*distance,distance+2,exception); if (p == (const PixelPacket *) NULL) { status=MagickFalse; continue; } indexes=GetCacheViewVirtualIndexQueue(image_view); p+=distance; indexes+=distance; for (x=0; x < (ssize_t) image->columns; x++) { for (i=0; i < 4; i++) { switch (i) { case 0: default: { /* Horizontal adjacency. */ offset=(ssize_t) distance; break; } case 1: { /* Vertical adjacency. */ offset=(ssize_t) (image->columns+2*distance); break; } case 2: { /* Right diagonal adjacency. */ offset=(ssize_t) ((image->columns+2*distance)-distance); break; } case 3: { /* Left diagonal adjacency. */ offset=(ssize_t) ((image->columns+2*distance)+distance); break; } } u=0; v=0; while (grays[u].red != ScaleQuantumToMap(GetPixelRed(p))) u++; while (grays[v].red != ScaleQuantumToMap(GetPixelRed(p+offset))) v++; cooccurrence[u][v].direction[i].red++; cooccurrence[v][u].direction[i].red++; u=0; v=0; while (grays[u].green != ScaleQuantumToMap(GetPixelGreen(p))) u++; while (grays[v].green != ScaleQuantumToMap(GetPixelGreen(p+offset))) v++; cooccurrence[u][v].direction[i].green++; cooccurrence[v][u].direction[i].green++; u=0; v=0; while (grays[u].blue != ScaleQuantumToMap(GetPixelBlue(p))) u++; while (grays[v].blue != ScaleQuantumToMap((p+offset)->blue)) v++; cooccurrence[u][v].direction[i].blue++; cooccurrence[v][u].direction[i].blue++; if (image->colorspace == CMYKColorspace) { u=0; v=0; while (grays[u].index != ScaleQuantumToMap(GetPixelIndex(indexes+x))) u++; while (grays[v].index != ScaleQuantumToMap(GetPixelIndex(indexes+x+offset))) v++; cooccurrence[u][v].direction[i].index++; cooccurrence[v][u].direction[i].index++; } if (image->matte != MagickFalse) { u=0; v=0; while (grays[u].opacity != ScaleQuantumToMap(GetPixelOpacity(p))) u++; while (grays[v].opacity != ScaleQuantumToMap((p+offset)->opacity)) v++; cooccurrence[u][v].direction[i].opacity++; cooccurrence[v][u].direction[i].opacity++; } } p++; } } grays=(LongPixelPacket *) RelinquishMagickMemory(grays); image_view=DestroyCacheView(image_view); if (status == MagickFalse) { for (i=0; i < (ssize_t) number_grays; i++) cooccurrence[i]=(ChannelStatistics *) RelinquishMagickMemory(cooccurrence[i]); cooccurrence=(ChannelStatistics **) RelinquishMagickMemory(cooccurrence); channel_features=(ChannelFeatures *) RelinquishMagickMemory( channel_features); (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(channel_features); } /* Normalize spatial dependence matrix. */ for (i=0; i < 4; i++) { double normalize; register ssize_t y; switch (i) { case 0: default: { /* Horizontal adjacency. */ normalize=2.0*image->rows*(image->columns-distance); break; } case 1: { /* Vertical adjacency. */ normalize=2.0*(image->rows-distance)*image->columns; break; } case 2: { /* Right diagonal adjacency. */ normalize=2.0*(image->rows-distance)*(image->columns-distance); break; } case 3: { /* Left diagonal adjacency. */ normalize=2.0*(image->rows-distance)*(image->columns-distance); break; } } normalize=1.0/(fabs((double) normalize) <= MagickEpsilon ? 1.0 : normalize); for (y=0; y < (ssize_t) number_grays; y++) { register ssize_t x; for (x=0; x < (ssize_t) number_grays; x++) { cooccurrence[x][y].direction[i].red*=normalize; cooccurrence[x][y].direction[i].green*=normalize; cooccurrence[x][y].direction[i].blue*=normalize; if (image->colorspace == CMYKColorspace) cooccurrence[x][y].direction[i].index*=normalize; if (image->matte != MagickFalse) cooccurrence[x][y].direction[i].opacity*=normalize; } } } /* Compute texture features. */ #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (i=0; i < 4; i++) { register ssize_t y; for (y=0; y < (ssize_t) number_grays; y++) { register ssize_t x; for (x=0; x < (ssize_t) number_grays; x++) { /* Angular second moment: measure of homogeneity of the image. */ channel_features[RedChannel].angular_second_moment[i]+= cooccurrence[x][y].direction[i].red* cooccurrence[x][y].direction[i].red; channel_features[GreenChannel].angular_second_moment[i]+= cooccurrence[x][y].direction[i].green* cooccurrence[x][y].direction[i].green; channel_features[BlueChannel].angular_second_moment[i]+= cooccurrence[x][y].direction[i].blue* cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) channel_features[BlackChannel].angular_second_moment[i]+= cooccurrence[x][y].direction[i].index* cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) channel_features[OpacityChannel].angular_second_moment[i]+= cooccurrence[x][y].direction[i].opacity* cooccurrence[x][y].direction[i].opacity; /* Correlation: measure of linear-dependencies in the image. */ sum[y].direction[i].red+=cooccurrence[x][y].direction[i].red; sum[y].direction[i].green+=cooccurrence[x][y].direction[i].green; sum[y].direction[i].blue+=cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) sum[y].direction[i].index+=cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) sum[y].direction[i].opacity+=cooccurrence[x][y].direction[i].opacity; correlation.direction[i].red+=x*y*cooccurrence[x][y].direction[i].red; correlation.direction[i].green+=x*y* cooccurrence[x][y].direction[i].green; correlation.direction[i].blue+=x*y* cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) correlation.direction[i].index+=x*y* cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) correlation.direction[i].opacity+=x*y* cooccurrence[x][y].direction[i].opacity; /* Inverse Difference Moment. */ channel_features[RedChannel].inverse_difference_moment[i]+= cooccurrence[x][y].direction[i].red/((y-x)*(y-x)+1); channel_features[GreenChannel].inverse_difference_moment[i]+= cooccurrence[x][y].direction[i].green/((y-x)*(y-x)+1); channel_features[BlueChannel].inverse_difference_moment[i]+= cooccurrence[x][y].direction[i].blue/((y-x)*(y-x)+1); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].inverse_difference_moment[i]+= cooccurrence[x][y].direction[i].index/((y-x)*(y-x)+1); if (image->matte != MagickFalse) channel_features[OpacityChannel].inverse_difference_moment[i]+= cooccurrence[x][y].direction[i].opacity/((y-x)*(y-x)+1); /* Sum average. */ density_xy[y+x+2].direction[i].red+= cooccurrence[x][y].direction[i].red; density_xy[y+x+2].direction[i].green+= cooccurrence[x][y].direction[i].green; density_xy[y+x+2].direction[i].blue+= cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) density_xy[y+x+2].direction[i].index+= cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) density_xy[y+x+2].direction[i].opacity+= cooccurrence[x][y].direction[i].opacity; /* Entropy. */ channel_features[RedChannel].entropy[i]-= cooccurrence[x][y].direction[i].red* log10(cooccurrence[x][y].direction[i].red+MagickEpsilon); channel_features[GreenChannel].entropy[i]-= cooccurrence[x][y].direction[i].green* log10(cooccurrence[x][y].direction[i].green+MagickEpsilon); channel_features[BlueChannel].entropy[i]-= cooccurrence[x][y].direction[i].blue* log10(cooccurrence[x][y].direction[i].blue+MagickEpsilon); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].entropy[i]-= cooccurrence[x][y].direction[i].index* log10(cooccurrence[x][y].direction[i].index+MagickEpsilon); if (image->matte != MagickFalse) channel_features[OpacityChannel].entropy[i]-= cooccurrence[x][y].direction[i].opacity* log10(cooccurrence[x][y].direction[i].opacity+MagickEpsilon); /* Information Measures of Correlation. */ density_x[x].direction[i].red+=cooccurrence[x][y].direction[i].red; density_x[x].direction[i].green+=cooccurrence[x][y].direction[i].green; density_x[x].direction[i].blue+=cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) density_x[x].direction[i].index+= cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) density_x[x].direction[i].opacity+= cooccurrence[x][y].direction[i].opacity; density_y[y].direction[i].red+=cooccurrence[x][y].direction[i].red; density_y[y].direction[i].green+=cooccurrence[x][y].direction[i].green; density_y[y].direction[i].blue+=cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) density_y[y].direction[i].index+= cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) density_y[y].direction[i].opacity+= cooccurrence[x][y].direction[i].opacity; } mean.direction[i].red+=y*sum[y].direction[i].red; sum_squares.direction[i].red+=y*y*sum[y].direction[i].red; mean.direction[i].green+=y*sum[y].direction[i].green; sum_squares.direction[i].green+=y*y*sum[y].direction[i].green; mean.direction[i].blue+=y*sum[y].direction[i].blue; sum_squares.direction[i].blue+=y*y*sum[y].direction[i].blue; if (image->colorspace == CMYKColorspace) { mean.direction[i].index+=y*sum[y].direction[i].index; sum_squares.direction[i].index+=y*y*sum[y].direction[i].index; } if (image->matte != MagickFalse) { mean.direction[i].opacity+=y*sum[y].direction[i].opacity; sum_squares.direction[i].opacity+=y*y*sum[y].direction[i].opacity; } } /* Correlation: measure of linear-dependencies in the image. */ channel_features[RedChannel].correlation[i]= (correlation.direction[i].red-mean.direction[i].red* mean.direction[i].red)/(sqrt(sum_squares.direction[i].red- (mean.direction[i].red*mean.direction[i].red))*sqrt( sum_squares.direction[i].red-(mean.direction[i].red* mean.direction[i].red))); channel_features[GreenChannel].correlation[i]= (correlation.direction[i].green-mean.direction[i].green* mean.direction[i].green)/(sqrt(sum_squares.direction[i].green- (mean.direction[i].green*mean.direction[i].green))*sqrt( sum_squares.direction[i].green-(mean.direction[i].green* mean.direction[i].green))); channel_features[BlueChannel].correlation[i]= (correlation.direction[i].blue-mean.direction[i].blue* mean.direction[i].blue)/(sqrt(sum_squares.direction[i].blue- (mean.direction[i].blue*mean.direction[i].blue))*sqrt( sum_squares.direction[i].blue-(mean.direction[i].blue* mean.direction[i].blue))); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].correlation[i]= (correlation.direction[i].index-mean.direction[i].index* mean.direction[i].index)/(sqrt(sum_squares.direction[i].index- (mean.direction[i].index*mean.direction[i].index))*sqrt( sum_squares.direction[i].index-(mean.direction[i].index* mean.direction[i].index))); if (image->matte != MagickFalse) channel_features[OpacityChannel].correlation[i]= (correlation.direction[i].opacity-mean.direction[i].opacity* mean.direction[i].opacity)/(sqrt(sum_squares.direction[i].opacity- (mean.direction[i].opacity*mean.direction[i].opacity))*sqrt( sum_squares.direction[i].opacity-(mean.direction[i].opacity* mean.direction[i].opacity))); } /* Compute more texture features. */ #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (i=0; i < 4; i++) { register ssize_t x; for (x=2; x < (ssize_t) (2*number_grays); x++) { /* Sum average. */ channel_features[RedChannel].sum_average[i]+= x*density_xy[x].direction[i].red; channel_features[GreenChannel].sum_average[i]+= x*density_xy[x].direction[i].green; channel_features[BlueChannel].sum_average[i]+= x*density_xy[x].direction[i].blue; if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].sum_average[i]+= x*density_xy[x].direction[i].index; if (image->matte != MagickFalse) channel_features[OpacityChannel].sum_average[i]+= x*density_xy[x].direction[i].opacity; /* Sum entropy. */ channel_features[RedChannel].sum_entropy[i]-= density_xy[x].direction[i].red* log10(density_xy[x].direction[i].red+MagickEpsilon); channel_features[GreenChannel].sum_entropy[i]-= density_xy[x].direction[i].green* log10(density_xy[x].direction[i].green+MagickEpsilon); channel_features[BlueChannel].sum_entropy[i]-= density_xy[x].direction[i].blue* log10(density_xy[x].direction[i].blue+MagickEpsilon); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].sum_entropy[i]-= density_xy[x].direction[i].index* log10(density_xy[x].direction[i].index+MagickEpsilon); if (image->matte != MagickFalse) channel_features[OpacityChannel].sum_entropy[i]-= density_xy[x].direction[i].opacity* log10(density_xy[x].direction[i].opacity+MagickEpsilon); /* Sum variance. */ channel_features[RedChannel].sum_variance[i]+= (x-channel_features[RedChannel].sum_entropy[i])* (x-channel_features[RedChannel].sum_entropy[i])* density_xy[x].direction[i].red; channel_features[GreenChannel].sum_variance[i]+= (x-channel_features[GreenChannel].sum_entropy[i])* (x-channel_features[GreenChannel].sum_entropy[i])* density_xy[x].direction[i].green; channel_features[BlueChannel].sum_variance[i]+= (x-channel_features[BlueChannel].sum_entropy[i])* (x-channel_features[BlueChannel].sum_entropy[i])* density_xy[x].direction[i].blue; if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].sum_variance[i]+= (x-channel_features[IndexChannel].sum_entropy[i])* (x-channel_features[IndexChannel].sum_entropy[i])* density_xy[x].direction[i].index; if (image->matte != MagickFalse) channel_features[OpacityChannel].sum_variance[i]+= (x-channel_features[OpacityChannel].sum_entropy[i])* (x-channel_features[OpacityChannel].sum_entropy[i])* density_xy[x].direction[i].opacity; } } /* Compute more texture features. */ #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (i=0; i < 4; i++) { register ssize_t y; for (y=0; y < (ssize_t) number_grays; y++) { register ssize_t x; for (x=0; x < (ssize_t) number_grays; x++) { /* Sum of Squares: Variance */ variance.direction[i].red+=(y-mean.direction[i].red+1)* (y-mean.direction[i].red+1)*cooccurrence[x][y].direction[i].red; variance.direction[i].green+=(y-mean.direction[i].green+1)* (y-mean.direction[i].green+1)*cooccurrence[x][y].direction[i].green; variance.direction[i].blue+=(y-mean.direction[i].blue+1)* (y-mean.direction[i].blue+1)*cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) variance.direction[i].index+=(y-mean.direction[i].index+1)* (y-mean.direction[i].index+1)*cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) variance.direction[i].opacity+=(y-mean.direction[i].opacity+1)* (y-mean.direction[i].opacity+1)* cooccurrence[x][y].direction[i].opacity; /* Sum average / Difference Variance. */ density_xy[MagickAbsoluteValue(y-x)].direction[i].red+= cooccurrence[x][y].direction[i].red; density_xy[MagickAbsoluteValue(y-x)].direction[i].green+= cooccurrence[x][y].direction[i].green; density_xy[MagickAbsoluteValue(y-x)].direction[i].blue+= cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) density_xy[MagickAbsoluteValue(y-x)].direction[i].index+= cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) density_xy[MagickAbsoluteValue(y-x)].direction[i].opacity+= cooccurrence[x][y].direction[i].opacity; /* Information Measures of Correlation. */ entropy_xy.direction[i].red-=cooccurrence[x][y].direction[i].red* log10(cooccurrence[x][y].direction[i].red+MagickEpsilon); entropy_xy.direction[i].green-=cooccurrence[x][y].direction[i].green* log10(cooccurrence[x][y].direction[i].green+MagickEpsilon); entropy_xy.direction[i].blue-=cooccurrence[x][y].direction[i].blue* log10(cooccurrence[x][y].direction[i].blue+MagickEpsilon); if (image->colorspace == CMYKColorspace) entropy_xy.direction[i].index-=cooccurrence[x][y].direction[i].index* log10(cooccurrence[x][y].direction[i].index+MagickEpsilon); if (image->matte != MagickFalse) entropy_xy.direction[i].opacity-= cooccurrence[x][y].direction[i].opacity*log10( cooccurrence[x][y].direction[i].opacity+MagickEpsilon); entropy_xy1.direction[i].red-=(cooccurrence[x][y].direction[i].red* log10(density_x[x].direction[i].red*density_y[y].direction[i].red+ MagickEpsilon)); entropy_xy1.direction[i].green-=(cooccurrence[x][y].direction[i].green* log10(density_x[x].direction[i].green*density_y[y].direction[i].green+ MagickEpsilon)); entropy_xy1.direction[i].blue-=(cooccurrence[x][y].direction[i].blue* log10(density_x[x].direction[i].blue*density_y[y].direction[i].blue+ MagickEpsilon)); if (image->colorspace == CMYKColorspace) entropy_xy1.direction[i].index-=( cooccurrence[x][y].direction[i].index*log10( density_x[x].direction[i].index*density_y[y].direction[i].index+ MagickEpsilon)); if (image->matte != MagickFalse) entropy_xy1.direction[i].opacity-=( cooccurrence[x][y].direction[i].opacity*log10( density_x[x].direction[i].opacity*density_y[y].direction[i].opacity+ MagickEpsilon)); entropy_xy2.direction[i].red-=(density_x[x].direction[i].red* density_y[y].direction[i].red*log10(density_x[x].direction[i].red* density_y[y].direction[i].red+MagickEpsilon)); entropy_xy2.direction[i].green-=(density_x[x].direction[i].green* density_y[y].direction[i].green*log10(density_x[x].direction[i].green* density_y[y].direction[i].green+MagickEpsilon)); entropy_xy2.direction[i].blue-=(density_x[x].direction[i].blue* density_y[y].direction[i].blue*log10(density_x[x].direction[i].blue* density_y[y].direction[i].blue+MagickEpsilon)); if (image->colorspace == CMYKColorspace) entropy_xy2.direction[i].index-=(density_x[x].direction[i].index* density_y[y].direction[i].index*log10( density_x[x].direction[i].index*density_y[y].direction[i].index+ MagickEpsilon)); if (image->matte != MagickFalse) entropy_xy2.direction[i].opacity-=(density_x[x].direction[i].opacity* density_y[y].direction[i].opacity*log10( density_x[x].direction[i].opacity*density_y[y].direction[i].opacity+ MagickEpsilon)); } } channel_features[RedChannel].variance_sum_of_squares[i]= variance.direction[i].red; channel_features[GreenChannel].variance_sum_of_squares[i]= variance.direction[i].green; channel_features[BlueChannel].variance_sum_of_squares[i]= variance.direction[i].blue; if (image->colorspace == CMYKColorspace) channel_features[RedChannel].variance_sum_of_squares[i]= variance.direction[i].index; if (image->matte != MagickFalse) channel_features[RedChannel].variance_sum_of_squares[i]= variance.direction[i].opacity; } /* Compute more texture features. */ (void) ResetMagickMemory(&variance,0,sizeof(variance)); (void) ResetMagickMemory(&sum_squares,0,sizeof(sum_squares)); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (i=0; i < 4; i++) { register ssize_t x; for (x=0; x < (ssize_t) number_grays; x++) { /* Difference variance. */ variance.direction[i].red+=density_xy[x].direction[i].red; variance.direction[i].green+=density_xy[x].direction[i].green; variance.direction[i].blue+=density_xy[x].direction[i].blue; if (image->colorspace == CMYKColorspace) variance.direction[i].index+=density_xy[x].direction[i].index; if (image->matte != MagickFalse) variance.direction[i].opacity+=density_xy[x].direction[i].opacity; sum_squares.direction[i].red+=density_xy[x].direction[i].red* density_xy[x].direction[i].red; sum_squares.direction[i].green+=density_xy[x].direction[i].green* density_xy[x].direction[i].green; sum_squares.direction[i].blue+=density_xy[x].direction[i].blue* density_xy[x].direction[i].blue; if (image->colorspace == CMYKColorspace) sum_squares.direction[i].index+=density_xy[x].direction[i].index* density_xy[x].direction[i].index; if (image->matte != MagickFalse) sum_squares.direction[i].opacity+=density_xy[x].direction[i].opacity* density_xy[x].direction[i].opacity; /* Difference entropy. */ channel_features[RedChannel].difference_entropy[i]-= density_xy[x].direction[i].red* log10(density_xy[x].direction[i].red+MagickEpsilon); channel_features[GreenChannel].difference_entropy[i]-= density_xy[x].direction[i].green* log10(density_xy[x].direction[i].green+MagickEpsilon); channel_features[BlueChannel].difference_entropy[i]-= density_xy[x].direction[i].blue* log10(density_xy[x].direction[i].blue+MagickEpsilon); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].difference_entropy[i]-= density_xy[x].direction[i].index* log10(density_xy[x].direction[i].index+MagickEpsilon); if (image->matte != MagickFalse) channel_features[OpacityChannel].difference_entropy[i]-= density_xy[x].direction[i].opacity* log10(density_xy[x].direction[i].opacity+MagickEpsilon); /* Information Measures of Correlation. */ entropy_x.direction[i].red-=(density_x[x].direction[i].red* log10(density_x[x].direction[i].red+MagickEpsilon)); entropy_x.direction[i].green-=(density_x[x].direction[i].green* log10(density_x[x].direction[i].green+MagickEpsilon)); entropy_x.direction[i].blue-=(density_x[x].direction[i].blue* log10(density_x[x].direction[i].blue+MagickEpsilon)); if (image->colorspace == CMYKColorspace) entropy_x.direction[i].index-=(density_x[x].direction[i].index* log10(density_x[x].direction[i].index+MagickEpsilon)); if (image->matte != MagickFalse) entropy_x.direction[i].opacity-=(density_x[x].direction[i].opacity* log10(density_x[x].direction[i].opacity+MagickEpsilon)); entropy_y.direction[i].red-=(density_y[x].direction[i].red* log10(density_y[x].direction[i].red+MagickEpsilon)); entropy_y.direction[i].green-=(density_y[x].direction[i].green* log10(density_y[x].direction[i].green+MagickEpsilon)); entropy_y.direction[i].blue-=(density_y[x].direction[i].blue* log10(density_y[x].direction[i].blue+MagickEpsilon)); if (image->colorspace == CMYKColorspace) entropy_y.direction[i].index-=(density_y[x].direction[i].index* log10(density_y[x].direction[i].index+MagickEpsilon)); if (image->matte != MagickFalse) entropy_y.direction[i].opacity-=(density_y[x].direction[i].opacity* log10(density_y[x].direction[i].opacity+MagickEpsilon)); } /* Difference variance. */ channel_features[RedChannel].difference_variance[i]= (((double) number_grays*number_grays*sum_squares.direction[i].red)- (variance.direction[i].red*variance.direction[i].red))/ ((double) number_grays*number_grays*number_grays*number_grays); channel_features[GreenChannel].difference_variance[i]= (((double) number_grays*number_grays*sum_squares.direction[i].green)- (variance.direction[i].green*variance.direction[i].green))/ ((double) number_grays*number_grays*number_grays*number_grays); channel_features[BlueChannel].difference_variance[i]= (((double) number_grays*number_grays*sum_squares.direction[i].blue)- (variance.direction[i].blue*variance.direction[i].blue))/ ((double) number_grays*number_grays*number_grays*number_grays); if (image->matte != MagickFalse) channel_features[OpacityChannel].difference_variance[i]= (((double) number_grays*number_grays*sum_squares.direction[i].opacity)- (variance.direction[i].opacity*variance.direction[i].opacity))/ ((double) number_grays*number_grays*number_grays*number_grays); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].difference_variance[i]= (((double) number_grays*number_grays*sum_squares.direction[i].index)- (variance.direction[i].index*variance.direction[i].index))/ ((double) number_grays*number_grays*number_grays*number_grays); /* Information Measures of Correlation. */ channel_features[RedChannel].measure_of_correlation_1[i]= (entropy_xy.direction[i].red-entropy_xy1.direction[i].red)/ (entropy_x.direction[i].red > entropy_y.direction[i].red ? entropy_x.direction[i].red : entropy_y.direction[i].red); channel_features[GreenChannel].measure_of_correlation_1[i]= (entropy_xy.direction[i].green-entropy_xy1.direction[i].green)/ (entropy_x.direction[i].green > entropy_y.direction[i].green ? entropy_x.direction[i].green : entropy_y.direction[i].green); channel_features[BlueChannel].measure_of_correlation_1[i]= (entropy_xy.direction[i].blue-entropy_xy1.direction[i].blue)/ (entropy_x.direction[i].blue > entropy_y.direction[i].blue ? entropy_x.direction[i].blue : entropy_y.direction[i].blue); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].measure_of_correlation_1[i]= (entropy_xy.direction[i].index-entropy_xy1.direction[i].index)/ (entropy_x.direction[i].index > entropy_y.direction[i].index ? entropy_x.direction[i].index : entropy_y.direction[i].index); if (image->matte != MagickFalse) channel_features[OpacityChannel].measure_of_correlation_1[i]= (entropy_xy.direction[i].opacity-entropy_xy1.direction[i].opacity)/ (entropy_x.direction[i].opacity > entropy_y.direction[i].opacity ? entropy_x.direction[i].opacity : entropy_y.direction[i].opacity); channel_features[RedChannel].measure_of_correlation_2[i]= (sqrt(fabs(1.0-exp(-2.0*(entropy_xy2.direction[i].red- entropy_xy.direction[i].red))))); channel_features[GreenChannel].measure_of_correlation_2[i]= (sqrt(fabs(1.0-exp(-2.0*(entropy_xy2.direction[i].green- entropy_xy.direction[i].green))))); channel_features[BlueChannel].measure_of_correlation_2[i]= (sqrt(fabs(1.0-exp(-2.0*(entropy_xy2.direction[i].blue- entropy_xy.direction[i].blue))))); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].measure_of_correlation_2[i]= (sqrt(fabs(1.0-exp(-2.0*(entropy_xy2.direction[i].index- entropy_xy.direction[i].index))))); if (image->matte != MagickFalse) channel_features[OpacityChannel].measure_of_correlation_2[i]= (sqrt(fabs(1.0-exp(-2.0*(entropy_xy2.direction[i].opacity- entropy_xy.direction[i].opacity))))); } /* Compute more texture features. */ #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (i=0; i < 4; i++) { for (z=0; z < (ssize_t) number_grays; z++) { register ssize_t y; ChannelStatistics pixel; (void) ResetMagickMemory(&pixel,0,sizeof(pixel)); for (y=0; y < (ssize_t) number_grays; y++) { register ssize_t x; for (x=0; x < (ssize_t) number_grays; x++) { /* Contrast: amount of local variations present in an image. */ if (((y-x) == z) || ((x-y) == z)) { pixel.direction[i].red+=cooccurrence[x][y].direction[i].red; pixel.direction[i].green+=cooccurrence[x][y].direction[i].green; pixel.direction[i].blue+=cooccurrence[x][y].direction[i].blue; if (image->colorspace == CMYKColorspace) pixel.direction[i].index+=cooccurrence[x][y].direction[i].index; if (image->matte != MagickFalse) pixel.direction[i].opacity+= cooccurrence[x][y].direction[i].opacity; } /* Maximum Correlation Coefficient. */ Q[z][y].direction[i].red+=cooccurrence[z][x].direction[i].red* cooccurrence[y][x].direction[i].red/density_x[z].direction[i].red/ density_y[x].direction[i].red; Q[z][y].direction[i].green+=cooccurrence[z][x].direction[i].green* cooccurrence[y][x].direction[i].green/ density_x[z].direction[i].green/density_y[x].direction[i].red; Q[z][y].direction[i].blue+=cooccurrence[z][x].direction[i].blue* cooccurrence[y][x].direction[i].blue/density_x[z].direction[i].blue/ density_y[x].direction[i].blue; if (image->colorspace == CMYKColorspace) Q[z][y].direction[i].index+=cooccurrence[z][x].direction[i].index* cooccurrence[y][x].direction[i].index/ density_x[z].direction[i].index/density_y[x].direction[i].index; if (image->matte != MagickFalse) Q[z][y].direction[i].opacity+= cooccurrence[z][x].direction[i].opacity* cooccurrence[y][x].direction[i].opacity/ density_x[z].direction[i].opacity/ density_y[x].direction[i].opacity; } } channel_features[RedChannel].contrast[i]+=z*z*pixel.direction[i].red; channel_features[GreenChannel].contrast[i]+=z*z*pixel.direction[i].green; channel_features[BlueChannel].contrast[i]+=z*z*pixel.direction[i].blue; if (image->colorspace == CMYKColorspace) channel_features[BlackChannel].contrast[i]+=z*z* pixel.direction[i].index; if (image->matte != MagickFalse) channel_features[OpacityChannel].contrast[i]+=z*z* pixel.direction[i].opacity; } /* Maximum Correlation Coefficient. Future: return second largest eigenvalue of Q. */ channel_features[RedChannel].maximum_correlation_coefficient[i]= sqrt((double) -1.0); channel_features[GreenChannel].maximum_correlation_coefficient[i]= sqrt((double) -1.0); channel_features[BlueChannel].maximum_correlation_coefficient[i]= sqrt((double) -1.0); if (image->colorspace == CMYKColorspace) channel_features[IndexChannel].maximum_correlation_coefficient[i]= sqrt((double) -1.0); if (image->matte != MagickFalse) channel_features[OpacityChannel].maximum_correlation_coefficient[i]= sqrt((double) -1.0); } /* Relinquish resources. */ sum=(ChannelStatistics *) RelinquishMagickMemory(sum); for (i=0; i < (ssize_t) number_grays; i++) Q[i]=(ChannelStatistics *) RelinquishMagickMemory(Q[i]); Q=(ChannelStatistics **) RelinquishMagickMemory(Q); density_y=(ChannelStatistics *) RelinquishMagickMemory(density_y); density_xy=(ChannelStatistics *) RelinquishMagickMemory(density_xy); density_x=(ChannelStatistics *) RelinquishMagickMemory(density_x); for (i=0; i < (ssize_t) number_grays; i++) cooccurrence[i]=(ChannelStatistics *) RelinquishMagickMemory(cooccurrence[i]); cooccurrence=(ChannelStatistics **) RelinquishMagickMemory(cooccurrence); return(channel_features); }