STATIC inline int INIT unlzo(u8 *input, int in_len,
				int (*fill) (void *, unsigned int),
				int (*flush) (void *, unsigned int),
				u8 *output, int *posp,
				void (*error) (char *x))
{
	u8 r = 0;
	int skip = 0;
	u32 src_len, dst_len;
	size_t tmp;
	u8 *in_buf, *in_buf_save, *out_buf;
	int ret = -1;

	if (output) {
		out_buf = output;
	} else if (!flush) {
		error("NULL output pointer and no flush function provided");
		goto exit;
	} else {
		out_buf = malloc(LZO_BLOCK_SIZE);
		if (!out_buf) {
			error("Could not allocate output buffer");
			goto exit;
		}
	}

	if (input && fill) {
		error("Both input pointer and fill function provided, don't know what to do");
		goto exit_1;
	} else if (input) {
		in_buf = input;
	} else if (!fill) {
		error("NULL input pointer and missing fill function");
		goto exit_1;
	} else {
		in_buf = malloc(lzo1x_worst_compress(LZO_BLOCK_SIZE));
		if (!in_buf) {
			error("Could not allocate input buffer");
			goto exit_1;
		}
	}
	in_buf_save = in_buf;

	if (posp)
		*posp = 0;

	if (fill) {
		/*
		 * Start from in_buf + HEADER_SIZE_MAX to make it possible
		 * to use memcpy() to copy the unused data to the beginning
		 * of the buffer. This way memmove() isn't needed which
		 * is missing from pre-boot environments of most archs.
		 */
		in_buf += HEADER_SIZE_MAX;
		in_len = fill(in_buf, HEADER_SIZE_MAX);
	}

	if (!parse_header(in_buf, &skip, in_len)) {
		error("invalid header");
		goto exit_2;
	}
	in_buf += skip;
	in_len -= skip;

	if (fill) {
		/* Move the unused data to the beginning of the buffer. */
		memcpy(in_buf_save, in_buf, in_len);
		in_buf = in_buf_save;
	}

	if (posp)
		*posp = skip;

	for (;;) {
		/* read uncompressed block size */
		if (fill && in_len < 4) {
			skip = fill(in_buf + in_len, 4 - in_len);
			if (skip > 0)
				in_len += skip;
		}
		if (in_len < 4) {
			error("file corrupted");
			goto exit_2;
		}
		dst_len = get_unaligned_be32(in_buf);
		in_buf += 4;
		in_len -= 4;

		/* exit if last block */
		if (dst_len == 0) {
			if (posp)
				*posp += 4;
			break;
		}

		if (dst_len > LZO_BLOCK_SIZE) {
			error("dest len longer than block size");
			goto exit_2;
		}

		/* read compressed block size, and skip block checksum info */
		if (fill && in_len < 8) {
			skip = fill(in_buf + in_len, 8 - in_len);
			if (skip > 0)
				in_len += skip;
		}
		if (in_len < 8) {
			error("file corrupted");
			goto exit_2;
		}
		src_len = get_unaligned_be32(in_buf);
		in_buf += 8;
		in_len -= 8;

		if (src_len <= 0 || src_len > dst_len) {
			error("file corrupted");
			goto exit_2;
		}

		/* decompress */
		if (fill && in_len < src_len) {
			skip = fill(in_buf + in_len, src_len - in_len);
			if (skip > 0)
				in_len += skip;
		}
		if (in_len < src_len) {
			error("file corrupted");
			goto exit_2;
		}
		tmp = dst_len;

		/* When the input data is not compressed at all,
		 * lzo1x_decompress_safe will fail, so call memcpy()
		 * instead */
		if (unlikely(dst_len == src_len))
			memcpy(out_buf, in_buf, src_len);
		else {
			r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
						out_buf, &tmp);

			if (r != LZO_E_OK || dst_len != tmp) {
				error("Compressed data violation");
				goto exit_2;
			}
		}

		if (flush && flush(out_buf, dst_len) != dst_len)
			goto exit_2;
		if (output)
			out_buf += dst_len;
		if (posp)
			*posp += src_len + 12;

		in_buf += src_len;
		in_len -= src_len;
		if (fill) {
			/*
			 * If there happens to still be unused data left in
			 * in_buf, move it to the beginning of the buffer.
			 * Use a loop to avoid memmove() dependency.
			 */
			if (in_len > 0)
				for (skip = 0; skip < in_len; ++skip)
					in_buf_save[skip] = in_buf[skip];
			in_buf = in_buf_save;
		}
	}

	ret = 0;
exit_2:
	if (!input)
		free(in_buf_save);
exit_1:
	if (!output)
		free(out_buf);
exit:
	return ret;
}
Exemplo n.º 2
0
static int zram_read(struct zram *zram, struct bio *bio)
{
	int i;
	u32 index;
	struct bio_vec *bvec;

	if (unlikely(!zram->init_done)) {
		set_bit(BIO_UPTODATE, &bio->bi_flags);
		bio_endio(bio, 0);
		return 0;
	}

	zram_inc_stat(zram, ZRAM_STAT_NUM_READS);
	index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;

	bio_for_each_segment(bvec, bio, i) {
		int ret;
		size_t zlen;
		u32 zoffset;
		struct page *bio_page, *zpage;
		unsigned char *bio_mem, *zmem;

		bio_page = bvec->bv_page;

		if (zram_is_zero_page(zram, index)) {
			handle_zero_page(bio_page);
			continue;
		}

		zram_find_obj(zram, index, &zpage, &zoffset);

		/* Requested page is not present in compressed area */
		if (unlikely(!zpage)) {
			pr_debug("Read before write on swap device: "
				"sector=%lu, size=%u",
				(ulong)(bio->bi_sector), bio->bi_size);
			/* Do nothing */
			continue;
		}

		/* Page is stored uncompressed since it's incompressible */
		if (unlikely(!zoffset)) {
			handle_uncompressed_page(zram, bio_page, index);
			continue;
		}

		bio_mem = kmap_atomic(bio_page, KM_USER0);
		zlen = PAGE_SIZE;

		zmem = kmap_atomic(zpage, KM_USER1) + zoffset;

		ret = lzo1x_decompress_safe(zmem, xv_get_object_size(zmem),
					bio_mem, &zlen);

		kunmap_atomic(bio_mem, KM_USER0);
		kunmap_atomic(zmem, KM_USER1);

		/* This should NEVER happen - return bio error if it does! */
		if (unlikely(ret != LZO_E_OK)) {
			pr_err("Decompression failed! err=%d, page=%u\n",
				ret, index);
			goto out;
		}

		flush_dcache_page(bio_page);
		index++;
	}
Exemplo n.º 3
0
Arquivo: H5Zlzo.c Projeto: 87/PyTables
size_t lzo_deflate (unsigned flags, size_t cd_nelmts,
		    const unsigned cd_values[], size_t nbytes,
		    size_t *buf_size, void **buf)
{
  size_t ret_value = 0;
#ifdef HAVE_LZO_LIB
  void *outbuf = NULL, *wrkmem = NULL;
  int status;
  size_t  nalloc = *buf_size;
  lzo_uint out_len = (lzo_uint) nalloc;
  /* max_len_buffer will keep the likely output buffer size
     after processing the first chunk */
  static unsigned int max_len_buffer = 0;
  int complevel = 1;
  int object_version = 10;    	/* Default version 1.0 */
  int object_type = Table;      /* Default object type */
#ifdef CHECKSUM
  lzo_uint32 checksum;
#endif

  /* Check arguments */
  /* For Table versions < 20, there were no parameters */
  if (cd_nelmts==1 ) {
    complevel = cd_values[0];	/* This do nothing right now */
  }
  else if (cd_nelmts==2 ) {
    complevel = cd_values[0];	/* This do nothing right now */
    object_version = cd_values[1]; /* The table VERSION attribute */
  }
  else if (cd_nelmts==3 ) {
    complevel = cd_values[0];	/* This do nothing right now */
    object_version = cd_values[1]; /* The table VERSION attribute */
    object_type = cd_values[2]; /* A tag for identifying the object 
				   (see tables.h) */
  }

#ifdef DEBUG
  printf("Object type: %d. ", object_type);
  printf("object_version:%d\n", object_version);
#endif

  if (flags & H5Z_FLAG_REVERSE) {
    /* Input */

/*     printf("Decompressing chunk with LZO\n"); */
#ifdef CHECKSUM
    if ((object_type == Table && object_version >= 20) ||
	object_type != Table) {
      nbytes -= 4; 		/* Point to uncompressed buffer length */
      memcpy(&nalloc, ((unsigned char *)(*buf)+nbytes), 4);
      out_len = nalloc;
      nbytes -= 4; 		/* Point to the checksum */
#ifdef DEBUG
      printf("Compressed bytes: %d. Uncompressed bytes: %d\n", nbytes, nalloc);
#endif
    }
#endif

    /* Only allocate the bytes for the outbuf */
    if (max_len_buffer == 0) {
      if (NULL==(outbuf = (void *)malloc(nalloc)))
	fprintf(stderr, "Memory allocation failed for lzo uncompression.\n");
    }
    else {
      if (NULL==(outbuf = (void *)malloc(max_len_buffer)))
	fprintf(stderr, "Memory allocation failed for lzo uncompression.\n");
      out_len = max_len_buffer;
      nalloc =  max_len_buffer;
    }

    while(1) {

#ifdef DEBUG
      printf("nbytes -->%d\n", nbytes);
      printf("nalloc -->%d\n", nalloc);
      printf("max_len_buffer -->%d\n", max_len_buffer);
#endif /* DEBUG */

      /* The assembler version is a 10% slower than the C version with 
	 gcc 3.2.2 and gcc 3.3.3 */
/*       status = lzo1x_decompress_asm_safe(*buf, (lzo_uint)nbytes, outbuf, */
/* 				     &out_len, NULL); */
      /* The safe and unsafe versions have the same speed more or less */
      status = lzo1x_decompress_safe(*buf, (lzo_uint)nbytes, outbuf,
				       &out_len, NULL);

      if (status == LZO_E_OK) {
#ifdef DEBUG
	printf("decompressed %lu bytes back into %lu bytes\n",
	       (long) nbytes, (long) out_len);
#endif
	max_len_buffer = out_len;
	break; /* done */
      }
      else if (status == LZO_E_OUTPUT_OVERRUN) {
	nalloc *= 2;
	out_len = (lzo_uint) nalloc;
	if (NULL==(outbuf = realloc(outbuf, nalloc))) {
	  fprintf(stderr, "Memory allocation failed for lzo uncompression\n");
	}
      }
      else {
	/* this should NEVER happen */
	fprintf(stderr, "internal error - decompression failed: %d\n", status);
	ret_value = 0; /* fail */
	goto done;
      }
    }

#ifdef CHECKSUM
    if ((object_type == Table && object_version >= 20) ||
	object_type != Table) {
#ifdef DEBUG
      printf("Checksum uncompressing...");
#endif
      /* Compute the checksum */
      checksum=lzo_adler32(lzo_adler32(0,NULL,0), outbuf, out_len);
  
      /* Compare */
      if (memcmp(&checksum, (unsigned char*)(*buf)+nbytes, 4)) {
	ret_value = 0; /*fail*/
	fprintf(stderr,"Checksum failed!.\n");
	goto done;
      }
    }
#endif /* CHECKSUM */

    free(*buf);
    *buf = outbuf;
    outbuf = NULL;
    *buf_size = nalloc;
    ret_value = out_len;

  } else {
    /*
     * Output; compress but fail if the result would be larger than the
     * input.  The library doesn't provide in-place compression, so we
     * must allocate a separate buffer for the result.
     */
    lzo_byte *z_src = (lzo_byte*)(*buf);
    lzo_byte *z_dst;         /*destination buffer            */
    lzo_uint z_src_nbytes = (lzo_uint)(nbytes);
    /* The next was the original computation for worst-case expansion */
    /* I don't know why the difference with LZO1*. Perhaps some wrong docs in
       LZO package? */
/*     lzo_uint z_dst_nbytes = (lzo_uint)(nbytes + (nbytes / 64) + 16 + 3); */
    /* The next is for LZO1* algorithms */
/*     lzo_uint z_dst_nbytes = (lzo_uint)(nbytes + (nbytes / 16) + 64 + 3); */
    /* The next is for LZO2* algorithms. This will be the default */
    lzo_uint z_dst_nbytes = (lzo_uint)(nbytes + (nbytes / 8) + 128 + 3);

#ifdef CHECKSUM
    if ((object_type == Table && object_version >= 20) ||
	object_type != Table) {
      z_dst_nbytes += 4+4;      /* Checksum + buffer size */
    }
#endif

    if (NULL==(z_dst=outbuf=(void *)malloc(z_dst_nbytes))) {
      fprintf(stderr, "Unable to allocate lzo destination buffer.\n");
      ret_value = 0; /* fail */
      goto done;
    }

    /* Compress this buffer */
    wrkmem = malloc(LZO1X_1_MEM_COMPRESS);
    if (wrkmem == NULL) {
      fprintf(stderr, "Memory allocation failed for lzo compression\n");
      ret_value = 0;
      goto done;
    }

    status = lzo1x_1_compress (z_src, z_src_nbytes, z_dst, &z_dst_nbytes,
			       wrkmem);

    free(wrkmem);
    wrkmem = NULL;

#ifdef CHECKSUM
    if ((object_type == Table && object_version >= 20) ||
	object_type != Table) {
#ifdef DEBUG
      printf("Checksum compressing ...");
      printf("src_nbytes: %d, dst_nbytes: %d\n", z_src_nbytes, z_dst_nbytes);
#endif
      /* Append checksum of *uncompressed* data at the end */
      checksum = lzo_adler32(lzo_adler32(0,NULL,0), *buf, nbytes);
      memcpy((unsigned char*)(z_dst)+z_dst_nbytes, &checksum, 4);
      memcpy((unsigned char*)(z_dst)+z_dst_nbytes+4, &nbytes, 4);
      z_dst_nbytes += (lzo_uint)4+4;
      nbytes += 4+4;
    }
#endif

    if (z_dst_nbytes >= nbytes) {
#ifdef DEBUG
      printf("The compressed buffer takes more space than uncompressed!.\n");
#endif
      ret_value = 0; /* fail */
      goto done;
    } else if (LZO_E_OK != status) {
      fprintf(stderr,"lzo library error in compression\n");
      ret_value = 0; /* fail */
      goto done;
    } else {
      free(*buf);
      *buf = outbuf;
      outbuf = NULL;
      *buf_size = z_dst_nbytes;
      ret_value = z_dst_nbytes;
    }
  }

done:
  if(outbuf)
    free(outbuf);

#endif  /* HAVE_LZO_LIB */

  return ret_value;
}
Exemplo n.º 4
0
static int xc_try_lzo1x_decode(
    struct xc_dom_image *dom, void **blob, size_t *size)
{
    int ret;
    const unsigned char *cur = dom->kernel_blob;
    unsigned char *out_buf = NULL;
    size_t left = dom->kernel_size;
    const char *msg;
    unsigned version;
    static const unsigned char magic[] = {
        0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a
    };

    ret = lzo_init();
    if ( ret != LZO_E_OK )
    {
        DOMPRINTF("LZO1x: Failed to init library (%d)\n", ret);
        return -1;
    }

    if ( left < 16 || memcmp(cur, magic, 9) )
    {
        DOMPRINTF("LZO1x: Unrecognized magic\n");
        return -1;
    }

    /* get version (2bytes), skip library version (2),
     * 'need to be extracted' version (2) and method (1) */
    version = lzo_read_16(cur + 9);
    cur += 16;
    left -= 16;

    if ( version >= 0x0940 )
    {
        /* skip level */
        ++cur;
        if ( left )
            --left;
    }

    if ( left >= 4 && (lzo_read_32(cur) & LZOP_HEADER_HAS_FILTER) )
        ret = 8; /* flags + filter info */
    else
        ret = 4; /* flags */

    /* skip mode and mtime_low */
    ret += 8;
    if ( version >= 0x0940 )
        ret += 4; /* skip mtime_high */

    /* don't care about the file name, and skip checksum */
    if ( left > ret )
        ret += 1 + cur[ret] + 4;

    if ( left < ret )
    {
        DOMPRINTF("LZO1x: Incomplete header\n");
        return -1;
    }
    cur += ret;
    left -= ret;

    for ( *size = 0; ; )
    {
        lzo_uint src_len, dst_len, out_len;
        unsigned char *tmp_buf;

        msg = "Short input";
        if ( left < 4 )
            break;

        dst_len = lzo_read_32(cur);
        if ( !dst_len )
            return 0;

        if ( dst_len > LZOP_MAX_BLOCK_SIZE )
        {
            msg = "Block size too large";
            break;
        }

        if ( left < 12 )
            break;

        src_len = lzo_read_32(cur + 4);
        cur += 12; /* also skip block checksum info */
        left -= 12;

        msg = "Bad source length";
        if ( src_len <= 0 || src_len > dst_len || src_len > left )
            break;

        msg = "Failed to (re)alloc memory";
        tmp_buf = realloc(out_buf, *size + dst_len);
        if ( tmp_buf == NULL )
            break;

        out_buf = tmp_buf;
        out_len = dst_len;

        ret = lzo1x_decompress_safe(cur, src_len,
                                    out_buf + *size, &out_len, NULL);
        switch ( ret )
        {
        case LZO_E_OK:
            msg = "Input underrun";
            if ( out_len != dst_len )
                break;

            *blob = out_buf;
            *size += out_len;
            cur += src_len;
            left -= src_len;
            continue;

        case LZO_E_INPUT_NOT_CONSUMED:
            msg = "Unconsumed input";
            break;

        case LZO_E_OUTPUT_OVERRUN:
            msg = "Output overrun";
            break;

        case LZO_E_INPUT_OVERRUN:
            msg = "Input overrun";
            break;

        case LZO_E_LOOKBEHIND_OVERRUN:
            msg = "Look-behind overrun";
            break;

        case LZO_E_EOF_NOT_FOUND:
            msg = "No EOF marker";
            break;

        case LZO_E_ERROR:
            msg = "General error";
            break;

        default:
            msg = "Internal program error (bug)";
            break;
        }

        break;
    }

    free(out_buf);
    DOMPRINTF("LZO1x decompression error: %s\n", msg);

    return -1;
}
Exemplo n.º 5
0
static int decompress_lzo(struct btrfs_root *root, unsigned char *inbuf,
			char *outbuf, u64 compress_len, u64 *decompress_len)
{
	size_t new_len;
	size_t in_len;
	size_t out_len = 0;
	size_t tot_len;
	size_t tot_in;
	int ret;

	ret = lzo_init();
	if (ret != LZO_E_OK) {
		error("lzo init returned %d", ret);
		return -1;
	}

	tot_len = read_compress_length(inbuf);
	inbuf += LZO_LEN;
	tot_in = LZO_LEN;

	while (tot_in < tot_len) {
		size_t mod_page;
		size_t rem_page;
		in_len = read_compress_length(inbuf);

		if ((tot_in + LZO_LEN + in_len) > tot_len) {
			error("bad compress length %lu",
				(unsigned long)in_len);
			return -1;
		}

		inbuf += LZO_LEN;
		tot_in += LZO_LEN;
		new_len = lzo1x_worst_compress(root->sectorsize);
		ret = lzo1x_decompress_safe((const unsigned char *)inbuf, in_len,
					    (unsigned char *)outbuf,
					    (void *)&new_len, NULL);
		if (ret != LZO_E_OK) {
			error("lzo decompress failed: %d", ret);
			return -1;
		}
		out_len += new_len;
		outbuf += new_len;
		inbuf += in_len;
		tot_in += in_len;

		/*
		 * If the 4 byte header does not fit to the rest of the page we
		 * have to move to the next one, unless we read some garbage
		 */
		mod_page = tot_in % root->sectorsize;
		rem_page = root->sectorsize - mod_page;
		if (rem_page < LZO_LEN) {
			inbuf += rem_page;
			tot_in += rem_page;
		}
	}

	*decompress_len = out_len;

	return 0;
}
Exemplo n.º 6
0
int __lzo_cdecl_main main(int argc, char *argv[])
{
    int r;
    int lazy;
    const int max_try_lazy = 5;
    const lzo_uint big = 65536L;    /* can result in very slow compression */
    const lzo_uint32_t flags = 0x1;

    lzo_bytep in;
    lzo_uint in_len;

    lzo_bytep out;
    lzo_uint out_bufsize;
    lzo_uint out_len = 0;

    lzo_voidp wrkmem;
    lzo_uint wrkmem_size;

    lzo_uint best_len;
    int best_compress = -1;
    int best_lazy = -1;

    lzo_uint orig_len;
    lzo_uint32_t uncompressed_checksum;
    lzo_uint32_t compressed_checksum;

    FILE *fp;
    const char *in_name = NULL;
    const char *out_name = NULL;
    long l;


    lzo_wildargv(&argc, &argv);

    printf("\nLZO real-time data compression library (v%s, %s).\n",
           lzo_version_string(), lzo_version_date());
    printf("Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n");

    progname = argv[0];
    if (argc < 2 || argc > 3)
    {
        printf("usage: %s file [output-file]\n", progname);
        exit(1);
    }
    in_name = argv[1];
    if (argc > 2) out_name = argv[2];

/*
 * Step 1: initialize the LZO library
 */
    if (lzo_init() != LZO_E_OK)
    {
        printf("internal error - lzo_init() failed !!!\n");
        printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)\n");
        exit(1);
    }

/*
 * Step 2: allocate the work-memory
 */
    wrkmem_size = 1;
#ifdef USE_LZO1X
    wrkmem_size = (LZO1X_999_MEM_COMPRESS > wrkmem_size) ? LZO1X_999_MEM_COMPRESS : wrkmem_size;
#endif
#ifdef USE_LZO1Y
    wrkmem_size = (LZO1Y_999_MEM_COMPRESS > wrkmem_size) ? LZO1Y_999_MEM_COMPRESS : wrkmem_size;
#endif
    wrkmem = (lzo_voidp) xmalloc(wrkmem_size);
    if (wrkmem == NULL)
    {
        printf("%s: out of memory\n", progname);
        exit(1);
    }

/*
 * Step 3: open the input file
 */
    fp = fopen(in_name,"rb");
    if (fp == NULL)
    {
        printf("%s: cannot open file %s\n", progname, in_name);
        exit(1);
    }
    fseek(fp, 0, SEEK_END);
    l = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    if (l <= 0)
    {
        printf("%s: %s: empty file\n", progname, in_name);
        fclose(fp); fp = NULL;
        exit(1);
    }
    in_len = (lzo_uint) l;
    out_bufsize = in_len + in_len / 16 + 64 + 3;
    best_len = in_len;

/*
 * Step 4: allocate compression buffers and read the file
 */
    in = (lzo_bytep) xmalloc(in_len);
    out = (lzo_bytep) xmalloc(out_bufsize);
    if (in == NULL || out == NULL)
    {
        printf("%s: out of memory\n", progname);
        exit(1);
    }
    in_len = (lzo_uint) lzo_fread(fp, in, in_len);
    printf("%s: loaded file %s: %ld bytes\n", progname, in_name, (long) in_len);
    fclose(fp); fp = NULL;

/*
 * Step 5: compute a checksum of the uncompressed data
 */
    uncompressed_checksum = lzo_adler32(0,NULL,0);
    uncompressed_checksum = lzo_adler32(uncompressed_checksum,in,in_len);

/*
 * Step 6a: compress from 'in' to 'out' with LZO1X-999
 */
#ifdef USE_LZO1X
    for (lazy = 0; lazy <= max_try_lazy; lazy++)
    {
        out_len = out_bufsize;
        r = lzo1x_999_compress_internal(in,in_len,out,&out_len,wrkmem,
                                        NULL, 0, 0,
                                        lazy, big, big, big, big, flags);
        if (r != LZO_E_OK)
        {
            /* this should NEVER happen */
            printf("internal error - compression failed: %d\n", r);
            exit(1);
        }
        printf("LZO1X-999: lazy =%2d: %8lu -> %8lu\n",
                lazy, (unsigned long) in_len, (unsigned long) out_len);
        if (out_len < best_len)
        {
            best_len = out_len;
            best_lazy = lazy;
            best_compress = 1;      /* LZO1X-999 */
        }
    }
#endif /* USE_LZO1X */

/*
 * Step 6b: compress from 'in' to 'out' with LZO1Y-999
 */
#ifdef USE_LZO1Y
    for (lazy = 0; lazy <= max_try_lazy; lazy++)
    {
        out_len = out_bufsize;
        r = lzo1y_999_compress_internal(in,in_len,out,&out_len,wrkmem,
                                        NULL, 0, 0,
                                        lazy, big, big, big, big, flags);
        if (r != LZO_E_OK)
        {
            /* this should NEVER happen */
            printf("internal error - compression failed: %d\n", r);
            exit(1);
        }
        printf("LZO1Y-999: lazy =%2d: %8lu -> %8lu\n",
                lazy, (unsigned long) in_len, (unsigned long) out_len);
        if (out_len < best_len)
        {
            best_len = out_len;
            best_lazy = lazy;
            best_compress = 2;      /* LZO1Y-999 */
        }
    }
#endif /* USE_LZO1Y */

/*
 * Step 7: check if compressible
 */
    if (best_len >= in_len)
    {
        printf("This file contains incompressible data.\n");
        return 0;
    }

/*
 * Step 8: compress data again using the best compressor found
 */
    out_len = out_bufsize;
    if (best_compress == 1)
        r = lzo1x_999_compress_internal(in,in_len,out,&out_len,wrkmem,
                                        NULL, 0, 0,
                                        best_lazy, big, big, big, big, flags);
    else if (best_compress == 2)
        r = lzo1y_999_compress_internal(in,in_len,out,&out_len,wrkmem,
                                        NULL, 0, 0,
                                        best_lazy, big, big, big, big, flags);
    else
        r = -100;
    assert(r == LZO_E_OK);
    assert(out_len == best_len);

/*
 * Step 9: optimize compressed data (compressed data is in 'out' buffer)
 */
#if 1
    /* Optimization does not require any data in the buffer that will
     * hold the uncompressed data. To prove this, we clear the buffer.
     */
    lzo_memset(in,0,in_len);
#endif

    orig_len = in_len;
    r = -100;
#ifdef USE_LZO1X
    if (best_compress == 1)
        r = lzo1x_optimize(out,out_len,in,&orig_len,NULL);
#endif
#ifdef USE_LZO1Y
    if (best_compress == 2)
        r = lzo1y_optimize(out,out_len,in,&orig_len,NULL);
#endif
    if (r != LZO_E_OK || orig_len != in_len)
    {
        /* this should NEVER happen */
        printf("internal error - optimization failed: %d\n", r);
        exit(1);
    }

/*
 * Step 10: compute a checksum of the compressed data
 */
    compressed_checksum = lzo_adler32(0,NULL,0);
    compressed_checksum = lzo_adler32(compressed_checksum,out,out_len);

/*
 * Step 11: write compressed data to a file
 */
    printf("%s: %s: %ld -> %ld, checksum 0x%08lx 0x%08lx\n",
            progname, in_name, (long) in_len, (long) out_len,
            (long) uncompressed_checksum, (long) compressed_checksum);

    if (out_name && out_name[0])
    {
        printf("%s: writing to file %s\n", progname, out_name);
        fp = fopen(out_name,"wb");
        if (fp == NULL)
        {
            printf("%s: cannot open output file %s\n", progname, out_name);
            exit(1);
        }
        if (lzo_fwrite(fp, out, out_len) != out_len || fclose(fp) != 0)
        {
            printf("%s: write error !!\n", progname);
            exit(1);
        }
    }

/*
 * Step 12: verify decompression
 */
#ifdef PARANOID
    lzo_memset(in,0,in_len);    /* paranoia - clear output buffer */
    orig_len = in_len;
    r = -100;
#ifdef USE_LZO1X
    if (best_compress == 1)
        r = lzo1x_decompress_safe(out,out_len,in,&orig_len,NULL);
#endif
#ifdef USE_LZO1Y
    if (best_compress == 2)
        r = lzo1y_decompress_safe(out,out_len,in,&orig_len,NULL);
#endif
    if (r != LZO_E_OK || orig_len != in_len)
    {
        /* this should NEVER happen */
        printf("internal error - decompression failed: %d\n", r);
        exit(1);
    }
    if (uncompressed_checksum != lzo_adler32(lzo_adler32(0,NULL,0),in,in_len))
    {
        /* this should NEVER happen */
        printf("internal error - decompression data error\n");
        exit(1);
    }
    /* Now you could also verify decompression under similar conditions as in
     * your application, e.g. overlapping assembler decompression etc.
     */
#endif

    lzo_free(in);
    lzo_free(out);
    lzo_free(wrkmem);

    return 0;
}
Exemplo n.º 7
0
lzo_bool lzo_decompress(file_t *fip, file_t *fop,
                        const header_t *h, lzo_bool skip)
{
    int r;
    lzo_uint32 src_len, dst_len;
    lzo_uint32 c_adler32 = ADLER32_INIT_VALUE, d_adler32 = ADLER32_INIT_VALUE;
    lzo_uint32 c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE;
    lzo_bool ok = 1;
    lzo_bool use_seek;
    mblock_t * const block = &blocks[1];
    lzo_bytep b1;
    lzo_bytep const b2 = block->mb_mem;

    use_seek = skip || opt_cmd == CMD_LIST || opt_cmd == CMD_LS ||
                       opt_cmd == CMD_INFO;

    for (;;)
    {
        lzo_bytep dst;

        /* read uncompressed block size */
        read32(fip,&dst_len);

        /* exit if last block */
        if (dst_len == 0)
            break;

        /* error if split file */
        if (dst_len == 0xffffffffUL)
        {
            /* should not happen - not yet implemented */
            error(fip,"this file is a split " PACKAGE " file");
            ok = 0; break;
        }

        if (dst_len > MAX_BLOCK_SIZE)
        {
            error(fip, PACKAGE " file corrupted");
            ok = 0; break;
        }

        /* read compressed block size */
        read32(fip,&src_len);
        if (src_len <= 0 || src_len > dst_len)
        {
            error(fip, PACKAGE " file corrupted");
            ok = 0; break;
        }

        if (dst_len > BLOCK_SIZE)
        {
            fatal(fip,"block size too small -- recompile " PACKAGE);
            ok = 0; break;
        }
        if (dst_len > block_size)
        {
            /* should not happen - not yet implemented */
            fatal(fip,"block size too small -- use option `--blocksize'");
            ok = 0; break;
        }
        assert(block->mb_size >= src_len);

        /* read checksum of uncompressed block */
        if (h->flags & F_ADLER32_D)
            read32(fip,&d_adler32);
        if (h->flags & F_CRC32_D)
            read32(fip,&d_crc32);

        /* read checksum of compressed block */
        if (h->flags & F_ADLER32_C)
        {
            if (src_len < dst_len)
                read32(fip,&c_adler32);
            else
            {
                assert(h->flags & F_ADLER32_D);
                c_adler32 = d_adler32;
            }
        }
        if (h->flags & F_CRC32_C)
        {
            if (src_len < dst_len)
                read32(fip,&c_crc32);
            else
            {
                assert(h->flags & F_CRC32_D);
                c_crc32 = d_crc32;
            }
        }

        /* read the block */
        b1 = block->mb_mem + block->mb_size - src_len;
        if (use_seek && fip->fd != STDIN_FILENO)
        {
            if (lseek(fip->fd, src_len, SEEK_CUR) == -1)
                read_error(fip);
        }
        else
        {
            if (read_buf(fip, b1, src_len) != (lzo_int) src_len)
                read_error(fip);
        }

        fip->bytes_processed += src_len;
        if (use_seek)
        {
            fop->bytes_processed += dst_len;
            continue;
        }
        assert(block->mb_size >= MAX_COMPRESSED_SIZE(dst_len));

        /* verify checksum of compressed block */
        if (opt_checksum && (h->flags & F_ADLER32_C))
        {
            lzo_uint32 c;
            c = lzo_adler32(ADLER32_INIT_VALUE,b1,src_len);
            if (c != c_adler32)
            {
                error(fip,"Checksum error (" PACKAGE " file corrupted)");
                ok = 0; break;
            }
        }
        if (opt_checksum && (h->flags & F_CRC32_C))
        {
            lzo_uint32 c;
            c = lzo_crc32(CRC32_INIT_VALUE,b1,src_len);
            if (c != c_crc32)
            {
                error(fip,"Checksum error (" PACKAGE " file corrupted)");
                ok = 0; break;
            }
        }

        if (src_len < dst_len)
        {
            lzo_uint d = dst_len;

            /* decompress */
            if (opt_decompress_safe)
                r = lzo1x_decompress_safe(b1,src_len,b2,&d,NULL);
            else
                r = lzo1x_decompress(b1,src_len,b2,&d,NULL);

            if (r != LZO_E_OK || dst_len != d)
            {
                error(fip,"Compressed data violation");
#if 0
                fprintf(stderr,"%d %ld %ld\n", r, (long)dst_len, (long)d);
#endif
                ok = 0; break;
            }
            dst = b2;
        }
        else
        {
            assert(dst_len == src_len);
            dst = b1;
        }

        x_filter(dst,dst_len,h);

        /* verify checksum of uncompressed block */
        if (opt_checksum && (h->flags & F_ADLER32_D))
        {
            lzo_uint32 c;
            c = lzo_adler32(ADLER32_INIT_VALUE,dst,dst_len);
            if (c != d_adler32)
            {
                error(fip,"Checksum error");
                ok = 0; break;
            }
        }
        if (opt_checksum && (h->flags & F_CRC32_D))
        {
            lzo_uint32 c;
            c = lzo_crc32(CRC32_INIT_VALUE,dst,dst_len);
            if (c != d_crc32)
            {
                error(fip,"Checksum error");
                ok = 0; break;
            }
        }

        /* write uncompressed block data */
        write_buf(fop,dst,dst_len);
        fop->bytes_processed += dst_len;
    }

    return ok;
}
Exemplo n.º 8
0
STATIC inline int INIT unlzo(u8 *input, int in_len,
				int (*fill) (void *, unsigned int),
				int (*flush) (void *, unsigned int),
				u8 *output, int *posp,
				void (*error_fn) (char *x))
{
	u8 skip = 0, r = 0;
	u32 src_len, dst_len;
	size_t tmp;
	u8 *in_buf, *in_buf_save, *out_buf;
	int obytes_processed = 0;

	set_error_fn(error_fn);

	if (output)
		out_buf = output;
	else if (!flush) {
		error("NULL output pointer and no flush function provided");
		goto exit;
	} else {
		out_buf = malloc(LZO_BLOCK_SIZE);
		if (!out_buf) {
			error("Could not allocate output buffer");
			goto exit;
		}
	}

	if (input && fill) {
		error("Both input pointer and fill function provided, don't know what to do");
		goto exit_1;
	} else if (input)
		in_buf = input;
	else if (!fill || !posp) {
		error("NULL input pointer and missing position pointer or fill function");
		goto exit_1;
	} else {
		in_buf = malloc(lzo1x_worst_compress(LZO_BLOCK_SIZE));
		if (!in_buf) {
			error("Could not allocate input buffer");
			goto exit_1;
		}
	}
	in_buf_save = in_buf;

	if (posp)
		*posp = 0;

	if (fill)
		fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE));

	if (!parse_header(input, &skip)) {
		error("invalid header");
		goto exit_2;
	}
	in_buf += skip;

	if (posp)
		*posp = skip;

	for (;;) {
		/* read uncompressed block size */
		dst_len = get_unaligned_be32(in_buf);
		in_buf += 4;

		/* exit if last block */
		if (dst_len == 0) {
			if (posp)
				*posp += 4;
			break;
		}

		if (dst_len > LZO_BLOCK_SIZE) {
			error("dest len longer than block size");
			goto exit_2;
		}

		/* read compressed block size, and skip block checksum info */
		src_len = get_unaligned_be32(in_buf);
		in_buf += 8;

		if (src_len <= 0 || src_len > dst_len) {
			error("file corrupted");
			goto exit_2;
		}

		/* decompress */
		tmp = dst_len;
		r = lzo1x_decompress_safe((u8 *) in_buf, src_len, out_buf, &tmp);

		if (r != LZO_E_OK || dst_len != tmp) {
			error("Compressed data violation");
			goto exit_2;
		}

		obytes_processed += dst_len;
		if (flush)
			flush(out_buf, dst_len);
		if (output)
			out_buf += dst_len;
		if (posp)
			*posp += src_len + 12;
		if (fill) {
			in_buf = in_buf_save;
			fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE));
		} else
			in_buf += src_len;
	}

exit_2:
	if (!input)
		free(in_buf);
exit_1:
	if (!output)
		free(out_buf);
exit:
	return obytes_processed;
}
Exemplo n.º 9
0
static ssize_t
lzop_filter_read(struct archive_read_filter *self, const void **p)
{
	struct read_lzop *state = (struct read_lzop *)self->data;
	const void *b;
	lzo_uint out_size;
	uint32_t cksum;
	int ret, r;

	if (state->unconsumed_bytes) {
		__archive_read_filter_consume(self->upstream,
		    state->unconsumed_bytes);
		state->unconsumed_bytes = 0;
	}
	if (state->eof)
		return (0);

	for (;;) {
		if (!state->in_stream) {
			ret = consume_header(self);
			if (ret < ARCHIVE_OK)
				return (ret);
			if (ret == ARCHIVE_EOF) {
				state->eof = 1;
				return (0);
			}
		}
		ret = consume_block_info(self);
		if (ret < ARCHIVE_OK)
			return (ret);
		if (ret == ARCHIVE_EOF)
			state->in_stream = 0;
		else
			break;
	}

	if (state->out_block == NULL ||
	    state->out_block_size < state->uncompressed_size) {
		void *new_block;

		new_block = realloc(state->out_block, state->uncompressed_size);
		if (new_block == NULL) {
			archive_set_error(&self->archive->archive, ENOMEM,
			    "Can't allocate data for lzop decompression");
			return (ARCHIVE_FATAL);
		}
		state->out_block = new_block;
		state->out_block_size = state->uncompressed_size;
	}

	b = __archive_read_filter_ahead(self->upstream,
		state->compressed_size, NULL);
	if (b == NULL) {
		archive_set_error(&self->archive->archive,
		    ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data");
		return (ARCHIVE_FATAL);
	}
	if (state->flags & CRC32_COMPRESSED)
		cksum = crc32(crc32(0, NULL, 0), b, state->compressed_size);
	else if (state->flags & ADLER32_COMPRESSED)
		cksum = adler32(adler32(0, NULL, 0), b, state->compressed_size);
	else
		cksum = state->compressed_cksum;
	if (cksum != state->compressed_cksum) {
		archive_set_error(&self->archive->archive,
		    ARCHIVE_ERRNO_MISC, "Corrupted data");
		return (ARCHIVE_FATAL);
	}

	/*
	 * If the both uncompressed size and compressed size are the same,
	 * we do not decompress this block.
	 */
	if (state->uncompressed_size == state->compressed_size) {
		*p = b;
		state->total_out += state->compressed_size;
		state->unconsumed_bytes = state->compressed_size;
		return ((ssize_t)state->uncompressed_size);
	}

	/*
	 * Drive lzo uncompresison.
	 */
	out_size = (lzo_uint)state->uncompressed_size;
	r = lzo1x_decompress_safe(b, (lzo_uint)state->compressed_size,
		state->out_block, &out_size, NULL);
	switch (r) {
	case LZO_E_OK:
		if (out_size == state->uncompressed_size)
			break;
		archive_set_error(&self->archive->archive,
		    ARCHIVE_ERRNO_MISC, "Corrupted data");
		return (ARCHIVE_FATAL);
	case LZO_E_OUT_OF_MEMORY:
		archive_set_error(&self->archive->archive, ENOMEM,
		    "lzop decompression failed: out of memory");
		return (ARCHIVE_FATAL);
	default:
		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
		    "lzop decompression failed: %d", r);
		return (ARCHIVE_FATAL);
	}

	if (state->flags & CRC32_UNCOMPRESSED)
		cksum = crc32(crc32(0, NULL, 0), state->out_block,
		    state->uncompressed_size);
	else if (state->flags & ADLER32_UNCOMPRESSED)
		cksum = adler32(adler32(0, NULL, 0), state->out_block,
		    state->uncompressed_size);
	else
		cksum = state->uncompressed_cksum;
	if (cksum != state->uncompressed_cksum) {
		archive_set_error(&self->archive->archive,
		    ARCHIVE_ERRNO_MISC, "Corrupted data");
		return (ARCHIVE_FATAL);
	}

	__archive_read_filter_consume(self->upstream, state->compressed_size);
	*p = state->out_block;
	state->total_out += out_size;
	return ((ssize_t)out_size);
}
Exemplo n.º 10
0
static bool decompress_with_lzo(JCR *jcr,
                                const char *last_fname,
                                char **data,
                                uint32_t *length,
                                bool sparse,
                                bool want_data_stream)
{
   char ec1[50]; /* Buffer printing huge values */
   lzo_uint compress_len;
   const unsigned char *cbuf;
   unsigned char *wbuf;
   int status, real_compress_len;

   if (sparse && want_data_stream) {
      compress_len = jcr->compress.inflate_buffer_size - OFFSET_FADDR_SIZE;
      cbuf = (const unsigned char *)*data + OFFSET_FADDR_SIZE + sizeof(comp_stream_header);
      wbuf = (unsigned char *)jcr->compress.inflate_buffer + OFFSET_FADDR_SIZE;
   } else {
      compress_len = jcr->compress.inflate_buffer_size;
      cbuf = (const unsigned char *)*data + sizeof(comp_stream_header);
      wbuf = (unsigned char *)jcr->compress.inflate_buffer;
   }

   real_compress_len = *length - sizeof(comp_stream_header);
   Dmsg2(400, "Comp_len=%d msglen=%d\n", compress_len, *length);
   while ((status = lzo1x_decompress_safe(cbuf, real_compress_len, wbuf, &compress_len, NULL)) == LZO_E_OUTPUT_OVERRUN) {
      /*
       * The buffer size is too small, try with a bigger one
       */
      jcr->compress.inflate_buffer_size = jcr->compress.inflate_buffer_size + (jcr->compress.inflate_buffer_size >> 1);
      jcr->compress.inflate_buffer = check_pool_memory_size(jcr->compress.inflate_buffer, jcr->compress.inflate_buffer_size);

      if (sparse && want_data_stream) {
         compress_len = jcr->compress.inflate_buffer_size - OFFSET_FADDR_SIZE;
         wbuf = (unsigned char *)jcr->compress.inflate_buffer + OFFSET_FADDR_SIZE;
      } else {
         compress_len = jcr->compress.inflate_buffer_size;
         wbuf = (unsigned char *)jcr->compress.inflate_buffer;
      }
      Dmsg2(400, "Comp_len=%d msglen=%d\n", compress_len, *length);
   }

   if (status != LZO_E_OK) {
      Qmsg(jcr, M_ERROR, 0, _("LZO uncompression error on file %s. ERR=%d\n"), last_fname, status);
      return false;
   }

   /*
    * We return a decompressed data stream with the fileoffset encoded when this was a sparse stream.
    */
   if (sparse && want_data_stream) {
      memcpy(jcr->compress.inflate_buffer, *data, OFFSET_FADDR_SIZE);
   }

   *data = jcr->compress.inflate_buffer;
   *length = compress_len;

   Dmsg2(400, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));

   return true;
}
Exemplo n.º 11
0
static int
_fill_decompressed_buffer(struct compressed_chunk_s * chunk, gsize to_skip)
{
	DEBUG("_fill_decompressed_buffer: START\n");
	gsize nb_read;
	gsize in_len;
	gulong out_len;
	gsize total_skipped = 0;
	int r;

	if(chunk->buf)
		g_free(chunk->buf);

	chunk->buf = NULL;
	chunk->buf_len = 0;
	chunk->buf_offset = 0;
	chunk->data_len = 0;

	while(1) {
		/* read uncompressed size */
		nb_read = 0;
		nb_read = fread(&out_len, sizeof(out_len), 1, chunk->fd);
		if (nb_read != 1) {
			DEBUG("Failed to read compressed chunk size");
			return -1;
		}
		/* exit if last block (EOF marker) */
		if(out_len == 0) {
			return 0;
		}

		/* read compressed size */
		in_len = 0;
		nb_read = 0;
		nb_read = fread(&in_len, sizeof(in_len), 1, chunk->fd);

		if (nb_read != 1) {
			return -1;
		}
		/* check if we are in good block */
		if(to_skip < total_skipped + out_len) {
			/* data in this block */
			chunk->data_len = out_len;
			chunk->buf_offset = to_skip - total_skipped;
			break;
		} else {
			/* don't need to uncompress this block, go to the next */
			total_skipped += out_len;
			if(fseek(chunk->fd, in_len, SEEK_CUR)) {
				/* fseek issue */
				return -1;
			}
		}
	}

	/* Consider the "to_skip" bytes already read */
	chunk->read += to_skip;

	DEBUG("_fill_decompressed_buffer: current block compressed size (read from file): %"G_GSIZE_FORMAT, in_len);
	DEBUG("_fill_decompressed_buffer: block_size = %u", (uint)chunk->block_size);

	/* sanity check of the size values */
	if (in_len > chunk->block_size || chunk->data_len > chunk->block_size ||
			in_len == 0 || in_len > chunk->data_len){
		DEBUG("_fill_decompressed_buffer: block size error - data corrupted");
		r = -1;
		goto err;
	}
	DEBUG("_fill_decompressed_buffer: ok, data not corrupted, it's time to work");

	/* Manage the case of uncompressed data */
	if (in_len == chunk->data_len) {
		chunk->buf_len = chunk->data_len;
		chunk->buf = g_malloc0(chunk->buf_len);
		nb_read = 0;
		nb_read = fread(chunk->buf, chunk->buf_len, 1, chunk->fd);
		if (nb_read != 1) {
			DEBUG("Failed to read uncompressed block");
			r = -1;
			goto err;
		}
	}
	else { /* in_len < chunk->data_len */
		lzo_bytep in;
		lzo_uint new_len;

		chunk->buf_len = chunk->data_len;
		chunk->buf = g_malloc0(chunk->buf_len);

		DEBUG("_fill_uncompressed_buffer: before lzo1x_decompress_safe"
				" (input=%u max_out=%u expected=%u)\n",
				(uint)in_len, (uint)chunk->buf_len, (uint)chunk->data_len);

		in = g_malloc0(in_len);
		nb_read = 0;
		nb_read = fread(in, in_len, 1, chunk->fd);
		if (nb_read != 1) {
			g_free(in);
			DEBUG("Failed to read compressed block");
			r = -1;
			goto err;
		}

		/* decompress - use safe decompressor as data might be corrupted
		 * during a file transfer */
		new_len = chunk->buf_len;
		r = lzo1x_decompress_safe(in, in_len, chunk->buf, &new_len, NULL);
		g_free(in);

		if (r != LZO_E_OK || new_len != chunk->data_len) {
			DEBUG("_fill_uncompressed_buffer: compressed data violation"
					" (input=%u max_out=%u expected=%u got=%u)\n",
					(uint)in_len, (uint)chunk->buf_len, (uint)chunk->data_len, (uint)new_len);
			r = -1;
			goto err;
		}

		DEBUG("_fill_uncompressed_buffer: afetr lzo1x_decompress_safe"
				" (input=%u max_out=%u expected=%u got=%u)\n",
				(uint)in_len, (uint)chunk->buf_len, (uint)chunk->data_len, (uint)new_len);
	}

	/* update checksum */
	if (chunk->flags & LZO_FLAG_CHECKSUM) {
		DEBUG("data used for checksum : %u\n", (uint)chunk->data_len);
		lzo_uint32 checksum32 = 0;
		checksum32 = chunk->checksum;
		checksum32 = lzo_adler32(checksum32, chunk->buf, chunk->data_len);
		chunk->checksum = checksum32;
		DEBUG("_fill_decompressed_buffer: checksum updated\n");
	}

	r = 1;
err:
	return r;
}
Exemplo n.º 12
0
static int zram_read(struct zram *zram, struct bio *bio)
{

	int i;
	u32 index;
	struct bio_vec *bvec;

	if (unlikely(!zram->init_done)) {
		set_bit(BIO_UPTODATE, &bio->bi_flags);
		bio_endio(bio, 0);
		return 0;
	}

	zram_stat64_inc(zram, &zram->stats.num_reads);
	index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;

	bio_for_each_segment(bvec, bio, i) {
		int ret;
		size_t clen;
		struct page *page;
		struct zobj_header *zheader;
		unsigned char *user_mem, *cmem;

		page = bvec->bv_page;

		if (zram_test_flag(zram, index, ZRAM_ZERO)) {
			handle_zero_page(page);
			index++;
			continue;
		}

		/* Requested page is not present in compressed area */
		if (unlikely(!zram->table[index].page)) {
			pr_debug("Read before write: sector=%lu, size=%u",
				(ulong)(bio->bi_sector), bio->bi_size);
			/* Do nothing */
			index++;
			continue;
		}

		/* Page is stored uncompressed since it's incompressible */
		if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) {
			handle_uncompressed_page(zram, page, index);
			index++;
			continue;
		}

		user_mem = kmap_atomic(page, KM_USER0);
		clen = PAGE_SIZE;

		cmem = kmap_atomic(zram->table[index].page, KM_USER1) +
				zram->table[index].offset;

		ret = lzo1x_decompress_safe(
			cmem + sizeof(*zheader),
			xv_get_object_size(cmem) - sizeof(*zheader),
			user_mem, &clen);

		kunmap_atomic(user_mem, KM_USER0);
		kunmap_atomic(cmem, KM_USER1);

		/* Should NEVER happen. Return bio error if it does. */
		if (unlikely(ret != LZO_E_OK)) {
			pr_err("Decompression failed! err=%d, page=%u\n",
				ret, index);
			zram_stat64_inc(zram, &zram->stats.failed_reads);
			goto out;
		}

		flush_dcache_page(page);
		index++;
	}
bool xboxIMGCompression::Decompress( CFile *input, CFile *output )
{
    // Make sure we have LZO.
    this->InitializeLZO();

    if ( !this->isUsingLZO )
    {
        // We cannot continue if LZO has failed to initialize.
        return false;
    }

    bool decompressionSuccess = false;

    // Determine what kind of compression we have and decompress.
    fsUInt_t magic = 0;

    bool couldReadMagic = input->ReadUInt( magic );

    if ( couldReadMagic )
    {
        // Also read the compression header.
        compressionHeader header;

        bool couldReadHeader = input->ReadStruct( header );

        if ( couldReadHeader )
        {
            // lzo1x(-999)
            if ( magic == 0x67A3A1CE )
            {
                // Prepare a memory block that will be used as compression buffer.
                void *compressedFileData = malloc( header.blockSize );

                // Copy the work buffer over fast.
                // This leaves the decompress buffer in our class in an invalid state.
                simpleWorkBuffer localDecompressBuffer = this->decompressBuffer;

                bool hasDecompressBufferChanged = false;

                // Make sure we have got any decompression buffer before we start.
                bool hasAllocatedMinimum = localDecompressBuffer.MinimumSize( minimumDecompressBufferSize );

                if ( hasAllocatedMinimum )
                {
                    hasDecompressBufferChanged = true;
                }

                if ( compressedFileData && localDecompressBuffer.IsReady() )
                {
                    size_t segmentRemaining = header.blockSize;

                    bool lzoSuccess = true;

                    checksumCallback_t _checksumCallback = NULL;

                    if ( _performLZOChecksumVerify )
                    {
                        _checksumCallback = this->_checksumCallback;
                    }

                    // Verify the checksum.
                    lzo_uint32_t checksum = 0;

                    if ( _checksumCallback != NULL )
                    {
                        checksum = _checksumCallback( 0, NULL, 0 );
                    }

                    // Read all blocks.
                    while ( true )
                    {
                        // Check whether we reached the end.
                        if ( segmentRemaining == 0 )
                        {
                            // We can safely exit the loop here.
                            break;
                        }

                        // Read the block header.
                        perBlockHeader blockHeader;

                        bool couldReadBlock = input->ReadStruct( blockHeader );

                        if ( !couldReadBlock )
                        {
                            lzoSuccess = false;
                            break;
                        }

                        // Verify that this block is valid.
                        if ( blockHeader.compressedSize > header.blockSize )
                        {
                            lzoSuccess = false;
                            break;
                        }

                        // Check some non-trivial stuff.
                        if ( blockHeader.unk != 4 || blockHeader.compressedSize != blockHeader.uncompressedSize )
                        {
                            lzoSuccess = false;
                            break;
                        }

                        // Read the compressed block.
                        size_t dataReadCount = input->Read( compressedFileData, 1, blockHeader.compressedSize );

                        if ( dataReadCount != blockHeader.compressedSize )
                        {
                            lzoSuccess = false;
                            break;
                        }

repeatDecompress:
                        // Decompress our block.
                        void *decompressBuffer = localDecompressBuffer.GetPointer();

                        lzo_uint realDecompressedSize = localDecompressBuffer.GetSize();

                        int lzoerr = lzo1x_decompress_safe(
                            (const unsigned char*)compressedFileData, blockHeader.compressedSize,
                            (unsigned char*)decompressBuffer, &realDecompressedSize,
                            NULL
                        );

                        // Handle valid errors.
                        if ( lzoerr == LZO_E_OUTPUT_OVERRUN )
                        {
                            // Increase buffer size.
                            localDecompressBuffer.Grow( realDecompressedSize );

                            // Remember that we updated the decompression buffer.
                            hasDecompressBufferChanged = true;

                            // Try again.
                            goto repeatDecompress;
                        }

                        if ( lzoerr != LZO_E_OK )
                        {
                            lzoSuccess = false;
                            break;
                        }

                        // Write the decompressed stuff into the file.
                        output->Write( decompressBuffer, 1, realDecompressedSize );

                        if ( _checksumCallback != NULL )
                        {
                            // Update checksum.
                            checksum = _checksumCallback( checksum, decompressBuffer, realDecompressedSize );
                        }

                        // Decrease the remaining bytes.
                        size_t processedSize = ( blockHeader.compressedSize + sizeof( blockHeader ) );

                        if ( segmentRemaining < processedSize )
                        {
                            lzoSuccess = false;
                            break;
                        }

                        segmentRemaining -= processedSize;
                    }

                    if ( lzoSuccess )
                    {
                        // Verify the checksum.
                        bool isDataValid = true;

                        if ( isDataValid && ( _checksumCallback != NULL ) )
                        {
                            bool isChecksumValid = ( checksum == header.checksum );

                            if ( !isChecksumValid )
                            {
                                isDataValid = false;
                            }
                        }

                        if ( isDataValid )
                        {
                            // If we succeeded, we have got decompressed data in the output stream.
                            decompressionSuccess = true;
                        }
                    }
                }

                // Clean up.
                if ( compressedFileData )
                {
                    free( compressedFileData );
                }

                // Update the decompress buffer.
                if ( hasDecompressBufferChanged )
                {
                    // Validate the decompress buffer in our class again.
                    this->decompressBuffer = localDecompressBuffer;
                }

                // Release our buffer so we do not free it.
                localDecompressBuffer.Release();
            }
        }
    }

    return decompressionSuccess;
}
Exemplo n.º 14
0
int appDecompress(byte *CompressedBuffer, int CompressedSize, byte *UncompressedBuffer, int UncompressedSize, int Flags)
{
	guard(appDecompress);

#if BLADENSOUL
	if (GForceGame == GAME_BladeNSoul && Flags == COMPRESS_LZO_ENC_BNS)	// note: GForceGame is required (to not pass 'Game' here)
	{
		if (CompressedSize >= 32)
		{
			static const char *key = "qiffjdlerdoqymvketdcl0er2subioxq";
			for (int i = 0; i < CompressedSize; i++)
				CompressedBuffer[i] ^= key[i % 32];
		}
		// overide compression
		Flags = COMPRESS_LZO;
	}
#endif // BLADENSOUL

#if SMITE
	if (GForceGame == GAME_Smite && Flags == COMPRESS_LZO_ENC_SMITE)
	{
		for (int i = 0; i < CompressedSize; i++)
			CompressedBuffer[i] ^= 0x2A;
		// overide compression
		Flags = COMPRESS_LZO;
	}
#endif // SMITE

#if TAO_YUAN
	if (GForceGame == GAME_TaoYuan)	// note: GForceGame is required (to not pass 'Game' here);
	{
		static const byte key[] =
		{
			137, 35, 95, 142, 69, 136, 243, 119, 25, 35, 111, 94, 101, 136, 243, 204,
			243, 67, 95, 158, 69, 106, 107, 187, 237, 35, 103, 142, 72, 142, 243
		};
		for (int i = 0; i < CompressedSize; i++)
			CompressedBuffer[i] ^= key[i % 31];		// note: "N % 31" is not the same as "N & 0x1F"
	}
#endif // TAO_YUAN

#if ALICE
	// this code exists in Alice: Madness Returns only
	if (GForceGame == GAME_Alice && CompressedSize == UncompressedSize)
	{
		// CompressedSize == UncompressedSize -> no compression
		memcpy(UncompressedBuffer, CompressedBuffer, UncompressedSize);
		return UncompressedSize;
	}
#endif // ALICE

	if (Flags == COMPRESS_FIND && CompressedSize >= 2)
	{
		byte b1 = CompressedBuffer[0];
		byte b2 = CompressedBuffer[1];
		// detect compression
		// zlib:
		//   http://tools.ietf.org/html/rfc1950
		//   http://stackoverflow.com/questions/9050260/what-does-a-zlib-header-look-like
		if ( b1 == 0x78 &&					// b1=CMF: 7=32k buffer (CINFO), 8=deflate (CM)
			(b2 == 0x9C || b2 == 0xDA) )	// b2=FLG
		{
			Flags = COMPRESS_ZLIB;
		}
		else
			Flags = COMPRESS_LZO;
	}

	if (Flags == COMPRESS_LZO)
	{
		int r;
		r = lzo_init();
		if (r != LZO_E_OK) appError("lzo_init() returned %d", r);
		lzo_uint newLen = UncompressedSize;
		r = lzo1x_decompress_safe(CompressedBuffer, CompressedSize, UncompressedBuffer, &newLen, NULL);
		if (r != LZO_E_OK) appError("lzo_decompress(%d,%d) returned %d", CompressedSize, UncompressedSize, r);
		if (newLen != UncompressedSize) appError("len mismatch: %d != %d", newLen, UncompressedSize);
		return newLen;
	}

	if (Flags == COMPRESS_ZLIB)
	{
#if 0
		appError("appDecompress: Zlib compression is not supported");
#else
		unsigned long newLen = UncompressedSize;
		int r = uncompress(UncompressedBuffer, &newLen, CompressedBuffer, CompressedSize);
		if (r != Z_OK) appError("zlib uncompress(%d,%d) returned %d", CompressedSize, UncompressedSize, r);
//		if (newLen != UncompressedSize) appError("len mismatch: %d != %d", newLen, UncompressedSize); -- needed by Bioshock
		return newLen;
#endif
	}

	if (Flags == COMPRESS_LZX)
	{
#if SUPPORT_XBOX360
#	if !USE_XDK
		appDecompressLZX(CompressedBuffer, CompressedSize, UncompressedBuffer, UncompressedSize);
		return UncompressedSize;
#	else
		void *context;
		int r;
		r = XMemCreateDecompressionContext(0, NULL, 0, &context);
		if (r < 0) appError("XMemCreateDecompressionContext failed");
		unsigned int newLen = UncompressedSize;
		r = XMemDecompress(context, UncompressedBuffer, &newLen, CompressedBuffer, CompressedSize);
		if (r < 0) appError("XMemDecompress failed");
		if (newLen != UncompressedSize) appError("len mismatch: %d != %d", newLen, UncompressedSize);
		XMemDestroyDecompressionContext(context);
		return newLen;
#	endif // USE_XDK
#else  // SUPPORT_XBOX360
		appError("appDecompress: LZX compression is not supported");
#endif // SUPPORT_XBOX360
	}

	appError("appDecompress: unknown compression flags: %d", Flags);
	return 0;

	unguardf("CompSize=%d UncompSize=%d Flags=0x%X", CompressedSize, UncompressedSize, Flags);
}
Exemplo n.º 15
0
    void compressor::lzo_read_and_uncompress_to_buffer()
    {
#if LIBLZO2_AVAILABLE
	lzo_block_header lzo_bh;
	lzo_uint compr_size;
	int status;
#if LZO1X_MEM_DECOMPRESS > 0
	char wrkmem[LZO1X_MEM_DECOMPRESS];
#else
	char *wrkmem = NULL;
#endif

	if(compressed == NULL)
	    throw SRC_BUG;

	lzo_bh.set_from(*compressed);
	if(lzo_bh.type != BLOCK_HEADER_LZO && lzo_bh.type != BLOCK_HEADER_EOF)
	    throw Erange("compressor::lzo_read_and_uncompress_to_buffer", gettext("data corruption detected: Incoherence in LZO compressed data"));
	if(lzo_bh.type == BLOCK_HEADER_EOF)
	{
	    if(lzo_bh.size != 0)
		throw Erange("compressor::lzo_read_and_uncompress_to_buffer", gettext("compressed data corruption detected"));
	    lzo_read_size = 0;
	    lzo_read_start = 0;
	}
	else
	{
	    lzo_uint read;

	    if(lzo_bh.size > LZO_COMPRESSED_BUFFER_SIZE)
#if !defined(SSIZE_MAX) || SSIZE_MAX > BUFFER_SIZE
		throw Erange("compressor::lzo_read_and_uncompress_to_buffer", gettext("data corruption detected: Too large block of compressed data"));
#else
	    throw Erange("compressor::lzo_read_and_uncompress_to_buffer", gettext("Too large block of compressed data: Either due to data corruption or current system limitation where SSIZE_MAX value implied smaller buffers than required"));
#endif

	    compr_size = 0;
	    lzo_bh.size.unstack(compr_size);
	    if(lzo_bh.size != 0)
		throw SRC_BUG;

	    read = compressed->read(lzo_compressed, compr_size);
	    if(read != compr_size)
		Erange("compressor::lzo_read_and_uncompress_to_buffer", gettext("compressed data corruption detected"));
	    read = LZO_CLEAR_BUFFER_SIZE;
	    status = lzo1x_decompress_safe((lzo_bytep)lzo_compressed, compr_size, (lzo_bytep)lzo_read_buffer, &read, wrkmem);
	    lzo_read_size = read;
	    lzo_read_start = 0;

	    switch(status)
	    {
	    case LZO_E_OK:
		break; // all is fine
	    case LZO_E_INPUT_NOT_CONSUMED:
		throw SRC_BUG;
	    default:
		lzo_read_size = 0;
		throw Erange("compressor::lzo_read_and_uncompress_to_buffer", gettext("compressed data corruption detected"));
	    }
	}
#else
	throw Efeature(gettext("lzo compression"));
#endif
    }
static int eeprom_config_read_compressed_data(struct msm_eeprom_ctrl_t *e_ctrl,
	struct msm_eeprom_cfg_data *cdata)
{
	int rc = 0;
#if 0 //  just once to power up when load lib
	bool down;
#endif

	uint8_t *buf_comp = NULL;
	uint8_t *buf_decomp = NULL;
	uint32_t decomp_size;

	pr_err("%s: address (0x%x) comp_size (%d) after decomp (%d)", __func__,
   cdata->cfg.read_data.addr,
   cdata->cfg.read_data.comp_size, cdata->cfg.read_data.num_bytes);

	buf_comp = kmalloc(cdata->cfg.read_data.comp_size, GFP_KERNEL);
	buf_decomp = kmalloc(cdata->cfg.read_data.num_bytes, GFP_KERNEL);
	if (!buf_decomp || !buf_comp) {
    pr_err("%s: kmalloc fail", __func__);
    rc = -ENOMEM;
    goto FREE;
	}

#if 0 //  just once to power up when load lib
	rc = msm_eeprom_power_up(e_ctrl, &down);
	if (rc < 0) {
    pr_err("%s: failed to power on eeprom\n", __func__);
    goto FREE;
	}
#endif

  rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_read_seq(
    &(e_ctrl->i2c_client), cdata->cfg.read_data.addr,
    buf_comp, cdata->cfg.read_data.comp_size);

  if (rc < 0) {
    pr_err("%s: failed to read data, rc %d\n", __func__, rc);
    goto POWER_DOWN;
  }

  pr_err("%s: crc = 0x%08X\n", __func__, *(uint32_t*)&buf_comp[cdata->cfg.read_data.comp_size-4]);
  //  compressed data(buf_comp) contains uncompressed crc32 value.
  rc = msm_eeprom_verify_sum(buf_comp, cdata->cfg.read_data.comp_size-4,
    *(uint32_t*)&buf_comp[cdata->cfg.read_data.comp_size-4]);

  if (rc < 0) {
    pr_err("%s: crc check error, rc %d\n", __func__, rc);
    goto POWER_DOWN;
  }

	decomp_size = cdata->cfg.read_data.num_bytes;
	rc = lzo1x_decompress_safe(buf_comp, cdata->cfg.read_data.comp_size-4,
	                           buf_decomp, &decomp_size);
  if (rc != LZO_E_OK) {
    pr_err("%s: decompression failed %d", __func__, rc);
    goto POWER_DOWN;
  }
	rc = copy_to_user(cdata->cfg.read_data.dbuffer, buf_decomp, decomp_size);

	if (rc < 0) {
    pr_err("%s: failed to copy to user\n", __func__);
    goto POWER_DOWN;
  }

	pr_info("%s: done", __func__);

POWER_DOWN:
#if 0 //  just once to power up when load lib
	msm_eeprom_power_down(e_ctrl, down);
#endif

	FREE:
	if (buf_comp) kfree(buf_comp);
	if (buf_decomp) kfree(buf_decomp);

	return rc;
}
STATIC inline int INIT unlzo(u8 *input, int in_len,
				int (*fill) (void *, unsigned int),
				int (*flush) (void *, unsigned int),
				u8 *output, int *posp,
				void (*error) (char *x))
{
	u8 r = 0;
	int skip = 0;
	u32 src_len, dst_len;
	size_t tmp;
	u8 *in_buf, *in_buf_save, *out_buf;
	int ret = -1;

	if (output) {
		out_buf = output;
	} else if (!flush) {
		error("NULL output pointer and no flush function provided");
		goto exit;
	} else {
		out_buf = malloc(LZO_BLOCK_SIZE);
		if (!out_buf) {
			error("Could not allocate output buffer");
			goto exit;
		}
	}

	if (input && fill) {
		error("Both input pointer and fill function provided, don't know what to do");
		goto exit_1;
	} else if (input) {
		in_buf = input;
	} else if (!fill) {
		error("NULL input pointer and missing fill function");
		goto exit_1;
	} else {
		in_buf = malloc(lzo1x_worst_compress(LZO_BLOCK_SIZE));
		if (!in_buf) {
			error("Could not allocate input buffer");
			goto exit_1;
		}
	}
	in_buf_save = in_buf;

	if (posp)
		*posp = 0;

	if (fill) {
		/*
                                                            
                                                             
                                                         
                                                         
   */
		in_buf += HEADER_SIZE_MAX;
		in_len = fill(in_buf, HEADER_SIZE_MAX);
	}

	if (!parse_header(in_buf, &skip, in_len)) {
		error("invalid header");
		goto exit_2;
	}
	in_buf += skip;
	in_len -= skip;

	if (fill) {
		/*                                                      */
		memcpy(in_buf_save, in_buf, in_len);
		in_buf = in_buf_save;
	}

	if (posp)
		*posp = skip;

	for (;;) {
		/*                              */
		if (fill && in_len < 4) {
			skip = fill(in_buf + in_len, 4 - in_len);
			if (skip > 0)
				in_len += skip;
		}
		if (in_len < 4) {
			error("file corrupted");
			goto exit_2;
		}
		dst_len = get_unaligned_be32(in_buf);
		in_buf += 4;
		in_len -= 4;

		/*                    */
		if (dst_len == 0) {
			if (posp)
				*posp += 4;
			break;
		}

		if (dst_len > LZO_BLOCK_SIZE) {
			error("dest len longer than block size");
			goto exit_2;
		}

		/*                                                          */
		if (fill && in_len < 8) {
			skip = fill(in_buf + in_len, 8 - in_len);
			if (skip > 0)
				in_len += skip;
		}
		if (in_len < 8) {
			error("file corrupted");
			goto exit_2;
		}
		src_len = get_unaligned_be32(in_buf);
		in_buf += 8;
		in_len -= 8;

		if (src_len <= 0 || src_len > dst_len) {
			error("file corrupted");
			goto exit_2;
		}

		/*            */
		if (fill && in_len < src_len) {
			skip = fill(in_buf + in_len, src_len - in_len);
			if (skip > 0)
				in_len += skip;
		}
		if (in_len < src_len) {
			error("file corrupted");
			goto exit_2;
		}
		tmp = dst_len;

		/*                                              
                                                      
             */
		if (unlikely(dst_len == src_len))
			memcpy(out_buf, in_buf, src_len);
		else {
			r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
						out_buf, &tmp);

			if (r != LZO_E_OK || dst_len != tmp) {
				error("Compressed data violation");
				goto exit_2;
			}
		}

		if (flush && flush(out_buf, dst_len) != dst_len)
			goto exit_2;
		if (output)
			out_buf += dst_len;
		if (posp)
			*posp += src_len + 12;

		in_buf += src_len;
		in_len -= src_len;
		if (fill) {
			/*
                                                      
                                                     
                                               
    */
			if (in_len > 0)
				for (skip = 0; skip < in_len; ++skip)
					in_buf_save[skip] = in_buf[skip];
			in_buf = in_buf_save;
		}
	}

	ret = 0;
exit_2:
	if (!input)
		free(in_buf_save);
exit_1:
	if (!output)
		free(out_buf);
exit:
	return ret;
}
Exemplo n.º 18
0
BOOL GetFileUBISOFT_BF(const char * PackName, const char * FileName, const char * PathName, long StartOffset, long FileSize, long UnpSize, struct RIP_SERVICE_FUNC* func, struct RIP_FLAGS *flags){
	unsigned char * bufIn;
    unsigned char * bufOut;
    char * dstpath;    
    unsigned long rd, FrameUnp, FramePack, FOffset;
	unsigned int iFrameUnp;
	BOOL CanUnpacking;

	FOffset = StartOffset;
	CanUnpacking = TRUE;	

	if (UnpSize == 0) {
		dstpath = my_strdup(PathName, strlen(FileName)+2);
		strcat(dstpath, "\\");
		strcat(dstpath, FileName);
		while (FOffset-StartOffset < FileSize){
			rd = func->ReadFromFile(PackName, FOffset, &FrameUnp, sizeof FrameUnp);
			if (rd < sizeof FrameUnp) {my_free(dstpath); return FALSE;}
			FOffset += rd;

			rd = func->ReadFromFile(PackName, FOffset, &FramePack, sizeof FramePack);
			if (rd < sizeof FramePack) {my_free(dstpath); return FALSE;}
			FOffset += rd;

			if ((FramePack == 0)||(FrameUnp == 0)) {my_free(dstpath); return TRUE;}

			if (FramePack != FrameUnp){
				bufIn = (unsigned char *)my_malloc(FramePack);
				if (!bufIn) {my_free(dstpath); return FALSE;}

				bufOut = (unsigned char *)my_malloc(FrameUnp);
				if (!bufOut) {my_free(bufIn);my_free(dstpath); return FALSE;}

				rd = func->ReadFromFile(PackName, FOffset, bufIn, FramePack);
				if (rd < FramePack) {
					my_free(dstpath);
					my_free(bufIn);
					my_free(bufOut);				
					return FALSE;
				}
				FOffset += rd;			
				iFrameUnp = FrameUnp;
				int r = lzo1x_decompress_safe(bufIn, FramePack, bufOut, &iFrameUnp, NULL);
				if(r == LZO_E_OK || r == LZO_E_INPUT_NOT_CONSUMED && iFrameUnp){
				} else {
					my_free(dstpath); 
					my_free(bufIn);
					my_free(bufOut);				
					return FALSE;
				}
				my_free(bufIn);
				
				if (func->AppendToFile(dstpath, bufOut, iFrameUnp) != iFrameUnp){
					my_free(dstpath);
					my_free(bufOut);
					return FALSE;
				}
				my_free(bufOut);
			} else {
				bufIn = (unsigned char *)my_malloc(FramePack);
				if (!bufIn) {my_free(dstpath); return FALSE;}

				rd = func->ReadFromFile(PackName, FOffset, bufIn, FramePack);
				if (rd < FramePack) {
					my_free(dstpath);
					my_free(bufIn);					
					return FALSE;
				}
				FOffset += rd;

				if (func->AppendToFile(dstpath, bufIn, FramePack) != FramePack){
					my_free(dstpath);
					my_free(bufIn);
					return FALSE;
				}
			}
		}
		my_free(dstpath);
		return TRUE;
	}
	return FALSE;
}