github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/jxrlib/jxrgluelib/JXRGluePFC.c (about)

     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
    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  
    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  
   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.0 / 2.4)) - 0.055f)) + 0.5f);
   115      }
   116      else
   117      {
   118          return 255;
   119      }
   120  }
   121  
   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  
   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  
   162  ERR BGR24_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
   163  {
   164      return RGB24_BGR24(pFC, pRect, pb, cbStride);
   165  }
   166  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
   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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  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  
  2286  ERR PKFormatConverter_GetPixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF)
  2287  {
  2288      *pPF = pFC->enPixelFormat;
  2289  
  2290      return WMP_errSuccess;
  2291  }
  2292  
  2293  ERR PKFormatConverter_GetSourcePixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF)
  2294  {
  2295      return pFC->pDecoder->GetPixelFormat(pFC->pDecoder, pPF);
  2296  }
  2297  
  2298  ERR PKFormatConverter_GetSize(PKFormatConverter* pFC, I32* piWidth, I32* piHeight)
  2299  {
  2300      return pFC->pDecoder->GetSize(pFC->pDecoder, piWidth, piHeight);
  2301  }
  2302  
  2303  ERR PKFormatConverter_GetResolution(PKFormatConverter* pFC, Float* pfrX, Float* pfrY)
  2304  {
  2305      return pFC->pDecoder->GetResolution(pFC->pDecoder, pfrX, pfrY);
  2306  }
  2307  
  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  
  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  
  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