⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lz77_decomp.c

📁 Develop Zigbee network real-time Os
💻 C
字号:
/************************************************************************** * * lz77_decomp.c * * The LZ77 decompression algorithm. * * This file is licensed under the GNU GPL. * * (C) 2005, Klaus S. Madsen <klaussm@diku.dk> * */#include "lz77.h"#include <inttypes.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <assert.h>#include "../buffer.h"uint8_t membuffer[MEMBUFSIZE];uint8_t *data;uint8_t read_count;uint16_t buffer;int lengths[33];int offsets[2000];void init_comp(){  memset(lengths, 0, sizeof(lengths));  memset(offsets, 0, sizeof(offsets));}void end_comp(){  int i;  printf("Lengths:\n");  for (i = 0; i < 33; i++) {    printf("%02d: %d\n", i, lengths[i]);  }  printf("Offsets:\n");  for (i = 0; i < 1501; i++) {    printf("%04d: %d\n", i, offsets[i]);  }}static uint8_t read_bits(uint8_t len){  assert(len <= 8);  uint8_t res;  // Fill the buffer  while (read_count < len) {    buffer <<= 8;    buffer |= *data++;    read_count += 8;  }  res = (buffer >> (read_count - len)) & ((1 << len) - 1);  read_count -= len;  buffer &= (1 << read_count) - 1;  return res;}uint16_t bits_left(){  uint16_t res = MEMBUFSIZE - (data - membuffer); // Amount of unread data;    res *= 8;  res += read_count; // Bits read, but not outputted yet.    return res;}#define SEARCH_SIZE WINDOW_SIZEuint8_t window[SEARCH_SIZE];uint8_t *search_end;void fill_buffer(){#ifdef DEBUG  fprintf(stderr, "**Filling buffer\n");#endif  if (fread(membuffer, MEMBUFSIZE, 1, stdin) != 1) {    fprintf(stderr, "Error reading from stdin: %s\n", 	    strerror(errno));    exit(1);  }    read_count = 0;  buffer = 0;  data = membuffer;}uint16_t cyclic_difference(uint8_t *start, uint8_t *end){  if (start > end) {    end += SEARCH_SIZE;  }  return end - start;}uint8_t *cyclic_adjust(uint8_t *v) {  if (v < window) {    v += SEARCH_SIZE;      } else if (v >= window + SEARCH_SIZE) {    v -= SEARCH_SIZE;  }  assert(v < window + SEARCH_SIZE && v >= window);  return v;}void insert_into_buffer(uint8_t b){  assert(search_end >= window && search_end < window + SEARCH_SIZE);  *search_end = b;  search_end = cyclic_adjust(search_end + 1);  //  fprintf(stderr, "Buffer contains %d elements\n",   //	  cyclic_difference(search_start, search_end));}uint8_t match_length = 0;uint8_t *match_pos;uint8_t *orig_match_pos;int max_length = 0;#ifdef DEBUGvoid output_match(uint8_t *pos, uint8_t len){  int i;  fprintf(stderr, "@%p (window starts @ %p): ", pos, window);    for (i = 0; i < len; i++) {    fprintf(stderr, "%02x", *pos);    pos = cyclic_adjust(pos + 1);  }  fprintf(stderr, "\n");}#endifuint8_t get_byte(){  if (match_length) {    uint8_t tmp;    if (match_pos == search_end) {      match_pos = orig_match_pos;    }    tmp = *match_pos;    match_pos = cyclic_adjust(match_pos + 1);    insert_into_buffer(tmp);    match_length--;    return tmp;  } else {    uint8_t tmp;        if (bits_left() < OFFSET_BITS + LENGTH_BITS + 1)       fill_buffer();    tmp = read_bits(1);         if (tmp) {      /* This was a single byte. */      uint8_t res = read_bits(8);      insert_into_buffer(res);#ifdef DEBUG      fprintf(stderr, "Reading single byte %d\n", (int)res);#endif      lengths[0]++;      offsets[0]++;      return res;    } else {      uint16_t offset;      offset = (uint16_t) read_bits(OFFSET_BITS - 8) << 8;      offset |= read_bits(8);      offsets[offset]++;            match_length = read_bits(LENGTH_BITS);      if (match_length == (1 << LENGTH_BITS) - 1) {	max_length++;      }      lengths[match_length + 1]++;      orig_match_pos = match_pos = cyclic_adjust(search_end - offset);#ifdef DEBUG      fprintf(stderr, "Read offset %d and length %d. Values: ", offset, 	      match_length);      output_match(match_pos, match_length + 1);#endif            tmp = *match_pos;      match_pos = cyclic_adjust(match_pos + 1);      insert_into_buffer(tmp);      return tmp;    }  }}int decompress_sample(int16_t *digi_x, int16_t *digi_y, 		      int16_t *digi_z, uint16_t *analog_x,		      uint16_t *analog_y){  static int first = 1;#ifdef DIFFERENCE  static int16_t last_vals[3];  int i;#endif  if (first) {    first = 0;    fill_buffer();    search_end = window;#ifdef DIFFERENCE    for (i = 0; i < 3; i++) {      last_vals[i] = (get_byte() << 8) | get_byte();    }  } else {    for (i = 0; i < 3; i++) {      last_vals[i] += (get_byte() << 8) | get_byte();    }#endif   }  #ifdef DIFFERENCE  *digi_x = last_vals[0];  *digi_y = last_vals[1];  *digi_z = last_vals[2];#else  *digi_x = (get_byte() << 8) | get_byte();  *digi_y = (get_byte() << 8) | get_byte();  *digi_z = (get_byte() << 8) | get_byte();#endif  return max_length;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -