summaryrefslogtreecommitdiff
path: root/core/src/fxcodec/codec/fx_codec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fxcodec/codec/fx_codec.cpp')
-rw-r--r--core/src/fxcodec/codec/fx_codec.cpp341
1 files changed, 341 insertions, 0 deletions
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<FX_DWORD, FX_LPBYTE>* 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<FX_DWORD, FX_LPBYTE>* pHead, FX_LPBYTE data, FX_DWORD len, CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE>* 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: