//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// #ifndef QUANTIZE_H #define QUANTIZE_H #ifndef STRING_H #include #endif #define MAXDIMS 768 #define MAXQUANT 16000 #include struct Sample; struct QuantizedValue { double MinError; // minimum possible error. used // for neighbor searches. struct QuantizedValue *Children[2]; // splits int32 value; // only exists for leaf nodes struct Sample *Samples; // every sample quantized into this // entry int32 NSamples; // how many were quantized to this. int32 TotSamples; double *ErrorMeasure; // variance measure for each dimension double TotalError; // sum of errors uint8 *Mean; // average value of each dimension uint8 *Mins; // min box for children and this uint8 *Maxs; // max box for children and this int NQuant; // the number of samples which were // quantzied to this node since the // last time OptimizeQuantizer() // was called. int *Sums; // sum used by OptimizeQuantizer int sortdim; // dimension currently sorted along. }; struct Sample { int32 ID; // identifier of this sample. can // be used for any purpose. int32 Count; // number of samples this sample // represents int32 QNum; // what value this sample ended up quantized // to. struct QuantizedValue *qptr; // ptr to what this was quantized to. uint8 Value[1]; // array of values for multi-dimensional // variables. }; void FreeQuantization(struct QuantizedValue *t); struct QuantizedValue *Quantize(struct Sample *s, int nsamples, int ndims, int nvalues, uint8 *weights, int value0=0); int CompressSamples(struct Sample *s, int nsamples, int ndims); struct QuantizedValue *FindMatch(uint8 const *sample, int ndims,uint8 *weights, struct QuantizedValue *QTable); void PrintSamples(struct Sample const *s, int nsamples, int ndims); struct QuantizedValue *FindQNode(struct QuantizedValue const *q, int32 code); inline struct Sample *NthSample(struct Sample *s, int i, int nd) { uint8 *r=(uint8 *) s; r+=i*(sizeof(*s)+(nd-1)); return (struct Sample *) r; } inline struct Sample *AllocSamples(int ns, int nd) { size_t size5=(sizeof(struct Sample)+(nd-1))*ns; void *ret=new uint8[size5]; memset(ret,0,size5); for(int i=0;iCount=1; return (struct Sample *) ret; } // MinimumError: what is the min error which will occur if quantizing // a sample to the given qnode? This is just the error if the qnode // is a leaf. double MinimumError(struct QuantizedValue const *q, uint8 const *sample, int ndims, uint8 const *weights); double MaximumError(struct QuantizedValue const *q, uint8 const *sample, int ndims, uint8 const *weights); void PrintQTree(struct QuantizedValue const *p,int idlevel=0); void OptimizeQuantizer(struct QuantizedValue *q, int ndims); // RecalculateVelues: update the means in a sample tree, based upon // the samples. can be used to reoptimize when samples are deleted, // for instance. void RecalculateValues(struct QuantizedValue *q, int ndims); extern double SquaredError; // may be reset and examined. updated by // FindMatch() // the routines below can be used for uniform quantization via dart-throwing. typedef void (*GENERATOR)(void *); // generate a random sample typedef double (*COMPARER)(void const *a, void const *b); void *DartThrow(int NResults, int NTries, size_t itemsize, GENERATOR gen, COMPARER cmp); void *FindClosestDart(void *items,int NResults, size_t itemsize, COMPARER cmp, void *lookfor, int *idx); // color quantization of 24 bit images #define QUANTFLAGS_NODITHER 1 // don't do Floyd-steinberg dither extern void ColorQuantize( uint8 const *pImage, // 4 byte pixels ARGB int nWidth, int nHeight, int nFlags, // QUANTFLAGS_xxx int nColors, // # of colors to fill in in palette uint8 *pOutPixels, // where to store resulting 8 bit pixels uint8 *pOutPalette, // where to store resulting 768-byte palette int nFirstColor); // first color to use in mapping #endif