static int sc_decompress_zlib_alloc(u8** out, size_t* outLen, const u8* in, size_t inLen, int gzip) {
    /* Since uncompress does not offer a way to make it uncompress gzip... manually set it up */
    z_stream gz;
    int err;
    int window_size = 15;
    const int startSize = inLen < 1024 ? 2048 : inLen * 2;
    const int blockSize = inLen < 1024 ? 512 : inLen / 2;
    int bufferSize = startSize;
    if(gzip)
        window_size += 0x20;
    memset(&gz, 0, sizeof(gz));

    gz.next_in = (u8*)in;
    gz.avail_in = inLen;

    err = inflateInit2(&gz, window_size);
    if(err != Z_OK) return zerr_to_opensc(err);

    *outLen = 0;

    while(1) {
        /* Setup buffer... */
        int num;
        u8* buf = realloc(*out, bufferSize);
        if(!buf) {
            if(*out)
                free(*out);
            *out = NULL;
            return Z_MEM_ERROR;
        }
        *out = buf;
        gz.next_out = buf + *outLen;
        gz.avail_out = bufferSize - *outLen;

        err = inflate(&gz, Z_FULL_FLUSH);
        if(err != Z_STREAM_END && err != Z_OK) {
            if(*out)
                free(*out);
            *out = NULL;
            break;
        }
        num = bufferSize - *outLen - gz.avail_out;
        if(num > 0) {
            *outLen += num;
            bufferSize += num + blockSize;
        }
        if(err == Z_STREAM_END) {
            buf = realloc(buf, *outLen); /* Shrink it down, if it fails, just use old data */
            if(buf) {
                *out = buf;
            }
            break;
        }
    }
    inflateEnd(&gz);
    return zerr_to_opensc(err);
}
static int sc_decompress_gzip(u8* out, size_t* outLen, const u8* in, size_t inLen) {
    /* Since uncompress does not offer a way to make it uncompress gzip... manually set it up */
    z_stream gz;
    int err;
    int window_size = 15 + 0x20;
    memset(&gz, 0, sizeof(gz));

    gz.next_in = (u8*)in;
    gz.avail_in = inLen;
    gz.next_out = out;
    gz.avail_out = *outLen;

    err = inflateInit2(&gz, window_size);
    if(err != Z_OK) return zerr_to_opensc(err);
    err = inflate(&gz, Z_FINISH);
    if(err != Z_STREAM_END) {
        inflateEnd(&gz);
        return zerr_to_opensc(err);
    }
    *outLen = gz.total_out;

    err = inflateEnd(&gz);
    return zerr_to_opensc(err);
}
Example #3
0
static int sc_compress_gzip(u8* out, size_t* outLen, const u8* in, size_t inLen) {
    /* Since compress does not offer a way to make it compress gzip... manually set it up */
    z_stream gz;
    int err;
    int window_size = 15 + 0x10;
    memset(&gz, 0, sizeof(gz));

    gz.next_in = (u8*)in;
    gz.avail_in = inLen;
    gz.next_out = out;
    gz.avail_out = *outLen;

    err = deflateInit2(&gz, Z_BEST_COMPRESSION, Z_DEFLATED, window_size, 9, Z_DEFAULT_STRATEGY);
    if(err != Z_OK) return zerr_to_opensc(err);
    err = deflate(&gz, Z_FINISH);
    if(err != Z_STREAM_END) {
        deflateEnd(&gz);
        return zerr_to_opensc(err);
    }
    *outLen = gz.total_out;

    err = deflateEnd(&gz);
    return zerr_to_opensc(err);
}
Example #4
0
int sc_compress(u8* out, size_t* outLen, const u8* in, size_t inLen, int method) {
    unsigned long zlib_outlen;
    int rc;

    switch(method) {
    case COMPRESSION_ZLIB:
        zlib_outlen = *outLen;
        rc = zerr_to_opensc(compress(out, &zlib_outlen, in, inLen));
        *outLen = zlib_outlen;
        return rc;
    case COMPRESSION_GZIP:
        return sc_compress_gzip(out, outLen, in, inLen);
    default:
        return SC_ERROR_INVALID_ARGUMENTS;
    }
}
int sc_decompress(u8* out, size_t* outLen, const u8* in, size_t inLen, int method) {
    unsigned long zlib_outlen;
    int rc;

    if(method == COMPRESSION_AUTO) {
        method = detect_method(in, inLen);
        if(method == COMPRESSION_UNKNOWN) {
            return SC_ERROR_UNKNOWN_DATA_RECEIVED;
        }
    }
    switch(method) {
    case COMPRESSION_ZLIB:
        zlib_outlen = *outLen;
        rc = zerr_to_opensc(uncompress(out, &zlib_outlen, in, inLen));
        *outLen = zlib_outlen;
        return rc;
    case COMPRESSION_GZIP:
        return sc_decompress_gzip(out, outLen, in, inLen);
    default:
        return SC_ERROR_INVALID_ARGUMENTS;
    }
}