      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129

    //! Decoding and Encoding of PNG Images
    //!
    //! PNG (Portable Network Graphics) is an image format that supports lossless compression.
    //!
    //! # Related Links
    //! * <http://www.w3.org/TR/PNG/> - The PNG Specification
    //!

    extern crate png;

    use self::png::HasParameters;

    use std;
    use std::io::{self, Cursor, Read, Write};

    use color::ColorType;
    use image::{ImageDecoder, ImageError, ImageResult};

    /// PNG decoder
    pub struct PNGDecoder<R: Read> {
        colortype: ColorType,
        reader: png::Reader<R>,
    }

    impl<R: Read> PNGDecoder<R> {
        /// Creates a new decoder that decodes from the stream ```r```
        pub fn new(r: R) -> ImageResult<PNGDecoder<R>> {
            let limits = png::Limits {
                pixels: std::u64::MAX,
            };
            let decoder = png::Decoder::new_with_limits(r, limits);
            let (_, mut reader) = decoder.read_info()?;
            let colortype = reader.output_color_type().into();

            Ok(PNGDecoder { colortype, reader })
        }
    }

    impl<R: Read> ImageDecoder for PNGDecoder<R> {
        type Reader = Cursor<Vec<u8>>;

        fn dimensions(&self) -> (u64, u64) {
            let (w, h) = self.reader.info().size();
            (w as u64, h as u64)
        }

        fn colortype(&self) -> ColorType {
            self.colortype
        }

        fn into_reader(self) -> ImageResult<Self::Reader> {
            Ok(Cursor::new(self.read_image()?))
        }

        fn read_image(mut self) -> ImageResult<Vec<u8>> {
            let mut data = vec![0; self.reader.output_buffer_size()];
            self.reader.next_frame(&mut data)?;
            Ok(data)
        }
    }

    /// PNG encoder
    pub struct PNGEncoder<W: Write> {
        w: W,
    }

    impl<W: Write> PNGEncoder<W> {
        /// Create a new encoder that writes its output to ```w```
        pub fn new(w: W) -> PNGEncoder<W> {
            PNGEncoder { w }
        }

        /// Encodes the image ```image```
        /// that has dimensions ```width``` and ```height```
        /// and ```ColorType``` ```c```
        pub fn encode(self, data: &[u8], width: u32, height: u32, color: ColorType) -> io::Result<()> {
            let (ct, bits) = color.into();
            let mut encoder = png::Encoder::new(self.w, width, height);
            encoder.set(ct).set(bits);
            let mut writer = try!(encoder.write_header());
            writer.write_image_data(data).map_err(|e| e.into())
        }
    }

    impl From<(png::ColorType, png::BitDepth)> for ColorType {
        fn from((ct, bits): (png::ColorType, png::BitDepth)) -> ColorType {
            use self::png::ColorType::*;
            let bits = bits as u8;
            match ct {
                Grayscale => ColorType::Gray(bits),
                RGB => ColorType::RGB(bits),
                Indexed => ColorType::Palette(bits),
                GrayscaleAlpha => ColorType::GrayA(bits),
                RGBA => ColorType::RGBA(bits),
            }
        }
    }

    impl From<ColorType> for (png::ColorType, png::BitDepth) {
        fn from(ct: ColorType) -> (png::ColorType, png::BitDepth) {
            use self::png::ColorType::*;
            let (ct, bits) = match ct {
                ColorType::Gray(bits) => (Grayscale, bits),
                ColorType::RGB(bits) => (RGB, bits),
                ColorType::Palette(bits) => (Indexed, bits),
                ColorType::GrayA(bits) => (GrayscaleAlpha, bits),
                ColorType::RGBA(bits) => (RGBA, bits),
                ColorType::BGRA(bits) => (RGBA, bits),
                ColorType::BGR(bits) => (RGB, bits),
            };
            (ct, png::BitDepth::from_u8(bits).unwrap())
        }
    }

    impl From<png::DecodingError> for ImageError {
        fn from(err: png::DecodingError) -> ImageError {
            use self::png::DecodingError::*;
            match err {
                IoError(err) => ImageError::IoError(err),
                Format(desc) => ImageError::FormatError(desc.into_owned()),
                InvalidSignature => ImageError::FormatError("invalid signature".into()),
                CrcMismatch { .. } => ImageError::FormatError("CRC error".into()),
                Other(desc) => ImageError::FormatError(desc.into_owned()),
                CorruptFlateStream => {
                    ImageError::FormatError("compressed data stream corrupted".into())
                }
            }
        }
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g., `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g., `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g., `str,u8` or `String,struct:Vec,test`)