/* * Return a block of data from the decompression buffer. Decompress more * as necessary. */ static ssize_t compress_filter_read(struct archive_read_filter *self, const void **pblock) { struct private_data *state; unsigned char *p, *start, *end; int ret; state = (struct private_data *)self->data; if (state->end_of_stream) { *pblock = NULL; return (0); } p = start = (unsigned char *)state->out_block; end = start + state->out_block_size; while (p < end && !state->end_of_stream) { if (state->stackp > state->stack) { *p++ = *--state->stackp; } else { ret = next_code(self); if (ret == -1) state->end_of_stream = ret; else if (ret != ARCHIVE_OK) return (ret); } } *pblock = start; return (p - start); }
/* * Setup the callbacks. */ static int compress_bidder_init(struct archive_read_filter *self) { struct private_data *state; static const size_t out_block_size = 64 * 1024; void *out_block; int code; self->code = ARCHIVE_FILTER_COMPRESS; self->name = "compress (.Z)"; state = (struct private_data *)calloc(sizeof(*state), 1); out_block = malloc(out_block_size); if (state == NULL || out_block == NULL) { free(out_block); free(state); archive_set_error(&self->archive->archive, ENOMEM, "Can't allocate data for %s decompression", self->name); return (ARCHIVE_FATAL); } self->data = state; state->out_block_size = out_block_size; state->out_block = out_block; self->read = compress_filter_read; self->skip = NULL; /* not supported */ self->close = compress_filter_close; /* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */ (void)getbits(self, 8); /* Skip first signature byte. */ (void)getbits(self, 8); /* Skip second signature byte. */ code = getbits(self, 8); state->maxcode_bits = code & 0x1f; state->maxcode = (1 << state->maxcode_bits); state->use_reset_code = code & 0x80; /* Initialize decompressor. */ state->free_ent = 256; state->stackp = state->stack; if (state->use_reset_code) state->free_ent++; state->bits = 9; state->section_end_code = (1<<state->bits) - 1; state->oldcode = -1; for (code = 255; code >= 0; code--) { state->prefix[code] = 0; state->suffix[code] = code; } next_code(self); return (ARCHIVE_OK); }
int main() { uint64_t first_code = 20151125LL; int row = 1; int col = 1; while (row != 2947 || col != 3029) { first_code = next_code(first_code); if (row == 1) { row = col + 1; col = 1; } else { row--; col++; } } printf("%d %d %llu\n", row, col, first_code); }
/* * Process the next code and fill the stack with the expansion * of the code. Returns ARCHIVE_FATAL if there is a fatal I/O or * format error, ARCHIVE_EOF if we hit end of data, ARCHIVE_OK otherwise. */ static int next_code(struct archive_read_filter *self) { struct private_data *state = (struct private_data *)self->data; int code, newcode; static int debug_buff[1024]; static unsigned debug_index; code = newcode = getbits(self, state->bits); if (code < 0) return (code); debug_buff[debug_index++] = code; if (debug_index >= sizeof(debug_buff)/sizeof(debug_buff[0])) debug_index = 0; /* If it's a reset code, reset the dictionary. */ if ((code == 256) && state->use_reset_code) { /* * The original 'compress' implementation blocked its * I/O in a manner that resulted in junk bytes being * inserted after every reset. The next section skips * this junk. (Yes, the number of *bytes* to skip is * a function of the current *bit* length.) */ int skip_bytes = state->bits - (state->bytes_in_section % state->bits); skip_bytes %= state->bits; state->bits_avail = 0; /* Discard rest of this byte. */ while (skip_bytes-- > 0) { code = getbits(self, 8); if (code < 0) return (code); } /* Now, actually do the reset. */ state->bytes_in_section = 0; state->bits = 9; state->section_end_code = (1 << state->bits) - 1; state->free_ent = 257; state->oldcode = -1; return (next_code(self)); } if (code > state->free_ent) { /* An invalid code is a fatal error. */ archive_set_error(&(self->archive->archive), -1, "Invalid compressed data"); return (ARCHIVE_FATAL); } /* Special case for KwKwK string. */ if (code >= state->free_ent) { *state->stackp++ = state->finbyte; code = state->oldcode; } /* Generate output characters in reverse order. */ while (code >= 256) { *state->stackp++ = state->suffix[code]; code = state->prefix[code]; } *state->stackp++ = state->finbyte = code; /* Generate the new entry. */ code = state->free_ent; if (code < state->maxcode && state->oldcode >= 0) { state->prefix[code] = state->oldcode; state->suffix[code] = state->finbyte; ++state->free_ent; } if (state->free_ent > state->section_end_code) { state->bits++; state->bytes_in_section = 0; if (state->bits == state->maxcode_bits) state->section_end_code = state->maxcode; else state->section_end_code = (1 << state->bits) - 1; } /* Remember previous code. */ state->oldcode = newcode; return (ARCHIVE_OK); }