static HRESULT WINAPI JpegDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface, double *pDpiX, double *pDpiY) { JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); EnterCriticalSection(&This->lock); switch (This->cinfo.density_unit) { case 2: /* pixels per centimeter */ *pDpiX = This->cinfo.X_density * 2.54; *pDpiY = This->cinfo.Y_density * 2.54; break; case 1: /* pixels per inch */ *pDpiX = This->cinfo.X_density; *pDpiY = This->cinfo.Y_density; break; case 0: /* unknown */ default: *pDpiX = 96.0; *pDpiY = 96.0; break; } LeaveCriticalSection(&This->lock); TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY); return S_OK; }
static HRESULT WINAPI PngDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, void **ppv) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); if (!ppv) return E_INVALIDARG; if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapSource, iid) || IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) { *ppv = &This->IWICBitmapFrameDecode_iface; } else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid)) { *ppv = &This->IWICMetadataBlockReader_iface; } else { *ppv = NULL; return E_NOINTERFACE; } IUnknown_AddRef((IUnknown*)*ppv); return S_OK; }
static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface, double *pDpiX, double *pDpiY) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); png_uint_32 ret, xres, yres; int unit_type; EnterCriticalSection(&This->lock); ret = ppng_get_pHYs(This->png_ptr, This->info_ptr, &xres, &yres, &unit_type); if (ret && unit_type == PNG_RESOLUTION_METER) { *pDpiX = xres * 0.0254; *pDpiY = yres * 0.0254; } else { WARN("no pHYs block present\n"); *pDpiX = *pDpiY = 96.0; } LeaveCriticalSection(&This->lock); TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY); return S_OK; }
static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, double *pDpiX, double *pDpiY) { BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface); TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY); return BmpHeader_GetResolution(&This->bih, pDpiX, pDpiY); }
static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); png_uint_32 ret; png_colorp png_palette; int num_palette; WICColor palette[256]; png_bytep trans; int num_trans; png_color_16p trans_values; int i; HRESULT hr=S_OK; TRACE("(%p,%p)\n", iface, pIPalette); EnterCriticalSection(&This->lock); ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette); if (!ret) { hr = WINCODEC_ERR_PALETTEUNAVAILABLE; goto end; } if (num_palette > 256) { ERR("palette has %i colors?!\n", num_palette); hr = E_FAIL; goto end; } for (i=0; i<num_palette; i++) { palette[i] = (0xff000000| png_palette[i].red << 16| png_palette[i].green << 8| png_palette[i].blue); } ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values); if (ret) { for (i=0; i<num_trans; i++) { palette[trans[i]] = 0x00000000; } } end: LeaveCriticalSection(&This->lock); if (SUCCEEDED(hr)) hr = IWICPalette_InitializeCustom(pIPalette, palette, num_palette); return hr; }
static HRESULT WINAPI PngDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface, UINT *puiWidth, UINT *puiHeight) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); *puiWidth = This->width; *puiHeight = This->height; TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight); return S_OK; }
static HRESULT WINAPI PngDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface, WICPixelFormatGUID *pPixelFormat) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); TRACE("(%p,%p)\n", iface, pPixelFormat); memcpy(pPixelFormat, This->format, sizeof(GUID)); return S_OK; }
static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); return copy_pixels(This->bpp, This->image_bits, This->width, This->height, This->stride, prc, cbStride, cbBufferSize, pbBuffer); }
static HRESULT WINAPI JpegDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, IWICMetadataQueryReader **ppIMetadataQueryReader) { JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); if (!ppIMetadataQueryReader) return E_INVALIDARG; return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); }
static HRESULT WINAPI JpegDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface, WICPixelFormatGUID *pPixelFormat) { JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); TRACE("(%p,%p)\n", iface, pPixelFormat); if (This->cinfo.out_color_space == JCS_RGB) memcpy(pPixelFormat, &GUID_WICPixelFormat24bppBGR, sizeof(GUID)); else if (This->cinfo.out_color_space == JCS_CMYK) memcpy(pPixelFormat, &GUID_WICPixelFormat32bppCMYK, sizeof(GUID)); else /* This->cinfo.out_color_space == JCS_GRAYSCALE */ memcpy(pPixelFormat, &GUID_WICPixelFormat8bppGray, sizeof(GUID)); return S_OK; }
static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface, UINT *puiWidth, UINT *puiHeight) { BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface); TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight); if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER)) { BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih; *puiWidth = bch->bcWidth; *puiHeight = bch->bcHeight; } else { *puiWidth = This->bih.bV5Width; *puiHeight = abs(This->bih.bV5Height); } return S_OK; }
static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface); HRESULT hr=S_OK; UINT width, height; TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); EnterCriticalSection(&This->lock); if (!This->imagedata) { hr = This->read_data_func(This); } LeaveCriticalSection(&This->lock); if (FAILED(hr)) return hr; hr = BmpFrameDecode_GetSize(iface, &width, &height); if (FAILED(hr)) return hr; return copy_pixels(This->bitsperpixel, This->imagedatastart, width, height, This->stride, prc, cbStride, cbBufferSize, pbBuffer); }
static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, void **ppv) { BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface); TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); if (!ppv) return E_INVALIDARG; if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapSource, iid) || IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) { *ppv = &This->IWICBitmapFrameDecode_iface; } else { *ppv = NULL; return E_NOINTERFACE; } IUnknown_AddRef((IUnknown*)*ppv); return S_OK; }
static HRESULT WINAPI PngDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface, UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); png_charp name; BYTE *profile; png_uint_32 len; int compression_type; HRESULT hr; TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); if (!pcActualCount) return E_INVALIDARG; EnterCriticalSection(&This->lock); if (ppng_get_iCCP(This->png_ptr, This->info_ptr, &name, &compression_type, (void *)&profile, &len)) { if (cCount && ppIColorContexts) { hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, len); if (FAILED(hr)) { LeaveCriticalSection(&This->lock); return hr; } } *pcActualCount = 1; } else *pcActualCount = 0; LeaveCriticalSection(&This->lock); return S_OK; }
static ULONG WINAPI JpegDecoder_Frame_Release(IWICBitmapFrameDecode *iface) { JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); return IUnknown_Release((IUnknown*)This); }
static ULONG WINAPI BmpFrameDecode_AddRef(IWICBitmapFrameDecode *iface) { BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface); return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); }
static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); UINT bpp; UINT stride; UINT data_size; UINT max_row_needed; jmp_buf jmpbuf; WICRect rect; TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); if (!prc) { rect.X = 0; rect.Y = 0; rect.Width = This->cinfo.output_width; rect.Height = This->cinfo.output_height; prc = ▭ } else { if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->cinfo.output_width || prc->Y+prc->Height > This->cinfo.output_height) return E_INVALIDARG; } if (This->cinfo.out_color_space == JCS_GRAYSCALE) bpp = 8; else if (This->cinfo.out_color_space == JCS_CMYK) bpp = 32; else bpp = 24; stride = bpp * This->cinfo.output_width; data_size = stride * This->cinfo.output_height; max_row_needed = prc->Y + prc->Height; if (max_row_needed > This->cinfo.output_height) return E_INVALIDARG; EnterCriticalSection(&This->lock); if (!This->image_data) { This->image_data = HeapAlloc(GetProcessHeap(), 0, data_size); if (!This->image_data) { LeaveCriticalSection(&This->lock); return E_OUTOFMEMORY; } } This->cinfo.client_data = &jmpbuf; if (setjmp(jmpbuf)) { LeaveCriticalSection(&This->lock); return E_FAIL; } while (max_row_needed > This->cinfo.output_scanline) { UINT first_scanline = This->cinfo.output_scanline; UINT max_rows; JSAMPROW out_rows[4]; UINT i; JDIMENSION ret; max_rows = min(This->cinfo.output_height-first_scanline, 4); for (i=0; i<max_rows; i++) out_rows[i] = This->image_data + stride * (first_scanline+i); ret = pjpeg_read_scanlines(&This->cinfo, out_rows, max_rows); if (ret == 0) { ERR("read_scanlines failed\n"); LeaveCriticalSection(&This->lock); return E_FAIL; } if (bpp == 24) { /* libjpeg gives us RGB data and we want BGR, so byteswap the data */ reverse_bgr8(3, This->image_data + stride * first_scanline, This->cinfo.output_width, This->cinfo.output_scanline - first_scanline, stride); } if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker) /* Adobe JPEG's have inverted CMYK data. */ for (i=0; i<data_size; i++) This->image_data[i] ^= 0xff; } LeaveCriticalSection(&This->lock); return copy_pixels(bpp, This->image_data, This->cinfo.output_width, This->cinfo.output_height, stride, prc, cbStride, cbBufferSize, pbBuffer); }
static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { HRESULT hr; BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface); int count; WICColor *wiccolors=NULL; RGBTRIPLE *bgrcolors=NULL; TRACE("(%p,%p)\n", iface, pIPalette); EnterCriticalSection(&This->lock); if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER)) { BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih; if (bch->bcBitCount <= 8) { /* 2**n colors in BGR format after the header */ ULONG tablesize, bytesread; LARGE_INTEGER offset; int i; count = 1 << bch->bcBitCount; wiccolors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count); tablesize = sizeof(RGBTRIPLE) * count; bgrcolors = HeapAlloc(GetProcessHeap(), 0, tablesize); if (!wiccolors || !bgrcolors) { hr = E_OUTOFMEMORY; goto end; } offset.QuadPart = This->palette_offset; hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL); if (FAILED(hr)) goto end; hr = IStream_Read(This->stream, bgrcolors, tablesize, &bytesread); if (FAILED(hr)) goto end; if (bytesread != tablesize) { hr = E_FAIL; goto end; } for (i=0; i<count; i++) { wiccolors[i] = 0xff000000| (bgrcolors[i].rgbtRed<<16)| (bgrcolors[i].rgbtGreen<<8)| bgrcolors[i].rgbtBlue; } } else { hr = WINCODEC_ERR_PALETTEUNAVAILABLE; goto end; } } else { if (This->bih.bV5BitCount <= 8) { ULONG tablesize, bytesread; LARGE_INTEGER offset; int i; if (This->bih.bV5ClrUsed == 0) count = 1 << This->bih.bV5BitCount; else count = This->bih.bV5ClrUsed; tablesize = sizeof(WICColor) * count; wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize); if (!wiccolors) { hr = E_OUTOFMEMORY; goto end; } offset.QuadPart = This->palette_offset; hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL); if (FAILED(hr)) goto end; hr = IStream_Read(This->stream, wiccolors, tablesize, &bytesread); if (FAILED(hr)) goto end; if (bytesread != tablesize) { hr = E_FAIL; goto end; } /* convert from BGR to BGRA by setting alpha to 100% */ for (i=0; i<count; i++) wiccolors[i] |= 0xff000000; } else { hr = WINCODEC_ERR_PALETTEUNAVAILABLE; goto end; } } end: LeaveCriticalSection(&This->lock); if (SUCCEEDED(hr)) hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count); HeapFree(GetProcessHeap(), 0, wiccolors); HeapFree(GetProcessHeap(), 0, bgrcolors); return hr; }
static ULONG WINAPI PngDecoder_Frame_Release(IWICBitmapFrameDecode *iface) { PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); }