2 * Copyright 2010 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
19 #define WIN32_NO_STATUS
21 #define COM_NO_WINDOWS_H
34 //#include "wincodecs_private.h"
36 #include <wine/debug.h>
38 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
40 typedef struct FlipRotator
{
41 IWICBitmapFlipRotator IWICBitmapFlipRotator_iface
;
43 IWICBitmapSource
*source
;
47 CRITICAL_SECTION lock
; /* must be held when initialized */
50 static inline FlipRotator
*impl_from_IWICBitmapFlipRotator(IWICBitmapFlipRotator
*iface
)
52 return CONTAINING_RECORD(iface
, FlipRotator
, IWICBitmapFlipRotator_iface
);
55 static HRESULT WINAPI
FlipRotator_QueryInterface(IWICBitmapFlipRotator
*iface
, REFIID iid
,
58 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
59 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
61 if (!ppv
) return E_INVALIDARG
;
63 if (IsEqualIID(&IID_IUnknown
, iid
) ||
64 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
65 IsEqualIID(&IID_IWICBitmapFlipRotator
, iid
))
67 *ppv
= &This
->IWICBitmapFlipRotator_iface
;
75 IUnknown_AddRef((IUnknown
*)*ppv
);
79 static ULONG WINAPI
FlipRotator_AddRef(IWICBitmapFlipRotator
*iface
)
81 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
82 ULONG ref
= InterlockedIncrement(&This
->ref
);
84 TRACE("(%p) refcount=%u\n", iface
, ref
);
89 static ULONG WINAPI
FlipRotator_Release(IWICBitmapFlipRotator
*iface
)
91 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
92 ULONG ref
= InterlockedDecrement(&This
->ref
);
94 TRACE("(%p) refcount=%u\n", iface
, ref
);
98 This
->lock
.DebugInfo
->Spare
[0] = 0;
99 DeleteCriticalSection(&This
->lock
);
100 if (This
->source
) IWICBitmapSource_Release(This
->source
);
101 HeapFree(GetProcessHeap(), 0, This
);
107 static HRESULT WINAPI
FlipRotator_GetSize(IWICBitmapFlipRotator
*iface
,
108 UINT
*puiWidth
, UINT
*puiHeight
)
110 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
111 TRACE("(%p,%p,%p)\n", iface
, puiWidth
, puiHeight
);
114 return WINCODEC_ERR_WRONGSTATE
;
115 else if (This
->swap_xy
)
116 return IWICBitmapSource_GetSize(This
->source
, puiHeight
, puiWidth
);
118 return IWICBitmapSource_GetSize(This
->source
, puiWidth
, puiHeight
);
121 static HRESULT WINAPI
FlipRotator_GetPixelFormat(IWICBitmapFlipRotator
*iface
,
122 WICPixelFormatGUID
*pPixelFormat
)
124 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
125 TRACE("(%p,%p)\n", iface
, pPixelFormat
);
128 return WINCODEC_ERR_WRONGSTATE
;
130 return IWICBitmapSource_GetPixelFormat(This
->source
, pPixelFormat
);
133 static HRESULT WINAPI
FlipRotator_GetResolution(IWICBitmapFlipRotator
*iface
,
134 double *pDpiX
, double *pDpiY
)
136 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
137 TRACE("(%p,%p,%p)\n", iface
, pDpiX
, pDpiY
);
140 return WINCODEC_ERR_WRONGSTATE
;
141 else if (This
->swap_xy
)
142 return IWICBitmapSource_GetResolution(This
->source
, pDpiY
, pDpiX
);
144 return IWICBitmapSource_GetResolution(This
->source
, pDpiX
, pDpiY
);
147 static HRESULT WINAPI
FlipRotator_CopyPalette(IWICBitmapFlipRotator
*iface
,
148 IWICPalette
*pIPalette
)
150 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
151 TRACE("(%p,%p)\n", iface
, pIPalette
);
154 return WINCODEC_ERR_WRONGSTATE
;
156 return IWICBitmapSource_CopyPalette(This
->source
, pIPalette
);
159 static HRESULT WINAPI
FlipRotator_CopyPixels(IWICBitmapFlipRotator
*iface
,
160 const WICRect
*prc
, UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
)
162 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
165 UINT srcy
, srcwidth
, srcheight
;
169 TRACE("(%p,%p,%u,%u,%p)\n", iface
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
171 if (!This
->source
) return WINCODEC_ERR_WRONGSTATE
;
173 if (This
->swap_xy
|| This
->flip_x
)
175 /* This requires knowledge of the pixel format. */
176 FIXME("flipping x and rotating are not implemented\n");
180 hr
= IWICBitmapSource_GetSize(This
->source
, &srcwidth
, &srcheight
);
181 if (FAILED(hr
)) return hr
;
186 hr
= IWICBitmapFlipRotator_GetSize(iface
, &width
, &height
);
187 if (FAILED(hr
)) return hr
;
191 rect
.Height
= height
;
195 for (y
=prc
->Y
; y
- prc
->Y
< prc
->Height
; y
++)
198 srcy
= srcheight
- 1 - y
;
204 rc
.Width
= prc
->Width
;
207 hr
= IWICBitmapSource_CopyPixels(This
->source
, &rc
, cbStride
, cbStride
,
210 if (FAILED(hr
)) break;
212 pbBuffer
+= cbStride
;
218 static HRESULT WINAPI
FlipRotator_Initialize(IWICBitmapFlipRotator
*iface
,
219 IWICBitmapSource
*pISource
, WICBitmapTransformOptions options
)
221 FlipRotator
*This
= impl_from_IWICBitmapFlipRotator(iface
);
224 TRACE("(%p,%p,%u)\n", iface
, pISource
, options
);
226 EnterCriticalSection(&This
->lock
);
230 hr
= WINCODEC_ERR_WRONGSTATE
;
234 if (options
&WICBitmapTransformRotate90
)
237 This
->flip_x
= !This
->flip_x
;
240 if (options
&WICBitmapTransformRotate180
)
242 This
->flip_x
= !This
->flip_x
;
243 This
->flip_y
= !This
->flip_y
;
246 if (options
&WICBitmapTransformFlipHorizontal
)
247 This
->flip_x
= !This
->flip_x
;
249 if (options
&WICBitmapTransformFlipVertical
)
250 This
->flip_y
= !This
->flip_y
;
252 IWICBitmapSource_AddRef(pISource
);
253 This
->source
= pISource
;
256 LeaveCriticalSection(&This
->lock
);
261 static const IWICBitmapFlipRotatorVtbl FlipRotator_Vtbl
= {
262 FlipRotator_QueryInterface
,
266 FlipRotator_GetPixelFormat
,
267 FlipRotator_GetResolution
,
268 FlipRotator_CopyPalette
,
269 FlipRotator_CopyPixels
,
270 FlipRotator_Initialize
273 HRESULT
FlipRotator_Create(IWICBitmapFlipRotator
**fliprotator
)
277 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(FlipRotator
));
278 if (!This
) return E_OUTOFMEMORY
;
280 This
->IWICBitmapFlipRotator_iface
.lpVtbl
= &FlipRotator_Vtbl
;
286 InitializeCriticalSection(&This
->lock
);
287 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": FlipRotator.lock");
289 *fliprotator
= &This
->IWICBitmapFlipRotator_iface
;