| Index: core/fxcodec/codec/fx_codec.cpp
|
| diff --git a/core/fxcodec/codec/fx_codec.cpp b/core/fxcodec/codec/fx_codec.cpp
|
| index aa2ecef34576ce49c4ed8da5b1f48cba07ee7393..bf9a4d9dbdec8b19b44ef15510331ff9408020c3 100644
|
| --- a/core/fxcodec/codec/fx_codec.cpp
|
| +++ b/core/fxcodec/codec/fx_codec.cpp
|
| @@ -97,6 +97,158 @@ uint8_t* CCodec_ScanlineDecoder::ReadNextLine() {
|
| return v_GetNextLine();
|
| }
|
|
|
| +bool CCodec_BasicModule::RunLengthEncode(const uint8_t* src_buf,
|
| + uint32_t src_size,
|
| + uint8_t*& dest_buf,
|
| + uint32_t& dest_size) {
|
| + // Handle edge cases
|
| + if (src_size == 0)
|
| + return false;
|
| + if (src_size == 1) {
|
| + dest_buf = FX_Alloc(uint8_t, 3);
|
| + dest_buf[0] = 0;
|
| + dest_buf[1] = src_buf[0];
|
| + dest_buf[2] = 128;
|
| + return true;
|
| + }
|
| +
|
| + uint32_t est_size = src_size * 2;
|
| + dest_buf = FX_Alloc(uint8_t, est_size);
|
| +
|
| + // Set up pointers.
|
| + uint8_t* out = dest_buf;
|
| + uint32_t run_start = 0;
|
| + uint32_t run_end = 1;
|
| + uint8_t x = src_buf[run_start];
|
| + uint8_t y = src_buf[run_end];
|
| + while (run_end < src_size) {
|
| + uint32_t max_len = run_start + 128 < src_size ? 128 : src_size - run_start;
|
| + while (x == y && ((run_end - run_start) < max_len - 1))
|
| + y = src_buf[++run_end];
|
| + // Reached end with matched run. Update variables to expected values.
|
| + if (x == y) {
|
| + run_end++;
|
| + if (run_end < src_size)
|
| + y = src_buf[run_end];
|
| + }
|
| + if (run_end - run_start > 1) { // Matched run
|
| + out[0] = 257 - (run_end - run_start);
|
| + out[1] = x;
|
| + x = y;
|
| + run_start = run_end;
|
| + run_end++;
|
| + if (run_end < src_size)
|
| + y = src_buf[run_end];
|
| + out += 2;
|
| + continue;
|
| + }
|
| + // Mismatched run
|
| + while (x != y && run_end <= run_start + max_len) {
|
| + out[(run_end - run_start)] = x;
|
| + x = y;
|
| + run_end++;
|
| + if (run_end == src_size) {
|
| + if (run_end <= run_start + max_len) {
|
| + out[(run_end - run_start)] = x;
|
| + run_end++;
|
| + }
|
| + break;
|
| + }
|
| + y = src_buf[run_end];
|
| + }
|
| + out[0] = run_end - run_start - 2;
|
| + out += run_end - run_start;
|
| + run_start = run_end - 1;
|
| + }
|
| + if (run_start < src_size) {
|
| + out[0] = 0;
|
| + out[1] = x;
|
| + out += 2;
|
| + }
|
| + *out = 128;
|
| + dest_size = out + 1 - dest_buf;
|
| + return true;
|
| +}
|
| +
|
| +namespace A85Encode {
|
| +static const uint64_t a[4] = {256 * 256 * 256, 256 * 256, 256, 1};
|
| +static const uint64_t b[5] = {85 * 85 * 85 * 85, 85 * 85 * 85, 85 * 85, 85, 1};
|
| +}
|
| +
|
| +bool CCodec_BasicModule::A85Encode(const uint8_t* src_buf,
|
| + uint32_t src_size,
|
| + uint8_t*& dest_buf,
|
| + uint32_t& dest_size) {
|
| + // Handle edge cases
|
| + if (src_size == 0) {
|
| + dest_size = 0;
|
| + return false;
|
| + }
|
| +
|
| + uint32_t est_size = 5 * (src_size / 4 + 1) + src_size / 30 + 1;
|
| + dest_buf = FX_Alloc(uint8_t, est_size);
|
| +
|
| + // Set up pointers.
|
| + uint8_t* out = dest_buf;
|
| + uint32_t pos = 0;
|
| + uint32_t line_length = 0;
|
| + while (src_size >= 4 && pos < src_size - 3) {
|
| + uint64_t val = (uint64_t)(src_buf[pos]) * A85Encode::a[0] +
|
| + (uint64_t)(src_buf[pos + 1]) * A85Encode::a[1] +
|
| + (uint64_t)(src_buf[pos + 2]) * A85Encode::a[2] +
|
| + (uint64_t)(src_buf[pos + 3]);
|
| + pos += 4;
|
| + if (val == 0) { // All zero special case
|
| + *out = 'z';
|
| + out++;
|
| + line_length++;
|
| + } else {
|
| + uint64_t c1 = val / A85Encode::b[0];
|
| + val -= c1 * A85Encode::b[0];
|
| + out[0] = (uint8_t)c1 + 33;
|
| + uint64_t c2 = val / A85Encode::b[1];
|
| + val -= c2 * A85Encode::b[1];
|
| + out[1] = (uint8_t)c2 + 33;
|
| + uint64_t c3 = val / A85Encode::b[2];
|
| + val -= c3 * A85Encode::b[2];
|
| + out[2] = (uint8_t)c3 + 33;
|
| + uint64_t c4 = val / A85Encode::b[3];
|
| + val -= c4 * A85Encode::b[3];
|
| + out[3] = (uint8_t)c4 + 33;
|
| + out[4] = (uint8_t)val + 33;
|
| + out += 5;
|
| + line_length += 5;
|
| + }
|
| + if (line_length >= 75) {
|
| + *out = '\r';
|
| + *++out = '\n';
|
| + out++;
|
| + line_length = 0;
|
| + }
|
| + }
|
| + if (pos < src_size) { // Leftover bytes
|
| + uint64_t val = 0;
|
| + uint32_t count = 0;
|
| + while (pos < src_size) {
|
| + val += (uint64_t)(src_buf[pos]) * A85Encode::a[count];
|
| + count++;
|
| + pos++;
|
| + }
|
| + for (uint32_t i = 0; i < count + 1; i++) {
|
| + uint64_t c = val / A85Encode::b[i];
|
| + val -= c * A85Encode::b[i];
|
| + out[i] = (uint8_t)c + 33;
|
| + }
|
| + out += count + 1;
|
| + }
|
| +
|
| + out[0] = '~';
|
| + out[1] = '>';
|
| + out += 2;
|
| + dest_size = out - dest_buf;
|
| + return true;
|
| +}
|
| +
|
| #ifdef PDF_ENABLE_XFA
|
| CFX_DIBAttribute::CFX_DIBAttribute()
|
| : m_nXDPI(-1),
|
|
|