369 lines
7.8 KiB
C++
369 lines
7.8 KiB
C++
#ifndef _APPPROC_HPP_
|
|
#define _APPPROC_HPP_
|
|
|
|
extern "C" {
|
|
#include "jpeglib.h"
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
WORD wTag;
|
|
WORD wType;
|
|
DWORD dwCount; // Number of "wTypes"
|
|
union
|
|
{
|
|
DWORD dwOffset; // either value (if 4-bytes or less) or address of
|
|
// value
|
|
USHORT us;
|
|
ULONG ul;
|
|
BYTE b;
|
|
LONG l;
|
|
};
|
|
|
|
} IFD_TAG;
|
|
|
|
#define SWAP_DWORD(_x) ((((_x) & 0xff) << 24)|((((_x)>>8) & 0xff) << 16)|((((_x)>>16) & 0xff) << 8)|((((_x)>>24) & 0xff) << 0))
|
|
#define SWAP_WORD(_x) ((((_x) & 0xff) << 8)|((((_x)>>8) & 0xff) << 0))
|
|
|
|
// Get thumbnail from APP1 header
|
|
|
|
HRESULT
|
|
GetAPP1Thumbnail(OUT IImage** thumbImage,
|
|
IN PVOID APP1_marker,
|
|
IN UINT16 APP1_length);
|
|
|
|
// Get thumbnail from APP13 header
|
|
|
|
HRESULT
|
|
GetAPP13Thumbnail(OUT IImage** thumbImage,
|
|
IN PVOID APP13_marker,
|
|
IN UINT16 APP13_length);
|
|
|
|
// Doing APP1 header reansformation
|
|
|
|
HRESULT
|
|
TransformApp1(BYTE* pApp1Data,
|
|
UINT16 uiApp1Length,
|
|
UINT uiXForm,
|
|
UINT uiNewWidth,
|
|
UINT uiNewHeight);
|
|
|
|
// Doing APP13 header reansformation
|
|
|
|
HRESULT
|
|
TransformApp13(BYTE* pApp1Data,
|
|
UINT16 uiApp1Length);
|
|
|
|
HRESULT
|
|
BuildApp1PropertyList(InternalPropertyItem* pTail,
|
|
UINT* puiListSize,
|
|
UINT* puiNumOfItems,
|
|
LPBYTE lpStart,
|
|
UINT16 uiApp1Length);
|
|
|
|
HRESULT
|
|
BuildApp2PropertyList(InternalPropertyItem* pTail,
|
|
UINT* puiListSize,
|
|
UINT* puiNumOfItems,
|
|
LPBYTE lpStart,
|
|
UINT16 uiApp2Length);
|
|
|
|
HRESULT
|
|
BuildApp13PropertyList(InternalPropertyItem* pTail,
|
|
UINT* puiListSize,
|
|
UINT* puiNumOfItems,
|
|
LPBYTE lpStart,
|
|
UINT16 uiApp13Length);
|
|
|
|
HRESULT
|
|
ReadApp1HeaderInfo(j_decompress_ptr cinfo,
|
|
BYTE* pApp1Data,
|
|
UINT16 uiApp1Length);
|
|
|
|
HRESULT
|
|
ReadApp13HeaderInfo(j_decompress_ptr cinfo,
|
|
BYTE* pApp13Data,
|
|
UINT16 uiApp13Length);
|
|
|
|
HRESULT
|
|
CreateAPP1Marker(IN PropertyItem *pItemBuffer,
|
|
IN UINT uiNumOfPropertyItems,
|
|
IN BYTE *pMarkerBuffer,
|
|
OUT UINT* puiCurrentLength,
|
|
IN UINT uiTransformation);
|
|
|
|
void
|
|
SortTags(PropertyItem *pItemBuffer, UINT cPropertyItems);
|
|
|
|
void
|
|
SwapIDIfNeeded(PropertyItem *pItem);
|
|
|
|
BOOL
|
|
IsInLargeSection(PROPID id);
|
|
|
|
BOOL
|
|
IsInExifIFDSection(PROPID id);
|
|
|
|
BOOL
|
|
IsInGpsIFDSection(PROPID id);
|
|
|
|
BOOL
|
|
IsInFilterOutSection(PROPID id);
|
|
|
|
BOOL
|
|
IsInThumbNailSection(PROPID id);
|
|
|
|
BOOL
|
|
IsInInterOPIFDSection(PROPID id);
|
|
|
|
HRESULT
|
|
WriteATag(
|
|
BYTE *pMarkerBuffer,
|
|
IFD_TAG *pCurrentTag,
|
|
PropertyItem *pTempItem,
|
|
BYTE **ppbCurrent,
|
|
UINT *puiTotalBytesWritten);
|
|
|
|
HRESULT
|
|
WriteThumbnailTags(
|
|
PropertyItem *pItemBuffer,
|
|
BYTE *pMarkerBuffer,
|
|
IFD_TAG *pTags,
|
|
UINT uiNumOfPropertyItems,
|
|
UINT *puiNumOfThumbnailTagsWritten,
|
|
UINT *puiTotalBytesWritten,
|
|
BOOL fWriteSmallTag);
|
|
|
|
HRESULT
|
|
WriteExifIFD(
|
|
BYTE *pMarkerBuffer,
|
|
PropertyItem *pItemBuffer,
|
|
UINT uiNumOfPropertyItems,
|
|
UINT uiNumOfExifTags,
|
|
UINT uiNumOfInterOPTags,
|
|
UINT *puiTotalBytesWritten);
|
|
|
|
HRESULT
|
|
WriteGpsIFD(
|
|
BYTE *pMarkerBuffer,
|
|
PropertyItem *pItemBuffer,
|
|
UINT uiNumOfPropertyItems,
|
|
UINT uiNumOfGpsTags,
|
|
UINT *puiTotalBytesWritten);
|
|
|
|
HRESULT
|
|
Write1stIFD(
|
|
BYTE *pMarkerBuffer,
|
|
PropertyItem *pItemBuffer,
|
|
UINT uiNumOfPropertyItems,
|
|
ULONG uiNumOfThumbnailTags,
|
|
ULONG ulThumbnailLength,
|
|
BYTE *pbThumbBits,
|
|
BYTE **ppbIFDOffset,
|
|
UINT *puiTotalBytesWritten);
|
|
|
|
HRESULT
|
|
WriteInterOPIFD(
|
|
PBYTE pMarkerBuffer,
|
|
PropertyItem *pItemBuffer,
|
|
UINT uiNumOfPropertyItems,
|
|
UINT uiNumOfInterOPTags,
|
|
UINT *puiTotalBytesWritten);
|
|
|
|
HRESULT
|
|
DecodeTiffThumbnail(
|
|
BYTE *pApp1Data,
|
|
BYTE *pIFD1,
|
|
BOOL fBigEndian,
|
|
INT nApp1Length,
|
|
OUT IImage **thumbImage);
|
|
|
|
HRESULT
|
|
ConvertTiffThumbnailToJPEG(
|
|
LPBYTE lpApp1Data,
|
|
LPBYTE lpIFD1,
|
|
BOOL fBigEndian,
|
|
INT nApp1Length,
|
|
InternalPropertyItem *pTail,
|
|
UINT *puiNumOfItems,
|
|
UINT *puiListSize);
|
|
|
|
void
|
|
ThumbTagToMainImgTag(PropertyItem *pTag);
|
|
|
|
HRESULT
|
|
BuildInterOpPropertyList(
|
|
InternalPropertyItem *pTail,
|
|
UINT *puiListSize,
|
|
UINT *puiNumOfItems,
|
|
BYTE *lpBase,
|
|
INT count,
|
|
IFD_TAG UNALIGNED *pTag,
|
|
BOOL bBigEndian);
|
|
|
|
void
|
|
InterOPTagToGpTag(IFD_TAG UNALIGNED *pInterOPTag);
|
|
|
|
void
|
|
RestoreInterOPTag(IFD_TAG UNALIGNED *pInterOPTag);
|
|
|
|
inline
|
|
void MakeOffsetEven(UINT& nOffset)
|
|
{
|
|
if (nOffset % 2)
|
|
{
|
|
nOffset++;
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
Get420YCbCrChannels(
|
|
IN int nWidth,
|
|
IN int nHeight,
|
|
IN BYTE *pBits,
|
|
OUT BYTE *pbY,
|
|
OUT int *pnCb,
|
|
OUT int *pnCr,
|
|
IN float rYLow,
|
|
IN float rYHigh,
|
|
IN float rCbLow,
|
|
IN float rCbHigh,
|
|
IN float rCrLow,
|
|
IN float rCrHigh
|
|
);
|
|
|
|
HRESULT
|
|
Get422YCbCrChannels(
|
|
IN int nWidth,
|
|
IN int nHeight,
|
|
IN BYTE *pBits,
|
|
OUT BYTE *pbY,
|
|
OUT int *pnCb,
|
|
OUT int *pnCr,
|
|
IN float rYLow,
|
|
IN float rYHigh,
|
|
IN float rCbLow,
|
|
IN float rCbHigh,
|
|
IN float rCrLow,
|
|
IN float rCrHigh
|
|
);
|
|
|
|
HRESULT
|
|
YCbCrToRgbNoCoeff(
|
|
BYTE *pbY,
|
|
int *pnCb,
|
|
int *pnCr,
|
|
BYTE *pbDestBuf,
|
|
int nRows,
|
|
int nCols,
|
|
INT nOutputStride
|
|
);
|
|
|
|
HRESULT
|
|
YCbCrToRgbWithCoeff(
|
|
BYTE *pbY,
|
|
int *pnCb,
|
|
int *pnCr,
|
|
float rLumRed,
|
|
float rLumGreen,
|
|
float rLumBlue,
|
|
BYTE *pbDestBuf,
|
|
int nRows,
|
|
int nCols,
|
|
int nOutputStride);
|
|
|
|
inline
|
|
void
|
|
CopyPropertyItem(
|
|
PropertyItem *pSrc,
|
|
PropertyItem *pDst
|
|
)
|
|
{
|
|
pDst->id = pSrc->id;
|
|
pDst->length = pSrc->length;
|
|
pDst->type = pSrc->type;
|
|
pDst->value = pSrc->value;
|
|
}
|
|
|
|
inline BYTE
|
|
ByteSaturate(
|
|
INT i
|
|
)
|
|
{
|
|
if (i > 255)
|
|
{
|
|
i = 255;
|
|
}
|
|
else if (i < 0)
|
|
{
|
|
i = 0;
|
|
}
|
|
|
|
return (BYTE)i;
|
|
}
|
|
|
|
// This function retrives a rational value from the input buffer and return the
|
|
// the final value. It also does the endian swap if necessary.
|
|
// Note: this is an internal service function. So the caller should be sure
|
|
// to pass valid pointers in. This saves some return code checking
|
|
|
|
inline float
|
|
GetValueFromRational(
|
|
int UNALIGNED *piValue, // int pointer to source data
|
|
BOOL fBigEndian // Flag for endian value
|
|
)
|
|
{
|
|
INT32 nNum = *piValue;
|
|
INT32 nDen = *(piValue + 1);
|
|
|
|
if (fBigEndian)
|
|
{
|
|
nNum = SWAP_DWORD(nNum);
|
|
nDen = SWAP_DWORD(nDen);
|
|
}
|
|
|
|
float rRetValue = 0.0f;
|
|
|
|
if (0 != nDen)
|
|
{
|
|
rRetValue = (float)nNum / (float)nDen;
|
|
}
|
|
|
|
return rRetValue;
|
|
}
|
|
|
|
HRESULT
|
|
DoSwapRandB(IImage** ppSrcImage);
|
|
|
|
HRESULT
|
|
DecodeApp13Thumbnail(
|
|
IImage** pThumbImage,
|
|
PVOID pStart,
|
|
INT iNumOfBytes,
|
|
BOOL bNeedConvert);
|
|
|
|
WCHAR*
|
|
ResUnits(int iType);
|
|
|
|
WCHAR*
|
|
LengthUnits(int iType);
|
|
|
|
WCHAR*
|
|
Shape(int i);
|
|
|
|
HRESULT
|
|
AddThumbToPropertyList(
|
|
IN InternalPropertyItem* pTail,
|
|
IN GpMemoryBitmap *pThumbImg,
|
|
IN INT nSize,
|
|
OUT UINT *puThumbLength);
|
|
|
|
HRESULT
|
|
AddPS4ThumbnailToPropertyList(
|
|
InternalPropertyItem* pTail,
|
|
PVOID pStart,
|
|
INT cBytes,
|
|
OUT UINT *puThumbLength);
|
|
|
|
#endif
|