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.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  7.7 KB  |  274 lines

  1. #include <vector>
  2. #include <vd2/system/memory.h>
  3. #include <vd2/system/cpuaccel.h>
  4. #include <vd2/system/vdstl.h>
  5. #include <vd2/Kasumi/pixmap.h>
  6. #include <vd2/Kasumi/pixmaputils.h>
  7. #include <vd2/Kasumi/pixmapops.h>
  8.  
  9. #if _MSC_VER >= 1300
  10.     #define VDNOINLINE __declspec(noinline)
  11. #else
  12.     #define VDNOINLINE
  13. #endif
  14.  
  15. using namespace nsVDPixmap;
  16.  
  17. namespace {
  18.     typedef void (*tpPalettedBlitter)(void *dst, ptrdiff_t dstpitch, const void *src, ptrdiff_t srcpitch, vdpixsize w, vdpixsize h, const void *pal);
  19.     typedef void (*tpChunkyBlitter)(void *dst, ptrdiff_t dstpitch, const void *src, ptrdiff_t srcpitch, vdpixsize w, vdpixsize h);
  20.     typedef void (*tpPlanarBlitter)(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h);
  21. }
  22.  
  23. bool VDPixmapBltDirect(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h);
  24.  
  25. void VDPixmapBltDirectPalettedConversion(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h, tpPalettedBlitter pBlitter) {
  26.     uint8 palbytes[256 * 3];
  27.  
  28.     int palsize;
  29.  
  30.     switch(src.format) {
  31.     case kPixFormat_Pal1:
  32.         palsize = 2;
  33.         break;
  34.     case kPixFormat_Pal2:
  35.         palsize = 4;
  36.         break;
  37.     case kPixFormat_Pal4:
  38.         palsize = 16;
  39.         break;
  40.     case kPixFormat_Pal8:
  41.         palsize = 256;
  42.         break;
  43.     default:
  44.         VDNEVERHERE;
  45.     }
  46.  
  47.     VDASSERT(src.palette);
  48.  
  49.     VDPixmap srcpal = { (void *)src.palette, NULL, palsize, 1, 0, kPixFormat_XRGB8888 };
  50.     VDPixmap dstpal = { palbytes, NULL, palsize, 1, 0, dst.format };
  51.  
  52.     VDVERIFY(VDPixmapBltDirect(dstpal, srcpal, palsize, 1));
  53.  
  54.     pBlitter(dst.data, dst.pitch, src.data, src.pitch, w, h, palbytes);
  55. }
  56.  
  57. tpVDPixBltTable VDPixmapGetBlitterTable() {
  58. #if defined(_WIN32) && defined(_M_IX86)
  59.     static tpVDPixBltTable pBltTable;
  60.     
  61.     if (CPUGetEnabledExtensions() & CPUF_SUPPORTS_MMX) {
  62.         return VDGetPixBltTableX86MMX();
  63.     } else {
  64.         return VDGetPixBltTableX86Scalar();
  65.     }
  66. #else
  67.     static tpVDPixBltTable pBltTable = VDGetPixBltTableReference();
  68.     return pBltTable;
  69. #endif
  70. }
  71.  
  72. bool VDPixmapBltDirect(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h) {
  73.     if ((unsigned)src.format >= kPixFormat_Max_Standard) {
  74.         VDASSERT(false);
  75.         return false;
  76.     }
  77.  
  78.     if ((unsigned)dst.format >= kPixFormat_Max_Standard) {
  79.         VDASSERT(false);
  80.         return false;
  81.     }
  82.  
  83.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(src.format);
  84.  
  85.     if (src.format == dst.format) {
  86.         int qw = w;
  87.         int qh = h;
  88.  
  89.         if (srcinfo.qchunky) {
  90.             qw = (qw + srcinfo.qw - 1) / srcinfo.qw;
  91.             qh = -(-h >> srcinfo.qhbits);
  92.         }
  93.  
  94.         const int auxw = -(-w >> srcinfo.auxwbits);
  95.         const int auxh = -(-h >> srcinfo.auxhbits);
  96.  
  97.         switch(srcinfo.auxbufs) {
  98.         case 2:
  99.             VDMemcpyRect(dst.data3, dst.pitch3, src.data3, src.pitch3, srcinfo.auxsize * auxw, auxh);
  100.         case 1:
  101.             VDMemcpyRect(dst.data2, dst.pitch2, src.data2, src.pitch2, srcinfo.auxsize * auxw, auxh);
  102.         case 0:
  103.             VDMemcpyRect(dst.data, dst.pitch, src.data, src.pitch, srcinfo.qsize * qw, qh);
  104.         }
  105.  
  106.         return true;
  107.     }
  108.  
  109.     VDPixmapBlitterFn pBlitter = VDPixmapGetBlitterTable()[src.format][dst.format];
  110.  
  111.     if (!pBlitter)
  112.         return false;
  113.  
  114.     pBlitter(dst, src, w, h);
  115.     return true;
  116. }
  117.  
  118. bool VDPixmapIsBltPossible(int dst_format, int src_format) {
  119.     if (src_format == dst_format)
  120.         return true;
  121.  
  122.     tpVDPixBltTable tab(VDPixmapGetBlitterTable());
  123.  
  124.     if (tab[src_format][dst_format])
  125.         return true;
  126.  
  127.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(src_format);
  128.     const VDPixmapFormatInfo& dstinfo = VDPixmapGetInfo(dst_format);
  129.  
  130.     if (srcinfo.auxbufs > 0 || dstinfo.auxbufs > 0)
  131.         return false;        // fail, planar buffers involved (can't do scanlines independently)
  132.  
  133.     return       (tab[src_format][kPixFormat_YUV444_XVYU] && tab[kPixFormat_YUV444_XVYU][dst_format])
  134.             ||(tab[src_format][kPixFormat_XRGB8888] && tab[kPixFormat_XRGB8888][dst_format]);
  135. }
  136.  
  137. bool VDNOINLINE VDPixmapBltTwoStage(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h) {
  138.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(src.format);
  139.     const VDPixmapFormatInfo& dstinfo = VDPixmapGetInfo(dst.format);
  140.  
  141.     if (srcinfo.auxbufs > 0 || dstinfo.auxbufs > 0)
  142.         return false;        // fail, planar buffers involved
  143.  
  144.     if (srcinfo.qh > 1)
  145.         return false;        // fail, vertically packed formats involved
  146.  
  147.     if (srcinfo.palsize)
  148.         return false;        // fail, paletted formats involved
  149.  
  150.     // Allocate a 4xW buffer and try round-tripping through either
  151.     // RGB32 or XYVU.
  152.     vdblock<uint32>        tempBuf;
  153.     
  154.     tpVDPixBltTable tab(VDPixmapGetBlitterTable());
  155.  
  156.     VDPixmap linesrc(src);
  157.     VDPixmap linedst(dst);
  158.     VDPixmap linetmp = {};
  159.  
  160.     if (w < 1024) {
  161.         linetmp.data = _alloca(sizeof(uint32) * w);
  162.     } else {
  163.         tempBuf.resize(w + 1);
  164.         linetmp.data = tempBuf.data();
  165.     }
  166.     linetmp.pitch = 0;
  167.     linetmp.format = kPixFormat_YUV444_XVYU;
  168.     linetmp.w = w;
  169.     linetmp.h = 1;
  170.  
  171.     VDPixmapBlitterFn pb1 = tab[src.format][kPixFormat_YUV444_XVYU];
  172.     VDPixmapBlitterFn pb2 = tab[kPixFormat_YUV444_XVYU][dst.format];
  173.     if (!pb1 || !pb2) {
  174.         pb1 = tab[src.format][kPixFormat_XRGB8888];
  175.         pb2 = tab[kPixFormat_XRGB8888][dst.format];
  176.         if (!pb1 || !pb2)
  177.             return false;
  178.  
  179.         linetmp.format = kPixFormat_XRGB8888;
  180.     }
  181.  
  182.     do {
  183.         pb1(linetmp, linesrc, w, 1);
  184.         pb2(linedst, linetmp, w, 1);
  185.         vdptrstep(linesrc.data, linesrc.pitch);
  186.         vdptrstep(linedst.data, linedst.pitch);
  187.     } while(--h);
  188.     return true;
  189. }
  190.  
  191. bool VDPixmapBltFast(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h) {
  192.     if (VDPixmapBltDirect(dst, src, w, h))
  193.         return true;
  194.  
  195.     // Oro... let's see if we can do a two-stage conversion.
  196.     return VDPixmapBltTwoStage(dst, src, w, h);
  197. }
  198.  
  199. bool VDPixmapBlt(const VDPixmap& dst, const VDPixmap& src) {
  200.     vdpixsize w = std::min<vdpixsize>(src.w, dst.w);
  201.     vdpixsize h = std::min<vdpixsize>(src.h, dst.h);
  202.  
  203.     if (!w || !h)
  204.         return true;
  205.  
  206.     return VDPixmapBltFast(dst, src, w, h);
  207. }
  208.  
  209. bool VDPixmapBlt(const VDPixmap& dst, vdpixpos x1, vdpixpos y1, const VDPixmap& src, vdpixpos x2, vdpixpos y2, vdpixsize w, vdpixsize h) {
  210.     if (x1 < 0) {
  211.         x2 -= x1;
  212.         w -= x1;
  213.         x1 = 0;
  214.     }
  215.  
  216.     if (y1 < 0) {
  217.         y2 -= y1;
  218.         h -= y1;
  219.         y1 = 0;
  220.     }
  221.  
  222.     if (x2 < 0) {
  223.         x1 -= x2;
  224.         w -= x2;
  225.         x2 = 0;
  226.     }
  227.  
  228.     if (y2 < 0) {
  229.         y1 -= y2;
  230.         h -= y2;
  231.         y2 = 0;
  232.     }
  233.  
  234.     if (w > dst.w - x1)
  235.         w = dst.w - x1;
  236.  
  237.     if (h > dst.h - y1)
  238.         h = dst.h - y1;
  239.  
  240.     if (w > src.w - x2)
  241.         w = src.w - x2;
  242.  
  243.     if (h > src.h - y2)
  244.         h = src.h - y2;
  245.  
  246.     if (w>=0 && h >= 0) {
  247.         VDPixmap dst2(VDPixmapOffset(dst, x1, y1));
  248.         VDPixmap src2(VDPixmapOffset(src, x2, y2));
  249.  
  250.         return VDPixmapBltFast(dst2, src2, w, h);
  251.     }
  252.  
  253.     return true;
  254. }
  255.  
  256. extern bool VDPixmapStretchBltNearest_reference(const VDPixmap& dst, sint32 x1, sint32 y1, sint32 x2, sint32 y2, const VDPixmap& src, sint32 u1, sint32 v1, sint32 u2, sint32 v2);
  257. extern bool VDPixmapStretchBltBilinear_reference(const VDPixmap& dst, sint32 x1, sint32 y1, sint32 x2, sint32 y2, const VDPixmap& src, sint32 u1, sint32 v1, sint32 u2, sint32 v2);
  258.  
  259. bool VDPixmapStretchBltNearest(const VDPixmap& dst, const VDPixmap& src) {
  260.     return VDPixmapStretchBltNearest(dst, 0, 0, dst.w<<16, dst.h<<16, src, 0, 0, src.w<<16, src.h<<16);
  261. }
  262.  
  263. bool VDPixmapStretchBltNearest(const VDPixmap& dst, sint32 x1, sint32 y1, sint32 x2, sint32 y2, const VDPixmap& src, sint32 u1, sint32 v1, sint32 u2, sint32 v2) {
  264.     return VDPixmapStretchBltNearest_reference(dst, x1, y1, x2, y2, src, u1, v1, u2, v2);
  265. }
  266.  
  267. bool VDPixmapStretchBltBilinear(const VDPixmap& dst, const VDPixmap& src) {
  268.     return VDPixmapStretchBltBilinear(dst, 0, 0, dst.w<<16, dst.h<<16, src, 0, 0, src.w<<16, src.h<<16);
  269. }
  270.  
  271. bool VDPixmapStretchBltBilinear(const VDPixmap& dst, sint32 x1, sint32 y1, sint32 x2, sint32 y2, const VDPixmap& src, sint32 u1, sint32 v1, sint32 u2, sint32 v2) {
  272.     return VDPixmapStretchBltBilinear_reference(dst, x1, y1, x2, y2, src, u1, v1, u2, v2);
  273. }
  274.