Start work on webp support

This commit is contained in:
asonix 2020-06-16 15:55:24 -05:00
parent 80d9387dbb
commit df85faff8b
10 changed files with 667 additions and 465 deletions

BIN
client-examples/1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -1,8 +1,37 @@
FROM rustembedded/cross:x86_64-unknown-linux-gnu AS x86_64-builder
# Target environment
FROM amd64/ubuntu:20.04 as target-env
ENV \
TARGET=x86_64-unknown-linux-gnu \
BUILD_MODE=release
# Basic cross-build environment
FROM ubuntu:20.04 as cross-build
ENV \
ARCH=amd64 \
HOST=x86_64-unknown-linux \
TOOL=x86_64-linux-gnu \
TARGET=x86_64-unknown-linux-gnu \
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \
CC_X86_64_UNKNOWN_LINUX_GNU=x86_64-linux-gnu-gcc \
CXX_X86_64_UNKNOWN_LINUX_GNU=x86_64-linux-gnu-g++ \
BUILD_MODE=release
ENV \
TOOLCHAIN=stable \
DEBIAN_FRONTEND=noninteractive \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LD_RUN_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LDFLAGS="-L/usr/lib/$TOOL -L/usr/$TOOL/lib -Wl,-rpath-link,/usr/lib/$TOOL -Wl,-rpath-link,/usr/$TOOL/lib" \
CFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \
apt-get update && \
apt-get upgrade -y && \
sed 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch-=amd64,i386] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list > /etc/apt/sources.list.d/ports.list && \
sed -i 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch=amd64,i386] http:\/\/\1.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list && \
addgroup --gid 991 build && \
adduser \
--disabled-password \
@ -10,167 +39,174 @@ RUN \
--ingroup build \
--uid 991 \
--home /opt/build \
build
ADD https://sh.rustup.rs /opt/build/rustup.sh
RUN \
chown -R build:build /opt/build
USER build
WORKDIR /opt/build
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
TOOLCHAIN=stable \
HOST=x86_64-unknown-linux \
TARGET=x86_64-unknown-linux-gnu \
TOOL=x86_64-linux-gnu \
ARCH=amd64
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
FROM x86_64-builder as builder
USER root
ADD https://imagemagick.org/download/ImageMagick.tar.gz ./
RUN \
build && \
dpkg --add-architecture $ARCH && \
apt-get update && \
apt-get -y install \
libgexiv2-dev:$ARCH \
apt-get upgrade -y && \
apt-get install -y \
pkg-config \
build-essential \
crossbuild-essential-$ARCH
WORKDIR /opt/build
# Environment for ImageMagick
FROM cross-build as imagemagick-builder
RUN \
apt-get install -y \
libltdl-dev:$ARCH \
libjpeg-dev:$ARCH \
libpng-dev:$ARCH \
libwebp-dev:$ARCH \
liblzma-dev:$ARCH \
llvm-dev \
libclang-dev \
clang && \
chown build:build ImageMagick.tar.gz
libxml2-dev:$ARCH
ADD --chown=build:build https://imagemagick.org/download/ImageMagick.tar.gz /opt/build/ImageMagick.tar.gz
USER build
RUN \
tar xvzf ImageMagick.tar.gz && \
tar zxf ImageMagick.tar.gz && \
mv ImageMagick-* ImageMagick
WORKDIR /opt/build/ImageMagick
ENV \
USER=build \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL \
LD_RUN_PATH=$LD_RUN_PATH:/usr/lib/$TOOL \
LDFLAGS="$LDFLAGS -L/usr/lib/$TOOL -Wl,-rpath-link,/usr/lib/$TOOL" \
CFLAGS="$CFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="$CPPFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \
./configure \
CC=$TOOL-gcc \
CXX=$TOOL-g++ \
--prefix=/imagemagick \
--with-modules \
--enable-shared \
--disable-static \
--without-perl \
--with-xml=yes \
--with-png=yes \
--with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
CC=$TOOL-gcc \
CXX=$TOOL-g++ \
--enable-shared \
--with-modules \
--disable-static \
--disable-docs \
--prefix=/usr/local \
--with-utilities=no \
--without-perl \
--with-xml=yes \
--with-png=yes \
--with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
make
USER root
RUN \
make install && \
ldconfig /imagemagick/lib
ldconfig /usr/local/lib
# Environment for Rust
FROM cross-build as rust
RUN \
apt-get install -y curl
ENV \
PATH=$PATH:/opt/build/.cargo/bin
ADD --chown=build:build https://sh.rustup.rs /opt/build/rustup.sh
USER build
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
USER root
# Environment for pict-rs
FROM cross-build as pict-rs-builder
RUN \
apt-get install -y \
libgexiv2-dev:$ARCH \
libxml2:$ARCH \
libltdl7:$ARCH \
llvm-dev \
libclang-dev \
clang
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \
LD_RUN_PATH=$LD_RUN_PATH:/usr/local/lib \
LDFLAGS="$LDFLAGS -L/usr/local/lib" \
IMAGE_MAGICK_LIB_DIRS=/usr/local/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/usr/local/include/ImageMagick-7 \
CFLAGS="$CFLAGS -I/usr/local/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/usr/local/include/ImageMagick-7" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -L/usr/$TOOL/lib -C link-arg=-Wl,-rpath-link,/usr/$TOOL/lib"
COPY --from=rust --chown=build:build /opt/build/.cargo /opt/build/.cargo
COPY --from=rust --chown=build:build /opt/build/.rustup /opt/build/.rustup
COPY --from=imagemagick-builder /usr/local/ /usr/local
USER build
WORKDIR /opt/build
RUN \
cargo new repo
USER=build cargo new repo
WORKDIR /opt/build/repo
COPY Cargo.toml Cargo.lock ./
USER root
RUN \
chown -R build:build ./
USER build
ENV \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/imagemagick/lib \
LD_RUN_PATH=$LD_RUN_PATH:/imagemagick/lib \
LDFLAGS="$LDFLAGS -L/imagemagick/lib" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL" \
IMAGE_MAGICK_LIB_DIRS=/imagemagick/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/imagemagick/include/ImageMagick-7 \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/imagemagick/lib/pkgconfig \
CFLAGS="$CFLAGS -I/imagemagick/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/imagemagick/include/ImageMagick-7"
COPY --chown=build:build Cargo.toml Cargo.lock ./
RUN \
mkdir -p ./src && \
echo 'fn main() { println!("Dummy") }' > ./src/main.rs && \
cargo build --release && \
rm -rf ./src
USER=build cargo build --$BUILD_MODE && \
rm -rf ./src && \
rm -rf ./target/$BUILD_MODE/deps/pict_rs-*
COPY src ./src/
USER root
RUN \
chown -R build:build ./src && \
rm -r ./target/release/deps/pict_rs-*
USER build
RUN cargo build --release --frozen
FROM ubuntu:20.04
ARG UID=1000
ARG GID=1000
ARG BINARY=pict-rs
ARG TARGET=x86_64-unknown-linux-gnu
COPY --chown=build:build src ./src/
RUN \
cargo build --$BUILD_MODE --frozen
# Producing target binary
FROM target-env
ARG UID=991
ARG GID=991
RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install \
tini \
libgexiv2-2 \
libgomp1 \
libltdl7 && \
addgroup --gid $GID pictrs && \
adduser \
--disabled-password \
--gecos "" \
--ingroup pictrs \
--uid $UID \
--home /opt/pictrs \
pictrs
--home /opt/pict-rs \
pictrs && \
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
libgexiv2-2 \
libpng16-16 \
libjpeg8 \
libwebp6 \
libwebpdemux2 \
libwebpmux3 \
libltdl7 \
libgomp1 \
libxml2 \
tini
COPY --from=builder /imagemagick /imagemagick
COPY --from=builder /opt/build/repo/target/release/$BINARY /usr/bin/$BINARY
COPY --from=pict-rs-builder /opt/build/repo/target/$BUILD_MODE/pict-rs /usr/local/bin/pict-rs
COPY --from=imagemagick-builder /usr/local /usr/local
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
VOLUME /mnt
WORKDIR /opt/pictrs
WORKDIR /opt/pict-rs
USER pictrs
EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/bin/pict-rs", "-p", "/mnt", "-a", "0.0.0.0:8080"]
CMD ["/usr/local/bin/pict-rs", "-p", "/mnt"]

View file

@ -12,6 +12,6 @@ services:
- "127.0.0.1:8080:8080"
restart: always
environment:
- PICTRS_PATH=/app/data
- RUST_LOG=info,pict_rs=debug
volumes:
- ./volumes/pictrs:/mnt

View file

@ -1,8 +1,37 @@
FROM rustembedded/cross:x86_64-unknown-linux-gnu AS x86_64-builder
# Target environment
FROM amd64/ubuntu:20.04 as target-env
ENV \
TARGET=x86_64-unknown-linux-gnu \
BUILD_MODE=release
# Basic cross-build environment
FROM ubuntu:20.04 as cross-build
ENV \
ARCH=amd64 \
HOST=x86_64-unknown-linux \
TOOL=x86_64-linux-gnu \
TARGET=x86_64-unknown-linux-gnu \
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \
CC_X86_64_UNKNOWN_LINUX_GNU=x86_64-linux-gnu-gcc \
CXX_X86_64_UNKNOWN_LINUX_GNU=x86_64-linux-gnu-g++ \
BUILD_MODE=release
ENV \
TOOLCHAIN=stable \
DEBIAN_FRONTEND=noninteractive \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LD_RUN_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LDFLAGS="-L/usr/lib/$TOOL -L/usr/$TOOL/lib -Wl,-rpath-link,/usr/lib/$TOOL -Wl,-rpath-link,/usr/$TOOL/lib" \
CFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \
apt-get update && \
apt-get upgrade -y && \
sed 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch-=amd64,i386] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list > /etc/apt/sources.list.d/ports.list && \
sed -i 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch=amd64,i386] http:\/\/\1.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list && \
addgroup --gid 991 build && \
adduser \
--disabled-password \
@ -10,153 +39,168 @@ RUN \
--ingroup build \
--uid 991 \
--home /opt/build \
build
ADD https://sh.rustup.rs /opt/build/rustup.sh
RUN \
chown -R build:build /opt/build
USER build
WORKDIR /opt/build
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
TOOLCHAIN=stable \
HOST=x86_64-unknown-linux \
TARGET=x86_64-unknown-linux-gnu \
TOOL=x86_64-linux-gnu \
ARCH=amd64
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
FROM x86_64-builder as builder
USER root
ADD https://imagemagick.org/download/ImageMagick.tar.gz ./
RUN \
build && \
dpkg --add-architecture $ARCH && \
apt-get update && \
apt-get -y install \
libgexiv2-dev:$ARCH \
apt-get upgrade -y && \
apt-get install -y \
pkg-config \
build-essential \
crossbuild-essential-$ARCH
WORKDIR /opt/build
# Environment for ImageMagick
FROM cross-build as imagemagick-builder
RUN \
apt-get install -y \
libltdl-dev:$ARCH \
libjpeg-dev:$ARCH \
libpng-dev:$ARCH \
libwebp-dev:$ARCH \
libxml2-dev:$ARCH \
liblzma-dev:$ARCH \
llvm-dev \
libclang-dev \
clang && \
chown build:build ImageMagick.tar.gz
libxml2-dev:$ARCH
ADD --chown=build:build https://imagemagick.org/download/ImageMagick.tar.gz /opt/build/ImageMagick.tar.gz
USER build
RUN \
tar xzf ImageMagick.tar.gz && \
tar zxf ImageMagick.tar.gz && \
mv ImageMagick-* ImageMagick
WORKDIR /opt/build/ImageMagick
ENV \
USER=build \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL \
LD_RUN_PATH=$LD_RUN_PATH:/usr/lib/$TOOL \
LDFLAGS="$LDFLAGS -L/usr/lib/$TOOL -Wl,-rpath-link,/usr/lib/$TOOL" \
CFLAGS="$CFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="$CPPFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \
./configure \
CC=$TOOL-gcc \
CXX=$TOOL-g++ \
--prefix=/imagemagick \
--disable-docs \
--with-modules \
--enable-shared \
--disable-static \
--without-perl \
--with-xml=yes \
--with-png=yes \
--with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
CC=$TOOL-gcc \
CXX=$TOOL-g++ \
--enable-shared \
--with-modules \
--disable-static \
--disable-docs \
--prefix=/usr/local \
--with-utilities=no \
--without-perl \
--with-xml=yes \
--with-png=yes \
--with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
make
USER root
RUN \
make install && \
ldconfig /imagemagick/lib
ldconfig /usr/local/lib
# Environment for Rust
FROM cross-build as rust
RUN \
apt-get install -y curl
ENV \
PATH=$PATH:/opt/build/.cargo/bin
ADD --chown=build:build https://sh.rustup.rs /opt/build/rustup.sh
USER build
WORKDIR /opt/build
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
ARG TAG=master
ARG REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ARG BINARY=pict-rs
USER root
# Environment for pict-rs
FROM cross-build as pict-rs-builder
RUN \
git clone -b $TAG $REPOSITORY repo
WORKDIR /opt/build/repo
apt-get install -y \
libgexiv2-dev:$ARCH \
libxml2:$ARCH \
libltdl7:$ARCH \
llvm-dev \
libclang-dev \
clang
ENV \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/imagemagick/lib \
LD_RUN_PATH=$LD_RUN_PATH:/imagemagick/lib \
LDFLAGS="$LDFLAGS -L/imagemagick/lib" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL" \
IMAGE_MAGICK_LIB_DIRS=/imagemagick/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/imagemagick/include/ImageMagick-7 \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/imagemagick/lib/pkgconfig \
CFLAGS="$CFLAGS -I/imagemagick/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/imagemagick/include/ImageMagick-7"
PATH=$PATH:/opt/build/.cargo/bin \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \
LD_RUN_PATH=$LD_RUN_PATH:/usr/local/lib \
LDFLAGS="$LDFLAGS -L/usr/local/lib" \
IMAGE_MAGICK_LIB_DIRS=/usr/local/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/usr/local/include/ImageMagick-7 \
CFLAGS="$CFLAGS -I/usr/local/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/usr/local/include/ImageMagick-7" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -L/usr/$TOOL/lib -C link-arg=-Wl,-rpath-link,/usr/$TOOL/lib"
COPY --from=rust --chown=build:build /opt/build/.cargo /opt/build/.cargo
COPY --from=rust --chown=build:build /opt/build/.rustup /opt/build/.rustup
COPY --from=imagemagick-builder /usr/local/ /usr/local
ARG TAG=master
ARG GIT_REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ADD --chown=build:build $GIT_REPOSITORY/archive/$TAG.tar.gz /opt/build/$TAG.tar.gz
USER build
RUN \
cargo build --release --target $TARGET && \
$TOOL-strip target/$TARGET/release/$BINARY
tar zxf $TAG.tar.gz
FROM amd64/ubuntu:20.04
WORKDIR /opt/build/pict-rs
RUN \
USER=build cargo build --target=$TARGET --$BUILD_MODE && \
$TOOL-strip /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs
# Producing target binary
FROM target-env
ARG TARGET=x86_64-unknown-linux-gnu
ARG UID=991
ARG GID=991
ARG BINARY=pict-rs
RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install \
tini \
libgexiv2-2 \
libgomp1 \
libltdl7 && \
addgroup --gid $GID pictrs && \
adduser \
--disabled-password \
--gecos "" \
--ingroup pictrs \
--uid $UID \
--home /opt/pictrs \
--home /opt/pict-rs \
pictrs && \
chown -R pictrs:pictrs /mnt
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
libgexiv2-2 \
libpng16-16 \
libjpeg8 \
libwebp6 \
libwebpdemux2 \
libwebpmux3 \
libltdl7 \
libgomp1 \
libxml2 \
tini
COPY --from=builder /imagemagick /imagemagick
COPY --from=builder /opt/build/repo/target/$TARGET/release/$BINARY /usr/bin/$BINARY
COPY --from=pict-rs-builder /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs /usr/local/bin/pict-rs
COPY --from=imagemagick-builder /usr/local /usr/local
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
VOLUME /mnt
WORKDIR /opt/pictrs
WORKDIR /opt/pict-rs
USER pictrs
EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/bin/pict-rs", "-p", "/mnt", "-a", "0.0.0.0:8080", "-w", "thumbnail"]
CMD ["/usr/local/bin/pict-rs", "-p", "/mnt"]

View file

@ -1,8 +1,37 @@
FROM rustembedded/cross:arm-unknown-linux-gnueabihf AS arm32v7-builder
# Target environment
FROM arm32v7/ubuntu:20.04 as target-env
ENV \
TARGET=armv7-unknown-linux-gnueabihf \
BUILD_MODE=release
# Basic cross-build environment
FROM ubuntu:20.04 as cross-build
ENV \
ARCH=armhf \
HOST=arm-unknown-linux \
TOOL=arm-linux-gnueabihf \
TARGET=armv7-unknown-linux-gnueabihf \
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
CC_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
CXX_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \
BUILD_MODE=release
ENV \
TOOLCHAIN=stable \
DEBIAN_FRONTEND=noninteractive \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LD_RUN_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LDFLAGS="-L/usr/lib/$TOOL -L/usr/$TOOL/lib -Wl,-rpath-link,/usr/lib/$TOOL -Wl,-rpath-link,/usr/$TOOL/lib" \
CFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \
apt-get update && \
apt-get upgrade -y && \
sed 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch-=amd64,i386] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list > /etc/apt/sources.list.d/ports.list && \
sed -i 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch=amd64,i386] http:\/\/\1.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list && \
addgroup --gid 991 build && \
adduser \
--disabled-password \
@ -10,156 +39,169 @@ RUN \
--ingroup build \
--uid 991 \
--home /opt/build \
build
ADD https://sh.rustup.rs /opt/build/rustup.sh
RUN \
chown -R build:build /opt/build
USER build
WORKDIR /opt/build
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
TOOLCHAIN=stable \
HOST=arm-unknown-linux \
TARGET=arm-unknown-linux-gnueabihf \
TOOL=arm-linux-gnueabihf \
ARCH=armhf
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
FROM arm32v7-builder as builder
USER root
ADD https://imagemagick.org/download/ImageMagick.tar.gz ./
RUN \
build && \
dpkg --add-architecture $ARCH && \
apt-get update && \
apt-get -y install \
libgexiv2-dev:$ARCH \
apt-get upgrade -y && \
apt-get install -y \
pkg-config \
build-essential \
crossbuild-essential-$ARCH
WORKDIR /opt/build
# Environment for ImageMagick
FROM cross-build as imagemagick-builder
RUN \
apt-get install -y \
libltdl-dev:$ARCH \
libjpeg-dev:$ARCH \
libpng-dev:$ARCH \
libwebp-dev:$ARCH \
libxml2-dev:$ARCH \
liblzma-dev:$ARCH \
libc6-dev-$ARCH-cross \
llvm-dev \
libclang-dev \
clang \
libexpat1-dev:$ARCH && \
chown build:build ImageMagick.tar.gz
libxml2-dev:$ARCH
ADD --chown=build:build https://imagemagick.org/download/ImageMagick.tar.gz /opt/build/ImageMagick.tar.gz
USER build
RUN \
tar xzf ImageMagick.tar.gz && \
tar zxf ImageMagick.tar.gz && \
mv ImageMagick-* ImageMagick
WORKDIR /opt/build/ImageMagick
ENV \
USER=build \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL \
LD_RUN_PATH=$LD_RUN_PATH:/usr/lib/$TOOL \
LDFLAGS="$LDFLAGS -L/lib/$TOOL -L/usr/lib/$TOOL -Wl,-rpath-link,/usr/lib/$TOOL" \
CFLAGS="$CFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="$CPPFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \
./configure \
CC=$TOOL-gcc \
CXX=$TOOL-g++ \
--prefix=/imagemagick \
--disable-docs \
--with-modules \
--enable-shared \
--disable-static \
--without-perl \
--with-xml=yes \
--with-png=yes \
--with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
CC=$TOOL-gcc \
CXX=$TOOL-g++ \
--enable-shared \
--with-modules \
--disable-static \
--disable-docs \
--prefix=/usr/local \
--with-utilities=no \
--without-perl \
--with-xml=yes \
--with-png=yes \
--with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
make
USER root
RUN \
make install && \
ldconfig /imagemagick/lib && \
rm -r /usr/include/x86_64-linux-gnu
ldconfig /usr/local/lib
# Environment for Rust
FROM cross-build as rust
RUN \
apt-get install -y curl
ENV \
PATH=$PATH:/opt/build/.cargo/bin
ADD --chown=build:build https://sh.rustup.rs /opt/build/rustup.sh
USER build
WORKDIR /opt/build
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
ARG TAG=master
ARG REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ARG BINARY=pict-rs
USER root
# Environment for pict-rs
FROM cross-build as pict-rs-builder
RUN \
git clone -b $TAG $REPOSITORY repo
WORKDIR /opt/build/repo
apt-get install -y \
libgexiv2-dev:$ARCH \
libxml2:$ARCH \
libltdl7:$ARCH \
llvm-dev \
libclang-dev \
clang && \
rm -rf /usr/include/x86_64-linux-gnu
ENV \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/imagemagick/lib \
LD_RUN_PATH=$LD_RUN_PATH:/imagemagick/lib \
LDFLAGS="$LDFLAGS -L/imagemagick/lib" \
RUSTFLAGS="-L/usr/lib/$TOOL -L/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/lib/$TOOL" \
IMAGE_MAGICK_LIB_DIRS=/imagemagick/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/imagemagick/include/ImageMagick-7 \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/imagemagick/lib/pkgconfig \
CFLAGS="$CFLAGS -I/imagemagick/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/imagemagick/include/ImageMagick-7"
PATH=$PATH:/opt/build/.cargo/bin \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \
LD_RUN_PATH=$LD_RUN_PATH:/usr/local/lib \
LDFLAGS="$LDFLAGS -L/usr/local/lib" \
IMAGE_MAGICK_LIB_DIRS=/usr/local/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/usr/local/include/ImageMagick-7 \
CFLAGS="$CFLAGS -I/usr/local/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/usr/local/include/ImageMagick-7" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -L/usr/$TOOL/lib -C link-arg=-Wl,-rpath-link,/usr/$TOOL/lib"
COPY --from=rust --chown=build:build /opt/build/.cargo /opt/build/.cargo
COPY --from=rust --chown=build:build /opt/build/.rustup /opt/build/.rustup
COPY --from=imagemagick-builder /usr/local/ /usr/local
ARG TAG=master
ARG GIT_REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ADD --chown=build:build $GIT_REPOSITORY/archive/$TAG.tar.gz /opt/build/$TAG.tar.gz
USER build
RUN \
cargo build --release --target $TARGET && \
$TOOL-strip target/$TARGET/release/$BINARY
tar zxf $TAG.tar.gz
FROM arm32v7/ubuntu:20.04
WORKDIR /opt/build/pict-rs
RUN \
USER=build cargo build --target=$TARGET --$BUILD_MODE && \
$TOOL-strip /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs
# Producing target binary
FROM target-env
ARG TARGET=arm-unknown-linux-gnueabihf
ARG UID=991
ARG GID=991
ARG BINARY=pict-rs
RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install \
tini \
libgexiv2-2 \
libgomp1 \
libltdl7 && \
addgroup --gid $GID pictrs && \
adduser \
--disabled-password \
--gecos "" \
--ingroup pictrs \
--uid $UID \
--home /opt/pictrs \
--home /opt/pict-rs \
pictrs && \
chown -R pictrs:pictrs /mnt
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
libgexiv2-2 \
libpng16-16 \
libjpeg8 \
libwebp6 \
libwebpdemux2 \
libwebpmux3 \
libltdl7 \
libgomp1 \
libxml2 \
tini
COPY --from=builder /imagemagick /imagemagick
COPY --from=builder /opt/build/repo/target/$TARGET/release/$BINARY /usr/bin/$BINARY
COPY --from=pict-rs-builder /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs /usr/local/bin/pict-rs
COPY --from=imagemagick-builder /usr/local /usr/local
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
VOLUME /mnt
WORKDIR /opt/pictrs
WORKDIR /opt/pict-rs
USER pictrs
EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/bin/pict-rs", "-p", "/mnt", "-a", "0.0.0.0:8080", "-w", "thumbnail"]
CMD ["/usr/local/bin/pict-rs", "-p", "/mnt"]

View file

@ -1,8 +1,37 @@
FROM rustembedded/cross:aarch64-unknown-linux-gnu AS aarch64-builder
# Target environment
FROM arm64v8/ubuntu:20.04 as target-env
ENV \
TARGET=aarch64-unknown-linux-gnu \
BUILD_MODE=release
# Basic cross-build environment
FROM ubuntu:20.04 as cross-build
ENV \
ARCH=arm64 \
HOST=aarch64-unknown-linux \
TOOL=aarch64-linux-gnu \
TARGET=aarch64-unknown-linux-gnu \
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
CC_AARCH64_UNKNOWN_LINUX_GNU=aarch64-linux-gnu-gcc \
CXX_AARCH64_UNKNOWN_LINUX_GNU=aarch64-linux-gnu-g++ \
BUILD_MODE=release
ENV \
TOOLCHAIN=stable \
DEBIAN_FRONTEND=noninteractive \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LD_RUN_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LDFLAGS="-L/usr/lib/$TOOL -L/usr/$TOOL/lib -Wl,-rpath-link,/usr/lib/$TOOL -Wl,-rpath-link,/usr/$TOOL/lib" \
CFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \
apt-get update && \
apt-get upgrade -y && \
sed 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch-=amd64,i386] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list > /etc/apt/sources.list.d/ports.list && \
sed -i 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch=amd64,i386] http:\/\/\1.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list && \
addgroup --gid 991 build && \
adduser \
--disabled-password \
@ -10,155 +39,169 @@ RUN \
--ingroup build \
--uid 991 \
--home /opt/build \
build
ADD https://sh.rustup.rs /opt/build/rustup.sh
RUN \
chown -R build:build /opt/build
USER build
WORKDIR /opt/build
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
TOOLCHAIN=stable \
HOST=aarch64-unknown-linux \
TARGET=aarch64-unknown-linux-gnu \
TOOL=aarch64-linux-gnu \
ARCH=arm64
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
FROM aarch64-builder as builder
USER root
ADD https://imagemagick.org/download/ImageMagick.tar.gz ./
RUN \
build && \
dpkg --add-architecture $ARCH && \
apt-get update && \
apt-get -y install \
libgexiv2-dev:$ARCH \
apt-get upgrade -y && \
apt-get install -y \
pkg-config \
build-essential \
crossbuild-essential-$ARCH
WORKDIR /opt/build
# Environment for ImageMagick
FROM cross-build as imagemagick-builder
RUN \
apt-get install -y \
libltdl-dev:$ARCH \
libjpeg-dev:$ARCH \
libpng-dev:$ARCH \
libwebp-dev:$ARCH \
libxml2-dev:$ARCH \
liblzma-dev:$ARCH \
libc6-dev-$ARCH-cross \
llvm-dev \
libclang-dev \
clang && \
chown build:build ImageMagick.tar.gz
libxml2-dev:$ARCH
ADD --chown=build:build https://imagemagick.org/download/ImageMagick.tar.gz /opt/build/ImageMagick.tar.gz
USER build
RUN \
tar xzf ImageMagick.tar.gz && \
tar zxf ImageMagick.tar.gz && \
mv ImageMagick-* ImageMagick
WORKDIR /opt/build/ImageMagick
ENV \
USER=build \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL \
LD_RUN_PATH=$LD_RUN_PATH:/usr/lib/$TOOL \
LDFLAGS="$LDFLAGS -L/usr/lib/$TOOL -Wl,-rpath-link,/usr/lib/$TOOL" \
CFLAGS="$CFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="$CPPFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \
./configure \
CC=$TOOL-gcc \
CXX=$TOOL-g++ \
--prefix=/imagemagick \
--disable-docs \
--with-modules \
--enable-shared \
--disable-static \
--without-perl \
--with-xml=yes \
--with-png=yes \
--with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
CC=$TOOL-gcc \
CXX=$TOOL-g++ \
--enable-shared \
--with-modules \
--disable-static \
--disable-docs \
--prefix=/usr/local \
--with-utilities=no \
--without-perl \
--with-xml=yes \
--with-png=yes \
--with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
make
USER root
RUN \
make install && \
ldconfig /imagemagick/lib && \
rm -r /usr/include/x86_64-linux-gnu
ldconfig /usr/local/lib
# Environment for Rust
FROM cross-build as rust
RUN \
apt-get install -y curl
ENV \
PATH=$PATH:/opt/build/.cargo/bin
ADD --chown=build:build https://sh.rustup.rs /opt/build/rustup.sh
USER build
WORKDIR /opt/build
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
ARG TAG=master
ARG REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ARG BINARY=pict-rs
USER root
# Environment for pict-rs
FROM cross-build as pict-rs-builder
RUN \
git clone -b $TAG $REPOSITORY repo
WORKDIR /opt/build/repo
apt-get install -y \
libgexiv2-dev:$ARCH \
libxml2:$ARCH \
libltdl7:$ARCH \
llvm-dev \
libclang-dev \
clang && \
rm -rf /usr/include/x86_64-linux-gnu
ENV \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/imagemagick/lib \
LD_RUN_PATH=$LD_RUN_PATH:/imagemagick/lib \
LDFLAGS="$LDFLAGS -L/imagemagick/lib" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL" \
IMAGE_MAGICK_LIB_DIRS=/imagemagick/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/imagemagick/include/ImageMagick-7 \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/imagemagick/lib/pkgconfig \
CFLAGS="$CFLAGS -I/imagemagick/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/imagemagick/include/ImageMagick-7"
PATH=$PATH:/opt/build/.cargo/bin \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \
LD_RUN_PATH=$LD_RUN_PATH:/usr/local/lib \
LDFLAGS="$LDFLAGS -L/usr/local/lib" \
IMAGE_MAGICK_LIB_DIRS=/usr/local/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/usr/local/include/ImageMagick-7 \
CFLAGS="$CFLAGS -I/usr/local/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/usr/local/include/ImageMagick-7" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -L/usr/$TOOL/lib -C link-arg=-Wl,-rpath-link,/usr/$TOOL/lib"
COPY --from=rust --chown=build:build /opt/build/.cargo /opt/build/.cargo
COPY --from=rust --chown=build:build /opt/build/.rustup /opt/build/.rustup
COPY --from=imagemagick-builder /usr/local/ /usr/local
ARG TAG=master
ARG GIT_REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ADD --chown=build:build $GIT_REPOSITORY/archive/$TAG.tar.gz /opt/build/$TAG.tar.gz
USER build
RUN \
cargo build --release --target $TARGET && \
$TOOL-strip target/$TARGET/release/$BINARY
tar zxf $TAG.tar.gz
FROM arm64v8/ubuntu:20.04
WORKDIR /opt/build/pict-rs
RUN \
USER=build cargo build --target=$TARGET --$BUILD_MODE && \
$TOOL-strip /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs
# Producing target binary
FROM target-env
ARG TARGET=aarch64-unknown-linux-gnu
ARG UID=991
ARG GID=991
ARG BINARY=pict-rs
RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install \
tini \
libgexiv2-2 \
libgomp1 \
libltdl7 && \
addgroup --gid $GID pictrs && \
adduser \
--disabled-password \
--gecos "" \
--ingroup pictrs \
--uid $UID \
--home /opt/pictrs \
--home /opt/pict-rs \
pictrs && \
chown -R pictrs:pictrs /mnt
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
libgexiv2-2 \
libpng16-16 \
libjpeg8 \
libwebp6 \
libwebpdemux2 \
libwebpmux3 \
libltdl7 \
libgomp1 \
libxml2 \
tini
COPY --from=builder /imagemagick /imagemagick
COPY --from=builder /opt/build/repo/target/$TARGET/release/$BINARY /usr/bin/$BINARY
COPY --from=pict-rs-builder /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs /usr/local/bin/pict-rs
COPY --from=imagemagick-builder /usr/local /usr/local
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
VOLUME /mnt
WORKDIR /opt/pictrs
WORKDIR /opt/pict-rs
USER pictrs
EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/bin/pict-rs", "-p", "/mnt", "-a", "0.0.0.0:8080", "-w", "thumbnail"]
CMD ["/usr/local/bin/pict-rs", "-p", "/mnt"]

View file

@ -30,7 +30,7 @@ pub(crate) struct Config {
short,
long,
env = "PICTRS_FORMAT",
help = "An optional image format to convert all uploaded files into, supports 'jpg' and 'png'"
help = "An optional image format to convert all uploaded files into, supports 'jpg', 'png', and 'webp'"
)]
format: Option<Format>,
@ -88,6 +88,7 @@ pub(crate) struct FormatError(String);
pub(crate) enum Format {
Jpeg,
Png,
Webp,
}
impl std::str::FromStr for Format {
@ -97,6 +98,7 @@ impl std::str::FromStr for Format {
match s {
"png" => Ok(Format::Png),
"jpg" => Ok(Format::Jpeg),
"webp" => Ok(Format::Webp),
other => Err(FormatError(other.to_string())),
}
}

View file

@ -68,6 +68,9 @@ pub(crate) enum UploadError {
#[error("File metadata could not be parsed, {0}")]
Validate(#[from] rexiv2::Rexiv2Error),
#[error("Error in MagickWand, {0}")]
Wand(String),
}
impl From<actix_web::client::SendRequestError> for UploadError {

View file

@ -23,6 +23,7 @@ mod validate;
use self::{
config::Config, error::UploadError, middleware::Tracing, upload_manager::UploadManager,
validate::image_webp,
};
const MEGABYTES: usize = 1024 * 1024;
@ -75,7 +76,7 @@ fn to_ext(mime: mime::Mime) -> &'static str {
} else if mime == mime::IMAGE_GIF {
".gif"
} else {
".bmp"
".webp"
}
}
@ -84,7 +85,7 @@ fn from_ext(ext: std::ffi::OsString) -> mime::Mime {
Some("png") => mime::IMAGE_PNG,
Some("jpg") => mime::IMAGE_JPEG,
Some("gif") => mime::IMAGE_GIF,
_ => mime::IMAGE_BMP,
_ => image_webp(),
}
}

View file

@ -1,13 +1,37 @@
use crate::{config::Format, error::UploadError, upload_manager::tmp_file};
use actix_web::web;
use image::{io::Reader, ImageDecoder, ImageEncoder, ImageFormat};
use image::{io::Reader, ImageFormat};
use magick_rust::MagickWand;
use rexiv2::{MediaType, Metadata};
use std::{
fs::File,
io::{BufReader, BufWriter, Write},
path::PathBuf,
};
use tracing::{debug, instrument, trace, Span};
use tracing::{debug, error, instrument, trace, warn, Span};
pub(crate) trait Op {
fn op<F, T>(&self, f: F) -> Result<T, UploadError>
where
F: Fn(&Self) -> Result<T, &'static str>;
}
impl Op for MagickWand {
fn op<F, T>(&self, f: F) -> Result<T, UploadError>
where
F: Fn(&Self) -> Result<T, &'static str>,
{
match f(self) {
Ok(t) => Ok(t),
Err(e) => {
if let Ok(e) = self.get_exception() {
error!("WandError: {}", e.0);
}
Err(UploadError::Wand(e.to_owned()))
}
}
}
}
#[derive(Debug, thiserror::Error)]
pub(crate) enum GifError {
@ -18,12 +42,21 @@ pub(crate) enum GifError {
Io(#[from] std::io::Error),
}
pub(crate) fn image_webp() -> mime::Mime {
"image/webp".parse().unwrap()
}
fn ptos(p: &PathBuf) -> Result<String, UploadError> {
Ok(p.to_str().ok_or(UploadError::Path)?.to_owned())
}
// import & export image using the image crate
#[instrument]
pub(crate) async fn validate_image(
tmpfile: PathBuf,
prescribed_format: Option<Format>,
) -> Result<mime::Mime, UploadError> {
let tmpfile_str = ptos(&tmpfile)?;
let span = Span::current();
let content_type = web::block(move || {
@ -39,21 +72,54 @@ pub(crate) async fn validate_image(
mime::IMAGE_GIF
}
(Some(Format::Jpeg), MediaType::Jpeg) | (None, MediaType::Jpeg) => {
validate(&tmpfile, ImageFormat::Jpeg)?;
{
let wand = MagickWand::new();
debug!("reading: {}", tmpfile_str);
wand.op(|w| w.read_image(&tmpfile_str))?;
debug!("format: {}", wand.op(|w| w.get_format())?);
}
let meta = Metadata::new_from_path(&tmpfile)?;
meta.clear();
meta.save_to_file(&tmpfile)?;
mime::IMAGE_JPEG
}
(Some(Format::Png), MediaType::Png) | (None, MediaType::Png) => {
validate(&tmpfile, ImageFormat::Png)?;
{
let wand = MagickWand::new();
debug!("reading: {}", tmpfile_str);
wand.op(|w| w.read_image(&tmpfile_str))?;
debug!("format: {}", wand.op(|w| w.get_format())?);
}
let meta = Metadata::new_from_path(&tmpfile)?;
meta.clear();
meta.save_to_file(&tmpfile)?;
mime::IMAGE_PNG
}
(Some(Format::Webp), MediaType::Other(webp)) | (None, MediaType::Other(webp))
if webp == "image/webp" =>
{
{
let wand = MagickWand::new();
debug!("reading: {}", tmpfile_str);
wand.op(|w| w.read_image(&tmpfile_str))?;
debug!("format: {}", wand.op(|w| w.get_format())?);
debug!("type: {}", wand.op(|w| Ok(w.get_type()))?);
debug!("image_type: {}", wand.op(|w| Ok(w.get_image_type()))?);
}
// let meta = Metadata::new_from_path(&tmpfile)?;
// meta.clear();
// meta.save_to_file(&tmpfile)?;
image_webp()
}
(Some(Format::Jpeg), _) => {
let newfile = tmp_file();
convert(&tmpfile, &newfile, ImageFormat::Jpeg)?;
@ -66,13 +132,10 @@ pub(crate) async fn validate_image(
mime::IMAGE_PNG
}
(_, MediaType::Bmp) => {
let newfile = tmp_file();
validate_bmp(&tmpfile, &newfile)?;
mime::IMAGE_BMP
(_, media_type) => {
warn!("Unsupported media type, {}", media_type);
return Err(UploadError::UnsupportedFormat);
}
_ => return Err(UploadError::UnsupportedFormat),
};
drop(entered);
@ -112,20 +175,6 @@ fn validate(path: &PathBuf, format: ImageFormat) -> Result<(), UploadError> {
Ok(())
}
#[instrument]
fn validate_bmp(from: &PathBuf, to: &PathBuf) -> Result<(), UploadError> {
debug!("Transmuting BMP");
let decoder = image::bmp::BmpDecoder::new(BufReader::new(File::open(from)?))?;
let mut writer = BufWriter::new(File::create(to)?);
let encoder = image::bmp::BMPEncoder::new(&mut writer);
validate_still_image(decoder, encoder)?;
writer.flush()?;
std::fs::rename(to, from)?;
Ok(())
}
#[instrument]
fn validate_gif(from: &PathBuf, to: &PathBuf) -> Result<(), GifError> {
debug!("Transmuting GIF");
@ -157,21 +206,3 @@ fn validate_gif(from: &PathBuf, to: &PathBuf) -> Result<(), GifError> {
std::fs::rename(to, from)?;
Ok(())
}
fn validate_still_image<'a, D, E>(decoder: D, encoder: E) -> Result<(), UploadError>
where
D: ImageDecoder<'a>,
E: ImageEncoder,
{
let (width, height) = decoder.dimensions();
let color_type = decoder.color_type();
let total_bytes = decoder.total_bytes();
debug!("Reading image");
let mut decoded_bytes = vec![0u8; total_bytes as usize];
decoder.read_image(&mut decoded_bytes)?;
debug!("Writing image");
encoder.write_image(&decoded_bytes, width, height, color_type)?;
Ok(())
}