Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
### next
<<<<<<< HEAD
- fix panic when previewing an image with 16 bits per channel, or HDR - Fix #1209
- alt-arrows are bound like ctrl-arrows (panels, root up/down), as macOS captures ctrl-arrows; hints and help show the alt ones on macOS
=======

#### Major Feature: git diff preview, and many git related enhancements
The `libgit2` library has been replaced by `gix`. With this change, broot becomes pure Rust, which simplifies compilation (no C compiler needed anymore).
A unified diff preview is now the default preview of a file with a git change (modified, staged, added, renamed or in conflict) when git statuses are displayed. `:preview_diff` shows it for any file.
Expand All @@ -17,7 +17,6 @@ A unified diff preview is now the default preview of a file with a git change (m
- alt-g toggles the git status filter (`:toggle_git_status`). Status line suggests using it in git repo.
- `-gg` shows only the files with a git status (same as `--git-status`), `-G` removes one level of git information
- the Kitty keyboard protocol is now used by default when the terminal supports it, which notably makes `alt` combinations work on macOS terminals; multi-key combinations without modifier still need `enable_kitty_keyboard: true`
>>>>>>> replace-libgit2-with-gix

<a name="v1.59.0"></a>
### v1.59.0 - 2026-08-22
Expand Down
41 changes: 38 additions & 3 deletions src/image/zune_compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ use {
crate::errors::ProgramError,
image::GenericImageView,
std::path::Path,
zune_core::colorspace::ColorSpace,
zune_core::{
bit_depth::BitDepth,
colorspace::ColorSpace,
},
zune_image::{
core_filters::depth::Depth,
traits::OperationsTrait,
},
};

impl From<zune_image::errors::ImageErrors> for ProgramError {
Expand All @@ -22,6 +29,16 @@ impl From<image::ImageError> for ProgramError {
}
}

/// Tell whether the file starts with the PNG magic number
fn is_png(path: &Path) -> bool {
use std::io::Read;
let mut magic = [0u8; 8];
std::fs::File::open(path)
.and_then(|mut f| f.read_exact(&mut magic))
.is_ok()
&& magic == *b"\x89PNG\r\n\x1a\n"
}

/// Image type that uses either zune-image (fast) or image crate (fallback)
#[derive(Clone)]
pub enum DynamicImage {
Expand All @@ -33,7 +50,11 @@ pub enum DynamicImage {

impl DynamicImage {
pub fn from_path_as_zune(path: &Path) -> Result<Self, ProgramError> {
let img = zune_image::image::Image::open(path)?;
let mut img = zune_image::image::Image::open(path)?;
if img.depth() != BitDepth::Eight {
// the rest of the module assumes u8 channels
Depth::new(BitDepth::Eight).execute(&mut img)?;
}
let nb_components = img.colorspace().num_components();
if nb_components < 3 {
// Current implementation of the module requires an RGB image and
Expand All @@ -47,8 +68,22 @@ impl DynamicImage {
}
Ok(Self::Zune(img))
}
/// Load an image, choosing the fastest decoder for the format:
/// the image crate for PNG, zune-image for the other formats,
/// each one falling back to the other on failure.
///
/// Perf note: zune decodes JPEG faster, but the image crate decodes
/// PNG faster whatever the bit depth (measured on both x86 and
/// Apple Silicon, up to several times faster).
pub fn from_path(path: &Path) -> Result<Self, ProgramError> {
// Try zune-image first (fast path)
if is_png(path) {
if let Ok(reader) = image::ImageReader::open(path) {
if let Ok(img) = reader.decode() {
debug!("Loaded PNG with image crate: {path:?}");
return Ok(Self::Image(img));
}
}
}
match Self::from_path_as_zune(path) {
Ok(img) => {
debug!("Loaded with zune-image: {path:?}");
Expand Down
Loading