| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "../../../include/fxcodec/fx_codec.h" | 7 #include "../../../include/fxcodec/fx_codec.h" |
| 8 #include "codec_int.h" | 8 #include "codec_int.h" |
| 9 CCodec_ModuleMgr::CCodec_ModuleMgr() | 9 CCodec_ModuleMgr::CCodec_ModuleMgr() |
| 10 : m_pBasicModule(new CCodec_BasicModule), | 10 : m_pBasicModule(new CCodec_BasicModule), |
| 11 m_pFaxModule(new CCodec_FaxModule), | 11 m_pFaxModule(new CCodec_FaxModule), |
| 12 m_pJpegModule(new CCodec_JpegModule), | 12 m_pJpegModule(new CCodec_JpegModule), |
| 13 m_pJpxModule(new CCodec_JpxModule), | 13 m_pJpxModule(new CCodec_JpxModule), |
| 14 m_pJbig2Module(new CCodec_Jbig2Module), | 14 m_pJbig2Module(new CCodec_Jbig2Module), |
| 15 m_pIccModule(new CCodec_IccModule), | 15 m_pIccModule(new CCodec_IccModule), |
| 16 m_pFlateModule(new CCodec_FlateModule) { | 16 m_pFlateModule(new CCodec_FlateModule) {} |
| 17 } | 17 CCodec_ScanlineDecoder::CCodec_ScanlineDecoder() { |
| 18 CCodec_ScanlineDecoder::CCodec_ScanlineDecoder() | 18 m_NextLine = -1; |
| 19 { | 19 m_pDataCache = NULL; |
| 20 m_NextLine = -1; | 20 m_pLastScanline = NULL; |
| 21 } |
| 22 CCodec_ScanlineDecoder::~CCodec_ScanlineDecoder() { |
| 23 if (m_pDataCache) { |
| 24 FX_Free(m_pDataCache); |
| 25 } |
| 26 } |
| 27 uint8_t* CCodec_ScanlineDecoder::GetScanline(int line) { |
| 28 if (m_pDataCache && line < m_pDataCache->m_nCachedLines) { |
| 29 return &m_pDataCache->m_Data + line * m_Pitch; |
| 30 } |
| 31 if (m_NextLine == line + 1) { |
| 32 return m_pLastScanline; |
| 33 } |
| 34 if (m_NextLine < 0 || m_NextLine > line) { |
| 35 if (!v_Rewind()) { |
| 36 return NULL; |
| 37 } |
| 38 m_NextLine = 0; |
| 39 } |
| 40 while (m_NextLine < line) { |
| 41 ReadNextLine(); |
| 42 m_NextLine++; |
| 43 } |
| 44 m_pLastScanline = ReadNextLine(); |
| 45 m_NextLine++; |
| 46 return m_pLastScanline; |
| 47 } |
| 48 FX_BOOL CCodec_ScanlineDecoder::SkipToScanline(int line, IFX_Pause* pPause) { |
| 49 if (m_pDataCache && line < m_pDataCache->m_nCachedLines) { |
| 50 return FALSE; |
| 51 } |
| 52 if (m_NextLine == line || m_NextLine == line + 1) { |
| 53 return FALSE; |
| 54 } |
| 55 if (m_NextLine < 0 || m_NextLine > line) { |
| 56 v_Rewind(); |
| 57 m_NextLine = 0; |
| 58 } |
| 59 m_pLastScanline = NULL; |
| 60 while (m_NextLine < line) { |
| 61 m_pLastScanline = ReadNextLine(); |
| 62 m_NextLine++; |
| 63 if (pPause && pPause->NeedToPauseNow()) { |
| 64 return TRUE; |
| 65 } |
| 66 } |
| 67 return FALSE; |
| 68 } |
| 69 uint8_t* CCodec_ScanlineDecoder::ReadNextLine() { |
| 70 uint8_t* pLine = v_GetNextLine(); |
| 71 if (pLine == NULL) { |
| 72 return NULL; |
| 73 } |
| 74 if (m_pDataCache && m_NextLine == m_pDataCache->m_nCachedLines) { |
| 75 FXSYS_memcpy(&m_pDataCache->m_Data + m_NextLine * m_Pitch, pLine, m_Pitch); |
| 76 m_pDataCache->m_nCachedLines++; |
| 77 } |
| 78 return pLine; |
| 79 } |
| 80 void CCodec_ScanlineDecoder::DownScale(int dest_width, int dest_height) { |
| 81 if (dest_width < 0) { |
| 82 dest_width = -dest_width; |
| 83 } |
| 84 if (dest_height < 0) { |
| 85 dest_height = -dest_height; |
| 86 } |
| 87 v_DownScale(dest_width, dest_height); |
| 88 if (m_pDataCache) { |
| 89 if (m_pDataCache->m_Height == m_OutputHeight && |
| 90 m_pDataCache->m_Width == m_OutputWidth) { |
| 91 return; |
| 92 } |
| 93 FX_Free(m_pDataCache); |
| 21 m_pDataCache = NULL; | 94 m_pDataCache = NULL; |
| 22 m_pLastScanline = NULL; | 95 } |
| 23 } | 96 m_pDataCache = (CCodec_ImageDataCache*)FX_TryAlloc( |
| 24 CCodec_ScanlineDecoder::~CCodec_ScanlineDecoder() | 97 uint8_t, sizeof(CCodec_ImageDataCache) + m_Pitch * m_OutputHeight); |
| 25 { | 98 if (m_pDataCache == NULL) { |
| 26 if (m_pDataCache) { | 99 return; |
| 27 FX_Free(m_pDataCache); | 100 } |
| 28 } | 101 m_pDataCache->m_Height = m_OutputHeight; |
| 29 } | 102 m_pDataCache->m_Width = m_OutputWidth; |
| 30 uint8_t* CCodec_ScanlineDecoder::GetScanline(int line) | 103 m_pDataCache->m_nCachedLines = 0; |
| 31 { | 104 } |
| 32 if (m_pDataCache && line < m_pDataCache->m_nCachedLines) { | 105 FX_BOOL CCodec_BasicModule::RunLengthEncode(const uint8_t* src_buf, |
| 33 return &m_pDataCache->m_Data + line * m_Pitch; | 106 FX_DWORD src_size, |
| 34 } | 107 uint8_t*& dest_buf, |
| 35 if (m_NextLine == line + 1) { | 108 FX_DWORD& dest_size) { |
| 36 return m_pLastScanline; | 109 return FALSE; |
| 37 } | 110 } |
| 38 if (m_NextLine < 0 || m_NextLine > line) { | 111 extern "C" double FXstrtod(const char* nptr, char** endptr) { |
| 39 if (!v_Rewind()) { | 112 double ret = 0.0; |
| 40 return NULL; | 113 const char* ptr = nptr; |
| 114 const char* exp_ptr = NULL; |
| 115 int e_number = 0, e_signal = 0, e_point = 0, is_negative = 0; |
| 116 int exp_ret = 0, exp_sig = 1, fra_ret = 0, fra_count = 0, fra_base = 1; |
| 117 if (nptr == NULL) { |
| 118 return 0.0; |
| 119 } |
| 120 for (;; ptr++) { |
| 121 if (!e_number && !e_point && (*ptr == '\t' || *ptr == ' ')) { |
| 122 continue; |
| 123 } |
| 124 if (*ptr >= '0' && *ptr <= '9') { |
| 125 if (!e_number) { |
| 126 e_number = 1; |
| 127 } |
| 128 if (!e_point) { |
| 129 ret *= 10; |
| 130 ret += (*ptr - '0'); |
| 131 } else { |
| 132 fra_count++; |
| 133 fra_ret *= 10; |
| 134 fra_ret += (*ptr - '0'); |
| 135 } |
| 136 continue; |
| 137 } |
| 138 if (!e_point && *ptr == '.') { |
| 139 e_point = 1; |
| 140 continue; |
| 141 } |
| 142 if (!e_number && !e_point && !e_signal) { |
| 143 switch (*ptr) { |
| 144 case '-': |
| 145 is_negative = 1; |
| 146 case '+': |
| 147 e_signal = 1; |
| 148 continue; |
| 149 } |
| 150 } |
| 151 if (e_number && (*ptr == 'e' || *ptr == 'E')) { |
| 152 #define EXPONENT_DETECT(ptr) \ |
| 153 for (;; ptr++) { \ |
| 154 if (*ptr < '0' || *ptr > '9') { \ |
| 155 if (endptr) \ |
| 156 *endptr = (char*)ptr; \ |
| 157 break; \ |
| 158 } else { \ |
| 159 exp_ret *= 10; \ |
| 160 exp_ret += (*ptr - '0'); \ |
| 161 continue; \ |
| 162 } \ |
| 163 } |
| 164 exp_ptr = ptr++; |
| 165 if (*ptr == '+' || *ptr == '-') { |
| 166 exp_sig = (*ptr++ == '+') ? 1 : -1; |
| 167 if (*ptr < '0' || *ptr > '9') { |
| 168 if (endptr) { |
| 169 *endptr = (char*)exp_ptr; |
| 170 } |
| 171 break; |
| 41 } | 172 } |
| 42 m_NextLine = 0; | 173 EXPONENT_DETECT(ptr); |
| 43 } | 174 } else if (*ptr >= '0' && *ptr <= '9') { |
| 44 while (m_NextLine < line) { | 175 EXPONENT_DETECT(ptr); |
| 45 ReadNextLine(); | 176 } else { |
| 46 m_NextLine ++; | 177 if (endptr) { |
| 47 } | 178 *endptr = (char*)exp_ptr; |
| 48 m_pLastScanline = ReadNextLine(); | |
| 49 m_NextLine ++; | |
| 50 return m_pLastScanline; | |
| 51 } | |
| 52 FX_BOOL CCodec_ScanlineDecoder::SkipToScanline(int line, IFX_Pause* pPause) | |
| 53 { | |
| 54 if (m_pDataCache && line < m_pDataCache->m_nCachedLines) { | |
| 55 return FALSE; | |
| 56 } | |
| 57 if (m_NextLine == line || m_NextLine == line + 1) { | |
| 58 return FALSE; | |
| 59 } | |
| 60 if (m_NextLine < 0 || m_NextLine > line) { | |
| 61 v_Rewind(); | |
| 62 m_NextLine = 0; | |
| 63 } | |
| 64 m_pLastScanline = NULL; | |
| 65 while (m_NextLine < line) { | |
| 66 m_pLastScanline = ReadNextLine(); | |
| 67 m_NextLine ++; | |
| 68 if (pPause && pPause->NeedToPauseNow()) { | |
| 69 return TRUE; | |
| 70 } | |
| 71 } | |
| 72 return FALSE; | |
| 73 } | |
| 74 uint8_t* CCodec_ScanlineDecoder::ReadNextLine() | |
| 75 { | |
| 76 uint8_t* pLine = v_GetNextLine(); | |
| 77 if (pLine == NULL) { | |
| 78 return NULL; | |
| 79 } | |
| 80 if (m_pDataCache && m_NextLine == m_pDataCache->m_nCachedLines) { | |
| 81 FXSYS_memcpy(&m_pDataCache->m_Data + m_NextLine * m_Pitch, pLine, m_Pitc
h); | |
| 82 m_pDataCache->m_nCachedLines ++; | |
| 83 } | |
| 84 return pLine; | |
| 85 } | |
| 86 void CCodec_ScanlineDecoder::DownScale(int dest_width, int dest_height) | |
| 87 { | |
| 88 if (dest_width < 0) { | |
| 89 dest_width = -dest_width; | |
| 90 } | |
| 91 if (dest_height < 0) { | |
| 92 dest_height = -dest_height; | |
| 93 } | |
| 94 v_DownScale(dest_width, dest_height); | |
| 95 if (m_pDataCache) { | |
| 96 if (m_pDataCache->m_Height == m_OutputHeight && m_pDataCache->m_Width ==
m_OutputWidth) { | |
| 97 return; | |
| 98 } | |
| 99 FX_Free(m_pDataCache); | |
| 100 m_pDataCache = NULL; | |
| 101 } | |
| 102 m_pDataCache = (CCodec_ImageDataCache*)FX_TryAlloc(uint8_t, sizeof(CCodec_Im
ageDataCache) + m_Pitch * m_OutputHeight); | |
| 103 if (m_pDataCache == NULL) { | |
| 104 return; | |
| 105 } | |
| 106 m_pDataCache->m_Height = m_OutputHeight; | |
| 107 m_pDataCache->m_Width = m_OutputWidth; | |
| 108 m_pDataCache->m_nCachedLines = 0; | |
| 109 } | |
| 110 FX_BOOL CCodec_BasicModule::RunLengthEncode(const uint8_t* src_buf, FX_DWORD src
_size, uint8_t*& dest_buf, | |
| 111 FX_DWORD& dest_size) | |
| 112 { | |
| 113 return FALSE; | |
| 114 } | |
| 115 extern "C" double FXstrtod(const char* nptr, char** endptr) | |
| 116 { | |
| 117 double ret = 0.0; | |
| 118 const char* ptr = nptr; | |
| 119 const char* exp_ptr = NULL; | |
| 120 int»e_number = 0, | |
| 121 e_signal = 0, | |
| 122 e_point = 0, | |
| 123 is_negative = 0; | |
| 124 int exp_ret = 0, exp_sig = 1, | |
| 125 fra_ret = 0, fra_count = 0, fra_base = 1; | |
| 126 if(nptr == NULL) { | |
| 127 return 0.0; | |
| 128 } | |
| 129 for (;; ptr++) { | |
| 130 if(!e_number && !e_point && (*ptr == '\t' || *ptr == ' ')) { | |
| 131 continue; | |
| 132 } | |
| 133 if(*ptr >= '0' && *ptr <= '9') { | |
| 134 if(!e_number) { | |
| 135 e_number = 1; | |
| 136 } | |
| 137 if(!e_point) { | |
| 138 ret *= 10; | |
| 139 ret += (*ptr - '0'); | |
| 140 } else { | |
| 141 fra_count++; | |
| 142 fra_ret *= 10; | |
| 143 fra_ret += (*ptr - '0'); | |
| 144 } | |
| 145 continue; | |
| 146 } | |
| 147 if(!e_point && *ptr == '.') { | |
| 148 e_point = 1; | |
| 149 continue; | |
| 150 } | |
| 151 if(!e_number && !e_point && !e_signal) { | |
| 152 switch(*ptr) { | |
| 153 case '-': | |
| 154 is_negative = 1; | |
| 155 case '+': | |
| 156 e_signal = 1; | |
| 157 continue; | |
| 158 } | |
| 159 } | |
| 160 if(e_number && (*ptr == 'e' || *ptr == 'E')) { | |
| 161 #define EXPONENT_DETECT(ptr)» \ | |
| 162 for(;;ptr++){» » \ | |
| 163 if(*ptr < '0' || *ptr > '9'){» \ | |
| 164 if(endptr)» *endptr = (char*)ptr;» \ | |
| 165 break;» \ | |
| 166 }else{» » \ | |
| 167 exp_ret *= 10;» \ | |
| 168 exp_ret += (*ptr - '0');» \ | |
| 169 continue;» » \ | |
| 170 }» \ | |
| 171 } | |
| 172 exp_ptr = ptr++; | |
| 173 if(*ptr == '+' || *ptr == '-') { | |
| 174 exp_sig = (*ptr++ == '+') ? 1 : -1; | |
| 175 if(*ptr < '0' || *ptr > '9') { | |
| 176 if(endptr)» { | |
| 177 *endptr = (char*)exp_ptr; | |
| 178 } | |
| 179 break; | |
| 180 } | |
| 181 EXPONENT_DETECT(ptr); | |
| 182 } else if(*ptr >= '0' && *ptr <= '9') { | |
| 183 EXPONENT_DETECT(ptr); | |
| 184 } else { | |
| 185 if(endptr)» { | |
| 186 *endptr = (char*)exp_ptr; | |
| 187 } | |
| 188 break; | |
| 189 } | |
| 190 #undef EXPONENT_DETECT | |
| 191 break; | |
| 192 } | |
| 193 if(ptr != nptr && !e_number) { | |
| 194 if(endptr)» { | |
| 195 *endptr = (char*)nptr; | |
| 196 } | |
| 197 break; | |
| 198 } | |
| 199 if(endptr)» { | |
| 200 *endptr = (char*)ptr; | |
| 201 } | 179 } |
| 202 break; | 180 break; |
| 203 } | 181 } |
| 204 while(fra_count--) { | 182 #undef EXPONENT_DETECT |
| 205 fra_base *= 10; | 183 break; |
| 206 } | 184 } |
| 207 ret += (double)fra_ret / (double)fra_base; | 185 if (ptr != nptr && !e_number) { |
| 208 if(exp_sig == 1) { | 186 if (endptr) { |
| 209 while(exp_ret--) { | 187 *endptr = (char*)nptr; |
| 210 ret *= 10.0; | 188 } |
| 211 } | 189 break; |
| 212 } else { | 190 } |
| 213 while(exp_ret--) { | 191 if (endptr) { |
| 214 ret /= 10.0; | 192 *endptr = (char*)ptr; |
| 215 } | 193 } |
| 216 } | 194 break; |
| 217 return is_negative ? -ret : ret; | 195 } |
| 218 } | 196 while (fra_count--) { |
| 219 FX_BOOL CCodec_BasicModule::A85Encode(const uint8_t* src_buf, FX_DWORD src_size,
uint8_t*& dest_buf, | 197 fra_base *= 10; |
| 220 FX_DWORD& dest_size) | 198 } |
| 221 { | 199 ret += (double)fra_ret / (double)fra_base; |
| 222 return FALSE; | 200 if (exp_sig == 1) { |
| 223 } | 201 while (exp_ret--) { |
| 224 class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder | 202 ret *= 10.0; |
| 225 { | 203 } |
| 226 public: | 204 } else { |
| 227 CCodec_RLScanlineDecoder(); | 205 while (exp_ret--) { |
| 228 virtual ~CCodec_RLScanlineDecoder(); | 206 ret /= 10.0; |
| 229 FX_BOOL» » » » Create(const uint8_t* src_buf, FX_DWORD
src_size, int width, int height, int nComps, int bpc); | 207 } |
| 230 virtual void» » v_DownScale(int dest_width, int dest_height) {} | 208 } |
| 231 virtual FX_BOOL» » v_Rewind(); | 209 return is_negative ? -ret : ret; |
| 232 virtual uint8_t*» v_GetNextLine(); | 210 } |
| 233 virtual FX_DWORD» GetSrcOffset() | 211 FX_BOOL CCodec_BasicModule::A85Encode(const uint8_t* src_buf, |
| 234 { | 212 FX_DWORD src_size, |
| 235 return m_SrcOffset; | 213 uint8_t*& dest_buf, |
| 236 } | 214 FX_DWORD& dest_size) { |
| 237 protected: | 215 return FALSE; |
| 238 FX_BOOL» » » » CheckDestSize(); | 216 } |
| 239 void» » » » GetNextOperator(); | 217 class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder { |
| 240 void» » » » UpdateOperator(uint8_t used_bytes); | 218 public: |
| 219 CCodec_RLScanlineDecoder(); |
| 220 virtual ~CCodec_RLScanlineDecoder(); |
| 221 FX_BOOL Create(const uint8_t* src_buf, |
| 222 FX_DWORD src_size, |
| 223 int width, |
| 224 int height, |
| 225 int nComps, |
| 226 int bpc); |
| 227 virtual void v_DownScale(int dest_width, int dest_height) {} |
| 228 virtual FX_BOOL v_Rewind(); |
| 229 virtual uint8_t* v_GetNextLine(); |
| 230 virtual FX_DWORD GetSrcOffset() { return m_SrcOffset; } |
| 241 | 231 |
| 242 uint8_t*» » » m_pScanline; | 232 protected: |
| 243 const uint8_t*» » » m_pSrcBuf; | 233 FX_BOOL CheckDestSize(); |
| 244 FX_DWORD» » » m_SrcSize; | 234 void GetNextOperator(); |
| 245 FX_DWORD» » » m_dwLineBytes; | 235 void UpdateOperator(uint8_t used_bytes); |
| 246 FX_DWORD» » » m_SrcOffset; | 236 |
| 247 FX_BOOL» » » » m_bEOD; | 237 uint8_t* m_pScanline; |
| 248 uint8_t» » » » m_Operator; | 238 const uint8_t* m_pSrcBuf; |
| 239 FX_DWORD m_SrcSize; |
| 240 FX_DWORD m_dwLineBytes; |
| 241 FX_DWORD m_SrcOffset; |
| 242 FX_BOOL m_bEOD; |
| 243 uint8_t m_Operator; |
| 249 }; | 244 }; |
| 250 CCodec_RLScanlineDecoder::CCodec_RLScanlineDecoder() | 245 CCodec_RLScanlineDecoder::CCodec_RLScanlineDecoder() |
| 251 : m_pScanline(NULL) | 246 : m_pScanline(NULL), |
| 252 , m_pSrcBuf(NULL) | 247 m_pSrcBuf(NULL), |
| 253 , m_SrcSize(0) | 248 m_SrcSize(0), |
| 254 , m_dwLineBytes(0) | 249 m_dwLineBytes(0), |
| 255 , m_SrcOffset(0) | 250 m_SrcOffset(0), |
| 256 , m_bEOD(FALSE) | 251 m_bEOD(FALSE), |
| 257 , m_Operator(0) | 252 m_Operator(0) {} |
| 258 { | 253 CCodec_RLScanlineDecoder::~CCodec_RLScanlineDecoder() { |
| 259 } | 254 if (m_pScanline) { |
| 260 CCodec_RLScanlineDecoder::~CCodec_RLScanlineDecoder() | 255 FX_Free(m_pScanline); |
| 261 { | 256 } |
| 262 if (m_pScanline) { | 257 } |
| 263 FX_Free(m_pScanline); | 258 FX_BOOL CCodec_RLScanlineDecoder::CheckDestSize() { |
| 264 } | 259 FX_DWORD i = 0; |
| 265 } | 260 FX_DWORD old_size = 0; |
| 266 FX_BOOL CCodec_RLScanlineDecoder::CheckDestSize() | 261 FX_DWORD dest_size = 0; |
| 267 { | 262 while (i < m_SrcSize) { |
| 268 FX_DWORD i = 0; | 263 if (m_pSrcBuf[i] < 128) { |
| 269 FX_DWORD old_size = 0; | 264 old_size = dest_size; |
| 270 FX_DWORD dest_size = 0; | 265 dest_size += m_pSrcBuf[i] + 1; |
| 271 while (i < m_SrcSize) { | 266 if (dest_size < old_size) { |
| 272 if (m_pSrcBuf[i] < 128) { | |
| 273 old_size = dest_size; | |
| 274 dest_size += m_pSrcBuf[i] + 1; | |
| 275 if (dest_size < old_size) { | |
| 276 return FALSE; | |
| 277 } | |
| 278 i += m_pSrcBuf[i] + 2; | |
| 279 } else if (m_pSrcBuf[i] > 128) { | |
| 280 old_size = dest_size; | |
| 281 dest_size += 257 - m_pSrcBuf[i]; | |
| 282 if (dest_size < old_size) { | |
| 283 return FALSE; | |
| 284 } | |
| 285 i += 2; | |
| 286 } else { | |
| 287 break; | |
| 288 } | |
| 289 } | |
| 290 if (((FX_DWORD)m_OrigWidth * m_nComps * m_bpc * m_OrigHeight + 7) / 8 > dest
_size) { | |
| 291 return FALSE; | 267 return FALSE; |
| 292 } | 268 } |
| 293 return TRUE; | 269 i += m_pSrcBuf[i] + 2; |
| 294 } | 270 } else if (m_pSrcBuf[i] > 128) { |
| 295 FX_BOOL CCodec_RLScanlineDecoder::Create(const uint8_t* src_buf, FX_DWORD src_si
ze, int width, int height, int nComps, int bpc) | 271 old_size = dest_size; |
| 296 { | 272 dest_size += 257 - m_pSrcBuf[i]; |
| 297 m_pSrcBuf = src_buf; | 273 if (dest_size < old_size) { |
| 298 m_SrcSize = src_size; | 274 return FALSE; |
| 299 m_OutputWidth = m_OrigWidth = width; | 275 } |
| 300 m_OutputHeight = m_OrigHeight = height; | 276 i += 2; |
| 301 m_nComps = nComps; | |
| 302 m_bpc = bpc; | |
| 303 m_bColorTransformed = FALSE; | |
| 304 m_DownScale = 1; | |
| 305 m_Pitch = (width * nComps * bpc + 31) / 32 * 4; | |
| 306 m_dwLineBytes = (width * nComps * bpc + 7) / 8; | |
| 307 m_pScanline = FX_Alloc(uint8_t, m_Pitch); | |
| 308 return CheckDestSize(); | |
| 309 } | |
| 310 FX_BOOL CCodec_RLScanlineDecoder::v_Rewind() | |
| 311 { | |
| 312 FXSYS_memset(m_pScanline, 0, m_Pitch); | |
| 313 m_SrcOffset = 0; | |
| 314 m_bEOD = FALSE; | |
| 315 m_Operator = 0; | |
| 316 return TRUE; | |
| 317 } | |
| 318 uint8_t* CCodec_RLScanlineDecoder::v_GetNextLine() | |
| 319 { | |
| 320 if (m_SrcOffset == 0) { | |
| 321 GetNextOperator(); | |
| 322 } else { | 277 } else { |
| 323 if (m_bEOD) { | 278 break; |
| 324 return NULL; | 279 } |
| 325 } | 280 } |
| 326 } | 281 if (((FX_DWORD)m_OrigWidth * m_nComps * m_bpc * m_OrigHeight + 7) / 8 > |
| 327 FXSYS_memset(m_pScanline, 0, m_Pitch); | 282 dest_size) { |
| 328 FX_DWORD col_pos = 0; | 283 return FALSE; |
| 329 FX_BOOL» eol = FALSE; | 284 } |
| 330 while (m_SrcOffset < m_SrcSize && !eol) { | 285 return TRUE; |
| 331 if (m_Operator < 128) { | 286 } |
| 332 FX_DWORD copy_len = m_Operator + 1; | 287 FX_BOOL CCodec_RLScanlineDecoder::Create(const uint8_t* src_buf, |
| 333 if (col_pos + copy_len >= m_dwLineBytes) { | 288 FX_DWORD src_size, |
| 334 copy_len = m_dwLineBytes - col_pos; | 289 int width, |
| 335 eol = TRUE; | 290 int height, |
| 336 } | 291 int nComps, |
| 337 if (copy_len >= m_SrcSize - m_SrcOffset) { | 292 int bpc) { |
| 338 copy_len = m_SrcSize - m_SrcOffset; | 293 m_pSrcBuf = src_buf; |
| 339 m_bEOD = TRUE; | 294 m_SrcSize = src_size; |
| 340 } | 295 m_OutputWidth = m_OrigWidth = width; |
| 341 FXSYS_memcpy(m_pScanline + col_pos, m_pSrcBuf + m_SrcOffset, copy_le
n); | 296 m_OutputHeight = m_OrigHeight = height; |
| 342 col_pos += copy_len; | 297 m_nComps = nComps; |
| 343 UpdateOperator((uint8_t)copy_len); | 298 m_bpc = bpc; |
| 344 } else if (m_Operator > 128) { | 299 m_bColorTransformed = FALSE; |
| 345 int fill = 0; | 300 m_DownScale = 1; |
| 346 if (m_SrcOffset - 1 < m_SrcSize - 1) { | 301 m_Pitch = (width * nComps * bpc + 31) / 32 * 4; |
| 347 fill = m_pSrcBuf[m_SrcOffset]; | 302 m_dwLineBytes = (width * nComps * bpc + 7) / 8; |
| 348 } | 303 m_pScanline = FX_Alloc(uint8_t, m_Pitch); |
| 349 FX_DWORD duplicate_len = 257 - m_Operator; | 304 return CheckDestSize(); |
| 350 if (col_pos + duplicate_len >= m_dwLineBytes) { | 305 } |
| 351 duplicate_len = m_dwLineBytes - col_pos; | 306 FX_BOOL CCodec_RLScanlineDecoder::v_Rewind() { |
| 352 eol = TRUE; | 307 FXSYS_memset(m_pScanline, 0, m_Pitch); |
| 353 } | 308 m_SrcOffset = 0; |
| 354 FXSYS_memset(m_pScanline + col_pos, fill, duplicate_len); | 309 m_bEOD = FALSE; |
| 355 col_pos += duplicate_len; | 310 m_Operator = 0; |
| 356 UpdateOperator((uint8_t)duplicate_len); | 311 return TRUE; |
| 357 } else { | 312 } |
| 358 m_bEOD = TRUE; | 313 uint8_t* CCodec_RLScanlineDecoder::v_GetNextLine() { |
| 359 break; | 314 if (m_SrcOffset == 0) { |
| 360 } | 315 GetNextOperator(); |
| 361 } | 316 } else { |
| 362 return m_pScanline; | 317 if (m_bEOD) { |
| 363 } | 318 return NULL; |
| 364 void CCodec_RLScanlineDecoder::GetNextOperator() | 319 } |
| 365 { | 320 } |
| 321 FXSYS_memset(m_pScanline, 0, m_Pitch); |
| 322 FX_DWORD col_pos = 0; |
| 323 FX_BOOL eol = FALSE; |
| 324 while (m_SrcOffset < m_SrcSize && !eol) { |
| 325 if (m_Operator < 128) { |
| 326 FX_DWORD copy_len = m_Operator + 1; |
| 327 if (col_pos + copy_len >= m_dwLineBytes) { |
| 328 copy_len = m_dwLineBytes - col_pos; |
| 329 eol = TRUE; |
| 330 } |
| 331 if (copy_len >= m_SrcSize - m_SrcOffset) { |
| 332 copy_len = m_SrcSize - m_SrcOffset; |
| 333 m_bEOD = TRUE; |
| 334 } |
| 335 FXSYS_memcpy(m_pScanline + col_pos, m_pSrcBuf + m_SrcOffset, copy_len); |
| 336 col_pos += copy_len; |
| 337 UpdateOperator((uint8_t)copy_len); |
| 338 } else if (m_Operator > 128) { |
| 339 int fill = 0; |
| 340 if (m_SrcOffset - 1 < m_SrcSize - 1) { |
| 341 fill = m_pSrcBuf[m_SrcOffset]; |
| 342 } |
| 343 FX_DWORD duplicate_len = 257 - m_Operator; |
| 344 if (col_pos + duplicate_len >= m_dwLineBytes) { |
| 345 duplicate_len = m_dwLineBytes - col_pos; |
| 346 eol = TRUE; |
| 347 } |
| 348 FXSYS_memset(m_pScanline + col_pos, fill, duplicate_len); |
| 349 col_pos += duplicate_len; |
| 350 UpdateOperator((uint8_t)duplicate_len); |
| 351 } else { |
| 352 m_bEOD = TRUE; |
| 353 break; |
| 354 } |
| 355 } |
| 356 return m_pScanline; |
| 357 } |
| 358 void CCodec_RLScanlineDecoder::GetNextOperator() { |
| 359 if (m_SrcOffset >= m_SrcSize) { |
| 360 m_Operator = 128; |
| 361 return; |
| 362 } |
| 363 m_Operator = m_pSrcBuf[m_SrcOffset]; |
| 364 m_SrcOffset++; |
| 365 } |
| 366 void CCodec_RLScanlineDecoder::UpdateOperator(uint8_t used_bytes) { |
| 367 if (used_bytes == 0) { |
| 368 return; |
| 369 } |
| 370 if (m_Operator < 128) { |
| 371 FXSYS_assert((FX_DWORD)m_Operator + 1 >= used_bytes); |
| 372 if (used_bytes == m_Operator + 1) { |
| 373 m_SrcOffset += used_bytes; |
| 374 GetNextOperator(); |
| 375 return; |
| 376 } |
| 377 m_Operator -= used_bytes; |
| 378 m_SrcOffset += used_bytes; |
| 366 if (m_SrcOffset >= m_SrcSize) { | 379 if (m_SrcOffset >= m_SrcSize) { |
| 367 m_Operator = 128; | 380 m_Operator = 128; |
| 368 return; | 381 } |
| 369 } | 382 return; |
| 370 m_Operator = m_pSrcBuf[m_SrcOffset]; | 383 } |
| 371 m_SrcOffset ++; | 384 uint8_t count = 257 - m_Operator; |
| 372 } | 385 FXSYS_assert((FX_DWORD)count >= used_bytes); |
| 373 void CCodec_RLScanlineDecoder::UpdateOperator(uint8_t used_bytes) | 386 if (used_bytes == count) { |
| 374 { | 387 m_SrcOffset++; |
| 375 if (used_bytes == 0) { | 388 GetNextOperator(); |
| 376 return; | 389 return; |
| 377 } | 390 } |
| 378 if (m_Operator < 128) { | 391 count -= used_bytes; |
| 379 FXSYS_assert((FX_DWORD)m_Operator + 1 >= used_bytes); | 392 m_Operator = 257 - count; |
| 380 if (used_bytes == m_Operator + 1) { | 393 } |
| 381 m_SrcOffset += used_bytes; | 394 ICodec_ScanlineDecoder* CCodec_BasicModule::CreateRunLengthDecoder( |
| 382 GetNextOperator(); | 395 const uint8_t* src_buf, |
| 383 return; | 396 FX_DWORD src_size, |
| 384 } | 397 int width, |
| 385 m_Operator -= used_bytes; | 398 int height, |
| 386 m_SrcOffset += used_bytes; | 399 int nComps, |
| 387 if (m_SrcOffset >= m_SrcSize) { | 400 int bpc) { |
| 388 m_Operator = 128; | 401 CCodec_RLScanlineDecoder* pRLScanlineDecoder = new CCodec_RLScanlineDecoder; |
| 389 } | 402 if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps, |
| 390 return; | 403 bpc)) { |
| 391 } | 404 delete pRLScanlineDecoder; |
| 392 uint8_t count = 257 - m_Operator; | 405 return NULL; |
| 393 FXSYS_assert((FX_DWORD)count >= used_bytes); | 406 } |
| 394 if (used_bytes == count) { | 407 return pRLScanlineDecoder; |
| 395 m_SrcOffset ++; | 408 } |
| 396 GetNextOperator(); | |
| 397 return; | |
| 398 } | |
| 399 count -= used_bytes; | |
| 400 m_Operator = 257 - count; | |
| 401 } | |
| 402 ICodec_ScanlineDecoder* CCodec_BasicModule::CreateRunLengthDecoder(const uint8_t
* src_buf, FX_DWORD src_size, int width, int height, | |
| 403 int nComps, int bpc) | |
| 404 { | |
| 405 CCodec_RLScanlineDecoder* pRLScanlineDecoder = new CCodec_RLScanlineDecoder; | |
| 406 if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps, bp
c)) { | |
| 407 delete pRLScanlineDecoder; | |
| 408 return NULL; | |
| 409 } | |
| 410 return pRLScanlineDecoder; | |
| 411 } | |
| OLD | NEW |