#![allow(dead_code)]
use super::*;
use super::Result;
use crate::meta::attributes::{IntRect, PixelType};
use crate::meta::{Header};
use crate::io::Data;
use crate::error::IoResult;
use crate::math::Vec2;
fn div_p (x: i32, y: i32) -> i32 {
if x >= 0 {
if y >= 0 { x / y }
else { -(x / -y) }
}
else {
if y >= 0 { -((y-1-x) / y) }
else { (-y-1-x) / -y }
}
}
fn mod_p(x: i32, y: i32) -> i32 {
x - y * div_p(x, y)
}
const U16_RANGE: i32 = (1 << 16);
const BITMAP_SIZE: i32 = (U16_RANGE >> 3);
pub fn decompress_bytes(
header: &Header,
compressed: ByteVec,
rectangle: IntRect,
_expected_byte_size: usize,
) -> Result<Vec<u8>>
{
struct ChannelData {
start_index: u32,
end_index: u32,
number_samples: Vec2<u32>,
y_samples: u32,
size: u32,
}
let xdr = true;
let format = xdr;
let has_only_half_channels = header.channels.list
.iter().all(|channel| channel.pixel_type == PixelType::F16);
let _use_native_format = has_only_half_channels;
if compressed.len() == 0 {
return Ok(Vec::new())
}
let _min_x = rectangle.position.0;
let min_y = rectangle.position.1;
let mut _max_x = rectangle.max().0;
let mut max_y = rectangle.max().1;
if _max_x > header.data_window().max().0 {
_max_x = header.data_window().max().0;
}
if max_y > header.data_window().max().1 {
max_y = header.data_window().max().1;
}
let mut channel_data: Vec<ChannelData> = Vec::new();
let mut tmp_buffer = vec![0_u16; header.data_size.0]; let mut tmp_buffer_end = 0_u32;
for (_index, channel) in header.channels.list.iter().enumerate() {
let channel = ChannelData {
start_index: tmp_buffer_end,
end_index: tmp_buffer_end,
y_samples: channel.sampling.1 as u32,
number_samples: channel.subsampled_resolution(rectangle.size).map(|x| x as u32),
size: (channel.pixel_type.bytes_per_sample() / PixelType::F16.bytes_per_sample()) as u32
};
tmp_buffer_end += channel.number_samples.0 * channel.number_samples.1 * channel.size;
channel_data.push(channel);
}
let mut bitmap = vec![0_u8; BITMAP_SIZE as usize];
let mut read = compressed.as_slice();
let min_non_zero = u16::read(&mut read)?;
let max_non_zero = u16::read(&mut read)?;
if max_non_zero as i32 >= BITMAP_SIZE {
println!("invalid bitmap size");
return Err(Error::invalid("compression data"));
}
if min_non_zero <= max_non_zero {
let length = max_non_zero - min_non_zero + 1;
bitmap[ min_non_zero as usize .. (min_non_zero + length) as usize ]
.copy_from_slice(&read[.. length as usize]);
}
let (lookup_table, max_value) = reverse_lookup_table_from_bitmap(&bitmap);
let length = i32::read(&mut read)?;
if length as usize > read.len() {
println!("invalid array length");
return Err(Error::invalid("compression data"));
}
huffman_decompress(&read[..length as usize], &mut tmp_buffer)?;
for channel in &channel_data {
for size in 0..channel.size {
wave_2_decode(
&mut tmp_buffer[(channel.start_index + size) as usize..],
channel.number_samples.0, channel.size, channel.number_samples.1,
channel.number_samples.0 * channel.size, max_value
)?;
}
}
apply_lookup_table(&mut tmp_buffer, &lookup_table);
let mut out = Vec::new();
if format == xdr {
for y in min_y ..= max_y {
for channel in &mut channel_data {
if mod_p(y, channel.y_samples as i32) != 0 {
continue;
}
for _x in (0 .. channel.number_samples.0 * channel.size).rev() {
out.push(tmp_buffer[channel.end_index as usize]);
channel.end_index += 1;
}
}
}
}
else { for y in min_y ..= max_y {
for channel in &mut channel_data {
if mod_p(y, channel.y_samples as i32) != 0 {
continue;
}
let n = channel.number_samples.0 * channel.size;
out.extend_from_slice(&tmp_buffer[channel.end_index as usize .. (channel.end_index + n) as usize]);
channel.end_index += n;
}
}
}
for index in 1..channel_data.len() {
assert_eq!(channel_data[index - 1].end_index, channel_data[index].start_index);
}
assert_eq!(channel_data.last().unwrap().end_index as usize, tmp_buffer.len());
unimplemented!("Ok(out)")
}
fn huffman_decompress(_data: &[u8], _result: &mut [u16]) -> IoResult<()> {
unimplemented!()
}
fn wave_2_decode(_buffer: &[u16], _x_size: u32, _x_offset: u32, _y_size: u32, _y_offset: u32, _max: u16 ) -> IoResult<()> {
unimplemented!()
}
fn reverse_lookup_table_from_bitmap(bitmap: Bytes<'_>) -> (Vec<u16>, u16) {
assert_eq!(U16_RANGE as u16 as i32, U16_RANGE);
let mut table = Vec::with_capacity(U16_RANGE as usize);
for index in 0 .. U16_RANGE as u16 {
if index == 0 || (bitmap[index as usize >> 3] as usize & (1 << (index as usize & 7)) != 0) { table.push(index);
}
}
let n = table.len() as u16;
assert_eq!(table.len() as u16 as usize, table.len());
table.resize(U16_RANGE as usize, 0);
(table, n)
}
fn apply_lookup_table(data: &mut [u16], table: &[u16]) {
for data in data {
*data = table[*data as usize];
}
}
pub fn compress_bytes(_packed: Bytes<'_>) -> Result<ByteVec> {
unimplemented!();
}