Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.3 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include <quantize.h>
  9. // NOTE: This has to be the last file included!
  10. #include "tier0/memdbgon.h"
  11. #define N_EXTRAVALUES 1
  12. #define N_DIMENSIONS (3+N_EXTRAVALUES)
  13. #define PIXEL(x,y,c) Image[4*((x)+((Width*(y))))+c]
  14. static uint8 Weights[]={5,7,4,8};
  15. static int ExtraValueXForms[3*N_EXTRAVALUES]={
  16. 76,151,28,
  17. };
  18. #define MAX_QUANTIZE_IMAGE_WIDTH 4096
  19. void ColorQuantize(uint8 const *Image,
  20. int Width,
  21. int Height,
  22. int flags, int ncolors,
  23. uint8 *out_pixels,
  24. uint8 *out_palette,
  25. int firstcolor)
  26. {
  27. int Error[MAX_QUANTIZE_IMAGE_WIDTH+1][3][2];
  28. struct Sample *s=AllocSamples(Width*Height,N_DIMENSIONS);
  29. int x,y,c;
  30. for(y=0;y<Height;y++)
  31. for(x=0;x<Width;x++)
  32. {
  33. for(c=0;c<3;c++)
  34. NthSample(s,y*Width+x,N_DIMENSIONS)->Value[c]=PIXEL(x,y,c);
  35. // now, let's generate extra values to quantize on
  36. for(int i=0;i<N_EXTRAVALUES;i++)
  37. {
  38. int val1=0;
  39. for(c=0;c<3;c++)
  40. val1+=PIXEL(x,y,c)*ExtraValueXForms[i*3+c];
  41. val1>>=8;
  42. NthSample(s,y*Width+x,N_DIMENSIONS)->Value[c]=(uint8)
  43. (MIN(255,MAX(0,val1)));
  44. }
  45. }
  46. struct QuantizedValue *q=Quantize(s,Width*Height,N_DIMENSIONS,
  47. ncolors,Weights,firstcolor);
  48. delete[] s;
  49. memset(out_palette,0x55,768);
  50. for(int p=0;p<256;p++)
  51. {
  52. struct QuantizedValue *v=FindQNode(q,p);
  53. if (v)
  54. for(int c=0;c<3;c++)
  55. out_palette[p*3+c]=v->Mean[c];
  56. }
  57. memset(Error,0,sizeof(Error));
  58. for(y=0;y<Height;y++)
  59. {
  60. int ErrorUse=y & 1;
  61. int ErrorUpdate=ErrorUse^1;
  62. for(x=0;x<Width;x++)
  63. {
  64. uint8 samp[3];
  65. for(c=0;c<3;c++)
  66. {
  67. int tryc=PIXEL(x,y,c);
  68. if (! (flags & QUANTFLAGS_NODITHER))
  69. {
  70. tryc+=Error[x][c][ErrorUse];
  71. Error[x][c][ErrorUse]=0;
  72. }
  73. samp[c]=(uint8) MIN(255,MAX(0,tryc));
  74. }
  75. struct QuantizedValue *f=FindMatch(samp,3,Weights,q);
  76. out_pixels[Width*y+x]=(uint8) (f->value);
  77. if (! (flags & QUANTFLAGS_NODITHER))
  78. for(int i=0;i<3;i++)
  79. {
  80. int newerr=samp[i]-f->Mean[i];
  81. int orthog_error=(newerr*3)/8;
  82. Error[x+1][i][ErrorUse]+=orthog_error;
  83. Error[x][i][ErrorUpdate]=orthog_error;
  84. Error[x+1][i][ErrorUpdate]=newerr-2*orthog_error;
  85. }
  86. }
  87. }
  88. if (q) FreeQuantization(q);
  89. }