static HRESULT WINAPI JpegDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface, UINT *puiWidth, UINT *puiHeight) { JpegDecoder *This = decoder_from_frame(iface); *puiWidth = This->cinfo.output_width; *puiHeight = This->cinfo.output_height; TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight); return S_OK; }
static HRESULT WINAPI JpegDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface, WICPixelFormatGUID *pPixelFormat) { JpegDecoder *This = decoder_from_frame(iface); TRACE("(%p,%p)\n", iface, pPixelFormat); if (This->cinfo.out_color_space == JCS_RGB) memcpy(pPixelFormat, &GUID_WICPixelFormat24bppBGR, sizeof(GUID)); else /* This->cinfo.out_color_space == JCS_GRAYSCALE */ memcpy(pPixelFormat, &GUID_WICPixelFormat8bppGray, sizeof(GUID)); return S_OK; }
static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { JpegDecoder *This = decoder_from_frame(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, j; 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 */ for (i=first_scanline; i<This->cinfo.output_scanline; i++) { BYTE *pixel = This->image_data + stride * i; for (j=0; j<This->cinfo.output_width; j++) { BYTE red=pixel[0]; BYTE blue=pixel[2]; pixel[0]=blue; pixel[2]=red; pixel+=3; } } } 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 ULONG WINAPI JpegDecoder_Frame_Release(IWICBitmapFrameDecode *iface) { JpegDecoder *This = decoder_from_frame(iface); return IUnknown_Release((IUnknown*)This); }