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 |