use std::io::Read;
use std::io::Write;
use crate::bitpix::Bitpix;
use crate::error::Result;
use super::be_to_i64_into;
pub(super) const DEFAULT_GZIP_LEVEL: u32 = 1;
pub(super) fn gzip_encode(raw: &[u8], level: u32) -> Vec<u8> {
let mut enc = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::new(level));
enc.write_all(raw).expect("gzip into a Vec cannot fail");
enc.finish().expect("gzip finish into a Vec cannot fail")
}
pub(super) fn gzip2_encode(raw: &[u8], width: usize, level: u32) -> Vec<u8> {
gzip_encode(&shuffle_bytes(raw, width), level)
}
pub(super) fn shuffle_bytes(raw: &[u8], width: usize) -> Vec<u8> {
if width <= 1 {
return raw.to_vec();
}
let n = raw.len() / width;
let mut out = vec![0u8; raw.len()];
for p in 0..width {
for i in 0..n {
out[p * n + i] = raw[i * width + p];
}
}
out
}
pub(super) fn unshuffle_bytes(shuffled: &[u8], width: usize) -> Vec<u8> {
if width <= 1 {
return shuffled.to_vec();
}
let n = shuffled.len() / width;
let mut out = vec![0u8; shuffled.len()];
for p in 0..width {
for i in 0..n {
out[i * width + p] = shuffled[p * n + i];
}
}
out
}
pub(super) fn gunzip(bytes: &[u8]) -> Result<Vec<u8>> {
let mut out = Vec::new();
flate2::read::GzDecoder::new(bytes).read_to_end(&mut out)?;
Ok(out)
}
pub(super) fn gzip_tile_into(bytes: &[u8], bitpix: Bitpix, out: &mut Vec<i64>) -> Result<()> {
be_to_i64_into(&gunzip(bytes)?, bitpix, out);
Ok(())
}
pub(super) fn gzip2_tile_into(bytes: &[u8], bitpix: Bitpix, out: &mut Vec<i64>) -> Result<()> {
let raw = unshuffle_bytes(&gunzip(bytes)?, bitpix.elem_size());
be_to_i64_into(&raw, bitpix, out);
Ok(())
}