Skip to content

Commit

Permalink
Rename color space → model
Browse files Browse the repository at this point in the history
Fixes #88
  • Loading branch information
kornelski committed Dec 7, 2024
1 parent ed676dd commit e03108a
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 35 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cavif"
description = "Encodes images in AVIF format (image2avif converter) using a pure-Rust encoder."
version = "1.5.6"
version = "1.5.7"
authors = ["Kornel Lesiński <[email protected]>"]
edition = "2021"
license = "BSD-3-Clause"
Expand All @@ -14,7 +14,7 @@ include = ["README.md", "LICENSE", "/src/*.rs"]
rust-version = "1.70"

[dependencies]
ravif = { version = "0.11.11", path = "./ravif", default-features = false, features = ["threading"] }
ravif = { version = "0.11.12", path = "./ravif", default-features = false, features = ["threading"] }
rayon = "1.10.0"
rgb = { version = "0.8.50", default-features = false }
cocoa_image = { version = "1.0.7", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion ravif/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "ravif"
description = "rav1e-based pure Rust library for encoding images in AVIF format (powers the `cavif` tool)"
version = "0.11.11"
version = "0.11.12"
authors = ["Kornel Lesiński <[email protected]>"]
edition = "2021"
license = "BSD-3-Clause"
Expand Down
55 changes: 30 additions & 25 deletions ravif/src/av1encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use rgb::RGBA8;
#[cfg(not(feature = "threading"))]
use crate::rayoff as rayon;

/// For [`Encoder::with_internal_color_space`]
/// For [`Encoder::with_internal_color_model`]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ColorSpace {
pub enum ColorModel {
/// Standard color space for photographic content. Usually the best choice.
/// This library always uses full-resolution color (4:4:4).
/// This library will automatically choose between BT.601 or BT.709.
Expand Down Expand Up @@ -64,7 +64,7 @@ pub struct Encoder {
/// True if RGBA input has already been premultiplied. It inserts appropriate metadata.
premultiplied_alpha: bool,
/// Which pixel format to use in AVIF file. RGB tends to give larger files.
color_space: ColorSpace,
color_model: ColorModel,
/// How many threads should be used (0 = match core count), None - use global rayon thread pool
threads: Option<usize>,
/// [`AlphaColorMode`]
Expand All @@ -84,7 +84,7 @@ impl Encoder {
speed: 5,
depth: None,
premultiplied_alpha: false,
color_space: ColorSpace::YCbCr,
color_model: ColorModel::YCbCr,
threads: None,
alpha_color_mode: AlphaColorMode::UnassociatedClean,
}
Expand Down Expand Up @@ -134,14 +134,19 @@ impl Encoder {
/// Changes how color channels are stored in the image. The default is YCbCr.
///
/// Note that this is only internal detail for the AVIF file, and doesn't
/// change color space of inputs to encode functions.
/// change color model of inputs to encode functions.
#[inline(always)]
#[must_use]
pub fn with_internal_color_space(mut self, color_space: ColorSpace) -> Self {
self.color_space = color_space;
pub fn with_internal_color_model(mut self, color_model: ColorModel) -> Self {
self.color_model = color_model;
self
}

#[doc(hidden)]
pub fn with_internal_color_space(self, color_model: ColorModel) -> Self {
self.with_internal_color_model(color_model)
}

/// Configures `rayon` thread pool size.
/// The default `None` is to use all threads in the default `rayon` thread pool.
#[inline(always)]
Expand Down Expand Up @@ -196,17 +201,17 @@ impl Encoder {

let width = buffer.width();
let height = buffer.height();
let matrix_coefficients = match self.color_space {
ColorSpace::YCbCr => MatrixCoefficients::BT601,
ColorSpace::RGB => MatrixCoefficients::Identity,
let matrix_coefficients = match self.color_model {
ColorModel::YCbCr => MatrixCoefficients::BT601,
ColorModel::RGB => MatrixCoefficients::Identity,
};
if self.depth == Some(10) {
let planes = buffer.pixels().map(|px| {
let (y,u,v) = match self.color_space {
ColorSpace::YCbCr => {
let (y,u,v) = match self.color_model {
ColorModel::YCbCr => {
rgb_to_10_bit_ycbcr(px.rgb(), BT601)
},
ColorSpace::RGB => {
ColorModel::RGB => {
rgb_to_10_bit_gbr(px.rgb())
},
};
Expand All @@ -216,11 +221,11 @@ impl Encoder {
self.encode_raw_planes_10_bit(width, height, planes, Some(alpha), PixelRange::Full, matrix_coefficients)
} else {
let planes = buffer.pixels().map(|px| {
let (y,u,v) = match self.color_space {
ColorSpace::YCbCr => {
let (y,u,v) = match self.color_model {
ColorModel::YCbCr => {
rgb_to_8_bit_ycbcr(px.rgb(), BT601)
},
ColorSpace::RGB => {
ColorModel::RGB => {
rgb_to_8_bit_gbr(px.rgb())
},
};
Expand Down Expand Up @@ -274,17 +279,17 @@ pub fn encode_rgb(&self, buffer: Img<&[RGB8]>) -> Result<EncodedImage, Error> {
}

fn encode_rgb_internal(&self, width: usize, height: usize, pixels: impl Iterator<Item = RGB8> + Send + Sync) -> Result<EncodedImage, Error> {
let matrix_coefficients = match self.color_space {
ColorSpace::YCbCr => MatrixCoefficients::BT601,
ColorSpace::RGB => MatrixCoefficients::Identity,
let matrix_coefficients = match self.color_model {
ColorModel::YCbCr => MatrixCoefficients::BT601,
ColorModel::RGB => MatrixCoefficients::Identity,
};
if self.depth == Some(8) {
let planes = pixels.map(|px| {
let (y,u,v) = match self.color_space {
ColorSpace::YCbCr => {
let (y,u,v) = match self.color_model {
ColorModel::YCbCr => {
rgb_to_8_bit_ycbcr(px, BT601)
},
ColorSpace::RGB => {
ColorModel::RGB => {
rgb_to_8_bit_gbr(px)
},
};
Expand All @@ -293,11 +298,11 @@ fn encode_rgb_internal(&self, width: usize, height: usize, pixels: impl Iterator
self.encode_raw_planes_8_bit(width, height, planes, None::<[_; 0]>, PixelRange::Full, matrix_coefficients)
} else {
let planes = pixels.map(|px| {
let (y,u,v) = match self.color_space {
ColorSpace::YCbCr => {
let (y,u,v) = match self.color_model {
ColorModel::YCbCr => {
rgb_to_10_bit_ycbcr(px, BT601)
},
ColorSpace::RGB => {
ColorModel::RGB => {
rgb_to_10_bit_gbr(px)
},
};
Expand Down
6 changes: 5 additions & 1 deletion ravif/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ mod av1encoder;

mod error;
pub use error::Error;
pub use av1encoder::ColorSpace;
pub use av1encoder::ColorModel;

#[doc(hidden)]
pub use ColorModel as ColorSpace;

pub use av1encoder::AlphaColorMode;
pub use av1encoder::Encoder;
pub use av1encoder::EncodedImage;
Expand Down
12 changes: 6 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use clap::ArgAction;
use clap::value_parser;
use clap::{Arg, Command};
use imgref::ImgVec;
use ravif::{AlphaColorMode, ColorSpace, Encoder, EncodedImage, RGBA8};
use ravif::{AlphaColorMode, ColorModel, Encoder, EncodedImage, RGBA8};
use rayon::prelude::*;
use std::fs;
use std::io::Read;
Expand Down Expand Up @@ -99,7 +99,7 @@ fn run() -> Result<(), BoxError> {
.long("color")
.default_value("ycbcr")
.value_parser(["ycbcr", "rgb"])
.help("Internal AVIF color space. YCbCr works better for human eyes."))
.help("Internal AVIF color model. YCbCr works better for human eyes."))
.arg(Arg::new("depth")
.long("depth")
.default_value("auto")
Expand All @@ -126,9 +126,9 @@ fn run() -> Result<(), BoxError> {
let threads = args.get_one::<u8>("threads").copied();
let dirty_alpha = args.get_flag("dirty-alpha");

let color_space = match args.get_one::<String>("color").expect("default").as_str() {
"ycbcr" => ColorSpace::YCbCr,
"rgb" => ColorSpace::RGB,
let color_model = match args.get_one::<String>("color").expect("default").as_str() {
"ycbcr" => ColorModel::YCbCr,
"rgb" => ColorModel::RGB,
x => Err(format!("bad color type: {x}"))?,
};

Expand Down Expand Up @@ -209,7 +209,7 @@ fn run() -> Result<(), BoxError> {
.with_depth(depth)
.with_speed(speed)
.with_alpha_quality(alpha_quality)
.with_internal_color_space(color_space)
.with_internal_color_model(color_model)
.with_alpha_color_mode(if dirty_alpha { AlphaColorMode::UnassociatedDirty } else { AlphaColorMode::UnassociatedClean })
.with_num_threads(threads.filter(|&n| n > 0).map(usize::from));
let EncodedImage { avif_file, color_byte_size, alpha_byte_size , .. } = enc.encode_rgba(img.as_ref())?;
Expand Down

0 comments on commit e03108a

Please sign in to comment.