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
29 #include "wincodecs_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
35 typedef struct ColorContext
{
36 IWICColorContext IWICColorContext_iface
;
38 WICColorContextType type
;
41 UINT exif_color_space
;
44 static inline ColorContext
*impl_from_IWICColorContext(IWICColorContext
*iface
)
46 return CONTAINING_RECORD(iface
, ColorContext
, IWICColorContext_iface
);
49 static HRESULT WINAPI
ColorContext_QueryInterface(IWICColorContext
*iface
, REFIID iid
,
52 ColorContext
*This
= impl_from_IWICColorContext(iface
);
53 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
55 if (!ppv
) return E_INVALIDARG
;
57 if (IsEqualIID(&IID_IUnknown
, iid
) ||
58 IsEqualIID(&IID_IWICColorContext
, iid
))
60 *ppv
= &This
->IWICColorContext_iface
;
68 IUnknown_AddRef((IUnknown
*)*ppv
);
72 static ULONG WINAPI
ColorContext_AddRef(IWICColorContext
*iface
)
74 ColorContext
*This
= impl_from_IWICColorContext(iface
);
75 ULONG ref
= InterlockedIncrement(&This
->ref
);
77 TRACE("(%p) refcount=%u\n", iface
, ref
);
82 static ULONG WINAPI
ColorContext_Release(IWICColorContext
*iface
)
84 ColorContext
*This
= impl_from_IWICColorContext(iface
);
85 ULONG ref
= InterlockedDecrement(&This
->ref
);
87 TRACE("(%p) refcount=%u\n", iface
, ref
);
91 HeapFree(GetProcessHeap(), 0, This
->profile
);
92 HeapFree(GetProcessHeap(), 0, This
);
98 static HRESULT
load_profile(const WCHAR
*filename
, BYTE
**profile
, UINT
*len
)
107 handle
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
108 if (handle
== INVALID_HANDLE_VALUE
) return HRESULT_FROM_WIN32(GetLastError());
110 if (!(GetFileSizeEx(handle
, &size
)))
113 return HRESULT_FROM_WIN32(GetLastError());
117 WARN("file too large\n");
121 if (!(*profile
= HeapAlloc(GetProcessHeap(), 0, size
.u
.LowPart
)))
124 return E_OUTOFMEMORY
;
126 ret
= ReadFile(handle
, *profile
, size
.u
.LowPart
, &count
, NULL
);
129 HeapFree (GetProcessHeap(),0,*profile
);
131 return HRESULT_FROM_WIN32(GetLastError());
133 if (count
!= size
.u
.LowPart
) {
134 HeapFree (GetProcessHeap(),0,*profile
);
142 static HRESULT WINAPI
ColorContext_InitializeFromFilename(IWICColorContext
*iface
,
145 ColorContext
*This
= impl_from_IWICColorContext(iface
);
149 TRACE("(%p,%s)\n", iface
, debugstr_w(wzFilename
));
151 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextProfile
)
152 return WINCODEC_ERR_WRONGSTATE
;
154 if (!wzFilename
) return E_INVALIDARG
;
156 hr
= load_profile(wzFilename
, &profile
, &len
);
157 if (FAILED(hr
)) return hr
;
159 HeapFree(GetProcessHeap(), 0, This
->profile
);
160 This
->profile
= profile
;
161 This
->profile_len
= len
;
162 This
->type
= WICColorContextProfile
;
167 static HRESULT WINAPI
ColorContext_InitializeFromMemory(IWICColorContext
*iface
,
168 const BYTE
*pbBuffer
, UINT cbBufferSize
)
170 ColorContext
*This
= impl_from_IWICColorContext(iface
);
172 TRACE("(%p,%p,%u)\n", iface
, pbBuffer
, cbBufferSize
);
174 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextProfile
)
175 return WINCODEC_ERR_WRONGSTATE
;
177 if (!(profile
= HeapAlloc(GetProcessHeap(), 0, cbBufferSize
))) return E_OUTOFMEMORY
;
178 memcpy(profile
, pbBuffer
, cbBufferSize
);
180 HeapFree(GetProcessHeap(), 0, This
->profile
);
181 This
->profile
= profile
;
182 This
->profile_len
= cbBufferSize
;
183 This
->type
= WICColorContextProfile
;
188 static HRESULT WINAPI
ColorContext_InitializeFromExifColorSpace(IWICColorContext
*iface
,
191 ColorContext
*This
= impl_from_IWICColorContext(iface
);
192 TRACE("(%p,%u)\n", iface
, value
);
194 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextExifColorSpace
)
195 return WINCODEC_ERR_WRONGSTATE
;
197 This
->exif_color_space
= value
;
198 This
->type
= WICColorContextExifColorSpace
;
203 static HRESULT WINAPI
ColorContext_GetType(IWICColorContext
*iface
,
204 WICColorContextType
*pType
)
206 ColorContext
*This
= impl_from_IWICColorContext(iface
);
207 TRACE("(%p,%p)\n", iface
, pType
);
209 if (!pType
) return E_INVALIDARG
;
215 static HRESULT WINAPI
ColorContext_GetProfileBytes(IWICColorContext
*iface
,
216 UINT cbBuffer
, BYTE
*pbBuffer
, UINT
*pcbActual
)
218 ColorContext
*This
= impl_from_IWICColorContext(iface
);
219 TRACE("(%p,%u,%p,%p)\n", iface
, cbBuffer
, pbBuffer
, pcbActual
);
221 if (This
->type
!= WICColorContextProfile
)
222 return WINCODEC_ERR_NOTINITIALIZED
;
224 if (!pcbActual
) return E_INVALIDARG
;
226 if (cbBuffer
>= This
->profile_len
&& pbBuffer
)
227 memcpy(pbBuffer
, This
->profile
, This
->profile_len
);
229 *pcbActual
= This
->profile_len
;
234 static HRESULT WINAPI
ColorContext_GetExifColorSpace(IWICColorContext
*iface
,
237 ColorContext
*This
= impl_from_IWICColorContext(iface
);
238 TRACE("(%p,%p)\n", iface
, pValue
);
240 if (!pValue
) return E_INVALIDARG
;
242 *pValue
= This
->exif_color_space
;
246 static const IWICColorContextVtbl ColorContext_Vtbl
= {
247 ColorContext_QueryInterface
,
249 ColorContext_Release
,
250 ColorContext_InitializeFromFilename
,
251 ColorContext_InitializeFromMemory
,
252 ColorContext_InitializeFromExifColorSpace
,
253 ColorContext_GetType
,
254 ColorContext_GetProfileBytes
,
255 ColorContext_GetExifColorSpace
258 HRESULT
ColorContext_Create(IWICColorContext
**colorcontext
)
262 if (!colorcontext
) return E_INVALIDARG
;
264 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ColorContext
));
265 if (!This
) return E_OUTOFMEMORY
;
267 This
->IWICColorContext_iface
.lpVtbl
= &ColorContext_Vtbl
;
270 This
->profile
= NULL
;
271 This
->profile_len
= 0;
272 This
->exif_color_space
= ~0u;
274 *colorcontext
= &This
->IWICColorContext_iface
;