Skip to content

Commit

Permalink
Better validation of images for potential UHD feature.
Browse files Browse the repository at this point in the history
Scale invalid images in legacy converter.
Use higher quality resize algorithm.
  • Loading branch information
Jupeyy committed Jan 8, 2025
1 parent ee57149 commit 2791c4f
Show file tree
Hide file tree
Showing 27 changed files with 495 additions and 681 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions examples/wasm-modules/graphics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ pub mod handles;
pub mod graphics_mt {
pub use ::graphics::graphics_mt::*;
}
pub mod image {
pub use ::graphics::image::*;
}

pub mod quad_container {
pub use ::graphics::quad_container::*;
}
Expand Down
33 changes: 25 additions & 8 deletions game/client-containers/src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ use either::Either;
use game_interface::types::resource_key::ResourceKey;
use graphics::{
graphics::graphics::Graphics, graphics_mt::GraphicsMultiThreaded,
handles::texture::texture::GraphicsTextureHandle, image::texture_2d_to_3d,
handles::texture::texture::GraphicsTextureHandle,
};
use graphics_types::{
commands::TexFlags,
types::{GraphicsBackendMemory, GraphicsMemoryAllocationType},
};
use hashlink::LinkedHashMap;
use hiarc::Hiarc;
use image::png::{is_png_image_valid, load_png_image, PngResultPersistent};
use image::{
png::{is_png_image_valid, load_png_image_as_rgba, PngResultPersistent, PngValidatorOptions},
utils::texture_2d_to_3d,
};
use log::info;
use sound::{
ogg_vorbis::verify_ogg_vorbis, scene_object::SceneObject, sound::SoundManager,
Expand Down Expand Up @@ -415,10 +418,20 @@ where
}

/// Verifies a resource, prints warnings on error
fn verify_resource(file_ty: &str, file_name: &str, file: &[u8]) -> bool {
fn verify_resource(file_ty: &str, file_name: &str, file: &[u8], allow_hq_assets: bool) -> bool {
match file_ty {
"png" => {
if let Err(err) = is_png_image_valid(file, Default::default()) {
if let Err(err) = is_png_image_valid(
file,
if allow_hq_assets {
PngValidatorOptions {
max_width: 4096.try_into().unwrap(),
max_height: 4096.try_into().unwrap(),
}
} else {
Default::default()
},
) {
log::warn!(
"downloaded image resource (png) {}\
is not a valid png file: {}",
Expand Down Expand Up @@ -523,6 +536,8 @@ where
game_server_http: Option<Url>,
resource_http_download: HttpIndexAndUrl,
) -> anyhow::Result<ContainerLoadedItem> {
let allow_hq_assets = false;

let read_tar = |file: &[u8]| {
let mut file = tar::Archive::new(std::io::Cursor::new(file));
match file.entries() {
Expand Down Expand Up @@ -637,6 +652,7 @@ where
name.extension().and_then(|s| s.to_str()).unwrap_or(""),
name.file_stem().and_then(|s| s.to_str()).unwrap_or(""),
file,
allow_hq_assets,
) {
verified = false;
break;
Expand All @@ -663,7 +679,7 @@ where
}) {
let _g = http_download_tasks.acquire().await?;
if let Ok(file) = http.download_binary(game_server_http, &hash).await {
if Self::verify_resource("png", &name, &file) {
if Self::verify_resource("png", &name, &file, allow_hq_assets) {
save_to_disk(&name, &file).await;
files = Some(ContainerLoadedItem::SingleFile(file.to_vec()));
}
Expand Down Expand Up @@ -799,6 +815,7 @@ where
name.extension().and_then(|s| s.to_str()).unwrap_or(""),
name.file_stem().and_then(|s| s.to_str()).unwrap_or(""),
file,
allow_hq_assets,
) {
verified = false;
break;
Expand All @@ -816,7 +833,7 @@ where
false
}
} else if ty == "png" {
if Self::verify_resource("png", &name, &file) {
if Self::verify_resource("png", &name, &file, allow_hq_assets) {
files = Some(ContainerLoadedItem::SingleFile(file.to_vec()));
true
} else {
Expand Down Expand Up @@ -1372,7 +1389,7 @@ pub fn load_file_part_as_png_ex(
allow_default,
)?;
let mut img_data = Vec::<u8>::new();
let part_img = load_png_image(file.data, |width, height, bytes_per_pixel| {
let part_img = load_png_image_as_rgba(file.data, |width, height, bytes_per_pixel| {
img_data = vec![0; width * height * bytes_per_pixel];
&mut img_data
})?;
Expand Down Expand Up @@ -1548,7 +1565,7 @@ pub fn load_file_part_as_png_and_convert_3d(
true,
)?;
let mut img_data = Vec::<u8>::new();
let part_img = load_png_image(file.data, |width, height, bytes_per_pixel| {
let part_img = load_png_image_as_rgba(file.data, |width, height, bytes_per_pixel| {
img_data = vec![0; width * height * bytes_per_pixel];
&mut img_data
})?;
Expand Down
2 changes: 1 addition & 1 deletion game/client-containers/src/emoticons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl LoadEmoticons {
fn load_full(files: &mut FxHashMap<PathBuf, Vec<u8>>, file: Vec<u8>) -> anyhow::Result<()> {
let mut mem: Vec<u8> = Default::default();
let img: image::png::PngResult<'_> =
image::png::load_png_image(&file, |width, height, bytes_per_pixel| {
image::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| {
mem.resize(width * height * bytes_per_pixel, Default::default());
&mut mem
})?;
Expand Down
2 changes: 1 addition & 1 deletion game/client-containers/src/hud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl LoadHud {
fn load_full(files: &mut FxHashMap<PathBuf, Vec<u8>>, file: Vec<u8>) -> anyhow::Result<()> {
let mut mem: Vec<u8> = Default::default();
let img: image::png::PngResult<'_> =
image::png::load_png_image(&file, |width, height, bytes_per_pixel| {
image::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| {
mem.resize(width * height * bytes_per_pixel, Default::default());
&mut mem
})?;
Expand Down
2 changes: 1 addition & 1 deletion game/client-containers/src/particles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl LoadParticle {
fn load_full(files: &mut FxHashMap<PathBuf, Vec<u8>>, file: Vec<u8>) -> anyhow::Result<()> {
let mut mem: Vec<u8> = Default::default();
let img: image::png::PngResult<'_> =
image::png::load_png_image(&file, |width, height, bytes_per_pixel| {
image::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| {
mem.resize(width * height * bytes_per_pixel, Default::default());
&mut mem
})?;
Expand Down
2 changes: 1 addition & 1 deletion game/client-containers/src/skins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl LoadSkinTexturesData {
) -> anyhow::Result<()> {
let mut mem: Vec<u8> = Default::default();
let img: image::png::PngResult<'_> =
image::png::load_png_image(&file, |width, height, bytes_per_pixel| {
image::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| {
mem.resize(width * height * bytes_per_pixel, Default::default());
&mut mem
})?;
Expand Down
44 changes: 33 additions & 11 deletions game/client-render-base/src/map/render_map_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ use graphics::{
stream::stream::GraphicsStreamHandle,
texture::texture::{GraphicsTextureHandle, TextureContainer, TextureContainer2dArray},
},
image::{highest_bit, resize, texture_2d_to_3d},
};
use graphics_types::{commands::TexFlags, types::GraphicsMemoryAllocationType};
use image::png::{is_png_image_valid, load_png_image};
use image::{
png::{is_png_image_valid, load_png_image_as_rgba, resize_rgba, PngValidatorOptions},
utils::{highest_bit, texture_2d_to_3d},
};
use map::map::Map;
use math::math::vector::vec2;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
Expand Down Expand Up @@ -195,6 +197,7 @@ impl RenderMapLoading {
file_ty.as_str(),
file_name.as_str(),
&file,
load_hq_assets,
)?;
let file_path: &Path = read_file_path.as_ref();
if let Some(dir) = file_path.parent() {
Expand Down Expand Up @@ -254,19 +257,23 @@ impl RenderMapLoading {
|| convert_height == 0
|| (convert_height % 16) != 0
{
// TODO sys.log("image").msg("3D/2D array texture was resized");
let new_width =
std::cmp::max(highest_bit(convert_width as u32) as usize, 16);
let new_height =
std::cmp::max(highest_bit(convert_height as u32) as usize, 16);
conv_data = resize(
&runtime_tp,
upload_data,
conv_data = resize_rgba(
upload_data.into(),
convert_width as u32,
convert_height as u32,
new_width as u32,
new_height as u32,
);
log::warn!(
"3D/2D array texture had to be resized, {}x{} to {}x{}",
convert_width,
convert_height,
new_width,
new_height,
image_color_channels,
new_height
);

convert_width = new_width;
Expand Down Expand Up @@ -314,7 +321,7 @@ impl RenderMapLoading {
.into_par_iter()
.map(|(hash, file)| {
let mut img_data: Vec<u8> = Default::default();
let img = load_png_image(
let img = load_png_image_as_rgba(
&file,
|width, height, color_channel_count| {
img_data.resize(
Expand Down Expand Up @@ -456,10 +463,25 @@ impl RenderMapLoading {
}
}

fn verify_resource(file_ty: &str, file_name: &str, file: &[u8]) -> anyhow::Result<()> {
fn verify_resource(
file_ty: &str,
file_name: &str,
file: &[u8],
allow_hq_assets: bool,
) -> anyhow::Result<()> {
match file_ty {
"png" => {
if let Err(err) = is_png_image_valid(file, Default::default()) {
if let Err(err) = is_png_image_valid(
file,
if allow_hq_assets {
PngValidatorOptions {
max_width: 4096.try_into().unwrap(),
max_height: 4096.try_into().unwrap(),
}
} else {
Default::default()
},
) {
return Err(anyhow!(
"downloaded image resource (png) {}\
is not a valid png file: {}",
Expand Down
4 changes: 2 additions & 2 deletions game/client-ui/src/main_menu/leftbar/main_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use graphics::handles::{
canvas::canvas::GraphicsCanvasHandle, stream::stream::GraphicsStreamHandle,
};
use graphics_types::{commands::TexFlags, types::GraphicsMemoryAllocationType};
use image::png::load_png_image;
use image::png::load_png_image_as_rgba;
use math::math::vector::vec2;
use ui_base::{style::bg_frame_color, types::UiState};

Expand Down Expand Up @@ -39,7 +39,7 @@ fn update_communities(user_data: &mut UserData) {
let icon = http.download_binary_secure(url).await?.to_vec();

let mut img_mem = None;
let img = load_png_image(&icon, |width, height, _| {
let img = load_png_image_as_rgba(&icon, |width, height, _| {
img_mem = Some(graphics_mt.mem_alloc(
GraphicsMemoryAllocationType::TextureRgbaU8 {
width: width.try_into().unwrap(),
Expand Down
7 changes: 3 additions & 4 deletions game/editor/src/action_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ use graphics::{
buffer_object::buffer_object::GraphicsBufferObjectHandle,
texture::texture::GraphicsTextureHandle,
},
image::texture_2d_to_3d,
};
use graphics_types::{commands::TexFlags, types::GraphicsMemoryAllocationType};
use image::png::load_png_image;
use image::{png::load_png_image_as_rgba, utils::texture_2d_to_3d};
use map::{
map::groups::layers::{
design::{
Expand Down Expand Up @@ -628,7 +627,7 @@ pub fn do_action(
act.base.index
);
let mut img_mem = None;
let _ = load_png_image(&act.base.file, |width, height, _| {
let _ = load_png_image_as_rgba(&act.base.file, |width, height, _| {
img_mem = Some(backend_handle.mem_alloc(
GraphicsMemoryAllocationType::TextureRgbaU8 {
width: width.try_into().unwrap(),
Expand Down Expand Up @@ -658,7 +657,7 @@ pub fn do_action(
act.base.index
);
let mut png = Vec::new();
let img = load_png_image(&act.base.file, |width, height, _| {
let img = load_png_image_as_rgba(&act.base.file, |width, height, _| {
png = vec![0; width * height * 4];
&mut png
})?;
Expand Down
7 changes: 3 additions & 4 deletions game/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ use graphics::{
stream::stream::GraphicsStreamHandle,
texture::texture::{GraphicsTextureHandle, TextureContainer, TextureContainer2dArray},
},
image::texture_2d_to_3d,
};
use graphics_types::{commands::TexFlags, types::GraphicsMemoryAllocationType};
use hiarc::HiarcTrait;
use image::png::load_png_image;
use image::{png::load_png_image_as_rgba, utils::texture_2d_to_3d};
use map::{
map::{
animations::{AnimBase, AnimPointCurveType, AnimPointPos},
Expand Down Expand Up @@ -504,7 +503,7 @@ impl Editor {
let file = resources.get(&meta.blake3_hash).unwrap();

let mut mem = None;
let _ = load_png_image(file, |width, height, _| {
let _ = load_png_image_as_rgba(file, |width, height, _| {
mem = Some(graphics_mt.mem_alloc(
GraphicsMemoryAllocationType::TextureRgbaU8 {
width: width.try_into().unwrap(),
Expand All @@ -531,7 +530,7 @@ impl Editor {
let file = resources.get(&meta.blake3_hash).unwrap();

let mut png = Vec::new();
let img = load_png_image(
let img = load_png_image_as_rgba(
file,
|width, height, color_chanel_count| {
png.resize(
Expand Down
Loading

0 comments on commit 2791c4f

Please sign in to comment.