Release 1.5.29.
[wine] / dlls / windowscodecs / colortransform.c
1 /*
2  * Copyright 2013 Hans Leidekker for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #define COBJMACROS
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
28 #include "wincodec.h"
29
30 #include "wincodecs_private.h"
31
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
35
36 typedef struct ColorTransform {
37     IWICColorTransform IWICColorTransform_iface;
38     LONG ref;
39     IWICBitmapSource *dst;
40 } ColorTransform;
41
42 static inline ColorTransform *impl_from_IWICColorTransform(IWICColorTransform *iface)
43 {
44     return CONTAINING_RECORD(iface, ColorTransform, IWICColorTransform_iface);
45 }
46
47 static HRESULT WINAPI ColorTransform_QueryInterface(IWICColorTransform *iface, REFIID iid,
48     void **ppv)
49 {
50     ColorTransform *This = impl_from_IWICColorTransform(iface);
51     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
52
53     if (!ppv) return E_INVALIDARG;
54
55     if (IsEqualIID(&IID_IUnknown, iid) ||
56         IsEqualIID(&IID_IWICBitmapSource, iid) ||
57         IsEqualIID(&IID_IWICColorTransform, iid))
58     {
59         *ppv = &This->IWICColorTransform_iface;
60     }
61     else
62     {
63         *ppv = NULL;
64         return E_NOINTERFACE;
65     }
66
67     IUnknown_AddRef((IUnknown*)*ppv);
68     return S_OK;
69 }
70
71 static ULONG WINAPI ColorTransform_AddRef(IWICColorTransform *iface)
72 {
73     ColorTransform *This = impl_from_IWICColorTransform(iface);
74     ULONG ref = InterlockedIncrement(&This->ref);
75
76     TRACE("(%p) refcount=%u\n", iface, ref);
77
78     return ref;
79 }
80
81 static ULONG WINAPI ColorTransform_Release(IWICColorTransform *iface)
82 {
83     ColorTransform *This = impl_from_IWICColorTransform(iface);
84     ULONG ref = InterlockedDecrement(&This->ref);
85
86     TRACE("(%p) refcount=%u\n", iface, ref);
87
88     if (ref == 0)
89     {
90         if (This->dst) IWICBitmapSource_Release(This->dst);
91         HeapFree(GetProcessHeap(), 0, This);
92     }
93
94     return ref;
95 }
96
97 static HRESULT WINAPI ColorTransform_GetSize(IWICColorTransform *iface,
98     UINT *puiWidth, UINT *puiHeight)
99 {
100     ColorTransform *This = impl_from_IWICColorTransform(iface);
101     TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
102
103     return IWICBitmapSource_GetSize(This->dst, puiWidth, puiHeight);
104 }
105
106 static HRESULT WINAPI ColorTransform_GetPixelFormat(IWICColorTransform *iface,
107     WICPixelFormatGUID *pPixelFormat)
108 {
109     ColorTransform *This = impl_from_IWICColorTransform(iface);
110     TRACE("(%p,%p)\n", iface, pPixelFormat);
111
112     return IWICBitmapSource_GetPixelFormat(This->dst, pPixelFormat);
113 }
114
115 static HRESULT WINAPI ColorTransform_GetResolution(IWICColorTransform *iface,
116     double *pDpiX, double *pDpiY)
117 {
118     ColorTransform *This = impl_from_IWICColorTransform(iface);
119     TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
120
121     return IWICBitmapSource_GetResolution(This->dst, pDpiX, pDpiY);
122 }
123
124 static HRESULT WINAPI ColorTransform_CopyPalette(IWICColorTransform *iface,
125     IWICPalette *pIPalette)
126 {
127     ColorTransform *This = impl_from_IWICColorTransform(iface);
128     TRACE("(%p,%p)\n", iface, pIPalette);
129
130     return IWICBitmapSource_CopyPalette(This->dst, pIPalette);
131 }
132
133 static HRESULT WINAPI ColorTransform_CopyPixels(IWICColorTransform *iface,
134     const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
135 {
136     ColorTransform *This = impl_from_IWICColorTransform(iface);
137     TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
138
139     return IWICBitmapSource_CopyPixels(This->dst, prc, cbStride, cbBufferSize, pbBuffer);
140 }
141
142 static HRESULT WINAPI ColorTransform_Initialize(IWICColorTransform *iface,
143     IWICBitmapSource *pIBitmapSource, IWICColorContext *pIContextSource,
144     IWICColorContext *pIContextDest, REFWICPixelFormatGUID pixelFmtDest)
145 {
146     ColorTransform *This = impl_from_IWICColorTransform(iface);
147     IWICBitmapSource *dst;
148     HRESULT hr;
149
150     TRACE("(%p,%p,%p,%p,%s)\n", iface, pIBitmapSource, pIContextSource,
151           pIContextDest, debugstr_guid(pixelFmtDest));
152
153     FIXME("ignoring color contexts\n");
154
155     hr = WICConvertBitmapSource(pixelFmtDest, pIBitmapSource, &dst);
156     if (FAILED(hr)) return hr;
157
158     if (This->dst) IWICBitmapSource_Release(This->dst);
159     This->dst = dst;
160     return S_OK;
161 }
162
163 static const IWICColorTransformVtbl ColorTransform_Vtbl = {
164     ColorTransform_QueryInterface,
165     ColorTransform_AddRef,
166     ColorTransform_Release,
167     ColorTransform_GetSize,
168     ColorTransform_GetPixelFormat,
169     ColorTransform_GetResolution,
170     ColorTransform_CopyPalette,
171     ColorTransform_CopyPixels,
172     ColorTransform_Initialize
173 };
174
175 HRESULT ColorTransform_Create(IWICColorTransform **colortransform)
176 {
177     ColorTransform *This;
178
179     if (!colortransform) return E_INVALIDARG;
180
181     This = HeapAlloc(GetProcessHeap(), 0, sizeof(ColorTransform));
182     if (!This) return E_OUTOFMEMORY;
183
184     This->IWICColorTransform_iface.lpVtbl = &ColorTransform_Vtbl;
185     This->ref = 1;
186     This->dst = NULL;
187
188     *colortransform = &This->IWICColorTransform_iface;
189
190     return S_OK;
191 }