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.cpp894
1 files changed, 447 insertions, 447 deletions
diff --git a/core/src/fxcodec/codec/fx_codec.cpp b/core/src/fxcodec/codec/fx_codec.cpp
index 2f586ca94b..c6b3ccee43 100644
--- a/core/src/fxcodec/codec/fx_codec.cpp
+++ b/core/src/fxcodec/codec/fx_codec.cpp
@@ -1,447 +1,447 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fxcodec/fx_codec.h"
-#include "codec_int.h"
-CCodec_ModuleMgr::CCodec_ModuleMgr()
-{
- m_pBasicModule = FX_NEW CCodec_BasicModule;
- m_pFaxModule = FX_NEW CCodec_FaxModule;
- m_pJpegModule = FX_NEW CCodec_JpegModule;
- m_pJpxModule = FX_NEW CCodec_JpxModule;
- m_pJbig2Module = FX_NEW CCodec_Jbig2Module;
- m_pIccModule = FX_NEW CCodec_IccModule;
- m_pFlateModule = FX_NEW CCodec_FlateModule;
-}
-CCodec_ModuleMgr::~CCodec_ModuleMgr()
-{
- delete m_pBasicModule;
- delete m_pFaxModule;
- delete m_pJpegModule;
- delete m_pFlateModule;
- delete m_pJpxModule;
- delete m_pJbig2Module;
- delete m_pIccModule;
-}
-void CCodec_ModuleMgr::InitJbig2Decoder()
-{
-}
-void CCodec_ModuleMgr::InitJpxDecoder()
-{
-}
-void CCodec_ModuleMgr::InitIccDecoder()
-{
-}
-CCodec_ScanlineDecoder::CCodec_ScanlineDecoder()
-{
- m_NextLine = -1;
- m_pDataCache = NULL;
- m_pLastScanline = NULL;
-}
-CCodec_ScanlineDecoder::~CCodec_ScanlineDecoder()
-{
- if (m_pDataCache) {
- FX_Free(m_pDataCache);
- }
-}
-FX_LPBYTE CCodec_ScanlineDecoder::GetScanline(int line)
-{
- if (m_pDataCache && line < m_pDataCache->m_nCachedLines) {
- return &m_pDataCache->m_Data + line * m_Pitch;
- }
- if (m_NextLine == line + 1) {
- return m_pLastScanline;
- }
- if (m_NextLine < 0 || m_NextLine > line) {
- if (!v_Rewind()) {
- return NULL;
- }
- m_NextLine = 0;
- }
- while (m_NextLine < line) {
- ReadNextLine();
- m_NextLine ++;
- }
- m_pLastScanline = ReadNextLine();
- m_NextLine ++;
- return m_pLastScanline;
-}
-FX_BOOL CCodec_ScanlineDecoder::SkipToScanline(int line, IFX_Pause* pPause)
-{
- if (m_pDataCache && line < m_pDataCache->m_nCachedLines) {
- return FALSE;
- }
- if (m_NextLine == line || m_NextLine == line + 1) {
- return FALSE;
- }
- if (m_NextLine < 0 || m_NextLine > line) {
- v_Rewind();
- m_NextLine = 0;
- }
- m_pLastScanline = NULL;
- while (m_NextLine < line) {
- m_pLastScanline = ReadNextLine();
- m_NextLine ++;
- if (pPause && pPause->NeedToPauseNow()) {
- return TRUE;
- }
- }
- return FALSE;
-}
-FX_LPBYTE CCodec_ScanlineDecoder::ReadNextLine()
-{
- FX_LPBYTE pLine = v_GetNextLine();
- if (pLine == NULL) {
- return NULL;
- }
- if (m_pDataCache && m_NextLine == m_pDataCache->m_nCachedLines) {
- FXSYS_memcpy32(&m_pDataCache->m_Data + m_NextLine * m_Pitch, pLine, m_Pitch);
- m_pDataCache->m_nCachedLines ++;
- }
- return pLine;
-}
-void CCodec_ScanlineDecoder::DownScale(int dest_width, int dest_height)
-{
- if (dest_width < 0) {
- dest_width = -dest_width;
- }
- if (dest_height < 0) {
- dest_height = -dest_height;
- }
- v_DownScale(dest_width, dest_height);
- if (m_pDataCache) {
- if (m_pDataCache->m_Height == m_OutputHeight && m_pDataCache->m_Width == m_OutputWidth) {
- return;
- }
- FX_Free(m_pDataCache);
- m_pDataCache = NULL;
- }
- m_pDataCache = (CCodec_ImageDataCache*)FXMEM_DefaultAlloc(
- sizeof(CCodec_ImageDataCache) + m_Pitch * m_OutputHeight, FXMEM_NONLEAVE);
- if (m_pDataCache == NULL) {
- return;
- }
- m_pDataCache->m_Height = m_OutputHeight;
- m_pDataCache->m_Width = m_OutputWidth;
- m_pDataCache->m_nCachedLines = 0;
-}
-FX_BOOL CCodec_BasicModule::RunLengthEncode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf,
- FX_DWORD& dest_size)
-{
- return FALSE;
-}
-extern "C" double FXstrtod(const char* nptr, char** endptr)
-{
- double ret = 0.0;
- const char* ptr = nptr;
- const char* exp_ptr = NULL;
- int e_number = 0,
- e_signal = 0,
- e_point = 0,
- is_negative = 0;
- int exp_ret = 0, exp_sig = 1,
- fra_ret = 0, fra_count = 0, fra_base = 1;
- if(nptr == NULL) {
- return 0.0;
- }
- for (;; ptr++) {
- if(!e_number && !e_point && (*ptr == '\t' || *ptr == ' ')) {
- continue;
- }
- if(*ptr >= '0' && *ptr <= '9') {
- if(!e_number) {
- e_number = 1;
- }
- if(!e_point) {
- ret *= 10;
- ret += (*ptr - '0');
- } else {
- fra_count++;
- fra_ret *= 10;
- fra_ret += (*ptr - '0');
- }
- continue;
- }
- if(!e_point && *ptr == '.') {
- e_point = 1;
- continue;
- }
- if(!e_number && !e_point && !e_signal) {
- switch(*ptr) {
- case '-':
- is_negative = 1;
- case '+':
- e_signal = 1;
- continue;
- }
- }
- if(e_number && (*ptr == 'e' || *ptr == 'E')) {
-#define EXPONENT_DETECT(ptr) \
- for(;;ptr++){ \
- if(*ptr < '0' || *ptr > '9'){ \
- if(endptr) *endptr = (char*)ptr; \
- break; \
- }else{ \
- exp_ret *= 10; \
- exp_ret += (*ptr - '0'); \
- continue; \
- } \
- }
- exp_ptr = ptr++;
- if(*ptr == '+' || *ptr == '-') {
- exp_sig = (*ptr++ == '+') ? 1 : -1;
- if(*ptr < '0' || *ptr > '9') {
- if(endptr) {
- *endptr = (char*)exp_ptr;
- }
- break;
- }
- EXPONENT_DETECT(ptr);
- } else if(*ptr >= '0' && *ptr <= '9') {
- EXPONENT_DETECT(ptr);
- } else {
- if(endptr) {
- *endptr = (char*)exp_ptr;
- }
- break;
- }
-#undef EXPONENT_DETECT
- break;
- }
- if(ptr != nptr && !e_number) {
- if(endptr) {
- *endptr = (char*)nptr;
- }
- break;
- }
- if(endptr) {
- *endptr = (char*)ptr;
- }
- break;
- }
- while(fra_count--) {
- fra_base *= 10;
- }
- ret += (double)fra_ret / (double)fra_base;
- if(exp_sig == 1) {
- while(exp_ret--) {
- ret *= 10.0;
- }
- } else {
- while(exp_ret--) {
- ret /= 10.0;
- }
- }
- return is_negative ? -ret : ret;
-}
-FX_BOOL CCodec_BasicModule::A85Encode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf,
- FX_DWORD& dest_size)
-{
- return FALSE;
-}
-CCodec_ModuleMgr* CCodec_ModuleMgr::Create()
-{
- return FX_NEW CCodec_ModuleMgr;
-}
-void CCodec_ModuleMgr::Destroy()
-{
- delete this;
-}
-class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder
-{
-public:
- CCodec_RLScanlineDecoder();
- virtual ~CCodec_RLScanlineDecoder();
- FX_BOOL Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, int nComps, int bpc);
- virtual void v_DownScale(int dest_width, int dest_height) {}
- virtual FX_BOOL v_Rewind();
- virtual FX_LPBYTE v_GetNextLine();
- virtual FX_DWORD GetSrcOffset()
- {
- return m_SrcOffset;
- }
-protected:
- FX_BOOL CheckDestSize();
- void GetNextOperator();
- void UpdateOperator(FX_BYTE used_bytes);
-
- FX_LPBYTE m_pScanline;
- FX_LPCBYTE m_pSrcBuf;
- FX_DWORD m_SrcSize;
- FX_DWORD m_dwLineBytes;
- FX_DWORD m_SrcOffset;
- FX_BOOL m_bEOD;
- FX_BYTE m_Operator;
-};
-CCodec_RLScanlineDecoder::CCodec_RLScanlineDecoder()
- : m_pScanline(NULL)
- , m_pSrcBuf(NULL)
- , m_SrcSize(0)
- , m_dwLineBytes(0)
- , m_SrcOffset(0)
- , m_bEOD(FALSE)
- , m_Operator(0)
-{
-}
-CCodec_RLScanlineDecoder::~CCodec_RLScanlineDecoder()
-{
- if (m_pScanline) {
- FX_Free(m_pScanline);
- }
-}
-FX_BOOL CCodec_RLScanlineDecoder::CheckDestSize()
-{
- FX_DWORD i = 0;
- FX_DWORD old_size = 0;
- FX_DWORD dest_size = 0;
- while (i < m_SrcSize) {
- if (m_pSrcBuf[i] < 128) {
- old_size = dest_size;
- dest_size += m_pSrcBuf[i] + 1;
- if (dest_size < old_size) {
- return FALSE;
- }
- i += m_pSrcBuf[i] + 2;
- } else if (m_pSrcBuf[i] > 128) {
- old_size = dest_size;
- dest_size += 257 - m_pSrcBuf[i];
- if (dest_size < old_size) {
- return FALSE;
- }
- i += 2;
- } else {
- break;
- }
- }
- if (((FX_DWORD)m_OrigWidth * m_nComps * m_bpc * m_OrigHeight + 7) / 8 > dest_size) {
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CCodec_RLScanlineDecoder::Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, int nComps, int bpc)
-{
- m_pSrcBuf = src_buf;
- m_SrcSize = src_size;
- m_OutputWidth = m_OrigWidth = width;
- m_OutputHeight = m_OrigHeight = height;
- m_nComps = nComps;
- m_bpc = bpc;
- m_bColorTransformed = FALSE;
- m_DownScale = 1;
- m_Pitch = (width * nComps * bpc + 31) / 32 * 4;
- m_dwLineBytes = (width * nComps * bpc + 7) / 8;
- m_pScanline = FX_Alloc(FX_BYTE, m_Pitch);
- if (m_pScanline == NULL) {
- return FALSE;
- }
- FXSYS_memset32(m_pScanline, 0, m_Pitch);
- return CheckDestSize();
-}
-FX_BOOL CCodec_RLScanlineDecoder::v_Rewind()
-{
- FXSYS_memset32(m_pScanline, 0, m_Pitch);
- m_SrcOffset = 0;
- m_bEOD = FALSE;
- m_Operator = 0;
- return TRUE;
-}
-FX_LPBYTE CCodec_RLScanlineDecoder::v_GetNextLine()
-{
- if (m_SrcOffset == 0) {
- GetNextOperator();
- } else {
- if (m_bEOD) {
- return NULL;
- }
- }
- FXSYS_memset32(m_pScanline, 0, m_Pitch);
- FX_DWORD col_pos = 0;
- FX_BOOL eol = FALSE;
- while (m_SrcOffset < m_SrcSize && !eol) {
- if (m_Operator < 128) {
- FX_DWORD copy_len = m_Operator + 1;
- if (col_pos + copy_len >= m_dwLineBytes) {
- copy_len = m_dwLineBytes - col_pos;
- eol = TRUE;
- }
- if (copy_len >= m_SrcSize - m_SrcOffset) {
- copy_len = m_SrcSize - m_SrcOffset;
- m_bEOD = TRUE;
- }
- FXSYS_memcpy32(m_pScanline + col_pos, m_pSrcBuf + m_SrcOffset, copy_len);
- col_pos += copy_len;
- UpdateOperator((FX_BYTE)copy_len);
- } else if (m_Operator > 128) {
- int fill = 0;
- if (m_SrcOffset - 1 < m_SrcSize - 1) {
- fill = m_pSrcBuf[m_SrcOffset];
- }
- FX_DWORD duplicate_len = 257 - m_Operator;
- if (col_pos + duplicate_len >= m_dwLineBytes) {
- duplicate_len = m_dwLineBytes - col_pos;
- eol = TRUE;
- }
- FXSYS_memset8(m_pScanline + col_pos, fill, duplicate_len);
- col_pos += duplicate_len;
- UpdateOperator((FX_BYTE)duplicate_len);
- } else {
- m_bEOD = TRUE;
- break;
- }
- }
- return m_pScanline;
-}
-void CCodec_RLScanlineDecoder::GetNextOperator()
-{
- if (m_SrcOffset >= m_SrcSize) {
- m_Operator = 128;
- return;
- }
- m_Operator = m_pSrcBuf[m_SrcOffset];
- m_SrcOffset ++;
-}
-void CCodec_RLScanlineDecoder::UpdateOperator(FX_BYTE used_bytes)
-{
- if (used_bytes == 0) {
- return;
- }
- if (m_Operator < 128) {
- FXSYS_assert((FX_DWORD)m_Operator + 1 >= used_bytes);
- if (used_bytes == m_Operator + 1) {
- m_SrcOffset += used_bytes;
- GetNextOperator();
- return;
- }
- m_Operator -= used_bytes;
- m_SrcOffset += used_bytes;
- if (m_SrcOffset >= m_SrcSize) {
- m_Operator = 128;
- }
- return;
- }
- FX_BYTE count = 257 - m_Operator;
- FXSYS_assert((FX_DWORD)count >= used_bytes);
- if (used_bytes == count) {
- m_SrcOffset ++;
- GetNextOperator();
- return;
- }
- count -= used_bytes;
- m_Operator = 257 - count;
-}
-ICodec_ScanlineDecoder* CCodec_BasicModule::CreateRunLengthDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
- int nComps, int bpc)
-{
- CCodec_RLScanlineDecoder* pRLScanlineDecoder = FX_NEW CCodec_RLScanlineDecoder;
- if (pRLScanlineDecoder == NULL) {
- return NULL;
- }
- if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps, bpc)) {
- delete pRLScanlineDecoder;
- return NULL;
- }
- return pRLScanlineDecoder;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxcodec/fx_codec.h"
+#include "codec_int.h"
+CCodec_ModuleMgr::CCodec_ModuleMgr()
+{
+ m_pBasicModule = FX_NEW CCodec_BasicModule;
+ m_pFaxModule = FX_NEW CCodec_FaxModule;
+ m_pJpegModule = FX_NEW CCodec_JpegModule;
+ m_pJpxModule = FX_NEW CCodec_JpxModule;
+ m_pJbig2Module = FX_NEW CCodec_Jbig2Module;
+ m_pIccModule = FX_NEW CCodec_IccModule;
+ m_pFlateModule = FX_NEW CCodec_FlateModule;
+}
+CCodec_ModuleMgr::~CCodec_ModuleMgr()
+{
+ delete m_pBasicModule;
+ delete m_pFaxModule;
+ delete m_pJpegModule;
+ delete m_pFlateModule;
+ delete m_pJpxModule;
+ delete m_pJbig2Module;
+ delete m_pIccModule;
+}
+void CCodec_ModuleMgr::InitJbig2Decoder()
+{
+}
+void CCodec_ModuleMgr::InitJpxDecoder()
+{
+}
+void CCodec_ModuleMgr::InitIccDecoder()
+{
+}
+CCodec_ScanlineDecoder::CCodec_ScanlineDecoder()
+{
+ m_NextLine = -1;
+ m_pDataCache = NULL;
+ m_pLastScanline = NULL;
+}
+CCodec_ScanlineDecoder::~CCodec_ScanlineDecoder()
+{
+ if (m_pDataCache) {
+ FX_Free(m_pDataCache);
+ }
+}
+FX_LPBYTE CCodec_ScanlineDecoder::GetScanline(int line)
+{
+ if (m_pDataCache && line < m_pDataCache->m_nCachedLines) {
+ return &m_pDataCache->m_Data + line * m_Pitch;
+ }
+ if (m_NextLine == line + 1) {
+ return m_pLastScanline;
+ }
+ if (m_NextLine < 0 || m_NextLine > line) {
+ if (!v_Rewind()) {
+ return NULL;
+ }
+ m_NextLine = 0;
+ }
+ while (m_NextLine < line) {
+ ReadNextLine();
+ m_NextLine ++;
+ }
+ m_pLastScanline = ReadNextLine();
+ m_NextLine ++;
+ return m_pLastScanline;
+}
+FX_BOOL CCodec_ScanlineDecoder::SkipToScanline(int line, IFX_Pause* pPause)
+{
+ if (m_pDataCache && line < m_pDataCache->m_nCachedLines) {
+ return FALSE;
+ }
+ if (m_NextLine == line || m_NextLine == line + 1) {
+ return FALSE;
+ }
+ if (m_NextLine < 0 || m_NextLine > line) {
+ v_Rewind();
+ m_NextLine = 0;
+ }
+ m_pLastScanline = NULL;
+ while (m_NextLine < line) {
+ m_pLastScanline = ReadNextLine();
+ m_NextLine ++;
+ if (pPause && pPause->NeedToPauseNow()) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_LPBYTE CCodec_ScanlineDecoder::ReadNextLine()
+{
+ FX_LPBYTE pLine = v_GetNextLine();
+ if (pLine == NULL) {
+ return NULL;
+ }
+ if (m_pDataCache && m_NextLine == m_pDataCache->m_nCachedLines) {
+ FXSYS_memcpy32(&m_pDataCache->m_Data + m_NextLine * m_Pitch, pLine, m_Pitch);
+ m_pDataCache->m_nCachedLines ++;
+ }
+ return pLine;
+}
+void CCodec_ScanlineDecoder::DownScale(int dest_width, int dest_height)
+{
+ if (dest_width < 0) {
+ dest_width = -dest_width;
+ }
+ if (dest_height < 0) {
+ dest_height = -dest_height;
+ }
+ v_DownScale(dest_width, dest_height);
+ if (m_pDataCache) {
+ if (m_pDataCache->m_Height == m_OutputHeight && m_pDataCache->m_Width == m_OutputWidth) {
+ return;
+ }
+ FX_Free(m_pDataCache);
+ m_pDataCache = NULL;
+ }
+ m_pDataCache = (CCodec_ImageDataCache*)FXMEM_DefaultAlloc(
+ sizeof(CCodec_ImageDataCache) + m_Pitch * m_OutputHeight, FXMEM_NONLEAVE);
+ if (m_pDataCache == NULL) {
+ return;
+ }
+ m_pDataCache->m_Height = m_OutputHeight;
+ m_pDataCache->m_Width = m_OutputWidth;
+ m_pDataCache->m_nCachedLines = 0;
+}
+FX_BOOL CCodec_BasicModule::RunLengthEncode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf,
+ FX_DWORD& dest_size)
+{
+ return FALSE;
+}
+extern "C" double FXstrtod(const char* nptr, char** endptr)
+{
+ double ret = 0.0;
+ const char* ptr = nptr;
+ const char* exp_ptr = NULL;
+ int e_number = 0,
+ e_signal = 0,
+ e_point = 0,
+ is_negative = 0;
+ int exp_ret = 0, exp_sig = 1,
+ fra_ret = 0, fra_count = 0, fra_base = 1;
+ if(nptr == NULL) {
+ return 0.0;
+ }
+ for (;; ptr++) {
+ if(!e_number && !e_point && (*ptr == '\t' || *ptr == ' ')) {
+ continue;
+ }
+ if(*ptr >= '0' && *ptr <= '9') {
+ if(!e_number) {
+ e_number = 1;
+ }
+ if(!e_point) {
+ ret *= 10;
+ ret += (*ptr - '0');
+ } else {
+ fra_count++;
+ fra_ret *= 10;
+ fra_ret += (*ptr - '0');
+ }
+ continue;
+ }
+ if(!e_point && *ptr == '.') {
+ e_point = 1;
+ continue;
+ }
+ if(!e_number && !e_point && !e_signal) {
+ switch(*ptr) {
+ case '-':
+ is_negative = 1;
+ case '+':
+ e_signal = 1;
+ continue;
+ }
+ }
+ if(e_number && (*ptr == 'e' || *ptr == 'E')) {
+#define EXPONENT_DETECT(ptr) \
+ for(;;ptr++){ \
+ if(*ptr < '0' || *ptr > '9'){ \
+ if(endptr) *endptr = (char*)ptr; \
+ break; \
+ }else{ \
+ exp_ret *= 10; \
+ exp_ret += (*ptr - '0'); \
+ continue; \
+ } \
+ }
+ exp_ptr = ptr++;
+ if(*ptr == '+' || *ptr == '-') {
+ exp_sig = (*ptr++ == '+') ? 1 : -1;
+ if(*ptr < '0' || *ptr > '9') {
+ if(endptr) {
+ *endptr = (char*)exp_ptr;
+ }
+ break;
+ }
+ EXPONENT_DETECT(ptr);
+ } else if(*ptr >= '0' && *ptr <= '9') {
+ EXPONENT_DETECT(ptr);
+ } else {
+ if(endptr) {
+ *endptr = (char*)exp_ptr;
+ }
+ break;
+ }
+#undef EXPONENT_DETECT
+ break;
+ }
+ if(ptr != nptr && !e_number) {
+ if(endptr) {
+ *endptr = (char*)nptr;
+ }
+ break;
+ }
+ if(endptr) {
+ *endptr = (char*)ptr;
+ }
+ break;
+ }
+ while(fra_count--) {
+ fra_base *= 10;
+ }
+ ret += (double)fra_ret / (double)fra_base;
+ if(exp_sig == 1) {
+ while(exp_ret--) {
+ ret *= 10.0;
+ }
+ } else {
+ while(exp_ret--) {
+ ret /= 10.0;
+ }
+ }
+ return is_negative ? -ret : ret;
+}
+FX_BOOL CCodec_BasicModule::A85Encode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf,
+ FX_DWORD& dest_size)
+{
+ return FALSE;
+}
+CCodec_ModuleMgr* CCodec_ModuleMgr::Create()
+{
+ return FX_NEW CCodec_ModuleMgr;
+}
+void CCodec_ModuleMgr::Destroy()
+{
+ delete this;
+}
+class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder
+{
+public:
+ CCodec_RLScanlineDecoder();
+ virtual ~CCodec_RLScanlineDecoder();
+ FX_BOOL Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, int nComps, int bpc);
+ virtual void v_DownScale(int dest_width, int dest_height) {}
+ virtual FX_BOOL v_Rewind();
+ virtual FX_LPBYTE v_GetNextLine();
+ virtual FX_DWORD GetSrcOffset()
+ {
+ return m_SrcOffset;
+ }
+protected:
+ FX_BOOL CheckDestSize();
+ void GetNextOperator();
+ void UpdateOperator(FX_BYTE used_bytes);
+
+ FX_LPBYTE m_pScanline;
+ FX_LPCBYTE m_pSrcBuf;
+ FX_DWORD m_SrcSize;
+ FX_DWORD m_dwLineBytes;
+ FX_DWORD m_SrcOffset;
+ FX_BOOL m_bEOD;
+ FX_BYTE m_Operator;
+};
+CCodec_RLScanlineDecoder::CCodec_RLScanlineDecoder()
+ : m_pScanline(NULL)
+ , m_pSrcBuf(NULL)
+ , m_SrcSize(0)
+ , m_dwLineBytes(0)
+ , m_SrcOffset(0)
+ , m_bEOD(FALSE)
+ , m_Operator(0)
+{
+}
+CCodec_RLScanlineDecoder::~CCodec_RLScanlineDecoder()
+{
+ if (m_pScanline) {
+ FX_Free(m_pScanline);
+ }
+}
+FX_BOOL CCodec_RLScanlineDecoder::CheckDestSize()
+{
+ FX_DWORD i = 0;
+ FX_DWORD old_size = 0;
+ FX_DWORD dest_size = 0;
+ while (i < m_SrcSize) {
+ if (m_pSrcBuf[i] < 128) {
+ old_size = dest_size;
+ dest_size += m_pSrcBuf[i] + 1;
+ if (dest_size < old_size) {
+ return FALSE;
+ }
+ i += m_pSrcBuf[i] + 2;
+ } else if (m_pSrcBuf[i] > 128) {
+ old_size = dest_size;
+ dest_size += 257 - m_pSrcBuf[i];
+ if (dest_size < old_size) {
+ return FALSE;
+ }
+ i += 2;
+ } else {
+ break;
+ }
+ }
+ if (((FX_DWORD)m_OrigWidth * m_nComps * m_bpc * m_OrigHeight + 7) / 8 > dest_size) {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CCodec_RLScanlineDecoder::Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, int nComps, int bpc)
+{
+ m_pSrcBuf = src_buf;
+ m_SrcSize = src_size;
+ m_OutputWidth = m_OrigWidth = width;
+ m_OutputHeight = m_OrigHeight = height;
+ m_nComps = nComps;
+ m_bpc = bpc;
+ m_bColorTransformed = FALSE;
+ m_DownScale = 1;
+ m_Pitch = (width * nComps * bpc + 31) / 32 * 4;
+ m_dwLineBytes = (width * nComps * bpc + 7) / 8;
+ m_pScanline = FX_Alloc(FX_BYTE, m_Pitch);
+ if (m_pScanline == NULL) {
+ return FALSE;
+ }
+ FXSYS_memset32(m_pScanline, 0, m_Pitch);
+ return CheckDestSize();
+}
+FX_BOOL CCodec_RLScanlineDecoder::v_Rewind()
+{
+ FXSYS_memset32(m_pScanline, 0, m_Pitch);
+ m_SrcOffset = 0;
+ m_bEOD = FALSE;
+ m_Operator = 0;
+ return TRUE;
+}
+FX_LPBYTE CCodec_RLScanlineDecoder::v_GetNextLine()
+{
+ if (m_SrcOffset == 0) {
+ GetNextOperator();
+ } else {
+ if (m_bEOD) {
+ return NULL;
+ }
+ }
+ FXSYS_memset32(m_pScanline, 0, m_Pitch);
+ FX_DWORD col_pos = 0;
+ FX_BOOL eol = FALSE;
+ while (m_SrcOffset < m_SrcSize && !eol) {
+ if (m_Operator < 128) {
+ FX_DWORD copy_len = m_Operator + 1;
+ if (col_pos + copy_len >= m_dwLineBytes) {
+ copy_len = m_dwLineBytes - col_pos;
+ eol = TRUE;
+ }
+ if (copy_len >= m_SrcSize - m_SrcOffset) {
+ copy_len = m_SrcSize - m_SrcOffset;
+ m_bEOD = TRUE;
+ }
+ FXSYS_memcpy32(m_pScanline + col_pos, m_pSrcBuf + m_SrcOffset, copy_len);
+ col_pos += copy_len;
+ UpdateOperator((FX_BYTE)copy_len);
+ } else if (m_Operator > 128) {
+ int fill = 0;
+ if (m_SrcOffset - 1 < m_SrcSize - 1) {
+ fill = m_pSrcBuf[m_SrcOffset];
+ }
+ FX_DWORD duplicate_len = 257 - m_Operator;
+ if (col_pos + duplicate_len >= m_dwLineBytes) {
+ duplicate_len = m_dwLineBytes - col_pos;
+ eol = TRUE;
+ }
+ FXSYS_memset8(m_pScanline + col_pos, fill, duplicate_len);
+ col_pos += duplicate_len;
+ UpdateOperator((FX_BYTE)duplicate_len);
+ } else {
+ m_bEOD = TRUE;
+ break;
+ }
+ }
+ return m_pScanline;
+}
+void CCodec_RLScanlineDecoder::GetNextOperator()
+{
+ if (m_SrcOffset >= m_SrcSize) {
+ m_Operator = 128;
+ return;
+ }
+ m_Operator = m_pSrcBuf[m_SrcOffset];
+ m_SrcOffset ++;
+}
+void CCodec_RLScanlineDecoder::UpdateOperator(FX_BYTE used_bytes)
+{
+ if (used_bytes == 0) {
+ return;
+ }
+ if (m_Operator < 128) {
+ FXSYS_assert((FX_DWORD)m_Operator + 1 >= used_bytes);
+ if (used_bytes == m_Operator + 1) {
+ m_SrcOffset += used_bytes;
+ GetNextOperator();
+ return;
+ }
+ m_Operator -= used_bytes;
+ m_SrcOffset += used_bytes;
+ if (m_SrcOffset >= m_SrcSize) {
+ m_Operator = 128;
+ }
+ return;
+ }
+ FX_BYTE count = 257 - m_Operator;
+ FXSYS_assert((FX_DWORD)count >= used_bytes);
+ if (used_bytes == count) {
+ m_SrcOffset ++;
+ GetNextOperator();
+ return;
+ }
+ count -= used_bytes;
+ m_Operator = 257 - count;
+}
+ICodec_ScanlineDecoder* CCodec_BasicModule::CreateRunLengthDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
+ int nComps, int bpc)
+{
+ CCodec_RLScanlineDecoder* pRLScanlineDecoder = FX_NEW CCodec_RLScanlineDecoder;
+ if (pRLScanlineDecoder == NULL) {
+ return NULL;
+ }
+ if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps, bpc)) {
+ delete pRLScanlineDecoder;
+ return NULL;
+ }
+ return pRLScanlineDecoder;
+}