Skip to content

Commit

Permalink
fix: segmentation fault on any specific webp images.
Browse files Browse the repository at this point in the history
  • Loading branch information
tukinami committed Jun 14, 2024
1 parent ba64e42 commit c709359
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ rgb = "0.8.37"
png = "0.17.13"
gif = "0.13.1"
jpeg-decoder = "0.3.1"
libwebp-sys = "0.9.5"
tinybmp = "0.5.0"
embedded-graphics = "0.8.1"
image-webp = "0.1.2"

[target.'cfg(windows)'.dependencies]
winapi = {version = "0.3.9", features = ["winbase", "libloaderapi", "stringapiset"]}
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,14 @@ Argument0に、使用する機能名を指定して使用します。
+ [png](https://github.com/image-rs/image-png) / The image-rs Developers
+ [gif](https://github.com/image-rs/image-gif) / The image-rs Developers
+ [jpeg-decoder](https://github.com/image-rs/jpeg-decoder) / The image-rs Developers
+ [libwebp-sys](https://github.com/NoXF/libwebp-sys) / XianYou, Kornel Lesiński
+ [tinybmp](https://github.com/embedded-graphics/tinybmp) / James Waples, Ralf Fuest
+ [embedded-graphics](https://github.com/embedded-graphics/embedded-graphics) / James Waples, Ralf Fuest
+ [resize](https://github.com/PistonDevelopers/resize) / Kornel, Kagami Hiiragi
+ [rgb](https://github.com/kornelski/rust-rgb) / Kornel Lesiński
+ [image-webp](https://github.com/image-rs/image-webp) / Jonathan Behrens
+ (テスト実行時) [encoding\_rs](https://github.com/hsivonen/encoding_rs) / Henri Sivonen
+ (テスト実行時) [tempfile](https://github.com/Stebalien/tempfile) / Steven Allen, The Rust Project Developers, Ashley Mannix, Jason White


## ライセンス

MITにて配布いたします。
Expand Down
50 changes: 30 additions & 20 deletions src/image/webp.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
use core::slice;
use std::{fs::File, io::prelude::Read, path::PathBuf};
use std::{fs::File, io::BufReader, path::PathBuf};

use libwebp_sys::{WebPDecodeRGBA, WebPGetInfo};
use image_webp::{DecodingError, WebPDecoder};

use crate::error::ResizedPngError;

use super::ImageData;

pub(crate) fn read_image_data(path: &PathBuf) -> Result<ImageData, ResizedPngError> {
let mut fs = File::open(path)?;
let mut bytes = Vec::new();
fs.read_to_end(&mut bytes)?;

let mut width = 0;
let mut height = 0;
let len = bytes.len();

let is_webp = unsafe { WebPGetInfo(bytes.as_ptr(), len, &mut width, &mut height) };

if is_webp == 0 {
return Err(ResizedPngError::Unsupported);
impl From<DecodingError> for ResizedPngError {
fn from(value: DecodingError) -> Self {
match value {
DecodingError::IoError(_) => ResizedPngError::IoError,
_ => ResizedPngError::DecodingError,
}
}
}

let out_buf = unsafe { WebPDecodeRGBA(bytes.as_ptr(), len, &mut width, &mut height) };

let data_raw = unsafe { slice::from_raw_parts(out_buf, (width * height * 4) as usize) };
pub(crate) fn read_image_data(path: &PathBuf) -> Result<ImageData, ResizedPngError> {
let fs = File::open(path)?;
let buf_reader = BufReader::new(fs);
let mut decoder = WebPDecoder::new(buf_reader)?;

let output_buffer_size = decoder
.output_buffer_size()
.ok_or(ResizedPngError::Unsupported)?;
let mut buffer = vec![0; output_buffer_size];

decoder.read_image(&mut buffer)?;

if !decoder.has_alpha() {
buffer = buffer.chunks(3).fold(Vec::new(), |mut acc, item| {
acc.extend(item);
acc.push(u8::MAX);
acc
});
}
let (width, height) = decoder.dimensions();

Ok((data_raw.to_vec(), width as u32, height as u32))
Ok((buffer, width, height))
}

#[cfg(test)]
Expand Down

0 comments on commit c709359

Please sign in to comment.