Chromium Code Reviews| 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 "core/fxcodec/fx_codec.h" | 7 #include "core/fxcodec/fx_codec.h" |
| 8 | 8 |
| 9 #include <cmath> | 9 #include <cmath> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 } | 94 } |
| 95 | 95 |
| 96 uint8_t* CCodec_ScanlineDecoder::ReadNextLine() { | 96 uint8_t* CCodec_ScanlineDecoder::ReadNextLine() { |
| 97 return v_GetNextLine(); | 97 return v_GetNextLine(); |
| 98 } | 98 } |
| 99 | 99 |
| 100 bool CCodec_BasicModule::RunLengthEncode(const uint8_t* src_buf, | 100 bool CCodec_BasicModule::RunLengthEncode(const uint8_t* src_buf, |
| 101 uint32_t src_size, | 101 uint32_t src_size, |
| 102 uint8_t** dest_buf, | 102 uint8_t** dest_buf, |
| 103 uint32_t* dest_size) { | 103 uint32_t* dest_size) { |
| 104 return false; | 104 // Handle edge cases |
| 105 if (src_size == 0) | |
| 106 return false; | |
| 107 if (src_size == 1) { | |
| 108 *dest_buf = FX_Alloc(uint8_t, 3); | |
| 109 (*dest_buf)[0] = 0; | |
| 110 (*dest_buf)[1] = src_buf[0]; | |
| 111 (*dest_buf)[2] = 128; | |
| 112 *dest_size = 3; | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 // Worst case: 1 nonmatch, 2 match, 1 nonmatch, 2 match, etc. This becomes | |
| 117 // 4 output chars for every 3 input, plus up to 4 more for the 1-2 chars | |
| 118 // rounded off plus the terminating character. | |
| 119 uint32_t est_size = 4 * src_size / 3 + 4; | |
|
Tom Sepez
2017/01/09 20:18:19
Can we get a better estimate by first rounding up
rbpotter
2017/01/10 20:28:23
Done.
| |
| 120 *dest_buf = FX_Alloc(uint8_t, est_size); | |
| 121 | |
| 122 // Set up pointers. | |
| 123 uint8_t* out = *dest_buf; | |
| 124 uint32_t run_start = 0; | |
| 125 uint32_t run_end = 1; | |
| 126 uint8_t x = src_buf[run_start]; | |
| 127 uint8_t y = src_buf[run_end]; | |
| 128 while (run_end < src_size) { | |
|
Tom Sepez
2017/01/09 20:18:19
I'm having trouble following all of this, maybe it
| |
| 129 uint32_t max_len = run_start + 128 < src_size ? 128 : src_size - run_start; | |
|
Tom Sepez
2017/01/09 20:18:19
nit: maybe std::min(src_size - run_start, 128);
rbpotter
2017/01/10 20:28:23
Done.
| |
| 130 while (x == y && ((run_end - run_start) < max_len - 1)) | |
|
Tom Sepez
2017/01/09 20:18:19
Can max_len be 0 here?
nit: overparenthesized.
rbpotter
2017/01/10 20:28:23
Should not be. run_end is always at least one ahea
| |
| 131 y = src_buf[++run_end]; | |
| 132 // Reached end with matched run. Update variables to expected values. | |
|
Tom Sepez
2017/01/09 20:18:19
nit: maybe blank line here.
rbpotter
2017/01/10 20:28:24
Done.
| |
| 133 if (x == y) { | |
| 134 run_end++; | |
| 135 if (run_end < src_size) | |
| 136 y = src_buf[run_end]; | |
| 137 } | |
| 138 if (run_end - run_start > 1) { // Matched run but not at end of input. | |
| 139 out[0] = 257 - (run_end - run_start); | |
| 140 out[1] = x; | |
| 141 x = y; | |
| 142 run_start = run_end; | |
| 143 run_end++; | |
| 144 if (run_end < src_size) | |
| 145 y = src_buf[run_end]; | |
| 146 out += 2; | |
| 147 continue; | |
| 148 } | |
| 149 // Mismatched run | |
| 150 while (x != y && run_end <= run_start + max_len) { | |
| 151 out[(run_end - run_start)] = x; | |
|
Tom Sepez
2017/01/09 20:18:20
nit: overparenthesized, couple places.
rbpotter
2017/01/10 20:28:24
Done.
| |
| 152 x = y; | |
| 153 run_end++; | |
| 154 if (run_end == src_size) { | |
| 155 if (run_end <= run_start + max_len) { | |
| 156 out[(run_end - run_start)] = x; | |
| 157 run_end++; | |
| 158 } | |
| 159 break; | |
| 160 } | |
| 161 y = src_buf[run_end]; | |
| 162 } | |
| 163 out[0] = run_end - run_start - 2; | |
| 164 out += run_end - run_start; | |
| 165 run_start = run_end - 1; | |
| 166 } | |
| 167 if (run_start < src_size) { // 1 leftover character | |
| 168 out[0] = 0; | |
| 169 out[1] = x; | |
| 170 out += 2; | |
| 171 } | |
| 172 *out = 128; | |
| 173 *dest_size = out + 1 - *dest_buf; | |
| 174 return true; | |
| 175 } | |
| 176 | |
| 177 namespace A85Encode { | |
| 178 static const uint64_t a[4] = {256 * 256 * 256, 256 * 256, 256, 1}; | |
|
Tom Sepez
2017/01/09 20:18:20
Can we put these into an empty namespace up top, l
rbpotter
2017/01/10 20:28:23
Done.
| |
| 179 static const uint64_t b[5] = {85 * 85 * 85 * 85, 85 * 85 * 85, 85 * 85, 85, 1}; | |
| 105 } | 180 } |
| 106 | 181 |
| 107 bool CCodec_BasicModule::A85Encode(const uint8_t* src_buf, | 182 bool CCodec_BasicModule::A85Encode(const uint8_t* src_buf, |
| 108 uint32_t src_size, | 183 uint32_t src_size, |
| 109 uint8_t** dest_buf, | 184 uint8_t** dest_buf, |
| 110 uint32_t* dest_size) { | 185 uint32_t* dest_size) { |
| 111 return false; | 186 // Handle edge cases |
| 187 if (src_size == 0) { | |
| 188 *dest_size = 0; | |
| 189 return false; | |
| 190 } | |
| 191 | |
| 192 // Worst case: 5 output for each 4 input (+ up to 4 from leftover), + | |
| 193 // 2 character new lines each 75 output chars = 2*5*src/(4*75), + 2 | |
|
Tom Sepez
2017/01/09 20:18:19
nit: this might read clearer without = = 2*5*src/(
rbpotter
2017/01/10 20:28:24
Done.
| |
| 194 // termination chars. May have fewer if there are special "z" chars. | |
| 195 uint32_t est_size = 5 * (src_size / 4) + 4 + src_size / 30 + 2; | |
| 196 *dest_buf = FX_Alloc(uint8_t, est_size); | |
| 197 | |
| 198 // Set up pointers. | |
| 199 uint8_t* out = *dest_buf; | |
| 200 uint32_t pos = 0; | |
| 201 uint32_t line_length = 0; | |
| 202 while (src_size >= 4 && pos < src_size - 3) { | |
| 203 uint64_t val = (uint64_t)(src_buf[pos]) * A85Encode::a[0] + | |
|
Tom Sepez
2017/01/09 20:18:19
nit: casst not needed, we're multiplying a uint8_t
Tom Sepez
2017/01/09 20:18:19
Wouldn't this also fit into a uint32_t ?
rbpotter
2017/01/10 20:28:23
Done.
rbpotter
2017/01/10 20:28:24
Done.
rbpotter
2017/01/10 20:28:24
Changed this to shifts, but had to keep the cast t
Tom Sepez
2017/01/10 21:08:41
Right. When we go to shifts, we lose the other bi
| |
| 204 (uint64_t)(src_buf[pos + 1]) * A85Encode::a[1] + | |
| 205 (uint64_t)(src_buf[pos + 2]) * A85Encode::a[2] + | |
| 206 (uint64_t)(src_buf[pos + 3]); | |
| 207 pos += 4; | |
| 208 if (val == 0) { // All zero special case | |
| 209 *out = 'z'; | |
| 210 out++; | |
| 211 line_length++; | |
| 212 } else { // Compute base 85 characters and add 33. | |
| 213 uint64_t c1 = val / A85Encode::b[0]; | |
|
Tom Sepez
2017/01/09 20:18:19
I would imagine we just take c = val % 85 and val
rbpotter
2017/01/10 20:28:24
Done. I was trying to avoid calling %, but this is
| |
| 214 val -= c1 * A85Encode::b[0]; | |
| 215 out[0] = (uint8_t)c1 + 33; | |
| 216 uint64_t c2 = val / A85Encode::b[1]; | |
| 217 val -= c2 * A85Encode::b[1]; | |
| 218 out[1] = (uint8_t)c2 + 33; | |
| 219 uint64_t c3 = val / A85Encode::b[2]; | |
| 220 val -= c3 * A85Encode::b[2]; | |
| 221 out[2] = (uint8_t)c3 + 33; | |
| 222 uint64_t c4 = val / A85Encode::b[3]; | |
| 223 val -= c4 * A85Encode::b[3]; | |
| 224 out[3] = (uint8_t)c4 + 33; | |
| 225 out[4] = (uint8_t)val + 33; | |
| 226 out += 5; | |
| 227 line_length += 5; | |
| 228 } | |
| 229 if (line_length >= 75) { // Add a return. | |
| 230 *out = '\r'; | |
|
Tom Sepez
2017/01/09 20:18:19
nit:
*out++ = '\r';
*out++ = '\n';
line_length =
rbpotter
2017/01/10 20:28:23
Done.
| |
| 231 *++out = '\n'; | |
| 232 out++; | |
| 233 line_length = 0; | |
| 234 } | |
| 235 } | |
| 236 if (pos < src_size) { // Leftover bytes | |
| 237 uint64_t val = 0; | |
| 238 uint32_t count = 0; | |
| 239 while (pos < src_size) { | |
| 240 val += (uint64_t)(src_buf[pos]) * A85Encode::a[count]; | |
| 241 count++; | |
| 242 pos++; | |
| 243 } | |
| 244 for (uint32_t i = 0; i < count + 1; i++) { | |
| 245 uint64_t c = val / A85Encode::b[i]; | |
| 246 val -= c * A85Encode::b[i]; | |
| 247 out[i] = (uint8_t)c + 33; | |
| 248 } | |
| 249 out += count + 1; | |
| 250 } | |
| 251 | |
| 252 // Terminating characters. | |
| 253 out[0] = '~'; | |
| 254 out[1] = '>'; | |
| 255 out += 2; | |
| 256 *dest_size = out - *dest_buf; | |
| 257 return true; | |
| 112 } | 258 } |
| 113 | 259 |
| 114 #ifdef PDF_ENABLE_XFA | 260 #ifdef PDF_ENABLE_XFA |
| 115 CFX_DIBAttribute::CFX_DIBAttribute() | 261 CFX_DIBAttribute::CFX_DIBAttribute() |
| 116 : m_nXDPI(-1), | 262 : m_nXDPI(-1), |
| 117 m_nYDPI(-1), | 263 m_nYDPI(-1), |
| 118 m_fAspectRatio(-1.0f), | 264 m_fAspectRatio(-1.0f), |
| 119 m_wDPIUnit(0), | 265 m_wDPIUnit(0), |
| 120 m_nGifLeft(0), | 266 m_nGifLeft(0), |
| 121 m_nGifTop(0), | 267 m_nGifTop(0), |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 int width, | 469 int width, |
| 324 int height, | 470 int height, |
| 325 int nComps, | 471 int nComps, |
| 326 int bpc) { | 472 int bpc) { |
| 327 auto pDecoder = pdfium::MakeUnique<CCodec_RLScanlineDecoder>(); | 473 auto pDecoder = pdfium::MakeUnique<CCodec_RLScanlineDecoder>(); |
| 328 if (!pDecoder->Create(src_buf, src_size, width, height, nComps, bpc)) | 474 if (!pDecoder->Create(src_buf, src_size, width, height, nComps, bpc)) |
| 329 return nullptr; | 475 return nullptr; |
| 330 | 476 |
| 331 return std::move(pDecoder); | 477 return std::move(pDecoder); |
| 332 } | 478 } |
| OLD | NEW |