Skip to content

Commit

Permalink
Merge pull request #49 from Brooooooklyn/lazy-load-font-db
Browse files Browse the repository at this point in the history
perf(image): lazy load fontdb Database
  • Loading branch information
Brooooooklyn authored Mar 12, 2023
2 parents 5a8a6e0 + 0a35dbb commit ced0e73
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 54 deletions.
20 changes: 20 additions & 0 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base", "group:allNonMajor", ":preserveSemverRanges", ":disablePeerDependencies"],
"labels": ["dependencies"],
"packageRules": [
{
"matchPackageNames": ["@napi/cli", "napi", "napi-build", "napi-derive"],
"addLabels": ["napi-rs"],
"groupName": "napi-rs"
},
{
"matchPackagePatterns": ["^eslint", "^@typescript-eslint"],
"groupName": "linter"
}
],
"commitMessagePrefix": "chore: ",
"commitMessageAction": "bump up",
"commitMessageTopic": "{{depName}} version",
"ignoreDeps": []
}
29 changes: 18 additions & 11 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ env:
- docs/**
- website/**
pull_request: null
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
if: "!contains(github.event.head_commit.message, 'skip ci')"
Expand Down Expand Up @@ -88,7 +91,7 @@ jobs:
set -e &&
export LDFLAGS="-L/usr/aarch64-unknown-linux-gnu/lib/gcc/aarch64-unknown-linux-gnu/4.8.5" &&
export CFLAGS="-fuse-ld=lld -mcrc -B/usr/aarch64-unknown-linux-gnu/lib/gcc/aarch64-unknown-linux-gnu/4.8.5 --sysroot=/usr/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot" &&
export CXXFLAGS="-fuse-ld=lld -mcrc -B/usr/aarch64-unknown-linux-gnu/lib/gcc/aarch64-unknown-linux-gnu/4.8.5 --sysroot=/usr/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot" &&
export CXXFLAGS="-fuse-ld=lld -mcrc -B/usr/aarch64-unknown-linux-gnu/lib/gcc/aarch64-unknown-linux-gnu/4.8.5 --sysroot=/usr/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot -L/usr/aarch64-unknown-linux-gnu/lib/llvm-15/lib -stdlib=libc++" &&
yarn workspace @napi-rs/image build --features with_simd --target aarch64-unknown-linux-gnu &&
llvm-strip packages/*/*.node
- host: ubuntu-latest
Expand Down Expand Up @@ -263,7 +266,6 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
check-latest: true
cache: yarn
- name: Install dependencies
run: yarn install --immutable
Expand Down Expand Up @@ -300,7 +302,6 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
check-latest: true
cache: yarn
- name: Install dependencies
run: yarn install --immutable
Expand Down Expand Up @@ -335,7 +336,6 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
check-latest: true
cache: yarn
- name: Install dependencies
run: yarn install --immutable --mode=skip-build
Expand Down Expand Up @@ -365,7 +365,6 @@ jobs:
- '18'
runs-on: ubuntu-latest
steps:
- run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
- uses: actions/checkout@v3
- name: Download artifacts
uses: actions/download-artifact@v3
Expand All @@ -380,11 +379,16 @@ jobs:
- name: List packages
run: ls -R packages
shell: bash
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: arm64
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: Setup and run tests
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/napi-rs/napi-rs/nodejs:aarch64-${{ matrix.node }}
options: '-v ${{ github.workspace }}:/build -w /build'
image: node:${{ matrix.node }}-slim
options: '--platform linux/arm64 -v ${{ github.workspace }}:/build -w /build'
run: |
set -e
yarn test
Expand All @@ -402,7 +406,6 @@ jobs:
- '18'
runs-on: ubuntu-latest
steps:
- run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
- uses: actions/checkout@v3
- name: Download artifacts
uses: actions/download-artifact@v3
Expand All @@ -417,11 +420,16 @@ jobs:
- name: List packages
run: ls -R packages
shell: bash
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: arm
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: Setup and run tests
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/napi-rs/napi-rs/nodejs:armhf-${{ matrix.node }}
options: '-v ${{ github.workspace }}:/build -w /build'
image: node:${{ matrix.node }}-bullseye-slim
options: '--platform linux/arm/v7 -v ${{ github.workspace }}:/build -w /build'
run: |
set -e
yarn test
Expand All @@ -442,7 +450,6 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18
check-latest: true
cache: yarn
- name: Install dependencies
run: yarn install --immutable --mode=skip-build
Expand Down
3 changes: 2 additions & 1 deletion packages/binding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ image = { version = "0.24", default-features = false, features = [
"openexr",
] }
jpeg-decoder = "0.3"
libavif = { version = "=0.10.1", default-features = false, features = [
libavif = { version = "0.11", default-features = false, features = [
"codec-aom",
] }
libc = "0.2"
Expand All @@ -47,6 +47,7 @@ napi-derive = { version = "2", default-features = false, features = [
] }
num-complex = "0.4"
num_cpus = "1"
once_cell = "1"
png = "0.17"
rexif = "0.7"
rgb = "0.8"
Expand Down
8 changes: 3 additions & 5 deletions packages/binding/src/fast_resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use napi::bindgen_prelude::*;
use napi_derive::napi;

#[napi]
#[derive(Default)]
pub enum FastResizeFilter {
/// Each pixel of source image contributes to one pixel of the
/// destination image with identical weights. For upscaling is equivalent
Expand All @@ -32,14 +33,11 @@ pub enum FastResizeFilter {
/// Lanczos3 filter calculate the output pixel value using a high-quality
/// Lanczos filter (a truncated sinc) on all pixels that may contribute
/// to the output value.
#[default]
Lanczos3,
}

impl Default for FastResizeFilter {
fn default() -> Self {
FastResizeFilter::Lanczos3
}
}


impl From<FastResizeFilter> for FilterType {
fn from(value: FastResizeFilter) -> Self {
Expand Down
10 changes: 5 additions & 5 deletions packages/binding/src/jpeg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ pub fn compress_jpeg_sync(
.map_err(|err| {
Error::new(
Status::InvalidArg,
format!("Load input jpeg image failed {}", err),
format!("Load input jpeg image failed {err}"),
)
})?;
let mut dest = Cursor::new(Vec::with_capacity(input.len()));
let mut encoder = image::codecs::jpeg::JpegEncoder::new_with_quality(&mut dest, quality as u8);
encoder.encode_image(&img).map_err(|err| {
Error::new(
Status::GenericFailure,
format!("Encode image from input jpeg failed {}", err),
format!("Encode image from input jpeg failed {err}"),
)
})?;
return env
Expand Down Expand Up @@ -110,7 +110,7 @@ unsafe fn moz_jpeg_compress(
.map_err(|err| {
Error::new(
Status::GenericFailure,
format!("Compress JPEG failed {:?}", err),
format!("Compress JPEG failed {err:?}"),
)
})
}
Expand Down Expand Up @@ -176,7 +176,7 @@ impl Task for CompressJpegTask {
.map_err(|err| {
Error::new(
Status::InvalidArg,
format!("Load input jpeg image failed {}", err),
format!("Load input jpeg image failed {err}"),
)
})?;
let mut dest = Cursor::new(Vec::with_capacity(self.input.len()));
Expand All @@ -185,7 +185,7 @@ impl Task for CompressJpegTask {
encoder.encode_image(&img).map_err(|err| {
Error::new(
Status::GenericFailure,
format!("Encode image from input jpeg failed {}", err),
format!("Encode image from input jpeg failed {err}"),
)
})?;
return Ok(JpegOptimizeOutput::Lossy(dest.into_inner()));
Expand Down
40 changes: 18 additions & 22 deletions packages/binding/src/png.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@ use napi_derive::napi;
use rgb::FromSlice;

#[napi]
#[derive(Default)]
pub enum CompressionType {
/// Default compression level
#[default]
Default,
/// Fast, minimal compression
Fast,
/// High compression level
Best,
}

impl Default for CompressionType {
fn default() -> Self {
CompressionType::Default
}
}


impl From<CompressionType> for image::codecs::png::CompressionType {
fn from(compression_type: CompressionType) -> Self {
Expand All @@ -29,9 +27,11 @@ impl From<CompressionType> for image::codecs::png::CompressionType {
}

#[napi]
#[derive(Default)]
pub enum FilterType {
/// No processing done, best used for low bit depth greyscale or data with a
/// low color count
#[default]
NoFilter,
/// Filters based on previous pixel in the same scanline
Sub,
Expand All @@ -46,11 +46,7 @@ pub enum FilterType {
Adaptive,
}

impl Default for FilterType {
fn default() -> Self {
FilterType::NoFilter
}
}


impl From<FilterType> for image::codecs::png::FilterType {
fn from(filter: FilterType) -> Self {
Expand Down Expand Up @@ -186,7 +182,7 @@ pub fn lossless_compress_png_sync(
input.as_ref(),
&to_oxipng_options(&options.unwrap_or_default()),
)
.map_err(|err| Error::new(Status::InvalidArg, format!("Optimize failed {}", err)))?;
.map_err(|err| Error::new(Status::InvalidArg, format!("Optimize failed {err}")))?;
Ok(output.into())
}

Expand All @@ -202,7 +198,7 @@ impl Task for LosslessPngTask {

fn compute(&mut self) -> Result<Self::Output> {
oxipng::optimize_from_memory(self.input.as_ref(), &to_oxipng_options(&self.options))
.map_err(|err| Error::new(Status::InvalidArg, format!("Optimize failed {}", err)))
.map_err(|err| Error::new(Status::InvalidArg, format!("Optimize failed {err}")))
}

fn resolve(&mut self, _env: Env, output: Self::Output) -> Result<Self::JsValue> {
Expand Down Expand Up @@ -252,11 +248,11 @@ fn png_quantize_inner(input: &[u8], options: &PngQuantOptions) -> Result<Vec<u8>
let decoder = png::Decoder::new(input);
let mut reader = decoder
.read_info()
.map_err(|err| Error::new(Status::InvalidArg, format!("Read png info failed {}", err)))?;
.map_err(|err| Error::new(Status::InvalidArg, format!("Read png info failed {err}")))?;
let mut decoded_buf = vec![0; reader.output_buffer_size()];
let output_info = reader
.next_frame(&mut decoded_buf)
.map_err(|err| Error::new(Status::InvalidArg, format!("Read png frame failed {}", err)))?;
.map_err(|err| Error::new(Status::InvalidArg, format!("Read png frame failed {err}")))?;
let width = output_info.width;
let height = output_info.height;
// The input png quality is too low
Expand All @@ -266,43 +262,43 @@ fn png_quantize_inner(input: &[u8], options: &PngQuantOptions) -> Result<Vec<u8>
let mut liq = imagequant::new();
liq
.set_speed(options.speed.unwrap_or(5) as i32)
.map_err(|err| Error::new(Status::GenericFailure, format!("{}", err)))?;
.map_err(|err| Error::new(Status::GenericFailure, format!("{err}")))?;
liq
.set_quality(
options.min_quality.unwrap_or(70) as u8,
options.max_quality.unwrap_or(99) as u8,
)
.map_err(|err| Error::new(Status::GenericFailure, format!("{}", err)))?;
.map_err(|err| Error::new(Status::GenericFailure, format!("{err}")))?;
let mut img = liq
.new_image(decoded_buf.as_rgba(), width as usize, height as usize, 0.0)
.map_err(|err| {
Error::new(
Status::GenericFailure,
format!("Create image failed {}", err),
format!("Create image failed {err}"),
)
})?;
let mut quantization_result = liq
.quantize(&mut img)
.map_err(|err| Error::new(Status::GenericFailure, format!("quantize failed {}", err)))?;
.map_err(|err| Error::new(Status::GenericFailure, format!("quantize failed {err}")))?;
quantization_result
.set_dithering_level(1.0)
.map_err(|err| Error::new(Status::GenericFailure, format!("{}", err)))?;
.map_err(|err| Error::new(Status::GenericFailure, format!("{err}")))?;
let (palette, pixels) = quantization_result
.remapped(&mut img)
.map_err(|err| Error::new(Status::GenericFailure, format!("remap failed {}", err)))?;
.map_err(|err| Error::new(Status::GenericFailure, format!("remap failed {err}")))?;
let mut encoder = lodepng::Encoder::new();
encoder.set_palette(palette.as_slice()).map_err(|err| {
Error::new(
Status::GenericFailure,
format!("Set palette on png encoder {}", err),
format!("Set palette on png encoder {err}"),
)
})?;
let output = encoder
.encode(pixels.as_slice(), width as usize, height as usize)
.map_err(|err| {
Error::new(
Status::GenericFailure,
format!("Encode quantized png failed {}", err),
format!("Encode quantized png failed {err}"),
)
})?;
Ok(output)
Expand Down
Loading

1 comment on commit ced0e73

@vercel
Copy link

@vercel vercel bot commented on ced0e73 Mar 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

image – ./

image-lynweklm.vercel.app
image-two.vercel.app
image.napi.rs
image-git-main-lynweklm.vercel.app

Please sign in to comment.