mirror of
https://git.suyu.dev/suyu/Yucom.git
synced 2026-01-06 06:28:00 +01:00
jxrlib: Add library sources
This commit is contained in:
parent
9a746c257e
commit
d9d777072a
63 changed files with 37177 additions and 0 deletions
315
jxrlib/jxrtestlib/JXRTest.c
Normal file
315
jxrlib/jxrtestlib/JXRTest.c
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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>
|
||||
|
||||
//================================================================
|
||||
const PKIID IID_PKImagePnmEncode = 102;
|
||||
const PKIID IID_PKImageBmpEncode = 103;
|
||||
const PKIID IID_PKImageTifEncode = 104;
|
||||
const PKIID IID_PKImageHdrEncode = 105;
|
||||
const PKIID IID_PKImageIyuvEncode = 106;
|
||||
const PKIID IID_PKImageYuv422Encode = 107;
|
||||
const PKIID IID_PKImageYuv444Encode = 108;
|
||||
|
||||
const PKIID IID_PKImageBmpDecode = 202;
|
||||
const PKIID IID_PKImagePnmDecode = 203;
|
||||
const PKIID IID_PKImageTifDecode = 204;
|
||||
const PKIID IID_PKImageHdrDecode = 205;
|
||||
const PKIID IID_PKImageIyuvDecode = 206;
|
||||
const PKIID IID_PKImageYuv422Decode = 207;
|
||||
const PKIID IID_PKImageYuv444Decode = 208;
|
||||
|
||||
//================================================================
|
||||
// Misc supporting functions
|
||||
//================================================================
|
||||
extern int PKStrnicmp(const char* s1, const char* s2, size_t c);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
typedef struct tagPKIIDInfo
|
||||
{
|
||||
const char* szExt;
|
||||
const PKIID* pIIDEnc;
|
||||
const PKIID* pIIDDec;
|
||||
} PKIIDInfo;
|
||||
|
||||
static ERR GetTestInfo(const char* szExt, const PKIIDInfo** ppInfo)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
static PKIIDInfo iidInfo[] = {
|
||||
{".bmp", &IID_PKImageBmpEncode, &IID_PKImageBmpDecode},
|
||||
{".ppm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode},
|
||||
{".pgm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode},
|
||||
{".pnm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode},
|
||||
{".pfm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode},
|
||||
{".tif", &IID_PKImageTifEncode, &IID_PKImageTifDecode},
|
||||
{".hdr", &IID_PKImageHdrEncode, &IID_PKImageHdrDecode},
|
||||
{".iyuv", &IID_PKImageIyuvEncode, &IID_PKImageIyuvDecode},
|
||||
{".yuv422", &IID_PKImageYuv422Encode, &IID_PKImageYuv422Decode},
|
||||
{".yuv444", &IID_PKImageYuv444Encode, &IID_PKImageYuv444Decode},
|
||||
};
|
||||
size_t i = 0;
|
||||
|
||||
*ppInfo = NULL;
|
||||
for (i = 0; i < sizeof2(iidInfo); ++i)
|
||||
{
|
||||
if (0 == PKStrnicmp(szExt, iidInfo[i].szExt, strlen(iidInfo[i].szExt)))
|
||||
{
|
||||
*ppInfo = &iidInfo[i];
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR GetTestEncodeIID(const char* szExt, const PKIID** ppIID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
const PKIIDInfo* pInfo = NULL;
|
||||
|
||||
Call(GetTestInfo(szExt, &pInfo));
|
||||
*ppIID = pInfo->pIIDEnc;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR GetTestDecodeIID(const char* szExt, const PKIID** ppIID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
const PKIIDInfo* pInfo = NULL;
|
||||
|
||||
Call(GetTestInfo(szExt, &pInfo));
|
||||
*ppIID = pInfo->pIIDDec;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKTestFactory
|
||||
//================================================================
|
||||
ERR PKTestFactory_CreateCodec(const PKIID* iid, void** ppv)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
if (IID_PKImageBmpEncode == *iid)
|
||||
{
|
||||
Call(PKImageEncode_Create_BMP((PKImageEncode**)ppv));
|
||||
}
|
||||
else if (IID_PKImagePnmEncode == *iid)
|
||||
{
|
||||
Call(PKImageEncode_Create_PNM((PKImageEncode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageTifEncode == *iid)
|
||||
{
|
||||
Call(PKImageEncode_Create_TIF((PKImageEncode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageHdrEncode == *iid)
|
||||
{
|
||||
Call(PKImageEncode_Create_HDR((PKImageEncode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageIyuvEncode == *iid)
|
||||
{
|
||||
Call(PKImageEncode_Create_IYUV((PKImageEncode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageYuv422Encode == *iid)
|
||||
{
|
||||
Call(PKImageEncode_Create_YUV422((PKImageEncode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageYuv444Encode == *iid)
|
||||
{
|
||||
Call(PKImageEncode_Create_YUV444((PKImageEncode**)ppv));
|
||||
}
|
||||
|
||||
else if (IID_PKImageBmpDecode == *iid)
|
||||
{
|
||||
Call(PKImageDecode_Create_BMP((PKTestDecode**)ppv));
|
||||
}
|
||||
else if (IID_PKImagePnmDecode == *iid)
|
||||
{
|
||||
Call(PKImageDecode_Create_PNM((PKTestDecode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageTifDecode == *iid)
|
||||
{
|
||||
Call(PKImageDecode_Create_TIF((PKTestDecode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageHdrDecode == *iid)
|
||||
{
|
||||
Call(PKImageDecode_Create_HDR((PKTestDecode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageIyuvDecode == *iid)
|
||||
{
|
||||
Call(PKImageDecode_Create_IYUV((PKTestDecode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageYuv422Decode == *iid)
|
||||
{
|
||||
Call(PKImageDecode_Create_YUV422((PKTestDecode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageYuv444Decode == *iid)
|
||||
{
|
||||
Call(PKImageDecode_Create_YUV444((PKTestDecode**)ppv));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKTestFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
char *pExt = NULL;
|
||||
PKIID* pIID = NULL;
|
||||
|
||||
struct WMPStream* pStream = NULL;
|
||||
PKImageDecode* pDecoder = NULL;
|
||||
|
||||
// get file extension
|
||||
pExt = strrchr(szFilename, '.');
|
||||
FailIf(NULL == pExt, WMP_errUnsupportedFormat);
|
||||
|
||||
// get decode PKIID
|
||||
Call(GetTestDecodeIID(pExt, &pIID));
|
||||
|
||||
// create stream
|
||||
Call(CreateWS_File(&pStream, szFilename, "rb"));
|
||||
|
||||
// Create decoder
|
||||
Call(PKTestFactory_CreateCodec(pIID, ppDecoder));
|
||||
pDecoder = *ppDecoder;
|
||||
|
||||
// attach stream to decoder
|
||||
Call(pDecoder->Initialize(pDecoder, pStream));
|
||||
pDecoder->fStreamOwner = !0;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKCreateTestFactory(PKCodecFactory** ppCFactory, U32 uVersion)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKCodecFactory* pCFactory = NULL;
|
||||
|
||||
UNREFERENCED_PARAMETER( uVersion );
|
||||
|
||||
Call(PKAlloc(ppCFactory, sizeof(**ppCFactory)));
|
||||
pCFactory = *ppCFactory;
|
||||
|
||||
pCFactory->CreateCodec = PKTestFactory_CreateCodec;
|
||||
pCFactory->CreateDecoderFromFile = PKTestFactory_CreateDecoderFromFile;
|
||||
pCFactory->CreateFormatConverter = PKCodecFactory_CreateFormatConverter;
|
||||
pCFactory->Release = PKCreateCodecFactory_Release;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKTestDecode
|
||||
//================================================================
|
||||
ERR PKTestDecode_Initialize(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pStream)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
pID->pStream = pStream;
|
||||
pID->guidPixFormat = GUID_PKPixelFormatDontCare;
|
||||
pID->fResX = 96;
|
||||
pID->fResY = 96;
|
||||
pID->cFrame = 1;
|
||||
|
||||
Call(pID->pStream->GetPos(pID->pStream, &pID->offStart));
|
||||
|
||||
Cleanup:
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKTestDecode_Copy(
|
||||
PKTestDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pID );
|
||||
UNREFERENCED_PARAMETER( pRect );
|
||||
UNREFERENCED_PARAMETER( pb );
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
|
||||
return WMP_errAbstractMethod;
|
||||
}
|
||||
|
||||
ERR PKTestDecode_Release(
|
||||
PKTestDecode** ppID)
|
||||
{
|
||||
PKTestDecode* pID = *ppID;
|
||||
|
||||
pID->fStreamOwner && pID->pStream->Close(&pID->pStream);
|
||||
|
||||
return PKFree(ppID);
|
||||
}
|
||||
|
||||
ERR PKTestDecode_Create(
|
||||
PKTestDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKTestDecode* pID = NULL;
|
||||
|
||||
Call(PKAlloc(ppID, sizeof(**ppID)));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKTestDecode_Initialize;
|
||||
pID->GetPixelFormat = PKImageDecode_GetPixelFormat;
|
||||
pID->GetSize = PKImageDecode_GetSize;
|
||||
pID->GetResolution = PKImageDecode_GetResolution;
|
||||
pID->GetColorContext = PKImageDecode_GetColorContext;
|
||||
pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata;
|
||||
pID->Copy = PKTestDecode_Copy;
|
||||
pID->GetFrameCount = PKImageDecode_GetFrameCount;
|
||||
pID->SelectFrame = PKImageDecode_SelectFrame;
|
||||
pID->Release = PKTestDecode_Release;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
164
jxrlib/jxrtestlib/JXRTest.h
Normal file
164
jxrlib/jxrtestlib/JXRTest.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <JXRGlue.h>
|
||||
|
||||
EXTERN_C const PKIID IID_PKImageBmpEncode;
|
||||
EXTERN_C const PKIID IID_PKImagePnmEncode;
|
||||
EXTERN_C const PKIID IID_PKImageTifEncode;
|
||||
|
||||
EXTERN_C const PKIID IID_PKImageBmpDecode;
|
||||
EXTERN_C const PKIID IID_PKImagePnmDecode;
|
||||
EXTERN_C const PKIID IID_PKImageTifDecode;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR GetTestEncodeIID(const char* szExt, const PKIID** ppIID);
|
||||
ERR GetTestDecodeIID(const char* szExt, const PKIID** ppIID);
|
||||
|
||||
//================================================================
|
||||
#ifdef __ANSI__
|
||||
#define PKTestDecode struct tagPKTestDecode
|
||||
#else // __ANSI__
|
||||
typedef struct tagPKTestDecode PKTestDecode;
|
||||
#endif // __ANSI__
|
||||
//================================================================
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKTestFactory_CreateCodec(const PKIID* iid, void** ppv);
|
||||
|
||||
EXTERN_C ERR PKCreateTestFactory(PKCodecFactory**, U32);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKImageEncode_Create_BMP(PKImageEncode** ppIE);
|
||||
ERR PKImageEncode_Create_PNM(PKImageEncode** ppIE);
|
||||
ERR PKImageEncode_Create_TIF(PKImageEncode** ppIE);
|
||||
ERR PKImageEncode_Create_HDR(PKImageEncode** ppIE);
|
||||
ERR PKImageEncode_Create_IYUV(PKImageEncode** ppIE);
|
||||
ERR PKImageEncode_Create_YUV422(PKImageEncode** ppIE);
|
||||
ERR PKImageEncode_Create_YUV444(PKImageEncode** ppIE);
|
||||
|
||||
//================================================================
|
||||
typedef struct tagPKTestDecode
|
||||
{
|
||||
ERR (*Initialize)(PKTestDecode*, struct WMPStream* pStream);
|
||||
|
||||
ERR (*GetPixelFormat)(PKImageDecode*, PKPixelFormatGUID*);
|
||||
ERR (*GetSize)(PKImageDecode*, I32*, I32*);
|
||||
ERR (*GetResolution)(PKImageDecode*, Float*, Float*);
|
||||
ERR (*GetColorContext)(PKImageDecode *pID, U8 *pbColorContext,
|
||||
U32 *pcbColorContext);
|
||||
ERR (*GetDescriptiveMetadata)(PKImageDecode *pIE,
|
||||
DESCRIPTIVEMETADATA *pDescMetadata);
|
||||
|
||||
ERR (*GetRawStream)(PKImageDecode*, struct WMPStream**);
|
||||
|
||||
ERR (*Copy)(PKTestDecode*, const PKRect*, U8*, U32);
|
||||
|
||||
ERR (*GetFrameCount)(PKImageDecode*, U32*);
|
||||
ERR (*SelectFrame)(PKImageDecode*, U32);
|
||||
|
||||
ERR (*Release)(PKTestDecode**);
|
||||
|
||||
struct WMPStream* pStream;
|
||||
Bool fStreamOwner;
|
||||
size_t offStart;
|
||||
|
||||
PKPixelFormatGUID guidPixFormat;
|
||||
|
||||
U32 uWidth;
|
||||
U32 uHeight;
|
||||
U32 idxCurrentLine;
|
||||
|
||||
Float fResX;
|
||||
Float fResY;
|
||||
|
||||
U32 cFrame;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
size_t offPixel;
|
||||
size_t cbPixel;
|
||||
} BMP;
|
||||
struct
|
||||
{
|
||||
size_t offPixel;
|
||||
size_t cbPixel;
|
||||
} HDR;
|
||||
struct
|
||||
{
|
||||
size_t offPixel;
|
||||
} PNM;
|
||||
struct
|
||||
{
|
||||
U32 uRowsPerStrip;
|
||||
U32* uStripOffsets;
|
||||
U32* uStripByteCounts;
|
||||
|
||||
U32 uInterpretation;
|
||||
U32 uSamplePerPixel;
|
||||
U32 uBitsPerSample;
|
||||
U32 uSampleFormat;
|
||||
U32 uExtraSamples;
|
||||
|
||||
U16 uResolutionUnit;
|
||||
Float fResX;
|
||||
Float fResY;
|
||||
Bool fLittleEndian;
|
||||
} TIF;
|
||||
} EXT;
|
||||
#ifdef __ANSI__
|
||||
#undef PKTestDecode
|
||||
#endif // __ANSI__
|
||||
} PKTestDecode;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKImageDecode_Create_BMP(PKTestDecode** ppID);
|
||||
ERR PKImageDecode_Create_PNM(PKTestDecode** ppID);
|
||||
ERR PKImageDecode_Create_TIF(PKTestDecode** ppID);
|
||||
ERR PKImageDecode_Create_HDR(PKTestDecode** ppID);
|
||||
ERR PKImageDecode_Create_IYUV(PKTestDecode** ppID);
|
||||
ERR PKImageDecode_Create_YUV422(PKTestDecode** ppID);
|
||||
ERR PKImageDecode_Create_YUV444(PKTestDecode** ppID);
|
||||
|
||||
ERR PKTestDecode_Initialize(PKTestDecode* pID, struct WMPStream* pStream);
|
||||
ERR PKTestDecode_Copy(PKTestDecode* pID, const PKRect* pRect, U8* pb, U32 cbStride);
|
||||
ERR PKTestDecode_Release(PKTestDecode** ppID);
|
||||
|
||||
ERR PKTestDecode_Create(PKTestDecode** ppID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
401
jxrlib/jxrtestlib/JXRTestBmp.c
Normal file
401
jxrlib/jxrtestlib/JXRTestBmp.c
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <JXRTest.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#define BI_RGB 0
|
||||
#define BI_BITFIELDS 3
|
||||
|
||||
#define BI_RGB555_MASK_B 0x001F
|
||||
#define BI_RGB555_MASK_G 0x03E0
|
||||
#define BI_RGB555_MASK_R 0x7C00
|
||||
|
||||
#define BI_RGB565_MASK_B 0x001F
|
||||
#define BI_RGB565_MASK_G 0x07E0
|
||||
#define BI_RGB565_MASK_R 0xF800
|
||||
|
||||
#define BI_RGB101010_MASK_B 0x000003FF
|
||||
#define BI_RGB101010_MASK_G 0x000FFC00
|
||||
#define BI_RGB101010_MASK_R 0x3FF00000
|
||||
|
||||
typedef struct tagBITMAPFILEHEADER {
|
||||
U8 szBM[2];
|
||||
U32 uSize;
|
||||
U16 reserved1;
|
||||
U16 reserved2;
|
||||
U32 uOffBits;
|
||||
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
|
||||
|
||||
typedef struct tagBITMAPINFOHEADER{
|
||||
U32 uSize;
|
||||
I32 iWidth;
|
||||
I32 iHeight;
|
||||
I16 iPlanes;
|
||||
I16 iBitCount;
|
||||
U32 uCompression;
|
||||
U32 uImageSize;
|
||||
I32 iPelsPerMeterX;
|
||||
I32 iPelsPerMeterY;
|
||||
U32 uColorUsed;
|
||||
U32 uColorImportant;
|
||||
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
|
||||
|
||||
typedef struct tagBITMAPINFOHEADEREXT{
|
||||
U32 uA;
|
||||
U32 uB;
|
||||
U32 uC;
|
||||
U32 uD;
|
||||
} BITMAPINFOHEADEREXT, *PBITMAPINFOHEADEREXT;
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_BMP
|
||||
//================================================================
|
||||
ERR WriteBMPHeader(
|
||||
PKImageEncode* pIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
static U32 rguColorTable[256] = {0};
|
||||
size_t cbColorTable = 0;
|
||||
size_t cbLineS = 0;
|
||||
U32 i = 0;
|
||||
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
BITMAPFILEHEADER bmpFH = { 0, };
|
||||
BITMAPINFOHEADER bmpIH = {sizeof(bmpIH), 0, };
|
||||
|
||||
bmpFH.szBM[0] = 'B';
|
||||
bmpFH.szBM[1] = 'M';
|
||||
|
||||
if (IsEqualGUID(&GUID_PKPixelFormat24bppRGB, &pIE->guidPixFormat) || IsEqualGUID(&GUID_PKPixelFormat24bppBGR, &pIE->guidPixFormat))
|
||||
{
|
||||
pIE->cbPixel = 3;
|
||||
cbColorTable = 0;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat32bppBGRA, &pIE->guidPixFormat)
|
||||
|| IsEqualGUID(&GUID_PKPixelFormat32bppBGR, &pIE->guidPixFormat)
|
||||
|| IsEqualGUID(&GUID_PKPixelFormat32bppPBGRA, &pIE->guidPixFormat))
|
||||
{
|
||||
pIE->cbPixel = 4;
|
||||
cbColorTable = 0;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat8bppGray, &pIE->guidPixFormat))
|
||||
{
|
||||
pIE->cbPixel = 1;
|
||||
|
||||
cbColorTable = sizeof(rguColorTable);
|
||||
for (i = 0; i < sizeof2(rguColorTable); ++i)
|
||||
{
|
||||
rguColorTable[i] = i | (i << 8) | (i << 16);
|
||||
}
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat16bppRGB555, &pIE->guidPixFormat))
|
||||
{
|
||||
pIE->cbPixel = 2;
|
||||
bmpIH.uCompression = BI_BITFIELDS;
|
||||
|
||||
cbColorTable = sizeof(rguColorTable[0]) * 3;
|
||||
rguColorTable[0] = BI_RGB555_MASK_R;
|
||||
rguColorTable[1] = BI_RGB555_MASK_G;
|
||||
rguColorTable[2] = BI_RGB555_MASK_B;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat16bppRGB565, &pIE->guidPixFormat))
|
||||
{
|
||||
pIE->cbPixel = 2;
|
||||
bmpIH.uCompression = BI_BITFIELDS;
|
||||
|
||||
cbColorTable = sizeof(rguColorTable[0]) * 3;
|
||||
rguColorTable[0] = BI_RGB565_MASK_R;
|
||||
rguColorTable[1] = BI_RGB565_MASK_G;
|
||||
rguColorTable[2] = BI_RGB565_MASK_B;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat32bppRGB101010, &pIE->guidPixFormat))
|
||||
{
|
||||
pIE->cbPixel = 4;
|
||||
bmpIH.uCompression = BI_BITFIELDS;
|
||||
|
||||
cbColorTable = sizeof(rguColorTable[0]) * 3;
|
||||
rguColorTable[0] = BI_RGB101010_MASK_R;
|
||||
rguColorTable[1] = BI_RGB101010_MASK_G;
|
||||
rguColorTable[2] = BI_RGB101010_MASK_B;
|
||||
}
|
||||
else
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
|
||||
cbLineS = (pIE->cbPixel * pIE->uWidth + 3) / 4 * 4;
|
||||
|
||||
bmpFH.uOffBits = (U32)(sizeof(bmpFH) + sizeof(bmpIH) + cbColorTable);
|
||||
bmpFH.uSize = (U32)(bmpFH.uOffBits + cbLineS * pIE->uHeight);
|
||||
|
||||
bmpIH.iWidth = pIE->uWidth;
|
||||
bmpIH.iHeight = pIE->uHeight;
|
||||
bmpIH.iPlanes = 1;
|
||||
bmpIH.iBitCount = (I16)(8 * pIE->cbPixel);
|
||||
bmpIH.uImageSize = (U32)(cbLineS * pIE->uHeight);
|
||||
bmpIH.iPelsPerMeterX = (I32)(pIE->fResX * 39.37);
|
||||
bmpIH.iPelsPerMeterY = (I32)(pIE->fResY * 39.37);
|
||||
|
||||
Call(pS->Write(pS, &bmpFH, sizeof(bmpFH)));
|
||||
Call(pS->Write(pS, &bmpIH, sizeof(bmpIH)));
|
||||
Call(pS->Write(pS, rguColorTable, cbColorTable));
|
||||
|
||||
pIE->offPixel = pIE->offStart + bmpFH.uOffBits;
|
||||
pIE->fHeaderDone = !FALSE;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_WritePixels_BMP(
|
||||
PKImageEncode* pIE,
|
||||
U32 cLine,
|
||||
U8* pbPixel,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
size_t cbLineM = 0, cbLineS = 0;
|
||||
I32 i = 0;
|
||||
static U8 pPadding[4] = {0};
|
||||
|
||||
// header
|
||||
if (!pIE->fHeaderDone)
|
||||
{
|
||||
// WriteBMPHeader() also inits this object
|
||||
Call(WriteBMPHeader(pIE));
|
||||
}
|
||||
|
||||
// body
|
||||
// calculate line size in memory and in stream
|
||||
cbLineM = pIE->cbPixel * pIE->uWidth;
|
||||
cbLineS = (cbLineM + 3) / 4 * 4;
|
||||
|
||||
//FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter);
|
||||
FailIf(cbStride < cbLineM, WMP_errInvalidParameter);
|
||||
|
||||
for (i = cLine - 1; 0 <= i; --i)
|
||||
{
|
||||
size_t offM = cbStride * i;
|
||||
size_t offS = cbLineS * (pIE->uHeight - (pIE->idxCurrentLine + i + 1));
|
||||
|
||||
Call(pS->SetPos(pS, pIE->offPixel + offS));
|
||||
Call(pS->Write(pS, pbPixel + offM, cbLineM));
|
||||
}
|
||||
Call(pS->Write(pS, pPadding, (cbLineS - cbLineM)));
|
||||
pIE->idxCurrentLine += cLine;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Create_BMP(
|
||||
PKImageEncode** ppIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageEncode* pIE = NULL;
|
||||
|
||||
Call(PKImageEncode_Create(ppIE));
|
||||
|
||||
pIE = *ppIE;
|
||||
pIE->WritePixels = PKImageEncode_WritePixels_BMP;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_BMP
|
||||
//================================================================
|
||||
ERR ParseBMPHeader(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
BITMAPFILEHEADER bmpFH = {0};
|
||||
BITMAPINFOHEADER bmpIH = {0};
|
||||
static U32 bmpIHE[32] = {0}; // should be >= sizeof(BITMAPV5HEADER) - sizeof(BITMAPINFOHEADER)
|
||||
static U32 rguColorTable[256] = {0};
|
||||
U32 i = 0;
|
||||
|
||||
Call(pWS->Read(pWS, &bmpFH, sizeof(bmpFH)));
|
||||
FailIf(bmpFH.szBM != (U8 *) strstr((char *) bmpFH.szBM, "BM"), WMP_errUnsupportedFormat);
|
||||
|
||||
Call(pWS->Read(pWS, &bmpIH, sizeof(bmpIH)));
|
||||
|
||||
FailIf(((sizeof(bmpIH) > bmpIH.uSize) || ((sizeof(bmpIH) + sizeof(bmpIHE)) < bmpIH.uSize)), WMP_errUnsupportedFormat);
|
||||
|
||||
if (sizeof(bmpIH) < bmpIH.uSize)
|
||||
Call(pWS->Read(pWS, &bmpIHE, bmpIH.uSize - sizeof(bmpIH)));
|
||||
|
||||
switch (bmpIH.iBitCount)
|
||||
{
|
||||
case 8:
|
||||
// check the color table to verify the image is actually gray scale
|
||||
Call(pWS->Read(pWS, rguColorTable, sizeof(rguColorTable)));
|
||||
for (i = 0; i < sizeof2(rguColorTable); ++i)
|
||||
{
|
||||
U32 c = i | (i << 8) | (i << 16);
|
||||
FailIf(c != rguColorTable[i], WMP_errUnsupportedFormat);
|
||||
}
|
||||
|
||||
pID->guidPixFormat = GUID_PKPixelFormat8bppGray;
|
||||
pID->EXT.BMP.cbPixel = 1;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// Call(pWS->Read(pWS, rguColorTable, sizeof(rguColorTable[0] * 3)));
|
||||
/* if (BI_RGB555_MASK_B == rguColorTable[0] && BI_RGB555_MASK_G == rguColorTable[1] && BI_RGB555_MASK_R == rguColorTable[2])
|
||||
{
|
||||
pID->guidPixFormat = GUID_PKPixelFormat16bppRGB555;
|
||||
}
|
||||
if (BI_RGB565_MASK_B == rguColorTable[0] && BI_RGB565_MASK_G == rguColorTable[1] && BI_RGB565_MASK_R == rguColorTable[2])
|
||||
{
|
||||
pID->guidPixFormat = GUID_PKPixelFormat16bppRGB565;
|
||||
}
|
||||
else
|
||||
{
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
}
|
||||
*/
|
||||
pID->EXT.BMP.cbPixel = 2;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
pID->guidPixFormat = GUID_PKPixelFormat24bppBGR;
|
||||
pID->EXT.BMP.cbPixel = 3;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
/* Call(pWS->Read(pWS, rguColorTable, sizeof(rguColorTable[0] * 3)));
|
||||
if (BI_RGB101010_MASK_B == rguColorTable[0] && BI_RGB101010_MASK_G == rguColorTable[1] && BI_RGB101010_MASK_R == rguColorTable[2])
|
||||
{
|
||||
pID->guidPixFormat = GUID_PKPixelFormat32bppRGB101010;
|
||||
}
|
||||
else
|
||||
{
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
}
|
||||
*/
|
||||
// pID->guidPixFormat = GUID_PKPixelFormat32bppBGRA;
|
||||
pID->EXT.BMP.cbPixel = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
break;
|
||||
}
|
||||
|
||||
pID->uWidth = (U32)bmpIH.iWidth;
|
||||
pID->uHeight = (U32)bmpIH.iHeight;
|
||||
|
||||
pID->fResX = (0 == bmpIH.iPelsPerMeterX ? 96 : (Float)(bmpIH.iPelsPerMeterX * .0254));
|
||||
pID->fResY = (0 == bmpIH.iPelsPerMeterY ? 96 : (Float)(bmpIH.iPelsPerMeterY * .0254));
|
||||
|
||||
pID->EXT.BMP.offPixel = pID->offStart + bmpFH.uOffBits;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Initialize_BMP(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKTestDecode_Initialize(pID, pWS));
|
||||
Call(ParseBMPHeader(pID, pWS));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Copy_BMP(
|
||||
PKTestDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pS = pID->pStream;
|
||||
|
||||
size_t cbLineS = (pID->EXT.BMP.cbPixel * pID->uWidth + 3) / 4 * 4;
|
||||
size_t cbLineM = pID->EXT.BMP.cbPixel * pRect->Width;
|
||||
|
||||
I32 i = 0;
|
||||
|
||||
//FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter);
|
||||
FailIf(cbStride < cbLineM, WMP_errInvalidParameter);
|
||||
|
||||
for (i = pRect->Y + pRect->Height - 1; pRect->Y <= i; --i)
|
||||
{
|
||||
size_t offLine = pID->EXT.BMP.cbPixel * pRect->X;
|
||||
size_t offS = cbLineS * (pID->uHeight - i - 1) + offLine;
|
||||
size_t offM = cbStride * (i - pRect->Y) + offLine;
|
||||
|
||||
Call(pS->SetPos(pS, pID->EXT.BMP.offPixel + offS));
|
||||
Call(pS->Read(pS, pb + offM, cbLineM));
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Create_BMP(
|
||||
PKTestDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKTestDecode* pID = NULL;
|
||||
|
||||
Call(PKTestDecode_Create(ppID));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKImageDecode_Initialize_BMP;
|
||||
pID->Copy = PKImageDecode_Copy_BMP;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
242
jxrlib/jxrtestlib/JXRTestHdr.c
Normal file
242
jxrlib/jxrtestlib/JXRTestHdr.c
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
#ifndef ANSI
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif ANSI
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <JXRTest.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma pack(pop)
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_HDR
|
||||
//================================================================
|
||||
ERR WriteHDRHeader(
|
||||
PKImageEncode* pIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
|
||||
char txtbuff[100];
|
||||
|
||||
strcpy(txtbuff, "#?RADIANCE\nFORMAT=32-bit_rle_rgbe\n\n");
|
||||
Call(pS->Write(pS, txtbuff, strlen(txtbuff)));
|
||||
|
||||
pIE->offPixel = strlen(txtbuff);
|
||||
|
||||
sprintf(txtbuff, "-Y %d +X %d\n", pIE->uHeight, pIE->uWidth);
|
||||
Call(pS->Write(pS, txtbuff, strlen(txtbuff)));
|
||||
pIE->offPixel += strlen(txtbuff);
|
||||
|
||||
pIE->cbPixel = 4;
|
||||
|
||||
pIE->fHeaderDone = !FALSE;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_WritePixels_HDR(
|
||||
PKImageEncode* pIE,
|
||||
U32 cLine,
|
||||
U8* pbPixel,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
size_t cbLineM = 0, cbLineS = 0;
|
||||
size_t i = 0;
|
||||
|
||||
// header
|
||||
if (!pIE->fHeaderDone)
|
||||
{
|
||||
// WriteHDRHeader() also inits this object
|
||||
Call(WriteHDRHeader(pIE));
|
||||
}
|
||||
|
||||
// body
|
||||
// calculate line size in memory and in stream
|
||||
cbLineM = pIE->cbPixel * pIE->uWidth;
|
||||
cbLineS = (cbLineM + 3) / 4 * 4;
|
||||
|
||||
//FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter);
|
||||
FailIf(cbStride < cbLineM, WMP_errInvalidParameter);
|
||||
|
||||
for (i = 0; i <= cLine - 1; i++)
|
||||
{
|
||||
size_t offM = cbStride * i;
|
||||
size_t offS = cbLineS * (pIE->idxCurrentLine + i);
|
||||
|
||||
Call(pS->SetPos(pS, pIE->offPixel + offS));
|
||||
Call(pS->Write(pS, pbPixel + offM, cbLineM));
|
||||
}
|
||||
pIE->idxCurrentLine += cLine;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Create_HDR(
|
||||
PKImageEncode** ppIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageEncode* pIE = NULL;
|
||||
|
||||
Call(PKImageEncode_Create(ppIE));
|
||||
|
||||
pIE = *ppIE;
|
||||
pIE->WritePixels = PKImageEncode_WritePixels_HDR;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_HDR
|
||||
//================================================================
|
||||
ERR ParseHDRHeader(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
char txtbuff[512];
|
||||
Bool done = FALSE;
|
||||
|
||||
FailIf(NULL == fgets(txtbuff, 12, pWS->state.file.pFile), WMP_errUnsupportedFormat);
|
||||
FailIf(0 != strcmp(txtbuff, "#?RADIANCE\n"), WMP_errUnsupportedFormat);
|
||||
|
||||
// Read lines to image size
|
||||
while (!done) {
|
||||
FailIf(NULL == fgets(txtbuff, 512, pWS->state.file.pFile), WMP_errUnsupportedFormat);
|
||||
|
||||
if (0 == strncmp(txtbuff, "FORMAT", 6)) {
|
||||
FailIf(0 != strcmp(txtbuff, "FORMAT=32-bit_rle_rgbe\n"), WMP_errUnsupportedFormat);
|
||||
}
|
||||
if (0 == strncmp(txtbuff, "-Y", 2)) {
|
||||
sscanf(txtbuff, "-Y %d +X %d\n", &pID->uHeight, &pID->uWidth);
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Call(pWS->Read(pWS, txtbuff, 3));
|
||||
|
||||
if(((2 == txtbuff[0]) && (2 == txtbuff[1]) && (0 == (txtbuff[2] & 0x80))) ||
|
||||
((1 == txtbuff[0]) && (1 == txtbuff[1]) && (1 == txtbuff[2])))
|
||||
{
|
||||
printf("Doesn't support compressed HDR files.\n");
|
||||
err = WMP_errUnsupportedFormat;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Set header other header parameters
|
||||
pID->guidPixFormat = GUID_PKPixelFormat32bppRGBE;
|
||||
pID->EXT.HDR.cbPixel = 4;
|
||||
// Set pointer to first pixel
|
||||
Call(pWS->GetPos(pWS, &pID->EXT.HDR.offPixel));
|
||||
pID->EXT.HDR.offPixel -= 3;
|
||||
Call(pWS->SetPos(pWS, pID->EXT.HDR.offPixel));
|
||||
|
||||
// We don't need: pID->fResX and pID->fResY
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Initialize_HDR(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKTestDecode_Initialize(pID, pWS));
|
||||
Call(ParseHDRHeader(pID, pWS));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Copy_HDR(
|
||||
PKTestDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pS = pID->pStream;
|
||||
|
||||
size_t cbLineS = (pID->EXT.HDR.cbPixel * pID->uWidth + 3) / 4 * 4;
|
||||
size_t cbLineM = pID->EXT.HDR.cbPixel * pRect->Width;
|
||||
|
||||
I32 i = 0;
|
||||
|
||||
//FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter);
|
||||
//FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter);
|
||||
FailIf(cbStride < cbLineM, WMP_errInvalidParameter);
|
||||
|
||||
for (i = pRect->Y ; i < pRect->Y + pRect->Height ; i++)
|
||||
{
|
||||
size_t offLine = pID->EXT.HDR.cbPixel * pRect->X;
|
||||
size_t offS = cbLineS * i + offLine;
|
||||
size_t offM = cbStride * (i - pRect->Y) + offLine;
|
||||
|
||||
Call(pS->SetPos(pS, pID->EXT.HDR.offPixel + offS));
|
||||
Call(pS->Read(pS, pb + offM, cbLineM));
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Create_HDR(
|
||||
PKTestDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKTestDecode* pID = NULL;
|
||||
|
||||
Call(PKTestDecode_Create(ppID));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKImageDecode_Initialize_HDR;
|
||||
pID->Copy = PKImageDecode_Copy_HDR;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
179
jxrlib/jxrtestlib/JXRTestLib_vc11.vcxproj
Normal file
179
jxrlib/jxrtestlib/JXRTestLib_vc11.vcxproj
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>JXRTestLib</ProjectName>
|
||||
<ProjectGuid>{A69603CC-65E8-443F-8E31-737DBD6BB0DC}</ProjectGuid>
|
||||
<RootNamespace>JXRTestLib</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)/$(ProjectName)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\$(ProjectName)\$(Platform)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)/$(ProjectName)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\$(ProjectName)\$(Platform)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</IntDir>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\image\sys;..\image\x86;..\JXRTestLib;..\JXRGlueLib;..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName).lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\image\sys;..\image\x86;..\JXRTestLib;..\JXRGlueLib;..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName).lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<AdditionalIncludeDirectories>..\image\sys;..\image\x86;..\JXRTestLib;..\JXRGlueLib;..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;ENABLE_OPTIMIZATIONS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<AdditionalOptions>/LTCG %(AdditionalOptions)</AdditionalOptions>
|
||||
<OutputFile>$(OutDir)$(ProjectName).lib</OutputFile>
|
||||
<LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\image\sys;..\image\x86;..\JXRTestLib;..\JXRGlueLib;..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName).lib</OutputFile>
|
||||
<LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="JXRTest.c" />
|
||||
<ClCompile Include="JXRTestBmp.c" />
|
||||
<ClCompile Include="JXRTestHdr.c" />
|
||||
<ClCompile Include="JXRTestPnm.c" />
|
||||
<ClCompile Include="JXRTestTif.c" />
|
||||
<ClCompile Include="JXRTestYUV.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="JXRTest.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
331
jxrlib/jxrtestlib/JXRTestPnm.c
Normal file
331
jxrlib/jxrtestlib/JXRTestPnm.c
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
#ifndef ANSI
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif ANSI
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <JXRTest.h>
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_PNM helpers
|
||||
//================================================================
|
||||
ERR WritePNMHeader(PKImageEncode* pIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
PKPixelInfo PI;
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
U8 buf[64] = {0};
|
||||
int cb = 0;
|
||||
|
||||
char szSig[2];
|
||||
U32 uMaxVal = 0;
|
||||
|
||||
PI.pGUIDPixFmt = &pIE->guidPixFormat;
|
||||
PixelFormatLookup(&PI, LOOKUP_FORWARD);
|
||||
|
||||
if (IsEqualGUID(&GUID_PKPixelFormatBlackWhite, PI.pGUIDPixFmt))
|
||||
{
|
||||
szSig[0] = 'P', szSig[1] = '5';
|
||||
uMaxVal = 1;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat8bppGray, PI.pGUIDPixFmt))
|
||||
{
|
||||
szSig[0] = 'P', szSig[1] = '5';
|
||||
uMaxVal = 255;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat24bppRGB, PI.pGUIDPixFmt))
|
||||
{
|
||||
szSig[0] = 'P', szSig[1] = '6';
|
||||
uMaxVal = 255;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat48bppRGB, PI.pGUIDPixFmt))
|
||||
{
|
||||
szSig[0] = 'P', szSig[1] = '6';
|
||||
uMaxVal = 65535;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat16bppGray, PI.pGUIDPixFmt))
|
||||
{
|
||||
szSig[0] = 'P', szSig[1] = '6';
|
||||
uMaxVal = 65535;
|
||||
}
|
||||
else if (IsEqualGUID(&GUID_PKPixelFormat96bppRGBFloat, PI.pGUIDPixFmt))
|
||||
{
|
||||
szSig[0] = 'P', szSig[1] = 'F';
|
||||
}
|
||||
else
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
|
||||
if('P' == szSig[0] && 'F' == szSig[1])
|
||||
cb = sprintf((char *) buf, "%c%c\n%u\n%u\n%s\n",
|
||||
szSig[0], szSig[1], (int)pIE->uWidth, (int)pIE->uHeight, "-1.0000");
|
||||
else
|
||||
cb = sprintf((char *) buf, "%c%c\n%u %u\n%u\n",
|
||||
szSig[0], szSig[1], (int)pIE->uWidth, (int)pIE->uHeight, (int)uMaxVal);
|
||||
|
||||
assert(cb < sizeof2(buf));
|
||||
Call(pS->Write(pS, buf, cb));
|
||||
|
||||
Call(pS->GetPos(pS, &pIE->offPixel));
|
||||
pIE->cbPixel = ((PI.cbitUnit + 7) >> 3);// ->cbPixel / pPI->cbPixelDenom;
|
||||
pIE->fHeaderDone = !FALSE;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_PNM
|
||||
//================================================================
|
||||
ERR PKImageEncode_WritePixels_PNM(
|
||||
PKImageEncode* pIE,
|
||||
U32 cLine,
|
||||
U8* pbPixel,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
size_t cbLine = 0;
|
||||
size_t offPos = 0;
|
||||
size_t i = 0;
|
||||
|
||||
// header
|
||||
if (!pIE->fHeaderDone)
|
||||
{
|
||||
Call(WritePNMHeader(pIE));
|
||||
}
|
||||
|
||||
// body
|
||||
cbLine = pIE->cbPixel * pIE->uWidth;
|
||||
FailIf(cbStride < cbLine, WMP_errInvalidParameter);
|
||||
|
||||
offPos = pIE->offPixel + cbLine * pIE->idxCurrentLine;
|
||||
Call(pS->SetPos(pS, offPos));
|
||||
|
||||
for (i = 0; i < cLine; ++i)
|
||||
{
|
||||
Call(pS->Write(pS, pbPixel + cbStride * i, cbLine));
|
||||
}
|
||||
pIE->idxCurrentLine += cLine;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Create_PNM(
|
||||
PKImageEncode** ppIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageEncode* pIE = NULL;
|
||||
|
||||
Call(PKImageEncode_Create(ppIE));
|
||||
|
||||
pIE = *ppIE;
|
||||
pIE->WritePixels = PKImageEncode_WritePixels_PNM;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_PNM helpers
|
||||
//================================================================
|
||||
ERR GetLineSkipPound(struct WMPStream* pWS, U8* pb, size_t cb)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U8 *pb1;
|
||||
size_t cb1;
|
||||
|
||||
do
|
||||
{
|
||||
pb1 = pb;
|
||||
cb1 = cb;
|
||||
|
||||
do {
|
||||
Call(pWS->Read(pWS, pb1, 1));
|
||||
cb1--;
|
||||
pb1++;
|
||||
}
|
||||
while (cb1 > 0 && pb1[-1] != '\n');
|
||||
|
||||
//Call(pWS->GetLine(pWS, pb, cb));
|
||||
} while('#' == pb[0]);
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR ParsePNMHeader(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
U8 line[128] = {0};
|
||||
size_t idxChannel = 0, idxBitDepth = 0;
|
||||
unsigned int width = 0, height = 0, maxval = 0;
|
||||
|
||||
static const PKPixelFormatGUID* pixFormat[2][2] =
|
||||
{
|
||||
{&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat16bppGray,},
|
||||
{&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat48bppRGB,},
|
||||
};
|
||||
|
||||
//================================
|
||||
Call(GetLineSkipPound(pWS, line, sizeof2(line)));
|
||||
if (line == (U8 *) strstr((char *) line, "P5"))
|
||||
{
|
||||
idxChannel = 0;
|
||||
Call(GetLineSkipPound(pWS, line, sizeof2(line)));
|
||||
FailIf(2 != sscanf((char *) line, "%u %u", &width, &height), WMP_errUnsupportedFormat);
|
||||
}
|
||||
else if(line == (U8 *) strstr((char *) line, "P6"))
|
||||
{
|
||||
idxChannel = 1;
|
||||
Call(GetLineSkipPound(pWS, line, sizeof2(line)));
|
||||
FailIf(2 != sscanf((char *) line, "%u %u", &width, &height), WMP_errUnsupportedFormat);
|
||||
}
|
||||
else if(line == (U8 *) strstr((char *) line, "PF"))
|
||||
{
|
||||
idxChannel = 2;
|
||||
Call(GetLineSkipPound(pWS, line, sizeof2(line)));
|
||||
FailIf(1 != sscanf((char *) line, "%u", &width), WMP_errUnsupportedFormat);
|
||||
Call(GetLineSkipPound(pWS, line, sizeof2(line)));
|
||||
FailIf(1 != sscanf((char *) line, "%u", &height), WMP_errUnsupportedFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
}
|
||||
|
||||
//================================
|
||||
// Call(GetLineSkipPound(pWS, line, sizeof2(line)));
|
||||
// FailIf(2 != sscanf(line, "%u %u", &width, &height), WMP_errUnsupportedFormat);
|
||||
|
||||
FailIf(0 == width || 0 == height, WMP_errUnsupportedFormat);
|
||||
|
||||
pID->uWidth = (U32)width;
|
||||
pID->uHeight = (U32)height;
|
||||
|
||||
//================================
|
||||
Call(GetLineSkipPound(pWS, line, sizeof2(line)));
|
||||
|
||||
FailIf(1 != sscanf((char *) line, "%u", &maxval), WMP_errUnsupportedFormat);
|
||||
|
||||
if (2==idxChannel)
|
||||
{
|
||||
FailIf(maxval != -1, WMP_errUnsupportedFormat);
|
||||
pID->guidPixFormat = GUID_PKPixelFormat96bppRGBFloat;
|
||||
}
|
||||
else
|
||||
{
|
||||
FailIf(maxval < 1 || 65535 < maxval, WMP_errUnsupportedFormat);
|
||||
idxBitDepth = 255 < maxval;
|
||||
pID->guidPixFormat = *pixFormat[idxChannel][idxBitDepth];
|
||||
}
|
||||
|
||||
Call(pWS->GetPos(pWS, &pID->EXT.PNM.offPixel));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_PNM
|
||||
//================================================================
|
||||
ERR PKImageDecode_Initialize_PNM(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKTestDecode_Initialize(pID, pWS));
|
||||
Call(ParsePNMHeader(pID, pWS));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageDecode_Copy_PNM(
|
||||
PKTestDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pS = pID->pStream;
|
||||
PKPixelInfo PI;
|
||||
size_t cbLineS = 0;
|
||||
size_t cbLineM = 0;
|
||||
I32 i = 0;
|
||||
|
||||
PI.pGUIDPixFmt = &pID->guidPixFormat;
|
||||
PixelFormatLookup(&PI, LOOKUP_FORWARD);
|
||||
|
||||
cbLineS = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pID->uWidth + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pID->uWidth));
|
||||
cbLineM = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pRect->Width + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pRect->Width));
|
||||
FailIf(cbStride < cbLineM, WMP_errInvalidParameter);
|
||||
|
||||
for (i = 0; i < pRect->Height; ++i)
|
||||
{
|
||||
size_t offLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pRect->X + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pRect->X));
|
||||
size_t offS = cbLineS * (pRect->Y + i) + offLine;
|
||||
size_t offM = cbStride * i + offLine;
|
||||
|
||||
Call(pS->SetPos(pS, pID->EXT.PNM.offPixel + offS));
|
||||
Call(pS->Read(pS, pb + offM, cbLineM));
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Create_PNM(
|
||||
PKTestDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKTestDecode* pID = NULL;
|
||||
|
||||
Call(PKTestDecode_Create(ppID));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKImageDecode_Initialize_PNM;
|
||||
pID->Copy = PKImageDecode_Copy_PNM;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
936
jxrlib/jxrtestlib/JXRTestTif.c
Normal file
936
jxrlib/jxrtestlib/JXRTestTif.c
Normal file
|
|
@ -0,0 +1,936 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <strcodec.h>
|
||||
#include <JXRTest.h>
|
||||
|
||||
//================================================================
|
||||
#define TIF_tagNull 0
|
||||
#define TIF_tagSubfileType 0xff
|
||||
#define TIF_tagNewSubfileType 0xfe
|
||||
#define TIF_tagImageWidth 0x100
|
||||
#define TIF_tagImageLength 0x101
|
||||
#define TIF_tagBitsPerSample 0x102
|
||||
#define TIF_tagCompression 0x103
|
||||
#define TIF_tagPhotometricInterpretation 0x106
|
||||
#define TIF_tagStripOffsets 0x111
|
||||
#define TIF_tagOrientation 0x112
|
||||
#define TIF_tagSamplesPerPixel 0x115
|
||||
#define TIF_tagRowsPerStrip 0x116
|
||||
#define TIF_tagStripByteCounts 0x117
|
||||
#define TIF_tagXResolution 0x11a
|
||||
#define TIF_tagYResolution 0x11b
|
||||
#define TIF_tagPlanarConfiguration 0x11c
|
||||
#define TIF_tagResolutionUnit 0x128
|
||||
#define TIF_tagSoftware 0x131
|
||||
#define TIF_tagColorMap 0x140
|
||||
#define TIF_tagPredictor 0x13d
|
||||
#define TIF_tagInkSet 0x14c
|
||||
#define TIF_tagExtraSamples 0x152
|
||||
#define TIF_tagSampleFormat 0x153
|
||||
|
||||
#define TIF_typBYTE 1
|
||||
#define TIF_typASCII 2
|
||||
#define TIF_typSHORT 3
|
||||
#define TIF_typLONG 4
|
||||
#define TIF_typRATIOAL 5
|
||||
#define TIF_typSBYTE 6
|
||||
#define TIF_typUNDEFINED 7
|
||||
#define TIF_typSSHORT 8
|
||||
#define TIF_typSLONG 9
|
||||
#define TIF_typSRATIONAL 10
|
||||
#define TIF_typFLOAT 11
|
||||
#define TIF_typDOUBLE 12
|
||||
|
||||
|
||||
//================================================================
|
||||
typedef float FLOAT;
|
||||
typedef double DOUBLE;
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_TIF helpers
|
||||
//================================================================
|
||||
typedef struct tagTifDE
|
||||
{
|
||||
U16 uTag;
|
||||
U16 uType;
|
||||
U32 uCount;
|
||||
U32 uValueOrOffset;
|
||||
} TifDE;
|
||||
|
||||
typedef struct tagTifDEMisc
|
||||
{
|
||||
U32 offBitsPerSample;
|
||||
U32 offSampleFormat;
|
||||
U32 bps, spp, sf;
|
||||
U32 iPhotometricInterpretation;
|
||||
|
||||
U32 offXResolution;
|
||||
U32 resXF, resXD;
|
||||
|
||||
U32 offYResolution;
|
||||
U32 resYF, resYD;
|
||||
} TifDEMisc;
|
||||
|
||||
ERR PutTifUShort(
|
||||
struct WMPStream* pS,
|
||||
size_t offPos,
|
||||
U16 uValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(pS->SetPos(pS, offPos));
|
||||
Call(pS->Write(pS, &uValue, sizeof(uValue)));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PutTifULong(
|
||||
struct WMPStream* pS,
|
||||
size_t offPos,
|
||||
U32 uValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(pS->SetPos(pS, offPos));
|
||||
Call(pS->Write(pS, &uValue, sizeof(uValue)));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR WriteTifDE(
|
||||
struct WMPStream* pS,
|
||||
size_t offPos,
|
||||
TifDE* pDE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
assert(-1 != pDE->uCount);
|
||||
assert(-1 != pDE->uValueOrOffset);
|
||||
|
||||
Call(PutTifUShort(pS, offPos, pDE->uTag)); offPos += 2;
|
||||
Call(PutTifUShort(pS, offPos, pDE->uType)); offPos += 2;
|
||||
Call(PutTifULong(pS, offPos, pDE->uCount)); offPos += 4;
|
||||
|
||||
switch (pDE->uType)
|
||||
{
|
||||
case TIF_typSHORT:
|
||||
if (1 == pDE->uCount)
|
||||
{
|
||||
Call(PutTifUShort(pS, offPos, (U16)pDE->uValueOrOffset)); offPos += 2;
|
||||
Call(PutTifUShort(pS, offPos, 0)); offPos += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
case TIF_typLONG:
|
||||
case TIF_typRATIOAL:
|
||||
Call(PutTifULong(pS, offPos, pDE->uValueOrOffset)); offPos += 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
Call(WMP_errInvalidParameter);
|
||||
break;
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR WriteTifHeader(
|
||||
PKImageEncode* pIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
size_t offPos = 0;
|
||||
|
||||
#ifdef _BIG__ENDIAN_
|
||||
U8 IIMM[3] = "MM";
|
||||
#else // _BIG__ENDIAN_
|
||||
U8 IIMM[3] = "II";
|
||||
#endif // _BIG__ENDIAN_
|
||||
|
||||
TifDEMisc tifDEMisc = {
|
||||
(U32) -1, (U32) -1, (U32) -1, (U32) -1, (U32) -1,
|
||||
2, // photometric interpretation
|
||||
(U32) -1, 10000, 10000,
|
||||
(U32) -1, 10000, 10000,
|
||||
};
|
||||
// const U32 cbTifDEMisc = sizeof(U16) * 10 + sizeof(U32) * 2 * 2;
|
||||
|
||||
const static TifDE tifDEs[] =
|
||||
{
|
||||
{0x100, 4, 1, (U32) -1}, // TIF_tagImageWidth
|
||||
{0x101, 4, 1, (U32) -1}, // TIF_tagImageLength
|
||||
{0x102, 3, (U32) -1, (U32) -1}, // TIF_tagBitsPerSample
|
||||
{0x103, 3, 1, 1}, // TIF_tagCompression
|
||||
{0x106, 3, 1, (U32) -1}, // TIF_tagPhotometricInterpretation
|
||||
{0x111, 4, 1, (U32) -1}, // TIF_tagStripOffsets
|
||||
{0x112, 3, 1, 1}, // TIF_tagOrientation
|
||||
{0x115, 3, 1, (U32) -1}, // TIF_tagSamplesPerPixel
|
||||
{0x116, 4, 1, (U32) -1}, // TIF_tagRowsPerStrip
|
||||
{0x117, 4, 1, (U32) -1}, // TIF_tagStripByteCounts
|
||||
{0x11a, 5, 1, (U32) -1}, // TIF_tagXResolution
|
||||
{0x11b, 5, 1, (U32) -1}, // TIF_tagYResolution
|
||||
{0x11c, 3, 1, 1}, // TIF_tagPlanarConfiguration
|
||||
{0x128, 3, 1, 2}, // TIF_tagResolutionUnit
|
||||
{0x153, 3, (U32) -1, (U32) -1}, // TIF_tagSampleFormat
|
||||
// {0x131, 2, -1, -1}, // TIF_tagSoftware
|
||||
// {0x140, 3, -1, -1}, // TIF_tagColorMap
|
||||
};
|
||||
U16 cTifDEs = sizeof2(tifDEs);
|
||||
TifDE tifDE = {0};
|
||||
PKPixelInfo PI;
|
||||
size_t cbLine = 0;
|
||||
|
||||
size_t i = 0;
|
||||
size_t j;
|
||||
|
||||
tifDEMisc.resXF = (U32)(pIE->fResX * 10000);
|
||||
tifDEMisc.resYF = (U32)(pIE->fResY * 10000);
|
||||
|
||||
Call(pS->GetPos(pS, &offPos));
|
||||
FailIf(0 != offPos, WMP_errUnsupportedFormat);
|
||||
|
||||
//================
|
||||
// TifHeader
|
||||
Call(pS->Write(pS, IIMM, 2)); offPos += 2;
|
||||
Call(PutTifUShort(pS, offPos, 42)); offPos += 2;
|
||||
Call(PutTifULong(pS, offPos, (U32)(offPos + 4))); offPos += 4;
|
||||
|
||||
//================
|
||||
// TifDEMisc
|
||||
PI.pGUIDPixFmt = &pIE->guidPixFormat;
|
||||
PixelFormatLookup(&PI, LOOKUP_FORWARD);
|
||||
|
||||
tifDEMisc.iPhotometricInterpretation =
|
||||
//the N channel TIF by PS has PhotometricInterpretation of PK_PI_RGB
|
||||
PI.uInterpretation == PK_PI_NCH || PI.uInterpretation == PK_PI_RGBE ? PK_PI_RGB :
|
||||
(PI.uInterpretation == PK_PI_B0 && pIE->WMP.wmiSCP.bBlackWhite ? PK_PI_W0 : PI.uInterpretation);
|
||||
tifDEMisc.spp = PI.uSamplePerPixel;
|
||||
tifDEMisc.bps = PI.uBitsPerSample;
|
||||
tifDEMisc.sf = PI.uSampleFormat;
|
||||
|
||||
if (tifDEMisc.iPhotometricInterpretation == PK_PI_CMYK)
|
||||
cTifDEs++;
|
||||
if (PI.grBit & PK_pixfmtHasAlpha)
|
||||
cTifDEs++;
|
||||
tifDEMisc.offBitsPerSample = (U32)offPos + sizeof(U16) + 12 * cTifDEs + sizeof(U32);
|
||||
tifDEMisc.offSampleFormat = tifDEMisc.offBitsPerSample + (tifDEMisc.spp == 1 ? 0 : tifDEMisc.spp * 2);
|
||||
tifDEMisc.offXResolution = tifDEMisc.offSampleFormat + (tifDEMisc.spp == 1 ? 0 : tifDEMisc.spp * 2);
|
||||
tifDEMisc.offYResolution = tifDEMisc.offXResolution + 8;
|
||||
|
||||
//================
|
||||
// TifIFD
|
||||
pIE->offPixel = tifDEMisc.offYResolution + 8;
|
||||
Call(PutTifUShort(pS, offPos, cTifDEs)); offPos += 2;
|
||||
|
||||
//================
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagImageWidth == tifDE.uTag);
|
||||
tifDE.uValueOrOffset = pIE->uWidth;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagImageLength == tifDE.uTag);
|
||||
tifDE.uValueOrOffset = pIE->uHeight;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagBitsPerSample == tifDE.uTag);
|
||||
tifDE.uCount = tifDEMisc.spp;
|
||||
tifDE.uValueOrOffset = 1 == tifDE.uCount ? tifDEMisc.bps : tifDEMisc.offBitsPerSample;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagCompression == tifDE.uTag);
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagPhotometricInterpretation == tifDE.uTag);
|
||||
tifDE.uValueOrOffset = tifDEMisc.iPhotometricInterpretation;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagStripOffsets == tifDE.uTag);
|
||||
tifDE.uValueOrOffset = (U32)pIE->offPixel;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagOrientation == tifDE.uTag);
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagSamplesPerPixel == tifDE.uTag);
|
||||
tifDE.uValueOrOffset = tifDEMisc.spp;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagRowsPerStrip == tifDE.uTag);
|
||||
tifDE.uValueOrOffset = pIE->uHeight;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagStripByteCounts == tifDE.uTag);
|
||||
cbLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pIE->uWidth + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pIE->uWidth));
|
||||
tifDE.uValueOrOffset = (U32)(cbLine * pIE->uHeight);
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagXResolution == tifDE.uTag);
|
||||
tifDE.uValueOrOffset = tifDEMisc.offXResolution;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagYResolution == tifDE.uTag);
|
||||
tifDE.uValueOrOffset = tifDEMisc.offYResolution;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagPlanarConfiguration == tifDE.uTag);
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagResolutionUnit == tifDE.uTag);
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
if (tifDEMisc.iPhotometricInterpretation == PK_PI_CMYK)
|
||||
{
|
||||
TifDE tifDE = {TIF_tagInkSet, 3, 1, 1};
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
}
|
||||
|
||||
if (PI.grBit & PK_pixfmtHasAlpha)
|
||||
{
|
||||
TifDE tifDE = {TIF_tagExtraSamples, 3, 1, 1};
|
||||
if (!(PI.grBit & PK_pixfmtPreMul))
|
||||
tifDE.uValueOrOffset++;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
}
|
||||
|
||||
tifDE = tifDEs[i++];
|
||||
assert(TIF_tagSampleFormat == tifDE.uTag);
|
||||
tifDE.uCount = tifDEMisc.spp;
|
||||
tifDE.uValueOrOffset = 1 == tifDE.uCount ? tifDEMisc.sf : tifDEMisc.offSampleFormat;
|
||||
Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12;
|
||||
|
||||
//================
|
||||
Call(PutTifULong(pS, offPos, 0)); offPos += 4;
|
||||
|
||||
//================
|
||||
// TifDEMisc
|
||||
if (tifDE.uCount > 1)
|
||||
{
|
||||
assert(tifDEMisc.offBitsPerSample == offPos);
|
||||
if (PI.bdBitDepth == BD_565)
|
||||
{
|
||||
Call(PutTifUShort(pS, offPos, 5)); offPos += 2;
|
||||
Call(PutTifUShort(pS, offPos, 6)); offPos += 2;
|
||||
Call(PutTifUShort(pS, offPos, 5)); offPos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < tifDE.uCount; j++)
|
||||
{
|
||||
Call(PutTifUShort(pS, offPos, (U16)tifDEMisc.bps)); offPos += 2;
|
||||
}
|
||||
}
|
||||
|
||||
assert(tifDEMisc.offSampleFormat == offPos);
|
||||
for (j = 0; j < tifDE.uCount; j++)
|
||||
{
|
||||
Call(PutTifUShort(pS, offPos, (U16)tifDEMisc.sf)); offPos += 2;
|
||||
}
|
||||
}
|
||||
|
||||
assert(tifDEMisc.offXResolution == offPos);
|
||||
Call(PutTifULong(pS, offPos, tifDEMisc.resXF)); offPos += 4;
|
||||
Call(PutTifULong(pS, offPos, tifDEMisc.resXD)); offPos += 4;
|
||||
|
||||
assert(tifDEMisc.offYResolution == offPos);
|
||||
Call(PutTifULong(pS, offPos, tifDEMisc.resYF)); offPos += 4;
|
||||
Call(PutTifULong(pS, offPos, tifDEMisc.resYD)); offPos += 4;
|
||||
|
||||
assert(pIE->offPixel == offPos);
|
||||
|
||||
pIE->fHeaderDone = !FALSE;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_TIF
|
||||
//================================================================
|
||||
ERR PKImageEncode_WritePixels_TIF(
|
||||
PKImageEncode* pIE,
|
||||
U32 cLine,
|
||||
U8* pbPixel,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
PKPixelInfo PI;
|
||||
size_t cbLine = 0;
|
||||
size_t offPos = 0;
|
||||
size_t i = 0;
|
||||
|
||||
// header
|
||||
if (!pIE->fHeaderDone)
|
||||
{
|
||||
Call(WriteTifHeader(pIE));
|
||||
}
|
||||
|
||||
// body
|
||||
PI.pGUIDPixFmt = &pIE->guidPixFormat;
|
||||
PixelFormatLookup(&PI, LOOKUP_FORWARD);
|
||||
|
||||
cbLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pIE->uWidth + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pIE->uWidth));
|
||||
|
||||
FailIf(cbStride < cbLine, WMP_errInvalidParameter);
|
||||
|
||||
offPos = pIE->offPixel + cbLine * pIE->idxCurrentLine;
|
||||
Call(pS->SetPos(pS, offPos));
|
||||
|
||||
for (i = 0; i < cLine; ++i)
|
||||
{
|
||||
Call(pS->Write(pS, pbPixel + cbStride * i, cbLine));
|
||||
}
|
||||
pIE->idxCurrentLine += cLine;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Create_TIF(PKImageEncode** ppIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
PKImageEncode* pIE = NULL;
|
||||
|
||||
Call(PKImageEncode_Create(ppIE));
|
||||
|
||||
pIE = *ppIE;
|
||||
pIE->WritePixels = PKImageEncode_WritePixels_TIF;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_TIF helpers
|
||||
//================================================================
|
||||
ERR GetTifUShort(
|
||||
struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
Bool fLittleEndian,
|
||||
U16* puValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U8 buf[2];
|
||||
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
Call(pWS->Read(pWS, buf, sizeof2(buf)));
|
||||
|
||||
if (fLittleEndian)
|
||||
{
|
||||
*puValue = buf[0] + ((U16)buf[1] << 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
*puValue = ((U16)buf[0] << 8) + buf[1];
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR GetTifULong(
|
||||
struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
Bool fLittleEndian,
|
||||
U32* puValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U8 buf[4];
|
||||
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
Call(pWS->Read(pWS, buf, sizeof2(buf)));
|
||||
|
||||
if (fLittleEndian)
|
||||
{
|
||||
*puValue = buf[0] + ((U32)buf[1] << 8) + ((U32)buf[2] << 16) + ((U32)buf[3] << 24);
|
||||
}
|
||||
else
|
||||
{
|
||||
*puValue = ((U32)buf[0] << 24) + ((U32)buf[1] << 16) + ((U32)buf[2] << 8) + buf[3];
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR GetTifULongArray(
|
||||
struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
size_t cElements,
|
||||
Bool fLittleEndian,
|
||||
U32* puValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
if (1 == cElements)
|
||||
{
|
||||
puValue[0] = (U32)offPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i = 0;
|
||||
for (i = 0; i < cElements; ++i)
|
||||
{
|
||||
Call(GetTifULong(pWS, offPos, fLittleEndian, &puValue[i]));
|
||||
offPos += sizeof(*puValue);
|
||||
}
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR ParseTifDEValue(
|
||||
PKTestDecode* pID,
|
||||
U16 uTag,
|
||||
U16 uType,
|
||||
U32 uCount)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pWS = pID->pStream;
|
||||
U16 bpc[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
U16 sf[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
U32 uPos = 0;
|
||||
U16 usValue = 0;
|
||||
U32 uValue0 = 0;
|
||||
U32 uValue1 = 0;
|
||||
size_t i, offPos = 0;
|
||||
|
||||
//================================
|
||||
Call(pWS->GetPos(pWS, &offPos));
|
||||
|
||||
//================================
|
||||
switch (uType)
|
||||
{
|
||||
case TIF_typSHORT:
|
||||
Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &usValue));
|
||||
uValue0 = usValue;
|
||||
break;
|
||||
|
||||
case TIF_typLONG:
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0));
|
||||
break;
|
||||
}
|
||||
|
||||
//================================
|
||||
switch (uTag)
|
||||
{
|
||||
case TIF_tagNewSubfileType:
|
||||
FailIf(0 != uValue0, WMP_errUnsupportedFormat);
|
||||
break;
|
||||
|
||||
case TIF_tagSubfileType:
|
||||
case TIF_tagPredictor:
|
||||
FailIf(1 != uValue0, WMP_errUnsupportedFormat);
|
||||
break;
|
||||
|
||||
case TIF_tagImageWidth:
|
||||
pID->uWidth = uValue0;
|
||||
break;
|
||||
|
||||
case TIF_tagImageLength:
|
||||
pID->uHeight = uValue0;
|
||||
break;
|
||||
|
||||
case TIF_tagBitsPerSample:
|
||||
if (1 == uCount)
|
||||
{
|
||||
pID->EXT.TIF.uBitsPerSample = uValue0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Bool bpcAnd = 1;
|
||||
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uPos));
|
||||
offPos = uPos;
|
||||
|
||||
Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &bpc[0]));
|
||||
|
||||
for (i = 1; i < uCount; i++)
|
||||
{
|
||||
Call(GetTifUShort(pWS, offPos + (i << 1) , pID->EXT.TIF.fLittleEndian, &bpc[i]));
|
||||
bpcAnd = (bpcAnd && (bpc[0] == bpc[i]));
|
||||
}
|
||||
|
||||
if (bpcAnd)
|
||||
pID->EXT.TIF.uBitsPerSample = bpc[0];
|
||||
else
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
}
|
||||
break;
|
||||
|
||||
case TIF_tagExtraSamples:
|
||||
FailIf(0 != uValue0 && 1 != uValue0 && 2 != uValue0, WMP_errUnsupportedFormat);
|
||||
pID->EXT.TIF.uExtraSamples = uValue0;
|
||||
break;
|
||||
|
||||
case TIF_tagSampleFormat:
|
||||
if (1 == uCount)
|
||||
{
|
||||
pID->EXT.TIF.uSampleFormat = uValue0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Bool sfAnd = 1;
|
||||
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uPos));
|
||||
offPos = uPos;
|
||||
|
||||
Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &sf[0]));
|
||||
|
||||
for (i = 1; i < uCount; i++)
|
||||
{
|
||||
Call(GetTifUShort(pWS, offPos + (i << 1) , pID->EXT.TIF.fLittleEndian, &sf[i]));
|
||||
sfAnd = (sfAnd && (sf[0] == sf[i]));
|
||||
}
|
||||
|
||||
if (sfAnd)
|
||||
pID->EXT.TIF.uSampleFormat = sf[0];
|
||||
else
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
}
|
||||
break;
|
||||
|
||||
case TIF_tagCompression:
|
||||
FailIf(1 != uValue0, WMP_errUnsupportedFormat);
|
||||
break;
|
||||
|
||||
case TIF_tagPhotometricInterpretation:
|
||||
Test(PK_PI_W0 == uValue0 || PK_PI_B0 == uValue0 || PK_PI_RGB == uValue0
|
||||
|| PK_PI_RGBPalette == uValue0 || PK_PI_TransparencyMask == uValue0
|
||||
|| PK_PI_CMYK == uValue0 || PK_PI_YCbCr == uValue0
|
||||
|| PK_PI_CIELab == uValue0, WMP_errUnsupportedFormat);
|
||||
|
||||
pID->EXT.TIF.uInterpretation = uValue0;
|
||||
break;
|
||||
|
||||
case TIF_tagStripOffsets:
|
||||
Call(WMPAlloc((void **) &pID->EXT.TIF.uStripOffsets, sizeof(*pID->EXT.TIF.uStripOffsets) * uCount));
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0));
|
||||
Call(GetTifULongArray(pWS, uValue0, uCount, pID->EXT.TIF.fLittleEndian, pID->EXT.TIF.uStripOffsets));
|
||||
break;
|
||||
|
||||
case TIF_tagOrientation:
|
||||
case TIF_tagSamplesPerPixel:
|
||||
pID->EXT.TIF.uSamplePerPixel = uValue0;
|
||||
break;
|
||||
|
||||
case TIF_tagRowsPerStrip:
|
||||
pID->EXT.TIF.uRowsPerStrip = uValue0;
|
||||
break;
|
||||
|
||||
case TIF_tagStripByteCounts:
|
||||
Call(WMPAlloc((void **) &pID->EXT.TIF.uStripByteCounts, sizeof(*pID->EXT.TIF.uStripByteCounts) * uCount));
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0));
|
||||
Call(GetTifULongArray(pWS, uValue0, uCount, pID->EXT.TIF.fLittleEndian, pID->EXT.TIF.uStripByteCounts));
|
||||
break;
|
||||
|
||||
case TIF_tagXResolution:
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uPos));
|
||||
offPos = uPos;
|
||||
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0));//numerator
|
||||
Call(GetTifULong(pWS, offPos + 4, pID->EXT.TIF.fLittleEndian, &uValue1));//denominator
|
||||
|
||||
pID->EXT.TIF.fResX = (Float)uValue0/(Float)uValue1;
|
||||
break;
|
||||
|
||||
case TIF_tagYResolution:
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uPos));
|
||||
offPos = uPos;
|
||||
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0));//numerator
|
||||
Call(GetTifULong(pWS, offPos + 4, pID->EXT.TIF.fLittleEndian, &uValue1));//denominator
|
||||
pID->EXT.TIF.fResY = (Float)uValue0/(Float)uValue1;
|
||||
break;
|
||||
|
||||
case TIF_tagResolutionUnit:
|
||||
pID->EXT.TIF.uResolutionUnit = usValue;
|
||||
break;
|
||||
|
||||
case TIF_tagPlanarConfiguration:
|
||||
case TIF_tagSoftware:
|
||||
case TIF_tagColorMap:
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unrecognized TIFTag: %d(%#x), %d, %d" CRLF, (int)uTag, (int)uTag, (int)uType, (int)uCount);
|
||||
break;
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR ParseTifDEArray(
|
||||
PKTestDecode* pID,
|
||||
size_t offPos)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pWS = pID->pStream;
|
||||
U16 uTag = 0;
|
||||
U16 uType = 0;
|
||||
U32 uCount = 0;
|
||||
|
||||
Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uTag));
|
||||
offPos += 2;
|
||||
|
||||
Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uType));
|
||||
offPos += 2;
|
||||
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uCount));
|
||||
offPos += 4;
|
||||
|
||||
Call(ParseTifDEValue(pID, uTag, uType, uCount));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR ParseTifHeader(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKPixelInfo PI;
|
||||
|
||||
size_t offPosBase = 0;
|
||||
size_t offPos = 0;
|
||||
|
||||
U8 szSig[3] = {0, 0, '\0'};
|
||||
U16 uTiffId = 0;
|
||||
U32 uOffNextIFD = 0;
|
||||
U16 uCountDE = 0, i = 0;
|
||||
|
||||
//default
|
||||
pID->EXT.TIF.uRowsPerStrip = (U32) -1;
|
||||
pID->EXT.TIF.uInterpretation = (U32) -1;
|
||||
pID->EXT.TIF.uSamplePerPixel = (U32) -1;
|
||||
pID->EXT.TIF.uBitsPerSample = (U32) -1;
|
||||
pID->EXT.TIF.uSampleFormat = 1;
|
||||
pID->EXT.TIF.uResolutionUnit = 2;
|
||||
pID->EXT.TIF.fResX = 96;
|
||||
pID->EXT.TIF.fResY = 96;
|
||||
|
||||
//================================
|
||||
Call(pWS->GetPos(pWS, &offPosBase));
|
||||
FailIf(0 != offPosBase, WMP_errUnsupportedFormat);
|
||||
|
||||
//================================
|
||||
// Header
|
||||
Call(pWS->Read(pWS, szSig, 2));
|
||||
offPos += 2;
|
||||
if (szSig == (U8 *) strstr((char *) szSig, "II"))
|
||||
{
|
||||
pID->EXT.TIF.fLittleEndian = !FALSE;
|
||||
}
|
||||
else if (szSig == (U8 *) strstr((char *) szSig, "MM"))
|
||||
{
|
||||
pID->EXT.TIF.fLittleEndian = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
}
|
||||
|
||||
Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uTiffId));
|
||||
offPos += 2;
|
||||
FailIf(42 != uTiffId, WMP_errUnsupportedFormat);
|
||||
|
||||
Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uOffNextIFD));
|
||||
offPos += 4;
|
||||
|
||||
//================================
|
||||
// IFD
|
||||
offPos = (size_t)uOffNextIFD;
|
||||
Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uCountDE));
|
||||
offPos += 2;
|
||||
|
||||
for (i = 0; i < uCountDE; ++i)
|
||||
{
|
||||
Call(ParseTifDEArray(pID, offPos));
|
||||
offPos += 12;
|
||||
}
|
||||
|
||||
if(pID->EXT.TIF.uRowsPerStrip == -1)
|
||||
pID->EXT.TIF.uRowsPerStrip = pID->uHeight;//default
|
||||
|
||||
FailIf((-1 == pID->EXT.TIF.uInterpretation
|
||||
|| -1 == pID->EXT.TIF.uSamplePerPixel
|
||||
|| -1 == pID->EXT.TIF.uBitsPerSample), WMP_errUnsupportedFormat);
|
||||
|
||||
PI.uInterpretation = pID->EXT.TIF.uInterpretation;
|
||||
PI.uSamplePerPixel = pID->EXT.TIF.uSamplePerPixel;
|
||||
PI.uBitsPerSample = pID->EXT.TIF.uBitsPerSample;
|
||||
PI.uSampleFormat = pID->EXT.TIF.uSampleFormat;
|
||||
|
||||
PI.grBit = pID->EXT.TIF.uExtraSamples == 1 || pID->EXT.TIF.uExtraSamples == 2 ||
|
||||
/* Workaround for some images without correct info about alpha channel */
|
||||
(pID->EXT.TIF.uExtraSamples == 0 && pID->EXT.TIF.uSamplePerPixel > 3) ? PK_pixfmtHasAlpha : 0x0;
|
||||
PI.grBit |= pID->EXT.TIF.uExtraSamples == 1 ? PK_pixfmtPreMul : 0x0;
|
||||
|
||||
pID->fResX = (3 == pID->EXT.TIF.uResolutionUnit ? (Float)(pID->EXT.TIF.fResX * 2.54) : pID->EXT.TIF.fResX);//cm -> inch
|
||||
pID->fResY = (3 == pID->EXT.TIF.uResolutionUnit ? (Float)(pID->EXT.TIF.fResY * 2.54) : pID->EXT.TIF.fResY);//cm -> inch
|
||||
|
||||
Call(PixelFormatLookup(&PI, LOOKUP_BACKWARD_TIF));
|
||||
|
||||
pID->guidPixFormat = *(PI.pGUIDPixFmt);
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_TIF
|
||||
//================================================================
|
||||
ERR PKImageDecode_Initialize_TIF(
|
||||
PKTestDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKTestDecode_Initialize(pID, pWS));
|
||||
Call(ParseTifHeader(pID, pWS));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR GetScanLineOffset(
|
||||
PKTestDecode* pID,
|
||||
I32 iLine,
|
||||
U32 cbLine,
|
||||
U32 *offLine)
|
||||
{
|
||||
*offLine = pID->EXT.TIF.uRowsPerStrip ?
|
||||
(pID->EXT.TIF.uStripOffsets[iLine / pID->EXT.TIF.uRowsPerStrip] +
|
||||
cbLine * (iLine % pID->EXT.TIF.uRowsPerStrip)) :
|
||||
0;
|
||||
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Copy_TIF(
|
||||
PKTestDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
struct WMPStream* pS = pID->pStream;
|
||||
PKPixelInfo PI;
|
||||
U32 cbLine = 0;
|
||||
I32 i = 0;
|
||||
|
||||
PI.pGUIDPixFmt = &pID->guidPixFormat;
|
||||
PixelFormatLookup(&PI, LOOKUP_FORWARD);
|
||||
|
||||
cbLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pRect->Width + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pRect->Width));
|
||||
|
||||
assert(0 == pRect->X && pID->uWidth == (U32)pRect->Width);
|
||||
assert(cbLine <= cbStride);
|
||||
|
||||
for (i = 0; i < pRect->Height; ++i)
|
||||
{
|
||||
U32 offPixels = 0;
|
||||
Call(GetScanLineOffset(pID, pRect->Y + i, cbLine, &offPixels));
|
||||
|
||||
Call(pS->SetPos(pS, offPixels));
|
||||
Call(pS->Read(pS, pb + cbStride * i, cbLine));
|
||||
|
||||
if (PK_PI_W0 == pID->EXT.TIF.uInterpretation)
|
||||
{
|
||||
U32 j, begin = cbStride * (U32)i, end = begin + cbLine;
|
||||
for (j = begin; j < end; ++j)
|
||||
{
|
||||
pb[j] = ~pb[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Release_TIF(PKTestDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
PKTestDecode *pID = *ppID;
|
||||
|
||||
Call(WMPFree(&pID->EXT.TIF.uStripOffsets));
|
||||
Call(WMPFree(&pID->EXT.TIF.uStripByteCounts));
|
||||
|
||||
Call(PKTestDecode_Release(ppID));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Create_TIF(PKTestDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKTestDecode* pID = NULL;
|
||||
|
||||
Call(PKTestDecode_Create(ppID));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKImageDecode_Initialize_TIF;
|
||||
pID->Copy = PKImageDecode_Copy_TIF;
|
||||
pID->Release = PKImageDecode_Release_TIF;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
723
jxrlib/jxrtestlib/JXRTestYUV.c
Normal file
723
jxrlib/jxrtestlib/JXRTestYUV.c
Normal file
|
|
@ -0,0 +1,723 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <JXRGlue.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma pack(pop)
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_Iyuv
|
||||
//================================================================
|
||||
ERR WriteIYUVHeader(
|
||||
PKImageEncode* pIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
// struct WMPStream* pS = pIE->pStream;
|
||||
|
||||
pIE->offPixel = 0;
|
||||
|
||||
pIE->cbPixel = 3;
|
||||
|
||||
pIE->fHeaderDone = !FALSE;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_Yuv422
|
||||
//================================================================
|
||||
ERR WriteYUV422Header(
|
||||
PKImageEncode* pIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
// struct WMPStream* pS = pIE->pStream;
|
||||
|
||||
pIE->offPixel = 0;
|
||||
|
||||
pIE->cbPixel = 3;
|
||||
|
||||
pIE->fHeaderDone = !FALSE;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode_Yuv444
|
||||
//================================================================
|
||||
ERR WriteYUV444Header(
|
||||
PKImageEncode* pIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
// struct WMPStream* pS = pIE->pStream;
|
||||
|
||||
pIE->offPixel = 0;
|
||||
|
||||
pIE->cbPixel = 3;
|
||||
|
||||
pIE->fHeaderDone = !FALSE;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_WritePixels_IYUV(
|
||||
PKImageEncode* pIE,
|
||||
U32 cLine,
|
||||
U8* pbPixel,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
size_t iRow, iCol;
|
||||
U32 uYSize, uUVSize;
|
||||
U8 *pY;
|
||||
U8 *pU;
|
||||
U8 *pV;
|
||||
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
|
||||
// header
|
||||
if (!pIE->fHeaderDone)
|
||||
{
|
||||
Call(WriteIYUVHeader(pIE));
|
||||
}
|
||||
|
||||
//from packed to planar:
|
||||
uYSize = cLine * pIE->uWidth;
|
||||
uUVSize = (uYSize >> 2);
|
||||
|
||||
pY = (U8 *)malloc(uYSize);
|
||||
pU = (U8 *)malloc(uUVSize);
|
||||
pV = (U8 *)malloc(uUVSize);
|
||||
|
||||
if(pY == NULL || pU == NULL || pV == NULL)
|
||||
{
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
|
||||
for (iRow = 0; iRow < pIE->uHeight; iRow += 2, pY += pIE->uWidth)
|
||||
{
|
||||
for (iCol = 0; iCol < pIE->uWidth; iCol += 2, pY += 2)
|
||||
{
|
||||
|
||||
*pY = *pbPixel;
|
||||
pbPixel++;
|
||||
*(pY + 1)= *pbPixel;
|
||||
pbPixel++;
|
||||
*(pY + pIE->uWidth) = *pbPixel;
|
||||
pbPixel++;
|
||||
*(pY + pIE->uWidth + 1) = *pbPixel;
|
||||
pbPixel++;
|
||||
|
||||
*pU = *pbPixel;
|
||||
pbPixel++; pU++;
|
||||
*pV = *pbPixel;
|
||||
pbPixel++; pV++;
|
||||
}
|
||||
}
|
||||
|
||||
pY-=uYSize;
|
||||
pU-=uUVSize;
|
||||
pV-=uUVSize;
|
||||
|
||||
Call(pS->Write(pS, pY, uYSize));
|
||||
Call(pS->Write(pS, pU, uUVSize));
|
||||
Call(pS->Write(pS, pV, uUVSize));
|
||||
|
||||
if(pY!=NULL)
|
||||
free(pY);
|
||||
if(pU!=NULL)
|
||||
free(pU);
|
||||
if(pV!=NULL)
|
||||
free(pV);
|
||||
|
||||
pIE->idxCurrentLine += cLine;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageEncode_WritePixels_YUV422(
|
||||
PKImageEncode* pIE,
|
||||
U32 cLine,
|
||||
U8* pbPixel,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
size_t iRow, iCol;
|
||||
U32 uYSize, uUVSize;
|
||||
U8 *pY;
|
||||
U8 *pU;
|
||||
U8 *pV;
|
||||
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
|
||||
// header
|
||||
if (!pIE->fHeaderDone)
|
||||
{
|
||||
Call(WriteIYUVHeader(pIE));
|
||||
}
|
||||
|
||||
//from packed to planar:
|
||||
uYSize = cLine * pIE->uWidth;
|
||||
uUVSize = (uYSize >> 1);
|
||||
|
||||
pY = (U8 *)malloc(uYSize);
|
||||
pU = (U8 *)malloc(uUVSize);
|
||||
pV = (U8 *)malloc(uUVSize);
|
||||
|
||||
if(pY == NULL || pU == NULL || pV == NULL)
|
||||
{
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
//YYUV
|
||||
for (iRow = 0; iRow < pIE->uHeight; iRow += 1)
|
||||
{
|
||||
for (iCol = 0; iCol < pIE->uWidth; iCol += 2)
|
||||
{
|
||||
*pU = *pbPixel;
|
||||
pbPixel++; pU++;
|
||||
|
||||
*pY = *pbPixel;
|
||||
pbPixel++; pY++;
|
||||
|
||||
*pV = *pbPixel;
|
||||
pbPixel++; pV++;
|
||||
|
||||
*pY = *pbPixel;
|
||||
pbPixel++; pY++;
|
||||
}
|
||||
}
|
||||
|
||||
pY-=uYSize;
|
||||
pU-=uUVSize;
|
||||
pV-=uUVSize;
|
||||
|
||||
Call(pS->Write(pS, pY, uYSize));
|
||||
Call(pS->Write(pS, pU, uUVSize));
|
||||
Call(pS->Write(pS, pV, uUVSize));
|
||||
|
||||
if(pY!=NULL)
|
||||
free(pY);
|
||||
if(pU!=NULL)
|
||||
free(pU);
|
||||
if(pV!=NULL)
|
||||
free(pV);
|
||||
|
||||
pIE->idxCurrentLine += cLine;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageEncode_WritePixels_YUV444(
|
||||
PKImageEncode* pIE,
|
||||
U32 cLine,
|
||||
U8* pbPixel,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
struct WMPStream* pS = pIE->pStream;
|
||||
size_t iRow, iCol;
|
||||
U32 uYSize, uUVSize;
|
||||
U8 *pY;
|
||||
U8 *pU;
|
||||
U8 *pV;
|
||||
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
|
||||
// header
|
||||
if (!pIE->fHeaderDone)
|
||||
{
|
||||
Call(WriteIYUVHeader(pIE));
|
||||
}
|
||||
|
||||
//from packed to planar:
|
||||
uYSize = cLine * pIE->uWidth;
|
||||
uUVSize = uYSize;
|
||||
|
||||
pY = (U8 *)malloc(uYSize);
|
||||
pU = (U8 *)malloc(uUVSize);
|
||||
pV = (U8 *)malloc(uUVSize);
|
||||
|
||||
if(pY == NULL || pU == NULL || pV == NULL)
|
||||
{
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
|
||||
for (iRow = 0; iRow < pIE->uHeight; iRow += 1)
|
||||
{
|
||||
for (iCol = 0; iCol < pIE->uWidth; iCol += 1)
|
||||
{
|
||||
|
||||
*pY = *pbPixel;
|
||||
pbPixel++; pY++;
|
||||
|
||||
*pU = *pbPixel;
|
||||
pbPixel++; pU++;
|
||||
*pV = *pbPixel;
|
||||
pbPixel++; pV++;
|
||||
}
|
||||
}
|
||||
|
||||
pY-=uYSize;
|
||||
pU-=uUVSize;
|
||||
pV-=uUVSize;
|
||||
|
||||
Call(pS->Write(pS, pY, uYSize));
|
||||
Call(pS->Write(pS, pU, uUVSize));
|
||||
Call(pS->Write(pS, pV, uUVSize));
|
||||
|
||||
if(pY!=NULL)
|
||||
free(pY);
|
||||
if(pU!=NULL)
|
||||
free(pU);
|
||||
if(pV!=NULL)
|
||||
free(pV);
|
||||
|
||||
pIE->idxCurrentLine += cLine;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR PKImageEncode_Create_IYUV(
|
||||
PKImageEncode** ppIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageEncode* pIE = NULL;
|
||||
|
||||
Call(PKImageEncode_Create(ppIE));
|
||||
|
||||
pIE = *ppIE;
|
||||
pIE->WritePixels = PKImageEncode_WritePixels_IYUV;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Create_YUV422(
|
||||
PKImageEncode** ppIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageEncode* pIE = NULL;
|
||||
|
||||
Call(PKImageEncode_Create(ppIE));
|
||||
|
||||
pIE = *ppIE;
|
||||
pIE->WritePixels = PKImageEncode_WritePixels_YUV422;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Create_YUV444(
|
||||
PKImageEncode** ppIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageEncode* pIE = NULL;
|
||||
|
||||
Call(PKImageEncode_Create(ppIE));
|
||||
|
||||
pIE = *ppIE;
|
||||
pIE->WritePixels = PKImageEncode_WritePixels_YUV444;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_IYUV
|
||||
//================================================================
|
||||
ERR ParseIYUVHeader(
|
||||
PKImageDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
UNREFERENCED_PARAMETER( pWS );
|
||||
|
||||
// Set header other header parameters
|
||||
pID->guidPixFormat = GUID_PKPixelFormat12bppYUV420;
|
||||
|
||||
pID->uHeight = 144;
|
||||
pID->uWidth = 176;
|
||||
|
||||
//I don't need offpixel for raw data! Call(pWS->GetPos(pWS, &pID->YUV420.offPixel));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_YUV422
|
||||
//================================================================
|
||||
ERR ParseYUV422Header(
|
||||
PKImageDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
UNREFERENCED_PARAMETER( pWS );
|
||||
|
||||
// Set header other header parameters
|
||||
pID->guidPixFormat = GUID_PKPixelFormat16bppYUV422;
|
||||
|
||||
pID->uHeight = 144;
|
||||
pID->uWidth = 176;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode_YUV422
|
||||
//================================================================
|
||||
ERR ParseYUV444Header(
|
||||
PKImageDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
UNREFERENCED_PARAMETER( pWS );
|
||||
|
||||
// Set header other header parameters
|
||||
pID->guidPixFormat = GUID_PKPixelFormat24bppYUV444;
|
||||
|
||||
pID->uHeight = 144;
|
||||
pID->uWidth = 176;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Initialize_IYUV(
|
||||
PKImageDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKImageDecode_Initialize(pID, pWS));
|
||||
Call(ParseIYUVHeader(pID, pWS));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Initialize_YUV422(
|
||||
PKImageDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKImageDecode_Initialize(pID, pWS));
|
||||
Call(ParseYUV422Header(pID, pWS));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Initialize_YUV444(
|
||||
PKImageDecode* pID,
|
||||
struct WMPStream* pWS)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKImageDecode_Initialize(pID, pWS));
|
||||
Call(ParseYUV444Header(pID, pWS));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageDecode_Copy_IYUV(
|
||||
PKImageDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U32 uYSize, uUVSize;
|
||||
U8 *pY;
|
||||
U8 *pU;
|
||||
U8 *pV;
|
||||
|
||||
struct WMPStream* pS = pID->pStream;
|
||||
|
||||
size_t iRow, iCol;
|
||||
|
||||
UNREFERENCED_PARAMETER( pRect );
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
|
||||
//from planar to packed! YYYYUV YYYYUV
|
||||
uYSize = pID->uWidth * pID->uHeight;
|
||||
uUVSize = (uYSize >> 2);
|
||||
|
||||
pY = (U8 *)malloc(uYSize);
|
||||
pU = (U8 *)malloc(uUVSize);
|
||||
pV = (U8 *)malloc(uUVSize);
|
||||
|
||||
if(pY == NULL || pU == NULL || pV == NULL)
|
||||
{
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
|
||||
Call(pS->Read(pS, pY, uYSize));
|
||||
Call(pS->Read(pS, pU, uUVSize));
|
||||
Call(pS->Read(pS, pV, uUVSize));
|
||||
|
||||
//re-organize it to Y0 Y1
|
||||
// Y2 Y3 U V
|
||||
|
||||
for (iRow = 0; iRow < pID->uHeight; iRow += 2, pY += pID->uWidth)
|
||||
{
|
||||
for (iCol = 0; iCol < pID->uWidth; iCol += 2, pY += 2)
|
||||
{
|
||||
*pb = *pY;
|
||||
pb++;
|
||||
*pb = *(pY + 1);
|
||||
pb++;
|
||||
*pb = *(pY + pID->uWidth);
|
||||
pb++;
|
||||
*pb = *(pY + pID->uWidth + 1);
|
||||
pb++;
|
||||
|
||||
*pb = *pU;
|
||||
pb++; pU++;
|
||||
*pb = *pV;
|
||||
pb++; pV++;
|
||||
}
|
||||
}
|
||||
|
||||
pY-=uYSize;
|
||||
pU-=uUVSize;
|
||||
pV-=uUVSize;
|
||||
if(pY!=NULL)
|
||||
free(pY);
|
||||
if(pU!=NULL)
|
||||
free(pU);
|
||||
if(pV!=NULL)
|
||||
free(pV);
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageDecode_Copy_YUV422(
|
||||
PKImageDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U32 uYSize, uUVSize;
|
||||
U8 *pY;
|
||||
U8 *pU;
|
||||
U8 *pV;
|
||||
|
||||
struct WMPStream* pS = pID->pStream;
|
||||
|
||||
size_t iRow, iCol;
|
||||
|
||||
UNREFERENCED_PARAMETER( pRect );
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
|
||||
uYSize = pID->uWidth * pID->uHeight;
|
||||
uUVSize = (uYSize >> 1);
|
||||
|
||||
pY = (U8 *)malloc(uYSize);
|
||||
pU = (U8 *)malloc(uUVSize);
|
||||
pV = (U8 *)malloc(uUVSize);
|
||||
|
||||
if(pY == NULL || pU == NULL || pV == NULL)
|
||||
{
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
|
||||
Call(pS->Read(pS, pY, uYSize));
|
||||
Call(pS->Read(pS, pU, uUVSize));
|
||||
Call(pS->Read(pS, pV, uUVSize));
|
||||
|
||||
//re-organize to iMode 0 : YYUV
|
||||
|
||||
for (iRow = 0; iRow < pID->uHeight; iRow += 1)
|
||||
{
|
||||
for (iCol = 0; iCol < pID->uWidth; iCol += 2)
|
||||
{
|
||||
*pb = *pU;
|
||||
pb++; pU++;
|
||||
|
||||
*pb = *pY;
|
||||
pb++; pY++;
|
||||
|
||||
*pb = *pV;
|
||||
pb++; pV++;
|
||||
|
||||
*pb = *pY;
|
||||
pb++; pY++;
|
||||
}
|
||||
}
|
||||
|
||||
pY-=uYSize;
|
||||
pU-=uUVSize;
|
||||
pV-=uUVSize;
|
||||
if(pY!=NULL)
|
||||
free(pY);
|
||||
if(pU!=NULL)
|
||||
free(pU);
|
||||
if(pV!=NULL)
|
||||
free(pV);
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageDecode_Copy_YUV444(
|
||||
PKImageDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U32 uYSize, uUVSize;
|
||||
U8 *pY;
|
||||
U8 *pU;
|
||||
U8 *pV;
|
||||
|
||||
struct WMPStream* pS = pID->pStream;
|
||||
|
||||
size_t iRow, iCol;
|
||||
|
||||
UNREFERENCED_PARAMETER( pRect );
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
|
||||
//from planar to packed! YYYYUV YYYYUV
|
||||
uYSize = pID->uWidth * pID->uHeight;
|
||||
uUVSize = uYSize;
|
||||
|
||||
pY = (U8 *)malloc(uYSize);
|
||||
pU = (U8 *)malloc(uUVSize);
|
||||
pV = (U8 *)malloc(uUVSize);
|
||||
|
||||
if(pY == NULL || pU == NULL || pV == NULL)
|
||||
{
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
|
||||
Call(pS->Read(pS, pY, uYSize));
|
||||
Call(pS->Read(pS, pU, uUVSize));
|
||||
Call(pS->Read(pS, pV, uUVSize));
|
||||
|
||||
//Organize it as YUVYUVYUV...
|
||||
|
||||
for (iRow = 0; iRow < pID->uHeight; iRow += 1)
|
||||
{
|
||||
for (iCol = 0; iCol < pID->uWidth; iCol += 1)
|
||||
{
|
||||
*pb = *pY;
|
||||
pb++; pY++;
|
||||
|
||||
*pb = *pU;
|
||||
pb++; pU++;
|
||||
*pb = *pV;
|
||||
pb++; pV++;
|
||||
}
|
||||
}
|
||||
|
||||
pY-=uYSize;
|
||||
pU-=uUVSize;
|
||||
pV-=uUVSize;
|
||||
if(pY!=NULL)
|
||||
free(pY);
|
||||
if(pU!=NULL)
|
||||
free(pU);
|
||||
if(pV!=NULL)
|
||||
free(pV);
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageDecode_Create_IYUV(
|
||||
PKImageDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageDecode* pID = NULL;
|
||||
|
||||
Call(PKImageDecode_Create(ppID));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKImageDecode_Initialize_IYUV;
|
||||
pID->Copy = PKImageDecode_Copy_IYUV;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Create_YUV422(
|
||||
PKImageDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageDecode* pID = NULL;
|
||||
|
||||
Call(PKImageDecode_Create(ppID));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKImageDecode_Initialize_YUV422;
|
||||
pID->Copy = PKImageDecode_Copy_YUV422;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Create_YUV444(
|
||||
PKImageDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageDecode* pID = NULL;
|
||||
|
||||
Call(PKImageDecode_Create(ppID));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKImageDecode_Initialize_YUV444;
|
||||
pID->Copy = PKImageDecode_Copy_YUV444;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue