tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

png.rs (2967B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 use crate::{WindowWrapper, NotifierEvent};
      6 use image::png::PNGEncoder;
      7 use image::{self, ColorType, GenericImageView};
      8 use std::fs::File;
      9 use std::path::{Path, PathBuf};
     10 use std::sync::mpsc::Receiver;
     11 use webrender::api::units::*;
     12 use crate::wrench::{Wrench, WrenchThing};
     13 use crate::yaml_frame_reader::YamlFrameReader;
     14 
     15 pub enum ReadSurface {
     16    Screen,
     17 }
     18 
     19 pub struct SaveSettings {
     20    pub flip_vertical: bool,
     21    pub try_crop: bool,
     22 }
     23 
     24 pub fn save<P: Clone + AsRef<Path>>(
     25    path: P,
     26    orig_pixels: Vec<u8>,
     27    size: DeviceIntSize,
     28    settings: SaveSettings
     29 ) {
     30    let mut width = size.width as u32;
     31    let mut height = size.height as u32;
     32    let mut buffer = image::RgbaImage::from_raw(
     33        width,
     34        height,
     35        orig_pixels,
     36    ).expect("bug: unable to construct image buffer");
     37 
     38    if settings.flip_vertical {
     39        // flip image vertically (texture is upside down)
     40        buffer = image::imageops::flip_vertical(&buffer);
     41    }
     42 
     43    if settings.try_crop {
     44        if let Ok(existing_image) = image::open(path.clone()) {
     45            let old_dims = existing_image.dimensions();
     46            println!("Crop from {:?} to {:?}", size, old_dims);
     47            width = old_dims.0;
     48            height = old_dims.1;
     49            buffer = image::imageops::crop(
     50                &mut buffer,
     51                0,
     52                0,
     53                width,
     54                height
     55            ).to_image();
     56        }
     57    }
     58 
     59    let encoder = PNGEncoder::new(File::create(path).unwrap());
     60    encoder
     61        .encode(&buffer, width, height, ColorType::Rgba8)
     62        .expect("Unable to encode PNG!");
     63 }
     64 
     65 pub fn save_flipped<P: Clone + AsRef<Path>>(
     66    path: P,
     67    orig_pixels: Vec<u8>,
     68    size: DeviceIntSize,
     69 ) {
     70    save(path, orig_pixels, size, SaveSettings {
     71        flip_vertical: true,
     72        try_crop: true,
     73    })
     74 }
     75 
     76 pub fn png(
     77    wrench: &mut Wrench,
     78    surface: ReadSurface,
     79    window: &mut WindowWrapper,
     80    mut reader: YamlFrameReader,
     81    rx: Receiver<NotifierEvent>,
     82    out_path: Option<PathBuf>,
     83 ) {
     84    reader.do_frame(wrench);
     85 
     86    // wait for the frame
     87    rx.recv().unwrap();
     88    wrench.render();
     89 
     90    let (fb_size, data, settings) = match surface {
     91        ReadSurface::Screen => {
     92            let dim = window.get_inner_size();
     93            let rect = FramebufferIntSize::new(dim.width, dim.height).into();
     94            let data = wrench.renderer.read_pixels_rgba8(rect);
     95            (dim, data, SaveSettings {
     96                flip_vertical: true,
     97                try_crop: true,
     98            })
     99        }
    100    };
    101 
    102    let out_path = out_path.unwrap_or_else(|| {
    103        let mut path = reader.yaml_path().clone();
    104        path.set_extension("png");
    105        path
    106    });
    107 
    108    save(out_path, data, fb_size, settings);
    109 }