static HRESULT WINAPI BitmapClipper_CopyPixels(IWICBitmapClipper *iface, const WICRect *rc, UINT stride, UINT buffer_size, BYTE *buffer) { BitmapClipper *This = impl_from_IWICBitmapClipper(iface); WICRect rect; TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(rc), stride, buffer_size, buffer); if (!This->source) return WINCODEC_ERR_WRONGSTATE; if (rc) { rect = *rc; /* transform to source coordinates */ rect.X += This->rect.X; rect.Y += This->rect.Y; if ((rect.X + rect.Width > This->rect.X + This->rect.Width) || (rect.Y + rect.Height > This->rect.Y + This->rect.Height)) return E_INVALIDARG; rc = ▭ } else rc = &This->rect; return IWICBitmapSource_CopyPixels(This->source, rc, stride, buffer_size, buffer); }
static HRESULT WINAPI ColorTransform_CopyPixels(IWICColorTransform *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { ColorTransform *This = impl_from_IWICColorTransform(iface); TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); return IWICBitmapSource_CopyPixels(This->dst, prc, cbStride, cbBufferSize, pbBuffer); }
static HRESULT WINAPI FlipRotator_CopyPixels(IWICBitmapFlipRotator *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface); HRESULT hr; UINT y; UINT srcy, srcwidth, srcheight; WICRect rc; WICRect rect; TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); if (!This->source) return WINCODEC_ERR_WRONGSTATE; if (This->swap_xy || This->flip_x) { /* This requires knowledge of the pixel format. */ FIXME("flipping x and rotating are not implemented\n"); return E_NOTIMPL; } hr = IWICBitmapSource_GetSize(This->source, &srcwidth, &srcheight); if (FAILED(hr)) return hr; if (!prc) { UINT width, height; hr = IWICBitmapSource_GetSize(iface, &width, &height); if (FAILED(hr)) return hr; rect.X = 0; rect.Y = 0; rect.Width = width; rect.Height = height; prc = ▭ } for (y=prc->Y; y - prc->Y < prc->Height; y++) { if (This->flip_y) srcy = srcheight - 1 - y; else srcy = y; rc.X = prc->X; rc.Y = srcy; rc.Width = prc->Width; rc.Height = 1; hr = IWICBitmapSource_CopyPixels(This->source, &rc, cbStride, cbStride, pbBuffer); if (FAILED(hr)) break; pbBuffer += cbStride; } return hr; }
static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, IWICBitmapSource *pIBitmapSource, WICRect *prc) { PngEncoder *This = encoder_from_frame(iface); HRESULT hr; WICRect rc; WICPixelFormatGUID guid; UINT stride; BYTE *pixeldata; TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc); if (!This->frame_initialized || !This->width || !This->height) return WINCODEC_ERR_WRONGSTATE; if (!This->format) { hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid); if (FAILED(hr)) return hr; hr = IWICBitmapFrameEncode_SetPixelFormat(iface, &guid); if (FAILED(hr)) return hr; } hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid); if (FAILED(hr)) return hr; if (memcmp(&guid, This->format->guid, sizeof(GUID)) != 0) { /* FIXME: should use WICConvertBitmapSource to convert */ ERR("format %s unsupported\n", debugstr_guid(&guid)); return E_FAIL; } if (This->xres == 0.0 || This->yres == 0.0) { double xres, yres; hr = IWICBitmapSource_GetResolution(pIBitmapSource, &xres, &yres); if (FAILED(hr)) return hr; hr = IWICBitmapFrameEncode_SetResolution(iface, xres, yres); if (FAILED(hr)) return hr; } if (!prc) { UINT width, height; hr = IWICBitmapSource_GetSize(pIBitmapSource, &width, &height); if (FAILED(hr)) return hr; rc.X = 0; rc.Y = 0; rc.Width = width; rc.Height = height; prc = &rc; } if (prc->Width != This->width) return E_INVALIDARG; stride = (This->format->bpp * This->width + 7)/8; pixeldata = HeapAlloc(GetProcessHeap(), 0, stride * prc->Height); if (!pixeldata) return E_OUTOFMEMORY; hr = IWICBitmapSource_CopyPixels(pIBitmapSource, prc, stride, stride*prc->Height, pixeldata); if (SUCCEEDED(hr)) { hr = IWICBitmapFrameEncode_WritePixels(iface, prc->Height, stride, stride*prc->Height, pixeldata); } HeapFree(GetProcessHeap(), 0, pixeldata); return hr; }
static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface, IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap) { IWICBitmap *result; IWICBitmapLock *lock; IWICPalette *palette; UINT width, height; WICPixelFormatGUID pixelformat = {0}; HRESULT hr; WICRect rc; double dpix, dpiy; IWICComponentInfo *info; IWICPixelFormatInfo2 *formatinfo; WICPixelFormatNumericRepresentation format_type; TRACE("(%p,%p,%u,%p)\n", iface, piBitmapSource, option, ppIBitmap); if (!piBitmapSource || !ppIBitmap) return E_INVALIDARG; hr = IWICBitmapSource_GetSize(piBitmapSource, &width, &height); if (SUCCEEDED(hr)) hr = IWICBitmapSource_GetPixelFormat(piBitmapSource, &pixelformat); if (SUCCEEDED(hr)) hr = CreateComponentInfo(&pixelformat, &info); if (SUCCEEDED(hr)) { hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&formatinfo); if (SUCCEEDED(hr)) { hr = IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo, &format_type); IWICPixelFormatInfo2_Release(formatinfo); } IWICComponentInfo_Release(info); } if (SUCCEEDED(hr)) hr = BitmapImpl_Create(width, height, &pixelformat, option, &result); if (SUCCEEDED(hr)) { hr = IWICBitmap_Lock(result, NULL, WICBitmapLockWrite, &lock); if (SUCCEEDED(hr)) { UINT stride, buffersize; BYTE *buffer; rc.X = rc.Y = 0; rc.Width = width; rc.Height = height; hr = IWICBitmapLock_GetStride(lock, &stride); if (SUCCEEDED(hr)) hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer); if (SUCCEEDED(hr)) hr = IWICBitmapSource_CopyPixels(piBitmapSource, &rc, stride, buffersize, buffer); IWICBitmapLock_Release(lock); } if (SUCCEEDED(hr)) hr = PaletteImpl_Create(&palette); if (SUCCEEDED(hr) && (format_type == WICPixelFormatNumericRepresentationUnspecified || format_type == WICPixelFormatNumericRepresentationIndexed)) { hr = IWICBitmapSource_CopyPalette(piBitmapSource, palette); if (SUCCEEDED(hr)) hr = IWICBitmap_SetPalette(result, palette); else hr = S_OK; IWICPalette_Release(palette); } if (SUCCEEDED(hr)) { hr = IWICBitmapSource_GetResolution(piBitmapSource, &dpix, &dpiy); if (SUCCEEDED(hr)) hr = IWICBitmap_SetResolution(result, dpix, dpiy); else hr = S_OK; } if (SUCCEEDED(hr)) *ppIBitmap = result; else IWICBitmap_Release(result); } return hr; }
HRESULT WINAPI IWICBitmapSource_CopyPixels_Proxy_W(IWICBitmapSource *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { return IWICBitmapSource_CopyPixels(iface, prc, cbStride, cbBufferSize, pbBuffer); }
static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, IWICBitmapSource *pIBitmapSource, WICRect *prc) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr; WICRect rc; WICPixelFormatGUID guid; TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc); if (!This->initialized || !This->width || !This->height) return WINCODEC_ERR_WRONGSTATE; if (!This->format) { hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid); if (FAILED(hr)) return hr; hr = BmpFrameEncode_SetPixelFormat(iface, &guid); if (FAILED(hr)) return hr; } hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid); if (FAILED(hr)) return hr; if (memcmp(&guid, This->format->guid, sizeof(GUID)) != 0) { /* should use WICConvertBitmapSource to convert, but that's unimplemented */ ERR("format %s unsupported\n", debugstr_guid(&guid)); return E_FAIL; } if (This->xres == 0.0 || This->yres == 0.0) { double xres, yres; hr = IWICBitmapSource_GetResolution(pIBitmapSource, &xres, &yres); if (FAILED(hr)) return hr; hr = BmpFrameEncode_SetResolution(iface, xres, yres); if (FAILED(hr)) return hr; } if (!prc) { UINT width, height; hr = IWICBitmapSource_GetSize(pIBitmapSource, &width, &height); if (FAILED(hr)) return hr; rc.X = 0; rc.Y = 0; rc.Width = width; rc.Height = height; prc = &rc; } if (prc->Width != This->width) return E_INVALIDARG; hr = BmpFrameEncode_AllocateBits(This); if (FAILED(hr)) return hr; hr = IWICBitmapSource_CopyPixels(pIBitmapSource, prc, This->stride, This->stride*(This->height-This->lineswritten), This->bits + This->stride*This->lineswritten); This->lineswritten += prc->Height; return S_OK; }
static void compare_bitmap_data(const struct bitmap_data *expect, IWICBitmapSource *source, const char *name) { BYTE *converted_bits; UINT width, height; double xres, yres; WICRect prc; UINT stride, buffersize; GUID dst_pixelformat; HRESULT hr; hr = IWICBitmapSource_GetSize(source, &width, &height); ok(SUCCEEDED(hr), "GetSize(%s) failed, hr=%x\n", name, hr); ok(width == expect->width, "expecting %u, got %u (%s)\n", expect->width, width, name); ok(height == expect->height, "expecting %u, got %u (%s)\n", expect->height, height, name); hr = IWICBitmapSource_GetResolution(source, &xres, &yres); ok(SUCCEEDED(hr), "GetResolution(%s) failed, hr=%x\n", name, hr); ok(fabs(xres - expect->xres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->xres, xres, name); ok(fabs(yres - expect->yres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->yres, yres, name); hr = IWICBitmapSource_GetPixelFormat(source, &dst_pixelformat); ok(SUCCEEDED(hr), "GetPixelFormat(%s) failed, hr=%x\n", name, hr); ok(IsEqualGUID(&dst_pixelformat, expect->format), "got unexpected pixel format (%s)\n", name); prc.X = 0; prc.Y = 0; prc.Width = expect->width; prc.Height = expect->height; stride = (expect->bpp * expect->width + 7) / 8; buffersize = stride * expect->height; converted_bits = HeapAlloc(GetProcessHeap(), 0, buffersize); hr = IWICBitmapSource_CopyPixels(source, &prc, stride, buffersize, converted_bits); ok(SUCCEEDED(hr), "CopyPixels(%s) failed, hr=%x\n", name, hr); if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppBGR)) { /* ignore the padding byte when comparing data */ UINT i; BOOL equal=TRUE; const DWORD *a=(const DWORD*)expect->bits, *b=(const DWORD*)converted_bits; for (i=0; i<(buffersize/4); i++) if ((a[i]&0xffffff) != (b[i]&0xffffff)) { equal = FALSE; break; } ok(equal, "unexpected pixel data (%s)\n", name); } else ok(memcmp(expect->bits, converted_bits, buffersize) == 0, "unexpected pixel data (%s)\n", name); /* Test with NULL rectangle - should copy the whole bitmap */ hr = IWICBitmapSource_CopyPixels(source, NULL, stride, buffersize, converted_bits); ok(SUCCEEDED(hr), "CopyPixels(%s,rc=NULL) failed, hr=%x\n", name, hr); if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppBGR)) { /* ignore the padding byte when comparing data */ UINT i; BOOL equal=TRUE; const DWORD *a=(const DWORD*)expect->bits, *b=(const DWORD*)converted_bits; for (i=0; i<(buffersize/4); i++) if ((a[i]&0xffffff) != (b[i]&0xffffff)) { equal = FALSE; break; } ok(equal, "unexpected pixel data with rc=NULL (%s)\n", name); } else ok(memcmp(expect->bits, converted_bits, buffersize) == 0, "unexpected pixel data with rc=NULL (%s)\n", name); HeapFree(GetProcessHeap(), 0, converted_bits); }
static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { BitmapScaler *This = impl_from_IWICBitmapScaler(iface); HRESULT hr; WICRect dest_rect; WICRect src_rect_ul, src_rect_br, src_rect; BYTE **src_rows; BYTE *src_bits; ULONG bytesperrow; ULONG src_bytesperrow; ULONG buffer_size; UINT y; TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); EnterCriticalSection(&This->lock); if (!This->source) { hr = WINCODEC_ERR_WRONGSTATE; goto end; } if (prc) dest_rect = *prc; else { dest_rect.X = dest_rect.Y = 0; dest_rect.Width = This->width; dest_rect.Height = This->height; } if (dest_rect.X < 0 || dest_rect.Y < 0 || dest_rect.X+dest_rect.Width > This->width|| dest_rect.Y+dest_rect.Height > This->height) { hr = E_INVALIDARG; goto end; } bytesperrow = ((This->bpp * dest_rect.Width)+7)/8; if (cbStride < bytesperrow) { hr = E_INVALIDARG; goto end; } if ((cbStride * dest_rect.Height) > cbBufferSize) { hr = E_INVALIDARG; goto end; } /* MSDN recommends calling CopyPixels once for each scanline from top to * bottom, and claims codecs optimize for this. Ideally, when called in this * way, we should avoid requesting a scanline from the source more than * once, by saving the data that will be useful for the next scanline after * the call returns. The GetRequiredSourceRect/CopyScanline functions are * designed to make it possible to do this in a generic way, but for now we * just grab all the data we need in each call. */ This->fn_get_required_source_rect(This, dest_rect.X, dest_rect.Y, &src_rect_ul); This->fn_get_required_source_rect(This, dest_rect.X+dest_rect.Width-1, dest_rect.Y+dest_rect.Height-1, &src_rect_br); src_rect.X = src_rect_ul.X; src_rect.Y = src_rect_ul.Y; src_rect.Width = src_rect_br.Width + src_rect_br.X - src_rect_ul.X; src_rect.Height = src_rect_br.Height + src_rect_br.Y - src_rect_ul.Y; src_bytesperrow = (src_rect.Width * This->bpp + 7)/8; buffer_size = src_bytesperrow * src_rect.Height; src_rows = HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE*) * src_rect.Height); src_bits = HeapAlloc(GetProcessHeap(), 0, buffer_size); if (!src_rows || !src_bits) { HeapFree(GetProcessHeap(), 0, src_rows); HeapFree(GetProcessHeap(), 0, src_bits); hr = E_OUTOFMEMORY; goto end; } for (y=0; y<src_rect.Height; y++) src_rows[y] = src_bits + y * src_bytesperrow; hr = IWICBitmapSource_CopyPixels(This->source, &src_rect, src_bytesperrow, buffer_size, src_bits); if (SUCCEEDED(hr)) { for (y=0; y < dest_rect.Height; y++) { This->fn_copy_scanline(This, dest_rect.X, dest_rect.Y+y, dest_rect.Width, src_rows, src_rect.X, src_rect.Y, pbBuffer + cbStride * y); } } HeapFree(GetProcessHeap(), 0, src_rows); HeapFree(GetProcessHeap(), 0, src_bits); end: LeaveCriticalSection(&This->lock); return hr; }