Coverage Report

Created: 2023-12-08 06:53

/src/freeimage-svn/FreeImage/trunk/Source/LibJXR/jxrgluelib/JXRGlue.c
Line
Count
Source (jump to first uncovered line)
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
//================================================================
46
ERR PKAlloc(void** ppv, size_t cb)
47
0
{
48
0
    *ppv = calloc(1, cb);
49
0
    return *ppv ? WMP_errSuccess : WMP_errOutOfMemory;
50
0
}
51
52
53
ERR PKFree(void** ppv)
54
0
{
55
0
  if (ppv) {
56
0
    free(*ppv);
57
0
    *ppv = NULL;
58
0
  }
59
60
0
  return WMP_errSuccess;
61
0
}
62
63
ERR PKAllocAligned(void** ppv, size_t cb, size_t iAlign)
64
0
{
65
0
    U8          *pOrigPtr;
66
0
    U8          *pReturnedPtr;
67
0
    size_t       iAlignmentCorrection;
68
0
    const size_t c_cbBlockSize = cb + sizeof(void*) + iAlign - 1;
69
70
0
    *ppv = NULL;
71
0
    pOrigPtr = calloc(1, c_cbBlockSize);
72
0
  if (NULL == pOrigPtr) {
73
0
    return WMP_errOutOfMemory;
74
0
  }
75
76
0
    iAlignmentCorrection = iAlign - ((size_t)pOrigPtr % iAlign);
77
0
  if (iAlignmentCorrection < sizeof(void*)) {
78
    // Alignment correction won't leave us enough space to store pOrigPtr - advance to next block
79
0
    iAlignmentCorrection += iAlign;
80
0
  }
81
82
0
    assert(iAlignmentCorrection >= sizeof(void*)); // Alignment correction must have space for pOrigPtr
83
0
    assert(iAlignmentCorrection + cb <= c_cbBlockSize); // Don't exceed right edge of memory block
84
85
0
    pReturnedPtr = pOrigPtr + iAlignmentCorrection;
86
0
    *(void**)(pReturnedPtr - sizeof(void*)) = pOrigPtr;
87
88
0
    assert(0 == ((size_t)pReturnedPtr % iAlign)); // Are we in fact aligned?
89
0
    *ppv = pReturnedPtr;
90
0
    return WMP_errSuccess;
91
0
}
92
93
ERR PKFreeAligned(void** ppv)
94
0
{
95
0
    if (ppv && *ppv) {
96
0
        U8 **ppOrigPtr = (U8**)((U8*)(*ppv) - sizeof(void*));
97
0
        assert(*ppOrigPtr <= (U8*)ppOrigPtr); // Something's wrong if pOrigPtr points forward
98
0
        free(*ppOrigPtr);
99
0
        *ppv = NULL;
100
0
    }
101
0
    return WMP_errSuccess;
102
0
}
103
104
105
106
int PKStrnicmp(const char* s1, const char* s2, size_t c)
107
0
{
108
0
    for(; tolower(*s1) == tolower(*s2) && *s1 && *s2 && c; ++s1, ++s2, --c);
109
0
    return c ? *s1 - *s2 : 0;
110
0
}
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)
217
ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType)
218
0
{
219
0
  ERR err = WMP_errSuccess;
220
0
  size_t i;
221
222
0
  for (i = 0; i < sizeof2(pixelInfo); ++i) {
223
0
    if (LOOKUP_FORWARD == uLookupType) {
224
0
      if (IsEqualGUID(pPI->pGUIDPixFmt, pixelInfo[i].pGUIDPixFmt)) {
225
0
        *pPI = pixelInfo[i];
226
0
        goto Cleanup;
227
0
      }
228
0
    }
229
0
    else if (LOOKUP_BACKWARD_TIF == uLookupType) {
230
0
      if (pPI->uSamplePerPixel == pixelInfo[i].uSamplePerPixel &&
231
0
        pPI->uBitsPerSample == pixelInfo[i].uBitsPerSample &&
232
0
        pPI->uSampleFormat == pixelInfo[i].uSampleFormat &&
233
0
        pPI->uInterpretation == pixelInfo[i].uInterpretation) {
234
        // match alpha & premult
235
0
        if ((pPI->grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)) ==
236
0
          (pixelInfo[i].grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul))) {
237
0
          *pPI = pixelInfo[i];
238
0
          goto Cleanup;
239
0
        }
240
0
      }
241
0
    }
242
0
  }
243
0
  Call(WMP_errUnsupportedFormat);
244
245
0
Cleanup:
246
0
  return err;
247
0
}
248
249
250
const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash)
251
0
{
252
0
  int i;
253
254
0
  for (i = 0; i < sizeof2(pixelInfo); i++) {
255
0
    if (pixelInfo[i].pGUIDPixFmt->Data4[7] == uPFHash) {
256
0
      return pixelInfo[i].pGUIDPixFmt;
257
0
    }
258
0
  }
259
260
  // If we reached this point, we did not find anything which matched the hash
261
0
  return NULL;
262
0
}
263
264
//----------------------------------------------------------------
265
typedef struct tagPKIIDInfo
266
{
267
    const char* szExt;
268
    const PKIID* pIIDEnc;
269
    const PKIID* pIIDDec;
270
} PKIIDInfo;
271
272
static ERR GetIIDInfo(const char* szExt, const PKIIDInfo** ppInfo)
273
0
{
274
0
  ERR err = WMP_errSuccess;
275
276
0
  static PKIIDInfo iidInfo[] = {
277
0
    {".jxr", &IID_PKImageWmpEncode, &IID_PKImageWmpDecode},
278
0
    {".wdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
279
0
    {".hdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
280
0
  };
281
0
  size_t i = 0;
282
283
0
  *ppInfo = NULL;
284
0
  for (i = 0; i < sizeof2(iidInfo); ++i) {
285
0
    if (0 == PKStrnicmp(szExt, iidInfo[i].szExt, strlen(iidInfo[i].szExt))) {
286
0
      *ppInfo = &iidInfo[i];
287
0
      goto Cleanup;
288
0
    }
289
0
  }
290
291
0
  Call(WMP_errUnsupportedFormat);
292
293
0
Cleanup:
294
0
  return err;
295
0
}
296
297
ERR GetImageEncodeIID(const char* szExt, const PKIID** ppIID)
298
0
{
299
0
    ERR err = WMP_errSuccess;
300
301
0
    const PKIIDInfo* pInfo = NULL;
302
303
0
    Call(GetIIDInfo(szExt, &pInfo));
304
0
    *ppIID = pInfo->pIIDEnc;
305
306
0
Cleanup:
307
0
    return err;
308
0
}
309
310
ERR GetImageDecodeIID(const char* szExt, const PKIID** ppIID)
311
0
{
312
0
    ERR err = WMP_errSuccess;
313
314
0
    const PKIIDInfo* pInfo = NULL;
315
316
0
    Call(GetIIDInfo(szExt, &pInfo));
317
0
    *ppIID = pInfo->pIIDDec;
318
319
0
Cleanup:
320
0
    return err;
321
0
}
322
323
//================================================================
324
// PKFactory
325
//================================================================
326
ERR PKCreateFactory_CreateStream(PKStream** ppStream)
327
0
{
328
0
    ERR err = WMP_errSuccess;
329
330
0
    Call(PKAlloc((void **) ppStream, sizeof(**ppStream)));
331
332
0
Cleanup:
333
0
    return err;
334
0
}
335
336
ERR PKCreateFactory_Release(PKFactory** ppFactory)
337
0
{
338
0
    ERR err = WMP_errSuccess;
339
340
0
    Call(PKFree((void **) ppFactory));
341
342
0
Cleanup: 
343
0
    return err;
344
0
}
345
346
//----------------------------------------------------------------
347
ERR PKCreateFactory(PKFactory** ppFactory, U32 uVersion)
348
0
{
349
0
    ERR err = WMP_errSuccess;
350
0
    PKFactory* pFactory = NULL;
351
352
0
    UNREFERENCED_PARAMETER( uVersion );
353
354
0
    Call(PKAlloc((void **) ppFactory, sizeof(**ppFactory)));
355
0
    pFactory = *ppFactory;
356
357
0
    pFactory->CreateStream = PKCreateFactory_CreateStream;
358
359
0
    pFactory->CreateStreamFromFilename = CreateWS_File;
360
0
    pFactory->CreateStreamFromMemory = CreateWS_Memory;
361
    
362
0
    pFactory->Release = PKCreateFactory_Release;
363
364
0
Cleanup:
365
0
    return err;
366
0
}
367
368
369
//================================================================
370
// PKCodecFactory
371
//================================================================
372
ERR PKCodecFactory_CreateCodec(const PKIID* iid, void** ppv)
373
0
{
374
0
  ERR err = WMP_errSuccess;
375
376
0
  if (IID_PKImageWmpEncode == *iid) {
377
0
    Call(PKImageEncode_Create_WMP((PKImageEncode**)ppv));
378
0
  }
379
0
  else if (IID_PKImageWmpDecode == *iid) {
380
0
    Call(PKImageDecode_Create_WMP((PKImageDecode**)ppv));
381
0
  }
382
0
  else {
383
0
    Call(WMP_errUnsupportedFormat);
384
0
  }
385
386
0
Cleanup:
387
0
  return err;
388
0
}
389
390
ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder)
391
0
{
392
0
    ERR err = WMP_errSuccess;
393
394
0
    char *pExt = NULL;
395
0
    const PKIID* pIID = NULL;
396
397
0
    struct WMPStream* pStream = NULL;
398
0
    PKImageDecode* pDecoder = NULL;
399
400
    // get file extension
401
0
    pExt = strrchr(szFilename, '.');
402
0
    FailIf(NULL == pExt, WMP_errUnsupportedFormat);
403
404
    // get decode PKIID
405
0
    Call(GetImageDecodeIID(pExt, &pIID));
406
407
    // create stream
408
0
    Call(CreateWS_File(&pStream, szFilename, "rb"));
409
410
    // Create decoder
411
0
    Call(PKCodecFactory_CreateCodec(pIID, (void **) ppDecoder));
412
0
    pDecoder = *ppDecoder;
413
414
    // attach stream to decoder
415
0
    Call(pDecoder->Initialize(pDecoder, pStream));
416
0
    pDecoder->fStreamOwner = !0;
417
418
0
Cleanup:
419
0
    return err;
420
0
}
421
422
ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter)
423
0
{
424
0
    ERR err = WMP_errSuccess;
425
0
    PKFormatConverter* pFC = NULL;
426
427
0
    Call(PKAlloc((void **) ppFConverter, sizeof(**ppFConverter)));
428
0
    pFC = *ppFConverter;
429
430
0
    pFC->Initialize = PKFormatConverter_Initialize;
431
0
    pFC->InitializeConvert = PKFormatConverter_InitializeConvert;
432
0
    pFC->GetPixelFormat = PKFormatConverter_GetPixelFormat;
433
0
    pFC->GetSourcePixelFormat = PKFormatConverter_GetSourcePixelFormat;
434
0
    pFC->GetSize = PKFormatConverter_GetSize;
435
0
    pFC->GetResolution = PKFormatConverter_GetResolution;
436
0
    pFC->Copy = PKFormatConverter_Copy;
437
0
    pFC->Convert = PKFormatConverter_Convert;
438
0
    pFC->Release = PKFormatConverter_Release;
439
440
0
Cleanup:
441
0
    return err;
442
0
}
443
444
ERR PKCreateCodecFactory_Release(PKCodecFactory** ppCFactory)
445
0
{
446
0
    ERR err = WMP_errSuccess;
447
448
0
    Call(PKFree((void **) ppCFactory));
449
450
0
Cleanup:
451
0
    return err;
452
0
}
453
454
ERR PKCreateCodecFactory(PKCodecFactory** ppCFactory, U32 uVersion)
455
0
{
456
0
    ERR err = WMP_errSuccess;
457
0
    PKCodecFactory* pCFactory = NULL;
458
459
0
    UNREFERENCED_PARAMETER( uVersion );
460
461
0
    Call(PKAlloc((void **) ppCFactory, sizeof(**ppCFactory)));
462
0
    pCFactory = *ppCFactory;
463
464
0
    pCFactory->CreateCodec = PKCodecFactory_CreateCodec;
465
0
    pCFactory->CreateDecoderFromFile = PKCodecFactory_CreateDecoderFromFile;
466
0
    pCFactory->CreateFormatConverter = PKCodecFactory_CreateFormatConverter;
467
0
    pCFactory->Release = PKCreateCodecFactory_Release;
468
469
0
Cleanup:
470
0
    return err;
471
0
}
472
473
474
//================================================================
475
// PKImageEncode
476
//================================================================
477
ERR PKImageEncode_Initialize(PKImageEncode* pIE, struct WMPStream* pStream, void* pvParam, size_t cbParam)
478
0
{
479
0
    ERR err = WMP_errSuccess;
480
481
0
    UNREFERENCED_PARAMETER( pIE );
482
0
    UNREFERENCED_PARAMETER( pvParam );
483
0
    UNREFERENCED_PARAMETER( cbParam );
484
485
0
    pIE->pStream = pStream;
486
0
    pIE->guidPixFormat = GUID_PKPixelFormatDontCare;
487
0
    pIE->fResX = 96;
488
0
    pIE->fResY = 96;
489
0
    pIE->cFrame = 1;
490
491
0
    Call(pIE->pStream->GetPos(pIE->pStream, &pIE->offStart));
492
493
0
Cleanup:
494
0
    return err;
495
0
}
496
497
ERR PKImageEncode_Terminate(PKImageEncode* pIE)
498
0
{
499
0
    UNREFERENCED_PARAMETER( pIE );
500
0
    return WMP_errSuccess;
501
0
}
502
503
ERR PKImageEncode_SetPixelFormat(PKImageEncode* pIE, PKPixelFormatGUID enPixelFormat)
504
0
{
505
0
    pIE->guidPixFormat = enPixelFormat;
506
507
0
    return WMP_errSuccess;
508
0
}
509
510
ERR PKImageEncode_SetSize(PKImageEncode* pIE, I32 iWidth, I32 iHeight)
511
0
{
512
0
    ERR err = WMP_errSuccess;
513
514
0
    pIE->uWidth = (U32)iWidth;
515
0
    pIE->uHeight = (U32)iHeight;
516
517
0
    return err;
518
0
}
519
520
ERR PKImageEncode_SetResolution(PKImageEncode* pIE, Float fResX, Float fResY)
521
0
{
522
0
    pIE->fResX = fResX;
523
0
    pIE->fResY = fResY;
524
525
0
    return WMP_errSuccess;
526
0
}
527
528
ERR PKImageEncode_SetColorContext(PKImageEncode *pIE, const U8 *pbColorContext, U32 cbColorContext)
529
0
{
530
0
    UNREFERENCED_PARAMETER( pIE );
531
0
    UNREFERENCED_PARAMETER( pbColorContext );
532
0
    UNREFERENCED_PARAMETER( cbColorContext );
533
0
    return WMP_errNotYetImplemented;
534
0
}
535
536
537
ERR PKImageEncode_SetDescriptiveMetadata(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pDescMetadata)
538
0
{
539
0
    UNREFERENCED_PARAMETER( pIE );
540
0
    UNREFERENCED_PARAMETER( pDescMetadata );
541
0
    return WMP_errNotYetImplemented;
542
0
}
543
544
ERR PKImageEncode_WritePixels(PKImageEncode* pIE, U32 cLine, U8* pbPixels, U32 cbStride)
545
0
{
546
0
    UNREFERENCED_PARAMETER( pIE );
547
0
    UNREFERENCED_PARAMETER( cLine );
548
0
    UNREFERENCED_PARAMETER( pbPixels );
549
0
    UNREFERENCED_PARAMETER( cbStride );
550
0
    return WMP_errAbstractMethod;
551
0
}
552
553
ERR PKImageEncode_WriteSource(PKImageEncode* pIE, PKFormatConverter* pFC, PKRect* pRect)
554
0
{
555
0
    ERR err = WMP_errSuccess;
556
557
0
    PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
558
0
    PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
559
560
0
    PKPixelInfo pPIFrom;
561
0
    PKPixelInfo pPITo;
562
563
0
    U32 cbStrideTo = 0;
564
0
    U32 cbStrideFrom = 0;
565
0
    U32 cbStride = 0;
566
567
0
    U8* pb = NULL;
568
569
  // CWMTranscodingParam* pParam = NULL; 
570
571
    // get pixel format
572
0
    Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
573
0
    Call(pFC->GetPixelFormat(pFC, &enPFTo));
574
0
    FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
575
576
    // calc common stride
577
//    Call(GetPixelInfo(enPFFrom, &pPIFrom));
578
0
    pPIFrom.pGUIDPixFmt = &enPFFrom;
579
0
    PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
580
581
//    Call(GetPixelInfo(enPFTo, &pPITo));
582
0
    pPITo.pGUIDPixFmt = &enPFTo;
583
0
    PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
584
585
//    cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
586
0
    cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width)); 
587
0
    if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt 
588
0
        || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt) 
589
0
        cbStrideFrom >>= 1;
590
591
//    cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
592
0
    cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth)); 
593
0
    if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
594
0
        || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) 
595
0
        cbStrideTo >>= 1;
596
597
0
    cbStride = max(cbStrideFrom, cbStrideTo);
598
599
    // actual dec/enc with local buffer
600
0
    Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
601
602
0
    Call(pFC->Copy(pFC, pRect, pb, cbStride));
603
604
0
  Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
605
606
0
Cleanup:
607
0
    PKFreeAligned((void **) &pb);
608
0
    return err;
609
0
}
610
611
ERR PKImageEncode_WritePixelsBandedBegin(PKImageEncode* pEncoder, struct WMPStream *pPATempFile)
612
0
{
613
0
    UNREFERENCED_PARAMETER( pEncoder );
614
0
    UNREFERENCED_PARAMETER( pPATempFile );
615
0
    return WMP_errAbstractMethod;
616
0
}
617
618
ERR PKImageEncode_WritePixelsBanded(PKImageEncode* pEncoder, U32 cLines, U8* pbPixels, U32 cbStride, Bool fLastCall)
619
0
{
620
0
    UNREFERENCED_PARAMETER( pEncoder );
621
0
    UNREFERENCED_PARAMETER( cLines );
622
0
    UNREFERENCED_PARAMETER( pbPixels );
623
0
    UNREFERENCED_PARAMETER( cbStride );
624
0
    UNREFERENCED_PARAMETER( fLastCall );
625
0
    return WMP_errAbstractMethod;
626
0
}
627
628
ERR PKImageEncode_WritePixelsBandedEnd(PKImageEncode* pEncoder)
629
0
{
630
0
    UNREFERENCED_PARAMETER( pEncoder );
631
0
    return WMP_errAbstractMethod;
632
0
}
633
634
635
ERR PKImageEncode_Transcode(PKImageEncode* pIE, PKFormatConverter* pFC, PKRect* pRect)
636
0
{
637
0
    ERR err = WMP_errSuccess;
638
639
0
    PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
640
0
    PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
641
642
0
    PKPixelInfo pPIFrom;
643
0
    PKPixelInfo pPITo;
644
645
0
    U32 cbStrideTo = 0;
646
0
    U32 cbStrideFrom = 0;
647
0
    U32 cbStride = 0;
648
649
0
    U8* pb = NULL;
650
651
0
    CWMTranscodingParam cParam = {0}; 
652
653
    // get pixel format
654
0
    Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
655
0
    Call(pFC->GetPixelFormat(pFC, &enPFTo));
656
0
    FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
657
658
    // calc common stride
659
//    Call(GetPixelInfo(enPFFrom, &pPIFrom));
660
0
    pPIFrom.pGUIDPixFmt = &enPFFrom;
661
0
    PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
662
663
//    Call(GetPixelInfo(enPFTo, &pPITo));
664
0
    pPITo.pGUIDPixFmt = &enPFTo;
665
0
    PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
666
667
//    cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
668
0
    cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width)); 
669
0
    if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt 
670
0
        || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt) 
671
0
        cbStrideFrom >>= 1;
672
673
//    cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
674
0
    cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth)); 
675
0
    if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
676
0
        || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) 
677
0
        cbStrideTo >>= 1;
678
679
0
    cbStride = max(cbStrideFrom, cbStrideTo);
680
681
0
    if(pIE->bWMP){
682
0
        cParam.cLeftX = pFC->pDecoder->WMP.wmiI.cROILeftX;
683
0
        cParam.cTopY = pFC->pDecoder->WMP.wmiI.cROITopY;
684
0
        cParam.cWidth = pFC->pDecoder->WMP.wmiI.cROIWidth;
685
0
        cParam.cHeight = pFC->pDecoder->WMP.wmiI.cROIHeight;
686
0
        cParam.oOrientation = pFC->pDecoder->WMP.wmiI.oOrientation;
687
//        cParam.cfColorFormat = pFC->pDecoder->WMP.wmiI.cfColorFormat;
688
0
        cParam.uAlphaMode = pFC->pDecoder->WMP.wmiSCP.uAlphaMode;
689
0
        cParam.bfBitstreamFormat = pFC->pDecoder->WMP.wmiSCP.bfBitstreamFormat;
690
0
        cParam.sbSubband = pFC->pDecoder->WMP.wmiSCP.sbSubband;
691
0
        cParam.bIgnoreOverlap = pFC->pDecoder->WMP.bIgnoreOverlap;
692
        
693
0
        Call(pIE->Transcode(pIE, pFC->pDecoder, &cParam));
694
0
    }
695
0
  else 
696
0
  {
697
    // actual dec/enc with local buffer
698
0
      Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
699
0
    Call(pFC->Copy(pFC, pRect, pb, cbStride));
700
0
    Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
701
0
  }
702
703
0
Cleanup:
704
0
    PKFreeAligned((void **) &pb);
705
0
    return err;
706
0
}
707
708
ERR PKImageEncode_CreateNewFrame(PKImageEncode* pIE, void* pvParam, size_t cbParam)
709
0
{
710
0
    UNREFERENCED_PARAMETER( pIE );
711
0
    UNREFERENCED_PARAMETER( pvParam );
712
0
    UNREFERENCED_PARAMETER( cbParam );
713
    // NYI
714
0
    return WMP_errSuccess;
715
0
}
716
717
ERR PKImageEncode_Release(PKImageEncode** ppIE)
718
0
{
719
0
    PKImageEncode *pIE = *ppIE;
720
0
    pIE->pStream->Close(&pIE->pStream);
721
722
0
    return PKFree((void **) ppIE);
723
0
}
724
725
ERR PKImageEncode_Create(PKImageEncode** ppIE)
726
0
{
727
0
    ERR err = WMP_errSuccess;
728
0
    PKImageEncode* pIE = NULL;
729
730
0
    Call(PKAlloc((void **) ppIE, sizeof(**ppIE)));
731
732
0
    pIE = *ppIE;
733
0
    pIE->Initialize = PKImageEncode_Initialize;
734
0
    pIE->Terminate = PKImageEncode_Terminate;
735
0
    pIE->SetPixelFormat = PKImageEncode_SetPixelFormat;
736
0
    pIE->SetSize = PKImageEncode_SetSize;
737
0
    pIE->SetResolution = PKImageEncode_SetResolution;
738
0
    pIE->SetColorContext = PKImageEncode_SetColorContext;
739
0
    pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata;
740
0
    pIE->WritePixels = PKImageEncode_WritePixels;
741
//    pIE->WriteSource = PKImageEncode_WriteSource;
742
743
0
    pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin;
744
0
    pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded;
745
0
    pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd;
746
747
0
    pIE->CreateNewFrame = PKImageEncode_CreateNewFrame;
748
0
    pIE->Release = PKImageEncode_Release;
749
0
  pIE->bWMP = FALSE; 
750
751
0
Cleanup:
752
0
    return err;
753
0
}
754
  
755
756
//================================================================
757
// PKImageDecode
758
//================================================================
759
ERR PKImageDecode_Initialize(PKImageDecode* pID, struct WMPStream* pStream)
760
0
{
761
0
    ERR err = WMP_errSuccess;
762
763
0
    pID->pStream = pStream;
764
0
    pID->guidPixFormat = GUID_PKPixelFormatDontCare;
765
0
    pID->fResX = 96;
766
0
    pID->fResY = 96;
767
0
    pID->cFrame = 1;
768
769
0
    Call(pID->pStream->GetPos(pID->pStream, &pID->offStart));
770
771
0
    memset(&pID->WMP.wmiDEMisc, 0, sizeof(pID->WMP.wmiDEMisc));
772
773
0
Cleanup:
774
0
    return WMP_errSuccess;
775
0
}
776
777
ERR PKImageDecode_GetPixelFormat(PKImageDecode* pID, PKPixelFormatGUID* pPF)
778
0
{
779
0
    *pPF = pID->guidPixFormat;
780
781
0
    return WMP_errSuccess;
782
0
}
783
784
ERR PKImageDecode_GetSize(PKImageDecode* pID, I32* piWidth, I32* piHeight)
785
0
{
786
0
    *piWidth = (I32)pID->uWidth;
787
0
    *piHeight = (I32)pID->uHeight;
788
789
0
    return WMP_errSuccess;
790
0
}
791
792
ERR PKImageDecode_GetResolution(PKImageDecode* pID, Float* pfResX, Float* pfResY)
793
0
{
794
0
    *pfResX = pID->fResX;
795
0
    *pfResY = pID->fResY;
796
797
0
    return WMP_errSuccess;
798
0
}
799
800
ERR PKImageDecode_GetColorContext(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext)
801
0
{
802
0
    UNREFERENCED_PARAMETER( pID );
803
0
    UNREFERENCED_PARAMETER( pbColorContext );
804
0
    UNREFERENCED_PARAMETER( pcbColorContext );
805
0
    return WMP_errNotYetImplemented;
806
0
}
807
808
ERR PKImageDecode_GetDescriptiveMetadata(PKImageDecode *pIE, DESCRIPTIVEMETADATA *pDescMetadata)
809
0
{
810
0
    UNREFERENCED_PARAMETER( pIE );
811
0
    UNREFERENCED_PARAMETER( pDescMetadata );
812
0
    return WMP_errNotYetImplemented;
813
0
}
814
815
ERR PKImageDecode_Copy(PKImageDecode* pID, const PKRect* pRect, U8* pb, U32 cbStride)
816
0
{
817
0
    UNREFERENCED_PARAMETER( pID );
818
0
    UNREFERENCED_PARAMETER( pRect );
819
0
    UNREFERENCED_PARAMETER( pb );
820
0
    UNREFERENCED_PARAMETER( cbStride );
821
0
    return WMP_errAbstractMethod;
822
0
}
823
824
ERR PKImageDecode_GetFrameCount(PKImageDecode* pID, U32* puCount)
825
0
{
826
0
    *puCount = pID->cFrame;
827
828
0
    return WMP_errSuccess;
829
0
}
830
831
ERR PKImageDecode_SelectFrame(PKImageDecode* pID, U32 uFrame)
832
0
{
833
0
    UNREFERENCED_PARAMETER( pID );
834
0
    UNREFERENCED_PARAMETER( uFrame );
835
    // NYI
836
0
    return WMP_errSuccess;
837
0
}
838
839
ERR PKImageDecode_Release(PKImageDecode** ppID)
840
0
{
841
0
    PKImageDecode* pID = *ppID;
842
843
0
    pID->fStreamOwner && pID->pStream->Close(&pID->pStream);
844
845
0
    return PKFree((void **) ppID);
846
0
}
847
848
ERR PKImageDecode_Create(PKImageDecode** ppID)
849
0
{
850
0
    ERR err = WMP_errSuccess;
851
0
    PKImageDecode* pID = NULL;
852
853
0
    Call(PKAlloc((void **) ppID, sizeof(**ppID)));
854
855
0
    pID = *ppID;
856
0
    pID->Initialize = PKImageDecode_Initialize;
857
0
    pID->GetPixelFormat = PKImageDecode_GetPixelFormat;
858
0
    pID->GetSize = PKImageDecode_GetSize;
859
0
    pID->GetResolution = PKImageDecode_GetResolution;
860
0
    pID->GetColorContext = PKImageDecode_GetColorContext;
861
0
    pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata;
862
0
    pID->Copy = PKImageDecode_Copy;
863
0
    pID->GetFrameCount = PKImageDecode_GetFrameCount;
864
0
    pID->SelectFrame = PKImageDecode_SelectFrame;
865
0
    pID->Release = PKImageDecode_Release;
866
867
0
Cleanup:
868
0
    return err;
869
0
}
870