Expand description
DCV color primitives is a library to perform image color model conversion.
It is able to convert the following pixel formats:
Source pixel format | Destination pixel formats |
---|---|
ARGB | I420, I444, NV12 |
BGR | I420, I444, NV12, RGB |
BGRA | I420, I444, NV12, RGB |
I420 | BGRA, RGBA |
I444 | BGRA, RGBA |
NV12 | BGRA, RGB, RGBA |
RGB | BGRA |
The supported color models are:
- ycbcr, ITU-R Recommendation BT.601 (standard video system)
- ycbcr, ITU-R Recommendation BT.709 (CSC systems)
Both standard range (0-235) and full range (0-255) are supported.
§Examples
Convert an image from bgra to nv12 (single plane) format, with Bt601 color space:
use dcv_color_primitives as dcp;
use dcp::{convert_image, ColorSpace, ImageFormat, PixelFormat};
fn convert() {
const WIDTH: u32 = 640;
const HEIGHT: u32 = 480;
let src_data = Box::new([0u8; 4 * (WIDTH as usize) * (HEIGHT as usize)]);
let mut dst_data = Box::new([0u8; 3 * (WIDTH as usize) * (HEIGHT as usize) / 2]);
let src_format = ImageFormat {
pixel_format: PixelFormat::Bgra,
color_space: ColorSpace::Rgb,
num_planes: 1,
};
let dst_format = ImageFormat {
pixel_format: PixelFormat::Nv12,
color_space: ColorSpace::Bt601,
num_planes: 1,
};
convert_image(
WIDTH,
HEIGHT,
&src_format,
None,
&[&*src_data],
&dst_format,
None,
&mut [&mut *dst_data],
);
}
Handle conversion errors:
use dcv_color_primitives as dcp;
use dcp::{convert_image, ColorSpace, ImageFormat, PixelFormat};
use std::error;
fn convert() -> Result<(), Box<dyn error::Error>> {
const WIDTH: u32 = 640;
const HEIGHT: u32 = 480;
let src_data = Box::new([0u8; 4 * (WIDTH as usize) * (HEIGHT as usize)]);
let mut dst_data = Box::new([0u8; 3 * (WIDTH as usize) * (HEIGHT as usize) / 2]);
let src_format = ImageFormat {
pixel_format: PixelFormat::Bgra,
color_space: ColorSpace::Bt709,
num_planes: 1,
};
let dst_format = ImageFormat {
pixel_format: PixelFormat::Nv12,
color_space: ColorSpace::Bt601,
num_planes: 1,
};
convert_image(
WIDTH,
HEIGHT,
&src_format,
None,
&[&*src_data],
&dst_format,
None,
&mut [&mut *dst_data],
)?;
Ok(())
}
Compute how many bytes are needed to store and image of a given format and size:
use dcv_color_primitives as dcp;
use dcp::{get_buffers_size, ColorSpace, ImageFormat, PixelFormat};
use std::error;
fn compute_size() -> Result<(), Box<dyn error::Error>> {
const WIDTH: u32 = 640;
const HEIGHT: u32 = 480;
const NUM_PLANES: u32 = 1;
let format = ImageFormat {
pixel_format: PixelFormat::Bgra,
color_space: ColorSpace::Rgb,
num_planes: NUM_PLANES,
};
let sizes: &mut [usize] = &mut [0usize; NUM_PLANES as usize];
get_buffers_size(WIDTH, HEIGHT, &format, None, sizes)?;
let buffer: Vec<_> = vec![0u8; sizes[0]];
// Do something with buffer
// --snip--
Ok(())
}
Provide image planes to handle data scattered in multiple buffers that are not necessarily contiguous:
use dcv_color_primitives as dcp;
use dcp::{convert_image, get_buffers_size, ColorSpace, ImageFormat, PixelFormat};
use std::error;
fn convert() -> Result<(), Box<dyn error::Error>> {
const WIDTH: u32 = 640;
const HEIGHT: u32 = 480;
const NUM_SRC_PLANES: u32 = 2;
const NUM_DST_PLANES: u32 = 1;
let src_format = ImageFormat {
pixel_format: PixelFormat::Nv12,
color_space: ColorSpace::Bt709,
num_planes: NUM_SRC_PLANES,
};
let src_sizes: &mut [usize] = &mut [0usize; NUM_SRC_PLANES as usize];
get_buffers_size(WIDTH, HEIGHT, &src_format, None, src_sizes)?;
let src_y: Vec<_> = vec![0u8; src_sizes[0]];
let src_uv: Vec<_> = vec![0u8; src_sizes[1]];
let dst_format = ImageFormat {
pixel_format: PixelFormat::Bgra,
color_space: ColorSpace::Rgb,
num_planes: NUM_DST_PLANES,
};
let dst_sizes: &mut [usize] = &mut [0usize; NUM_DST_PLANES as usize];
get_buffers_size(WIDTH, HEIGHT, &dst_format, None, dst_sizes)?;
let mut dst_rgba: Vec<_> = vec![0u8; dst_sizes[0]];
convert_image(
WIDTH,
HEIGHT,
&src_format,
None,
&[&src_y[..], &src_uv[..]],
&dst_format,
None,
&mut [&mut dst_rgba[..]],
)?;
Ok(())
}
Provide image strides to convert data which is not tightly packed:
use dcv_color_primitives as dcp;
use dcp::{convert_image, get_buffers_size, ColorSpace, ImageFormat, PixelFormat};
use std::error;
fn convert() -> Result<(), Box<dyn error::Error>> {
const WIDTH: u32 = 640;
const HEIGHT: u32 = 480;
const NUM_SRC_PLANES: u32 = 1;
const NUM_DST_PLANES: u32 = 2;
const RGB_STRIDE: usize = 4 * (((3 * (WIDTH as usize)) + 3) / 4);
let src_format = ImageFormat {
pixel_format: PixelFormat::Bgr,
color_space: ColorSpace::Rgb,
num_planes: NUM_SRC_PLANES,
};
let src_strides: &[usize] = &[RGB_STRIDE];
let src_sizes: &mut [usize] = &mut [0usize; NUM_SRC_PLANES as usize];
get_buffers_size(WIDTH, HEIGHT, &src_format, Some(src_strides), src_sizes)?;
let src_rgba: Vec<_> = vec![0u8; src_sizes[0]];
let dst_format = ImageFormat {
pixel_format: PixelFormat::Nv12,
color_space: ColorSpace::Bt709,
num_planes: NUM_DST_PLANES,
};
let dst_sizes: &mut [usize] = &mut [0usize; NUM_DST_PLANES as usize];
get_buffers_size(WIDTH, HEIGHT, &dst_format, None, dst_sizes)?;
let mut dst_y: Vec<_> = vec![0u8; dst_sizes[0]];
let mut dst_uv: Vec<_> = vec![0u8; dst_sizes[1]];
convert_image(
WIDTH,
HEIGHT,
&src_format,
Some(src_strides),
&[&src_rgba[..]],
&dst_format,
None,
&mut [&mut dst_y[..], &mut dst_uv[..]],
)?;
Ok(())
}
Structs§
- Describes how the image data is laid out in memory and its color space.
Enums§
- An enumeration of supported color models.
- An enumeration of errors.
- An enumeration of supported pixel formats.
Constants§
- If a plane stride is assigned to this constant, the plane will be assumed to contain packed data
Functions§
- Converts from a color space to another one, applying downsampling/upsampling to match destination image format.
- Returns a description of the algorithms that are best for the running cpu and available instruction sets
- Compute number of bytes required to store an image given its format, dimensions and optionally its strides