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