Beispiel #1
0
static void appDecompressLZX(byte *CompressedBuffer, int CompressedSize, byte *UncompressedBuffer, int UncompressedSize)
{
	guard(appDecompressLZX);

	// setup streams
	mspack_file src, dst;
	src.buf     = CompressedBuffer;
	src.bufSize = CompressedSize;
	src.pos     = 0;
	src.rest    = 0;
	dst.buf     = UncompressedBuffer;
	dst.bufSize = UncompressedSize;
	dst.pos     = 0;
	// prepare decompressor
	lzxd_stream *lzxd = lzxd_init(&lzxSys, &src, &dst, 17, 0, 256*1024, UncompressedSize);
	assert(lzxd);
	// decompress
	int r = lzxd_decompress(lzxd, UncompressedSize);
	if (r != MSPACK_ERR_OK)
		appError("lzxd_decompress(%d,%d) returned %d", CompressedSize, UncompressedSize, r);
	// free resources
	lzxd_free(lzxd);

	unguard;
}
Beispiel #2
0
static int oabd_decompress(struct msoab_decompressor *_self, const char *input,
			   const char *output)
{
  struct msoab_decompressor_p *self = (struct msoab_decompressor_p *) _self;
  struct mspack_system *sys;
  struct mspack_file *infh = NULL;
  struct mspack_file *outfh = NULL;
  unsigned char *buf = NULL;
  unsigned char hdrbuf[oabhead_SIZEOF];
  unsigned int block_max, target_size;
  struct lzxd_stream *lzx = NULL;
  struct mspack_system oabd_sys;
  struct oabd_file in_ofh, out_ofh;
  unsigned int window_bits;
  int ret = MSPACK_ERR_OK;

  if (!self) return MSPACK_ERR_ARGS;
  sys = self->system;

  infh = sys->open(sys, input, MSPACK_SYS_OPEN_READ);
  if (!infh) {
    ret = MSPACK_ERR_OPEN;
    goto out;
  }

  if (sys->read(infh, hdrbuf, oabhead_SIZEOF) != oabhead_SIZEOF) {
    ret = MSPACK_ERR_READ;
    goto out;
  }

  if (EndGetI32(&hdrbuf[oabhead_VersionHi]) != 3 ||
      EndGetI32(&hdrbuf[oabhead_VersionLo]) != 1) {
    ret = MSPACK_ERR_SIGNATURE;
    goto out;
  }

  block_max   = EndGetI32(&hdrbuf[oabhead_BlockMax]);
  target_size = EndGetI32(&hdrbuf[oabhead_TargetSize]);

  /* We use it for reading block headers too */
  if (block_max < oabblk_SIZEOF)
    block_max = oabblk_SIZEOF;

  outfh = sys->open(sys, output, MSPACK_SYS_OPEN_WRITE);
  if (!outfh) {
    ret = MSPACK_ERR_OPEN;
    goto out;
  }

  buf = sys->alloc(sys, block_max);
  if (!buf) {
    ret = MSPACK_ERR_NOMEMORY;
    goto out;
  }

  oabd_sys = *sys;
  oabd_sys.read = oabd_sys_read;
  oabd_sys.write = oabd_sys_write;

  in_ofh.orig_sys = sys;
  in_ofh.orig_file = infh;

  out_ofh.orig_sys = sys;
  out_ofh.orig_file = outfh;

  while (target_size) {
    unsigned int blk_csize, blk_dsize, blk_crc, blk_flags;

    if (sys->read(infh, buf, oabblk_SIZEOF) != oabblk_SIZEOF) {
      ret = MSPACK_ERR_READ;
      goto out;
    }
    blk_flags = EndGetI32(&buf[oabblk_Flags]);
    blk_csize = EndGetI32(&buf[oabblk_CompSize]);
    blk_dsize = EndGetI32(&buf[oabblk_UncompSize]);
    blk_crc   = EndGetI32(&buf[oabblk_CRC]);

    if (blk_dsize > block_max || blk_dsize > target_size || blk_flags > 1) {
      ret = MSPACK_ERR_DATAFORMAT;
      goto out;
    }

    if (!blk_flags) {
      /* Uncompressed block */
      if (blk_dsize != blk_csize) {
	ret = MSPACK_ERR_DATAFORMAT;
	goto out;
      }
      if (sys->read(infh, buf, blk_dsize) != (int)blk_dsize) {
	ret = MSPACK_ERR_READ;
	goto out;
      }
      if (sys->write(outfh, buf, blk_dsize) != (int)blk_dsize) {
	ret = MSPACK_ERR_WRITE;
	goto out;
      }
    } else {
      /* LZX compressed block */
      window_bits = 17;

      while (window_bits < 25 && (1U << window_bits) < blk_dsize)
	window_bits++;

      in_ofh.available = blk_csize;
      out_ofh.crc = 0xffffffff;

      lzx = lzxd_init(&oabd_sys, (void *)&in_ofh, (void *)&out_ofh, window_bits,
		      0, 4096, blk_dsize, 1);
      if (!lzx) {
	ret = MSPACK_ERR_NOMEMORY;
	goto out;
      }

      ret = lzxd_decompress(lzx, blk_dsize);
      if (ret != MSPACK_ERR_OK)
	goto out;

      lzxd_free(lzx);
      lzx = NULL;

      /* Consume any trailing padding bytes before the next block */
      while (in_ofh.available) {
	int count = block_max;
	if ((size_t)count > in_ofh.available)
	  count = in_ofh.available;

	count = sys->read(infh, buf, count);
	if (count < 0) {
	  ret = MSPACK_ERR_READ;
	  goto out;
	}
	in_ofh.available -= count;
      }

      if (out_ofh.crc != blk_crc) {
	ret = MSPACK_ERR_CHECKSUM;
	goto out;
      }
    }
    target_size -= blk_dsize;
  }

 out:
  if (lzx)
    lzxd_free(lzx);
  if (buf)
    sys->free(buf);
  if (outfh)
    sys->close(outfh);
  if (infh)
    sys->close(infh);

  return ret;
}