long zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
		      __u32 srclen, __u32 destlen)
{
    return (decompress_block(cpage_out, data_in + 2, ldr_memcpy));

}
Example #2
0
int hadoop_decode_snappy_block(
    size_t n_records,
    int record_size, /* special encoding where negative numbers mean swap bytes */
    const char *compressed_lengths, size_t compressed_lengths_size,
    const char *compressed_data,    size_t compressed_data_size,
    struct block *output)
{
    size_t uncompressed_lengths_size = 0;
    char *uncompressed_lengths = NULL;
    size_t *lengths = NULL;

    size_t uncompressed_data_size = 0;
    char *uncompressed_data = NULL;

    /* Lengths are only relevant for variable length records */
    if (record_size != 0) {
        output->lengths = NULL;
    } else {
        uncompressed_lengths = decompress_block(
            compressed_lengths_size,
            compressed_lengths,
            &uncompressed_lengths_size);

        lengths = calloc(n_records, sizeof(size_t));
        output->lengths = lengths;

        int records_remaining = (int)n_records;
        char *bytes = uncompressed_lengths;
        size_t bytes_remaining = uncompressed_lengths_size;

        while (records_remaining > 0 && bytes_remaining > 0) {
            size_t vint_size = 0;
            *lengths = (size_t)vint_decode(bytes, &vint_size);

            lengths++;
            records_remaining--;

            bytes += vint_size;
            bytes_remaining -= vint_size;
        }

        free(uncompressed_lengths);

        if (records_remaining != 0 || bytes_remaining != 0) {
            goto fail;
        }
    }

    uncompressed_data = decompress_block(
        compressed_data_size,
        compressed_data,
        &uncompressed_data_size);

    if (record_size != 0 && uncompressed_data_size != n_records * (size_t)abs(record_size)) {
        goto fail;
    }


/* The casts below are acceptable because we know that the memory was allocated
 * using calloc. */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-align"

    if (record_size == -2) {
        uint16_t *values = (uint16_t *)uncompressed_data;
        uint16_t *end    = values + n_records;
        while (values < end) {
            *values = bswap16(*values);
            values++;
        }
    } else if (record_size == -4) {
        uint32_t *values = (uint32_t *)uncompressed_data;
        uint32_t *end    = values + n_records;
        while (values < end) {
            *values = bswap32(*values);
            values++;
        }
    } else if (record_size == -8) {
        uint64_t *values = (uint64_t *)uncompressed_data;
        uint64_t *end    = values + n_records;
        while (values < end) {
            *values = bswap64(*values);
            values++;
        }
    } else if (record_size < 0) {
        /* Only 2,4,8-byte byte swapping is supported. */
        goto fail;
    }

#pragma clang diagnostic pop

    output->data_size = uncompressed_data_size;
    output->data      = uncompressed_data;

    return 0;

fail:
    output->lengths   = NULL;
    output->data_size = 0;
    output->data      = NULL;

    free(uncompressed_data);
    free(lengths);

    return -1;
}
Example #3
0
static void* decompress_dds(el_file_ptr file, DdsHeader *header,
	const Uint32 strip_mipmaps, const Uint32 base_level)
{
	Uint32 width, height, size, format, mipmap_count;
	Uint32 x, y, i, w, h;
	Uint32 index;
	Uint8 *dest;

	if ((header->m_height % 4) != 0)
	{
		LOG_ERROR_OLD("Can`t decompressed DDS file %s because height is"
			" %d and not a multiple of four.", el_file_name(file),
			header->m_height);
		return 0;
	}

	if ((header->m_width % 4) != 0)
	{
		LOG_ERROR_OLD("Can`t decompressed DDS file %s because width is"
			" %d and not a multiple of four.", el_file_name(file),
			header->m_width);
		return 0;
	}

	format = header->m_pixel_format.m_fourcc;

	if ((format != DDSFMT_DXT1) && (format != DDSFMT_DXT2) &&
		(format != DDSFMT_DXT3) && (format != DDSFMT_DXT4) &&
		(format != DDSFMT_DXT5) && (format != DDSFMT_ATI1) &&
		(format != DDSFMT_ATI2))
	{
		return 0;
	}

	index = 0;

	size = get_dds_size(header, 1, strip_mipmaps, base_level);
	width = max2u(header->m_width >> base_level, 1);
	height = max2u(header->m_height >> base_level, 1);
	mipmap_count = header->m_mipmap_count;

	if (strip_mipmaps != 0)
	{
		if (mipmap_count > (base_level + 1))
		{
			mipmap_count = base_level + 1;
		}
	}

	dest = malloc_aligned(size, 16);

	el_seek(file, get_dds_offset(header, base_level), SEEK_CUR);

	for (i = base_level; i < mipmap_count; i++)
	{
		w = (width + 3) / 4;
		h = (height + 3) / 4;

		assert(index * 4 <= size);

		// 4x4 blocks in x/y
		for (y = 0; y < h; y++)
		{
			for (x = 0; x < w; x++)
			{
				decompress_block(file, format, x * 4, y * 4,
					width, height, index, dest);
			}
		}

		index += width * height;

		if (width > 1)
		{
			width /= 2;
		}

		if (height > 1)
		{
			height /= 2;
		}
	}

	assert(index * 4 == size);

	return dest;
}