#![forbid(unsafe_code)]
#[cfg(all(feature = "blake3", feature = "xxh3"))]
compile_error!(
"hashavatar features `blake3` and `xxh3` are mutually exclusive; choose one identity hash mode"
);
#[cfg(all(feature = "fuzzing", not(any(debug_assertions, fuzzing))))]
compile_error!(
"hashavatar's fuzzing feature exposes internal fuzz harness entry points and must not be enabled in non-fuzzing release builds"
);
use std::io::Cursor;
use std::mem::swap;
use std::str::FromStr;
#[cfg(feature = "gif")]
use image::codecs::gif::GifEncoder;
#[cfg(feature = "jpeg")]
use image::codecs::jpeg::JpegEncoder;
#[cfg(feature = "png")]
use image::codecs::png::{CompressionType, FilterType, PngEncoder};
use image::codecs::webp::WebPEncoder;
use image::error::{LimitError, LimitErrorKind};
use image::{
ExtendedColorType, ImageBuffer, ImageEncoder, ImageError, ImageResult, Rgba, RgbaImage,
};
use palette::{FromColor, Hsl, Srgb};
use rand::{RngExt, SeedableRng, rngs::StdRng};
use sanitization::unsafe_wipe::volatile_sanitize_vec;
use sanitization::{Secret, SecureSanitize, sanitize_bytes};
#[cfg(feature = "blake3")]
use sanitization_crypto_interop::blake3::blake3_xof_fill;
use sanitization_crypto_interop::sha2::sha512_digest as sanitized_sha512_digest;
use subtle::ConstantTimeEq;
pub const AVATAR_STYLE_VERSION: u32 = 2;
pub const MIN_AVATAR_DIMENSION: u32 = 64;
pub const MAX_AVATAR_DIMENSION: u32 = 2048;
pub const AVATAR_RGBA_BYTES_PER_PIXEL: usize = 4;
pub const MAX_AVATAR_PIXELS: usize =
(MAX_AVATAR_DIMENSION as usize) * (MAX_AVATAR_DIMENSION as usize);
pub const MAX_AVATAR_RGBA_BYTES: usize = MAX_AVATAR_PIXELS * AVATAR_RGBA_BYTES_PER_PIXEL;
pub const MAX_AVATAR_ID_BYTES: usize = 1024;
pub const MAX_AVATAR_NAMESPACE_COMPONENT_BYTES: usize = 128;
pub const AVATAR_STYLE_KIND_BYTE: usize = 0;
pub const AVATAR_STYLE_BACKGROUND_BYTE: usize = 1;
pub const AVATAR_STYLE_ACCESSORY_BYTE: usize = 2;
pub const AVATAR_STYLE_COLOR_BYTE: usize = 3;
pub const AVATAR_STYLE_EXPRESSION_BYTE: usize = 4;
pub const AVATAR_STYLE_SHAPE_BYTE: usize = 5;
pub mod prelude {
pub use crate::{
AvatarAccessory, AvatarBackground, AvatarBuilder, AvatarColor, AvatarError,
AvatarExpression, AvatarIdentity, AvatarIdentityOptions, AvatarKind, AvatarNamespace,
AvatarOptions, AvatarOutputFormat, AvatarShape, AvatarSpec, AvatarStyleOptions,
};
}
const HASH_DOMAIN: &[u8] = b"hashavatar";
const HASH_DOMAIN_ALGORITHM_COMPONENT: &[u8] = b"identity-hash";
const CACHE_KEY_DOMAIN: &[u8] = b"hashavatar-cache-key-v1";
#[cfg(feature = "blake3")]
const ACTIVE_HASH_ALGORITHM_LABEL: &[u8] = b"blake3";
#[cfg(all(not(feature = "blake3"), feature = "xxh3"))]
const ACTIVE_HASH_ALGORITHM_LABEL: &[u8] = b"xxh3-128";
#[cfg(all(not(feature = "blake3"), not(feature = "xxh3")))]
const ACTIVE_HASH_ALGORITHM_LABEL: &[u8] = b"sha512";
#[cfg(feature = "xxh3")]
const HASH_XOF_CHUNK_COMPONENT: &[u8] = b"digest-chunk";
mod api;
mod avatars;
mod backgrounds;
mod cat_support;
mod core;
mod encoding;
mod layers;
mod model;
mod primitives;
mod renderer_types;
mod svg;
#[cfg(test)]
mod tests;
pub(crate) use self::backgrounds::*;
pub(crate) use self::cat_support::*;
pub(crate) use self::encoding::*;
pub(crate) use self::layers::*;
pub(crate) use self::primitives::*;
pub(crate) use self::svg::*;
pub use self::api::*;
pub use self::avatars::*;
pub use self::core::*;
pub use self::model::*;
pub use self::primitives::Color;
#[cfg(feature = "fuzzing")]
pub use self::primitives::fuzz_draw_polygon_rgba;
pub use self::renderer_types::*;