#include "wincodecs_private.h"
+#include "wine/heap.h"
#include "wine/debug.h"
#include "wine/library.h"
struct jpeg_error_mgr jerr;
struct jpeg_source_mgr source_mgr;
BYTE source_buffer[1024];
+ UINT bpp, stride;
BYTE *image_data;
CRITICAL_SECTION lock;
} JpegDecoder;
int ret;
LARGE_INTEGER seek;
jmp_buf jmpbuf;
+ UINT data_size, i;
+
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions);
EnterCriticalSection(&This->lock);
return E_FAIL;
}
+ if (This->cinfo.out_color_space == JCS_GRAYSCALE) This->bpp = 8;
+ else if (This->cinfo.out_color_space == JCS_CMYK) This->bpp = 32;
+ else This->bpp = 24;
+
+ This->stride = (This->bpp * This->cinfo.output_width + 7) / 8;
+ data_size = This->stride * This->cinfo.output_height;
+
+ This->image_data = heap_alloc(data_size);
+ if (!This->image_data)
+ {
+ LeaveCriticalSection(&This->lock);
+ return E_OUTOFMEMORY;
+ }
+
+ while (This->cinfo.output_scanline < This->cinfo.output_height)
+ {
+ UINT first_scanline = This->cinfo.output_scanline;
+ UINT max_rows;
+ JSAMPROW out_rows[4];
+ 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 + This->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 (This->bpp == 24)
+ {
+ /* libjpeg gives us RGB data and we want BGR, so byteswap the data */
+ reverse_bgr8(3, This->image_data,
+ This->cinfo.output_width, This->cinfo.output_height,
+ This->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;
+ }
+
This->initialized = TRUE;
LeaveCriticalSection(&This->lock);
static HRESULT WINAPI JpegDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICJpegDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICJpegDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI JpegDecoder_CopyPalette(IWICBitmapDecoder *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)
- {
- DWORD *pDwordData = (DWORD*) (This->image_data + stride * first_scanline);
- DWORD *pDwordDataEnd = (DWORD*) (This->image_data + This->cinfo.output_scanline * stride);
-
- /* Adobe JPEG's have inverted CMYK data. */
- while(pDwordData < pDwordDataEnd)
- *pDwordData++ ^= 0xffffffff;
- }
-
- }
-
- LeaveCriticalSection(&This->lock);
+ TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
- return copy_pixels(bpp, This->image_data,
- This->cinfo.output_width, This->cinfo.output_height, stride,
+ return copy_pixels(This->bpp, This->image_data,
+ This->cinfo.output_width, This->cinfo.output_height, This->stride,
prc, cbStride, cbBufferSize, pbBuffer);
}