1 //*@@@+++@@@@******************************************************************
2 //
3 // Copyright � Microsoft Corp.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 //
9 // � Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // � Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 // POSSIBILITY OF SUCH DAMAGE.
26 //
27 //*@@@---@@@@******************************************************************
28 #include <stdlib.h>
29 #include <ctype.h>
30
31 #define INITGUID
32 #include <JXRGlue.h>
33
34 //================================================================
35 const PKIID IID_PKImageScanEncode = 1;
36 const PKIID IID_PKImageFrameEncode = 2;
37
38 const PKIID IID_PKImageUnsupported = 100;
39 const PKIID IID_PKImageWmpEncode = 101;
40
41 const PKIID IID_PKImageWmpDecode = 201;
42
43 //================================================================
44 // Misc supporting functions
45 //================================================================
PKAlloc(void ** ppv,size_t cb)46 ERR PKAlloc(void** ppv, size_t cb)
47 {
48 *ppv = calloc(1, cb);
49 return *ppv ? WMP_errSuccess : WMP_errOutOfMemory;
50 }
51
52
PKFree(void ** ppv)53 ERR PKFree(void** ppv)
54 {
55 if (ppv)
56 {
57 free(*ppv);
58 *ppv = NULL;
59 }
60
61 return WMP_errSuccess;
62 }
63
PKAllocAligned(void ** ppv,size_t cb,size_t iAlign)64 ERR PKAllocAligned(void** ppv, size_t cb, size_t iAlign)
65 {
66 U8 *pOrigPtr;
67 U8 *pReturnedPtr;
68 size_t iAlignmentCorrection;
69 const size_t c_cbBlockSize = cb + sizeof(void*) + iAlign - 1;
70
71 *ppv = NULL;
72 pOrigPtr = calloc(1, c_cbBlockSize);
73 if (NULL == pOrigPtr)
74 return WMP_errOutOfMemory;
75
76 iAlignmentCorrection = iAlign - ((size_t)pOrigPtr % iAlign);
77 if (iAlignmentCorrection < sizeof(void*))
78 // Alignment correction won't leave us enough space to store pOrigPtr - advance to next block
79 iAlignmentCorrection += iAlign;
80
81 assert(iAlignmentCorrection >= sizeof(void*)); // Alignment correction must have space for pOrigPtr
82 assert(iAlignmentCorrection + cb <= c_cbBlockSize); // Don't exceed right edge of memory block
83
84 pReturnedPtr = pOrigPtr + iAlignmentCorrection;
85 *(void**)(pReturnedPtr - sizeof(void*)) = pOrigPtr;
86
87 assert(0 == ((size_t)pReturnedPtr % iAlign)); // Are we in fact aligned?
88 *ppv = pReturnedPtr;
89 return WMP_errSuccess;
90 }
91
PKFreeAligned(void ** ppv)92 ERR PKFreeAligned(void** ppv)
93 {
94 if (ppv && *ppv)
95 {
96 U8 **ppOrigPtr = (U8**)((U8*)(*ppv) - sizeof(void*));
97 assert(*ppOrigPtr <= (U8*)ppOrigPtr); // Something's wrong if pOrigPtr points forward
98 free(*ppOrigPtr);
99 *ppv = NULL;
100 }
101 return WMP_errSuccess;
102 }
103
104
105
PKStrnicmp(const char * s1,const char * s2,size_t c)106 int PKStrnicmp(const char* s1, const char* s2, size_t c)
107 {
108 for(; tolower(*s1) == tolower(*s2) && *s1 && *s2 && c; ++s1, ++s2, --c);
109 return c ? *s1 - *s2 : 0;
110 }
111
112 static const PKPixelInfo pixelInfo[] =
113 {
114 {&GUID_PKPixelFormatDontCare, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul, 0, 0, 0, 0},
115
116 // Gray
117 //{&GUID_PKPixelFormat2bppGray, 1, Y_ONLY, BD_8, 2, PK_pixfmtNul},
118 //{&GUID_PKPixelFormat4bppGray, 1, Y_ONLY, BD_8, 4, PK_pixfmtNul},
119
120 {&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul, 1, 1, 1, 1},//BlackIsZero is default for GUID_PKPixelFormatBlackWhite
121 {&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul, 0, 1, 1, 1},//WhiteIsZero
122 {&GUID_PKPixelFormat8bppGray, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul, 1, 1, 8, 1},
123 {&GUID_PKPixelFormat16bppGray, 1, Y_ONLY, BD_16, 16, PK_pixfmtNul, 1, 1, 16, 1},
124 {&GUID_PKPixelFormat16bppGrayFixedPoint, 1, Y_ONLY, BD_16S, 16, PK_pixfmtNul, 1, 1, 16, 2},
125 {&GUID_PKPixelFormat16bppGrayHalf, 1, Y_ONLY, BD_16F, 16, PK_pixfmtNul, 1, 1, 16, 3},
126 //{&GUID_PKPixelFormat32bppGray, 1, Y_ONLY, BD_32, 32, PK_pixfmtNul, 1, 1, 32, 1},
127 {&GUID_PKPixelFormat32bppGrayFixedPoint, 1, Y_ONLY, BD_32S, 32, PK_pixfmtNul, 1, 1, 32, 2},
128 {&GUID_PKPixelFormat32bppGrayFloat, 1, Y_ONLY, BD_32F, 32, PK_pixfmtNul, 1, 1, 32, 3},
129
130 // RGB
131 {&GUID_PKPixelFormat24bppRGB, 3, CF_RGB, BD_8, 24, PK_pixfmtNul, 2, 3, 8, 1},
132 {&GUID_PKPixelFormat24bppBGR, 3, CF_RGB, BD_8, 24, PK_pixfmtBGR, 2, 3, 8, 1},
133 {&GUID_PKPixelFormat32bppRGB, 3, CF_RGB, BD_8, 32, PK_pixfmtNul, 2, 3, 8, 1},
134 {&GUID_PKPixelFormat32bppBGR, 3, CF_RGB, BD_8, 32, PK_pixfmtBGR, 2, 3, 8, 1},
135 {&GUID_PKPixelFormat48bppRGB, 3, CF_RGB, BD_16, 48, PK_pixfmtNul, 2, 3, 16, 1},
136 {&GUID_PKPixelFormat48bppRGBFixedPoint, 3, CF_RGB, BD_16S, 48, PK_pixfmtNul, 2, 3, 16, 2},
137 {&GUID_PKPixelFormat48bppRGBHalf, 3, CF_RGB, BD_16F, 48, PK_pixfmtNul, 2, 3, 16, 3},
138 {&GUID_PKPixelFormat64bppRGBFixedPoint, 3, CF_RGB, BD_16S, 64, PK_pixfmtNul, 2, 3, 16, 2},
139 {&GUID_PKPixelFormat64bppRGBHalf, 3, CF_RGB, BD_16F, 64, PK_pixfmtNul, 2, 3, 16, 3},
140 //{&GUID_PKPixelFormat96bppRGB, 3, CF_RGB, BD_32, 96, PK_pixfmtNul, 2, 3, 32, 1},
141 {&GUID_PKPixelFormat96bppRGBFixedPoint, 3, CF_RGB, BD_32S, 96, PK_pixfmtNul, 2, 3, 32, 2},
142 {&GUID_PKPixelFormat96bppRGBFloat, 3, CF_RGB, BD_32F, 96, PK_pixfmtNul, 2, 3, 32, 3},
143 {&GUID_PKPixelFormat128bppRGBFixedPoint, 3, CF_RGB, BD_32S, 128, PK_pixfmtNul, 2, 3, 32, 2},
144 {&GUID_PKPixelFormat128bppRGBFloat, 3, CF_RGB, BD_32F, 128, PK_pixfmtNul, 2, 3, 32, 3},
145
146 // RGBA
147 {&GUID_PKPixelFormat32bppBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtBGR, 2, 4, 8, 1},
148 {&GUID_PKPixelFormat32bppRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha, 2, 4, 8, 1},
149 {&GUID_PKPixelFormat64bppRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha, 2, 4, 16, 1},
150 {&GUID_PKPixelFormat64bppRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha, 2, 4, 16, 2},
151 {&GUID_PKPixelFormat64bppRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha, 2, 4, 16, 3},
152 //{&GUID_PKPixelFormat128bppRGBA, 4, CF_RGB, BD_32, 128, PK_pixfmtHasAlpha, 2, 4, 32, 1},
153 {&GUID_PKPixelFormat128bppRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha, 2, 4, 32, 2},
154 {&GUID_PKPixelFormat128bppRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha, 2, 4, 32, 3},
155
156 // PRGBA
157 {&GUID_PKPixelFormat32bppPBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul | PK_pixfmtBGR, 2, 4, 8, 1},
158 {&GUID_PKPixelFormat32bppPRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 8, 1},
159 {&GUID_PKPixelFormat64bppPRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 16, 1},
160 //{&GUID_PKPixelFormat64bppPRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha, 2, 4, 16, 2},
161 //{&GUID_PKPixelFormat64bppPRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha, 2, 4, 16, 3},
162 //{&GUID_PKPixelFormat128bppPRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha, 2, 4, 32, 2},
163 {&GUID_PKPixelFormat128bppPRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 32, 3},
164
165 // Packed formats
166 {&GUID_PKPixelFormat16bppRGB555, 3, CF_RGB, BD_5, 16, PK_pixfmtNul, 2, 3, 5, 1},
167 {&GUID_PKPixelFormat16bppRGB565, 3, CF_RGB, BD_565, 16, PK_pixfmtNul, 2, 3, 6, 1},
168 {&GUID_PKPixelFormat32bppRGB101010, 3, CF_RGB, BD_10, 32, PK_pixfmtNul, 2, 3, 10, 1},
169
170 // CMYK
171 {&GUID_PKPixelFormat32bppCMYK, 4, CMYK, BD_8, 32, PK_pixfmtNul, 5, 4, 8, 1},
172 {&GUID_PKPixelFormat40bppCMYKAlpha, 5, CMYK, BD_8, 40, PK_pixfmtHasAlpha, 5, 5, 8, 1},
173
174 {&GUID_PKPixelFormat64bppCMYK, 4, CMYK, BD_16, 64, PK_pixfmtNul, 5, 4, 16, 1},
175 {&GUID_PKPixelFormat80bppCMYKAlpha, 5, CMYK, BD_16, 80, PK_pixfmtHasAlpha, 5, 5, 16, 1},
176
177 // N_CHANNEL
178 {&GUID_PKPixelFormat24bpp3Channels, 3, NCOMPONENT, BD_8, 24, PK_pixfmtNul, PK_PI_NCH, 3, 8, 1},//the N channel TIF by PS has PhotometricInterpretation of PK_PI_RGB
179 {&GUID_PKPixelFormat32bpp4Channels, 4, NCOMPONENT, BD_8, 32, PK_pixfmtNul, PK_PI_NCH, 4, 8, 1},
180 {&GUID_PKPixelFormat40bpp5Channels, 5, NCOMPONENT, BD_8, 40, PK_pixfmtNul, PK_PI_NCH, 5, 8, 1},
181 {&GUID_PKPixelFormat48bpp6Channels, 6, NCOMPONENT, BD_8, 48, PK_pixfmtNul, PK_PI_NCH, 6, 8, 1},
182 {&GUID_PKPixelFormat56bpp7Channels, 7, NCOMPONENT, BD_8, 56, PK_pixfmtNul, PK_PI_NCH, 7, 8, 1},
183 {&GUID_PKPixelFormat64bpp8Channels, 8, NCOMPONENT, BD_8, 64, PK_pixfmtNul, PK_PI_NCH, 8, 8, 1},
184
185 {&GUID_PKPixelFormat32bpp3ChannelsAlpha, 4, NCOMPONENT, BD_8, 32, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 8, 1},
186 {&GUID_PKPixelFormat40bpp4ChannelsAlpha, 5, NCOMPONENT, BD_8, 40, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 8, 1},
187 {&GUID_PKPixelFormat48bpp5ChannelsAlpha, 6, NCOMPONENT, BD_8, 48, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 8, 1},
188 {&GUID_PKPixelFormat56bpp6ChannelsAlpha, 7, NCOMPONENT, BD_8, 56, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 8, 1},
189 {&GUID_PKPixelFormat64bpp7ChannelsAlpha, 8, NCOMPONENT, BD_8, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 8, 1},
190 {&GUID_PKPixelFormat72bpp8ChannelsAlpha, 9, NCOMPONENT, BD_8, 72, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 8, 1},
191
192 {&GUID_PKPixelFormat48bpp3Channels, 3, NCOMPONENT, BD_16, 48, PK_pixfmtNul, PK_PI_NCH, 3, 16, 1},
193 {&GUID_PKPixelFormat64bpp4Channels, 4, NCOMPONENT, BD_16, 64, PK_pixfmtNul, PK_PI_NCH, 4, 16, 1},
194 {&GUID_PKPixelFormat80bpp5Channels, 5, NCOMPONENT, BD_16, 80, PK_pixfmtNul, PK_PI_NCH, 5, 16, 1},
195 {&GUID_PKPixelFormat96bpp6Channels, 6, NCOMPONENT, BD_16, 96, PK_pixfmtNul, PK_PI_NCH, 6, 16, 1},
196 {&GUID_PKPixelFormat112bpp7Channels, 7, NCOMPONENT, BD_16, 112, PK_pixfmtNul, PK_PI_NCH, 7, 16, 1},
197 {&GUID_PKPixelFormat128bpp8Channels, 8, NCOMPONENT, BD_16, 128, PK_pixfmtNul, PK_PI_NCH, 8, 16, 1},
198
199 {&GUID_PKPixelFormat64bpp3ChannelsAlpha, 4, NCOMPONENT, BD_16, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 16, 1},
200 {&GUID_PKPixelFormat80bpp4ChannelsAlpha, 5, NCOMPONENT, BD_16, 80, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 16, 1},
201 {&GUID_PKPixelFormat96bpp5ChannelsAlpha, 6, NCOMPONENT, BD_16, 96, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 16, 1},
202 {&GUID_PKPixelFormat112bpp6ChannelsAlpha, 7, NCOMPONENT, BD_16, 112, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 16, 1},
203 {&GUID_PKPixelFormat128bpp7ChannelsAlpha, 8, NCOMPONENT, BD_16, 128, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 16, 1},
204 {&GUID_PKPixelFormat144bpp8ChannelsAlpha, 9, NCOMPONENT, BD_16, 144, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 16, 1},
205
206 //RGBE
207 {&GUID_PKPixelFormat32bppRGBE, 4, CF_RGBE, BD_8, 32, PK_pixfmtNul, PK_PI_RGBE, 4, 8, 1},
208
209 //YUV
210 {&GUID_PKPixelFormat12bppYUV420, 3, YUV_420, BD_8, 48, PK_pixfmtNul},
211 {&GUID_PKPixelFormat16bppYUV422, 3, YUV_422, BD_8, 32, PK_pixfmtNul},
212 {&GUID_PKPixelFormat24bppYUV444, 3, YUV_444, BD_8, 24, PK_pixfmtNul},
213 };
214
215 //----------------------------------------------------------------
216 //ERR GetPixelInfo(PKPixelFormatGUID enPixelFormat, const PKPixelInfo** ppPI)
PixelFormatLookup(PKPixelInfo * pPI,U8 uLookupType)217 ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType)
218 {
219 ERR err = WMP_errSuccess;
220 size_t i;
221
222 for (i = 0; i < sizeof2(pixelInfo); ++i)
223 {
224 if (LOOKUP_FORWARD == uLookupType)
225 {
226 if (IsEqualGUID(pPI->pGUIDPixFmt, pixelInfo[i].pGUIDPixFmt))
227 {
228 *pPI = pixelInfo[i];
229 goto Cleanup;
230 }
231 }
232 else if (LOOKUP_BACKWARD_TIF == uLookupType)
233 {
234 if (pPI->uSamplePerPixel == pixelInfo[i].uSamplePerPixel &&
235 pPI->uBitsPerSample == pixelInfo[i].uBitsPerSample &&
236 pPI->uSampleFormat == pixelInfo[i].uSampleFormat &&
237 pPI->uInterpretation == pixelInfo[i].uInterpretation)
238 {
239 // match alpha & premult
240 if ((pPI->grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)) ==
241 (pixelInfo[i].grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)))
242 {
243 *pPI = pixelInfo[i];
244 goto Cleanup;
245 }
246 }
247 }
248 }
249 Call(WMP_errUnsupportedFormat);
250
251 Cleanup:
252 return err;
253 }
254
255
GetPixelFormatFromHash(const U8 uPFHash)256 const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash)
257 {
258 int i;
259
260 for (i = 0; i < sizeof2(pixelInfo); i++)
261 {
262 if (pixelInfo[i].pGUIDPixFmt->Data4[7] == uPFHash)
263 return pixelInfo[i].pGUIDPixFmt;
264 }
265
266 // If we reached this point, we did not find anything which matched the hash
267 return NULL;
268 }
269
270 //----------------------------------------------------------------
271 typedef struct tagPKIIDInfo
272 {
273 const char* szExt;
274 const PKIID* pIIDEnc;
275 const PKIID* pIIDDec;
276 } PKIIDInfo;
277
GetIIDInfo(const char * szExt,const PKIIDInfo ** ppInfo)278 static ERR GetIIDInfo(const char* szExt, const PKIIDInfo** ppInfo)
279 {
280 ERR err = WMP_errSuccess;
281
282 static PKIIDInfo iidInfo[] = {
283 {".jxr", &IID_PKImageWmpEncode, &IID_PKImageWmpDecode},
284 {".wdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
285 {".hdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
286 };
287 size_t i = 0;
288
289 *ppInfo = NULL;
290 for (i = 0; i < sizeof2(iidInfo); ++i)
291 {
292 if (0 == PKStrnicmp(szExt, iidInfo[i].szExt, strlen(iidInfo[i].szExt)))
293 {
294 *ppInfo = &iidInfo[i];
295 goto Cleanup;
296 }
297 }
298
299 Call(WMP_errUnsupportedFormat);
300
301 Cleanup:
302 return err;
303 }
304
GetImageEncodeIID(const char * szExt,const PKIID ** ppIID)305 ERR GetImageEncodeIID(const char* szExt, const PKIID** ppIID)
306 {
307 ERR err = WMP_errSuccess;
308
309 const PKIIDInfo* pInfo = NULL;
310
311 Call(GetIIDInfo(szExt, &pInfo));
312 *ppIID = pInfo->pIIDEnc;
313
314 Cleanup:
315 return err;
316 }
317
GetImageDecodeIID(const char * szExt,const PKIID ** ppIID)318 ERR GetImageDecodeIID(const char* szExt, const PKIID** ppIID)
319 {
320 ERR err = WMP_errSuccess;
321
322 const PKIIDInfo* pInfo = NULL;
323
324 Call(GetIIDInfo(szExt, &pInfo));
325 *ppIID = pInfo->pIIDDec;
326
327 Cleanup:
328 return err;
329 }
330
331 //================================================================
332 // PKFactory
333 //================================================================
PKCreateFactory_CreateStream(PKStream ** ppStream)334 ERR PKCreateFactory_CreateStream(PKStream** ppStream)
335 {
336 ERR err = WMP_errSuccess;
337
338 Call(PKAlloc((void **) ppStream, sizeof(**ppStream)));
339
340 Cleanup:
341 return err;
342 }
343
PKCreateFactory_Release(PKFactory ** ppFactory)344 ERR PKCreateFactory_Release(PKFactory** ppFactory)
345 {
346 ERR err = WMP_errSuccess;
347
348 Call(PKFree((void **) ppFactory));
349
350 Cleanup:
351 return err;
352 }
353
354 //----------------------------------------------------------------
PKCreateFactory(PKFactory ** ppFactory,U32 uVersion)355 ERR PKCreateFactory(PKFactory** ppFactory, U32 uVersion)
356 {
357 ERR err = WMP_errSuccess;
358 PKFactory* pFactory = NULL;
359
360 UNREFERENCED_PARAMETER( uVersion );
361
362 Call(PKAlloc((void **) ppFactory, sizeof(**ppFactory)));
363 pFactory = *ppFactory;
364
365 pFactory->CreateStream = PKCreateFactory_CreateStream;
366
367 pFactory->CreateStreamFromFilename = CreateWS_File;
368 pFactory->CreateStreamFromMemory = CreateWS_Memory;
369
370 pFactory->Release = PKCreateFactory_Release;
371
372 Cleanup:
373 return err;
374 }
375
376
377 //================================================================
378 // PKCodecFactory
379 //================================================================
PKCodecFactory_CreateCodec(const PKIID * iid,void ** ppv)380 ERR PKCodecFactory_CreateCodec(const PKIID* iid, void** ppv)
381 {
382 ERR err = WMP_errSuccess;
383
384 if (IID_PKImageWmpEncode == *iid)
385 {
386 Call(PKImageEncode_Create_WMP((PKImageEncode**)ppv));
387 }
388 else if (IID_PKImageWmpDecode == *iid)
389 {
390 Call(PKImageDecode_Create_WMP((PKImageDecode**)ppv));
391 }
392 else
393 {
394 Call(WMP_errUnsupportedFormat);
395 }
396
397 Cleanup:
398 return err;
399 }
400
PKCodecFactory_CreateDecoderFromFile(const char * szFilename,PKImageDecode ** ppDecoder)401 ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder)
402 {
403 ERR err = WMP_errSuccess;
404
405 char *pExt = NULL;
406 const PKIID* pIID = NULL;
407
408 struct WMPStream* pStream = NULL;
409 PKImageDecode* pDecoder = NULL;
410
411 // get file extension
412 pExt = strrchr(szFilename, '.');
413 FailIf(NULL == pExt, WMP_errUnsupportedFormat);
414
415 // get decode PKIID
416 Call(GetImageDecodeIID(pExt, &pIID));
417
418 // create stream
419 Call(CreateWS_File(&pStream, szFilename, "rb"));
420
421 // Create decoder
422 Call(PKCodecFactory_CreateCodec(pIID, (void **) ppDecoder));
423 pDecoder = *ppDecoder;
424
425 // attach stream to decoder
426 Call(pDecoder->Initialize(pDecoder, pStream));
427 pDecoder->fStreamOwner = !0;
428
429 Cleanup:
430 return err;
431 }
432
PKCodecFactory_CreateFormatConverter(PKFormatConverter ** ppFConverter)433 ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter)
434 {
435 ERR err = WMP_errSuccess;
436 PKFormatConverter* pFC = NULL;
437
438 Call(PKAlloc((void **) ppFConverter, sizeof(**ppFConverter)));
439 pFC = *ppFConverter;
440
441 pFC->Initialize = PKFormatConverter_Initialize;
442 pFC->InitializeConvert = PKFormatConverter_InitializeConvert;
443 pFC->GetPixelFormat = PKFormatConverter_GetPixelFormat;
444 pFC->GetSourcePixelFormat = PKFormatConverter_GetSourcePixelFormat;
445 pFC->GetSize = PKFormatConverter_GetSize;
446 pFC->GetResolution = PKFormatConverter_GetResolution;
447 pFC->Copy = PKFormatConverter_Copy;
448 pFC->Convert = PKFormatConverter_Convert;
449 pFC->Release = PKFormatConverter_Release;
450
451 Cleanup:
452 return err;
453 }
454
PKCreateCodecFactory_Release(PKCodecFactory ** ppCFactory)455 ERR PKCreateCodecFactory_Release(PKCodecFactory** ppCFactory)
456 {
457 ERR err = WMP_errSuccess;
458
459 Call(PKFree((void **) ppCFactory));
460
461 Cleanup:
462 return err;
463 }
464
PKCreateCodecFactory(PKCodecFactory ** ppCFactory,U32 uVersion)465 ERR PKCreateCodecFactory(PKCodecFactory** ppCFactory, U32 uVersion)
466 {
467 ERR err = WMP_errSuccess;
468 PKCodecFactory* pCFactory = NULL;
469
470 UNREFERENCED_PARAMETER( uVersion );
471
472 Call(PKAlloc((void **) ppCFactory, sizeof(**ppCFactory)));
473 pCFactory = *ppCFactory;
474
475 pCFactory->CreateCodec = PKCodecFactory_CreateCodec;
476 pCFactory->CreateDecoderFromFile = PKCodecFactory_CreateDecoderFromFile;
477 pCFactory->CreateFormatConverter = PKCodecFactory_CreateFormatConverter;
478 pCFactory->Release = PKCreateCodecFactory_Release;
479
480 Cleanup:
481 return err;
482 }
483
484
485 //================================================================
486 // PKImageEncode
487 //================================================================
PKImageEncode_Initialize(PKImageEncode * pIE,struct WMPStream * pStream,void * pvParam,size_t cbParam)488 ERR PKImageEncode_Initialize(
489 PKImageEncode* pIE,
490 struct WMPStream* pStream,
491 void* pvParam,
492 size_t cbParam)
493 {
494 ERR err = WMP_errSuccess;
495
496 UNREFERENCED_PARAMETER( pIE );
497 UNREFERENCED_PARAMETER( pvParam );
498 UNREFERENCED_PARAMETER( cbParam );
499
500 pIE->pStream = pStream;
501 pIE->guidPixFormat = GUID_PKPixelFormatDontCare;
502 pIE->fResX = 96;
503 pIE->fResY = 96;
504 pIE->cFrame = 1;
505
506 Call(pIE->pStream->GetPos(pIE->pStream, &pIE->offStart));
507
508 Cleanup:
509 return err;
510 }
511
PKImageEncode_Terminate(PKImageEncode * pIE)512 ERR PKImageEncode_Terminate(
513 PKImageEncode* pIE)
514 {
515 UNREFERENCED_PARAMETER( pIE );
516 return WMP_errSuccess;
517 }
518
PKImageEncode_SetPixelFormat(PKImageEncode * pIE,PKPixelFormatGUID enPixelFormat)519 ERR PKImageEncode_SetPixelFormat(
520 PKImageEncode* pIE,
521 PKPixelFormatGUID enPixelFormat)
522 {
523 pIE->guidPixFormat = enPixelFormat;
524
525 return WMP_errSuccess;
526 }
527
PKImageEncode_SetSize(PKImageEncode * pIE,I32 iWidth,I32 iHeight)528 ERR PKImageEncode_SetSize(
529 PKImageEncode* pIE,
530 I32 iWidth,
531 I32 iHeight)
532 {
533 ERR err = WMP_errSuccess;
534
535 pIE->uWidth = (U32)iWidth;
536 pIE->uHeight = (U32)iHeight;
537
538 return err;
539 }
540
PKImageEncode_SetResolution(PKImageEncode * pIE,Float fResX,Float fResY)541 ERR PKImageEncode_SetResolution(
542 PKImageEncode* pIE,
543 Float fResX,
544 Float fResY)
545 {
546 pIE->fResX = fResX;
547 pIE->fResY = fResY;
548
549 return WMP_errSuccess;
550 }
551
PKImageEncode_SetColorContext(PKImageEncode * pIE,const U8 * pbColorContext,U32 cbColorContext)552 ERR PKImageEncode_SetColorContext(PKImageEncode *pIE,
553 const U8 *pbColorContext,
554 U32 cbColorContext)
555 {
556 UNREFERENCED_PARAMETER( pIE );
557 UNREFERENCED_PARAMETER( pbColorContext );
558 UNREFERENCED_PARAMETER( cbColorContext );
559 return WMP_errNotYetImplemented;
560 }
561
562
PKImageEncode_SetDescriptiveMetadata(PKImageEncode * pIE,const DESCRIPTIVEMETADATA * pDescMetadata)563 ERR PKImageEncode_SetDescriptiveMetadata(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pDescMetadata)
564 {
565 UNREFERENCED_PARAMETER( pIE );
566 UNREFERENCED_PARAMETER( pDescMetadata );
567 return WMP_errNotYetImplemented;
568 }
569
PKImageEncode_WritePixels(PKImageEncode * pIE,U32 cLine,U8 * pbPixels,U32 cbStride)570 ERR PKImageEncode_WritePixels(
571 PKImageEncode* pIE,
572 U32 cLine,
573 U8* pbPixels,
574 U32 cbStride)
575 {
576 UNREFERENCED_PARAMETER( pIE );
577 UNREFERENCED_PARAMETER( cLine );
578 UNREFERENCED_PARAMETER( pbPixels );
579 UNREFERENCED_PARAMETER( cbStride );
580 return WMP_errAbstractMethod;
581 }
582
PKImageEncode_WriteSource(PKImageEncode * pIE,PKFormatConverter * pFC,PKRect * pRect)583 ERR PKImageEncode_WriteSource(
584 PKImageEncode* pIE,
585 PKFormatConverter* pFC,
586 PKRect* pRect)
587 {
588 ERR err = WMP_errSuccess;
589
590 PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
591 PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
592
593 PKPixelInfo pPIFrom;
594 PKPixelInfo pPITo;
595
596 U32 cbStrideTo = 0;
597 U32 cbStrideFrom = 0;
598 U32 cbStride = 0;
599
600 U8* pb = NULL;
601
602 // CWMTranscodingParam* pParam = NULL;
603
604 // get pixel format
605 Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
606 Call(pFC->GetPixelFormat(pFC, &enPFTo));
607 FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
608
609 // calc common stride
610 // Call(GetPixelInfo(enPFFrom, &pPIFrom));
611 pPIFrom.pGUIDPixFmt = &enPFFrom;
612 PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
613
614 // Call(GetPixelInfo(enPFTo, &pPITo));
615 pPITo.pGUIDPixFmt = &enPFTo;
616 PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
617
618 // cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
619 cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width));
620 if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt
621 || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt)
622 cbStrideFrom >>= 1;
623
624 // cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
625 cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth));
626 if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
627 || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt)
628 cbStrideTo >>= 1;
629
630 cbStride = max(cbStrideFrom, cbStrideTo);
631
632 // actual dec/enc with local buffer
633 Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
634
635 Call(pFC->Copy(pFC, pRect, pb, cbStride));
636
637 Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
638
639 Cleanup:
640 PKFreeAligned((void **) &pb);
641 return err;
642 }
643
PKImageEncode_WritePixelsBandedBegin(PKImageEncode * pEncoder,struct WMPStream * pPATempFile)644 ERR PKImageEncode_WritePixelsBandedBegin(PKImageEncode* pEncoder, struct WMPStream *pPATempFile)
645 {
646 UNREFERENCED_PARAMETER( pEncoder );
647 UNREFERENCED_PARAMETER( pPATempFile );
648 return WMP_errAbstractMethod;
649 }
650
PKImageEncode_WritePixelsBanded(PKImageEncode * pEncoder,U32 cLines,U8 * pbPixels,U32 cbStride,Bool fLastCall)651 ERR PKImageEncode_WritePixelsBanded(PKImageEncode* pEncoder, U32 cLines, U8* pbPixels, U32 cbStride, Bool fLastCall)
652 {
653 UNREFERENCED_PARAMETER( pEncoder );
654 UNREFERENCED_PARAMETER( cLines );
655 UNREFERENCED_PARAMETER( pbPixels );
656 UNREFERENCED_PARAMETER( cbStride );
657 UNREFERENCED_PARAMETER( fLastCall );
658 return WMP_errAbstractMethod;
659 }
660
PKImageEncode_WritePixelsBandedEnd(PKImageEncode * pEncoder)661 ERR PKImageEncode_WritePixelsBandedEnd(PKImageEncode* pEncoder)
662 {
663 UNREFERENCED_PARAMETER( pEncoder );
664 return WMP_errAbstractMethod;
665 }
666
667
PKImageEncode_Transcode(PKImageEncode * pIE,PKFormatConverter * pFC,PKRect * pRect)668 ERR PKImageEncode_Transcode(
669 PKImageEncode* pIE,
670 PKFormatConverter* pFC,
671 PKRect* pRect)
672 {
673 ERR err = WMP_errSuccess;
674
675 PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
676 PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
677
678 PKPixelInfo pPIFrom;
679 PKPixelInfo pPITo;
680
681 U32 cbStrideTo = 0;
682 U32 cbStrideFrom = 0;
683 U32 cbStride = 0;
684
685 U8* pb = NULL;
686
687 CWMTranscodingParam cParam = {0};
688
689 // get pixel format
690 Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
691 Call(pFC->GetPixelFormat(pFC, &enPFTo));
692 FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
693
694 // calc common stride
695 // Call(GetPixelInfo(enPFFrom, &pPIFrom));
696 pPIFrom.pGUIDPixFmt = &enPFFrom;
697 PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
698
699 // Call(GetPixelInfo(enPFTo, &pPITo));
700 pPITo.pGUIDPixFmt = &enPFTo;
701 PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
702
703 // cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
704 cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width));
705 if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt
706 || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt)
707 cbStrideFrom >>= 1;
708
709 // cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
710 cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth));
711 if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
712 || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt)
713 cbStrideTo >>= 1;
714
715 cbStride = max(cbStrideFrom, cbStrideTo);
716
717 if(pIE->bWMP){
718 cParam.cLeftX = pFC->pDecoder->WMP.wmiI.cROILeftX;
719 cParam.cTopY = pFC->pDecoder->WMP.wmiI.cROITopY;
720 cParam.cWidth = pFC->pDecoder->WMP.wmiI.cROIWidth;
721 cParam.cHeight = pFC->pDecoder->WMP.wmiI.cROIHeight;
722 cParam.oOrientation = pFC->pDecoder->WMP.wmiI.oOrientation;
723 // cParam.cfColorFormat = pFC->pDecoder->WMP.wmiI.cfColorFormat;
724 cParam.uAlphaMode = pFC->pDecoder->WMP.wmiSCP.uAlphaMode;
725 cParam.bfBitstreamFormat = pFC->pDecoder->WMP.wmiSCP.bfBitstreamFormat;
726 cParam.sbSubband = pFC->pDecoder->WMP.wmiSCP.sbSubband;
727 cParam.bIgnoreOverlap = pFC->pDecoder->WMP.bIgnoreOverlap;
728
729 Call(pIE->Transcode(pIE, pFC->pDecoder, &cParam));
730 }
731 else
732 {
733 // actual dec/enc with local buffer
734 Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
735 Call(pFC->Copy(pFC, pRect, pb, cbStride));
736 Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
737 }
738
739 Cleanup:
740 PKFreeAligned((void **) &pb);
741 return err;
742 }
743
PKImageEncode_CreateNewFrame(PKImageEncode * pIE,void * pvParam,size_t cbParam)744 ERR PKImageEncode_CreateNewFrame(
745 PKImageEncode* pIE,
746 void* pvParam,
747 size_t cbParam)
748 {
749 UNREFERENCED_PARAMETER( pIE );
750 UNREFERENCED_PARAMETER( pvParam );
751 UNREFERENCED_PARAMETER( cbParam );
752 // NYI
753 return WMP_errSuccess;
754 }
755
PKImageEncode_Release(PKImageEncode ** ppIE)756 ERR PKImageEncode_Release(
757 PKImageEncode** ppIE)
758 {
759 PKImageEncode *pIE = *ppIE;
760 pIE->pStream->Close(&pIE->pStream);
761
762 return PKFree((void **) ppIE);
763 }
764
PKImageEncode_Create(PKImageEncode ** ppIE)765 ERR PKImageEncode_Create(PKImageEncode** ppIE)
766 {
767 ERR err = WMP_errSuccess;
768 PKImageEncode* pIE = NULL;
769
770 Call(PKAlloc((void **) ppIE, sizeof(**ppIE)));
771
772 pIE = *ppIE;
773 pIE->Initialize = PKImageEncode_Initialize;
774 pIE->Terminate = PKImageEncode_Terminate;
775 pIE->SetPixelFormat = PKImageEncode_SetPixelFormat;
776 pIE->SetSize = PKImageEncode_SetSize;
777 pIE->SetResolution = PKImageEncode_SetResolution;
778 pIE->SetColorContext = PKImageEncode_SetColorContext;
779 pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata;
780 pIE->WritePixels = PKImageEncode_WritePixels;
781 // pIE->WriteSource = PKImageEncode_WriteSource;
782
783 pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin;
784 pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded;
785 pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd;
786
787 pIE->CreateNewFrame = PKImageEncode_CreateNewFrame;
788 pIE->Release = PKImageEncode_Release;
789 pIE->bWMP = FALSE;
790
791 Cleanup:
792 return err;
793 }
794
795
796 //================================================================
797 // PKImageDecode
798 //================================================================
PKImageDecode_Initialize(PKImageDecode * pID,struct WMPStream * pStream)799 ERR PKImageDecode_Initialize(
800 PKImageDecode* pID,
801 struct WMPStream* pStream)
802 {
803 ERR err = WMP_errSuccess;
804
805 pID->pStream = pStream;
806 pID->guidPixFormat = GUID_PKPixelFormatDontCare;
807 pID->fResX = 96;
808 pID->fResY = 96;
809 pID->cFrame = 1;
810
811 Call(pID->pStream->GetPos(pID->pStream, &pID->offStart));
812
813 memset(&pID->WMP.wmiDEMisc, 0, sizeof(pID->WMP.wmiDEMisc));
814
815 Cleanup:
816 return WMP_errSuccess;
817 }
818
PKImageDecode_GetPixelFormat(PKImageDecode * pID,PKPixelFormatGUID * pPF)819 ERR PKImageDecode_GetPixelFormat(
820 PKImageDecode* pID,
821 PKPixelFormatGUID* pPF)
822 {
823 *pPF = pID->guidPixFormat;
824
825 return WMP_errSuccess;
826 }
827
PKImageDecode_GetSize(PKImageDecode * pID,I32 * piWidth,I32 * piHeight)828 ERR PKImageDecode_GetSize(
829 PKImageDecode* pID,
830 I32* piWidth,
831 I32* piHeight)
832 {
833 *piWidth = (I32)pID->uWidth;
834 *piHeight = (I32)pID->uHeight;
835
836 return WMP_errSuccess;
837 }
838
PKImageDecode_GetResolution(PKImageDecode * pID,Float * pfResX,Float * pfResY)839 ERR PKImageDecode_GetResolution(
840 PKImageDecode* pID,
841 Float* pfResX,
842 Float* pfResY)
843 {
844 *pfResX = pID->fResX;
845 *pfResY = pID->fResY;
846
847 return WMP_errSuccess;
848 }
849
PKImageDecode_GetColorContext(PKImageDecode * pID,U8 * pbColorContext,U32 * pcbColorContext)850 ERR PKImageDecode_GetColorContext(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext)
851 {
852 UNREFERENCED_PARAMETER( pID );
853 UNREFERENCED_PARAMETER( pbColorContext );
854 UNREFERENCED_PARAMETER( pcbColorContext );
855 return WMP_errNotYetImplemented;
856 }
857
PKImageDecode_GetDescriptiveMetadata(PKImageDecode * pIE,DESCRIPTIVEMETADATA * pDescMetadata)858 ERR PKImageDecode_GetDescriptiveMetadata(PKImageDecode *pIE, DESCRIPTIVEMETADATA *pDescMetadata)
859 {
860 UNREFERENCED_PARAMETER( pIE );
861 UNREFERENCED_PARAMETER( pDescMetadata );
862 return WMP_errNotYetImplemented;
863 }
864
PKImageDecode_Copy(PKImageDecode * pID,const PKRect * pRect,U8 * pb,U32 cbStride)865 ERR PKImageDecode_Copy(
866 PKImageDecode* pID,
867 const PKRect* pRect,
868 U8* pb,
869 U32 cbStride)
870 {
871 UNREFERENCED_PARAMETER( pID );
872 UNREFERENCED_PARAMETER( pRect );
873 UNREFERENCED_PARAMETER( pb );
874 UNREFERENCED_PARAMETER( cbStride );
875 return WMP_errAbstractMethod;
876 }
877
PKImageDecode_GetFrameCount(PKImageDecode * pID,U32 * puCount)878 ERR PKImageDecode_GetFrameCount(
879 PKImageDecode* pID,
880 U32* puCount)
881 {
882 *puCount = pID->cFrame;
883
884 return WMP_errSuccess;
885 }
886
PKImageDecode_SelectFrame(PKImageDecode * pID,U32 uFrame)887 ERR PKImageDecode_SelectFrame(
888 PKImageDecode* pID,
889 U32 uFrame)
890 {
891 UNREFERENCED_PARAMETER( pID );
892 UNREFERENCED_PARAMETER( uFrame );
893 // NYI
894 return WMP_errSuccess;
895 }
896
PKImageDecode_Release(PKImageDecode ** ppID)897 ERR PKImageDecode_Release(
898 PKImageDecode** ppID)
899 {
900 PKImageDecode* pID = *ppID;
901
902 pID->fStreamOwner && pID->pStream->Close(&pID->pStream);
903
904 return PKFree((void **) ppID);
905 }
906
PKImageDecode_Create(PKImageDecode ** ppID)907 ERR PKImageDecode_Create(
908 PKImageDecode** ppID)
909 {
910 ERR err = WMP_errSuccess;
911 PKImageDecode* pID = NULL;
912
913 Call(PKAlloc((void **) ppID, sizeof(**ppID)));
914
915 pID = *ppID;
916 pID->Initialize = PKImageDecode_Initialize;
917 pID->GetPixelFormat = PKImageDecode_GetPixelFormat;
918 pID->GetSize = PKImageDecode_GetSize;
919 pID->GetResolution = PKImageDecode_GetResolution;
920 pID->GetColorContext = PKImageDecode_GetColorContext;
921 pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata;
922 pID->Copy = PKImageDecode_Copy;
923 pID->GetFrameCount = PKImageDecode_GetFrameCount;
924 pID->SelectFrame = PKImageDecode_SelectFrame;
925 pID->Release = PKImageDecode_Release;
926
927 Cleanup:
928 return err;
929 }
930
931