2 * Copyright 2009 Vincent Povirk for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * 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 extern BOOL WINAPI
WIC_DllMain(HINSTANCE
, DWORD
, LPVOID
) DECLSPEC_HIDDEN
;
38 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
43 case DLL_PROCESS_ATTACH
:
44 DisableThreadLibraryCalls(hinstDLL
);
48 return WIC_DllMain(hinstDLL
, fdwReason
, lpvReserved
);
51 HRESULT WINAPI
DllCanUnloadNow(void)
56 HRESULT
copy_pixels(UINT bpp
, const BYTE
*srcbuffer
,
57 UINT srcwidth
, UINT srcheight
, INT srcstride
,
58 const WICRect
*rc
, UINT dststride
, UINT dstbuffersize
, BYTE
*dstbuffer
)
61 UINT row_offset
; /* number of bits into the source rows where the data starts */
68 rect
.Width
= srcwidth
;
69 rect
.Height
= srcheight
;
74 if (rc
->X
< 0 || rc
->Y
< 0 || rc
->X
+rc
->Width
> srcwidth
|| rc
->Y
+rc
->Height
> srcheight
)
78 bytesperrow
= ((bpp
* rc
->Width
)+7)/8;
80 if (dststride
< bytesperrow
)
83 if ((dststride
* (rc
->Height
-1)) + ((rc
->Width
* bpp
) + 7)/8 > dstbuffersize
)
86 /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */
87 if (rc
->X
== 0 && rc
->Y
== 0 && rc
->Width
== srcwidth
&& rc
->Height
== srcheight
&&
88 srcstride
== dststride
&& srcstride
== bytesperrow
)
90 memcpy(dstbuffer
, srcbuffer
, srcstride
* srcheight
);
94 row_offset
= rc
->X
* bpp
;
96 if (row_offset
% 8 == 0)
98 /* everything lines up on a byte boundary */
103 src
= srcbuffer
+ (row_offset
/ 8) + srcstride
* rc
->Y
;
105 for (row
=0; row
< rc
->Height
; row
++)
107 memcpy(dst
, src
, bytesperrow
);
115 /* we have to do a weird bitwise copy. eww. */
116 FIXME("cannot reliably copy bitmap data if bpp < 8\n");
121 HRESULT
configure_write_source(IWICBitmapFrameEncode
*iface
,
122 IWICBitmapSource
*source
, const WICRect
*prc
,
123 const WICPixelFormatGUID
*format
,
124 INT width
, INT height
, double xres
, double yres
)
127 WICPixelFormatGUID src_format
, dst_format
;
129 if (width
== 0 || height
== 0)
130 return WINCODEC_ERR_WRONGSTATE
;
132 hr
= IWICBitmapSource_GetPixelFormat(source
, &src_format
);
133 if (FAILED(hr
)) return hr
;
137 dst_format
= src_format
;
139 hr
= IWICBitmapFrameEncode_SetPixelFormat(iface
, &dst_format
);
140 if (FAILED(hr
)) return hr
;
142 format
= &dst_format
;
145 if (!IsEqualGUID(&src_format
, format
))
147 /* FIXME: should use WICConvertBitmapSource to convert */
148 ERR("format %s unsupported\n", debugstr_guid(&src_format
));
152 if (xres
== 0.0 || yres
== 0.0)
154 hr
= IWICBitmapSource_GetResolution(source
, &xres
, &yres
);
155 if (FAILED(hr
)) return hr
;
156 hr
= IWICBitmapFrameEncode_SetResolution(iface
, xres
, yres
);
157 if (FAILED(hr
)) return hr
;
163 HRESULT
write_source(IWICBitmapFrameEncode
*iface
,
164 IWICBitmapSource
*source
, const WICRect
*prc
,
165 const WICPixelFormatGUID
*format
, UINT bpp
,
166 INT width
, INT height
)
175 UINT src_width
, src_height
;
176 hr
= IWICBitmapSource_GetSize(source
, &src_width
, &src_height
);
177 if (FAILED(hr
)) return hr
;
180 rc
.Width
= src_width
;
181 rc
.Height
= src_height
;
185 if (prc
->Width
!= width
|| prc
->Height
<= 0)
188 stride
= (bpp
* width
+ 7)/8;
190 pixeldata
= HeapAlloc(GetProcessHeap(), 0, stride
* prc
->Height
);
191 if (!pixeldata
) return E_OUTOFMEMORY
;
193 hr
= IWICBitmapSource_CopyPixels(source
, prc
, stride
,
194 stride
*prc
->Height
, pixeldata
);
198 hr
= IWICBitmapFrameEncode_WritePixels(iface
, prc
->Height
, stride
,
199 stride
*prc
->Height
, pixeldata
);
202 HeapFree(GetProcessHeap(), 0, pixeldata
);
207 void reverse_bgr8(UINT bytesperpixel
, LPBYTE bits
, UINT width
, UINT height
, INT stride
)
212 for (y
=0; y
<height
; y
++)
214 pixel
= bits
+ stride
* y
;
216 for (x
=0; x
<width
; x
++)
221 pixel
+= bytesperpixel
;
226 HRESULT
get_pixelformat_bpp(const GUID
*pixelformat
, UINT
*bpp
)
229 IWICComponentInfo
*info
;
230 IWICPixelFormatInfo
*formatinfo
;
232 hr
= CreateComponentInfo(pixelformat
, &info
);
235 hr
= IWICComponentInfo_QueryInterface(info
, &IID_IWICPixelFormatInfo
, (void**)&formatinfo
);
239 hr
= IWICPixelFormatInfo_GetBitsPerPixel(formatinfo
, bpp
);
241 IWICPixelFormatInfo_Release(formatinfo
);
244 IWICComponentInfo_Release(info
);