1 /* 2 * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <time.h> 17 #include <stdio.h> 18 #include <errno.h> 19 #include <ctype.h> 20 #include <fcntl.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <getopt.h> 24 #include <dirent.h> 25 #include <unistd.h> 26 #include <stdarg.h> 27 #ifdef __MINGW32__ 28 #include <windows.h> 29 #else 30 #include <signal.h> 31 #include <pthread.h> 32 #include <termios.h> 33 #include <sys/ioctl.h> 34 #endif 35 36 #define WM_TOOL_PATH_MAX 256 37 #define WM_TOOL_ONCE_READ_LEN 1024 38 39 #define WM_TOOL_RUN_IMG_HEADER_LEN 0x100 40 41 #define WM_TOOL_SECBOOT_IMG_ADDR (0x2100) 42 #define WM_TOOL_SECBOOT_HEADER_LEN (0x100) 43 #define WM_TOOL_SECBOOT_HEADER_POS (WM_TOOL_SECBOOT_IMG_ADDR - WM_TOOL_SECBOOT_HEADER_LEN) 44 45 #define WM_TOOL_IMG_HEAD_MAGIC_NO (0xA0FFFF9F) 46 47 #define WM_TOOL_DEFAULT_BAUD_RATE 115200 48 49 #define WM_TOOL_DOWNLOAD_TIMEOUT_SEC (60 * 1) 50 51 #define WM_TOOL_USE_1K_XMODEM 1 /* 1 for use 1k_xmodem 0 for xmodem */ 52 53 #define WM_TOOL_IMAGE_VERSION_LEN 16 54 55 /* Xmodem Frame form: <SOH><blk #><255-blk #><--128 data bytes--><CRC hi><CRC lo> */ 56 #define XMODEM_SOH 0x01 57 #define XMODEM_STX 0x02 58 #define XMODEM_EOT 0x04 59 #define XMODEM_ACK 0x06 60 #define XMODEM_NAK 0x15 61 #define XMODEM_CAN 0x18 62 #define XMODEM_CRC_CHR 'C' 63 #define XMODEM_CRC_SIZE 2 /* Crc_High Byte + Crc_Low Byte */ 64 #define XMODEM_FRAME_ID_SIZE 2 /* Frame_Id + 255-Frame_Id */ 65 #define XMODEM_DATA_SIZE_SOH 128 /* for Xmodem protocol */ 66 #define XMODEM_DATA_SIZE_STX 1024 /* for 1K xmodem protocol */ 67 68 #if (WM_TOOL_USE_1K_XMODEM) 69 #define XMODEM_DATA_SIZE XMODEM_DATA_SIZE_STX 70 #define XMODEM_HEAD XMODEM_STX 71 #else 72 #define XMODEM_DATA_SIZE XMODEM_DATA_SIZE_SOH 73 #define XMODEM_HEAD XMODEM_SOH 74 #endif 75 76 #ifdef WM_DEBUG 77 #define WM_TOOL_DBG_PRINT wm_tool_printf 78 #else 79 #define WM_TOOL_DBG_PRINT(...) 80 #endif 81 82 typedef enum { 83 WM_TOOL_DL_ACTION_NONE = 0, 84 WM_TOOL_DL_ACTION_AT, 85 WM_TOOL_DL_ACTION_RTS 86 } wm_tool_dl_action_e; 87 88 typedef enum { 89 WM_TOOL_DL_ERASE_NONE = 0, 90 WM_TOOL_DL_ERASE_ALL 91 } wm_tool_dl_erase_e; 92 93 typedef enum { 94 WM_TOOL_DL_TYPE_IMAGE = 0, 95 WM_TOOL_DL_TYPE_FLS 96 } wm_tool_dl_type_e; 97 98 typedef enum { 99 WM_TOOL_LAYOUT_TYPE_1M = 0, 100 WM_TOOL_LAYOUT_TYPE_2M = 3 101 } wm_tool_layout_type_e; 102 103 typedef enum { 104 WM_TOOL_ZIP_TYPE_UNCOMPRESS = 0, 105 WM_TOOL_ZIP_TYPE_COMPRESS 106 } wm_tool_zip_type_e; 107 108 typedef enum { 109 WM_TOOL_CRC32_REFLECT_OUTPUT = 1, 110 WM_TOOL_CRC32_REFLECT_INPUT = 2 111 } wm_tool_crc32_reflect_e; 112 113 typedef enum { 114 WM_TOOL_SHOW_LOG_NONE = 0, 115 WM_TOOL_SHOW_LOG_STR, 116 WM_TOOL_SHOW_LOG_HEX 117 } wm_tool_show_log_e; 118 119 typedef struct { 120 unsigned int magic_no; 121 unsigned short img_type; 122 unsigned short zip_type; 123 unsigned int run_img_addr; 124 unsigned int run_img_len; 125 unsigned int img_header_addr; 126 unsigned int upgrade_img_addr; 127 unsigned int run_org_checksum; 128 unsigned int upd_no; 129 unsigned char ver[WM_TOOL_IMAGE_VERSION_LEN]; 130 unsigned int reserved0; 131 unsigned int reserved1; 132 unsigned int next_boot; 133 unsigned int hd_checksum; 134 } wm_tool_firmware_booter_t; 135 136 const static char *wm_tool_version = "1.0.4"; 137 138 static int wm_tool_show_usage = 0; 139 static int wm_tool_list_com = 0; 140 static int wm_tool_show_ver = 0; 141 142 static char wm_tool_serial_path[WM_TOOL_PATH_MAX] = "/dev/ttyS0"; 143 static unsigned int wm_tool_download_serial_rate = WM_TOOL_DEFAULT_BAUD_RATE; 144 static unsigned int wm_tool_normal_serial_rate = WM_TOOL_DEFAULT_BAUD_RATE; 145 146 static wm_tool_dl_action_e wm_tool_dl_action = WM_TOOL_DL_ACTION_NONE; 147 static wm_tool_dl_erase_e wm_tool_dl_erase = WM_TOOL_DL_ERASE_NONE; 148 static wm_tool_dl_type_e wm_tool_dl_type = WM_TOOL_DL_TYPE_IMAGE; 149 static char *wm_tool_download_image = NULL; 150 151 static char *wm_tool_input_binary = NULL; 152 static char *wm_tool_output_image = NULL; 153 static char *wm_tool_secboot_image = NULL; 154 static unsigned int wm_tool_src_binary_len = 0; 155 static unsigned int wm_tool_src_binary_crc = 0; 156 static int wm_tool_is_debug = 0; 157 static char wm_tool_image_version[WM_TOOL_IMAGE_VERSION_LEN]; 158 static wm_tool_layout_type_e wm_tool_image_type = WM_TOOL_LAYOUT_TYPE_1M; 159 static wm_tool_zip_type_e wm_tool_zip_type = WM_TOOL_ZIP_TYPE_COMPRESS; 160 static unsigned int wm_tool_upd_addr = 0x8090000; 161 static unsigned int wm_tool_run_addr = 0x8002400; 162 163 static unsigned int wm_tool_image_header = 0x8002000; 164 static unsigned int wm_tool_next_image_header = 0x0; 165 static unsigned int wm_tool_image_upd_no = 0x0; 166 167 static unsigned int wm_tool_file_crc = 0xFFFFFFFF; 168 169 static wm_tool_show_log_e wm_tool_show_log_type = WM_TOOL_SHOW_LOG_NONE; 170 171 #ifdef __MINGW32__ 172 173 #ifndef CBR_2000000 174 #define CBR_2000000 2000000 175 #endif 176 177 #ifndef CBR_1000000 178 #define CBR_1000000 1000000 179 #endif 180 181 #ifndef CBR_921600 182 #define CBR_921600 921600 183 #endif 184 185 #ifndef CBR_460800 186 #define CBR_460800 460800 187 #endif 188 189 static DWORD wm_tool_uart_block = 0; 190 191 static HANDLE wm_tool_uart_handle = NULL; 192 193 const static int wm_tool_uart_speed_array[] = {CBR_2000000, CBR_1000000, CBR_921600, CBR_460800, CBR_115200, CBR_38400, 194 CBR_19200, CBR_9600, CBR_4800, CBR_2400, CBR_1200}; 195 #else /* __MINGW32__ */ 196 197 #ifndef B2000000 198 #define B2000000 2000000 199 #endif 200 201 #ifndef B1000000 202 #define B1000000 1000000 203 #endif 204 205 #ifndef B921600 206 #define B921600 921600 207 #endif 208 209 #ifndef B460800 210 #define B460800 460800 211 #endif 212 213 static int wm_tool_uart_fd = -1; 214 215 static struct termios wm_tool_saved_serial_cfg; 216 217 const static int wm_tool_uart_speed_array[] = {B2000000, B1000000, B921600, B460800, B115200, B38400, 218 B19200, B9600, B4800, B2400, B1200}; 219 220 #endif /* __MINGW32__ */ 221 222 const static int wm_tool_uart_name_array[] = {2000000, 1000000, 921600, 460800, 115200, 38400, 223 19200, 9600, 4800, 2400, 1200}; 224 225 const static unsigned char wm_tool_chip_cmd_b115200[] = {0x21, 0x0a, 0x00, 0x97, 0x4b, 0x31, \ 226 0x00, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00}; 227 const static unsigned char wm_tool_chip_cmd_b460800[] = {0x21, 0x0a, 0x00, 0x07, 0x00, 0x31, \ 228 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x00}; 229 const static unsigned char wm_tool_chip_cmd_b921600[] = {0x21, 0x0a, 0x00, 0x5d, 0x50, 0x31, \ 230 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00}; 231 const static unsigned char wm_tool_chip_cmd_b1000000[] = {0x21, 0x0a, 0x00, 0x5e, 0x3d, 0x31, \ 232 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00}; 233 const static unsigned char wm_tool_chip_cmd_b2000000[] = {0x21, 0x0a, 0x00, 0xef, 0x2a, 0x31, \ 234 0x00, 0x00, 0x00, 0x80, 0x84, 0x1e, 0x00}; 235 236 const static unsigned char wm_tool_chip_cmd_get_mac[] = {0x21, 0x06, 0x00, 0xea, 0x2d, 0x38, 0x00, 0x00, 0x00}; 237 238 static const unsigned int wm_tool_crc32_tab[] = {0x00000000L, 0x77073096L, 0xee0e612cL, 239 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 240 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 241 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 242 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 243 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 244 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 245 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 246 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 247 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 248 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 249 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 250 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 251 0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 252 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 253 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 254 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 255 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 256 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 257 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 258 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 259 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 260 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 261 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 262 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 263 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 264 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 265 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 266 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 267 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 268 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 269 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 270 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 271 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 272 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 273 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 274 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 275 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 276 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 277 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 278 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 279 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 280 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 281 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 282 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 283 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 284 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 285 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 286 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 287 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 288 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 289 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL}; 290 291 static void wm_tool_signal_proc_entry(void); 292 static void wm_tool_stdin_to_uart(void); 293 294 /* ============================ zlib gzip ================================== */ 295 296 #define ALLOC(size) zcalloc((voidp)0, 1, size) 297 #define TRYFREE(p) {if (p) zcfree((voidp)0, p);} 298 299 #define BINARY 0 300 #define ASCII 1 301 #define UNKNOWN 2 302 303 #define STORED_BLOCK 0 304 #define STATIC_TREES 1 305 #define DYN_TREES 2 306 307 #define REP_3_6 16 308 #define REPZ_3_10 17 309 #define REPZ_11_138 18 310 311 #define MAX_BL_BITS 7 312 313 #define BASE 65521 /* largest prime smaller than 65536 */ 314 #define NMAX 5552 315 316 #define DO1(buf) do { 317 s1 += *buf++; \ 318 s2 += s1; \ 319 } while (0) 320 #define DO2(buf) do { 321 DO1(buf); \ 322 DO1(buf); \ 323 } while (0) 324 #define DO4(buf) do { 325 DO2(buf); \ 326 DO2(buf); \ 327 } while (0) 328 #define DO8(buf) do { 329 DO4(buf); \ 330 DO4(buf); \ 331 } while (0) 332 #define DO16(buf) do { 333 DO8(buf); \ 334 DO8(buf); \ 335 } while (0) 336 337 #define Z_OK 0 338 #define Z_STREAM_END 1 339 #define Z_ERRNO (-1) 340 #define Z_STREAM_ERROR (-2) 341 #define Z_DATA_ERROR (-3) 342 #define Z_MEM_ERROR (-4) 343 #define Z_BUF_ERROR (-5) 344 345 #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ 346 347 #define Z_BEST_SPEED 1 348 #define Z_BEST_COMPRESSION 9 349 #define Z_DEFAULT_COMPRESSION (-1) 350 351 #define DEFLATED 8 352 353 #ifndef WBITS 354 # define WBITS 15 /* 32K window */ 355 #endif 356 357 #ifndef MEM_LEVEL 358 # define MEM_LEVEL 8 359 #endif 360 361 #define Z_BUFSIZE 4096 362 363 #define GZ_MAGIC_1 0x1f 364 #define GZ_MAGIC_2 0x8b 365 366 #ifndef OS_CODE 367 # define OS_CODE 0x03 /* assume Unix */ 368 #endif 369 370 #ifndef TOO_FAR 371 # define TOO_FAR 4096 372 #endif 373 374 #define Z_NO_FLUSH 0 375 #define Z_FINISH 4 376 377 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ 378 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 379 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 380 #define COMMENT 0x10 /* bit 4 set: file comment present */ 381 #define RESERVED 0xE0 /* bits 5..7: reserved */ 382 383 #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ 384 #define LITERALS 256 /* number of literal bytes 0..255 */ 385 #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ 386 #define D_CODES 30 /* number of distance codes */ 387 #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ 388 #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ 389 390 #define END_BLOCK 256 391 392 #define MAX_BITS 15 393 394 #define MAX_MEM_LEVEL 9 395 396 #define MIN_MATCH 3 397 #define MAX_MATCH 258 398 399 #define Z_UNKNOWN 2 400 401 #define INIT_STATE 42 402 #define BUSY_STATE 113 403 #define FINISH_STATE 666 404 405 #define NIL 0 406 407 #define Z_FILTERED 1 408 #define Z_HUFFMAN_ONLY 2 409 #define Z_DEFAULT_STRATEGY 0 410 411 #define SMALLEST 1 412 413 #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) 414 415 #define UPDATE_HASH(s, h, c) ((h) = (((h)<<(s)->hash_shift) ^ (c)) & (s)->hash_mask) 416 417 #define ERR_RETURN(strm, err) return ((strm)->msg=z_errmsg[1-(err)], (err)) 418 419 #define put_byte(s, c) {(s)->pending_buf[(s)->pending++] = (c);} 420 421 #define put_short(s, w) do { \ 422 put_byte((s), (uch)((w) & 0xff)); \ 423 put_byte((s), (uch)((ush)(w) >> 8)); \ 424 } while (0) 425 426 #define INSERT_STRING(s, str, match_head) \ 427 (UPDATE_HASH((s), (s)->ins_h, (s)->window[(str) + MIN_MATCH - 1]), \ 428 (s)->prev[(str) & (s)->w_mask] = (match_head) = (s)->head[(s)->ins_h], \ 429 (s)->head[(s)->ins_h] = (str)) 430 431 #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) 432 433 #define check_match(s, start, match, length) 434 435 #define d_code(dist) \ 436 ((dist) < 256 ? dist_code[dist] : dist_code[256 + ((dist) >> 7)]) 437 438 #define FLUSH_BLOCK_ONLY(s, eof) do { \ 439 ct_flush_block((s), ((s)->block_start >= 0L ? \ 440 (char*)&(s)->window[(unsigned)(s)->block_start] : \ 441 (char*)Z_NULL), (long)(s)->strstart - (s)->block_start, (eof)); \ 442 (s)->block_start = (s)->strstart; \ 443 flush_pending((s)->strm); \ 444 } while (0) 445 446 #define FLUSH_BLOCK(s, eof) do { \ 447 FLUSH_BLOCK_ONLY(s, eof); \ 448 if ((s)->strm->avail_out == 0) return 1; \ 449 } while (0) 450 451 #define send_code(s, c, tree) send_bits((s), (tree)[c].Code, (tree)[c].Len) 452 453 #define MAX(a, b) ((a) >= (b) ? (a) : (b)) 454 455 #define Buf_size (8 * 2*sizeof(char)) 456 457 #define smaller(tree, n, m, depth) \ 458 ((tree)[n].Freq < (tree)[m].Freq || \ 459 ((tree)[n].Freq == (tree)[m].Freq && (depth)[n] <= (depth)[m])) 460 461 #define pqremove(s, tree, top) do { \ 462 top = (s)->heap[SMALLEST]; \ 463 (s)->heap[SMALLEST] = (s)->heap[(s)->heap_len--]; \ 464 pqdownheap(s, tree, SMALLEST); \ 465 } while (0) 466 467 #ifndef local 468 # define local static 469 #endif 470 471 #ifndef __P 472 #define __P(args) args 473 #endif 474 475 #define ZALLOC(strm, items, size) \ 476 (*((strm)->zalloc))((strm)->opaque, (items), (size)) 477 #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidp)(addr)) 478 #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} 479 480 #define Assert(cond, msg) 481 482 #ifndef Byte 483 typedef unsigned char Byte; /* 8 bits */ 484 #endif 485 #ifndef uInt 486 typedef unsigned int uInt; /* may be 16 or 32 bits */ 487 #endif 488 #ifndef uLong 489 typedef unsigned long uLong; /* 32 bits or more */ 490 #endif 491 typedef Byte *voidp; 492 typedef voidp gzFile; 493 typedef unsigned char uch; 494 typedef unsigned long ulg; 495 typedef unsigned short ush; 496 typedef ush Pos; 497 typedef unsigned IPos; 498 499 typedef voidp (*alloc_func) __P((voidp opaque, uInt items, uInt size)); 500 typedef void (*free_func) __P((voidp opaque, voidp address)); 501 502 typedef uLong (*check_func) __P((uLong check, Byte *buf, uInt len)); 503 504 typedef struct z_stream_s { 505 Byte *next_in; /* next input byte */ 506 uInt avail_in; /* number of bytes available at next_in */ 507 uLong total_in; /* total nb of input bytes read so far */ 508 509 Byte *next_out; /* next output byte should be put there */ 510 uInt avail_out; /* remaining free space at next_out */ 511 uLong total_out; /* total nb of bytes output so far */ 512 513 char *msg; /* last error message, NULL if no error */ 514 struct internal_state *state; /* not visible by applications */ 515 516 alloc_func zalloc; /* used to allocate the internal state */ 517 free_func zfree; /* used to free the internal state */ 518 voidp opaque; /* private data object passed to zalloc and zfree */ 519 520 Byte data_type; /* best guess about the data type: ascii or binary */ 521 } z_stream; 522 523 typedef struct gz_stream { 524 z_stream stream; 525 int z_err; /* error code for last stream operation */ 526 int z_eof; /* set if end of input file */ 527 FILE *file; /* .gz file */ 528 Byte *inbuf; /* input buffer */ 529 Byte *outbuf; /* output buffer */ 530 uLong crc; /* crc32 of uncompressed data */ 531 char *msg; /* error message */ 532 char *path; /* path name for debugging only */ 533 int transparent; /* 1 if input file is not a .gz file */ 534 char mode; /* 'w' or 'r' */ 535 } gz_stream; 536 537 /* Data structure describing a single value and its code string. */ 538 typedef struct ct_data_s { 539 union { 540 ush freq; /* frequency count */ 541 ush code; /* bit string */ 542 } fc; 543 union { 544 ush dad; /* father node in Huffman tree */ 545 ush len; /* length of bit string */ 546 } dl; 547 } ct_data; 548 549 struct static_tree_desc_s { 550 ct_data *static_tree; /* static tree or NULL */ 551 int *extra_bits; /* extra bits for each code or NULL */ 552 int extra_base; /* base index for extra_bits */ 553 int elems; /* max number of elements in the tree */ 554 int max_length; /* max bit length for the codes */ 555 }; 556 557 typedef struct static_tree_desc_s static_tree_desc; 558 559 typedef struct tree_desc_s { 560 ct_data *dyn_tree; /* the dynamic tree */ 561 int max_code; /* largest code with non zero frequency */ 562 static_tree_desc *stat_desc; /* the corresponding static tree */ 563 } tree_desc; 564 565 typedef struct inflate_huft_s inflate_huft; 566 struct inflate_huft_s { 567 union { 568 struct { 569 char Exop; /* number of extra bits or operation */ 570 char Bits; /* number of bits in this code or subcode */ 571 } what; 572 Byte *pad; /* pad structure to a power of 2 (4 bytes for */ 573 } word; /* 16-bit, 8 bytes for 32-bit machines) */ 574 union { 575 uInt Base; /* literal, length base, or distance base */ 576 inflate_huft *Next; /* pointer to next level of table */ 577 } more; 578 }; 579 580 /* inflate codes private state */ 581 struct inflate_codes_state { 582 /* mode */ 583 enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ 584 START, /* x: set up for LEN */ 585 LEN, /* i: get length/literal/eob next */ 586 LENEXT, /* i: getting length extra (have base) */ 587 DIST, /* i: get distance next */ 588 DISTEXT, /* i: getting distance extra */ 589 COPY, /* o: copying bytes in window, waiting for space */ 590 LIT, /* o: got literal, waiting for output space */ 591 WASH, /* o: got eob, possibly still output waiting */ 592 END, /* x: got eob and all data flushed */ 593 BAD /* x: got error */ 594 } mode; /* current inflate_codes mode */ 595 596 /* mode dependent information */ 597 uInt len; 598 union { 599 struct { 600 inflate_huft *tree; /* pointer into tree */ 601 uInt need; /* bits needed */ 602 } code; /* if LEN or DIST, where in tree */ 603 uInt lit; /* if LIT, literal */ 604 struct { 605 uInt get; /* bits to get for extra */ 606 uInt dist; /* distance back to copy from */ 607 } copy; /* if EXT or COPY, where and how much */ 608 } sub; /* submode */ 609 610 /* mode independent information */ 611 Byte lbits; /* ltree bits decoded per branch */ 612 Byte dbits; /* dtree bits decoder per branch */ 613 inflate_huft *ltree; /* literal/length/eob tree */ 614 inflate_huft *dtree; /* distance tree */ 615 }; 616 617 /* inflate blocks semi-private state */ 618 struct inflate_blocks_state { 619 /* mode */ 620 enum { 621 TYPE, /* get type bits (3, including end bit) */ 622 LENS, /* get lengths for stored */ 623 STORED, /* processing stored block */ 624 TABLE, /* get table lengths */ 625 BTREE, /* get bit lengths tree for a dynamic block */ 626 DTREE, /* get length, distance trees for a dynamic block */ 627 CODES, /* processing fixed or dynamic block */ 628 DRY, /* output remaining window bytes */ 629 DONE, /* finished last block, done */ 630 INF_ERROR /* got a data error--stuck here */ 631 } mode; /* current inflate_block mode */ 632 633 /* mode dependent information */ 634 union { 635 uInt left; /* if STORED, bytes left to copy */ 636 struct { 637 uInt table; /* table lengths (14 bits) */ 638 uInt index; /* index into blens (or border) */ 639 uInt *blens; /* bit lengths of codes */ 640 uInt bb; /* bit length tree depth */ 641 inflate_huft *tb; /* bit length decoding tree */ 642 } trees; /* if DTREE, decoding info for trees */ 643 struct inflate_codes_state 644 *codes; /* if CODES, current state */ 645 } sub; /* submode */ 646 uInt last; /* true if this block is the last block */ 647 648 /* mode independent information */ 649 uInt bitk; /* bits in bit buffer */ 650 uLong bitb; /* bit buffer */ 651 Byte *window; /* sliding window */ 652 Byte *end; /* one byte after sliding window */ 653 Byte *read; /* window read pointer */ 654 Byte *write; /* window write pointer */ 655 check_func checkfn; /* check function */ 656 uLong check; /* check on output */ 657 }; 658 659 typedef struct internal_state { 660 z_stream *strm; /* pointer back to this zlib stream */ 661 int status; /* as the name implies */ 662 Byte *pending_buf; /* output still pending */ 663 Byte *pending_out; /* next pending byte to output to the stream */ 664 int pending; /* nb of bytes in the pending buffer */ 665 uLong adler; /* adler32 of uncompressed data */ 666 int noheader; /* suppress zlib header and adler32 */ 667 Byte data_type; /* UNKNOWN, BINARY or ASCII */ 668 Byte method; /* STORED (for zip only) or DEFLATED */ 669 670 /* used by deflate.c: */ 671 672 uInt w_size; /* LZ77 window size (32K by default) */ 673 uInt w_bits; /* log2(w_size) (8..16) */ 674 uInt w_mask; /* w_size - 1 */ 675 676 Byte *window; 677 /* Sliding window. Input bytes are read into the second half of the window, 678 * and move to the first half later to keep a dictionary of at least wSize 679 * bytes. With this organization, matches are limited to a distance of 680 * wSize-MAX_MATCH bytes, but this ensures that IO is always 681 * performed with a length multiple of the block size. Also, it limits 682 * the window size to 64K, which is quite useful on MSDOS. 683 * To do: use the user input buffer as sliding window. 684 */ 685 686 ulg window_size; 687 /* Actual size of window: 2*wSize, except when the user input buffer 688 * is directly used as sliding window. 689 */ 690 691 Pos *prev; 692 /* Link to older string with same hash index. To limit the size of this 693 * array to 64K, this link is maintained only for the last 32K strings. 694 * An index in this array is thus a window index modulo 32K. 695 */ 696 697 Pos *head; /* Heads of the hash chains or NIL. */ 698 699 uInt ins_h; /* hash index of string to be inserted */ 700 uInt hash_size; /* number of elements in hash table */ 701 uInt hash_bits; /* log2(hash_size) */ 702 uInt hash_mask; /* hash_size-1 */ 703 704 uInt hash_shift; 705 /* Number of bits by which ins_h must be shifted at each input 706 * step. It must be such that after MIN_MATCH steps, the oldest 707 * byte no longer takes part in the hash key, that is: 708 * hash_shift * MIN_MATCH >= hash_bits 709 */ 710 711 long block_start; 712 /* Window position at the beginning of the current output block. Gets 713 * negative when the window is moved backwards. 714 */ 715 716 uInt match_length; /* length of best match */ 717 IPos prev_match; /* previous match */ 718 int match_available; /* set if previous match exists */ 719 uInt strstart; /* start of string to insert */ 720 uInt match_start; /* start of matching string */ 721 uInt lookahead; /* number of valid bytes ahead in window */ 722 723 uInt prev_length; 724 /* Length of the best match at previous step. Matches not greater than this 725 * are discarded. This is used in the lazy match evaluation. 726 */ 727 728 uInt max_chain_length; 729 /* To speed up deflation, hash chains are never searched beyond this 730 * length. A higher limit improves compression ratio but degrades the 731 * speed. 732 */ 733 734 uInt max_lazy_match; 735 /* Attempt to find a better match only when the current match is strictly 736 * smaller than this value. This mechanism is used only for compression 737 * levels >= 4. 738 */ 739 #define max_insert_length max_lazy_match 740 /* Insert new strings in the hash table only if the match length is not 741 * greater than this length. This saves time but degrades compression. 742 * max_insert_length is used only for compression levels <= 3. 743 */ 744 745 int level; /* compression level (1..9) */ 746 int strategy; /* favor or force Huffman coding */ 747 748 uInt good_match; 749 /* Use a faster search when the previous match is longer than this */ 750 751 int nice_match; /* Stop searching when current match exceeds this */ 752 753 /* used by trees.c: */ 754 755 ct_data dyn_ltree[HEAP_SIZE]; /* literal and length tree */ 756 ct_data dyn_dtree[2*D_CODES+1]; /* distance tree */ 757 ct_data bl_tree[2*BL_CODES+1]; /* Huffman tree for the bit lengths */ 758 759 tree_desc l_desc; /* descriptor for literal tree */ 760 tree_desc d_desc; /* descriptor for distance tree */ 761 tree_desc bl_desc; /* descriptor for bit length tree */ 762 763 ush bl_count[MAX_BITS+1]; 764 /* number of codes at each bit length for an optimal tree */ 765 766 int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ 767 int heap_len; /* number of elements in the heap */ 768 int heap_max; /* element of largest frequency */ 769 /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. 770 * The same heap array is used to build all trees. 771 */ 772 773 uch depth[2*L_CODES+1]; 774 /* Depth of each subtree used as tie breaker for trees of equal frequency 775 */ 776 777 uch *l_buf; /* buffer for literals or lengths */ 778 779 uInt lit_bufsize; 780 /* Size of match buffer for literals/lengths. There are 4 reasons for 781 * limiting lit_bufsize to 64K: 782 * - frequencies can be kept in 16 bit counters 783 * - if compression is not successful for the first block, all input 784 * data is still in the window so we can still emit a stored block even 785 * when input comes from standard input. (This can also be done for 786 * all blocks if lit_bufsize is not greater than 32K.) 787 * - if compression is not successful for a file smaller than 64K, we can 788 * even emit a stored file instead of a stored block (saving 5 bytes). 789 * This is applicable only for zip (not gzip or zlib). 790 * - creating new Huffman trees less frequently may not provide fast 791 * adaptation to changes in the input data statistics. (Take for 792 * example a binary file with poorly compressible code followed by 793 * a highly compressible string table.) Smaller buffer sizes give 794 * fast adaptation but have of course the overhead of transmitting 795 * trees more frequently. 796 * - I can't count above 4 797 */ 798 799 uInt last_lit; /* running index in l_buf */ 800 801 ush *d_buf; 802 /* Buffer for distances. To simplify the code, d_buf and l_buf have 803 * the same number of elements. To use different lengths, an extra flag 804 * array would be necessary. 805 */ 806 807 ulg opt_len; /* bit length of current block with optimal trees */ 808 ulg static_len; /* bit length of current block with static trees */ 809 ulg compressed_len; /* total bit length of compressed file */ 810 uInt matches; /* number of string matches in current block */ 811 812 #ifdef DEBUG 813 ulg bits_sent; /* bit length of the compressed data */ 814 #endif 815 816 ush bi_buf; 817 /* Output buffer. bits are inserted starting at the bottom (least 818 * significant bits). 819 */ 820 int bi_valid; 821 /* Number of valid bits in bi_buf. All bits above the last valid bit 822 * are always zero. 823 */ 824 825 /* mode */ 826 enum { 827 METHOD, /* waiting for method byte */ 828 FLAG, /* waiting for flag byte */ 829 BLOCKS, /* decompressing blocks */ 830 CHECK4, /* four check bytes to go */ 831 CHECK3, /* three check bytes to go */ 832 CHECK2, /* two check bytes to go */ 833 CHECK1, /* one check byte to go */ 834 } 835 mode; /* current inflate mode */ 836 837 /* mode dependent information */ 838 union { 839 uInt method; /* if FLAGS, method byte */ 840 struct inflate_blocks_state 841 *blocks; /* if BLOCKS, current state */ 842 struct { 843 uLong was; /* computed check value */ 844 uLong need; /* stream check value */ 845 } check; /* if CHECK, check values to compare */ 846 } sub; /* submode */ 847 848 /* mode independent information */ 849 int nowrap; /* flag for no wrapper */ 850 uInt wbits; /* log2(window size) (8..15, defaults to 15) */ 851 } deflate_state; 852 853 typedef struct config_s { 854 ush good_length; /* reduce lazy search above this match length */ 855 ush max_lazy; /* do not perform lazy search above this match length */ 856 ush nice_length; /* quit search above this match length */ 857 ush max_chain; 858 } config; 859 860 char *z_errmsg[] = { 861 "stream end", /* Z_STREAM_END 1 */ 862 "", /* Z_OK 0 */ 863 "file error", /* Z_ERRNO (-1) */ 864 "stream error", /* Z_STREAM_ERROR (-2) */ 865 "data error", /* Z_DATA_ERROR (-3) */ 866 "insufficient memory", /* Z_MEM_ERROR (-4) */ 867 "buffer error", /* Z_BUF_ERROR (-5) */ 868 ""}; 869 870 local int base_length[LENGTH_CODES]; 871 local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ 872 = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; 873 local uch length_code[MAX_MATCH-MIN_MATCH+1]; 874 local int base_dist[D_CODES]; 875 local int extra_dbits[D_CODES] /* extra bits for each distance code */ 876 = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; 877 local ct_data static_ltree[L_CODES+2]; 878 local uch dist_code[512]; 879 local int base_dist[D_CODES]; 880 local ct_data static_dtree[D_CODES]; 881 882 local static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; 883 884 local static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; 885 886 local int extra_blbits[BL_CODES] /* extra bits for each bit length code */ 887 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; 888 889 local static_tree_desc static_bl_desc = {(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; 890 891 local uch bl_order[BL_CODES] 892 = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 893 894 local config configuration_table[10] = { 895 /* good lazy nice chain */ 896 {0, 0, 0, 0}, /* 0 */ /* store only */ 897 {4, 4, 8, 4}, /* 1 */ /* maximum speed, no lazy matches */ 898 {4, 5, 16, 8}, /* 2 */ 899 {4, 6, 32, 32}, /* 3 */ 900 {4, 4, 16, 16}, /* 4 */ /* lazy matches */ 901 {8, 16, 32, 32}, /* 5 */ 902 {8, 16, 128, 128}, /* 6 */ 903 {8, 32, 128, 256}, /* 7 */ 904 {32, 128, 258, 1024}, /* 8 */ 905 {32, 258, 258, 4096}}; /* 9 */ /* maximum compression */ 906 907 #define FIXEDH 530 /* number of hufts used by fixed tables */ 908 local inflate_huft fixed_mem[FIXEDH]; 909 910 #define next more.Next 911 912 #define Freq fc.freq 913 #define Code fc.code 914 #define Dad dl.dad 915 #define Len dl.len 916 917 local voidp zcalloc (opaque, items, size) 918 voidp opaque; 919 unsigned items; 920 unsigned size; 921 { 922 return calloc(items, size); 923 } 924 925 local void zcfree (opaque, ptr) 926 voidp opaque; 927 voidp ptr; 928 { 929 free(ptr); 930 } 931 932 local uLong crc32(crc, buf, len) 933 uLong crc; 934 Byte *buf; 935 uInt len; 936 { 937 if (buf == Z_NULL) { 938 return 0L; 939 } 940 crc = crc ^ 0xffffffffL; 941 if (len) { 942 do { 943 crc = wm_tool_crc32_tab[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); // 8:byte alignment 944 } while (--len); 945 } 946 return crc ^ 0xffffffffL; 947 } 948 949 local void zmemcpy(dest, source, len) 950 Byte* dest; 951 Byte* source; 952 uInt len; 953 { 954 if (len == 0) { 955 return; 956 } 957 do { 958 *dest++ = *source++; /* ??? to be unrolled */ 959 } while (--len != 0); 960 } 961 962 local void zmemzero(dest, len) 963 Byte* dest; 964 uInt len; 965 { 966 if (len == 0) { 967 return; 968 } 969 do { 970 *dest++ = 0; /* ??? to be unrolled */ 971 } while (--len != 0); 972 } 973 974 local uLong adler32(adler, buf, len) 975 uLong adler; 976 Byte *buf; 977 uInt len; 978 { 979 unsigned long s1 = adler & 0xffff; 980 unsigned long s2 = (adler >> 16) & 0xffff; // 16:byte alignment 981 int k; 982 983 if (buf == Z_NULL) { 984 return 1L; 985 } 986 987 while (len > 0) { 988 k = len < NMAX ? len : NMAX; 989 len -= k; 990 while (k >= 16) { // 16:byte alignment 991 DO16(buf); 992 k -= 16; // 16:byte alignment 993 } 994 if (k != 0) { 995 do { 996 DO1(buf); 997 } while (--k); 998 } 999 s1 %= BASE; 1000 s2 %= BASE; 1001 } 1002 return (s2 << 16) | s1; // 16:byte alignment 1003 } 1004 1005 local int read_buf(strm, buf, size) 1006 z_stream *strm; 1007 char *buf; 1008 unsigned size; 1009 { 1010 unsigned len = strm->avail_in; 1011 1012 if (len > size) { 1013 len = size; 1014 } 1015 if (len == 0) { 1016 return 0; 1017 } 1018 1019 strm->avail_in -= len; 1020 1021 if (!strm->state->noheader) { 1022 strm->state->adler = adler32(strm->state->adler, strm->next_in, len); 1023 } 1024 zmemcpy((Byte *)buf, strm->next_in, len); 1025 strm->next_in += len; 1026 strm->total_in += len; 1027 1028 return (int)len; 1029 } 1030 1031 local int inflate_trees_free(t, z) 1032 inflate_huft *t; /* table to free */ 1033 z_stream *z; /* for zfree function */ 1034 /* Free the malloc'ed tables built by huft_build(), which makes a linked 1035 list of the tables it made, with the links in a dummy first entry of 1036 each table. */ 1037 { 1038 register inflate_huft *p, *q; 1039 1040 /* Don't free fixed trees */ 1041 if (t >= fixed_mem && t <= fixed_mem + FIXEDH) { 1042 return Z_OK; 1043 } 1044 1045 /* Go through linked list, freeing from the malloced (t[-1]) address. */ 1046 p = t; 1047 while (p != Z_NULL) { 1048 q = (--p)->next; 1049 ZFREE(z, p); 1050 p = q; 1051 } 1052 return Z_OK; 1053 } 1054 1055 local void inflate_codes_free(c, z) 1056 struct inflate_codes_state *c; 1057 z_stream *z; 1058 { 1059 inflate_trees_free(c->dtree, z); 1060 inflate_trees_free(c->ltree, z); 1061 ZFREE(z, c); 1062 } 1063 1064 local int inflate_blocks_free(s, z, c) 1065 struct inflate_blocks_state *s; 1066 z_stream *z; 1067 uLong *c; 1068 { 1069 if (s->checkfn != Z_NULL) { 1070 *c = s->check; 1071 } 1072 if (s->mode == BTREE || s->mode == DTREE) { 1073 ZFREE(z, s->sub.trees.blens); 1074 } 1075 if (s->mode == CODES) { 1076 inflate_codes_free(s->sub.codes, z); 1077 } 1078 ZFREE(z, s->window); 1079 ZFREE(z, s); 1080 return Z_OK; 1081 } 1082 1083 local int deflateEnd (strm) 1084 z_stream *strm; 1085 { 1086 if (strm == Z_NULL || strm->state == Z_NULL) { 1087 return Z_STREAM_ERROR; 1088 } 1089 1090 TRY_FREE(strm, strm->state->window); 1091 TRY_FREE(strm, strm->state->prev); 1092 TRY_FREE(strm, strm->state->head); 1093 TRY_FREE(strm, strm->state->pending_buf); 1094 1095 ZFREE(strm, strm->state); 1096 strm->state = Z_NULL; 1097 1098 return Z_OK; 1099 } 1100 1101 local int inflateEnd(z) 1102 z_stream *z; 1103 { 1104 uLong c; 1105 1106 if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) { 1107 return Z_STREAM_ERROR; 1108 } 1109 if (z->state->mode == BLOCKS) { 1110 inflate_blocks_free(z->state->sub.blocks, z, &c); 1111 } 1112 ZFREE(z, z->state); 1113 z->state = Z_NULL; 1114 return Z_OK; 1115 } 1116 1117 local int destroy (s) 1118 gz_stream *s; 1119 { 1120 int err = Z_OK; 1121 1122 if (!s) return { 1123 Z_STREAM_ERROR; 1124 } 1125 1126 TRYFREE(s->inbuf); 1127 TRYFREE(s->outbuf); 1128 TRYFREE((voidp)s->path); 1129 TRYFREE((voidp)s->msg); 1130 1131 if (s->stream.state != NULL) { 1132 if (s->mode == 'w') { 1133 err = deflateEnd(&(s->stream)); 1134 } else if (s->mode == 'r') { 1135 err = inflateEnd(&(s->stream)); 1136 } 1137 } 1138 if (s->file != NULL && fclose(s->file)) { 1139 err = Z_ERRNO; 1140 } 1141 if (s->z_err < 0) { 1142 err = s->z_err; 1143 } 1144 zcfree((voidp)0, (voidp)s); 1145 return err; 1146 } 1147 1148 local void putLong (file, x) 1149 FILE *file; 1150 uLong x; 1151 { 1152 int n; 1153 for (n = 0; n < 4; n++) { // 4:byte alignment 1154 fputc((int)(x & 0xff), file); 1155 x >>= 8; // 8:byte alignment 1156 } 1157 } 1158 1159 local uLong getLong (buf) 1160 Byte *buf; 1161 { 1162 uLong x = 0; 1163 Byte *p = buf + 4; // 4:byte alignment 1164 1165 do { 1166 x <<= 8; // 8:byte alignment 1167 x |= *--p; 1168 } while (p != buf); 1169 return x; 1170 } 1171 1172 local unsigned bi_reverse(code, len) 1173 unsigned code; /* the value to invert */ 1174 int len; /* its bit length */ 1175 { 1176 register unsigned res = 0; 1177 do { 1178 res |= code & 1; 1179 code >>= 1, res <<= 1; 1180 } while (--len > 0); 1181 return res >> 1; 1182 } 1183 1184 local void gen_codes (tree, max_code, bl_count) 1185 ct_data *tree; /* the tree to decorate */ 1186 int max_code; /* largest code with non zero frequency */ 1187 ush bl_count[]; /* number of codes at each bit length */ 1188 { 1189 ush next_code[MAX_BITS+1]; /* next code value for each bit length */ 1190 ush code = 0; /* running code value */ 1191 int bits; /* bit index */ 1192 int n; /* code index */ 1193 1194 /* The distribution counts are first used to generate the code values 1195 * without bit reversal. 1196 */ 1197 for (bits = 1; bits <= MAX_BITS; bits++) { 1198 next_code[bits] = code = (code + bl_count[bits - 1]) << 1; 1199 } 1200 /* Check that the bit counts in bl_count are consistent. The last code 1201 * must be all ones. 1202 */ 1203 Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, 1204 "inconsistent bit counts"); 1205 1206 for (n = 0; n <= max_code; n++) { 1207 int len = tree[n].Len; 1208 if (len == 0) { 1209 continue; 1210 } 1211 /* Now reverse the bits */ 1212 tree[n].Code = bi_reverse(next_code[len]++, len); 1213 } 1214 } 1215 1216 local void ct_static_init(void) 1217 { 1218 int n; /* iterates over tree elements */ 1219 int bits; /* bit counter */ 1220 int length; /* length value */ 1221 int code; /* code value */ 1222 int dist; /* distance index */ 1223 ush bl_count[MAX_BITS+1]; 1224 /* number of codes at each bit length for an optimal tree */ 1225 1226 /* Initialize the mapping length (0..255) -> length code (0..28) */ 1227 length = 0; 1228 for (code = 0; code < LENGTH_CODES-1; code++) { 1229 base_length[code] = length; 1230 for (n = 0; n < (1 << extra_lbits[code]); n++) { 1231 length_code[length++] = (uch)code; 1232 } 1233 } 1234 Assert (length == 256, "ct_static_init: length != 256"); 1235 /* Note that the length 255 (match length 258) can be represented 1236 * in two different ways: code 284 + 5 bits or code 285, so we 1237 * overwrite length_code[255] to use the best encoding: 1238 */ 1239 length_code[length-1] = (uch)code; 1240 1241 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ 1242 dist = 0; 1243 for (code = 0 ; code < 16; code++) { // 16:byte alignment 1244 base_dist[code] = dist; 1245 for (n = 0; n < (1 << extra_dbits[code]); n++) { 1246 dist_code[dist++] = (uch)code; 1247 } 1248 } 1249 Assert (dist == 256, "ct_static_init: dist != 256"); 1250 dist >>= 7; /* from now on, all distances are divided by 128 */ // 7:byte alignment 1251 for (; code < D_CODES; code++) { 1252 base_dist[code] = dist << 7; // 7:byte alignment 1253 for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { // 7:byte alignment 1254 dist_code[256 + dist++] = (uch)code; // 256:byte alignment 1255 } 1256 } 1257 Assert (dist == 256, "ct_static_init: 256+dist != 512"); // 256:byte alignment 1258 1259 /* Construct the codes of the static literal tree */ 1260 for (bits = 0; bits <= MAX_BITS; bits++) { 1261 bl_count[bits] = 0; 1262 } 1263 n = 0; 1264 while (n <= 143) { // 143:byte alignment 1265 static_ltree[n++].Len = 8, bl_count[8]++; // 8:byte alignment 1266 } 1267 while (n <= 255) { // 255:byte alignment 1268 static_ltree[n++].Len = 9, bl_count[9]++; // 9:byte alignment 1269 } 1270 while (n <= 279) { // 279:byte alignment 1271 static_ltree[n++].Len = 7, bl_count[7]++; // 7:byte alignment 1272 } 1273 while (n <= 287) { // 287:byte alignment 1274 static_ltree[n++].Len = 8, bl_count[8]++; // 8:byte alignment 1275 } 1276 /* Codes 286 and 287 do not exist, but we must include them in the 1277 * tree construction to get a canonical Huffman tree (longest code 1278 * all ones) 1279 */ 1280 gen_codes((ct_data *)static_ltree, L_CODES + 1, bl_count); 1281 1282 /* The static distance tree is trivial: */ 1283 for (n = 0; n < D_CODES; n++) { 1284 static_dtree[n].Len = 5; // 5:byte alignment 1285 static_dtree[n].Code = bi_reverse(n, 5); // 5:byte alignment 1286 } 1287 } 1288 1289 local void init_block(s) 1290 deflate_state *s; 1291 { 1292 int n; /* iterates over tree elements */ 1293 1294 /* Initialize the trees. */ 1295 for (n = 0; n < L_CODES; n++) { 1296 s->dyn_ltree[n].Freq = 0; 1297 } 1298 for (n = 0; n < D_CODES; n++) { 1299 s->dyn_dtree[n].Freq = 0; 1300 } 1301 for (n = 0; n < BL_CODES;n++) { 1302 s->bl_tree[n].Freq = 0; 1303 } 1304 1305 s->dyn_ltree[END_BLOCK].Freq = 1; 1306 s->opt_len = s->static_len = 0L; 1307 s->last_lit = s->matches = 0; 1308 } 1309 1310 local void ct_init(s) 1311 deflate_state *s; 1312 { 1313 if (static_dtree[0].Len == 0) { 1314 ct_static_init(); /* To do: at compile time */ 1315 } 1316 1317 s->compressed_len = 0L; 1318 1319 s->l_desc.dyn_tree = s->dyn_ltree; 1320 s->l_desc.stat_desc = &static_l_desc; 1321 1322 s->d_desc.dyn_tree = s->dyn_dtree; 1323 s->d_desc.stat_desc = &static_d_desc; 1324 1325 s->bl_desc.dyn_tree = s->bl_tree; 1326 s->bl_desc.stat_desc = &static_bl_desc; 1327 1328 s->bi_buf = 0; 1329 s->bi_valid = 0; 1330 #ifdef DEBUG 1331 s->bits_sent = 0L; 1332 #endif 1333 1334 /* Initialize the first block of the first file: */ 1335 init_block(s); 1336 } 1337 1338 local void lm_init (s) 1339 deflate_state *s; 1340 { 1341 register unsigned j; 1342 1343 s->window_size = (ulg)2L*s->w_size; 1344 1345 /* Initialize the hash table (avoiding 64K overflow for 16 bit systems). 1346 * prev[] will be initialized on the fly. 1347 */ 1348 s->head[s->hash_size-1] = NIL; 1349 zmemzero((unsigned char*)s->head, (unsigned int)(s->hash_size-1)*sizeof(*s->head)); 1350 1351 /* Set the default configuration parameters: 1352 */ 1353 s->max_lazy_match = configuration_table[s->level].max_lazy; 1354 s->good_match = configuration_table[s->level].good_length; 1355 s->nice_match = configuration_table[s->level].nice_length; 1356 s->max_chain_length = configuration_table[s->level].max_chain; 1357 1358 s->strstart = 0; 1359 s->block_start = 0L; 1360 s->lookahead = 0; 1361 s->match_length = MIN_MATCH-1; 1362 s->match_available = 0; 1363 #ifdef ASMV 1364 match_init(); /* initialize the asm code */ 1365 #endif 1366 1367 s->ins_h = 0; 1368 for (j=0; j<MIN_MATCH-1; j++) { 1369 UPDATE_HASH(s, s->ins_h, s->window[j]); 1370 } 1371 /* If lookahead < MIN_MATCH, ins_h is garbage, but this is 1372 * not important since only literal bytes will be emitted. 1373 */ 1374 } 1375 1376 local int deflateReset (strm) 1377 z_stream *strm; 1378 { 1379 deflate_state *s; 1380 1381 if (strm == Z_NULL || strm->state == Z_NULL || 1382 strm->zalloc == Z_NULL || strm->zfree == Z_NULL) { 1383 return Z_STREAM_ERROR; 1384 } 1385 1386 strm->total_in = strm->total_out = 0; 1387 strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ 1388 strm->data_type = Z_UNKNOWN; 1389 1390 s = (deflate_state *)strm->state; 1391 s->pending = 0; 1392 s->pending_out = s->pending_buf; 1393 1394 s->status = s->noheader ? BUSY_STATE : INIT_STATE; 1395 s->adler = 1; 1396 1397 ct_init(s); 1398 lm_init(s); 1399 1400 return Z_OK; 1401 } 1402 1403 local int deflateInit2 (strm, level, method, windowBits, memLevel, strategy) 1404 z_stream *strm; 1405 int level; 1406 int method; 1407 int windowBits; 1408 int memLevel; 1409 int strategy; 1410 { 1411 deflate_state *s; 1412 int noheader = 0; 1413 1414 if (strm == Z_NULL) { 1415 return Z_STREAM_ERROR; 1416 } 1417 1418 strm->msg = Z_NULL; 1419 if (strm->zalloc == Z_NULL) { 1420 strm->zalloc = zcalloc; 1421 } 1422 if (strm->zfree == Z_NULL) { 1423 strm->zfree = zcfree; 1424 } 1425 1426 if (level == Z_DEFAULT_COMPRESSION) { 1427 level = 6; 1428 } 1429 1430 if (windowBits < 0) { /* undocumented feature: suppress zlib header */ 1431 noheader = 1; 1432 windowBits = -windowBits; 1433 } 1434 if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED || 1435 windowBits < 8 || windowBits > 15 || // 8:byte alignment, 15:byte alignment 1436 level < 1 || level > 9) { // 9:byte alignment 1437 return Z_STREAM_ERROR; 1438 } 1439 s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); 1440 if (s == Z_NULL) { 1441 return Z_MEM_ERROR; 1442 } 1443 strm->state = (struct internal_state *)s; 1444 s->strm = strm; 1445 1446 s->noheader = noheader; 1447 s->w_bits = windowBits; 1448 s->w_size = 1 << s->w_bits; 1449 s->w_mask = s->w_size - 1; 1450 1451 s->hash_bits = memLevel + 7; // 7:byte alignment 1452 s->hash_size = 1 << s->hash_bits; 1453 s->hash_mask = s->hash_size - 1; 1454 s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); 1455 1456 s->window = (Byte*) ZALLOC(strm, s->w_size, 2 * sizeof(Byte)); // 2:byte alignment 1457 s->prev = (Pos*) ZALLOC(strm, s->w_size, sizeof(Pos)); 1458 s->head = (Pos*) ZALLOC(strm, s->hash_size, sizeof(Pos)); 1459 1460 s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ // 6:byte alignment 1461 1462 s->pending_buf = (uch*) ZALLOC(strm, s->lit_bufsize, 2 * sizeof(ush)); // 2:byte alignment 1463 1464 if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { 1465 strm->msg = z_errmsg[1 - Z_MEM_ERROR]; 1466 deflateEnd (strm); 1467 return Z_MEM_ERROR; 1468 } 1469 s->d_buf = (ush*) &(s->pending_buf[s->lit_bufsize]); 1470 s->l_buf = (uch*) &(s->pending_buf[3 * s->lit_bufsize]); // 3:byte alignment 1471 /* We overlay pending_buf and d_buf+l_buf. This works since the average 1472 * output size for (length,distance) codes is <= 32 bits (worst case 1473 * is 15+15+13=33). 1474 */ 1475 1476 s->level = level; 1477 s->strategy = strategy; 1478 s->method = (Byte)method; 1479 1480 return deflateReset(strm); 1481 } 1482 1483 local int inflateInit2(z, w) 1484 z_stream *z; 1485 int w; 1486 { 1487 /* initialize state */ 1488 if (z == Z_NULL) { 1489 return Z_STREAM_ERROR; 1490 } 1491 if (z->zalloc == Z_NULL) { 1492 z->zalloc = zcalloc; 1493 } 1494 if (z->zfree == Z_NULL) { 1495 z->zfree = zcfree; 1496 } 1497 z->total_in = z->total_out = 0; 1498 z->msg = Z_NULL; 1499 if ((z->state = (struct internal_state *) 1500 ZALLOC(z, 1, sizeof(struct internal_state))) == Z_NULL) { 1501 return Z_MEM_ERROR; 1502 } 1503 z->state->mode = METHOD; 1504 1505 /* handle undocumented nowrap option (no zlib header or check) */ 1506 z->state->nowrap = 0; 1507 if (w < 0) { 1508 w = - w; 1509 z->state->nowrap = 1; 1510 z->state->mode = START; 1511 } 1512 1513 /* set window size */ 1514 if (w < 8 || w > 15) { // 8:window size, 15:window size 1515 inflateEnd(z); 1516 return Z_STREAM_ERROR; 1517 } 1518 z->state->wbits = w; 1519 return Z_OK; 1520 } 1521 1522 local void putShortMSB (s, b) 1523 deflate_state *s; 1524 uInt b; 1525 { 1526 put_byte(s, (Byte)(b >> 8)); // 8:byte alignment 1527 put_byte(s, (Byte)(b & 0xff)); 1528 } 1529 1530 local void flush_pending(strm) 1531 z_stream *strm; 1532 { 1533 unsigned len = strm->state->pending; 1534 1535 if (len > strm->avail_out) { 1536 len = strm->avail_out; 1537 } 1538 if (len == 0) { 1539 return; 1540 } 1541 1542 zmemcpy(strm->next_out, strm->state->pending_out, len); 1543 strm->next_out += len; 1544 strm->state->pending_out += len; 1545 strm->total_out += len; 1546 strm->avail_out -= len; 1547 strm->state->pending -= len; 1548 if (strm->state->pending == 0) { 1549 strm->state->pending_out = strm->state->pending_buf; 1550 } 1551 } 1552 1553 local void fill_window(s) 1554 deflate_state *s; 1555 { 1556 register unsigned n, m; 1557 unsigned more; /* Amount of free space at the end of the window. */ 1558 1559 do { 1560 more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); 1561 1562 /* Deal with !@#$% 64K limit: */ 1563 if (more == 0 && s->strstart == 0 && s->lookahead == 0) { 1564 more = s->w_size; 1565 } else if (more == (unsigned)(-1)) { 1566 /* Very unlikely, but possible on 16 bit machine if strstart == 0 1567 * and lookahead == 1 (input done one byte at time) 1568 */ 1569 more--; 1570 1571 /* If the window is almost full and there is insufficient lookahead, 1572 * move the upper half to the lower one to make room in the upper half. 1573 */ 1574 } else if (s->strstart >= s->w_size+MAX_DIST(s)) { 1575 /* By the IN assertion, the window is not empty so we can't confuse 1576 * more == 0 with more == 64K on a 16 bit machine. 1577 */ 1578 memcpy((char*)s->window, (char*)s->window+s->w_size, 1579 (unsigned)s->w_size); 1580 s->match_start -= s->w_size; 1581 s->strstart -= s->w_size; /* we now have strstart >= MAX_DIST */ 1582 1583 s->block_start -= (long) s->w_size; 1584 1585 for (n = 0; n < s->hash_size; n++) { 1586 m = s->head[n]; 1587 s->head[n] = (Pos)(m >= s->w_size ? m-s->w_size : NIL); 1588 } 1589 for (n = 0; n < s->w_size; n++) { 1590 m = s->prev[n]; 1591 s->prev[n] = (Pos)(m >= s->w_size ? m-s->w_size : NIL); 1592 /* If n is not on any hash chain, prev[n] is garbage but 1593 * its value will never be used. 1594 */ 1595 } 1596 more += s->w_size; 1597 } 1598 if (s->strm->avail_in == 0) { 1599 return; 1600 } 1601 1602 /* If there was no sliding: 1603 * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && 1604 * more == window_size - lookahead - strstart 1605 * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) 1606 * => more >= window_size - 2*WSIZE + 2 1607 * In the BIG_MEM or MMAP case (not yet supported), 1608 * window_size == input_size + MIN_LOOKAHEAD && 1609 * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. 1610 * Otherwise, window_size == 2*WSIZE so more >= 2. 1611 * If there was sliding, more >= WSIZE. So in all cases, more >= 2. 1612 */ 1613 Assert(more >= 2, "more < 2"); // 2:byte alignment 1614 1615 n = read_buf(s->strm, (char*)s->window + s->strstart + s->lookahead, 1616 more); 1617 s->lookahead += n; 1618 } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); 1619 } 1620 1621 /* For 80x86 and 680x0, an optimized version will be provided in match.asm or 1622 * match.S. The code will be functionally equivalent. 1623 */ 1624 local int longest_match(s, cur_match) 1625 deflate_state *s; 1626 IPos cur_match; /* current match */ 1627 { 1628 unsigned chain_length = s->max_chain_length; /* max hash chain length */ 1629 register Byte *scan = s->window + s->strstart; /* current string */ 1630 register Byte *match; /* matched string */ 1631 register int len; /* length of current match */ 1632 int best_len = s->prev_length; /* best match length so far */ 1633 IPos limit = s->strstart > (IPos)MAX_DIST(s) ? 1634 s->strstart - (IPos)MAX_DIST(s) : NIL; 1635 /* Stop when cur_match becomes <= limit. To simplify the code, 1636 * we prevent matches with the string of window index 0. 1637 */ 1638 1639 #ifdef UNALIGNED_OK 1640 /* Compare two bytes at a time. Note: this is not always beneficial. 1641 * Try with and without -DUNALIGNED_OK to check. 1642 */ 1643 register Byte *strend = s->window + s->strstart + MAX_MATCH - 1; 1644 register ush scan_start = *(ush*)scan; 1645 register ush scan_end = *(ush*)(scan + best_len-1); 1646 #else 1647 register Byte *strend = s->window + s->strstart + MAX_MATCH; 1648 register Byte scan_end1 = scan[best_len - 1]; 1649 register Byte scan_end = scan[best_len]; 1650 #endif 1651 1652 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. 1653 * It is easy to get rid of this optimization if necessary. 1654 */ 1655 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); 1656 1657 /* Do not waste too much time if we already have a good match: */ 1658 if (s->prev_length >= s->good_match) { 1659 chain_length >>= 2; // 2:byte alignment 1660 } 1661 Assert(s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); 1662 1663 do { 1664 Assert(cur_match < s->strstart, "no future"); 1665 match = s->window + cur_match; 1666 1667 /* Skip to next match if the match length cannot increase 1668 * or if the match length is less than 2: 1669 */ 1670 #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) // 258:byte alignment 1671 /* This code assumes sizeof(unsigned short) == 2. Do not use 1672 * UNALIGNED_OK if your compiler uses a different size. 1673 */ 1674 if (*(ush*)(match+best_len - 1) != scan_end || 1675 *(ush*)match != scan_start) continue; 1676 1677 /* It is not necessary to compare scan[2] and match[2] since they are 1678 * always equal when the other bytes match, given that the hash keys 1679 * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at 1680 * strstart+3, +5, ... up to strstart+257. We check for insufficient 1681 * lookahead only every 4th comparison; the 128th check will be made 1682 * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is 1683 * necessary to put more guard bytes at the end of the window, or 1684 * to check more often for insufficient lookahead. 1685 */ 1686 scan++, match++; 1687 do { 1688 } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && // 2:byte alignment 1689 *(ush*)(scan+=2) == *(ush*)(match+=2) && // 2:byte alignment 1690 *(ush*)(scan+=2) == *(ush*)(match+=2) && // 2:byte alignment 1691 *(ush*)(scan+=2) == *(ush*)(match+=2) && // 2:byte alignment 1692 scan < strend); 1693 /* The funny "do {}" generates better code on most compilers */ 1694 1695 /* Here, scan <= window+strstart+257 */ 1696 Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); 1697 if (*scan == *match) scan++; 1698 1699 len = (MAX_MATCH - 1) - (int)(strend-scan); 1700 scan = strend - (MAX_MATCH-1); 1701 1702 #else /* UNALIGNED_OK */ 1703 1704 if (match[best_len] != scan_end || 1705 match[best_len-1] != scan_end1 || 1706 *match != *scan || 1707 *++match != scan[1]) { 1708 continue; 1709 } 1710 1711 /* The check at best_len-1 can be removed because it will be made 1712 * again later. (This heuristic is not always a win.) 1713 * It is not necessary to compare scan[2] and match[2] since they 1714 * are always equal when the other bytes match, given that 1715 * the hash keys are equal and that HASH_BITS >= 8. 1716 */ 1717 scan += 2, match++; // 2:byte alignment 1718 1719 /* We check for insufficient lookahead only every 8th comparison; 1720 * the 256th check will be made at strstart+258. 1721 */ 1722 do { 1723 } while (*++scan == *++match && *++scan == *++match && 1724 *++scan == *++match && *++scan == *++match && 1725 *++scan == *++match && *++scan == *++match && 1726 *++scan == *++match && *++scan == *++match && 1727 scan < strend); 1728 1729 Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); 1730 1731 len = MAX_MATCH - (int)(strend - scan); 1732 scan = strend - MAX_MATCH; 1733 1734 #endif /* UNALIGNED_OK */ 1735 1736 if (len > best_len) { 1737 s->match_start = cur_match; 1738 best_len = len; 1739 if (len >= s->nice_match) { 1740 break; 1741 } 1742 #ifdef UNALIGNED_OK 1743 scan_end = *(ush*)(scan+best_len-1); 1744 #else 1745 scan_end1 = scan[best_len-1]; 1746 scan_end = scan[best_len]; 1747 #endif 1748 } 1749 } while ((cur_match = s->prev[cur_match & s->w_mask]) > limit 1750 && --chain_length != 0); 1751 1752 return best_len; 1753 } 1754 1755 local int ct_tally (s, dist, lc) 1756 deflate_state *s; 1757 int dist; /* distance of matched string */ 1758 int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ 1759 { 1760 s->d_buf[s->last_lit] = (ush)dist; 1761 s->l_buf[s->last_lit++] = (uch)lc; 1762 if (dist == 0) { 1763 /* lc is the unmatched char */ 1764 s->dyn_ltree[lc].Freq++; 1765 } else { 1766 s->matches++; 1767 /* Here, lc is the match length - MIN_MATCH */ 1768 dist--; /* dist = match distance - 1 */ 1769 Assert((ush)dist < (ush)MAX_DIST(s) && 1770 (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && 1771 (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); 1772 1773 s->dyn_ltree[length_code[lc] + LITERALS + 1].Freq++; 1774 s->dyn_dtree[d_code(dist)].Freq++; 1775 } 1776 1777 /* Try to guess if it is profitable to stop the current block here */ 1778 if (s->level > 2 && (s->last_lit & 0xfff) == 0) { // 2:byte alignment 1779 /* Compute an upper bound for the compressed length */ 1780 ulg out_length = (ulg)s->last_lit * 8L; 1781 ulg in_length = (ulg)s->strstart - s->block_start; 1782 int dcode; 1783 for (dcode = 0; dcode < D_CODES; dcode++) { 1784 out_length += (ulg)s->dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]); 1785 } 1786 out_length >>= 3; // 3:byte alignment 1787 1788 if (s->matches < s->last_lit / 2 && out_length < in_length / 2) { // 2:byte alignment 1789 return 1; 1790 } 1791 } 1792 return (s->last_lit == s->lit_bufsize - 1); 1793 /* We avoid equality with lit_bufsize because of wraparound at 64K 1794 * on 16 bit machines and because stored fblocks are restricted to 1795 * 64K-1 bytes. 1796 */ 1797 } 1798 1799 local void set_data_type(s) 1800 deflate_state *s; 1801 { 1802 int n = 0; 1803 unsigned ascii_freq = 0; 1804 unsigned bin_freq = 0; 1805 while (n < 7) { // 7:byte alignment 1806 bin_freq += s->dyn_ltree[n++].Freq; 1807 } 1808 while (n < 128) { // 128:byte alignment 1809 ascii_freq += s->dyn_ltree[n++].Freq; 1810 } 1811 while (n < LITERALS) { 1812 bin_freq += s->dyn_ltree[n++].Freq; 1813 } 1814 s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII); // 2:byte alignment 1815 } 1816 1817 local void pqdownheap(s, tree, k) 1818 deflate_state *s; 1819 ct_data *tree; /* the tree to restore */ 1820 int k; /* node to move down */ 1821 { 1822 int v = s->heap[k]; 1823 int j = k << 1; /* left son of k */ 1824 while (j <= s->heap_len) { 1825 /* Set j to the smallest of the two sons: */ 1826 if (j < s->heap_len && 1827 smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { 1828 j++; 1829 } 1830 /* Exit if v is smaller than both sons */ 1831 if (smaller(tree, v, s->heap[j], s->depth)) { 1832 break; 1833 } 1834 1835 /* Exchange v with the smallest son */ 1836 s->heap[k] = s->heap[j]; 1837 k = j; 1838 1839 /* And continue down the tree, setting j to the left son of k */ 1840 j <<= 1; 1841 } 1842 s->heap[k] = v; 1843 } 1844 1845 local void gen_bitlen(s, desc) 1846 deflate_state *s; 1847 tree_desc *desc; /* the tree descriptor */ 1848 { 1849 ct_data *tree = desc->dyn_tree; 1850 int max_code = desc->max_code; 1851 ct_data *stree = desc->stat_desc->static_tree; 1852 int *extra = desc->stat_desc->extra_bits; 1853 int base = desc->stat_desc->extra_base; 1854 int max_length = desc->stat_desc->max_length; 1855 int h; /* heap index */ 1856 int n, m; /* iterate over the tree elements */ 1857 int bits; /* bit length */ 1858 int xbits; /* extra bits */ 1859 ush f; /* frequency */ 1860 int overflow = 0; /* number of elements with bit length too large */ 1861 1862 for (bits = 0; bits <= MAX_BITS; bits++) { 1863 s->bl_count[bits] = 0; 1864 } 1865 1866 /* In a first pass, compute the optimal bit lengths (which may 1867 * overflow in the case of the bit length tree). 1868 */ 1869 tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ 1870 1871 for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { 1872 n = s->heap[h]; 1873 bits = tree[tree[n].Dad].Len + 1; 1874 if (bits > max_length) { 1875 bits = max_length, overflow++; 1876 } 1877 tree[n].Len = (ush)bits; 1878 /* We overwrite tree[n].Dad which is no longer needed */ 1879 1880 if (n > max_code) { 1881 continue; /* not a leaf node */ 1882 } 1883 1884 s->bl_count[bits]++; 1885 xbits = 0; 1886 if (n >= base) { 1887 xbits = extra[n - base]; 1888 } 1889 f = tree[n].Freq; 1890 s->opt_len += (ulg)f * (bits + xbits); 1891 if (stree) { 1892 s->static_len += (ulg)f * (stree[n].Len + xbits); 1893 } 1894 } 1895 if (overflow == 0) { 1896 return; 1897 } 1898 1899 /* This happens for example on obj2 and pic of the Calgary corpus */ 1900 1901 /* Find the first bit length which could increase: */ 1902 do { 1903 bits = max_length-1; 1904 while (s->bl_count[bits] == 0) { 1905 bits--; 1906 } 1907 s->bl_count[bits]--; /* move one leaf down the tree */ 1908 s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ // 2:byte alignment 1909 s->bl_count[max_length]--; 1910 /* The brother of the overflow item also moves one step up, 1911 * but this does not affect bl_count[max_length] 1912 */ 1913 overflow -= 2; // 2:byte alignment 1914 } while (overflow > 0); 1915 1916 /* Now recompute all bit lengths, scanning in increasing frequency. 1917 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all 1918 * lengths instead of fixing only the wrong ones. This idea is taken 1919 * from 'ar' written by Haruhiko Okumura.) 1920 */ 1921 for (bits = max_length; bits != 0; bits--) { 1922 n = s->bl_count[bits]; 1923 while (n != 0) { 1924 m = s->heap[--h]; 1925 if (m > max_code) { 1926 continue; 1927 } 1928 if (tree[m].Len != (unsigned) bits) { 1929 s->opt_len += ((long)bits - (long)tree[m].Len) 1930 *(long)tree[m].Freq; 1931 tree[m].Len = (ush)bits; 1932 } 1933 n--; 1934 } 1935 } 1936 } 1937 1938 local void build_tree(s, desc) 1939 deflate_state *s; 1940 tree_desc *desc; /* the tree descriptor */ 1941 { 1942 ct_data *tree = desc->dyn_tree; 1943 ct_data *stree = desc->stat_desc->static_tree; 1944 int elems = desc->stat_desc->elems; 1945 int n, m; /* iterate over heap elements */ 1946 int max_code = -1; /* largest code with non zero frequency */ 1947 int node = elems; /* next internal node of the tree */ 1948 int new; /* new node being created */ 1949 1950 /* Construct the initial heap, with least frequent element in 1951 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. 1952 * heap[0] is not used. 1953 */ 1954 s->heap_len = 0, s->heap_max = HEAP_SIZE; 1955 1956 for (n = 0; n < elems; n++) { 1957 if (tree[n].Freq != 0) { 1958 s->heap[++(s->heap_len)] = max_code = n; 1959 s->depth[n] = 0; 1960 } else { 1961 tree[n].Len = 0; 1962 } 1963 } 1964 1965 /* The pkzip format requires that at least one distance code exists, 1966 * and that at least one bit should be sent even if there is only one 1967 * possible code. So to avoid special checks later on we force at least 1968 * two codes of non zero frequency. 1969 */ 1970 while (s->heap_len < 2) { // 2:byte alignment 1971 new = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); // 2:byte alignment 1972 tree[new].Freq = 1; 1973 s->depth[new] = 0; 1974 s->opt_len--; 1975 if (stree) { 1976 s->static_len -= stree[new].Len; 1977 } 1978 /* new is 0 or 1 so it does not have extra bits */ 1979 } 1980 desc->max_code = max_code; 1981 1982 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, 1983 * establish sub-heaps of increasing lengths: 1984 */ 1985 for (n = s->heap_len / 2; n >= 1; n--) { // 2:byte alignment 1986 pqdownheap(s, tree, n); 1987 } 1988 1989 /* Construct the Huffman tree by repeatedly combining the least two 1990 * frequent nodes. 1991 */ 1992 do { 1993 pqremove(s, tree, n); /* n = node of least frequency */ 1994 m = s->heap[SMALLEST]; /* m = node of next least frequency */ 1995 1996 s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ 1997 s->heap[--(s->heap_max)] = m; 1998 1999 /* Create a new node father of n and m */ 2000 tree[node].Freq = tree[n].Freq + tree[m].Freq; 2001 s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); 2002 tree[n].Dad = tree[m].Dad = (ush)node; 2003 #ifdef DUMP_BL_TREE 2004 if (tree == s->bl_tree) { 2005 fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", 2006 node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); 2007 } 2008 #endif 2009 /* and insert the new node in the heap */ 2010 s->heap[SMALLEST] = node++; 2011 pqdownheap(s, tree, SMALLEST); 2012 } while (s->heap_len >= 2); // 2:byte alignment 2013 2014 s->heap[--(s->heap_max)] = s->heap[SMALLEST]; 2015 2016 /* At this point, the fields freq and dad are set. We can now 2017 * generate the bit lengths. 2018 */ 2019 gen_bitlen(s, (tree_desc *)desc); 2020 2021 /* The field len is now set, we can generate the bit codes */ 2022 gen_codes ((ct_data *)tree, max_code, s->bl_count); 2023 } 2024 2025 local void scan_tree (s, tree, max_code) 2026 deflate_state *s; 2027 ct_data *tree; /* the tree to be scanned */ 2028 int max_code; /* and its largest code of non zero frequency */ 2029 { 2030 int n; /* iterates over all tree elements */ 2031 int prevlen = -1; /* last emitted length */ 2032 int curlen; /* length of current code */ 2033 int nextlen = tree[0].Len; /* length of next code */ 2034 int count = 0; /* repeat count of the current code */ 2035 int max_count = 7; /* max repeat count */ 2036 int min_count = 4; /* min repeat count */ 2037 2038 if (nextlen == 0) { 2039 max_count = 138, min_count = 3; // 3:byte alignment, 138:byte alignment 2040 } 2041 tree[max_code + 1].Len = (ush)0xffff; /* guard */ 2042 2043 for (n = 0; n <= max_code; n++) { 2044 curlen = nextlen; 2045 nextlen = tree[n+1].Len; 2046 if (++count < max_count && curlen == nextlen) { 2047 continue; 2048 } else if (count < min_count) { 2049 s->bl_tree[curlen].Freq += count; 2050 } else if (curlen != 0) { 2051 if (curlen != prevlen) { 2052 s->bl_tree[curlen].Freq++; 2053 } 2054 s->bl_tree[REP_3_6].Freq++; 2055 } else if (count <= 10) { // 10:byte alignment 2056 s->bl_tree[REPZ_3_10].Freq++; 2057 } else { 2058 s->bl_tree[REPZ_11_138].Freq++; 2059 } 2060 count = 0; 2061 prevlen = curlen; 2062 if (nextlen == 0) { 2063 max_count = 138, min_count = 3; // 3:byte alignment, 138:byte alignment 2064 } else if (curlen == nextlen) { 2065 max_count = 6, min_count = 3; // 3:byte alignment, 6:byte alignment 2066 } else { 2067 max_count = 7, min_count = 4; // 7:byte alignment, 4:byte alignment 2068 } 2069 } 2070 } 2071 2072 local int build_bl_tree(s) 2073 deflate_state *s; 2074 { 2075 int max_blindex; /* index of last bit length code of non zero freq */ 2076 2077 /* Determine the bit length frequencies for literal and distance trees */ 2078 scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); 2079 scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); 2080 2081 /* Build the bit length tree: */ 2082 build_tree(s, (tree_desc *)(&(s->bl_desc))); 2083 /* opt_len now includes the length of the tree representations, except 2084 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. 2085 */ 2086 2087 /* Determine the number of bit length codes to send. The pkzip format 2088 * requires that at least 4 bit length codes be sent. (appnote.txt says 2089 * 3 but the actual value used is 4.) 2090 */ 2091 for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { // 3:byte alignment 2092 if (s->bl_tree[bl_order[max_blindex]].Len != 0) { 2093 break; 2094 } 2095 } 2096 /* Update opt_len to include the bit length tree and counts */ 2097 s->opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; // 3:byte alignment, 4:byte alignment, 5:byte alignment 2098 2099 return max_blindex; 2100 } 2101 2102 local void send_bits(s, value, length) 2103 deflate_state *s; 2104 int value; /* value to send */ 2105 int length; /* number of bits */ 2106 { 2107 #ifdef DEBUG 2108 Assert(length > 0 && length <= 15, "invalid length"); // 15:byte alignment 2109 s->bits_sent += (ulg)length; 2110 #endif 2111 /* If not enough room in bi_buf, use (valid) bits from bi_buf and 2112 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) 2113 * unused bits in value. 2114 */ 2115 if (s->bi_valid > (int)Buf_size - length) { 2116 s->bi_buf |= (value << s->bi_valid); 2117 put_short(s, s->bi_buf); 2118 s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); 2119 s->bi_valid += length - Buf_size; 2120 } else { 2121 s->bi_buf |= value << s->bi_valid; 2122 s->bi_valid += length; 2123 } 2124 } 2125 2126 local void bi_windup(s) 2127 deflate_state *s; 2128 { 2129 if (s->bi_valid > 8) { // 8:byte alignment 2130 put_short(s, s->bi_buf); 2131 } else if (s->bi_valid > 0) { 2132 put_byte(s, (Byte)s->bi_buf); 2133 } 2134 s->bi_buf = 0; 2135 s->bi_valid = 0; 2136 #ifdef DEBUG 2137 s->bits_sent = (s->bits_sent + 7) & ~7; // 7:byte alignment 2138 #endif 2139 } 2140 2141 local void copy_block(s, buf, len, header) 2142 deflate_state *s; 2143 char *buf; /* the input data */ 2144 unsigned len; /* its length */ 2145 int header; /* true if block header must be written */ 2146 { 2147 bi_windup(s); /* align on byte boundary */ 2148 2149 if (header) { 2150 put_short(s, (ush)len); 2151 put_short(s, (ush)~len); 2152 #ifdef DEBUG 2153 s->bits_sent += 2 * 16; // 2:byte alignment, 16:byte alignment 2154 #endif 2155 } 2156 #ifdef DEBUG 2157 s->bits_sent += (ulg)len << 3; // 3:byte alignment 2158 #endif 2159 while (len--) { 2160 put_byte(s, *buf++); 2161 } 2162 } 2163 2164 local void compress_block(s, ltree, dtree) 2165 deflate_state *s; 2166 ct_data *ltree; /* literal tree */ 2167 ct_data *dtree; /* distance tree */ 2168 { 2169 unsigned dist; /* distance of matched string */ 2170 int lc; /* match length or unmatched char (if dist == 0) */ 2171 unsigned lx = 0; /* running index in l_buf */ 2172 unsigned code; /* the code to send */ 2173 int extra; /* number of extra bits to send */ 2174 2175 if (s->last_lit != 0) { 2176 do { 2177 dist = s->d_buf[lx]; 2178 lc = s->l_buf[lx++]; 2179 if (dist == 0) { 2180 send_code(s, lc, ltree); /* send a literal byte */ 2181 } else { 2182 /* Here, lc is the match length - MIN_MATCH */ 2183 code = length_code[lc]; 2184 send_code(s, code+LITERALS + 1, ltree); /* send the length code */ 2185 extra = extra_lbits[code]; 2186 if (extra != 0) { 2187 lc -= base_length[code]; 2188 send_bits(s, lc, extra); /* send the extra length bits */ 2189 } 2190 dist--; /* dist is now the match distance - 1 */ 2191 code = d_code(dist); 2192 Assert (code < D_CODES, "bad d_code"); 2193 2194 send_code(s, code, dtree); /* send the distance code */ 2195 extra = extra_dbits[code]; 2196 if (extra != 0) { 2197 dist -= base_dist[code]; 2198 send_bits(s, dist, extra); /* send the extra distance bits */ 2199 } 2200 } /* literal or match pair ? */ 2201 2202 /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ 2203 Assert(s->pending < s->lit_bufsize + 2 * lx, "pendingBuf overflow"); 2204 } while (lx < s->last_lit); 2205 } 2206 send_code(s, END_BLOCK, ltree); 2207 } 2208 2209 local void send_tree (s, tree, max_code) 2210 deflate_state *s; 2211 ct_data *tree; /* the tree to be scanned */ 2212 int max_code; /* and its largest code of non zero frequency */ 2213 { 2214 int n; /* iterates over all tree elements */ 2215 int prevlen = -1; /* last emitted length */ 2216 int curlen; /* length of current code */ 2217 int nextlen = tree[0].Len; /* length of next code */ 2218 int count = 0; /* repeat count of the current code */ 2219 int max_count = 7; /* max repeat count */ 2220 int min_count = 4; /* min repeat count */ 2221 2222 if (nextlen == 0) { 2223 max_count = 138, min_count = 3; // 138:byte alignment, 3:byte alignment 2224 } 2225 2226 for (n = 0; n <= max_code; n++) { 2227 curlen = nextlen; 2228 nextlen = tree[n + 1].Len; 2229 if (++count < max_count && curlen == nextlen) { 2230 continue; 2231 } else if (count < min_count) { 2232 do { 2233 send_code(s, curlen, s->bl_tree); 2234 } while (--count != 0); 2235 } else if (curlen != 0) { 2236 if (curlen != prevlen) { 2237 send_code(s, curlen, s->bl_tree); 2238 count--; 2239 } 2240 Assert(count >= 3 && count <= 6, " 3_6?"); // 3:byte alignment, 6:byte alignment 2241 send_code(s, REP_3_6, s->bl_tree); 2242 send_bits(s, count - 3, 2); // 3:byte alignment, 2:byte alignment 2243 } else if (count <= 10) { // 10:byte alignment 2244 send_code(s, REPZ_3_10, s->bl_tree); 2245 send_bits(s, count - 3, 3); // 3:byte alignment 2246 } else { 2247 send_code(s, REPZ_11_138, s->bl_tree); 2248 send_bits(s, count - 11, 7); // 11:byte alignment, 7:byte alignment 2249 } 2250 count = 0; 2251 prevlen = curlen; 2252 if (nextlen == 0) { 2253 max_count = 138, min_count = 3; // 138:byte alignment, 3:byte alignment 2254 } else if (curlen == nextlen) { 2255 max_count = 6, min_count = 3; // 6:byte alignment, 3:byte alignment 2256 } else { 2257 max_count = 7, min_count = 4; // 7:byte alignment, 4:byte alignment 2258 } 2259 } 2260 } 2261 2262 local void send_all_trees(s, lcodes, dcodes, blcodes) 2263 deflate_state *s; 2264 int lcodes, dcodes, blcodes; /* number of codes for each tree */ 2265 { 2266 int rank; /* index in bl_order */ 2267 2268 Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); // 257:byte alignment, 4:byte alignment 2269 Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, 2270 "too many codes"); 2271 send_bits(s, lcodes - 257, 5); // 257:byte alignment, 5:byte alignment 2272 send_bits(s, dcodes-1, 5); // 5:byte alignment 2273 send_bits(s, blcodes - 4, 4); // 4:byte alignment 2274 for (rank = 0; rank < blcodes; rank++) { 2275 send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); // 3:byte alignment 2276 } 2277 2278 send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ 2279 2280 send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ 2281 } 2282 2283 ulg ct_flush_block(s, buf, stored_len, eof) 2284 deflate_state *s; 2285 char *buf; /* input block, or NULL if too old */ 2286 ulg stored_len; /* length of input block */ 2287 int eof; /* true if this is the last block for a file */ 2288 { 2289 ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ 2290 int max_blindex; /* index of last bit length code of non zero freq */ 2291 2292 /* Check if the file is ascii or binary */ 2293 if (s->data_type == UNKNOWN) { 2294 set_data_type(s); 2295 } 2296 2297 /* Construct the literal and distance trees */ 2298 build_tree(s, (tree_desc *)(&(s->l_desc))); 2299 2300 build_tree(s, (tree_desc *)(&(s->d_desc))); 2301 2302 /* At this point, opt_len and static_len are the total bit lengths of 2303 * the compressed block data, excluding the tree representations. 2304 */ 2305 2306 /* Build the bit length tree for the above two trees, and get the index 2307 * in bl_order of the last bit length code to send. 2308 */ 2309 max_blindex = build_bl_tree(s); 2310 2311 /* Determine the best encoding. Compute first the block length in bytes */ 2312 opt_lenb = (s->opt_len + 3 + 7) >> 3; // 7:byte alignment, 3:byte alignment 2313 static_lenb = (s->static_len + 3 + 7) >> 3; // 3:byte alignment, 7:byte alignment 2314 2315 if (static_lenb <= opt_lenb) { 2316 opt_lenb = static_lenb; 2317 } 2318 2319 /* If compression failed and this is the first and last block, 2320 * and if the .zip file can be seeked (to rewrite the local header), 2321 * the whole file is transformed into a stored file: 2322 */ 2323 2324 if (stored_len+4 <= opt_lenb && buf != (char*)0) { 2325 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. 2326 * Otherwise we can't have processed more than WSIZE input bytes since 2327 * the last block flush, because compression would have been 2328 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to 2329 * transform a block into a stored block. 2330 */ 2331 send_bits(s, (STORED_BLOCK << 1) + eof, 3); // 3:byte alignment /* send block type */ 2332 s->compressed_len = (s->compressed_len + 3 + 7) & ~7L; // 7:byte alignment, 3:byte alignment 2333 s->compressed_len += (stored_len + 4) << 3; // 3:byte alignment, 4:byte alignment 2334 2335 copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ 2336 } else if (static_lenb == opt_lenb) { 2337 send_bits(s, (STATIC_TREES << 1) + eof, 3); // 3:byte alignment 2338 compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); 2339 s->compressed_len += 3 + s->static_len; // 3:byte alignment 2340 } else { 2341 send_bits(s, (DYN_TREES << 1) + eof, 3); // 3:byte alignment 2342 send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code + 1, 2343 max_blindex+1); 2344 compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); 2345 s->compressed_len += 3 + s->opt_len; // 3:byte alignment 2346 } 2347 Assert (s->compressed_len == s->bits_sent, "bad compressed size"); 2348 init_block(s); 2349 2350 if (eof) { 2351 bi_windup(s); 2352 s->compressed_len += 7; /* align on byte boundary */ 2353 } 2354 2355 return s->compressed_len >> 3; // 3:byte alignment 2356 } 2357 2358 local int deflate_fast(s, flush) 2359 deflate_state *s; 2360 int flush; 2361 { 2362 IPos hash_head; /* head of the hash chain */ 2363 int bflush; /* set if current block must be flushed */ 2364 2365 s->prev_length = MIN_MATCH - 1; 2366 2367 for (;;) { 2368 /* Make sure that we always have enough lookahead, except 2369 * at the end of the input file. We need MAX_MATCH bytes 2370 * for the next match, plus MIN_MATCH bytes to insert the 2371 * string following the next match. 2372 */ 2373 if (s->lookahead < MIN_LOOKAHEAD) { 2374 fill_window(s); 2375 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { 2376 return 1; 2377 } 2378 2379 if (s->lookahead == 0) { 2380 break; /* flush the current block */ 2381 } 2382 } 2383 2384 /* Insert the string window[strstart .. strstart+2] in the 2385 * dictionary, and set hash_head to the head of the hash chain: 2386 */ 2387 INSERT_STRING(s, s->strstart, hash_head); 2388 2389 /* Find the longest match, discarding those <= prev_length. 2390 * At this point we have always match_length < MIN_MATCH 2391 */ 2392 if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { 2393 /* To simplify the code, we prevent matches with the string 2394 * of window index 0 (in particular we have to avoid a match 2395 * of the string with itself at the start of the input file). 2396 */ 2397 if (s->strategy != Z_HUFFMAN_ONLY) { 2398 s->match_length = longest_match(s, hash_head); 2399 } 2400 /* longest_match() sets match_start */ 2401 2402 if (s->match_length > s->lookahead) { 2403 s->match_length = s->lookahead; 2404 } 2405 } 2406 if (s->match_length >= MIN_MATCH) { 2407 check_match(s, s->strstart, s->match_start, s->match_length); 2408 2409 bflush = ct_tally(s, s->strstart - s->match_start, 2410 s->match_length - MIN_MATCH); 2411 2412 s->lookahead -= s->match_length; 2413 2414 /* Insert new strings in the hash table only if the match length 2415 * is not too large. This saves time but degrades compression. 2416 */ 2417 if (s->match_length <= s->max_insert_length) { 2418 s->match_length--; /* string at strstart already in hash table */ 2419 do { 2420 s->strstart++; 2421 INSERT_STRING(s, s->strstart, hash_head); 2422 /* strstart never exceeds WSIZE-MAX_MATCH, so there are 2423 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH 2424 * these bytes are garbage, but it does not matter since 2425 * the next lookahead bytes will be emitted as literals. 2426 */ 2427 } while (--s->match_length != 0); 2428 s->strstart++; 2429 } else { 2430 s->strstart += s->match_length; 2431 s->match_length = 0; 2432 s->ins_h = s->window[s->strstart]; 2433 UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); 2434 #if MIN_MATCH != 3 2435 Call UPDATE_HASH() MIN_MATCH-3 more times 2436 #endif 2437 } 2438 } else { 2439 /* No match, output a literal byte */ 2440 bflush = ct_tally (s, 0, s->window[s->strstart]); 2441 s->lookahead--; 2442 s->strstart++; 2443 } 2444 if (bflush) { 2445 FLUSH_BLOCK(s, 0); 2446 } 2447 } 2448 FLUSH_BLOCK(s, flush == Z_FINISH); 2449 return 0; /* normal exit */ 2450 } 2451 2452 local int deflate_slow(s, flush) 2453 deflate_state *s; 2454 int flush; 2455 { 2456 IPos hash_head; /* head of hash chain */ 2457 int bflush; /* set if current block must be flushed */ 2458 2459 /* Process the input block. */ 2460 for (;;) { 2461 /* Make sure that we always have enough lookahead, except 2462 * at the end of the input file. We need MAX_MATCH bytes 2463 * for the next match, plus MIN_MATCH bytes to insert the 2464 * string following the next match. 2465 */ 2466 if (s->lookahead < MIN_LOOKAHEAD) { 2467 fill_window(s); 2468 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { 2469 return 1; 2470 } 2471 2472 if (s->lookahead == 0) { 2473 break; /* flush the current block */ 2474 } 2475 } 2476 2477 /* Insert the string window[strstart .. strstart+2] in the 2478 * dictionary, and set hash_head to the head of the hash chain: 2479 */ 2480 INSERT_STRING(s, s->strstart, hash_head); 2481 2482 /* Find the longest match, discarding those <= prev_length. 2483 */ 2484 s->prev_length = s->match_length, s->prev_match = s->match_start; 2485 s->match_length = MIN_MATCH-1; 2486 2487 if (hash_head != NIL && s->prev_length < s->max_lazy_match && 2488 s->strstart - hash_head <= MAX_DIST(s)) { 2489 /* To simplify the code, we prevent matches with the string 2490 * of window index 0 (in particular we have to avoid a match 2491 * of the string with itself at the start of the input file). 2492 */ 2493 if (s->strategy != Z_HUFFMAN_ONLY) { 2494 s->match_length = longest_match (s, hash_head); 2495 } 2496 /* longest_match() sets match_start */ 2497 if (s->match_length > s->lookahead) { 2498 s->match_length = s->lookahead; 2499 } 2500 2501 if (s->match_length <= 5 && (s->strategy == Z_FILTERED || // 5:byte alignment 2502 (s->match_length == MIN_MATCH && 2503 s->strstart - s->match_start > TOO_FAR))) { 2504 /* If prev_match is also MIN_MATCH, match_start is garbage 2505 * but we will ignore the current match anyway. 2506 */ 2507 s->match_length = MIN_MATCH - 1; 2508 } 2509 } 2510 /* If there was a match at the previous step and the current 2511 * match is not better, output the previous match: 2512 */ 2513 if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { 2514 check_match(s, s->strstart - 1, s->prev_match, s->prev_length); 2515 2516 bflush = ct_tally(s, s->strstart -1 - s->prev_match, 2517 s->prev_length - MIN_MATCH); 2518 2519 /* Insert in hash table all strings up to the end of the match. 2520 * strstart-1 and strstart are already inserted. 2521 */ 2522 s->lookahead -= s->prev_length - 1; 2523 s->prev_length -= 2; 2524 do { 2525 s->strstart++; 2526 INSERT_STRING(s, s->strstart, hash_head); 2527 /* strstart never exceeds WSIZE-MAX_MATCH, so there are 2528 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH 2529 * these bytes are garbage, but it does not matter since the 2530 * next lookahead bytes will always be emitted as literals. 2531 */ 2532 } while (--s->prev_length != 0); 2533 s->match_available = 0; 2534 s->match_length = MIN_MATCH - 1; 2535 s->strstart++; 2536 2537 if (bflush) { 2538 FLUSH_BLOCK(s, 0); 2539 } 2540 } else if (s->match_available) { 2541 /* If there was no match at the previous position, output a 2542 * single literal. If there was a match but the current match 2543 * is longer, truncate the previous match to a single literal. 2544 */ 2545 if (ct_tally (s, 0, s->window[s->strstart - 1])) { 2546 FLUSH_BLOCK_ONLY(s, 0); 2547 } 2548 s->strstart++; 2549 s->lookahead--; 2550 if (s->strm->avail_out == 0) { 2551 return 1; 2552 } 2553 } else { 2554 /* There is no previous match to compare with, wait for 2555 * the next step to decide. 2556 */ 2557 s->match_available = 1; 2558 s->strstart++; 2559 s->lookahead--; 2560 } 2561 } 2562 if (s->match_available) { 2563 ct_tally (s, 0, s->window[s->strstart - 1]); 2564 } 2565 2566 FLUSH_BLOCK(s, flush == Z_FINISH); 2567 return 0; 2568 } 2569 2570 local int deflate (strm, flush) 2571 z_stream *strm; 2572 int flush; 2573 { 2574 if (strm == Z_NULL || strm->state == Z_NULL) { 2575 return Z_STREAM_ERROR; 2576 } 2577 2578 if (strm->next_out == Z_NULL || strm->next_in == Z_NULL) { 2579 ERR_RETURN(strm, Z_STREAM_ERROR); 2580 } 2581 if (strm->avail_out == 0) { 2582 ERR_RETURN(strm, Z_BUF_ERROR); 2583 } 2584 2585 strm->state->strm = strm; /* just in case */ 2586 2587 /* Write the zlib header */ 2588 if (strm->state->status == INIT_STATE) { 2589 uInt header = (DEFLATED + ((strm->state->w_bits - 8) << 4)) << 8; // 4:byte alignment, 8:byte alignment 2590 uInt level_flags = (strm->state->level - 1) >> 1; 2591 2592 if (level_flags > 3) { // 3:byte alignment 2593 level_flags = 3; // 3:byte alignment 2594 } 2595 header |= (level_flags << 6); // 3:byte alignment 2596 header += 31 - (header % 31); // 31:byte alignment 2597 2598 strm->state->status = BUSY_STATE; 2599 putShortMSB(strm->state, header); 2600 } 2601 2602 /* Flush as much pending output as possible */ 2603 if (strm->state->pending != 0) { 2604 flush_pending(strm); 2605 if (strm->avail_out == 0) { 2606 return Z_OK; 2607 } 2608 } 2609 2610 /* User must not provide more input after the first FINISH: */ 2611 if (strm->state->status == FINISH_STATE && strm->avail_in != 0) { 2612 ERR_RETURN(strm, Z_BUF_ERROR); 2613 } 2614 2615 /* Start a new block or continue the current one. 2616 */ 2617 if (strm->avail_in != 0 || 2618 (flush == Z_FINISH && strm->state->status != FINISH_STATE)) { 2619 if (flush == Z_FINISH) { 2620 strm->state->status = FINISH_STATE; 2621 } 2622 if (strm->state->level <= 3) { // 3:byte alignment 2623 if (deflate_fast(strm->state, flush)) { 2624 return Z_OK; 2625 } 2626 } else { 2627 if (deflate_slow(strm->state, flush)) { 2628 return Z_OK; 2629 } 2630 } 2631 } 2632 Assert(strm->avail_out > 0, "bug2"); 2633 2634 if (flush != Z_FINISH) { 2635 return Z_OK; 2636 } 2637 if (strm->state->noheader) { 2638 return Z_STREAM_END; 2639 } 2640 2641 /* Write the zlib trailer (adler32) */ 2642 putShortMSB(strm->state, (uInt)(strm->state->adler >> 16)); // 16:byte alignment 2643 putShortMSB(strm->state, (uInt)(strm->state->adler & 0xffff)); 2644 flush_pending(strm); 2645 /* If avail_out is zero, the application will call deflate again 2646 * to flush the rest. 2647 */ 2648 strm->state->noheader = 1; /* write the trailer only once! */ 2649 return strm->state->pending != 0 ? Z_OK : Z_STREAM_END; 2650 } 2651 2652 local int gzflush (file, flush) 2653 gzFile file; 2654 int flush; 2655 { 2656 uInt len; 2657 int done = 0; 2658 gz_stream *s = (gz_stream*)file; 2659 2660 if (s == NULL || s->mode != 'w') { 2661 return Z_STREAM_ERROR; 2662 } 2663 2664 s->stream.avail_in = 0; /* should be zero already anyway */ 2665 2666 for (;;) { 2667 len = Z_BUFSIZE - s->stream.avail_out; 2668 2669 if (len != 0) { 2670 if (fwrite(s->outbuf, 1, len, s->file) != len) { 2671 s->z_err = Z_ERRNO; 2672 return Z_ERRNO; 2673 } 2674 s->stream.next_out = s->outbuf; 2675 s->stream.avail_out = Z_BUFSIZE; 2676 } 2677 if (done) { 2678 break; 2679 } 2680 s->z_err = deflate(&(s->stream), flush); 2681 2682 /* deflate has finished flushing only when it hasn't used up 2683 * all the available space in the output buffer: 2684 */ 2685 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); 2686 2687 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) { 2688 break; 2689 } 2690 } 2691 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; 2692 } 2693 2694 local gzFile gz_open (path, mode, fd) 2695 char *path; 2696 char *mode; 2697 int fd; 2698 { 2699 int err; 2700 char *p = mode; 2701 gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream)); 2702 2703 if (!s) { 2704 return Z_NULL; 2705 } 2706 2707 s->stream.zalloc = (alloc_func)0; 2708 s->stream.zfree = (free_func)0; 2709 s->stream.next_in = s->inbuf = Z_NULL; 2710 s->stream.next_out = s->outbuf = Z_NULL; 2711 s->stream.avail_in = s->stream.avail_out = 0; 2712 s->file = NULL; 2713 s->z_err = Z_OK; 2714 s->z_eof = 0; 2715 s->crc = crc32(0L, Z_NULL, 0); 2716 s->msg = NULL; 2717 s->transparent = 0; 2718 2719 s->path = (char*)ALLOC(strlen(path)+1); 2720 if (s->path == NULL) { 2721 return destroy(s), (gzFile)Z_NULL; 2722 } 2723 strcpy(s->path, path); /* do this early for debugging */ 2724 2725 s->mode = '\0'; 2726 do { 2727 if (*p == 'r') { 2728 s->mode = 'r'; 2729 } 2730 if (*p == 'w') { 2731 s->mode = 'w'; 2732 } 2733 } while (*p++); 2734 if (s->mode == '\0') { 2735 return destroy(s), (gzFile)Z_NULL; 2736 } 2737 2738 if (s->mode == 'w') { 2739 err = deflateInit2(&(s->stream), Z_BEST_COMPRESSION, 2740 DEFLATED, -WBITS, MEM_LEVEL, 0); 2741 /* windowBits is passed < 0 to suppress zlib header */ 2742 2743 s->stream.next_out = s->outbuf = ALLOC(Z_BUFSIZE); 2744 2745 if (err != Z_OK || s->outbuf == Z_NULL) { 2746 return destroy(s), (gzFile)Z_NULL; 2747 } 2748 } else { 2749 err = inflateInit2(&(s->stream), -WBITS); 2750 s->stream.next_in = s->inbuf = ALLOC(Z_BUFSIZE); 2751 2752 if (err != Z_OK || s->inbuf == Z_NULL) { 2753 return destroy(s), (gzFile)Z_NULL; 2754 } 2755 } 2756 s->stream.avail_out = Z_BUFSIZE; 2757 2758 errno = 0; 2759 s->file = fd < 0 ? fopen(path, mode) : fdopen(fd, mode); 2760 2761 if (s->file == NULL) { 2762 return destroy(s), (gzFile)Z_NULL; 2763 } 2764 if (s->mode == 'w') { 2765 /* Write a very simple .gz header: 2766 */ 2767 fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2, 2768 DEFLATED, 0, 0, 0, 0, 0, 0, OS_CODE); 2769 } else { 2770 /* Check and skip the header: 2771 */ 2772 Byte c1 = 0, c2 = 0; 2773 Byte method = 0; 2774 Byte flags = 0; 2775 Byte xflags = 0; 2776 Byte time[4]; 2777 Byte osCode; 2778 int c; 2779 2780 s->stream.avail_in = fread(s->inbuf, 1, 2, s->file); // 2:size 2781 if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1 // 2:byte alignment 2782 || s->inbuf[1] != GZ_MAGIC_2) { 2783 s->transparent = 1; 2784 return (gzFile)s; 2785 } 2786 s->stream.avail_in = 0; 2787 err = fscanf(s->file, "%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode); 2788 2789 if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) { 2790 s->z_err = Z_DATA_ERROR; 2791 return (gzFile)s; 2792 } 2793 if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ 2794 long len; 2795 err = fscanf(s->file, "%c%c", &c1, &c2); 2796 len = c1 + ((long)c2 << 8); // 8:byte alignment 2797 fseek(s->file, len, SEEK_CUR); 2798 } 2799 if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ 2800 while ((c = getc(s->file)) != 0 && c != EOF) { 2801 } 2802 } 2803 if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ 2804 while ((c = getc(s->file)) != 0 && c != EOF) { 2805 } 2806 } 2807 if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ 2808 err = fscanf(s->file, "%c%c", &c1, &c2); 2809 } 2810 if (feof(s->file)) { 2811 s->z_err = Z_DATA_ERROR; 2812 } 2813 } 2814 return (gzFile)s; 2815 } 2816 2817 local gzFile gzopen (path, mode) 2818 char *path; 2819 char *mode; 2820 { 2821 return gz_open (path, mode, -1); 2822 } 2823 2824 local int gzwrite (file, buf, len) 2825 gzFile file; 2826 voidp buf; 2827 unsigned len; 2828 { 2829 gz_stream *s = (gz_stream*)file; 2830 2831 if (s == NULL || s->mode != 'w') { 2832 return Z_STREAM_ERROR; 2833 } 2834 2835 s->stream.next_in = buf; 2836 s->stream.avail_in = len; 2837 2838 while (s->stream.avail_in != 0) { 2839 if (s->stream.avail_out == 0) { 2840 s->stream.next_out = s->outbuf; 2841 if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { 2842 s->z_err = Z_ERRNO; 2843 break; 2844 } 2845 s->stream.avail_out = Z_BUFSIZE; 2846 } 2847 s->z_err = deflate(&(s->stream), Z_NO_FLUSH); 2848 2849 if (s->z_err != Z_OK) { 2850 break; 2851 } 2852 } 2853 s->crc = crc32(s->crc, buf, len); 2854 2855 return len - s->stream.avail_in; 2856 } 2857 2858 local int gzclose (file) 2859 gzFile file; 2860 { 2861 uInt n; 2862 int err; 2863 gz_stream *s = (gz_stream*)file; 2864 2865 if (s == NULL) { 2866 return Z_STREAM_ERROR; 2867 } 2868 2869 if (s->mode == 'w') { 2870 err = gzflush(file, Z_FINISH); 2871 if (err != Z_OK) { 2872 return destroy((gz_stream *)file); 2873 } 2874 2875 putLong (s->file, s->crc); 2876 putLong (s->file, s->stream.total_in); 2877 } else if (s->mode == 'r' && s->z_err == Z_STREAM_END) { 2878 /* slide CRC and original size if they are at the end of inbuf */ 2879 if ((n = s->stream.avail_in) < 8 && !s->z_eof) { // 8:byte alignment 2880 Byte *p = s->inbuf; 2881 Byte *q = s->stream.next_in; 2882 while (n--) { 2883 *p++ = *q++; 2884 } 2885 2886 n = s->stream.avail_in; 2887 n += fread(p, 1, 8, s->file); // 8:size 2888 s->stream.next_in = s->inbuf; 2889 } 2890 /* check CRC and original size */ 2891 if (n < 8 || 2892 getLong(s->stream.next_in) != s->crc || 2893 getLong(s->stream.next_in + 4) != s->stream.total_out) { // 4:byte alignment 2894 s->z_err = Z_DATA_ERROR; 2895 } 2896 } 2897 return destroy((gz_stream *)file); 2898 } 2899 2900 /* ========================================================================= */ 2901 2902 static int wm_tool_printf(const char *format, ...) 2903 { 2904 int ret; 2905 va_list ap; 2906 2907 va_start(ap, format); 2908 ret = vprintf(format, ap); 2909 va_end(ap); 2910 2911 fflush(stdout); 2912 2913 return ret; 2914 } 2915 2916 static unsigned long long wm_tool_crc32_reflect(unsigned long long ref, unsigned char ch) 2917 { 2918 int i; 2919 unsigned long long value = 0; 2920 2921 for (i = 1; i < (ch + 1); i++) { 2922 if (ref & 1) { 2923 value |= 1 << (ch - i); 2924 } 2925 ref >>= 1; 2926 } 2927 2928 return value; 2929 } 2930 2931 static unsigned int wm_tool_crc32(unsigned int crc, unsigned char *buffer, int size, wm_tool_crc32_reflect_e mode) 2932 { 2933 int i; 2934 unsigned char temp; 2935 2936 for (i = 0; i < size; i++) { 2937 if (mode & WM_TOOL_CRC32_REFLECT_INPUT) { 2938 temp = wm_tool_crc32_reflect(buffer[i], 8); // 8:ch 2939 } else { 2940 temp = buffer[i]; 2941 } 2942 crc = wm_tool_crc32_tab[(crc ^ temp) & 0xff] ^ (crc >> 8); // 8:byte alignment 2943 } 2944 2945 return crc ; 2946 } 2947 2948 static unsigned int wm_tool_get_crc32(unsigned char *buffer, int size, wm_tool_crc32_reflect_e mode) 2949 { 2950 wm_tool_file_crc = wm_tool_crc32(wm_tool_file_crc, buffer, size, mode); 2951 if (mode & WM_TOOL_CRC32_REFLECT_OUTPUT) { 2952 wm_tool_file_crc = wm_tool_crc32_reflect(wm_tool_file_crc, 32); // 32:size 2953 } 2954 return wm_tool_file_crc; 2955 } 2956 2957 static unsigned short wm_tool_get_crc16(unsigned char *ptr, unsigned short count) 2958 { 2959 unsigned short crc, i; 2960 2961 crc = 0; 2962 2963 while (count--) { 2964 crc = crc ^ (int) *ptr++ << 8; // 8:byte alignment 2965 2966 for (i = 0; i < 8; i++) { // 8:loop cap 2967 if (crc & 0x8000) 2968 crc = crc << 1 ^ 0x1021; 2969 else 2970 crc = crc << 1; 2971 } 2972 } 2973 2974 return (crc & 0xFFFF); 2975 } 2976 2977 static int wm_tool_char_to_hex(char ch) 2978 { 2979 int hex; 2980 2981 hex = -1; 2982 2983 if ((ch >= '0') && (ch <= '9')) { 2984 hex = ch - '0'; 2985 } else if ((ch >= 'a') && (ch <= 'f')) { 2986 hex = ch - 'a' + 0xa; 2987 } else if ((ch >= 'A') && (ch <= 'F')) { 2988 hex = ch - 'A' + 0xa; 2989 } 2990 2991 return hex; 2992 } 2993 2994 static int wm_tool_str_to_hex_array(char *str, int cnt, unsigned char array[]) 2995 { 2996 int hex; 2997 unsigned char tmp; 2998 unsigned char *des; 2999 3000 des = array; 3001 3002 while (cnt-- > 0) { 3003 hex = wm_tool_char_to_hex(*str++); 3004 if (hex < 0) { 3005 return -1; 3006 } else { 3007 tmp = (hex << 4) & 0xf0; 3008 } 3009 3010 hex = wm_tool_char_to_hex(*str++); 3011 if (hex < 0) { 3012 return -1; 3013 } else { 3014 tmp = tmp | (hex & 0x0f); 3015 } 3016 3017 *des++ = (unsigned char) tmp; 3018 } 3019 3020 return ((*str == 0) ? 0 : -1); 3021 } 3022 3023 static char *wm_tool_strcasestr(const char *str1, const char *str2) 3024 { 3025 char *cp = (char *) str1; 3026 char *s1, *s2; 3027 3028 if (!*str2) { 3029 return (char *) str1; 3030 } 3031 3032 while (*cp) { 3033 s1 = cp; 3034 s2 = (char *) str2; 3035 3036 while (*s1 && *s2 && !(tolower((int)*s1) - tolower((int)*s2))) { 3037 s1++, s2++; 3038 } 3039 if (!*s2) { 3040 return cp; 3041 } 3042 cp++; 3043 } 3044 3045 return NULL; 3046 } 3047 3048 static int wm_tool_get_file_size(const char* filename) 3049 { 3050 FILE *fp = fopen(filename, "r"); 3051 if (!fp) { 3052 return -1; 3053 } 3054 fseek(fp, 0L, SEEK_END); 3055 int size = ftell(fp); 3056 fclose(fp); 3057 return size; 3058 } 3059 3060 static char *wm_tool_get_name(const char *name) 3061 { 3062 static char sz_name[WM_TOOL_PATH_MAX] = {0}; 3063 char *p = (char *)name; 3064 char *q = (char *)name; 3065 3066 do { 3067 #ifdef __MINGW32__ 3068 p = strchr(p, '\\'); 3069 #else 3070 p = strchr(p, '/'); 3071 #endif 3072 if (p) { 3073 p++; 3074 q = p; 3075 } 3076 } while (p); 3077 3078 strncpy(sz_name, q, WM_TOOL_PATH_MAX - 1); 3079 3080 #ifdef __MINGW32__ 3081 p = wm_tool_strcasestr(sz_name, ".exe"); 3082 if (p) 3083 *p = '\0'; 3084 #endif 3085 3086 return sz_name; 3087 } 3088 3089 static void wm_tool_print_usage(const char *name) 3090 { 3091 wm_tool_printf("Usage: %s [-h] [-v] [-b] [-o] [-sb] [-ct] [-it]" 3092 " [-ua] [-ra] [-ih] [-nh] [-un] [-df] [-vs]" 3093 " [-l] [-c] [-ws] [-ds] [-rs] [-eo] [-dl] [-sl]" 3094 "\r\n" 3095 "\r\n" 3096 "WinnerMicro firmware packaging " 3097 "and programming " 3098 "tool\r\n\r\n" 3099 "options:\r\n\r\n" 3100 " -h , show usage\r\n" 3101 " -v , show version\r\n" 3102 "\r\n" 3103 " -b binary , original binary file\r\n" 3104 " -o output_name , output firmware file\r\n" 3105 " the default is the same as the original binary file name\r\n" 3106 " -sb second_boot , second boot file, used to generate fls file\r\n" 3107 " -fc compress_type , whether the firmware is compressed, default is compressed\r\n" 3108 " <0 | 1> or <uncompress | compress>\r\n" 3109 " -it image_type , firmware image layout type, default is 0\r\n" 3110 " <0 | 1>\r\n" 3111 " -ua update_address , upgrade storage location (hexadecimal)\r\n" 3112 " the default is 8090000\r\n" 3113 " -ra run_address , runtime position (hexadecimal)\r\n" 3114 " the default is 8002400\r\n" 3115 " -ih image_header , image header storage location (hexadecimal)\r\n" 3116 " the default is 8002000\r\n" 3117 " -nh next_image_header , next image header storage location (hexadecimal)\r\n" 3118 " the default is 0\r\n" 3119 " -un upd_no , upd no version number (hexadecimal)\r\n" 3120 " the default is 0\r\n" 3121 " -df , generate debug firmware for openocd\r\n" 3122 " -vs version_string , firmware version string, cannot exceed 16 bytes\r\n" 3123 "\r\n" 3124 " -l , list the local serial port\r\n" 3125 " -c serial_name , connect a serial port\r\n" 3126 #if defined(__APPLE__) && defined(__MACH__) 3127 " e.g: tty.usbserial0 tty.usbserial3 tty.usbserial7\r\n" 3128 #elif defined(__MINGW32__) || defined(__CYGWIN__) 3129 " e.g: COM0 COM3 COM7\r\n" 3130 #elif defined(__linux__) 3131 " e.g: ttyUSB0 ttyUSB3 ttyUSB7\r\n" 3132 #endif 3133 " -ws baud_rate , set the serial port speed during normal work, default is 115200\r\n" 3134 " <1200 - 2000000> or <1M | 2M>\r\n" 3135 " -ds baud_rate , set the serial port speed when downloading, default is 115200\r\n" 3136 " <115200 | 460800 | 921600 | 1000000 | 2000000> or <1M | 2M>\r\n" 3137 " -rs reset_action , set device reset method, default is manual control\r\n" 3138 " <none | at | rts>\r\n" 3139 " none - manual control device reset\r\n" 3140 " at - use the at command to control the device reset\r\n" 3141 " rts - use the serial port rts pin to control the device reset\r\n" 3142 " -eo erase_option , firmware area erase option\r\n" 3143 " <all>\r\n" 3144 " all - erase all areas\r\n" 3145 " -dl download_firmware , firmware file to be downloaded, default download compressed image\r\n" 3146 " -sl display_format , display the log information output from the serial port\r\n" 3147 " <0 | 1> or <str | hex>\r\n" 3148 " str - string mode display\r\n" 3149 " hex - hexadecimal format\r\n", 3150 wm_tool_get_name(name)); 3151 3152 return; 3153 } 3154 3155 static void wm_tool_print_version(const char *name) 3156 { 3157 wm_tool_printf("%s %s for w800\r\nCopyright (C) 2013 - 2020 WinnerMicro, Inc.\r\n", \ 3158 wm_tool_get_name(name), wm_tool_version); 3159 3160 return; 3161 } 3162 3163 static int wm_tool_parse_arv(int argc, char *argv[]) 3164 { 3165 int opt; 3166 int option_index = 0; 3167 char *opt_string = "hvlc:b:o:"; 3168 int cnt = 0; 3169 3170 opterr = 1; /* show err info */ 3171 3172 struct option long_options[] = { 3173 {"dl", required_argument, NULL, 'd'}, 3174 {"ws", required_argument, NULL, 'w'}, 3175 {"ds", required_argument, NULL, 's'}, 3176 {"sb", required_argument, NULL, 'S'}, 3177 {"it", required_argument, NULL, 'i'}, 3178 {"fc", required_argument, NULL, 'C'}, 3179 {"ua", required_argument, NULL, 'u'}, 3180 {"ra", required_argument, NULL, 'r'}, 3181 {"ih", required_argument, NULL, 'H'}, 3182 {"nh", required_argument, NULL, 'n'}, 3183 {"un", required_argument, NULL, 'U'}, 3184 {"df", no_argument, NULL, 'D'}, 3185 {"vs", required_argument, NULL, 'V'}, 3186 {"rs", required_argument, NULL, 'a'}, 3187 {"eo", required_argument, NULL, 'e'}, 3188 {"sl", required_argument, NULL, 'g'}, 3189 {0, 0, NULL, 0} 3190 }; 3191 3192 while ((opt = getopt_long_only(argc, argv, opt_string, long_options, &option_index)) != -1) { 3193 WM_TOOL_DBG_PRINT("%c-%s\r\n", opt, optarg); 3194 3195 switch (opt) { 3196 case '?': 3197 case 'h': 3198 { 3199 wm_tool_show_usage = 1; 3200 break; 3201 } 3202 case 'v': 3203 { 3204 wm_tool_show_ver = 1; 3205 break; 3206 } 3207 case 'l': 3208 { 3209 wm_tool_list_com = 1; 3210 break; 3211 } 3212 case 'c': 3213 { 3214 #if defined(__MINGW32__) 3215 strcpy(wm_tool_serial_path, optarg); 3216 #elif defined(__CYGWIN__) 3217 sprintf(wm_tool_serial_path, "/dev/ttyS%d", atoi(optarg + strlen("COM")) - 1); 3218 #else 3219 sprintf(wm_tool_serial_path, "/dev/%s", optarg); 3220 #endif 3221 break; 3222 } 3223 case 'w': 3224 { 3225 if (optarg[1] == 'M') { 3226 wm_tool_normal_serial_rate = (optarg[0] - 0x30) * 1000000; // 1000000:byte alignment 3227 } else { 3228 wm_tool_normal_serial_rate = strtol(optarg, NULL, 10); 3229 } 3230 break; 3231 } 3232 case 's': 3233 { 3234 if (optarg[1] == 'M') { 3235 wm_tool_download_serial_rate = (optarg[0] - 0x30) * 1000000; // 1000000:byte alignment 3236 } else { 3237 wm_tool_download_serial_rate = strtol(optarg, NULL, 10); // 10:base 3238 } 3239 break; 3240 } 3241 case 'a': 3242 { 3243 if (strncmp(optarg, "none", strlen("none")) == 0) { 3244 wm_tool_dl_action = WM_TOOL_DL_ACTION_NONE; 3245 } else if (strncmp(optarg, "at", strlen("at")) == 0) { 3246 wm_tool_dl_action = WM_TOOL_DL_ACTION_AT; 3247 } else if (strncmp(optarg, "rts", strlen("rts")) == 0) { 3248 wm_tool_dl_action = WM_TOOL_DL_ACTION_RTS; 3249 } else { 3250 wm_tool_show_usage = 1; 3251 } 3252 break; 3253 } 3254 case 'e': 3255 { 3256 if (strncmp(optarg, "all", strlen("all")) == 0) { 3257 wm_tool_dl_erase = WM_TOOL_DL_ERASE_ALL; 3258 } else { 3259 wm_tool_show_usage = 1; 3260 } 3261 break; 3262 } 3263 case 'd': 3264 { 3265 wm_tool_download_image = strdup(optarg); 3266 if (wm_tool_strcasestr(wm_tool_download_image, ".fls")) { 3267 wm_tool_dl_type = WM_TOOL_DL_TYPE_FLS; 3268 } 3269 break; 3270 } 3271 case 'o': 3272 { 3273 wm_tool_output_image = strdup(optarg); 3274 break; 3275 } 3276 case 'b': 3277 { 3278 wm_tool_input_binary = strdup(optarg); 3279 break; 3280 } 3281 case 'S': 3282 { 3283 wm_tool_secboot_image = strdup(optarg); 3284 break; 3285 } 3286 case 'i': 3287 { 3288 { 3289 if (isdigit((int)optarg[0])) { 3290 wm_tool_image_type = atoi(optarg); // optarg[0] - 0x30; 3291 } else { 3292 wm_tool_show_usage = 1; 3293 } 3294 } 3295 break; 3296 } 3297 case 'C': 3298 { 3299 if (optarg[0] == '0') { 3300 wm_tool_zip_type = WM_TOOL_ZIP_TYPE_UNCOMPRESS; 3301 } else if (optarg[0] == '1') { 3302 wm_tool_zip_type = WM_TOOL_ZIP_TYPE_COMPRESS; 3303 } else if (strncmp(optarg, "compress", strlen("compress")) == 0) { 3304 wm_tool_zip_type = WM_TOOL_ZIP_TYPE_COMPRESS; 3305 } else if (strncmp(optarg, "uncompress", strlen("uncompress")) == 0) { 3306 wm_tool_zip_type = WM_TOOL_ZIP_TYPE_UNCOMPRESS; 3307 } else { 3308 wm_tool_show_usage = 1; 3309 } 3310 break; 3311 } 3312 case 'u': 3313 { 3314 wm_tool_upd_addr = strtol(optarg, NULL, 16); // 16:value of base 3315 break; 3316 } 3317 case 'r': 3318 { 3319 wm_tool_run_addr = strtol(optarg, NULL, 16); // 16:value of base 3320 break; 3321 } 3322 case 'D': 3323 { 3324 wm_tool_is_debug = 1; 3325 break; 3326 } 3327 case 'V': 3328 { 3329 strncpy(wm_tool_image_version, optarg, WM_TOOL_IMAGE_VERSION_LEN); 3330 wm_tool_image_version[WM_TOOL_IMAGE_VERSION_LEN - 1] = '\0'; 3331 break; 3332 } 3333 case 'g': 3334 { 3335 if (optarg[0] == '0') { 3336 wm_tool_show_log_type = WM_TOOL_SHOW_LOG_STR; 3337 } else if (optarg[0] == '1') { 3338 wm_tool_show_log_type = WM_TOOL_SHOW_LOG_HEX; 3339 } else if (strncmp(optarg, "str", strlen("str")) == 0) { 3340 wm_tool_show_log_type = WM_TOOL_SHOW_LOG_STR; 3341 } else if (strncmp(optarg, "hex", strlen("hex")) == 0) { 3342 wm_tool_show_log_type = WM_TOOL_SHOW_LOG_HEX; 3343 } else { 3344 wm_tool_show_usage = 1; 3345 } 3346 break; 3347 } 3348 case 'H': 3349 { 3350 wm_tool_image_header = strtol(optarg, NULL, 16); // 16:value of base 3351 break; 3352 } 3353 case 'n': 3354 { 3355 wm_tool_next_image_header = strtol(optarg, NULL, 16); // 16:value of base 3356 break; 3357 } 3358 case 'U': 3359 { 3360 wm_tool_image_upd_no = strtol(optarg, NULL, 16); // 16:value of base 3361 break; 3362 } 3363 default: 3364 { 3365 wm_tool_show_usage = 1; 3366 break; 3367 } 3368 } 3369 3370 cnt++; 3371 } 3372 3373 return cnt; 3374 } 3375 3376 static int wm_tool_pack_image(const char *outfile) 3377 { 3378 FILE *fpbin; 3379 FILE *fpimg; 3380 int readlen = 0; 3381 int filelen = 0; 3382 int patch = 0; 3383 wm_tool_firmware_booter_t fbooter; 3384 unsigned char buf[WM_TOOL_ONCE_READ_LEN + 1]; 3385 3386 fpbin = fopen(wm_tool_input_binary, "rb"); 3387 if (fpbin == NULL) { 3388 wm_tool_printf("can not open input file [%s].\r\n", wm_tool_input_binary); 3389 return -2; 3390 } 3391 3392 fpimg = fopen(outfile, "wb+"); 3393 if (fpimg == NULL) { 3394 wm_tool_printf("open img file error: [%s].\r\n", outfile); 3395 fclose(fpbin); 3396 return -3; 3397 } 3398 3399 /* --------deal with upgrade image's CRC begin---- */ 3400 wm_tool_file_crc = 0xFFFFFFFF; 3401 while (!feof(fpbin)) { 3402 memset(buf, 0, sizeof(buf)); 3403 readlen = fread(buf, 1, WM_TOOL_ONCE_READ_LEN, fpbin); 3404 if (readlen % WM_TOOL_ONCE_READ_LEN != 0) { 3405 patch = WM_TOOL_ONCE_READ_LEN - readlen%WM_TOOL_ONCE_READ_LEN; 3406 readlen += patch; 3407 } 3408 filelen += readlen; 3409 wm_tool_get_crc32((unsigned char*)buf, readlen, 0); 3410 } 3411 /* --------deal with upgrade image's CRC end---- */ 3412 3413 wm_tool_src_binary_len = filelen; 3414 wm_tool_src_binary_crc = wm_tool_file_crc; 3415 3416 memset(&fbooter, 0, sizeof(wm_tool_firmware_booter_t)); 3417 strcpy((char *)fbooter.ver, wm_tool_image_version); 3418 fbooter.magic_no = WM_TOOL_IMG_HEAD_MAGIC_NO; 3419 3420 fbooter.run_org_checksum = wm_tool_file_crc; 3421 fbooter.img_type = wm_tool_image_type; 3422 fbooter.run_img_len = filelen; 3423 fbooter.run_img_addr = wm_tool_run_addr; 3424 fbooter.zip_type = WM_TOOL_ZIP_TYPE_UNCOMPRESS; 3425 fbooter.img_header_addr = wm_tool_image_header; 3426 fbooter.upgrade_img_addr = wm_tool_upd_addr; 3427 fbooter.upd_no = wm_tool_image_upd_no; 3428 fbooter.next_boot = wm_tool_next_image_header; 3429 3430 /* calculate image's header's CRC */ 3431 wm_tool_file_crc = 0xFFFFFFFF; 3432 wm_tool_get_crc32((unsigned char *)&fbooter, sizeof(wm_tool_firmware_booter_t) - 4, 0); // 4:byte alignment 3433 fbooter.hd_checksum = wm_tool_file_crc; 3434 3435 /* write image's header to output file */ 3436 fwrite(&fbooter, 1, sizeof(wm_tool_firmware_booter_t), fpimg); 3437 3438 /* write image to output file */ 3439 fseek(fpbin, 0, SEEK_SET); 3440 while (!feof(fpbin)) { 3441 readlen = fread(buf, 1, WM_TOOL_ONCE_READ_LEN, fpbin); 3442 fwrite(buf, 1, readlen, fpimg); 3443 } 3444 3445 /* write dummy data to pad 4byte-aligned */ 3446 if (patch > 0) { 3447 memset(buf, 0, patch); 3448 fwrite(buf, 1, patch, fpimg); 3449 } 3450 3451 if (fpbin) { 3452 fclose(fpbin); 3453 } 3454 3455 if (fpimg) { 3456 fclose(fpimg); 3457 } 3458 3459 wm_tool_printf("generate normal image completed.\r\n"); 3460 3461 return 0; 3462 } 3463 3464 static int wm_tool_pack_gz_image(const char *gzbin, const char *outfile) 3465 { 3466 FILE *fpbin; 3467 FILE *fpimg; 3468 int readlen = 0; 3469 int filelen = 0; 3470 int patch = 0; 3471 wm_tool_firmware_booter_t fbooter; 3472 unsigned char buf[WM_TOOL_ONCE_READ_LEN + 1]; 3473 3474 fpbin = fopen(gzbin, "rb"); 3475 if (fpbin == NULL) { 3476 wm_tool_printf("can not open input file [%s].\r\n", gzbin); 3477 return -2; // -2:byte alignment 3478 } 3479 3480 fpimg = fopen(outfile, "wb+"); 3481 if (fpimg == NULL) { 3482 wm_tool_printf("create img file error: [%s].\r\n", outfile); 3483 fclose(fpbin); 3484 return -3; // -3:byte alignment 3485 } 3486 3487 /* --------deal with upgrade image's CRC begin---- */ 3488 wm_tool_file_crc = 0xFFFFFFFF; 3489 while (!feof(fpbin)) { 3490 memset(buf, 0, sizeof(buf)); 3491 readlen = fread(buf, 1, WM_TOOL_ONCE_READ_LEN, fpbin); 3492 if (readlen % 4 != 0) { // 4:byte alignment 3493 patch = 4 - readlen % 4; // 4:byte alignment 3494 readlen += patch; 3495 } 3496 filelen += readlen; 3497 wm_tool_get_crc32((unsigned char*)buf, readlen, 0); 3498 } 3499 /* --------deal with upgrade image's CRC end---- */ 3500 3501 memset(&fbooter, 0, sizeof(wm_tool_firmware_booter_t)); 3502 strcpy((char *)fbooter.ver, wm_tool_image_version); 3503 fbooter.magic_no = WM_TOOL_IMG_HEAD_MAGIC_NO; 3504 3505 fbooter.run_org_checksum = wm_tool_file_crc; 3506 fbooter.img_type = wm_tool_image_type; 3507 fbooter.run_img_len = filelen; 3508 fbooter.run_img_addr = wm_tool_run_addr; 3509 fbooter.zip_type = wm_tool_zip_type; 3510 fbooter.img_header_addr = wm_tool_image_header; 3511 fbooter.upgrade_img_addr = wm_tool_upd_addr; 3512 fbooter.upd_no = wm_tool_image_upd_no; 3513 fbooter.next_boot = wm_tool_next_image_header; 3514 3515 /* calculate image's header's CRC */ 3516 wm_tool_file_crc = 0xFFFFFFFF; 3517 wm_tool_get_crc32((unsigned char *)&fbooter, sizeof(wm_tool_firmware_booter_t) - 4, 0); 3518 fbooter.hd_checksum = wm_tool_file_crc; 3519 3520 /* write image's header to output file */ 3521 fwrite(&fbooter, 1, sizeof(wm_tool_firmware_booter_t), fpimg); 3522 3523 /* write image to output file */ 3524 fseek(fpbin, 0, SEEK_SET); 3525 while (!feof(fpbin)) { 3526 readlen = fread(buf, 1, WM_TOOL_ONCE_READ_LEN, fpbin); 3527 fwrite(buf, 1, readlen, fpimg); 3528 } 3529 3530 /* write dummy data to pad 4byte-aligned */ 3531 if (patch > 0) { 3532 memset(buf, 0, patch); 3533 fwrite(buf, 1, patch, fpimg); 3534 } 3535 3536 if (fpbin) { 3537 fclose(fpbin); 3538 } 3539 3540 if (fpimg) { 3541 fclose(fpimg); 3542 } 3543 3544 wm_tool_printf("generate compressed image completed.\r\n"); 3545 3546 return 0; 3547 } 3548 3549 static int wm_tool_pack_dbg_image(const char *image, const char *outfile) 3550 { 3551 FILE *fpimg; 3552 FILE *fout; 3553 unsigned char buf[WM_TOOL_ONCE_READ_LEN + 1]; 3554 int readlen = 0; 3555 int i; 3556 wm_tool_firmware_booter_t fbooter; 3557 int appimg_len = 0; 3558 int final_len = 0; 3559 int magic_word = 0; 3560 3561 fpimg = fopen(image, "rb"); 3562 if (fpimg == NULL) { 3563 wm_tool_printf("open img file error: [%s].\r\n", image); 3564 return -4; // -4:byte alignment 3565 } 3566 3567 magic_word = 0; 3568 readlen = fread(&magic_word, 1, 4, fpimg); // 4:size 3569 if (magic_word != WM_TOOL_IMG_HEAD_MAGIC_NO) { 3570 wm_tool_printf("input [%s] file magic error.\n", image); 3571 fclose(fpimg); 3572 return -5; // -5:byte alignment 3573 } 3574 3575 fout = fopen(outfile, "wb+"); 3576 if (fout == NULL) { 3577 wm_tool_printf("create img file error [%s].\r\n", outfile); 3578 fclose(fpimg); 3579 return -6; // -6:byte alignment 3580 } 3581 3582 appimg_len = wm_tool_get_file_size(image); 3583 3584 /* write 0xFF to output file */ 3585 final_len = WM_TOOL_RUN_IMG_HEADER_LEN + (appimg_len - sizeof(wm_tool_firmware_booter_t)); 3586 for (i = 0; i < (final_len /WM_TOOL_ONCE_READ_LEN); i++) { 3587 memset(buf, 0xff, WM_TOOL_ONCE_READ_LEN); 3588 fwrite(buf, 1, WM_TOOL_ONCE_READ_LEN, fout); 3589 } 3590 memset(buf, 0xff, final_len % WM_TOOL_ONCE_READ_LEN); 3591 fwrite(buf, 1, final_len % WM_TOOL_ONCE_READ_LEN, fout); 3592 3593 memset(&fbooter, 0, sizeof(wm_tool_firmware_booter_t)); 3594 3595 /* write sec img to output file */ 3596 fseek(fpimg, 0, SEEK_SET); 3597 readlen = fread((unsigned char *)&fbooter, 1, sizeof(wm_tool_firmware_booter_t), fpimg); 3598 3599 fseek(fout, 0, SEEK_SET); 3600 fwrite(&fbooter, 1, sizeof(wm_tool_firmware_booter_t), fout); 3601 fseek(fout, WM_TOOL_RUN_IMG_HEADER_LEN, SEEK_SET); 3602 3603 while (!feof(fpimg)) { 3604 readlen = fread(buf, 1, WM_TOOL_ONCE_READ_LEN, fpimg); 3605 fwrite(buf, 1, readlen, fout); 3606 } 3607 3608 if (fpimg) { 3609 fclose(fpimg); 3610 } 3611 3612 if (fout) { 3613 fclose(fout); 3614 } 3615 3616 wm_tool_printf("generate debug image completed.\r\n"); 3617 3618 return 0; 3619 } 3620 3621 static int wm_tool_pack_fls(const char *image, const char *outfile) 3622 { 3623 FILE *fpsec; 3624 FILE *fpimg; 3625 FILE *fout; 3626 unsigned char buf[WM_TOOL_ONCE_READ_LEN + 1]; 3627 int readlen = 0; 3628 int magic_word = 0; 3629 3630 fpsec = fopen(wm_tool_secboot_image, "rb"); 3631 if (fpsec == NULL) { 3632 wm_tool_printf("can not open input file [%s].\r\n", wm_tool_secboot_image); 3633 return -2; // -2:byte alignment 3634 } 3635 3636 magic_word = 0; 3637 readlen = fread(&magic_word, 1, 4, fpsec); 3638 if (magic_word != WM_TOOL_IMG_HEAD_MAGIC_NO) { 3639 wm_tool_printf("input [%s] file magic error.\r\n", wm_tool_secboot_image); 3640 fclose(fpsec); 3641 return -3; // -3:byte alignment 3642 } 3643 3644 fpimg = fopen(image, "rb"); 3645 if (fpimg == NULL) { 3646 wm_tool_printf("open img file error [%s].\r\n", image); 3647 fclose(fpsec); 3648 return -4; // -4:byte alignment 3649 } 3650 3651 magic_word = 0; 3652 readlen = fread(&magic_word, 1, 4, fpimg); 3653 if (magic_word != WM_TOOL_IMG_HEAD_MAGIC_NO) { 3654 wm_tool_printf("input [%s] file magic error.\r\n", image); 3655 fclose(fpsec); 3656 fclose(fpimg); 3657 return -5; // -5:byte alignment 3658 } 3659 3660 fout = fopen(outfile, "wb+"); 3661 if (fout == NULL) { 3662 wm_tool_printf("create img file error [%s].\r\n", outfile); 3663 fclose(fpsec); 3664 fclose(fpimg); 3665 return -6; // -6:byte alignment 3666 } 3667 3668 fseek(fpsec, 0, SEEK_SET); 3669 3670 while (!feof(fpsec)) { 3671 readlen = fread(buf, 1, WM_TOOL_ONCE_READ_LEN, fpsec); 3672 fwrite(buf, 1, readlen, fout); 3673 } 3674 3675 fseek(fpimg, 0, SEEK_SET); 3676 3677 while (!feof(fpimg)) { 3678 readlen = fread(buf, 1, WM_TOOL_ONCE_READ_LEN, fpimg); 3679 fwrite(buf, 1, readlen, fout); 3680 } 3681 3682 if (fpsec) { 3683 fclose(fpsec); 3684 } 3685 3686 if (fpimg) { 3687 fclose(fpimg); 3688 } 3689 3690 if (fout) { 3691 fclose(fout); 3692 } 3693 3694 wm_tool_printf("generate flash file completed.\r\n"); 3695 3696 return 0; 3697 } 3698 3699 static int wm_tool_gzip_bin(const char *binary, const char *gzbin) 3700 { 3701 FILE *bfp; 3702 gzFile gzfp; 3703 int ret; 3704 char buf[1024]; 3705 3706 bfp = fopen(binary, "rb"); 3707 if (!bfp) { 3708 wm_tool_printf("can not open binary.\r\n"); 3709 return -1; 3710 } 3711 3712 gzfp = gzopen((char *)gzbin, "wb+"); 3713 if (!gzfp) { 3714 wm_tool_printf("can not gzip binary.\r\n"); 3715 fclose(bfp); 3716 return -1; 3717 } 3718 3719 do { 3720 ret = fread(buf, 1, sizeof(buf), bfp); 3721 if (ret > 0) { 3722 ret = gzwrite(gzfp, (voidp)buf, ret); 3723 if (ret <= 0) { 3724 wm_tool_printf("can not write gzip binary.\r\n"); 3725 return -2; 3726 } 3727 } 3728 } while (ret > 0); 3729 3730 gzclose(gzfp); 3731 fclose(bfp); 3732 3733 wm_tool_printf("compress binary completed.\r\n"); 3734 3735 return 0; 3736 } 3737 3738 static int wm_tool_pack_firmware(void) 3739 { 3740 int ret; 3741 char *path; 3742 char *name; 3743 char *image; 3744 char *gzbin; 3745 char *gzimg; 3746 char *dbgimg; 3747 char *fls; 3748 3749 if (!wm_tool_input_binary) { 3750 return 1; 3751 } 3752 3753 if (!wm_tool_output_image) { 3754 char *r = wm_tool_input_binary; 3755 char *t = wm_tool_input_binary; 3756 do { 3757 r = strchr(r, '.'); 3758 if (r) { 3759 t = r; 3760 r++; 3761 } 3762 } while (r); 3763 wm_tool_output_image = malloc(t - wm_tool_input_binary + 1); 3764 if (!wm_tool_output_image) { 3765 return -1; 3766 } 3767 memcpy(wm_tool_output_image, wm_tool_input_binary, t - wm_tool_input_binary); 3768 wm_tool_output_image[t - wm_tool_input_binary] = '\0'; 3769 } 3770 3771 char *p = wm_tool_output_image; 3772 char *q = wm_tool_output_image; 3773 3774 do { 3775 p = strchr(p, '/'); 3776 if (p) { 3777 p++; 3778 q = p; 3779 } 3780 } while (p); 3781 3782 /* output file */ 3783 name = strdup(q); 3784 *q = '\0'; 3785 path = strdup(wm_tool_output_image); 3786 3787 image = malloc(strlen(path) + strlen(name) + strlen(".img") + 1); 3788 if (!image) { 3789 return -1; 3790 } 3791 sprintf(image, "%s%s.img", path, name); 3792 if (WM_TOOL_ZIP_TYPE_UNCOMPRESS == wm_tool_zip_type) { 3793 ret = wm_tool_pack_image(image); 3794 if (ret) { 3795 return ret; 3796 } 3797 } 3798 3799 if (WM_TOOL_ZIP_TYPE_COMPRESS == wm_tool_zip_type) { 3800 gzbin = malloc(strlen(path) + strlen(name) + strlen("_gz.bin") + 1); 3801 gzimg = malloc(strlen(path) + strlen(name) + strlen("_gz.img") + 1); 3802 if (!gzbin || !gzimg) { 3803 return -1; 3804 } 3805 sprintf(gzbin, "%s%s.bin.gz", path, name); 3806 sprintf(gzimg, "%s%s_gz.img", path, name); 3807 3808 ret = wm_tool_gzip_bin(wm_tool_input_binary, gzbin); 3809 if (ret) { 3810 free(gzbin); 3811 free(gzimg); 3812 return ret; 3813 } 3814 3815 ret = wm_tool_pack_gz_image(gzbin, gzimg); 3816 free(gzbin); 3817 free(gzimg); 3818 if (ret) 3819 return ret; 3820 } 3821 3822 if (wm_tool_is_debug) { 3823 dbgimg = malloc(strlen(path) + strlen(name) + strlen("_dbg.img") + 1); 3824 if (!dbgimg) { 3825 return -1; 3826 } 3827 sprintf(dbgimg, "%s%s_dbg.img", path, name); 3828 3829 ret = wm_tool_pack_dbg_image(image, dbgimg); 3830 free(dbgimg); 3831 if (ret) { 3832 return ret; 3833 } 3834 } 3835 3836 if (wm_tool_secboot_image) { 3837 fls = malloc(strlen(path) + strlen(name) + strlen(".fls") + 1); 3838 if (!fls) { 3839 return -1; 3840 } 3841 sprintf(fls, "%s%s.fls", path, name); 3842 3843 ret = wm_tool_pack_fls(image, fls); 3844 3845 free(fls); 3846 } 3847 3848 free(image); 3849 3850 return ret; 3851 } 3852 3853 #ifdef __MINGW32__ 3854 static BOOL wm_tool_signal_proc(DWORD no) 3855 { 3856 switch (no) { 3857 case CTRL_C_EVENT: 3858 wm_tool_signal_proc_entry(); 3859 return(FALSE); 3860 default: 3861 return FALSE; 3862 } 3863 } 3864 3865 static void wm_tool_signal_init(void) 3866 { 3867 SetConsoleCtrlHandler((PHANDLER_ROUTINE)wm_tool_signal_proc, TRUE); 3868 } 3869 3870 static void wm_tool_delay_ms(int ms) 3871 { 3872 Sleep(ms); 3873 3874 return; 3875 } 3876 3877 static int wm_tool_uart_set_rts(int boolflag) 3878 { 3879 return EscapeCommFunction(wm_tool_uart_handle, ((boolflag) ? SETRTS : CLRRTS)) ? 0 : -1; 3880 } 3881 3882 static int wm_tool_uart_set_dtr(int boolflag) 3883 { 3884 return EscapeCommFunction(wm_tool_uart_handle, ((boolflag) ? SETDTR : CLRDTR)) ? 0 : -1; 3885 } 3886 3887 static int wm_tool_uart_set_timeout(void) 3888 { 3889 BOOL ret; 3890 COMMTIMEOUTS timeout; 3891 3892 timeout.ReadIntervalTimeout = MAXDWORD; 3893 timeout.ReadTotalTimeoutConstant = 0; 3894 timeout.ReadTotalTimeoutMultiplier = 0; 3895 timeout.WriteTotalTimeoutConstant = 0; 3896 timeout.WriteTotalTimeoutMultiplier = 0; 3897 3898 ret = SetCommTimeouts(wm_tool_uart_handle, &timeout); 3899 if (ret) 3900 ret = SetCommMask(wm_tool_uart_handle, EV_TXEMPTY); 3901 3902 return ret ? 0 : -1; 3903 } 3904 3905 static void wm_tool_uart_set_block(int bolck) 3906 { 3907 if (bolck) 3908 wm_tool_uart_block = INFINITE; 3909 else 3910 wm_tool_uart_block = 0; 3911 3912 return; 3913 } 3914 3915 static int wm_tool_uart_set_speed(int speed) 3916 { 3917 int i; 3918 int size; 3919 DCB cfg; 3920 3921 size = sizeof(wm_tool_uart_speed_array) / sizeof(int); 3922 3923 for (i= 0; i < size; i++) { 3924 if (speed == wm_tool_uart_name_array[i]) { 3925 if (GetCommState(wm_tool_uart_handle, &cfg)) { 3926 cfg.DCBlength = sizeof(DCB); 3927 cfg.BaudRate = wm_tool_uart_speed_array[i]; 3928 cfg.fBinary = TRUE; 3929 cfg.fParity = FALSE; 3930 cfg.fDtrControl = DTR_CONTROL_DISABLE; 3931 cfg.fDsrSensitivity = FALSE; 3932 cfg.fRtsControl = RTS_CONTROL_DISABLE; 3933 cfg.ByteSize = 8; 3934 cfg.StopBits = ONESTOPBIT; 3935 cfg.fAbortOnError = FALSE; 3936 cfg.fOutX = FALSE; 3937 cfg.fInX = FALSE; 3938 cfg.fErrorChar = FALSE; 3939 cfg.fNull = FALSE; 3940 cfg.fOutxCtsFlow = FALSE; 3941 cfg.fOutxDsrFlow = FALSE; 3942 cfg.Parity = NOPARITY; 3943 cfg.fTXContinueOnXoff = FALSE; 3944 3945 return SetCommState(wm_tool_uart_handle, &cfg) ? 0 : -1; 3946 } else { 3947 return -3; // -4:byte alignment 3948 } 3949 } 3950 } 3951 3952 return -2; // -2:byte alignment 3953 } 3954 3955 static void wm_tool_uart_clear(void) 3956 { 3957 PurgeComm(wm_tool_uart_handle, PURGE_RXCLEAR); 3958 3959 return; 3960 } 3961 3962 static int wm_tool_uart_open(const char *device) 3963 { 3964 BOOL ret; 3965 char name[40]; 3966 3967 sprintf(name, "\\\\.\\%s", device); 3968 3969 wm_tool_uart_handle = CreateFile(name, GENERIC_WRITE | GENERIC_READ, 3970 0, NULL, OPEN_EXISTING, 3971 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 3972 NULL); 3973 if (wm_tool_uart_handle == INVALID_HANDLE_VALUE) { 3974 return -1; 3975 } 3976 3977 ret = SetupComm(wm_tool_uart_handle, 4096, 4096); 3978 if (ret) { 3979 ret = wm_tool_uart_set_speed(WM_TOOL_DEFAULT_BAUD_RATE); 3980 ret |= wm_tool_uart_set_timeout(); 3981 } else { 3982 ret = -1; 3983 } 3984 3985 return ret; 3986 } 3987 3988 static int wm_tool_uart_read(void *data, unsigned int size) 3989 { 3990 BOOL ret; 3991 DWORD wait; 3992 unsigned long len = 0; 3993 COMSTAT state; 3994 DWORD error; 3995 OVERLAPPED event; 3996 3997 do { 3998 memset(&event, 0, sizeof(OVERLAPPED)); 3999 4000 event.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 4001 4002 ClearCommError(wm_tool_uart_handle, &error, &state); 4003 4004 ret = ReadFile(wm_tool_uart_handle, data, size, &len, &event); 4005 if (!ret) { 4006 if (ERROR_IO_PENDING == GetLastError()) { 4007 wait = WaitForSingleObject(event.hEvent, wm_tool_uart_block); 4008 if (WAIT_OBJECT_0 == wait) 4009 ret = TRUE; 4010 } 4011 } 4012 } while (wm_tool_uart_block && !len); 4013 4014 if (ret) { 4015 if (len > 0) 4016 return (int)len; 4017 } 4018 4019 return -1; 4020 } 4021 4022 static int wm_tool_uart_write(const void *data, unsigned int size) 4023 { 4024 BOOL ret; 4025 DWORD wait; 4026 OVERLAPPED event; 4027 COMSTAT state; 4028 DWORD error; 4029 unsigned int snd = 0; 4030 unsigned long len = 0; 4031 4032 memset(&event, 0, sizeof(OVERLAPPED)); 4033 4034 event.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 4035 4036 do { 4037 ClearCommError(wm_tool_uart_handle, &error, &state); 4038 4039 ret = WriteFile(wm_tool_uart_handle, data + snd, size - snd, &len, &event); 4040 if (!ret) { 4041 if (ERROR_IO_PENDING == GetLastError()) { 4042 wait = WaitForSingleObject(event.hEvent, INFINITE); 4043 if (WAIT_OBJECT_0 == wait) 4044 ret = TRUE; 4045 } 4046 } 4047 4048 if (ret) { 4049 if ((len > 0) && (snd != size)) { 4050 snd += len; 4051 } else { 4052 return size; 4053 } 4054 } else { 4055 break; 4056 } 4057 } while (1); 4058 4059 return -1; 4060 } 4061 4062 static void wm_tool_uart_close(void) 4063 { 4064 FlushFileBuffers(wm_tool_uart_handle); 4065 CloseHandle(wm_tool_uart_handle); 4066 wm_tool_uart_handle = NULL; 4067 4068 return; 4069 } 4070 4071 static DWORD WINAPI wm_tool_uart_tx_thread(LPVOID arg) 4072 { 4073 wm_tool_stdin_to_uart(); 4074 4075 return 0; 4076 } 4077 4078 static int wm_tool_create_thread(void) 4079 { 4080 HANDLE thread_handle; 4081 thread_handle = CreateThread(0, 0, wm_tool_uart_tx_thread, NULL, 0, NULL); 4082 CloseHandle(thread_handle); 4083 return 0; 4084 } 4085 4086 #else 4087 4088 static void wm_tool_signal_proc(int no) 4089 { 4090 wm_tool_signal_proc_entry(); 4091 } 4092 4093 static void wm_tool_signal_init(void) 4094 { 4095 signal(SIGINT, wm_tool_signal_proc); 4096 } 4097 4098 static void wm_tool_delay_ms(int ms) 4099 { 4100 usleep(ms * 1000); 4101 4102 return; 4103 } 4104 4105 static int wm_tool_uart_set_rts(int boolflag) 4106 { 4107 int ret; 4108 int controlbits; 4109 4110 ret = ioctl(wm_tool_uart_fd, TIOCMGET, &controlbits); 4111 if (ret < 0) { 4112 WM_TOOL_DBG_PRINT("TIOCMGET failed!\r\n"); 4113 return ret; 4114 } 4115 4116 if (controlbits & TIOCM_RTS) { 4117 WM_TOOL_DBG_PRINT("TIOCM_RTS!, %d!\r\n", boolflag); 4118 } else { 4119 WM_TOOL_DBG_PRINT("~TIOCM_RTS!, %d!\r\n", boolflag); 4120 } 4121 4122 if (boolflag) { 4123 controlbits |= TIOCM_RTS; 4124 } else { 4125 controlbits &= ~TIOCM_RTS; 4126 } 4127 4128 ret = ioctl(wm_tool_uart_fd, TIOCMSET, &controlbits); 4129 if (ret < 0) { 4130 WM_TOOL_DBG_PRINT("TIOCMSET failed!\r\n"); 4131 } 4132 4133 if (ret >= 0) 4134 ret = 0; 4135 4136 return ret; 4137 } 4138 4139 static int wm_tool_uart_set_dtr(int boolflag) 4140 { 4141 int ret; 4142 int controlbits; 4143 4144 ret = ioctl(wm_tool_uart_fd, TIOCMGET, &controlbits); 4145 if (ret < 0) { 4146 WM_TOOL_DBG_PRINT("TIOCMGET failed!\r\n"); 4147 return ret; 4148 } 4149 4150 if (controlbits & TIOCM_DTR) { 4151 WM_TOOL_DBG_PRINT("TIOCM_DTR, %d!\r\n", boolflag); 4152 } else { 4153 WM_TOOL_DBG_PRINT("~TIOCM_DTR, %d!\r\n", boolflag); 4154 } 4155 4156 if (boolflag) { 4157 controlbits |= TIOCM_DTR; 4158 } else { 4159 controlbits &= ~TIOCM_DTR; 4160 } 4161 4162 ret = ioctl(wm_tool_uart_fd, TIOCMSET, &controlbits); 4163 if (ret < 0) { 4164 WM_TOOL_DBG_PRINT("TIOCMSET failed!\r\n"); 4165 } 4166 4167 if (ret >= 0) { 4168 ret = 0; 4169 } 4170 4171 return ret; 4172 } 4173 4174 static void wm_tool_uart_set_block(int bolck) 4175 { 4176 int comopt; 4177 4178 comopt = fcntl(wm_tool_uart_fd, F_GETFL, 0); 4179 4180 if (bolck) { 4181 fcntl(wm_tool_uart_fd, F_SETFL, comopt & ~O_NDELAY); 4182 } else { 4183 fcntl(wm_tool_uart_fd, F_SETFL, comopt | O_NDELAY); 4184 } 4185 4186 return; 4187 } 4188 4189 static int wm_tool_uart_set_speed(int speed) 4190 { 4191 int i; 4192 int size; 4193 int status = -1; 4194 struct termios opt; 4195 4196 tcgetattr(wm_tool_uart_fd, &opt); 4197 4198 size = sizeof(wm_tool_uart_speed_array) / sizeof(int); 4199 4200 for (i= 0; i < size; i++) { 4201 if (speed == wm_tool_uart_name_array[i]) { 4202 cfsetispeed(&opt, wm_tool_uart_speed_array[i]); 4203 cfsetospeed(&opt, wm_tool_uart_speed_array[i]); 4204 4205 status = tcsetattr(wm_tool_uart_fd, TCSANOW, &opt); 4206 4207 break; 4208 } 4209 } 4210 4211 return status; 4212 } 4213 4214 static void wm_tool_uart_clear(void) 4215 { 4216 tcflush(wm_tool_uart_fd, TCIFLUSH); 4217 4218 return; 4219 } 4220 4221 static int wm_tool_uart_open(const char *device) 4222 { 4223 struct termios tty; 4224 4225 wm_tool_uart_fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); 4226 if (-1 == wm_tool_uart_fd) { 4227 return -1; 4228 } 4229 4230 tcgetattr(wm_tool_uart_fd, &wm_tool_saved_serial_cfg); 4231 4232 wm_tool_uart_set_dtr(0); 4233 4234 tcgetattr(wm_tool_uart_fd, &tty); 4235 4236 /* databit 8bit */ 4237 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; 4238 4239 /* set into raw, no echo mode */ 4240 tty.c_iflag = IGNBRK; 4241 tty.c_lflag = 0; 4242 tty.c_oflag = 0; 4243 tty.c_cflag |= CLOCAL | CREAD; 4244 tty.c_cflag &= ~CRTSCTS; 4245 tty.c_cc[VMIN] = 1; 4246 tty.c_cc[VTIME] = 5; // 5:byte alignment 4247 4248 /* have no software flow control */ 4249 tty.c_iflag &= ~(IXON|IXOFF|IXANY); 4250 4251 /* parity none */ 4252 tty.c_cflag &= ~(PARENB | PARODD); 4253 4254 /* stopbit 1bit */ 4255 tty.c_cflag &= ~CSTOPB; 4256 4257 tcsetattr(wm_tool_uart_fd, TCSANOW, &tty); 4258 4259 return wm_tool_uart_set_speed(WM_TOOL_DEFAULT_BAUD_RATE); 4260 } 4261 4262 static int wm_tool_uart_read(void *data, unsigned int size) 4263 { 4264 return read(wm_tool_uart_fd, data, size); 4265 } 4266 4267 static int wm_tool_uart_write(const void *data, unsigned int size) 4268 { 4269 int snd = 0; 4270 int ret = 0; 4271 4272 do { 4273 ret = write(wm_tool_uart_fd, data + snd, size - snd); 4274 if (ret > 0) { 4275 snd += ret; 4276 4277 if (snd == size) { 4278 return size; 4279 } 4280 } else { 4281 break; 4282 } 4283 } while (1); 4284 4285 return -1; 4286 } 4287 4288 static void wm_tool_uart_close(void) 4289 { 4290 tcsetattr(wm_tool_uart_fd, TCSANOW, &wm_tool_saved_serial_cfg); 4291 4292 tcdrain(wm_tool_uart_fd); 4293 tcflush(wm_tool_uart_fd, TCIOFLUSH); 4294 4295 close(wm_tool_uart_fd); 4296 wm_tool_uart_fd = -1; 4297 4298 return; 4299 } 4300 4301 static void *wm_tool_uart_tx_thread(void *arg) 4302 { 4303 wm_tool_stdin_to_uart(); 4304 4305 return NULL; 4306 } 4307 4308 static int wm_tool_create_thread(void) 4309 { 4310 return 0; 4311 } 4312 #endif 4313 4314 static void wm_tool_signal_proc_entry(void) 4315 { 4316 WM_TOOL_DBG_PRINT("signal exit.\r\n"); 4317 exit(0); 4318 } 4319 4320 static void wm_tool_stdin_to_uart(void) 4321 { 4322 int ret; 4323 char buf[WM_TOOL_ONCE_READ_LEN]; 4324 4325 while (1) { 4326 if (fgets(buf, WM_TOOL_ONCE_READ_LEN, stdin)) { 4327 ret = wm_tool_uart_write(buf, strlen(buf)); 4328 if (ret <= 0) { 4329 WM_TOOL_DBG_PRINT("failed to write [%s].\r\n", buf); 4330 } 4331 } 4332 } 4333 4334 return; 4335 } 4336 4337 static int wm_tool_show_log_from_serial(void) 4338 { 4339 int i; 4340 int ret; 4341 unsigned int j = 0; 4342 unsigned char buf[WM_TOOL_ONCE_READ_LEN + 1]; 4343 4344 ret = wm_tool_uart_open(wm_tool_serial_path); 4345 if (ret) { 4346 wm_tool_printf("can not open serial\r\n"); 4347 return ret; 4348 } 4349 4350 if (wm_tool_normal_serial_rate != WM_TOOL_DEFAULT_BAUD_RATE) { 4351 ret = wm_tool_uart_set_speed(wm_tool_normal_serial_rate); 4352 if (ret) { 4353 wm_tool_printf("can not set serial baud rate.\r\n"); 4354 wm_tool_uart_close(); 4355 return ret; 4356 } 4357 } 4358 4359 ret = wm_tool_create_thread(); 4360 if (ret) { 4361 wm_tool_printf("can not create thread.\r\n"); 4362 wm_tool_uart_close(); 4363 return ret; 4364 } 4365 4366 wm_tool_uart_set_block(0); 4367 4368 wm_tool_signal_init(); 4369 4370 while (1) { 4371 ret = wm_tool_uart_read(buf, WM_TOOL_ONCE_READ_LEN); 4372 if (ret > 0) { 4373 if (WM_TOOL_SHOW_LOG_STR == wm_tool_show_log_type) { 4374 buf[ret] = '\0'; 4375 wm_tool_printf("%s", (char *)buf); 4376 } else if (WM_TOOL_SHOW_LOG_HEX == wm_tool_show_log_type) { 4377 for (i = 0; i < ret; i++, j++) { 4378 wm_tool_printf("%02X ", buf[i]); 4379 if ((j + 1) % 16 == 0) { // 16:byte alignment 4380 wm_tool_printf("\r\n"); 4381 } 4382 } 4383 } else { 4384 break; 4385 } 4386 } else { 4387 wm_tool_delay_ms(1); 4388 } 4389 } 4390 4391 wm_tool_uart_close(); 4392 4393 return ret; 4394 } 4395 4396 static int wm_tool_set_wifi_chip_speed(int speed) 4397 { 4398 int ret; 4399 4400 if (speed == 2000000) { // 2000000:value of speed 4401 ret = wm_tool_uart_write(wm_tool_chip_cmd_b2000000, sizeof(wm_tool_chip_cmd_b2000000)); 4402 } else if (speed == 1000000) { // 1000000:value of speed 4403 ret = wm_tool_uart_write(wm_tool_chip_cmd_b1000000, sizeof(wm_tool_chip_cmd_b1000000)); 4404 } else if (speed == 921600) { // 921600:value of speed 4405 ret = wm_tool_uart_write(wm_tool_chip_cmd_b921600, sizeof(wm_tool_chip_cmd_b921600)); 4406 } else if (speed == 460800) { // 460800:value of speed 4407 ret = wm_tool_uart_write(wm_tool_chip_cmd_b460800, sizeof(wm_tool_chip_cmd_b460800)); 4408 } else { 4409 ret = wm_tool_uart_write(wm_tool_chip_cmd_b115200, sizeof(wm_tool_chip_cmd_b115200)); 4410 } 4411 4412 return ret; 4413 } 4414 4415 static int wm_tool_send_esc2uart(int ms) 4416 { 4417 int i; 4418 int err = 0; 4419 unsigned char esc_key = 27; 4420 4421 for (i = 0; i < (ms / 10); i++) { // 10:byte alignment 4422 err = wm_tool_uart_write(&esc_key, 1); 4423 wm_tool_delay_ms(10); // 10:10ms 4424 } 4425 4426 return err; 4427 } 4428 4429 static int wm_tool_erase_image(wm_tool_dl_erase_e type) 4430 { 4431 int cnt = 0; 4432 int ret = -1; 4433 unsigned char ch; 4434 /* 2M-8k */ 4435 unsigned char rom_cmd[] = {0x21, 0x0a, 0x00, 0xc3, 0x35, 0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0xfe, 0x01}; 4436 4437 WM_TOOL_DBG_PRINT("start erase.\r\n"); 4438 4439 if (WM_TOOL_DL_ERASE_ALL == type) { 4440 wm_tool_printf("erase flash...\r\n"); 4441 ret = wm_tool_uart_write(rom_cmd, sizeof(rom_cmd)); 4442 } 4443 if (ret <= 0) { 4444 return -1; 4445 } 4446 4447 wm_tool_uart_clear(); 4448 4449 wm_tool_uart_set_block(1); 4450 4451 do { 4452 ret = wm_tool_uart_read(&ch, 1); 4453 if (ret > 0) { 4454 if ((ch == 'C') || (ch == 'P')) { 4455 cnt++; 4456 } else { 4457 cnt = 0; 4458 } 4459 } else { 4460 wm_tool_printf("erase error, errno = %d.\r\n", errno); 4461 return -2; // -2:byte alignment 4462 } 4463 } while (cnt < 3); // 3:loop condition 4464 4465 wm_tool_uart_set_block(0); 4466 4467 wm_tool_printf("erase finish.\r\n"); 4468 4469 return 0; 4470 } 4471 4472 static int wm_tool_query_mac(void) 4473 { 4474 int ret = -1; 4475 int err; 4476 int offset = 0; 4477 char macstr[32] = {0}; 4478 int len = strlen("MAC:AABBCCDDEEFF\n"); /* resp format, ROM "Mac:AABBCCDDEEFF\n", SECBOOT "MAC:AABBCCDDEEFF\n" */ 4479 unsigned char macaddr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 4480 4481 wm_tool_uart_clear(); 4482 4483 wm_tool_uart_set_block(1); 4484 4485 err = wm_tool_uart_write(wm_tool_chip_cmd_get_mac, sizeof(wm_tool_chip_cmd_get_mac)); 4486 if (err > 0) { 4487 do { 4488 err = wm_tool_uart_read((unsigned char *)(macstr + offset), sizeof(macstr) - 1 - offset); 4489 if (err > 0) { 4490 offset += err; 4491 if (offset >= len) { 4492 macstr[len - 1] = '\0'; /* \n -> 0 */ 4493 if (strstr(macstr, "Mac:")) { 4494 err = wm_tool_str_to_hex_array(macstr + strlen("MAC:"), 6, macaddr); // 6:cnt 4495 } else { 4496 err = 0; 4497 } 4498 4499 if (!err) { 4500 wm_tool_printf("mac %02X-%02X-%02X-%02X-%02X-%02X.\r\n", macaddr[0], 4501 macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); 4502 4503 if (!strncmp(macstr, "Mac:", strlen("Mac:")) && \ 4504 (WM_TOOL_DL_TYPE_FLS != wm_tool_dl_type) && \ 4505 !wm_tool_dl_erase) { 4506 wm_tool_printf("please download the firmware in .fls format.\r\n"); 4507 } else { 4508 ret = 0; 4509 } 4510 } 4511 break; 4512 } 4513 } 4514 } while (err > 0); 4515 } 4516 4517 wm_tool_uart_set_block(0); 4518 4519 return ret; 4520 } 4521 4522 static int wm_tool_xmodem_download(const char *image) 4523 { 4524 FILE *imgfp; 4525 unsigned char packet_data[XMODEM_DATA_SIZE]; 4526 unsigned char frame_data[XMODEM_DATA_SIZE + XMODEM_CRC_SIZE + XMODEM_FRAME_ID_SIZE + 1]; 4527 int complete, retry_num, pack_counter, read_number, write_number = 0, i; 4528 unsigned short crc_value; 4529 unsigned char ack_id; 4530 int sndlen; 4531 int total_size; 4532 int ret = -111; // -111:byte alignment 4533 int percent = 0; 4534 int curImgLen = 0; 4535 wm_tool_firmware_booter_t fbooter; 4536 int packet_data_len = 0; 4537 int packet_data_offset = 0; 4538 4539 imgfp = fopen(image, "rb"); 4540 if (!imgfp) { 4541 wm_tool_printf("can not open image to download.\r\n"); 4542 return -1; 4543 } 4544 total_size=wm_tool_get_file_size(image); 4545 wm_tool_printf("file size %d\r\n", total_size); 4546 sndlen = 0; 4547 pack_counter = 0; 4548 complete = 0; 4549 retry_num = 0; 4550 4551 wm_tool_printf("start download.\r\n"); 4552 wm_tool_printf("0%% ["); 4553 4554 wm_tool_uart_clear(); 4555 4556 wm_tool_uart_set_block(1); 4557 4558 ack_id = XMODEM_ACK; 4559 4560 while (!complete) { 4561 WM_TOOL_DBG_PRINT("switch ack_id = %x\r\n", ack_id); 4562 4563 switch (ack_id) { 4564 case XMODEM_ACK: 4565 { 4566 retry_num = 0; 4567 if (curImgLen == -1) { 4568 read_number = 0; 4569 curImgLen = 0; 4570 pack_counter = 0; 4571 } else { 4572 pack_counter++; 4573 4574 if (packet_data_offset > 0 && packet_data_len > 0) { 4575 WM_TOOL_DBG_PRINT("packet_data_offset = %d, packet_data_len = %d\r\n", \ 4576 packet_data_offset, packet_data_len); 4577 WM_TOOL_DBG_PRINT("header %x %x %x %x\r\n", packet_data[packet_data_offset], \ 4578 packet_data[packet_data_offset + 1], packet_data[packet_data_offset + 2], \ 4579 packet_data[packet_data_offset + 3]); 4580 memmove(packet_data, packet_data + packet_data_offset, packet_data_len); 4581 WM_TOOL_DBG_PRINT("header %x %x %x %x\r\n", packet_data[0], packet_data[1], 4582 packet_data[2], packet_data[3]); 4583 packet_data_offset = 0; 4584 } 4585 read_number = fread(packet_data + packet_data_len, sizeof(char), \ 4586 XMODEM_DATA_SIZE-packet_data_len, imgfp); 4587 read_number += packet_data_len; 4588 packet_data_len = 0; 4589 4590 WM_TOOL_DBG_PRINT("fread = %d\r\n", read_number); 4591 } 4592 if (read_number > 0) { 4593 if (curImgLen == 0) { 4594 memcpy(&fbooter, packet_data, sizeof(wm_tool_firmware_booter_t)); 4595 curImgLen = fbooter.run_img_len; 4596 curImgLen += sizeof(wm_tool_firmware_booter_t); 4597 if ((fbooter.img_type & 256) > 0) { // 256:byte alignment 4598 curImgLen += 128; // 128:byte alignment 4599 } 4600 WM_TOOL_DBG_PRINT("curImgLen %d\r\n", curImgLen); 4601 } 4602 if (read_number > curImgLen) { 4603 WM_TOOL_DBG_PRINT("read_number %d, curImgLen %d\r\n", read_number, curImgLen); 4604 packet_data_len = read_number - curImgLen; 4605 packet_data_offset = curImgLen; 4606 read_number = curImgLen; 4607 curImgLen = -1; 4608 } else { 4609 curImgLen -= read_number; 4610 } 4611 sndlen += read_number; 4612 4613 memset(&frame_data[0], 0, sizeof(frame_data)); 4614 frame_data[0] = XMODEM_HEAD; 4615 frame_data[1] = (char)pack_counter; 4616 frame_data[2] = (char)(255 - frame_data[1]); // 255:byte alignment, 2:array element 4617 4618 for (i = 0; i < read_number; i++) { 4619 frame_data[i + 3] = packet_data[i]; // 3:byte alignment 4620 } 4621 4622 crc_value = wm_tool_get_crc16(&frame_data[3], XMODEM_DATA_SIZE); 4623 4624 frame_data[XMODEM_DATA_SIZE + 3] = 4625 (unsigned char)(crc_value >> 8); // 8:byte alignment, 3:byte alignment 4626 frame_data[XMODEM_DATA_SIZE + 4] = (unsigned char)(crc_value); // 4:byte alignment 4627 4628 write_number = wm_tool_uart_write(frame_data, XMODEM_DATA_SIZE + 5); // 5:byte alignment 4629 if (write_number <= 0) { 4630 wm_tool_printf("write serial error, errno = %d.\r\n", errno); 4631 } 4632 4633 WM_TOOL_DBG_PRINT("waiting for ack, %d, %d ...\r\n", pack_counter, write_number); 4634 4635 if ((wm_tool_uart_read(&ack_id, 1)) <= 0) { 4636 WM_TOOL_DBG_PRINT("waiting ack timeout\r\n"); 4637 complete = 1; 4638 } else { 4639 if (ack_id == XMODEM_ACK) { 4640 int start_percent = 0; 4641 int step = 10; // 10:byte alignment 4642 WM_TOOL_DBG_PRINT("Ok!\r\n"); 4643 if (sndlen * step / total_size > percent) { 4644 percent = sndlen * step / total_size; 4645 wm_tool_printf("#"); 4646 } 4647 if (sndlen % 10240 == 0) { // 10240:byte alignment 4648 } 4649 } else { 4650 WM_TOOL_DBG_PRINT("error = %x!\r\n", ack_id); 4651 } 4652 } 4653 } else { 4654 ack_id = XMODEM_EOT; 4655 4656 WM_TOOL_DBG_PRINT("waiting for complete ack ...\r\n"); 4657 4658 while (ack_id != XMODEM_ACK) { 4659 ack_id = XMODEM_EOT; 4660 4661 write_number = wm_tool_uart_write(&ack_id, 1); 4662 if (write_number <= 0) { 4663 wm_tool_printf("write serial error, errno = %d.\r\n", errno); 4664 } 4665 4666 while ((wm_tool_uart_read(&ack_id, 1)) <= 0) { 4667 } 4668 } 4669 4670 if (sndlen >= total_size) { 4671 complete = 1; 4672 4673 WM_TOOL_DBG_PRINT("ok\r\n"); 4674 4675 wm_tool_printf("] 100%%\r\n"); 4676 4677 wm_tool_printf("download completed.\r\n"); 4678 4679 ret = 0; 4680 } else { 4681 wm_tool_delay_ms(100); // 100:100ms 4682 wm_tool_uart_clear(); 4683 } 4684 } 4685 break; 4686 } 4687 case XMODEM_NAK: 4688 { 4689 if (retry_num++ > 100) { // 100:retry_num 4690 WM_TOOL_DBG_PRINT("retry too many times, quit!\r\n"); 4691 wm_tool_printf("download firmware timeout.\r\n"); 4692 4693 complete = 1; 4694 } else { 4695 write_number = wm_tool_uart_write(frame_data, XMODEM_DATA_SIZE + 5); // 5:byte alignment 4696 if (write_number <= 0) { 4697 wm_tool_printf("write serial error, errno = %d.\r\n", errno); 4698 } 4699 4700 WM_TOOL_DBG_PRINT("retry for ack, %d, %d ...\r\n", pack_counter, write_number); 4701 while ((wm_tool_uart_read(&ack_id, 1)) <= 0) { 4702 } 4703 4704 if (ack_id == XMODEM_ACK) { 4705 WM_TOOL_DBG_PRINT("ok\r\n"); 4706 } else { 4707 WM_TOOL_DBG_PRINT("error!\r\n"); 4708 } 4709 } 4710 break; 4711 } 4712 default: 4713 { 4714 WM_TOOL_DBG_PRINT("fatal error!\r\n"); 4715 WM_TOOL_DBG_PRINT("unknown xmodem protocol [%x].\r\n", ack_id); 4716 wm_tool_printf("\r\ndownload failed, please reset and try again.\r\n"); 4717 4718 complete = 1; 4719 break; 4720 } 4721 } 4722 } 4723 4724 wm_tool_uart_set_block(0); 4725 4726 fclose(imgfp); 4727 4728 return ret; 4729 } 4730 static int wm_tool_download_firmware(void) 4731 { 4732 int ret; 4733 int cnt = 0; 4734 int note = 1; 4735 int timeout = 0; 4736 float timeuse; 4737 time_t start, end; 4738 unsigned char ch; 4739 4740 wm_tool_printf("connecting serial...\r\n"); 4741 4742 ret = wm_tool_uart_open(wm_tool_serial_path); 4743 if (ret) { 4744 wm_tool_printf("can not open serial\r\n"); 4745 return ret; 4746 } 4747 4748 /* In some cases, setting the serial port initialization setting requires a delay. */ 4749 wm_tool_delay_ms(500); // 500:500ms 4750 4751 wm_tool_printf("serial connected.\r\n"); 4752 4753 if (wm_tool_dl_action == WM_TOOL_DL_ACTION_AT) { 4754 if (wm_tool_normal_serial_rate != WM_TOOL_DEFAULT_BAUD_RATE) { 4755 wm_tool_uart_set_speed(wm_tool_normal_serial_rate); 4756 } 4757 4758 ret = wm_tool_uart_write("AT+Z\r\n", strlen("AT+Z\r\n")); 4759 if (ret <= 0) { 4760 wm_tool_printf("reset error.\r\n"); 4761 wm_tool_uart_close(); 4762 return -4; // -4:byte alignment 4763 } 4764 4765 if (wm_tool_normal_serial_rate != WM_TOOL_DEFAULT_BAUD_RATE) { 4766 wm_tool_uart_set_speed(WM_TOOL_DEFAULT_BAUD_RATE); 4767 } 4768 } else if (WM_TOOL_DL_ACTION_RTS == wm_tool_dl_action) { 4769 ret = wm_tool_uart_set_dtr(0); 4770 ret |= wm_tool_uart_set_rts(1); 4771 wm_tool_delay_ms(50); // 50:50ms 4772 ret |= wm_tool_uart_set_dtr(1); 4773 ret |= wm_tool_uart_set_rts(0); 4774 wm_tool_delay_ms(50); // 50:50ms 4775 ret |= wm_tool_uart_set_dtr(0); 4776 if (ret < 0) { 4777 wm_tool_printf("set rts to reboot error.\r\n"); 4778 wm_tool_uart_close(); 4779 return -5; // -5:byte alignment 4780 } 4781 } 4782 4783 wm_tool_printf("wait serial sync..."); 4784 4785 wm_tool_send_esc2uart(500); // 500:used for delay 4786 4787 start = time(NULL); 4788 4789 do { 4790 ret = wm_tool_uart_read(&ch, 1); 4791 4792 WM_TOOL_DBG_PRINT("ret=%d, %x-%c\r\n", ret, ch, ch); 4793 4794 if (ret > 0) { 4795 if ((ch == 'C') || (ch == 'P')) { 4796 cnt++; 4797 } else { 4798 cnt = 0; 4799 } 4800 } else { 4801 wm_tool_send_esc2uart(30); // 30:30ms 4802 } 4803 4804 end = time(NULL); 4805 timeuse = difftime(end, start); 4806 if (timeuse >= 1) { 4807 wm_tool_printf("."); 4808 4809 timeout++; 4810 if ((timeout >= (WM_TOOL_DOWNLOAD_TIMEOUT_SEC / 10)) && note) { // 10:byte alignment 4811 wm_tool_printf("\r\nplease manually reset the device.\r\n"); 4812 note = 0; 4813 } else if (timeout > WM_TOOL_DOWNLOAD_TIMEOUT_SEC) { 4814 wm_tool_uart_close(); 4815 wm_tool_printf("\r\nserial sync timeout.\r\n"); 4816 return -6; // -6:byte alignment 4817 } 4818 4819 start = time(NULL); 4820 } 4821 } while (cnt < 3); // 3:loop condition 4822 4823 wm_tool_printf("\r\nserial sync sucess.\r\n"); 4824 4825 ret = wm_tool_query_mac(); 4826 if (ret) { 4827 wm_tool_uart_close(); 4828 wm_tool_printf("download failed.\r\n"); 4829 return ret; 4830 } 4831 4832 if (WM_TOOL_DL_ERASE_ALL == wm_tool_dl_erase) { 4833 ret = wm_tool_erase_image(WM_TOOL_DL_ERASE_ALL); 4834 if (ret) { 4835 wm_tool_uart_close(); 4836 wm_tool_printf("failed to erase.\r\n"); 4837 return ret; 4838 } 4839 } 4840 4841 if (!wm_tool_download_image && wm_tool_dl_erase) { 4842 return 0; 4843 } 4844 4845 if (wm_tool_download_serial_rate != WM_TOOL_DEFAULT_BAUD_RATE) { 4846 ret = wm_tool_set_wifi_chip_speed(wm_tool_download_serial_rate); 4847 if (ret > 0) { 4848 wm_tool_delay_ms(1 * 1000); // 1000:ms 4849 wm_tool_uart_set_speed(wm_tool_download_serial_rate); 4850 } 4851 } 4852 4853 ret = wm_tool_xmodem_download(wm_tool_download_image); 4854 4855 if (wm_tool_download_serial_rate != WM_TOOL_DEFAULT_BAUD_RATE) { 4856 wm_tool_delay_ms(1 * 1000); // 1000:ms 4857 wm_tool_set_wifi_chip_speed(WM_TOOL_DEFAULT_BAUD_RATE); 4858 wm_tool_delay_ms(1 * 1000); // 1000:ms 4859 } 4860 4861 if (!ret) { 4862 if (WM_TOOL_DL_TYPE_FLS == wm_tool_dl_type) { 4863 if (WM_TOOL_DL_ACTION_RTS == wm_tool_dl_action) { /* auto reset */ 4864 wm_tool_uart_set_dtr(0); 4865 wm_tool_uart_set_rts(1); 4866 wm_tool_delay_ms(50); // 50:ms 4867 wm_tool_uart_set_dtr(1); 4868 wm_tool_uart_set_rts(0); 4869 wm_tool_delay_ms(50); // 50:ms 4870 wm_tool_uart_set_dtr(0); 4871 } else { 4872 wm_tool_printf("please manually reset the device.\r\n"); 4873 } 4874 } 4875 } 4876 4877 wm_tool_uart_close(); 4878 4879 return ret; 4880 } 4881 4882 static void wm_tool_show_local_com(void) 4883 { 4884 #if defined(__APPLE__) && defined(__MACH__) 4885 char *comstr = "tty.usbserial"; 4886 #elif defined(__CYGWIN__) 4887 int num; 4888 char *comstr = "ttyS"; 4889 #elif defined(__linux__) 4890 char *comstr = "ttyUSB"; 4891 #endif 4892 4893 #if defined(__APPLE__) || defined(__MACH__) || defined(__CYGWIN__) || defined(__linux__) 4894 4895 DIR *dir; 4896 struct dirent *file; 4897 4898 dir = opendir("/dev"); 4899 if (dir) { 4900 while ((file = readdir(dir)) != NULL) { 4901 if ((strncmp(file->d_name, comstr, strlen(comstr)) == 0) && (file->d_type == DT_CHR)) { 4902 #if defined(__CYGWIN__) 4903 num = atoi(file->d_name + strlen(comstr)); 4904 wm_tool_printf("COM%d ", num + 1); 4905 #else 4906 wm_tool_printf("%s ", file->d_name); 4907 #endif 4908 } 4909 } 4910 closedir(dir); 4911 wm_tool_printf("\r\n"); 4912 } 4913 4914 #elif defined(__MINGW32__) 4915 4916 LONG ret; 4917 HKEY key; 4918 DWORD i = 0; 4919 DWORD knlen; 4920 char kname[WM_TOOL_PATH_MAX] = {0}; 4921 DWORD kvlen; 4922 char kvalue[WM_TOOL_PATH_MAX] = {0}; 4923 REGSAM kmask = KEY_READ; 4924 4925 #if defined(KEY_WOW64_64KEY) 4926 BOOL is_64; 4927 4928 if (IsWow64Process(GetCurrentProcess(), &is_64)) { 4929 if (is_64) 4930 kmask |= KEY_WOW64_64KEY; 4931 } 4932 #endif 4933 4934 ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), \ 4935 0, NULL, 0, kmask, NULL, &key, NULL); 4936 if (ret != ERROR_SUCCESS) { 4937 return; 4938 } 4939 4940 do { 4941 knlen = sizeof(kname); 4942 kvlen = sizeof(kvalue); 4943 ret = RegEnumValue(key, i, kname, &knlen, 0, NULL, (LPBYTE)kvalue, &kvlen); 4944 if (ret == ERROR_SUCCESS) { 4945 if (strcmp(kvalue, "") != 0) { 4946 wm_tool_printf("%s ", kvalue); 4947 } 4948 } 4949 4950 i++; 4951 } while (ret != ERROR_NO_MORE_ITEMS); 4952 4953 RegCloseKey(key); 4954 4955 wm_tool_printf("\r\n"); 4956 4957 #else 4958 4959 wm_tool_printf("\r\nunsupported system.\r\n"); 4960 4961 #endif 4962 4963 return; 4964 } 4965 static void wm_tool_free_res(void) 4966 { 4967 if (wm_tool_download_image) { 4968 free(wm_tool_download_image); 4969 } 4970 4971 if (wm_tool_output_image) { 4972 free(wm_tool_output_image); 4973 } 4974 4975 if (wm_tool_input_binary) { 4976 free(wm_tool_input_binary); 4977 } 4978 4979 if (wm_tool_secboot_image) { 4980 free(wm_tool_secboot_image); 4981 } 4982 4983 return; 4984 } 4985 4986 int main(int argc, char *argv[]) 4987 { 4988 int ret = 0; 4989 4990 if (!wm_tool_parse_arv(argc, argv)) { 4991 wm_tool_print_usage(argv[0]); 4992 wm_tool_free_res(); 4993 return 0; 4994 } 4995 4996 if (wm_tool_show_usage) { 4997 wm_tool_print_usage(argv[0]); 4998 wm_tool_free_res(); 4999 return 0; 5000 } 5001 5002 if (wm_tool_show_ver) { 5003 wm_tool_print_version(argv[0]); 5004 wm_tool_free_res(); 5005 return 0; 5006 } 5007 5008 if (wm_tool_list_com) { 5009 wm_tool_show_local_com(); 5010 wm_tool_free_res(); 5011 return 0; 5012 } 5013 5014 if (wm_tool_input_binary) { 5015 ret = wm_tool_pack_firmware(); 5016 } 5017 5018 if (wm_tool_download_image || wm_tool_dl_erase) { 5019 ret = wm_tool_download_firmware(); 5020 } 5021 5022 if (wm_tool_show_log_type) { 5023 } 5024 5025 if (ret > 0) { 5026 wm_tool_print_usage(argv[0]); 5027 } 5028 5029 wm_tool_free_res(); 5030 5031 return ret; 5032 }