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
27 #include "wincodecs_private.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
33 typedef struct ColorContext
{
34 IWICColorContext IWICColorContext_iface
;
36 WICColorContextType type
;
39 UINT exif_color_space
;
42 static inline ColorContext
*impl_from_IWICColorContext(IWICColorContext
*iface
)
44 return CONTAINING_RECORD(iface
, ColorContext
, IWICColorContext_iface
);
47 static HRESULT WINAPI
ColorContext_QueryInterface(IWICColorContext
*iface
, REFIID iid
,
50 ColorContext
*This
= impl_from_IWICColorContext(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_IWICColorContext
, iid
))
58 *ppv
= &This
->IWICColorContext_iface
;
66 IUnknown_AddRef((IUnknown
*)*ppv
);
70 static ULONG WINAPI
ColorContext_AddRef(IWICColorContext
*iface
)
72 ColorContext
*This
= impl_from_IWICColorContext(iface
);
73 ULONG ref
= InterlockedIncrement(&This
->ref
);
75 TRACE("(%p) refcount=%u\n", iface
, ref
);
80 static ULONG WINAPI
ColorContext_Release(IWICColorContext
*iface
)
82 ColorContext
*This
= impl_from_IWICColorContext(iface
);
83 ULONG ref
= InterlockedDecrement(&This
->ref
);
85 TRACE("(%p) refcount=%u\n", iface
, ref
);
89 HeapFree(GetProcessHeap(), 0, This
->profile
);
90 HeapFree(GetProcessHeap(), 0, This
);
96 static HRESULT
load_profile(const WCHAR
*filename
, BYTE
**profile
, UINT
*len
)
105 handle
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
106 if (handle
== INVALID_HANDLE_VALUE
) return HRESULT_FROM_WIN32(GetLastError());
108 if (!(GetFileSizeEx(handle
, &size
)))
111 return HRESULT_FROM_WIN32(GetLastError());
115 WARN("file too large\n");
119 if (!(*profile
= HeapAlloc(GetProcessHeap(), 0, size
.u
.LowPart
)))
122 return E_OUTOFMEMORY
;
124 ret
= ReadFile(handle
, *profile
, size
.u
.LowPart
, &count
, NULL
);
127 HeapFree (GetProcessHeap(),0,*profile
);
129 return HRESULT_FROM_WIN32(GetLastError());
131 if (count
!= size
.u
.LowPart
) {
132 HeapFree (GetProcessHeap(),0,*profile
);
140 static HRESULT WINAPI
ColorContext_InitializeFromFilename(IWICColorContext
*iface
,
143 ColorContext
*This
= impl_from_IWICColorContext(iface
);
147 TRACE("(%p,%s)\n", iface
, debugstr_w(wzFilename
));
149 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextProfile
)
150 return WINCODEC_ERR_WRONGSTATE
;
152 if (!wzFilename
) return E_INVALIDARG
;
154 hr
= load_profile(wzFilename
, &profile
, &len
);
155 if (FAILED(hr
)) return hr
;
157 HeapFree(GetProcessHeap(), 0, This
->profile
);
158 This
->profile
= profile
;
159 This
->profile_len
= len
;
160 This
->type
= WICColorContextProfile
;
165 static HRESULT WINAPI
ColorContext_InitializeFromMemory(IWICColorContext
*iface
,
166 const BYTE
*pbBuffer
, UINT cbBufferSize
)
168 ColorContext
*This
= impl_from_IWICColorContext(iface
);
170 TRACE("(%p,%p,%u)\n", iface
, pbBuffer
, cbBufferSize
);
172 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextProfile
)
173 return WINCODEC_ERR_WRONGSTATE
;
175 if (!(profile
= HeapAlloc(GetProcessHeap(), 0, cbBufferSize
))) return E_OUTOFMEMORY
;
176 memcpy(profile
, pbBuffer
, cbBufferSize
);
178 HeapFree(GetProcessHeap(), 0, This
->profile
);
179 This
->profile
= profile
;
180 This
->profile_len
= cbBufferSize
;
181 This
->type
= WICColorContextProfile
;
186 static HRESULT WINAPI
ColorContext_InitializeFromExifColorSpace(IWICColorContext
*iface
,
189 ColorContext
*This
= impl_from_IWICColorContext(iface
);
190 TRACE("(%p,%u)\n", iface
, value
);
192 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextExifColorSpace
)
193 return WINCODEC_ERR_WRONGSTATE
;
195 This
->exif_color_space
= value
;
196 This
->type
= WICColorContextExifColorSpace
;
201 static HRESULT WINAPI
ColorContext_GetType(IWICColorContext
*iface
,
202 WICColorContextType
*pType
)
204 ColorContext
*This
= impl_from_IWICColorContext(iface
);
205 TRACE("(%p,%p)\n", iface
, pType
);
207 if (!pType
) return E_INVALIDARG
;
213 static HRESULT WINAPI
ColorContext_GetProfileBytes(IWICColorContext
*iface
,
214 UINT cbBuffer
, BYTE
*pbBuffer
, UINT
*pcbActual
)
216 ColorContext
*This
= impl_from_IWICColorContext(iface
);
217 TRACE("(%p,%u,%p,%p)\n", iface
, cbBuffer
, pbBuffer
, pcbActual
);
219 if (This
->type
!= WICColorContextProfile
)
220 return WINCODEC_ERR_NOTINITIALIZED
;
222 if (!pcbActual
) return E_INVALIDARG
;
224 if (cbBuffer
>= This
->profile_len
&& pbBuffer
)
225 memcpy(pbBuffer
, This
->profile
, This
->profile_len
);
227 *pcbActual
= This
->profile_len
;
232 static HRESULT WINAPI
ColorContext_GetExifColorSpace(IWICColorContext
*iface
,
235 ColorContext
*This
= impl_from_IWICColorContext(iface
);
236 TRACE("(%p,%p)\n", iface
, pValue
);
238 if (!pValue
) return E_INVALIDARG
;
240 *pValue
= This
->exif_color_space
;
244 static const IWICColorContextVtbl ColorContext_Vtbl
= {
245 ColorContext_QueryInterface
,
247 ColorContext_Release
,
248 ColorContext_InitializeFromFilename
,
249 ColorContext_InitializeFromMemory
,
250 ColorContext_InitializeFromExifColorSpace
,
251 ColorContext_GetType
,
252 ColorContext_GetProfileBytes
,
253 ColorContext_GetExifColorSpace
256 HRESULT
ColorContext_Create(IWICColorContext
**colorcontext
)
260 if (!colorcontext
) return E_INVALIDARG
;
262 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ColorContext
));
263 if (!This
) return E_OUTOFMEMORY
;
265 This
->IWICColorContext_iface
.lpVtbl
= &ColorContext_Vtbl
;
268 This
->profile
= NULL
;
269 This
->profile_len
= 0;
270 This
->exif_color_space
= ~0u;
272 *colorcontext
= &This
->IWICColorContext_iface
;