2 * Copyright 2013 Nikolay Sivov 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
27 #include "wincodecs_private.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
33 typedef struct BitmapClipper
{
34 IWICBitmapClipper IWICBitmapClipper_iface
;
36 IWICBitmapSource
*source
;
38 CRITICAL_SECTION lock
; /* must be held when initialized */
41 static inline BitmapClipper
*impl_from_IWICBitmapClipper(IWICBitmapClipper
*iface
)
43 return CONTAINING_RECORD(iface
, BitmapClipper
, IWICBitmapClipper_iface
);
46 static HRESULT WINAPI
BitmapClipper_QueryInterface(IWICBitmapClipper
*iface
, REFIID iid
,
49 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
50 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
52 if (!ppv
) return E_INVALIDARG
;
54 if (IsEqualIID(&IID_IUnknown
, iid
) ||
55 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
56 IsEqualIID(&IID_IWICBitmapClipper
, iid
))
58 *ppv
= &This
->IWICBitmapClipper_iface
;
66 IUnknown_AddRef((IUnknown
*)*ppv
);
70 static ULONG WINAPI
BitmapClipper_AddRef(IWICBitmapClipper
*iface
)
72 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
73 ULONG ref
= InterlockedIncrement(&This
->ref
);
75 TRACE("(%p) refcount=%u\n", iface
, ref
);
80 static ULONG WINAPI
BitmapClipper_Release(IWICBitmapClipper
*iface
)
82 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
83 ULONG ref
= InterlockedDecrement(&This
->ref
);
85 TRACE("(%p) refcount=%u\n", iface
, ref
);
89 This
->lock
.DebugInfo
->Spare
[0] = 0;
90 DeleteCriticalSection(&This
->lock
);
91 if (This
->source
) IWICBitmapSource_Release(This
->source
);
92 HeapFree(GetProcessHeap(), 0, This
);
98 static HRESULT WINAPI
BitmapClipper_GetSize(IWICBitmapClipper
*iface
,
99 UINT
*width
, UINT
*height
)
101 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
103 TRACE("(%p,%p,%p)\n", iface
, width
, height
);
105 if (!width
|| !height
)
109 return WINCODEC_ERR_WRONGSTATE
;
111 *width
= This
->rect
.Width
;
112 *height
= This
->rect
.Height
;
117 static HRESULT WINAPI
BitmapClipper_GetPixelFormat(IWICBitmapClipper
*iface
,
118 WICPixelFormatGUID
*format
)
120 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
121 TRACE("(%p,%p)\n", iface
, format
);
127 return WINCODEC_ERR_WRONGSTATE
;
129 return IWICBitmapSource_GetPixelFormat(This
->source
, format
);
132 static HRESULT WINAPI
BitmapClipper_GetResolution(IWICBitmapClipper
*iface
,
133 double *dpiX
, double *dpiY
)
135 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
137 TRACE("(%p,%p,%p)\n", iface
, dpiX
, dpiY
);
143 return WINCODEC_ERR_WRONGSTATE
;
145 return IWICBitmapSource_GetResolution(This
->source
, dpiX
, dpiY
);
148 static HRESULT WINAPI
BitmapClipper_CopyPalette(IWICBitmapClipper
*iface
,
149 IWICPalette
*palette
)
151 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
153 TRACE("(%p,%p)\n", iface
, palette
);
159 return WINCODEC_ERR_WRONGSTATE
;
161 return IWICBitmapSource_CopyPalette(This
->source
, palette
);
164 static HRESULT WINAPI
BitmapClipper_CopyPixels(IWICBitmapClipper
*iface
,
165 const WICRect
*rc
, UINT stride
, UINT buffer_size
, BYTE
*buffer
)
167 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
170 TRACE("(%p,%s,%u,%u,%p)\n", iface
, debug_wic_rect(rc
), stride
, buffer_size
, buffer
);
173 return WINCODEC_ERR_WRONGSTATE
;
179 /* transform to source coordinates */
180 rect
.X
+= This
->rect
.X
;
181 rect
.Y
+= This
->rect
.Y
;
183 if ((rect
.X
+ rect
.Width
> This
->rect
.X
+ This
->rect
.Width
) ||
184 (rect
.Y
+ rect
.Height
> This
->rect
.Y
+ This
->rect
.Height
))
192 return IWICBitmapSource_CopyPixels(This
->source
, rc
, stride
, buffer_size
, buffer
);
195 static HRESULT WINAPI
BitmapClipper_Initialize(IWICBitmapClipper
*iface
,
196 IWICBitmapSource
*source
, const WICRect
*rc
)
198 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
202 TRACE("(%p,%p,%s)\n", iface
, source
, debug_wic_rect(rc
));
204 EnterCriticalSection(&This
->lock
);
208 hr
= WINCODEC_ERR_WRONGSTATE
;
212 hr
= IWICBitmapSource_GetSize(source
, &width
, &height
);
213 if (FAILED(hr
)) goto end
;
215 if ((rc
->X
+ rc
->Width
> width
) || (rc
->Y
+ rc
->Height
> height
))
222 This
->source
= source
;
223 IWICBitmapSource_AddRef(This
->source
);
226 LeaveCriticalSection(&This
->lock
);
231 static const IWICBitmapClipperVtbl BitmapClipper_Vtbl
= {
232 BitmapClipper_QueryInterface
,
233 BitmapClipper_AddRef
,
234 BitmapClipper_Release
,
235 BitmapClipper_GetSize
,
236 BitmapClipper_GetPixelFormat
,
237 BitmapClipper_GetResolution
,
238 BitmapClipper_CopyPalette
,
239 BitmapClipper_CopyPixels
,
240 BitmapClipper_Initialize
243 HRESULT
BitmapClipper_Create(IWICBitmapClipper
**clipper
)
247 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapClipper
));
248 if (!This
) return E_OUTOFMEMORY
;
250 This
->IWICBitmapClipper_iface
.lpVtbl
= &BitmapClipper_Vtbl
;
253 InitializeCriticalSection(&This
->lock
);
254 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BitmapClipper.lock");
256 *clipper
= &This
->IWICBitmapClipper_iface
;