diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/mathlib/imagequant.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/mathlib/imagequant.cpp')
| -rw-r--r-- | mp/src/mathlib/imagequant.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/mp/src/mathlib/imagequant.cpp b/mp/src/mathlib/imagequant.cpp new file mode 100644 index 00000000..fddafa74 --- /dev/null +++ b/mp/src/mathlib/imagequant.cpp @@ -0,0 +1,96 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include <quantize.h>
+#include <minmax.h>
+
+#define N_EXTRAVALUES 1
+#define N_DIMENSIONS (3+N_EXTRAVALUES)
+
+#define PIXEL(x,y,c) Image[4*((x)+((Width*(y))))+c]
+
+static uint8 Weights[]={5,7,4,8};
+static int ExtraValueXForms[3*N_EXTRAVALUES]={
+ 76,151,28,
+};
+
+
+
+#define MAX_QUANTIZE_IMAGE_WIDTH 4096
+
+void ColorQuantize(uint8 const *Image,
+ int Width,
+ int Height,
+ int flags, int ncolors,
+ uint8 *out_pixels,
+ uint8 *out_palette,
+ int firstcolor)
+{
+ int Error[MAX_QUANTIZE_IMAGE_WIDTH+1][3][2];
+ struct Sample *s=AllocSamples(Width*Height,N_DIMENSIONS);
+ int x,y,c;
+ for(y=0;y<Height;y++)
+ for(x=0;x<Width;x++)
+ {
+ for(c=0;c<3;c++)
+ NthSample(s,y*Width+x,N_DIMENSIONS)->Value[c]=PIXEL(x,y,c);
+ // now, let's generate extra values to quantize on
+ for(int i=0;i<N_EXTRAVALUES;i++)
+ {
+ int val1=0;
+ for(c=0;c<3;c++)
+ val1+=PIXEL(x,y,c)*ExtraValueXForms[i*3+c];
+ val1>>=8;
+ NthSample(s,y*Width+x,N_DIMENSIONS)->Value[c]=(uint8)
+ (min(255,max(0,val1)));
+ }
+ }
+ struct QuantizedValue *q=Quantize(s,Width*Height,N_DIMENSIONS,
+ ncolors,Weights,firstcolor);
+ delete[] s;
+ memset(out_palette,0x55,768);
+ for(int p=0;p<256;p++)
+ {
+ struct QuantizedValue *v=FindQNode(q,p);
+ if (v)
+ for(int c=0;c<3;c++)
+ out_palette[p*3+c]=v->Mean[c];
+ }
+ memset(Error,0,sizeof(Error));
+ for(y=0;y<Height;y++)
+ {
+ int ErrorUse=y & 1;
+ int ErrorUpdate=ErrorUse^1;
+ for(x=0;x<Width;x++)
+ {
+ uint8 samp[3];
+ for(c=0;c<3;c++)
+ {
+ int tryc=PIXEL(x,y,c);
+ if (! (flags & QUANTFLAGS_NODITHER))
+ {
+ tryc+=Error[x][c][ErrorUse];
+ Error[x][c][ErrorUse]=0;
+ }
+ samp[c]=(uint8) min(255,max(0,tryc));
+ }
+ struct QuantizedValue *f=FindMatch(samp,3,Weights,q);
+ out_pixels[Width*y+x]=(uint8) (f->value);
+ if (! (flags & QUANTFLAGS_NODITHER))
+ for(int i=0;i<3;i++)
+ {
+ int newerr=samp[i]-f->Mean[i];
+ int orthog_error=(newerr*3)/8;
+ Error[x+1][i][ErrorUse]+=orthog_error;
+ Error[x][i][ErrorUpdate]=orthog_error;
+ Error[x+1][i][ErrorUpdate]=newerr-2*orthog_error;
+ }
+ }
+ }
+ if (q) FreeQuantization(q);
+}
+
|