| 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/lgif/fx_gif.h" | 7 #include "core/fxcodec/lgif/fx_gif.h" |
| 8 | 8 |
| 9 #include "core/fxcodec/lbmp/fx_bmp.h" | 9 #include "core/fxcodec/lbmp/fx_bmp.h" |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 code_store = 0; | 23 code_store = 0; |
| 24 next_in = NULL; | 24 next_in = NULL; |
| 25 avail_in = 0; | 25 avail_in = 0; |
| 26 stack_size = 0; | 26 stack_size = 0; |
| 27 code_first = 0; | 27 code_first = 0; |
| 28 ClearTable(); | 28 ClearTable(); |
| 29 } | 29 } |
| 30 void CGifLZWDecoder::ClearTable() { | 30 void CGifLZWDecoder::ClearTable() { |
| 31 code_size_cur = code_size + 1; | 31 code_size_cur = code_size + 1; |
| 32 code_next = code_end + 1; | 32 code_next = code_end + 1; |
| 33 code_old = (FX_WORD)-1; | 33 code_old = (uint16_t)-1; |
| 34 FXSYS_memset(code_table, 0, sizeof(tag_Table) * GIF_MAX_LZW_CODE); | 34 FXSYS_memset(code_table, 0, sizeof(tag_Table) * GIF_MAX_LZW_CODE); |
| 35 FXSYS_memset(stack, 0, GIF_MAX_LZW_CODE); | 35 FXSYS_memset(stack, 0, GIF_MAX_LZW_CODE); |
| 36 for (FX_WORD i = 0; i < code_clear; i++) { | 36 for (uint16_t i = 0; i < code_clear; i++) { |
| 37 code_table[i].suffix = (uint8_t)i; | 37 code_table[i].suffix = (uint8_t)i; |
| 38 } | 38 } |
| 39 } | 39 } |
| 40 void CGifLZWDecoder::DecodeString(FX_WORD code) { | 40 void CGifLZWDecoder::DecodeString(uint16_t code) { |
| 41 stack_size = 0; | 41 stack_size = 0; |
| 42 while (TRUE) { | 42 while (TRUE) { |
| 43 ASSERT(code <= code_next); | 43 ASSERT(code <= code_next); |
| 44 if (code < code_clear || code > code_next) { | 44 if (code < code_clear || code > code_next) { |
| 45 break; | 45 break; |
| 46 } | 46 } |
| 47 stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = code_table[code].suffix; | 47 stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = code_table[code].suffix; |
| 48 code = code_table[code].prefix; | 48 code = code_table[code].prefix; |
| 49 } | 49 } |
| 50 stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = (uint8_t)code; | 50 stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = (uint8_t)code; |
| 51 code_first = (uint8_t)code; | 51 code_first = (uint8_t)code; |
| 52 } | 52 } |
| 53 void CGifLZWDecoder::AddCode(FX_WORD prefix_code, uint8_t append_char) { | 53 void CGifLZWDecoder::AddCode(uint16_t prefix_code, uint8_t append_char) { |
| 54 if (code_next == GIF_MAX_LZW_CODE) { | 54 if (code_next == GIF_MAX_LZW_CODE) { |
| 55 return; | 55 return; |
| 56 } | 56 } |
| 57 code_table[code_next].prefix = prefix_code; | 57 code_table[code_next].prefix = prefix_code; |
| 58 code_table[code_next].suffix = append_char; | 58 code_table[code_next].suffix = append_char; |
| 59 if (++code_next < GIF_MAX_LZW_CODE) { | 59 if (++code_next < GIF_MAX_LZW_CODE) { |
| 60 if (code_next >> code_size_cur) { | 60 if (code_next >> code_size_cur) { |
| 61 code_size_cur++; | 61 code_size_cur++; |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 int32_t CGifLZWDecoder::Decode(uint8_t* des_buf, FX_DWORD& des_size) { | 65 int32_t CGifLZWDecoder::Decode(uint8_t* des_buf, FX_DWORD& des_size) { |
| 66 if (des_size == 0) { | 66 if (des_size == 0) { |
| 67 return 3; | 67 return 3; |
| 68 } | 68 } |
| 69 FX_DWORD i = 0; | 69 FX_DWORD i = 0; |
| 70 if (stack_size != 0) { | 70 if (stack_size != 0) { |
| 71 if (des_size < stack_size) { | 71 if (des_size < stack_size) { |
| 72 FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], des_size); | 72 FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], des_size); |
| 73 stack_size -= (FX_WORD)des_size; | 73 stack_size -= (uint16_t)des_size; |
| 74 return 3; | 74 return 3; |
| 75 } | 75 } |
| 76 FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size); | 76 FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size); |
| 77 des_buf += stack_size; | 77 des_buf += stack_size; |
| 78 i += stack_size; | 78 i += stack_size; |
| 79 stack_size = 0; | 79 stack_size = 0; |
| 80 } | 80 } |
| 81 FX_WORD code = 0; | 81 uint16_t code = 0; |
| 82 while (i <= des_size && (avail_in > 0 || bits_left >= code_size_cur)) { | 82 while (i <= des_size && (avail_in > 0 || bits_left >= code_size_cur)) { |
| 83 if (code_size_cur > 12) { | 83 if (code_size_cur > 12) { |
| 84 if (err_msg_ptr) { | 84 if (err_msg_ptr) { |
| 85 FXSYS_strncpy(err_msg_ptr, "Code Length Out Of Range", | 85 FXSYS_strncpy(err_msg_ptr, "Code Length Out Of Range", |
| 86 GIF_MAX_ERROR_SIZE - 1); | 86 GIF_MAX_ERROR_SIZE - 1); |
| 87 } | 87 } |
| 88 return 0; | 88 return 0; |
| 89 } | 89 } |
| 90 if (avail_in > 0) { | 90 if (avail_in > 0) { |
| 91 code_store |= (*next_in++) << bits_left; | 91 code_store |= (*next_in++) << bits_left; |
| 92 avail_in--; | 92 avail_in--; |
| 93 bits_left += 8; | 93 bits_left += 8; |
| 94 } | 94 } |
| 95 while (bits_left >= code_size_cur) { | 95 while (bits_left >= code_size_cur) { |
| 96 code = (FX_WORD)code_store & ((1 << code_size_cur) - 1); | 96 code = (uint16_t)code_store & ((1 << code_size_cur) - 1); |
| 97 code_store >>= code_size_cur; | 97 code_store >>= code_size_cur; |
| 98 bits_left -= code_size_cur; | 98 bits_left -= code_size_cur; |
| 99 if (code == code_clear) { | 99 if (code == code_clear) { |
| 100 ClearTable(); | 100 ClearTable(); |
| 101 continue; | 101 continue; |
| 102 } else if (code == code_end) { | 102 } else if (code == code_end) { |
| 103 des_size = i; | 103 des_size = i; |
| 104 return 1; | 104 return 1; |
| 105 } else { | 105 } else { |
| 106 if (code_old != (FX_WORD)-1) { | 106 if (code_old != (uint16_t)-1) { |
| 107 if (code_next < GIF_MAX_LZW_CODE) { | 107 if (code_next < GIF_MAX_LZW_CODE) { |
| 108 if (code == code_next) { | 108 if (code == code_next) { |
| 109 AddCode(code_old, code_first); | 109 AddCode(code_old, code_first); |
| 110 DecodeString(code); | 110 DecodeString(code); |
| 111 } else if (code > code_next) { | 111 } else if (code > code_next) { |
| 112 if (err_msg_ptr) { | 112 if (err_msg_ptr) { |
| 113 FXSYS_strncpy(err_msg_ptr, "Decode Error, Out Of Range", | 113 FXSYS_strncpy(err_msg_ptr, "Decode Error, Out Of Range", |
| 114 GIF_MAX_ERROR_SIZE - 1); | 114 GIF_MAX_ERROR_SIZE - 1); |
| 115 } | 115 } |
| 116 return 0; | 116 return 0; |
| 117 } else { | 117 } else { |
| 118 DecodeString(code); | 118 DecodeString(code); |
| 119 uint8_t append_char = stack[GIF_MAX_LZW_CODE - stack_size]; | 119 uint8_t append_char = stack[GIF_MAX_LZW_CODE - stack_size]; |
| 120 AddCode(code_old, append_char); | 120 AddCode(code_old, append_char); |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 } else { | 123 } else { |
| 124 DecodeString(code); | 124 DecodeString(code); |
| 125 } | 125 } |
| 126 code_old = code; | 126 code_old = code; |
| 127 if (i + stack_size > des_size) { | 127 if (i + stack_size > des_size) { |
| 128 FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], | 128 FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], |
| 129 des_size - i); | 129 des_size - i); |
| 130 stack_size -= (FX_WORD)(des_size - i); | 130 stack_size -= (uint16_t)(des_size - i); |
| 131 return 3; | 131 return 3; |
| 132 } | 132 } |
| 133 FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], | 133 FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], |
| 134 stack_size); | 134 stack_size); |
| 135 des_buf += stack_size; | 135 des_buf += stack_size; |
| 136 i += stack_size; | 136 i += stack_size; |
| 137 stack_size = 0; | 137 stack_size = 0; |
| 138 } | 138 } |
| 139 } | 139 } |
| 140 } | 140 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 uint8_t bit_use) { | 172 uint8_t bit_use) { |
| 173 FX_DWORD cut = ((1 << (index_bit - index_bit_use)) - 1) << index_bit_use; | 173 FX_DWORD cut = ((1 << (index_bit - index_bit_use)) - 1) << index_bit_use; |
| 174 val |= ((index & cut) >> index_bit_use) << bit_use; | 174 val |= ((index & cut) >> index_bit_use) << bit_use; |
| 175 } | 175 } |
| 176 static inline uint8_t gif_cut_buf(const uint8_t* buf, | 176 static inline uint8_t gif_cut_buf(const uint8_t* buf, |
| 177 FX_DWORD& offset, | 177 FX_DWORD& offset, |
| 178 uint8_t bit_cut, | 178 uint8_t bit_cut, |
| 179 uint8_t& bit_offset, | 179 uint8_t& bit_offset, |
| 180 FX_DWORD& bit_num) { | 180 FX_DWORD& bit_num) { |
| 181 if (bit_cut != 8) { | 181 if (bit_cut != 8) { |
| 182 FX_WORD index = 0; | 182 uint16_t index = 0; |
| 183 index |= ((1 << bit_cut) - 1) << (7 - bit_offset); | 183 index |= ((1 << bit_cut) - 1) << (7 - bit_offset); |
| 184 uint8_t ret = ((index & buf[offset]) >> (7 - bit_offset)); | 184 uint8_t ret = ((index & buf[offset]) >> (7 - bit_offset)); |
| 185 bit_offset += bit_cut; | 185 bit_offset += bit_cut; |
| 186 if (bit_offset >= 8) { | 186 if (bit_offset >= 8) { |
| 187 if (bit_offset > 8) { | 187 if (bit_offset > 8) { |
| 188 ret |= ((index & (buf[offset + 1] << 8)) >> 8); | 188 ret |= ((index & (buf[offset + 1] << 8)) >> 8); |
| 189 } | 189 } |
| 190 bit_offset -= 8; | 190 bit_offset -= 8; |
| 191 offset++; | 191 offset++; |
| 192 } | 192 } |
| 193 bit_num += bit_cut; | 193 bit_num += bit_cut; |
| 194 return ret; | 194 return ret; |
| 195 } | 195 } |
| 196 bit_num += bit_cut; | 196 bit_num += bit_cut; |
| 197 return buf[offset++]; | 197 return buf[offset++]; |
| 198 } | 198 } |
| 199 CGifLZWEncoder::CGifLZWEncoder() { | 199 CGifLZWEncoder::CGifLZWEncoder() { |
| 200 FXSYS_memset(this, 0, sizeof(CGifLZWEncoder)); | 200 FXSYS_memset(this, 0, sizeof(CGifLZWEncoder)); |
| 201 } | 201 } |
| 202 CGifLZWEncoder::~CGifLZWEncoder() {} | 202 CGifLZWEncoder::~CGifLZWEncoder() {} |
| 203 void CGifLZWEncoder::ClearTable() { | 203 void CGifLZWEncoder::ClearTable() { |
| 204 index_bit_cur = code_size + 1; | 204 index_bit_cur = code_size + 1; |
| 205 index_num = code_end + 1; | 205 index_num = code_end + 1; |
| 206 table_cur = code_end + 1; | 206 table_cur = code_end + 1; |
| 207 for (FX_WORD i = 0; i < GIF_MAX_LZW_CODE; i++) { | 207 for (uint16_t i = 0; i < GIF_MAX_LZW_CODE; i++) { |
| 208 code_table[i].prefix = 0; | 208 code_table[i].prefix = 0; |
| 209 code_table[i].suffix = 0; | 209 code_table[i].suffix = 0; |
| 210 } | 210 } |
| 211 } | 211 } |
| 212 void CGifLZWEncoder::Start(uint8_t code_len, | 212 void CGifLZWEncoder::Start(uint8_t code_len, |
| 213 const uint8_t* src_buf, | 213 const uint8_t* src_buf, |
| 214 uint8_t*& dst_buf, | 214 uint8_t*& dst_buf, |
| 215 FX_DWORD& offset) { | 215 FX_DWORD& offset) { |
| 216 code_size = code_len + 1; | 216 code_size = code_len + 1; |
| 217 src_bit_cut = code_size; | 217 src_bit_cut = code_size; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 } | 328 } |
| 329 } | 329 } |
| 330 src_offset = 0; | 330 src_offset = 0; |
| 331 src_bit_offset = 0; | 331 src_bit_offset = 0; |
| 332 src_bit_num = 0; | 332 src_bit_num = 0; |
| 333 return TRUE; | 333 return TRUE; |
| 334 } | 334 } |
| 335 FX_BOOL CGifLZWEncoder::LookUpInTable(const uint8_t* buf, | 335 FX_BOOL CGifLZWEncoder::LookUpInTable(const uint8_t* buf, |
| 336 FX_DWORD& offset, | 336 FX_DWORD& offset, |
| 337 uint8_t& bit_offset) { | 337 uint8_t& bit_offset) { |
| 338 for (FX_WORD i = table_cur; i < index_num; i++) { | 338 for (uint16_t i = table_cur; i < index_num; i++) { |
| 339 if (code_table[i].prefix == code_table[index_num].prefix && | 339 if (code_table[i].prefix == code_table[index_num].prefix && |
| 340 code_table[i].suffix == code_table[index_num].suffix) { | 340 code_table[i].suffix == code_table[index_num].suffix) { |
| 341 code_table[index_num].prefix = i; | 341 code_table[index_num].prefix = i; |
| 342 code_table[index_num].suffix = | 342 code_table[index_num].suffix = |
| 343 gif_cut_buf(buf, offset, src_bit_cut, bit_offset, src_bit_num); | 343 gif_cut_buf(buf, offset, src_bit_cut, bit_offset, src_bit_num); |
| 344 table_cur = i; | 344 table_cur = i; |
| 345 return TRUE; | 345 return TRUE; |
| 346 } | 346 } |
| 347 } | 347 } |
| 348 table_cur = code_end + 1; | 348 table_cur = code_end + 1; |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 FXSYS_memcpy(dst_buf, gif_ptr->header_ptr, sizeof(GifHeader)); | 1034 FXSYS_memcpy(dst_buf, gif_ptr->header_ptr, sizeof(GifHeader)); |
| 1035 gif_ptr->cur_offset += sizeof(GifHeader); | 1035 gif_ptr->cur_offset += sizeof(GifHeader); |
| 1036 SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->width); | 1036 SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->width); |
| 1037 gif_ptr->cur_offset += 2; | 1037 gif_ptr->cur_offset += 2; |
| 1038 SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->height); | 1038 SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->height); |
| 1039 gif_ptr->cur_offset += 2; | 1039 gif_ptr->cur_offset += 2; |
| 1040 dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->global_flag; | 1040 dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->global_flag; |
| 1041 dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->bc_index; | 1041 dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->bc_index; |
| 1042 dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->pixel_aspect; | 1042 dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->pixel_aspect; |
| 1043 if (gif_ptr->global_pal) { | 1043 if (gif_ptr->global_pal) { |
| 1044 FX_WORD size = sizeof(GifPalette) * gif_ptr->gpal_num; | 1044 uint16_t size = sizeof(GifPalette) * gif_ptr->gpal_num; |
| 1045 if (!gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + size)) { | 1045 if (!gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + size)) { |
| 1046 return FALSE; | 1046 return FALSE; |
| 1047 } | 1047 } |
| 1048 FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->global_pal, size); | 1048 FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->global_pal, size); |
| 1049 gif_ptr->cur_offset += size; | 1049 gif_ptr->cur_offset += size; |
| 1050 } | 1050 } |
| 1051 return TRUE; | 1051 return TRUE; |
| 1052 } | 1052 } |
| 1053 void interlace_buf(const uint8_t* buf, FX_DWORD pitch, FX_DWORD height) { | 1053 void interlace_buf(const uint8_t* buf, FX_DWORD pitch, FX_DWORD height) { |
| 1054 CFX_ArrayTemplate<uint8_t*> pass[4]; | 1054 CFX_ArrayTemplate<uint8_t*> pass[4]; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 gif_ptr->cur_offset = cur_offset; | 1220 gif_ptr->cur_offset = cur_offset; |
| 1221 res = FALSE; | 1221 res = FALSE; |
| 1222 } | 1222 } |
| 1223 dst_len = gif_ptr->cur_offset; | 1223 dst_len = gif_ptr->cur_offset; |
| 1224 dst_buf[dst_len - 1] = GIF_SIG_TRAILER; | 1224 dst_buf[dst_len - 1] = GIF_SIG_TRAILER; |
| 1225 if (res) { | 1225 if (res) { |
| 1226 gif_ptr->frames++; | 1226 gif_ptr->frames++; |
| 1227 } | 1227 } |
| 1228 return res; | 1228 return res; |
| 1229 } | 1229 } |
| OLD | NEW |