int uncompress_data(const u8* base, const u8* data, u32 size, u8* dstdata) { printf("entering uncompress_data\n"); const u32* buffs=(const u32*)(data); int nblocks=(size-1)/blksize+1; const u8* buff=(const u8*)(buffs+nblocks); const u8* nbuff; int block=0; uLongf len=size; if (size == 0) { return 0; } for (; block < nblocks; ++block, buff=nbuff, dstdata+=blksize, len-=blksize ) { uLongf tran=(len < blksize) ? len : blksize; nbuff=base+*(buffs+block); printf("dstlen %d compresslen %d\n",tran,nbuff-buff); if (lzma_decode(dstdata, tran, buff, nbuff-buff) == -2) { fprintf(stderr,"Uncompression failed"); return -1; } else { return 0; } } return 0; }
int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen, int comp_method) { switch (comp_method) { case CRAMFS_FLAG_COMP_METHOD_GZIP: return cramfs_uncompress_block_gzip(dst, dstlen, src, srclen); case CRAMFS_FLAG_COMP_METHOD_LZMA: return lzma_decode(dst, dstlen, src, srclen); case CRAMFS_FLAG_COMP_METHOD_NONE: memcpy(dst, src, srclen); return srclen; } return 0; }
static int f_decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp) { /* bp buffer provided | bz buffer "zipped", compressed | n len of buffer provided | z len of buffer zipped \*---------------------------------------------------------------*/ /* unsigned char *ib = intermediate_block; unsigned int m; return huff_decode (bz, z, ib, &m, MAXBLOCK) && rle_decode (ib, m, bp, &n, MAXBLOCK); */ #if defined(HUFFMAN) if (CP_SCHEME == CP1) { /* HUFFMAN */ return huff_decode (bz, z, bp, &n, MAXBLOCK); } else #endif #if defined(LIBLZF) if (CP_SCHEME == CP2) { /* LZF */ return lzf_decode (bz, z, bp, &n, MAXBLOCK); } else #endif #if defined (ZLIB) if (CP_SCHEME == CP3) { /* ZLIB */ return zlib_decode (bz, z, bp, &n, MAXBLOCK); } else #endif if (CP_SCHEME == CP4) { /* LZMA86 */ return lzma_decode (bz, z, bp, &n, n); /* maximum needs to be the exact number that it will produce */ } else if (CP_SCHEME == CP7) { /* RLE */ return rle_decode (bz, z, bp, &n, MAXBLOCK); #if defined (LIBBZIP2) } else if (CP_SCHEME == CP8) { /* BZIP2 */ return bzip2_decode (bz, z, bp, &n, MAXBLOCK); #endif } else if (CP_SCHEME == CP9) { return justcopy_decode (bz, z, bp, &n, MAXBLOCK); } else { return FALSE; } }
/* . Seek; read stream footer (SEEK) . Seek; read index (SEEK, INFO) . Seek; read stream header (SEEK) . Read data (DATA) . Skip index and stream footer (DONE) */ int ffxz_read(ffxz *xz, char *dst, size_t cap) { int r; for (;;) { switch (xz->state) { case R_START: xz->inoff = xz->inoff - sizeof(struct stm_ftr); xz->hsize = sizeof(struct stm_ftr); xz->state = R_GATHER, xz->nxstate = R_FTR; return FFXZ_SEEK; case R_GATHER: r = ffarr_append_until(&xz->buf, xz->in.ptr, xz->in.len, xz->hsize); switch (r) { case 0: xz->inoff += xz->in.len; return FFXZ_MORE; case -1: return ERR(xz, FFXZ_ESYS); } ffstr_shift(&xz->in, r); xz->inoff += r; xz->state = xz->nxstate; continue; case R_HDRSEEK: xz->inoff = 0; xz->hsize = sizeof(struct stm_hdr); xz->state = R_GATHER, xz->nxstate = R_HDR; return FFXZ_SEEK; case R_HDR: if (0 > (r = xz_stmhdr_parse(xz->buf.ptr))) return ERR(xz, -r); xz->check_method = r; xz->buf.len = 0; xz->hsize = 1; xz->state = R_GATHER, xz->nxstate = R_BLKHDR_SIZE; continue; case R_BLKHDR_SIZE: { const byte *b = (void*)xz->buf.ptr; if (*b == 0) { xz->state = R_SKIP_IDX_FTR; continue; } xz->hsize = (*b + 1) * 4; xz->state = R_GATHER, xz->nxstate = R_BLKHDR; continue; } case R_BLKHDR: { lzma_filter_props filts[4]; if (0 > (r = xz_hdr_parse(xz->buf.ptr, xz->buf.len, filts))) return ERR(xz, -r); xz->buf.len = 0; if (0 != (r = lzma_decode_init(&xz->dec, xz->check_method, filts, r))) { xz->lzma_err = r; return ERR(xz, FFXZ_ELZMA); } xz->state = R_DATA; //break } case R_DATA: { size_t rd = xz->in.len; r = lzma_decode(xz->dec, xz->in.ptr, &rd, dst, cap); if (r == LZMA_DONE) { xz->hsize = 1; xz->state = R_GATHER, xz->nxstate = R_BLKHDR_SIZE; continue; } else if (r < 0) { xz->lzma_err = r; return ERR(xz, FFXZ_ELZMA); } ffstr_shift(&xz->in, rd); xz->inoff += rd; xz->insize += rd; if (r == 0) return FFXZ_MORE; ffstr_set(&xz->out, dst, r); xz->outsize += r; return FFXZ_DATA; } case R_SKIP_IDX_FTR: r = xz->idx_size - 1 + sizeof(struct stm_ftr); ffstr_shift(&xz->in, r); xz->inoff += r; xz->state = R_DONE; return FFXZ_SEEK; case R_DONE: return FFXZ_DONE; case R_IDX: { int64 rr; if (0 > (rr = xz_idx_parse(xz->buf.ptr, xz->buf.len))) return ERR(xz, -rr); xz->osize = rr; xz->buf.len = 0; xz->state = R_HDRSEEK; return FFXZ_INFO; } case R_FTR: { int64 rr; if (0 > (rr = xz_stmftr_parse(xz->buf.ptr))) return ERR(xz, -rr); // if (ftr->flags != hdr->flags) // return ERR(xz, FFXZ_EFTRFLAGS); xz->hsize = rr; xz->state = R_GATHER, xz->nxstate = R_IDX; xz->inoff = xz->inoff - xz->buf.len - rr; xz->idx_size = rr; xz->buf.len = 0; return FFXZ_SEEK; } } } }