github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/jxrlib/jxrgluelib/JXRGlue.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  #include <ctype.h>
    30  
    31  #define INITGUID
    32  #include <JXRGlue.h>
    33  
    34  //================================================================
    35  const PKIID IID_PKImageScanEncode = 1;
    36  const PKIID IID_PKImageFrameEncode = 2;
    37  
    38  const PKIID IID_PKImageUnsupported = 100;
    39  const PKIID IID_PKImageWmpEncode = 101;
    40  
    41  const PKIID IID_PKImageWmpDecode = 201;
    42  
    43  //================================================================
    44  // Misc supporting functions
    45  //================================================================
    46  ERR PKAlloc(void** ppv, size_t cb)
    47  {
    48      *ppv = calloc(1, cb);
    49      return *ppv ? WMP_errSuccess : WMP_errOutOfMemory;
    50  }
    51  
    52  
    53  ERR PKFree(void** ppv)
    54  {
    55      if (ppv)
    56      {
    57          free(*ppv);
    58          *ppv = NULL;
    59      }
    60  
    61      return WMP_errSuccess;
    62  }
    63  
    64  ERR PKAllocAligned(void** ppv, size_t cb, size_t iAlign)
    65  {
    66      U8          *pOrigPtr;
    67      U8          *pReturnedPtr;
    68      size_t       iAlignmentCorrection;
    69      const size_t c_cbBlockSize = cb + sizeof(void*) + iAlign - 1;
    70  
    71      *ppv = NULL;
    72      pOrigPtr = calloc(1, c_cbBlockSize);
    73      if (NULL == pOrigPtr)
    74          return WMP_errOutOfMemory;
    75  
    76      iAlignmentCorrection = iAlign - ((size_t)pOrigPtr % iAlign);
    77      if (iAlignmentCorrection < sizeof(void*))
    78          // Alignment correction won't leave us enough space to store pOrigPtr - advance to next block
    79          iAlignmentCorrection += iAlign;
    80  
    81      assert(iAlignmentCorrection >= sizeof(void*)); // Alignment correction must have space for pOrigPtr
    82      assert(iAlignmentCorrection + cb <= c_cbBlockSize); // Don't exceed right edge of memory block
    83  
    84      pReturnedPtr = pOrigPtr + iAlignmentCorrection;
    85      *(void**)(pReturnedPtr - sizeof(void*)) = pOrigPtr;
    86  
    87      assert(0 == ((size_t)pReturnedPtr % iAlign)); // Are we in fact aligned?
    88      *ppv = pReturnedPtr;
    89      return WMP_errSuccess;
    90  }
    91  
    92  ERR PKFreeAligned(void** ppv)
    93  {
    94      if (ppv && *ppv)
    95      {
    96          U8 **ppOrigPtr = (U8**)((U8*)(*ppv) - sizeof(void*));
    97          assert(*ppOrigPtr <= (U8*)ppOrigPtr); // Something's wrong if pOrigPtr points forward
    98          free(*ppOrigPtr);
    99          *ppv = NULL;
   100      }
   101      return WMP_errSuccess;
   102  }
   103  
   104  
   105  
   106  int PKStrnicmp(const char* s1, const char* s2, size_t c)
   107  {
   108      for(; tolower(*s1) == tolower(*s2) && *s1 && *s2 && c; ++s1, ++s2, --c);
   109      return c ? *s1 - *s2 : 0;
   110  }
   111  
   112  static const PKPixelInfo pixelInfo[] =
   113  {
   114      {&GUID_PKPixelFormatDontCare, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul, 0, 0, 0, 0},
   115  
   116      // Gray
   117      //{&GUID_PKPixelFormat2bppGray, 1, Y_ONLY, BD_8, 2, PK_pixfmtNul},
   118      //{&GUID_PKPixelFormat4bppGray, 1, Y_ONLY, BD_8, 4, PK_pixfmtNul},
   119  
   120      {&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul,               1, 1, 1, 1},//BlackIsZero is default for GUID_PKPixelFormatBlackWhite
   121      {&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul,               0, 1, 1, 1},//WhiteIsZero
   122      {&GUID_PKPixelFormat8bppGray, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul,                 1, 1, 8, 1},
   123      {&GUID_PKPixelFormat16bppGray, 1, Y_ONLY, BD_16, 16, PK_pixfmtNul,              1, 1, 16, 1},
   124      {&GUID_PKPixelFormat16bppGrayFixedPoint, 1, Y_ONLY, BD_16S, 16, PK_pixfmtNul,   1, 1, 16, 2},
   125      {&GUID_PKPixelFormat16bppGrayHalf, 1, Y_ONLY, BD_16F, 16, PK_pixfmtNul,         1, 1, 16, 3},
   126      //{&GUID_PKPixelFormat32bppGray, 1, Y_ONLY, BD_32, 32, PK_pixfmtNul,              1, 1, 32, 1},
   127      {&GUID_PKPixelFormat32bppGrayFixedPoint, 1, Y_ONLY, BD_32S, 32, PK_pixfmtNul,   1, 1, 32, 2},
   128      {&GUID_PKPixelFormat32bppGrayFloat, 1, Y_ONLY, BD_32F, 32, PK_pixfmtNul,        1, 1, 32, 3},
   129  
   130      // RGB
   131      {&GUID_PKPixelFormat24bppRGB, 3, CF_RGB, BD_8, 24, PK_pixfmtNul,                2, 3, 8, 1},
   132      {&GUID_PKPixelFormat24bppBGR, 3, CF_RGB, BD_8, 24, PK_pixfmtBGR,                2, 3, 8, 1},
   133      {&GUID_PKPixelFormat32bppRGB, 3, CF_RGB, BD_8, 32, PK_pixfmtNul,                2, 3, 8, 1},
   134      {&GUID_PKPixelFormat32bppBGR, 3, CF_RGB, BD_8, 32, PK_pixfmtBGR,                2, 3, 8, 1},
   135      {&GUID_PKPixelFormat48bppRGB, 3, CF_RGB, BD_16, 48, PK_pixfmtNul,               2, 3, 16, 1},
   136      {&GUID_PKPixelFormat48bppRGBFixedPoint, 3, CF_RGB, BD_16S, 48, PK_pixfmtNul,    2, 3, 16, 2},
   137      {&GUID_PKPixelFormat48bppRGBHalf, 3, CF_RGB, BD_16F, 48, PK_pixfmtNul,          2, 3, 16, 3},
   138      {&GUID_PKPixelFormat64bppRGBFixedPoint, 3, CF_RGB, BD_16S, 64, PK_pixfmtNul,    2, 3, 16, 2},
   139      {&GUID_PKPixelFormat64bppRGBHalf, 3, CF_RGB, BD_16F, 64, PK_pixfmtNul,          2, 3, 16, 3},
   140      //{&GUID_PKPixelFormat96bppRGB, 3, CF_RGB, BD_32, 96, PK_pixfmtNul,               2, 3, 32, 1},
   141      {&GUID_PKPixelFormat96bppRGBFixedPoint, 3, CF_RGB, BD_32S, 96, PK_pixfmtNul,    2, 3, 32, 2},
   142      {&GUID_PKPixelFormat96bppRGBFloat, 3, CF_RGB, BD_32F, 96, PK_pixfmtNul,         2, 3, 32, 3},
   143      {&GUID_PKPixelFormat128bppRGBFixedPoint, 3, CF_RGB, BD_32S, 128, PK_pixfmtNul,  2, 3, 32, 2},
   144      {&GUID_PKPixelFormat128bppRGBFloat, 3, CF_RGB, BD_32F, 128, PK_pixfmtNul,       2, 3, 32, 3},
   145  
   146      // RGBA
   147      {&GUID_PKPixelFormat32bppBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtBGR,  2, 4, 8, 1},
   148      {&GUID_PKPixelFormat32bppRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha,                 2, 4, 8, 1},
   149      {&GUID_PKPixelFormat64bppRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha,                2, 4, 16, 1},
   150      {&GUID_PKPixelFormat64bppRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha,     2, 4, 16, 2},
   151      {&GUID_PKPixelFormat64bppRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha,           2, 4, 16, 3},
   152      //{&GUID_PKPixelFormat128bppRGBA, 4, CF_RGB, BD_32, 128, PK_pixfmtHasAlpha,              2, 4, 32, 1},
   153      {&GUID_PKPixelFormat128bppRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha,   2, 4, 32, 2},
   154      {&GUID_PKPixelFormat128bppRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha,        2, 4, 32, 3},
   155  
   156      // PRGBA
   157      {&GUID_PKPixelFormat32bppPBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul | PK_pixfmtBGR,   2, 4, 8, 1},
   158      {&GUID_PKPixelFormat32bppPRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul,                  2, 4, 8, 1},
   159      {&GUID_PKPixelFormat64bppPRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha | PK_pixfmtPreMul,                 2, 4, 16, 1},
   160      //{&GUID_PKPixelFormat64bppPRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha,      2, 4, 16, 2},
   161      //{&GUID_PKPixelFormat64bppPRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha,            2, 4, 16, 3},
   162      //{&GUID_PKPixelFormat128bppPRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha,    2, 4, 32, 2},
   163      {&GUID_PKPixelFormat128bppPRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha | PK_pixfmtPreMul,         2, 4, 32, 3},
   164  
   165      // Packed formats
   166      {&GUID_PKPixelFormat16bppRGB555, 3, CF_RGB,  BD_5, 16, PK_pixfmtNul,      2, 3, 5, 1},
   167      {&GUID_PKPixelFormat16bppRGB565, 3, CF_RGB, BD_565, 16, PK_pixfmtNul,     2, 3, 6, 1},
   168      {&GUID_PKPixelFormat32bppRGB101010, 3, CF_RGB, BD_10, 32, PK_pixfmtNul,   2, 3, 10, 1},
   169  
   170      // CMYK
   171      {&GUID_PKPixelFormat32bppCMYK, 4, CMYK, BD_8, 32, PK_pixfmtNul,               5, 4, 8, 1},
   172      {&GUID_PKPixelFormat40bppCMYKAlpha, 5, CMYK, BD_8, 40, PK_pixfmtHasAlpha,     5, 5, 8, 1},
   173  
   174      {&GUID_PKPixelFormat64bppCMYK, 4, CMYK, BD_16, 64, PK_pixfmtNul,              5, 4, 16, 1},
   175      {&GUID_PKPixelFormat80bppCMYKAlpha, 5, CMYK, BD_16, 80, PK_pixfmtHasAlpha,    5, 5, 16, 1},
   176  
   177      // N_CHANNEL
   178      {&GUID_PKPixelFormat24bpp3Channels, 3, NCOMPONENT, BD_8, 24, PK_pixfmtNul, PK_PI_NCH, 3, 8, 1},//the N channel TIF by PS has PhotometricInterpretation of PK_PI_RGB
   179      {&GUID_PKPixelFormat32bpp4Channels, 4, NCOMPONENT, BD_8, 32, PK_pixfmtNul, PK_PI_NCH, 4, 8, 1},
   180      {&GUID_PKPixelFormat40bpp5Channels, 5, NCOMPONENT, BD_8, 40, PK_pixfmtNul, PK_PI_NCH, 5, 8, 1},
   181      {&GUID_PKPixelFormat48bpp6Channels, 6, NCOMPONENT, BD_8, 48, PK_pixfmtNul, PK_PI_NCH, 6, 8, 1},
   182      {&GUID_PKPixelFormat56bpp7Channels, 7, NCOMPONENT, BD_8, 56, PK_pixfmtNul, PK_PI_NCH, 7, 8, 1},
   183      {&GUID_PKPixelFormat64bpp8Channels, 8, NCOMPONENT, BD_8, 64, PK_pixfmtNul, PK_PI_NCH, 8, 8, 1},
   184      
   185      {&GUID_PKPixelFormat32bpp3ChannelsAlpha, 4, NCOMPONENT, BD_8, 32, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 8, 1},
   186      {&GUID_PKPixelFormat40bpp4ChannelsAlpha, 5, NCOMPONENT, BD_8, 40, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 8, 1},
   187      {&GUID_PKPixelFormat48bpp5ChannelsAlpha, 6, NCOMPONENT, BD_8, 48, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 8, 1},
   188      {&GUID_PKPixelFormat56bpp6ChannelsAlpha, 7, NCOMPONENT, BD_8, 56, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 8, 1},
   189      {&GUID_PKPixelFormat64bpp7ChannelsAlpha, 8, NCOMPONENT, BD_8, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 8, 1},
   190      {&GUID_PKPixelFormat72bpp8ChannelsAlpha, 9, NCOMPONENT, BD_8, 72, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 8, 1},
   191  
   192      {&GUID_PKPixelFormat48bpp3Channels, 3, NCOMPONENT, BD_16, 48, PK_pixfmtNul, PK_PI_NCH, 3, 16, 1},
   193      {&GUID_PKPixelFormat64bpp4Channels, 4, NCOMPONENT, BD_16, 64, PK_pixfmtNul, PK_PI_NCH, 4, 16, 1},
   194      {&GUID_PKPixelFormat80bpp5Channels, 5, NCOMPONENT, BD_16, 80, PK_pixfmtNul, PK_PI_NCH, 5, 16, 1},
   195      {&GUID_PKPixelFormat96bpp6Channels, 6, NCOMPONENT, BD_16, 96, PK_pixfmtNul, PK_PI_NCH, 6, 16, 1},
   196      {&GUID_PKPixelFormat112bpp7Channels, 7, NCOMPONENT, BD_16, 112, PK_pixfmtNul, PK_PI_NCH, 7, 16, 1},
   197      {&GUID_PKPixelFormat128bpp8Channels, 8, NCOMPONENT, BD_16, 128, PK_pixfmtNul, PK_PI_NCH, 8, 16, 1},
   198  
   199      {&GUID_PKPixelFormat64bpp3ChannelsAlpha, 4, NCOMPONENT, BD_16, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 16, 1},
   200      {&GUID_PKPixelFormat80bpp4ChannelsAlpha, 5, NCOMPONENT, BD_16, 80, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 16, 1},
   201      {&GUID_PKPixelFormat96bpp5ChannelsAlpha, 6, NCOMPONENT, BD_16, 96, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 16, 1},
   202      {&GUID_PKPixelFormat112bpp6ChannelsAlpha, 7, NCOMPONENT, BD_16, 112, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 16, 1},
   203      {&GUID_PKPixelFormat128bpp7ChannelsAlpha, 8, NCOMPONENT, BD_16, 128, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 16, 1},
   204      {&GUID_PKPixelFormat144bpp8ChannelsAlpha, 9, NCOMPONENT, BD_16, 144, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 16, 1},
   205  
   206      //RGBE
   207      {&GUID_PKPixelFormat32bppRGBE, 4, CF_RGBE, BD_8, 32, PK_pixfmtNul, PK_PI_RGBE, 4, 8, 1},
   208  
   209      //YUV
   210      {&GUID_PKPixelFormat12bppYUV420, 3, YUV_420, BD_8, 48, PK_pixfmtNul},
   211      {&GUID_PKPixelFormat16bppYUV422, 3, YUV_422, BD_8, 32, PK_pixfmtNul},
   212      {&GUID_PKPixelFormat24bppYUV444, 3, YUV_444, BD_8, 24, PK_pixfmtNul},
   213  };
   214  
   215  //----------------------------------------------------------------
   216  //ERR GetPixelInfo(PKPixelFormatGUID enPixelFormat, const PKPixelInfo** ppPI)
   217  ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType)
   218  {
   219      ERR err = WMP_errSuccess;
   220      size_t i;
   221  
   222      for (i = 0; i < sizeof2(pixelInfo); ++i)
   223      {
   224          if (LOOKUP_FORWARD == uLookupType)
   225          {
   226              if (IsEqualGUID(pPI->pGUIDPixFmt, pixelInfo[i].pGUIDPixFmt))
   227              {
   228                  *pPI = pixelInfo[i];
   229                  goto Cleanup;
   230              }
   231          }
   232          else if (LOOKUP_BACKWARD_TIF == uLookupType)
   233          {
   234              if (pPI->uSamplePerPixel == pixelInfo[i].uSamplePerPixel &&
   235                  pPI->uBitsPerSample == pixelInfo[i].uBitsPerSample &&
   236                  pPI->uSampleFormat == pixelInfo[i].uSampleFormat &&
   237                  pPI->uInterpretation == pixelInfo[i].uInterpretation)
   238              {
   239                  // match alpha & premult
   240                  if ((pPI->grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)) ==
   241                      (pixelInfo[i].grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)))
   242                  {
   243                      *pPI = pixelInfo[i];
   244                      goto Cleanup;
   245                  }
   246              }
   247          }
   248      }
   249      Call(WMP_errUnsupportedFormat);
   250  
   251  Cleanup:
   252      return err;        
   253  }
   254  
   255  
   256  const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash)
   257  {
   258      int i;
   259  
   260      for (i = 0; i < sizeof2(pixelInfo); i++)
   261      {
   262          if (pixelInfo[i].pGUIDPixFmt->Data4[7] == uPFHash)
   263              return pixelInfo[i].pGUIDPixFmt;
   264      }
   265  
   266      // If we reached this point, we did not find anything which matched the hash
   267      return NULL;
   268  }
   269  
   270  //----------------------------------------------------------------
   271  typedef struct tagPKIIDInfo
   272  {
   273      const char* szExt;
   274      const PKIID* pIIDEnc;
   275      const PKIID* pIIDDec;
   276  } PKIIDInfo;
   277  
   278  static ERR GetIIDInfo(const char* szExt, const PKIIDInfo** ppInfo)
   279  {
   280      ERR err = WMP_errSuccess;
   281  
   282      static PKIIDInfo iidInfo[] = {
   283          {".jxr", &IID_PKImageWmpEncode, &IID_PKImageWmpDecode},
   284          {".wdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
   285          {".hdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
   286      };
   287      size_t i = 0;
   288  
   289      *ppInfo = NULL;
   290      for (i = 0; i < sizeof2(iidInfo); ++i)
   291      {
   292          if (0 == PKStrnicmp(szExt, iidInfo[i].szExt, strlen(iidInfo[i].szExt)))
   293          {
   294              *ppInfo = &iidInfo[i];
   295              goto Cleanup;
   296          }
   297      }
   298  
   299      Call(WMP_errUnsupportedFormat);
   300  
   301  Cleanup:
   302      return err;
   303  }
   304  
   305  ERR GetImageEncodeIID(const char* szExt, const PKIID** ppIID)
   306  {
   307      ERR err = WMP_errSuccess;
   308  
   309      const PKIIDInfo* pInfo = NULL;
   310  
   311      Call(GetIIDInfo(szExt, &pInfo));
   312      *ppIID = pInfo->pIIDEnc;
   313  
   314  Cleanup:
   315      return err;
   316  }
   317  
   318  ERR GetImageDecodeIID(const char* szExt, const PKIID** ppIID)
   319  {
   320      ERR err = WMP_errSuccess;
   321  
   322      const PKIIDInfo* pInfo = NULL;
   323  
   324      Call(GetIIDInfo(szExt, &pInfo));
   325      *ppIID = pInfo->pIIDDec;
   326  
   327  Cleanup:
   328      return err;
   329  }
   330  
   331  //================================================================
   332  // PKFactory
   333  //================================================================
   334  ERR PKCreateFactory_CreateStream(PKStream** ppStream)
   335  {
   336      ERR err = WMP_errSuccess;
   337  
   338      Call(PKAlloc((void **) ppStream, sizeof(**ppStream)));
   339  
   340  Cleanup:
   341      return err;
   342  }
   343  
   344  ERR PKCreateFactory_Release(PKFactory** ppFactory)
   345  {
   346      ERR err = WMP_errSuccess;
   347  
   348      Call(PKFree((void **) ppFactory));
   349  
   350  Cleanup: 
   351      return err;
   352  }
   353  
   354  //----------------------------------------------------------------
   355  ERR PKCreateFactory(PKFactory** ppFactory, U32 uVersion)
   356  {
   357      ERR err = WMP_errSuccess;
   358      PKFactory* pFactory = NULL;
   359  
   360      UNREFERENCED_PARAMETER( uVersion );
   361  
   362      Call(PKAlloc((void **) ppFactory, sizeof(**ppFactory)));
   363      pFactory = *ppFactory;
   364  
   365      pFactory->CreateStream = PKCreateFactory_CreateStream;
   366  
   367      pFactory->CreateStreamFromFilename = CreateWS_File;
   368      pFactory->CreateStreamFromMemory = CreateWS_Memory;
   369      
   370      pFactory->Release = PKCreateFactory_Release;
   371  
   372  Cleanup:
   373      return err;
   374  }
   375  
   376  
   377  //================================================================
   378  // PKCodecFactory
   379  //================================================================
   380  ERR PKCodecFactory_CreateCodec(const PKIID* iid, void** ppv)
   381  {
   382      ERR err = WMP_errSuccess;
   383  
   384      if (IID_PKImageWmpEncode == *iid)
   385      {
   386          Call(PKImageEncode_Create_WMP((PKImageEncode**)ppv));
   387      }
   388      else if (IID_PKImageWmpDecode == *iid)
   389      {
   390          Call(PKImageDecode_Create_WMP((PKImageDecode**)ppv));
   391      }
   392      else
   393      {
   394          Call(WMP_errUnsupportedFormat);
   395      }
   396  
   397  Cleanup:
   398      return err;
   399  }
   400  
   401  ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder)
   402  {
   403      ERR err = WMP_errSuccess;
   404  
   405      char *pExt = NULL;
   406      const PKIID* pIID = NULL;
   407  
   408      struct WMPStream* pStream = NULL;
   409      PKImageDecode* pDecoder = NULL;
   410  
   411      // get file extension
   412      pExt = strrchr(szFilename, '.');
   413      FailIf(NULL == pExt, WMP_errUnsupportedFormat);
   414  
   415      // get decode PKIID
   416      Call(GetImageDecodeIID(pExt, &pIID));
   417  
   418      // create stream
   419      Call(CreateWS_File(&pStream, szFilename, "rb"));
   420  
   421      // Create decoder
   422      Call(PKCodecFactory_CreateCodec(pIID, (void **) ppDecoder));
   423      pDecoder = *ppDecoder;
   424  
   425      // attach stream to decoder
   426      Call(pDecoder->Initialize(pDecoder, pStream));
   427      pDecoder->fStreamOwner = !0;
   428  
   429  Cleanup:
   430      return err;
   431  }
   432  
   433  ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter)
   434  {
   435      ERR err = WMP_errSuccess;
   436      PKFormatConverter* pFC = NULL;
   437  
   438      Call(PKAlloc((void **) ppFConverter, sizeof(**ppFConverter)));
   439      pFC = *ppFConverter;
   440  
   441      pFC->Initialize = PKFormatConverter_Initialize;
   442      pFC->InitializeConvert = PKFormatConverter_InitializeConvert;
   443      pFC->GetPixelFormat = PKFormatConverter_GetPixelFormat;
   444      pFC->GetSourcePixelFormat = PKFormatConverter_GetSourcePixelFormat;
   445      pFC->GetSize = PKFormatConverter_GetSize;
   446      pFC->GetResolution = PKFormatConverter_GetResolution;
   447      pFC->Copy = PKFormatConverter_Copy;
   448      pFC->Convert = PKFormatConverter_Convert;
   449      pFC->Release = PKFormatConverter_Release;
   450  
   451  Cleanup:
   452      return err;
   453  }
   454  
   455  ERR PKCreateCodecFactory_Release(PKCodecFactory** ppCFactory)
   456  {
   457      ERR err = WMP_errSuccess;
   458  
   459      Call(PKFree((void **) ppCFactory));
   460  
   461  Cleanup:
   462      return err;
   463  }
   464  
   465  ERR PKCreateCodecFactory(PKCodecFactory** ppCFactory, U32 uVersion)
   466  {
   467      ERR err = WMP_errSuccess;
   468      PKCodecFactory* pCFactory = NULL;
   469  
   470      UNREFERENCED_PARAMETER( uVersion );
   471  
   472      Call(PKAlloc((void **) ppCFactory, sizeof(**ppCFactory)));
   473      pCFactory = *ppCFactory;
   474  
   475      pCFactory->CreateCodec = PKCodecFactory_CreateCodec;
   476      pCFactory->CreateDecoderFromFile = PKCodecFactory_CreateDecoderFromFile;
   477      pCFactory->CreateFormatConverter = PKCodecFactory_CreateFormatConverter;
   478      pCFactory->Release = PKCreateCodecFactory_Release;
   479  
   480  Cleanup:
   481      return err;
   482  }
   483  
   484  
   485  //================================================================
   486  // PKImageEncode
   487  //================================================================
   488  ERR PKImageEncode_Initialize(
   489      PKImageEncode* pIE,
   490      struct WMPStream* pStream,
   491      void* pvParam,
   492      size_t cbParam)
   493  {
   494      ERR err = WMP_errSuccess;
   495  
   496      UNREFERENCED_PARAMETER( pIE );
   497      UNREFERENCED_PARAMETER( pvParam );
   498      UNREFERENCED_PARAMETER( cbParam );
   499  
   500      pIE->pStream = pStream;
   501      pIE->guidPixFormat = GUID_PKPixelFormatDontCare;
   502      pIE->fResX = 96;
   503      pIE->fResY = 96;
   504      pIE->cFrame = 1;
   505  
   506      Call(pIE->pStream->GetPos(pIE->pStream, &pIE->offStart));
   507  
   508  Cleanup:
   509      return err;
   510  }
   511  
   512  ERR PKImageEncode_Terminate(
   513      PKImageEncode* pIE)
   514  {
   515      UNREFERENCED_PARAMETER( pIE );
   516      return WMP_errSuccess;
   517  }
   518  
   519  ERR PKImageEncode_SetPixelFormat(
   520      PKImageEncode* pIE,
   521      PKPixelFormatGUID enPixelFormat)
   522  {
   523      pIE->guidPixFormat = enPixelFormat;
   524  
   525      return WMP_errSuccess;
   526  }
   527  
   528  ERR PKImageEncode_SetSize(
   529      PKImageEncode* pIE,
   530      I32 iWidth,
   531      I32 iHeight)
   532  {
   533      ERR err = WMP_errSuccess;
   534  
   535      pIE->uWidth = (U32)iWidth;
   536      pIE->uHeight = (U32)iHeight;
   537  
   538      return err;
   539  }
   540  
   541  ERR PKImageEncode_SetResolution(
   542      PKImageEncode* pIE,
   543      Float fResX, 
   544      Float fResY)
   545  {
   546      pIE->fResX = fResX;
   547      pIE->fResY = fResY;
   548  
   549      return WMP_errSuccess;
   550  }
   551  
   552  ERR PKImageEncode_SetColorContext(PKImageEncode *pIE,
   553                                    const U8 *pbColorContext,
   554                                    U32 cbColorContext)
   555  {
   556      UNREFERENCED_PARAMETER( pIE );
   557      UNREFERENCED_PARAMETER( pbColorContext );
   558      UNREFERENCED_PARAMETER( cbColorContext );
   559      return WMP_errNotYetImplemented;
   560  }
   561  
   562  
   563  ERR PKImageEncode_SetDescriptiveMetadata(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pDescMetadata)
   564  {
   565      UNREFERENCED_PARAMETER( pIE );
   566      UNREFERENCED_PARAMETER( pDescMetadata );
   567      return WMP_errNotYetImplemented;
   568  }
   569  
   570  ERR PKImageEncode_WritePixels(
   571      PKImageEncode* pIE,
   572      U32 cLine,
   573      U8* pbPixels,
   574      U32 cbStride)
   575  {
   576      UNREFERENCED_PARAMETER( pIE );
   577      UNREFERENCED_PARAMETER( cLine );
   578      UNREFERENCED_PARAMETER( pbPixels );
   579      UNREFERENCED_PARAMETER( cbStride );
   580      return WMP_errAbstractMethod;
   581  }
   582  
   583  ERR PKImageEncode_WriteSource(
   584      PKImageEncode* pIE,
   585      PKFormatConverter* pFC,
   586      PKRect* pRect)
   587  {
   588      ERR err = WMP_errSuccess;
   589  
   590      PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
   591      PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
   592  
   593      PKPixelInfo pPIFrom;
   594      PKPixelInfo pPITo;
   595  
   596      U32 cbStrideTo = 0;
   597      U32 cbStrideFrom = 0;
   598      U32 cbStride = 0;
   599  
   600      U8* pb = NULL;
   601  
   602  	// CWMTranscodingParam* pParam = NULL; 
   603  
   604      // get pixel format
   605      Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
   606      Call(pFC->GetPixelFormat(pFC, &enPFTo));
   607      FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
   608  
   609      // calc common stride
   610  //    Call(GetPixelInfo(enPFFrom, &pPIFrom));
   611      pPIFrom.pGUIDPixFmt = &enPFFrom;
   612      PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
   613  
   614  //    Call(GetPixelInfo(enPFTo, &pPITo));
   615      pPITo.pGUIDPixFmt = &enPFTo;
   616      PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
   617  
   618  //    cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
   619      cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width)); 
   620      if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt 
   621          || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt) 
   622          cbStrideFrom >>= 1;
   623  
   624  //    cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
   625      cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth)); 
   626      if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
   627          || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) 
   628          cbStrideTo >>= 1;
   629  
   630      cbStride = max(cbStrideFrom, cbStrideTo);
   631  
   632      // actual dec/enc with local buffer
   633      Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
   634  
   635      Call(pFC->Copy(pFC, pRect, pb, cbStride));
   636  
   637  	Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
   638  
   639  Cleanup:
   640      PKFreeAligned((void **) &pb);
   641      return err;
   642  }
   643  
   644  ERR PKImageEncode_WritePixelsBandedBegin(PKImageEncode* pEncoder, struct WMPStream *pPATempFile)
   645  {
   646      UNREFERENCED_PARAMETER( pEncoder );
   647      UNREFERENCED_PARAMETER( pPATempFile );
   648      return WMP_errAbstractMethod;
   649  }
   650  
   651  ERR PKImageEncode_WritePixelsBanded(PKImageEncode* pEncoder, U32 cLines, U8* pbPixels, U32 cbStride, Bool fLastCall)
   652  {
   653      UNREFERENCED_PARAMETER( pEncoder );
   654      UNREFERENCED_PARAMETER( cLines );
   655      UNREFERENCED_PARAMETER( pbPixels );
   656      UNREFERENCED_PARAMETER( cbStride );
   657      UNREFERENCED_PARAMETER( fLastCall );
   658      return WMP_errAbstractMethod;
   659  }
   660  
   661  ERR PKImageEncode_WritePixelsBandedEnd(PKImageEncode* pEncoder)
   662  {
   663      UNREFERENCED_PARAMETER( pEncoder );
   664      return WMP_errAbstractMethod;
   665  }
   666  
   667  
   668  ERR PKImageEncode_Transcode(
   669      PKImageEncode* pIE,
   670      PKFormatConverter* pFC,
   671      PKRect* pRect)
   672  {
   673      ERR err = WMP_errSuccess;
   674  
   675      PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
   676      PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
   677  
   678      PKPixelInfo pPIFrom;
   679      PKPixelInfo pPITo;
   680  
   681      U32 cbStrideTo = 0;
   682      U32 cbStrideFrom = 0;
   683      U32 cbStride = 0;
   684  
   685      U8* pb = NULL;
   686  
   687      CWMTranscodingParam cParam = {0}; 
   688  
   689      // get pixel format
   690      Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
   691      Call(pFC->GetPixelFormat(pFC, &enPFTo));
   692      FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
   693  
   694      // calc common stride
   695  //    Call(GetPixelInfo(enPFFrom, &pPIFrom));
   696      pPIFrom.pGUIDPixFmt = &enPFFrom;
   697      PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
   698  
   699  //    Call(GetPixelInfo(enPFTo, &pPITo));
   700      pPITo.pGUIDPixFmt = &enPFTo;
   701      PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
   702  
   703  //    cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
   704      cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width)); 
   705      if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt 
   706          || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt) 
   707          cbStrideFrom >>= 1;
   708  
   709  //    cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
   710      cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth)); 
   711      if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
   712          || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) 
   713          cbStrideTo >>= 1;
   714  
   715      cbStride = max(cbStrideFrom, cbStrideTo);
   716  
   717      if(pIE->bWMP){
   718          cParam.cLeftX = pFC->pDecoder->WMP.wmiI.cROILeftX;
   719          cParam.cTopY = pFC->pDecoder->WMP.wmiI.cROITopY;
   720          cParam.cWidth = pFC->pDecoder->WMP.wmiI.cROIWidth;
   721          cParam.cHeight = pFC->pDecoder->WMP.wmiI.cROIHeight;
   722          cParam.oOrientation = pFC->pDecoder->WMP.wmiI.oOrientation;
   723  //        cParam.cfColorFormat = pFC->pDecoder->WMP.wmiI.cfColorFormat;
   724          cParam.uAlphaMode = pFC->pDecoder->WMP.wmiSCP.uAlphaMode;
   725          cParam.bfBitstreamFormat = pFC->pDecoder->WMP.wmiSCP.bfBitstreamFormat;
   726          cParam.sbSubband = pFC->pDecoder->WMP.wmiSCP.sbSubband;
   727          cParam.bIgnoreOverlap = pFC->pDecoder->WMP.bIgnoreOverlap;
   728          
   729          Call(pIE->Transcode(pIE, pFC->pDecoder, &cParam));
   730      }
   731  	else 
   732  	{
   733  		// actual dec/enc with local buffer
   734  	    Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
   735  		Call(pFC->Copy(pFC, pRect, pb, cbStride));
   736  		Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
   737  	}
   738  
   739  Cleanup:
   740      PKFreeAligned((void **) &pb);
   741      return err;
   742  }
   743  
   744  ERR PKImageEncode_CreateNewFrame(
   745      PKImageEncode* pIE,
   746      void* pvParam,
   747      size_t cbParam)
   748  {
   749      UNREFERENCED_PARAMETER( pIE );
   750      UNREFERENCED_PARAMETER( pvParam );
   751      UNREFERENCED_PARAMETER( cbParam );
   752      // NYI
   753      return WMP_errSuccess;
   754  }
   755  
   756  ERR PKImageEncode_Release(
   757      PKImageEncode** ppIE)
   758  {
   759      PKImageEncode *pIE = *ppIE;
   760      pIE->pStream->Close(&pIE->pStream);
   761  
   762      return PKFree((void **) ppIE);
   763  }
   764  
   765  ERR PKImageEncode_Create(PKImageEncode** ppIE)
   766  {
   767      ERR err = WMP_errSuccess;
   768      PKImageEncode* pIE = NULL;
   769  
   770      Call(PKAlloc((void **) ppIE, sizeof(**ppIE)));
   771  
   772      pIE = *ppIE;
   773      pIE->Initialize = PKImageEncode_Initialize;
   774      pIE->Terminate = PKImageEncode_Terminate;
   775      pIE->SetPixelFormat = PKImageEncode_SetPixelFormat;
   776      pIE->SetSize = PKImageEncode_SetSize;
   777      pIE->SetResolution = PKImageEncode_SetResolution;
   778      pIE->SetColorContext = PKImageEncode_SetColorContext;
   779      pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata;
   780      pIE->WritePixels = PKImageEncode_WritePixels;
   781  //    pIE->WriteSource = PKImageEncode_WriteSource;
   782  
   783      pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin;
   784      pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded;
   785      pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd;
   786  
   787      pIE->CreateNewFrame = PKImageEncode_CreateNewFrame;
   788      pIE->Release = PKImageEncode_Release;
   789  	pIE->bWMP = FALSE; 
   790  
   791  Cleanup:
   792      return err;
   793  }
   794    
   795  
   796  //================================================================
   797  // PKImageDecode
   798  //================================================================
   799  ERR PKImageDecode_Initialize(
   800      PKImageDecode* pID,
   801      struct WMPStream* pStream)
   802  {
   803      ERR err = WMP_errSuccess;
   804  
   805      pID->pStream = pStream;
   806      pID->guidPixFormat = GUID_PKPixelFormatDontCare;
   807      pID->fResX = 96;
   808      pID->fResY = 96;
   809      pID->cFrame = 1;
   810  
   811      Call(pID->pStream->GetPos(pID->pStream, &pID->offStart));
   812  
   813      memset(&pID->WMP.wmiDEMisc, 0, sizeof(pID->WMP.wmiDEMisc));
   814  
   815  Cleanup:
   816      return WMP_errSuccess;
   817  }
   818  
   819  ERR PKImageDecode_GetPixelFormat(
   820      PKImageDecode* pID,
   821      PKPixelFormatGUID* pPF)
   822  {
   823      *pPF = pID->guidPixFormat;
   824  
   825      return WMP_errSuccess;
   826  }
   827  
   828  ERR PKImageDecode_GetSize(
   829      PKImageDecode* pID,
   830      I32* piWidth,
   831      I32* piHeight)
   832  {
   833      *piWidth = (I32)pID->uWidth;
   834      *piHeight = (I32)pID->uHeight;
   835  
   836      return WMP_errSuccess;
   837  }
   838  
   839  ERR PKImageDecode_GetResolution(
   840      PKImageDecode* pID,
   841      Float* pfResX,
   842      Float* pfResY)
   843  {
   844      *pfResX = pID->fResX;
   845      *pfResY = pID->fResY;
   846  
   847      return WMP_errSuccess;
   848  }
   849  
   850  ERR PKImageDecode_GetColorContext(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext)
   851  {
   852      UNREFERENCED_PARAMETER( pID );
   853      UNREFERENCED_PARAMETER( pbColorContext );
   854      UNREFERENCED_PARAMETER( pcbColorContext );
   855      return WMP_errNotYetImplemented;
   856  }
   857  
   858  ERR PKImageDecode_GetDescriptiveMetadata(PKImageDecode *pIE, DESCRIPTIVEMETADATA *pDescMetadata)
   859  {
   860      UNREFERENCED_PARAMETER( pIE );
   861      UNREFERENCED_PARAMETER( pDescMetadata );
   862      return WMP_errNotYetImplemented;
   863  }
   864  
   865  ERR PKImageDecode_Copy(
   866      PKImageDecode* pID,
   867      const PKRect* pRect,
   868      U8* pb,
   869      U32 cbStride)
   870  {
   871      UNREFERENCED_PARAMETER( pID );
   872      UNREFERENCED_PARAMETER( pRect );
   873      UNREFERENCED_PARAMETER( pb );
   874      UNREFERENCED_PARAMETER( cbStride );
   875      return WMP_errAbstractMethod;
   876  }
   877  
   878  ERR PKImageDecode_GetFrameCount(
   879      PKImageDecode* pID,
   880      U32* puCount)
   881  {
   882      *puCount = pID->cFrame;
   883  
   884      return WMP_errSuccess;
   885  }
   886  
   887  ERR PKImageDecode_SelectFrame(
   888      PKImageDecode* pID,
   889      U32 uFrame)
   890  {
   891      UNREFERENCED_PARAMETER( pID );
   892      UNREFERENCED_PARAMETER( uFrame );
   893      // NYI
   894      return WMP_errSuccess;
   895  }
   896  
   897  ERR PKImageDecode_Release(
   898      PKImageDecode** ppID)
   899  {
   900      PKImageDecode* pID = *ppID;
   901  
   902      pID->fStreamOwner && pID->pStream->Close(&pID->pStream);
   903  
   904      return PKFree((void **) ppID);
   905  }
   906  
   907  ERR PKImageDecode_Create(
   908      PKImageDecode** ppID)
   909  {
   910      ERR err = WMP_errSuccess;
   911      PKImageDecode* pID = NULL;
   912  
   913      Call(PKAlloc((void **) ppID, sizeof(**ppID)));
   914  
   915      pID = *ppID;
   916      pID->Initialize = PKImageDecode_Initialize;
   917      pID->GetPixelFormat = PKImageDecode_GetPixelFormat;
   918      pID->GetSize = PKImageDecode_GetSize;
   919      pID->GetResolution = PKImageDecode_GetResolution;
   920      pID->GetColorContext = PKImageDecode_GetColorContext;
   921      pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata;
   922      pID->Copy = PKImageDecode_Copy;
   923      pID->GetFrameCount = PKImageDecode_GetFrameCount;
   924      pID->SelectFrame = PKImageDecode_SelectFrame;
   925      pID->Release = PKImageDecode_Release;
   926  
   927  Cleanup:
   928      return err;
   929  }
   930