mirror of
https://github.com/TeamPiped/piped-proxy.git
synced 2024-08-14 23:50:45 +00:00
Add avif re-encoding support.
This commit is contained in:
parent
38caad047a
commit
6b46efb100
3 changed files with 981 additions and 24 deletions
959
Cargo.lock
generated
959
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -12,6 +12,8 @@ libwebp-sys = "0.9.2"
|
||||||
mimalloc = "0.1.37"
|
mimalloc = "0.1.37"
|
||||||
once_cell = "1.18.0"
|
once_cell = "1.18.0"
|
||||||
qstring = "0.7.2"
|
qstring = "0.7.2"
|
||||||
|
ravif = "0.11.2"
|
||||||
|
rgb = "0.8.36"
|
||||||
regex = "1.9.1"
|
regex = "1.9.1"
|
||||||
reqwest = {version = "0.11.18", features = ["rustls-tls", "stream", "brotli", "gzip"], default-features = false}
|
reqwest = {version = "0.11.18", features = ["rustls-tls", "stream", "brotli", "gzip"], default-features = false}
|
||||||
tokio = {version = "1.29.1", features = ["full"]}
|
tokio = {version = "1.29.1", features = ["full"]}
|
||||||
|
|
44
src/main.rs
44
src/main.rs
|
@ -7,8 +7,10 @@ use libwebp_sys::{WebPEncodeRGB, WebPFree};
|
||||||
use mimalloc::MiMalloc;
|
use mimalloc::MiMalloc;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use qstring::QString;
|
use qstring::QString;
|
||||||
|
use ravif::{Encoder, Img};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use reqwest::{Body, Client, Request, Url};
|
use reqwest::{Body, Client, Request, Url};
|
||||||
|
use rgb::FromSlice;
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL: MiMalloc = MiMalloc;
|
static GLOBAL: MiMalloc = MiMalloc;
|
||||||
|
@ -117,6 +119,14 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, Box<dyn Error>> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let avif = {
|
||||||
|
if let Some(avif) = query.get("avif") {
|
||||||
|
avif == "true"
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let host = res.unwrap();
|
let host = res.unwrap();
|
||||||
let domain = RE_DOMAIN.captures(host.as_str());
|
let domain = RE_DOMAIN.captures(host.as_str());
|
||||||
|
|
||||||
|
@ -200,6 +210,31 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, Box<dyn Error>> {
|
||||||
|
|
||||||
if rewrite {
|
if rewrite {
|
||||||
if let Some(content_type) = resp.headers().get("content-type") {
|
if let Some(content_type) = resp.headers().get("content-type") {
|
||||||
|
if content_type == "image/webp" || content_type == "image/jpeg" && avif {
|
||||||
|
let resp_bytes = resp.bytes().await.unwrap();
|
||||||
|
|
||||||
|
let image = image::load_from_memory(&resp_bytes).unwrap();
|
||||||
|
|
||||||
|
let buffer = Img::new(
|
||||||
|
image.as_rgb8().unwrap().as_raw().as_rgb(),
|
||||||
|
image.width() as usize,
|
||||||
|
image.height() as usize,
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = Encoder::new()
|
||||||
|
.with_quality(80f32)
|
||||||
|
.with_speed(4)
|
||||||
|
.encode_rgb(buffer);
|
||||||
|
|
||||||
|
return if let Ok(res) = res {
|
||||||
|
response.content_type("image/avif");
|
||||||
|
Ok(response.body(res.avif_file.to_vec()))
|
||||||
|
} else {
|
||||||
|
response.content_type("image/jpeg");
|
||||||
|
Ok(response.body(resp_bytes))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if content_type == "image/jpeg" {
|
if content_type == "image/jpeg" {
|
||||||
let resp_bytes = resp.bytes().await.unwrap();
|
let resp_bytes = resp.bytes().await.unwrap();
|
||||||
|
|
||||||
|
@ -214,7 +249,14 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, Box<dyn Error>> {
|
||||||
let bytes: Vec<u8> = unsafe {
|
let bytes: Vec<u8> = unsafe {
|
||||||
let mut out_buf = std::ptr::null_mut();
|
let mut out_buf = std::ptr::null_mut();
|
||||||
let stride = width as i32 * 3;
|
let stride = width as i32 * 3;
|
||||||
let len: usize = WebPEncodeRGB(data.as_ptr(), width as i32, height as i32, stride, quality as f32, &mut out_buf);
|
let len: usize = WebPEncodeRGB(
|
||||||
|
data.as_ptr(),
|
||||||
|
width as i32,
|
||||||
|
height as i32,
|
||||||
|
stride,
|
||||||
|
quality as f32,
|
||||||
|
&mut out_buf,
|
||||||
|
);
|
||||||
let vec = std::slice::from_raw_parts(out_buf, len).into();
|
let vec = std::slice::from_raw_parts(out_buf, len).into();
|
||||||
WebPFree(out_buf as *mut _);
|
WebPFree(out_buf as *mut _);
|
||||||
vec
|
vec
|
||||||
|
|
Loading…
Reference in a new issue