mirror of
https://github.com/ValveSoftware/Proton.git
synced 2024-12-27 23:25:50 +03:00
645 lines
23 KiB
C
645 lines
23 KiB
C
//*@@@+++@@@@******************************************************************
|
|
//
|
|
// Copyright © Microsoft Corp.
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are met:
|
|
//
|
|
// • Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
// • Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
//*@@@---@@@@******************************************************************
|
|
#include <JXRTest.h>
|
|
#include <time.h>
|
|
|
|
|
|
//================================================================
|
|
static const size_t SKIPFLEXBITS = 0xff;
|
|
|
|
//================================================================
|
|
// Command line argument support
|
|
//================================================================
|
|
typedef struct tagWMPDECAPPARGS
|
|
{
|
|
char* szInputFile;
|
|
char* szOutputFile;
|
|
|
|
Bool bVerbose;
|
|
|
|
PKPixelFormatGUID guidPixFormat;
|
|
// Bool bFlagRGB_BGR;
|
|
|
|
// region decode
|
|
size_t rLeftX;
|
|
size_t rTopY;
|
|
size_t rWidth;
|
|
size_t rHeight;
|
|
|
|
// thumbnail
|
|
size_t tThumbnailFactor;
|
|
|
|
// orientation
|
|
ORIENTATION oOrientation;
|
|
|
|
// post processing
|
|
U8 cPostProcStrength;
|
|
|
|
U8 uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha
|
|
|
|
SUBBAND sbSubband; // which subbands to keep (for transcoding)
|
|
|
|
BITSTREAMFORMAT bfBitstreamFormat; // desired bitsream format (for transcoding)
|
|
|
|
CWMIStrCodecParam wmiSCP;
|
|
|
|
Bool bIgnoreOverlap;
|
|
} WMPDECAPPARGS;
|
|
|
|
//----------------------------------------------------------------
|
|
void WmpDecAppUsage(const char* szExe)
|
|
{
|
|
printf(CRLF);
|
|
printf("JPEG XR Decoder Utility" CRLF);
|
|
printf("Copyright 2013 Microsoft Corporation - All Rights Reserved" CRLF);
|
|
printf(CRLF);
|
|
printf("%s [options]..." CRLF, szExe);
|
|
printf(CRLF);
|
|
printf(" -i input.jxr/wdp Input JPEG XR/HD Photo file name" CRLF);
|
|
printf(CRLF);
|
|
printf(" -o output.bmp/tif/jxr Output image file name" CRLF);
|
|
printf(" bmp: <=8bpc, BGR" CRLF);
|
|
printf(" tif: >=8bpc, RGB" CRLF);
|
|
printf(" jxr: for compressed domain transcode" CRLF);
|
|
printf(CRLF);
|
|
|
|
printf(" -c format Specifies the uncompressed output format" CRLF);
|
|
printf(" 0: 24bppBGR" CRLF);
|
|
printf(" 1: 1bppBlackWhite" CRLF);
|
|
printf(" 2: 8bppGray" CRLF);
|
|
printf(" 3: 16bppGray" CRLF);
|
|
printf(" 4: 16bppGrayFixedPoint" CRLF);
|
|
printf(" 5: 16bppGrayHalf" CRLF);
|
|
// printf(" 6: 32bppGray" CRLF);
|
|
printf(" 7: 32bppGrayFixedPoint" CRLF);
|
|
printf(" 8: 32bppGrayFloat" CRLF);
|
|
|
|
printf(" 9: 24bppRGB" CRLF);
|
|
printf(" 10: 48bppRGB" CRLF);
|
|
printf(" 11: 48bppRGBFixedPoint" CRLF);
|
|
printf(" 12: 48bppRGBHalf" CRLF);
|
|
// printf(" 13: 96bppRGB" CRLF);
|
|
printf(" 14: 96bppRGBFixedPoint" CRLF);
|
|
printf(" 15: 128bppRGBFloat" CRLF);
|
|
|
|
printf(" 16: 32bppRGBE" CRLF);
|
|
|
|
printf(" 17: 32bppCMYK" CRLF);
|
|
printf(" 18: 64bppCMYK" CRLF);
|
|
|
|
/*
|
|
printf(" 19 - YUV 420" CRLF);
|
|
printf(" 20 - YUV 422" CRLF);
|
|
printf(" 21 - YUV 444" CRLF);
|
|
*/
|
|
printf(" 22: 32bppBGRA" CRLF);
|
|
printf(" 23: 64bppRGBA" CRLF);
|
|
printf(" 24: 64bppRGBAFixedPoint" CRLF);
|
|
printf(" 25: 64bppRGBAHalf" CRLF);
|
|
// printf(" 26 - 128bpp RGBA" CRLF);
|
|
printf(" 27: 128bppRGBAFixedPoint" CRLF);
|
|
printf(" 28: 128bppRGBAFloat" CRLF);
|
|
|
|
printf(" 29: 16bppBGR555" CRLF);
|
|
printf(" 30: 16bppBGR565" CRLF);
|
|
printf(" 31: 32bppBGR101010" CRLF);
|
|
//printf(" 101..116 - 1..16 channel 8bpp" CRLF);
|
|
printf(" 32: 40bppCMYKA" CRLF);
|
|
printf(" 33: 80bppCMYKA" CRLF);
|
|
|
|
printf(" 34: 32bppBGR" CRLF);
|
|
/*
|
|
printf(" 35: 32bppPBGRA" CRLF);
|
|
printf(" 36: 64bppPRGBA" CRLF);
|
|
printf(" 37: 128bppPRGBA Float" CRLF);
|
|
*/
|
|
printf(CRLF);
|
|
|
|
printf(" -r top left height width Specifies the rectangle for region decode" CRLF);
|
|
printf(CRLF);
|
|
printf(" -T m Reduced resolution (mipmap) decode" CRLF);
|
|
printf(" 0: Full resolution (default)" CRLF);
|
|
printf(" 1: 1/2 res (down-sampled from full res)" CRLF);
|
|
printf(" 2: 1/4 res (native decode)" CRLF);
|
|
printf(" 3: 1/8 res (down-sampled from 1/4 res)" CRLF);
|
|
printf(" 4: 1/16 res (native decode)" CRLF);
|
|
printf(" >4: 1/(2^m) res (down-sampled from 1/16 res) " CRLF);
|
|
printf(CRLF);
|
|
|
|
printf(" -O orientation 0: No transformation (default)" CRLF);
|
|
printf(" 1: Flip vertically" CRLF);
|
|
printf(" 2: Flip horizontally" CRLF);
|
|
printf(" 3: Flip vertically & horizontally" CRLF);
|
|
printf(" 4: Rotate 90 degrees CW" CRLF);
|
|
printf(" 5: Rotate 90 degrees CW & flip vertically" CRLF);
|
|
printf(" 6: Rotate 90 degrees CW & flip horizontally" CRLF);
|
|
printf(" 7: Rotate 90 degrees CW & flip vert & horiz" CRLF);
|
|
printf(CRLF);
|
|
|
|
printf(" -s skip subbands Used for compressed domain transcoding" CRLF);
|
|
printf(" 0: All subbands included (default)" CRLF);
|
|
printf(" 1: Skip flexbits" CRLF);
|
|
printf(" 2: Skip highpass" CRLF);
|
|
printf(" 3: Skip highpass & lowpass (DC only)" CRLF);
|
|
printf(CRLF);
|
|
|
|
printf(" -a alpha decode 0: Decode without alpha channel" CRLF);
|
|
printf(" 1: Decode only alpha channel" CRLF);
|
|
printf(" 2: Decode image & alpha (default)" CRLF);
|
|
printf(CRLF);
|
|
|
|
printf(" -p strength Post processing filter strength" CRLF);
|
|
printf(" 0: None (default)" CRLF);
|
|
printf(" 1: Light" CRLF);
|
|
printf(" 2: Medium" CRLF);
|
|
printf(" 3: Strong" CRLF);
|
|
printf(" 4: Very strong" CRLF);
|
|
printf(CRLF);
|
|
|
|
printf(" -C Suppress overlapping boundary macro blocks" CRLF);
|
|
printf(" (Used for compressed domain tile extraction)" CRLF);
|
|
printf(CRLF);
|
|
|
|
printf(" -t Display timing information" CRLF);
|
|
printf(CRLF);
|
|
|
|
printf(" -v Display verbose decoder information" CRLF);
|
|
printf(CRLF);
|
|
printf("Eg: %s -i input.jxr -o output.bmp -c 0" CRLF, szExe);
|
|
}
|
|
|
|
void WmpDecAppShowArgs(WMPDECAPPARGS* args)
|
|
{
|
|
GUID guidPF = args->guidPixFormat;
|
|
|
|
printf("================================" CRLF);
|
|
printf("Input file: %s" CRLF, args->szInputFile);
|
|
printf("Output file: %s" CRLF, args->szOutputFile);
|
|
printf("Color format: %08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X" CRLF,
|
|
guidPF.Data1, guidPF.Data2, guidPF.Data3, guidPF.Data4[0], guidPF.Data4[1], guidPF.Data4[2],
|
|
guidPF.Data4[3], guidPF.Data4[4], guidPF.Data4[5], guidPF.Data4[6], guidPF.Data4[7]);
|
|
printf("Post processing strength: %d" CRLF, args->cPostProcStrength);
|
|
printf("Thumbnail: %d" CRLF, (int) args->tThumbnailFactor);
|
|
printf("================================" CRLF);
|
|
}
|
|
|
|
//----------------------------------------------------------------
|
|
void WmpDecAppInitDefaultArgs(WMPDECAPPARGS* args)
|
|
{
|
|
memset(args, 0, sizeof(*args));
|
|
args->guidPixFormat = GUID_PKPixelFormatDontCare;
|
|
// args->bFlagRGB_BGR = FALSE; //default BGR
|
|
args->bVerbose = FALSE;
|
|
args->tThumbnailFactor = 0;
|
|
args->oOrientation = O_NONE;
|
|
args->cPostProcStrength = 0;
|
|
args->uAlphaMode = 255;
|
|
args->sbSubband = SB_ALL;
|
|
}
|
|
|
|
ERR WmpDecAppValidateArgs(WMPDECAPPARGS* args)
|
|
{
|
|
ERR err = WMP_errSuccess;
|
|
|
|
Test(NULL != args->szInputFile, WMP_errInvalidParameter);
|
|
Test(NULL != args->szOutputFile, WMP_errInvalidParameter);
|
|
//Test(GUID_PKPixelFormatDontCare != args->enPixelFormat, WMP_errInvalidParameter);
|
|
|
|
Cleanup:
|
|
return err;
|
|
}
|
|
|
|
ERR WmpDecAppParseArgs(int argc, char* argv[], WMPDECAPPARGS* args)
|
|
{
|
|
ERR err = WMP_errSuccess;
|
|
|
|
int c = 0, i = 1;
|
|
// char* arg = NULL;
|
|
|
|
static const PKPixelFormatGUID* pixelFormat[] =
|
|
{
|
|
&GUID_PKPixelFormat24bppRGB,
|
|
|
|
&GUID_PKPixelFormatBlackWhite,
|
|
|
|
&GUID_PKPixelFormat8bppGray,
|
|
&GUID_PKPixelFormat16bppGray,
|
|
&GUID_PKPixelFormat16bppGrayFixedPoint,
|
|
&GUID_PKPixelFormat16bppGrayHalf,
|
|
&GUID_PKPixelFormatDontCare, // &GUID_PKPixelFormat32bppGray,
|
|
&GUID_PKPixelFormat32bppGrayFixedPoint,
|
|
&GUID_PKPixelFormat32bppGrayFloat,
|
|
|
|
&GUID_PKPixelFormat24bppRGB,
|
|
&GUID_PKPixelFormat48bppRGB,
|
|
&GUID_PKPixelFormat48bppRGBFixedPoint,
|
|
&GUID_PKPixelFormat48bppRGBHalf,
|
|
&GUID_PKPixelFormatDontCare, // &GUID_PKPixelFormat96bppRGB,
|
|
&GUID_PKPixelFormat96bppRGBFixedPoint,
|
|
&GUID_PKPixelFormat128bppRGBFloat,
|
|
|
|
&GUID_PKPixelFormat32bppRGBE,
|
|
&GUID_PKPixelFormat32bppCMYK,
|
|
&GUID_PKPixelFormat64bppCMYK,
|
|
|
|
&GUID_PKPixelFormat12bppYUV420,
|
|
&GUID_PKPixelFormat16bppYUV422,
|
|
&GUID_PKPixelFormat24bppYUV444,
|
|
|
|
// &GUID_PKPixelFormat32bppRGBA,
|
|
&GUID_PKPixelFormat32bppBGRA,
|
|
&GUID_PKPixelFormat64bppRGBA,
|
|
&GUID_PKPixelFormat64bppRGBAFixedPoint,
|
|
&GUID_PKPixelFormat64bppRGBAHalf,
|
|
&GUID_PKPixelFormatDontCare, // &GUID_PKPixelFormat128bppRGBA,
|
|
&GUID_PKPixelFormat128bppRGBAFixedPoint,
|
|
&GUID_PKPixelFormat128bppRGBAFloat,
|
|
&GUID_PKPixelFormat16bppRGB555,
|
|
&GUID_PKPixelFormat16bppRGB565,
|
|
&GUID_PKPixelFormat32bppRGB101010,
|
|
&GUID_PKPixelFormat40bppCMYKAlpha,
|
|
&GUID_PKPixelFormat80bppCMYKAlpha,
|
|
&GUID_PKPixelFormat32bppBGR,
|
|
&GUID_PKPixelFormat32bppPBGRA,
|
|
&GUID_PKPixelFormat64bppPRGBA,
|
|
&GUID_PKPixelFormat128bppPRGBAFloat,
|
|
};
|
|
|
|
size_t InvalidPF[9] = {6, 13, 19, 20, 21, 26, 35, 36, 37};
|
|
int k;
|
|
|
|
WmpDecAppInitDefaultArgs(args);
|
|
|
|
while(i < argc && argv[i][0] == '-')
|
|
// while (EOF != (c = argit(argc, argv, "i:o:c:ptv", &arg)))
|
|
{
|
|
/* separate out the no-argument switches */
|
|
switch ((c = argv[i][1])) {
|
|
case 't':
|
|
// NOOP - now we always print timing info
|
|
break;
|
|
|
|
case 'v':
|
|
args->bVerbose = !FALSE;
|
|
break;
|
|
|
|
case 'C':
|
|
args->bIgnoreOverlap = TRUE;
|
|
break;
|
|
|
|
case 'f':
|
|
args->bfBitstreamFormat = FREQUENCY;
|
|
break;
|
|
|
|
default:
|
|
i ++;
|
|
if (i == argc || argv[i][0] == '-') // need more info
|
|
Call(WMP_errInvalidArgument);
|
|
|
|
switch (c)
|
|
{
|
|
case 'i':
|
|
args->szInputFile= argv[i];
|
|
break;
|
|
|
|
case 'o':
|
|
args->szOutputFile = argv[i];
|
|
break;
|
|
|
|
case 'p':
|
|
args->cPostProcStrength = (U8)atoi(argv[i]);
|
|
break;
|
|
|
|
case 'c':
|
|
{
|
|
size_t idxPF = (size_t)atol(argv[i]);
|
|
|
|
FailIf(sizeof2(pixelFormat) <= idxPF, WMP_errUnsupportedFormat);
|
|
|
|
for (k = 0; k < 9; k++)
|
|
{
|
|
if (InvalidPF[k] == idxPF)
|
|
{
|
|
printf("*** ERROR: Unsupported format in JPEG XR ***\n");
|
|
Call(WMP_errInvalidArgument);
|
|
}
|
|
}
|
|
|
|
args->guidPixFormat = *pixelFormat[idxPF];
|
|
|
|
break;
|
|
}
|
|
|
|
/* case 'R':
|
|
args->bFlagRGB_BGR = (Bool)atoi(argv[i]);
|
|
break;
|
|
*/
|
|
case 'a':
|
|
args->uAlphaMode = (U8)atoi(argv[i]);
|
|
break;
|
|
|
|
case 's':
|
|
args->sbSubband = (SUBBAND)atoi(argv[i]);
|
|
break;
|
|
|
|
case 'r': // Region decode
|
|
if(i + 3 >= argc || argv[i + 1][0] == '-' || argv[i + 2][0] == '-' || argv[i + 3][0] == '-') // not a valid region
|
|
Call(WMP_errInvalidArgument);
|
|
|
|
args->rTopY = (size_t)atoi(argv[i]);
|
|
args->rLeftX = (size_t)atoi(argv[i + 1]);
|
|
args->rHeight = (size_t)atoi(argv[i + 2]);
|
|
args->rWidth = (size_t)atoi(argv[i + 3]);
|
|
i += 3;
|
|
|
|
break;
|
|
|
|
case 'T': // thumnail decode
|
|
args->tThumbnailFactor = (size_t)atoi(argv[i]);
|
|
if (args->tThumbnailFactor == 0) { // skip flexbits
|
|
args->tThumbnailFactor = SKIPFLEXBITS;
|
|
}
|
|
break;
|
|
|
|
case 'O': // orientation
|
|
args->oOrientation = (atoi(argv[i]) < 8 ? atoi(argv[i]) : O_NONE);
|
|
break;
|
|
|
|
default:
|
|
Call(WMP_errInvalidArgument);
|
|
break;
|
|
}
|
|
}
|
|
|
|
i ++;
|
|
}
|
|
|
|
Call(WmpDecAppValidateArgs(args));
|
|
|
|
Cleanup:
|
|
return err;
|
|
}
|
|
|
|
|
|
//================================================================
|
|
// Encoder factory on file extension
|
|
//================================================================
|
|
ERR WmpDecAppCreateEncoderFromExt(
|
|
PKCodecFactory* pCFactory,
|
|
const char* szExt,
|
|
PKImageEncode** ppIE)
|
|
{
|
|
ERR err = WMP_errSuccess;
|
|
const PKIID* pIID = NULL;
|
|
|
|
UNREFERENCED_PARAMETER( pCFactory );
|
|
|
|
// get encod PKIID
|
|
Call(GetTestEncodeIID(szExt, &pIID));
|
|
|
|
// Create encoder
|
|
Call(PKTestFactory_CreateCodec(pIID, ppIE));
|
|
|
|
Cleanup:
|
|
return err;
|
|
}
|
|
|
|
|
|
//================================================================
|
|
// main function
|
|
//================================================================
|
|
int
|
|
#ifndef __ANSI__
|
|
__cdecl
|
|
#endif // __ANSI__
|
|
main(int argc, char* argv[])
|
|
{
|
|
ERR err = WMP_errSuccess;
|
|
|
|
PKFactory* pFactory = NULL;
|
|
PKCodecFactory* pCodecFactory = NULL;
|
|
PKImageDecode* pDecoder = NULL;
|
|
|
|
WMPDECAPPARGS args = {0};
|
|
char* pExt = NULL;
|
|
U32 cFrame = 0;
|
|
U32 i = 0;
|
|
PKPixelInfo PI;
|
|
// static size_t cChannels[CFT_MAX] = {1, 3, 3, 3, 4, 4, -1, 3, 3, -1};
|
|
|
|
//================================
|
|
// parse command line parameters
|
|
if (1 == argc)
|
|
{
|
|
WmpDecAppUsage(argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
Call(WmpDecAppParseArgs(argc, argv, &args));
|
|
if (args.bVerbose)
|
|
{
|
|
WmpDecAppShowArgs(&args);
|
|
}
|
|
|
|
//================================
|
|
pExt = strrchr(args.szOutputFile, '.');
|
|
FailIf(NULL == pExt, WMP_errUnsupportedFormat);
|
|
|
|
//================================
|
|
Call(PKCreateFactory(&pFactory, PK_SDK_VERSION));
|
|
|
|
Call(PKCreateCodecFactory(&pCodecFactory, WMP_SDK_VERSION));
|
|
Call(pCodecFactory->CreateDecoderFromFile(args.szInputFile, &pDecoder));
|
|
|
|
//==== set default color format
|
|
if(IsEqualGUID(&args.guidPixFormat, &GUID_PKPixelFormatDontCare)) {
|
|
// take deocder color format and try to look up better one
|
|
// (e.g. 32bppBGR -> 24bppBGR etc.)
|
|
PKPixelInfo newPI;
|
|
newPI.pGUIDPixFmt = PI.pGUIDPixFmt = &pDecoder->guidPixFormat;
|
|
Call(PixelFormatLookup(&newPI, LOOKUP_FORWARD));
|
|
Call(PixelFormatLookup(&newPI, LOOKUP_BACKWARD_TIF));
|
|
args.guidPixFormat = *newPI.pGUIDPixFmt;
|
|
}
|
|
else
|
|
PI.pGUIDPixFmt = &args.guidPixFormat;
|
|
|
|
// pDecoder->WMP.wmiI.bRGB = args.bFlagRGB_BGR;
|
|
|
|
// == color transcoding,
|
|
if(IsEqualGUID(&args.guidPixFormat, &GUID_PKPixelFormat8bppGray) || IsEqualGUID(&args.guidPixFormat, &GUID_PKPixelFormat16bppGray)){ // ** => Y transcoding
|
|
pDecoder->guidPixFormat = args.guidPixFormat;
|
|
pDecoder->WMP.wmiI.cfColorFormat = Y_ONLY;
|
|
}
|
|
else if(IsEqualGUID(&args.guidPixFormat, &GUID_PKPixelFormat24bppRGB) && pDecoder->WMP.wmiI.cfColorFormat == CMYK){ // CMYK = > RGB
|
|
pDecoder->WMP.wmiI.cfColorFormat = CF_RGB;
|
|
pDecoder->guidPixFormat = args.guidPixFormat;
|
|
pDecoder->WMP.wmiI.bRGB = 1; //RGB
|
|
}
|
|
|
|
PixelFormatLookup(&PI, LOOKUP_FORWARD);
|
|
|
|
if(255 == args.uAlphaMode)//user didn't set
|
|
{
|
|
if(!!(PI.grBit & PK_pixfmtHasAlpha))
|
|
args.uAlphaMode = 2;//default is image & alpha for formats with alpha
|
|
else
|
|
args.uAlphaMode = 0;//otherwise, 0
|
|
}
|
|
|
|
pDecoder->WMP.wmiSCP.bfBitstreamFormat = args.bfBitstreamFormat;
|
|
pDecoder->WMP.wmiSCP.uAlphaMode = args.uAlphaMode;
|
|
pDecoder->WMP.wmiSCP.sbSubband = args.sbSubband;
|
|
pDecoder->WMP.bIgnoreOverlap = args.bIgnoreOverlap;
|
|
|
|
pDecoder->WMP.wmiI.cfColorFormat = PI.cfColorFormat;
|
|
|
|
pDecoder->WMP.wmiI.bdBitDepth = PI.bdBitDepth;
|
|
pDecoder->WMP.wmiI.cBitsPerUnit = PI.cbitUnit;
|
|
|
|
//==== Validate thumbnail decode parameters =====
|
|
pDecoder->WMP.wmiI.cThumbnailWidth = pDecoder->WMP.wmiI.cWidth;
|
|
pDecoder->WMP.wmiI.cThumbnailHeight = pDecoder->WMP.wmiI.cHeight;
|
|
pDecoder->WMP.wmiI.bSkipFlexbits = FALSE;
|
|
if(args.tThumbnailFactor > 0 && args.tThumbnailFactor != SKIPFLEXBITS){
|
|
size_t tSize = ((size_t)1 << args.tThumbnailFactor);
|
|
|
|
pDecoder->WMP.wmiI.cThumbnailWidth = (pDecoder->WMP.wmiI.cWidth + tSize - 1) / tSize;
|
|
pDecoder->WMP.wmiI.cThumbnailHeight = (pDecoder->WMP.wmiI.cHeight + tSize - 1) / tSize;
|
|
|
|
if(pDecoder->WMP.wmiI.cfColorFormat == YUV_420 || pDecoder->WMP.wmiI.cfColorFormat == YUV_422){ // unsupported thumbnail format
|
|
pDecoder->WMP.wmiI.cfColorFormat = YUV_444;
|
|
}
|
|
}
|
|
else if (args.tThumbnailFactor == SKIPFLEXBITS) {
|
|
pDecoder->WMP.wmiI.bSkipFlexbits = TRUE;
|
|
}
|
|
|
|
if(args.rWidth == 0 || args.rHeight == 0){ // no region decode
|
|
args.rLeftX = args.rTopY = 0;
|
|
args.rWidth = pDecoder->WMP.wmiI.cThumbnailWidth;
|
|
args.rHeight = pDecoder->WMP.wmiI.cThumbnailHeight;
|
|
}
|
|
pDecoder->WMP.wmiI.cROILeftX = args.rLeftX;
|
|
pDecoder->WMP.wmiI.cROITopY = args.rTopY;
|
|
pDecoder->WMP.wmiI.cROIWidth = args.rWidth;
|
|
pDecoder->WMP.wmiI.cROIHeight = args.rHeight;
|
|
|
|
pDecoder->WMP.wmiI.oOrientation = args.oOrientation;
|
|
|
|
pDecoder->WMP.wmiI.cPostProcStrength = args.cPostProcStrength;
|
|
|
|
pDecoder->WMP.wmiSCP.bVerbose = args.bVerbose;
|
|
|
|
Call(pDecoder->GetFrameCount(pDecoder, &cFrame));
|
|
|
|
//================================
|
|
for (i = 0; ; ++i)
|
|
{
|
|
struct WMPStream* pEncodeStream = NULL;
|
|
PKImageEncode* pEncoder = NULL;
|
|
|
|
PKFormatConverter* pConverter = NULL;
|
|
|
|
Float rX = 0.0, rY = 0.0;
|
|
PKRect rect = {0, 0, 0, 0};
|
|
|
|
//================================
|
|
Call(pCodecFactory->CreateFormatConverter(&pConverter));
|
|
|
|
Call(pConverter->Initialize(pConverter, pDecoder, pExt, args.guidPixFormat));
|
|
|
|
//================================
|
|
Call(pFactory->CreateStreamFromFilename(&pEncodeStream, args.szOutputFile, "wb"));
|
|
Call(WmpDecAppCreateEncoderFromExt(pCodecFactory, pExt, &pEncoder));
|
|
|
|
if(pEncoder->bWMP)
|
|
Call(pEncoder->Initialize(pEncoder, pEncodeStream, &args.wmiSCP, sizeof(args.wmiSCP)));
|
|
else
|
|
Call(pEncoder->Initialize(pEncoder, pEncodeStream, NULL, 0));
|
|
|
|
//================================
|
|
Call(pEncoder->SetPixelFormat(pEncoder, args.guidPixFormat));
|
|
pEncoder->WMP.wmiSCP.bBlackWhite = pDecoder->WMP.wmiSCP.bBlackWhite;
|
|
|
|
//Call(pDecoder->GetSize(pDecoder, &rect.Width, &rect.Height));
|
|
rect.Width = (I32)(pDecoder->WMP.wmiI.cROIWidth);
|
|
rect.Height = (I32)(pDecoder->WMP.wmiI.cROIHeight);
|
|
|
|
if(args.oOrientation > O_FLIPVH){ // allocate memory for rotated image!
|
|
I32 bah = rect.Width;
|
|
|
|
rect.Width = rect.Height;
|
|
rect.Height = bah;
|
|
}
|
|
|
|
Call(pEncoder->SetSize(pEncoder, rect.Width, rect.Height));
|
|
|
|
Call(pDecoder->GetResolution(pDecoder, &rX, &rY));
|
|
if(args.oOrientation > O_FLIPVH)
|
|
Call(pEncoder->SetResolution(pEncoder, rY, rX));
|
|
else
|
|
Call(pEncoder->SetResolution(pEncoder, rX, rY));
|
|
|
|
if(pEncoder->bWMP && args.tThumbnailFactor > 0){
|
|
printf("-T can not be used for compressed domain operation!\n");
|
|
return 0;
|
|
}
|
|
|
|
//================================
|
|
pEncoder->WriteSource = PKImageEncode_Transcode;
|
|
Call(pEncoder->WriteSource(pEncoder, pConverter, &rect));
|
|
|
|
//================================
|
|
// Call(pEncoder->Terminate(pEncoder));
|
|
pEncoder->Release(&pEncoder);
|
|
|
|
// multi-frame support NYI
|
|
if (i + 1 == cFrame)
|
|
{
|
|
break;
|
|
}
|
|
|
|
Call(pDecoder->SelectFrame(pDecoder, i + 1));
|
|
}
|
|
|
|
pDecoder->Release(&pDecoder);
|
|
|
|
Cleanup:
|
|
if (WMP_errUnsupportedFormat == err)
|
|
{
|
|
printf("*** ERROR: Unsupported format in JPEG XR ***\n");
|
|
}
|
|
else if (WMP_errSuccess != err)
|
|
{
|
|
WmpDecAppUsage(argv[0]);
|
|
}
|
|
|
|
return (int)err;
|
|
}
|