2 * Copyright 2012 Hans Leidekker 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
30 #include "wincodecs_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
36 typedef struct ColorContext
{
37 IWICColorContext IWICColorContext_iface
;
39 WICColorContextType type
;
42 UINT exif_color_space
;
45 static inline ColorContext
*impl_from_IWICColorContext(IWICColorContext
*iface
)
47 return CONTAINING_RECORD(iface
, ColorContext
, IWICColorContext_iface
);
50 static HRESULT WINAPI
ColorContext_QueryInterface(IWICColorContext
*iface
, REFIID iid
,
53 ColorContext
*This
= impl_from_IWICColorContext(iface
);
54 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
56 if (!ppv
) return E_INVALIDARG
;
58 if (IsEqualIID(&IID_IUnknown
, iid
) ||
59 IsEqualIID(&IID_IWICColorContext
, iid
))
61 *ppv
= &This
->IWICColorContext_iface
;
69 IUnknown_AddRef((IUnknown
*)*ppv
);
73 static ULONG WINAPI
ColorContext_AddRef(IWICColorContext
*iface
)
75 ColorContext
*This
= impl_from_IWICColorContext(iface
);
76 ULONG ref
= InterlockedIncrement(&This
->ref
);
78 TRACE("(%p) refcount=%u\n", iface
, ref
);
83 static ULONG WINAPI
ColorContext_Release(IWICColorContext
*iface
)
85 ColorContext
*This
= impl_from_IWICColorContext(iface
);
86 ULONG ref
= InterlockedDecrement(&This
->ref
);
88 TRACE("(%p) refcount=%u\n", iface
, ref
);
92 HeapFree(GetProcessHeap(), 0, This
->profile
);
93 HeapFree(GetProcessHeap(), 0, This
);
99 static HRESULT
load_profile(const WCHAR
*filename
, BYTE
**profile
, UINT
*len
)
108 handle
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
109 if (handle
== INVALID_HANDLE_VALUE
) return HRESULT_FROM_WIN32(GetLastError());
111 if (!(GetFileSizeEx(handle
, &size
)))
114 return HRESULT_FROM_WIN32(GetLastError());
118 WARN("file too large\n");
122 if (!(*profile
= HeapAlloc(GetProcessHeap(), 0, size
.u
.LowPart
)))
125 return E_OUTOFMEMORY
;
127 ret
= ReadFile(handle
, *profile
, size
.u
.LowPart
, &count
, NULL
);
130 HeapFree (GetProcessHeap(),0,*profile
);
132 return HRESULT_FROM_WIN32(GetLastError());
134 if (count
!= size
.u
.LowPart
) {
135 HeapFree (GetProcessHeap(),0,*profile
);
143 static HRESULT WINAPI
ColorContext_InitializeFromFilename(IWICColorContext
*iface
,
146 ColorContext
*This
= impl_from_IWICColorContext(iface
);
150 TRACE("(%p,%s)\n", iface
, debugstr_w(wzFilename
));
152 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextProfile
)
153 return WINCODEC_ERR_WRONGSTATE
;
155 if (!wzFilename
) return E_INVALIDARG
;
157 hr
= load_profile(wzFilename
, &profile
, &len
);
158 if (FAILED(hr
)) return hr
;
160 HeapFree(GetProcessHeap(), 0, This
->profile
);
161 This
->profile
= profile
;
162 This
->profile_len
= len
;
163 This
->type
= WICColorContextProfile
;
168 static HRESULT WINAPI
ColorContext_InitializeFromMemory(IWICColorContext
*iface
,
169 const BYTE
*pbBuffer
, UINT cbBufferSize
)
171 ColorContext
*This
= impl_from_IWICColorContext(iface
);
173 TRACE("(%p,%p,%u)\n", iface
, pbBuffer
, cbBufferSize
);
175 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextProfile
)
176 return WINCODEC_ERR_WRONGSTATE
;
178 if (!(profile
= HeapAlloc(GetProcessHeap(), 0, cbBufferSize
))) return E_OUTOFMEMORY
;
179 memcpy(profile
, pbBuffer
, cbBufferSize
);
181 HeapFree(GetProcessHeap(), 0, This
->profile
);
182 This
->profile
= profile
;
183 This
->profile_len
= cbBufferSize
;
184 This
->type
= WICColorContextProfile
;
189 static HRESULT WINAPI
ColorContext_InitializeFromExifColorSpace(IWICColorContext
*iface
,
192 ColorContext
*This
= impl_from_IWICColorContext(iface
);
193 TRACE("(%p,%u)\n", iface
, value
);
195 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextExifColorSpace
)
196 return WINCODEC_ERR_WRONGSTATE
;
198 This
->exif_color_space
= value
;
199 This
->type
= WICColorContextExifColorSpace
;
204 static HRESULT WINAPI
ColorContext_GetType(IWICColorContext
*iface
,
205 WICColorContextType
*pType
)
207 ColorContext
*This
= impl_from_IWICColorContext(iface
);
208 TRACE("(%p,%p)\n", iface
, pType
);
210 if (!pType
) return E_INVALIDARG
;
216 static HRESULT WINAPI
ColorContext_GetProfileBytes(IWICColorContext
*iface
,
217 UINT cbBuffer
, BYTE
*pbBuffer
, UINT
*pcbActual
)
219 ColorContext
*This
= impl_from_IWICColorContext(iface
);
220 TRACE("(%p,%u,%p,%p)\n", iface
, cbBuffer
, pbBuffer
, pcbActual
);
222 if (This
->type
!= WICColorContextProfile
)
223 return WINCODEC_ERR_NOTINITIALIZED
;
225 if (!pcbActual
) return E_INVALIDARG
;
227 if (cbBuffer
>= This
->profile_len
&& pbBuffer
)
228 memcpy(pbBuffer
, This
->profile
, This
->profile_len
);
230 *pcbActual
= This
->profile_len
;
235 static HRESULT WINAPI
ColorContext_GetExifColorSpace(IWICColorContext
*iface
,
238 ColorContext
*This
= impl_from_IWICColorContext(iface
);
239 TRACE("(%p,%p)\n", iface
, pValue
);
241 if (!pValue
) return E_INVALIDARG
;
243 *pValue
= This
->exif_color_space
;
247 static const IWICColorContextVtbl ColorContext_Vtbl
= {
248 ColorContext_QueryInterface
,
250 ColorContext_Release
,
251 ColorContext_InitializeFromFilename
,
252 ColorContext_InitializeFromMemory
,
253 ColorContext_InitializeFromExifColorSpace
,
254 ColorContext_GetType
,
255 ColorContext_GetProfileBytes
,
256 ColorContext_GetExifColorSpace
259 HRESULT
ColorContext_Create(IWICColorContext
**colorcontext
)
263 if (!colorcontext
) return E_INVALIDARG
;
265 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ColorContext
));
266 if (!This
) return E_OUTOFMEMORY
;
268 This
->IWICColorContext_iface
.lpVtbl
= &ColorContext_Vtbl
;
271 This
->profile
= NULL
;
272 This
->profile_len
= 0;
273 This
->exif_color_space
= ~0u;
275 *colorcontext
= &This
->IWICColorContext_iface
;