github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/jxrlib/jxrencoderdecoder/JxrDecApp.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 <JXRTest.h>
    29  #include <time.h>
    30  
    31  
    32  //================================================================
    33  static const size_t SKIPFLEXBITS = 0xff;
    34  
    35  //================================================================
    36  // Command line argument support
    37  //================================================================
    38  typedef struct tagWMPDECAPPARGS
    39  {
    40      char* szInputFile;
    41      char* szOutputFile;
    42  
    43      Bool bVerbose;
    44  
    45      PKPixelFormatGUID guidPixFormat;
    46  //    Bool bFlagRGB_BGR;
    47  
    48      // region decode
    49      size_t rLeftX;
    50      size_t rTopY;
    51      size_t rWidth;
    52      size_t rHeight;
    53  
    54      // thumbnail
    55      size_t tThumbnailFactor;
    56  
    57      // orientation
    58      ORIENTATION oOrientation;
    59  
    60      // post processing
    61      U8 cPostProcStrength;
    62  
    63      U8 uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha 
    64  
    65      SUBBAND sbSubband;  // which subbands to keep (for transcoding)
    66  
    67      BITSTREAMFORMAT bfBitstreamFormat; // desired bitsream format (for transcoding)
    68  
    69      CWMIStrCodecParam wmiSCP;
    70  
    71      Bool bIgnoreOverlap;
    72  } WMPDECAPPARGS;
    73  
    74  //----------------------------------------------------------------
    75  void WmpDecAppUsage(const char* szExe)
    76  {
    77      printf(CRLF);
    78      printf("JPEG XR Decoder Utility" CRLF);
    79      printf("Copyright 2013 Microsoft Corporation - All Rights Reserved" CRLF); 
    80      printf(CRLF);
    81      printf("%s [options]..." CRLF, szExe);
    82      printf(CRLF);
    83      printf("  -i input.jxr/wdp             Input JPEG XR/HD Photo file name" CRLF);
    84      printf(CRLF);
    85      printf("  -o output.bmp/tif/jxr        Output image file name" CRLF);
    86      printf("                               bmp: <=8bpc, BGR" CRLF);
    87      printf("                               tif: >=8bpc, RGB" CRLF);
    88      printf("                               jxr: for compressed domain transcode" CRLF);
    89      printf(CRLF);
    90  
    91      printf("  -c format                    Specifies the uncompressed output format" CRLF);
    92      printf("                                0: 24bppBGR" CRLF);
    93      printf("                                1: 1bppBlackWhite" CRLF);
    94      printf("                                2: 8bppGray" CRLF);
    95      printf("                                3: 16bppGray" CRLF);
    96      printf("                                4: 16bppGrayFixedPoint" CRLF);
    97      printf("                                5: 16bppGrayHalf" CRLF);
    98  //    printf("                               6: 32bppGray" CRLF);
    99      printf("                                7: 32bppGrayFixedPoint" CRLF);
   100      printf("                                8: 32bppGrayFloat" CRLF);
   101  
   102      printf("                                9: 24bppRGB" CRLF);
   103      printf("                               10: 48bppRGB" CRLF);
   104      printf("                               11: 48bppRGBFixedPoint" CRLF);
   105      printf("                               12: 48bppRGBHalf" CRLF);
   106  //    printf("                               13: 96bppRGB" CRLF);
   107      printf("                               14: 96bppRGBFixedPoint" CRLF);
   108      printf("                               15: 128bppRGBFloat" CRLF);
   109  
   110      printf("                               16: 32bppRGBE" CRLF);
   111  
   112      printf("                               17: 32bppCMYK" CRLF);
   113      printf("                               18: 64bppCMYK" CRLF);
   114  
   115  /*
   116      printf("                               19 - YUV 420" CRLF);
   117      printf("                               20 - YUV 422" CRLF);
   118      printf("                               21 - YUV 444" CRLF);
   119  */
   120      printf("                               22: 32bppBGRA" CRLF);
   121      printf("                               23: 64bppRGBA" CRLF);
   122      printf("                               24: 64bppRGBAFixedPoint" CRLF);
   123      printf("                               25: 64bppRGBAHalf" CRLF);
   124  //    printf("                               26 - 128bpp RGBA" CRLF);
   125      printf("                               27: 128bppRGBAFixedPoint" CRLF);
   126      printf("                               28: 128bppRGBAFloat" CRLF);
   127  
   128      printf("                               29: 16bppBGR555" CRLF);
   129      printf("                               30: 16bppBGR565" CRLF);
   130      printf("                               31: 32bppBGR101010" CRLF);
   131      //printf("                               101..116 - 1..16 channel 8bpp" CRLF);
   132      printf("                               32: 40bppCMYKA" CRLF);
   133      printf("                               33: 80bppCMYKA" CRLF);
   134  
   135      printf("                               34: 32bppBGR" CRLF);
   136  /*
   137      printf("                               35:  32bppPBGRA" CRLF);
   138      printf("                               36:  64bppPRGBA" CRLF);
   139      printf("                               37: 128bppPRGBA Float" CRLF);
   140  */
   141      printf(CRLF);
   142  
   143      printf("  -r top left height width     Specifies the rectangle for region decode" CRLF);
   144      printf(CRLF);
   145      printf("  -T m                         Reduced resolution (mipmap) decode" CRLF);
   146      printf("                                0: Full resolution (default)" CRLF);
   147      printf("                                1: 1/2 res (down-sampled from full res)" CRLF);
   148      printf("                                2: 1/4 res (native decode)" CRLF);
   149      printf("                                3: 1/8 res (down-sampled from 1/4 res)" CRLF);
   150      printf("                                4: 1/16 res (native decode)" CRLF);
   151      printf("                               >4: 1/(2^m) res (down-sampled from 1/16 res) " CRLF);
   152      printf(CRLF);
   153  
   154      printf("  -O orientation               0: No transformation (default)" CRLF);
   155      printf("                               1: Flip vertically" CRLF);
   156      printf("                               2: Flip horizontally" CRLF);
   157      printf("                               3: Flip vertically & horizontally" CRLF);
   158      printf("                               4: Rotate 90 degrees CW" CRLF);
   159      printf("                               5: Rotate 90 degrees CW & flip vertically" CRLF);
   160      printf("                               6: Rotate 90 degrees CW & flip horizontally" CRLF);
   161      printf("                               7: Rotate 90 degrees CW & flip vert & horiz" CRLF);
   162      printf(CRLF);
   163  
   164      printf("  -s skip subbands             Used for compressed domain transcoding" CRLF);    
   165      printf("                               0: All subbands included (default)" CRLF);    
   166      printf("                               1: Skip flexbits" CRLF);    
   167      printf("                               2: Skip highpass" CRLF);    
   168      printf("                               3: Skip highpass & lowpass (DC only)" CRLF);    
   169      printf(CRLF);
   170  
   171      printf("  -a alpha decode              0: Decode without alpha channel" CRLF);
   172      printf("                               1: Decode only alpha channel" CRLF);
   173      printf("                               2: Decode image & alpha (default)" CRLF);
   174      printf(CRLF);
   175  
   176      printf("  -p strength                  Post processing filter strength" CRLF);
   177      printf("                               0: None (default)" CRLF);
   178      printf("                               1: Light" CRLF);
   179      printf("                               2: Medium" CRLF);
   180      printf("                               3: Strong" CRLF);
   181      printf("                               4: Very strong" CRLF);
   182      printf(CRLF);
   183  
   184      printf("  -C                           Suppress overlapping boundary macro blocks" CRLF);
   185      printf("                               (Used for compressed domain tile extraction)" CRLF);
   186      printf(CRLF);
   187  
   188      printf("  -t                           Display timing information" CRLF);
   189      printf(CRLF);
   190  
   191      printf("  -v                           Display verbose decoder information" CRLF);
   192      printf(CRLF);
   193      printf("Eg: %s -i input.jxr -o output.bmp -c 0" CRLF, szExe);
   194  }
   195  
   196  void WmpDecAppShowArgs(WMPDECAPPARGS* args)
   197  {
   198  	GUID guidPF = args->guidPixFormat;
   199  
   200      printf("================================" CRLF);
   201      printf("Input file:     %s" CRLF, args->szInputFile);
   202      printf("Output file:    %s" CRLF, args->szOutputFile);
   203      printf("Color format:   %08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X" CRLF, 
   204          guidPF.Data1, guidPF.Data2, guidPF.Data3, guidPF.Data4[0], guidPF.Data4[1], guidPF.Data4[2],
   205          guidPF.Data4[3], guidPF.Data4[4], guidPF.Data4[5], guidPF.Data4[6], guidPF.Data4[7]);
   206      printf("Post processing strength: %d" CRLF, args->cPostProcStrength);
   207      printf("Thumbnail:      %d" CRLF, (int) args->tThumbnailFactor);
   208      printf("================================" CRLF);
   209  }
   210  
   211  //----------------------------------------------------------------
   212  void WmpDecAppInitDefaultArgs(WMPDECAPPARGS* args)
   213  {
   214      memset(args, 0, sizeof(*args));
   215      args->guidPixFormat = GUID_PKPixelFormatDontCare;
   216  //    args->bFlagRGB_BGR = FALSE; //default BGR
   217      args->bVerbose = FALSE;
   218      args->tThumbnailFactor = 0;
   219      args->oOrientation = O_NONE;
   220      args->cPostProcStrength = 0;
   221      args->uAlphaMode = 255;
   222      args->sbSubband = SB_ALL;
   223  }
   224  
   225  ERR WmpDecAppValidateArgs(WMPDECAPPARGS* args)
   226  {
   227      ERR err = WMP_errSuccess;
   228  
   229      Test(NULL != args->szInputFile, WMP_errInvalidParameter);
   230      Test(NULL != args->szOutputFile, WMP_errInvalidParameter);
   231      //Test(GUID_PKPixelFormatDontCare != args->enPixelFormat, WMP_errInvalidParameter);
   232  
   233  Cleanup:
   234      return err;
   235  }
   236  
   237  ERR WmpDecAppParseArgs(int argc, char* argv[], WMPDECAPPARGS* args)
   238  {
   239      ERR err = WMP_errSuccess;
   240  
   241      int c = 0, i = 1;
   242      // char* arg = NULL;
   243  
   244      static const PKPixelFormatGUID* pixelFormat[] =
   245      {
   246          &GUID_PKPixelFormat24bppRGB,
   247  
   248          &GUID_PKPixelFormatBlackWhite,
   249  
   250          &GUID_PKPixelFormat8bppGray,
   251          &GUID_PKPixelFormat16bppGray,
   252          &GUID_PKPixelFormat16bppGrayFixedPoint,
   253          &GUID_PKPixelFormat16bppGrayHalf,
   254          &GUID_PKPixelFormatDontCare, // &GUID_PKPixelFormat32bppGray,
   255          &GUID_PKPixelFormat32bppGrayFixedPoint,
   256          &GUID_PKPixelFormat32bppGrayFloat,
   257  
   258          &GUID_PKPixelFormat24bppRGB,
   259          &GUID_PKPixelFormat48bppRGB,
   260          &GUID_PKPixelFormat48bppRGBFixedPoint,
   261          &GUID_PKPixelFormat48bppRGBHalf,
   262          &GUID_PKPixelFormatDontCare, // &GUID_PKPixelFormat96bppRGB,
   263          &GUID_PKPixelFormat96bppRGBFixedPoint,
   264          &GUID_PKPixelFormat128bppRGBFloat,
   265  
   266          &GUID_PKPixelFormat32bppRGBE,
   267          &GUID_PKPixelFormat32bppCMYK,
   268          &GUID_PKPixelFormat64bppCMYK,
   269  
   270          &GUID_PKPixelFormat12bppYUV420, 
   271          &GUID_PKPixelFormat16bppYUV422,
   272          &GUID_PKPixelFormat24bppYUV444,
   273  
   274  //        &GUID_PKPixelFormat32bppRGBA,
   275          &GUID_PKPixelFormat32bppBGRA,
   276          &GUID_PKPixelFormat64bppRGBA,
   277          &GUID_PKPixelFormat64bppRGBAFixedPoint,
   278          &GUID_PKPixelFormat64bppRGBAHalf,
   279          &GUID_PKPixelFormatDontCare, // &GUID_PKPixelFormat128bppRGBA,
   280          &GUID_PKPixelFormat128bppRGBAFixedPoint,
   281          &GUID_PKPixelFormat128bppRGBAFloat,
   282          &GUID_PKPixelFormat16bppRGB555,
   283          &GUID_PKPixelFormat16bppRGB565,
   284          &GUID_PKPixelFormat32bppRGB101010,
   285          &GUID_PKPixelFormat40bppCMYKAlpha,
   286          &GUID_PKPixelFormat80bppCMYKAlpha,
   287          &GUID_PKPixelFormat32bppBGR,
   288          &GUID_PKPixelFormat32bppPBGRA,
   289          &GUID_PKPixelFormat64bppPRGBA,
   290          &GUID_PKPixelFormat128bppPRGBAFloat,
   291      };
   292  
   293      size_t InvalidPF[9] = {6, 13, 19, 20, 21, 26, 35, 36, 37};
   294      int k;
   295  
   296      WmpDecAppInitDefaultArgs(args);
   297  
   298      while(i < argc && argv[i][0] == '-')
   299  //    while (EOF != (c = argit(argc, argv, "i:o:c:ptv", &arg)))
   300      {
   301           /* separate out the no-argument switches */
   302          switch ((c = argv[i][1])) {
   303              case 't':
   304                  // NOOP - now we always print timing info
   305                  break;
   306  
   307              case 'v':
   308                  args->bVerbose = !FALSE;
   309                  break;
   310  
   311              case 'C':
   312                  args->bIgnoreOverlap = TRUE;
   313                  break;
   314              
   315              case 'f': 
   316                  args->bfBitstreamFormat = FREQUENCY;
   317                  break;
   318  
   319              default:
   320                  i ++;
   321                  if (i == argc || argv[i][0] == '-') // need more info
   322                      Call(WMP_errInvalidArgument);
   323                  
   324                  switch (c)
   325                  {
   326                  case 'i':
   327                      args->szInputFile= argv[i];
   328                      break;
   329  
   330                  case 'o':
   331                      args->szOutputFile = argv[i];
   332                      break;
   333                  
   334                  case 'p':
   335                      args->cPostProcStrength = (U8)atoi(argv[i]);
   336                      break;
   337  
   338                  case 'c':
   339                  {
   340                      size_t idxPF = (size_t)atol(argv[i]);
   341  
   342                      FailIf(sizeof2(pixelFormat) <= idxPF, WMP_errUnsupportedFormat);
   343  
   344                      for (k = 0; k < 9; k++)
   345                      {
   346                          if (InvalidPF[k] == idxPF)
   347                          {
   348                              printf("*** ERROR: Unsupported format in JPEG XR ***\n");
   349                              Call(WMP_errInvalidArgument);
   350                          }
   351                      }
   352  
   353                      args->guidPixFormat = *pixelFormat[idxPF];
   354  
   355                      break;
   356                  }
   357  
   358  /*                case 'R': 
   359                      args->bFlagRGB_BGR = (Bool)atoi(argv[i]);
   360                      break;
   361  */
   362                  case 'a': 
   363                      args->uAlphaMode = (U8)atoi(argv[i]);
   364                      break;
   365  
   366                  case 's': 
   367                      args->sbSubband = (SUBBAND)atoi(argv[i]);
   368                      break;
   369  
   370                  case 'r': // Region decode
   371                      if(i + 3 >= argc || argv[i + 1][0] == '-' || argv[i + 2][0] == '-' || argv[i + 3][0] == '-') // not a valid region
   372                          Call(WMP_errInvalidArgument);
   373  
   374                      args->rTopY = (size_t)atoi(argv[i]);
   375                      args->rLeftX = (size_t)atoi(argv[i + 1]);
   376                      args->rHeight = (size_t)atoi(argv[i + 2]);
   377                      args->rWidth = (size_t)atoi(argv[i + 3]);
   378                      i += 3;
   379  
   380                      break;
   381  
   382                  case 'T': // thumnail decode
   383                      args->tThumbnailFactor = (size_t)atoi(argv[i]);
   384                      if (args->tThumbnailFactor == 0) {  // skip flexbits
   385                          args->tThumbnailFactor = SKIPFLEXBITS;
   386                      }
   387                      break;
   388  
   389                  case 'O': // orientation
   390                      args->oOrientation = (atoi(argv[i]) < 8 ? atoi(argv[i]) : O_NONE);
   391                      break;
   392  
   393                  default:
   394                      Call(WMP_errInvalidArgument);
   395                      break;
   396              }
   397          }
   398  
   399          i ++;
   400      }
   401  
   402      Call(WmpDecAppValidateArgs(args));
   403  
   404  Cleanup:
   405      return err;
   406  }
   407  
   408  
   409  //================================================================
   410  // Encoder factory on file extension
   411  //================================================================
   412  ERR WmpDecAppCreateEncoderFromExt(
   413      PKCodecFactory* pCFactory,
   414      const char* szExt,
   415      PKImageEncode** ppIE)
   416  {
   417      ERR err = WMP_errSuccess;
   418      const PKIID* pIID = NULL;
   419  
   420      UNREFERENCED_PARAMETER( pCFactory );
   421  
   422      // get encod PKIID
   423      Call(GetTestEncodeIID(szExt, &pIID));
   424  
   425      // Create encoder
   426      Call(PKTestFactory_CreateCodec(pIID, ppIE));
   427  
   428  Cleanup:
   429      return err;
   430  }
   431  
   432  
   433  //================================================================
   434  // main function
   435  //================================================================
   436  int 
   437  #ifndef __ANSI__
   438  __cdecl
   439  #endif // __ANSI__
   440  main(int argc, char* argv[])
   441  {
   442      ERR err = WMP_errSuccess;
   443  
   444      PKFactory* pFactory = NULL;
   445      PKCodecFactory* pCodecFactory = NULL;
   446      PKImageDecode* pDecoder = NULL;
   447  
   448      WMPDECAPPARGS args = {0};
   449      char* pExt = NULL;
   450      U32 cFrame = 0;
   451      U32 i = 0;
   452      PKPixelInfo PI;
   453  //    static size_t cChannels[CFT_MAX] = {1, 3, 3, 3, 4, 4, -1, 3, 3, -1};
   454  
   455      //================================
   456      // parse command line parameters
   457      if (1 == argc)
   458      {
   459          WmpDecAppUsage(argv[0]);
   460          return 0;
   461      }
   462  
   463      Call(WmpDecAppParseArgs(argc, argv, &args));
   464      if (args.bVerbose)
   465      {
   466          WmpDecAppShowArgs(&args);
   467      }
   468  
   469      //================================
   470      pExt = strrchr(args.szOutputFile, '.');
   471      FailIf(NULL == pExt, WMP_errUnsupportedFormat);
   472  
   473      //================================
   474      Call(PKCreateFactory(&pFactory, PK_SDK_VERSION));
   475      
   476      Call(PKCreateCodecFactory(&pCodecFactory, WMP_SDK_VERSION));
   477      Call(pCodecFactory->CreateDecoderFromFile(args.szInputFile, &pDecoder));
   478  
   479      //==== set default color format
   480      if(IsEqualGUID(&args.guidPixFormat, &GUID_PKPixelFormatDontCare)) {
   481          // take deocder color format and try to look up better one
   482          // (e.g. 32bppBGR -> 24bppBGR etc.)
   483          PKPixelInfo newPI;
   484          newPI.pGUIDPixFmt = PI.pGUIDPixFmt = &pDecoder->guidPixFormat;
   485          Call(PixelFormatLookup(&newPI, LOOKUP_FORWARD));
   486          Call(PixelFormatLookup(&newPI, LOOKUP_BACKWARD_TIF));
   487          args.guidPixFormat = *newPI.pGUIDPixFmt;
   488      }
   489      else
   490          PI.pGUIDPixFmt = &args.guidPixFormat;
   491  
   492  //    pDecoder->WMP.wmiI.bRGB = args.bFlagRGB_BGR;
   493  
   494      // == color transcoding,
   495      if(IsEqualGUID(&args.guidPixFormat, &GUID_PKPixelFormat8bppGray) || IsEqualGUID(&args.guidPixFormat, &GUID_PKPixelFormat16bppGray)){ // ** => Y transcoding
   496          pDecoder->guidPixFormat = args.guidPixFormat;
   497          pDecoder->WMP.wmiI.cfColorFormat = Y_ONLY;
   498      }
   499      else if(IsEqualGUID(&args.guidPixFormat, &GUID_PKPixelFormat24bppRGB) && pDecoder->WMP.wmiI.cfColorFormat == CMYK){ // CMYK = > RGB
   500          pDecoder->WMP.wmiI.cfColorFormat = CF_RGB;
   501          pDecoder->guidPixFormat = args.guidPixFormat;
   502          pDecoder->WMP.wmiI.bRGB = 1; //RGB
   503      }
   504  
   505      PixelFormatLookup(&PI, LOOKUP_FORWARD);
   506  
   507      if(255 == args.uAlphaMode)//user didn't set
   508      {
   509          if(!!(PI.grBit & PK_pixfmtHasAlpha))
   510              args.uAlphaMode = 2;//default is image & alpha for formats with alpha
   511          else
   512              args.uAlphaMode = 0;//otherwise, 0
   513      }
   514  
   515      pDecoder->WMP.wmiSCP.bfBitstreamFormat = args.bfBitstreamFormat;
   516      pDecoder->WMP.wmiSCP.uAlphaMode = args.uAlphaMode;
   517      pDecoder->WMP.wmiSCP.sbSubband = args.sbSubband;
   518      pDecoder->WMP.bIgnoreOverlap = args.bIgnoreOverlap;
   519  
   520      pDecoder->WMP.wmiI.cfColorFormat = PI.cfColorFormat;
   521  
   522      pDecoder->WMP.wmiI.bdBitDepth = PI.bdBitDepth;
   523      pDecoder->WMP.wmiI.cBitsPerUnit = PI.cbitUnit;
   524  
   525      //==== Validate thumbnail decode parameters =====
   526      pDecoder->WMP.wmiI.cThumbnailWidth = pDecoder->WMP.wmiI.cWidth;
   527      pDecoder->WMP.wmiI.cThumbnailHeight = pDecoder->WMP.wmiI.cHeight;
   528      pDecoder->WMP.wmiI.bSkipFlexbits = FALSE;
   529      if(args.tThumbnailFactor > 0 && args.tThumbnailFactor != SKIPFLEXBITS){
   530          size_t tSize = ((size_t)1 << args.tThumbnailFactor);
   531          
   532          pDecoder->WMP.wmiI.cThumbnailWidth = (pDecoder->WMP.wmiI.cWidth + tSize - 1) / tSize;
   533          pDecoder->WMP.wmiI.cThumbnailHeight = (pDecoder->WMP.wmiI.cHeight + tSize - 1) / tSize;
   534  
   535          if(pDecoder->WMP.wmiI.cfColorFormat == YUV_420 || pDecoder->WMP.wmiI.cfColorFormat == YUV_422){ // unsupported thumbnail format
   536              pDecoder->WMP.wmiI.cfColorFormat = YUV_444;
   537          }
   538      }
   539      else if (args.tThumbnailFactor == SKIPFLEXBITS) {
   540          pDecoder->WMP.wmiI.bSkipFlexbits = TRUE;
   541      }
   542  
   543      if(args.rWidth == 0 || args.rHeight == 0){ // no region decode
   544          args.rLeftX = args.rTopY = 0;
   545          args.rWidth = pDecoder->WMP.wmiI.cThumbnailWidth;
   546          args.rHeight = pDecoder->WMP.wmiI.cThumbnailHeight;
   547      }
   548      pDecoder->WMP.wmiI.cROILeftX = args.rLeftX;
   549      pDecoder->WMP.wmiI.cROITopY = args.rTopY;
   550      pDecoder->WMP.wmiI.cROIWidth = args.rWidth;
   551      pDecoder->WMP.wmiI.cROIHeight = args.rHeight;
   552  
   553      pDecoder->WMP.wmiI.oOrientation = args.oOrientation;
   554  
   555      pDecoder->WMP.wmiI.cPostProcStrength = args.cPostProcStrength;
   556      
   557      pDecoder->WMP.wmiSCP.bVerbose = args.bVerbose;
   558  
   559      Call(pDecoder->GetFrameCount(pDecoder, &cFrame));
   560  
   561      //================================
   562      for (i = 0; ; ++i)
   563      {
   564          struct WMPStream* pEncodeStream = NULL;
   565          PKImageEncode* pEncoder = NULL;
   566  
   567          PKFormatConverter* pConverter = NULL;
   568  
   569          Float rX = 0.0, rY = 0.0;
   570          PKRect rect = {0, 0, 0, 0};
   571  
   572          //================================
   573          Call(pCodecFactory->CreateFormatConverter(&pConverter));
   574  
   575          Call(pConverter->Initialize(pConverter, pDecoder, pExt, args.guidPixFormat));
   576  
   577          //================================
   578          Call(pFactory->CreateStreamFromFilename(&pEncodeStream, args.szOutputFile, "wb"));
   579          Call(WmpDecAppCreateEncoderFromExt(pCodecFactory, pExt, &pEncoder));
   580  
   581  		if(pEncoder->bWMP)
   582  			Call(pEncoder->Initialize(pEncoder, pEncodeStream, &args.wmiSCP, sizeof(args.wmiSCP)));
   583  		else
   584  			Call(pEncoder->Initialize(pEncoder, pEncodeStream, NULL, 0));
   585  
   586          //================================
   587          Call(pEncoder->SetPixelFormat(pEncoder, args.guidPixFormat));
   588          pEncoder->WMP.wmiSCP.bBlackWhite = pDecoder->WMP.wmiSCP.bBlackWhite;
   589  
   590          //Call(pDecoder->GetSize(pDecoder, &rect.Width, &rect.Height));
   591          rect.Width = (I32)(pDecoder->WMP.wmiI.cROIWidth);
   592          rect.Height = (I32)(pDecoder->WMP.wmiI.cROIHeight);
   593  
   594          if(args.oOrientation > O_FLIPVH){ // allocate memory for rotated image!
   595              I32 bah = rect.Width;
   596  
   597              rect.Width = rect.Height;
   598              rect.Height = bah;
   599          }
   600  
   601          Call(pEncoder->SetSize(pEncoder, rect.Width, rect.Height));
   602  
   603          Call(pDecoder->GetResolution(pDecoder, &rX, &rY));
   604          if(args.oOrientation > O_FLIPVH) 
   605              Call(pEncoder->SetResolution(pEncoder, rY, rX));
   606          else
   607              Call(pEncoder->SetResolution(pEncoder, rX, rY));
   608  
   609          if(pEncoder->bWMP && args.tThumbnailFactor > 0){
   610              printf("-T can not be used for compressed domain operation!\n");
   611              return 0;
   612          }
   613  
   614          //================================
   615  		pEncoder->WriteSource = PKImageEncode_Transcode;
   616          Call(pEncoder->WriteSource(pEncoder, pConverter, &rect));
   617  
   618          //================================
   619  //        Call(pEncoder->Terminate(pEncoder));
   620          pEncoder->Release(&pEncoder);
   621  
   622          // multi-frame support NYI
   623          if (i + 1 == cFrame)
   624          {
   625              break;
   626          }
   627  
   628          Call(pDecoder->SelectFrame(pDecoder, i + 1));
   629      }
   630  
   631      pDecoder->Release(&pDecoder);
   632  
   633  Cleanup:
   634      if (WMP_errUnsupportedFormat == err)
   635      {
   636          printf("*** ERROR: Unsupported format in JPEG XR ***\n");
   637      }
   638      else if (WMP_errSuccess != err)
   639      {
   640          WmpDecAppUsage(argv[0]);
   641      }
   642      
   643      return (int)err;
   644  }