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

  1. #include <vd2/Kasumi/pixmaputils.h>
  2. #include <vd2/system/memory.h>
  3.  
  4. extern VDPixmapFormatInfo g_vdPixmapFormats[] = {
  5.                                     // name         qchnk qw qh qwb qhb  qs ab aw ah as   ps
  6.     /* Null */                        { "null",        false, 1, 1,  0,  0,  0, 0, 0, 0, 0,   0 },
  7.     /* Pal1 */                        { "Pal1",         true, 8, 1,  3,  0,  1, 0, 0, 0, 0,   2 },
  8.     /* Pal2 */                        { "Pal2",         true, 4, 1,  2,  0,  1, 0, 0, 0, 0,   4 },
  9.     /* Pal4 */                        { "Pal4",         true, 2, 1,  1,  0,  1, 0, 0, 0, 0,  16 },
  10.     /* Pal8 */                        { "Pal8",        false, 1, 1,  0,  0,  1, 0, 0, 0, 0, 256 },
  11.     /* RGB16_555 */                    { "XRGB1555",    false, 1, 1,  0,  0,  2, 0, 0, 0, 0,   0 },
  12.     /* RGB16_565 */                    { "RGB565",        false, 1, 1,  0,  0,  2, 0, 0, 0, 0,   0 },
  13.     /* RGB24 */                        { "RGB888",        false, 1, 1,  0,  0,  3, 0, 0, 0, 0,   0 },
  14.     /* RGB32 */                        { "XRGB8888",    false, 1, 1,  0,  0,  4, 0, 0, 0, 0,   0 },
  15.     /* Y8 */                        { "Y8",            false, 1, 1,  0,  0,  1, 0, 0, 0, 0,   0 },
  16.     /* YUV422_UYVY */                { "UYVY",         true, 2, 1,  1,  0,  4, 0, 0, 0, 0,   0 },
  17.     /* YUV422_YUYV */                { "YUYV",         true, 2, 1,  1,  0,  4, 0, 0, 0, 0,   0 },
  18.     /* YUV444_XVYU */                { "XVYU",        false, 1, 1,  0,  0,  4, 0, 0, 0, 0,   0 },
  19.     /* YUV444_Planar */                { "YUV444",        false, 1, 1,  0,  0,  1, 2, 0, 0, 1,   0 },
  20.     /* YUV422_Planar */                { "YUV422",        false, 1, 1,  0,  0,  1, 2, 1, 0, 1,   0 },
  21.     /* YUV420_Planar */                { "YUV420",        false, 1, 1,  0,  0,  1, 2, 1, 1, 1,   0 },
  22.     /* YUV411_Planar */                { "YUV411",        false, 1, 1,  0,  0,  1, 2, 2, 0, 1,   0 },
  23.     /* YUV410_Planar */                { "YUV410",        false, 1, 1,  0,  0,  1, 2, 2, 2, 1,   0 },
  24.     /* YUV422_Planar_Centered */    { "YUV422C",    false, 1, 1,  0,  0,  1, 2, 1, 0, 1,   0 },
  25.     /* YUV420_Planar_Centered */    { "YUV420C",    false, 1, 1,  0,  0,  1, 2, 1, 1, 1,   0 },
  26.     /* YUV422_Planar_16F */            { "YUV422_16F",    false, 1, 1,  0,  0,  2, 2, 1, 0, 2,   0 },
  27.     /* V210 */                        { "v210",         true,24, 1,  2,  0, 64, 0, 0, 0, 1,   0 },
  28.     /* YUV422_UYVY_709 */            { "UYVY-709",     true, 2, 1,  1,  0,  4, 0, 0, 0, 0,   0 },
  29.     /* NV12 */                        { "NV12",        false, 1, 1,  0,  0,  1, 1, 1, 1, 2,   0 },
  30. };
  31.  
  32. #ifdef _DEBUG
  33.     bool VDIsValidPixmapPlane(const void *p, ptrdiff_t pitch, vdpixsize w, vdpixsize h) {
  34.         bool isvalid;
  35.  
  36.         if (pitch < 0)
  37.             isvalid = VDIsValidReadRegion((const char *)p + pitch*(h-1), (-pitch)*(h-1)+w);
  38.         else
  39.             isvalid = VDIsValidReadRegion(p, pitch*(h-1)+w);
  40.  
  41.         if (!isvalid) {
  42.             VDDEBUG("Kasumi: Invalid pixmap plane detected.\n"
  43.                     "        Base=%p, pitch=%d, size=%dx%d (bytes)\n", p, (int)pitch, w, h);
  44.         }
  45.  
  46.         return isvalid;
  47.     }
  48.  
  49.     bool VDAssertValidPixmap(const VDPixmap& px) {
  50.         const VDPixmapFormatInfo& info = VDPixmapGetInfo(px.format);
  51.  
  52.         if (px.format) {
  53.             if (!VDIsValidPixmapPlane(px.data, px.pitch, -(-px.w / info.qw)*info.qsize, -(-px.h >> info.qhbits))) {
  54.                 VDDEBUG("Kasumi: Invalid primary plane detected in pixmap.\n"
  55.                         "        Pixmap info: format=%d (%s), dimensions=%dx%d\n", px.format, info.name, px.w, px.h);
  56.                 VDASSERT(!"Kasumi: Invalid primary plane detected in pixmap.\n");
  57.                 return false;
  58.             }
  59.  
  60.             if (info.palsize)
  61.                 if (!VDIsValidReadRegion(px.palette, sizeof(uint32) * info.palsize)) {
  62.                     VDDEBUG("Kasumi: Invalid palette detected in pixmap.\n"
  63.                             "        Pixmap info: format=%d (%s), dimensions=%dx%d\n", px.format, info.name, px.w, px.h);
  64.                     VDASSERT(!"Kasumi: Invalid palette detected in pixmap.\n");
  65.                     return false;
  66.                 }
  67.  
  68.             if (info.auxbufs) {
  69.                 const vdpixsize auxw = -(-px.w >> info.auxwbits);
  70.                 const vdpixsize auxh = -(-px.h >> info.auxhbits);
  71.  
  72.                 if (!VDIsValidPixmapPlane(px.data2, px.pitch2, auxw * info.auxsize, auxh)) {
  73.                     VDDEBUG("Kasumi: Invalid Cb plane detected in pixmap.\n"
  74.                             "        Pixmap info: format=%d (%s), dimensions=%dx%d\n", px.format, info.name, px.w, px.h);
  75.                     VDASSERT(!"Kasumi: Invalid Cb plane detected in pixmap.\n");
  76.                     return false;
  77.                 }
  78.  
  79.                 if (info.auxbufs > 2) {
  80.                     if (!VDIsValidPixmapPlane(px.data3, px.pitch3, auxw * info.auxsize, auxh)) {
  81.                         VDDEBUG("Kasumi: Invalid Cr plane detected in pixmap.\n"
  82.                                 "        Pixmap info: format=%d, dimensions=%dx%d\n", px.format, px.w, px.h);
  83.                         VDASSERT(!"Kasumi: Invalid Cr plane detected in pixmap.\n");
  84.                         return false;
  85.                     }
  86.                 }
  87.             }
  88.         }
  89.  
  90.         return true;
  91.     }
  92. #endif
  93.  
  94. VDPixmap VDPixmapOffset(const VDPixmap& src, vdpixpos x, vdpixpos y) {
  95.     VDPixmap temp(src);
  96.     const VDPixmapFormatInfo& info = VDPixmapGetInfo(temp.format);
  97.  
  98.     if (info.qchunky) {
  99.         x = (x + info.qw - 1) / info.qw;
  100.         y >>= info.qhbits;
  101.     }
  102.  
  103.     switch(info.auxbufs) {
  104.     case 2:
  105.         temp.data3 = (char *)temp.data3 + (x >> info.auxwbits)*info.auxsize + (y >> info.auxhbits)*temp.pitch3;
  106.     case 1:
  107.         temp.data2 = (char *)temp.data2 + (x >> info.auxwbits)*info.auxsize + (y >> info.auxhbits)*temp.pitch2;
  108.     case 0:
  109.         temp.data = (char *)temp.data + x*info.qsize + y*temp.pitch;
  110.     }
  111.  
  112.     return temp;
  113. }
  114.  
  115. VDPixmapLayout VDPixmapLayoutOffset(const VDPixmapLayout& src, vdpixpos x, vdpixpos y) {
  116.     VDPixmapLayout temp(src);
  117.     const VDPixmapFormatInfo& info = VDPixmapGetInfo(temp.format);
  118.  
  119.     if (info.qchunky) {
  120.         x = (x + info.qw - 1) / info.qw;
  121.         y = -(-y >> info.qhbits);
  122.     }
  123.  
  124.     switch(info.auxbufs) {
  125.     case 2:
  126.         temp.data3 += -(-x >> info.auxwbits)*info.auxsize + -(-y >> info.auxhbits)*temp.pitch3;
  127.     case 1:
  128.         temp.data2 += -(-x >> info.auxwbits)*info.auxsize + -(-y >> info.auxhbits)*temp.pitch2;
  129.     case 0:
  130.         temp.data += x*info.qsize + y*temp.pitch;
  131.     }
  132.  
  133.     return temp;
  134. }
  135.  
  136. uint32 VDPixmapCreateLinearLayout(VDPixmapLayout& layout, int format, vdpixsize w, vdpixsize h, int alignment) {
  137.     const ptrdiff_t alignmask = alignment - 1;
  138.  
  139.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(format);
  140.     sint32        qw            = (w + srcinfo.qw - 1) / srcinfo.qw;
  141.     sint32        qh            = -(-h >> srcinfo.qhbits);
  142.     sint32        subw        = -(-w >> srcinfo.auxwbits);
  143.     sint32        subh        = -(-h >> srcinfo.auxhbits);
  144.     sint32        auxsize        = srcinfo.auxsize;
  145.  
  146.     ptrdiff_t    mainpitch    = (srcinfo.qsize * qw + alignmask) & ~alignmask;
  147.     size_t        mainsize    = mainpitch * qh;
  148.  
  149.     layout.data        = 0;
  150.     layout.pitch    = mainpitch;
  151.     layout.palette    = NULL;
  152.     layout.data2    = 0;
  153.     layout.pitch2    = 0;
  154.     layout.data3    = 0;
  155.     layout.pitch3    = 0;
  156.     layout.w        = w;
  157.     layout.h        = h;
  158.     layout.format    = format;
  159.  
  160.     if (srcinfo.auxbufs >= 1) {
  161.         ptrdiff_t    subpitch    = (subw * auxsize + alignmask) & ~alignmask;
  162.         size_t        subsize        = subpitch * subh;
  163.  
  164.         layout.data2    = mainsize;
  165.         layout.pitch2    = subpitch;
  166.         mainsize += subsize;
  167.  
  168.         if (srcinfo.auxbufs >= 2) {
  169.             layout.data3    = mainsize;
  170.             layout.pitch3    = subpitch;
  171.             mainsize += subsize;
  172.         }
  173.     }
  174.  
  175.     return mainsize;
  176. }
  177.  
  178. void VDPixmapFlipV(VDPixmap& px) {
  179.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(px.format);
  180.     sint32        w            = px.w;
  181.     sint32        h            = px.h;
  182.     sint32        qw            = (w + srcinfo.qw - 1) / srcinfo.qw;
  183.     sint32        qh            = -(-h >> srcinfo.qhbits);
  184.     sint32        subh        = -(-h >> srcinfo.auxhbits);
  185.  
  186.     vdptrstep(px.data, px.pitch * (qh - 1));
  187.     px.pitch = -px.pitch;
  188.  
  189.     if (srcinfo.auxbufs >= 1) {
  190.         vdptrstep(px.data2, px.pitch2 * (subh - 1));
  191.         px.pitch2 = -px.pitch2;
  192.  
  193.         if (srcinfo.auxbufs >= 2) {
  194.             vdptrstep(px.data3, px.pitch3 * (subh - 1));
  195.             px.pitch3 = -px.pitch3;
  196.         }
  197.     }
  198. }
  199.  
  200. void VDPixmapLayoutFlipV(VDPixmapLayout& layout) {
  201.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(layout.format);
  202.     sint32        w            = layout.w;
  203.     sint32        h            = layout.h;
  204.     sint32        qw            = (w + srcinfo.qw - 1) / srcinfo.qw;
  205.     sint32        qh            = -(-h >> srcinfo.qhbits);
  206.     sint32        subh        = -(-h >> srcinfo.auxhbits);
  207.  
  208.     layout.data += layout.pitch * (qh - 1);
  209.     layout.pitch = -layout.pitch;
  210.  
  211.     if (srcinfo.auxbufs >= 1) {
  212.         layout.data2 += layout.pitch2 * (subh - 1);
  213.         layout.pitch2 = -layout.pitch2;
  214.  
  215.         if (srcinfo.auxbufs >= 2) {
  216.             layout.data3 += layout.pitch3 * (subh - 1);
  217.             layout.pitch3 = -layout.pitch3;
  218.         }
  219.     }
  220. }
  221.  
  222. uint32 VDPixmapLayoutGetMinSize(const VDPixmapLayout& layout) {
  223.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(layout.format);
  224.     sint32        w            = layout.w;
  225.     sint32        h            = layout.h;
  226.     sint32        qw            = (w + srcinfo.qw - 1) / srcinfo.qw;
  227.     sint32        qh            = -(-h >> srcinfo.qhbits);
  228.     sint32        subh        = -(-h >> srcinfo.auxhbits);
  229.  
  230.     uint32 limit = layout.data;
  231.     if (layout.pitch >= 0)
  232.         limit += layout.pitch * qh;
  233.     else
  234.         limit -= layout.pitch;
  235.  
  236.     if (srcinfo.auxbufs >= 1) {
  237.         uint32 limit2 = layout.data2;
  238.  
  239.         if (layout.pitch2 >= 0)
  240.             limit2 += layout.pitch2 * subh;
  241.         else
  242.             limit2 -= layout.pitch2;
  243.  
  244.         if (limit < limit2)
  245.             limit = limit2;
  246.  
  247.         if (srcinfo.auxbufs >= 2) {
  248.             uint32 limit3 = layout.data3;
  249.  
  250.             if (layout.pitch3 >= 0)
  251.                 limit3 += layout.pitch3 * subh;
  252.             else
  253.                 limit3 -= layout.pitch3;
  254.  
  255.             if (limit < limit3)
  256.                 limit = limit3;
  257.         }
  258.     }
  259.  
  260.     return limit;
  261. }
  262.  
  263. VDPixmap VDPixmapExtractField(const VDPixmap& src, bool field2) {
  264.     VDPixmap px(src);
  265.  
  266.     if (field2) {
  267.         const VDPixmapFormatInfo& info = VDPixmapGetInfo(px.format);
  268.  
  269.         if (px.data) {
  270.             if (info.qh == 1)
  271.                 vdptrstep(px.data, px.pitch);
  272.  
  273.             if (!info.auxhbits) {
  274.                 vdptrstep(px.data2, px.pitch2);
  275.                 vdptrstep(px.data3, px.pitch3);
  276.             }
  277.         }
  278.     }
  279.  
  280.     px.h >>= 1;
  281.     px.pitch += px.pitch;
  282.     px.pitch2 += px.pitch2;
  283.     px.pitch3 += px.pitch3;
  284.     return px;
  285. }
  286.  
  287. ///////////////////////////////////////////////////////////////////////////
  288.  
  289. VDPixmapBuffer::VDPixmapBuffer(const VDPixmap& src)
  290.     : mpBuffer(NULL)
  291.     , mLinearSize(0)
  292. {
  293.     assign(src);
  294. }
  295.  
  296. VDPixmapBuffer::VDPixmapBuffer(const VDPixmapBuffer& src)
  297.     : mpBuffer(NULL)
  298.     , mLinearSize(0)
  299. {
  300.     assign(src);
  301. }
  302.  
  303. VDPixmapBuffer::VDPixmapBuffer(const VDPixmapLayout& layout) {
  304.     init(layout);
  305. }
  306.  
  307. VDPixmapBuffer::~VDPixmapBuffer() {
  308. #ifdef _DEBUG
  309.     validate();
  310. #endif
  311.  
  312.     delete[] mpBuffer;
  313. }
  314.  
  315. void VDPixmapBuffer::init(sint32 width, sint32 height, int f) {
  316.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(f);
  317.     sint32        qw            = (width + srcinfo.qw - 1) / srcinfo.qw;
  318.     sint32        qh            = -(-height >> srcinfo.qhbits);
  319.     sint32        subw        = -(-width >> srcinfo.auxwbits);
  320.     sint32        subh        = -(-height >> srcinfo.auxhbits);
  321.     ptrdiff_t    mainpitch    = (srcinfo.qsize * qw + 15) & ~15;
  322.     ptrdiff_t    subpitch    = (srcinfo.auxsize * subw + 15) & ~15;
  323.     size_t        mainsize    = mainpitch * qh;
  324.     size_t        subsize        = subpitch * subh;
  325.     size_t        totalsize    = mainsize + subsize*srcinfo.auxbufs + 4 * srcinfo.palsize;
  326.  
  327. #ifdef _DEBUG
  328.     totalsize += 28;
  329. #endif
  330.  
  331.     if (mLinearSize != totalsize) {
  332.         clear();
  333.         mpBuffer = new char[totalsize + 15];
  334.         mLinearSize = totalsize;
  335.     }
  336.  
  337.     char *p = mpBuffer + (-(int)(uintptr)mpBuffer & 15);
  338.  
  339. #ifdef _DEBUG
  340.     *(uint32 *)p = totalsize;
  341.     for(int i=0; i<12; ++i)
  342.         p[4+i] = (char)(0xa0 + i);
  343.  
  344.     p += 16;
  345. #endif
  346.  
  347.     data    = p;
  348.     pitch    = mainpitch;
  349.     p += mainsize;
  350.  
  351.     palette    = NULL;
  352.     data2    = NULL;
  353.     pitch2    = NULL;
  354.     data3    = NULL;
  355.     pitch3    = NULL;
  356.     w        = width;
  357.     h        = height;
  358.     format    = f;
  359.  
  360.     if (srcinfo.auxbufs >= 1) {
  361.         data2    = p;
  362.         pitch2    = subpitch;
  363.         p += subsize;
  364.     }
  365.  
  366.     if (srcinfo.auxbufs >= 2) {
  367.         data3    = p;
  368.         pitch3    = subpitch;
  369.         p += subsize;
  370.     }
  371.  
  372.     if (srcinfo.palsize) {
  373.         palette = (const uint32 *)p;
  374.         p += srcinfo.palsize * 4;
  375.     }
  376.  
  377. #ifdef _DEBUG
  378.     for(int j=0; j<12; ++j)
  379.         p[j] = (char)(0xb0 + j);
  380. #endif
  381. }
  382.  
  383. void VDPixmapBuffer::init(const VDPixmapLayout& layout) {
  384.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(layout.format);
  385.     sint32        qw            = (layout.w + srcinfo.qw - 1) / srcinfo.qw;
  386.     sint32        qh            = -(-layout.h >> srcinfo.qhbits);
  387.     sint32        subw        = -(-layout.w >> srcinfo.auxwbits);
  388.     sint32        subh        = -(-layout.h >> srcinfo.auxhbits);
  389.  
  390.     ptrdiff_t mino=0, maxo=0;
  391.  
  392.     if (layout.pitch < 0) {
  393.         mino = std::min<ptrdiff_t>(mino, layout.data + layout.pitch * (qh-1));
  394.         maxo = std::max<ptrdiff_t>(maxo, layout.data - layout.pitch);
  395.     } else {
  396.         mino = std::min<ptrdiff_t>(mino, layout.data);
  397.         maxo = std::max<ptrdiff_t>(maxo, layout.data + layout.pitch*qh);
  398.     }
  399.  
  400.     if (srcinfo.auxbufs >= 1) {
  401.         if (layout.pitch2 < 0) {
  402.             mino = std::min<ptrdiff_t>(mino, layout.data2 + layout.pitch2 * (subh-1));
  403.             maxo = std::max<ptrdiff_t>(maxo, layout.data2 - layout.pitch2);
  404.         } else {
  405.             mino = std::min<ptrdiff_t>(mino, layout.data2);
  406.             maxo = std::max<ptrdiff_t>(maxo, layout.data2 + layout.pitch2*subh);
  407.         }
  408.  
  409.         if (srcinfo.auxbufs >= 2) {
  410.             if (layout.pitch3 < 0) {
  411.                 mino = std::min<ptrdiff_t>(mino, layout.data3 + layout.pitch3 * (subh-1));
  412.                 maxo = std::max<ptrdiff_t>(maxo, layout.data3 - layout.pitch3);
  413.             } else {
  414.                 mino = std::min<ptrdiff_t>(mino, layout.data3);
  415.                 maxo = std::max<ptrdiff_t>(maxo, layout.data3 + layout.pitch3*subh);
  416.             }
  417.         }
  418.     }
  419.  
  420.     ptrdiff_t linsize = ((maxo - mino + 3) & ~(uintptr)3);
  421.  
  422.     ptrdiff_t totalsize = linsize + 4*srcinfo.palsize;
  423.  
  424. #ifdef _DEBUG
  425.     totalsize += 28;
  426. #endif
  427.  
  428.     if (mLinearSize != totalsize) {
  429.         clear();
  430.         mpBuffer = new char[totalsize + 15];
  431.         mLinearSize = totalsize;
  432.     }
  433.  
  434.     char *p = mpBuffer + (-(int)(uintptr)mpBuffer & 15);
  435.  
  436. #ifdef _DEBUG
  437.     *(uint32 *)p = totalsize - 28;
  438.     for(int i=0; i<12; ++i)
  439.         p[4+i] = (char)(0xa0 + i);
  440.  
  441.     p += 16;
  442. #endif
  443.  
  444.     w        = layout.w;
  445.     h        = layout.h;
  446.     format    = layout.format;
  447.     data    = p + layout.data - mino;
  448.     data2    = p + layout.data2 - mino;
  449.     data3    = p + layout.data3 - mino;
  450.     pitch    = layout.pitch;
  451.     pitch2    = layout.pitch2;
  452.     pitch3    = layout.pitch3;
  453.     palette    = NULL;
  454.  
  455.     if (srcinfo.palsize) {
  456.         palette = (const uint32 *)(p + linsize);
  457.         memcpy((void *)palette, layout.palette, 4*srcinfo.palsize);
  458.     }
  459.  
  460. #ifdef _DEBUG
  461.     for(int j=0; j<12; ++j)
  462.         p[totalsize + j - 28] = (char)(0xb0 + j);
  463. #endif
  464.  
  465.     VDAssertValidPixmap(*this);
  466. }
  467.  
  468. void VDPixmapBuffer::assign(const VDPixmap& src) {
  469.     if (!src.format) {
  470.         delete[] mpBuffer;
  471.         mpBuffer = NULL;
  472.         data = NULL;
  473.         format = 0;
  474.     } else {
  475.         init(src.w, src.h, src.format);
  476.  
  477.         const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(src.format);
  478.         int qw = (src.w + srcinfo.qw - 1) / srcinfo.qw;
  479.         int qh = -(-src.h >> srcinfo.qhbits);
  480.         int subw = -(-src.w >> srcinfo.auxwbits);
  481.         int subh = -(-src.h >> srcinfo.auxhbits);
  482.  
  483.         if (srcinfo.palsize)
  484.             memcpy((void *)palette, src.palette, 4 * srcinfo.palsize);
  485.  
  486.         switch(srcinfo.auxbufs) {
  487.         case 2:
  488.             VDMemcpyRect(data3, pitch3, src.data3, src.pitch3, subw, subh);
  489.         case 1:
  490.             VDMemcpyRect(data2, pitch2, src.data2, src.pitch2, subw, subh);
  491.         case 0:
  492.             VDMemcpyRect(data, pitch, src.data, src.pitch, qw * srcinfo.qsize, qh);
  493.         }
  494.     }
  495. }
  496.  
  497. void VDPixmapBuffer::swap(VDPixmapBuffer& dst) {
  498.     std::swap(mpBuffer, dst.mpBuffer);
  499.     std::swap(mLinearSize, dst.mLinearSize);
  500.     std::swap(static_cast<VDPixmap&>(*this), static_cast<VDPixmap&>(dst));
  501. }
  502.  
  503. #ifdef _DEBUG
  504. void VDPixmapBuffer::validate() {
  505.     if (mpBuffer) {
  506.         char *p = (char *)(((uintptr)mpBuffer + 15) & ~(uintptr)15);
  507.  
  508.         // verify head bytes
  509.         for(int i=0; i<12; ++i)
  510.             if (p[i+4] != (char)(0xa0 + i))
  511.                 VDASSERT(!"VDPixmapBuffer: Buffer underflow detected.\n");
  512.  
  513.         // verify tail bytes
  514.         for(int j=0; j<12; ++j)
  515.             if (p[mLinearSize - 12 + j] != (char)(0xb0 + j))
  516.                 VDASSERT(!"VDPixmapBuffer: Buffer overflow detected.\n");
  517.     }
  518. }
  519. #endif
  520.