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
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 ColorContext
{
41 IWICColorContext IWICColorContext_iface
;
43 WICColorContextType type
;
46 UINT exif_color_space
;
49 static inline ColorContext
*impl_from_IWICColorContext(IWICColorContext
*iface
)
51 return CONTAINING_RECORD(iface
, ColorContext
, IWICColorContext_iface
);
54 static HRESULT WINAPI
ColorContext_QueryInterface(IWICColorContext
*iface
, REFIID iid
,
57 ColorContext
*This
= impl_from_IWICColorContext(iface
);
58 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
60 if (!ppv
) return E_INVALIDARG
;
62 if (IsEqualIID(&IID_IUnknown
, iid
) ||
63 IsEqualIID(&IID_IWICColorContext
, iid
))
65 *ppv
= &This
->IWICColorContext_iface
;
73 IUnknown_AddRef((IUnknown
*)*ppv
);
77 static ULONG WINAPI
ColorContext_AddRef(IWICColorContext
*iface
)
79 ColorContext
*This
= impl_from_IWICColorContext(iface
);
80 ULONG ref
= InterlockedIncrement(&This
->ref
);
82 TRACE("(%p) refcount=%u\n", iface
, ref
);
87 static ULONG WINAPI
ColorContext_Release(IWICColorContext
*iface
)
89 ColorContext
*This
= impl_from_IWICColorContext(iface
);
90 ULONG ref
= InterlockedDecrement(&This
->ref
);
92 TRACE("(%p) refcount=%u\n", iface
, ref
);
96 HeapFree(GetProcessHeap(), 0, This
->profile
);
97 HeapFree(GetProcessHeap(), 0, This
);
103 static HRESULT
load_profile(const WCHAR
*filename
, BYTE
**profile
, UINT
*len
)
112 handle
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
113 if (handle
== INVALID_HANDLE_VALUE
) return HRESULT_FROM_WIN32(GetLastError());
115 if (!(GetFileSizeEx(handle
, &size
)))
118 return HRESULT_FROM_WIN32(GetLastError());
122 WARN("file too large\n");
126 if (!(*profile
= HeapAlloc(GetProcessHeap(), 0, size
.u
.LowPart
)))
129 return E_OUTOFMEMORY
;
131 ret
= ReadFile(handle
, *profile
, size
.u
.LowPart
, &count
, NULL
);
134 HeapFree (GetProcessHeap(),0,*profile
);
136 return HRESULT_FROM_WIN32(GetLastError());
138 if (count
!= size
.u
.LowPart
) {
139 HeapFree (GetProcessHeap(),0,*profile
);
147 static HRESULT WINAPI
ColorContext_InitializeFromFilename(IWICColorContext
*iface
,
150 ColorContext
*This
= impl_from_IWICColorContext(iface
);
154 TRACE("(%p,%s)\n", iface
, debugstr_w(wzFilename
));
156 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextProfile
)
157 return WINCODEC_ERR_WRONGSTATE
;
159 if (!wzFilename
) return E_INVALIDARG
;
161 hr
= load_profile(wzFilename
, &profile
, &len
);
162 if (FAILED(hr
)) return hr
;
164 HeapFree(GetProcessHeap(), 0, This
->profile
);
165 This
->profile
= profile
;
166 This
->profile_len
= len
;
167 This
->type
= WICColorContextProfile
;
172 static HRESULT WINAPI
ColorContext_InitializeFromMemory(IWICColorContext
*iface
,
173 const BYTE
*pbBuffer
, UINT cbBufferSize
)
175 ColorContext
*This
= impl_from_IWICColorContext(iface
);
177 TRACE("(%p,%p,%u)\n", iface
, pbBuffer
, cbBufferSize
);
179 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextProfile
)
180 return WINCODEC_ERR_WRONGSTATE
;
182 if (!(profile
= HeapAlloc(GetProcessHeap(), 0, cbBufferSize
))) return E_OUTOFMEMORY
;
183 memcpy(profile
, pbBuffer
, cbBufferSize
);
185 HeapFree(GetProcessHeap(), 0, This
->profile
);
186 This
->profile
= profile
;
187 This
->profile_len
= cbBufferSize
;
188 This
->type
= WICColorContextProfile
;
193 static HRESULT WINAPI
ColorContext_InitializeFromExifColorSpace(IWICColorContext
*iface
,
196 ColorContext
*This
= impl_from_IWICColorContext(iface
);
197 TRACE("(%p,%u)\n", iface
, value
);
199 if (This
->type
!= WICColorContextUninitialized
&& This
->type
!= WICColorContextExifColorSpace
)
200 return WINCODEC_ERR_WRONGSTATE
;
202 This
->exif_color_space
= value
;
203 This
->type
= WICColorContextExifColorSpace
;
208 static HRESULT WINAPI
ColorContext_GetType(IWICColorContext
*iface
,
209 WICColorContextType
*pType
)
211 ColorContext
*This
= impl_from_IWICColorContext(iface
);
212 TRACE("(%p,%p)\n", iface
, pType
);
214 if (!pType
) return E_INVALIDARG
;
220 static HRESULT WINAPI
ColorContext_GetProfileBytes(IWICColorContext
*iface
,
221 UINT cbBuffer
, BYTE
*pbBuffer
, UINT
*pcbActual
)
223 ColorContext
*This
= impl_from_IWICColorContext(iface
);
224 TRACE("(%p,%u,%p,%p)\n", iface
, cbBuffer
, pbBuffer
, pcbActual
);
226 if (This
->type
!= WICColorContextProfile
)
227 return WINCODEC_ERR_NOTINITIALIZED
;
229 if (!pcbActual
) return E_INVALIDARG
;
231 if (cbBuffer
>= This
->profile_len
&& pbBuffer
)
232 memcpy(pbBuffer
, This
->profile
, This
->profile_len
);
234 *pcbActual
= This
->profile_len
;
239 static HRESULT WINAPI
ColorContext_GetExifColorSpace(IWICColorContext
*iface
,
242 ColorContext
*This
= impl_from_IWICColorContext(iface
);
243 TRACE("(%p,%p)\n", iface
, pValue
);
245 if (!pValue
) return E_INVALIDARG
;
247 *pValue
= This
->exif_color_space
;
251 static const IWICColorContextVtbl ColorContext_Vtbl
= {
252 ColorContext_QueryInterface
,
254 ColorContext_Release
,
255 ColorContext_InitializeFromFilename
,
256 ColorContext_InitializeFromMemory
,
257 ColorContext_InitializeFromExifColorSpace
,
258 ColorContext_GetType
,
259 ColorContext_GetProfileBytes
,
260 ColorContext_GetExifColorSpace
263 HRESULT
ColorContext_Create(IWICColorContext
**colorcontext
)
267 if (!colorcontext
) return E_INVALIDARG
;
269 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ColorContext
));
270 if (!This
) return E_OUTOFMEMORY
;
272 This
->IWICColorContext_iface
.lpVtbl
= &ColorContext_Vtbl
;
275 This
->profile
= NULL
;
276 This
->profile_len
= 0;
277 This
->exif_color_space
= ~0u;
279 *colorcontext
= &This
->IWICColorContext_iface
;