+static QuantizationTable *GetQuantizationTable(const char *filename,
+ const char *slot,ExceptionInfo *exception)
+{
+ char
+ *p,
+ *xml;
+
+ const char
+ *attribute,
+ *content;
+
+ double
+ value;
+
+ register ssize_t
+ i;
+
+ ssize_t
+ j;
+
+ QuantizationTable
+ *table;
+
+ size_t
+ length;
+
+ XMLTreeInfo
+ *description,
+ *levels,
+ *quantization_tables,
+ *table_iterator;
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Loading quantization tables \"%s\" ...",filename);
+ table=(QuantizationTable *) NULL;
+ xml=FileToString(filename,~0,exception);
+ if (xml == (char *) NULL)
+ return(table);
+ quantization_tables=NewXMLTree(xml,exception);
+ if (quantization_tables == (XMLTreeInfo *) NULL)
+ {
+ xml=DestroyString(xml);
+ return(table);
+ }
+ for (table_iterator=GetXMLTreeChild(quantization_tables,"table");
+ table_iterator != (XMLTreeInfo *) NULL;
+ table_iterator=GetNextXMLTreeTag(table_iterator))
+ {
+ attribute=GetXMLTreeAttribute(table_iterator,"slot");
+ if ((attribute != (char *) NULL) && (LocaleCompare(slot,attribute) == 0))
+ break;
+ attribute=GetXMLTreeAttribute(table_iterator,"alias");
+ if ((attribute != (char *) NULL) && (LocaleCompare(slot,attribute) == 0))
+ break;
+ }
+ if (table_iterator == (XMLTreeInfo *) NULL)
+ {
+ xml=DestroyString(xml);
+ return(table);
+ }
+ description=GetXMLTreeChild(table_iterator,"description");
+ if (description == (XMLTreeInfo *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingElement", "<description>, slot \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ levels=GetXMLTreeChild(table_iterator,"levels");
+ if (levels == (XMLTreeInfo *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingElement", "<levels>, slot \"%s\"", slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ table=(QuantizationTable *) AcquireMagickMemory(sizeof(*table));
+ if (table == (QuantizationTable *) NULL)
+ ThrowFatalException(ResourceLimitFatalError,
+ "UnableToAcquireQuantizationTable");
+ table->slot=(char *) NULL;
+ table->description=(char *) NULL;
+ table->levels=(unsigned int *) NULL;
+ attribute=GetXMLTreeAttribute(table_iterator,"slot");
+ if (attribute != (char *) NULL)
+ table->slot=ConstantString(attribute);
+ content=GetXMLTreeContent(description);
+ if (content != (char *) NULL)
+ table->description=ConstantString(content);
+ attribute=GetXMLTreeAttribute(levels,"width");
+ if (attribute == (char *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingAttribute", "<levels width>, slot \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ table->width=StringToUnsignedLong(attribute);
+ if (table->width == 0)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlInvalidAttribute", "<levels width>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ attribute=GetXMLTreeAttribute(levels,"height");
+ if (attribute == (char *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingAttribute", "<levels height>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ table->height=StringToUnsignedLong(attribute);
+ if (table->height == 0)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlInvalidAttribute", "<levels height>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ attribute=GetXMLTreeAttribute(levels,"divisor");
+ if (attribute == (char *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingAttribute", "<levels divisor>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ table->divisor=InterpretLocaleValue(attribute,(char **) NULL);
+ if (table->divisor == 0.0)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlInvalidAttribute", "<levels divisor>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ content=GetXMLTreeContent(levels);
+ if (content == (char *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingContent", "<levels>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ length=(size_t) table->width*table->height;
+ if (length < 64)
+ length=64;
+ table->levels=(unsigned int *) AcquireQuantumMemory(length,
+ sizeof(*table->levels));
+ if (table->levels == (unsigned int *) NULL)
+ ThrowFatalException(ResourceLimitFatalError,
+ "UnableToAcquireQuantizationTable");
+ for (i=0; i < (ssize_t) (table->width*table->height); i++)
+ {
+ table->levels[i]=(unsigned int) (InterpretLocaleValue(content,&p)/
+ table->divisor+0.5);
+ while (isspace((int) ((unsigned char) *p)) != 0)
+ p++;
+ if (*p == ',')
+ p++;
+ content=p;
+ }
+ value=InterpretLocaleValue(content,&p);
+ (void) value;
+ if (p != content)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlInvalidContent", "<level> too many values, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ for (j=i; j < 64; j++)
+ table->levels[j]=table->levels[j-1];
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ xml=DestroyString(xml);
+ return(table);
+}
+