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

  1. #include <vd2/Meia/MPEGConvert.h>
  2. #include "tables.h"
  3.  
  4. ///////////////////////////////////////////////////////////////////////////
  5.  
  6. using namespace nsVDMPEGTables;
  7.  
  8. namespace nsVDMPEGConvertReference {
  9.  
  10.     void DecodeUYVY(void *_dst, ptrdiff_t dpitch, const unsigned char *srcY1, ptrdiff_t ypitch, const unsigned char *srcCr, const unsigned char *srcCb, ptrdiff_t cpitch, int mbw, int height) {
  11.         unsigned char *dst1 = (unsigned char *)_dst;
  12.         unsigned char *dst2 = (unsigned char *)_dst + dpitch;
  13.         const unsigned char *srcY2 = srcY1 + ypitch;
  14.  
  15.         dpitch = dpitch*2 - mbw*16*2;
  16.         ypitch = ypitch*2 - mbw*16;
  17.         cpitch -= mbw*8;
  18.  
  19.         do {
  20.             int w = mbw*8;
  21.  
  22.             if (height == 1) {
  23.                 srcY2 = srcY1;
  24.                 dst2 = dst1;
  25.             }
  26.  
  27.             do {
  28.                 dst1[0] = srcCb[0];
  29.                 dst1[1] = srcY1[0];
  30.                 dst1[2] = srcCr[0];
  31.                 dst1[3] = srcY1[1];
  32.  
  33.                 dst2[0] = srcCb[0];
  34.                 dst2[1] = srcY2[0];
  35.                 dst2[2] = srcCr[0];
  36.                 dst2[3] = srcY2[1];
  37.  
  38.                 ++srcCb;
  39.                 ++srcCr;
  40.                 srcY1 += 2;
  41.                 srcY2 += 2;
  42.                 dst1 += 4;
  43.                 dst2 += 4;
  44.             } while(--w);
  45.  
  46.             srcY1 += ypitch;
  47.             srcY2 += ypitch;
  48.             srcCr += cpitch;
  49.             srcCb += cpitch;
  50.             dst1 += dpitch;
  51.             dst2 += dpitch;
  52.         } while((height-=2) > 0);
  53.     }
  54.  
  55.     void DecodeYUYV(void *_dst, ptrdiff_t dpitch, const unsigned char *srcY1, ptrdiff_t ypitch, const unsigned char *srcCr, const unsigned char *srcCb, ptrdiff_t cpitch, int mbw, int height) {
  56.         unsigned char *dst1 = (unsigned char *)_dst;
  57.         unsigned char *dst2 = (unsigned char *)_dst + dpitch;
  58.         const unsigned char *srcY2 = srcY1 + ypitch;
  59.  
  60.         dpitch = dpitch*2 - mbw*16*2;
  61.         ypitch = ypitch*2 - mbw*16;
  62.         cpitch -= mbw*8;
  63.  
  64.         do {
  65.             int w = mbw*8;
  66.  
  67.             if (height == 1) {
  68.                 srcY2 = srcY1;
  69.                 dst2 = dst1;
  70.             }
  71.  
  72.             do {
  73.                 dst1[0] = srcY1[0];
  74.                 dst1[1] = srcCb[0];
  75.                 dst1[2] = srcY1[1];
  76.                 dst1[3] = srcCr[0];
  77.  
  78.                 dst2[0] = srcY2[0];
  79.                 dst2[1] = srcCb[0];
  80.                 dst2[2] = srcY2[1];
  81.                 dst2[3] = srcCr[0];
  82.  
  83.                 ++srcCb;
  84.                 ++srcCr;
  85.                 srcY1 += 2;
  86.                 srcY2 += 2;
  87.                 dst1 += 4;
  88.                 dst2 += 4;
  89.             } while(--w);
  90.  
  91.             srcY1 += ypitch;
  92.             srcY2 += ypitch;
  93.             srcCr += cpitch;
  94.             srcCb += cpitch;
  95.             dst1 += dpitch;
  96.             dst2 += dpitch;
  97.         } while((height-=2)>0);
  98.     }
  99.  
  100.     void DecodeYVYU(void *_dst, ptrdiff_t dpitch, const unsigned char *srcY1, ptrdiff_t ypitch, const unsigned char *srcCr, const unsigned char *srcCb, ptrdiff_t cpitch, int mbw, int height) {
  101.         unsigned char *dst1 = (unsigned char *)_dst;
  102.         unsigned char *dst2 = (unsigned char *)_dst + dpitch;
  103.         const unsigned char *srcY2 = srcY1 + ypitch;
  104.  
  105.         dpitch = dpitch*2 - mbw*16*2;
  106.         ypitch = ypitch*2 - mbw*16;
  107.         cpitch -= mbw*8;
  108.  
  109.         do {
  110.             int w = mbw*8;
  111.  
  112.             if (height == 1) {
  113.                 srcY2 = srcY1;
  114.                 dst2 = dst1;
  115.             }
  116.  
  117.             do {
  118.                 dst1[0] = srcY1[0];
  119.                 dst1[1] = srcCr[0];
  120.                 dst1[2] = srcY1[1];
  121.                 dst1[3] = srcCb[0];
  122.  
  123.                 dst2[0] = srcY2[0];
  124.                 dst2[1] = srcCr[0];
  125.                 dst2[2] = srcY2[1];
  126.                 dst2[3] = srcCb[0];
  127.  
  128.                 ++srcCb;
  129.                 ++srcCr;
  130.                 srcY1 += 2;
  131.                 srcY2 += 2;
  132.                 dst1 += 4;
  133.                 dst2 += 4;
  134.             } while(--w);
  135.  
  136.             srcY1 += ypitch;
  137.             srcY2 += ypitch;
  138.             srcCr += cpitch;
  139.             srcCb += cpitch;
  140.             dst1 += dpitch;
  141.             dst2 += dpitch;
  142.         } while((height-=2)>0);
  143.     }
  144.  
  145.     // Byte order for DecodeY41P is U0Y0V0Y1 U4Y2V4Y3 Y4Y5Y6Y7
  146.  
  147.     void DecodeY41P(void *_dst, ptrdiff_t dpitch, const unsigned char *srcY1, ptrdiff_t ypitch, const unsigned char *srcCr, const unsigned char *srcCb, ptrdiff_t cpitch, int mbw, int height) {
  148.         unsigned char *dst1 = (unsigned char *)_dst;
  149.         unsigned char *dst2 = (unsigned char *)_dst + dpitch;
  150.         const unsigned char *srcY2 = srcY1 + ypitch;
  151.  
  152.         dpitch = dpitch*2 - mbw*16*2;
  153.         ypitch = ypitch*2 - mbw*16;
  154.         cpitch -= mbw*8;
  155.  
  156.         do {
  157.             int w = mbw*2;
  158.  
  159.             if (height == 1) {
  160.                 srcY2 = srcY1;
  161.                 dst2 = dst1;
  162.             }
  163.  
  164.             do {
  165.                 // chroma
  166.  
  167.                 dst1[0] = dst2[0] = (srcCb[0] + srcCb[1] + 1) >> 1;
  168.                 dst1[4] = dst2[4] = (srcCb[2] + srcCb[3] + 1) >> 1;
  169.  
  170.                 dst1[2] = dst2[2] = (srcCr[0] + srcCr[1] + 1) >> 1;
  171.                 dst1[6] = dst2[6] = (srcCr[2] + srcCr[3] + 1) >> 1;
  172.  
  173.                 dst1[ 1] = srcY1[0];
  174.                 dst1[ 3] = srcY1[1];
  175.                 dst1[ 5] = srcY1[2];
  176.                 dst1[ 7] = srcY1[3];
  177.                 dst1[ 8] = srcY1[4];
  178.                 dst1[ 9] = srcY1[5];
  179.                 dst1[10] = srcY1[6];
  180.                 dst1[11] = srcY1[7];
  181.  
  182.                 dst2[ 1] = srcY2[0];
  183.                 dst2[ 3] = srcY2[1];
  184.                 dst2[ 5] = srcY2[2];
  185.                 dst2[ 7] = srcY2[3];
  186.                 dst2[ 8] = srcY2[4];
  187.                 dst2[ 9] = srcY2[5];
  188.                 dst2[10] = srcY2[6];
  189.                 dst2[11] = srcY2[7];
  190.  
  191.                 srcCb += 4;
  192.                 srcCr += 4;
  193.                 srcY1 += 8;
  194.                 srcY2 += 8;
  195.                 dst1 += 12;
  196.                 dst2 += 12;
  197.             } while(--w);
  198.  
  199.             srcY1 += ypitch;
  200.             srcY2 += ypitch;
  201.             srcCr += cpitch;
  202.             srcCb += cpitch;
  203.             dst1 += dpitch;
  204.             dst2 += dpitch;
  205.         } while((height-=2)>0);
  206.     }
  207.  
  208.     // R = 1.164(Y-16) + 1.596(Cr-128)
  209.     // G = 1.164(Y-16) - 0.813(Cr-128) - 0.391(Cb-128)
  210.     // B = 1.164(Y-16) + 2.018(Cb-128)
  211.  
  212.     static const int y_coeff = (int)(1.164*65536 + 0.5);
  213.     static const int cr_red_coeff = (int)(1.596*65536 + 0.5);
  214.     static const int cr_grn_coeff = (int)(-0.813*65536 + 0.5);
  215.     static const int cb_grn_coeff = (int)(-0.391*65536 + 0.5);
  216.     static const int cb_blu_coeff = (int)(2.018*65536 + 0.5);
  217.  
  218.     void DecodeRGB15(void *_dst, ptrdiff_t dpitch, const unsigned char *srcY1, ptrdiff_t ypitch, const unsigned char *srcCr, const unsigned char *srcCb, ptrdiff_t cpitch, int mbw, int height) {
  219.         unsigned short *dst1 = (unsigned short *)_dst;
  220.         unsigned short *dst2 = (unsigned short *)((char *)_dst + dpitch);
  221.         const unsigned char *srcY2 = srcY1 + ypitch;
  222.  
  223.         dpitch = dpitch*2 - mbw*16*2;
  224.         ypitch = ypitch*2 - mbw*16;
  225.         cpitch -= mbw*8;
  226.  
  227.         do {
  228.             int w = mbw*8;
  229.  
  230.             if (height == 1) {
  231.                 srcY2 = srcY1;
  232.                 dst2 = dst1;
  233.             }
  234.  
  235.             do {
  236.                 int cr = (int)*srcCr++ - 128;
  237.                 int cb = (int)*srcCb++ - 128;
  238.                 int cred = cr * cr_red_coeff;
  239.                 int cgrn = cr * cr_grn_coeff + cb * cb_grn_coeff;
  240.                 int cblu = cb * cb_blu_coeff;
  241.                 int y;
  242.  
  243.                 y = y_coeff*((int)srcY1[0] - 16);
  244.                 *dst1++ = ((clip_table[(y + cblu + 32768 + 288*65536)>>16]&0xf8)>>3)
  245.                         + ((clip_table[(y + cgrn + 32768 + 288*65536)>>16]&0xf8)<<2)
  246.                         + ((clip_table[(y + cred + 32768 + 288*65536)>>16]&0xf8)<<7);
  247.  
  248.                 y = y_coeff*((int)srcY1[1] - 16);
  249.                 *dst1++ = ((clip_table[(y + cblu + 32768 + 288*65536)>>16]&0xf8)>>3)
  250.                         + ((clip_table[(y + cgrn + 32768 + 288*65536)>>16]&0xf8)<<2)
  251.                         + ((clip_table[(y + cred + 32768 + 288*65536)>>16]&0xf8)<<7);
  252.  
  253.                 y = y_coeff*((int)srcY2[0] - 16);
  254.                 *dst2++ = ((clip_table[(y + cblu + 32768 + 288*65536)>>16]&0xf8)>>3)
  255.                         + ((clip_table[(y + cgrn + 32768 + 288*65536)>>16]&0xf8)<<2)
  256.                         + ((clip_table[(y + cred + 32768 + 288*65536)>>16]&0xf8)<<7);
  257.  
  258.                 y = y_coeff*((int)srcY2[1] - 16);
  259.                 *dst2++ = ((clip_table[(y + cblu + 32768 + 288*65536)>>16]&0xf8)>>3)
  260.                         + ((clip_table[(y + cgrn + 32768 + 288*65536)>>16]&0xf8)<<2)
  261.                         + ((clip_table[(y + cred + 32768 + 288*65536)>>16]&0xf8)<<7);
  262.  
  263.                 srcY1 += 2;
  264.                 srcY2 += 2;
  265.             } while(--w);
  266.  
  267.             srcY1 += ypitch;
  268.             srcY2 += ypitch;
  269.             srcCr += cpitch;
  270.             srcCb += cpitch;
  271.             dst1 = (unsigned short *)((char *)dst1 + dpitch);
  272.             dst2 = (unsigned short *)((char *)dst2 + dpitch);
  273.         } while((height-=2)>0);
  274.     }
  275.  
  276.     void DecodeRGB16(void *dst, ptrdiff_t dpitch, const unsigned char *srcY1, ptrdiff_t ypitch, const unsigned char *srcCr, const unsigned char *srcCb, ptrdiff_t cpitch, int mbw, int height) {
  277.         unsigned short *dst1 = (unsigned short *)dst;
  278.         unsigned short *dst2 = (unsigned short *)((char *)dst + dpitch);
  279.         const unsigned char *srcY2 = srcY1 + ypitch;
  280.  
  281.         dpitch = dpitch*2 - mbw*16*2;
  282.         ypitch = ypitch*2 - mbw*16;
  283.         cpitch -= mbw*8;
  284.  
  285.         do {
  286.             int w = mbw*8;
  287.  
  288.             if (height == 1) {
  289.                 srcY2 = srcY1;
  290.                 dst2 = dst1;
  291.             }
  292.  
  293.             do {
  294.                 int cr = (int)*srcCr++ - 128;
  295.                 int cb = (int)*srcCb++ - 128;
  296.                 int cred = cr * cr_red_coeff;
  297.                 int cgrn = cr * cr_grn_coeff + cb * cb_grn_coeff;
  298.                 int cblu = cb * cb_blu_coeff;
  299.                 int y;
  300.  
  301.                 y = y_coeff*((int)srcY1[0] - 16);
  302.                 *dst1++ = ((clip_table[(y + cblu + 32768 + 288*65536)>>16]&0xf8)>>3)
  303.                         + ((clip_table[(y + cgrn + 32768 + 288*65536)>>16]&0xfc)<<3)
  304.                         + ((clip_table[(y + cred + 32768 + 288*65536)>>16]&0xf8)<<8);
  305.  
  306.                 y = y_coeff*((int)srcY1[1] - 16);
  307.                 *dst1++ = ((clip_table[(y + cblu + 32768 + 288*65536)>>16]&0xf8)>>3)
  308.                         + ((clip_table[(y + cgrn + 32768 + 288*65536)>>16]&0xfc)<<3)
  309.                         + ((clip_table[(y + cred + 32768 + 288*65536)>>16]&0xf8)<<8);
  310.  
  311.                 y = y_coeff*((int)srcY2[0] - 16);
  312.                 *dst2++ = ((clip_table[(y + cblu + 32768 + 288*65536)>>16]&0xf8)>>3)
  313.                         + ((clip_table[(y + cgrn + 32768 + 288*65536)>>16]&0xfc)<<3)
  314.                         + ((clip_table[(y + cred + 32768 + 288*65536)>>16]&0xf8)<<8);
  315.  
  316.                 y = y_coeff*((int)srcY2[1] - 16);
  317.                 *dst2++ = ((clip_table[(y + cblu + 32768 + 288*65536)>>16]&0xf8)>>3)
  318.                         + ((clip_table[(y + cgrn + 32768 + 288*65536)>>16]&0xfc)<<3)
  319.                         + ((clip_table[(y + cred + 32768 + 288*65536)>>16]&0xf8)<<8);
  320.  
  321.                 srcY1 += 2;
  322.                 srcY2 += 2;
  323.             } while(--w);
  324.  
  325.             srcY1 += ypitch;
  326.             srcY2 += ypitch;
  327.             srcCr += cpitch;
  328.             srcCb += cpitch;
  329.             dst1 = (unsigned short *)((char *)dst1 + dpitch);
  330.             dst2 = (unsigned short *)((char *)dst2 + dpitch);
  331.         } while((height-=2)>0);
  332.     }
  333.  
  334.     void DecodeRGB24(void *_dst, ptrdiff_t dpitch, const unsigned char *srcY1, ptrdiff_t ypitch, const unsigned char *srcCr, const unsigned char *srcCb, ptrdiff_t cpitch, int mbw, int height) {
  335.         unsigned char *dst1 = (unsigned char *)_dst;
  336.         unsigned char *dst2 = (unsigned char *)_dst + dpitch;
  337.         const unsigned char *srcY2 = srcY1 + ypitch;
  338.  
  339.         dpitch = dpitch*2 - mbw*16*3;
  340.         ypitch = ypitch*2 - mbw*16;
  341.         cpitch -= mbw*8;
  342.  
  343.         do {
  344.             int w = mbw*8;
  345.  
  346.             if (height == 1) {
  347.                 srcY2 = srcY1;
  348.                 dst2 = dst1;
  349.             }
  350.  
  351.             do {
  352.                 int cr = (int)*srcCr++ - 128;
  353.                 int cb = (int)*srcCb++ - 128;
  354.                 int cred = cr * cr_red_coeff;
  355.                 int cgrn = cr * cr_grn_coeff + cb * cb_grn_coeff;
  356.                 int cblu = cb * cb_blu_coeff;
  357.                 int y;
  358.  
  359.                 y = y_coeff*((int)srcY1[0] - 16);
  360.                 dst1[0] = clip_table[(y + cblu + 32768 + 288*65536)>>16];
  361.                 dst1[1] = clip_table[(y + cgrn + 32768 + 288*65536)>>16];
  362.                 dst1[2] = clip_table[(y + cred + 32768 + 288*65536)>>16];
  363.  
  364.                 y = y_coeff*((int)srcY1[1] - 16);
  365.                 dst1[3] = clip_table[(y + cblu + 32768 + 288*65536)>>16];
  366.                 dst1[4] = clip_table[(y + cgrn + 32768 + 288*65536)>>16];
  367.                 dst1[5] = clip_table[(y + cred + 32768 + 288*65536)>>16];
  368.  
  369.                 y = y_coeff*((int)srcY2[0] - 16);
  370.                 dst2[0] = clip_table[(y + cblu + 32768 + 288*65536)>>16];
  371.                 dst2[1] = clip_table[(y + cgrn + 32768 + 288*65536)>>16];
  372.                 dst2[2] = clip_table[(y + cred + 32768 + 288*65536)>>16];
  373.  
  374.                 y = y_coeff*((int)srcY2[1] - 16);
  375.                 dst2[3] = clip_table[(y + cblu + 32768 + 288*65536)>>16];
  376.                 dst2[4] = clip_table[(y + cgrn + 32768 + 288*65536)>>16];
  377.                 dst2[5] = clip_table[(y + cred + 32768 + 288*65536)>>16];
  378.  
  379.                 srcY1 += 2;
  380.                 srcY2 += 2;
  381.                 dst1 += 6;
  382.                 dst2 += 6;
  383.             } while(--w);
  384.  
  385.             srcY1 += ypitch;
  386.             srcY2 += ypitch;
  387.             srcCr += cpitch;
  388.             srcCb += cpitch;
  389.             dst1 += dpitch;
  390.             dst2 += dpitch;
  391.         } while((height-=2)>0);
  392.     }
  393.  
  394.     void DecodeRGB32(void *_dst, ptrdiff_t dpitch, const unsigned char *srcY1, ptrdiff_t ypitch, const unsigned char *srcCr, const unsigned char *srcCb, ptrdiff_t cpitch, int mbw, int height) {
  395.         unsigned char *dst1 = (unsigned char *)_dst;
  396.         unsigned char *dst2 = (unsigned char *)_dst + dpitch;
  397.         const unsigned char *srcY2 = srcY1 + ypitch;
  398.  
  399.         dpitch = dpitch*2 - mbw*16*4;
  400.         ypitch = ypitch*2 - mbw*16;
  401.         cpitch -= mbw*8;
  402.  
  403.         do {
  404.             int w = mbw*8;
  405.  
  406.             if (height == 1) {
  407.                 srcY2 = srcY1;
  408.                 dst2 = dst1;
  409.             }
  410.  
  411.             do {
  412.                 int cr = (int)*srcCr++ - 128;
  413.                 int cb = (int)*srcCb++ - 128;
  414.                 int cred = cr * cr_red_coeff;
  415.                 int cgrn = cr * cr_grn_coeff + cb * cb_grn_coeff;
  416.                 int cblu = cb * cb_blu_coeff;
  417.                 int y;
  418.  
  419.                 y = y_coeff*((int)srcY1[0] - 16);
  420.                 dst1[0] = clip_table[(y + cblu + 32768 + 288*65536)>>16];
  421.                 dst1[1] = clip_table[(y + cgrn + 32768 + 288*65536)>>16];
  422.                 dst1[2] = clip_table[(y + cred + 32768 + 288*65536)>>16];
  423.  
  424.                 y = y_coeff*((int)srcY1[1] - 16);
  425.                 dst1[4] = clip_table[(y + cblu + 32768 + 288*65536)>>16];
  426.                 dst1[5] = clip_table[(y + cgrn + 32768 + 288*65536)>>16];
  427.                 dst1[6] = clip_table[(y + cred + 32768 + 288*65536)>>16];
  428.  
  429.                 y = y_coeff*((int)srcY2[0] - 16);
  430.                 dst2[0] = clip_table[(y + cblu + 32768 + 288*65536)>>16];
  431.                 dst2[1] = clip_table[(y + cgrn + 32768 + 288*65536)>>16];
  432.                 dst2[2] = clip_table[(y + cred + 32768 + 288*65536)>>16];
  433.  
  434.                 y = y_coeff*((int)srcY2[1] - 16);
  435.                 dst2[4] = clip_table[(y + cblu + 32768 + 288*65536)>>16];
  436.                 dst2[5] = clip_table[(y + cgrn + 32768 + 288*65536)>>16];
  437.                 dst2[6] = clip_table[(y + cred + 32768 + 288*65536)>>16];
  438.  
  439.                 srcY1 += 2;
  440.                 srcY2 += 2;
  441.                 dst1 += 8;
  442.                 dst2 += 8;
  443.             } while(--w);
  444.  
  445.             srcY1 += ypitch;
  446.             srcY2 += ypitch;
  447.             srcCr += cpitch;
  448.             srcCb += cpitch;
  449.             dst1 += dpitch;
  450.             dst2 += dpitch;
  451.         } while((height-=2)>0);
  452.     }
  453. };
  454.  
  455. ///////////////////////////////////////////////////////////////////////////
  456.  
  457. const struct VDMPEGConverterSet g_VDMPEGConvert_reference = {
  458.     nsVDMPEGConvertReference::DecodeUYVY,
  459.     nsVDMPEGConvertReference::DecodeYUYV,
  460.     nsVDMPEGConvertReference::DecodeYVYU,
  461.     nsVDMPEGConvertReference::DecodeY41P,
  462.     nsVDMPEGConvertReference::DecodeRGB15,
  463.     nsVDMPEGConvertReference::DecodeRGB16,
  464.     nsVDMPEGConvertReference::DecodeRGB24,
  465.     nsVDMPEGConvertReference::DecodeRGB32,
  466. };
  467.