// Assign a DirectShow YUV sample to a YUV_frame extern HRESULT YUV_frame_from_DirectShow(const CMediaType* pMT, BYTE* buff, YUV_frame* pFrame) { BITMAPINFOHEADER* pBmi; pBmi = GetBMI(pMT); if (pBmi == NULL) return E_UNEXPECTED; // set line stride if ((pBmi->biBitCount != 0) && ((pBmi->biBitCount & 7) == 0)) // For 'normal' formats, biWidth is in pixels. // Expand to bytes and round up to a multiple of 4. pFrame->Y.lineStride = ((pBmi->biWidth * (pBmi->biBitCount / 8)) + 3) & ~3; else // Otherwise, biWidth is in bytes. pFrame->Y.lineStride = pBmi->biWidth; // set pixel stride switch (pBmi->biCompression) { case FCC('YV12'): case FCC('IF09'): case FCC('YVU9'): case FCC('IYUV'): // planar formats pFrame->Y.pixelStride = 1; break; case FCC('UYVY'): case FCC('YUY2'): case FCC('YVYU'): case FCC('HDYC'): // multiplexed formats pFrame->Y.pixelStride = 2; break; default: return E_UNEXPECTED; } // set dimensions RECT* rcTarget = GetTargetRect(pMT); // If rcTarget is empty, use the whole image. if (IsRectEmpty(rcTarget)) { pFrame->Y.w = pBmi->biWidth; pFrame->Y.h = abs(pBmi->biHeight); } else // rcTarget is NOT empty. Use a sub-rectangle in the image. { pFrame->Y.w = rcTarget->right - rcTarget->left; pFrame->Y.h = rcTarget->bottom - rcTarget->top; buff += (rcTarget->top * pFrame->Y.lineStride) + (rcTarget->left * pFrame->Y.pixelStride); } // set subsampling pFrame->U = pFrame->Y; switch (pBmi->biCompression) { case FCC('UYVY'): case FCC('YUY2'): case FCC('YVYU'): case FCC('HDYC'): // horizontal 2:1 pFrame->U.w = pFrame->Y.w / 2; pFrame->U.pixelStride = pFrame->Y.pixelStride * 2; break; case FCC('YV12'): case FCC('IYUV'): // horizontal 2:1, vertical 2:1 pFrame->U.w = pFrame->Y.w / 2; pFrame->U.h = pFrame->Y.h / 2; pFrame->U.lineStride = pFrame->Y.lineStride / 2; break; case FCC('IF09'): case FCC('YVU9'): // horizontal 4:1, vertical 4:1 pFrame->U.w = pFrame->Y.w / 4; pFrame->U.h = pFrame->Y.h / 4; pFrame->U.lineStride = pFrame->Y.lineStride / 4; break; default: return E_UNEXPECTED; } pFrame->V = pFrame->U; // set buffer pointers switch (pBmi->biCompression) { case FCC('UYVY'): case FCC('HDYC'): pFrame->Y.buff = buff + 1; pFrame->U.buff = buff; pFrame->V.buff = buff + 2; break; case FCC('YUY2'): pFrame->Y.buff = buff; pFrame->U.buff = buff + 1; pFrame->V.buff = buff + 3; break; case FCC('YVYU'): pFrame->Y.buff = buff; pFrame->U.buff = buff + 3; pFrame->V.buff = buff + 1; break; case FCC('IYUV'): case FCC('IF09'): case FCC('YVU9'): pFrame->Y.buff = buff; pFrame->U.buff = pFrame->Y.buff + (pFrame->Y.lineStride * pFrame->Y.h); pFrame->V.buff = pFrame->U.buff + (pFrame->U.lineStride * pFrame->U.h); break; case FCC('YV12'): pFrame->Y.buff = buff; pFrame->V.buff = pFrame->Y.buff + (pFrame->Y.lineStride * pFrame->Y.h); pFrame->U.buff = pFrame->V.buff + (pFrame->V.lineStride * pFrame->V.h); break; default: return E_UNEXPECTED; } return S_OK; }
BOOL TilePropWindow::DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch ( msg ) { case WM_ACTIVATE: if ( LOWORD(wParam) != WA_INACTIVE ) chkd.SetCurrDialog(hWnd); break; case WM_INITDIALOG: { HWND hEdit = GetDlgItem(hWnd, IDC_EDIT_TILEVALUE); SendMessage(hEdit, EM_SETLIMITTEXT, 10, 0); UpdateTile(); PostMessage(hWnd, WM_NEXTDLGCTL, (WPARAM)hEdit, true); return true; } break; case WM_PAINT: { RECT rect; GetClientRect(hWnd, &rect); int width = 32, height = 32; PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps), MemhDC = CreateCompatibleDC(hDC); HBITMAP Membitmap = CreateCompatibleBitmap(hDC, width, height); SelectObject(MemhDC, Membitmap); TCHAR lpszTile[11]; int TextLength = WORD(SendDlgItemMessage(hWnd, IDC_EDIT_TILEVALUE, EM_LINELENGTH, 0, 0)); *((LPWORD)lpszTile) = TextLength; SendDlgItemMessage(hWnd, IDC_EDIT_TILEVALUE, EM_GETLINE, 0, (LPARAM)lpszTile); lpszTile[TextLength] = '\0'; u16 tile = atoi(lpszTile), tileset = CM->getTileset(); TileSet* tiles = &chkd.scData.tilesets.set[tileset]; HBRUSH brush = CreateSolidBrush(RGB(166, 156, 132)); FillRect(MemhDC, &rect, brush); DeleteObject(brush); BITMAPINFO bmi = GetBMI(32, 32); DrawTile(MemhDC, tiles, 0, 0, tile, bmi, 0, 0, 0); BitBlt(hDC, 55, 50, width, height, MemhDC, 0, 0, SRCCOPY); BITMAPINFO bmiMini = GetBMI(8, 8); for ( int yMiniTile=0; yMiniTile<4; yMiniTile++ ) { for ( int xMiniTile=0; xMiniTile<4; xMiniTile++ ) DrawMiniTileElevation(hDC, tiles, 350+xMiniTile*9, 50+yMiniTile*9, tile, xMiniTile, yMiniTile, bmiMini); } DeleteObject(Membitmap); DeleteDC (MemhDC); DeleteDC (hDC); } break; case WM_DESTROY: EndDialog(hWnd, IDCANCEL); break; default: return false; break; } return 0; }
////////////////////////////////////////////////////////////////////// // Draw DIB on caller's DC. Does stretching from source to destination // rectangles. Generally, you can let the following default to zero/NULL: // // nStretchMode= 0 means 'use DrawDib'; any other value must be // a valid stretch-mode and will force GDI usage // hPal = palette, default=NULL, (use DIB's palette) // bForeground = realize in foreground (default true) // // If you are handling palette messages, you should use bForeground=false, // since you will realize the foreground palette in WM_QUERYNEWPALETTE. // BOOL PLWinBmpEx::DrawEx( HDC dc, const RECT* rcDst, const RECT* rcSrc, HPALETTE hPal, bool bForeground, int nStretchMode, DWORD ropcode ) { // Select, realize palette if (hPal==NULL) // no palette specified: hPal = GetLogPalette(); // use default HPALETTE hOldPal = ::SelectPalette(dc, hPal, !bForeground); ::RealizePalette(dc); // Compute rectangles where NULL specified RECT rc; if (!rcSrc) { // if no source rect, use whole bitmap rc.left = rc.top = 0; rc.right = GetWidth(); rc.bottom = GetHeight(); rcSrc = &rc; } if (!rcDst) // if no destination rect, use source rcDst = rcSrc; BOOL bRet = false; #ifndef _WITHOUT_VFW_ bool bUseDrawDib = nStretchMode < 0; if (bUseDrawDib) { if (!m_hdd) VERIFY(m_hdd = DrawDibOpen()); // Let DrawDib do the work! bRet = ::DrawDibDraw( m_hdd, dc, rcDst->left, rcDst->top, rcDst->right - rcDst->left, rcDst->bottom - rcDst->top, GetBMI(), GetBits(), rcSrc->left, rcSrc->top, rcSrc->right - rcSrc->left, rcSrc->bottom - rcSrc->top, bForeground ? 0 : DDF_BACKGROUNDPAL); } else // use normal draw function #endif { // If user wanted DrawDib but vfw support is not linked in, // then try to use best looking GDI mode if (nStretchMode < 0) nStretchMode = HALFTONE; int osm = 0; if (nStretchMode > 0) osm = ::SetStretchBltMode( dc, nStretchMode ); #if 0 // way too slooooooooooooooooooow! bRet = GDI_ERROR != ::StretchDIBits( dc, rcDst->left, rcDst->top, rcDst->right - rcDst->left, rcDst->bottom - rcDst->top, rcSrc->left, rcSrc->top, rcSrc->right - rcSrc->left, rcSrc->bottom - rcSrc->top, GetBits(), // Pointer to bits (BITMAPINFO*) GetBMI(), // BITMAPINFO DIB_RGB_COLORS, // Options ropcode); // Raster operator code #else HDC hSrcDC; hSrcDC = CreateCompatibleDC (dc); HGDIOBJ hOldBmp = ::SelectObject (hSrcDC, GetHandle()); if (m_pClrTab) // uses associated colormap (void) ::SetDIBColorTable (hSrcDC, 0, 256, (RGBQUAD *)m_pClrTab); bRet = ::StretchBlt ( dc, rcDst->left, rcDst->top, rcDst->right - rcDst->left, rcDst->bottom - rcDst->top, hSrcDC, rcSrc->left, rcSrc->top, rcSrc->right - rcSrc->left, rcSrc->bottom - rcSrc->top, ropcode ); ::SelectObject (hSrcDC, hOldBmp); ::DeleteDC(hSrcDC); // restore GDI stretch-mode if (osm) (void) ::SetStretchBltMode( dc, osm ); } #endif // _WITHOUT_VFW_ // restore DC palette if (hOldPal) ::SelectPalette(dc, hOldPal, true); return bRet; }