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); }
/* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */ TW_UINT16 GPHOTO2_ImageMemXferGet (pTW_IDENTITY pOrigin, TW_MEMREF pData) { #ifdef HAVE_GPHOTO2 TW_UINT16 twRC = TWRC_SUCCESS; pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData; LPBYTE buffer; int readrows; unsigned int curoff; TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n"); if (activeDS.currentState < 6 || activeDS.currentState > 7) { activeDS.twCC = TWCC_SEQERROR; return TWRC_FAILURE; } TRACE("pImageMemXfer.Compression is %d\n", pImageMemXfer->Compression); if (activeDS.currentState == 6) { if (TWRC_SUCCESS != _get_image_and_startup_jpeg()) { FIXME("Failed to get an image\n"); activeDS.twCC = TWCC_SEQERROR; return TWRC_FAILURE; } if (!activeDS.progressWnd) activeDS.progressWnd = TransferringDialogBox(NULL,0); TransferringDialogBox(activeDS.progressWnd,0); activeDS.currentState = 7; } else { if (!activeDS.file) { activeDS.twCC = TWRC_SUCCESS; return TWRC_XFERDONE; } } if (pImageMemXfer->Memory.Flags & TWMF_HANDLE) { FIXME("Memory Handle, may not be locked correctly\n"); buffer = LocalLock(pImageMemXfer->Memory.TheMem); } else buffer = pImageMemXfer->Memory.TheMem; memset(buffer,0,pImageMemXfer->Memory.Length); curoff = 0; readrows = 0; pImageMemXfer->YOffset = activeDS.jd.output_scanline; pImageMemXfer->XOffset = 0; /* we do whole strips */ while ((activeDS.jd.output_scanline<activeDS.jd.output_height) && ((pImageMemXfer->Memory.Length - curoff) > activeDS.jd.output_width*activeDS.jd.output_components) ) { JSAMPROW row = buffer+curoff; int x = pjpeg_read_scanlines(&activeDS.jd,&row,1); if (x != 1) { FIXME("failed to read current scanline?\n"); break; } readrows++; curoff += activeDS.jd.output_width*activeDS.jd.output_components; } pImageMemXfer->Compression = TWCP_NONE; pImageMemXfer->BytesPerRow = activeDS.jd.output_components * activeDS.jd.output_width; pImageMemXfer->Rows = readrows; pImageMemXfer->Columns = activeDS.jd.output_width; /* we do whole strips */ pImageMemXfer->BytesWritten = curoff; TransferringDialogBox(activeDS.progressWnd,0); if (activeDS.jd.output_scanline == activeDS.jd.output_height) { pjpeg_finish_decompress(&activeDS.jd); pjpeg_destroy_decompress(&activeDS.jd); gp_file_unref (activeDS.file); activeDS.file = NULL; TRACE("xfer is done!\n"); /*TransferringDialogBox(activeDS.progressWnd, -1);*/ twRC = TWRC_XFERDONE; } activeDS.twCC = TWRC_SUCCESS; if (pImageMemXfer->Memory.Flags & TWMF_HANDLE) LocalUnlock(pImageMemXfer->Memory.TheMem); return twRC; #else return TWRC_FAILURE; #endif }
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; TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); if (This->cinfo.out_color_space == JCS_GRAYSCALE) bpp = 8; 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; } } 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; } } } } LeaveCriticalSection(&This->lock); return copy_pixels(bpp, This->image_data, This->cinfo.output_width, This->cinfo.output_height, stride, prc, cbStride, cbBufferSize, pbBuffer); }