From 4c7f500bd9e45bafa57ed1c7a8c2978572f6d2bc Mon Sep 17 00:00:00 2001 From: Daniel Griffen Date: Sat, 7 Apr 2018 12:50:32 -0700 Subject: [PATCH 1/3] implement PermutePlanes ranges --- src/flif/components/transformations/bounds.rs | 1 - src/flif/components/transformations/mod.rs | 28 ++--- .../transformations/permute_planes.rs | 115 ++++++++++++++---- src/flif/numbers/near_zero.rs | 2 +- 4 files changed, 104 insertions(+), 42 deletions(-) diff --git a/src/flif/components/transformations/bounds.rs b/src/flif/components/transformations/bounds.rs index f49b207..b58273a 100644 --- a/src/flif/components/transformations/bounds.rs +++ b/src/flif/components/transformations/bounds.rs @@ -6,7 +6,6 @@ use numbers::rac::RacRead; use super::Transform; use ColorValue; -#[derive(Debug)] pub struct Bounds { ranges: [ColorRange; 4], previous_transformation: Box, diff --git a/src/flif/components/transformations/mod.rs b/src/flif/components/transformations/mod.rs index e6ef6c5..d0cd08f 100644 --- a/src/flif/components/transformations/mod.rs +++ b/src/flif/components/transformations/mod.rs @@ -1,17 +1,17 @@ -use error::*; -use numbers::rac::RacRead; -use numbers::symbol::UniformSymbolCoder; -use numbers::chances::UpdateTable; -use self::channel_compact::ChannelCompact; use self::bounds::Bounds; -use self::ycocg::YCoGg; +use self::channel_compact::ChannelCompact; use self::permute_planes::PermutePlanes; +use self::ycocg::YCoGg; use ColorValue; +use error::*; +use numbers::chances::UpdateTable; +use numbers::rac::RacRead; +use numbers::symbol::UniformSymbolCoder; mod bounds; mod channel_compact; -mod ycocg; mod permute_planes; +mod ycocg; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Transformation { @@ -64,7 +64,7 @@ impl ::std::fmt::Display for Transformation { } } -pub trait Transform: ::std::fmt::Debug { +pub trait Transform { fn snap(&self, channel: usize, values: &[ColorValue], pixel: ColorValue) -> ColorValue { let range = self.crange(channel, values); @@ -125,15 +125,13 @@ pub fn load_transformations( "Invalid transformation identifier read, possibly corrupt file".into(), ))?; transform = match id { - Transformation::ChannelCompact => Box::new(ChannelCompact::new( - rac, - transform, - channels, - update_table, - )?), + Transformation::ChannelCompact => { + Box::new(ChannelCompact::new(rac, transform, channels, update_table)?) + } Transformation::YCoGg => Box::new(YCoGg::new(transform)) as Box, Transformation::PermutePlanes => { - Box::new(PermutePlanes::new(transform)) as Box + Box::new(PermutePlanes::new(rac, transform, channels, update_table)?) + as Box } Transformation::Bounds => { Box::new(Bounds::new(rac, transform, channels, update_table)?) diff --git a/src/flif/components/transformations/permute_planes.rs b/src/flif/components/transformations/permute_planes.rs index fe7d9ae..e81354f 100644 --- a/src/flif/components/transformations/permute_planes.rs +++ b/src/flif/components/transformations/permute_planes.rs @@ -1,41 +1,106 @@ -use components::transformations::ColorRange; use super::Transform; -use ::ColorValue; +use ColorValue; +use components::transformations::ColorRange; +use error::*; +use numbers::chances::{ChanceTable, UpdateTable}; +use numbers::near_zero::NearZeroCoder; +use numbers::rac::RacRead; -#[derive(Debug)] -pub struct PermutePlanes { - max: i16, +pub struct PermutePlanes { + channel_map: Vec, + previous_transform: T, + range_function: fn(&T, usize, &[usize]) -> ColorRange, + crange_function: fn(&T, usize, &[ColorValue], &[usize]) -> ColorRange, } -impl PermutePlanes { - pub fn new(transformation: T) -> PermutePlanes { - let max_iter = [ - transformation.range(0).max, - transformation.range(1).max, - transformation.range(2).max, - ]; - - let old_max = max_iter.iter().max().unwrap(); - let new_max = (((old_max / 4) + 1) * 4) - 1; - PermutePlanes { max: new_max } +impl PermutePlanes { + pub fn new( + rac: &mut R, + previous_transform: T, + channels: usize, + update_table: &UpdateTable, + ) -> Result> { + let mut context = ChanceTable::new(update_table); + + let subtract = rac.read_near_zero(0, 1, &mut context)? == 1; + + let range_function = if subtract { + subtract_range + } else { + normal_range + }; + + let crange_function = if subtract { + subtract_crange + } else { + normal_crange + }; + + let channel_map: Vec<_> = (0..channels) + .map(|_| rac.read_near_zero(0, channels - 1, &mut context)) + .collect::>()?; + + Ok(PermutePlanes { + channel_map, + previous_transform, + range_function, + crange_function, + }) } } -impl Transform for PermutePlanes { +impl Transform for PermutePlanes { fn undo(&self, _pixel: &mut [ColorValue]) { - + unimplemented!() } fn range(&self, channel: usize) -> ColorRange { - let min = match channel { - 0 => 0, - _ => -self.max, - }; + (self.range_function)(&self.previous_transform, channel, &self.channel_map) + } - ColorRange { min, max: self.max } + fn crange(&self, channel: usize, values: &[ColorValue]) -> ColorRange { + (self.crange_function)(&self.previous_transform, channel, values, &self.channel_map) } +} - fn crange(&self, _channel: usize, _values: &[ColorValue]) -> ColorRange { - unimplemented!() +fn subtract_range( + transform: &T, + channel: usize, + permutation: &[usize], +) -> ColorRange { + if channel == 0 || channel == 3 { + transform.range(permutation[channel]) + } else { + let channel_range = transform.range(permutation[channel]); + let zero_range = transform.range(permutation[0]); + ColorRange { + min: channel_range.min - zero_range.max, + max: channel_range.max - zero_range.min, + } } } + +fn subtract_crange( + transform: &T, + channel: usize, + values: &[ColorValue], + permutation: &[usize], +) -> ColorRange { + let mut range = subtract_range(transform, channel, permutation); + range.min -= values[0]; + range.max -= values[0]; + range +} + +fn normal_range(transform: &T, channel: usize, permutation: &[usize]) -> ColorRange { + transform.range(permutation[channel]) +} + +fn normal_crange( + transform: &T, + channel: usize, + _values: &[ColorValue], + permutation: &[usize], +) -> ColorRange { + normal_range(transform, channel, permutation) +} diff --git a/src/flif/numbers/near_zero.rs b/src/flif/numbers/near_zero.rs index 11dc892..7f2c692 100644 --- a/src/flif/numbers/near_zero.rs +++ b/src/flif/numbers/near_zero.rs @@ -1,5 +1,5 @@ use error::*; -use num_traits::{PrimInt, Signed}; +use num_traits::PrimInt; use numbers::chances::{ChanceTable, ChanceTableEntry}; use numbers::rac::RacRead; From 68e9561d7122489b3f12e1bdcd88a68fedc4e10d Mon Sep 17 00:00:00 2001 From: Daniel Griffen Date: Sat, 7 Apr 2018 12:51:00 -0700 Subject: [PATCH 2/3] boilerplate transforms create modules for all the remaining non-animation transforms --- .../transformations/color_buckets.rs | 0 src/flif/components/transformations/mod.rs | 8 ++++ .../components/transformations/palette.rs | 45 +++++++++++++++++++ .../transformations/palette_alpha.rs | 0 4 files changed, 53 insertions(+) create mode 100644 src/flif/components/transformations/color_buckets.rs create mode 100644 src/flif/components/transformations/palette.rs create mode 100644 src/flif/components/transformations/palette_alpha.rs diff --git a/src/flif/components/transformations/color_buckets.rs b/src/flif/components/transformations/color_buckets.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/flif/components/transformations/mod.rs b/src/flif/components/transformations/mod.rs index d0cd08f..955e3b0 100644 --- a/src/flif/components/transformations/mod.rs +++ b/src/flif/components/transformations/mod.rs @@ -2,6 +2,8 @@ use self::bounds::Bounds; use self::channel_compact::ChannelCompact; use self::permute_planes::PermutePlanes; use self::ycocg::YCoGg; +use self::palette::Palette; + use ColorValue; use error::*; use numbers::chances::UpdateTable; @@ -10,6 +12,9 @@ use numbers::symbol::UniformSymbolCoder; mod bounds; mod channel_compact; +mod color_buckets; +mod palette; +mod palette_alpha; mod permute_planes; mod ycocg; @@ -136,6 +141,9 @@ pub fn load_transformations( Transformation::Bounds => { Box::new(Bounds::new(rac, transform, channels, update_table)?) } + Transformation::Palette => { + Box::new(Palette::new(rac, transform, channels, update_table)?) + } _ => { return Err(Error::Unimplemented( "found unimplemented transformation type", diff --git a/src/flif/components/transformations/palette.rs b/src/flif/components/transformations/palette.rs new file mode 100644 index 0000000..868aaf2 --- /dev/null +++ b/src/flif/components/transformations/palette.rs @@ -0,0 +1,45 @@ +use components::transformations::ColorRange; +use numbers::rac::RacRead; +use components::transformations::Transform; +use error::*; +use numbers::chances::{ChanceTable, UpdateTable}; +use ColorValue; +use numbers::near_zero::NearZeroCoder; + +const MAX_PALETTE_SIZE: usize = 30000; + +pub struct Palette { + palette: Vec, +} + +impl Palette { + pub fn new( + rac: &mut R, + transformation: T, + channels: usize, + update_table: &UpdateTable, + ) -> Result { + let mut context_a = ChanceTable::new(update_table); + let mut context_y = ChanceTable::new(update_table); + let mut context_i = ChanceTable::new(update_table); + let mut context_q = ChanceTable::new(update_table); + + let size = rac.read_near_zero(0, MAX_PALETTE_SIZE, &mut context_a)?; + + unimplemented!() + } +} + +impl Transform for Palette { + fn undo(&self, pixel: &mut [ColorValue]) { + unimplemented!() + } + + fn range(&self, channel: usize) -> ColorRange { + unimplemented!() + } + + fn crange(&self, channel: usize, values: &[ColorValue]) -> ColorRange { + unimplemented!() + } +} diff --git a/src/flif/components/transformations/palette_alpha.rs b/src/flif/components/transformations/palette_alpha.rs new file mode 100644 index 0000000..e69de29 From 804d818d1bd92bd712577da746c93f1f5abe8ba1 Mon Sep 17 00:00:00 2001 From: Daniel Griffen Date: Sat, 7 Apr 2018 21:09:43 -0700 Subject: [PATCH 3/3] implement PermutePlanes undo --- .../transformations/permute_planes.rs | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/flif/components/transformations/permute_planes.rs b/src/flif/components/transformations/permute_planes.rs index a4f8823..a7d2efa 100644 --- a/src/flif/components/transformations/permute_planes.rs +++ b/src/flif/components/transformations/permute_planes.rs @@ -6,20 +6,20 @@ use numbers::near_zero::NearZeroCoder; use numbers::rac::RacRead; use colors::{Channel, ChannelSet, ColorSpace, Pixel}; -pub struct PermutePlanes { +pub struct PermutePlanes { + channels: ColorSpace, channel_set: ChannelSet, - previous_transform: T, - range_function: fn(&T, Channel, &ChannelSet) -> ColorRange, - crange_function: fn(&T, Channel, &Pixel, &ChannelSet) -> ColorRange, + ranges: ChannelSet, + crange_function: fn(&PermutePlanes, Channel, &Pixel) -> ColorRange, } -impl PermutePlanes { - pub fn new( +impl PermutePlanes { + pub fn new( rac: &mut R, previous_transform: T, channels: ColorSpace, update_table: &UpdateTable, - ) -> Result> { + ) -> Result { let mut context = ChanceTable::new(update_table); let subtract = rac.read_near_zero(0, 1, &mut context)? == 1; @@ -43,26 +43,37 @@ impl PermutePlanes { channel_set[channel] = mapped_channel; } + let mut ranges: ChannelSet = Default::default(); + for channel in channels { + ranges[channel] = (range_function)(&previous_transform, channel, &channel_set); + } + Ok(PermutePlanes { + channels, channel_set, - previous_transform, - range_function, + ranges, crange_function, }) } } -impl Transform for PermutePlanes { - fn undo(&self, _pixel: &mut Pixel) { - unimplemented!() +impl Transform for PermutePlanes { + fn undo(&self, pixel: &mut Pixel) { + let mut new_pixel = Pixel::default(); + for channel in self.channels { + let permuted_channel = self.channel_set[channel]; + new_pixel[permuted_channel] = pixel[channel]; + } + + *pixel = new_pixel; } fn range(&self, channel: Channel) -> ColorRange { - (self.range_function)(&self.previous_transform, channel, &self.channel_set) + self.ranges[channel] } fn crange(&self, channel: Channel, values: &Pixel) -> ColorRange { - (self.crange_function)(&self.previous_transform, channel, values, &self.channel_set) + (self.crange_function)(self, channel, values) } } @@ -83,13 +94,8 @@ fn subtract_range( } } -fn subtract_crange( - transform: &T, - channel: Channel, - values: &Pixel, - permutation: &ChannelSet, -) -> ColorRange { - let mut range = subtract_range(transform, channel, permutation); +fn subtract_crange(transform: &PermutePlanes, channel: Channel, values: &Pixel) -> ColorRange { + let mut range = transform.ranges[channel]; range.min -= values[Channel::Red]; range.max -= values[Channel::Red]; range @@ -103,11 +109,6 @@ fn normal_range( transform.range(permutation[channel]) } -fn normal_crange( - transform: &T, - channel: Channel, - _values: &Pixel, - permutation: &ChannelSet, -) -> ColorRange { - normal_range(transform, channel, permutation) +fn normal_crange(transform: &PermutePlanes, channel: Channel, _values: &Pixel) -> ColorRange { + transform.ranges[channel] }