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
19 #include "wincodecs_private.h"
21 typedef struct BitmapClipper
{
22 IWICBitmapClipper IWICBitmapClipper_iface
;
24 IWICBitmapSource
*source
;
26 CRITICAL_SECTION lock
; /* must be held when initialized */
29 static inline BitmapClipper
*impl_from_IWICBitmapClipper(IWICBitmapClipper
*iface
)
31 return CONTAINING_RECORD(iface
, BitmapClipper
, IWICBitmapClipper_iface
);
34 static HRESULT WINAPI
BitmapClipper_QueryInterface(IWICBitmapClipper
*iface
, REFIID iid
,
37 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
38 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
40 if (!ppv
) return E_INVALIDARG
;
42 if (IsEqualIID(&IID_IUnknown
, iid
) ||
43 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
44 IsEqualIID(&IID_IWICBitmapClipper
, iid
))
46 *ppv
= &This
->IWICBitmapClipper_iface
;
54 IUnknown_AddRef((IUnknown
*)*ppv
);
58 static ULONG WINAPI
BitmapClipper_AddRef(IWICBitmapClipper
*iface
)
60 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
61 ULONG ref
= InterlockedIncrement(&This
->ref
);
63 TRACE("(%p) refcount=%u\n", iface
, ref
);
68 static ULONG WINAPI
BitmapClipper_Release(IWICBitmapClipper
*iface
)
70 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
71 ULONG ref
= InterlockedDecrement(&This
->ref
);
73 TRACE("(%p) refcount=%u\n", iface
, ref
);
77 This
->lock
.DebugInfo
->Spare
[0] = 0;
78 DeleteCriticalSection(&This
->lock
);
79 if (This
->source
) IWICBitmapSource_Release(This
->source
);
80 HeapFree(GetProcessHeap(), 0, This
);
86 static HRESULT WINAPI
BitmapClipper_GetSize(IWICBitmapClipper
*iface
,
87 UINT
*width
, UINT
*height
)
89 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
91 TRACE("(%p,%p,%p)\n", iface
, width
, height
);
93 if (!width
|| !height
)
97 return WINCODEC_ERR_WRONGSTATE
;
99 *width
= This
->rect
.Width
;
100 *height
= This
->rect
.Height
;
105 static HRESULT WINAPI
BitmapClipper_GetPixelFormat(IWICBitmapClipper
*iface
,
106 WICPixelFormatGUID
*format
)
108 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
109 TRACE("(%p,%p)\n", iface
, format
);
115 return WINCODEC_ERR_WRONGSTATE
;
117 return IWICBitmapSource_GetPixelFormat(This
->source
, format
);
120 static HRESULT WINAPI
BitmapClipper_GetResolution(IWICBitmapClipper
*iface
,
121 double *dpiX
, double *dpiY
)
123 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
125 TRACE("(%p,%p,%p)\n", iface
, dpiX
, dpiY
);
131 return WINCODEC_ERR_WRONGSTATE
;
133 return IWICBitmapSource_GetResolution(This
->source
, dpiX
, dpiY
);
136 static HRESULT WINAPI
BitmapClipper_CopyPalette(IWICBitmapClipper
*iface
,
137 IWICPalette
*palette
)
139 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
141 TRACE("(%p,%p)\n", iface
, palette
);
147 return WINCODEC_ERR_WRONGSTATE
;
149 return IWICBitmapSource_CopyPalette(This
->source
, palette
);
152 static HRESULT WINAPI
BitmapClipper_CopyPixels(IWICBitmapClipper
*iface
,
153 const WICRect
*rc
, UINT stride
, UINT buffer_size
, BYTE
*buffer
)
155 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
158 TRACE("(%p,%p,%u,%u,%p)\n", iface
, rc
, stride
, buffer_size
, buffer
);
161 return WINCODEC_ERR_WRONGSTATE
;
167 /* transform to source coordinates */
168 rect
.X
+= This
->rect
.X
;
169 rect
.Y
+= This
->rect
.Y
;
171 if ((rect
.X
+ rect
.Width
> This
->rect
.X
+ This
->rect
.Width
) ||
172 (rect
.Y
+ rect
.Height
> This
->rect
.Y
+ This
->rect
.Height
))
180 return IWICBitmapSource_CopyPixels(This
->source
, rc
, stride
, buffer_size
, buffer
);
183 static HRESULT WINAPI
BitmapClipper_Initialize(IWICBitmapClipper
*iface
,
184 IWICBitmapSource
*source
, const WICRect
*rc
)
186 BitmapClipper
*This
= impl_from_IWICBitmapClipper(iface
);
190 TRACE("(%p,%p,%p)\n", iface
, source
, rc
);
192 EnterCriticalSection(&This
->lock
);
196 hr
= WINCODEC_ERR_WRONGSTATE
;
200 hr
= IWICBitmapSource_GetSize(source
, &width
, &height
);
201 if (FAILED(hr
)) goto end
;
203 if ((rc
->X
+ rc
->Width
> width
) || (rc
->Y
+ rc
->Height
> height
))
210 This
->source
= source
;
211 IWICBitmapSource_AddRef(This
->source
);
214 LeaveCriticalSection(&This
->lock
);
219 static const IWICBitmapClipperVtbl BitmapClipper_Vtbl
= {
220 BitmapClipper_QueryInterface
,
221 BitmapClipper_AddRef
,
222 BitmapClipper_Release
,
223 BitmapClipper_GetSize
,
224 BitmapClipper_GetPixelFormat
,
225 BitmapClipper_GetResolution
,
226 BitmapClipper_CopyPalette
,
227 BitmapClipper_CopyPixels
,
228 BitmapClipper_Initialize
231 HRESULT
BitmapClipper_Create(IWICBitmapClipper
**clipper
)
235 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapClipper
));
236 if (!This
) return E_OUTOFMEMORY
;
238 This
->IWICBitmapClipper_iface
.lpVtbl
= &BitmapClipper_Vtbl
;
241 InitializeCriticalSection(&This
->lock
);
242 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BitmapClipper.lock");
244 *clipper
= &This
->IWICBitmapClipper_iface
;