* Decompress a packed data block. Returns the unpacked length if * successful, or negative error codes if not. * * If COMPRESSOR is defined, it also returns the leeway number * (which gets stored at offset 16 into the compressed-file header) * in `*leeway', if `leeway' isn't NULL. */
| 86 | * in `*leeway', if `leeway' isn't NULL. |
| 87 | */ |
| 88 | long rnc_unpack (void *packed, void *unpacked) { |
| 89 | unsigned char *input = (unsigned char*) packed; |
| 90 | unsigned char *output = (unsigned char*) unpacked; |
| 91 | unsigned char *inputend, *outputend; |
| 92 | bit_stream bs; |
| 93 | huf_table raw, dist, len; |
| 94 | unsigned long ch_count; |
| 95 | unsigned long ret_len; |
| 96 | unsigned out_crc; |
| 97 | #ifdef COMPRESSOR |
| 98 | long lee = 0; |
| 99 | #endif |
| 100 | if (blong(input) != RNC_SIGNATURE) |
| 101 | return RNC_FILE_IS_NOT_RNC; |
| 102 | |
| 103 | ret_len = blong (input+4); |
| 104 | outputend = output + ret_len; |
| 105 | inputend = input + 18 + blong(input+8); |
| 106 | |
| 107 | input += 18; /* skip header */ |
| 108 | |
| 109 | /* |
| 110 | * Check the packed-data CRC. Also save the unpacked-data CRC |
| 111 | * for later. |
| 112 | */ |
| 113 | if (rnc_crc(input, (long) (inputend-input)) != bword(input-4)) |
| 114 | return RNC_PACKED_CRC_ERROR; |
| 115 | out_crc = bword(input-6); |
| 116 | |
| 117 | bitread_init (&bs, &input); |
| 118 | bit_advance (&bs, 2, &input); /* discard first two bits */ |
| 119 | |
| 120 | /* |
| 121 | * Process chunks. |
| 122 | */ |
| 123 | while (output < outputend) { |
| 124 | #ifdef COMPRESSOR |
| 125 | long this_lee; |
| 126 | #endif |
| 127 | read_huftable (&raw, &bs, &input); |
| 128 | read_huftable (&dist, &bs, &input); |
| 129 | read_huftable (&len, &bs, &input); |
| 130 | ch_count = bit_read (&bs, 0xFFFF, 16, &input); |
| 131 | |
| 132 | while (1) { |
| 133 | long length, posn; |
| 134 | |
| 135 | length = huf_read (&raw, &bs, &input); |
| 136 | if (length == -1) |
| 137 | return RNC_HUF_DECODE_ERROR; |
| 138 | if (length) { |
| 139 | while (length--) |
| 140 | *output++ = *input++; |
| 141 | bitread_fix (&bs, &input); |
| 142 | } |
| 143 | if (--ch_count <= 0) |
| 144 | break; |
| 145 |
no test coverage detected