1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FXCODEC_LGIF_FX_GIF_H_ 8 #define CORE_FXCODEC_LGIF_FX_GIF_H_ 9 10 #include <setjmp.h> 11 #include <vector> 12 13 #include "core/fxcrt/fx_basic.h" 14 15 #define GIF_SIGNATURE "GIF" 16 #define GIF_SIG_EXTENSION 0x21 17 #define GIF_SIG_IMAGE 0x2C 18 #define GIF_SIG_TRAILER 0x3B 19 #define GIF_BLOCK_GCE 0xF9 20 #define GIF_BLOCK_PTE 0x01 21 #define GIF_BLOCK_CE 0xFE 22 #define GIF_BLOCK_AE 0xFF 23 #define GIF_BLOCK_TERMINAL 0x00 24 #define GIF_MAX_LZW_CODE 4096 25 #define GIF_DATA_BLOCK 255 26 #define GIF_MAX_ERROR_SIZE 256 27 #define GIF_D_STATUS_SIG 0x01 28 #define GIF_D_STATUS_TAIL 0x02 29 #define GIF_D_STATUS_EXT 0x03 30 #define GIF_D_STATUS_EXT_AE 0x04 31 #define GIF_D_STATUS_EXT_CE 0x05 32 #define GIF_D_STATUS_EXT_GCE 0x06 33 #define GIF_D_STATUS_EXT_PTE 0x07 34 #define GIF_D_STATUS_EXT_UNE 0x08 35 #define GIF_D_STATUS_IMG_INFO 0x09 36 #define GIF_D_STATUS_IMG_DATA 0x0A 37 #pragma pack(1) 38 typedef struct tagGifGF { 39 uint8_t pal_bits : 3; 40 uint8_t sort_flag : 1; 41 uint8_t color_resolution : 3; 42 uint8_t global_pal : 1; 43 } GifGF; 44 typedef struct tagGifLF { 45 uint8_t pal_bits : 3; 46 uint8_t reserved : 2; 47 uint8_t sort_flag : 1; 48 uint8_t interlace : 1; 49 uint8_t local_pal : 1; 50 } GifLF; 51 typedef struct tagGifHeader { 52 char signature[3]; 53 char version[3]; 54 } GifHeader; 55 typedef struct tagGifLSD { 56 uint16_t width; 57 uint16_t height; 58 uint8_t global_flag; 59 uint8_t bc_index; 60 uint8_t pixel_aspect; 61 } GifLSD; 62 typedef struct tagGifImageInfo { 63 uint16_t left; 64 uint16_t top; 65 uint16_t width; 66 uint16_t height; 67 68 uint8_t local_flag; 69 } GifImageInfo; 70 typedef struct tagGifCEF { 71 uint8_t transparency : 1; 72 uint8_t user_input : 1; 73 uint8_t disposal_method : 3; 74 uint8_t reserved : 3; 75 } GifCEF; 76 typedef struct tagGifGCE { 77 uint8_t block_size; 78 uint8_t gce_flag; 79 uint16_t delay_time; 80 uint8_t trans_index; 81 } GifGCE; 82 typedef struct tagGifPTE { 83 uint8_t block_size; 84 uint16_t grid_left; 85 uint16_t grid_top; 86 uint16_t grid_width; 87 uint16_t grid_height; 88 89 uint8_t char_width; 90 uint8_t char_height; 91 92 uint8_t fc_index; 93 uint8_t bc_index; 94 } GifPTE; 95 typedef struct tagGifAE { 96 uint8_t block_size; 97 uint8_t app_identify[8]; 98 uint8_t app_authentication[3]; 99 } GifAE; 100 typedef struct tagGifPalette { uint8_t r, g, b; } GifPalette; 101 #pragma pack() 102 typedef struct tagGifImage { 103 GifGCE* image_gce_ptr; 104 GifPalette* local_pal_ptr; 105 GifImageInfo* image_info_ptr; 106 uint8_t image_code_size; 107 uint32_t image_data_pos; 108 uint8_t* image_row_buf; 109 int32_t image_row_num; 110 } GifImage; 111 112 typedef struct tagGifPlainText { 113 GifGCE* gce_ptr; 114 GifPTE* pte_ptr; 115 CFX_ByteString* string_ptr; 116 } GifPlainText; 117 118 class CGifLZWDecoder { 119 public: 120 struct tag_Table { 121 uint16_t prefix; 122 uint8_t suffix; 123 }; 124 125 explicit CGifLZWDecoder(FX_CHAR* error_ptr); 126 ~CGifLZWDecoder(); 127 128 void InitTable(uint8_t code_len); 129 int32_t Decode(uint8_t* des_buf, uint32_t& des_size); 130 void Input(uint8_t* src_buf, uint32_t src_size); 131 uint32_t GetAvailInput(); 132 133 private: 134 void ClearTable(); 135 void AddCode(uint16_t prefix_code, uint8_t append_char); 136 void DecodeString(uint16_t code); 137 138 uint8_t code_size; 139 uint8_t code_size_cur; 140 uint16_t code_clear; 141 uint16_t code_end; 142 uint16_t code_next; 143 uint8_t code_first; 144 uint8_t stack[GIF_MAX_LZW_CODE]; 145 uint16_t stack_size; 146 tag_Table code_table[GIF_MAX_LZW_CODE]; 147 uint16_t code_old; 148 149 uint8_t* next_in; 150 uint32_t avail_in; 151 152 uint8_t bits_left; 153 uint32_t code_store; 154 155 FX_CHAR* err_msg_ptr; 156 }; 157 158 class CGifLZWEncoder { 159 public: 160 struct tag_Table { 161 uint16_t prefix; 162 uint8_t suffix; 163 }; 164 165 CGifLZWEncoder(); 166 ~CGifLZWEncoder(); 167 168 void Start(uint8_t code_len, 169 const uint8_t* src_buf, 170 uint8_t*& dst_buf, 171 uint32_t& offset); 172 bool Encode(const uint8_t* src_buf, 173 uint32_t src_len, 174 uint8_t*& dst_buf, 175 uint32_t& dst_len, 176 uint32_t& offset); 177 void Finish(uint8_t*& dst_buf, uint32_t& dst_len, uint32_t& offset); 178 179 private: 180 void ClearTable(); 181 bool LookUpInTable(const uint8_t* buf, uint32_t& offset, uint8_t& bit_offset); 182 void EncodeString(uint32_t index, 183 uint8_t*& dst_buf, 184 uint32_t& dst_len, 185 uint32_t& offset); 186 void WriteBlock(uint8_t*& dst_buf, uint32_t& dst_len, uint32_t& offset); 187 188 jmp_buf jmp; 189 uint32_t src_offset; 190 uint8_t src_bit_offset; 191 uint8_t src_bit_cut; 192 uint32_t src_bit_num; 193 uint8_t code_size; 194 uint16_t code_clear; 195 uint16_t code_end; 196 uint16_t index_num; 197 uint8_t bit_offset; 198 uint8_t index_bit_cur; 199 uint8_t index_buf[GIF_DATA_BLOCK]; 200 uint8_t index_buf_len; 201 tag_Table code_table[GIF_MAX_LZW_CODE]; 202 uint16_t table_cur; 203 }; 204 205 typedef struct tag_gif_decompress_struct gif_decompress_struct; 206 typedef gif_decompress_struct* gif_decompress_struct_p; 207 typedef gif_decompress_struct_p* gif_decompress_struct_pp; 208 static const int32_t s_gif_interlace_step[4] = {8, 8, 4, 2}; 209 struct tag_gif_decompress_struct { 210 jmp_buf jmpbuf; 211 FX_CHAR* err_ptr; 212 void (*gif_error_fn)(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg); 213 void* context_ptr; 214 int width; 215 int height; 216 GifPalette* global_pal_ptr; 217 int32_t global_pal_num; 218 uint8_t global_sort_flag; 219 uint8_t global_color_resolution; 220 221 uint8_t bc_index; 222 uint8_t pixel_aspect; 223 CGifLZWDecoder* img_decoder_ptr; 224 uint32_t img_row_offset; 225 uint32_t img_row_avail_size; 226 uint8_t img_pass_num; 227 std::vector<GifImage*>* img_ptr_arr_ptr; 228 uint8_t* (*gif_ask_buf_for_pal_fn)(gif_decompress_struct_p gif_ptr, 229 int32_t pal_size); 230 uint8_t* next_in; 231 uint32_t avail_in; 232 int32_t decode_status; 233 uint32_t skip_size; 234 void (*gif_record_current_position_fn)(gif_decompress_struct_p gif_ptr, 235 uint32_t* cur_pos_ptr); 236 void (*gif_get_row_fn)(gif_decompress_struct_p gif_ptr, 237 int32_t row_num, 238 uint8_t* row_buf); 239 bool (*gif_get_record_position_fn)(gif_decompress_struct_p gif_ptr, 240 uint32_t cur_pos, 241 int32_t left, 242 int32_t top, 243 int32_t width, 244 int32_t height, 245 int32_t pal_num, 246 void* pal_ptr, 247 int32_t delay_time, 248 bool user_input, 249 int32_t trans_index, 250 int32_t disposal_method, 251 bool interlace); 252 CFX_ByteString* cmt_data_ptr; 253 GifGCE* gce_ptr; 254 std::vector<GifPlainText*>* pt_ptr_arr_ptr; 255 }; 256 typedef struct tag_gif_compress_struct gif_compress_struct; 257 typedef gif_compress_struct* gif_compress_struct_p; 258 typedef gif_compress_struct_p* gif_compress_struct_pp; 259 struct tag_gif_compress_struct { 260 const uint8_t* src_buf; 261 uint32_t src_pitch; 262 uint32_t src_width; 263 uint32_t src_row; 264 uint32_t cur_offset; 265 uint32_t frames; 266 GifHeader* header_ptr; 267 GifLSD* lsd_ptr; 268 GifPalette* global_pal; 269 uint16_t gpal_num; 270 GifPalette* local_pal; 271 uint16_t lpal_num; 272 GifImageInfo* image_info_ptr; 273 CGifLZWEncoder* img_encoder_ptr; 274 275 uint8_t* cmt_data_ptr; 276 uint32_t cmt_data_len; 277 GifGCE* gce_ptr; 278 GifPTE* pte_ptr; 279 const uint8_t* pte_data_ptr; 280 uint32_t pte_data_len; 281 }; 282 283 void gif_error(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg); 284 void gif_warn(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg); 285 gif_decompress_struct_p gif_create_decompress(); 286 void gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr); 287 gif_compress_struct_p gif_create_compress(); 288 void gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr); 289 int32_t gif_read_header(gif_decompress_struct_p gif_ptr); 290 int32_t gif_get_frame(gif_decompress_struct_p gif_ptr); 291 int32_t gif_get_frame_num(gif_decompress_struct_p gif_ptr); 292 int32_t gif_decode_extension(gif_decompress_struct_p gif_ptr); 293 int32_t gif_decode_image_info(gif_decompress_struct_p gif_ptr); 294 void gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr, 295 GifGCE** gce_ptr_ptr); 296 int32_t gif_load_frame(gif_decompress_struct_p gif_ptr, int32_t frame_num); 297 uint8_t* gif_read_data(gif_decompress_struct_p gif_ptr, 298 uint8_t** des_buf_pp, 299 uint32_t data_size); 300 void gif_decoding_failure_at_tail_cleanup(gif_decompress_struct_p gif_ptr, 301 GifImage* gif_image_ptr); 302 void gif_save_decoding_status(gif_decompress_struct_p gif_ptr, int32_t status); 303 void gif_input_buffer(gif_decompress_struct_p gif_ptr, 304 uint8_t* src_buf, 305 uint32_t src_size); 306 uint32_t gif_get_avail_input(gif_decompress_struct_p gif_ptr, 307 uint8_t** avail_buf_ptr); 308 void interlace_buf(const uint8_t* buf, uint32_t width, uint32_t height); 309 bool gif_encode(gif_compress_struct_p gif_ptr, 310 uint8_t*& dst_buf, 311 uint32_t& dst_len); 312 313 #endif // CORE_FXCODEC_LGIF_FX_GIF_H_ 314