<commit_before>extern crate itertools;

use std::collections::{HashSet,HashMap};
use self::itertools::Itertools;        // fold_results
use std::io;                           // Error
use std::io::{Read,BufReader,BufRead}; // read_to_string
use std::path::Path;
use std::num;                          // ParseIntError
use std::fmt;                          // Formatter, format!, Display, Debug, write!
use std::error;
use std::fs::File;                     // File, open

// TODO "readm.mk"
// TODO documentation
// TODO error for duplicated transitions
#[derive(Debug)]
pub enum DFAError {
    MissingStartingState,
    MissingFinalStates,
    IncompleteTransition(usize),
    IllformedTransition(usize),
    Io(io::Error),
    Parse(num::ParseIntError,Option<usize>),
}

impl fmt::Display for DFAError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            DFAError::Io(ref err) => write!(f, "IO error: {}", err),
            DFAError::MissingStartingState => write!(f, "The file is empty or only contains white characters."),
            DFAError::MissingFinalStates => write!(f, "The file does not specify the list of final states."),
            DFAError::IncompleteTransition(ref line) => write!(f, "Line {}: missing the src or the dest state.", line),
            DFAError::IllformedTransition(ref line) => write!(f, "Line {}: too much elements.", line),
            DFAError::Parse(ref err,ref line) => write!(f, "Parse error on line {:?}: {}", line, err),
        }
    }
}

impl error::Error for DFAError {
    fn description(&self) -> &str {
        match *self {
            DFAError::Io(ref err) => err.description(),
            DFAError::MissingStartingState => "The file is empty or only contains white characters.",
            DFAError::MissingFinalStates => "The file does not specify the list of final states.",
            DFAError::IncompleteTransition(_) => "Missing the src or the dest state.",
            DFAError::IllformedTransition(_) => "Too much elements",
            DFAError::Parse(ref err,_) => err.description(),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            DFAError::Io(ref err) => Some(err),
            DFAError::Parse(ref err,_) => Some(err),
            _ => None,
        }
    }
}

impl From<io::Error> for DFAError {
    fn from(err: io::Error) -> DFAError {
        DFAError::Io(err)
    }
}

impl From<num::ParseIntError> for DFAError {
    fn from(err: num::ParseIntError) -> DFAError {
        DFAError::Parse(err,None)
    }
}

#[derive(Debug)]
pub struct DFA {
    transitions : HashMap<(char,usize),usize>,
    start       : usize,
    finals      : HashSet<usize>,
}

impl DFA {
    pub fn new() -> DFA {
        DFA{transitions: HashMap::new(), start: 0, finals: HashSet::new()}
    }

    fn parse_dfa_error(contents: &str, line: usize) -> Result<usize, DFAError> {
            contents.parse::<usize>()
                    .map_err(|e| DFAError::Parse(e,Some(line)))
    }

    pub fn new_from_file<P: AsRef<Path>>(file_path: P) -> Result<DFA, DFAError> {
        let file = try!(File::open(file_path));
        let file = BufReader::new(file);
        DFA::new_from_lines(&mut file.lines())
    }

    // TODO test if the tranisiton start with two symbols instead of one
    fn new_from_lines(lines : &mut Iterator<Item=io::Result<String>>) -> Result<DFA, DFAError> {
        let mut dfa = DFA::new();
        let mut lines = lines
            .map(|line| {
                line.and_then(|contents| Ok(contents.split('#').nth(0).unwrap().trim().to_owned()))
            })
            .enumerate().map(|(nline,line)| (nline+1,line))
            .filter(|&(_,ref line)| {
                // Mandatory otherwise unwrap will take the ownership of the String
                let line = line.as_ref();
                line.is_err() || !line.unwrap().is_empty()
            });
        // Starting state
        let (nline,line) = try!(lines.next().ok_or(DFAError::MissingStartingState));
        let line = try!(line);
        dfa.start = try!(DFA::parse_dfa_error(&line,nline));
        // Final states
        let (nline,line) = try!(lines.next().ok_or(DFAError::MissingFinalStates));
        let line = try!(line);
        dfa.finals = try!(line
            .split_whitespace()
            .map(|token| DFA::parse_dfa_error(token,nline))
            .fold_results(HashSet::new(), |mut acc, elt| {
                acc.insert(elt);
                acc
            }));
        for (nline,line) in lines {
            let line = try!(line);
            let mut tokens = line.split_whitespace();
            // can't fail because lines iterates over the non-empty line
            let symb = tokens.next().unwrap().chars().nth(0).unwrap();
            let src = try!(tokens
                .next()
                .ok_or(DFAError::IncompleteTransition(nline))
                .and_then(|contents| DFA::parse_dfa_error(contents,nline)));
            let dest = try!(tokens
                .next()
                .ok_or(DFAError::IncompleteTransition(nline))
                .and_then(|contents| DFA::parse_dfa_error(contents,nline)));
            if tokens.next().is_some() {
                return Err(DFAError::IllformedTransition(nline));
            }
            dfa.transitions.insert((symb,src), dest);
        }
        Ok(dfa)
    }

    pub fn new_from_string(file: &str) -> Result<DFA, DFAError> {
        DFA::new_from_lines(&mut file.lines().map(|line| Ok(line.to_string())))
    }

    // TODO return the position of the first match
    //      maybe create an another function to do that
    pub fn run(&self, input: &str) -> bool {
        let f = input
            .chars()
            .fold(Some(self.start), |state,c| {
                match state {
                    Some(n) => self.transitions.get(&(c,n)).map(|v| *v),
                    None => None,
                }
            });
        match f {
            Some(n) => self.finals.contains(&n),
            None => false
        }
    }
}

impl fmt::Display for DFA {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "START: {}", self.start));
        try!(writeln!(f, "FINALS:"));
        for fi in self.finals.iter() {
            try!(writeln!(f,"  {}", fi));
        }
        try!(writeln!(f, "TRANSITIONS:"));
        for (tr,d) in self.transitions.iter() {
            let (c,s) = *tr;
            try!(writeln!(f, "  ({},{}) => {}", c, s, d));
        }
        write!(f, "")
    }
}

// TODO add specific error analysis
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_dfa() {
        let model =
            "0\n\
             3\n\
             a 0 1\n\
             c 0 3\n\
             b 1 2\n\
             a 2 1\n\
             c 2 3";
        let dfa = DFA::new_from_string(&model).unwrap();
        let samples =
            vec![("ababac", false),
                 ("ababc", true),
                 ("", false),
                 ("abc", true),
                 ("c", true),
                 ("ac", false),
                 ("ababababababababababababababababababababc", true),];

        for (input,expected_result) in samples {
            assert!(dfa.run(input) == expected_result, "input false for: \"{}\"", input);
        }
    }

    #[test]
    fn test_empty_file() {
        let model =
            "";
        match DFA::new_from_string(model) {
            Err(DFAError::MissingStartingState) => assert!(true),
            _ => assert!(false, "Missing state expected."),
        }
    }

    #[test]
    fn test_start_not_a_number() {
        let model =
            "a";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 1),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_many_starts() {
        let model =
            "0 1\n\
             3\n\
             a 0 1\n\
             c 0 3\n\
             b 1 2\n\
             a 2 1\n\
             c 2 3";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 1),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_no_finals() {
        let model =
            "1\n\
            ";
        match DFA::new_from_string(model) {
            Err(DFAError::MissingFinalStates) => assert!(true),
            _ => assert!(false, "Missing final states expected."),
        }
    }

    #[test]
    fn test_finals_not_a_number() {
        let model =
            "1\n\
             2 a 3";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 2),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_no_transistions() {
        let model =
            "0\n\
             3";
        let _dfa = DFA::new_from_string(&model).unwrap();
    }

    #[test]
    fn test_transitions_with_at_least_four_elements() {
        let model =
            "0\n\
             3\n\
             a 0 1 8";
        match DFA::new_from_string(model) {
            Err(DFAError::IllformedTransition(line)) => assert!(line == 3),
            _ => assert!(false, "IllformedTransition expected."),
        }
    }

    #[test]
    #[should_panic]
    fn test_transitions_start_with_at_least_two_chars() {
        let model =
            "0\n\
             3\n\
             ab 2 3";
        let _dfa = DFA::new_from_string(&model).unwrap();
    }

    #[test]
    fn test_transitions_with_src_not_a_number() {
        let model =
            "0\n\
             3\n\
             c b 3";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 3),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_transitions_with_dest_not_a_number() {
        let model =
            "0\n\
             3\n\
             c 2 b";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 3),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_read_from_fake_file() {
        let file = "fake.txt";
        match DFA::new_from_file(file) {
            Err(DFAError::Io(_)) => assert!(true),
            _ => assert!(false, "Io::Error expected."),
        }
    }
}
<commit_msg>Add missing errors.<commit_after>extern crate itertools;

use std::collections::{HashSet,HashMap};
use self::itertools::Itertools;        // fold_results
use std::io;                           // Error
use std::io::{Read,BufReader,BufRead}; // read_to_string
use std::path::Path;
use std::num;                          // ParseIntError
use std::fmt;                          // Formatter, format!, Display, Debug, write!
use std::error;
use std::fs::File;                     // File, open

// TODO "readme.mk"
// TODO documentation
#[derive(Debug)]
pub enum DFAError {
    MissingStartingState,
    MissingFinalStates,
    IncompleteTransition(usize),
    IllformedTransition(usize),
    DuplicatedTransition(usize),
    Io(io::Error),
    Parse(num::ParseIntError,Option<usize>),
}

impl fmt::Display for DFAError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            DFAError::Io(ref err) => write!(f, "IO error: {}", err),
            DFAError::MissingStartingState => write!(f, "The file is empty or only contains white characters."),
            DFAError::MissingFinalStates => write!(f, "The file does not specify the list of final states."),
            DFAError::IncompleteTransition(ref line) => write!(f, "Line {}: missing the src or the dest state.", line),
            DFAError::IllformedTransition(ref line) => write!(f, "Line {}: too much elements.", line),
            DFAError::DuplicatedTransition(ref line) => write!(f, "Line {}: duplicated transition.", line),
            DFAError::Parse(ref err,ref line) => write!(f, "Parse error on line {:?}: {}", line, err),
        }
    }
}

impl error::Error for DFAError {
    fn description(&self) -> &str {
        match *self {
            DFAError::Io(ref err) => err.description(),
            DFAError::MissingStartingState => "The file is empty or only contains white characters.",
            DFAError::MissingFinalStates => "The file does not specify the list of final states.",
            DFAError::IncompleteTransition(_) => "Missing the src or the dest state.",
            DFAError::IllformedTransition(_) => "Too much elements.",
            DFAError::DuplicatedTransition(_) => "Duplicated transition.",
            DFAError::Parse(ref err,_) => err.description(),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            DFAError::Io(ref err) => Some(err),
            DFAError::Parse(ref err,_) => Some(err),
            _ => None,
        }
    }
}

impl From<io::Error> for DFAError {
    fn from(err: io::Error) -> DFAError {
        DFAError::Io(err)
    }
}

impl From<num::ParseIntError> for DFAError {
    fn from(err: num::ParseIntError) -> DFAError {
        DFAError::Parse(err,None)
    }
}

#[derive(Debug)]
pub struct DFA {
    transitions : HashMap<(char,usize),usize>,
    start       : usize,
    finals      : HashSet<usize>,
}

impl DFA {
    pub fn new() -> DFA {
        DFA{transitions: HashMap::new(), start: 0, finals: HashSet::new()}
    }

    fn parse_dfa_error(contents: &str, line: usize) -> Result<usize, DFAError> {
            contents.parse::<usize>()
                    .map_err(|e| DFAError::Parse(e,Some(line)))
    }

    pub fn new_from_file<P: AsRef<Path>>(file_path: P) -> Result<DFA, DFAError> {
        let file = try!(File::open(file_path));
        let file = BufReader::new(file);
        DFA::new_from_lines(&mut file.lines())
    }

    fn new_from_lines(lines : &mut Iterator<Item=io::Result<String>>) -> Result<DFA, DFAError> {
        let mut dfa = DFA::new();
        let mut lines = lines
            .map(|line| {
                line.and_then(|contents| Ok(contents.split('#').nth(0).unwrap().trim().to_owned()))
            })
            .enumerate().map(|(nline,line)| (nline+1,line))
            .filter(|&(_,ref line)| {
                // Mandatory otherwise unwrap will take the ownership of the String
                let line = line.as_ref();
                line.is_err() || !line.unwrap().is_empty()
            });
        // Starting state
        let (nline,line) = try!(lines.next().ok_or(DFAError::MissingStartingState));
        let line = try!(line);
        dfa.start = try!(DFA::parse_dfa_error(&line,nline));
        // Final states
        let (nline,line) = try!(lines.next().ok_or(DFAError::MissingFinalStates));
        let line = try!(line);
        dfa.finals = try!(line
            .split_whitespace()
            .map(|token| DFA::parse_dfa_error(token,nline))
            .fold_results(HashSet::new(), |mut acc, elt| {
                acc.insert(elt);
                acc
            }));
        for (nline,line) in lines {
            let line = try!(line);
            let mut tokens = line.split_whitespace();
            // can't fail because lines iterates over the non-empty line
            let mut symbs = tokens.next().unwrap().chars();
            let symb = symbs.nth(0).unwrap();
            if symbs.next().is_some() {
                return Err(DFAError::IllformedTransition(nline));
            }
            let src = try!(tokens
                .next()
                .ok_or(DFAError::IncompleteTransition(nline))
                .and_then(|contents| DFA::parse_dfa_error(contents,nline)));
            let dest = try!(tokens
                .next()
                .ok_or(DFAError::IncompleteTransition(nline))
                .and_then(|contents| DFA::parse_dfa_error(contents,nline)));
            if tokens.next().is_some() {
                return Err(DFAError::IllformedTransition(nline));
            }
            if dfa.transitions.insert((symb,src), dest).is_some() {
                return Err(DFAError::DuplicatedTransition(nline));
            }
        }
        Ok(dfa)
    }

    pub fn new_from_string(file: &str) -> Result<DFA, DFAError> {
        DFA::new_from_lines(&mut file.lines().map(|line| Ok(line.to_string())))
    }

    // TODO return the position of the first match
    //      maybe create an another function to do that
    pub fn run(&self, input: &str) -> bool {
        let f = input
            .chars()
            .fold(Some(self.start), |state,c| {
                match state {
                    Some(n) => self.transitions.get(&(c,n)).map(|v| *v),
                    None => None,
                }
            });
        match f {
            Some(n) => self.finals.contains(&n),
            None => false
        }
    }
}

impl fmt::Display for DFA {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "START: {}", self.start));
        try!(writeln!(f, "FINALS:"));
        for fi in self.finals.iter() {
            try!(writeln!(f,"  {}", fi));
        }
        try!(writeln!(f, "TRANSITIONS:"));
        for (tr,d) in self.transitions.iter() {
            let (c,s) = *tr;
            try!(writeln!(f, "  ({},{}) => {}", c, s, d));
        }
        write!(f, "")
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_dfa() {
        let model =
            "0\n\
             3\n\
             a 0 1\n\
             c 0 3\n\
             b 1 2\n\
             a 2 1\n\
             c 2 3";
        let dfa = DFA::new_from_string(&model).unwrap();
        let samples =
            vec![("ababac", false),
                 ("ababc", true),
                 ("", false),
                 ("abc", true),
                 ("c", true),
                 ("ac", false),
                 ("ababababababababababababababababababababc", true),];

        for (input,expected_result) in samples {
            assert!(dfa.run(input) == expected_result, "input false for: \"{}\"", input);
        }
    }

    #[test]
    fn test_empty_file() {
        let model =
            "";
        match DFA::new_from_string(model) {
            Err(DFAError::MissingStartingState) => assert!(true),
            _ => assert!(false, "Missing state expected."),
        }
    }

    #[test]
    fn test_start_not_a_number() {
        let model =
            "a";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 1),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_many_starts() {
        let model =
            "0 1\n\
             3\n\
             a 0 1\n\
             c 0 3\n\
             b 1 2\n\
             a 2 1\n\
             c 2 3";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 1),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_no_finals() {
        let model =
            "1\n\
            ";
        match DFA::new_from_string(model) {
            Err(DFAError::MissingFinalStates) => assert!(true),
            _ => assert!(false, "Missing final states expected."),
        }
    }

    #[test]
    fn test_finals_not_a_number() {
        let model =
            "1\n\
             2 a 3";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 2),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_no_transistions() {
        let model =
            "0\n\
             3";
        let _dfa = DFA::new_from_string(&model).unwrap();
    }

    #[test]
    fn test_transitions_with_at_least_four_elements() {
        let model =
            "0\n\
             3\n\
             a 0 1 8";
        match DFA::new_from_string(model) {
            Err(DFAError::IllformedTransition(line)) => assert!(line == 3),
            _ => assert!(false, "IllformedTransition expected."),
        }
    }

    #[test]
    #[should_panic]
    fn test_transitions_start_with_at_least_two_chars() {
        let model =
            "0\n\
             3\n\
             ab 2 3";
        let _dfa = DFA::new_from_string(&model).unwrap();
    }

    #[test]
    fn test_transitions_with_src_not_a_number() {
        let model =
            "0\n\
             3\n\
             c b 3";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 3),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_transitions_with_dest_not_a_number() {
        let model =
            "0\n\
             3\n\
             c 2 b";
        match DFA::new_from_string(model) {
            Err(DFAError::Parse(_,line)) => assert!(line.unwrap() == 3),
            _ => assert!(false, "Parsing error."),
        }
    }

    #[test]
    fn test_duplicated_transition() {
        let model =
            "0\n\
             3\n\
             c 2 3\n\
             c 2 4";
        match DFA::new_from_string(model) {
            Err(DFAError::DuplicatedTransition(line)) => assert!(line == 4),
            _ => assert!(false, "DuplicatedTransition expected."),
        }
    }

    #[test]
    fn test_read_from_fake_file() {
        let file = "fake.txt";
        match DFA::new_from_file(file) {
            Err(DFAError::Io(_)) => assert!(true),
            _ => assert!(false, "Io::Error expected."),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2018-2020, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use crate::cpu_features::CpuFeatureLevel;
use crate::util::*;

use super::TxType;

cfg_if::cfg_if! {
  if #[cfg(nasm_x86_64)] {
    pub use crate::asm::x86::transform::forward::*;
  } else {
    pub use self::rust::*;
  }
}

pub mod rust {
  use super::*;

  use crate::transform::forward_shared::*;
  use crate::transform::{av1_round_shift_array, valid_av1_transform, TxSize};
  use simd_helpers::cold_for_target_arch;

  pub trait TxOperations: Copy {
    fn zero() -> Self;

    fn tx_mul(self, _: (i32, i32)) -> Self;
    fn rshift1(self) -> Self;
    fn add(self, b: Self) -> Self;
    fn sub(self, b: Self) -> Self;
    fn add_avg(self, b: Self) -> Self;
    fn sub_avg(self, b: Self) -> Self;

    fn copy_fn(self) -> Self {
      self
    }
  }

  impl TxOperations for i32 {
    fn zero() -> Self {
      0
    }

    fn tx_mul(self, mul: (i32, i32)) -> Self {
      ((self * mul.0) + (1 << mul.1 >> 1)) >> mul.1
    }

    fn rshift1(self) -> Self {
      (self + if self < 0 { 1 } else { 0 }) >> 1
    }

    fn add(self, b: Self) -> Self {
      self + b
    }

    fn sub(self, b: Self) -> Self {
      self - b
    }

    fn add_avg(self, b: Self) -> Self {
      (self + b) >> 1
    }

    fn sub_avg(self, b: Self) -> Self {
      (self - b) >> 1
    }
  }

  impl_1d_tx!();

  type TxfmFunc = dyn Fn(&mut [i32]);

  fn get_func(t: TxfmType) -> &'static TxfmFunc {
    use self::TxfmType::*;
    match t {
      DCT4 => &daala_fdct4,
      DCT8 => &daala_fdct8,
      DCT16 => &daala_fdct16,
      DCT32 => &daala_fdct32,
      DCT64 => &daala_fdct64,
      ADST4 => &daala_fdst_vii_4,
      ADST8 => &daala_fdst8,
      ADST16 => &daala_fdst16,
      Identity4 => &fidentity,
      Identity8 => &fidentity,
      Identity16 => &fidentity,
      Identity32 => &fidentity,
      _ => unreachable!(),
    }
  }

  #[cold_for_target_arch("x86_64")]
  pub fn forward_transform<T: Coefficient>(
    input: &[i16], output: &mut [T], stride: usize, tx_size: TxSize,
    tx_type: TxType, bd: usize, _cpu: CpuFeatureLevel,
  ) {
    assert!(valid_av1_transform(tx_size, tx_type));

    // Note when assigning txfm_size_col, we use the txfm_size from the
    // row configuration and vice versa. This is intentionally done to
    // accurately perform rectangular transforms. When the transform is
    // rectangular, the number of columns will be the same as the
    // txfm_size stored in the row cfg struct. It will make no difference
    // for square transforms.
    let txfm_size_col = tx_size.width();
    let txfm_size_row = tx_size.height();

    let mut tmp: Aligned<[i32; 64 * 64]> = Aligned::uninitialized();
    let buf = &mut tmp.data[..txfm_size_col * txfm_size_row];

    let cfg = Txfm2DFlipCfg::fwd(tx_type, tx_size, bd);

    let txfm_func_col = get_func(cfg.txfm_type_col);
    let txfm_func_row = get_func(cfg.txfm_type_row);

    // Columns
    for c in 0..txfm_size_col {
      let mut col_coeffs_backing: Aligned<[i32; 64]> =
        Aligned::uninitialized();
      let col_coeffs = &mut col_coeffs_backing.data[..txfm_size_row];
      if cfg.ud_flip {
        // flip upside down
        for r in 0..txfm_size_row {
          col_coeffs[r] = (input[(txfm_size_row - r - 1) * stride + c]).into();
        }
      } else {
        for r in 0..txfm_size_row {
          col_coeffs[r] = (input[r * stride + c]).into();
        }
      }

      av1_round_shift_array(col_coeffs, txfm_size_row, -cfg.shift[0]);
      txfm_func_col(col_coeffs);
      av1_round_shift_array(col_coeffs, txfm_size_row, -cfg.shift[1]);
      if cfg.lr_flip {
        for r in 0..txfm_size_row {
          // flip from left to right
          buf[r * txfm_size_col + (txfm_size_col - c - 1)] = col_coeffs[r];
        }
      } else {
        for r in 0..txfm_size_row {
          buf[r * txfm_size_col + c] = col_coeffs[r];
        }
      }
    }

    // Rows
    for r in 0..txfm_size_row {
      let row_coeffs = &mut buf[r * txfm_size_col..];
      txfm_func_row(row_coeffs);
      av1_round_shift_array(row_coeffs, txfm_size_col, -cfg.shift[2]);

      // Store output in at most 32x32 chunks so that the first 32x32
      // coefficients are stored first. When we don't have 64 rows, there is no
      // change in order. With 64 rows, the chunks are in this order
      //  - First 32 rows and first 32 cols
      //  - Last 32 rows and first 32 cols
      //  - First 32 rows and last 32 cols
      //  - Last 32 rows and last 32 cols

      // Output is grouped into 32x32 chunks so a stride of at most 32 is
      // used for each chunk.
      let output_stride = txfm_size_row.min(32);

      // Split the first 32 rows from the last 32 rows
      let output = &mut output
        [(r >= 32) as usize * output_stride * txfm_size_col.min(32)..];

      for cg in (0..txfm_size_col).step_by(32) {
        // Split the first 32 cols from the last 32 cols
        let output = &mut output[txfm_size_row * cg..];

        for c in 0..txfm_size_col.min(32) {
          output[c * output_stride + (r & 31)] =
            T::cast_from(row_coeffs[c + cg]);
        }
      }
    }
  }
}
<commit_msg>Use function pointers instead of `dyn Fn` for `get_func`<commit_after>// Copyright (c) 2018-2020, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use crate::cpu_features::CpuFeatureLevel;
use crate::util::*;

use super::TxType;

cfg_if::cfg_if! {
  if #[cfg(nasm_x86_64)] {
    pub use crate::asm::x86::transform::forward::*;
  } else {
    pub use self::rust::*;
  }
}

pub mod rust {
  use super::*;

  use crate::transform::forward_shared::*;
  use crate::transform::{av1_round_shift_array, valid_av1_transform, TxSize};
  use simd_helpers::cold_for_target_arch;

  pub trait TxOperations: Copy {
    fn zero() -> Self;

    fn tx_mul(self, _: (i32, i32)) -> Self;
    fn rshift1(self) -> Self;
    fn add(self, b: Self) -> Self;
    fn sub(self, b: Self) -> Self;
    fn add_avg(self, b: Self) -> Self;
    fn sub_avg(self, b: Self) -> Self;

    fn copy_fn(self) -> Self {
      self
    }
  }

  impl TxOperations for i32 {
    fn zero() -> Self {
      0
    }

    fn tx_mul(self, mul: (i32, i32)) -> Self {
      ((self * mul.0) + (1 << mul.1 >> 1)) >> mul.1
    }

    fn rshift1(self) -> Self {
      (self + if self < 0 { 1 } else { 0 }) >> 1
    }

    fn add(self, b: Self) -> Self {
      self + b
    }

    fn sub(self, b: Self) -> Self {
      self - b
    }

    fn add_avg(self, b: Self) -> Self {
      (self + b) >> 1
    }

    fn sub_avg(self, b: Self) -> Self {
      (self - b) >> 1
    }
  }

  impl_1d_tx!();

  type TxfmFunc = fn(&mut [i32]);

  fn get_func(t: TxfmType) -> TxfmFunc {
    use self::TxfmType::*;
    match t {
      DCT4 => daala_fdct4,
      DCT8 => daala_fdct8,
      DCT16 => daala_fdct16,
      DCT32 => daala_fdct32,
      DCT64 => daala_fdct64,
      ADST4 => daala_fdst_vii_4,
      ADST8 => daala_fdst8,
      ADST16 => daala_fdst16,
      Identity4 => fidentity,
      Identity8 => fidentity,
      Identity16 => fidentity,
      Identity32 => fidentity,
      _ => unreachable!(),
    }
  }

  #[cold_for_target_arch("x86_64")]
  pub fn forward_transform<T: Coefficient>(
    input: &[i16], output: &mut [T], stride: usize, tx_size: TxSize,
    tx_type: TxType, bd: usize, _cpu: CpuFeatureLevel,
  ) {
    assert!(valid_av1_transform(tx_size, tx_type));

    // Note when assigning txfm_size_col, we use the txfm_size from the
    // row configuration and vice versa. This is intentionally done to
    // accurately perform rectangular transforms. When the transform is
    // rectangular, the number of columns will be the same as the
    // txfm_size stored in the row cfg struct. It will make no difference
    // for square transforms.
    let txfm_size_col = tx_size.width();
    let txfm_size_row = tx_size.height();

    let mut tmp: Aligned<[i32; 64 * 64]> = Aligned::uninitialized();
    let buf = &mut tmp.data[..txfm_size_col * txfm_size_row];

    let cfg = Txfm2DFlipCfg::fwd(tx_type, tx_size, bd);

    let txfm_func_col = get_func(cfg.txfm_type_col);
    let txfm_func_row = get_func(cfg.txfm_type_row);

    // Columns
    for c in 0..txfm_size_col {
      let mut col_coeffs_backing: Aligned<[i32; 64]> =
        Aligned::uninitialized();
      let col_coeffs = &mut col_coeffs_backing.data[..txfm_size_row];
      if cfg.ud_flip {
        // flip upside down
        for r in 0..txfm_size_row {
          col_coeffs[r] = (input[(txfm_size_row - r - 1) * stride + c]).into();
        }
      } else {
        for r in 0..txfm_size_row {
          col_coeffs[r] = (input[r * stride + c]).into();
        }
      }

      av1_round_shift_array(col_coeffs, txfm_size_row, -cfg.shift[0]);
      txfm_func_col(col_coeffs);
      av1_round_shift_array(col_coeffs, txfm_size_row, -cfg.shift[1]);
      if cfg.lr_flip {
        for r in 0..txfm_size_row {
          // flip from left to right
          buf[r * txfm_size_col + (txfm_size_col - c - 1)] = col_coeffs[r];
        }
      } else {
        for r in 0..txfm_size_row {
          buf[r * txfm_size_col + c] = col_coeffs[r];
        }
      }
    }

    // Rows
    for r in 0..txfm_size_row {
      let row_coeffs = &mut buf[r * txfm_size_col..];
      txfm_func_row(row_coeffs);
      av1_round_shift_array(row_coeffs, txfm_size_col, -cfg.shift[2]);

      // Store output in at most 32x32 chunks so that the first 32x32
      // coefficients are stored first. When we don't have 64 rows, there is no
      // change in order. With 64 rows, the chunks are in this order
      //  - First 32 rows and first 32 cols
      //  - Last 32 rows and first 32 cols
      //  - First 32 rows and last 32 cols
      //  - Last 32 rows and last 32 cols

      // Output is grouped into 32x32 chunks so a stride of at most 32 is
      // used for each chunk.
      let output_stride = txfm_size_row.min(32);

      // Split the first 32 rows from the last 32 rows
      let output = &mut output
        [(r >= 32) as usize * output_stride * txfm_size_col.min(32)..];

      for cg in (0..txfm_size_col).step_by(32) {
        // Split the first 32 cols from the last 32 cols
        let output = &mut output[txfm_size_row * cg..];

        for c in 0..txfm_size_col.min(32) {
          output[c * output_stride + (r & 31)] =
            T::cast_from(row_coeffs[c + cg]);
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>//! Common types used by multiple graph implementations.

use std::ops;
use std::fmt::Debug;
use std::default::Default;
use std::hash::{Hash};

use num_traits::{NumCast,ToPrimitive};

use super::interface::{self, Id, Graph};
use super::iter::Indices;

// ================================================================
// Indices: types used to identify nodes and edges.

/// Default integer type used to identify nodes and edges.
pub type DefaultIndexType = u32;

/// Any integer type used as the underlying type for node and edge indices.
pub trait IndexType: Copy + Eq + Hash + Ord + Debug + NumCast + ToPrimitive + 'static {}
impl<T> IndexType for T where T: Copy + Eq + Hash + Ord + Debug + NumCast + ToPrimitive + 'static {}

macro_rules! impl_index_wrapper_type {
    ($tp: ty, $n: ident, $T: ident) => {
        impl<$T: IndexType> Id for $tp {
            #[inline(always)]
            fn new(v: usize) -> Self { $n(NumCast::from(v).unwrap()) }
            #[inline(always)]
            fn index(&self) -> usize { NumCast::from(self.0).unwrap() }
        }

        impl<U: NumCast + ToPrimitive, $T: IndexType> From<U> for $tp {
            fn from(v: U) -> Self {
                Self::new(NumCast::from(v).unwrap())
            }
        }
    }
}

/// Type used to identify and index the edges of a graph.
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct EdgeIndex<T: IndexType>(T);
impl_index_wrapper_type!(EdgeIndex<T>,EdgeIndex,T);

/// Type used to identify and index the nodes of a graph.
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct NodeIndex<T: IndexType>(T);
impl_index_wrapper_type!(NodeIndex<T>,NodeIndex,T);

// --------------------------------

/// Implement `interface::Node` for a type with members `incoming_edges` and
/// `outgoing_edges` of types compatible with `Vec<$I>`.
macro_rules! impl_basic_node {
    ($I: ident) => {
        //type EdgeIter<'a> = std::slice::Iter<'a,$I>;

        #[inline(always)]
        fn incoming_edges(&self) -> std::slice::Iter<$I> {
            self.incoming_edges.iter()
        }

        fn incoming_edge_count(&self) -> usize {
            self.incoming_edges.len()
        }

        #[inline(always)]
        fn outgoing_edges(&self) -> std::slice::Iter<$I> {
            self.outgoing_edges.iter()
        }

        fn outgoing_edge_count(&self) -> usize {
            self.outgoing_edges.len()
        }

        #[inline(always)]
        fn add_incoming_edge(&mut self, e: $I) {
            self.incoming_edges.push(e);
        }

        #[inline(always)]
        fn add_outgoing_edge(&mut self, e: $I) {
            self.outgoing_edges.push(e);
        }
    }
}

// --------------------------------
// AdjacencyList

/// Adjacency-list graph implementation.
#[derive(Clone,Debug)]
pub struct AdjacencyList<N, E> {
    nodes: Vec<N>,
    edges: Vec<E>
}

impl<N, E> AdjacencyList<N, E> {
    /// Create an empty AdjacencyList instance.
    pub fn new() -> Self {
        AdjacencyList{nodes: Vec::new(), edges: Vec::new()}
    }
}

impl<N, E> Default for AdjacencyList<N, E> {
    #[inline(always)]
    fn default() -> Self {
        AdjacencyList::new()
   }
}

impl<N, E> interface::Graph for AdjacencyList<N, E>
    where N: interface::Node,
          E: interface::Edge
{
    type NodeId = <E as interface::Edge>::NodeId;
    type EdgeId = <N as interface::Node>::EdgeId;
    type EdgeIdIterator = Indices<Self::EdgeId>;
    type NodeIdIterator = Indices<Self::NodeId>;

    #[inline(always)]
    fn contains_node(&self, n: Self::NodeId) -> bool {
        n.index() < self.nodes.len()
    }

    #[inline]
    fn node_ids(&self) -> Self::NodeIdIterator {
        Indices::new(0..self.nodes.len())
    }

    #[inline]
    fn node_count(&self) -> usize {
        self.nodes.len()
    }

    fn contains_edge(&self, e: Self::EdgeId) -> bool {
        e.index() < self.edges.len()
    }

    fn edge_ids(&self) -> Self::EdgeIdIterator {
        Indices::new(0..self.edges.len())
    }

    fn edge_count(&self) -> usize {
        self.edges.len()
    }

}

impl<N, E> interface::ConcreteGraph for AdjacencyList<N, E>
    where N: interface::DirectedNode,
          E: interface::DirectedEdge
{
    type Node = N;
    type Edge = E;

    #[inline(always)]
    fn node(&self, n: Self::NodeId) -> &Self::Node {
        &self.nodes[n.index()]
    }

    #[inline(always)]
    fn node_mut(&mut self, n: Self::NodeId) -> &mut Self::Node {
        &mut self.nodes[n.index()]
    }

    #[inline(always)]
    fn edge(&self, e: Self::EdgeId) -> &Self::Edge {
        &self.edges[e.index()]
    }

    #[inline(always)]
    fn edge_mut(&mut self, e: Self::EdgeId) -> &mut Self::Edge {
        &mut self.edges[e.index()]
    }

    #[inline(always)]
    fn add_node<T: Into<Self::Node>>(&mut self, n: T) -> Self::NodeId {
        self.nodes.push(n.into());
        Self::NodeId::new(self.nodes.len() - 1)
    }

    fn add_edge<T: Into<Self::Edge>>(&mut self, e: T) -> Self::EdgeId {
        let edge = e.into();
        let (a, b) = edge.endpoints();
        let srcidx = a.index();
        let destidx = b.index();

        let node_count = self.node_count();
        panic_unless!(srcidx < node_count, "Invalid source-node index provided to `Graph::add_edge`");
        panic_unless!(destidx < node_count, "Invalid target-node index provided to `Graph::add_edge`");

        self.edges.push(edge);
        let index = Self::EdgeId::new(self.edges.len() - 1);

        // Update cross-referenced edge lists for the connected nodes.
        self.nodes[srcidx].add_outgoing_edge(index);
        self.nodes[destidx].add_incoming_edge(index);

        index
    }
}

// Implement node-data lookup via indexing.
macro_rules! graph_index_impl {
    ($tp: ty, $n: ident, $e: ident, $r: ident, $m: ident) => {
        impl<$n, $e, Ix> ops::Index<$tp> for AdjacencyList<N, E>
            where N: interface::Node,
                  E: interface::Edge,
                  Ix: IndexType {
            type Output = $r;
            fn index(&self, ix: $tp) -> &$r {
                &self.$m[ix.index()]
            }

        }
        impl<$n, $e, Ix> ops::IndexMut<$tp> for AdjacencyList<N, E>
            where N: interface::Node,
                  E: interface::Edge,
                  Ix: IndexType {
            fn index_mut(&mut self, ix: $tp) -> &mut $r {
                &mut self.$m[ix.index()]
            }

        }
    }
}
graph_index_impl!(EdgeIndex<Ix>, N, E, E, edges);
graph_index_impl!(NodeIndex<Ix>, N, E, N, nodes);
<commit_msg>util/graph/common: include index when we panic with bad ID in `add_edge`<commit_after>//! Common types used by multiple graph implementations.

use std::ops;
use std::fmt::Debug;
use std::default::Default;
use std::hash::{Hash};

use num_traits::{NumCast,ToPrimitive};

use super::interface::{self, Id, Graph};
use super::iter::Indices;

// ================================================================
// Indices: types used to identify nodes and edges.

/// Default integer type used to identify nodes and edges.
pub type DefaultIndexType = u32;

/// Any integer type used as the underlying type for node and edge indices.
pub trait IndexType: Copy + Eq + Hash + Ord + Debug + NumCast + ToPrimitive + 'static {}
impl<T> IndexType for T where T: Copy + Eq + Hash + Ord + Debug + NumCast + ToPrimitive + 'static {}

macro_rules! impl_index_wrapper_type {
    ($tp: ty, $n: ident, $T: ident) => {
        impl<$T: IndexType> Id for $tp {
            #[inline(always)]
            fn new(v: usize) -> Self { $n(NumCast::from(v).unwrap()) }
            #[inline(always)]
            fn index(&self) -> usize { NumCast::from(self.0).unwrap() }
        }

        impl<U: NumCast + ToPrimitive, $T: IndexType> From<U> for $tp {
            fn from(v: U) -> Self {
                Self::new(NumCast::from(v).unwrap())
            }
        }
    }
}

/// Type used to identify and index the edges of a graph.
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct EdgeIndex<T: IndexType>(T);
impl_index_wrapper_type!(EdgeIndex<T>,EdgeIndex,T);

/// Type used to identify and index the nodes of a graph.
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct NodeIndex<T: IndexType>(T);
impl_index_wrapper_type!(NodeIndex<T>,NodeIndex,T);

// --------------------------------

/// Implement `interface::Node` for a type with members `incoming_edges` and
/// `outgoing_edges` of types compatible with `Vec<$I>`.
macro_rules! impl_basic_node {
    ($I: ident) => {
        //type EdgeIter<'a> = std::slice::Iter<'a,$I>;

        #[inline(always)]
        fn incoming_edges(&self) -> std::slice::Iter<$I> {
            self.incoming_edges.iter()
        }

        fn incoming_edge_count(&self) -> usize {
            self.incoming_edges.len()
        }

        #[inline(always)]
        fn outgoing_edges(&self) -> std::slice::Iter<$I> {
            self.outgoing_edges.iter()
        }

        fn outgoing_edge_count(&self) -> usize {
            self.outgoing_edges.len()
        }

        #[inline(always)]
        fn add_incoming_edge(&mut self, e: $I) {
            self.incoming_edges.push(e);
        }

        #[inline(always)]
        fn add_outgoing_edge(&mut self, e: $I) {
            self.outgoing_edges.push(e);
        }
    }
}

// --------------------------------
// AdjacencyList

/// Adjacency-list graph implementation.
#[derive(Clone,Debug)]
pub struct AdjacencyList<N, E> {
    nodes: Vec<N>,
    edges: Vec<E>
}

impl<N, E> AdjacencyList<N, E> {
    /// Create an empty AdjacencyList instance.
    pub fn new() -> Self {
        AdjacencyList{nodes: Vec::new(), edges: Vec::new()}
    }
}

impl<N, E> Default for AdjacencyList<N, E> {
    #[inline(always)]
    fn default() -> Self {
        AdjacencyList::new()
   }
}

impl<N, E> interface::Graph for AdjacencyList<N, E>
    where N: interface::Node,
          E: interface::Edge
{
    type NodeId = <E as interface::Edge>::NodeId;
    type EdgeId = <N as interface::Node>::EdgeId;
    type EdgeIdIterator = Indices<Self::EdgeId>;
    type NodeIdIterator = Indices<Self::NodeId>;

    #[inline(always)]
    fn contains_node(&self, n: Self::NodeId) -> bool {
        n.index() < self.nodes.len()
    }

    #[inline]
    fn node_ids(&self) -> Self::NodeIdIterator {
        Indices::new(0..self.nodes.len())
    }

    #[inline]
    fn node_count(&self) -> usize {
        self.nodes.len()
    }

    fn contains_edge(&self, e: Self::EdgeId) -> bool {
        e.index() < self.edges.len()
    }

    fn edge_ids(&self) -> Self::EdgeIdIterator {
        Indices::new(0..self.edges.len())
    }

    fn edge_count(&self) -> usize {
        self.edges.len()
    }

}

impl<N, E> interface::ConcreteGraph for AdjacencyList<N, E>
    where N: interface::DirectedNode,
          E: interface::DirectedEdge
{
    type Node = N;
    type Edge = E;

    #[inline(always)]
    fn node(&self, n: Self::NodeId) -> &Self::Node {
        &self.nodes[n.index()]
    }

    #[inline(always)]
    fn node_mut(&mut self, n: Self::NodeId) -> &mut Self::Node {
        &mut self.nodes[n.index()]
    }

    #[inline(always)]
    fn edge(&self, e: Self::EdgeId) -> &Self::Edge {
        &self.edges[e.index()]
    }

    #[inline(always)]
    fn edge_mut(&mut self, e: Self::EdgeId) -> &mut Self::Edge {
        &mut self.edges[e.index()]
    }

    #[inline(always)]
    fn add_node<T: Into<Self::Node>>(&mut self, n: T) -> Self::NodeId {
        self.nodes.push(n.into());
        Self::NodeId::new(self.nodes.len() - 1)
    }

    fn add_edge<T: Into<Self::Edge>>(&mut self, e: T) -> Self::EdgeId {
        let edge = e.into();
        let (a, b) = edge.endpoints();
        let srcidx = a.index();
        let destidx = b.index();

        let node_count = self.node_count();
        panic_unless!(srcidx < node_count, "Invalid source node provided to `Graph::add_edge`: {:?}", a);
        panic_unless!(destidx < node_count, "Invalid target node provided to `Graph::add_edge`: {:?}", b);

        self.edges.push(edge);
        let index = Self::EdgeId::new(self.edges.len() - 1);

        // Update cross-referenced edge lists for the connected nodes.
        self.nodes[srcidx].add_outgoing_edge(index);
        self.nodes[destidx].add_incoming_edge(index);

        index
    }
}

// Implement node-data lookup via indexing.
macro_rules! graph_index_impl {
    ($tp: ty, $n: ident, $e: ident, $r: ident, $m: ident) => {
        impl<$n, $e, Ix> ops::Index<$tp> for AdjacencyList<N, E>
            where N: interface::Node,
                  E: interface::Edge,
                  Ix: IndexType {
            type Output = $r;
            fn index(&self, ix: $tp) -> &$r {
                &self.$m[ix.index()]
            }

        }
        impl<$n, $e, Ix> ops::IndexMut<$tp> for AdjacencyList<N, E>
            where N: interface::Node,
                  E: interface::Edge,
                  Ix: IndexType {
            fn index_mut(&mut self, ix: $tp) -> &mut $r {
                &mut self.$m[ix.index()]
            }

        }
    }
}
graph_index_impl!(EdgeIndex<Ix>, N, E, E, edges);
graph_index_impl!(NodeIndex<Ix>, N, E, N, nodes);
<|endoftext|>


<commit_before>use clap::{Arg, App, ArgGroup, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
	app
        .subcommand(SubCommand::with_name("tw-hook")
                    .about("For use in a taskwarrior hook")
                    .version("0.1")

                    .arg(Arg::with_name("add")
                         .long("add")
                         .short("a")
                         .takes_value(false)
                         .required(false)
                         .help("For use in an on-add hook"))

                    .arg(Arg::with_name("delete")
                         .long("delete")
                         .short("d")
                         .takes_value(false)
                         .required(false)
                         .help("For use in an on-delete hook"))

                    .group(ArgGroup::with_name("taskwarrior hooks")
                           .args(&[ "add",
                                    "delete",
                                ])
                           .required(true))
                    )

        .subcommand(SubCommand::with_name("exec")
                    .about("Send a command to taskwarrior")
                    .version("0.1")

                    .arg(Arg::with_name("command")
                         .long("command")
                         .short("c")
                         .takes_value(true)
			 .multiple(true)
                         .required(true)
                         .help("Args written in the string will be send directly to taskwarrior"))

                    )

}
<commit_msg>added exec/add with description,priority,project,due and frequency<commit_after>use clap::{Arg, App, ArgGroup, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
	app
        .subcommand(SubCommand::with_name("tw-hook")
                    .about("For use in a taskwarrior hook")
                    .version("0.1")

                    .arg(Arg::with_name("add")
                         .long("add")
                         .short("a")
                         .takes_value(false)
                         .required(false)
                         .help("For use in an on-add hook"))

                    .arg(Arg::with_name("delete")
                         .long("delete")
                         .short("d")
                         .takes_value(false)
                         .required(false)
                         .help("For use in an on-delete hook"))

                    .group(ArgGroup::with_name("taskwarrior hooks")
                           .args(&[ "add",
                                    "delete",
                                ])
                           .required(true))
                    )

        .subcommand(SubCommand::with_name("exec")
                    .about("Send a command to taskwarrior")
                    .version("0.1")

                    .arg(Arg::with_name("command")
                         .long("command")
                         .short("c")
                         .takes_value(true)
			 .multiple(true)
                         .required(true)
                         .help("Args written in the string will be send directly to taskwarrior"))

                    )

        .subcommand(SubCommand::with_name("add")
                    .about("create a task")
                    .version("0.1")

                    .arg(Arg::with_name("description")
                        .long("description")
                        .short("d")
                        .takes_value(true)
                        .required(true)
                        .help("Name/Description of the new task")
                    )

                    .arg(Arg::with_name("priority")
                        .long("priority")
                        .short("p")
                        .takes_value(true)
                        .required(false)
                        .help("One of l, m, h for low, medium and high priority")
                    )

                    .arg(Arg::with_name("project")
                        .long("project")
                        .takes_value(true)
                        .required(false)
                        .help("Name of the project the task is related to")
                    )

                    .arg(Arg::with_name("due")
                        .long("due")
                        .takes_value(true)
                        .required(false)
                        .help("Due date of the new task")
                    )

                    .arg(Arg::with_name("frequency")
                        .long("frequency")
                        .short("f")
                        .takes_value(true)
                        .required(false)
                        .help("Frequency of the recurrence of a task")
                    )

}
<|endoftext|>


<commit_before>use futures::{Async, Future, Poll, Stream};
use futures::task::{self, Task};
use std::io;
use std::net::SocketAddr;
use hyper::Chunk;
use hyper::server::Http;
use tokio_core::reactor::Core;
use tokio_core::net::{TcpListener, TcpStream};
use routing::Router;
use std::sync::{Arc, Mutex};
use futures::prelude::{async, await};
use std::thread;
use num_cpus;
use proto::{ArcHandler, ArcService, MiddleWare};
use super::{rootservice, Request, Response};
use self::rootservice::RootService;

// A wrapper around a closure i can run forever on an event loop.
struct ReactorFuture<F>
where
	F: Fn(),
{
	pub handler: F,
}

// The future never completes.
// This is because it takes care of dispatching connected clients on the event
// loop.
impl<F> Future for ReactorFuture<F>
where
	F: Fn(),
{
	type Item = ();
	type Error = ();

	fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
		(self.handler)();

		Ok(Async::NotReady)
	}
}

type ReactorAlias = Arc<Mutex<Reactor>>;

// Shared Mutable object to connected clients
// This struct is only shared by the main thread, and the another worker thread
// at any point in time. As new clients are connected, The main thread will
// lock the reactor and push the clients to `peers`. then the future running in
// the thread is notified that there are new clients that need to be handled.
struct Reactor {
	pub(crate) peers: Vec<(TcpStream, SocketAddr)>,
	pub(crate) taskHandle: Option<Task>,
}

// Creates a thread safe Mutable reactor.
impl Reactor {
	pub fn new() -> ReactorAlias {
		Arc::new(Mutex::new(Reactor {
			peers: Vec::new(),
			taskHandle: None,
		}))
	}
}

/// The main server, the ArcReactor is where you mount your routes, middlewares and initiate the
/// server.
///
/// #Examples
///
/// ```
/// extern crate arc_reactor;
/// use arc_reactor::ArcReactor;
///
/// fn main() {
///    ArcReactor::new().routes(..).port(1234).initiate().unwrap()
/// 	}
/// ```
pub struct ArcReactor {
	port: i16,
	handler: Option<ArcHandler>,
}

impl ArcReactor {
	/// Creates an instance of the server.
	/// with a default port of `8080`
	/// and *No* routes. Note that calling `initiate` on an `ArcReactor` without routes
	/// will cause your program to panic.
	pub fn new() -> ArcReactor {
		ArcReactor {
			port: 8080,
			handler: None,
		}
	}

	/// sets the port for the server to listen on and returns the instance.
	pub fn port(mut self, port: i16) -> Self {
		self.port = port;

		self
	}

	/// Mount a global MiddleWare on the server, Note that it takes a type
	/// [`MiddleWare<Request>`](trait.MiddleWare.html#impl-MiddleWare<Request>) this is because, the
	/// middleware(s) supplied here are run before any other middleware or route handlers.
	///
	/// read the [`MiddleWare<T>`](trait.MiddleWare.html) documentation to understand how middlewares
	/// work.
	pub fn before(mut self, before: Box<MiddleWare<Request>>) -> Self {
		if let Some(ref mut archandler) = self.handler {
			archandler.before = Some(Arc::new(before));
		}

		self
	}

	/// Mount a global MiddleWare on the server, Note that it takes a type
	/// [`MiddleWare<Response>`](trait.MiddleWare.html#impl-MiddleWare<Response>) this is because,
	/// the middleware(s) supplied here are run before any other middleware or route handlers.
	///
	/// read the [`MiddleWare<T>`](trait.MiddleWare.html) documentation to understand how middlewares
	/// work.
	pub fn after(mut self, after: Box<MiddleWare<Response>>) -> Self {
		if let Some(ref mut archandler) = self.handler {
			archandler.after = Some(Arc::new(after));
		}

		self
	}

	pub fn routes(mut self, routes: Router) -> Self {
		let routes = Arc::new(box routes as Box<ArcService>);
		if let Some(ref mut archandler) = self.handler {
			archandler.handler = routes;
		} else {
			self.handler = Some(ArcHandler {
				before: None,
				after: None,
				handler: routes,
			});
		}

		self
	}

	/// Binds the listener and blocks the main thread while listening for incoming connections.
	///
	/// # Panics
	///
	/// Calling this function will panic if: no routes are supplied, or it cannot
	/// start the main event loop.

	#[must_use]
	pub fn initiate(self) -> io::Result<()> {
		println!("[arc-reactor]: Spawning threads!");
		let reactors = spawn(self.handler.expect("This thing needs routes to work!"))?;
		println!(
			"[arc-reactor]: Starting main event loop!\n[arc-reactor]: Spawned {} threads",
			reactors.len()
		);
		let mut core = Core::new()?;

		println!("[arc-reactor]: Started Main event loop!");
		let handle = core.handle();

		let addr = format!("0.0.0.0:{}", self.port).parse().unwrap();
		println!("[arc-reactor]: Binding to port {}", self.port);
		let listener = match TcpListener::bind(&addr, &handle) {
			Ok(listener) => listener,
			Err(e) => {
				eprintln!(
					"[arc-reactor]: Whoops! something else is running on port {}, {}",
					&self.port, e
				);
				return Err(e);
			}
		};

		let mut counter = 0;

		println!("[arc-reactor]: Running Main Event loop");
		core.run(listener.incoming().for_each(move |(socket, peerIp)| {
			println!("current counter {}", counter);
			println!("current reactors {}", reactors.len());
			let mut reactor = reactors[counter].lock().unwrap();
			reactor.peers.push((socket, peerIp));

			if let Some(ref task) = reactor.taskHandle {
				task.notify();
			}

			counter += 1;
			if counter == reactors.len() {
				counter = 0
			}
			Ok(())
		}))?;

		Ok(())
	}
}

fn spawn(RouteService: ArcHandler) -> io::Result<Vec<ReactorAlias>> {
	let mut reactors = Vec::new();
	let routeService = Arc::new(RouteService);

	for id in 0..num_cpus::get() * 2 {
		let reactor = Reactor::new();
		reactors.push(reactor.clone());
		let routeService = routeService.clone();

		thread::spawn(move || {
			let mut core = Core::new().expect("Could not start event loop");
			let handle = core.handle();
			let http = Http::new();

			let handler = || {
				let mut reactor = reactor.lock().unwrap();
				for (socket, remote_ip) in reactor.peers.drain(..) {
					println!("thread {} handling", id);
					let service = routeService.clone();
					let future = socketHandler(socket, http.clone(), RootService { service, remote_ip, handle: handle.clone() });
					handle.spawn(future);
				}
				reactor.taskHandle = Some(task::current());
			};

			let future = ReactorFuture { handler };

			core.run(future).expect("Error running reactor core!");
		});
	}

	Ok(reactors)
}

#[async]
fn socketHandler(
	stream: TcpStream,
	http: Http<Chunk>,
	serviceHandler: RootService,
) -> Result<(), ()> {
	let _opaque = await!(http.serve_connection(stream, serviceHandler));
	Ok(())
}
<commit_msg>removed unnecessarily println's<commit_after>use futures::{Async, Future, Poll, Stream};
use futures::task::{self, Task};
use std::io;
use std::net::SocketAddr;
use hyper::Chunk;
use hyper::server::Http;
use tokio_core::reactor::Core;
use tokio_core::net::{TcpListener, TcpStream};
use routing::Router;
use std::sync::{Arc, Mutex};
use futures::prelude::{async, await};
use std::thread;
use num_cpus;
use proto::{ArcHandler, ArcService, MiddleWare};
use super::{rootservice, Request, Response};
use self::rootservice::RootService;

// A wrapper around a closure i can run forever on an event loop.
struct ReactorFuture<F>
where
	F: Fn(),
{
	pub handler: F,
}

// The future never completes.
// This is because it takes care of dispatching connected clients on the event
// loop.
impl<F> Future for ReactorFuture<F>
where
	F: Fn(),
{
	type Item = ();
	type Error = ();

	fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
		(self.handler)();

		Ok(Async::NotReady)
	}
}

type ReactorAlias = Arc<Mutex<Reactor>>;

// Shared Mutable object to connected clients
// This struct is only shared by the main thread, and the another worker thread
// at any point in time. As new clients are connected, The main thread will
// lock the reactor and push the clients to `peers`. then the future running in
// the thread is notified that there are new clients that need to be handled.
struct Reactor {
	pub(crate) peers: Vec<(TcpStream, SocketAddr)>,
	pub(crate) taskHandle: Option<Task>,
}

// Creates a thread safe Mutable reactor.
impl Reactor {
	pub fn new() -> ReactorAlias {
		Arc::new(Mutex::new(Reactor {
			peers: Vec::new(),
			taskHandle: None,
		}))
	}
}

/// The main server, the ArcReactor is where you mount your routes, middlewares and initiate the
/// server.
///
/// #Examples
///
/// ```
/// extern crate arc_reactor;
/// use arc_reactor::ArcReactor;
///
/// fn main() {
///    ArcReactor::new().routes(..).port(1234).initiate().unwrap()
/// 	}
/// ```
pub struct ArcReactor {
	port: i16,
	handler: Option<ArcHandler>,
}

impl ArcReactor {
	/// Creates an instance of the server.
	/// with a default port of `8080`
	/// and *No* routes. Note that calling `initiate` on an `ArcReactor` without routes
	/// will cause your program to panic.
	pub fn new() -> ArcReactor {
		ArcReactor {
			port: 8080,
			handler: None,
		}
	}

	/// sets the port for the server to listen on and returns the instance.
	pub fn port(mut self, port: i16) -> Self {
		self.port = port;

		self
	}

	/// Mount a global MiddleWare on the server, Note that it takes a type
	/// [`MiddleWare<Request>`](trait.MiddleWare.html#impl-MiddleWare<Request>) this is because, the
	/// middleware(s) supplied here are run before any other middleware or route handlers.
	///
	/// read the [`MiddleWare<T>`](trait.MiddleWare.html) documentation to understand how middlewares
	/// work.
	pub fn before(mut self, before: Box<MiddleWare<Request>>) -> Self {
		if let Some(ref mut archandler) = self.handler {
			archandler.before = Some(Arc::new(before));
		}

		self
	}

	/// Mount a global MiddleWare on the server, Note that it takes a type
	/// [`MiddleWare<Response>`](trait.MiddleWare.html#impl-MiddleWare<Response>) this is because,
	/// the middleware(s) supplied here are run before any other middleware or route handlers.
	///
	/// read the [`MiddleWare<T>`](trait.MiddleWare.html) documentation to understand how middlewares
	/// work.
	pub fn after(mut self, after: Box<MiddleWare<Response>>) -> Self {
		if let Some(ref mut archandler) = self.handler {
			archandler.after = Some(Arc::new(after));
		}

		self
	}

	pub fn routes(mut self, routes: Router) -> Self {
		let routes = Arc::new(box routes as Box<ArcService>);
		if let Some(ref mut archandler) = self.handler {
			archandler.handler = routes;
		} else {
			self.handler = Some(ArcHandler {
				before: None,
				after: None,
				handler: routes,
			});
		}

		self
	}

	/// Binds the listener and blocks the main thread while listening for incoming connections.
	///
	/// # Panics
	///
	/// Calling this function will panic if: no routes are supplied, or it cannot
	/// start the main event loop.

	#[must_use]
	pub fn initiate(self) -> io::Result<()> {
		println!("[arc-reactor]: Spawning threads!");
		let reactors = spawn(self.handler.expect("This thing needs routes to work!"))?;
		println!(
			"[arc-reactor]: Starting main event loop!\n[arc-reactor]: Spawned {} threads",
			reactors.len()
		);
		let mut core = Core::new()?;

		println!("[arc-reactor]: Started Main event loop!");
		let handle = core.handle();

		let addr = format!("0.0.0.0:{}", self.port).parse().unwrap();
		println!("[arc-reactor]: Binding to port {}", self.port);
		let listener = match TcpListener::bind(&addr, &handle) {
			Ok(listener) => listener,
			Err(e) => {
				eprintln!(
					"[arc-reactor]: Whoops! something else is running on port {}, {}",
					&self.port, e
				);
				return Err(e);
			}
		};

		let mut counter = 0;

		println!("[arc-reactor]: Running Main Event loop");
		core.run(listener.incoming().for_each(move |(socket, peerIp)| {
			let mut reactor = reactors[counter].lock().unwrap();
			reactor.peers.push((socket, peerIp));

			if let Some(ref task) = reactor.taskHandle {
				task.notify();
			}

			counter += 1;
			if counter == reactors.len() {
				counter = 0
			}
			Ok(())
		}))?;

		Ok(())
	}
}

fn spawn(RouteService: ArcHandler) -> io::Result<Vec<ReactorAlias>> {
	let mut reactors = Vec::new();
	let routeService = Arc::new(RouteService);

	for id in 0..num_cpus::get() * 2 {
		let reactor = Reactor::new();
		reactors.push(reactor.clone());
		let routeService = routeService.clone();

		thread::spawn(move || {
			let mut core = Core::new().expect("Could not start event loop");
			let handle = core.handle();
			let http = Http::new();

			let handler = || {
				let mut reactor = reactor.lock().unwrap();
				for (socket, remote_ip) in reactor.peers.drain(..) {
					let service = routeService.clone();
					let future = socketHandler(socket, http.clone(), RootService { service, remote_ip, handle: handle.clone() });
					handle.spawn(future);
				}
				reactor.taskHandle = Some(task::current());
			};

			let future = ReactorFuture { handler };

			core.run(future).expect("Error running reactor core!");
		});
	}

	Ok(reactors)
}

#[async]
fn socketHandler(
	stream: TcpStream,
	http: Http<Chunk>,
	serviceHandler: RootService,
) -> Result<(), ()> {
	let _opaque = await!(http.serve_connection(stream, serviceHandler));
	Ok(())
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use common::types::{PlayerId, MapPos, Size2, ZInt};
use core::{CoreEvent};
use internal_state::{InternalState};
use map::{Map, Terrain, distance};
use fov::{fov};
use db::{Db};
use unit::{Unit, UnitType, UnitClass};

#[derive(Clone, PartialEq, PartialOrd)]
pub enum TileVisibility {
    No,
    // Bad,
    Normal,
    Excellent,
}

pub fn fov_unit(
    db: &Db,
    terrain: &Map<Terrain>,
    fow: &mut Map<TileVisibility>,
    unit: &Unit,
) {
    fov_unit_in_pos(db, terrain, fow, unit, &unit.pos);
}

pub fn fov_unit_in_pos(
    db: &Db,
    terrain: &Map<Terrain>,
    fow: &mut Map<TileVisibility>,
    unit: &Unit,
    origin: &MapPos,
) {
    let unit_type = db.unit_type(&unit.type_id);
    let range = &unit_type.los_range;
    fov(
        terrain,
        origin,
        *range,
        &mut |pos| {
            let distance = distance(origin, pos);
            let vis = calc_visibility(terrain.tile(pos), unit_type, &distance);
            if vis > *fow.tile_mut(pos) {
                *fow.tile_mut(pos) = vis;
            }
        },
    );
}

fn calc_visibility(terrain: &Terrain, unit_type: &UnitType, distance: &ZInt)
    -> TileVisibility
{
    if *distance <= unit_type.cover_los_range {
        TileVisibility::Excellent
    } else if *distance <= unit_type.los_range {
        match terrain {
            &Terrain::Trees => TileVisibility::Normal,
            &Terrain::Plain => TileVisibility::Excellent,
        }
    } else {
        TileVisibility::No
    }
}

/// Fog of War
pub struct Fow {
    map: Map<TileVisibility>,
    player_id: PlayerId,
}

impl Fow {
    pub fn new(map_size: &Size2<ZInt>, player_id: &PlayerId) -> Fow {
        Fow {
            map: Map::new(map_size, TileVisibility::No),
            player_id: player_id.clone(),
        }
    }

    pub fn is_tile_visible(&self, pos: &MapPos) -> bool {
        match *self.map.tile(pos) {
            TileVisibility::Excellent => true,
            TileVisibility::Normal => true,
            TileVisibility::No => false,
        }
    }

    pub fn is_visible(&self, unit_type: &UnitType, pos: &MapPos) -> bool {
        match *self.map.tile(pos) {
            TileVisibility::Excellent => true,
            TileVisibility::Normal => match unit_type.class {
                UnitClass::Infantry => false,
                UnitClass::Vehicle => true,
            },
            TileVisibility::No => false,
        }
    }

    fn clear(&mut self) {
        for pos in self.map.get_iter() {
            *self.map.tile_mut(&pos) = TileVisibility::No;
        }
    }

    fn reset(&mut self, db: &Db, state: &InternalState) {
        self.clear();
        for (_, unit) in &state.units {
            if unit.player_id == self.player_id {
                fov_unit(db, &state.map, &mut self.map, &unit);
            }
        }
    }

    pub fn apply_event(
        &mut self,
        db: &Db,
        state: &InternalState,
        event: &CoreEvent,
    ) {
        match event {
            &CoreEvent::Move{ref unit_id, ref path, ..} => {
                let unit = state.units.get(unit_id)
                    .expect("BAD MOVE UNIT ID"); // TODO: fix errmsg
                if unit.player_id == self.player_id {
                    for path_node in path.nodes() {
                        let p = &path_node.pos;
                        fov_unit_in_pos(
                            db, &state.map, &mut self.map, unit, p);
                    }
                }
            },
            &CoreEvent::EndTurn{ref new_id, ..} => {
                if self.player_id == *new_id {
                    self.reset(db, state);
                }
            },
            &CoreEvent::CreateUnit{ref unit_id, ref player_id, ..} => {
                let unit = &state.units[unit_id];
                if self.player_id == *player_id {
                    fov_unit(db, &state.map, &mut self.map, unit);
                }
            },
            &CoreEvent::AttackUnit{..} => {},
            &CoreEvent::ShowUnit{..} => {},
            &CoreEvent::HideUnit{..} => {},
        }
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>fow.rs: Fixed err message<commit_after>// See LICENSE file for copyright and license details.

use common::types::{PlayerId, MapPos, Size2, ZInt};
use core::{CoreEvent};
use internal_state::{InternalState};
use map::{Map, Terrain, distance};
use fov::{fov};
use db::{Db};
use unit::{Unit, UnitType, UnitClass};

#[derive(Clone, PartialEq, PartialOrd)]
pub enum TileVisibility {
    No,
    // Bad,
    Normal,
    Excellent,
}

pub fn fov_unit(
    db: &Db,
    terrain: &Map<Terrain>,
    fow: &mut Map<TileVisibility>,
    unit: &Unit,
) {
    fov_unit_in_pos(db, terrain, fow, unit, &unit.pos);
}

pub fn fov_unit_in_pos(
    db: &Db,
    terrain: &Map<Terrain>,
    fow: &mut Map<TileVisibility>,
    unit: &Unit,
    origin: &MapPos,
) {
    let unit_type = db.unit_type(&unit.type_id);
    let range = &unit_type.los_range;
    fov(
        terrain,
        origin,
        *range,
        &mut |pos| {
            let distance = distance(origin, pos);
            let vis = calc_visibility(terrain.tile(pos), unit_type, &distance);
            if vis > *fow.tile_mut(pos) {
                *fow.tile_mut(pos) = vis;
            }
        },
    );
}

fn calc_visibility(terrain: &Terrain, unit_type: &UnitType, distance: &ZInt)
    -> TileVisibility
{
    if *distance <= unit_type.cover_los_range {
        TileVisibility::Excellent
    } else if *distance <= unit_type.los_range {
        match terrain {
            &Terrain::Trees => TileVisibility::Normal,
            &Terrain::Plain => TileVisibility::Excellent,
        }
    } else {
        TileVisibility::No
    }
}

/// Fog of War
pub struct Fow {
    map: Map<TileVisibility>,
    player_id: PlayerId,
}

impl Fow {
    pub fn new(map_size: &Size2<ZInt>, player_id: &PlayerId) -> Fow {
        Fow {
            map: Map::new(map_size, TileVisibility::No),
            player_id: player_id.clone(),
        }
    }

    pub fn is_tile_visible(&self, pos: &MapPos) -> bool {
        match *self.map.tile(pos) {
            TileVisibility::Excellent => true,
            TileVisibility::Normal => true,
            TileVisibility::No => false,
        }
    }

    pub fn is_visible(&self, unit_type: &UnitType, pos: &MapPos) -> bool {
        match *self.map.tile(pos) {
            TileVisibility::Excellent => true,
            TileVisibility::Normal => match unit_type.class {
                UnitClass::Infantry => false,
                UnitClass::Vehicle => true,
            },
            TileVisibility::No => false,
        }
    }

    fn clear(&mut self) {
        for pos in self.map.get_iter() {
            *self.map.tile_mut(&pos) = TileVisibility::No;
        }
    }

    fn reset(&mut self, db: &Db, state: &InternalState) {
        self.clear();
        for (_, unit) in &state.units {
            if unit.player_id == self.player_id {
                fov_unit(db, &state.map, &mut self.map, &unit);
            }
        }
    }

    pub fn apply_event(
        &mut self,
        db: &Db,
        state: &InternalState,
        event: &CoreEvent,
    ) {
        match event {
            &CoreEvent::Move{ref unit_id, ref path, ..} => {
                let unit = state.units.get(unit_id)
                    .expect("Can`t find moving unit");
                if unit.player_id == self.player_id {
                    for path_node in path.nodes() {
                        let p = &path_node.pos;
                        fov_unit_in_pos(
                            db, &state.map, &mut self.map, unit, p);
                    }
                }
            },
            &CoreEvent::EndTurn{ref new_id, ..} => {
                if self.player_id == *new_id {
                    self.reset(db, state);
                }
            },
            &CoreEvent::CreateUnit{ref unit_id, ref player_id, ..} => {
                let unit = &state.units[unit_id];
                if self.player_id == *player_id {
                    fov_unit(db, &state.map, &mut self.map, unit);
                }
            },
            &CoreEvent::AttackUnit{..} => {},
            &CoreEvent::ShowUnit{..} => {},
            &CoreEvent::HideUnit{..} => {},
        }
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before><commit_msg>removed unnecessary get* methods<commit_after><|endoftext|>


<commit_before>use decoders::*;
use decoders::tiff::*;
use decoders::basics::*;
use std::f32::NAN;

#[derive(Debug, Clone)]
pub struct Rw2Decoder<'a> {
  buffer: &'a [u8],
  rawloader: &'a RawLoader,
  tiff: TiffIFD<'a>,
}

impl<'a> Rw2Decoder<'a> {
  pub fn new(buf: &'a [u8], tiff: TiffIFD<'a>, rawloader: &'a RawLoader) -> Rw2Decoder<'a> {
    Rw2Decoder {
      buffer: buf,
      tiff: tiff,
      rawloader: rawloader,
    }
  }
}

impl<'a> Decoder for Rw2Decoder<'a> {
  fn image(&self) -> Result<Image,String> {
    let camera = try!(self.rawloader.check_supported(&self.tiff));
    let data = self.tiff.find_ifds_with_tag(Tag::StripOffsets);
    let raw = data[0];
    let width = fetch_tag!(raw, Tag::PanaWidth).get_u32(0) as usize;
    let height = fetch_tag!(raw, Tag::PanaLength).get_u32(0) as usize;
    let offset = fetch_tag!(raw, Tag::StripOffsets).get_u32(0) as usize;
    let src = &self.buffer[offset..];

    let image = if src.len() >= width*height*2 {
      decode_12le_unpacked_left_aligned(src, width, height)
    } else if src.len() >= width*height*3/2 {
      decode_12le_wcontrol(src, width, height)
    } else {
      Rw2Decoder::decode_panasonic(src, width, height)
    };

    ok_image(camera, width as u32, height as u32, try!(self.get_wb()), image)
  }
}

impl<'a> Rw2Decoder<'a> {
  fn get_wb(&self) -> Result<[f32;4], String> {
    if self.tiff.has_entry(Tag::PanaWBsR) && self.tiff.has_entry(Tag::PanaWBsB) {
      let r = fetch_tag!(self.tiff, Tag::PanaWBsR).get_u32(0) as f32;
      let b = fetch_tag!(self.tiff, Tag::PanaWBsB).get_u32(0) as f32;
      Ok([r, 256.0, b, NAN])
    } else if self.tiff.has_entry(Tag::PanaWBs2R)
           && self.tiff.has_entry(Tag::PanaWBs2G)
           && self.tiff.has_entry(Tag::PanaWBs2B) {
      let r = fetch_tag!(self.tiff, Tag::PanaWBs2R).get_u32(0) as f32;
      let g = fetch_tag!(self.tiff, Tag::PanaWBs2G).get_u32(0) as f32;
      let b = fetch_tag!(self.tiff, Tag::PanaWBs2B).get_u32(0) as f32;
      Ok([r, g, b, NAN])
    } else {
      Err("Couldn't find WB".to_string())
    }
  }

  fn decode_panasonic(buf: &[u8], width: usize, height: usize) -> Vec<u16> {
    let mut pump = BitPumpPanasonic::new(buf);
    let mut out: Vec<u16> = vec![0; (width*height) as usize];

    let mut sh: i32 = 0;
    let mut pred: [i32;2] = [0,0];
    let mut nonz: [i32;2] = [0,0];
    for row in 0..height {
      for col in 0..width {
        let i = col % 14;
        if i == 0 {
          pred = [0,0];
          nonz = [0,0];
        }
        if (i % 3) == 2 {
          sh = 4 >> (3 - pump.get_bits(2));
        }
        if nonz[i&1] != 0 {
          let j = pump.get_bits(8) as i32;
          if j != 0 {
            pred[i & 1] -= 0x80 << sh;
            if pred[i & 1] < 0 || sh == 4 {
              pred[i & 1] &= !(-1 << sh);
            }
            pred[i & 1] += j << sh;
          }
        } else {
          nonz[i & 1] = pump.get_bits(8) as i32;
          if nonz[i & 1] != 0 || i > 11 {
            pred[i & 1] = nonz[i & 1] << 4 | (pump.get_bits(4) as i32);
          }
        }
        out[row*width+col] = pred[col & 1] as u16;
      }
    }

    out
  }
}

pub struct BitPumpPanasonic<'a> {
  buffer: &'a [u8],
  pos: usize,
  nbits: u32,
}

impl<'a> BitPumpPanasonic<'a> {
  pub fn new(src: &'a [u8]) -> BitPumpPanasonic {
    BitPumpPanasonic {
      buffer: src,
      pos: 0,
      nbits: 0,
    }
  }
}

impl<'a> BitPump for BitPumpPanasonic<'a> {
  fn peek_bits(&mut self, num: u32) -> u32 {
    if num > self.nbits {
      self.nbits += 0x4000 * 8;
      self.pos += 0x4000;
    }
    let byte = (self.nbits-num) >> 3 ^ 0x3ff0;
    let bits = LEu16(self.buffer, byte as usize + self.pos - 0x4000) as u32;
    (bits >> ((self.nbits-num) & 7)) & (0x0ffffffffu32 >> (32-num))
  }

  fn consume_bits(&mut self, num: u32) {
    self.nbits -= num;
  }
}
<commit_msg>RW2: make the compressed decoder threaded<commit_after>use decoders::*;
use decoders::tiff::*;
use decoders::basics::*;
use std::f32::NAN;

#[derive(Debug, Clone)]
pub struct Rw2Decoder<'a> {
  buffer: &'a [u8],
  rawloader: &'a RawLoader,
  tiff: TiffIFD<'a>,
}

impl<'a> Rw2Decoder<'a> {
  pub fn new(buf: &'a [u8], tiff: TiffIFD<'a>, rawloader: &'a RawLoader) -> Rw2Decoder<'a> {
    Rw2Decoder {
      buffer: buf,
      tiff: tiff,
      rawloader: rawloader,
    }
  }
}

impl<'a> Decoder for Rw2Decoder<'a> {
  fn image(&self) -> Result<Image,String> {
    let camera = try!(self.rawloader.check_supported(&self.tiff));
    let data = self.tiff.find_ifds_with_tag(Tag::StripOffsets);
    let raw = data[0];
    let width = fetch_tag!(raw, Tag::PanaWidth).get_u32(0) as usize;
    let height = fetch_tag!(raw, Tag::PanaLength).get_u32(0) as usize;
    let offset = fetch_tag!(raw, Tag::StripOffsets).get_u32(0) as usize;
    let src = &self.buffer[offset..];

    let image = if src.len() >= width*height*2 {
      decode_12le_unpacked_left_aligned(src, width, height)
    } else if src.len() >= width*height*3/2 {
      decode_12le_wcontrol(src, width, height)
    } else {
      Rw2Decoder::decode_panasonic(src, width, height)
    };

    ok_image(camera, width as u32, height as u32, try!(self.get_wb()), image)
  }
}

impl<'a> Rw2Decoder<'a> {
  fn get_wb(&self) -> Result<[f32;4], String> {
    if self.tiff.has_entry(Tag::PanaWBsR) && self.tiff.has_entry(Tag::PanaWBsB) {
      let r = fetch_tag!(self.tiff, Tag::PanaWBsR).get_u32(0) as f32;
      let b = fetch_tag!(self.tiff, Tag::PanaWBsB).get_u32(0) as f32;
      Ok([r, 256.0, b, NAN])
    } else if self.tiff.has_entry(Tag::PanaWBs2R)
           && self.tiff.has_entry(Tag::PanaWBs2G)
           && self.tiff.has_entry(Tag::PanaWBs2B) {
      let r = fetch_tag!(self.tiff, Tag::PanaWBs2R).get_u32(0) as f32;
      let g = fetch_tag!(self.tiff, Tag::PanaWBs2G).get_u32(0) as f32;
      let b = fetch_tag!(self.tiff, Tag::PanaWBs2B).get_u32(0) as f32;
      Ok([r, g, b, NAN])
    } else {
      Err("Couldn't find WB".to_string())
    }
  }

  fn decode_panasonic(buf: &[u8], width: usize, height: usize) -> Vec<u16> {
    decode_threaded(width, height, &(|out: &mut [u16], row| {
      let skip = ((width * row * 9) + (width/14 * 2 * row)) / 8;
      let blocks = skip / 0x4000;
      let mut pump = BitPumpPanasonic::new(&buf[blocks*0x4000..]);
      for _ in 0..(skip % 0x4000) {
        pump.get_bits(8);
      }

      let mut sh: i32 = 0;
      let mut pred: [i32;2] = [0,0];
      let mut nonz: [i32;2] = [0,0];
      for col in 0..width {
        let i = col % 14;
        if i == 0 {
          pred = [0,0];
          nonz = [0,0];
        }
        if (i % 3) == 2 {
          sh = 4 >> (3 - pump.get_bits(2));
        }
        if nonz[i&1] != 0 {
          let j = pump.get_bits(8) as i32;
          if j != 0 {
            pred[i & 1] -= 0x80 << sh;
            if pred[i & 1] < 0 || sh == 4 {
              pred[i & 1] &= !(-1 << sh);
            }
            pred[i & 1] += j << sh;
          }
        } else {
          nonz[i & 1] = pump.get_bits(8) as i32;
          if nonz[i & 1] != 0 || i > 11 {
            pred[i & 1] = nonz[i & 1] << 4 | (pump.get_bits(4) as i32);
          }
        }
        out[col] = pred[col & 1] as u16;
      }
    }))
  }
}

pub struct BitPumpPanasonic<'a> {
  buffer: &'a [u8],
  pos: usize,
  nbits: u32,
}

impl<'a> BitPumpPanasonic<'a> {
  pub fn new(src: &'a [u8]) -> BitPumpPanasonic {
    BitPumpPanasonic {
      buffer: src,
      pos: 0,
      nbits: 0,
    }
  }
}

impl<'a> BitPump for BitPumpPanasonic<'a> {
  fn peek_bits(&mut self, num: u32) -> u32 {
    if num > self.nbits {
      self.nbits += 0x4000 * 8;
      self.pos += 0x4000;
    }
    let byte = (self.nbits-num) >> 3 ^ 0x3ff0;
    let bits = LEu16(self.buffer, byte as usize + self.pos - 0x4000) as u32;
    (bits >> ((self.nbits-num) & 7)) & (0x0ffffffffu32 >> (32-num))
  }

  fn consume_bits(&mut self, num: u32) {
    self.nbits -= num;
  }
}
<|endoftext|>


<commit_before>use std::io;
use toml;

use app_result::{AppResult, app_err};

use types::{
   TagsRoot,
   TagsRoots,
   SourceKind
};

/// Reads the dependecies from the `Cargo.toml` located in `cargo_toml_dir`
pub fn read_dependencies(cargo_toml_dir: &Path) -> AppResult<TagsRoots>
{
   let mut cargo_toml = cargo_toml_dir.clone();
   cargo_toml.push("Cargo.toml");

   let toml_string = try!(io::File::open(&cargo_toml).read_to_string());
   let mut toml_parser = toml::Parser::new(&*toml_string);

   let toml_table = try!(
      toml_parser.parse()
         .ok_or_else(|| app_err(format!("Couldn't parse '{}': {}", cargo_toml.display(), toml_parser.errors)))
   );

   let mut tags_roots: TagsRoots = Vec::new();
   let deps_string = "dependencies".to_string();
   if ! toml_table.contains_key(&deps_string) {
      tags_roots.push(TagsRoot::Src { src_dir: cargo_toml_dir.clone(), dependencies: Vec::new() });
      return Ok(tags_roots);
   }

   let deps_table = try!(
      toml_table.get(&deps_string)
         .and_then(|value| value.as_table())
         .ok_or(app_err(format!("Couldn't get toml::Table entry for 'dependency'!")))
   );

   let mut cargo_lock = cargo_toml_dir.clone();
   cargo_lock.push("Cargo.lock");

   let lock_string = try!(io::File::open(&cargo_lock).read_to_string());
   let mut lock_parser = toml::Parser::new(&*lock_string);

   let lock_table = try!(
      lock_parser.parse()
         .ok_or_else(|| app_err(format!("Couldn't parse '{}': {}", cargo_lock.display(), lock_parser.errors)))
   );

   let packages = try!(
      lock_table.get(&"package".to_string())
         .and_then(|value| value.as_slice())
         .and_then(|slice| {
            let tables = slice.iter()
               .filter_map(|value| value.as_table())
               .collect::<Vec<&toml::Table>>();

            if ! tables.is_empty() { Some(tables) } else { None }
         })
         .ok_or(app_err(format!("Couldn't get Array of Tables entry for 'package'!")))
   );

   for package in packages.iter() {
      let lib_name = try!(
         package.get(&"name".to_string())
            .and_then(|n| n.as_str().map(|n| n.to_string()))
            .ok_or_else(|| app_err(format!("Couldn't find name string in package: '{}'!", package)))
      );

      let dep_names = try!(get_dependencies(*package));
      let mut dep_src_kinds: Vec<SourceKind> = Vec::new();
      for dep_name in dep_names.iter() {
         let dep_package = try!(find_package(&packages, dep_name));
         dep_src_kinds.push(try!(get_source_kind(dep_package, dep_name)));
      }

      let src_kind = try!(get_source_kind(*package, &lib_name));
      tags_roots.push(TagsRoot::Lib { src_kind: src_kind, dependencies: dep_src_kinds });
   }

   let mut lib_src_kinds: Vec<SourceKind> = Vec::new();
   for (lib_name, value) in deps_table.iter() {
      match *value {
         toml::Value::String(_) | toml::Value::Table(_) => {
            let lib_package = try!(find_package(&packages, lib_name));
            lib_src_kinds.push(try!(get_source_kind(lib_package, lib_name)));
         }

         _ => {
            return Err(app_err(format!(
               "Expected a String or a Table for the dependency with the name '{}', but got: '{}'", lib_name, value
            )));
         }
      }
   }

   tags_roots.push(TagsRoot::Src { src_dir: cargo_toml_dir.clone(), dependencies: lib_src_kinds });

   Ok(tags_roots)
}

fn get_source_kind(lib_package: &toml::Table, lib_name: &String) -> AppResult<SourceKind>
{
   let version_str = &String::from_str("version");
   let source_str = &String::from_str("source");

   let source = try!(
      lib_package.get(source_str)
         .and_then(|src| src.as_str())
         .ok_or_else(|| app_err(format!("Couldn't find source string in package: '{}'!", lib_package)))
   );

   let src_type = try!(
      source.split('+')
         .nth(0)
         .ok_or_else(|| app_err(format!("Couldn't find source type in: '{}'!", source)))
   );

   let version = try!(
      lib_package.get(version_str)
         .and_then(|vers| vers.as_str())
         .ok_or_else(|| app_err(format!("Couldn't find version string in package: '{}'!", lib_package)))
   );

   match src_type {
      "git" => {
         let commit_hash = try!(
            source.split('#')
               .last()
               .ok_or_else(|| app_err(format!("Couldn't find commit hash in source entry: '{}'!", source)))
         );

         Ok(SourceKind::Git { lib_name: lib_name.clone(), commit_hash: commit_hash.to_string() })
      },

      "registry" => {
         Ok(SourceKind::CratesIo { lib_name: lib_name.clone(), version: version.to_string() })
      }

      _ => {
         Err(app_err(format!("Unexpected source type '{}' in package: '{}'!", src_type, lib_package)))
      }
   }
}

fn get_dependencies(lib_package: &toml::Table) -> AppResult<Vec<String>>
{
   let deps_str = &String::from_str("dependencies");
   let dep_strs = match lib_package.get(deps_str) {
      None => {
         Vec::<&str>::new()
      },

      Some(value) => {
         try!(
            value.as_slice()
               .and_then(|slice| {
                  let ds = slice.iter()
                     .filter_map(|v| v.as_str())
                     .collect::<Vec<&str>>();

                  if ! ds.is_empty() { Some(ds) } else { None }
               })
               .ok_or_else(|| app_err(format!("Couldn't get Array of Strings for 'dependencies' entry: '{}'!", lib_package)))
         )
      }
   };

   let mut dep_names: Vec<String> = Vec::new();
   for dep_str in dep_strs.iter() {
      let dep_name = try!(
         dep_str.split(' ')
            .nth(0)
            .map(|d| d.to_string())
            .ok_or_else(|| app_err(format!("Couldn't get name from dependency: '{}'!", dep_str)))
      );

      dep_names.push(dep_name);
   }

   Ok(dep_names)
}

fn find_package<'a>(packages: &'a Vec<&toml::Table>, lib_name: &String) -> AppResult<&'a toml::Table>
{
   let name_str = &String::from_str("name");

   let package = try!(
      packages.iter()
         .find(|t| t.get(name_str).and_then(|n| n.as_str()) == Some(lib_name[]))
         .ok_or_else(|| app_err(format!("Couldn't find package with name = '{}'!", lib_name)))
   );

   Ok(*package)
}
<commit_msg>Simplify somehow the implementation<commit_after>use std::io;
use toml;

use app_result::{AppResult, app_err};

use types::{
   TagsRoot,
   TagsRoots,
   SourceKind
};

/// Reads the dependecies from the `Cargo.toml` located in `cargo_toml_dir`
pub fn read_dependencies(cargo_toml_dir: &Path) -> AppResult<TagsRoots>
{
   let mut cargo_toml = cargo_toml_dir.clone();
   cargo_toml.push("Cargo.toml");

   let toml_string = try!(io::File::open(&cargo_toml).read_to_string());
   let mut toml_parser = toml::Parser::new(&*toml_string);

   let toml_table = try!(
      toml_parser.parse()
         .ok_or_else(|| app_err(format!("Couldn't parse '{}': {}", cargo_toml.display(), toml_parser.errors)))
   );

   let mut tags_roots: TagsRoots = Vec::new();
   if ! toml_table.contains_key("dependencies") {
      tags_roots.push(TagsRoot::Src { src_dir: cargo_toml_dir.clone(), dependencies: Vec::new() });
      return Ok(tags_roots);
   }

   let deps_table = try!(
      toml_table.get("dependencies")
         .and_then(toml::Value::as_table)
         .ok_or(app_err(format!("Couldn't get toml::Table entry for 'dependency'!")))
   );

   let mut cargo_lock = cargo_toml_dir.clone();
   cargo_lock.push("Cargo.lock");

   let lock_string = try!(io::File::open(&cargo_lock).read_to_string());
   let mut lock_parser = toml::Parser::new(&*lock_string);

   let lock_table = try!(
      lock_parser.parse()
         .ok_or_else(|| app_err(format!("Couldn't parse '{}': {}", cargo_lock.display(), lock_parser.errors)))
   );

   let packages: Vec<&toml::Table> = try!(
      lock_table.get("package")
         .and_then(toml::Value::as_slice)
         .map(|s| {
            s.iter()
             .filter_map(toml::Value::as_table)
             .collect()
         })
         .ok_or(app_err(format!("Couldn't get Array of Tables entry for 'package'!")))
   );

   for package in packages.iter() {
      let lib_name = try!(
         package.get("name")
            .and_then(toml::Value::as_str)
            .ok_or_else(|| app_err(format!("Couldn't find name string in package: '{}'!", package)))
      );

      let dep_names = try!(get_dependencies(*package));
      let mut dep_src_kinds: Vec<SourceKind> = Vec::new();
      for dep_name in dep_names.iter() {
         let dep_package = try!(find_package(&packages, *dep_name));
         dep_src_kinds.push(try!(get_source_kind(dep_package, *dep_name)));
      }

      let src_kind = try!(get_source_kind(*package, lib_name));
      tags_roots.push(TagsRoot::Lib { src_kind: src_kind, dependencies: dep_src_kinds });
   }

   let mut lib_src_kinds: Vec<SourceKind> = Vec::new();
   for (lib_name, value) in deps_table.iter() {
      match *value {
         toml::Value::String(_) | toml::Value::Table(_) => {
            let lib_package = try!(find_package(&packages, lib_name[]));
            lib_src_kinds.push(try!(get_source_kind(lib_package, lib_name[])));
         }

         _ => {
            return Err(app_err(format!(
               "Expected a String or a Table for the dependency with the name '{}', but got: '{}'", lib_name, value
            )));
         }
      }
   }

   tags_roots.push(TagsRoot::Src { src_dir: cargo_toml_dir.clone(), dependencies: lib_src_kinds });

   Ok(tags_roots)
}

fn get_source_kind(lib_package: &toml::Table, lib_name: &str) -> AppResult<SourceKind>
{
   let source = try!(
      lib_package.get("source")
         .and_then(toml::Value::as_str)
         .ok_or_else(|| app_err(format!("Couldn't find source string in package: '{}'!", lib_package)))
   );

   let src_type = try!(
      source.split('+')
         .nth(0)
         .ok_or_else(|| app_err(format!("Couldn't find source type in: '{}'!", source)))
   );

   let version = try!(
      lib_package.get("version")
         .and_then(toml::Value::as_str)
         .ok_or_else(|| app_err(format!("Couldn't find version string in package: '{}'!", lib_package)))
   );

   match src_type {
      "git" => {
         let commit_hash = try!(
            source.split('#')
               .last()
               .ok_or_else(|| app_err(format!("Couldn't find commit hash in source entry: '{}'!", source)))
         );

         Ok(SourceKind::Git { lib_name: lib_name.to_string(), commit_hash: commit_hash.to_string() })
      },

      "registry" => {
         Ok(SourceKind::CratesIo { lib_name: lib_name.to_string(), version: version.to_string() })
      }

      _ => {
         Err(app_err(format!("Unexpected source type '{}' in package: '{}'!", src_type, lib_package)))
      }
   }
}

fn get_dependencies(lib_package: &toml::Table) -> AppResult<Vec<&str>>
{
   let mut dep_names: Vec<&str> = Vec::new();

   if ! lib_package.contains_key("dependencies") {
      return Ok(dep_names);
   }

   let dep_strs: Vec<&str> = try!(
      lib_package.get("dependencies")
         .and_then(toml::Value::as_slice)
         .map(|s| {
            s.iter()
             .filter_map(toml::Value::as_str)
             .collect()
         })
         .ok_or_else(|| app_err(format!("Couldn't get Array of Strings for 'dependencies' entry: '{}'!", lib_package)))
   );

   for dep_str in dep_strs.iter() {
      let dep_name = try!(
         dep_str.split(' ')
            .nth(0)
            .ok_or_else(|| app_err(format!("Couldn't get name from dependency: '{}'!", dep_str)))
      );

      dep_names.push(dep_name);
   }

   Ok(dep_names)
}

fn find_package<'a>(packages: &'a Vec<&toml::Table>, lib_name: &str) -> AppResult<&'a toml::Table>
{
   let package = try!(
      packages.iter()
         .find(|p| p.get("name").and_then(toml::Value::as_str) == Some(lib_name))
         .ok_or_else(|| app_err(format!("Couldn't find package with name = '{}'!", lib_name)))
   );

   Ok(*package)
}
<|endoftext|>