Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Aug 14th, 2011  |  syntax: None  |  size: 6.50 KB  |  views: 850  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <nall/platform.hpp>
  2. #include <nall/stdint.hpp>
  3. using namespace nall;
  4.  
  5. extern "C" {
  6.   void filter_size(unsigned&, unsigned&);
  7.   void filter_render(uint32_t*, uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
  8. };
  9.  
  10. enum {
  11.   diff_offset = (0x440 << 21) + (0x207 << 11) + 0x407,
  12.   diff_mask   = (0x380 << 21) + (0x1f0 << 11) + 0x3f0,
  13. };
  14.  
  15. uint32_t *yuvTable;
  16. uint8_t rotate[256];
  17.  
  18. const uint8_t hqTable[256] = {
  19.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 15, 12, 5,  3, 17, 13,
  20.   4, 4, 6, 18, 4, 4, 6, 18, 5,  3, 12, 12, 5,  3,  1, 12,
  21.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 17, 13, 5,  3, 16, 14,
  22.   4, 4, 6, 18, 4, 4, 6, 18, 5,  3, 16, 12, 5,  3,  1, 14,
  23.   4, 4, 6,  2, 4, 4, 6,  2, 5, 19, 12, 12, 5, 19, 16, 12,
  24.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 16, 12, 5,  3, 16, 12,
  25.   4, 4, 6,  2, 4, 4, 6,  2, 5, 19,  1, 12, 5, 19,  1, 14,
  26.   4, 4, 6,  2, 4, 4, 6, 18, 5,  3, 16, 12, 5, 19,  1, 14,
  27.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 15, 12, 5,  3, 17, 13,
  28.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 16, 12, 5,  3, 16, 12,
  29.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 17, 13, 5,  3, 16, 14,
  30.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 16, 13, 5,  3,  1, 14,
  31.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 16, 12, 5,  3, 16, 13,
  32.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 16, 12, 5,  3,  1, 12,
  33.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3, 16, 12, 5,  3,  1, 14,
  34.   4, 4, 6,  2, 4, 4, 6,  2, 5,  3,  1, 12, 5,  3,  1, 14,
  35. };
  36.  
  37. static void initialize() {
  38.   static bool initialized = false;
  39.   if(initialized == true) return;
  40.   initialized = true;
  41.  
  42.   yuvTable = new uint32_t[32768];
  43.  
  44.   for(unsigned i = 0; i < 32768; i++) {
  45.     uint8_t R = (i >>  0) & 31;
  46.     uint8_t G = (i >>  5) & 31;
  47.     uint8_t B = (i >> 10) & 31;
  48.  
  49.     //bgr555->bgr888
  50.     double r = (R << 3) | (R >> 2);
  51.     double g = (G << 3) | (G >> 2);
  52.     double b = (B << 3) | (B >> 2);
  53.  
  54.     //bgr888->yuv888
  55.     double y = (r + g + b) * (0.25f * (63.5f / 48.0f));
  56.     double u = ((r - b) * 0.25f + 128.0f) * (7.5f / 7.0f);
  57.     double v = ((g * 2.0f - r - b) * 0.125f + 128.0f) * (7.5f / 6.0f);
  58.  
  59.     yuvTable[i] = ((unsigned)y << 21) + ((unsigned)u << 11) + ((unsigned)v);
  60.   }
  61.  
  62.   for(unsigned n = 0; n < 256; n++) {
  63.     rotate[n] = ((n >> 2) & 0x11) | ((n << 2) & 0x88)
  64.               | ((n & 0x01) << 5) | ((n & 0x08) << 3)
  65.               | ((n & 0x10) >> 3) | ((n & 0x80) >> 5);
  66.   }
  67. }
  68.  
  69. static void terminate() {
  70.   delete[] yuvTable;
  71. }
  72.  
  73. static bool same(uint16_t x, uint16_t y) {
  74.   return !((yuvTable[x] - yuvTable[y] + diff_offset) & diff_mask);
  75. }
  76.  
  77. static bool diff(uint32_t x, uint16_t y) {
  78.   return ((x - yuvTable[y]) & diff_mask);
  79. }
  80.  
  81. static void grow(uint32_t &n) { n |= n << 16; n &= 0x03e07c1f; }
  82. static uint16_t pack(uint32_t n) { n &= 0x03e07c1f; return n | (n >> 16); }
  83.  
  84. static uint16_t blend1(uint32_t A, uint32_t B) {
  85.   grow(A); grow(B);
  86.   A = (A * 3 + B) >> 2;
  87.   return pack(A);
  88. }
  89.  
  90. static uint16_t blend2(uint32_t A, uint32_t B, uint32_t C) {
  91.   grow(A); grow(B); grow(C);
  92.   return pack((A * 2 + B + C) >> 2);
  93. }
  94.  
  95. static uint16_t blend3(uint32_t A, uint32_t B, uint32_t C) {
  96.   grow(A); grow(B); grow(C);
  97.   return pack((A * 5 + B * 2 + C) >> 3);
  98. }
  99.  
  100. static uint16_t blend4(uint32_t A, uint32_t B, uint32_t C) {
  101.   grow(A); grow(B); grow(C);
  102.   return pack((A * 6 + B + C) >> 3);
  103. }
  104.  
  105. static uint16_t blend5(uint32_t A, uint32_t B, uint32_t C) {
  106.   grow(A); grow(B); grow(C);
  107.   return pack((A * 2 + (B + C) * 3) >> 3);
  108. }
  109.  
  110. static uint16_t blend6(uint32_t A, uint32_t B, uint32_t C) {
  111.   grow(A); grow(B); grow(C);
  112.   return pack((A * 14 + B + C) >> 4);
  113. }
  114.  
  115. static uint16_t blend(unsigned rule, uint16_t E, uint16_t A, uint16_t B, uint16_t D, uint16_t F, uint16_t H) {
  116.   switch(rule) { default:
  117.     case  0: return E;
  118.     case  1: return blend1(E, A);
  119.     case  2: return blend1(E, D);
  120.     case  3: return blend1(E, B);
  121.     case  4: return blend2(E, D, B);
  122.     case  5: return blend2(E, A, B);
  123.     case  6: return blend2(E, A, D);
  124.     case  7: return blend3(E, B, D);
  125.     case  8: return blend3(E, D, B);
  126.     case  9: return blend4(E, D, B);
  127.     case 10: return blend5(E, D, B);
  128.     case 11: return blend6(E, D, B);
  129.     case 12: return same(B, D) ? blend2(E, D, B) : E;
  130.     case 13: return same(B, D) ? blend5(E, D, B) : E;
  131.     case 14: return same(B, D) ? blend6(E, D, B) : E;
  132.     case 15: return same(B, D) ? blend2(E, D, B) : blend1(E, A);
  133.     case 16: return same(B, D) ? blend4(E, D, B) : blend1(E, A);
  134.     case 17: return same(B, D) ? blend5(E, D, B) : blend1(E, A);
  135.     case 18: return same(B, F) ? blend3(E, B, D) : blend1(E, D);
  136.     case 19: return same(D, H) ? blend3(E, D, B) : blend1(E, B);
  137.   }
  138. }
  139.  
  140. dllexport void filter_size(unsigned &width, unsigned &height) {
  141.   initialize();
  142.   width  *= 2;
  143.   height *= 2;
  144. }
  145.  
  146. dllexport void filter_render(
  147.   uint32_t *colortable, uint32_t *output, unsigned outpitch,
  148.   const uint16_t *input, unsigned pitch, unsigned width, unsigned height
  149. ) {
  150.   initialize();
  151.   pitch >>= 1;
  152.   outpitch >>= 2;
  153.  
  154. //#pragma omp parallel for
  155.   for(unsigned y = 0; y < height; y++) {
  156.     const uint16_t *in = input + y * pitch;
  157.     uint32_t *out0 = output + y * outpitch * 2;
  158.     uint32_t *out1 = output + y * outpitch * 2 + outpitch;
  159.  
  160.     int prevline = (y == 0 ? 0 : pitch);
  161.     int nextline = (y == height - 1 ? 0 : pitch);
  162.  
  163.     in++;
  164.     *out0++ = 0; *out0++ = 0;
  165.     *out1++ = 0; *out1++ = 0;
  166.  
  167.     for(unsigned x = 1; x < width - 1; x++) {
  168.       uint16_t A = *(in - prevline - 1);
  169.       uint16_t B = *(in - prevline + 0);
  170.       uint16_t C = *(in - prevline + 1);
  171.       uint16_t D = *(in - 1);
  172.       uint16_t E = *(in + 0);
  173.       uint16_t F = *(in + 1);
  174.       uint16_t G = *(in + nextline - 1);
  175.       uint16_t H = *(in + nextline + 0);
  176.       uint16_t I = *(in + nextline + 1);
  177.       uint32_t e = yuvTable[E] + diff_offset;
  178.  
  179.       uint8_t pattern;
  180.       pattern  = diff(e, A) << 0;
  181.       pattern |= diff(e, B) << 1;
  182.       pattern |= diff(e, C) << 2;
  183.       pattern |= diff(e, D) << 3;
  184.       pattern |= diff(e, F) << 4;
  185.       pattern |= diff(e, G) << 5;
  186.       pattern |= diff(e, H) << 6;
  187.       pattern |= diff(e, I) << 7;
  188.  
  189.       *(out0 + 0) = colortable[blend(hqTable[pattern], E, A, B, D, F, H)]; pattern = rotate[pattern];
  190.       *(out0 + 1) = colortable[blend(hqTable[pattern], E, C, F, B, H, D)]; pattern = rotate[pattern];
  191.       *(out1 + 1) = colortable[blend(hqTable[pattern], E, I, H, F, D, B)]; pattern = rotate[pattern];
  192.       *(out1 + 0) = colortable[blend(hqTable[pattern], E, G, D, H, B, F)];
  193.  
  194.       in++;
  195.       out0 += 2;
  196.       out1 += 2;
  197.     }
  198.  
  199.     in++;
  200.     *out0++ = 0; *out0++ = 0;
  201.     *out1++ = 0; *out1++ = 0;
  202.   }
  203. }
clone this paste RAW Paste Data