Coverage Report

Created: 2023-12-08 06:53

/src/freeimage-svn/FreeImage/trunk/Source/LibJXR/jxrgluelib/JXRGluePFC.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
30
#include <JXRGlue.h>
31
#include <math.h>
32
33
//================================================================
34
// PKFormatConverter
35
//================================================================
36
0
#define HLF_MIN 0.00006103515625f
37
0
#define HLF_MAX 65504.0f
38
39
#define HLF_MIN_BITS 0x0400
40
0
#define HLF_MAX_BITS 0x7bff
41
42
#define HLF_MIN_BITS_NEG (HLF_MIN_BITS | 0x8000)
43
0
#define HLF_MAX_BITS_NEG (HLF_MAX_BITS | 0x8000)
44
45
0
#define HLF_QNaN_BITZS 0x7fff
46
47
// simple and slow implementation of half <-> float conversion
48
static U32 Convert_Half_To_Float(U16 u16)
49
0
{
50
    // 1s5e10m -> 1s8e23m
51
0
    const U32 s = (u16 >> 15) & 0x0001;
52
0
    const U32 e = (u16 >> 10) & 0x001f;
53
0
    const U32 m = (u16 >>  0) & 0x03ff;
54
55
0
    if (0 == e) // 0, denorm
56
0
    {
57
0
        return s << 31;
58
0
    }
59
0
    else if (~(~0 << 5) == e) // inf, snan, qnan
60
0
    {
61
0
        return (s << 31) | ~(~0 << 8) << 23| (m << 13);
62
0
    }
63
64
0
    return (s << 31) | ((e - 15 + 127) << 23) | (m << 13); // norm
65
0
}
66
67
68
static U16 Convert_Float_To_Half(float f)
69
0
{
70
    // 1s5e10m -> 1s8e23m
71
0
    const U32 iFloat = *(U32*)&f; // Convert float to U32
72
73
0
    if (f != f)
74
0
    {
75
0
        return (U16)(iFloat | HLF_QNaN_BITZS); // +QNaN, -QNaN
76
0
    }
77
0
    else if (f < -HLF_MAX)
78
0
    {
79
0
        return HLF_MAX_BITS_NEG;
80
0
    }
81
0
    else if (HLF_MAX < f)
82
0
    {
83
0
        return HLF_MAX_BITS;
84
0
    }
85
0
    else if (-HLF_MIN < f && f < HLF_MIN)
86
0
    {
87
0
        return (U16)((iFloat >> 16) & 0x8000); // +0, -0
88
0
    }
89
90
    // Cut-and-paste from C++, introduce scope so we can decl more vars
91
0
    {
92
0
    const U32 s = (iFloat >> 31) & 0x00000001;
93
0
    const U32 e = (iFloat >> 23) & 0x000000ff;
94
0
    const U32 m = (iFloat >>  0) & 0x007fffff;
95
96
0
    return (U16) ((s << 15) | ((e - 127 + 15) << 10) | (m >> 13));
97
0
    }
98
0
}
99
100
101
static U8 Convert_Float_To_U8(float f)
102
0
{
103
    // convert from linear scRGB to non-linear sRGB
104
0
    if (f <= 0)
105
0
    {
106
0
        return 0;
107
0
    }
108
0
    else if (f <= 0.0031308f)
109
0
    {
110
0
        return (U8)((255.0f * f * 12.92f) + 0.5f);
111
0
    }
112
0
    else if (f < 1.0f)
113
0
    {
114
0
        return (U8)((255.0f * ((1.055f * (float)pow(f, 1.0 / 2.4)) - 0.055f)) + 0.5f);
115
0
    }
116
0
    else
117
0
    {
118
0
        return 255;
119
0
    }
120
0
}
121
122
static U8 Convert_AlphaFloat_To_U8(float f)
123
0
{
124
    // alpha is converted differently than RGB in scRGB
125
0
    if (f <= 0)
126
0
    {
127
0
        return 0;
128
0
    }
129
0
    else if (f < 1.0f)
130
0
    {
131
0
        return (U8)((255.0f * f) + 0.5f);
132
0
    }
133
0
    else
134
0
    {
135
0
        return 255;
136
0
    }
137
0
}
138
139
140
ERR RGB24_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
141
0
{
142
0
    I32 i = 0, j = 0;
143
144
0
    UNREFERENCED_PARAMETER( pFC );
145
   
146
0
    for (i = 0; i < pRect->Height; ++i)
147
0
    {
148
0
        for (j = 0; j < pRect->Width * 3; j += 3)
149
0
        {
150
            // swap red with blue
151
0
            U8 t = pb[j];
152
0
            pb[j] = pb[j + 2];
153
0
            pb[j + 2] = t;
154
0
        }
155
156
0
        pb += cbStride;
157
0
    }
158
159
0
    return WMP_errSuccess;
160
0
}
161
162
ERR BGR24_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
163
0
{
164
0
    return RGB24_BGR24(pFC, pRect, pb, cbStride);
165
0
}
166
167
ERR RGB24_BGR32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
168
0
{
169
0
    I32 i = 0, j = 0;
170
171
0
    UNREFERENCED_PARAMETER( pFC );
172
   
173
0
    for (i = 0; i < pRect->Height; ++i)
174
0
    {
175
0
        for (j = 0; j < pRect->Width; j++)
176
0
        {
177
            // swap red with blue
178
0
            U8 t = pb[3*j];
179
0
            pb[4*j] = pb[3*j + 2];
180
0
            pb[4*j + 1] = pb[3*j + 1];
181
0
            pb[4*j + 2] = t;
182
0
        }
183
184
0
        pb += cbStride;
185
0
    }
186
187
0
    return WMP_errSuccess;
188
0
}
189
190
ERR BGR32_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
191
0
{
192
0
    I32 i = 0, j = 0;
193
194
0
    UNREFERENCED_PARAMETER( pFC );
195
   
196
0
    for (i = 0; i < pRect->Height; ++i)
197
0
    {
198
0
        for (j = 0; j < pRect->Width; j++)
199
0
        {
200
            // swap red with blue
201
0
            U8 t = pb[4*j];
202
0
            pb[3*j] = pb[4*j + 2];
203
0
            pb[3*j + 1] = pb[4*j + 1];
204
0
            pb[3*j + 2] = t;
205
0
        }
206
207
0
        pb += cbStride;
208
0
    }
209
210
0
    return WMP_errSuccess;
211
0
}
212
213
ERR RGB24_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
214
0
{
215
0
    I32 i = 0, j = 0, k = 0;
216
217
0
    UNREFERENCED_PARAMETER( pFC );
218
    
219
0
    for (i = 0; i < pRect->Height; ++i)
220
0
    {
221
0
        for (j = 0, k = 0; j < pRect->Width * 3; j += 3, ++k)
222
0
        {
223
0
            U8 r = pb[j];
224
0
            U8 g = pb[j + 1];
225
0
            U8 b = pb[j + 2];
226
            
227
0
            pb[k] = r / 4 + g / 2 + b / 8 + 16;
228
0
        }
229
230
0
        pb += cbStride;
231
0
    }
232
233
0
    return WMP_errSuccess;
234
0
}
235
236
ERR BGR24_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
237
0
{
238
0
    ERR err = WMP_errSuccess;
239
240
0
    Call(BGR24_RGB24(pFC, pRect, pb, cbStride));
241
0
    Call(RGB24_Gray8(pFC, pRect, pb, cbStride));
242
243
0
Cleanup:
244
0
    return err;
245
0
}
246
247
ERR Gray8_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
248
0
{
249
0
    I32 i = 0, j = 0, k = 0;
250
251
0
    UNREFERENCED_PARAMETER( pFC );
252
    
253
0
    for (i = 0; i < pRect->Height; ++i)
254
0
    {
255
0
        for (j = pRect->Width - 1, k = 3 * j; 0 <= j; j--, k -= 3)
256
0
        {
257
0
            U8 v = pb[j];
258
259
0
            pb[k] = v;
260
0
            pb[k + 1] = v;
261
0
            pb[k + 2] = v;
262
0
        }
263
        
264
0
        pb += cbStride;
265
0
    }
266
267
0
    return WMP_errSuccess;
268
0
}
269
270
ERR Gray8_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
271
0
{
272
0
    return Gray8_RGB24(pFC, pRect, pb, cbStride);
273
0
}
274
275
#if 0
276
ERR RGB48_BGR48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
277
{
278
    ERR err = WMP_errSuccess;
279
280
    I32 i = 0, j = 0;
281
282
    UNREFERENCED_PARAMETER( pFC );
283
    
284
    Call(PKFormatConverter_Copy(pFC, pRect, pb, cbStride));
285
286
    for (i = 0; i < pRect->Height; ++i)
287
    {
288
        for (j = 0; j < pRect->Width; j += 3)
289
        {
290
            U16* ps = (U16*)pb;
291
            
292
            // swap red with blue
293
            U16 t = ps[j];
294
            ps[j] = ps[j + 2];
295
            ps[j + 2] = t;
296
        }
297
298
        pb += cbStride;
299
    }
300
301
Cleanup:
302
    return err;
303
}
304
305
ERR BGR48_RGB48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
306
{
307
    return RGB48_BGR48(pFC, pRect, pb, cbStride);
308
}
309
310
ERR RGB48_Gray16(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
311
{
312
    ERR err = WMP_errSuccess;
313
314
    I32 i = 0, j = 0, k = 0;
315
 
316
    UNREFERENCED_PARAMETER( pFC );
317
   
318
    Call(PKFormatConverter_Copy(pFC, pRect, pb, cbStride));
319
320
    for (i = 0; i < pRect->Height; ++i)
321
    {
322
        for (j = 0, k = 0; j < pRect->Width; j += 3, ++k)
323
        {
324
            U16* ps = (U16*)pb;
325
326
            // Y = r / 4 + g / 2 + b / 8 + 16
327
            U16 r = ps[j];
328
            U16 g = ps[j + 1];
329
            U16 b = ps[j + 2];
330
            
331
            ps[k] = r / 4 + g / 2 + b / 8 + 16;
332
        }
333
334
        pb += cbStride;
335
    }
336
337
Cleanup:
338
    return err;
339
}
340
#endif
341
342
ERR RGBA128Fixed_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
343
0
{
344
0
    const I32 iHeight = pRect->Height;
345
0
    const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A
346
0
    const float fltCvtFactor = 1.0F / (1 << 24);
347
0
    I32 y;
348
349
0
    UNREFERENCED_PARAMETER( pFC );
350
351
0
    for (y = 0; y < iHeight; y++)
352
0
    {
353
0
        I32 x;
354
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
355
0
        const I32 *piSrcPixel = (I32*)pfltDstPixel;
356
357
0
        for (x = 0; x < iWidthX4; x++)
358
0
            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
359
0
    }
360
    
361
0
    return WMP_errSuccess;
362
0
}
363
364
365
ERR RGBA128Float_RGBA128Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
366
0
{
367
0
    const I32 iHeight = pRect->Height;
368
0
    const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A
369
0
    const float fltCvtFactor = (float)(1 << 24);
370
0
    I32 y;
371
372
0
    UNREFERENCED_PARAMETER( pFC );
373
374
0
    for (y = 0; y < iHeight; y++)
375
0
    {
376
0
        I32 x;
377
0
        I32 *piDstPixel = (I32*)(pb + cbStride*y);
378
0
        const float *pfltSrcPixel = (float*)piDstPixel;
379
380
0
        for (x = 0; x < iWidthX4; x++)
381
0
            piDstPixel[x] = (I32) (pfltSrcPixel[x] * fltCvtFactor + 0.5F);
382
0
    }
383
    
384
0
    return WMP_errSuccess;
385
0
}
386
387
388
389
ERR RGB96Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
390
0
{
391
0
    const I32 iHeight = pRect->Height;
392
0
    const I32 iWidthX3 = 3 * pRect->Width; // 3 == R, G, B
393
0
    const float fltCvtFactor = 1.0F / (1 << 24);
394
0
    I32 y;
395
396
0
    UNREFERENCED_PARAMETER( pFC );
397
398
0
    for (y = 0; y < iHeight; y++)
399
0
    {
400
0
        I32 x;
401
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
402
0
        const I32 *piSrcPixel = (I32*)pfltDstPixel;
403
404
0
        for (x = 0; x < iWidthX3; x++)
405
0
            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
406
0
    }
407
    
408
0
    return WMP_errSuccess;
409
0
}
410
411
412
ERR RGB128Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
413
0
{
414
0
    const I32 iHeight = pRect->Height;
415
0
    const I32 iWidth = pRect->Width;
416
0
    const float fltCvtFactor = 1.0F / (1 << 24);
417
0
    I32 y;
418
419
0
    UNREFERENCED_PARAMETER( pFC );
420
421
0
    for (y = 0; y < iHeight; y++)
422
0
    {
423
0
        I32 x;
424
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
425
0
        const I32 *piSrcPixel = (I32*)pfltDstPixel;
426
427
0
        for (x = 0; x < iWidth; x++)
428
0
        {
429
0
            pfltDstPixel[3*x] = piSrcPixel[4*x] * fltCvtFactor;
430
0
            pfltDstPixel[3*x+1] = piSrcPixel[4*x+1] * fltCvtFactor;
431
0
            pfltDstPixel[3*x+2] = piSrcPixel[4*x+2] * fltCvtFactor;
432
0
        }
433
0
    }
434
    
435
0
    return WMP_errSuccess;
436
0
}
437
438
439
440
ERR RGB96Float_RGB96Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
441
0
{
442
0
    const I32 iHeight = pRect->Height;
443
0
    const I32 iWidthX3 = 3 * pRect->Width; // 3 == R, G, B
444
0
    const float fltCvtFactor = (float) (1 << 24);
445
0
    I32 y;
446
447
0
    UNREFERENCED_PARAMETER( pFC );
448
449
0
    for (y = 0; y < iHeight; y++)
450
0
    {
451
0
        I32 x;
452
0
        I32 *piDstPixel = (I32*)(pb + cbStride*y);
453
0
        const float *pfltSrcPixel = (float*)piDstPixel;
454
455
0
        for (x = 0; x < iWidthX3; x++)
456
0
            piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
457
0
    }
458
    
459
0
    return WMP_errSuccess;
460
0
}
461
462
463
ERR RGB96Float_RGB128Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
464
0
{
465
0
    const I32 iHeight = pRect->Height;
466
0
    const I32 iWidth = pRect->Width;
467
0
    const float fltCvtFactor = (float) (1 << 24);
468
0
    I32 y;
469
470
0
    UNREFERENCED_PARAMETER( pFC );
471
472
0
    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
473
0
    for (y = iHeight - 1; y >= 0; y--)
474
0
    {
475
0
        I32 x;
476
0
        I32 *piDstPixel = (I32*)(pb + cbStride*y);
477
0
        const float *pfltSrcPixel = (float*)piDstPixel;
478
479
0
        for (x = iWidth - 1; x >= 0; x--)
480
0
        {
481
0
            piDstPixel[4*x] = (I32)(pfltSrcPixel[3*x] * fltCvtFactor + 0.5F);
482
0
            piDstPixel[4*x+1] = (I32)(pfltSrcPixel[3*x+1] * fltCvtFactor + 0.5F);
483
0
            piDstPixel[4*x+2] = (I32)(pfltSrcPixel[3*x+2] * fltCvtFactor + 0.5F);
484
0
            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
485
0
        }
486
0
    }
487
    
488
0
    return WMP_errSuccess;
489
0
}
490
491
492
ERR RGB96Float_RGB128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
493
0
{
494
0
    const I32 iHeight = pRect->Height;
495
0
    const I32 iWidth = pRect->Width;
496
0
    I32 y;
497
498
0
    UNREFERENCED_PARAMETER( pFC );
499
500
0
    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
501
0
    for (y = iHeight - 1; y >= 0; y--)
502
0
    {
503
0
        I32 x;
504
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
505
0
        const float *pfltSrcPixel = (float*)pfltDstPixel;
506
507
0
        for (x = iWidth - 1; x >= 0; x--)
508
0
        {
509
0
            pfltDstPixel[4*x] = pfltSrcPixel[3*x];
510
0
            pfltDstPixel[4*x+1] = pfltSrcPixel[3*x+1];
511
0
            pfltDstPixel[4*x+2] = pfltSrcPixel[3*x+2];
512
0
            pfltDstPixel[4*x+3] = 0.0F; // Zero out the alpha channel
513
0
        }
514
0
    }
515
    
516
0
    return WMP_errSuccess;
517
0
}
518
519
520
ERR RGB128Float_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
521
0
{
522
0
    const I32 iHeight = pRect->Height;
523
0
    const I32 iWidth = pRect->Width;
524
0
    I32 y;
525
526
0
    UNREFERENCED_PARAMETER( pFC );
527
528
0
    for (y = 0; y < iHeight; y++)
529
0
    {
530
0
        I32 x;
531
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
532
0
        const float *pfltSrcPixel = (float*)pfltDstPixel;
533
534
0
        for (x = 0; x < iWidth; x++)
535
0
        {
536
0
            pfltDstPixel[3*x] = pfltSrcPixel[4*x];
537
0
            pfltDstPixel[3*x+1] = pfltSrcPixel[4*x+1];
538
0
            pfltDstPixel[3*x+2] = pfltSrcPixel[4*x+2];
539
0
        }
540
0
    }
541
    
542
0
    return WMP_errSuccess;
543
0
}
544
545
546
ERR RGB48Half_RGB64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
547
0
{
548
0
    const I32 iHeight = pRect->Height;
549
0
    const I32 iWidth = pRect->Width;
550
0
    I32 y;
551
552
0
    UNREFERENCED_PARAMETER( pFC );
553
554
0
    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
555
0
    for (y = iHeight - 1; y >= 0; y--)
556
0
    {
557
0
        I32 x;
558
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
559
0
        const I16 *piSrcPixel = (I16*)piDstPixel;
560
561
0
        for (x = iWidth - 1; x >= 0; x--)
562
0
        {
563
0
            piDstPixel[4*x] = piSrcPixel[3*x];
564
0
            piDstPixel[4*x+1] = piSrcPixel[3*x+1];
565
0
            piDstPixel[4*x+2] = piSrcPixel[3*x+2];
566
0
            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
567
0
        }
568
0
    }
569
    
570
0
    return WMP_errSuccess;
571
0
}
572
573
574
ERR RGB64Half_RGB48Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
575
0
{
576
0
    const I32 iHeight = pRect->Height;
577
0
    const I32 iWidth = pRect->Width;
578
0
    I32 y;
579
580
0
    UNREFERENCED_PARAMETER( pFC );
581
582
0
    for (y = 0; y < iHeight; y++)
583
0
    {
584
0
        I32 x;
585
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
586
0
        const short *piSrcPixel = (I16*)piDstPixel;
587
588
0
        for (x = 0; x < iWidth; x++)
589
0
        {
590
0
            piDstPixel[3*x] = piSrcPixel[4*x];
591
0
            piDstPixel[3*x+1] = piSrcPixel[4*x+1];
592
0
            piDstPixel[3*x+2] = piSrcPixel[4*x+2];
593
0
        }
594
0
    }
595
    
596
0
    return WMP_errSuccess;
597
0
}
598
599
600
ERR BGR24_BGR32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
601
0
{
602
0
    const I32 iHeight = pRect->Height;
603
0
    const I32 iWidth = pRect->Width;
604
0
    I32 y;
605
606
0
    UNREFERENCED_PARAMETER( pFC );
607
608
0
    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
609
0
    for (y = iHeight - 1; y >= 0; y--)
610
0
    {
611
0
        I32 x;
612
0
        U8 *piDstPixel = pb + cbStride*y;
613
0
        const U8 *piSrcPixel = piDstPixel;
614
615
0
        for (x = iWidth - 1; x >= 0; x--)
616
0
        {
617
0
            piDstPixel[4*x] = piSrcPixel[3*x];
618
0
            piDstPixel[4*x+1] = piSrcPixel[3*x+1];
619
0
            piDstPixel[4*x+2] = piSrcPixel[3*x+2];
620
0
            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
621
0
        }
622
0
    }
623
    
624
0
    return WMP_errSuccess;
625
0
}
626
627
628
ERR BGR32_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
629
0
{
630
0
    const I32 iHeight = pRect->Height;
631
0
    const I32 iWidth = pRect->Width;
632
0
    I32 y;
633
634
0
    UNREFERENCED_PARAMETER( pFC );
635
636
0
    for (y = 0; y < iHeight; y++)
637
0
    {
638
0
        I32 x;
639
0
        U8 *piDstPixel = pb + cbStride*y;
640
0
        const U8 *piSrcPixel = piDstPixel;
641
642
0
        for (x = 0; x < iWidth; x++)
643
0
        {
644
0
            piDstPixel[3*x] = piSrcPixel[4*x];
645
0
            piDstPixel[3*x+1] = piSrcPixel[4*x+1];
646
0
            piDstPixel[3*x+2] = piSrcPixel[4*x+2];
647
0
        }
648
0
    }
649
    
650
0
    return WMP_errSuccess;
651
0
}
652
653
654
ERR Gray32Fixed_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
655
0
{
656
0
    const I32 iHeight = pRect->Height;
657
0
    const I32 iWidth = pRect->Width;
658
0
    const float fltCvtFactor = 1.0F / (1 << 24);
659
0
    I32 y;
660
661
0
    UNREFERENCED_PARAMETER( pFC );
662
663
0
    for (y = 0; y < iHeight; y++)
664
0
    {
665
0
        I32 x;
666
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
667
0
        const I32 *piSrcPixel = (I32*)pfltDstPixel;
668
669
0
        for (x = 0; x < iWidth; x++)
670
0
            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
671
0
    }
672
    
673
0
    return WMP_errSuccess;
674
0
}
675
676
677
ERR Gray32Float_Gray32Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
678
0
{
679
0
    const I32 iHeight = pRect->Height;
680
0
    const I32 iWidth = pRect->Width;
681
0
    const float fltCvtFactor = (float) (1 << 24);
682
0
    I32 y;
683
684
0
    UNREFERENCED_PARAMETER( pFC );
685
686
0
    for (y = 0; y < iHeight; y++)
687
0
    {
688
0
        I32 x;
689
0
        I32 *piDstPixel = (I32*)(pb + cbStride*y);
690
0
        const float *pfltSrcPixel = (float*)piDstPixel;
691
692
0
        for (x = 0; x < iWidth; x++)
693
0
            piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
694
0
    }
695
    
696
0
    return WMP_errSuccess;
697
0
}
698
699
700
701
ERR Gray16Fixed_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
702
0
{
703
0
    const I32 iHeight = pRect->Height;
704
0
    const I32 iWidth = pRect->Width;
705
0
    const float fltCvtFactor = 1.0F / (1 << 13);
706
0
    I32 y;
707
708
0
    UNREFERENCED_PARAMETER( pFC );
709
710
    // Stride is assumed to be same for src/dst
711
0
    for (y = iHeight - 1; y >= 0; y--)
712
0
    {
713
0
        I32 x;
714
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
715
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
716
717
0
        for (x = iWidth - 1; x >= 0; x--)
718
0
            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
719
0
    }
720
    
721
0
    return WMP_errSuccess;
722
0
}
723
724
725
ERR Gray32Float_Gray16Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
726
0
{
727
0
    const I32 iHeight = pRect->Height;
728
0
    const I32 iWidth = pRect->Width;
729
0
    const float fltCvtFactor = (float) (1 << 13);
730
0
    I32 y;
731
732
0
    UNREFERENCED_PARAMETER( pFC );
733
734
    // Stride is assumed to be same for src/dst
735
0
    for (y = 0; y < iHeight; y++)
736
0
    {
737
0
        I32 x;
738
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
739
0
        const float *pfltSrcPixel = (float*)piDstPixel;
740
741
0
        for (x = 0; x < iWidth; x++)
742
0
            piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
743
0
    }
744
    
745
0
    return WMP_errSuccess;
746
0
}
747
748
749
ERR RGB48Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
750
0
{
751
0
    const I32 iHeight = pRect->Height;
752
0
    const I32 iWidthX3 = 3 * pRect->Width;
753
0
    const float fltCvtFactor = 1.0F / (1 << 13);
754
0
    I32 y;
755
756
0
    UNREFERENCED_PARAMETER( pFC );
757
758
    // Stride is assumed to be same for src/dst
759
0
    for (y = iHeight - 1; y >= 0; y--)
760
0
    {
761
0
        I32 x;
762
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
763
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
764
765
0
        for (x = iWidthX3 - 1; x >= 0; x--)
766
0
            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
767
0
    }
768
    
769
0
    return WMP_errSuccess;
770
0
}
771
772
773
ERR RGB96Float_RGB48Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
774
0
{
775
0
    const I32 iHeight = pRect->Height;
776
0
    const I32 iWidthX3 = 3 * pRect->Width;
777
0
    const float fltCvtFactor = (float)(1 << 13);
778
0
    I32 y;
779
780
0
    UNREFERENCED_PARAMETER( pFC );
781
782
    // Stride is assumed to be same for src/dst
783
0
    for (y = 0; y < iHeight; y++)
784
0
    {
785
0
        I32 x;
786
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
787
0
        const float *pfltSrcPixel = (float*)piDstPixel;
788
789
0
        for (x = 0; x < iWidthX3; x++)
790
0
            piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
791
0
    }
792
    
793
0
    return WMP_errSuccess;
794
0
}
795
796
797
ERR RGB64Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
798
0
{
799
0
    const I32 iHeight = pRect->Height;
800
0
    const I32 iWidth = pRect->Width;
801
0
    const float fltCvtFactor = 1.0F / (1 << 13);
802
0
    I32 y;
803
804
0
    UNREFERENCED_PARAMETER( pFC );
805
806
    // Stride is assumed to be same for src/dst
807
0
    for (y = iHeight - 1; y >= 0; y--)
808
0
    {
809
0
        I32 x;
810
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
811
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
812
813
0
        for (x = iWidth - 1; x >= 0; x--)
814
0
        {
815
0
            pfltDstPixel[3*x] = piSrcPixel[4*x] * fltCvtFactor;
816
0
            pfltDstPixel[3*x+1] = piSrcPixel[4*x+1] * fltCvtFactor;
817
0
            pfltDstPixel[3*x+2] = piSrcPixel[4*x+2] * fltCvtFactor;
818
0
        }
819
0
    }
820
    
821
0
    return WMP_errSuccess;
822
0
}
823
824
825
ERR RGB96Float_RGB64Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
826
0
{
827
0
    const I32 iHeight = pRect->Height;
828
0
    const I32 iWidth = pRect->Width;
829
0
    const float fltCvtFactor = (float)(1 << 13);
830
0
    I32 y;
831
832
0
    UNREFERENCED_PARAMETER( pFC );
833
834
    // Stride is assumed to be same for src/dst
835
0
    for (y = 0; y < iHeight; y++)
836
0
    {
837
0
        I32 x;
838
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
839
0
        const float *pfltSrcPixel = (float*)piDstPixel;
840
841
0
        for (x = 0; x < iWidth; x++)
842
0
        {
843
0
            piDstPixel[4*x] = (I16)(pfltSrcPixel[3*x] * fltCvtFactor + 0.5F);
844
0
            piDstPixel[4*x+1] = (I16)(pfltSrcPixel[3*x+1] * fltCvtFactor + 0.5F);
845
0
            piDstPixel[4*x+2] = (I16)(pfltSrcPixel[3*x+2] * fltCvtFactor + 0.5F);
846
0
            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
847
0
        }
848
0
    }
849
    
850
0
    return WMP_errSuccess;
851
0
}
852
853
854
ERR RGBA64Fixed_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
855
0
{
856
0
    const I32 iHeight = pRect->Height;
857
0
    const I32 iWidthX4 = 4 * pRect->Width;
858
0
    const float fltCvtFactor = 1.0F / (1 << 13);
859
0
    I32 y;
860
861
0
    UNREFERENCED_PARAMETER( pFC );
862
863
    // Stride is assumed to be same for src/dst
864
0
    for (y = iHeight - 1; y >= 0; y--)
865
0
    {
866
0
        I32 x;
867
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
868
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
869
870
0
        for (x = iWidthX4 - 1; x >= 0; x--)
871
0
            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
872
0
    }
873
    
874
0
    return WMP_errSuccess;
875
0
}
876
877
878
879
ERR RGBA128Float_RGBA64Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
880
0
{
881
0
    const I32 iHeight = pRect->Height;
882
0
    const I32 iWidthX4 = 4 * pRect->Width;
883
0
    const float fltCvtFactor = (float)(1 << 13);
884
0
    I32 y;
885
886
0
    UNREFERENCED_PARAMETER( pFC );
887
888
    // Stride is assumed to be same for src/dst
889
0
    for (y = 0; y < iHeight; y++)
890
0
    {
891
0
        I32 x;
892
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
893
0
        const float *pfltSrcPixel = (float*)piDstPixel;
894
895
0
        for (x = 0; x < iWidthX4; x++)
896
0
            piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
897
0
    }
898
    
899
0
    return WMP_errSuccess;
900
0
}
901
902
903
904
ERR RGBE_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
905
0
{
906
0
    const I32 iHeight = pRect->Height;
907
0
    const I32 iWidth = pRect->Width;
908
0
    I32 y;
909
910
0
    UNREFERENCED_PARAMETER( pFC );
911
912
    // Stride is assumed to be same for src/dst
913
0
    for (y = iHeight - 1; y >= 0; y--)
914
0
    {
915
0
        I32 x;
916
0
        float *pfltDstPixel = (float*)(pb + cbStride*y);
917
0
        const U8 *piSrcPixel = (U8*)pfltDstPixel;
918
919
0
        for (x = iWidth - 1; x >= 0; x--)
920
0
        {
921
            // First read the exponent
922
0
            const U8 rawExp = piSrcPixel[4*x+3];
923
924
0
            if (0 == rawExp)
925
0
            {
926
0
                pfltDstPixel[3*x] = 0.0F;
927
0
                pfltDstPixel[3*x+1] = 0.0F;
928
0
                pfltDstPixel[3*x+2] = 0.0F;
929
0
            }
930
0
            else
931
0
            {
932
0
                const I32 adjExp = (I32)rawExp - 128 - 8; // Can be negative
933
0
                float fltExp;
934
935
0
                if (adjExp > -32 && adjExp < 32)
936
0
                {
937
0
                    fltExp = (float) (((U32)1) << abs(adjExp));
938
0
                    if (adjExp < 0)
939
0
                        fltExp = 1.0F / fltExp;
940
0
                }
941
0
                else
942
0
                {
943
0
                    fltExp = (float)ldexp(1.0F, adjExp);
944
0
                }
945
946
0
                pfltDstPixel[3*x] = piSrcPixel[4*x] * fltExp;
947
0
                pfltDstPixel[3*x + 1] = piSrcPixel[4*x + 1] * fltExp;
948
0
                pfltDstPixel[3*x + 2] = piSrcPixel[4*x + 2] * fltExp;
949
0
            }
950
0
        }
951
0
    }
952
    
953
0
    return WMP_errSuccess;
954
0
}
955
956
957
ERR RGB96Float_RGBE(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
958
0
{
959
0
    const I32 iHeight = pRect->Height;
960
0
    const I32 iWidth = pRect->Width;
961
0
    I32 y;
962
963
0
    UNREFERENCED_PARAMETER( pFC );
964
965
0
    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
966
967
    // Stride is assumed to be same for src/dst
968
0
    for (y = 0; y < iHeight; y++)
969
0
    {
970
0
        I32 x;
971
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
972
0
        const float *pfltSrcPixel = (float*)piDstPixel;
973
974
0
        for (x = 0; x < iWidth; x++)
975
0
        {
976
            // We clamp source RGB values at zero (don't allow negative numbers)
977
0
            const float fltRed = max(pfltSrcPixel[3*x], 0.0F);
978
0
            const float fltGreen = max(pfltSrcPixel[3*x+1], 0.0F);
979
0
            const float fltBlue = max(pfltSrcPixel[3*x+2], 0.0F);
980
0
            float fltMaxPos = fltRed;
981
982
0
            if (fltGreen > fltMaxPos)
983
0
                fltMaxPos = fltGreen;
984
985
0
            if (fltBlue > fltMaxPos)
986
0
                fltMaxPos = fltBlue;
987
988
0
            if (fltMaxPos < 1e-32)
989
0
            {
990
0
                piDstPixel[4*x] = 0;    // R
991
0
                piDstPixel[4*x+1] = 0;  // G
992
0
                piDstPixel[4*x+2] = 0;  // B
993
0
                piDstPixel[4*x+3] = 0;  // E
994
0
            }
995
0
            else
996
0
            {
997
0
                int e;
998
0
                const float fltScale = (float)frexp(fltMaxPos, &e) * 256 / fltMaxPos;
999
1000
                // rounding SHOULD NOT be added - it has the potential to roll over to zero (and yes, 256 is the correct multiplier above)
1001
0
                piDstPixel[4*x] = (U8)(fltRed * fltScale);       // R
1002
0
                piDstPixel[4*x+1] = (U8)(fltGreen * fltScale);   // G
1003
0
                piDstPixel[4*x+2] = (U8)(fltBlue * fltScale);    // B
1004
0
                piDstPixel[4*x+3] = (U8)(e + 128);               // E
1005
0
            }
1006
0
        }
1007
0
    }
1008
    
1009
0
    return WMP_errSuccess;
1010
0
}
1011
1012
1013
ERR RGBA64Half_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1014
0
{
1015
0
    const I32 iHeight = pRect->Height;
1016
0
    const I32 iWidthX4 = 4 * pRect->Width;
1017
0
    I32 y;
1018
1019
0
    UNREFERENCED_PARAMETER( pFC );
1020
1021
    // Stride is assumed to be same for src/dst
1022
0
    for (y = iHeight - 1; y >= 0; y--)
1023
0
    {
1024
0
        I32 x;
1025
0
        U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr
1026
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
1027
1028
0
        for (x = iWidthX4 - 1; x >= 0; x--)
1029
0
            pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]);
1030
0
    }
1031
    
1032
0
    return WMP_errSuccess;
1033
0
}
1034
1035
1036
ERR RGBA128Float_RGBA64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1037
0
{
1038
0
    const I32 iHeight = pRect->Height;
1039
0
    const I32 iWidthX4 = 4 * pRect->Width;
1040
0
    I32 y;
1041
1042
0
    UNREFERENCED_PARAMETER( pFC );
1043
1044
    // Stride is assumed to be same for src/dst
1045
0
    for (y = 0; y < iHeight; y++)
1046
0
    {
1047
0
        I32 x;
1048
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
1049
0
        const float *pfltSrcPixel = (float*)piDstPixel;
1050
1051
0
        for (x = 0; x < iWidthX4; x++)
1052
0
            piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]);
1053
0
    }
1054
    
1055
0
    return WMP_errSuccess;
1056
0
}
1057
1058
1059
ERR RGB64Half_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1060
0
{
1061
0
    const I32 iHeight = pRect->Height;
1062
0
    const I32 iWidth = pRect->Width;
1063
0
    I32 y;
1064
1065
0
    UNREFERENCED_PARAMETER( pFC );
1066
1067
    // Stride is assumed to be same for src/dst
1068
0
    for (y = iHeight - 1; y >= 0; y--)
1069
0
    {
1070
0
        I32 x;
1071
0
        U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr
1072
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
1073
1074
0
        for (x = iWidth - 1; x >= 0; x--)
1075
0
        {
1076
0
            pfltDstPixel[3*x] = Convert_Half_To_Float(piSrcPixel[4*x]);
1077
0
            pfltDstPixel[3*x+1] = Convert_Half_To_Float(piSrcPixel[4*x+1]);
1078
0
            pfltDstPixel[3*x+2] = Convert_Half_To_Float(piSrcPixel[4*x+2]);
1079
0
        }
1080
0
    }
1081
    
1082
0
    return WMP_errSuccess;
1083
0
}
1084
1085
1086
ERR RGB96Float_RGB64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1087
0
{
1088
0
    const I32 iHeight = pRect->Height;
1089
0
    const I32 iWidth = pRect->Width;
1090
0
    I32 y;
1091
1092
0
    UNREFERENCED_PARAMETER( pFC );
1093
1094
    // Stride is assumed to be same for src/dst
1095
0
    for (y = 0; y < iHeight; y++)
1096
0
    {
1097
0
        I32 x;
1098
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
1099
0
        const float *pfltSrcPixel = (float*)piDstPixel;
1100
1101
0
        for (x = 0; x < iWidth; x++)
1102
0
        {
1103
0
            piDstPixel[4*x] = Convert_Float_To_Half(pfltSrcPixel[3*x]);
1104
0
            piDstPixel[4*x+1] = Convert_Float_To_Half(pfltSrcPixel[3*x+1]);
1105
0
            piDstPixel[4*x+2] = Convert_Float_To_Half(pfltSrcPixel[3*x+2]);
1106
0
            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
1107
0
        }
1108
0
    }
1109
    
1110
0
    return WMP_errSuccess;
1111
0
}
1112
1113
1114
ERR RGB48Half_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1115
0
{
1116
0
    const I32 iHeight = pRect->Height;
1117
0
    const I32 iWidthX3 = 3*pRect->Width;
1118
0
    I32 y;
1119
1120
0
    UNREFERENCED_PARAMETER( pFC );
1121
1122
    // Stride is assumed to be same for src/dst
1123
0
    for (y = iHeight - 1; y >= 0; y--)
1124
0
    {
1125
0
        I32 x;
1126
0
        U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr
1127
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
1128
1129
0
        for (x = iWidthX3 - 1; x >= 0; x--)
1130
0
            pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]);
1131
0
    }
1132
    
1133
0
    return WMP_errSuccess;
1134
0
}
1135
1136
1137
ERR RGB96Float_RGB48Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1138
0
{
1139
0
    const I32 iHeight = pRect->Height;
1140
0
    const I32 iWidthX3 = 3*pRect->Width;
1141
0
    I32 y;
1142
1143
0
    UNREFERENCED_PARAMETER( pFC );
1144
1145
    // Stride is assumed to be same for src/dst
1146
0
    for (y = 0; y < iHeight; y++)
1147
0
    {
1148
0
        I32 x;
1149
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
1150
0
        const float *pfltSrcPixel = (float*)piDstPixel;
1151
1152
0
        for (x = 0; x < iWidthX3; x++)
1153
0
            piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]);
1154
0
    }
1155
    
1156
0
    return WMP_errSuccess;
1157
0
}
1158
1159
1160
ERR Gray16Half_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1161
0
{
1162
0
    const I32 iHeight = pRect->Height;
1163
0
    const I32 iWidth = pRect->Width;
1164
0
    I32 y;
1165
1166
0
    UNREFERENCED_PARAMETER( pFC );
1167
1168
    // Stride is assumed to be same for src/dst
1169
0
    for (y = iHeight - 1; y >= 0; y--)
1170
0
    {
1171
0
        I32 x;
1172
0
        U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr
1173
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
1174
1175
0
        for (x = iWidth - 1; x >= 0; x--)
1176
0
            pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]);
1177
0
    }
1178
    
1179
0
    return WMP_errSuccess;
1180
0
}
1181
1182
1183
ERR Gray32Float_Gray16Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1184
0
{
1185
0
    const I32 iHeight = pRect->Height;
1186
0
    const I32 iWidth = pRect->Width;
1187
0
    I32 y;
1188
1189
0
    UNREFERENCED_PARAMETER( pFC );
1190
1191
    // Stride is assumed to be same for src/dst
1192
0
    for (y = 0; y < iHeight; y++)
1193
0
    {
1194
0
        I32 x;
1195
0
        I16 *piDstPixel = (I16*)(pb + cbStride*y);
1196
0
        const float *pfltSrcPixel = (float*)piDstPixel;
1197
1198
0
        for (x = 0; x < iWidth; x++)
1199
0
            piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]);
1200
0
    }
1201
    
1202
0
    return WMP_errSuccess;
1203
0
}
1204
1205
ERR RGB555_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1206
0
{
1207
0
    const I32 iHeight = pRect->Height;
1208
0
    const I32 iWidth = pRect->Width;
1209
0
    I32 y;
1210
1211
0
    UNREFERENCED_PARAMETER( pFC );
1212
1213
    // Stride is assumed to be same for src/dst
1214
0
    for (y = iHeight - 1; y >= 0; y--)
1215
0
    {
1216
0
        I32 x;
1217
0
        U8 *piDstPixel = (pb + cbStride*y);
1218
0
        const U16 *piSrcPixel = (U16*)piDstPixel;
1219
1220
0
        for (x = iWidth - 1; x >= 0; x--)
1221
0
        {
1222
0
            const U16 v = piSrcPixel[x];
1223
0
            const unsigned int r = ((v >> 10) & 0x1f);
1224
0
            const unsigned int g = ((v >> 5) & 0x1f);
1225
0
            const unsigned int b = (v & 0x1f);
1226
1227
0
            piDstPixel[3*x] = (U8)(r << 3);    // R
1228
0
            piDstPixel[3*x+1] = (U8)(g << 3);  // G
1229
0
            piDstPixel[3*x+2] = (U8)(b << 3);  // B
1230
0
        }
1231
0
    }
1232
    
1233
0
    return WMP_errSuccess;
1234
0
}
1235
1236
1237
ERR RGB101010_RGB48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1238
0
{
1239
0
    const I32 iHeight = pRect->Height;
1240
0
    const I32 iWidth = pRect->Width;
1241
0
    I32 y;
1242
1243
0
    UNREFERENCED_PARAMETER( pFC );
1244
1245
    // Stride is assumed to be same for src/dst
1246
0
    for (y = iHeight - 1; y >= 0; y--)
1247
0
    {
1248
0
        I32 x;
1249
0
        U16 *piDstPixel = (U16*)(pb + cbStride*y);
1250
0
        const U32 *piSrcPixel = (U32*)piDstPixel;
1251
1252
0
        for (x = iWidth - 1; x >= 0; x--)
1253
0
        {
1254
0
            const U32 v = piSrcPixel[x];
1255
0
            const unsigned int r = ((v >> 20) & 0x3FF);
1256
0
            const unsigned int g = ((v >> 10) & 0x3FF);
1257
0
            const unsigned int b = (v & 0x3FF);
1258
1259
0
            piDstPixel[3*x] = (U16)(r << 6);    // R
1260
0
            piDstPixel[3*x+1] = (U16)(g << 6);  // G
1261
0
            piDstPixel[3*x+2] = (U16)(b << 6);  // B
1262
0
        }
1263
0
    }
1264
    
1265
0
    return WMP_errSuccess;
1266
0
}
1267
1268
1269
ERR RGB24_RGB555(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1270
0
{
1271
0
    const I32 iHeight = pRect->Height;
1272
0
    const I32 iWidth = pRect->Width;
1273
0
    I32 y;
1274
1275
0
    UNREFERENCED_PARAMETER( pFC );
1276
1277
    // Stride is assumed to be same for src/dst
1278
0
    for (y = 0; y < iHeight; y++)
1279
0
    {
1280
0
        I32 x;
1281
0
        U16 *piDstPixel = (U16*)(pb + cbStride*y);
1282
0
        const U8 *piSrcPixel = (U8*)piDstPixel;
1283
1284
0
        for (x = 0; x < iWidth; x++)
1285
0
        {
1286
0
            const unsigned int r = piSrcPixel[3*x];
1287
0
            const unsigned int g = piSrcPixel[3*x+1];
1288
0
            const unsigned int b = piSrcPixel[3*x+2];
1289
1290
0
            piDstPixel[x] = (U16) (
1291
0
                            ((r & 0xF8) << 7) |
1292
0
                            ((g & 0xF8) << 2) |
1293
0
                             (b >> 3));
1294
0
        }
1295
0
    }
1296
1297
0
    return WMP_errSuccess;
1298
0
}
1299
1300
1301
1302
ERR RGB48_RGB101010(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1303
0
{
1304
0
    const I32 iHeight = pRect->Height;
1305
0
    const I32 iWidth = pRect->Width;
1306
0
    I32 y;
1307
1308
0
    UNREFERENCED_PARAMETER( pFC );
1309
1310
    // Stride is assumed to be same for src/dst
1311
0
    for (y = 0; y < iHeight; y++)
1312
0
    {
1313
0
        I32 x;
1314
0
        U32 *piDstPixel = (U32*)(pb + cbStride*y);
1315
0
        const U16 *piSrcPixel = (U16*)piDstPixel;
1316
1317
0
        for (x = 0; x < iWidth; x++)
1318
0
        {
1319
0
            const unsigned int r = piSrcPixel[3*x];
1320
0
            const unsigned int g = piSrcPixel[3*x+1];
1321
0
            const unsigned int b = piSrcPixel[3*x+2];
1322
1323
0
            piDstPixel[x] = (3 << 30) | // For compatibility with D3D's 2-10-10-10 format.
1324
0
                            ((r & 0x0000FFC0) << 14) |
1325
0
                            ((g & 0x0000FFC0) << 4) |
1326
0
                             (b >> 6);
1327
0
        }
1328
0
    }
1329
1330
0
    return WMP_errSuccess;
1331
0
}
1332
1333
1334
1335
ERR RGB565_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1336
0
{
1337
0
    const I32 iHeight = pRect->Height;
1338
0
    const I32 iWidth = pRect->Width;
1339
0
    I32 y;
1340
1341
0
    UNREFERENCED_PARAMETER( pFC );
1342
1343
    // Stride is assumed to be same for src/dst
1344
0
    for (y = iHeight - 1; y >= 0; y--)
1345
0
    {
1346
0
        I32 x;
1347
0
        U8 *piDstPixel = (pb + cbStride*y);
1348
0
        const U16 *piSrcPixel = (U16*)piDstPixel;
1349
1350
0
        for (x = iWidth - 1; x >= 0; x--)
1351
0
        {
1352
0
            const U16 v = piSrcPixel[x];
1353
0
            const unsigned int r = ((v >> 11) & 0x1f);
1354
0
            const unsigned int g = ((v >> 5) & 0x3f);
1355
0
            const unsigned int b = (v & 0x1f);
1356
1357
0
            piDstPixel[3*x] = (U8)(r << 3);    // R
1358
0
            piDstPixel[3*x+1] = (U8)(g << 2);  // G
1359
0
            piDstPixel[3*x+2] = (U8)(b << 3);  // B
1360
0
        }
1361
0
    }
1362
    
1363
0
    return WMP_errSuccess;
1364
0
}
1365
1366
1367
1368
ERR RGB24_RGB565(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1369
0
{
1370
0
    const I32 iHeight = pRect->Height;
1371
0
    const I32 iWidth = pRect->Width;
1372
0
    I32 y;
1373
1374
0
    UNREFERENCED_PARAMETER( pFC );
1375
1376
    // Stride is assumed to be same for src/dst
1377
0
    for (y = 0; y < iHeight; y++)
1378
0
    {
1379
0
        I32 x;
1380
0
        U16 *piDstPixel = (U16*)(pb + cbStride*y);
1381
0
        const U8 *piSrcPixel = (U8*)piDstPixel;
1382
1383
0
        for (x = 0; x < iWidth; x++)
1384
0
        {
1385
0
            const unsigned int r = piSrcPixel[3*x];
1386
0
            const unsigned int g = piSrcPixel[3*x+1];
1387
0
            const unsigned int b = piSrcPixel[3*x+2];
1388
1389
0
            piDstPixel[x] = (U16) (
1390
0
                            ((r & 0xF8) << 8) |
1391
0
                            ((g & 0xFC) << 3) |
1392
0
                             (b >> 3));
1393
0
        }
1394
0
    }
1395
1396
0
    return WMP_errSuccess;
1397
0
}
1398
1399
1400
ERR RGBA32_BGRA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1401
0
{
1402
0
    const I32 iHeight = pRect->Height;
1403
0
    const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A
1404
0
    I32 y;
1405
1406
0
    UNREFERENCED_PARAMETER( pFC );
1407
1408
0
    for (y = 0; y < iHeight; y++)
1409
0
    {
1410
0
        I32 x;
1411
0
        U8 *piPixel = (U8*)(pb + cbStride*y);
1412
1413
0
        for (x = 0; x < iWidthX4; x += 4)
1414
0
        {
1415
            // Swap R and B
1416
0
            U8 bTemp = piPixel[x];
1417
0
            piPixel[x] = piPixel[x+2];
1418
0
            piPixel[x+2] = bTemp;
1419
0
        }
1420
0
    }
1421
    
1422
0
    return WMP_errSuccess;
1423
0
}
1424
1425
1426
ERR BGRA32_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1427
0
{
1428
0
    return RGBA32_BGRA32(pFC, pRect, pb, cbStride);
1429
0
}
1430
1431
1432
ERR BlackWhite_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1433
0
{
1434
0
    const I32 iHeight = pRect->Height;
1435
0
    const I32 iWidth = pRect->Width;
1436
0
  Bool bBlackWhite = pFC->pDecoder->WMP.wmiSCP.bBlackWhite;
1437
0
    I32 y;
1438
1439
    // Stride is assumed to be same for src/dst
1440
0
    for (y = iHeight - 1; y >= 0; y--)
1441
0
    {
1442
0
        I32 x;
1443
0
    I32 n;
1444
0
        U8 *piDstPixel = (pb + cbStride*y);
1445
0
        const U8 *piSrcPixel = (U8*)piDstPixel;
1446
1447
0
    if (iWidth % 8 != 0)
1448
0
    {
1449
0
      const U8 v = piSrcPixel[iWidth / 8];
1450
1451
0
      for (n = 0; n < iWidth % 8; n++)
1452
0
      {
1453
0
        piDstPixel[iWidth/8*8+n] = (((v >> (7 - n)) & 0x1) != 0) ^ bBlackWhite ? 0xFF : 0x00;
1454
0
      }
1455
0
    }
1456
1457
0
        for (x = iWidth / 8 - 1; x >= 0; x--)
1458
0
        {
1459
0
            const U8 v = piSrcPixel[x];
1460
1461
0
      for (n = 0; n < 8; n++)
1462
0
      {
1463
0
                piDstPixel[8*x+n] = (((v >> (7 - n)) & 0x1) != 0) ^ bBlackWhite ? 0xFF : 0x00;
1464
0
      }
1465
0
        }
1466
0
    }
1467
    
1468
0
    return WMP_errSuccess;
1469
0
}
1470
1471
1472
ERR Gray16_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1473
0
{
1474
0
    I32 i = 0, j = 0;
1475
1476
0
    UNREFERENCED_PARAMETER( pFC );
1477
    
1478
0
    for (i = 0; i < pRect->Height; ++i)
1479
0
    {
1480
0
        for (j = 0; j < pRect->Width; ++j)
1481
0
        {
1482
0
            U16 v = ((U16*)pb)[j];
1483
            
1484
0
            pb[j] = v >> 8;
1485
0
        }
1486
1487
0
        pb += cbStride;
1488
0
    }
1489
1490
0
    return WMP_errSuccess;
1491
0
}
1492
1493
ERR RGB48_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1494
0
{
1495
0
    const I32 iHeight = pRect->Height;
1496
0
    const I32 iWidth = pRect->Width;
1497
0
    I32 y;
1498
1499
0
    UNREFERENCED_PARAMETER( pFC );
1500
1501
    // Stride is assumed to be same for src/dst
1502
0
    for (y = 0; y < iHeight; y++)
1503
0
    {
1504
0
        I32 x;
1505
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1506
0
        const U16 *piSrcPixel = (U16*)piDstPixel;
1507
1508
0
        for (x = 0; x < iWidth; x++)
1509
0
        {
1510
0
            const U16 r = piSrcPixel[3*x];
1511
0
            const U16 g = piSrcPixel[3*x+1];
1512
0
            const U16 b = piSrcPixel[3*x+2];
1513
1514
0
            piDstPixel[3*x] = r >> 8;
1515
0
            piDstPixel[3*x+1] = g >> 8;
1516
0
            piDstPixel[3*x+2] = b >> 8;
1517
0
        }
1518
0
    }
1519
1520
0
    return WMP_errSuccess;
1521
0
}
1522
1523
ERR RGBA64_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1524
0
{
1525
0
    const I32 iHeight = pRect->Height;
1526
0
    const I32 iWidth = pRect->Width;
1527
0
    I32 y;
1528
1529
0
    UNREFERENCED_PARAMETER( pFC );
1530
1531
    // Stride is assumed to be same for src/dst
1532
0
    for (y = 0; y < iHeight; y++)
1533
0
    {
1534
0
        I32 x;
1535
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1536
0
        const U16 *piSrcPixel = (U16*)piDstPixel;
1537
1538
0
        for (x = 0; x < iWidth; x++)
1539
0
        {
1540
0
            const U16 r = piSrcPixel[4*x];
1541
0
            const U16 g = piSrcPixel[4*x+1];
1542
0
            const U16 b = piSrcPixel[4*x+2];
1543
0
            const U16 a = piSrcPixel[4*x+3];
1544
1545
0
            piDstPixel[4*x] = r >> 8;
1546
0
            piDstPixel[4*x+1] = g >> 8;
1547
0
            piDstPixel[4*x+2] = b >> 8;
1548
0
            piDstPixel[4*x+3] = a >> 8;
1549
0
        }
1550
0
    }
1551
1552
0
    return WMP_errSuccess;
1553
0
}
1554
1555
ERR Gray32Float_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1556
0
{
1557
0
    const I32 iHeight = pRect->Height;
1558
0
    const I32 iWidth = pRect->Width;
1559
0
    I32 y;
1560
1561
0
    UNREFERENCED_PARAMETER( pFC );
1562
1563
    // Stride is assumed to be same for src/dst
1564
0
    for (y = 0; y < iHeight; y++)
1565
0
    {
1566
0
        I32 x;
1567
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1568
0
        const float *piSrcPixel = (float*)piDstPixel;
1569
1570
0
        for (x = 0; x < iWidth; x++)
1571
0
        {
1572
0
            const float v = piSrcPixel[x];
1573
                
1574
0
            piDstPixel[x] = Convert_Float_To_U8(v);
1575
0
        }
1576
0
    }
1577
1578
0
    return WMP_errSuccess;
1579
0
}
1580
1581
ERR RGB96Float_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1582
0
{
1583
0
    const I32 iHeight = pRect->Height;
1584
0
    const I32 iWidth = pRect->Width;
1585
0
    I32 y;
1586
1587
0
    UNREFERENCED_PARAMETER( pFC );
1588
1589
    // Stride is assumed to be same for src/dst
1590
0
    for (y = 0; y < iHeight; y++)
1591
0
    {
1592
0
        I32 x;
1593
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1594
0
        const float *piSrcPixel = (float*)piDstPixel;
1595
1596
0
        for (x = 0; x < iWidth; x++)
1597
0
        {
1598
0
            const float r = piSrcPixel[3*x];
1599
0
            const float g = piSrcPixel[3*x+1];
1600
0
            const float b = piSrcPixel[3*x+2];
1601
                
1602
0
            piDstPixel[3*x] = Convert_Float_To_U8(r);
1603
0
            piDstPixel[3*x+1] = Convert_Float_To_U8(g);
1604
0
            piDstPixel[3*x+2] = Convert_Float_To_U8(b);
1605
0
        }
1606
0
    }
1607
1608
0
    return WMP_errSuccess;
1609
0
}
1610
1611
ERR RGB128Float_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1612
0
{
1613
0
    const I32 iHeight = pRect->Height;
1614
0
    const I32 iWidth = pRect->Width;
1615
0
    I32 y;
1616
1617
0
    UNREFERENCED_PARAMETER( pFC );
1618
1619
    // Stride is assumed to be same for src/dst
1620
0
    for (y = 0; y < iHeight; y++)
1621
0
    {
1622
0
        I32 x;
1623
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1624
0
        const float *piSrcPixel = (float*)piDstPixel;
1625
1626
0
        for (x = 0; x < iWidth; x++)
1627
0
        {
1628
0
            const float r = piSrcPixel[4*x];
1629
0
            const float g = piSrcPixel[4*x+1];
1630
0
            const float b = piSrcPixel[4*x+2];
1631
                
1632
0
            piDstPixel[3*x] = Convert_Float_To_U8(r);
1633
0
            piDstPixel[3*x+1] = Convert_Float_To_U8(g);
1634
0
            piDstPixel[3*x+2] = Convert_Float_To_U8(b);
1635
0
        }
1636
0
    }
1637
1638
0
    return WMP_errSuccess;
1639
0
}
1640
1641
ERR RGBA128Float_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1642
0
{
1643
0
    const I32 iHeight = pRect->Height;
1644
0
    const I32 iWidth = pRect->Width;
1645
0
    I32 y;
1646
1647
0
    UNREFERENCED_PARAMETER( pFC );
1648
1649
    // Stride is assumed to be same for src/dst
1650
0
    for (y = 0; y < iHeight; y++)
1651
0
    {
1652
0
        I32 x;
1653
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1654
0
        const float *piSrcPixel = (float*)piDstPixel;
1655
1656
0
        for (x = 0; x < iWidth; x++)
1657
0
        {
1658
0
            const float r = piSrcPixel[4*x];
1659
0
            const float g = piSrcPixel[4*x+1];
1660
0
            const float b = piSrcPixel[4*x+2];
1661
0
            const float a = piSrcPixel[4*x+3];
1662
                
1663
0
            piDstPixel[4*x] = Convert_Float_To_U8(r);
1664
0
            piDstPixel[4*x+1] = Convert_Float_To_U8(g);
1665
0
            piDstPixel[4*x+2] = Convert_Float_To_U8(b);
1666
0
            piDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(a);
1667
0
        }
1668
0
    }
1669
1670
0
    return WMP_errSuccess;
1671
0
}
1672
1673
ERR Gray16Fixed_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1674
0
{
1675
0
    const I32 iHeight = pRect->Height;
1676
0
    const I32 iWidth = pRect->Width;
1677
0
    const float fltCvtFactor = 1.0F / (1 << 13);
1678
0
    I32 y;
1679
1680
0
    UNREFERENCED_PARAMETER( pFC );
1681
1682
    // Stride is assumed to be same for src/dst
1683
0
    for (y = 0; y < iHeight; y++)
1684
0
    {
1685
0
        I32 x;
1686
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1687
0
        const I16 *piSrcPixel = (I16*)piDstPixel;
1688
1689
0
        for (x = 0; x < iWidth; x++)
1690
0
        {
1691
0
            piDstPixel[x] = Convert_Float_To_U8(piSrcPixel[x] * fltCvtFactor);
1692
0
        }
1693
0
    }
1694
1695
0
    return WMP_errSuccess;
1696
0
}
1697
1698
ERR Gray32Fixed_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1699
0
{
1700
0
    const I32 iHeight = pRect->Height;
1701
0
    const I32 iWidth = pRect->Width;
1702
0
    const float fltCvtFactor = 1.0F / (1 << 24);
1703
0
    I32 y;
1704
1705
0
    UNREFERENCED_PARAMETER( pFC );
1706
1707
    // Stride is assumed to be same for src/dst
1708
0
    for (y = 0; y < iHeight; y++)
1709
0
    {
1710
0
        I32 x;
1711
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1712
0
        const I32 *piSrcPixel = (I32*)piDstPixel;
1713
1714
0
        for (x = 0; x < iWidth; x++)
1715
0
        {
1716
0
            piDstPixel[x] = Convert_Float_To_U8(piSrcPixel[x] * fltCvtFactor);
1717
0
        }
1718
0
    }
1719
1720
0
    return WMP_errSuccess;
1721
0
}
1722
1723
ERR RGB48Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1724
0
{
1725
0
    const I32 iHeight = pRect->Height;
1726
0
    const I32 iWidth = pRect->Width;
1727
0
    const float fltCvtFactor = 1.0F / (1 << 13);
1728
0
    I32 y;
1729
1730
0
    UNREFERENCED_PARAMETER( pFC );
1731
1732
0
    for (y = 0; y < iHeight; y++)
1733
0
    {
1734
0
        I32 x;
1735
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1736
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
1737
1738
0
        for (x = 0; x < iWidth; x++)
1739
0
        {
1740
0
            pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[3*x] * fltCvtFactor);
1741
0
            pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[3*x+1] * fltCvtFactor);
1742
0
            pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[3*x+2] * fltCvtFactor);
1743
0
        }
1744
0
    }
1745
    
1746
0
    return WMP_errSuccess;
1747
0
}
1748
1749
ERR RGB64Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1750
0
{
1751
0
    const I32 iHeight = pRect->Height;
1752
0
    const I32 iWidth = pRect->Width;
1753
0
    const float fltCvtFactor = 1.0F / (1 << 13);
1754
0
    I32 y;
1755
1756
0
    UNREFERENCED_PARAMETER( pFC );
1757
1758
0
    for (y = 0; y < iHeight; y++)
1759
0
    {
1760
0
        I32 x;
1761
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1762
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
1763
1764
0
        for (x = 0; x < iWidth; x++)
1765
0
        {
1766
0
            pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor);
1767
0
            pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor);
1768
0
            pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor);
1769
0
        }
1770
0
    }
1771
    
1772
0
    return WMP_errSuccess;
1773
0
}
1774
1775
ERR RGB96Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1776
0
{
1777
0
    const I32 iHeight = pRect->Height;
1778
0
    const I32 iWidth = pRect->Width;
1779
0
    const float fltCvtFactor = 1.0F / (1 << 24);
1780
0
    I32 y;
1781
1782
0
    UNREFERENCED_PARAMETER( pFC );
1783
1784
0
    for (y = 0; y < iHeight; y++)
1785
0
    {
1786
0
        I32 x;
1787
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1788
0
        const I32 *piSrcPixel = (I32*)pfltDstPixel;
1789
1790
0
        for (x = 0; x < iWidth; x++)
1791
0
        {
1792
0
            pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[3*x] * fltCvtFactor);
1793
0
            pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[3*x+1] * fltCvtFactor);
1794
0
            pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[3*x+2] * fltCvtFactor);
1795
0
        }
1796
0
    }
1797
    
1798
0
    return WMP_errSuccess;
1799
0
}
1800
1801
ERR RGB128Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1802
0
{
1803
0
    const I32 iHeight = pRect->Height;
1804
0
    const I32 iWidth = pRect->Width;
1805
0
    const float fltCvtFactor = 1.0F / (1 << 24);
1806
0
    I32 y;
1807
1808
0
    UNREFERENCED_PARAMETER( pFC );
1809
1810
0
    for (y = 0; y < iHeight; y++)
1811
0
    {
1812
0
        I32 x;
1813
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1814
0
        const I32 *piSrcPixel = (I32*)pfltDstPixel;
1815
1816
0
        for (x = 0; x < iWidth; x++)
1817
0
        {
1818
0
            pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor);
1819
0
            pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor);
1820
0
            pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor);
1821
0
        }
1822
0
    }
1823
    
1824
0
    return WMP_errSuccess;
1825
0
}
1826
1827
ERR RGBA64Fixed_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1828
0
{
1829
0
    const I32 iHeight = pRect->Height;
1830
0
    const I32 iWidth = pRect->Width;
1831
0
    const float fltCvtFactor = 1.0F / (1 << 13);
1832
0
    I32 y;
1833
1834
0
    UNREFERENCED_PARAMETER( pFC );
1835
1836
0
    for (y = 0; y < iHeight; y++)
1837
0
    {
1838
0
        I32 x;
1839
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1840
0
        const I16 *piSrcPixel = (I16*)pfltDstPixel;
1841
1842
0
        for (x = 0; x < iWidth; x++)
1843
0
        {
1844
0
            pfltDstPixel[4*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor);
1845
0
            pfltDstPixel[4*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor);
1846
0
            pfltDstPixel[4*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor);
1847
0
            pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(piSrcPixel[4*x+3] * fltCvtFactor);
1848
0
        }
1849
0
    }
1850
    
1851
0
    return WMP_errSuccess;
1852
0
}
1853
1854
ERR RGBA128Fixed_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1855
0
{
1856
0
    const I32 iHeight = pRect->Height;
1857
0
    const I32 iWidth = pRect->Width;
1858
0
    const float fltCvtFactor = 1.0F / (1 << 24);
1859
0
    I32 y;
1860
1861
0
    UNREFERENCED_PARAMETER( pFC );
1862
1863
0
    for (y = 0; y < iHeight; y++)
1864
0
    {
1865
0
        I32 x;
1866
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1867
0
        const I32 *piSrcPixel = (I32*)pfltDstPixel;
1868
1869
0
        for (x = 0; x < iWidth; x++)
1870
0
        {
1871
0
            pfltDstPixel[4*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor);
1872
0
            pfltDstPixel[4*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor);
1873
0
            pfltDstPixel[4*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor);
1874
0
            pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(piSrcPixel[4*x+3] * fltCvtFactor);
1875
0
        }
1876
0
    }
1877
    
1878
0
    return WMP_errSuccess;
1879
0
}
1880
1881
ERR Gray16Half_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1882
0
{
1883
0
    const I32 iHeight = pRect->Height;
1884
0
    const I32 iWidth = pRect->Width;
1885
0
    I32 y;
1886
1887
0
    UNREFERENCED_PARAMETER( pFC );
1888
1889
    // Stride is assumed to be same for src/dst
1890
0
    for (y = 0; y < iHeight; y++)
1891
0
    {
1892
0
        I32 x;
1893
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
1894
0
        const U16 *piSrcPixel = (U16*)piDstPixel;
1895
1896
0
        for (x = 0; x < iWidth; x++)
1897
0
        {
1898
0
            const U32 v = Convert_Half_To_Float(piSrcPixel[x]);
1899
                
1900
0
            piDstPixel[x] = Convert_Float_To_U8(*(float*)&v);
1901
0
        }
1902
0
    }
1903
1904
0
    return WMP_errSuccess;
1905
0
}
1906
1907
ERR RGB48Half_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1908
0
{
1909
0
    const I32 iHeight = pRect->Height;
1910
0
    const I32 iWidth = pRect->Width;
1911
0
    I32 y;
1912
1913
0
    UNREFERENCED_PARAMETER( pFC );
1914
1915
0
    for (y = 0; y < iHeight; y++)
1916
0
    {
1917
0
        I32 x;
1918
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1919
0
        const U16 *piSrcPixel = (U16*)pfltDstPixel;
1920
1921
0
        for (x = 0; x < iWidth; x++)
1922
0
        {
1923
0
            const U32 r = Convert_Half_To_Float(piSrcPixel[3*x]);
1924
0
            const U32 g = Convert_Half_To_Float(piSrcPixel[3*x+1]);
1925
0
            const U32 b = Convert_Half_To_Float(piSrcPixel[3*x+2]);
1926
        
1927
0
            pfltDstPixel[3*x] = Convert_Float_To_U8(*(float*)&r);
1928
0
            pfltDstPixel[3*x+1] = Convert_Float_To_U8(*(float*)&g);
1929
0
            pfltDstPixel[3*x+2] = Convert_Float_To_U8(*(float*)&b);
1930
0
        }
1931
0
    }
1932
    
1933
0
    return WMP_errSuccess;
1934
0
}
1935
1936
ERR RGB64Half_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1937
0
{
1938
0
    const I32 iHeight = pRect->Height;
1939
0
    const I32 iWidth = pRect->Width;
1940
0
    I32 y;
1941
1942
0
    UNREFERENCED_PARAMETER( pFC );
1943
1944
0
    for (y = 0; y < iHeight; y++)
1945
0
    {
1946
0
        I32 x;
1947
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1948
0
        const U16 *piSrcPixel = (U16*)pfltDstPixel;
1949
1950
0
        for (x = 0; x < iWidth; x++)
1951
0
        {
1952
0
            const U32 r = Convert_Half_To_Float(piSrcPixel[4*x]);
1953
0
            const U32 g = Convert_Half_To_Float(piSrcPixel[4*x+1]);
1954
0
            const U32 b = Convert_Half_To_Float(piSrcPixel[4*x+2]);
1955
        
1956
0
            pfltDstPixel[3*x] = Convert_Float_To_U8(*(float*)&r);
1957
0
            pfltDstPixel[3*x+1] = Convert_Float_To_U8(*(float*)&g);
1958
0
            pfltDstPixel[3*x+2] = Convert_Float_To_U8(*(float*)&b);
1959
0
        }
1960
0
    }
1961
    
1962
0
    return WMP_errSuccess;
1963
0
}
1964
1965
ERR RGBA64Half_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1966
0
{
1967
0
    const I32 iHeight = pRect->Height;
1968
0
    const I32 iWidth = pRect->Width;
1969
0
    I32 y;
1970
1971
0
    UNREFERENCED_PARAMETER( pFC );
1972
1973
0
    for (y = 0; y < iHeight; y++)
1974
0
    {
1975
0
        I32 x;
1976
0
        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
1977
0
        const U16 *piSrcPixel = (U16*)pfltDstPixel;
1978
1979
0
        for (x = 0; x < iWidth; x++)
1980
0
        {
1981
0
            const U32 r = Convert_Half_To_Float(piSrcPixel[4*x]);
1982
0
            const U32 g = Convert_Half_To_Float(piSrcPixel[4*x+1]);
1983
0
            const U32 b = Convert_Half_To_Float(piSrcPixel[4*x+2]);
1984
0
            const U32 a = Convert_Half_To_Float(piSrcPixel[4*x+3]);
1985
        
1986
0
            pfltDstPixel[4*x] = Convert_Float_To_U8(*(float*)&r);
1987
0
            pfltDstPixel[4*x+1] = Convert_Float_To_U8(*(float*)&g);
1988
0
            pfltDstPixel[4*x+2] = Convert_Float_To_U8(*(float*)&b);
1989
0
            pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(*(float*)&a);
1990
0
        }
1991
0
    }
1992
    
1993
0
    return WMP_errSuccess;
1994
0
}
1995
1996
ERR RGB101010_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
1997
0
{
1998
0
    const I32 iHeight = pRect->Height;
1999
0
    const I32 iWidth = pRect->Width;
2000
0
    I32 y;
2001
2002
0
    UNREFERENCED_PARAMETER( pFC );
2003
2004
    // Stride is assumed to be same for src/dst
2005
0
    for (y = 0; y < iHeight; y++)
2006
0
    {
2007
0
        I32 x;
2008
0
        U8 *piDstPixel = (U8*)(pb + cbStride*y);
2009
0
        const U32 *piSrcPixel = (U32*)piDstPixel;
2010
2011
0
        for (x = 0; x < iWidth; x++)
2012
0
        {
2013
0
            const U32 v = piSrcPixel[x];
2014
0
            const unsigned int r = ((v >> 20) & 0x3FF);
2015
0
            const unsigned int g = ((v >> 10) & 0x3FF);
2016
0
            const unsigned int b = (v & 0x3FF);
2017
2018
0
            piDstPixel[3*x] = (U8) (r >> 2);
2019
0
            piDstPixel[3*x+1] = (U8) (g >> 2);
2020
0
            piDstPixel[3*x+2] = (U8) (b >> 2);
2021
0
        }
2022
0
    }
2023
2024
0
    return WMP_errSuccess;
2025
0
}
2026
2027
ERR RGBE_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
2028
0
{
2029
0
    I32 i = 0, j = 0;
2030
2031
0
    UNREFERENCED_PARAMETER( pFC );
2032
   
2033
0
    for (i = 0; i < pRect->Height; ++i)
2034
0
    {
2035
0
        for (j = 0; j < pRect->Width; j++)
2036
0
        {
2037
            // First read the exponent
2038
0
            const U8 rawExp = pb[4*j+3];
2039
2040
0
            if (0 == rawExp)
2041
0
            {
2042
0
                pb[3*j] = 0;
2043
0
                pb[3*j+1] = 0;
2044
0
                pb[3*j+2] = 0;
2045
0
            }
2046
0
            else
2047
0
            {
2048
0
                const I32 adjExp = (I32)rawExp - 128 - 8; // Can be negative
2049
0
                float fltExp;
2050
2051
0
                if (adjExp > -32 && adjExp < 32)
2052
0
                {
2053
0
                    fltExp = (float) (((U32)1) << abs(adjExp));
2054
0
                    if (adjExp < 0)
2055
0
                        fltExp = 1.0F / fltExp;
2056
0
                }
2057
0
                else
2058
0
                {
2059
0
                    fltExp = (float)ldexp(1.0F, adjExp);
2060
0
                }
2061
2062
0
                pb[3*j] = Convert_Float_To_U8(pb[4*j] * fltExp);
2063
0
                pb[3*j + 1] = Convert_Float_To_U8(pb[4*j + 1] * fltExp);
2064
0
                pb[3*j + 2] = Convert_Float_To_U8(pb[4*j + 2] * fltExp);
2065
0
            }
2066
0
        }
2067
2068
0
        pb += cbStride;
2069
0
    }
2070
2071
0
    return WMP_errSuccess;
2072
0
}
2073
2074
//================================================================
2075
typedef struct tagPKPixelConverterInfo
2076
{
2077
    const PKPixelFormatGUID* pGUIDPixFmtFrom;
2078
    const PKPixelFormatGUID* pGUIDPixFmtTo;
2079
2080
    ERR (*Convert)(PKFormatConverter*, const PKRect*, U8*, U32);
2081
} PKPixelConverterInfo;
2082
2083
static PKPixelConverterInfo s_pcInfo[] = {
2084
    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat24bppBGR, RGB24_BGR24}, // Fwd
2085
    {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat24bppRGB, BGR24_RGB24}, // Rev
2086
    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat32bppBGR, RGB24_BGR32}, // Fwd
2087
    {&GUID_PKPixelFormat32bppBGR, &GUID_PKPixelFormat24bppRGB, BGR32_RGB24}, // Rev
2088
2089
    // The following are not to be exposed when building the Adobe Photoshop plugin
2090
#ifndef ADOBE_PS_PLUGIN
2091
    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat8bppGray, RGB24_Gray8}, // Fwd
2092
    {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat24bppRGB, Gray8_RGB24}, // Rev
2093
    {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat8bppGray, BGR24_Gray8}, // Fwd
2094
    {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat24bppBGR, Gray8_BGR24}, // Rev
2095
#endif // ADOBE_PS_PLUGIN
2096
2097
    {&GUID_PKPixelFormat128bppRGBAFixedPoint, &GUID_PKPixelFormat128bppRGBAFloat, RGBA128Fixed_RGBA128Float}, // Fwd
2098
    {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat128bppRGBAFixedPoint, RGBA128Float_RGBA128Fixed}, // Rev
2099
    {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB96Fixed_RGB96Float}, // Fwd
2100
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat96bppRGBFixedPoint, RGB96Float_RGB96Fixed}, // Rev
2101
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat128bppRGBFloat, RGB96Float_RGB128Float}, // Fwd
2102
    {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat96bppRGBFloat, RGB128Float_RGB96Float}, // Rev
2103
    {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat128bppRGBFixedPoint, RGB96Float_RGB128Float}, // Fwd
2104
    {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFixedPoint, RGB128Float_RGB96Float}, // Rev
2105
    {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat48bppRGBHalf, RGB64Half_RGB48Half}, // Fwd
2106
    {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat64bppRGBHalf, RGB48Half_RGB64Half}, // Rev
2107
    {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat48bppRGBFixedPoint, RGB64Half_RGB48Half}, // Fwd
2108
    {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat64bppRGBFixedPoint, RGB48Half_RGB64Half}, // Rev
2109
    {&GUID_PKPixelFormat32bppBGR, &GUID_PKPixelFormat24bppBGR, BGR32_BGR24}, // Fwd
2110
    {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat32bppBGR, BGR24_BGR32}, // Rev
2111
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat128bppRGBFixedPoint, RGB96Float_RGB128Fixed}, // Fwd
2112
    {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB128Fixed_RGB96Float}, // Rev
2113
    {&GUID_PKPixelFormat32bppGrayFixedPoint, &GUID_PKPixelFormat32bppGrayFloat, Gray32Fixed_Gray32Float}, // Fwd
2114
    {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat32bppGrayFixedPoint, Gray32Float_Gray32Fixed}, // Rev
2115
    {&GUID_PKPixelFormat16bppGrayFixedPoint, &GUID_PKPixelFormat32bppGrayFloat, Gray16Fixed_Gray32Float}, // Fwd
2116
    {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat16bppGrayFixedPoint, Gray32Float_Gray16Fixed}, // Rev
2117
    {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB48Fixed_RGB96Float}, // Fwd
2118
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat48bppRGBFixedPoint, RGB96Float_RGB48Fixed}, // Rev
2119
    {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB64Fixed_RGB96Float}, // Fwd
2120
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat64bppRGBFixedPoint, RGB96Float_RGB64Fixed}, // Rev
2121
    {&GUID_PKPixelFormat64bppRGBAFixedPoint, &GUID_PKPixelFormat128bppRGBAFloat, RGBA64Fixed_RGBA128Float}, // Fwd
2122
    {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat64bppRGBAFixedPoint, RGBA128Float_RGBA64Fixed}, // Rev
2123
    {&GUID_PKPixelFormat32bppRGBE, &GUID_PKPixelFormat96bppRGBFloat, RGBE_RGB96Float}, // Fwd
2124
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat32bppRGBE, RGB96Float_RGBE}, // Rev
2125
    {&GUID_PKPixelFormat64bppRGBAHalf, &GUID_PKPixelFormat128bppRGBAFloat, RGBA64Half_RGBA128Float}, // Fwd
2126
    {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat64bppRGBAHalf, RGBA128Float_RGBA64Half}, // Rev
2127
    {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat96bppRGBFloat, RGB64Half_RGB96Float}, // Fwd
2128
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat64bppRGBHalf, RGB96Float_RGB64Half}, // Rev
2129
    {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat96bppRGBFloat, RGB48Half_RGB96Float}, // Fwd
2130
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat48bppRGBHalf, RGB96Float_RGB48Half}, // Rev
2131
    {&GUID_PKPixelFormat16bppGrayHalf, &GUID_PKPixelFormat32bppGrayFloat, Gray16Half_Gray32Float}, // Fwd
2132
    {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat16bppGrayHalf, Gray32Float_Gray16Half}, // Rev
2133
    {&GUID_PKPixelFormat16bppRGB555, &GUID_PKPixelFormat24bppRGB, RGB555_RGB24}, // Fwd
2134
    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat16bppRGB555, RGB24_RGB555}, // Rev
2135
    {&GUID_PKPixelFormat16bppRGB565, &GUID_PKPixelFormat24bppRGB, RGB565_RGB24}, // Fwd
2136
    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat16bppRGB565, RGB24_RGB565}, // Rev
2137
    {&GUID_PKPixelFormat32bppRGB101010, &GUID_PKPixelFormat48bppRGB, RGB101010_RGB48}, // Fwd
2138
    {&GUID_PKPixelFormat48bppRGB, &GUID_PKPixelFormat32bppRGB101010, RGB48_RGB101010}, // Rev
2139
    {&GUID_PKPixelFormat32bppRGBA, &GUID_PKPixelFormat32bppBGRA, RGBA32_BGRA32}, // Fwd
2140
    {&GUID_PKPixelFormat32bppBGRA, &GUID_PKPixelFormat32bppRGBA, BGRA32_RGBA32}, // Rev
2141
    {&GUID_PKPixelFormat32bppPRGBA, &GUID_PKPixelFormat32bppPBGRA, RGBA32_BGRA32}, // Fwd
2142
    {&GUID_PKPixelFormat32bppPBGRA, &GUID_PKPixelFormat32bppPRGBA, BGRA32_RGBA32}, // Rev
2143
2144
  // conversions to 8bppGray / 24bppRGB / 32bppRGBA
2145
  {&GUID_PKPixelFormatBlackWhite, &GUID_PKPixelFormat8bppGray, BlackWhite_Gray8},
2146
    {&GUID_PKPixelFormat16bppGray, &GUID_PKPixelFormat8bppGray, Gray16_Gray8},
2147
    {&GUID_PKPixelFormat48bppRGB, &GUID_PKPixelFormat24bppRGB, RGB48_RGB24},
2148
    {&GUID_PKPixelFormat64bppRGBA, &GUID_PKPixelFormat32bppRGBA, RGBA64_RGBA32},
2149
    {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat8bppGray, Gray32Float_Gray8},     
2150
    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat24bppRGB, RGB96Float_RGB24},
2151
    {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat24bppRGB, RGB128Float_RGB24},
2152
    {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat32bppRGBA, RGBA128Float_RGBA32},
2153
    {&GUID_PKPixelFormat16bppGrayFixedPoint, &GUID_PKPixelFormat8bppGray, Gray16Fixed_Gray8}, 
2154
    {&GUID_PKPixelFormat32bppGrayFixedPoint, &GUID_PKPixelFormat8bppGray, Gray32Fixed_Gray8},  
2155
    {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB48Fixed_RGB24},
2156
    {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB64Fixed_RGB24},
2157
    {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB96Fixed_RGB24},
2158
    {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB128Fixed_RGB24},   
2159
    {&GUID_PKPixelFormat64bppRGBAFixedPoint, &GUID_PKPixelFormat32bppRGBA, RGBA64Fixed_RGBA32},
2160
    {&GUID_PKPixelFormat128bppRGBAFixedPoint, &GUID_PKPixelFormat32bppRGBA, RGBA128Fixed_RGBA32},    
2161
    {&GUID_PKPixelFormat16bppGrayHalf, &GUID_PKPixelFormat8bppGray, Gray16Half_Gray8},     
2162
    {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat24bppRGB, RGB48Half_RGB24},
2163
    {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat24bppRGB, RGB64Half_RGB24},
2164
    {&GUID_PKPixelFormat64bppRGBAHalf, &GUID_PKPixelFormat32bppRGBA, RGBA64Half_RGBA32},
2165
    {&GUID_PKPixelFormat32bppRGB101010, &GUID_PKPixelFormat24bppRGB, RGB101010_RGB24},    
2166
    {&GUID_PKPixelFormat32bppRGBE, &GUID_PKPixelFormat24bppRGB, RGBE_RGB24}
2167
};
2168
2169
/* auxiliary data structure and hack to support valid encoding from/to configurations that 
2170
// don't actually require any color conversion. This is a conservative approach, where we
2171
// include as few formats as necessary to encode situations that we're currently aware of.
2172
*/
2173
typedef struct tagPKPixelConverter2Info
2174
{
2175
    const PKPixelFormatGUID* pGUIDPixFmtFrom;
2176
    const PKPixelFormatGUID* pGUIDPixFmtTo;
2177
2178
} PKPixelConverter2Info;
2179
2180
static PKPixelConverter2Info s_pcInfo2[] = {
2181
  // This allows us to view an RGBA input file as RGB, for when we create a planar alpha file
2182
  {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat128bppRGBAFloat},
2183
  // 16- and 32-bpp RGB input files are given the "DontCare" GUID, so the next three 
2184
  // from/to combinations are ok, and allowed on encoding: 
2185
  {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat16bppRGB555},
2186
  {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat16bppRGB565},
2187
  {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat32bppBGRA}
2188
};
2189
2190
ERR PKFormatConverter_Initialize(PKFormatConverter* pFC, PKImageDecode* pID, char *pExt, PKPixelFormatGUID enPF)
2191
0
{
2192
0
    ERR err;
2193
0
    PKPixelFormatGUID   enPFFrom;
2194
2195
0
    Call(pID->GetPixelFormat(pID, &enPFFrom));
2196
0
    Call(PKFormatConverter_InitializeConvert(pFC, enPFFrom, pExt, enPF));
2197
2198
0
    pFC->pDecoder = pID;
2199
2200
0
Cleanup:
2201
0
    return err;
2202
0
}
2203
2204
2205
extern int PKStrnicmp(const char* s1, const char* s2, size_t c);
2206
2207
ERR PKFormatConverter_InitializeConvert(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom,
2208
                                        char *pExt, PKPixelFormatGUID enPFTo)
2209
0
{
2210
0
    ERR err = WMP_errSuccess;
2211
2212
    //================================
2213
0
    pFC->enPixelFormat = enPFTo;
2214
2215
0
    if (pExt != NULL && IsEqualGUID(&enPFTo, &GUID_PKPixelFormat24bppRGB) &&
2216
0
        0 == PKStrnicmp(pExt, ".bmp", strlen(pExt)))
2217
0
        enPFTo = GUID_PKPixelFormat24bppBGR;
2218
0
    if (pExt != NULL && (0 == PKStrnicmp(pExt, ".tif", strlen(pExt)) || 0 == PKStrnicmp(pExt, ".tiff", strlen(pExt))))
2219
0
    {
2220
0
        if (IsEqualGUID(&enPFTo, &GUID_PKPixelFormat32bppBGRA))
2221
0
            enPFTo = GUID_PKPixelFormat32bppRGBA;
2222
0
        if (IsEqualGUID(&enPFTo, &GUID_PKPixelFormat32bppPBGRA))
2223
0
            enPFTo = GUID_PKPixelFormat32bppPRGBA;
2224
0
    }
2225
2226
    //================================
2227
0
    if (!IsEqualGUID(&enPFFrom, &enPFTo))
2228
0
    {
2229
0
        size_t i = 0;
2230
0
        for (i = 0; i < sizeof2(s_pcInfo); ++i)
2231
0
        {
2232
0
            PKPixelConverterInfo* pPCI = s_pcInfo + i;
2233
2234
0
            if (IsEqualGUID(&enPFFrom, pPCI->pGUIDPixFmtFrom) && IsEqualGUID(&enPFTo, pPCI->pGUIDPixFmtTo))
2235
0
            {
2236
0
                pFC->Convert= pPCI->Convert;
2237
0
                goto Cleanup;
2238
0
            }
2239
0
        }
2240
        // Bugfix to allow legitimate encoding from/to combinations that don't actually 
2241
        // involve color conversions. 
2242
0
        for (i = 0; i < sizeof2(s_pcInfo2); ++i)
2243
0
        {
2244
0
            PKPixelConverter2Info* pPCI = s_pcInfo2 + i;
2245
2246
0
            if (IsEqualGUID(&enPFFrom, pPCI->pGUIDPixFmtFrom) && IsEqualGUID(&enPFTo, pPCI->pGUIDPixFmtTo))
2247
0
            {
2248
0
                goto Cleanup;
2249
0
            }
2250
0
        }
2251
        // If we failed the original check, and this bugfix check, then exit with error
2252
0
        Call(WMP_errUnsupportedFormat);
2253
0
    }
2254
2255
0
Cleanup:
2256
0
    return err;
2257
0
}
2258
2259
ERR PKFormatConverter_EnumConversions(const PKPixelFormatGUID *pguidSourcePF,
2260
                                      const U32 iIndex,
2261
                                      const PKPixelFormatGUID **ppguidTargetPF)
2262
0
{
2263
0
    U32 iCurrIdx = 0;
2264
0
    U32 i;
2265
0
    ERR errResult = WMP_errIndexNotFound;
2266
2267
0
    *ppguidTargetPF = &GUID_PKPixelFormatDontCare; // Init return value
2268
0
    for (i = 0; i < sizeof2(s_pcInfo); i++)
2269
0
    {
2270
0
        if (IsEqualGUID(s_pcInfo[i].pGUIDPixFmtFrom, pguidSourcePF))
2271
0
        {
2272
0
            if (iCurrIdx == iIndex)
2273
0
            {
2274
                // Found our target
2275
0
                errResult = WMP_errSuccess;
2276
0
                *ppguidTargetPF = s_pcInfo[i].pGUIDPixFmtTo;
2277
0
                break;
2278
0
            }
2279
0
            iCurrIdx += 1;
2280
0
        }
2281
0
    }
2282
2283
0
    return errResult;
2284
0
}
2285
2286
ERR PKFormatConverter_GetPixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF)
2287
0
{
2288
0
    *pPF = pFC->enPixelFormat;
2289
2290
0
    return WMP_errSuccess;
2291
0
}
2292
2293
ERR PKFormatConverter_GetSourcePixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF)
2294
0
{
2295
0
    return pFC->pDecoder->GetPixelFormat(pFC->pDecoder, pPF);
2296
0
}
2297
2298
ERR PKFormatConverter_GetSize(PKFormatConverter* pFC, I32* piWidth, I32* piHeight)
2299
0
{
2300
0
    return pFC->pDecoder->GetSize(pFC->pDecoder, piWidth, piHeight);
2301
0
}
2302
2303
ERR PKFormatConverter_GetResolution(PKFormatConverter* pFC, Float* pfrX, Float* pfrY)
2304
0
{
2305
0
    return pFC->pDecoder->GetResolution(pFC->pDecoder, pfrX, pfrY);
2306
0
}
2307
2308
ERR PKFormatConverter_Copy(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
2309
0
{
2310
0
    ERR err = WMP_errSuccess;
2311
2312
0
    Call(pFC->pDecoder->Copy(pFC->pDecoder, pRect, pb, cbStride));
2313
0
    Call(pFC->Convert(pFC, pRect, pb, cbStride));
2314
2315
0
Cleanup:
2316
0
    return err;
2317
0
}
2318
2319
ERR PKFormatConverter_Convert(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
2320
0
{
2321
0
    UNREFERENCED_PARAMETER( pFC );
2322
0
    UNREFERENCED_PARAMETER( pRect );
2323
0
    UNREFERENCED_PARAMETER( pb );
2324
0
    UNREFERENCED_PARAMETER( cbStride );
2325
2326
0
    return WMP_errSuccess;
2327
0
}
2328
2329
ERR PKFormatConverter_Release(PKFormatConverter** ppFC)
2330
0
{
2331
0
    ERR err = WMP_errSuccess;
2332
2333
0
    Call(PKFree((void **) ppFC));
2334
2335
0
Cleanup:
2336
0
    return err;
2337
0
}
2338