pub fn write_rgba_from_u8<W: ::std::io::Write>(
    file: &mut W,
    image: &[u8],
    w: u32,
    h: u32,
) -> Result<(), ::std::io::Error> {
    // assert!(w as usize * h as usize * 4 == image.len());

    fn png_pack<W: ::std::io::Write>(
        file: &mut W,
        png_tag: &[u8; 4],
        data: &[u8],
    ) -> Result<(), ::std::io::Error> {
        file.write(&u32_to_u8_be(data.len() as u32))?;
        file.write(png_tag)?;
        file.write(data)?;
        {
            let mut crc = crc32::Crc32::new();
            crc.start();
            crc.update(png_tag);
            crc.update(data);
            file.write(&u32_to_u8_be(crc.finalize()))?;
        }
        Ok(())
    }

    file.write(b"\x89PNG\r\n\x1a\n")?;
    {
        let wb = u32_to_u8_be(w);
        let hb = u32_to_u8_be(h);
        let data = [
            wb[0], wb[1], wb[2], wb[3], hb[0], hb[1], hb[2], hb[3], 8, 6, 0, 0, 0,
        ];
        png_pack(file, b"IHDR", &data)?;
    }

    {
        // this block was commented by Nikita Skobov
        // it creates a deep copy of the image data which doubles the memory usage
        // as well as the time it takes to save the image.
        // if the image data is already formatted in a way that fake_zlib can
        // "compress" it, then we save a lot of memory and time.

        // let width_byte_4 = w * 4;
        // let final_len = (width_byte_4 + 1) * h;
        // let mut raw_data = Vec::with_capacity(final_len as usize);
        // let mut span: u32 = (h - 1) * width_byte_4;
        // loop {
        //     raw_data.push(0);
        //     raw_data.extend((&image[(span as usize)..(span + width_byte_4) as usize]));
        //     if span == 0 {
        //         break;
        //     }
        //     span -= width_byte_4;
        // }
        // assert!(final_len == (raw_data.len() as u32));

        png_pack(file, b"IDAT", &fake_zlib::compress(&image))?;
    }

    png_pack(file, b"IEND", &[])?;

    Ok(())
}
///
/// Write RGBA pixels to uncompressed PNG.
///
Write RGBA pixels to uncompressed PNG.
Write RGBA pixels to uncompressed PNG .
pub fn write_rgba_from_u8<W: ::std::io::Write>(
    file: &mut W,
    image: &[u8],
    w: u32,
    h: u32,
) -> Result<(), ::std::io::Error> {
    // assert!(w as usize * h as usize * 4 == image.len());
    fn png_pack<W: ::std::io::Write>(
        file: &mut W,
        png_tag: &[u8; 4],
        data: &[u8],
    ) -> Result<(), ::std::io::Error> {
        file.write(&u32_to_u8_be(data.len() as u32))?;
        file.write(png_tag)?;
        file.write(data)?;
        {
            let mut crc = crc32::Crc32::new();
            crc.start();
            crc.update(png_tag);
            crc.update(data);
            file.write(&u32_to_u8_be(crc.finalize()))?;
        }
        Ok(())
    }
    file.write(b"\x89PNG\r\n\x1a\n")?;
    {
        let wb = u32_to_u8_be(w);
        let hb = u32_to_u8_be(h);
        let data = [
            wb[0], wb[1], wb[2], wb[3], hb[0], hb[1], hb[2], hb[3], 8, 6, 0, 0, 0,
        ];
        png_pack(file, b"IHDR", &data)?;
    }
    {
        // this block was commented by Nikita Skobov
        // it creates a deep copy of the image data which doubles the memory usage
        // as well as the time it takes to save the image.
        // if the image data is already formatted in a way that fake_zlib can
        // "compress" it, then we save a lot of memory and time.
        // let width_byte_4 = w * 4;
        // let final_len = (width_byte_4 + 1) * h;
        // let mut raw_data = Vec::with_capacity(final_len as usize);
        // let mut span: u32 = (h - 1) * width_byte_4;
        // loop {
        //     raw_data.push(0);
        //     raw_data.extend((&image[(span as usize)..(span + width_byte_4) as usize]));
        //     if span == 0 {
        //         break;
        //     }
        //     span -= width_byte_4;
        // }
        // assert!(final_len == (raw_data.len() as u32));
        png_pack(file, b"IDAT", &fake_zlib::compress(&image))?;
    }
    png_pack(file, b"IEND", &[])?;
    Ok(())
}
pub fn write_rgba_from_u8 < W : :: std :: io :: Write > ( file : & mut W , image : & [ u8 ] , w : u32 , h : u32 , ) -> Result < ( ) , :: std :: io :: Error > { // assert!(w as usize * h as usize * 4 == image.len()); fn png_pack < W : :: std :: io :: Write > ( file : & mut W , png_tag : & [ u8 ; 4 ] , data : & [ u8 ] , ) -> Result < ( ) , :: std :: io :: Error > { file . write ( & u32_to_u8_be ( data . len ( ) as u32 ) ) ? ; file . write ( png_tag ) ? ; file . write ( data ) ? ; { let mut crc = crc32 :: Crc32 :: new ( ) ; crc . start ( ) ; crc . update ( png_tag ) ; crc . update ( data ) ; file . write ( & u32_to_u8_be ( crc . finalize ( ) ) ) ? ; } Ok ( ( ) ) } file . write ( b" \x89 \r \n \x1a \n " ) ? ; { let wb = u32_to_u8_be ( w ) ; let hb = u32_to_u8_be ( h ) ; let data = [ wb [ 0 ] , wb [ 1 ] , wb [ 2 ] , wb [ 3 ] , hb [ 0 ] , hb [ 1 ] , hb [ 2 ] , hb [ 3 ] , 8 , 6 , 0 , 0 , 0 , ] ; png_pack ( file , b" " , & data ) ? ; } { // this block was commented by Nikita Skobov // it creates a deep copy of the image data which doubles the memory usage // as well as the time it takes to save the image. // if the image data is already formatted in a way that fake_zlib can // "compress" it, then we save a lot of memory and time. // let width_byte_4 = w * 4; // let final_len = (width_byte_4 + 1) * h; // let mut raw_data = Vec::with_capacity(final_len as usize); // let mut span: u32 = (h - 1) * width_byte_4; // loop { //     raw_data.push(0); //     raw_data.extend((&image[(span as usize)..(span + width_byte_4) as usize])); //     if span == 0 { //         break; //     } //     span -= width_byte_4; // } // assert!(final_len == (raw_data.len() as u32)); png_pack ( file , b" " , & fake_zlib :: compress ( & image ) ) ? ; } png_pack ( file , b" " , & [ ] ) ? ; Ok ( ( ) ) }
Write RGBA pixels to uncompressed PNG.
Write RGBA pixels to uncompressed PNG .
file
&mut W
image
&[u8]
w
u32
h
u32
file
&mut W
image
&[u8]
w
u32
h
u32