示例#1
0
文件: deflate.c 项目: evegard/pngview
int deflate_process_huffman(char *buf, int pos, bitstream_t *bitstream,
    htree_t *htree_lit, htree_t *htree_dist)
{
    htree_t *literal, *distance;

    do {
        literal = huffman_get_symbol(htree_lit, bitstream);

        if (literal->symbol < 256) {
            buf[pos++] = literal->symbol;
        } else if (literal->symbol > 256) {
            int extra = deflate_extra_bits_for_literal(literal->symbol);
            int length = read_bits(bitstream, extra);
            length += deflate_length_for_literal(literal->symbol);

            distance = huffman_get_symbol(htree_dist, bitstream);

            extra = deflate_extra_bits_for_distance(distance->symbol);
            int dist = read_bits(bitstream, extra);
            dist += deflate_length_for_distance(distance->symbol);

            for (int i = 0; i < length; i++) {
                buf[pos + i] = buf[pos - dist + i];
            }
            pos += length;
        }
    } while (literal->symbol != 256);

    return pos;
}
示例#2
0
文件: deflate.c 项目: evegard/pngview
void deflate_parse_htrees(bitstream_t *bitstream,
    htree_t **htree_lit, htree_t **htree_dist)
{
    int hlit = read_bits(bitstream, 5) + 257;
    int hdist = read_bits(bitstream, 5) + 1;
    int hclen = read_bits(bitstream, 4) + 4;

    int cl_order[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
    int cl_lengths[19] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

    for (int i = 0; i < hclen; i++) {
        cl_lengths[cl_order[i]] = read_bits(bitstream, 3);
    }

    htree_t *ht_cl = huffman_create_tree(19, cl_lengths);

    int tot = hlit + hdist;
    int *lengths = calloc(tot, sizeof(int));
    int cur_len = 0;

    while (cur_len < tot) {
        htree_t *cur_cl = huffman_get_symbol(ht_cl, bitstream);
        int symbol = 0, repeats = 1;

        if (cur_cl->symbol == 16) {
            /* Symbol 16: Copy previous length 3-6 times. */
            symbol = lengths[cur_len - 1];
            repeats = read_bits(bitstream, 2) + 3;
        } else if (cur_cl->symbol == 17) {
            /* Symbol 17: Repeat 0 for 3-10 times. */
            repeats = read_bits(bitstream, 3) + 3;
        } else if (cur_cl->symbol == 18) {
            /* Symbol 18: Repeat 0 for 11-138 times. */
            repeats = read_bits(bitstream, 7) + 11;
        } else {
            /* Otherwise: Emit length. */
            symbol = cur_cl->symbol;
        }

        for (int i = 0; i < repeats; i++) {
            lengths[cur_len++] = symbol;
        }
    }

    if (cur_len > tot) {
        printf("Error: Code tree lengths defined too far\n");
    }

    /* We don't need the code length Huffman tree anymore. */
    huffman_free_tree(ht_cl);

    int *lit_lengths = &lengths[0];
    int *dist_lengths = &lengths[hlit];

    *htree_lit = huffman_create_tree(hlit, lit_lengths);
    *htree_dist = huffman_create_tree(hdist, dist_lengths);

    /* Free the data arrays used to create the Huffman trees. */
    free(lengths);
}
示例#3
0
int rle_get(io_buffer * input, rle_state * s)
{
  // 
  // Reverse the encoding performed by rle_bits.
  // 

  unsigned char output_word = 0;
  int output_bits = 8;

  while (1) {
    if (s->run_length == 0) {
      s->running_digit = !s->running_digit;
      int run_length =
	  huffman_get_symbol(&s->huffman[s->running_digit], input);

      if (run_length < 0) {
	return -1;
      } else if(run_length == s->huffman_length[s->running_digit]) {
        s->run_length = io_buffer_get(input, 24);
      } else {
	s->run_length = run_length;
      }
    }

    while (s->run_length > 0) {

      if (output_bits > s->run_length) {
	output_word = output_word << s->run_length;
	if (s->running_digit == 1) {
	  output_word |= ones[s->run_length];
	}
	output_bits -= s->run_length;
	s->run_length = 0;
      } else {
	output_word = output_word << output_bits;
	if (s->running_digit == 1) {
	  output_word |= ones[output_bits];
	}
	s->run_length -= output_bits;

	return output_word;
      }
    }

  }
}