From fdc00a7042d912aafaabddae4d9c84199921ef23 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Tue, 28 Oct 2014 23:03:33 -0700 Subject: Merge XFA to PDFium master at 4dc95e7 on 10/28/2014 --- core/src/fxcodec/codec/fx_codec.cpp | 341 ++++++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) (limited to 'core/src/fxcodec/codec/fx_codec.cpp') diff --git a/core/src/fxcodec/codec/fx_codec.cpp b/core/src/fxcodec/codec/fx_codec.cpp index 456ec40fea..b2f70c73d1 100644 --- a/core/src/fxcodec/codec/fx_codec.cpp +++ b/core/src/fxcodec/codec/fx_codec.cpp @@ -14,6 +14,10 @@ CCodec_ModuleMgr::CCodec_ModuleMgr() m_pJpxModule = FX_NEW CCodec_JpxModule; m_pJbig2Module = FX_NEW CCodec_Jbig2Module; m_pIccModule = FX_NEW CCodec_IccModule; + m_pPngModule = FX_NEW CCodec_PngModule; + m_pGifModule = FX_NEW CCodec_GifModule; + m_pBmpModule = FX_NEW CCodec_BmpModule; + m_pTiffModule = FX_NEW CCodec_TiffModule; m_pFlateModule = FX_NEW CCodec_FlateModule; } CCodec_ModuleMgr::~CCodec_ModuleMgr() @@ -249,6 +253,343 @@ void CCodec_ModuleMgr::Destroy() { delete this; } +CFX_DIBAttribute::CFX_DIBAttribute() +{ + FXSYS_memset32(this, 0, sizeof(CFX_DIBAttribute)); + m_nXDPI = -1; + m_nYDPI = -1; + m_fAspectRatio = -1.0f; + m_pExif = FX_NEW CFX_DIBAttributeExif; +} +CFX_DIBAttribute::~CFX_DIBAttribute() +{ + if (m_pExif) { + delete m_pExif; + } +} +CFX_DIBAttributeExif::CFX_DIBAttributeExif() +{ + m_pExifData = NULL; + m_dwExifDataLen = 0; +} +CFX_DIBAttributeExif::~CFX_DIBAttributeExif() +{ + clear(); +} +void CFX_DIBAttributeExif::clear() +{ + if (m_pExifData) { + FX_Free(m_pExifData); + } + m_pExifData = NULL; + FX_DWORD key = 0; + FX_LPBYTE buf = NULL; + FX_POSITION pos = NULL; + pos = m_TagHead.GetStartPosition(); + while (pos) { + m_TagHead.GetNextAssoc(pos, key, buf); + if (buf) { + FX_Free(buf); + } + } + m_TagHead.RemoveAll(); + pos = m_TagVal.GetStartPosition(); + while (pos) { + m_TagVal.GetNextAssoc(pos, key, buf); + if (buf) { + FX_Free(buf); + } + } + m_TagVal.RemoveAll(); +} +static FX_WORD _Read2BytesL(FX_LPBYTE data) +{ + ASSERT(data); + return data[0] | (data[1] << 8); +} +static FX_WORD _Read2BytesB(FX_LPBYTE data) +{ + ASSERT(data); + return data[1] | (data[0] << 8); +} +static FX_DWORD _Read4BytesL(FX_LPBYTE data) +{ + return _Read2BytesL(data) | (_Read2BytesL(data + 2) << 16); +} +static FX_DWORD _Read4BytesB(FX_LPBYTE data) +{ + return _Read2BytesB(data + 2) | (_Read2BytesB(data) << 16); +} +typedef FX_WORD (*_Read2Bytes) (FX_LPBYTE data); +typedef FX_DWORD (*_Read4Bytes) (FX_LPBYTE data); +typedef void (*_Write2Bytes) (FX_LPBYTE data, FX_WORD val); +typedef void (*_Write4Bytes) (FX_LPBYTE data, FX_DWORD val); +FX_LPBYTE CFX_DIBAttributeExif::ParseExifIFH(FX_LPBYTE data, FX_DWORD len, _Read2Bytes* pReadWord, _Read4Bytes* pReadDword) +{ + if (len > 8) { + FX_BOOL tag = FALSE; + if (FXSYS_memcmp32(data, "\x49\x49\x2a\x00", 4) == 0) { + if (pReadWord) { + *pReadWord = _Read2BytesL; + } + if (pReadDword) { + *pReadDword = _Read4BytesL; + } + tag = TRUE; + } else if (FXSYS_memcmp32(data, "\x4d\x4d\x00\x2a", 4) == 0) { + if (pReadWord) { + *pReadWord = _Read2BytesB; + } + if (pReadDword) { + *pReadDword = _Read4BytesB; + } + tag = TRUE; + } + if (tag) { + data += 4; + if (pReadDword) { + data += (*pReadDword)(data) - 4; + } else { + data += 4; + } + } + } + return data; +} +FX_BOOL CFX_DIBAttributeExif::ParseExifIFD(CFX_MapPtrTemplate* pMap, FX_LPBYTE data, FX_DWORD len) +{ + if (pMap && data) { + if (len > 8) { + FX_WORD wTagNum = m_readWord(data); + data += 2; + FX_DWORD wTag; + FX_LPBYTE buf; + while (wTagNum--) { + wTag = m_readWord(data); + data += 2; + if (!pMap->Lookup(wTag, buf)) { + buf = FX_Alloc(FX_BYTE, 10); + if (buf == NULL) { + return FALSE; + } + FXSYS_memcpy32(buf, data, 10); + pMap->SetAt(wTag, buf); + } + data += 10; + } + FX_DWORD dwIFDOffset; + dwIFDOffset = m_readDword(data); + while (dwIFDOffset && dwIFDOffset < len) { + data = m_pExifData + dwIFDOffset; + wTagNum = m_readWord(data); + data += 2; + while (wTagNum--) { + wTag = m_readWord(data); + data += 2; + if (!pMap->Lookup(wTag, buf)) { + buf = FX_Alloc(FX_BYTE, 10); + if (buf == NULL) { + return FALSE; + } + FXSYS_memcpy32(buf, data, 10); + pMap->SetAt(wTag, buf); + } + data += 10; + } + dwIFDOffset = m_readDword(data); + } + return TRUE; + } + } + return FALSE; +} +enum FX_ExifDataType { + FX_UnsignedByte = 1, + FX_AscString, + FX_UnsignedShort, + FX_UnsignedLong, + FX_UnsignedRation, + FX_SignedByte, + FX_Undefined, + FX_SignedShort, + FX_SignedLong, + FX_SignedRation, + FX_SignedFloat, + FX_DoubleFloat +}; +FX_BOOL CFX_DIBAttributeExif::ParseExif(CFX_MapPtrTemplate* pHead, FX_LPBYTE data, FX_DWORD len, CFX_MapPtrTemplate* pVal) +{ + if (pHead && data && pVal) { + if (len > 8) { + FX_LPBYTE old_data = data; + data = ParseExifIFH(data, len, &m_readWord, &m_readDword); + if (data == old_data) { + return FALSE; + } + if (pHead->GetCount() == 0) { + if (!ParseExifIFD(pHead, data, len)) { + return FALSE; + } + } + FX_DWORD dwModuleNum; + FX_WORD type; + FX_DWORD dwSize; + FX_DWORD tag; + FX_LPBYTE head; + FX_POSITION pos = pHead->GetStartPosition(); + while (pos) { + pHead->GetNextAssoc(pos, tag, head); + FX_LPBYTE val = NULL, buf = NULL, temp = NULL; + int i; + if (head) { + type = m_readWord(head); + head += 2; + dwModuleNum = m_readDword(head); + head += 4; + switch (type) { + case FX_UnsignedByte: + case FX_AscString: + case FX_SignedByte: + case FX_Undefined: + dwSize = dwModuleNum; + val = FX_Alloc(FX_BYTE, dwSize); + if (val == NULL) { + return FALSE; + } + if (dwSize > 4) { + FXSYS_memcpy32(val, old_data + m_readDword(head), dwSize); + } else { + FXSYS_memcpy32(val, head, dwSize); + } + break; + case FX_UnsignedShort: + case FX_SignedShort: + dwSize = dwModuleNum << 1; + val = FX_Alloc(FX_BYTE, dwSize); + if (val == NULL) { + return FALSE; + } + if (dwSize > 4) { + FXSYS_memcpy32(val, old_data + m_readDword(head), dwSize); + } else { + FXSYS_memcpy32(val, head, dwSize); + } + buf = val; + for(i = 0; i < (int)dwModuleNum; i ++) { + *(FX_WORD*)buf = m_readWord(buf); + buf += 2; + } + break; + case FX_UnsignedLong: + case FX_SignedLong: + case FX_SignedFloat: + dwSize = dwModuleNum << 2; + val = FX_Alloc(FX_BYTE, dwSize); + if (val == NULL) { + return FALSE; + } + if (dwSize > 4) { + FXSYS_memcpy32(val, old_data + m_readDword(head), dwSize); + } else { + FXSYS_memcpy32(val, head, dwSize); + } + buf = val; + for(i = 0; i < (int)dwModuleNum; i ++) { + *(FX_DWORD*)buf = m_readDword(buf); + buf += 4; + } + break; + case FX_UnsignedRation: + case FX_SignedRation: { + dwSize = dwModuleNum << 3; + buf = FX_Alloc(FX_BYTE, dwSize); + if (buf == NULL) { + return FALSE; + } + if (dwSize > 4) { + FXSYS_memcpy32(buf, old_data + m_readDword(head), dwSize); + } else { + FXSYS_memcpy32(buf, head, dwSize); + } + temp = buf; + val = FX_Alloc(FX_BYTE, dwSize / 2); + if (val == NULL) { + FX_Free(buf); + return FALSE; + } + for(i = 0; i < (int)dwModuleNum; i ++) { + *(FX_DWORD*)temp = m_readDword(temp); + *(FX_DWORD*)(temp + 4) = m_readDword(temp + 4); + FX_DWORD* lNumerator = (FX_DWORD*)temp; + FX_DWORD* lNenominator = (FX_DWORD*)(temp + 4); + *(FX_FLOAT*)(val + i * 4) = (FX_FLOAT)(*lNumerator) / (FX_FLOAT)(*lNenominator); + temp += 8; + } + FX_Free(buf); + } + break; + case FX_DoubleFloat: + dwSize = dwModuleNum << 3; + val = FX_Alloc(FX_BYTE, dwSize); + if (val == NULL) { + return FALSE; + } + if (dwSize > 4) { + FXSYS_memcpy32(val, old_data + m_readDword(head), dwSize); + } else { + FXSYS_memcpy32(val, head, dwSize); + } + buf = val; + for(i = 0; i < (int)dwModuleNum; i ++) { + *(FX_DWORD*)buf = m_readDword(buf); + *(FX_DWORD*)(buf + 4) = m_readDword(buf + 4); + buf += 8; + } + break; + default: + return FALSE; + } + } + pVal->SetAt(tag, val); + } + return TRUE; + } + } + return FALSE; +} +#define FXEXIF_INFOCONVERT(T) {T* src = (T*)ptr; T* dst = (T*)val; *dst = *src;} +FX_BOOL CFX_DIBAttributeExif::GetInfo( FX_WORD tag, FX_LPVOID val ) +{ + if (m_TagVal.GetCount() == 0) { + if (!ParseExif(&m_TagHead, m_pExifData, m_dwExifDataLen, &m_TagVal)) { + return FALSE; + } + } + FX_LPBYTE ptr = NULL; + if (m_TagVal.Lookup(tag, ptr)) { + switch (tag) { + case EXIFTAG_USHORT_RESUNIT: + FXEXIF_INFOCONVERT(FX_WORD); + { + FX_WORD* ptr = (FX_WORD*)val; + *ptr -= 1; + } + break; + case EXIFTAG_FLOAT_DPIX: + case EXIFTAG_FLOAT_DPIY: + FXEXIF_INFOCONVERT(FX_FLOAT); + break; + case EXIFTAG_USHORT_ORIENTATION: + FXEXIF_INFOCONVERT(FX_WORD); + break; + default: { + FX_LPBYTE* dst = (FX_LPBYTE*)val; + *dst = ptr; + } + } + } + return TRUE; +} class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder { public: -- cgit v1.2.3