<commit_before>#![crate_name = "ansi_term"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![feature(macro_rules)]

//! This is a library for controlling colours and formatting, such as
//! red bold text or blue underlined text, on ANSI terminals.
//!
//! ```rust
//! extern crate ansi_term;
//! use ansi_term::Colour::{Black, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
//! use ansi_term::Style::Plain;
//! ```
//!
//! Simple Colours
//! --------------
//!
//! You can format strings by calling the `paint` method on a Colour
//! or a Style object, passing in the string you want to format. For
//! example, to get some red text, call the `paint` method on `Red`:
//!
//! ```rust
//! println!("This is in red: {}!", Red.paint("a red string"));
//! ```
//!
//! The `paint` method returns an `ANSIString` object, which will get
//! automatically converted to the correct sequence of escape codes when
//! used in a `println!` or `format!` macro, or anything else that
//! supports using the `Show` trait. This means that if you just want a
//! string of the escape codes without anything else, you can still use
//! the `to_string` method:
//!
//! ```rust
//! let red_string: String = Red.paint("another red string").to_string();
//! ```
//!
//! Bold, Underline, and Background
//! -------------------------------
//!
//! To do anything more complex than just foreground colours, you need
//! to use Style objects. Calling the `bold` or `underline` method on
//! a Colour returns a Style that has the appropriate property set on
//! it:
//!
//! ```rust
//! println!("Demonstrating {} and {}!",
//!          Blue.bold().paint("blue bold"),
//!          Yellow.underline().paint("yellow underline"));
//! ```
//!
//! These methods chain, so you can call them on existing Style
//! objects to set more than one particular properly, like so:
//!
//! ```rust
//! Blue.underline().bold().paint("Blue underline bold!")
//! ```
//!
//! You can set the background colour of a Style by using the `on`
//! method:
//!
//! ```rust
//! Blue.on(Yellow).paint("Blue on yellow!")
//! ```
//!
//! Finally, you can turn a Colour into a Style with the `normal`
//! method, though it'll produce the exact same string if you just use
//! the Colour. It's only useful if you're writing a method that can
//! return either normal or bold (or underline) styles, and need to
//! return a Style object from it.
//!
//! ```rust
//! Red.normal().paint("yet another red string")
//! ```
//!
//! Extended Colours
//! ----------------
//!
//! You can access the extended range of 256 colours by using the
//! Fixed constructor, which takes an argument of the colour number to
//! use. This can be used wherever you would use a Colour:
//!
//! ```rust
//! Fixed(134).paint("A sort of light purple.")
//! ```
//!
//! This even works for background colours:
//!
//! ```rust
//! Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup.")
//! ```
//!
//! No Formatting
//! -------------
//!
//! Finally, for the sake of completeness, the Plain style provides
//! neither colours nor formatting.
//!
//! ```rust
//! Plain.paint("No colours here.")
//! ```

#![feature(phase)] extern crate regex;
#[phase(plugin)] extern crate regex_macros;
use Colour::{Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed};
use Style::{Plain, Foreground, Styled};
use std::fmt;

/// An ANSI String is a string coupled with the Style to display it
/// in a terminal.
///
/// Although not technically a string itself, it can be turned into
/// one with the `to_string` method.
pub struct ANSIString<'a> {
    string: &'a str,
    style: Style,
}

impl<'a> ANSIString<'a> {
    /// Creates a new ANSI String with the given contents and style.
    pub fn new(contents: &'a str, style: Style) -> ANSIString<'a> {
        ANSIString { string: contents, style: style }
    }
}

impl<'a> fmt::Show for ANSIString<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.style {
            Plain => write!(f, "{}", self.string),
            Foreground(colour) => {
                try!(f.write(b"\x1B["));
                try!(colour.write_foreground_code(f));
                write!(f, "m{}\x1B[0m", self.string)
            },
            Styled { foreground, background, bold, underline } => {
                try!(f.write(b"\x1B["));

                if bold {
                    try!(f.write(b"1;"));
                }

                if underline {
                    try!(f.write(b"4;"));
                }

                match background {
                    Some(c) => {
                        try!(c.write_background_code(f));
                        try!(f.write(b";"));
                    },
                    None => {},
                }

                try!(foreground.write_foreground_code(f));

                write!(f, "m{}\x1B[0m", self.string)
            }
        }
    }
}

/// A colour is one specific type of ANSI escape code, and can refer
/// to either the foreground or background colour.
///
/// These use the standard numeric sequences.
/// See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
pub enum Colour {
    Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed(u8),
}

// I'm not beyond calling Colour Colour, rather than Color, but I did
// purposefully name this crate 'ansi-term' so people wouldn't get
// confused when they tried to install it.
//
// Only *after* they'd installed it.

impl Colour {
    fn write_foreground_code(self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Black  => f.write(b"30"),
            Red    => f.write(b"31"),
            Green  => f.write(b"32"),
            Yellow => f.write(b"33"),
            Blue   => f.write(b"34"),
            Purple => f.write(b"35"),
            Cyan   => f.write(b"36"),
            White  => f.write(b"37"),
            Fixed(num) => write!(f, "38;5;{}", num),
        }
    }

    fn write_background_code(self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Black  => f.write(b"40"),
            Red    => f.write(b"41"),
            Green  => f.write(b"42"),
            Yellow => f.write(b"43"),
            Blue   => f.write(b"44"),
            Purple => f.write(b"45"),
            Cyan   => f.write(b"46"),
            White  => f.write(b"47"),
            Fixed(num) => write!(f, "48;5;{}", num),
        }
    }

    /// Return a Style with the foreground colour set to this colour.
    pub fn normal(self) -> Style {
        Styled { foreground: self, background: None, bold: false, underline: false }
    }

    /// Paints the given text with this colour, returning an ANSI string.
    /// This is a short-cut so you don't have to use Blue.normal() just
    /// to get blue text.
    pub fn paint(self, input: &str) -> ANSIString {
        ANSIString::new(input, Foreground(self))
    }

    /// Returns a Style with the underline property set.
    pub fn underline(self) -> Style {
        Styled { foreground: self, background: None, bold: false, underline: true }
    }

    /// Returns a Style with the bold property set.
    pub fn bold(self) -> Style {
        Styled { foreground: self, background: None, bold: true, underline: false }
    }

    /// Returns a Style with the background colour property set.
    pub fn on(self, background: Colour) -> Style {
        Styled { foreground: self, background: Some(background), bold: false, underline: false }
    }
}

/// A style is a collection of properties that can format a string
/// using ANSI escape codes.
pub enum Style {

    /// The Plain style provides no formatting.
    Plain,

    /// The Foreground style provides just a foreground colour.
    Foreground(Colour),

    /// The Styled style is a catch-all for anything more complicated
    /// than that. It's technically possible for there to be other
    /// cases, such as "bold foreground", but probably isn't worth it.
    Styled { foreground: Colour, background: Option<Colour>, bold: bool, underline: bool, },
}

impl Style {
    /// Paints the given text with this colour, returning an ANSI string.
    pub fn paint(self, input: &str) -> ANSIString {
        ANSIString::new(input, self)
    }

    /// Returns a Style with the bold property set.
    pub fn bold(self) -> Style {
        match self {
            Plain => Styled { foreground: White, background: None, bold: true, underline: false },
            Foreground(c) => Styled { foreground: c, background: None, bold: true, underline: false },
            Styled { foreground, background, bold: _, underline } => Styled { foreground: foreground, background: background, bold: true, underline: underline },
        }
    }

    /// Returns a Style with the underline property set.
    pub fn underline(self) -> Style {
        match self {
            Plain => Styled { foreground: White, background: None, bold: false, underline: true },
            Foreground(c) => Styled { foreground: c, background: None, bold: false, underline: true },
            Styled { foreground, background, bold, underline: _ } => Styled { foreground: foreground, background: background, bold: bold, underline: true },
        }
    }

    /// Returns a Style with the background colour property set.
    pub fn on(self, background: Colour) -> Style {
        match self {
            Plain => Styled { foreground: White,background: Some(background), bold: false, underline: false },
            Foreground(c) => Styled { foreground: c, background: Some(background), bold: false, underline: false },
            Styled { foreground, background: _, bold, underline } => Styled { foreground: foreground, background: Some(background), bold: bold, underline: underline },
        }
    }
}

/// Return a String with all ANSI escape codes removed.
///
/// For example:
///
/// ```rust
/// strip_formatting(Blue.paint("hello!").to_string()) == "hello!"
/// ```
pub fn strip_formatting(input: &str) -> String {
    // What's blue and smells like red paint? Blue paint.
    let re = regex!("\x1B\\[.+?m");
    re.replace_all(input, "").to_string()
}

#[cfg(test)]
mod tests {
    use super::strip_formatting;
    use super::Style::Plain;
    use super::Colour::{Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed};

    macro_rules! test {
        ($name: ident: $style: expr $input: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($style.paint($input).to_string(), $result.to_string())
            }
        };
    }

    test!(plain:                 Plain                             "text/plain" => "text/plain")
    test!(red:                   Red                               "hi" => "\x1B[31mhi\x1B[0m")
    test!(black:                 Black.normal()                    "hi" => "\x1B[30mhi\x1B[0m")
    test!(yellow_bold:           Yellow.bold()                     "hi" => "\x1B[1;33mhi\x1B[0m")
    test!(yellow_bold_2:         Yellow.normal().bold()            "hi" => "\x1B[1;33mhi\x1B[0m")
    test!(blue_underline:        Blue.underline()                  "hi" => "\x1B[4;34mhi\x1B[0m")
    test!(green_bold_ul:         Green.bold().underline()          "hi" => "\x1B[1;4;32mhi\x1B[0m")
    test!(green_bold_ul_2:       Green.underline().bold()          "hi" => "\x1B[1;4;32mhi\x1B[0m")
    test!(purple_on_white:       Purple.on(White)                  "hi" => "\x1B[47;35mhi\x1B[0m")
    test!(purple_on_white_2:     Purple.normal().on(White)         "hi" => "\x1B[47;35mhi\x1B[0m")
    test!(cyan_bold_on_white:    Cyan.bold().on(White)             "hi" => "\x1B[1;47;36mhi\x1B[0m")
    test!(cyan_ul_on_white:      Cyan.underline().on(White)        "hi" => "\x1B[4;47;36mhi\x1B[0m")
    test!(cyan_bold_ul_on_white: Cyan.bold().underline().on(White) "hi" => "\x1B[1;4;47;36mhi\x1B[0m")
    test!(cyan_ul_bold_on_white: Cyan.underline().bold().on(White) "hi" => "\x1B[1;4;47;36mhi\x1B[0m")
    test!(fixed:                 Fixed(100)                        "hi" => "\x1B[38;5;100mhi\x1B[0m")
    test!(fixed_on_purple:       Fixed(100).on(Purple)             "hi" => "\x1B[45;38;5;100mhi\x1B[0m")
    test!(fixed_on_fixed:        Fixed(100).on(Fixed(200))         "hi" => "\x1B[48;5;200;38;5;100mhi\x1B[0m")

    #[test]
    fn test_strip_formatting() {
        let hi = strip_formatting(Blue.paint("hi").to_string().as_slice());
        assert!(hi == "hi".to_string());
    }

    #[test]
    fn test_strip_formatting_2() {
        let hi = strip_formatting(Blue.on(Fixed(230)).bold().paint("hi").to_string().as_slice());
        assert!(hi == "hi".to_string());
    }
}
<commit_msg>Make everything Copyable to appease latest Rust<commit_after>#![crate_name = "ansi_term"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![feature(macro_rules)]

//! This is a library for controlling colours and formatting, such as
//! red bold text or blue underlined text, on ANSI terminals.
//!
//! ```rust
//! extern crate ansi_term;
//! use ansi_term::Colour::{Black, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
//! use ansi_term::Style::Plain;
//! ```
//!
//! Simple Colours
//! --------------
//!
//! You can format strings by calling the `paint` method on a Colour
//! or a Style object, passing in the string you want to format. For
//! example, to get some red text, call the `paint` method on `Red`:
//!
//! ```rust
//! println!("This is in red: {}!", Red.paint("a red string"));
//! ```
//!
//! The `paint` method returns an `ANSIString` object, which will get
//! automatically converted to the correct sequence of escape codes when
//! used in a `println!` or `format!` macro, or anything else that
//! supports using the `Show` trait. This means that if you just want a
//! string of the escape codes without anything else, you can still use
//! the `to_string` method:
//!
//! ```rust
//! let red_string: String = Red.paint("another red string").to_string();
//! ```
//!
//! Bold, Underline, and Background
//! -------------------------------
//!
//! To do anything more complex than just foreground colours, you need
//! to use Style objects. Calling the `bold` or `underline` method on
//! a Colour returns a Style that has the appropriate property set on
//! it:
//!
//! ```rust
//! println!("Demonstrating {} and {}!",
//!          Blue.bold().paint("blue bold"),
//!          Yellow.underline().paint("yellow underline"));
//! ```
//!
//! These methods chain, so you can call them on existing Style
//! objects to set more than one particular properly, like so:
//!
//! ```rust
//! Blue.underline().bold().paint("Blue underline bold!")
//! ```
//!
//! You can set the background colour of a Style by using the `on`
//! method:
//!
//! ```rust
//! Blue.on(Yellow).paint("Blue on yellow!")
//! ```
//!
//! Finally, you can turn a Colour into a Style with the `normal`
//! method, though it'll produce the exact same string if you just use
//! the Colour. It's only useful if you're writing a method that can
//! return either normal or bold (or underline) styles, and need to
//! return a Style object from it.
//!
//! ```rust
//! Red.normal().paint("yet another red string")
//! ```
//!
//! Extended Colours
//! ----------------
//!
//! You can access the extended range of 256 colours by using the
//! Fixed constructor, which takes an argument of the colour number to
//! use. This can be used wherever you would use a Colour:
//!
//! ```rust
//! Fixed(134).paint("A sort of light purple.")
//! ```
//!
//! This even works for background colours:
//!
//! ```rust
//! Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup.")
//! ```
//!
//! No Formatting
//! -------------
//!
//! Finally, for the sake of completeness, the Plain style provides
//! neither colours nor formatting.
//!
//! ```rust
//! Plain.paint("No colours here.")
//! ```

#![feature(phase)] extern crate regex;
#[phase(plugin)] extern crate regex_macros;
use Colour::{Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed};
use Style::{Plain, Foreground, Styled};
use std::fmt;

/// An ANSI String is a string coupled with the Style to display it
/// in a terminal.
///
/// Although not technically a string itself, it can be turned into
/// one with the `to_string` method.
pub struct ANSIString<'a> {
    string: &'a str,
    style: Style,
}

impl<'a> Copy for ANSIString<'a> { }

impl<'a> ANSIString<'a> {
    /// Creates a new ANSI String with the given contents and style.
    pub fn new(contents: &'a str, style: Style) -> ANSIString<'a> {
        ANSIString { string: contents, style: style }
    }
}

impl<'a> fmt::Show for ANSIString<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.style {
            Plain => write!(f, "{}", self.string),
            Foreground(colour) => {
                try!(f.write(b"\x1B["));
                try!(colour.write_foreground_code(f));
                write!(f, "m{}\x1B[0m", self.string)
            },
            Styled { foreground, background, bold, underline } => {
                try!(f.write(b"\x1B["));

                if bold {
                    try!(f.write(b"1;"));
                }

                if underline {
                    try!(f.write(b"4;"));
                }

                match background {
                    Some(c) => {
                        try!(c.write_background_code(f));
                        try!(f.write(b";"));
                    },
                    None => {},
                }

                try!(foreground.write_foreground_code(f));

                write!(f, "m{}\x1B[0m", self.string)
            }
        }
    }
}

/// A colour is one specific type of ANSI escape code, and can refer
/// to either the foreground or background colour.
///
/// These use the standard numeric sequences.
/// See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
pub enum Colour {
    Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed(u8),
}

impl Copy for Colour { }

// I'm not beyond calling Colour Colour, rather than Color, but I did
// purposefully name this crate 'ansi-term' so people wouldn't get
// confused when they tried to install it.
//
// Only *after* they'd installed it.

impl Colour {
    fn write_foreground_code(self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Black  => f.write(b"30"),
            Red    => f.write(b"31"),
            Green  => f.write(b"32"),
            Yellow => f.write(b"33"),
            Blue   => f.write(b"34"),
            Purple => f.write(b"35"),
            Cyan   => f.write(b"36"),
            White  => f.write(b"37"),
            Fixed(num) => write!(f, "38;5;{}", num),
        }
    }

    fn write_background_code(self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Black  => f.write(b"40"),
            Red    => f.write(b"41"),
            Green  => f.write(b"42"),
            Yellow => f.write(b"43"),
            Blue   => f.write(b"44"),
            Purple => f.write(b"45"),
            Cyan   => f.write(b"46"),
            White  => f.write(b"47"),
            Fixed(num) => write!(f, "48;5;{}", num),
        }
    }

    /// Return a Style with the foreground colour set to this colour.
    pub fn normal(self) -> Style {
        Styled { foreground: self, background: None, bold: false, underline: false }
    }

    /// Paints the given text with this colour, returning an ANSI string.
    /// This is a short-cut so you don't have to use Blue.normal() just
    /// to get blue text.
    pub fn paint(self, input: &str) -> ANSIString {
        ANSIString::new(input, Foreground(self))
    }

    /// Returns a Style with the underline property set.
    pub fn underline(self) -> Style {
        Styled { foreground: self, background: None, bold: false, underline: true }
    }

    /// Returns a Style with the bold property set.
    pub fn bold(self) -> Style {
        Styled { foreground: self, background: None, bold: true, underline: false }
    }

    /// Returns a Style with the background colour property set.
    pub fn on(self, background: Colour) -> Style {
        Styled { foreground: self, background: Some(background), bold: false, underline: false }
    }
}

/// A style is a collection of properties that can format a string
/// using ANSI escape codes.
pub enum Style {

    /// The Plain style provides no formatting.
    Plain,

    /// The Foreground style provides just a foreground colour.
    Foreground(Colour),

    /// The Styled style is a catch-all for anything more complicated
    /// than that. It's technically possible for there to be other
    /// cases, such as "bold foreground", but probably isn't worth it.
    Styled { foreground: Colour, background: Option<Colour>, bold: bool, underline: bool, },
}

impl Copy for Style { }

impl Style {
    /// Paints the given text with this colour, returning an ANSI string.
    pub fn paint(self, input: &str) -> ANSIString {
        ANSIString::new(input, self)
    }

    /// Returns a Style with the bold property set.
    pub fn bold(self) -> Style {
        match self {
            Plain => Styled { foreground: White, background: None, bold: true, underline: false },
            Foreground(c) => Styled { foreground: c, background: None, bold: true, underline: false },
            Styled { foreground, background, bold: _, underline } => Styled { foreground: foreground, background: background, bold: true, underline: underline },
        }
    }

    /// Returns a Style with the underline property set.
    pub fn underline(self) -> Style {
        match self {
            Plain => Styled { foreground: White, background: None, bold: false, underline: true },
            Foreground(c) => Styled { foreground: c, background: None, bold: false, underline: true },
            Styled { foreground, background, bold, underline: _ } => Styled { foreground: foreground, background: background, bold: bold, underline: true },
        }
    }

    /// Returns a Style with the background colour property set.
    pub fn on(self, background: Colour) -> Style {
        match self {
            Plain => Styled { foreground: White,background: Some(background), bold: false, underline: false },
            Foreground(c) => Styled { foreground: c, background: Some(background), bold: false, underline: false },
            Styled { foreground, background: _, bold, underline } => Styled { foreground: foreground, background: Some(background), bold: bold, underline: underline },
        }
    }
}

/// Return a String with all ANSI escape codes removed.
///
/// For example:
///
/// ```rust
/// strip_formatting(Blue.paint("hello!").to_string()) == "hello!"
/// ```
pub fn strip_formatting(input: &str) -> String {
    // What's blue and smells like red paint? Blue paint.
    let re = regex!("\x1B\\[.+?m");
    re.replace_all(input, "").to_string()
}

#[cfg(test)]
mod tests {
    use super::strip_formatting;
    use super::Style::Plain;
    use super::Colour::{Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed};

    macro_rules! test {
        ($name: ident: $style: expr $input: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($style.paint($input).to_string(), $result.to_string())
            }
        };
    }

    test!(plain:                 Plain                             "text/plain" => "text/plain")
    test!(red:                   Red                               "hi" => "\x1B[31mhi\x1B[0m")
    test!(black:                 Black.normal()                    "hi" => "\x1B[30mhi\x1B[0m")
    test!(yellow_bold:           Yellow.bold()                     "hi" => "\x1B[1;33mhi\x1B[0m")
    test!(yellow_bold_2:         Yellow.normal().bold()            "hi" => "\x1B[1;33mhi\x1B[0m")
    test!(blue_underline:        Blue.underline()                  "hi" => "\x1B[4;34mhi\x1B[0m")
    test!(green_bold_ul:         Green.bold().underline()          "hi" => "\x1B[1;4;32mhi\x1B[0m")
    test!(green_bold_ul_2:       Green.underline().bold()          "hi" => "\x1B[1;4;32mhi\x1B[0m")
    test!(purple_on_white:       Purple.on(White)                  "hi" => "\x1B[47;35mhi\x1B[0m")
    test!(purple_on_white_2:     Purple.normal().on(White)         "hi" => "\x1B[47;35mhi\x1B[0m")
    test!(cyan_bold_on_white:    Cyan.bold().on(White)             "hi" => "\x1B[1;47;36mhi\x1B[0m")
    test!(cyan_ul_on_white:      Cyan.underline().on(White)        "hi" => "\x1B[4;47;36mhi\x1B[0m")
    test!(cyan_bold_ul_on_white: Cyan.bold().underline().on(White) "hi" => "\x1B[1;4;47;36mhi\x1B[0m")
    test!(cyan_ul_bold_on_white: Cyan.underline().bold().on(White) "hi" => "\x1B[1;4;47;36mhi\x1B[0m")
    test!(fixed:                 Fixed(100)                        "hi" => "\x1B[38;5;100mhi\x1B[0m")
    test!(fixed_on_purple:       Fixed(100).on(Purple)             "hi" => "\x1B[45;38;5;100mhi\x1B[0m")
    test!(fixed_on_fixed:        Fixed(100).on(Fixed(200))         "hi" => "\x1B[48;5;200;38;5;100mhi\x1B[0m")

    #[test]
    fn test_strip_formatting() {
        let hi = strip_formatting(Blue.paint("hi").to_string().as_slice());
        assert!(hi == "hi".to_string());
    }

    #[test]
    fn test_strip_formatting_2() {
        let hi = strip_formatting(Blue.on(Fixed(230)).bold().paint("hi").to_string().as_slice());
        assert!(hi == "hi".to_string());
    }
}
<|endoftext|>


<commit_before>//! Encoding and decoding of the (15, 11, 3) standard and (10, 6, 3) shortened Hamming
//! codes described by P25.
//!
//! Both codes can correct up to 1 error. These algorithms are sourced from *Coding Theory
//! and Cryptography: The Essentials*, Hankerson, Hoffman, et al, 2000.

use binfield_matrix::{matrix_mul, matrix_mul_systematic};
use num::PrimInt;

/// Encoding and decoding of the (15, 11, 3) code.
pub mod standard {
    use super::*;

    /// Encode the given 11 bits of data into a 15-bit codeword.
    pub fn encode(data: u16) -> u16 {
        assert!(data >> 11 == 0);
        matrix_mul_systematic(data, GEN)
    }

    /// Try to decode the given 15-bit word to the nearest codeword, correcting up to 1
    /// error.
    ///
    /// If decoding was successful, return `Some((data, err))`, where `data` is the 11
    /// data bits and `err` is the number of corrected bits. Otherwise, return `None` to
    /// indicate an unrecoverable error.
    pub fn decode(word: u16) -> Option<(u16, usize)> {
        assert!(word >> 15 == 0);
        super::decode(word, PAR, LOCATIONS).map(|(w, n)| (w >> 4, n))
    }

    /// Generator matrix from the standard, without identity part.
    const GEN: &[u16] = &[
        0b11111110000,
        0b11110001110,
        0b11001101101,
        0b10101011011,
    ];

    /// Parity-check matrix derived from generator using standard method.
    const PAR: &[u16] = &[
        0b111111100001000,
        0b111100011100100,
        0b110011011010010,
        0b101010110110001,
    ];

    /// Maps 4-bit syndrome values to bit error locations.
    const LOCATIONS: &[u16] = &[
        0,
        0b0000000000000001,
        0b0000000000000010,
        0b0000000000010000,
        0b0000000000000100,
        0b0000000000100000,
        0b0000000001000000,
        0b0000000010000000,
        0b0000000000001000,
        0b0000000100000000,
        0b0000001000000000,
        0b0000010000000000,
        0b0000100000000000,
        0b0001000000000000,
        0b0010000000000000,
        0b0100000000000000,
    ];
}

/// Encoding and decoding of the (10, 6, 3) code.
pub mod shortened {
    use super::*;

    /// Encode the given 6 data bits into a 10-bit codeword.
    pub fn encode(data: u8) -> u16 {
        assert!(data >> 6 == 0);
        matrix_mul_systematic(data, GEN)
    }

    /// Try to decode the given 10-bit word to the nearest codeword, correcting up to 1
    /// error.
    ///
    /// If decoding was successful, return `Some((data, err))`, where `data` is the 6
    /// data bits and `err` is the number of corrected bits. Otherwise, return `None` to
    /// indicate an unrecoverable error.
    pub fn decode(word: u16) -> Option<(u8, usize)> {
        assert!(word >> 10 == 0);
        super::decode(word, PAR, LOCATIONS).map(|(w, n)| ((w >> 4) as u8, n))
    }

    const GEN: &[u8] = &[
        0b111001,
        0b110101,
        0b101110,
        0b011110,
    ];

    const PAR: &[u16] = &[
        0b1110011000,
        0b1101010100,
        0b1011100010,
        0b0111100001,
    ];

    const LOCATIONS: &[u16] = &[
        0,
        0b0000000000000001,
        0b0000000000000010,
        0b0000000000100000,
        0b0000000000000100,
        0,
        0,
        0b0000000001000000,
        0b0000000000001000,
        0,
        0,
        0b0000000010000000,
        0b0000000000010000,
        0b0000000100000000,
        0b0000001000000000,
        0,
    ];
}

fn decode<T: PrimInt>(word: T, par: &[T], locs: &[T]) -> Option<(T, usize)> {
    let s: usize = matrix_mul(word, par);

    if s == 0 {
        return Some((word, 0));
    }

    locs.get(s).and_then(|&loc| if loc == T::zero() {
        None
    } else {
        Some((word ^ loc, 1))
    })
}

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

    #[test]
    fn test_standard() {
        let w = 0b10101010101;
        let e = standard::encode(w);
        assert_eq!(standard::decode(e^0b000000000000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000000000001).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000000000010).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000000000100).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000000001000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000000010000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000000100000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000001000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000010000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000000100000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000001000000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000010000000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b000100000000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b001000000000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b010000000000000).unwrap().0, w);
        assert_eq!(standard::decode(e^0b100000000000000).unwrap().0, w);

        for i in 0..1<<11 {
            assert_eq!(standard::decode(standard::encode(i)).unwrap().0, i);
        }
    }

    #[test]
    fn test_shortened() {
        let w = 0b110011;
        let e = shortened::encode(w);
        assert_eq!(shortened::decode(e ^ 0b0000000000).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0000000001).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0000000010).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0000000100).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0000001000).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0000010000).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0000100000).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0001000000).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0010000000).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b0100000000).unwrap().0, w);
        assert_eq!(shortened::decode(e ^ 0b1000000000).unwrap().0, w);

        for i in 0..1<<6 {
            assert_eq!(shortened::decode(shortened::encode(i)).unwrap().0, i);
        }
    }
}
<commit_msg>Add more exhaustive hamming tests<commit_after>//! Encoding and decoding of the (15, 11, 3) standard and (10, 6, 3) shortened Hamming
//! codes described by P25.
//!
//! Both codes can correct up to 1 error. These algorithms are sourced from *Coding Theory
//! and Cryptography: The Essentials*, Hankerson, Hoffman, et al, 2000.

use binfield_matrix::{matrix_mul, matrix_mul_systematic};
use num::PrimInt;

/// Encoding and decoding of the (15, 11, 3) code.
pub mod standard {
    use super::*;

    /// Encode the given 11 bits of data into a 15-bit codeword.
    pub fn encode(data: u16) -> u16 {
        assert!(data >> 11 == 0);
        matrix_mul_systematic(data, GEN)
    }

    /// Try to decode the given 15-bit word to the nearest codeword, correcting up to 1
    /// error.
    ///
    /// If decoding was successful, return `Some((data, err))`, where `data` is the 11
    /// data bits and `err` is the number of corrected bits. Otherwise, return `None` to
    /// indicate an unrecoverable error.
    pub fn decode(word: u16) -> Option<(u16, usize)> {
        assert!(word >> 15 == 0);
        super::decode(word, PAR, LOCATIONS).map(|(w, n)| (w >> 4, n))
    }

    /// Generator matrix from the standard, without identity part.
    const GEN: &[u16] = &[
        0b11111110000,
        0b11110001110,
        0b11001101101,
        0b10101011011,
    ];

    /// Parity-check matrix derived from generator using standard method.
    const PAR: &[u16] = &[
        0b111111100001000,
        0b111100011100100,
        0b110011011010010,
        0b101010110110001,
    ];

    /// Maps 4-bit syndrome values to bit error locations.
    const LOCATIONS: &[u16] = &[
        0,
        0b0000000000000001,
        0b0000000000000010,
        0b0000000000010000,
        0b0000000000000100,
        0b0000000000100000,
        0b0000000001000000,
        0b0000000010000000,
        0b0000000000001000,
        0b0000000100000000,
        0b0000001000000000,
        0b0000010000000000,
        0b0000100000000000,
        0b0001000000000000,
        0b0010000000000000,
        0b0100000000000000,
    ];
}

/// Encoding and decoding of the (10, 6, 3) code.
pub mod shortened {
    use super::*;

    /// Encode the given 6 data bits into a 10-bit codeword.
    pub fn encode(data: u8) -> u16 {
        assert!(data >> 6 == 0);
        matrix_mul_systematic(data, GEN)
    }

    /// Try to decode the given 10-bit word to the nearest codeword, correcting up to 1
    /// error.
    ///
    /// If decoding was successful, return `Some((data, err))`, where `data` is the 6
    /// data bits and `err` is the number of corrected bits. Otherwise, return `None` to
    /// indicate an unrecoverable error.
    pub fn decode(word: u16) -> Option<(u8, usize)> {
        assert!(word >> 10 == 0);
        super::decode(word, PAR, LOCATIONS).map(|(w, n)| ((w >> 4) as u8, n))
    }

    const GEN: &[u8] = &[
        0b111001,
        0b110101,
        0b101110,
        0b011110,
    ];

    const PAR: &[u16] = &[
        0b1110011000,
        0b1101010100,
        0b1011100010,
        0b0111100001,
    ];

    const LOCATIONS: &[u16] = &[
        0,
        0b0000000000000001,
        0b0000000000000010,
        0b0000000000100000,
        0b0000000000000100,
        0,
        0,
        0b0000000001000000,
        0b0000000000001000,
        0,
        0,
        0b0000000010000000,
        0b0000000000010000,
        0b0000000100000000,
        0b0000001000000000,
        0,
    ];
}

fn decode<T: PrimInt>(word: T, par: &[T], locs: &[T]) -> Option<(T, usize)> {
    let s: usize = matrix_mul(word, par);

    if s == 0 {
        return Some((word, 0));
    }

    locs.get(s).and_then(|&loc| if loc == T::zero() {
        None
    } else {
        Some((word ^ loc, 1))
    })
}

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

    #[test]
    fn test_standard() {
        assert_eq!(standard::encode(0), 0);
        assert_eq!(standard::encode(0b11111111111), 0b11111111111_1111);

        for w in 0..1<<11 {
            assert_eq!(standard::decode(standard::encode(w)), Some((w, 0)));
        }

        let w = standard::encode(0b10101010101);
        assert_eq!(w, 0b10101010101_0101);
        assert_eq!(standard::decode(w), Some((0b10101010101, 0)));

        for i in 0..15 {
            assert_eq!(standard::decode(w ^ 1 << i), Some((0b10101010101, 1)));
        }

        for (i, j) in (0..15).zip(0..15) {
            if i != j {
                // Two-bit errors are detected as one-bit errors with an incorrect bit
                // correction, so just check for the detection.
                let (_, n) = standard::decode(w ^ (1 << i) ^ (1 << j)).unwrap();
                assert_eq!(n, 1);
            }
        }
    }

    #[test]
    fn test_shortened() {
        assert_eq!(shortened::encode(0), 0);
        assert_eq!(shortened::encode(0b111111), 0b111111_0000);

        for w in 0..1<<6 {
            assert_eq!(shortened::decode(shortened::encode(w)), Some((w, 0)));
        }

        let w = shortened::encode(0b101010);
        assert_eq!(w, 0b101010_0110);
        assert_eq!(shortened::decode(w), Some((0b101010, 0)));

        for i in 0..10 {
            assert_eq!(shortened::decode(w ^ 1 << i), Some((0b101010, 1)));
        }

        for (i, j) in (0..10).zip(0..10) {
            if i != j {
                // Two-bit errors are detected as one-bit errors with an incorrect bit
                // correction, so just check for the detection.
                let (_, n) = shortened::decode(w ^ (1 << i) ^ (1 << j)).unwrap();
                assert_eq!(n, 1);
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::fs;
use std::path::{Path, PathBuf};
use std::env;
use std::process;
use std::process::{Command, Stdio};

use clap::ArgMatches;
use kuchiki::traits::*;
use hyper::{Client, Url};
use hyper::client::Response;
use hyper::Result as HyperResult;
use util;

pub fn versions() {
    let groonga_versioned_dir = util::obtain_groonga_versioned_path();
    let paths = fs::read_dir(&Path::new(&groonga_versioned_dir)).unwrap();

    let names = paths.filter_map(|entry| {
            entry.ok().and_then(|e| {
                e.path()
                    .file_name()
                    .and_then(|n| n.to_str().map(|s| String::from(s)))
            })
        })
        .collect::<Vec<String>>();

    println!("Installed Groonga:");
    println!("\tsystem");
    for entry in names {
        let e = entry.split("-").collect::<Vec<_>>();
        println!("\t{} ({})", e.get(1).unwrap_or(&""), e.get(2).unwrap_or(&"build from source"));
    }
}

pub struct MaybeProxyUrl {
    pub url: Url,
}

impl<'a> IntoResponse for MaybeProxyUrl {
    fn into_response(self) -> HyperResult<Response> {
        extern crate env_proxy;
        let maybe_proxy = env_proxy::for_url(&self.url);

        let client = match maybe_proxy {
            None => Client::new(),
            Some(host_port) => Client::with_http_proxy(host_port.0, host_port.1),
        };
        client.get(self.url).send()
    }
}

pub fn execute_external_command(cmd: &str, ext_m: &ArgMatches) {
    let command_exe = format!("grnenv-{}{}", cmd, env::consts::EXE_SUFFIX);
    let ext_args: Vec<&str> = match ext_m.values_of("") {
        Some(c) => c.collect(),
        None => vec![],
    };
    let path = search_directories()
        .iter()
        .map(|dir| dir.join(&command_exe))
        .find(|file| is_executable(file));
    let command = match path {
        Some(command) => command,
        None => {
            println!("no such subcommand: `{}`", cmd);
            process::exit(1);
        }
    };
    let err = match Command::new(command)
        .args(&ext_args.as_slice()[0..])
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .spawn() {
        Ok(_) => return (),
        Err(e) => e,
    };

    println!("Failed to execute external subcommand. reason: {:?}", err);
    process::exit(1);
}

fn search_directories() -> Vec<PathBuf> {
    let home = env::home_dir().unwrap();
    let mut dirs = vec![home.join("bin")];
    if let Some(val) = env::var_os("PATH") {
        dirs.extend(env::split_paths(&val));
    }
    dirs
}

#[cfg(unix)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
    use std::os::unix::prelude::*;
    fs::metadata(path)
        .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
        .unwrap_or(false)
}
#[cfg(windows)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
    fs::metadata(path).map(|metadata| metadata.is_file()).unwrap_or(false)
}
<commit_msg>rustfmt<commit_after>use std::fs;
use std::path::{Path, PathBuf};
use std::env;
use std::process;
use std::process::{Command, Stdio};

use clap::ArgMatches;
use kuchiki::traits::*;
use hyper::{Client, Url};
use hyper::client::Response;
use hyper::Result as HyperResult;
use util;

pub fn versions() {
    let groonga_versioned_dir = util::obtain_groonga_versioned_path();
    let paths = fs::read_dir(&Path::new(&groonga_versioned_dir)).unwrap();

    let names = paths.filter_map(|entry| {
            entry.ok().and_then(|e| {
                e.path()
                    .file_name()
                    .and_then(|n| n.to_str().map(|s| String::from(s)))
            })
        })
        .collect::<Vec<String>>();

    println!("Installed Groonga:");
    println!("\tsystem");
    for entry in names {
        let e = entry.split("-").collect::<Vec<_>>();
        println!("\t{} ({})",
                 e.get(1).unwrap_or(&""),
                 e.get(2).unwrap_or(&"build from source"));
    }
}

pub struct MaybeProxyUrl {
    pub url: Url,
}

impl<'a> IntoResponse for MaybeProxyUrl {
    fn into_response(self) -> HyperResult<Response> {
        extern crate env_proxy;
        let maybe_proxy = env_proxy::for_url(&self.url);

        let client = match maybe_proxy {
            None => Client::new(),
            Some(host_port) => Client::with_http_proxy(host_port.0, host_port.1),
        };
        client.get(self.url).send()
    }
}

pub fn execute_external_command(cmd: &str, ext_m: &ArgMatches) {
    let command_exe = format!("grnenv-{}{}", cmd, env::consts::EXE_SUFFIX);
    let ext_args: Vec<&str> = match ext_m.values_of("") {
        Some(c) => c.collect(),
        None => vec![],
    };
    let path = search_directories()
        .iter()
        .map(|dir| dir.join(&command_exe))
        .find(|file| is_executable(file));
    let command = match path {
        Some(command) => command,
        None => {
            println!("no such subcommand: `{}`", cmd);
            process::exit(1);
        }
    };
    let err = match Command::new(command)
        .args(&ext_args.as_slice()[0..])
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .spawn() {
        Ok(_) => return (),
        Err(e) => e,
    };

    println!("Failed to execute external subcommand. reason: {:?}", err);
    process::exit(1);
}

fn search_directories() -> Vec<PathBuf> {
    let home = env::home_dir().unwrap();
    let mut dirs = vec![home.join("bin")];
    if let Some(val) = env::var_os("PATH") {
        dirs.extend(env::split_paths(&val));
    }
    dirs
}

#[cfg(unix)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
    use std::os::unix::prelude::*;
    fs::metadata(path)
        .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
        .unwrap_or(false)
}
#[cfg(windows)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
    fs::metadata(path).map(|metadata| metadata.is_file()).unwrap_or(false)
}
<|endoftext|>


<commit_before>extern crate mime = "mime-types";
extern crate conduit;

use std::fmt::Show;
use std::collections::HashMap;
use std::io::fs::File;
use std::io::util::NullReader;
use conduit::{Request, Response, Handler};

pub struct Static {
    path: Path,
    types: mime::Types
}

impl Static {
    pub fn new(path: Path) -> Static {
        Static {
            path: path,
            types: mime::Types::new()
                .ok().expect("Couldn't load mime-types")
        }
    }
}

impl Handler for Static {
    fn call(&self, request: &mut Request) -> Result<Response, Box<Show>> {
        let request_path = request.path().slice_from(1);
        let path = self.path.join(request_path);

        if !self.path.is_ancestor_of(&path) {
            return Ok(Response {
                status: (404, "Not Found"),
                headers: HashMap::new(),
                body: box NullReader
            })
        }

        let mime = self.types.mime_for_path(&path);
        let file = try!(File::open(&path).map_err(|e| box e as Box<Show>));

        let mut headers = HashMap::new();
        headers.insert("Content-Type".to_str(), vec!(mime.to_str()));

        Ok(Response {
            status: (200, "OK"),
            headers: headers,
            body: box file as Box<Reader + Send>
        })
    }
}

#[cfg(test)]
mod tests {
    extern crate test = "conduit-test";
    use conduit;
    use conduit::Handler;
    use Static;

    #[test]
    fn test_static() {
        let root = Path::new(file!()).dir_path().dir_path();
        let handler = Static::new(root);
        let mut req = test::MockRequest::new(conduit::Get, "/Cargo.toml");
        let mut res = handler.call(&mut req).ok().expect("No response");
        let body = res.body.read_to_str().ok().expect("No body");
        assert!(body.as_slice().contains("[package]"), "The Cargo.toml was provided");
        assert_eq!(res.headers.find_equiv(&"Content-Type").expect("No content-type"), &vec!("text/plain".to_str()));
    }

    #[test]
    fn test_mime_types() {
        let root = Path::new(file!()).dir_path().dir_path();
        let handler = Static::new(root);
        let mut req = test::MockRequest::new(conduit::Get, "/src/fixture.css");
        let res = handler.call(&mut req).ok().expect("No response");
        assert_eq!(res.headers.find_equiv(&"Content-Type").expect("No content-type"), &vec!("text/css".to_str()));
    }
}
<commit_msg>Have tests run independently of project structure<commit_after>extern crate mime = "mime-types";
extern crate conduit;

use std::fmt::Show;
use std::collections::HashMap;
use std::io::fs::File;
use std::io::util::NullReader;
use conduit::{Request, Response, Handler};

pub struct Static {
    path: Path,
    types: mime::Types
}

impl Static {
    pub fn new(path: Path) -> Static {
        Static {
            path: path,
            types: mime::Types::new()
                .ok().expect("Couldn't load mime-types")
        }
    }
}

impl Handler for Static {
    fn call(&self, request: &mut Request) -> Result<Response, Box<Show>> {
        let request_path = request.path().slice_from(1);
        let path = self.path.join(request_path);

        if !self.path.is_ancestor_of(&path) {
            return Ok(Response {
                status: (404, "Not Found"),
                headers: HashMap::new(),
                body: box NullReader
            })
        }

        let mime = self.types.mime_for_path(&path);
        let file = try!(File::open(&path).map_err(|e| box e as Box<Show>));

        let mut headers = HashMap::new();
        headers.insert("Content-Type".to_str(), vec!(mime.to_str()));

        Ok(Response {
            status: (200, "OK"),
            headers: headers,
            body: box file as Box<Reader + Send>
        })
    }
}

#[cfg(test)]
mod tests {
    extern crate test = "conduit-test";

    use std::io::{fs, File, TempDir, UserRWX};

    use conduit;
    use conduit::Handler;
    use Static;

    #[test]
    fn test_static() {
        let td = TempDir::new("conduit-static").unwrap();
        let root = td.path();
        let handler = Static::new(root.clone());
        File::create(&root.join("Cargo.toml")).write(b"[package]").unwrap();
        let mut req = test::MockRequest::new(conduit::Get, "/Cargo.toml");
        let mut res = handler.call(&mut req).ok().expect("No response");
        let body = res.body.read_to_str().ok().expect("No body");
        assert_eq!(body.as_slice(), "[package]");
        assert_eq!(res.headers.find_equiv(&"Content-Type")
                      .expect("No content-type"),
                   &vec!("text/plain".to_str()));
    }

    #[test]
    fn test_mime_types() {
        let td = TempDir::new("conduit-static").unwrap();
        let root = td.path();
        fs::mkdir(&root.join("src"), UserRWX).unwrap();
        File::create(&root.join("src/fixture.css")).unwrap();

        let handler = Static::new(root.clone());
        let mut req = test::MockRequest::new(conduit::Get, "/src/fixture.css");
        let res = handler.call(&mut req).ok().expect("No response");
        assert_eq!(res.headers.find_equiv(&"Content-Type")
                      .expect("No content-type"),
                   &vec!("text/css".to_str()));
    }
}
<|endoftext|>


<commit_before>#![macro_use]
use super::super::Core;
use cpu::{CFLAG_SET, ZFLAG_SET, XFLAG_SET, NFLAG_SET, ZFLAG_CLEAR, VFLAG_CLEAR, CFLAG_CLEAR, XFLAG_CLEAR, NFLAG_CLEAR};
use std::num::Wrapping;

macro_rules! ir_dx {
	($e:ident) => (($e.ir >> 9 & 7) as usize);
}
macro_rules! ir_dy {
	($e:ident) => (($e.ir & 7) as usize);
}
macro_rules! ir_ax {
	($e:ident) => (8+($e.ir >> 9 & 7) as usize);
}
macro_rules! ir_ay {
	($e:ident) => (8+($e.ir & 7) as usize);
}
macro_rules! dx {
	($e:ident) => ($e.dar[ir_dx!($e)]);
}
macro_rules! dy {
	($e:ident) => ($e.dar[ir_dy!($e)]);
}
macro_rules! ax {
	($e:ident) => ($e.dar[ir_ax!($e)]);
}
macro_rules! ay {
	($e:ident) => ($e.dar[ir_ay!($e)]);
}
macro_rules! mask_out_above_8 {
	($e:expr) => ($e & 0xff)
}
macro_rules! mask_out_below_8 {
	($e:expr) => ($e & !0xff)
}
macro_rules! mask_out_above_16 {
	($e:expr) => ($e & 0xffff)
}
macro_rules! mask_out_below_16 {
	($e:expr) => ($e & !0xffff)
}
macro_rules! mask_out_above_32 {
	($e:expr) => ($e & 0xffffffff)
}
macro_rules! low_nibble {
	($e:expr) => ($e & 0x0f);
}
macro_rules! high_nibble {
	($e:expr) => ($e & 0xf0);
}
macro_rules! true1 {
	($e:expr) => (if $e {1} else {0})
}
macro_rules! not1 {
	($e:expr) => (true1!($e == 0))
}

// All instructions are ported from https://github.com/kstenerud/Musashi
pub fn abcd_8(core: &mut Core, dst: u32, src: u32) -> u32 {
	// unsigned int res = ((src) & 0x0f) + ((dst) & 0x0f) + ((m68ki_cpu.x_flag>>8)&1);
	let mut res = low_nibble!(src) + low_nibble!(dst) + core.x_flag_as_1();

	// m68ki_cpu.v_flag = ~res;
	core.v_flag = !res;

	// if(res > 9)
	//  res += 6;
	if res > 9 {
		res += 6;
	}
	// res += ((src) & 0xf0) + ((dst) & 0xf0);
	res += high_nibble!(src) + high_nibble!(dst);
	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = (res > 0x99) << 8;
	core.c_flag = true1!(res > 0x99) << 8;
	core.x_flag = core.c_flag;

	if core.c_flag > 0 {
		res = (Wrapping(res) - Wrapping(0xa0)).0;
	}

	// m68ki_cpu.v_flag &= res;
	// m68ki_cpu.n_flag = (res);
	core.v_flag &= res;
	core.n_flag = res;

	// res = ((res) & 0xff);
	// m68ki_cpu.not_z_flag |= res;
	res = mask_out_above_8!(res);
	core.not_z_flag |= res;
	res
}

pub fn add_8(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_8!(dst);
	let src = mask_out_above_8!(src);

	let res = dst + src;
	// m68ki_cpu.n_flag = (res);
	core.n_flag = res;
	// m68ki_cpu.v_flag = ((src^res) & (dst^res));
	core.v_flag = (src ^ res) & (dst ^ res);
	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = (res);
	core.c_flag = res;
	core.x_flag = res;
	// m68ki_cpu.not_z_flag = ((res) & 0xff);
	let res8 = mask_out_above_8!(res);
	core.not_z_flag = res8;
	res8
}
pub fn add_16(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_16!(dst);
	let src = mask_out_above_16!(src);
	let res = dst + src;

	// m68ki_cpu.n_flag = ((res)>>8);
	let res_hi = res >> 8;
	core.n_flag = res_hi;
	// m68ki_cpu.v_flag = (((src^res) & (dst^res))>>8);
	core.v_flag = ((src ^ res) & (dst ^ res)) >> 8;
	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = ((res)>>8);
	core.c_flag = res_hi;
	core.x_flag = res_hi;
	// m68ki_cpu.not_z_flag = ((res) & 0xffff);
	let res16 = mask_out_above_16!(res);
	core.not_z_flag = res16;

	res16
}
pub fn add_32(core: &mut Core, dst: u32, src: u32) -> u32 {
	let res: u64 = (dst as u64) + (src as u64);

	let res_hi = (res >> 24) as u32;
	core.n_flag = res_hi;
	// m68ki_cpu.v_flag = (((src^res) & (dst^res))>>24);
	core.v_flag = (((src as u64 ^ res) & (dst as u64 ^ res)) >> 24) as u32;
 	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = (((src & dst) | (~res & (src | dst)))>>23);
	core.c_flag = res_hi;
	core.x_flag = res_hi;

	let res32 = res as u32;

	core.not_z_flag = res32;

	res32
}

pub fn addx_8(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_8!(dst);
	let src = mask_out_above_8!(src);

	let res = dst + src + core.x_flag_as_1();

	core.n_flag = res;
	core.v_flag = (src ^ res) & (dst ^ res);
	core.c_flag = res;
	core.x_flag = res;

	let res8 = mask_out_above_8!(res);
	core.not_z_flag |= res8;
	res8
}
pub fn addx_16(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_16!(dst);
	let src = mask_out_above_16!(src);
	let res = dst + src + core.x_flag_as_1();

	let res_hi = res >> 8;
	core.n_flag = res_hi;
	core.v_flag = ((src ^ res) & (dst ^ res)) >> 8;
	core.c_flag = res_hi;
	core.x_flag = res_hi;

	let res16 = mask_out_above_16!(res);
	core.not_z_flag |= res16;
	res16
}
pub fn addx_32(core: &mut Core, dst: u32, src: u32) -> u32 {
	let res: u64 = (dst as u64) + (src as u64) + core.x_flag_as_1() as u64;

	let res_hi = (res >> 24) as u32;
	core.n_flag = res_hi;
	core.v_flag = (((src as u64 ^ res) & (dst as u64 ^ res)) >> 24) as u32;
	core.c_flag = res_hi;
	core.x_flag = res_hi;

	let res32 = res as u32;
	core.not_z_flag |= res32;
	res32
}

pub fn and_8(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_8!(dst);
	let src = mask_out_above_8!(src);
	let res = dst & src;

	core.not_z_flag = res;
	core.n_flag = res;
	core.c_flag = 0;
	core.v_flag = 0;

	res
}
pub fn and_16(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_16!(dst);
	let src = mask_out_above_16!(src);
	let res = dst & src;

	let res_hi = res >> 8;
	core.not_z_flag = res;
	core.n_flag = res_hi;
	core.c_flag = 0;
	core.v_flag = 0;

	res
}
pub fn and_32(core: &mut Core, dst: u32, src: u32) -> u32 {
	let res = dst & src;

	let res_hi = res >> 24;
	core.not_z_flag = res;
	core.n_flag = res_hi;
	core.c_flag = 0;
	core.v_flag = 0;

	res
}

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

	#[test]
	fn low_nibble() {
		assert_eq!(0x0a, low_nibble!(0xba));
	}
	#[test]
	fn high_nibble() {
		assert_eq!(0xb0, high_nibble!(0xba));
	}
	#[test]
	fn mask_out_below_8() {
		assert_eq!(0x2bcdef00, mask_out_below_8!(0x2bcdef73));
	}
	#[test]
	fn mask_out_above_8() {
		assert_eq!(0xf1, mask_out_above_8!(0x2bcdeff1));
	}
	#[test]
	fn dx_and_dy() {
		let mut core = Core::new(0x40);
		core.dar[0] = 0x00;
		core.dar[1] = 0x11;
		core.dar[2] = 0x22;
		core.dar[3] = 0x33;
		core.dar[4] = 0x44;
		core.dar[5] = 0x55;
		core.dar[6] = 0x66;
		core.dar[7] = 0x77;

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		assert_eq!(0x22, dy!(core));
		assert_eq!(0x44, dx!(core));

		core.ir = 0b1111_1011_1111_1110; // X=5, Y=6
		assert_eq!(0x66, dy!(core));
		assert_eq!(0x55, dx!(core));
	}
}
<commit_msg>Rename macros for bool to 1, add for MSB 8/16/32<commit_after>#![macro_use]
use super::super::Core;
use cpu::{CFLAG_SET, ZFLAG_SET, XFLAG_SET, NFLAG_SET, ZFLAG_CLEAR, VFLAG_CLEAR, CFLAG_CLEAR, XFLAG_CLEAR, NFLAG_CLEAR};
use std::num::Wrapping;

macro_rules! ir_dx {
	($e:ident) => (($e.ir >> 9 & 7) as usize);
}
macro_rules! ir_dy {
	($e:ident) => (($e.ir & 7) as usize);
}
macro_rules! ir_ax {
	($e:ident) => (8+($e.ir >> 9 & 7) as usize);
}
macro_rules! ir_ay {
	($e:ident) => (8+($e.ir & 7) as usize);
}
macro_rules! dx {
	($e:ident) => ($e.dar[ir_dx!($e)]);
}
macro_rules! dy {
	($e:ident) => ($e.dar[ir_dy!($e)]);
}
macro_rules! ax {
	($e:ident) => ($e.dar[ir_ax!($e)]);
}
macro_rules! ay {
	($e:ident) => ($e.dar[ir_ay!($e)]);
}
macro_rules! mask_out_above_8 {
	($e:expr) => ($e & 0xff)
}
macro_rules! mask_out_below_8 {
	($e:expr) => ($e & !0xff)
}
macro_rules! mask_out_above_16 {
	($e:expr) => ($e & 0xffff)
}
macro_rules! mask_out_below_16 {
	($e:expr) => ($e & !0xffff)
}
macro_rules! mask_out_above_32 {
	($e:expr) => ($e & 0xffffffff)
}
macro_rules! low_nibble {
	($e:expr) => ($e & 0x0f);
}
macro_rules! high_nibble {
	($e:expr) => ($e & 0xf0);
}
macro_rules! true_is_1 {
	($e:expr) => (if $e {1} else {0})
}
macro_rules! false_is_1 {
	($e:expr) => (if $e {0} else {1})
}
macro_rules! not1 {
	($e:expr) => (true_is_1!($e == 0))
}
macro_rules! msb_8_set {
	($e:expr) => (($e & 0x80) > 0)
}
macro_rules! msb_16_set {
	($e:expr) => (($e & 0x8000) > 0)
}
macro_rules! msb_32_set {
	($e:expr) => (($e & 0x80000000) > 0)
}
// All instructions are ported from https://github.com/kstenerud/Musashi
pub fn abcd_8(core: &mut Core, dst: u32, src: u32) -> u32 {
	// unsigned int res = ((src) & 0x0f) + ((dst) & 0x0f) + ((m68ki_cpu.x_flag>>8)&1);
	let mut res = low_nibble!(src) + low_nibble!(dst) + core.x_flag_as_1();

	// m68ki_cpu.v_flag = ~res;
	core.v_flag = !res;

	// if(res > 9)
	//  res += 6;
	if res > 9 {
		res += 6;
	}
	// res += ((src) & 0xf0) + ((dst) & 0xf0);
	res += high_nibble!(src) + high_nibble!(dst);
	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = (res > 0x99) << 8;
	core.c_flag = true_is_1!(res > 0x99) << 8;
	core.x_flag = core.c_flag;

	if core.c_flag > 0 {
		res = (Wrapping(res) - Wrapping(0xa0)).0;
	}

	// m68ki_cpu.v_flag &= res;
	// m68ki_cpu.n_flag = (res);
	core.v_flag &= res;
	core.n_flag = res;

	// res = ((res) & 0xff);
	// m68ki_cpu.not_z_flag |= res;
	res = mask_out_above_8!(res);
	core.not_z_flag |= res;
	res
}

pub fn add_8(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_8!(dst);
	let src = mask_out_above_8!(src);

	let res = dst + src;
	// m68ki_cpu.n_flag = (res);
	core.n_flag = res;
	// m68ki_cpu.v_flag = ((src^res) & (dst^res));
	core.v_flag = (src ^ res) & (dst ^ res);
	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = (res);
	core.c_flag = res;
	core.x_flag = res;
	// m68ki_cpu.not_z_flag = ((res) & 0xff);
	let res8 = mask_out_above_8!(res);
	core.not_z_flag = res8;
	res8
}
pub fn add_16(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_16!(dst);
	let src = mask_out_above_16!(src);
	let res = dst + src;

	// m68ki_cpu.n_flag = ((res)>>8);
	let res_hi = res >> 8;
	core.n_flag = res_hi;
	// m68ki_cpu.v_flag = (((src^res) & (dst^res))>>8);
	core.v_flag = ((src ^ res) & (dst ^ res)) >> 8;
	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = ((res)>>8);
	core.c_flag = res_hi;
	core.x_flag = res_hi;
	// m68ki_cpu.not_z_flag = ((res) & 0xffff);
	let res16 = mask_out_above_16!(res);
	core.not_z_flag = res16;

	res16
}
pub fn add_32(core: &mut Core, dst: u32, src: u32) -> u32 {
	let res: u64 = (dst as u64) + (src as u64);

	let res_hi = (res >> 24) as u32;
	core.n_flag = res_hi;
	// m68ki_cpu.v_flag = (((src^res) & (dst^res))>>24);
	core.v_flag = (((src as u64 ^ res) & (dst as u64 ^ res)) >> 24) as u32;
 	// m68ki_cpu.x_flag = m68ki_cpu.c_flag = (((src & dst) | (~res & (src | dst)))>>23);
	core.c_flag = res_hi;
	core.x_flag = res_hi;

	let res32 = res as u32;

	core.not_z_flag = res32;

	res32
}

pub fn addx_8(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_8!(dst);
	let src = mask_out_above_8!(src);

	let res = dst + src + core.x_flag_as_1();

	core.n_flag = res;
	core.v_flag = (src ^ res) & (dst ^ res);
	core.c_flag = res;
	core.x_flag = res;

	let res8 = mask_out_above_8!(res);
	core.not_z_flag |= res8;
	res8
}
pub fn addx_16(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_16!(dst);
	let src = mask_out_above_16!(src);
	let res = dst + src + core.x_flag_as_1();

	let res_hi = res >> 8;
	core.n_flag = res_hi;
	core.v_flag = ((src ^ res) & (dst ^ res)) >> 8;
	core.c_flag = res_hi;
	core.x_flag = res_hi;

	let res16 = mask_out_above_16!(res);
	core.not_z_flag |= res16;
	res16
}
pub fn addx_32(core: &mut Core, dst: u32, src: u32) -> u32 {
	let res: u64 = (dst as u64) + (src as u64) + core.x_flag_as_1() as u64;

	let res_hi = (res >> 24) as u32;
	core.n_flag = res_hi;
	core.v_flag = (((src as u64 ^ res) & (dst as u64 ^ res)) >> 24) as u32;
	core.c_flag = res_hi;
	core.x_flag = res_hi;

	let res32 = res as u32;
	core.not_z_flag |= res32;
	res32
}

pub fn and_8(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_8!(dst);
	let src = mask_out_above_8!(src);
	let res = dst & src;

	core.not_z_flag = res;
	core.n_flag = res;
	core.c_flag = 0;
	core.v_flag = 0;

	res
}
pub fn and_16(core: &mut Core, dst: u32, src: u32) -> u32 {
	let dst = mask_out_above_16!(dst);
	let src = mask_out_above_16!(src);
	let res = dst & src;

	let res_hi = res >> 8;
	core.not_z_flag = res;
	core.n_flag = res_hi;
	core.c_flag = 0;
	core.v_flag = 0;

	res
}
pub fn and_32(core: &mut Core, dst: u32, src: u32) -> u32 {
	let res = dst & src;

	let res_hi = res >> 24;
	core.not_z_flag = res;
	core.n_flag = res_hi;
	core.c_flag = 0;
	core.v_flag = 0;

	res
}

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

	#[test]
	fn low_nibble() {
		assert_eq!(0x0a, low_nibble!(0xba));
	}
	#[test]
	fn high_nibble() {
		assert_eq!(0xb0, high_nibble!(0xba));
	}
	#[test]
	fn mask_out_below_8() {
		assert_eq!(0x2bcdef00, mask_out_below_8!(0x2bcdef73));
	}
	#[test]
	fn mask_out_above_8() {
		assert_eq!(0xf1, mask_out_above_8!(0x2bcdeff1));
	}
	#[test]
	fn dx_and_dy() {
		let mut core = Core::new(0x40);
		core.dar[0] = 0x00;
		core.dar[1] = 0x11;
		core.dar[2] = 0x22;
		core.dar[3] = 0x33;
		core.dar[4] = 0x44;
		core.dar[5] = 0x55;
		core.dar[6] = 0x66;
		core.dar[7] = 0x77;

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		assert_eq!(0x22, dy!(core));
		assert_eq!(0x44, dx!(core));

		core.ir = 0b1111_1011_1111_1110; // X=5, Y=6
		assert_eq!(0x66, dy!(core));
		assert_eq!(0x55, dx!(core));
	}
}
<|endoftext|>


<commit_before>use decoders::*;
use decoders::cfa::*;
use imageops;

#[derive(Debug, Clone)]
pub struct RawImage {
  pub make: String,
  pub model: String,
  pub clean_make: String,
  pub clean_model: String,
  pub width: usize,
  pub height: usize,
  pub cpp: usize,
  pub wb_coeffs: [f32;4],
  pub data: Vec<u16>,
  pub whitelevels: [u16;4],
  pub blacklevels: [u16;4],
  pub xyz_to_cam: [[f32;3];4],
  pub cfa: CFA,
  pub crops: [usize;4],
}

#[derive(Debug, Clone)]
pub struct RGBImage {
  pub width: usize,
  pub height: usize,
  pub data: Vec<f32>,
}

impl RawImage {
  pub fn new(camera: &Camera, width: usize, height: usize, wb_coeffs: [f32;4], image: Vec<u16>) -> RawImage {
    let blacks = if camera.blackareah.1 != 0 || camera.blackareav.1 != 0 {
      let mut avg = [0 as f32; 4];
      let mut count = [0 as f32; 4];
      for row in camera.blackareah.0 .. camera.blackareah.0+camera.blackareah.1 {
        for col in 0..width {
          let color = camera.cfa.color_at(row,col);
          avg[color] += image[row*width+col] as f32;
          count[color] += 1.0;
        }
      }
      for row in 0..height {
        for col in camera.blackareav.0 .. camera.blackareav.0+camera.blackareav.1 {
          let color = camera.cfa.color_at(row,col);
          avg[color] += image[row*width+col] as f32;
          count[color] += 1.0;
        }
      }
      [(avg[0]/count[0]) as u16,
       (avg[1]/count[1]) as u16,
       (avg[2]/count[2]) as u16,
       (avg[3]/count[3]) as u16]
    } else {
      camera.blacklevels
    };

    RawImage {
      make: camera.make.clone(),
      model: camera.model.clone(),
      clean_make: camera.clean_make.clone(),
      clean_model: camera.clean_model.clone(),
      width: width,
      height: height,
      cpp: 1,
      wb_coeffs: wb_coeffs,
      data: image,
      blacklevels: blacks,
      whitelevels: camera.whitelevels,
      xyz_to_cam: camera.xyz_to_cam,
      cfa: camera.cfa.clone(),
      crops: camera.crops,
    }
  }

  pub fn cam_to_xyz(&self) -> [[f32;4];3] {
    let (cam_to_xyz, _) = self.xyz_matrix_and_neutralwb();
    cam_to_xyz
  }

  pub fn neutralwb(&self) -> [f32;4] {
    let (_, neutralwb) = self.xyz_matrix_and_neutralwb();
    [neutralwb[0]/neutralwb[1],
     neutralwb[1]/neutralwb[1],
     neutralwb[2]/neutralwb[1],
     neutralwb[3]/neutralwb[1]]
  }

  fn xyz_matrix_and_neutralwb(&self) -> ([[f32;4];3],[f32;4]) {
    let d65_white = [0.9547,1.0,1.08883];
    let rgb_to_xyz = [
    // sRGB D65
      [ 0.412453, 0.357580, 0.180423 ],
      [ 0.212671, 0.715160, 0.072169 ],
      [ 0.019334, 0.119193, 0.950227 ],
    ];

    // Multiply RGB matrix
    let mut rgb_to_cam = [[0.0;3];4];
    for i in 0..4 {
      for j in 0..3 {
        rgb_to_cam[i][j] = 0.0;
        for k in 0..3 {
          rgb_to_cam[i][j] += self.xyz_to_cam[i][k] * rgb_to_xyz[k][j];
        }
      }
    }

    let mut neutralwb = [0 as f32; 4];
    // Normalize rgb_to_cam so that rgb_to_cam * (1,1,1) is (1,1,1,1)
    for i in 0..4 {
      let mut num = 0.0;
      for j in 0..3 {
        num += rgb_to_cam[i][j];
      }
      for j in 0..3 {
        rgb_to_cam[i][j] = if num == 0.0 {
          0.0
        }  else {
          rgb_to_cam[i][j] / num
        };
      }
      neutralwb[i] = 1.0 / num;
    }

    let cam_to_rgb = self.pseudoinverse(rgb_to_cam);
    let mut cam_to_xyz = [[0.0;4];3];
    // Multiply RGB matrix and adjust white to get a cam_to_xyz
    for i in 0..3 {
      for j in 0..4 {
        cam_to_xyz[i][j] = 0.0;
        for k in 0..3 {
          cam_to_xyz[i][j] += cam_to_rgb[k][j] * rgb_to_xyz[i][k] / d65_white[i];
        }
      }
    }

    (cam_to_xyz, neutralwb)
  }

  fn pseudoinverse(&self, inm: [[f32;3];4]) -> [[f32;4];3] {
    let mut temp: [[f32;6];3] = [[0.0; 6];3];

    for i in 0..3 {
      for j in 0..6 {
        temp[i][j] = if j == i+3 { 1.0 } else { 0.0 };
      }
      for j in 0..3 {
        for k in 0..4 {
          temp[i][j] += inm[k][i] * inm[k][j];
        }
      }
    }

    for i in 0..3 {
      let mut num = temp[i][i];
      for j in 0..6 {
        temp[i][j] /= num;
      }
      for k in 0..3 {
        if k == i { continue }
        num = temp[k][i];
        for j in 0..6 {
          temp[k][j] -= temp[i][j] * num;
        }
      }
    }

    let mut out: [[f32;4];3] = [[0.0; 4];3];

    for i in 0..4 {
      for j in 0..3 {
        out[j][i] = 0.0;
        for k in 0..3 {
          out[j][i] += temp[j][k+3] * inm[i][k];
        }
      }
    }

    out
  }

  pub fn to_rgb(&self, maxwidth: usize, maxheight: usize) -> Result<RGBImage,String> {
    let buffer = imageops::simple_decode(self, maxwidth, maxheight);

    Ok(RGBImage{
      width: buffer.width,
      height: buffer.height,
      data: buffer.data,
    })
  }
}
<commit_msg>image: add basic documentation<commit_after>use decoders::*;
use decoders::cfa::*;
use imageops;

/// All the data needed to process this raw image, including the image data itself as well
/// as all the needed metadata
#[derive(Debug, Clone)]
pub struct RawImage {
  /// camera make as encoded in the file
  pub make: String,
  /// camera model as encoded in the file
  pub model: String,
  /// make cleaned up to be consistent and short
  pub clean_make: String,
  /// model cleaned up to be consistent and short
  pub clean_model: String,
  /// width of the full image
  pub width: usize,
  /// height of the full image
  pub height: usize,
  /// number of components per pixel (1 for bayer, 3 for RGB images)
  pub cpp: usize,
  /// whitebalance coefficients encoded in the file in RGBE order
  pub wb_coeffs: [f32;4],
  /// image whitelevels in RGBE order
  pub whitelevels: [u16;4],
  /// image blacklevels in RGBE order
  pub blacklevels: [u16;4],
  /// matrix to convert XYZ to camera RGBE
  pub xyz_to_cam: [[f32;3];4],
  /// color filter array
  pub cfa: CFA,
  /// how much to crop the image to get all the usable area, order is top, right, bottom, left
  pub crops: [usize;4],
  /// image data itself, has width*height*cpp elements
  pub data: Vec<u16>,
}

/// A RawImage processed into a full RGB image with levels and gamma
///
/// The data is a Vec<f32> width width*height*3 elements, where each element is a value
/// between 0 and 1 with the intensity of the color channel
#[derive(Debug, Clone)]
pub struct RGBImage {
  pub width: usize,
  pub height: usize,
  pub data: Vec<f32>,
}

impl RawImage {
  pub fn new(camera: &Camera, width: usize, height: usize, wb_coeffs: [f32;4], image: Vec<u16>) -> RawImage {
    let blacks = if camera.blackareah.1 != 0 || camera.blackareav.1 != 0 {
      let mut avg = [0 as f32; 4];
      let mut count = [0 as f32; 4];
      for row in camera.blackareah.0 .. camera.blackareah.0+camera.blackareah.1 {
        for col in 0..width {
          let color = camera.cfa.color_at(row,col);
          avg[color] += image[row*width+col] as f32;
          count[color] += 1.0;
        }
      }
      for row in 0..height {
        for col in camera.blackareav.0 .. camera.blackareav.0+camera.blackareav.1 {
          let color = camera.cfa.color_at(row,col);
          avg[color] += image[row*width+col] as f32;
          count[color] += 1.0;
        }
      }
      [(avg[0]/count[0]) as u16,
       (avg[1]/count[1]) as u16,
       (avg[2]/count[2]) as u16,
       (avg[3]/count[3]) as u16]
    } else {
      camera.blacklevels
    };

    RawImage {
      make: camera.make.clone(),
      model: camera.model.clone(),
      clean_make: camera.clean_make.clone(),
      clean_model: camera.clean_model.clone(),
      width: width,
      height: height,
      cpp: 1,
      wb_coeffs: wb_coeffs,
      data: image,
      blacklevels: blacks,
      whitelevels: camera.whitelevels,
      xyz_to_cam: camera.xyz_to_cam,
      cfa: camera.cfa.clone(),
      crops: camera.crops,
    }
  }

  pub fn cam_to_xyz(&self) -> [[f32;4];3] {
    let (cam_to_xyz, _) = self.xyz_matrix_and_neutralwb();
    cam_to_xyz
  }

  pub fn neutralwb(&self) -> [f32;4] {
    let (_, neutralwb) = self.xyz_matrix_and_neutralwb();
    [neutralwb[0]/neutralwb[1],
     neutralwb[1]/neutralwb[1],
     neutralwb[2]/neutralwb[1],
     neutralwb[3]/neutralwb[1]]
  }

  fn xyz_matrix_and_neutralwb(&self) -> ([[f32;4];3],[f32;4]) {
    let d65_white = [0.9547,1.0,1.08883];
    let rgb_to_xyz = [
    // sRGB D65
      [ 0.412453, 0.357580, 0.180423 ],
      [ 0.212671, 0.715160, 0.072169 ],
      [ 0.019334, 0.119193, 0.950227 ],
    ];

    // Multiply RGB matrix
    let mut rgb_to_cam = [[0.0;3];4];
    for i in 0..4 {
      for j in 0..3 {
        rgb_to_cam[i][j] = 0.0;
        for k in 0..3 {
          rgb_to_cam[i][j] += self.xyz_to_cam[i][k] * rgb_to_xyz[k][j];
        }
      }
    }

    let mut neutralwb = [0 as f32; 4];
    // Normalize rgb_to_cam so that rgb_to_cam * (1,1,1) is (1,1,1,1)
    for i in 0..4 {
      let mut num = 0.0;
      for j in 0..3 {
        num += rgb_to_cam[i][j];
      }
      for j in 0..3 {
        rgb_to_cam[i][j] = if num == 0.0 {
          0.0
        }  else {
          rgb_to_cam[i][j] / num
        };
      }
      neutralwb[i] = 1.0 / num;
    }

    let cam_to_rgb = self.pseudoinverse(rgb_to_cam);
    let mut cam_to_xyz = [[0.0;4];3];
    // Multiply RGB matrix and adjust white to get a cam_to_xyz
    for i in 0..3 {
      for j in 0..4 {
        cam_to_xyz[i][j] = 0.0;
        for k in 0..3 {
          cam_to_xyz[i][j] += cam_to_rgb[k][j] * rgb_to_xyz[i][k] / d65_white[i];
        }
      }
    }

    (cam_to_xyz, neutralwb)
  }

  fn pseudoinverse(&self, inm: [[f32;3];4]) -> [[f32;4];3] {
    let mut temp: [[f32;6];3] = [[0.0; 6];3];

    for i in 0..3 {
      for j in 0..6 {
        temp[i][j] = if j == i+3 { 1.0 } else { 0.0 };
      }
      for j in 0..3 {
        for k in 0..4 {
          temp[i][j] += inm[k][i] * inm[k][j];
        }
      }
    }

    for i in 0..3 {
      let mut num = temp[i][i];
      for j in 0..6 {
        temp[i][j] /= num;
      }
      for k in 0..3 {
        if k == i { continue }
        num = temp[k][i];
        for j in 0..6 {
          temp[k][j] -= temp[i][j] * num;
        }
      }
    }

    let mut out: [[f32;4];3] = [[0.0; 4];3];

    for i in 0..4 {
      for j in 0..3 {
        out[j][i] = 0.0;
        for k in 0..3 {
          out[j][i] += temp[j][k+3] * inm[i][k];
        }
      }
    }

    out
  }

  pub fn to_rgb(&self, maxwidth: usize, maxheight: usize) -> Result<RGBImage,String> {
    let buffer = imageops::simple_decode(self, maxwidth, maxheight);

    Ok(RGBImage{
      width: buffer.width,
      height: buffer.height,
      data: buffer.data,
    })
  }
}
<|endoftext|>


<commit_before>use std::io::Read;
use hilbert_curve::BytewiseCached;
use typedrw::TypedMemoryMap;

pub trait EdgeMapper {
    fn map_edges<F: FnMut(u32, u32) -> ()>(&self, action: F) -> ();
}

pub struct DeltaCompressedReaderMapper<R: Read, F: Fn()->R> {
    reader: F,
}

impl<R: Read, F: Fn()->R> DeltaCompressedReaderMapper<R, F> {
    pub fn new(reader: F) -> DeltaCompressedReaderMapper<R, F> {
        DeltaCompressedReaderMapper {
            reader: reader,
        }
    }
}

impl<R: Read, F: Fn()->R> EdgeMapper for DeltaCompressedReaderMapper<R, F> {
    fn map_edges<A: FnMut(u32, u32) -> ()>(&self, mut action: A) -> () {

        let mut hilbert = BytewiseCached::new();
        let mut current = 0u64;
        let mut reader = (self.reader)();

        let mut delta = 0u64;    // for accumulating a delta
        let mut depth = 0u8;     // for counting number of zeros

        let mut buffer = vec![0u8; 1 << 16];
        while let Ok(read) = reader.read(&mut buffer[..]) {
            for &byte in &buffer[..read] {
                if byte == 0 && delta == 0 {
                    depth += 1;
                }
                else {
                    delta = (delta << 8) + (byte as u64);
                    if depth == 0 {
                        current += delta;
                        delta = 0;
                        let (x,y) = hilbert.detangle(current);
                        action(x,y);
                    }
                    else {
                        depth -= 1;
                    }
                }
            }
        }
    }
}

// // naughty method using unsafe transmute to read a filled binary buffer as a typed buffer
// fn read_as_typed<'a, R: Read, T: Copy>(reader: &mut R, buffer: &'a mut[u8]) -> Result<&'a[T]> {
//     if mem::size_of::<T>() * (buffer.len() / mem::size_of::<T>()) < buffer.len() {
//         panic!("buffer size must be a multiple of mem::size_of::<T>() = {:?}", mem::size_of::<T>());
//     }
//
//     let mut read = try!(reader.read(buffer));
//     while mem::size_of::<T>() * (read / mem::size_of::<T>()) < read {
//         read += try!(reader.read(&mut buffer[read..]));
//     }
//
//     Ok(unsafe { mem::transmute(RawSlice {
//         data: buffer.as_mut_ptr() as *const T,
//         len:  read / mem::size_of::<T>(),
//     }) })
// }

// pub struct UpperLowerMapper<R1: Read, R2: Read, F1: Fn()->R1, F2: Fn()->R2> {
//     pub upper: F1,
//     pub lower: F2,
// }
//
// impl<R1: Read, R2: Read, F1: Fn()->R1, F2: Fn()->R2> EdgeMapper for UpperLowerMapper<R1, R2, F1, F2> {
//     fn map_edges<F: FnMut(u32, u32) -> ()>(&self, mut action: F) -> () {
//         let mut upper_reader = (self.upper)();
//         let mut lower_reader = (self.lower)();
//         let mut upper_buffer = vec![0u8; 1 << 20];
//         let mut lower_buffer = vec![0u8; 1 << 20];
//         while let Ok(upper) = read_as_typed::<_,((u16,u16),u32)>(&mut upper_reader, &mut upper_buffer[..]) {
//             for &((ux, uy), mut count) in upper {
//                 let ux = (ux as u32) << 16;
//                 let uy = (uy as u32) << 16;
//                 while count > 0 {
//                     let size = min(lower_buffer.len(), 4 * count as usize);
//                     if let Ok(lower) = read_as_typed::<_,(u16,u16)>(&mut lower_reader, &mut lower_buffer[..size]) {
//                         for &(lx, ly) in lower {
//                             action(ux + lx as u32, uy + ly as u32);
//                         }
//                         count -= lower.len() as u32;
//                     }
//                 }
//             }
//         }
//     }
// }

// pub struct NodesEdgesMapper<R1: Read, R2: Read, F1: Fn()->R1, F2: Fn()->R2> {
//     pub nodes: F1,
//     pub edges: F2,
// }
//
// impl<R1: Read, R2: Read, F1: Fn()->R1, F2: Fn()->R2> EdgeMapper for NodesEdgesMapper<R1, R2, F1, F2> {
//     fn map_edges<F: FnMut(u32, u32) -> ()>(&self, mut action: F) -> () {
//         let mut nodes_reader = (self.nodes)();
//         let mut edges_reader = (self.edges)();
//         let mut nodes_buffer = vec![0u8; 1 << 20];
//         let mut edges_buffer = vec![0u8; 1 << 20];
//         while let Ok(nodes) = read_as_typed::<_,(u32,u32)>(&mut nodes_reader, &mut nodes_buffer[..]) {
//             for &(source, mut count) in nodes {
//                 while count > 0 {
//                     let size = min(edges_buffer.len(), 4 * count as usize);
//                     if let Ok(edges) = read_as_typed::<_,u32>(&mut edges_reader, &mut edges_buffer[..size]) {
//                         for &target in edges {
//                             action(source, target);
//                         }
//                         count -= edges.len() as u32;
//                     }
//                 }
//             }
//         }
//     }
// }

pub struct UpperLowerMemMapper {
    upper:  TypedMemoryMap<((u16,u16), u32)>,
    lower:  TypedMemoryMap<(u16, u16)>,
}

impl UpperLowerMemMapper {
    pub fn new(graph_name: &str) -> UpperLowerMemMapper {
        UpperLowerMemMapper {
            upper: TypedMemoryMap::new(format!("{}.upper", graph_name)),
            lower: TypedMemoryMap::new(format!("{}.lower", graph_name)),
        }
    }
}

impl EdgeMapper for UpperLowerMemMapper {
    fn map_edges<F: FnMut(u32, u32) -> ()>(&self, mut action: F) -> () {
        let mut slice = &self.lower[..];
        for &((u16_x, u16_y), count) in &self.upper[..] {
            let u16_x = (u16_x as u32) << 16;
            let u16_y = (u16_y as u32) << 16;
            for &(l16_x, l16_y) in &slice[.. count as usize] {
                action(u16_x | l16_x as u32, u16_y | l16_y as u32);
            }

            slice = &slice[count as usize ..];
        }
    }
}

pub struct NodesEdgesMemMapper {
    nodes:  TypedMemoryMap<(u32, u32)>,
    edges:  TypedMemoryMap<u32>,
}

impl NodesEdgesMemMapper {
    pub fn new(graph_name: &str) -> NodesEdgesMemMapper {
        NodesEdgesMemMapper {
            nodes: TypedMemoryMap::new(format!("{}.nodes", graph_name)),
            edges: TypedMemoryMap::new(format!("{}.edges", graph_name)),
        }
    }
}

impl EdgeMapper for NodesEdgesMemMapper {
    fn map_edges<F: FnMut(u32, u32) -> ()>(&self, mut action: F) -> () {
        let mut slice = &self.edges[..];
        for &(node, count) in &self.nodes[..] {
            for &edge in &slice[.. count as usize] {
                action(node, edge);
            }

            slice = &slice[count as usize ..];
        }
    }
}
<commit_msg>Fix infinite loop in DeltaCompressedReaderMapper.<commit_after>use std::io::Read;
use hilbert_curve::BytewiseCached;
use typedrw::TypedMemoryMap;

pub trait EdgeMapper {
    fn map_edges<F: FnMut(u32, u32) -> ()>(&self, action: F) -> ();
}

pub struct DeltaCompressedReaderMapper<R: Read, F: Fn()->R> {
    reader: F,
}

impl<R: Read, F: Fn()->R> DeltaCompressedReaderMapper<R, F> {
    pub fn new(reader: F) -> DeltaCompressedReaderMapper<R, F> {
        DeltaCompressedReaderMapper {
            reader: reader,
        }
    }
}

impl<R: Read, F: Fn()->R> EdgeMapper for DeltaCompressedReaderMapper<R, F> {
    fn map_edges<A: FnMut(u32, u32) -> ()>(&self, mut action: A) -> () {

        let mut hilbert = BytewiseCached::new();
        let mut current = 0u64;
        let mut reader = (self.reader)();

        let mut delta = 0u64;    // for accumulating a delta
        let mut depth = 0u8;     // for counting number of zeros

        let mut buffer = vec![0u8; 1 << 16];
        while let Ok(read) = reader.read(&mut buffer[..]) {
            if read == 0 {
                // Reached EOF.
                break;
            }
            for &byte in &buffer[..read] {
                if byte == 0 && delta == 0 {
                    depth += 1;
                }
                else {
                    delta = (delta << 8) + (byte as u64);
                    if depth == 0 {
                        current += delta;
                        delta = 0;
                        let (x,y) = hilbert.detangle(current);
                        action(x,y);
                    }
                    else {
                        depth -= 1;
                    }
                }
            }
        }
    }
}

// // naughty method using unsafe transmute to read a filled binary buffer as a typed buffer
// fn read_as_typed<'a, R: Read, T: Copy>(reader: &mut R, buffer: &'a mut[u8]) -> Result<&'a[T]> {
//     if mem::size_of::<T>() * (buffer.len() / mem::size_of::<T>()) < buffer.len() {
//         panic!("buffer size must be a multiple of mem::size_of::<T>() = {:?}", mem::size_of::<T>());
//     }
//
//     let mut read = try!(reader.read(buffer));
//     while mem::size_of::<T>() * (read / mem::size_of::<T>()) < read {
//         read += try!(reader.read(&mut buffer[read..]));
//     }
//
//     Ok(unsafe { mem::transmute(RawSlice {
//         data: buffer.as_mut_ptr() as *const T,
//         len:  read / mem::size_of::<T>(),
//     }) })
// }

// pub struct UpperLowerMapper<R1: Read, R2: Read, F1: Fn()->R1, F2: Fn()->R2> {
//     pub upper: F1,
//     pub lower: F2,
// }
//
// impl<R1: Read, R2: Read, F1: Fn()->R1, F2: Fn()->R2> EdgeMapper for UpperLowerMapper<R1, R2, F1, F2> {
//     fn map_edges<F: FnMut(u32, u32) -> ()>(&self, mut action: F) -> () {
//         let mut upper_reader = (self.upper)();
//         let mut lower_reader = (self.lower)();
//         let mut upper_buffer = vec![0u8; 1 << 20];
//         let mut lower_buffer = vec![0u8; 1 << 20];
//         while let Ok(upper) = read_as_typed::<_,((u16,u16),u32)>(&mut upper_reader, &mut upper_buffer[..]) {
//             for &((ux, uy), mut count) in upper {
//                 let ux = (ux as u32) << 16;
//                 let uy = (uy as u32) << 16;
//                 while count > 0 {
//                     let size = min(lower_buffer.len(), 4 * count as usize);
//                     if let Ok(lower) = read_as_typed::<_,(u16,u16)>(&mut lower_reader, &mut lower_buffer[..size]) {
//                         for &(lx, ly) in lower {
//                             action(ux + lx as u32, uy + ly as u32);
//                         }
//                         count -= lower.len() as u32;
//                     }
//                 }
//             }
//         }
//     }
// }

// pub struct NodesEdgesMapper<R1: Read, R2: Read, F1: Fn()->R1, F2: Fn()->R2> {
//     pub nodes: F1,
//     pub edges: F2,
// }
//
// impl<R1: Read, R2: Read, F1: Fn()->R1, F2: Fn()->R2> EdgeMapper for NodesEdgesMapper<R1, R2, F1, F2> {
//     fn map_edges<F: FnMut(u32, u32) -> ()>(&self, mut action: F) -> () {
//         let mut nodes_reader = (self.nodes)();
//         let mut edges_reader = (self.edges)();
//         let mut nodes_buffer = vec![0u8; 1 << 20];
//         let mut edges_buffer = vec![0u8; 1 << 20];
//         while let Ok(nodes) = read_as_typed::<_,(u32,u32)>(&mut nodes_reader, &mut nodes_buffer[..]) {
//             for &(source, mut count) in nodes {
//                 while count > 0 {
//                     let size = min(edges_buffer.len(), 4 * count as usize);
//                     if let Ok(edges) = read_as_typed::<_,u32>(&mut edges_reader, &mut edges_buffer[..size]) {
//                         for &target in edges {
//                             action(source, target);
//                         }
//                         count -= edges.len() as u32;
//                     }
//                 }
//             }
//         }
//     }
// }

pub struct UpperLowerMemMapper {
    upper:  TypedMemoryMap<((u16,u16), u32)>,
    lower:  TypedMemoryMap<(u16, u16)>,
}

impl UpperLowerMemMapper {
    pub fn new(graph_name: &str) -> UpperLowerMemMapper {
        UpperLowerMemMapper {
            upper: TypedMemoryMap::new(format!("{}.upper", graph_name)),
            lower: TypedMemoryMap::new(format!("{}.lower", graph_name)),
        }
    }
}

impl EdgeMapper for UpperLowerMemMapper {
    fn map_edges<F: FnMut(u32, u32) -> ()>(&self, mut action: F) -> () {
        let mut slice = &self.lower[..];
        for &((u16_x, u16_y), count) in &self.upper[..] {
            let u16_x = (u16_x as u32) << 16;
            let u16_y = (u16_y as u32) << 16;
            for &(l16_x, l16_y) in &slice[.. count as usize] {
                action(u16_x | l16_x as u32, u16_y | l16_y as u32);
            }

            slice = &slice[count as usize ..];
        }
    }
}

pub struct NodesEdgesMemMapper {
    nodes:  TypedMemoryMap<(u32, u32)>,
    edges:  TypedMemoryMap<u32>,
}

impl NodesEdgesMemMapper {
    pub fn new(graph_name: &str) -> NodesEdgesMemMapper {
        NodesEdgesMemMapper {
            nodes: TypedMemoryMap::new(format!("{}.nodes", graph_name)),
            edges: TypedMemoryMap::new(format!("{}.edges", graph_name)),
        }
    }
}

impl EdgeMapper for NodesEdgesMemMapper {
    fn map_edges<F: FnMut(u32, u32) -> ()>(&self, mut action: F) -> () {
        let mut slice = &self.edges[..];
        for &(node, count) in &self.nodes[..] {
            for &edge in &slice[.. count as usize] {
                action(node, edge);
            }

            slice = &slice[count as usize ..];
        }
    }
}
<|endoftext|>