static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, WICPixelFormatGUID *pPixelFormat) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); int i; TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE; if (IsEqualGUID(pPixelFormat, &GUID_WICPixelFormatBlackWhite)) *pPixelFormat = GUID_WICPixelFormat1bppIndexed; else if (IsEqualGUID(pPixelFormat, &GUID_WICPixelFormat2bppIndexed)) *pPixelFormat = GUID_WICPixelFormat4bppIndexed; for (i=0; formats[i].guid; i++) { if (IsEqualGUID(formats[i].guid, pPixelFormat)) break; } if (!formats[i].guid) i = 0; This->format = &formats[i]; memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); return S_OK; }
static HRESULT WINAPI JpegEncoder_Frame_Commit(IWICBitmapFrameEncode *iface) { JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); jmp_buf jmpbuf; TRACE("(%p)\n", iface); EnterCriticalSection(&This->lock); if (!This->started_compress || This->lines_written != This->height || This->frame_committed) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } /* set up setjmp/longjmp error handling */ if (setjmp(jmpbuf)) { LeaveCriticalSection(&This->lock); return E_FAIL; } This->cinfo.client_data = jmpbuf; pjpeg_finish_compress(&This->cinfo); This->frame_committed = TRUE; LeaveCriticalSection(&This->lock); return S_OK; }
static HRESULT WINAPI BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr; WICRect rc; TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); if (!This->initialized || !This->width || !This->height || !This->format) return WINCODEC_ERR_WRONGSTATE; hr = BmpFrameEncode_AllocateBits(This); if (FAILED(hr)) return hr; rc.X = 0; rc.Y = 0; rc.Width = This->width; rc.Height = lineCount; hr = copy_pixels(This->format->bpp, pbPixels, This->width, lineCount, cbStride, &rc, This->stride, This->stride*(This->height-This->lineswritten), This->bits + This->stride*This->lineswritten); if (SUCCEEDED(hr)) This->lineswritten += lineCount; return hr; }
static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, WICPixelFormatGUID *pPixelFormat) { PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); int i; TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); EnterCriticalSection(&This->lock); if (!This->frame_initialized || This->info_written) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } for (i=0; formats[i].guid; i++) { if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0) break; } if (!formats[i].guid) i = 0; This->format = &formats[i]; memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); LeaveCriticalSection(&This->lock); return S_OK; }
static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface) { PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); jmp_buf jmpbuf; TRACE("(%p)\n", iface); EnterCriticalSection(&This->lock); if (!This->info_written || This->lines_written != This->height || This->frame_committed) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } /* set up setjmp/longjmp error handling */ if (setjmp(jmpbuf)) { LeaveCriticalSection(&This->lock); return E_FAIL; } ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); ppng_write_end(This->png_ptr, This->info_ptr); This->frame_committed = TRUE; LeaveCriticalSection(&This->lock); return S_OK; }
static ULONG WINAPI IcnsFrameEncode_AddRef(IWICBitmapFrameEncode *iface) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) refcount=%u\n", iface, ref); return ref; }
static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface, IPropertyBag2 *pIEncoderOptions) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); TRACE("(%p,%p)\n", iface, pIEncoderOptions); if (This->initialized) return WINCODEC_ERR_WRONGSTATE; This->initialized = TRUE; return S_OK; }
static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface) { PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); png_byte **row_pointers=NULL; jmp_buf jmpbuf; TRACE("(%p)\n", iface); EnterCriticalSection(&This->lock); if (!This->info_written || This->lines_written != This->height || This->frame_committed) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } /* set up setjmp/longjmp error handling */ if (setjmp(jmpbuf)) { LeaveCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, row_pointers); return E_FAIL; } ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); if (This->interlace) { int i; row_pointers = HeapAlloc(GetProcessHeap(), 0, This->height * sizeof(png_byte*)); if (!row_pointers) { LeaveCriticalSection(&This->lock); return E_OUTOFMEMORY; } for (i=0; i<This->height; i++) row_pointers[i] = This->data + This->stride * i; for (i=0; i<This->passes; i++) ppng_write_rows(This->png_ptr, row_pointers, This->height); } ppng_write_end(This->png_ptr, This->info_ptr); This->frame_committed = TRUE; HeapFree(GetProcessHeap(), 0, row_pointers); LeaveCriticalSection(&This->lock); return S_OK; }
static HRESULT WINAPI BmpFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, double dpiX, double dpiY) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE; This->xres = dpiX; This->yres = dpiY; return S_OK; }
static HRESULT WINAPI BmpFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT uiWidth, UINT uiHeight) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE; This->width = uiWidth; This->height = uiHeight; return S_OK; }
static ULONG WINAPI BmpFrameEncode_Release(IWICBitmapFrameEncode *iface) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) refcount=%u\n", iface, ref); if (ref == 0) { if (This->stream) IStream_Release(This->stream); HeapFree(GetProcessHeap(), 0, This->bits); HeapFree(GetProcessHeap(), 0, This); } return ref; }
static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface, IPropertyBag2 *pIEncoderOptions) { PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); BOOL interlace; PROPBAG2 opts[1]= {{0}}; VARIANT opt_values[1]; HRESULT opt_hres[1]; HRESULT hr; TRACE("(%p,%p)\n", iface, pIEncoderOptions); opts[0].pstrName = (LPOLESTR)wszPngInterlaceOption; opts[0].vt = VT_BOOL; if (pIEncoderOptions) { hr = IPropertyBag2_Read(pIEncoderOptions, 1, opts, NULL, opt_values, opt_hres); if (FAILED(hr)) return hr; } else memset(opt_values, 0, sizeof(opt_values)); if (V_VT(&opt_values[0]) == VT_EMPTY) interlace = FALSE; else interlace = (V_BOOL(&opt_values[0]) != 0); EnterCriticalSection(&This->lock); if (This->frame_initialized) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } This->interlace = interlace; This->frame_initialized = TRUE; LeaveCriticalSection(&This->lock); return S_OK; }
static HRESULT WINAPI IcnsFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT uiWidth, UINT uiHeight) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr = S_OK; TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); EnterCriticalSection(&This->encoder->lock); if (!This->initialized || This->icns_image) { hr = WINCODEC_ERR_WRONGSTATE; goto end; } if (uiWidth != uiHeight) { WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight); hr = E_INVALIDARG; goto end; } switch (uiWidth) { case 16: case 32: case 48: case 128: case 256: case 512: break; default: WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size); hr = E_INVALIDARG; goto end; } This->size = uiWidth; end: LeaveCriticalSection(&This->encoder->lock); return hr; }
static HRESULT WINAPI IcnsFrameEncode_Commit(IWICBitmapFrameEncode *iface) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); Handle handle; OSErr ret; HRESULT hr = S_OK; TRACE("(%p)\n", iface); EnterCriticalSection(&This->encoder->lock); if (!This->icns_image || This->lines_written != This->size || This->committed) { hr = WINCODEC_ERR_WRONGSTATE; goto end; } ret = PtrToHand(This->icns_image, &handle, This->size * This->size * 4); if (ret != noErr || !handle) { WARN("PtrToHand failed with error %d\n", ret); hr = E_FAIL; goto end; } ret = SetIconFamilyData(This->encoder->icns_family, This->icns_type, handle); DisposeHandle(handle); if (ret != noErr) { WARN("SetIconFamilyData failed for image with error %d\n", ret); hr = E_FAIL; goto end; } This->committed = TRUE; This->encoder->any_frame_committed = TRUE; This->encoder->outstanding_commits--; end: LeaveCriticalSection(&This->encoder->lock); return hr; }
static HRESULT WINAPI IcnsFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, double dpiX, double dpiY) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr = S_OK; TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); EnterCriticalSection(&This->encoder->lock); if (!This->initialized || This->icns_image) { hr = WINCODEC_ERR_WRONGSTATE; goto end; } end: LeaveCriticalSection(&This->encoder->lock); return S_OK; }
static HRESULT WINAPI JpegEncoder_Frame_Initialize(IWICBitmapFrameEncode *iface, IPropertyBag2 *pIEncoderOptions) { JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); TRACE("(%p,%p)\n", iface, pIEncoderOptions); EnterCriticalSection(&This->lock); if (This->frame_initialized) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } This->frame_initialized = TRUE; LeaveCriticalSection(&This->lock); return S_OK; }
static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT uiWidth, UINT uiHeight) { PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); EnterCriticalSection(&This->lock); if (!This->frame_initialized || This->info_written) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } This->width = uiWidth; This->height = uiHeight; LeaveCriticalSection(&This->lock); return S_OK; }
static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, double dpiX, double dpiY) { PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); EnterCriticalSection(&This->lock); if (!This->frame_initialized || This->info_written) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } This->xres = dpiX; This->yres = dpiY; LeaveCriticalSection(&This->lock); return S_OK; }
static HRESULT WINAPI IcnsFrameEncode_Initialize(IWICBitmapFrameEncode *iface, IPropertyBag2 *pIEncoderOptions) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr = S_OK; TRACE("(%p,%p)\n", iface, pIEncoderOptions); EnterCriticalSection(&This->encoder->lock); if (This->initialized) { hr = WINCODEC_ERR_WRONGSTATE; goto end; } This->initialized = TRUE; end: LeaveCriticalSection(&This->encoder->lock); return hr; }
static HRESULT WINAPI IcnsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, WICPixelFormatGUID *pPixelFormat) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr = S_OK; TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); EnterCriticalSection(&This->encoder->lock); if (!This->initialized || This->icns_image) { hr = WINCODEC_ERR_WRONGSTATE; goto end; } memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID)); end: LeaveCriticalSection(&This->encoder->lock); return S_OK; }
static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, WICPixelFormatGUID *pPixelFormat) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); int i; TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE; for (i=0; formats[i].guid; i++) { if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0) break; } if (!formats[i].guid) i = 0; This->format = &formats[i]; memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); return S_OK; }
static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, IWICPalette *palette) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr; TRACE("(%p,%p)\n", iface, palette); if (!palette) return E_INVALIDARG; if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED; hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); if (hr == S_OK) { UINT i; for (i = 0; i < This->colors; i++) This->palette[i] |= 0xff000000; /* BMP palette has no alpha */ } return hr; }
static HRESULT WINAPI IcnsFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, void **ppv) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); if (!ppv) return E_INVALIDARG; if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) { *ppv = &This->IWICBitmapFrameEncode_iface; } else { *ppv = NULL; return E_NOINTERFACE; } IUnknown_AddRef((IUnknown*)*ppv); return S_OK; }
static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, IWICBitmapSource *pIBitmapSource, WICRect *prc) { PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr; TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc); if (!This->frame_initialized) return WINCODEC_ERR_WRONGSTATE; hr = configure_write_source(iface, pIBitmapSource, prc, This->format ? This->format->guid : NULL, This->width, This->height, This->xres, This->yres); if (SUCCEEDED(hr)) { hr = write_source(iface, pIBitmapSource, prc, This->format->guid, This->format->bpp, This->width, This->height); } return hr; }
static HRESULT WINAPI BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); UINT dstbuffersize, bytesperrow, row; BYTE *dst, *src; HRESULT hr; TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); if (!This->initialized || !This->width || !This->height || !This->format) return WINCODEC_ERR_WRONGSTATE; hr = BmpFrameEncode_AllocateBits(This); if (FAILED(hr)) return hr; bytesperrow = ((This->format->bpp * This->width) + 7) / 8; if (This->stride < bytesperrow) return E_INVALIDARG; dstbuffersize = This->stride * (This->height - This->lineswritten); if ((This->stride * (lineCount - 1)) + bytesperrow > dstbuffersize) return E_INVALIDARG; src = pbPixels; dst = This->bits + This->stride * (This->height - This->lineswritten - 1); for (row = 0; row < lineCount; row++) { memcpy(dst, src, bytesperrow); src += cbStride; dst -= This->stride; } This->lineswritten += lineCount; return S_OK; }
static HRESULT WINAPI IcnsFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, IWICBitmapSource *pIBitmapSource, WICRect *prc) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr; TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc); if (!This->initialized) return WINCODEC_ERR_WRONGSTATE; hr = configure_write_source(iface, pIBitmapSource, prc, &GUID_WICPixelFormat32bppBGRA, This->size, This->size, 1.0, 1.0); if (SUCCEEDED(hr)) { hr = write_source(iface, pIBitmapSource, prc, &GUID_WICPixelFormat32bppBGRA, 32, This->size, This->size); } return hr; }
static ULONG WINAPI IcnsFrameEncode_Release(IWICBitmapFrameEncode *iface) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) refcount=%u\n", iface, ref); if (ref == 0) { if (!This->committed) { EnterCriticalSection(&This->encoder->lock); This->encoder->outstanding_commits--; LeaveCriticalSection(&This->encoder->lock); } HeapFree(GetProcessHeap(), 0, This->icns_image); IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface); HeapFree(GetProcessHeap(), 0, This); } return ref; }
static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); BITMAPFILEHEADER bfh; BITMAPV5HEADER bih; UINT info_size; LARGE_INTEGER pos; ULONG byteswritten; HRESULT hr; TRACE("(%p)\n", iface); if (!This->bits || This->committed || This->height != This->lineswritten) return WINCODEC_ERR_WRONGSTATE; bfh.bfType = 0x4d42; /* "BM" */ bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bih.bV5Size = info_size = sizeof(BITMAPINFOHEADER); bih.bV5Width = This->width; bih.bV5Height = -This->height; /* top-down bitmap */ bih.bV5Planes = 1; bih.bV5BitCount = This->format->bpp; bih.bV5Compression = This->format->compression; bih.bV5SizeImage = This->stride*This->height; bih.bV5XPelsPerMeter = (This->xres+0.0127) / 0.0254; bih.bV5YPelsPerMeter = (This->yres+0.0127) / 0.0254; bih.bV5ClrUsed = 0; bih.bV5ClrImportant = 0; if (This->format->compression == BI_BITFIELDS) { if (This->format->alphamask) bih.bV5Size = info_size = sizeof(BITMAPV4HEADER); else info_size = sizeof(BITMAPINFOHEADER)+12; bih.bV5RedMask = This->format->redmask; bih.bV5GreenMask = This->format->greenmask; bih.bV5BlueMask = This->format->bluemask; bih.bV5AlphaMask = This->format->alphamask; bih.bV5CSType = LCS_DEVICE_RGB; } bfh.bfSize = sizeof(BITMAPFILEHEADER) + info_size + bih.bV5SizeImage; bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + info_size; pos.QuadPart = 0; hr = IStream_Seek(This->stream, pos, STREAM_SEEK_SET, NULL); if (FAILED(hr)) return hr; hr = IStream_Write(This->stream, &bfh, sizeof(BITMAPFILEHEADER), &byteswritten); if (FAILED(hr)) return hr; if (byteswritten != sizeof(BITMAPFILEHEADER)) return E_FAIL; hr = IStream_Write(This->stream, &bih, info_size, &byteswritten); if (FAILED(hr)) return hr; if (byteswritten != info_size) return E_FAIL; hr = IStream_Write(This->stream, This->bits, bih.bV5SizeImage, &byteswritten); if (FAILED(hr)) return hr; if (byteswritten != bih.bV5SizeImage) return E_FAIL; This->committed = TRUE; return S_OK; }
static HRESULT WINAPI IcnsFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) { IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); HRESULT hr = S_OK; UINT i; TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); EnterCriticalSection(&This->encoder->lock); if (!This->initialized || !This->size) { hr = WINCODEC_ERR_WRONGSTATE; goto end; } if (lineCount == 0 || lineCount + This->lines_written > This->size) { hr = E_INVALIDARG; goto end; } if (!This->icns_image) { switch (This->size) { case 16: This->icns_type = kIconServices16PixelDataARGB; break; case 32: This->icns_type = kIconServices32PixelDataARGB; break; case 48: This->icns_type = kIconServices48PixelDataARGB; break; case 128: This->icns_type = kIconServices128PixelDataARGB; break; case 256: This->icns_type = kIconServices256PixelDataARGB; break; case 512: This->icns_type = kIconServices512PixelDataARGB; break; default: WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size); hr = E_INVALIDARG; goto end; } This->icns_image = HeapAlloc(GetProcessHeap(), 0, This->size * This->size * 4); if (!This->icns_image) { WARN("failed to allocate image buffer\n"); hr = E_FAIL; goto end; } } for (i = 0; i < lineCount; i++) { BYTE *src_row, *dst_row; UINT j; src_row = pbPixels + cbStride * i; dst_row = This->icns_image + (This->lines_written + i)*(This->size*4); /* swap bgr -> rgb */ for (j = 0; j < This->size*4; j += 4) { dst_row[j] = src_row[j+3]; dst_row[j+1] = src_row[j+2]; dst_row[j+2] = src_row[j+1]; dst_row[j+3] = src_row[j]; } } This->lines_written += lineCount; end: LeaveCriticalSection(&This->encoder->lock); return hr; }
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; }