/*********************************************************************** * DrawDibRealize [MSVFW32.@] */ UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) { WINE_HDD *whdd; UINT ret = 0; FIXME("(%p, %p, %d), stub\n", hdd, hdc, fBackground); whdd = MSVIDEO_GetHddPtr(hdd); if (!whdd) return FALSE; if (!whdd->begun) { ret = 0; goto out; } if (!whdd->hpal) whdd->hpal = CreateHalftonePalette(hdc); SelectPalette(hdc, whdd->hpal, fBackground); ret = RealizePalette(hdc); out: TRACE("=> %u\n", ret); return ret; }
/*********************************************************************** * DrawDibGetPalette [MSVFW32.@] */ HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) { WINE_HDD *whdd; TRACE("(%p)\n", hdd); whdd = MSVIDEO_GetHddPtr(hdd); if (!whdd) return FALSE; return whdd->hpal; }
/*********************************************************************** * DrawDibOpen [MSVFW32.@] */ HDRAWDIB VFWAPI DrawDibOpen(void) { WINE_HDD* whdd; TRACE("(void)\n"); whdd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_HDD)); TRACE("=> %p\n", whdd); while (MSVIDEO_GetHddPtr((HDRAWDIB)HDD_HandleRef) != NULL) HDD_HandleRef++; whdd->hSelf = (HDRAWDIB)HDD_HandleRef++; whdd->next = HDD_FirstHdd; HDD_FirstHdd = whdd; return whdd->hSelf; }
/*********************************************************************** * DrawDibSetPalette [MSVFW32.@] */ BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) { WINE_HDD *whdd; TRACE("(%p, %p)\n", hdd, hpal); whdd = MSVIDEO_GetHddPtr(hdd); if (!whdd) return FALSE; whdd->hpal = hpal; if (whdd->begun) { SelectPalette(whdd->hdc, hpal, 0); RealizePalette(whdd->hdc); } return TRUE; }
/*********************************************************************** * DrawDibEnd [MSVFW32.@] */ BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) { BOOL ret = TRUE; WINE_HDD *whdd = MSVIDEO_GetHddPtr(hdd); TRACE("(%p)\n", hdd); if (!whdd) return FALSE; whdd->hpal = 0; /* Do not free this */ whdd->hdc = 0; HeapFree(GetProcessHeap(), 0, whdd->lpbi); whdd->lpbi = NULL; HeapFree(GetProcessHeap(), 0, whdd->lpbiOut); whdd->lpbiOut = NULL; whdd->begun = FALSE; /*if (whdd->lpvbits) HeapFree(GetProcessHeap(), 0, whdd->lpvbuf);*/ if (whdd->hMemDC) { SelectObject(whdd->hMemDC, whdd->hOldDib); DeleteDC(whdd->hMemDC); whdd->hMemDC = 0; } if (whdd->hDib) DeleteObject(whdd->hDib); whdd->hDib = 0; if (whdd->hic) { ICDecompressEnd(whdd->hic); ICClose(whdd->hic); whdd->hic = 0; } whdd->lpvbits = NULL; return ret; }
/*********************************************************************** * DrawDibClose [MSVFW32.@] */ BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) { WINE_HDD* whdd = MSVIDEO_GetHddPtr(hdd); WINE_HDD** p; TRACE("(%p)\n", hdd); if (!whdd) return FALSE; if (whdd->begun) DrawDibEnd(hdd); for (p = &HDD_FirstHdd; *p != NULL; p = &((*p)->next)) { if (*p == whdd) { *p = whdd->next; break; } } HeapFree(GetProcessHeap(), 0, whdd); return TRUE; }
/********************************************************************** * DrawDibDraw [MSVFW32.@] */ BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc, INT xDst, INT yDst, INT dxDst, INT dyDst, LPBITMAPINFOHEADER lpbi, LPVOID lpBits, INT xSrc, INT ySrc, INT dxSrc, INT dySrc, UINT wFlags) { WINE_HDD *whdd; BOOL ret; int reopen = 0; TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08x)\n", hdd, hdc, xDst, yDst, dxDst, dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags); whdd = MSVIDEO_GetHddPtr(hdd); if (!whdd) return FALSE; TRACE("whdd=%p\n", whdd); if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | DDF_UPDATE | DDF_DONTDRAW | DDF_BACKGROUNDPAL)) FIXME("wFlags == 0x%08x not handled\n", wFlags); if (!lpBits) { /* Undocumented? */ lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD)); } #define CHANGED(x) (whdd->x != x) /* Check if anything changed from the parameters passed and our struct. * If anything changed we need to run DrawDibBegin again to ensure we * can support the changes. */ if (!whdd->begun) reopen = 1; else if (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) reopen = 2; else if (!(wFlags & DDF_SAME_DRAW)) { if (CHANGED(lpbi) && memcmp(lpbi, whdd->lpbi, sizeof(*lpbi))) reopen = 3; else if (CHANGED(dxSrc)) reopen = 4; else if (CHANGED(dySrc)) reopen = 5; else if (CHANGED(dxDst)) reopen = 6; else if (CHANGED(dyDst)) reopen = 7; } if (reopen) { TRACE("Something changed (reason %d)!\n", reopen); ret = DrawDibBegin(hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, 0); if (!ret) return ret; } #undef CHANGED /* If source dimensions are not specified derive them from bitmap header */ if (dxSrc == -1 && dySrc == -1) { dxSrc = lpbi->biWidth; dySrc = lpbi->biHeight; } /* If destination dimensions are not specified derive them from source */ if (dxDst == -1 && dyDst == -1) { dxDst = dxSrc; dyDst = dySrc; } if (!(wFlags & DDF_UPDATE)) { if (lpbi->biCompression) { DWORD flags = 0; TRACE("Compression == 0x%08x\n", lpbi->biCompression); if (wFlags & DDF_NOTKEYFRAME) flags |= ICDECOMPRESS_NOTKEYFRAME; ICDecompress(whdd->hic, flags, lpbi, lpBits, whdd->lpbiOut, whdd->lpvbits); } else { /* BI_RGB: lpbi->biSizeImage isn't reliable */ DWORD biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight; memcpy(whdd->lpvbits, lpBits, biSizeImage); } } if (!(wFlags & DDF_DONTDRAW) && whdd->hpal) { if ((wFlags & DDF_BACKGROUNDPAL) && ! (wFlags & DDF_SAME_HDC)) SelectPalette(hdc, whdd->hpal, TRUE); else SelectPalette(hdc, whdd->hpal, FALSE); } ret = StretchBlt(whdd->hdc, xDst, yDst, dxDst, dyDst, whdd->hMemDC, xSrc, ySrc, dxSrc, dySrc, SRCCOPY); TRACE("Painting %dx%d at %d,%d from %dx%d at %d,%d -> %d\n", dxDst, dyDst, xDst, yDst, dxSrc, dySrc, xSrc, ySrc, ret); return ret; }
/*********************************************************************** * DrawDibBegin [MSVFW32.@] */ BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd, HDC hdc, INT dxDst, INT dyDst, LPBITMAPINFOHEADER lpbi, INT dxSrc, INT dySrc, UINT wFlags) { BOOL ret = TRUE; WINE_HDD *whdd; TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08x)\n", hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, wFlags); TRACE("lpbi: %d,%d/%d,%d,%d,%d,%d,%d,%d,%d,%d\n", lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes, lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage, lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed, lpbi->biClrImportant); if (wFlags & ~(DDF_BUFFER)) FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER)); whdd = MSVIDEO_GetHddPtr(hdd); if (!whdd) return FALSE; if (whdd->begun) DrawDibEnd(hdd); if (lpbi->biCompression) { DWORD size = 0; whdd->hic = ICOpen(ICTYPE_VIDEO, lpbi->biCompression, ICMODE_DECOMPRESS); if (!whdd->hic) { WARN("Could not open IC. biCompression == 0x%08x\n", lpbi->biCompression); ret = FALSE; } if (ret) { size = ICDecompressGetFormat(whdd->hic, lpbi, NULL); if (size == ICERR_UNSUPPORTED) { WARN("Codec doesn't support GetFormat, giving up.\n"); ret = FALSE; } } if (ret) { whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, size); if (ICDecompressGetFormat(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK) ret = FALSE; } if (ret) { /* FIXME: Use Ex functions if available? */ if (ICDecompressBegin(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK) ret = FALSE; TRACE("biSizeImage == %d\n", whdd->lpbiOut->biSizeImage); TRACE("biCompression == %d\n", whdd->lpbiOut->biCompression); TRACE("biBitCount == %d\n", whdd->lpbiOut->biBitCount); } } else { DWORD dwSize; /* No compression */ TRACE("Not compressed!\n"); if (lpbi->biHeight <= 0) { /* we don't draw inverted DIBs */ TRACE("detected inverted DIB\n"); ret = FALSE; } else { dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD); whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, dwSize); memcpy(whdd->lpbiOut, lpbi, dwSize); } } if (ret) { /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(), 0, whdd->lpbiOut->biSizeImage);*/ whdd->hMemDC = CreateCompatibleDC(hdc); TRACE("Creating: %d, %p\n", whdd->lpbiOut->biSize, whdd->lpvbits); whdd->hDib = CreateDIBSection(whdd->hMemDC, (BITMAPINFO *)whdd->lpbiOut, DIB_RGB_COLORS, &(whdd->lpvbits), 0, 0); if (whdd->hDib) { TRACE("Created: %p,%p\n", whdd->hDib, whdd->lpvbits); } else { ret = FALSE; TRACE("Error: %d\n", GetLastError()); } whdd->hOldDib = SelectObject(whdd->hMemDC, whdd->hDib); } if (ret) { whdd->hdc = hdc; whdd->dxDst = dxDst; whdd->dyDst = dyDst; whdd->lpbi = HeapAlloc(GetProcessHeap(), 0, lpbi->biSize); memcpy(whdd->lpbi, lpbi, lpbi->biSize); whdd->dxSrc = dxSrc; whdd->dySrc = dySrc; whdd->begun = TRUE; whdd->hpal = 0; } else { if (whdd->hic) ICClose(whdd->hic); HeapFree(GetProcessHeap(), 0, whdd->lpbiOut); whdd->lpbiOut = NULL; } return ret; }
/********************************************************************** * DrawDibDraw [MSVFW32.@] */ BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc, INT xDst, INT yDst, INT dxDst, INT dyDst, LPBITMAPINFOHEADER lpbi, LPVOID lpBits, INT xSrc, INT ySrc, INT dxSrc, INT dySrc, UINT wFlags) { WINE_HDD *whdd; BOOL ret = TRUE; TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08x)\n", hdd, hdc, xDst, yDst, dxDst, dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags); whdd = MSVIDEO_GetHddPtr(hdd); if (!whdd) return FALSE; TRACE("whdd=%p\n", whdd); if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | DDF_UPDATE | DDF_DONTDRAW | DDF_BACKGROUNDPAL)) FIXME("wFlags == 0x%08x not handled\n", wFlags); if (!lpBits) { /* Undocumented? */ lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD)); } #define CHANGED(x) (whdd->x != x) if ((!whdd->begun) || (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || (!(wFlags & DDF_SAME_DRAW) && (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) { TRACE("Something changed!\n"); ret = DrawDibBegin(hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, 0); if (!ret) return ret; } #undef CHANGED if ((dxDst == -1) && (dyDst == -1)) { dxDst = dxSrc; dyDst = dySrc; } if (!(wFlags & DDF_UPDATE)) { if (lpbi->biCompression) { DWORD flags = 0; TRACE("Compression == 0x%08x\n", lpbi->biCompression); if (wFlags & DDF_NOTKEYFRAME) flags |= ICDECOMPRESS_NOTKEYFRAME; ICDecompress(whdd->hic, flags, lpbi, lpBits, whdd->lpbiOut, whdd->lpvbits); } else { /* BI_RGB: lpbi->biSizeImage isn't reliable */ DWORD biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight; memcpy(whdd->lpvbits, lpBits, biSizeImage); } } if (!(wFlags & DDF_DONTDRAW) && whdd->hpal) { if ((wFlags & DDF_BACKGROUNDPAL) && ! (wFlags & DDF_SAME_HDC)) SelectPalette(hdc, whdd->hpal, TRUE); else SelectPalette(hdc, whdd->hpal, FALSE); } if (!(StretchBlt(whdd->hdc, xDst, yDst, dxDst, dyDst, whdd->hMemDC, xSrc, ySrc, dxSrc, dySrc, SRCCOPY))) ret = FALSE; return ret; }