Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/archival/libunarchive/decompress_unlzma.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/archival/libunarchive/decompress_unlzma.c
r821 r1770 1 /* vi: setts=4: */1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 3 * Small lzma deflate implementation. … … 13 13 #include "unarchive.h" 14 14 15 #if def CONFIG_FEATURE_LZMA_FAST16 # define speed_inline A TTRIBUTE_ALWAYS_INLINE15 #if ENABLE_FEATURE_LZMA_FAST 16 # define speed_inline ALWAYS_INLINE 17 17 #else 18 18 # define speed_inline … … 23 23 int fd; 24 24 uint8_t *ptr; 25 uint8_t *buffer; 25 26 /* Was keeping rc on stack in unlzma and separately allocating buffer, 27 * but with "buffer 'attached to' allocated rc" code is smaller: */ 28 /* uint8_t *buffer; */ 29 #define RC_BUFFER ((uint8_t*)(rc+1)) 30 26 31 uint8_t *buffer_end; 27 int buffer_size; 32 33 /* Had provisions for variable buffer, but we don't need it here */ 34 /* int buffer_size; */ 35 #define RC_BUFFER_SIZE 0x10000 36 28 37 uint32_t code; 29 38 uint32_t range; … … 31 40 } rc_t; 32 41 33 34 42 #define RC_TOP_BITS 24 35 43 #define RC_MOVE_BITS 5 … … 40 48 static void rc_read(rc_t * rc) 41 49 { 42 rc->buffer_size = read(rc->fd, rc->buffer, rc->buffer_size);43 if ( rc->buffer_size <= 0)50 int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE); 51 if (buffer_size <= 0) 44 52 bb_error_msg_and_die("unexpected EOF"); 45 rc->ptr = rc->buffer;46 rc->buffer_end = rc->buffer + rc->buffer_size;53 rc->ptr = RC_BUFFER; 54 rc->buffer_end = RC_BUFFER + buffer_size; 47 55 } 48 56 49 57 /* Called once */ 50 static void rc_init(rc_t * rc, int fd, int buffer_size)58 static rc_t* rc_init(int fd) /*, int buffer_size) */ 51 59 { 52 60 int i; 61 rc_t* rc; 62 63 rc = xmalloc(sizeof(rc_t) + RC_BUFFER_SIZE); 53 64 54 65 rc->fd = fd; 55 rc->buffer = xmalloc(buffer_size); 56 rc->buffer_size = buffer_size; 57 rc->buffer_end = rc->buffer + rc->buffer_size; 66 /* rc->buffer_size = buffer_size; */ 67 rc->buffer_end = RC_BUFFER + RC_BUFFER_SIZE; 58 68 rc->ptr = rc->buffer_end; 59 69 … … 65 75 rc->code = (rc->code << 8) | *rc->ptr++; 66 76 } 67 } 68 69 /* Called once. TODO: bb_maybe_free() */ 70 static ATTRIBUTE_ALWAYS_INLINE void rc_free(rc_t * rc) 77 return rc; 78 } 79 80 /* Called once */ 81 static ALWAYS_INLINE void rc_free(rc_t * rc) 71 82 { 72 83 if (ENABLE_FEATURE_CLEAN_UP) 73 free(rc ->buffer);84 free(rc); 74 85 } 75 86 … … 82 93 rc->code = (rc->code << 8) | *rc->ptr++; 83 94 } 84 static A TTRIBUTE_ALWAYS_INLINE void rc_normalize(rc_t * rc)95 static ALWAYS_INLINE void rc_normalize(rc_t * rc) 85 96 { 86 97 if (rc->range < (1 << RC_TOP_BITS)) { … … 89 100 } 90 101 91 /* Called 9 times */102 /* rc_is_bit_0 is called 9 times */ 92 103 /* Why rc_is_bit_0_helper exists? 93 * Because we want to always expose (rc->code < rc->bound) to optimizer 104 * Because we want to always expose (rc->code < rc->bound) to optimizer. 105 * Thus rc_is_bit_0 is always inlined, and rc_is_bit_0_helper is inlined 106 * only if we compile for speed. 94 107 */ 95 108 static speed_inline uint32_t rc_is_bit_0_helper(rc_t * rc, uint16_t * p) … … 99 112 return rc->bound; 100 113 } 101 static A TTRIBUTE_ALWAYS_INLINE int rc_is_bit_0(rc_t * rc, uint16_t * p)114 static ALWAYS_INLINE int rc_is_bit_0(rc_t * rc, uint16_t * p) 102 115 { 103 116 uint32_t t = rc_is_bit_0_helper(rc, p); … … 133 146 134 147 /* Called once */ 135 static A TTRIBUTE_ALWAYS_INLINE int rc_direct_bit(rc_t * rc)148 static ALWAYS_INLINE int rc_direct_bit(rc_t * rc) 136 149 { 137 150 rc_normalize(rc); … … 164 177 165 178 166 #define LZMA_BASE_SIZE 1846 167 #define LZMA_LIT_SIZE 768 168 169 #define LZMA_NUM_POS_BITS_MAX 4 170 171 #define LZMA_LEN_NUM_LOW_BITS 3 172 #define LZMA_LEN_NUM_MID_BITS 3 173 #define LZMA_LEN_NUM_HIGH_BITS 8 174 175 #define LZMA_LEN_CHOICE 0 176 #define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1) 177 #define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1) 178 #define LZMA_LEN_MID (LZMA_LEN_LOW \ 179 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))) 180 #define LZMA_LEN_HIGH (LZMA_LEN_MID \ 181 +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))) 182 #define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)) 183 184 #define LZMA_NUM_STATES 12 185 #define LZMA_NUM_LIT_STATES 7 186 187 #define LZMA_START_POS_MODEL_INDEX 4 188 #define LZMA_END_POS_MODEL_INDEX 14 189 #define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1)) 190 191 #define LZMA_NUM_POS_SLOT_BITS 6 192 #define LZMA_NUM_LEN_TO_POS_STATES 4 193 194 #define LZMA_NUM_ALIGN_BITS 4 195 196 #define LZMA_MATCH_MIN_LEN 2 197 198 #define LZMA_IS_MATCH 0 199 #define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES <<LZMA_NUM_POS_BITS_MAX)) 200 #define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES) 201 #define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES) 202 #define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES) 203 #define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES) 204 #define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \ 205 + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) 206 #define LZMA_SPEC_POS (LZMA_POS_SLOT \ 207 +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)) 208 #define LZMA_ALIGN (LZMA_SPEC_POS \ 209 + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX) 210 #define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)) 211 #define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS) 212 #define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS) 213 214 215 int unlzma(int src_fd, int dst_fd) 216 { 179 /* #defines will force compiler to compute/optimize each one with each usage. 180 * Have heart and use enum instead. */ 181 enum { 182 LZMA_BASE_SIZE = 1846, 183 LZMA_LIT_SIZE = 768, 184 185 LZMA_NUM_POS_BITS_MAX = 4, 186 187 LZMA_LEN_NUM_LOW_BITS = 3, 188 LZMA_LEN_NUM_MID_BITS = 3, 189 LZMA_LEN_NUM_HIGH_BITS = 8, 190 191 LZMA_LEN_CHOICE = 0, 192 LZMA_LEN_CHOICE_2 = (LZMA_LEN_CHOICE + 1), 193 LZMA_LEN_LOW = (LZMA_LEN_CHOICE_2 + 1), 194 LZMA_LEN_MID = (LZMA_LEN_LOW \ 195 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))), 196 LZMA_LEN_HIGH = (LZMA_LEN_MID \ 197 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))), 198 LZMA_NUM_LEN_PROBS = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)), 199 200 LZMA_NUM_STATES = 12, 201 LZMA_NUM_LIT_STATES = 7, 202 203 LZMA_START_POS_MODEL_INDEX = 4, 204 LZMA_END_POS_MODEL_INDEX = 14, 205 LZMA_NUM_FULL_DISTANCES = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)), 206 207 LZMA_NUM_POS_SLOT_BITS = 6, 208 LZMA_NUM_LEN_TO_POS_STATES = 4, 209 210 LZMA_NUM_ALIGN_BITS = 4, 211 212 LZMA_MATCH_MIN_LEN = 2, 213 214 LZMA_IS_MATCH = 0, 215 LZMA_IS_REP = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), 216 LZMA_IS_REP_G0 = (LZMA_IS_REP + LZMA_NUM_STATES), 217 LZMA_IS_REP_G1 = (LZMA_IS_REP_G0 + LZMA_NUM_STATES), 218 LZMA_IS_REP_G2 = (LZMA_IS_REP_G1 + LZMA_NUM_STATES), 219 LZMA_IS_REP_0_LONG = (LZMA_IS_REP_G2 + LZMA_NUM_STATES), 220 LZMA_POS_SLOT = (LZMA_IS_REP_0_LONG \ 221 + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), 222 LZMA_SPEC_POS = (LZMA_POS_SLOT \ 223 + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)), 224 LZMA_ALIGN = (LZMA_SPEC_POS \ 225 + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX), 226 LZMA_LEN_CODER = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)), 227 LZMA_REP_LEN_CODER = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS), 228 LZMA_LITERAL = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS), 229 }; 230 231 232 USE_DESKTOP(long long) int 233 unpack_lzma_stream(int src_fd, int dst_fd) 234 { 235 USE_DESKTOP(long long total_written = 0;) 217 236 lzma_header_t header; 218 237 int lc, pb, lp; … … 225 244 int num_bits; 226 245 int num_probs; 227 rc_t rc;246 rc_t *rc; 228 247 int i, mi; 229 248 uint8_t *buffer; … … 234 253 uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; 235 254 236 if (read(src_fd, &header, sizeof(header)) != sizeof(header)) 237 bb_error_msg_and_die("can't read header"); 255 xread(src_fd, &header, sizeof(header)); 238 256 239 257 if (header.pos >= (9 * 5 * 5)) … … 260 278 p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; 261 279 262 rc _init(&rc, src_fd, 0x10000);280 rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */ 263 281 264 282 while (global_pos + buffer_pos < header.dst_size) { … … 267 285 prob = 268 286 p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state; 269 if (rc_is_bit_0( &rc, prob)) {287 if (rc_is_bit_0(rc, prob)) { 270 288 mi = 1; 271 rc_update_bit_0( &rc, prob);289 rc_update_bit_0(rc, prob); 272 290 prob = (p + LZMA_LITERAL + (LZMA_LIT_SIZE 273 291 * ((((buffer_pos + global_pos) & literal_pos_mask) << lc) … … 287 305 bit = match_byte & 0x100; 288 306 prob_lit = prob + 0x100 + bit + mi; 289 if (rc_get_bit( &rc, prob_lit, &mi)) {307 if (rc_get_bit(rc, prob_lit, &mi)) { 290 308 if (!bit) 291 309 break; … … 298 316 while (mi < 0x100) { 299 317 prob_lit = prob + mi; 300 rc_get_bit( &rc, prob_lit, &mi);318 rc_get_bit(rc, prob_lit, &mi); 301 319 } 302 320 previous_byte = (uint8_t) mi; … … 306 324 buffer_pos = 0; 307 325 global_pos += header.dict_size; 308 write(dst_fd, buffer, header.dict_size); 326 if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) 327 goto bad; 328 USE_DESKTOP(total_written += header.dict_size;) 309 329 } 310 330 if (state < 4) … … 318 338 uint16_t *prob_len; 319 339 320 rc_update_bit_1( &rc, prob);340 rc_update_bit_1(rc, prob); 321 341 prob = p + LZMA_IS_REP + state; 322 if (rc_is_bit_0( &rc, prob)) {323 rc_update_bit_0( &rc, prob);342 if (rc_is_bit_0(rc, prob)) { 343 rc_update_bit_0(rc, prob); 324 344 rep3 = rep2; 325 345 rep2 = rep1; … … 328 348 prob = p + LZMA_LEN_CODER; 329 349 } else { 330 rc_update_bit_1( &rc, prob);350 rc_update_bit_1(rc, prob); 331 351 prob = p + LZMA_IS_REP_G0 + state; 332 if (rc_is_bit_0( &rc, prob)) {333 rc_update_bit_0( &rc, prob);352 if (rc_is_bit_0(rc, prob)) { 353 rc_update_bit_0(rc, prob); 334 354 prob = (p + LZMA_IS_REP_0_LONG 335 355 + (state << LZMA_NUM_POS_BITS_MAX) + pos_state); 336 if (rc_is_bit_0( &rc, prob)) {337 rc_update_bit_0( &rc, prob);356 if (rc_is_bit_0(rc, prob)) { 357 rc_update_bit_0(rc, prob); 338 358 339 359 state = state < LZMA_NUM_LIT_STATES ? 9 : 11; … … 346 366 buffer_pos = 0; 347 367 global_pos += header.dict_size; 348 write(dst_fd, buffer, header.dict_size); 368 if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) 369 goto bad; 370 USE_DESKTOP(total_written += header.dict_size;) 349 371 } 350 372 continue; 351 373 } else { 352 rc_update_bit_1( &rc, prob);374 rc_update_bit_1(rc, prob); 353 375 } 354 376 } else { 355 377 uint32_t distance; 356 378 357 rc_update_bit_1( &rc, prob);379 rc_update_bit_1(rc, prob); 358 380 prob = p + LZMA_IS_REP_G1 + state; 359 if (rc_is_bit_0( &rc, prob)) {360 rc_update_bit_0( &rc, prob);381 if (rc_is_bit_0(rc, prob)) { 382 rc_update_bit_0(rc, prob); 361 383 distance = rep1; 362 384 } else { 363 rc_update_bit_1( &rc, prob);385 rc_update_bit_1(rc, prob); 364 386 prob = p + LZMA_IS_REP_G2 + state; 365 if (rc_is_bit_0( &rc, prob)) {366 rc_update_bit_0( &rc, prob);387 if (rc_is_bit_0(rc, prob)) { 388 rc_update_bit_0(rc, prob); 367 389 distance = rep2; 368 390 } else { 369 rc_update_bit_1( &rc, prob);391 rc_update_bit_1(rc, prob); 370 392 distance = rep3; 371 393 rep3 = rep2; … … 381 403 382 404 prob_len = prob + LZMA_LEN_CHOICE; 383 if (rc_is_bit_0( &rc, prob_len)) {384 rc_update_bit_0( &rc, prob_len);405 if (rc_is_bit_0(rc, prob_len)) { 406 rc_update_bit_0(rc, prob_len); 385 407 prob_len = (prob + LZMA_LEN_LOW 386 408 + (pos_state << LZMA_LEN_NUM_LOW_BITS)); … … 388 410 num_bits = LZMA_LEN_NUM_LOW_BITS; 389 411 } else { 390 rc_update_bit_1( &rc, prob_len);412 rc_update_bit_1(rc, prob_len); 391 413 prob_len = prob + LZMA_LEN_CHOICE_2; 392 if (rc_is_bit_0( &rc, prob_len)) {393 rc_update_bit_0( &rc, prob_len);414 if (rc_is_bit_0(rc, prob_len)) { 415 rc_update_bit_0(rc, prob_len); 394 416 prob_len = (prob + LZMA_LEN_MID 395 417 + (pos_state << LZMA_LEN_NUM_MID_BITS)); … … 397 419 num_bits = LZMA_LEN_NUM_MID_BITS; 398 420 } else { 399 rc_update_bit_1( &rc, prob_len);421 rc_update_bit_1(rc, prob_len); 400 422 prob_len = prob + LZMA_LEN_HIGH; 401 423 offset = ((1 << LZMA_LEN_NUM_LOW_BITS) … … 404 426 } 405 427 } 406 rc_bit_tree_decode( &rc, prob_len, num_bits, &len);428 rc_bit_tree_decode(rc, prob_len, num_bits, &len); 407 429 len += offset; 408 430 … … 417 439 LZMA_NUM_LEN_TO_POS_STATES - 1) 418 440 << LZMA_NUM_POS_SLOT_BITS); 419 rc_bit_tree_decode( &rc, prob, LZMA_NUM_POS_SLOT_BITS,441 rc_bit_tree_decode(rc, prob, LZMA_NUM_POS_SLOT_BITS, 420 442 &pos_slot); 421 443 if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { … … 428 450 num_bits -= LZMA_NUM_ALIGN_BITS; 429 451 while (num_bits--) 430 rep0 = (rep0 << 1) | rc_direct_bit( &rc);452 rep0 = (rep0 << 1) | rc_direct_bit(rc); 431 453 prob = p + LZMA_ALIGN; 432 454 rep0 <<= LZMA_NUM_ALIGN_BITS; … … 436 458 mi = 1; 437 459 while (num_bits--) { 438 if (rc_get_bit( &rc, prob + mi, &mi))460 if (rc_get_bit(rc, prob + mi, &mi)) 439 461 rep0 |= i; 440 462 i <<= 1; … … 457 479 buffer_pos = 0; 458 480 global_pos += header.dict_size; 459 write(dst_fd, buffer, header.dict_size); 481 if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) 482 goto bad; 483 USE_DESKTOP(total_written += header.dict_size;) 460 484 } 461 485 len--; … … 464 488 } 465 489 466 write(dst_fd, buffer, buffer_pos); 467 rc_free(&rc); 468 return 0; 469 } 470 471 /* vi:set ts=4: */ 490 491 if (full_write(dst_fd, buffer, buffer_pos) != buffer_pos) { 492 bad: 493 rc_free(rc); 494 return -1; 495 } 496 rc_free(rc); 497 USE_DESKTOP(total_written += buffer_pos;) 498 return USE_DESKTOP(total_written) + 0; 499 }
Note:
See TracChangeset
for help on using the changeset viewer.