Example #1
0
size_t ZlibRecompress(unsigned char *src, size_t src_len, size_t size_leanified /*= 0*/)
{
    if (!is_fast)
    {
        size_t s = 0;
        unsigned char *buffer = (unsigned char *)tinfl_decompress_mem_to_heap(src, src_len, &s, TINFL_FLAG_PARSE_ZLIB_HEADER);
        if (!buffer)
        {
            std::cerr << "Decompress Zlib data failed." << std::endl;
        }
        else
        {
            ZopfliOptions zopfli_options;
            ZopfliInitOptions(&zopfli_options);
            zopfli_options.numiterations = iterations;

            size_t new_size = 0;
            unsigned char *out_buffer = NULL;
            ZopfliZlibCompress(&zopfli_options, buffer, s, &out_buffer, &new_size);
            mz_free(buffer);
            if (new_size < src_len)
            {
                memcpy(src - size_leanified, out_buffer, new_size);
                delete[] out_buffer;
                return new_size;
            }
            delete[] out_buffer;
        }
    }

    memmove(src - size_leanified, src, src_len);
    return src_len;
}
/* --- GATEWAY FUNCTION --- */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

char *action;
unsigned char *IN = NULL, *OUT = NULL;
size_t INlen, OUTlen;

/* Check for proper number of arguments */
if (nrhs < 2)
    mexErrMsgTxt("Not enough input arguments.");
else if (nrhs > 2)
    mexErrMsgTxt("Too many input arguments.");
else if (nlhs > 1)
    mexErrMsgTxt("Too many output arguments.");

/* The input ACTION must be a string */
if (!mxIsChar(prhs[0]))
    mexErrMsgTxt("Input ACTION must be a string.");
action = mxArrayToString(prhs[0]);

/* The input IN must be a real uint8 array */
if (!mxIsUint8(prhs[1]) || mxIsComplex(prhs[1]))
    mexErrMsgTxt("Input IN must be a real uint8 array.");

INlen = mxGetNumberOfElements(prhs[1]);
IN = mxGetData(prhs[1]);

if (!strcmp(action,"D")) {

    /* Decompress data */
    OUT = tinfl_decompress_mem_to_heap(IN, INlen, &OUTlen, TINFL_FLAG_PARSE_ZLIB_HEADER);

    if (OUT == NULL)
        mexErrMsgTxt("Error when decompressing data.");
}
else if (!strcmp(action,"C")) {
    /* Compress data */
    OUT = tdefl_compress_mem_to_heap(IN, INlen, &OUTlen, TDEFL_WRITE_ZLIB_HEADER);
    
    if (OUT == NULL)
        mexErrMsgTxt("Error when compressing data.");
}
else {
    mexErrMsgTxt("Unknown ACTION type.");
}

/*  */
plhs[0] = mxCreateNumericMatrix(OUTlen,1,mxUINT8_CLASS,mxREAL);
if (plhs[0] == NULL)
    mexErrMsgTxt("Error when creating output variable.");

memcpy(mxGetData(plhs[0]), OUT, OUTlen);

mxFree(action);
mz_free(OUT);

}
Example #3
0
static int ltinfl(lua_State* L) {
  size_t in_len;
  const char* in_buf = luaL_checklstring(L, 1, &in_len);
  size_t out_len;
  int flags = luaL_optint(L, 2, 0);
  char* out_buf = tinfl_decompress_mem_to_heap(in_buf, in_len, &out_len, flags);
  lua_pushlstring(L, out_buf, out_len);
  free(out_buf);
  return 1;
}
Example #4
0
size_t Gz::Leanify(size_t size_leanified /*= 0*/)
{
    // written according to this specification
    // http://www.gzip.org/zlib/rfc-gzip.html

    if (size <= 18)
    {
        std::cerr << "Not a valid GZ file." << std::endl;
        return Format::Leanify(size_leanified);
    }

    depth++;
    char flags = *(fp + 3);
    // set the flags to 0, remove all unnecessary section
    *(fp + 3 - size_leanified) = 0;

    char *p_read = fp + 10;
    char *p_write = p_read - size_leanified;

    *(p_write - 2) = 2;     // XFL

    if (flags & (1 << 2))   // FEXTRA
    {
        p_read += *(uint16_t *)p_read + 2;
    }

    std::string filename;
    if (flags & (1 << 3))   // FNAME
    {
        for (int i = 1; i < depth; i++)
        {
            std::cout << "-> ";
        }
        std::cout << p_read << std::endl;
        filename = std::string(p_read);
        while (p_read < fp + size && *p_read++)
        {
            // skip string
        }
    }

    if (flags & (1 << 4))   // FCOMMENT
    {
        while (p_read < fp + size && *p_read++)
        {
            // skip string
        }
    }

    if (flags & (1 << 1))   // FHCRC
    {
        p_read += 2;
    }

    if (p_read >= fp + size)
    {
        return Format::Leanify(size_leanified);
    }

    if (size_leanified)
    {
        memmove(fp - size_leanified, fp, 10);
    }

    if (is_fast)
    {
        memmove(p_write, p_read, fp + size - p_read);
        return size - (p_read - p_write);
    }

    uint32_t uncompressed_size = *(uint32_t *)(fp + size - 4);
    uint32_t crc = *(uint32_t *)(fp + size - 8);
    size_t original_size = fp + size - 8 - p_read;

    size_t s = 0;
    unsigned char *buffer = (unsigned char *)tinfl_decompress_mem_to_heap(p_read, original_size, &s, 0);

    if (!buffer ||
        s != uncompressed_size ||
        crc != mz_crc32(0, buffer, uncompressed_size))
    {
        std::cerr << "GZ corrupted!" << std::endl;
        mz_free(buffer);
        memmove(p_write, p_read, original_size + 8);
        return size - (p_read - p_write);
    }

    uncompressed_size = LeanifyFile(buffer, uncompressed_size, 0, filename);

    ZopfliOptions options;
    ZopfliInitOptions(&options);
    options.numiterations = iterations;

    unsigned char bp = 0, *out = NULL;
    size_t outsize = 0;
    ZopfliDeflate(&options, 2, 1, buffer, uncompressed_size, &bp, &out, &outsize);


    if (outsize < original_size)
    {
        memcpy(p_write, out, outsize);
        p_write += outsize;
        *(uint32_t *)p_write = mz_crc32(0, buffer, uncompressed_size);
        *(uint32_t *)(p_write + 4) = uncompressed_size;
    }
    else
    {
        memmove(p_write, p_read, original_size + 8);
        p_write += original_size;
    }
    mz_free(buffer);
    delete[] out;
    depth--;
    fp -= size_leanified;
    return p_write + 8 - fp;
}