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