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
28 #include "wincodecs_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
34 typedef struct BitmapClipper
{
35 IWICBitmapClipper IWICBitmapClipper_iface
;
37 IWICBitmapSource
*source
;
39 CRITICAL_SECTION lock
; /* must be held when initialized */
42 static inline BitmapClipper
*impl_from_IWICBitmapClipper(IWICBitmapClipper
*iface
)
44 return CONTAINING_RECORD(iface
, BitmapClipper
, IWICBitmapClipper_iface
);
47 static HRESULT WINAPI
BitmapClipper_QueryInterface(IWICBitmapClipper
*iface
, REFIID iid
,
50 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
51 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
53 if (!ppv
) return E_INVALIDARG
;
55 if (IsEqualIID(&IID_IUnknown
, iid
) ||
56 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
57 IsEqualIID(&IID_IWICBitmapClipper
, iid
))
59 *ppv
= &This
->IWICBitmapClipper_iface
;
67 IUnknown_AddRef((IUnknown
*)*ppv
);
71 static ULONG WINAPI
BitmapClipper_AddRef(IWICBitmapClipper
*iface
)
73 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
74 ULONG ref
= InterlockedIncrement(&This
->ref
);
76 TRACE("(%p) refcount=%u\n", iface
, ref
);
81 static ULONG WINAPI
BitmapClipper_Release(IWICBitmapClipper
*iface
)
83 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
84 ULONG ref
= InterlockedDecrement(&This
->ref
);
86 TRACE("(%p) refcount=%u\n", iface
, ref
);
90 This
->lock
.DebugInfo
->Spare
[0] = 0;
91 DeleteCriticalSection(&This
->lock
);
92 if (This
->source
) IWICBitmapSource_Release(This
->source
);
93 HeapFree(GetProcessHeap(), 0, This
);
99 static HRESULT WINAPI
BitmapClipper_GetSize(IWICBitmapClipper
*iface
,
100 UINT
*width
, UINT
*height
)
102 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
104 TRACE("(%p,%p,%p)\n", iface
, width
, height
);
106 if (!width
|| !height
)
110 return WINCODEC_ERR_WRONGSTATE
;
112 *width
= This
->rect
.Width
;
113 *height
= This
->rect
.Height
;
118 static HRESULT WINAPI
BitmapClipper_GetPixelFormat(IWICBitmapClipper
*iface
,
119 WICPixelFormatGUID
*format
)
121 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
122 TRACE("(%p,%p)\n", iface
, format
);
128 return WINCODEC_ERR_WRONGSTATE
;
130 return IWICBitmapSource_GetPixelFormat(This
->source
, format
);
133 static HRESULT WINAPI
BitmapClipper_GetResolution(IWICBitmapClipper
*iface
,
134 double *dpiX
, double *dpiY
)
136 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
138 TRACE("(%p,%p,%p)\n", iface
, dpiX
, dpiY
);
144 return WINCODEC_ERR_WRONGSTATE
;
146 return IWICBitmapSource_GetResolution(This
->source
, dpiX
, dpiY
);
149 static HRESULT WINAPI
BitmapClipper_CopyPalette(IWICBitmapClipper
*iface
,
150 IWICPalette
*palette
)
152 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
154 TRACE("(%p,%p)\n", iface
, palette
);
160 return WINCODEC_ERR_WRONGSTATE
;
162 return IWICBitmapSource_CopyPalette(This
->source
, palette
);
165 static HRESULT WINAPI
BitmapClipper_CopyPixels(IWICBitmapClipper
*iface
,
166 const WICRect
*rc
, UINT stride
, UINT buffer_size
, BYTE
*buffer
)
168 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
171 TRACE("(%p,%p,%u,%u,%p)\n", iface
, rc
, stride
, buffer_size
, buffer
);
174 return WINCODEC_ERR_WRONGSTATE
;
180 /* transform to source coordinates */
181 rect
.X
+= This
->rect
.X
;
182 rect
.Y
+= This
->rect
.Y
;
184 if ((rect
.X
+ rect
.Width
> This
->rect
.X
+ This
->rect
.Width
) ||
185 (rect
.Y
+ rect
.Height
> This
->rect
.Y
+ This
->rect
.Height
))
193 return IWICBitmapSource_CopyPixels(This
->source
, rc
, stride
, buffer_size
, buffer
);
196 static HRESULT WINAPI
BitmapClipper_Initialize(IWICBitmapClipper
*iface
,
197 IWICBitmapSource
*source
, const WICRect
*rc
)
199 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
203 TRACE("(%p,%p,%p)\n", iface
, source
, rc
);
205 EnterCriticalSection(&This
->lock
);
209 hr
= WINCODEC_ERR_WRONGSTATE
;
213 hr
= IWICBitmapSource_GetSize(source
, &width
, &height
);
214 if (FAILED(hr
)) goto end
;
216 if ((rc
->X
+ rc
->Width
> width
) || (rc
->Y
+ rc
->Height
> height
))
223 This
->source
= source
;
224 IWICBitmapSource_AddRef(This
->source
);
227 LeaveCriticalSection(&This
->lock
);
232 static const IWICBitmapClipperVtbl BitmapClipper_Vtbl
= {
233 BitmapClipper_QueryInterface
,
234 BitmapClipper_AddRef
,
235 BitmapClipper_Release
,
236 BitmapClipper_GetSize
,
237 BitmapClipper_GetPixelFormat
,
238 BitmapClipper_GetResolution
,
239 BitmapClipper_CopyPalette
,
240 BitmapClipper_CopyPixels
,
241 BitmapClipper_Initialize
244 HRESULT
BitmapClipper_Create(IWICBitmapClipper
**clipper
)
248 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapClipper
));
249 if (!This
) return E_OUTOFMEMORY
;
251 This
->IWICBitmapClipper_iface
.lpVtbl
= &BitmapClipper_Vtbl
;
254 InitializeCriticalSection(&This
->lock
);
255 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BitmapClipper.lock");
257 *clipper
= &This
->IWICBitmapClipper_iface
;