static int debit_file(gchar *input_file, gchar *output_dir) { gint err = 0; bitstream_parsed_t *bit; bit = parse_bitstream(input_file); if (bit == NULL) { err = -1; goto out; } /* Have some action */ if (framedump) design_write_frames(bit, output_dir); if (unkdump) design_dump_frames(bit, output_dir); /* Just rewrite the bitstream. This is a test for the bitstream-writing code */ if (ofile) bitstream_write(bit,output_dir,ofile); if (sitedump || pipdump || lutdump || bramdump || netdump) { bitstream_analyzed_t *analysis = analyze_bitstream(bit, datadir); if (analysis == NULL) { g_warning("Problem during analysis"); err = -1; goto out_free; } /* print_chip(analysis->chip); */ if (sitedump) dump_sites(analysis, output_dir, suffix); if (pipdump) dump_pips(analysis); if (lutdump) dump_luts(analysis); if (bramdump) dump_bram(analysis); if (netdump) dump_nets(analysis); free_analysis(analysis); } out_free: free_bitstream(bit); out: return err; }
int lzw_compress(lzw_t *lzw, read_func_t src_r, write_func_t dst_w, void *ctx) { bitstream_t bs_w; bitstream_init_w(&bs_w, dst_w, ctx); dst_w(ctx, &lzw->code_len, 1); uint8_t buf[LZW_BUFFER_SIZE*2]; uint8_t *inp = buf; size_t r_bytes = src_r(ctx, buf, LZW_BUFFER_SIZE*2); while (inp<=buf+r_bytes) { // advance buffer if (inp-buf>LZW_BUFFER_SIZE) { memcpy(buf, inp, r_bytes-(inp-buf)); r_bytes -= inp-buf; r_bytes += src_r(ctx, buf+r_bytes, LZW_BUFFER_SIZE+(LZW_BUFFER_SIZE-r_bytes)); inp = buf; } // find longest inp match in the dictionary int outc = -1; for (int i = lzw->dict_i-1; i>=0; i--) { if (lzw->dict[i].size && !memcmp(lzw->dict[i].data, inp, lzw->dict[i].size)) { outc = i; break; } } assert(outc>=0); bitstream_write(&bs_w, outc, lzw->code_len); inp += lzw->dict[outc].size; // expand the dictionary if necessary if (lzw->dict_i==(1 << lzw->code_len)) { lzw->code_len++; lzw_resize_dict(lzw); } // add this match, along with the next character, to the dictionary lzw_dict_entry_t *di = &lzw->dict[lzw->dict_i]; di->size = lzw->dict[outc].size+1; di->data = malloc(di->size); memcpy(di->data, lzw->dict[outc].data, lzw->dict[outc].size); di->data[di->size-1] = *inp; lzw->dict_i++; } return 0; }
ssize_t th_lzss( thtk_io_t* input, size_t input_size, thtk_io_t* output, thtk_error_t** error) { struct bitstream bs; hash_t hash; unsigned char dict[LZSS_DICTSIZE]; unsigned int dict_head = 1; unsigned int dict_head_key; unsigned int waiting_bytes = 0; size_t bytes_read = 0; unsigned int i; unsigned char c; if (!input || !output) { thtk_error_new(error, "input or output is NULL"); return -1; } bitstream_init(&bs, output); memset(&hash, 0, sizeof(hash)); memset(dict, 0, sizeof(dict)); /* Fill the forward-looking buffer. */ for (i = 0; i < LZSS_MAX_MATCH && i < input_size; ++i) { int ret = thtk_io_read(input, &c, 1, error); if (ret == -1) { return -1; } else if (ret != 1) { break; } ++bytes_read; dict[dict_head + i] = c; waiting_bytes++; } dict_head_key = generate_key(dict, dict_head); while (waiting_bytes) { unsigned int match_len = LZSS_MIN_MATCH - 1; unsigned int match_offset = 0; unsigned int offset; /* Find a good match. */ for (offset = hash.hash[dict_head_key]; offset != HASH_NULL && waiting_bytes > match_len; offset = hash.next[offset]) { /* First check a character further ahead to see if this match can * be any longer than the current match. */ if (dict[(dict_head + match_len) & LZSS_DICTSIZE_MASK] == dict[(offset + match_len) & LZSS_DICTSIZE_MASK]) { /* Then check the previous characters. */ for (i = 0; i < match_len && (dict[(dict_head + i) & LZSS_DICTSIZE_MASK] == dict[(offset + i) & LZSS_DICTSIZE_MASK]); ++i) ; if (i < match_len) continue; /* Finally try to extend the match. */ for (++match_len; match_len < waiting_bytes && (dict[(dict_head + match_len) & LZSS_DICTSIZE_MASK] == dict[(offset + match_len) & LZSS_DICTSIZE_MASK]); ++match_len) ; match_offset = offset; } } /* Write data to the output buffer. */ if (match_len < LZSS_MIN_MATCH) { match_len = 1; bitstream_write1(&bs, 1); bitstream_write(&bs, 8, dict[dict_head]); } else { bitstream_write1(&bs, 0); bitstream_write(&bs, 13, match_offset); bitstream_write(&bs, 4, match_len - LZSS_MIN_MATCH); } /* Add bytes to the dictionary. */ for (i = 0; i < match_len; ++i) { const unsigned int offset = (dict_head + LZSS_MAX_MATCH) & LZSS_DICTSIZE_MASK; if (offset != HASH_NULL) list_remove(&hash, generate_key(dict, offset), offset); if (dict_head != HASH_NULL) list_add(&hash, dict_head_key, dict_head); if (bytes_read < input_size) { int ret = thtk_io_read(input, &c, 1, error); if (ret == 1) { dict[offset] = c; ++bytes_read; } else if (ret == 0) { --waiting_bytes; } else { return -1; } } else { --waiting_bytes; } dict_head = (dict_head + 1) & LZSS_DICTSIZE_MASK; dict_head_key = generate_key(dict, dict_head); } } bitstream_write1(&bs, 0); bitstream_write(&bs, 13, HASH_NULL); bitstream_write(&bs, 4, 0); bitstream_finish(&bs); return bs.byte_count; }