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

  1. //    VirtualDub - Video processing and capture application
  2. //    A/V interface library
  3. //    Copyright (C) 1998-2004 Avery Lee
  4. //
  5. //    This program is free software; you can redistribute it and/or modify
  6. //    it under the terms of the GNU General Public License as published by
  7. //    the Free Software Foundation; either version 2 of the License, or
  8. //    (at your option) any later version.
  9. //
  10. //    This program is distributed in the hope that it will be useful,
  11. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. //    GNU General Public License for more details.
  14. //
  15. //    You should have received a copy of the GNU General Public License
  16. //    along with this program; if not, write to the Free Software
  17. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <windows.h>
  20. #include <vd2/Riza/bitmap.h>
  21. #include <vd2/Kasumi/pixmap.h>
  22. #include <vd2/Kasumi/pixmaputils.h>
  23.  
  24. int VDBitmapFormatToPixmapFormat(const VDAVIBitmapInfoHeader& hdr) {
  25.     int variant;
  26.  
  27.     return VDBitmapFormatToPixmapFormat(hdr, variant);
  28. }
  29.  
  30. int VDBitmapFormatToPixmapFormat(const VDAVIBitmapInfoHeader& hdr, int& variant) {
  31.     using namespace nsVDPixmap;
  32.  
  33.     variant = 1;
  34.  
  35.     switch(hdr.biCompression) {
  36.     case VDAVIBitmapInfoHeader::kCompressionRGB:
  37.         if (hdr.biPlanes == 1) {
  38.             if (hdr.biBitCount == 1)
  39.                 return kPixFormat_Pal1;
  40.             else if (hdr.biBitCount == 2)
  41.                 return kPixFormat_Pal2;
  42.             else if (hdr.biBitCount == 4)
  43.                 return kPixFormat_Pal4;
  44.             else if (hdr.biBitCount == 8)
  45.                 return kPixFormat_Pal8;
  46.             else if (hdr.biBitCount == 16)
  47.                 return kPixFormat_XRGB1555;
  48.             else if (hdr.biBitCount == 24)
  49.                 return kPixFormat_RGB888;
  50.             else if (hdr.biBitCount == 32)
  51.                 return kPixFormat_XRGB8888;
  52.         }
  53.         break;
  54.     case VDAVIBitmapInfoHeader::kCompressionBitfields:
  55.         {
  56.             const BITMAPV4HEADER& v4hdr = (const BITMAPV4HEADER&)hdr;
  57.             const int bits = v4hdr.bV4BitCount;
  58.             const uint32 r = v4hdr.bV4RedMask;
  59.             const uint32 g = v4hdr.bV4GreenMask;
  60.             const uint32 b = v4hdr.bV4BlueMask;
  61.  
  62.             if (bits == 16 && r == 0x7c00 && g == 0x03e0 && b == 0x001f)
  63.                 return kPixFormat_XRGB1555;
  64.             else if (bits == 16 && r == 0xf800 && g == 0x07e0 && b == 0x001f)
  65.                 return kPixFormat_RGB565;
  66.             else if (bits == 32 && r == 0xff0000 && g == 0x00ff00 && b == 0x0000ff)
  67.                 return kPixFormat_XRGB8888;
  68.         }
  69.         break;
  70.  
  71.     case VDMAKEFOURCC('U', 'Y', 'V', 'Y'):
  72.         return kPixFormat_YUV422_UYVY;
  73.  
  74.     case VDMAKEFOURCC('Y', 'U', 'Y', 'V'):
  75.     case VDMAKEFOURCC('Y', 'U', 'Y', '2'):
  76.         return kPixFormat_YUV422_YUYV;
  77.  
  78.     case VDMAKEFOURCC('Y', 'V', '2', '4'):    // Avisynth format
  79.         return kPixFormat_YUV444_Planar;
  80.  
  81.     case VDMAKEFOURCC('Y', 'V', '1', '6'):
  82.         return kPixFormat_YUV422_Planar;
  83.  
  84.     case VDMAKEFOURCC('Y', 'V', '1', '2'):
  85.         return kPixFormat_YUV420_Planar;
  86.  
  87.     case VDMAKEFOURCC('I', '4', '2', '0'):
  88.         variant = 2;
  89.         return kPixFormat_YUV420_Planar;
  90.  
  91.     case VDMAKEFOURCC('I', 'Y', 'U', 'V'):
  92.         variant = 3;
  93.         return kPixFormat_YUV420_Planar;
  94.  
  95.     case VDMAKEFOURCC('Y', 'V', 'U', '9'):
  96.         return kPixFormat_YUV410_Planar;
  97.  
  98.     case VDMAKEFOURCC('Y', '8', ' ', ' '):
  99.     case VDMAKEFOURCC('Y', '8', '0', '0'):
  100.         return kPixFormat_Y8;
  101.  
  102.     case VDMAKEFOURCC('v', '2', '1', '0'):
  103.         return kPixFormat_YUV422_V210;
  104.  
  105.     case VDMAKEFOURCC('H', 'D', 'Y', 'C'):
  106.         return kPixFormat_YUV422_UYVY_709;
  107.  
  108.     case VDMAKEFOURCC('N', 'V', '1', '2'):
  109.         return kPixFormat_YUV420_NV12;
  110.     }
  111.     return 0;
  112. }
  113.  
  114. int VDGetPixmapToBitmapVariants(int format) {
  115.     if (format == nsVDPixmap::kPixFormat_YUV420_Planar)
  116.         return 3;
  117.  
  118.     if (format == nsVDPixmap::kPixFormat_Y8)
  119.         return 2;
  120.  
  121.     return 1;
  122. }
  123.  
  124. bool VDMakeBitmapFormatFromPixmapFormat(vdstructex<VDAVIBitmapInfoHeader>& dst, const vdstructex<VDAVIBitmapInfoHeader>& src, int format, int variant) {
  125.     return VDMakeBitmapFormatFromPixmapFormat(dst, src, format, variant, src->biWidth, src->biHeight);
  126. }
  127.  
  128. bool VDMakeBitmapFormatFromPixmapFormat(vdstructex<VDAVIBitmapInfoHeader>& dst, const vdstructex<VDAVIBitmapInfoHeader>& src, int format, int variant, uint32 w, uint32 h) {
  129.     if (format == nsVDPixmap::kPixFormat_Pal8) {
  130.         if (src->biBitCount > 8)
  131.             return false;
  132.  
  133.         uint32 clrUsed = src->biClrUsed;
  134.         uint32 clrImportant = src->biClrImportant;
  135.  
  136.         if (clrUsed == 0) {
  137.             if (src->biCompression != BI_RGB && src->biCompression != BI_RLE4 && src->biCompression != BI_RLE8)
  138.                 return false;
  139.  
  140.             clrUsed = 1 << src->biBitCount;
  141.         }
  142.         if (clrUsed >= 256)
  143.             clrUsed = 0;                // means 'max for type'
  144.         if (clrImportant >= clrUsed)
  145.             clrImportant = 0;            // means 'all required'
  146.  
  147.         uint32 clrEntries = clrUsed;
  148.         if (!clrEntries)
  149.             clrEntries = 256;
  150.  
  151.         dst.resize(sizeof(VDAVIBitmapInfoHeader) + sizeof(RGBQUAD) * clrEntries);
  152.         dst->biSize                = sizeof(VDAVIBitmapInfoHeader);
  153.         dst->biWidth            = w;
  154.         dst->biHeight            = h;
  155.         dst->biPlanes            = 1;
  156.         dst->biBitCount            = 8;
  157.         dst->biCompression        = BI_RGB;
  158.         dst->biSizeImage        = ((w+3)&~3)*h;
  159.         dst->biXPelsPerMeter    = src->biXPelsPerMeter;
  160.         dst->biYPelsPerMeter    = src->biYPelsPerMeter;
  161.         dst->biClrUsed            = src->biClrUsed;
  162.         dst->biClrImportant        = src->biClrImportant;
  163.  
  164.         uint32 clrTableSize = sizeof(RGBQUAD)*clrEntries;
  165.         memcpy((char *)dst.data() + sizeof(VDAVIBitmapInfoHeader), (const char *)src.data() + src->biSize, clrTableSize);
  166.  
  167.         return true;
  168.     }
  169.  
  170.     if (!VDMakeBitmapFormatFromPixmapFormat(dst, format, variant, w, h))
  171.         return false;
  172.  
  173.     dst->biXPelsPerMeter = src->biXPelsPerMeter;
  174.     dst->biYPelsPerMeter = src->biYPelsPerMeter;
  175.  
  176.     return true;
  177. }
  178.  
  179. bool VDMakeBitmapFormatFromPixmapFormat(vdstructex<VDAVIBitmapInfoHeader>& dst, int format, int variant, uint32 w, uint32 h) {
  180.     using namespace nsVDPixmap;
  181.  
  182.     dst.resize(sizeof(VDAVIBitmapInfoHeader));
  183.     dst->biSize                = sizeof(VDAVIBitmapInfoHeader);
  184.     dst->biWidth            = w;
  185.     dst->biHeight            = h;
  186.     dst->biPlanes            = 1;
  187.     dst->biXPelsPerMeter    = 0;
  188.     dst->biYPelsPerMeter    = 0;
  189.     dst->biClrUsed            = 0;
  190.     dst->biClrImportant        = 0;
  191.  
  192.     switch(format) {
  193.     case kPixFormat_XRGB1555:
  194.         dst->biCompression    = BI_RGB;
  195.         dst->biBitCount        = 16;
  196.         dst->biSizeImage    = ((w*2+3)&~3) * h;
  197.         break;
  198.     case kPixFormat_RGB565:
  199.         dst->biCompression    = BI_BITFIELDS;
  200.         dst->biBitCount        = 16;
  201.         dst->biSizeImage    = ((w*2+3)&~3) * h;
  202.         dst.resize(sizeof(VDAVIBitmapInfoHeader) + 3*sizeof(DWORD));
  203.         {
  204.             DWORD *fields = (DWORD *)(dst.data() + 1);
  205.             fields[0] = 0xf800;
  206.             fields[1] = 0x07e0;
  207.             fields[2] = 0x001f;
  208.         }
  209.         break;
  210.     case kPixFormat_RGB888:
  211.         dst->biCompression    = BI_RGB;
  212.         dst->biBitCount        = 24;
  213.         dst->biSizeImage    = ((w*3+3)&~3) * h;
  214.         break;
  215.     case kPixFormat_XRGB8888:
  216.         dst->biCompression    = BI_RGB;
  217.         dst->biBitCount        = 32;
  218.         dst->biSizeImage    = w*4 * h;
  219.         break;
  220.     case kPixFormat_YUV422_UYVY:
  221.         dst->biCompression    = VDMAKEFOURCC('U', 'Y', 'V', 'Y');
  222.         dst->biBitCount        = 16;
  223.         dst->biSizeImage    = ((w+1)&~1)*2*h;
  224.         break;
  225.     case kPixFormat_YUV422_YUYV:
  226.         dst->biCompression    = VDMAKEFOURCC('Y', 'U', 'Y', '2');
  227.         dst->biBitCount        = 16;
  228.         dst->biSizeImage    = ((w+1)&~1)*2*h;
  229.         break;
  230.     case kPixFormat_YUV444_Planar:
  231.         dst->biCompression    = VDMAKEFOURCC('Y', 'V', '2', '4');
  232.         dst->biBitCount        = 24;
  233.         dst->biSizeImage    = w * h * 3;
  234.         break;
  235.     case kPixFormat_YUV422_Planar:
  236.         dst->biCompression    = VDMAKEFOURCC('Y', 'V', '1', '6');
  237.         dst->biBitCount        = 16;
  238.         dst->biSizeImage    = ((w+1)>>1) * h * 4;
  239.         break;
  240.     case kPixFormat_YUV420_Planar:
  241.         switch(variant) {
  242.         case 3:
  243.             dst->biCompression    = VDMAKEFOURCC('I', 'Y', 'U', 'V');
  244.             break;
  245.         case 2:
  246.             dst->biCompression    = VDMAKEFOURCC('I', '4', '2', '0');
  247.             break;
  248.         case 1:
  249.         default:
  250.             dst->biCompression    = VDMAKEFOURCC('Y', 'V', '1', '2');
  251.             break;
  252.         }
  253.         dst->biBitCount        = 12;
  254.         dst->biSizeImage    = w*h + ((w+1)>>1)*((h+1)>>1)*2;
  255.         break;
  256.     case kPixFormat_YUV410_Planar:
  257.         dst->biCompression    = VDMAKEFOURCC('Y', 'V', 'U', '9');
  258.         dst->biBitCount        = 9;
  259.         dst->biSizeImage    = ((w+2)>>2) * ((h+2)>>2) * 18;
  260.         break;
  261.     case kPixFormat_Y8:
  262.         switch(variant) {
  263.         case 2:
  264.             dst->biCompression    = VDMAKEFOURCC('Y', '8', '0', '0');
  265.             break;
  266.         case 1:
  267.         default:
  268.             dst->biCompression    = VDMAKEFOURCC('Y', '8', ' ', ' ');
  269.             break;
  270.         }
  271.         dst->biBitCount        = 8;
  272.         dst->biSizeImage    = ((w+3) & ~3) * h;
  273.         break;
  274.     case kPixFormat_YUV422_V210:
  275.         dst->biCompression    = VDMAKEFOURCC('v', '2', '1', '0');
  276.         dst->biBitCount        = 20;
  277.         dst->biSizeImage    = ((w + 23) / 24) * 64 * h;
  278.         break;
  279.     case kPixFormat_YUV422_UYVY_709:
  280.         dst->biCompression    = VDMAKEFOURCC('H', 'D', 'Y', 'C');
  281.         dst->biBitCount        = 16;
  282.         dst->biSizeImage    = ((w+1)&~1) * h * 2;
  283.         break;
  284.     case kPixFormat_YUV420_NV12:
  285.         dst->biCompression    = VDMAKEFOURCC('N', 'V', '1', '2');
  286.         dst->biBitCount        = 16;
  287.         dst->biSizeImage    = w*h + ((w+1)>>1)*((h+1)>>1)*2;
  288.         break;
  289.     default:
  290.         return false;
  291.     };
  292.  
  293.     return true;
  294. }
  295.  
  296. uint32 VDMakeBitmapCompatiblePixmapLayout(VDPixmapLayout& layout, sint32 w, sint32 h, int format, int variant, const uint32 *palette) {
  297.     using namespace nsVDPixmap;
  298.  
  299.     uint32 linspace = VDPixmapCreateLinearLayout(layout, format, w, abs(h), VDPixmapGetInfo(format).auxbufs > 1 ? 1 : 4);
  300.  
  301.     switch(format) {
  302.     case kPixFormat_Pal8:
  303.         layout.palette = palette;
  304.         // fall through
  305.     case kPixFormat_XRGB1555:
  306.     case kPixFormat_RGB888:
  307.     case kPixFormat_RGB565:
  308.     case kPixFormat_XRGB8888:
  309.         // RGB can be flipped (but YUV can't)
  310.         if (h > 0) {
  311.             layout.data += layout.pitch * (h-1);
  312.             layout.pitch = -layout.pitch;
  313.         }
  314.         break;
  315.     case kPixFormat_YUV444_Planar:        // swap YV24 to match YV12
  316.     case kPixFormat_YUV422_Planar:        // swap YV16 to match YV12
  317.         std::swap(layout.data2, layout.data3);
  318.         std::swap(layout.pitch2, layout.pitch3);
  319.         break;
  320.     case kPixFormat_YUV420_Planar:
  321.         if (variant < 2) {                // need to swap UV planes for YV12 (1)
  322.             std::swap(layout.data2, layout.data3);
  323.             std::swap(layout.pitch2, layout.pitch3);
  324.         }
  325.         break;
  326.     case kPixFormat_YUV410_Planar:
  327.         std::swap(layout.data2, layout.data3);
  328.         std::swap(layout.pitch2, layout.pitch3);
  329.         break;
  330.     }
  331.  
  332.     return linspace;
  333. }
  334.  
  335. VDPixmap VDGetPixmapForBitmap(const VDAVIBitmapInfoHeader& hdr, const void *data) {
  336.     int variant;
  337.  
  338.     int format = VDBitmapFormatToPixmapFormat(hdr, variant);
  339.     VDPixmapLayout layout;
  340.     VDMakeBitmapCompatiblePixmapLayout(layout, hdr.biWidth, hdr.biHeight, format, variant);
  341.  
  342.     return VDPixmapFromLayout(layout, (void *)data);
  343. }
  344.