cvm-rs: Add jpegResizeEncode(), remove usage of sharp
sharp sucks.
This commit is contained in:
@@ -9,6 +9,12 @@ use rayon::{ThreadPool, ThreadPoolBuilder};
|
||||
|
||||
use crate::jpeg_compressor::*;
|
||||
|
||||
|
||||
use resize::Pixel::RGBA8;
|
||||
use resize::Type::Triangle;
|
||||
use rgb::FromSlice;
|
||||
|
||||
|
||||
/// Gives a Rayon thread pool we use for parallelism
|
||||
fn rayon_pool() -> &'static ThreadPool {
|
||||
static RUNTIME: OnceCell<ThreadPool> = OnceCell::new();
|
||||
@@ -69,9 +75,76 @@ pub fn jpeg_encode(env: Env, input: JpegInputArgs) -> napi::Result<napi::JsObjec
|
||||
});
|
||||
|
||||
deferred_resolver.resolve(move |env| {
|
||||
let buffer = env
|
||||
.create_buffer_with_data(vec)
|
||||
.expect("Couldn't create node Buffer, things are probably very broken by this point");
|
||||
let buffer = env.create_buffer_with_data(vec).expect(
|
||||
"Couldn't create node Buffer, things are probably very broken by this point",
|
||||
);
|
||||
// no longer need the input buffer
|
||||
buf.unref(env)?;
|
||||
Ok(buffer.into_raw())
|
||||
});
|
||||
});
|
||||
|
||||
Ok(promise)
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
pub struct JpegResizeInputArgs {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub desired_width: u32,
|
||||
pub desired_height: u32,
|
||||
pub buffer: napi::JsBuffer,
|
||||
}
|
||||
|
||||
#[napi(js_name = "jpegResizeEncode")]
|
||||
#[allow(unused)]
|
||||
pub fn jpeg_resize_and_encode(
|
||||
env: Env,
|
||||
input: JpegResizeInputArgs,
|
||||
) -> napi::Result<napi::JsObject> {
|
||||
let (deferred_resolver, promise) = env.create_deferred::<napi::JsBuffer, _>()?;
|
||||
let mut buf = input.buffer.into_ref()?;
|
||||
|
||||
// Spawn a task on the rayon pool that encodes the JPEG and fufills the promise
|
||||
// once it is done encoding.
|
||||
rayon_pool().spawn_fifo(move || {
|
||||
let mut new_data: Vec<u8> =
|
||||
vec![0; (input.desired_width * input.desired_height) as usize * 4];
|
||||
|
||||
let mut resizer = resize::new(
|
||||
input.width as usize,
|
||||
input.height as usize,
|
||||
input.desired_width as usize,
|
||||
input.desired_height as usize,
|
||||
RGBA8,
|
||||
Triangle,
|
||||
)
|
||||
.expect("Could not create resizer");
|
||||
|
||||
resizer
|
||||
.resize(&buf.as_rgba(), new_data.as_rgba_mut())
|
||||
.expect("Resize operation failed");
|
||||
|
||||
// then just jpeg encode. Ideally this would be shared :(
|
||||
let image = Image {
|
||||
buffer: &new_data,
|
||||
width: input.desired_width as u32,
|
||||
height: input.desired_height as u32,
|
||||
stride: (input.desired_width as u64 * 4u64) as u32,
|
||||
format: turbojpeg_sys::TJPF_TJPF_RGBA,
|
||||
};
|
||||
|
||||
let vec = COMPRESSOR.with(|lazy| {
|
||||
let mut b = lazy.borrow_mut();
|
||||
b.set_quality(35);
|
||||
b.set_subsamp(turbojpeg_sys::TJSAMP_TJSAMP_420);
|
||||
b.compress_buffer(&image)
|
||||
});
|
||||
|
||||
deferred_resolver.resolve(move |env| {
|
||||
let buffer = env.create_buffer_with_data(vec).expect(
|
||||
"Couldn't create node Buffer, things are probably very broken by this point",
|
||||
);
|
||||
// no longer need the input buffer
|
||||
buf.unref(env)?;
|
||||
Ok(buffer.into_raw())
|
||||
|
||||
Reference in New Issue
Block a user