mirror of
https://github.com/gen2brain/cbconvert
synced 2026-06-30 17:21:54 +02:00
Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f01e858a24 | |||
| 8c21b430a9 | |||
| 5fbd462a78 | |||
| 0797c8456f | |||
| c3f6c5a499 | |||
| fa162972b2 | |||
| aa65bfa4f4 | |||
| 6c293adc1f | |||
| 6936f697b4 | |||
| 83d7a1ea6e | |||
| 3d56765415 | |||
| b1fcf530da | |||
| 7dc21fc0b4 | |||
| fdfa80875e | |||
| 50b0911586 | |||
| 8db1690d3c | |||
| 91e336f772 | |||
| 903a8bbcfc | |||
| e938b140f0 | |||
| 0a3f4d6992 | |||
| c5902fb131 | |||
| d6ece90041 | |||
| c34b4d0a98 | |||
| f0e2232e51 | |||
| 0ba0337ef8 | |||
| 6e97d977ae | |||
| 685b6bf153 | |||
| 14f2e87525 | |||
| cd2f7501e0 | |||
| 69b0b51010 | |||
| c5494af60b | |||
| f447c618de | |||
| 54261d8528 | |||
| f92125643f | |||
| 7b6c766dcc | |||
| dfea3dc6a3 | |||
| 16d01e292e | |||
| 6fe10f5bdb | |||
| 547a3937a8 | |||
| d47c1c1464 | |||
| 5befff07ae | |||
| d4abc99239 | |||
| f1804ce13c | |||
| a74034d669 | |||
| 64fb152c36 | |||
| 7082e3db90 | |||
| 943cd9bb95 | |||
| ec2c321ff3 | |||
| a0ed277971 | |||
| b5b4457088 | |||
| c24d7b7e18 | |||
| 8ba065e68b | |||
| 9cd5616b48 | |||
| 13a3b6e23e | |||
| 9a047d1977 | |||
| d6e7248112 | |||
| 9eb20db167 | |||
| 04d2dd79d5 | |||
| 2b2788ed6e | |||
| 164e7bfd75 | |||
| 27da60ed76 | |||
| 0963cb1762 | |||
| 443c4e6aaa | |||
| 9da5b97f15 | |||
| adbb86f9f7 | |||
| efb8b776fb | |||
| fa954fce1a | |||
| 7d80f5238e | |||
| 56e07aae23 | |||
| 3c3123a50d | |||
| 2e03350437 | |||
| 1fdc1610f5 | |||
| a5e796d017 | |||
| cffd119eba | |||
| cda03e0122 | |||
| 6a73f6f20e | |||
| 5df10a58ee | |||
| 081736ee04 | |||
| 50f1edb843 | |||
| 2c5bc9e21d | |||
| d9cdf2e197 | |||
| 68e868944b | |||
| 3a84012005 | |||
| 23802d2d00 | |||
| 17e598bb3b | |||
| 2fd32c30e3 | |||
| b930b06a7d | |||
| c8d472e576 | |||
| 6701bfcfb0 | |||
| 6cea1aa441 | |||
| a05b46e6b8 | |||
| d77d2c0ce7 | |||
| bc8520d825 | |||
| 3619ed6c0d |
@@ -0,0 +1,78 @@
|
|||||||
|
on: [push, pull_request]
|
||||||
|
name: Test
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Setup cmake
|
||||||
|
uses: jwlawson/actions-setup-cmake@v1.13
|
||||||
|
with:
|
||||||
|
cmake-version: '3.27.x'
|
||||||
|
|
||||||
|
- name: Wget libaom
|
||||||
|
uses: wei/wget@v1
|
||||||
|
with:
|
||||||
|
args: https://storage.googleapis.com/aom-releases/libaom-3.7.0.tar.gz
|
||||||
|
- name: Unpack libaom
|
||||||
|
run: |
|
||||||
|
tar -xpf libaom-3.7.0.tar.gz && mkdir build
|
||||||
|
- name: Configure libaom
|
||||||
|
working-directory: build
|
||||||
|
run: |
|
||||||
|
cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_DOCS=OFF \
|
||||||
|
-DENABLE_EXAMPLES=OFF -DENABLE_NASM=OFF -DENABLE_TESTS=OFF -DENABLE_TOOLS=OFF -DENABLE_WERROR=OFF \
|
||||||
|
-DAOM_TARGET_CPU=generic ../libaom-3.7.0
|
||||||
|
- name: Install libaom
|
||||||
|
working-directory: build
|
||||||
|
run: |
|
||||||
|
make -j3 && sudo make install
|
||||||
|
|
||||||
|
- name: Wget libheif
|
||||||
|
uses: wei/wget@v1
|
||||||
|
with:
|
||||||
|
args: https://github.com/strukturag/libheif/releases/download/v1.15.2/libheif-1.15.2.tar.gz
|
||||||
|
- name: Unpack libheif
|
||||||
|
run: |
|
||||||
|
tar -xpf libheif-1.15.2.tar.gz
|
||||||
|
- name: Configure libheif
|
||||||
|
working-directory: libheif-1.15.2
|
||||||
|
run: |
|
||||||
|
./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu --enable-shared --disable-static --disable-libde265 \
|
||||||
|
--disable-dav1d --disable-go --enable-aom --disable-gdk-pixbuf --disable-rav1e --disable-tests --disable-x265
|
||||||
|
- name: Install libheif
|
||||||
|
working-directory: libheif-1.15.2
|
||||||
|
run: |
|
||||||
|
make -j3 && sudo make install
|
||||||
|
|
||||||
|
- name: Wget ImageMagick
|
||||||
|
uses: wei/wget@v1
|
||||||
|
with:
|
||||||
|
args: -O ImageMagick-7.1.1-15.tar.gz https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.1-15.tar.gz
|
||||||
|
- name: Unpack ImageMagick
|
||||||
|
run: |
|
||||||
|
tar -xpf ImageMagick-7.1.1-15.tar.gz
|
||||||
|
- name: Configure ImageMagick
|
||||||
|
working-directory: ImageMagick-7.1.1-15
|
||||||
|
run: |
|
||||||
|
./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu --enable-shared --disable-static --enable-zero-configuration \
|
||||||
|
--without-frozenpaths --without-utilities --disable-hdri --disable-opencl --without-modules --without-magick-plus-plus --without-perl \
|
||||||
|
--without-bzlib --without-x --without-zip --with-zlib --without-dps --without-djvu --without-autotrace --without-fftw \
|
||||||
|
--without-fpx --without-fontconfig --without-freetype --without-gslib --without-gvc --without-jbig --without-openjp2 \
|
||||||
|
--without-jxl --without-lcms --without-lqr --without-lzma --without-openexr --without-pango --without-raw \
|
||||||
|
--without-rsvg --without-wmf --without-xml --disable-openmp --with-jpeg --with-heic --with-png --with-tiff --with-webp
|
||||||
|
- name: Install ImageMagick
|
||||||
|
working-directory: ImageMagick-7.1.1-15
|
||||||
|
run: |
|
||||||
|
make -j3 && sudo make install
|
||||||
|
|
||||||
|
- name: Install Go
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.21
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: go test
|
||||||
@@ -1,156 +1,203 @@
|
|||||||
CBconvert
|
## CBconvert
|
||||||
=========
|
|
||||||
|
|
||||||
Introduction
|
### Introduction
|
||||||
------------
|
|
||||||
|
|
||||||
CBconvert is a [Comic Book](http://en.wikipedia.org/wiki/Comic_Book_Archive_file) converter.
|
CBconvert is a [Comic Book](http://en.wikipedia.org/wiki/Comic_Book_Archive_file) converter.
|
||||||
It allows you to convert individual comics or bulk convert comics to different formats to fit your various devices.
|
|
||||||
|
|
||||||
Features
|
It can convert comics to different formats to fit your various devices.
|
||||||
--------
|
|
||||||
|
|
||||||
- reads RAR, ZIP, 7Z, GZ, BZ2, CBR, CBZ, CB7, CBT, PDF, EPUB, XPS and plain directory
|
### Features
|
||||||
- always saves processed comic in CBZ (ZIP) archive format
|
|
||||||
- images can be converted to JPEG, PNG, GIF, TIFF or 4-Bit BMP (16 colors) file format
|
|
||||||
- choose resize algorithm (NearestNeighbor, Box, Linear, MitchellNetravali, CatmullRom, Gaussian, Lanczos)
|
|
||||||
- rotate, flip, adjust brightness/contrast or grayscale images
|
|
||||||
- export covers from comics
|
|
||||||
- create thumbnails from covers by [freedesktop](http://www.freedesktop.org/wiki/) specification
|
|
||||||
|
|
||||||
Download
|
* reads CBR (RAR), CBZ (ZIP), CB7 (7Z), CBT (TAR), PDF, EPUB, MOBI and plain directory
|
||||||
--------
|
* saves processed comics in ZIP archive format or TAR
|
||||||
|
* images can be converted to JPEG, PNG, TIFF, WEBP, AVIF, or 4-Bit BMP (16 colors) file format
|
||||||
|
* rotate, adjust brightness/contrast, adjust levels (Photoshop-like) or grayscale images
|
||||||
|
* resize filters (NearestNeighbor, Box, Linear, MitchellNetravali, CatmullRom, Gaussian, Lanczos)
|
||||||
|
* export covers from comics
|
||||||
|
* create thumbnails from covers by [FreeDesktop](http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html) specification
|
||||||
|
|
||||||
- [Windows binary](https://github.com/gen2brain/cbconvert/releases/download/0.4.0/cbconvert-0.4.0.zip)
|
### Download
|
||||||
|
|
||||||
- [Linux 64bit binary](https://github.com/gen2brain/cbconvert/releases/download/0.4.0/cbconvert-0.4.0.tar.gz)
|
* [Windows x86_64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-0.9.0-windows-x86_64.zip)
|
||||||
- [Linux 64bit static binary](https://github.com/gen2brain/cbconvert/releases/download/0.4.0/cbconvert-0.4.0-static.tar.gz)
|
* [Linux x86_64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-0.9.0-linux-x86_64.tar.gz)
|
||||||
|
* [Linux aarch64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-0.9.0-linux-aarch64.tar.gz)
|
||||||
|
* [macOS x86_64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-0.9.0-darwin-x86_64.zip)
|
||||||
|
* [macOS aarch64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-0.9.0-darwin-aarch64.zip)
|
||||||
|
|
||||||
Using
|
### Using cbconvert in file managers to generate FreeDesktop thumbnails
|
||||||
-----
|
|
||||||
|
|
||||||
usage: cbconvert [<flags>] <command> [<args> ...]
|
Copy cbconvert cli binary to your PATH and create file ~/.local/share/thumbnailers/cbconvert.thumbnailer:
|
||||||
|
|
||||||
Comic Book convert tool.
|
```
|
||||||
|
[Thumbnailer Entry]
|
||||||
|
TryExec=cbconvert
|
||||||
|
Exec=cbconvert thumbnail --quiet --width %s --outfile %o %i
|
||||||
|
MimeType=application/pdf;application/x-cb7;application/x-cbt;application/epub+zip;application/vnd.comicbook-rar;application/vnd.comicbook+zip;application/x-mobipocket-ebook;
|
||||||
|
```
|
||||||
|
|
||||||
Flags:
|
This is what it looks like in the PCManFM file manager:
|
||||||
--help Show context-sensitive help (also try --help-long and --help-man).
|
|
||||||
--version Show application version.
|
|
||||||
--outdir="." Output directory
|
|
||||||
--size=0 Process only files larger then size (in MB)
|
|
||||||
--recursive Process subdirectories recursively
|
|
||||||
--quiet Hide console output
|
|
||||||
|
|
||||||
Args:
|

|
||||||
<args> filename or directory
|
|
||||||
|
|
||||||
Commands:
|
|
||||||
help [<command>...]
|
|
||||||
Show help.
|
|
||||||
|
|
||||||
|
|
||||||
convert [<flags>] <args>...
|
### Using command line app
|
||||||
Convert archive or document (default command)
|
|
||||||
|
|
||||||
--width=0 Image width
|
```
|
||||||
--height=0 Image height
|
Usage: cbconvert <command> [<flags>] [file1 dir1 ... fileOrDirN]
|
||||||
--fit Best fit for required width and height
|
|
||||||
--quality=75 JPEG image quality
|
|
||||||
--filter=2 0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos
|
|
||||||
--png Encode images to PNG instead of JPEG
|
|
||||||
--bmp Encode images to 4-Bit BMP (16 colors) instead of JPEG
|
|
||||||
--gif Encode images to GIF instead of JPEG
|
|
||||||
--tiff Encode images to TIFF instead of JPEG
|
|
||||||
--rgb Convert images that have RGB colorspace (use --no-rgb if you only want to convert grayscale images)
|
|
||||||
--nonimage Leave non image files in archive (use --no-nonimage to remove non image files from archive)
|
|
||||||
--grayscale Convert images to grayscale (monochromatic)
|
|
||||||
--rotate=0 Rotate images, valid values are 0, 90, 180, 270
|
|
||||||
--flip="none" Flip images, valid values are none, horizontal, vertical
|
|
||||||
--brightness=0 Adjust brightness of the images, must be in range (-100, 100)
|
|
||||||
--contrast=0 Adjust contrast of the images, must be in range (-100, 100)
|
|
||||||
--suffix=SUFFIX Add suffix to file basename
|
|
||||||
|
|
||||||
cover [<flags>] <args>...
|
|
||||||
Extract cover
|
|
||||||
|
|
||||||
--width=0 Image width
|
Commands:
|
||||||
--height=0 Image height
|
|
||||||
--fit Best fit for required width and height
|
|
||||||
--quality=75 JPEG image quality
|
|
||||||
--filter=2 0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos
|
|
||||||
|
|
||||||
thumbnail [<flags>] <args>...
|
convert
|
||||||
Extract cover thumbnail (freedesktop spec.)
|
Convert archive or document
|
||||||
|
|
||||||
--width=0 Image width
|
--width
|
||||||
--height=0 Image height
|
Image width (default "0")
|
||||||
--fit Best fit for required width and height
|
--height
|
||||||
--filter=2 0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos
|
Image height (default "0")
|
||||||
|
--fit
|
||||||
|
Best fit for required width and height (default "false")
|
||||||
|
--format
|
||||||
|
Image format, valid values are jpeg, png, tiff, bmp, webp, avif (default "jpeg")
|
||||||
|
--archive
|
||||||
|
Archive format, valid values are zip, tar (default "zip")
|
||||||
|
--quality
|
||||||
|
Image quality (default "75")
|
||||||
|
--lossless
|
||||||
|
Lossless compression (avif) (default "false")
|
||||||
|
--filter
|
||||||
|
0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos (default "2")
|
||||||
|
--no-cover
|
||||||
|
Do not convert the cover image (default "false")
|
||||||
|
--no-rgb
|
||||||
|
Do not convert images that have RGB colorspace (default "false")
|
||||||
|
--no-nonimage
|
||||||
|
Remove non-image files from the archive (default "false")
|
||||||
|
--no-convert
|
||||||
|
Do not transform or convert images (default "false")
|
||||||
|
--grayscale
|
||||||
|
Convert images to grayscale (monochromatic) (default "false")
|
||||||
|
--rotate
|
||||||
|
Rotate images, valid values are 0, 90, 180, 270 (default "0")
|
||||||
|
--brightness
|
||||||
|
Adjust the brightness of the images, must be in the range (-100, 100) (default "0")
|
||||||
|
--contrast
|
||||||
|
Adjust the contrast of the images, must be in the range (-100, 100) (default "0")
|
||||||
|
--suffix
|
||||||
|
Add suffix to file basename (default "")
|
||||||
|
--levels-inmin
|
||||||
|
Shadow input value (default "0")
|
||||||
|
--levels-gamma
|
||||||
|
Midpoint/Gamma (default "1")
|
||||||
|
--levels-inmax
|
||||||
|
Highlight input value (default "255")
|
||||||
|
--levels-outmin
|
||||||
|
Shadow output value (default "0")
|
||||||
|
--levels-outmax
|
||||||
|
Highlight output value (default "255")
|
||||||
|
--outdir
|
||||||
|
Output directory (default ".")
|
||||||
|
--size
|
||||||
|
Process only files larger than size (in MB) (default "0")
|
||||||
|
--recursive
|
||||||
|
Process subdirectories recursively (default "false")
|
||||||
|
--quiet
|
||||||
|
Hide console output (default "false")
|
||||||
|
|
||||||
[man page](https://en.wikipedia.org/wiki/Man_page) is also available:
|
cover
|
||||||
|
Extract cover
|
||||||
|
|
||||||
cbconvert --help-man | man /dev/stdin
|
--width
|
||||||
|
Image width (default "0")
|
||||||
|
--height
|
||||||
|
Image height (default "0")
|
||||||
|
--fit
|
||||||
|
Best fit for required width and height (default "false")
|
||||||
|
--format
|
||||||
|
Image format, valid values are jpeg, png, tiff, bmp, webp, avif (default "jpeg")
|
||||||
|
--quality
|
||||||
|
Image quality (default "75")
|
||||||
|
--filter
|
||||||
|
0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos (default "2")
|
||||||
|
--outdir
|
||||||
|
Output directory (default ".")
|
||||||
|
--size
|
||||||
|
Process only files larger than size (in MB) (default "0")
|
||||||
|
--recursive
|
||||||
|
Process subdirectories recursively (default "false")
|
||||||
|
--quiet
|
||||||
|
Hide console output (default "false")
|
||||||
|
|
||||||
Examples
|
thumbnail
|
||||||
--------
|
Extract cover thumbnail (freedesktop spec.)
|
||||||
|
|
||||||
Rescale images to 1200px for all supported files found in directory with size larger then 60MB:
|
--width
|
||||||
|
Image width (default "0")
|
||||||
|
--height
|
||||||
|
Image height (default "0")
|
||||||
|
--fit
|
||||||
|
Best fit for required width and height (default "false")
|
||||||
|
--filter
|
||||||
|
0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos (default "2")
|
||||||
|
--outdir
|
||||||
|
Output directory (default ".")
|
||||||
|
--outfile
|
||||||
|
Output file (default "")
|
||||||
|
--size
|
||||||
|
Process only files larger than size (in MB) (default "0")
|
||||||
|
--recursive
|
||||||
|
Process subdirectories recursively (default "false")
|
||||||
|
--quiet
|
||||||
|
Hide console output (default "false")
|
||||||
|
|
||||||
cbconvert --recursive --width 1200 --size 60 /media/comics/Thorgal/
|
meta
|
||||||
|
CBZ metadata
|
||||||
|
|
||||||
Convert all images in pdf to 4bit BMP image and save result in ~/comics directory:
|
--cover
|
||||||
|
Print cover name (default "false")
|
||||||
|
--comment
|
||||||
|
Print zip comment (default "false")
|
||||||
|
--comment-body
|
||||||
|
Set zip comment (default "")
|
||||||
|
--file-add
|
||||||
|
Add file to archive (default "")
|
||||||
|
--file-remove
|
||||||
|
Remove file(s) from archive (glob pattern, i.e. *.xml) (default "")
|
||||||
|
|
||||||
cbconvert --bmp --outdir ~/comics /media/comics/Garfield/Garfield_01.pdf
|
```
|
||||||
|
|
||||||
[BMP](http://en.wikipedia.org/wiki/BMP_file_format) format is very good choice for black&white pages. Archive size can be smaller 2-3x and file will be readable by comic readers.
|
### Examples
|
||||||
|
|
||||||
Generate thumbnails by freedesktop specification in ~/.thumbnails/normal directory with width 512:
|
* Rescale images to 1200px for all supported files found in a directory with a size larger than 60MB:
|
||||||
|
|
||||||
cbconvert thumbnail --width 512 --outdir ~/.thumbnails/normal /media/comics/GrooTheWanderer/
|
`cbconvert --recursive --width 1200 --size 60 /media/comics/Thorgal/`
|
||||||
|
|
||||||
Extract covers to ~/covers dir for all supported files found in directory, Lanczos algorithm is used for resizing:
|
* Convert all images in pdf to 4bit BMP images and save the result in ~/comics directory:
|
||||||
|
|
||||||
cbconvert cover --outdir ~/covers --filter=7 /media/comics/GrooTheWanderer/
|
`cbconvert --format bmp --outdir ~/comics /media/comics/Garfield/Garfield_01.pdf`
|
||||||
|
|
||||||
Compile
|
[BMP](http://en.wikipedia.org/wiki/BMP_file_format) format is a very good choice for black&white pages. Archive size can be smaller 2-3x and the file will be readable by comic readers.
|
||||||
-------
|
|
||||||
|
|
||||||
Install imagemagick dev packages:
|
* Extract covers to ~/covers dir for all supported files found in the directory, Lanczos algorithm is used for resizing:
|
||||||
|
|
||||||
apt-get install libmagickcore-dev libmagickwand-dev
|
`cbconvert cover --outdir ~/covers --filter=7 /media/comics/GrooTheWanderer/`
|
||||||
|
|
||||||
Compile latest MuPDF:
|
* Convert all images to AVIF format:
|
||||||
|
|
||||||
git clone git://git.ghostscript.com/mupdf.git && cd mupdf
|
`cbconvert --format avif --quality 50 --width 1280 --outdir ~/comics /media/comics/Misc/`
|
||||||
git submodule update --init --recursive
|
|
||||||
curl -L https://gist.githubusercontent.com/gen2brain/7869ac4c6db5933f670f/raw/1619394dc957ae10bcd73c713760993466b4bfea/mupdf-openssl-curl.patch | patch -p1
|
|
||||||
sed -e "1iHAVE_X11 = no" -e "1iWANT_OPENSSL = no" -e "1iWANT_CURL = no" -i Makerules
|
|
||||||
HAVE_X11=no HAVE_GLFW=no HAVE_GLUT=no WANT_OPENSSL=no WANT_CURL=no HAVE_MUJS=yes HAVE_JSCORE=no HAVE_V8=no make && make install
|
|
||||||
|
|
||||||
Compile unarr library:
|
### Quality settings
|
||||||
|
|
||||||
git clone https://github.com/zeniko/unarr && cd unarr
|
This table maps quality settings for JPEG to the respective AVIF and WEBP quality settings:
|
||||||
mkdir lzma920 && cd lzma920 && curl -L http://www.7-zip.org/a/lzma920.tar.bz2 | tar -xjvp && cd ..
|
|
||||||
curl -L http://zlib.net/zlib-1.2.8.tar.gz | tar -xzvp
|
|
||||||
curl -L http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz | tar -xzvp
|
|
||||||
curl -L https://gist.githubusercontent.com/gen2brain/89fe506863be3fb139e8/raw/8783a7d81e22ad84944d146c5e33beab6dffc641/unarr-makefile.patch | patch -p1
|
|
||||||
CFLAGS="-DHAVE_7Z -DHAVE_ZLIB -DHAVE_BZIP2 -I./lzma920/C -I./zlib-1.2.8 -I./bzip2-1.0.6" make
|
|
||||||
cp build/debug/libunarr.a /usr/lib64/ && cp unarr.h /usr/include
|
|
||||||
|
|
||||||
Install dependencies:
|
| | | | | |
|
||||||
|
|--------------|----|----|----|----|
|
||||||
|
| JPEG quality | 50 | 60 | 70 | 80 |
|
||||||
|
| AVIF quality | 48 | 51 | 56 | 64 |
|
||||||
|
| WEBP quality | 55 | 64 | 72 | 82 |
|
||||||
|
|
||||||
go get github.com/cheggaaa/pb
|
### Compile
|
||||||
go get github.com/disintegration/imaging
|
|
||||||
go get github.com/gen2brain/go-fitz
|
|
||||||
go get github.com/gen2brain/go-unarr
|
|
||||||
go get github.com/gographics/imagick/imagick
|
|
||||||
go get github.com/hotei/bmp
|
|
||||||
go get github.com/skarademir/naturalsort
|
|
||||||
go get golang.org/x/image/tiff
|
|
||||||
go get golang.org/x/image/webp
|
|
||||||
go get gopkg.in/alecthomas/kingpin.v2
|
|
||||||
|
|
||||||
Install go package:
|
Install ImageMagick7, MuPDF and libheif (with libaom) libraries and headers and then install to GOBIN:
|
||||||
|
|
||||||
go get github.com/gen2brain/cbconvert
|
`go install -tags extlib github.com/gen2brain/cbconvert/cmd/cbconvert@latest`
|
||||||
go install github.com/gen2brain/cbconvert
|
|
||||||
|
|||||||
+1703
-847
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,117 @@
|
|||||||
|
package cbconvert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConvert(t *testing.T) {
|
||||||
|
tmpDir, err := os.MkdirTemp(os.TempDir(), "cbc")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := Options{}
|
||||||
|
opts.OutDir = tmpDir
|
||||||
|
opts.Archive = "zip"
|
||||||
|
opts.Quality = 75
|
||||||
|
opts.Filter = 2
|
||||||
|
|
||||||
|
conv := New(opts)
|
||||||
|
|
||||||
|
conv.Initialize()
|
||||||
|
defer conv.Terminate()
|
||||||
|
|
||||||
|
files, err := conv.Files([]string{"testdata/test", "testdata"})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, format := range []string{"jpeg", "png", "tiff", "bmp", "webp", "avif"} {
|
||||||
|
conv.Opts.Format = format
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
conv.Opts.Suffix = fmt.Sprintf("_%s%s", format, filepath.Ext(file.Path))
|
||||||
|
|
||||||
|
err = conv.Convert(file.Path, file.Stat)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("format %s: file %s: %v", format, file.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.RemoveAll(tmpDir)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCover(t *testing.T) {
|
||||||
|
tmpDir, err := os.MkdirTemp(os.TempDir(), "cbc")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := Options{}
|
||||||
|
opts.OutDir = tmpDir
|
||||||
|
opts.Quality = 75
|
||||||
|
opts.Filter = 2
|
||||||
|
opts.Format = "jpeg"
|
||||||
|
|
||||||
|
conv := New(opts)
|
||||||
|
|
||||||
|
conv.Initialize()
|
||||||
|
defer conv.Terminate()
|
||||||
|
|
||||||
|
files, err := conv.Files([]string{"testdata/test.cbt"})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
err = conv.Cover(file.Path, file.Stat)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.RemoveAll(tmpDir)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestThumbnail(t *testing.T) {
|
||||||
|
tmpDir, err := os.MkdirTemp(os.TempDir(), "cbc")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := Options{}
|
||||||
|
opts.OutDir = tmpDir
|
||||||
|
opts.Filter = 2
|
||||||
|
|
||||||
|
conv := New(opts)
|
||||||
|
|
||||||
|
conv.Initialize()
|
||||||
|
defer conv.Terminate()
|
||||||
|
|
||||||
|
files, err := conv.Files([]string{"testdata/test.pdf"})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
err = conv.Thumbnail(file.Path, file.Stat)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.RemoveAll(tmpDir)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
module github.com/gen2brain/cbconvert/cmd/cbconvert
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
toolchain go1.21.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gen2brain/cbconvert v0.0.0-20230902080208-6936f697b466
|
||||||
|
github.com/schollz/progressbar/v3 v3.10.0
|
||||||
|
github.com/spf13/pflag v1.0.5
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/chai2010/webp v1.1.1 // indirect
|
||||||
|
github.com/disintegration/imaging v1.6.2 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/fvbommel/sortorder v1.1.0 // indirect
|
||||||
|
github.com/gen2brain/go-fitz v1.23.1 // indirect
|
||||||
|
github.com/gen2brain/go-unarr v0.1.7 // indirect
|
||||||
|
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||||
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||||
|
github.com/rivo/uniseg v0.3.4 // indirect
|
||||||
|
github.com/strukturag/libheif v1.15.2 // indirect
|
||||||
|
golang.org/x/image v0.11.0 // indirect
|
||||||
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.5.0 // indirect
|
||||||
|
golang.org/x/term v0.5.0 // indirect
|
||||||
|
gopkg.in/gographics/imagick.v3 v3.4.3 // indirect
|
||||||
|
)
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
|
||||||
|
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
|
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||||
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
|
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
|
||||||
|
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||||
|
github.com/gen2brain/cbconvert v0.0.0-20230902080208-6936f697b466 h1:xrc1+L/Wc9BHokp+smaBt/A2R2+nfK0Ws0cvyzTHE7I=
|
||||||
|
github.com/gen2brain/cbconvert v0.0.0-20230902080208-6936f697b466/go.mod h1:5CIPgEHKNZtfH7FR0zzGMAzkFwagUyH7FcjIUDEx7Ps=
|
||||||
|
github.com/gen2brain/go-fitz v1.23.1 h1:x69/szWZXpI3jZ57mMqCg7WqqvtYnQG0lXts3L6M1Fc=
|
||||||
|
github.com/gen2brain/go-fitz v1.23.1/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ=
|
||||||
|
github.com/gen2brain/go-unarr v0.1.7 h1:mEE7bPShJIsmAX67t6BW2ibpEUO7j5WK152KgNM9NbQ=
|
||||||
|
github.com/gen2brain/go-unarr v0.1.7/go.mod h1:MK9a3hddpaIxjEtrE1f/LA5yJ7gA34cS7Oyr325sY9s=
|
||||||
|
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7 h1:NlUATi3cllRJhpM4mfR9BxiLRXT83bcSLcOa+S8lrME=
|
||||||
|
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7/go.mod h1:Hku3FQ2laCEwSv7Z8YkC0er38jLaUycUCbsFkWMr+z4=
|
||||||
|
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||||
|
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
||||||
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
|
||||||
|
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
|
github.com/schollz/progressbar/v3 v3.10.0 h1:pOab0roS2jf6zkEBKAe9EyEdmRKJvhbbuxqVp9/Qjyw=
|
||||||
|
github.com/schollz/progressbar/v3 v3.10.0/go.mod h1:0N6zRwbDVLFCFy5chxuukVlRkoHWYFFLzlxQrw/sf3M=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/strukturag/libheif v1.15.2 h1:pgdcpDHqtLKRXL9ETSTeht0CsJODB3BojpTsb3S/3Wg=
|
||||||
|
github.com/strukturag/libheif v1.15.2/go.mod h1:E/PNRlmVtrtj9j2AvBZlrO4dsBDu6KfwDZn7X1Ce8Ks=
|
||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||||
|
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||||
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/gographics/imagick.v3 v3.4.3 h1:9plKFE/Us913jBN6KohtLG9FNW8LPvfpjiGAORIiEHg=
|
||||||
|
gopkg.in/gographics/imagick.v3 v3.4.3/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
|
||||||
@@ -0,0 +1,330 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime/debug"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/gen2brain/cbconvert"
|
||||||
|
pb "github.com/schollz/progressbar/v3"
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
var appVersion string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if appVersion != "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.Main.Version != "" {
|
||||||
|
appVersion = info.Main.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, kv := range info.Settings {
|
||||||
|
if kv.Value == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if kv.Key == "vcs.revision" {
|
||||||
|
appVersion = kv.Value
|
||||||
|
if len(appVersion) > 10 {
|
||||||
|
appVersion = kv.Value[:10]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
opts, args := parseFlags()
|
||||||
|
|
||||||
|
if opts.Version {
|
||||||
|
fmt.Println(filepath.Base(os.Args[0]), appVersion)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
conv := cbconvert.New(opts)
|
||||||
|
|
||||||
|
c := make(chan os.Signal, 2)
|
||||||
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
|
go func() {
|
||||||
|
for range c {
|
||||||
|
fmt.Println("\naborting")
|
||||||
|
if err := os.RemoveAll(conv.Workdir); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if _, err := os.Stat(opts.OutDir); err != nil {
|
||||||
|
if err := os.MkdirAll(opts.OutDir, 0775); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
conv.Initialize()
|
||||||
|
defer conv.Terminate()
|
||||||
|
|
||||||
|
files, err := conv.Files(args)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bar *pb.ProgressBar
|
||||||
|
if opts.Cover || opts.Thumbnail || opts.Meta {
|
||||||
|
if !opts.Quiet {
|
||||||
|
bar = pb.NewOptions(conv.Nfiles,
|
||||||
|
pb.OptionShowCount(),
|
||||||
|
pb.OptionClearOnFinish(),
|
||||||
|
pb.OptionUseANSICodes(true),
|
||||||
|
pb.OptionSetPredictTime(false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conv.OnStart = func() {
|
||||||
|
if !opts.Quiet {
|
||||||
|
bar = pb.NewOptions(conv.Ncontents,
|
||||||
|
pb.OptionShowCount(),
|
||||||
|
pb.OptionClearOnFinish(),
|
||||||
|
pb.OptionUseANSICodes(true),
|
||||||
|
pb.OptionSetDescription(fmt.Sprintf("Converting %d of %d:", conv.CurrFile, conv.Nfiles)),
|
||||||
|
pb.OptionSetPredictTime(false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conv.OnProgress = func() {
|
||||||
|
if !opts.Quiet {
|
||||||
|
_ = bar.Add(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conv.OnCompress = func() {
|
||||||
|
if !opts.Quiet {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "Compressing %d of %d...\r", conv.CurrFile, conv.Nfiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
switch {
|
||||||
|
case opts.Meta:
|
||||||
|
ret, err := conv.Meta(file.Path)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Cover {
|
||||||
|
fmt.Println(ret)
|
||||||
|
} else if opts.Comment {
|
||||||
|
fmt.Println(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
case opts.Cover:
|
||||||
|
if err := conv.Cover(file.Path, file.Stat); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
case opts.Thumbnail:
|
||||||
|
if err = conv.Thumbnail(file.Path, file.Stat); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := conv.Convert(file.Path, file.Stat); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "\r")
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseFlags parses command line flags.
|
||||||
|
func parseFlags() (cbconvert.Options, []string) {
|
||||||
|
opts := cbconvert.Options{}
|
||||||
|
var args []string
|
||||||
|
|
||||||
|
convert := flag.NewFlagSet("convert", flag.ExitOnError)
|
||||||
|
convert.SortFlags = false
|
||||||
|
convert.IntVar(&opts.Width, "width", 0, "Image width")
|
||||||
|
convert.IntVar(&opts.Height, "height", 0, "Image height")
|
||||||
|
convert.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
|
||||||
|
convert.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif")
|
||||||
|
convert.StringVar(&opts.Archive, "archive", "zip", "Archive format, valid values are zip, tar")
|
||||||
|
convert.IntVar(&opts.Quality, "quality", 75, "Image quality")
|
||||||
|
convert.BoolVar(&opts.Lossless, "lossless", false, "Lossless compression (avif)")
|
||||||
|
convert.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
|
||||||
|
convert.BoolVar(&opts.NoCover, "no-cover", false, "Do not convert the cover image")
|
||||||
|
convert.BoolVar(&opts.NoRGB, "no-rgb", false, "Do not convert images that have RGB colorspace")
|
||||||
|
convert.BoolVar(&opts.NoNonImage, "no-nonimage", false, "Remove non-image files from the archive")
|
||||||
|
convert.BoolVar(&opts.NoConvert, "no-convert", false, "Do not transform or convert images")
|
||||||
|
convert.BoolVar(&opts.Grayscale, "grayscale", false, "Convert images to grayscale (monochromatic)")
|
||||||
|
convert.IntVar(&opts.Rotate, "rotate", 0, "Rotate images, valid values are 0, 90, 180, 270")
|
||||||
|
convert.IntVar(&opts.Brightness, "brightness", 0, "Adjust the brightness of the images, must be in the range (-100, 100)")
|
||||||
|
convert.IntVar(&opts.Contrast, "contrast", 0, "Adjust the contrast of the images, must be in the range (-100, 100)")
|
||||||
|
convert.StringVar(&opts.Suffix, "suffix", "", "Add suffix to file basename")
|
||||||
|
convert.IntVar(&opts.LevelsInMin, "levels-inmin", 0, "Shadow input value")
|
||||||
|
convert.Float64Var(&opts.LevelsGamma, "levels-gamma", 1.0, "Midpoint/Gamma")
|
||||||
|
convert.IntVar(&opts.LevelsInMax, "levels-inmax", 255, "Highlight input value")
|
||||||
|
convert.IntVar(&opts.LevelsOutMin, "levels-outmin", 0, "Shadow output value")
|
||||||
|
convert.IntVar(&opts.LevelsOutMax, "levels-outmax", 255, "Highlight output value")
|
||||||
|
convert.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
|
||||||
|
convert.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
|
||||||
|
convert.BoolVar(&opts.Recursive, "recursive", false, "Process subdirectories recursively")
|
||||||
|
convert.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
|
||||||
|
|
||||||
|
cover := flag.NewFlagSet("cover", flag.ExitOnError)
|
||||||
|
cover.SortFlags = false
|
||||||
|
cover.IntVar(&opts.Width, "width", 0, "Image width")
|
||||||
|
cover.IntVar(&opts.Height, "height", 0, "Image height")
|
||||||
|
cover.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
|
||||||
|
cover.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif")
|
||||||
|
cover.IntVar(&opts.Quality, "quality", 75, "Image quality")
|
||||||
|
cover.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
|
||||||
|
cover.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
|
||||||
|
cover.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
|
||||||
|
cover.BoolVar(&opts.Recursive, "recursive", false, "Process subdirectories recursively")
|
||||||
|
cover.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
|
||||||
|
|
||||||
|
thumbnail := flag.NewFlagSet("thumbnail", flag.ExitOnError)
|
||||||
|
thumbnail.SortFlags = false
|
||||||
|
thumbnail.IntVar(&opts.Width, "width", 0, "Image width")
|
||||||
|
thumbnail.IntVar(&opts.Height, "height", 0, "Image height")
|
||||||
|
thumbnail.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
|
||||||
|
thumbnail.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
|
||||||
|
thumbnail.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
|
||||||
|
thumbnail.StringVar(&opts.OutFile, "outfile", "", "Output file")
|
||||||
|
thumbnail.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
|
||||||
|
thumbnail.BoolVar(&opts.Recursive, "recursive", false, "Process subdirectories recursively")
|
||||||
|
thumbnail.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
|
||||||
|
|
||||||
|
meta := flag.NewFlagSet("meta", flag.ExitOnError)
|
||||||
|
meta.SortFlags = false
|
||||||
|
meta.BoolVar(&opts.Cover, "cover", false, "Print cover name")
|
||||||
|
meta.BoolVar(&opts.Comment, "comment", false, "Print zip comment")
|
||||||
|
meta.StringVar(&opts.CommentBody, "comment-body", "", "Set zip comment")
|
||||||
|
meta.StringVar(&opts.FileAdd, "file-add", "", "Add file to archive")
|
||||||
|
meta.StringVar(&opts.FileRemove, "file-remove", "", "Remove file from archive (glob pattern, i.e. *.xml)")
|
||||||
|
|
||||||
|
flag.NewFlagSet("version", flag.ExitOnError)
|
||||||
|
|
||||||
|
flag.Usage = func() {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "Usage: %s <command> [<flags>] [file1 dir1 ... fileOrDirN]\n\n", filepath.Base(os.Args[0]))
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "\nCommands:\n")
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "\n convert\n \tConvert archive or document\n\n")
|
||||||
|
convert.VisitAll(func(f *flag.Flag) {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
|
})
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n")
|
||||||
|
cover.VisitAll(func(f *flag.Flag) {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
|
})
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "\n thumbnail\n \tExtract cover thumbnail (freedesktop spec.)\n\n")
|
||||||
|
thumbnail.VisitAll(func(f *flag.Flag) {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
|
})
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "\n meta\n \tCBZ metadata\n\n")
|
||||||
|
meta.VisitAll(func(f *flag.Flag) {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
|
})
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "\n version\n \tPrint version\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
convert.Usage()
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "no command\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe := piped()
|
||||||
|
if pipe {
|
||||||
|
args = lines(os.Stdin)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch os.Args[1] {
|
||||||
|
case "convert":
|
||||||
|
_ = convert.Parse(os.Args[2:])
|
||||||
|
if !pipe {
|
||||||
|
args = convert.Args()
|
||||||
|
}
|
||||||
|
case "cover":
|
||||||
|
opts.Cover = true
|
||||||
|
_ = cover.Parse(os.Args[2:])
|
||||||
|
if !pipe {
|
||||||
|
args = cover.Args()
|
||||||
|
}
|
||||||
|
case "thumbnail":
|
||||||
|
opts.Thumbnail = true
|
||||||
|
_ = thumbnail.Parse(os.Args[2:])
|
||||||
|
if !pipe {
|
||||||
|
args = thumbnail.Args()
|
||||||
|
}
|
||||||
|
case "meta":
|
||||||
|
opts.Meta = true
|
||||||
|
_ = meta.Parse(os.Args[2:])
|
||||||
|
if !pipe {
|
||||||
|
args = meta.Args()
|
||||||
|
}
|
||||||
|
case "version":
|
||||||
|
opts.Version = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) == 0 && !opts.Version {
|
||||||
|
flag.Usage()
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "no arguments\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts, args
|
||||||
|
}
|
||||||
|
|
||||||
|
// piped checks if we have a piped stdin.
|
||||||
|
func piped() bool {
|
||||||
|
f, err := os.Stdin.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.Mode()&os.ModeNamedPipe == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// lines returns slice of lines from reader.
|
||||||
|
func lines(r io.Reader) []string {
|
||||||
|
data := make([]string, 0)
|
||||||
|
scanner := bufio.NewScanner(r)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
text := scanner.Text()
|
||||||
|
data = append(data, text)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
Executable
+73
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
GLIBC_x86_64="/usr/x86_64-pc-linux-gnu-static"
|
||||||
|
MUSL_aarch64="/usr/aarch64-pc-linux-musl"
|
||||||
|
MINGW_x86_64="/usr/x86_64-w64-mingw32"
|
||||||
|
MACOS_x86_64="/usr/x86_64-apple-darwin"
|
||||||
|
MACOS_aarch64="/usr/aarch64-apple-darwin"
|
||||||
|
|
||||||
|
VERSION="`git --git-dir ../../.git describe --tags --abbrev=0 2>/dev/null || echo '0.0.0'`"
|
||||||
|
|
||||||
|
BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR}
|
||||||
|
CC=x86_64-pc-linux-gnu-gcc \
|
||||||
|
PKG_CONFIG="x86_64-pc-linux-gnu-pkg-config" \
|
||||||
|
PKG_CONFIG_PATH="$GLIBC_x86_64/usr/lib64/pkgconfig" \
|
||||||
|
PKG_CONFIG_LIBDIR="$GLIBC_x86_64/usr/lib64/pkgconfig" \
|
||||||
|
CGO_CFLAGS="-I$GLIBC_x86_64/usr/include" \
|
||||||
|
CGO_LDFLAGS="-L$GLIBC_x86_64/usr/lib64" \
|
||||||
|
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \
|
||||||
|
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert -ldflags "-linkmode external -s -w -X main.appVersion=${VERSION} '-extldflags=-static'" && \
|
||||||
|
cp ../../README.md ../../AUTHORS ../../COPYING ${BUILDDIR} && tar -czf "${BUILDDIR}-linux-x86_64.tar.gz" ${BUILDDIR}
|
||||||
|
rm -rf ${BUILDDIR}
|
||||||
|
|
||||||
|
BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR}
|
||||||
|
CC=aarch64-pc-linux-musl-gcc \
|
||||||
|
PKG_CONFIG="aarch64-pc-linux-musl-pkg-config" \
|
||||||
|
PKG_CONFIG_PATH="$MUSL_aarch64/usr/lib/pkgconfig" \
|
||||||
|
PKG_CONFIG_LIBDIR="$MUSL_aarch64/usr/lib/pkgconfig" \
|
||||||
|
CGO_CFLAGS="-I$MUSL_aarch64/usr/include" \
|
||||||
|
CGO_LDFLAGS="-L$MUSL_aarch64/usr/lib" \
|
||||||
|
CGO_ENABLED=1 GOOS=linux GOARCH=arm64 \
|
||||||
|
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert -ldflags "-linkmode external -s -w -X main.appVersion=${VERSION} '-extldflags=-static'" && \
|
||||||
|
cp ../../README.md ../../AUTHORS ../../COPYING ${BUILDDIR} && tar -czf "${BUILDDIR}-linux-aarch64.tar.gz" ${BUILDDIR}
|
||||||
|
rm -rf ${BUILDDIR}
|
||||||
|
|
||||||
|
BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR}
|
||||||
|
CC=x86_64-w64-mingw32-gcc \
|
||||||
|
PKG_CONFIG="/usr/bin/x86_64-w64-mingw32-pkg-config" \
|
||||||
|
PKG_CONFIG_PATH="$MINGW_x86_64/usr/lib/pkgconfig" \
|
||||||
|
PKG_CONFIG_LIBDIR="$MINGW_x86_64/usr/lib/pkgconfig" \
|
||||||
|
CGO_CFLAGS="-I$MINGW_x86_64/usr/include" \
|
||||||
|
CGO_LDFLAGS="-L$MINGW_x86_64/usr/lib" \
|
||||||
|
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 \
|
||||||
|
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert.exe -ldflags "-s -w -X main.appVersion=${VERSION} '-extldflags=-static -Wl,--allow-multiple-definition'" && \
|
||||||
|
cp ../../README.md ../../AUTHORS ../../COPYING ${BUILDDIR} && zip -rq "${BUILDDIR}-windows-x86_64.zip" ${BUILDDIR}
|
||||||
|
rm -rf ${BUILDDIR}
|
||||||
|
|
||||||
|
export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1
|
||||||
|
BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR}
|
||||||
|
PATH=${PATH}:${MACOS_x86_64}/bin \
|
||||||
|
CC=x86_64-apple-darwin21.1-clang \
|
||||||
|
PKG_CONFIG="x86_64-apple-darwin21.1-pkg-config" \
|
||||||
|
PKG_CONFIG_PATH="$MACOS_x86_64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
|
||||||
|
PKG_CONFIG_LIBDIR="$MACOS_x86_64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
|
||||||
|
CGO_CFLAGS="-I$MACOS_x86_64/usr/include -I$MACOS_x86_64/macports/pkgs/opt/local/include" \
|
||||||
|
CGO_LDFLAGS="-L$MACOS_x86_64/SDK/MacOSX12.1.sdk/usr/lib -L$MACOS_x86_64/macports/pkgs/opt/local/lib -mmacosx-version-min=10.13" \
|
||||||
|
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 \
|
||||||
|
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert -ldflags "-linkmode external -s -w -X main.appVersion=${VERSION}" && \
|
||||||
|
cp ../../README.md ../../AUTHORS ../../COPYING ${BUILDDIR} && zip -rq "${BUILDDIR}-darwin-x86_64.zip" ${BUILDDIR}
|
||||||
|
rm -rf ${BUILDDIR}
|
||||||
|
|
||||||
|
export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1
|
||||||
|
BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR}
|
||||||
|
PATH=${PATH}:${MACOS_aarch64}/bin \
|
||||||
|
CC=aarch64-apple-darwin21.1-clang \
|
||||||
|
PKG_CONFIG="aarch64-apple-darwin21.1-pkg-config" \
|
||||||
|
PKG_CONFIG_PATH="$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
|
||||||
|
PKG_CONFIG_LIBDIR="$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
|
||||||
|
CGO_CFLAGS="-I$MACOS_aarch64/usr/include -I$MACOS_aarch64/macports/pkgs/opt/local/include" \
|
||||||
|
CGO_LDFLAGS="-L$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib -L$MACOS_aarch64/macports/pkgs/opt/local/lib -mmacosx-version-min=10.13" \
|
||||||
|
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 \
|
||||||
|
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert -ldflags "-linkmode external -s -w -X main.appVersion=${VERSION}" && \
|
||||||
|
cp ../../README.md ../../AUTHORS ../../COPYING ${BUILDDIR} && zip -rq "${BUILDDIR}-darwin-aarch64.zip" ${BUILDDIR}
|
||||||
|
rm -rf ${BUILDDIR}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
module github.com/gen2brain/cbconvert
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/chai2010/webp v1.1.1
|
||||||
|
github.com/disintegration/imaging v1.6.2
|
||||||
|
github.com/dustin/go-humanize v1.0.1
|
||||||
|
github.com/fvbommel/sortorder v1.1.0
|
||||||
|
github.com/gen2brain/go-fitz v1.23.1
|
||||||
|
github.com/gen2brain/go-unarr v0.1.7
|
||||||
|
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7
|
||||||
|
github.com/strukturag/libheif v1.15.2
|
||||||
|
golang.org/x/image v0.11.0
|
||||||
|
golang.org/x/sync v0.3.0
|
||||||
|
gopkg.in/gographics/imagick.v3 v3.4.3
|
||||||
|
)
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
|
||||||
|
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
|
||||||
|
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
|
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||||
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
|
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
|
||||||
|
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||||
|
github.com/gen2brain/go-fitz v1.23.1 h1:x69/szWZXpI3jZ57mMqCg7WqqvtYnQG0lXts3L6M1Fc=
|
||||||
|
github.com/gen2brain/go-fitz v1.23.1/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ=
|
||||||
|
github.com/gen2brain/go-unarr v0.1.7 h1:mEE7bPShJIsmAX67t6BW2ibpEUO7j5WK152KgNM9NbQ=
|
||||||
|
github.com/gen2brain/go-unarr v0.1.7/go.mod h1:MK9a3hddpaIxjEtrE1f/LA5yJ7gA34cS7Oyr325sY9s=
|
||||||
|
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7 h1:NlUATi3cllRJhpM4mfR9BxiLRXT83bcSLcOa+S8lrME=
|
||||||
|
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7/go.mod h1:Hku3FQ2laCEwSv7Z8YkC0er38jLaUycUCbsFkWMr+z4=
|
||||||
|
github.com/strukturag/libheif v1.15.2 h1:pgdcpDHqtLKRXL9ETSTeht0CsJODB3BojpTsb3S/3Wg=
|
||||||
|
github.com/strukturag/libheif v1.15.2/go.mod h1:E/PNRlmVtrtj9j2AvBZlrO4dsBDu6KfwDZn7X1Ce8Ks=
|
||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||||
|
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||||
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/gographics/imagick.v3 v3.4.3 h1:9plKFE/Us913jBN6KohtLG9FNW8LPvfpjiGAORIiEHg=
|
||||||
|
gopkg.in/gographics/imagick.v3 v3.4.3/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
mkdir -p build
|
|
||||||
|
|
||||||
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o build/cbconvert
|
|
||||||
strip build/cbconvert
|
|
||||||
|
|
||||||
CGO_LDFLAGS="-ldl -lltdl -lfreetype -lm -lz -static-libgcc" CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o build/cbconvert-static --ldflags '-extldflags "-static"'
|
|
||||||
strip build/cbconvert-static
|
|
||||||
|
|
||||||
CGO_LDFLAGS="-L/usr/i686-pc-mingw32/usr/lib" \
|
|
||||||
CGO_CFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
|
|
||||||
CGO_CXXFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
|
|
||||||
CGO_CPPFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
|
|
||||||
PKG_CONFIG=/usr/bin/i686-pc-mingw32-pkg-config \
|
|
||||||
PKG_CONFIG_PATH=/usr/i686-pc-mingw32/usr/lib/pkgconfig \
|
|
||||||
PKG_CONFIG_LIBDIR=/usr/i686-pc-mingw32/usr/lib/pkgconfig \
|
|
||||||
CC="i686-pc-mingw32-gcc" CXX="i686-pc-mingw32-g++" \
|
|
||||||
CC_FOR_TARGET=i686-pc-mingw32-gcc CXX_FOR_TARGET=i686-pc-mingw32-g++ \
|
|
||||||
CGO_ENABLED=1 GOOS=windows GOARCH=386 go build -o build/cbconvert.exe -ldflags "-linkmode external -extldflags -static"
|
|
||||||
i686-pc-mingw32-strip build/cbconvert.exe
|
|
||||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 229 KiB |
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 387 KiB |
Reference in New Issue
Block a user