2 * wincodecs_common.c - Functions shared with other WIC libraries.
4 * Copyright 2020 Esme Povirk
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wincodecs_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
36 #include "wincodecs_common.h"
38 HRESULT
configure_write_source(IWICBitmapFrameEncode
*iface
,
39 IWICBitmapSource
*source
, const WICRect
*prc
,
40 const WICPixelFormatGUID
*format
,
41 INT width
, INT height
, double xres
, double yres
)
43 UINT src_width
, src_height
;
46 if (width
== 0 && height
== 0)
50 if (prc
->Width
<= 0 || prc
->Height
<= 0) return E_INVALIDARG
;
56 hr
= IWICBitmapSource_GetSize(source
, &src_width
, &src_height
);
57 if (FAILED(hr
)) return hr
;
58 if (src_width
== 0 || src_height
== 0) return E_INVALIDARG
;
62 hr
= IWICBitmapFrameEncode_SetSize(iface
, (UINT
)width
, (UINT
)height
);
63 if (FAILED(hr
)) return hr
;
65 if (width
== 0 || height
== 0) return E_INVALIDARG
;
69 WICPixelFormatGUID src_format
;
71 hr
= IWICBitmapSource_GetPixelFormat(source
, &src_format
);
72 if (FAILED(hr
)) return hr
;
74 hr
= IWICBitmapFrameEncode_SetPixelFormat(iface
, &src_format
);
75 if (FAILED(hr
)) return hr
;
78 if (xres
== 0.0 || yres
== 0.0)
80 hr
= IWICBitmapSource_GetResolution(source
, &xres
, &yres
);
81 if (FAILED(hr
)) return hr
;
82 hr
= IWICBitmapFrameEncode_SetResolution(iface
, xres
, yres
);
83 if (FAILED(hr
)) return hr
;
89 HRESULT
write_source(IWICBitmapFrameEncode
*iface
,
90 IWICBitmapSource
*source
, const WICRect
*prc
,
91 const WICPixelFormatGUID
*format
, UINT bpp
, BOOL need_palette
,
92 INT width
, INT height
)
94 IWICBitmapSource
*converted_source
;
102 UINT src_width
, src_height
;
103 hr
= IWICBitmapSource_GetSize(source
, &src_width
, &src_height
);
104 if (FAILED(hr
)) return hr
;
107 rc
.Width
= src_width
;
108 rc
.Height
= src_height
;
112 if (prc
->Width
!= width
|| prc
->Height
<= 0)
115 hr
= WICConvertBitmapSource(format
, source
, &converted_source
);
118 ERR("Failed to convert source, target format %s, %#x\n", debugstr_guid(format
), hr
);
124 IWICImagingFactory
*factory
;
125 IWICPalette
*palette
;
127 hr
= create_instance(&CLSID_WICImagingFactory
, &IID_IWICImagingFactory
, (void**)&factory
);
131 hr
= IWICImagingFactory_CreatePalette(factory
, &palette
);
132 IWICImagingFactory_Release(factory
);
137 hr
= IWICBitmapSource_CopyPalette(converted_source
, palette
);
140 hr
= IWICBitmapFrameEncode_SetPalette(iface
, palette
);
142 IWICPalette_Release(palette
);
147 IWICBitmapSource_Release(converted_source
);
152 stride
= (bpp
* width
+ 7)/8;
154 pixeldata
= HeapAlloc(GetProcessHeap(), 0, stride
* prc
->Height
);
157 IWICBitmapSource_Release(converted_source
);
158 return E_OUTOFMEMORY
;
161 hr
= IWICBitmapSource_CopyPixels(converted_source
, prc
, stride
,
162 stride
*prc
->Height
, pixeldata
);
166 hr
= IWICBitmapFrameEncode_WritePixels(iface
, prc
->Height
, stride
,
167 stride
*prc
->Height
, pixeldata
);
170 HeapFree(GetProcessHeap(), 0, pixeldata
);
171 IWICBitmapSource_Release(converted_source
);
176 HRESULT CDECL
stream_getsize(IStream
*stream
, ULONGLONG
*size
)
181 hr
= IStream_Stat(stream
, &statstg
, STATFLAG_NONAME
);
184 *size
= statstg
.cbSize
.QuadPart
;
189 HRESULT CDECL
stream_read(IStream
*stream
, void *buffer
, ULONG read
, ULONG
*bytes_read
)
191 return IStream_Read(stream
, buffer
, read
, bytes_read
);
194 HRESULT CDECL
stream_seek(IStream
*stream
, LONGLONG ofs
, DWORD origin
, ULONGLONG
*new_position
)
197 LARGE_INTEGER ofs_large
;
198 ULARGE_INTEGER pos_large
;
200 ofs_large
.QuadPart
= ofs
;
201 hr
= IStream_Seek(stream
, ofs_large
, origin
, &pos_large
);
203 *new_position
= pos_large
.QuadPart
;
208 HRESULT CDECL
stream_write(IStream
*stream
, const void *buffer
, ULONG write
, ULONG
*bytes_written
)
210 return IStream_Write(stream
, buffer
, write
, bytes_written
);