home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Kasumi / source / blt_spanutils.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  8.3 KB  |  366 lines

  1. #include "blt_spanutils.h"
  2. #include "bitutils.h"
  3.  
  4. using namespace nsVDPixmapBitUtils;
  5.  
  6. namespace nsVDPixmapSpanUtils {
  7.     void horiz_expand2x_centered(uint8 *dst, const uint8 *src, sint32 w) {
  8.         w = -w;
  9.  
  10.         *dst++ = *src;
  11.  
  12.         if (++w) {
  13.             if (++w) {
  14.                 do {
  15.                     dst[0] = (uint8)((3*src[0] + src[1] + 2)>>2);
  16.                     dst[1] = (uint8)((src[0] + 3*src[1] + 2)>>2);
  17.                     dst += 2;
  18.                     ++src;
  19.                 } while((w+=2)<0);
  20.             }
  21.  
  22.             if (!(w & 1)) {
  23.                 *dst = src[0];
  24.             }
  25.         }
  26.     }
  27.  
  28.     void horiz_expand2x_coaligned(uint8 *dst, const uint8 *src, sint32 w) {
  29.         w = -w;
  30.  
  31.         if ((w+=2) < 0) {
  32.             do {
  33.                 dst[0] = src[0];
  34.                 dst[1] = (uint8)((src[0] + src[1] + 1)>>1);
  35.                 dst += 2;
  36.                 ++src;
  37.             } while((w+=2)<0);
  38.         }
  39.  
  40.         w -= 2;
  41.         while(w < 0) {
  42.             ++w;
  43.             *dst++ = src[0];
  44.         }
  45.     }
  46.  
  47.     void horiz_expand4x_coaligned(uint8 *dst, const uint8 *src, sint32 w) {
  48.         w = -w;
  49.  
  50.         if ((w+=4) < 0) {
  51.             do {
  52.                 dst[0] = src[0];
  53.                 dst[1] = (uint8)((3*src[0] + src[1] + 2)>>2);
  54.                 dst[2] = (uint8)((src[0] + src[1] + 1)>>1);
  55.                 dst[3] = (uint8)((src[0] + 3*src[1] + 2)>>2);
  56.                 dst += 4;
  57.                 ++src;
  58.             } while((w+=4)<0);
  59.         }
  60.  
  61.         w -= 4;
  62.         while(w < 0) {
  63.             ++w;
  64.             *dst++ = src[0];
  65.         }
  66.     }
  67.  
  68.     void horiz_compress2x_coaligned(uint8 *dst, const uint8 *src, sint32 w) {
  69.         if (w == 1) {
  70.             *dst = *src;
  71.             return;
  72.         }
  73.  
  74.         *dst++ = (uint8)((3*src[0] + src[1] + 2) >> 2);
  75.         ++src;
  76.         --w;
  77.  
  78.         while(w >= 3) {
  79.             w -= 2;
  80.             *dst++ = (uint8)((src[0] + 2*src[1] + src[2] + 2) >> 2);
  81.             src += 2;
  82.         }
  83.  
  84.         if (w >= 2)
  85.             *dst++ = (uint8)((src[0] + 3*src[1] + 2) >> 2);
  86.     }
  87.  
  88.     void horiz_compress2x_centered(uint8 *dst, const uint8 *src, sint32 w) {
  89.         if (w == 1) {
  90.             *dst = *src;
  91.             return;
  92.         }
  93.  
  94.         if (w == 2) {
  95.             *dst = (uint8)((src[0] + src[1] + 1) >> 1);
  96.             return;
  97.         }
  98.  
  99.         *dst++ = (uint8)((4*src[0] + 3*src[1] + src[2] + 4) >> 3);
  100.         --w;
  101.         ++src;
  102.  
  103.         while(w >= 4) {
  104.             w -= 2;
  105.             *dst++ = (uint8)(((src[0] + src[3]) + 3*(src[1] + src[2]) + 4) >> 3);
  106.             src += 2;
  107.         }
  108.  
  109.         switch(w) {
  110.         case 3:
  111.             *dst++ = (uint8)((src[0] + 3*src[1] + 4*src[2] + 4) >> 3);
  112.             break;
  113.         case 2:
  114.             *dst++ = (uint8)((src[0] + 7*src[1] + 4) >> 3);
  115.             break;
  116.         }
  117.     }
  118.  
  119.     void horiz_compress4x_coaligned(uint8 *dst, const uint8 *src, sint32 w) {
  120.         if (w == 1) {
  121.             *dst = *src;
  122.             return;
  123.         }
  124.  
  125.         if (w == 2) {
  126.             *dst++ = (uint8)((11*src[0] + 5*src[1] + 8) >> 4);
  127.             return;
  128.         }
  129.  
  130.         *dst++ = (uint8)((11*src[0] + 4*src[1] + src[2] + 8) >> 4);
  131.         src += 2;
  132.         w -= 2;
  133.  
  134.         while(w >= 5) {
  135.             w -= 4;
  136.             *dst++ = (uint8)(((src[0] + src[4]) + 4*(src[1] + src[3]) + 6*src[2] + 8) >> 4);
  137.             src += 4;
  138.         }
  139.  
  140.         switch(w) {
  141.         case 4:
  142.             *dst = (uint8)((src[0] + 4*src[1] + 6*src[2] + 5*src[3] + 8) >> 4);
  143.             break;
  144.         case 3:
  145.             *dst = (uint8)((src[0] + 4*src[1] + 11*src[2] + 8) >> 4);
  146.             break;
  147.         }
  148.     }
  149.  
  150.     void horiz_compress4x_centered(uint8 *dst, const uint8 *src, sint32 w) {
  151.  
  152.         switch(w) {
  153.         case 1:
  154.             *dst = *src;
  155.             return;
  156.         case 2:        // 29 99
  157.             *dst = (uint8)((29*src[0] + 99*src[1] + 64) >> 7);
  158.             return;
  159.         case 3:        // 29 35 64
  160.             *dst = (uint8)((29*src[0] + 35*src[1] + 64*src[1] + 64) >> 7);
  161.             return;
  162.         case 4:        // 29 35 35 29
  163.             *dst = (uint8)((29*src[0] + 35*(src[1] + src[2]) + 29*src[3] + 64) >> 7);
  164.             return;
  165.         case 5:        // 29 35 35 21 8
  166.                     //        1 7 120
  167.             dst[0] = (uint8)((29*src[0] + 35*(src[1] + src[2]) + 21*src[3] + 8*src[4] + 64) >> 7);
  168.             dst[1] = (uint8)((src[2] + 7*src[3] + 120*src[4] + 64) >> 7);
  169.             return;
  170.         }
  171.  
  172.         *dst++ = (uint8)((29*src[0] + 35*(src[1] + src[2]) + 21*src[3] + 7*src[4] + src[5] + 64) >> 7);
  173.         src += 2;
  174.         w -= 2;
  175.  
  176.         while(w >= 8) {
  177.             w -= 4;
  178.             *dst++ = (uint8)(((src[0] + src[7]) + 7*(src[1] + src[6]) + 21*(src[2] + src[5]) + 35*(src[3] + src[4]) + 64) >> 7);
  179.             src += 4;
  180.         }
  181.  
  182.         switch(w) {
  183.         case 4:        // 1 7 21 99
  184.             *dst = (uint8)((src[0] + 7*src[1] + 21*src[2] + 99*src[3] + 64) >> 7);
  185.             break;
  186.         case 5:        // 1 7 21 35 64
  187.             *dst = (uint8)((src[0] + 7*src[1] + 21*src[2] + 35*src[3] + 64*src[4] + 64) >> 7);
  188.             break;
  189.         case 6:        // 1 7 21 35 35 29
  190.             *dst = (uint8)((src[0] + 7*src[1] + 21*src[2] + 29*src[5] + 35*(src[3] + src[4]) + 64) >> 7);
  191.             break;
  192.         case 7:        // 1 7 21 35 35 21 8
  193.                     //            1 7 120
  194.             dst[0] = (uint8)((src[0] + 7*src[1] + 8*src[6] + 21*(src[2] + src[5]) + 35*(src[3] + src[4]) + 64) >> 7);
  195.             dst[1] = (uint8)((src[4] + 7*src[5] + 120*src[6] + 64) >> 7);
  196.             break;
  197.         }
  198.     }
  199.  
  200.     void horiz_realign_to_centered(uint8 *dst, const uint8 *src, sint32 w) {
  201.         // luma samples:    Y        Y        Y        Y        Y
  202.         // coaligned:        C                C                C
  203.         // centered:            C                C
  204.         //
  205.         // To realign coaligned samples to centered, we need to shift them
  206.         // right by a quarter sample in chroma space. This can be done via
  207.         // a [3 1]/4 filter.
  208.  
  209.         for(sint32 i=1; i<w; ++i) {
  210.             dst[0] = (uint8)((3*(uint32)src[0] + (uint32)src[1] + 2) >> 2);
  211.             ++dst;
  212.             ++src;
  213.         }
  214.  
  215.         *dst++ = *src++;
  216.     }
  217.  
  218.     void horiz_realign_to_coaligned(uint8 *dst, const uint8 *src, sint32 w) {
  219.         // luma samples:    Y        Y        Y        Y        Y
  220.         // coaligned:        C                C                C
  221.         // centered:            C                C
  222.         //
  223.         // To realign centered samples to coaligned, we need to shift them
  224.         // left by a quarter sample in chroma space. This can be done via
  225.         // a [1 3]/4 filter.
  226.  
  227.         *dst++ = *src++;
  228.  
  229.         for(sint32 i=1; i<w; ++i) {
  230.             dst[0] = (uint8)(((uint32)src[-1] + 3*(uint32)src[0] + 2) >> 2);
  231.             ++dst;
  232.             ++src;
  233.         }
  234.     }
  235.  
  236.     void vert_expand2x_centered(uint8 *dst, const uint8 *const *srcs, sint32 w, uint8 phase) {
  237.         const uint8 *src3 = srcs[0];
  238.         const uint8 *src1 = srcs[1];
  239.  
  240.         if (phase >= 128)
  241.             std::swap(src1, src3);
  242.  
  243.         sint32 w4 = w>>2;
  244.         w &= 3;
  245.  
  246.         if (w4) {
  247.             const uint32 *src34 = (const uint32 *)src3;
  248.             const uint32 *src14 = (const uint32 *)src1;
  249.                   uint32 *dst4  = (      uint32 *)dst;
  250.  
  251.             do {
  252.                 const uint32 a = *src34++;
  253.                 const uint32 b = *src14++;
  254.                 const uint32 ab = (a&b) + (((a^b)&0xfefefefe)>>1);
  255.  
  256.                 *dst4++ = (a|ab) - (((a^ab)&0xfefefefe)>>1);
  257.             } while(--w4);
  258.  
  259.             src3 = (const uint8 *)src34;
  260.             src1 = (const uint8 *)src14;
  261.             dst  = (      uint8 *)dst4;
  262.         }
  263.  
  264.         if (w) {
  265.             do {
  266.                 *dst++ = (uint8)((*src1++ + 3**src3++ + 2) >> 2);
  267.             } while(--w);
  268.         }
  269.     }
  270.  
  271.     void vert_expand4x_centered(uint8 *dst, const uint8 *const *srcs, sint32 w, uint8 phase) {
  272.         const uint8 *src3 = srcs[0];
  273.         const uint8 *src1 = srcs[1];
  274.  
  275.         switch(phase & 0xc0) {
  276.         case 0x00:
  277.             do {
  278.                 *dst++ = (uint8)((1**src1++ + 7**src3++ + 4) >> 3);
  279.             } while(--w);
  280.             break;
  281.         case 0x40:
  282.             do {
  283.                 *dst++ = (uint8)((3**src1++ + 5**src3++ + 4) >> 3);
  284.             } while(--w);
  285.             break;
  286.         case 0x80:
  287.             do {
  288.                 *dst++ = (uint8)((5**src1++ + 3**src3++ + 4) >> 3);
  289.             } while(--w);
  290.             break;
  291.         case 0xc0:
  292.             do {
  293.                 *dst++ = (uint8)((7**src1++ + 1**src3++ + 4) >> 3);
  294.             } while(--w);
  295.             break;
  296.         default:
  297.             VDNEVERHERE;
  298.         }
  299.     }
  300.  
  301.     void vert_compress2x_centered_fast(uint8 *dst, const uint8 *const *srcarray, sint32 w, uint8 phase) {
  302.         const uint8 *src1 = srcarray[0];
  303.         const uint8 *src2 = srcarray[1];
  304.  
  305.         w = -w;
  306.         w += 3;
  307.  
  308.         while(w < 0) {
  309.             *(uint32 *)dst = avg_8888_11(*(uint32 *)src1, *(uint32 *)src2);
  310.             dst += 4;
  311.             src1 += 4;
  312.             src2 += 4;
  313.             w += 4;
  314.         }
  315.  
  316.         w -= 3;
  317.  
  318.         while(w < 0) {
  319.             *dst = (uint8)((*src1 + *src2 + 1)>>1);
  320.             ++dst;
  321.             ++src1;
  322.             ++src2;
  323.             ++w;
  324.         }
  325.     }
  326.  
  327.     void vert_compress2x_centered(uint8 *dst, const uint8 *const *srcarray, sint32 w, uint8 phase) {
  328.         const uint8 *src1 = srcarray[0];
  329.         const uint8 *src2 = srcarray[1];
  330.         const uint8 *src3 = srcarray[2];
  331.         const uint8 *src4 = srcarray[3];
  332.  
  333.         w = -w;
  334.  
  335.         while(w < 0) {
  336.             *dst++ = (uint8)(((*src1++ + *src4++) + 3*(*src2++ + *src3++) + 4)>>3);
  337.             ++w;
  338.         }
  339.     }
  340.  
  341.     void vert_compress4x_centered(uint8 *dst, const uint8 *const *srcarray, sint32 w, uint8 phase) {
  342.         const uint8 *src1 = srcarray[0];
  343.         const uint8 *src2 = srcarray[1];
  344.         const uint8 *src3 = srcarray[2];
  345.         const uint8 *src4 = srcarray[3];
  346.         const uint8 *src5 = srcarray[4];
  347.         const uint8 *src6 = srcarray[5];
  348.         const uint8 *src7 = srcarray[6];
  349.         const uint8 *src8 = srcarray[7];
  350.  
  351.         w = -w;
  352.  
  353.         while(w < 0) {
  354.             int sum18 = *src1++ + *src8++;
  355.             int sum27 = *src2++ + *src7++;
  356.             int sum36 = *src3++ + *src6++;
  357.             int sum45 = *src4++ + *src5++;
  358.  
  359.             *dst++ = (uint8)((sum18 + 7*sum27 + 21*sum36 + 35*sum45 + 64) >> 7);
  360.  
  361.             ++w;
  362.         }
  363.     }
  364. }
  365.  
  366.