Yucom/jxrlib/jxrtestlib/JXRTestYUV.c
2020-09-29 14:29:06 -05:00

723 lines
15 KiB
C

//*@@@+++@@@@******************************************************************
//
// Copyright © Microsoft Corp.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// • Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// • Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//*@@@---@@@@******************************************************************
#include <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;
}