126 lines
4.7 KiB
C
126 lines
4.7 KiB
C
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
#ifndef QUANTIZE_H
|
|
#define QUANTIZE_H
|
|
|
|
#ifndef STRING_H
|
|
#include <string.h>
|
|
#endif
|
|
|
|
#define MAXDIMS 768
|
|
#define MAXQUANT 16000
|
|
|
|
#include <tier0/platform.h>
|
|
|
|
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; i < ns; i++)
|
|
NthSample((struct Sample *)ret, i, nd)->Count = 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
|