feat(imaging): add pure-Rust JPEG 2000 backend (#109)
Some checks failed
CI / required (push) Failing after 3m18s
Some checks failed
CI / required (push) Failing after 3m18s
This commit is contained in:
@@ -150,7 +150,7 @@ impl Baker {
|
||||
let texture = crate::assets::AssetTexture::new_with_managed_image(output)?;
|
||||
// JPEG2000 is the protocol representation. Keep the decoded image even
|
||||
// when a build intentionally excludes that optional codec.
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
#[cfg(any(feature = "jpeg2000", feature = "rust-j2k"))]
|
||||
texture.encode()?;
|
||||
self.baked_texture = Some(texture);
|
||||
Ok(())
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
)]
|
||||
|
||||
use crate::{Error, Permissions};
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
use libremetaverse_imaging::J2kCodec as TextureJ2kCodec;
|
||||
use libremetaverse_imaging::ManagedImage;
|
||||
#[cfg(all(not(feature = "jpeg2000"), feature = "rust-j2k"))]
|
||||
use libremetaverse_imaging::RustJ2kCodec as TextureJ2kCodec;
|
||||
use libremetaverse_structured_data::{OSD, OSDMap, OSDParser};
|
||||
use libremetaverse_types::{AssetType, SaleType, UUID, Vector3, WearableType};
|
||||
use std::collections::HashMap;
|
||||
@@ -526,9 +530,9 @@ impl AssetTexture {
|
||||
if self.image.is_some() {
|
||||
return Ok(true);
|
||||
}
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
#[cfg(any(feature = "jpeg2000", feature = "rust-j2k"))]
|
||||
{
|
||||
self.image = Some(libremetaverse_imaging::J2kCodec::decode_bytes(
|
||||
self.image = Some(TextureJ2kCodec::decode_bytes(
|
||||
&self.raw.bytes(),
|
||||
libremetaverse_imaging::J2kDecodeOptions::default(),
|
||||
)?);
|
||||
@@ -543,7 +547,7 @@ impl AssetTexture {
|
||||
};
|
||||
Ok(true)
|
||||
}
|
||||
#[cfg(not(feature = "jpeg2000"))]
|
||||
#[cfg(not(any(feature = "jpeg2000", feature = "rust-j2k")))]
|
||||
{
|
||||
Err(Error::InvalidOperation)
|
||||
}
|
||||
@@ -570,15 +574,15 @@ impl AssetTexture {
|
||||
})
|
||||
}
|
||||
pub fn decode(&self) -> Result<bool, Error> {
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
#[cfg(any(feature = "jpeg2000", feature = "rust-j2k"))]
|
||||
{
|
||||
Ok(libremetaverse_imaging::J2kCodec::decode_bytes(
|
||||
Ok(TextureJ2kCodec::decode_bytes(
|
||||
&self.raw.bytes(),
|
||||
libremetaverse_imaging::J2kDecodeOptions::default(),
|
||||
)
|
||||
.is_ok())
|
||||
}
|
||||
#[cfg(not(feature = "jpeg2000"))]
|
||||
#[cfg(not(any(feature = "jpeg2000", feature = "rust-j2k")))]
|
||||
{
|
||||
validate_bytes(&self.raw.bytes())?;
|
||||
Err(Error::InvalidOperation)
|
||||
@@ -586,15 +590,15 @@ impl AssetTexture {
|
||||
}
|
||||
pub fn encode(&self) -> Result<(), Error> {
|
||||
let image = self.image.as_ref().ok_or(Error::InvalidOperation)?;
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
#[cfg(any(feature = "jpeg2000", feature = "rust-j2k"))]
|
||||
{
|
||||
let encoded = libremetaverse_imaging::J2kCodec::encode(
|
||||
let encoded = TextureJ2kCodec::encode(
|
||||
image,
|
||||
libremetaverse_imaging::J2kEncodeOptions::default(),
|
||||
)?;
|
||||
self.raw.replace(encoded)
|
||||
}
|
||||
#[cfg(not(feature = "jpeg2000"))]
|
||||
#[cfg(not(any(feature = "jpeg2000", feature = "rust-j2k")))]
|
||||
{
|
||||
let _ = image;
|
||||
Err(Error::InvalidOperation)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
#[cfg(any(feature = "jpeg2000", feature = "rust-j2k"))]
|
||||
use crate::assets::AssetTexture;
|
||||
use crate::assets::{AssetMesh, AssetMutable, AssetSound};
|
||||
use crate::{
|
||||
AssetCache, AssetCacheComputeAssetCacheFilenameDelegate, Error, GridClient, ImageCodec,
|
||||
};
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
#[cfg(any(feature = "jpeg2000", feature = "rust-j2k"))]
|
||||
use libremetaverse_imaging::{ManagedImage, ManagedImageImageChannels};
|
||||
use libremetaverse_types::{AssetType, UUID};
|
||||
use std::fs;
|
||||
@@ -58,7 +58,7 @@ fn sound_codec_is_explicitly_feature_gated() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
#[cfg(any(feature = "jpeg2000", feature = "rust-j2k"))]
|
||||
fn texture_codec_produces_real_valid_payload() {
|
||||
let mut image = ManagedImage::new(2, 2, ManagedImageImageChannels::COLOR).unwrap();
|
||||
image.red.fill(255);
|
||||
|
||||
@@ -11,6 +11,10 @@ use std::path::{Component, Path, PathBuf};
|
||||
|
||||
use flate2::{Compression, write::ZlibEncoder};
|
||||
use libremetaverse_imaging::ITextureCodec;
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
use libremetaverse_imaging::J2kCodec as TextureJ2kCodec;
|
||||
#[cfg(all(not(feature = "jpeg2000"), feature = "rust-j2k"))]
|
||||
use libremetaverse_imaging::RustJ2kCodec as TextureJ2kCodec;
|
||||
use libremetaverse_structured_data::{OSD, OSDFormat, OSDParser};
|
||||
use libremetaverse_types::compat::{CancellationToken, Uri};
|
||||
use libremetaverse_types::{AssetType, Color4, Error, Quaternion, UUID, Vector2, Vector3};
|
||||
@@ -956,14 +960,14 @@ fn load_texture(
|
||||
return Err(Error::InvalidOperation);
|
||||
};
|
||||
let image = codec.decode(Box::new(std::io::Cursor::new(bytes)))?;
|
||||
#[cfg(feature = "jpeg2000")]
|
||||
#[cfg(any(feature = "jpeg2000", feature = "rust-j2k"))]
|
||||
{
|
||||
return libremetaverse_imaging::J2kCodec::encode(
|
||||
return TextureJ2kCodec::encode(
|
||||
&image,
|
||||
libremetaverse_imaging::J2kEncodeOptions::default(),
|
||||
);
|
||||
}
|
||||
#[cfg(not(feature = "jpeg2000"))]
|
||||
#[cfg(not(any(feature = "jpeg2000", feature = "rust-j2k")))]
|
||||
{
|
||||
let _ = image;
|
||||
return Err(Error::InvalidOperation);
|
||||
|
||||
Reference in New Issue
Block a user