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)); }
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; }
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; }