Team Fortress 2 Source Code as on 22/4/2020
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.

96 lines
2.3 KiB

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