65 Commits

Author SHA1 Message Date
Milan Nikolic a9e3281a5f Add modules 2024-02-08 16:05:56 +01:00
Milan Nikolic 962fde8c8d Update modules 2024-02-08 15:50:40 +01:00
Milan Nikolic a8084ed897 Update metadata 2024-02-08 15:47:35 +01:00
Milan Nikolic 183c42613f Change webp library 2024-02-08 15:38:41 +01:00
Milan Nikolic cad75231b1 Update modules 2024-02-08 15:12:10 +01:00
Milan Nikolic c32019615d Merge pull request #22 from kianmeng/fix-typo
Fix typo, convertor -> converter
2023-11-16 07:43:27 +01:00
Kian-Meng Ang dd9000cfea Fix typo, convertor -> converter
Found via `codespell`.
2023-11-16 13:01:43 +08:00
Milan Nikolic 4fc3209b4e Update README.md 2023-09-29 09:53:27 +02:00
Milan Nikolic 000bd20f71 Update README.md 2023-09-16 14:17:10 +02:00
Milan Nikolic f558b109e5 Update manifest 2023-09-14 16:44:12 +02:00
Milan Nikolic 5922f102be Update manifest 2023-09-14 16:42:34 +02:00
Milan Nikolic f84d2d4333 Update modules 2023-09-14 15:05:49 +02:00
Milan Nikolic 551ab9e137 Change flatpak exec/command name to cbconvert 2023-09-14 15:02:27 +02:00
Milan Nikolic 046cc2c1fd Update modules 2023-09-14 11:51:48 +02:00
Milan Nikolic a5b1f41ba6 Update modules 2023-09-14 04:33:48 +02:00
Milan Nikolic 9f628741e0 Update metainfo 2023-09-14 04:28:53 +02:00
Milan Nikolic ccbb27ff6d Update modules 2023-09-14 04:04:36 +02:00
Milan Nikolic 04473e95bf Update url 2023-09-14 03:48:06 +02:00
Milan Nikolic c061297ad0 Update modules 2023-09-14 03:43:17 +02:00
Milan Nikolic 544344d5c2 Update make.bash 2023-09-14 03:39:19 +02:00
Milan Nikolic e14aa6baab Add GUI 2023-09-14 03:27:07 +02:00
Milan Nikolic 6400ae14d8 Update modules 2023-09-13 13:39:13 +02:00
Milan Nikolic 788a9d3bd5 Add Cancel, split file 2023-09-13 13:14:09 +02:00
Milan Nikolic bff17636f6 Update modules 2023-09-11 16:03:04 +02:00
Milan Nikolic bd19faf18e Add mobi test file 2023-09-11 15:42:48 +02:00
Milan Nikolic cf1e8a1fec Add support for JXL 2023-09-11 15:34:11 +02:00
Milan Nikolic 63ad96ac3a Add support for XPS 2023-09-07 21:43:31 +02:00
Milan Nikolic 9bd7193124 Remove hotei/bmp 2023-09-07 21:38:15 +02:00
Milan Nikolic 09a27ac9a4 Remove musl build 2023-09-02 18:42:27 +02:00
Milan Nikolic 4109ae154f Update README.md 2023-09-02 18:41:33 +02:00
Milan Nikolic f01e858a24 Update build 2023-09-02 18:20:46 +02:00
Milan Nikolic 8c21b430a9 Update actions 2023-09-02 17:19:36 +02:00
Milan Nikolic 5fbd462a78 Update actions 2023-09-02 16:17:46 +02:00
Milan Nikolic 0797c8456f Add actions 2023-09-02 16:14:32 +02:00
Milan Nikolic c3f6c5a499 Update README.md 2023-09-02 12:14:06 +02:00
Milan Nikolic fa162972b2 Update README.md 2023-09-02 12:11:24 +02:00
Milan Nikolic aa65bfa4f4 Add tests 2023-09-02 12:11:09 +02:00
Milan Nikolic 6c293adc1f Update modules 2023-09-02 10:11:03 +02:00
Milan Nikolic 6936f697b4 Remove flip 2023-09-02 10:02:08 +02:00
Milan Nikolic 83d7a1ea6e Update README.md 2023-09-02 09:23:02 +02:00
Milan Nikolic 3d56765415 Update modules 2023-09-02 09:20:33 +02:00
Milan Nikolic b1fcf530da Add version and preview 2023-09-02 09:18:47 +02:00
Milan Nikolic 7dc21fc0b4 Update modules 2023-08-29 20:15:22 +02:00
Milan Nikolic fdfa80875e Add File type 2023-08-29 20:07:35 +02:00
Milan Nikolic 50b0911586 Close archive 2023-08-27 11:43:19 +02:00
Milan Nikolic 8db1690d3c Update thumbnail 2023-08-27 11:38:41 +02:00
Milan Nikolic 91e336f772 Update README.md 2023-08-24 15:04:51 +02:00
Milan Nikolic 903a8bbcfc Update modules 2023-08-24 11:46:48 +02:00
Milan Nikolic e938b140f0 Update README.md 2023-08-24 11:43:14 +02:00
Milan Nikolic 0a3f4d6992 Add support for MOBI 2023-08-24 11:42:19 +02:00
Milan Nikolic c5902fb131 Update modules 2023-08-24 09:05:37 +02:00
Milan Nikolic d6ece90041 Add support for adding/removing files 2023-08-24 09:00:52 +02:00
Milan Nikolic c34b4d0a98 Allow recursive for plain directories 2023-08-23 13:16:30 +02:00
Milan Nikolic f0e2232e51 Update modules 2023-08-23 12:43:05 +02:00
Milan Nikolic 0ba0337ef8 Preserve output directory structure when recursive is enabled 2023-08-23 12:17:32 +02:00
Milan Nikolic 6e97d977ae Update modules 2023-08-22 14:39:07 +02:00
Milan Nikolic 685b6bf153 Update modules 2023-08-22 14:37:05 +02:00
Milan Nikolic 14f2e87525 Lint 2023-08-22 14:36:03 +02:00
Milan Nikolic cd2f7501e0 Update modules 2023-08-22 11:30:50 +02:00
Milan Nikolic 69b0b51010 Allow for piped input 2023-08-22 11:29:33 +02:00
Milan Nikolic c5494af60b Add support for CBT 2023-08-22 10:27:48 +02:00
Milan Nikolic f447c618de Update README.md 2023-08-21 20:12:03 +02:00
Milan Nikolic 54261d8528 Set comment 2023-08-21 20:04:05 +02:00
Milan Nikolic f92125643f Update modules 2023-08-21 17:54:10 +02:00
Milan Nikolic 7b6c766dcc Refactor 2023-08-21 17:52:57 +02:00
54 changed files with 3491 additions and 967 deletions
+120
View File
@@ -0,0 +1,120 @@
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: Update apt-get
run: |
sudo apt-get update
- 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: Install libheif dependencies
run: |
sudo apt-get install libaom-dev -y
- 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 --disable-examples
- name: Install libheif
working-directory: libheif-1.15.2
run: |
make -j3 && sudo make install
- name: Wget lcms2
uses: wei/wget@v1
with:
args: https://github.com/mm2/Little-CMS/releases/download/lcms2.15/lcms2-2.15.tar.gz
- name: Unpack lcms2
run: |
tar -xpf lcms2-2.15.tar.gz
- name: Configure lcms2
working-directory: lcms2-2.15
run: |
./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu --enable-shared --disable-static
- name: Install lcms2
working-directory: lcms2-2.15
run: |
make -j3 && sudo make install
- name: Wget highway
uses: wei/wget@v1
with:
args: -O highway-1.0.5.tar.gz https://github.com/google/highway/archive/refs/tags/1.0.5.tar.gz
- name: Unpack highway
run: |
tar -xpf highway-1.0.5.tar.gz && mkdir -p highway-1.0.5/build
- name: Configure highway
working-directory: highway-1.0.5/build
run: |
cmake -DCMAKE_INSTALL_PREFIX=/usr -DHWY_ENABLE_TESTS=OFF -DHWY_ENABLE_EXAMPLES=OFF -DHWY_WARNINGS_ARE_ERRORS=OFF ../
- name: Install highway
working-directory: highway-1.0.5/build
run: |
make -j3 && sudo make install
- name: Wget libjxl
uses: wei/wget@v1
with:
args: -O libjxl-0.8.2.tar.gz https://github.com/libjxl/libjxl/archive/refs/tags/v0.8.2.tar.gz
- name: Unpack libjxl
run: |
tar -xpf libjxl-0.8.2.tar.gz && mkdir -p libjxl-0.8.2/build
- name: Configure libjxl
working-directory: libjxl-0.8.2/build
run: |
cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DJPEGXL_ENABLE_BENCHMARK=OFF \
-DJPEGXL_ENABLE_COVERAGE=OFF -DJPEGXL_ENABLE_FUZZERS=OFF -DJPEGXL_ENABLE_SJPEG=OFF -DJPEGXL_WARNINGS_AS_ERRORS=OFF \
-DJPEGXL_ENABLE_SKCMS=OFF -DJPEGXL_ENABLE_VIEWERS=OFF -DJPEGXL_ENABLE_PLUGINS=OFF -DJPEGXL_ENABLE_DOXYGEN=OFF \
-DJPEGXL_ENABLE_MANPAGES=OFF -DJPEGXL_ENABLE_JNI=OFF -DJPEGXL_ENABLE_JPEGLI_LIBJPEG=OFF -DJPEGXL_ENABLE_TCMALLOC=OFF \
-DJPEGXL_ENABLE_EXAMPLES=OFF -DJPEGXL_ENABLE_TOOLS=OFF -DJPEGXL_ENABLE_OPENEXR=OFF -DBUILD_TESTING=OFF \
-DJXL_HWY_DISABLED_TARGETS_FORCED=ON -DJPEGXL_FORCE_SYSTEM_BROTLI=ON -DJPEGXL_FORCE_SYSTEM_HWY=ON ../
- name: Install libjxl
working-directory: libjxl-0.8.2/build
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-lcms --without-lqr --without-lzma --without-openexr --without-pango --without-raw --without-rsvg --without-wmf \
--without-xml --disable-openmp --with-jpeg --with-heic --with-jxl --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@v3
with:
go-version: 1.21
- name: Checkout code
uses: actions/checkout@v3
- name: Test
run: go test
+58 -32
View File
@@ -6,38 +6,43 @@ CBconvert is a [Comic Book](http://en.wikipedia.org/wiki/Comic_Book_Archive_file
It can convert comics to different formats to fit your various devices. It can convert comics to different formats to fit your various devices.
<img src="cmd/cbconvert-gui/screenshots/linux-01.jpg" width="700" alt="screenshot" />
See more [screenshots](https://github.com/gen2brain/cbconvert/blob/master/cmd/cbconvert-gui/screenshots/).
### Features ### Features
* reads RAR, ZIP, 7Z, CBR, CBZ, CB7, CBT, PDF, EPUB, and plain directory * reads CBR (RAR), CBZ (ZIP), CB7 (7Z), CBT (TAR), PDF, XPS, EPUB, MOBI and plain directory
* always saves processed comics in CBZ (ZIP) archive format * saves processed files in ZIP archive format or TAR
* images can be converted to JPEG, PNG, TIFF, WEBP, AVIF, or 4-Bit BMP (16 colors) file format * images can be converted to JPEG, PNG, TIFF, WEBP, AVIF, JXL, or 4-Bit BMP (16 colors) image format
* rotate, flip, adjust brightness/contrast, adjust levels (Photoshop-like) or grayscale images * rotate, adjust brightness/contrast, adjust levels (Photoshop-like) or grayscale images
* resize algorithms (NearestNeighbor, Box, Linear, MitchellNetravali, CatmullRom, Gaussian, Lanczos) * resize filters (NearestNeighbor, Box, Linear, MitchellNetravali, CatmullRom, Gaussian, Lanczos)
* export covers from comics * export covers from comics
* create thumbnails from covers by [FreeDesktop](http://www.freedesktop.org/wiki/) specification * create thumbnails from covers by [FreeDesktop](http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html) specification
### Download ### Download
* [Windows x86_64](https://github.com/gen2brain/cbconvert/releases/download/0.8.3/cbconvert-0.8.3-windows-x86_64.zip) * [Windows x86_64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-1.0.0-windows-x86_64.zip)
* [Linux x86_64](https://github.com/gen2brain/cbconvert/releases/download/0.8.3/cbconvert-0.8.3-linux-x86_64.tar.gz) * [Linux x86_64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-1.0.0-linux-x86_64.tar.gz)
* [Linux aarch64](https://github.com/gen2brain/cbconvert/releases/download/0.8.3/cbconvert-0.8.3-linux-aarch64.tar.gz) * [macOS x86_64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-1.0.0-darwin-x86_64.zip)
* [macOS x86_64](https://github.com/gen2brain/cbconvert/releases/download/0.8.3/cbconvert-0.8.3-darwin-x86_64.zip) * [macOS aarch64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-1.0.0-darwin-aarch64.zip)
* [macOS aarch64](https://github.com/gen2brain/cbconvert/releases/download/0.8.3/cbconvert-0.8.3-darwin-aarch64.zip)
[![flathub](https://dl.flathub.org/assets/badges/flathub-badge-en.png)](https://flathub.org/apps/io.github.gen2brain.cbconvert)
### Using cbconvert in file managers to generate FreeDesktop thumbnails ### Using cbconvert in file managers to generate FreeDesktop thumbnails
Copy cbconvert cli binary to your PATH and create file ~/.local/share/thumbnailers/cbconvert.thumbnailer: Copy `cbconvert` cli binary to your PATH and create file `~/.local/share/thumbnailers/cbconvert.thumbnailer`:
``` ```
[Thumbnailer Entry] [Thumbnailer Entry]
TryExec=cbconvert TryExec=cbconvert
Exec=cbconvert thumbnail --quiet --width %s --outfile %o %i Exec=cbconvert thumbnail --quiet --width %s --outfile %o %i
MimeType=application/pdf;application/x-pdf;image/pdf;application/x-cbz;application/x-cbr;application/x-cb7;application/x-cbt;application/epub+zip;application/vnd.comicbook-rar;application/vnd.comicbook+zip; MimeType=application/pdf;application/x-cb7;application/x-cbt;application/epub+zip;application/vnd.comicbook-rar;application/vnd.comicbook+zip;application/x-mobipocket-ebook;application/vnd.ms-xpsdocument;
``` ```
This is what it looks like in the PCManFM file manager: This is what it looks like in the PCManFM file manager:
![thumbnails](https://bit.ly/3BaTvTV) <img src="cmd/cbconvert/screenshots/thumbnails.jpg" width="700" alt="thumbnails" />
### Using command line app ### Using command line app
@@ -48,8 +53,8 @@ This is what it looks like in the PCManFM file manager:
    Commands:     Commands:
      convert*       convert
            Convert archive or document (default command)             Convert archive or document
        --width         --width
            Image width (default "0")             Image width (default "0")
@@ -58,11 +63,11 @@ This is what it looks like in the PCManFM file manager:
        --fit         --fit
            Best fit for required width and height (default "false")             Best fit for required width and height (default "false")
        --format         --format
            Image format, valid values are jpeg, png, tiff, bmp, webp, avif (default "jpeg")             Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl (default "jpeg")
--archive
Archive format, valid values are zip, tar (default "zip")
        --quality         --quality
            Image quality (default "75")             Image quality (default "75")
        --lossless
            Lossless compression (avif) (default "false")
        --filter         --filter
            0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos (default "2")             0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos (default "2")
        --no-cover         --no-cover
@@ -77,8 +82,6 @@ This is what it looks like in the PCManFM file manager:
            Convert images to grayscale (monochromatic) (default "false")             Convert images to grayscale (monochromatic) (default "false")
        --rotate         --rotate
            Rotate images, valid values are 0, 90, 180, 270 (default "0")             Rotate images, valid values are 0, 90, 180, 270 (default "0")
        --flip
            Flip images, valid values are none, horizontal, vertical (default "none")
        --brightness         --brightness
            Adjust the brightness of the images, must be in the range (-100, 100) (default "0")             Adjust the brightness of the images, must be in the range (-100, 100) (default "0")
        --contrast         --contrast
@@ -114,7 +117,7 @@ This is what it looks like in the PCManFM file manager:
        --fit         --fit
            Best fit for required width and height (default "false")             Best fit for required width and height (default "false")
        --format         --format
            Image format, valid values are jpeg, png, tiff, bmp, webp, avif (default "jpeg")             Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl (default "jpeg")
        --quality         --quality
            Image quality (default "75")             Image quality (default "75")
        --filter         --filter
@@ -155,30 +158,53 @@ This is what it looks like in the PCManFM file manager:
--cover --cover
Print cover name (default "false") 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 "")
``` ```
### Examples ### Examples
Rescale images to 1200px for all supported files found in a directory with a size larger than 60MB: * Rescale images to 1200px for all supported files found in a directory with a size larger than 60MB:
`cbconvert --recursive --width 1200 --size 60 /media/comics/Thorgal/` `cbconvert --recursive --width 1200 --size 60 /media/comics/Thorgal/`
Convert all images in pdf to 4bit BMP images and save the result in ~/comics directory: * Convert all images in pdf to 4bit BMP images and save the result in ~/comics directory:
`cbconvert --bmp --outdir ~/comics /media/comics/Garfield/Garfield_01.pdf` `cbconvert --format bmp --outdir ~/comics /media/comics/Garfield/Garfield_01.pdf`
[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. [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.
Generate thumbnails by [freedesktop specification](http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html) in ~/.cache/thumbnails/normal directory with width 512: * Extract covers to ~/covers dir for all supported files found in the directory, Lanczos algorithm is used for resizing:
`cbconvert thumbnail --width 512 --outdir ~/.cache/thumbnails/normal /media/comics/GrooTheWanderer/`
Extract covers to ~/covers dir for all supported files found in the directory, Lanczos algorithm is used for resizing:
`cbconvert cover --outdir ~/covers --filter=7 /media/comics/GrooTheWanderer/` `cbconvert cover --outdir ~/covers --filter=7 /media/comics/GrooTheWanderer/`
* Convert all images to AVIF format:
`cbconvert --format avif --quality 50 --width 1280 --outdir ~/comics /media/comics/Misc/`
### Quality settings
This table maps quality settings for JPEG to the respective AVIF and WEBP quality settings:
| | | | | |
|--------------|----|----|----|----|
| JPEG quality | 50 | 60 | 70 | 80 |
| AVIF quality | 48 | 51 | 56 | 64 |
| WEBP quality | 55 | 64 | 72 | 82 |
### Compile ### Compile
Install ImageMagick7 and libheif (with libaom) libraries and headers and then install to GOBIN: Install ImageMagick7 (with libheif/libjxl support) and MuPDF libraries and headers and then install to GOBIN:
`go install github.com/gen2brain/cbconvert/cmd/cbconvert@latest` `go install -tags extlib github.com/gen2brain/cbconvert/cmd/cbconvert@latest`
For GUI app, check [IUP requirements](https://github.com/gen2brain/iup-go), and then install:
`go install -tags extlib github.com/gen2brain/cbconvert/cmd/cbconvert-gui@latest`
+654 -683
View File
File diff suppressed because it is too large Load Diff
+422
View File
@@ -0,0 +1,422 @@
package cbconvert
import (
"archive/tar"
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"github.com/gen2brain/go-unarr"
)
// archiveSave saves workdir to CBZ archive.
func (c *Converter) archiveSave(fileName string) error {
if c.Opts.Archive == "zip" {
return c.archiveSaveZip(fileName)
} else if c.Opts.Archive == "tar" {
return c.archiveSaveTar(fileName)
}
return nil
}
// archiveSaveZip saves workdir to CBZ archive.
func (c *Converter) archiveSaveZip(fileName string) error {
if c.OnCompress != nil {
c.OnCompress()
}
var zipName string
if c.Opts.Recursive {
err := os.MkdirAll(filepath.Join(c.Opts.OutDir, filepath.Dir(fileName)), 0755)
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
zipName = filepath.Join(c.Opts.OutDir, filepath.Dir(fileName), fmt.Sprintf("%s%s.cbz", baseNoExt(fileName), c.Opts.Suffix))
} else {
zipName = filepath.Join(c.Opts.OutDir, fmt.Sprintf("%s%s.cbz", baseNoExt(fileName), c.Opts.Suffix))
}
zipFile, err := os.Create(zipName)
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
z := zip.NewWriter(zipFile)
files, err := os.ReadDir(c.Workdir)
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
for _, file := range files {
r, err := os.ReadFile(filepath.Join(c.Workdir, file.Name()))
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
info, err := file.Info()
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
zipInfo, err := zip.FileInfoHeader(info)
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
zipInfo.Method = zip.Deflate
w, err := z.CreateHeader(zipInfo)
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
_, err = w.Write(r)
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
}
if err = z.Close(); err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
if err = zipFile.Close(); err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
err = os.RemoveAll(c.Workdir)
if err != nil {
return fmt.Errorf("archiveSaveZip: %w", err)
}
return nil
}
// archiveSaveTar saves workdir to CBT archive.
func (c *Converter) archiveSaveTar(fileName string) error {
if c.OnCompress != nil {
c.OnCompress()
}
var tarName string
if c.Opts.Recursive {
err := os.MkdirAll(filepath.Join(c.Opts.OutDir, filepath.Dir(fileName)), 0755)
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
tarName = filepath.Join(c.Opts.OutDir, filepath.Dir(fileName), fmt.Sprintf("%s%s.cbt", baseNoExt(fileName), c.Opts.Suffix))
} else {
tarName = filepath.Join(c.Opts.OutDir, fmt.Sprintf("%s%s.cbt", baseNoExt(fileName), c.Opts.Suffix))
}
tarFile, err := os.Create(tarName)
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
tw := tar.NewWriter(tarFile)
files, err := os.ReadDir(c.Workdir)
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
for _, file := range files {
r, err := os.ReadFile(filepath.Join(c.Workdir, file.Name()))
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
info, err := file.Info()
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
header, err := tar.FileInfoHeader(info, info.Name())
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
err = tw.WriteHeader(header)
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
_, err = tw.Write(r)
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
}
if err = tw.Close(); err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
if err = tarFile.Close(); err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
err = os.RemoveAll(c.Workdir)
if err != nil {
return fmt.Errorf("archiveSaveTar: %w", err)
}
return nil
}
// archiveList lists contents of archive.
func (c *Converter) archiveList(fileName string) ([]string, error) {
var contents []string
archive, err := unarr.NewArchive(fileName)
if err != nil {
return contents, fmt.Errorf("archiveList: %w", err)
}
defer archive.Close()
contents, err = archive.List()
if err != nil {
return contents, fmt.Errorf("archiveList: %w", err)
}
return contents, nil
}
// archiveComment returns ZIP comment.
func (c *Converter) archiveComment(fileName string) (string, error) {
zr, err := zip.OpenReader(fileName)
if err != nil {
return "", fmt.Errorf("archiveComment: %w", err)
}
defer zr.Close()
return zr.Comment, nil
}
// archiveSetComment sets ZIP comment.
func (c *Converter) archiveSetComment(fileName, commentBody string) error {
zr, err := zip.OpenReader(fileName)
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
defer zr.Close()
zf, err := os.CreateTemp(os.TempDir(), "cbc")
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
tmpName := zf.Name()
defer os.Remove(tmpName)
zw := zip.NewWriter(zf)
err = zw.SetComment(commentBody)
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
for _, item := range zr.File {
ir, err := item.OpenRaw()
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
item := item
it, err := zw.CreateRaw(&item.FileHeader)
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
_, err = io.Copy(it, ir)
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
}
err = zw.Close()
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
err = zf.Close()
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
data, err := os.ReadFile(tmpName)
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
err = os.WriteFile(fileName, data, 0644)
if err != nil {
return fmt.Errorf("archiveSetComment: %w", err)
}
return nil
}
// archiveFileAdd adds file to archive.
func (c *Converter) archiveFileAdd(fileName, newFileName string) error {
zr, err := zip.OpenReader(fileName)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
defer zr.Close()
zf, err := os.CreateTemp(os.TempDir(), "cbc")
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
tmpName := zf.Name()
defer os.Remove(tmpName)
zw := zip.NewWriter(zf)
for _, item := range zr.File {
if item.Name == newFileName {
continue
}
ir, err := item.OpenRaw()
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
item := item
it, err := zw.CreateRaw(&item.FileHeader)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
_, err = io.Copy(it, ir)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
}
info, err := os.Stat(newFileName)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
newData, err := os.ReadFile(newFileName)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
zipInfo, err := zip.FileInfoHeader(info)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
zipInfo.Method = zip.Deflate
w, err := zw.CreateHeader(zipInfo)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
_, err = w.Write(newData)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
err = zw.Close()
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
err = zf.Close()
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
data, err := os.ReadFile(tmpName)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
err = os.WriteFile(fileName, data, 0644)
if err != nil {
return fmt.Errorf("archiveFileAdd: %w", err)
}
return nil
}
// archiveFileRemove removes files from archive.
func (c *Converter) archiveFileRemove(fileName, pattern string) error {
zr, err := zip.OpenReader(fileName)
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
defer zr.Close()
zf, err := os.CreateTemp(os.TempDir(), "cbc")
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
tmpName := zf.Name()
defer os.Remove(tmpName)
zw := zip.NewWriter(zf)
for _, item := range zr.File {
matched, err := filepath.Match(pattern, item.Name)
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
if matched {
continue
}
ir, err := item.OpenRaw()
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
item := item
it, err := zw.CreateRaw(&item.FileHeader)
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
_, err = io.Copy(it, ir)
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
}
err = zw.Close()
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
err = zf.Close()
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
data, err := os.ReadFile(tmpName)
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
err = os.WriteFile(fileName, data, 0644)
if err != nil {
return fmt.Errorf("archiveFileRemove: %w", err)
}
return nil
}
+184
View File
@@ -0,0 +1,184 @@
package cbconvert
import (
"fmt"
"image"
"image/color"
"image/draw"
"io"
"os"
"path/filepath"
"strings"
)
// imageToRGBA converts an image.Image to *image.RGBA.
func imageToRGBA(src image.Image) *image.RGBA {
if dst, ok := src.(*image.RGBA); ok {
return dst
}
b := src.Bounds()
dst := image.NewRGBA(b)
draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)
return dst
}
// imageToGray converts an image.Image to *image.Gray.
func imageToGray(src image.Image) *image.Gray {
if dst, ok := src.(*image.Gray); ok {
return dst
}
b := src.Bounds()
dst := image.NewGray(b)
draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)
return dst
}
// imagesFromPath returns list of found image files for given directory.
func imagesFromPath(path string) ([]string, error) {
var images []string
walkFiles := func(fp string, f os.FileInfo, err error) error {
if !f.IsDir() && f.Mode()&os.ModeType == 0 {
if f.Size() > 0 && (isImage(fp)) {
images = append(images, fp)
}
}
return nil
}
f, err := filepath.Abs(path)
if err != nil {
return images, fmt.Errorf("imagesFromPath: %w", err)
}
stat, err := os.Stat(f)
if err != nil {
return images, fmt.Errorf("imagesFromPath: %w", err)
}
if !stat.IsDir() && stat.Mode()&os.ModeType == 0 {
if isImage(f) {
images = append(images, f)
}
} else {
err = filepath.Walk(f, walkFiles)
if err != nil {
return images, fmt.Errorf("imagesFromPath: %w", err)
}
}
return images, nil
}
// imagesFromSlice returns list of found image files for given slice of files.
func imagesFromSlice(files []string) []string {
var images []string
for _, f := range files {
if isImage(f) {
images = append(images, f)
}
}
return images
}
// isArchive checks if file is archive.
func isArchive(f string) bool {
var types = []string{".rar", ".zip", ".7z", ".tar", ".cbr", ".cbz", ".cb7", ".cbt"}
for _, t := range types {
if strings.ToLower(filepath.Ext(f)) == t {
return true
}
}
return false
}
// isDocument checks if file is document.
func isDocument(f string) bool {
var types = []string{".pdf", ".xps", ".epub", ".mobi"}
for _, t := range types {
if strings.ToLower(filepath.Ext(f)) == t {
return true
}
}
return false
}
// isImage checks if file is image.
func isImage(f string) bool {
var types = []string{".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".tif", ".webp", ".avif", ".jxl"}
for _, t := range types {
if strings.ToLower(filepath.Ext(f)) == t {
return true
}
}
return false
}
// isNonImage checks for allowed files in archive.
func isNonImage(f string) bool {
var types = []string{".nfo", ".xml", ".txt"}
for _, t := range types {
if strings.ToLower(filepath.Ext(f)) == t {
return true
}
}
return false
}
// isSize checks size of file.
func isSize(a, b int64) bool {
if a > 0 {
if b < int64(a)*(1024*1024) {
return false
}
}
return true
}
// isGrayScale checks if image is grayscale.
func isGrayScale(img image.Image) bool {
model := img.ColorModel()
if model == color.GrayModel || model == color.Gray16Model {
return true
}
return false
}
// baseNoExt returns base name without extension.
func baseNoExt(filename string) string {
return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename))
}
// copyFile copies reader to file.
func copyFile(reader io.Reader, filename string) error {
err := os.MkdirAll(filepath.Dir(filename), 0755)
if err != nil {
return fmt.Errorf("copyFile: %w", err)
}
file, err := os.Create(filename)
if err != nil {
return fmt.Errorf("copyFile: %w", err)
}
defer file.Close()
_, err = io.Copy(file, reader)
if err != nil {
return fmt.Errorf("copyFile: %w", err)
}
return nil
}
+110
View File
@@ -0,0 +1,110 @@
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 := NewOptions()
opts.OutDir = tmpDir
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", "jxl"} {
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 := NewOptions()
opts.OutDir = tmpDir
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 := NewOptions()
opts.OutDir = tmpDir
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)
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

+10
View File
@@ -0,0 +1,10 @@
[Desktop Entry]
Name=CBconvert
GenericName=A Comic Book converter
Comment=A comic converter with support for .cb*, .pdf, .xps, .epub, .mobi and directories.
Exec=cbconvert-gui
Icon=cbconvert
Terminal=false
Type=Application
StartupNotify=true
Categories=Graphics;Utility;
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

+4
View File
@@ -0,0 +1,4 @@
[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;application/vnd.ms-xpsdocument;
@@ -0,0 +1,10 @@
[Desktop Entry]
Name=CBconvert
GenericName=A Comic Book converter
Comment=A comic converter with support for .cb*, .pdf, .xps, .epub, .mobi and directories
Exec=cbconvert
Icon=io.github.gen2brain.cbconvert
Terminal=false
Type=Application
StartupNotify=true
Categories=Graphics;
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>io.github.gen2brain.cbconvert</id>
<name>CBconvert</name>
<developer_name>Milan Nikolic</developer_name>
<summary>A Comic Book converter</summary>
<metadata_license>MIT</metadata_license>
<project_license>GPL-3</project_license>
<description>
<p>
A comic book converter with support for .cb*, .pdf, .xps, .epub, .mobi and directories.
Images can be converted to JPEG, PNG, TIFF, WEBP, AVIF, JXL or 4-Bit BMP (16 colors) file format.
</p>
</description>
<launchable type="desktop-id">io.github.gen2brain.cbconvert.desktop</launchable>
<screenshots>
<screenshot type="default">
<image>https://raw.githubusercontent.com/gen2brain/cbconvert/master/cmd/cbconvert-gui/screenshots/linux-02.jpg</image>
</screenshot>
<screenshot>
<image>https://raw.githubusercontent.com/gen2brain/cbconvert/master/cmd/cbconvert-gui/screenshots/linux-01.jpg</image>
</screenshot>
</screenshots>
<url type="homepage">https://github.com/gen2brain/cbconvert</url>
<url type="bugtracker">https://github.com/gen2brain/cbconvert/issues</url>
<content_rating type="oars-1.1"/>
<releases>
<release version="1.0.4" date="2024-02-08" type="stable">
<description>
<ul>
<li>Update modules and dependencies</li>
</ul>
</description>
<url type="details">https://github.com/gen2brain/cbconvert/releases/tag/v1.0.4</url>
</release>
<release version="1.0.3" date="2023-09-14" type="stable">
<description>
<ul>
<li>Add content rating</li>
</ul>
</description>
<url type="details">https://github.com/gen2brain/cbconvert/releases/tag/v1.0.3</url>
</release>
<release version="1.0.2" date="2023-09-14" type="stable">
<description>
<ul>
<li>Change flatpak exec/command name to cbconvert</li>
</ul>
</description>
<url type="details">https://github.com/gen2brain/cbconvert/releases/tag/v1.0.2</url>
</release>
<release version="1.0.1" date="2023-09-14" type="stable">
<description>
<ul>
<li>Add flatpak manifest</li>
</ul>
</description>
<url type="details">https://github.com/gen2brain/cbconvert/releases/tag/v1.0.1</url>
</release>
<release version="1.0.0" date="2023-09-14" type="stable">
<description>
<ul>
<li>Add GUI</li>
<li>Add support for JPEG XL</li>
</ul>
</description>
<url type="details">https://github.com/gen2brain/cbconvert/releases/tag/v1.0.0</url>
</release>
</releases>
</component>
+105
View File
@@ -0,0 +1,105 @@
# git.sr.ht/~jackmordaunt/go-libwebp v1.1.0
## explicit; go 1.21
git.sr.ht/~jackmordaunt/go-libwebp/lib/common
git.sr.ht/~jackmordaunt/go-libwebp/lib/dynamic/webp
git.sr.ht/~jackmordaunt/go-libwebp/lib/transpiled/webp
git.sr.ht/~jackmordaunt/go-libwebp/webp
# github.com/disintegration/imaging v1.6.2
## explicit
github.com/disintegration/imaging
# github.com/dustin/go-humanize v1.0.1
## explicit; go 1.16
github.com/dustin/go-humanize
# github.com/ebitengine/purego v0.5.2
## explicit; go 1.18
github.com/ebitengine/purego
github.com/ebitengine/purego/internal/cgo
github.com/ebitengine/purego/internal/fakecgo
github.com/ebitengine/purego/internal/strings
# github.com/fvbommel/sortorder v1.1.0
## explicit; go 1.13
github.com/fvbommel/sortorder
# github.com/gen2brain/cbconvert v1.0.4-0.20240208144735-a8084ed89758
## explicit; go 1.21
github.com/gen2brain/cbconvert
# github.com/gen2brain/go-fitz v1.23.7
## explicit; go 1.20
github.com/gen2brain/go-fitz
# github.com/gen2brain/go-unarr v0.2.0
## explicit; go 1.19
github.com/gen2brain/go-unarr
github.com/gen2brain/go-unarr/unarrc
# github.com/gen2brain/iup-go/iup v0.0.0-20230906093706-8b037fe6a7bd
## explicit; go 1.19
github.com/gen2brain/iup-go/iup
github.com/gen2brain/iup-go/iup/manifest
# github.com/godbus/dbus/v5 v5.1.0
## explicit; go 1.12
github.com/godbus/dbus/v5
# github.com/google/uuid v1.6.0
## explicit
github.com/google/uuid
# github.com/mattn/go-isatty v0.0.20
## explicit; go 1.15
github.com/mattn/go-isatty
# github.com/ncruces/go-strftime v0.1.9
## explicit; go 1.17
github.com/ncruces/go-strftime
# github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec
## explicit; go 1.12
github.com/remyoudompheng/bigfft
# golang.org/x/image v0.15.0
## explicit; go 1.18
golang.org/x/image/bmp
golang.org/x/image/ccitt
golang.org/x/image/riff
golang.org/x/image/tiff
golang.org/x/image/tiff/lzw
golang.org/x/image/vp8
golang.org/x/image/vp8l
golang.org/x/image/webp
# golang.org/x/sync v0.6.0
## explicit; go 1.18
golang.org/x/sync/errgroup
# golang.org/x/sys v0.17.0
## explicit; go 1.18
golang.org/x/sys/unix
golang.org/x/sys/windows
# gopkg.in/gographics/imagick.v3 v3.5.1
## explicit; go 1.13
gopkg.in/gographics/imagick.v3/imagick
gopkg.in/gographics/imagick.v3/imagick/types
# modernc.org/libc v1.41.0
## explicit; go 1.20
modernc.org/libc
modernc.org/libc/errno
modernc.org/libc/fcntl
modernc.org/libc/fts
modernc.org/libc/grp
modernc.org/libc/honnef.co/go/netdb
modernc.org/libc/langinfo
modernc.org/libc/limits
modernc.org/libc/netdb
modernc.org/libc/netinet/in
modernc.org/libc/poll
modernc.org/libc/pthread
modernc.org/libc/pwd
modernc.org/libc/signal
modernc.org/libc/stdio
modernc.org/libc/stdlib
modernc.org/libc/sys/socket
modernc.org/libc/sys/stat
modernc.org/libc/sys/types
modernc.org/libc/termios
modernc.org/libc/time
modernc.org/libc/unistd
modernc.org/libc/utime
modernc.org/libc/uuid
modernc.org/libc/uuid/uuid
modernc.org/libc/wctype
# modernc.org/mathutil v1.6.0
## explicit; go 1.18
modernc.org/mathutil
# modernc.org/memory v1.7.2
## explicit; go 1.18
modernc.org/memory
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>cbconvert-gui</string>
<key>CFBundleIconFile</key>
<string>icon</string>
<key>CFBundleIdentifier</key>
<string>com.github.gen2brain.cbconvert</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>CBconvert</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
</dict>
</plist>
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19H2</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>iup</string>
<key>CFBundleIdentifier</key>
<string>br.puc-rio.tecgraf.iup</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>iup</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>12D4e</string>
<key>DTPlatformName</key>
<string>macosx</string>
<key>DTPlatformVersion</key>
<string>11.1</string>
<key>DTSDKBuild</key>
<string>20C63</string>
<key>DTSDKName</key>
<string>macosx11.1</string>
<key>DTXcode</key>
<string>1240</string>
<key>DTXcodeBuild</key>
<string>12D4e</string>
<key>LSMinimumSystemVersion</key>
<string>10.14</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015 Tecgraf, PUC-Rio, Brazil. All rights reserved.</string>
</dict>
</plist>
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

+30
View File
@@ -0,0 +1,30 @@
module github.com/gen2brain/cbconvert/cmd/cbconvert-gui
go 1.21
require (
github.com/gen2brain/cbconvert v1.0.4-0.20240208144735-a8084ed89758
github.com/gen2brain/iup-go/iup v0.0.0-20230906093706-8b037fe6a7bd
github.com/godbus/dbus/v5 v5.1.0
)
require (
git.sr.ht/~jackmordaunt/go-libwebp v1.1.0 // indirect
github.com/disintegration/imaging v1.6.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.5.2 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/gen2brain/go-fitz v1.23.7 // indirect
github.com/gen2brain/go-unarr v0.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/image v0.15.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.17.0 // indirect
gopkg.in/gographics/imagick.v3 v3.5.1 // indirect
modernc.org/libc v1.41.0 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
)
+45
View File
@@ -0,0 +1,45 @@
git.sr.ht/~jackmordaunt/go-libwebp v1.1.0 h1:rfDv89tb6OuNp8f1TyprOZWaeC/TxqaYvLCI6nHKBY8=
git.sr.ht/~jackmordaunt/go-libwebp v1.1.0/go.mod h1:8557wZRj8KWRPBM+osAuAXVVR5nVURZ3SCG5rnACBdE=
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/ebitengine/purego v0.5.2 h1:r2MQEtkGzZ4LRtFZVAg5bjYKnUbxxloaeuGxH0t7qfs=
github.com/ebitengine/purego v0.5.2/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
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 v1.0.4-0.20240208144735-a8084ed89758 h1:VXWir2Nq5qkXuIeoCTavOlQ7j2Yab0vIJe1mvKsLe3I=
github.com/gen2brain/cbconvert v1.0.4-0.20240208144735-a8084ed89758/go.mod h1:jtc/vKGuG66vIemtQc6Ge69FXo33hX+gFvGtEP/z/SM=
github.com/gen2brain/go-fitz v1.23.7 h1:HPhzEVzmOINvCKqQgB/DwMzYh4ArIgy3tMwq1eJTcbg=
github.com/gen2brain/go-fitz v1.23.7/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ=
github.com/gen2brain/go-unarr v0.2.0 h1:sYKSjbeNSuZgudd59iGAbMbr113XRFoA7Rt9XWA+QVE=
github.com/gen2brain/go-unarr v0.2.0/go.mod h1:hoHheVuf0KT8/hfvkEL7GMwj2h7fq0lF72NdyySdr3c=
github.com/gen2brain/iup-go/iup v0.0.0-20230906093706-8b037fe6a7bd h1:k1EaRqSEu/2eahOBY44uYZevryE1HQBz0t7RYCufnHI=
github.com/gen2brain/iup-go/iup v0.0.0-20230906093706-8b037fe6a7bd/go.mod h1:HeMeojpQFldBWCMmU5dkmU640AdEcS+SPyEVLMJjjrw=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/gographics/imagick.v3 v3.5.1 h1:58JqK0UCx5RfvbRggF5FKuK6jHwAtTQopUxK8mzFa40=
gopkg.in/gographics/imagick.v3 v3.5.1/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
File diff suppressed because it is too large Load Diff
+65
View File
@@ -0,0 +1,65 @@
//go:build !portal
package main
import (
"path/filepath"
"strings"
"github.com/gen2brain/iup-go/iup"
)
func fileDlg(title string, multiple, directory bool) ([]string, error) {
ret := make([]string, 0)
dlg := iup.FileDlg()
defer dlg.Destroy()
if !directory {
mf := "YES"
if !multiple {
mf = "NO"
}
dlg.SetAttributes(map[string]string{
"DIALOGTYPE": "OPEN",
"MULTIPLEFILES": mf,
"EXTFILTER": "Comic Files|*.rar;*.zip;*.7z;*.tar;*.cbr;*.cbz;*.cb7;*.cbt;*.pdf;*.epub;*.mobi;*.xps|",
"FILTER": "*.cb*", // for Motif
"TITLE": title,
})
} else {
dlg.SetAttributes(map[string]string{
"DIALOGTYPE": "DIR",
"TITLE": title,
})
}
iup.Popup(dlg, iup.CENTERPARENT, iup.CENTERPARENT)
if dlg.GetInt("STATUS") == 0 {
if !directory {
value := dlg.GetAttribute("VALUE")
sp := strings.Split(value, "|")
if strings.ToLower(iup.GetGlobal("DRIVER")) == "cocoa" {
for _, file := range sp {
ret = append(ret, file)
}
} else {
if len(sp) > 1 {
for _, file := range sp[1 : len(sp)-1] {
ret = append(ret, filepath.Join(sp[0], file))
}
} else {
ret = append(ret, value)
}
}
} else {
value := dlg.GetAttribute("VALUE")
ret = append(ret, value)
}
}
return ret, nil
}
+105
View File
@@ -0,0 +1,105 @@
//go:build portal
package main
import (
"net/url"
"github.com/godbus/dbus/v5"
)
func fileDlg(title string, multiple, directory bool) ([]string, error) {
ret := make([]string, 0)
conn, err := dbus.ConnectSessionBus()
if err != nil {
return ret, err
}
defer conn.Close()
dest := "org.freedesktop.portal.Desktop"
path := "/org/freedesktop/portal/desktop"
resp := "org.freedesktop.portal.Request.Response"
if err = conn.AddMatchSignal(
dbus.WithMatchInterface(dest),
dbus.WithMatchObjectPath(dbus.ObjectPath(path)),
dbus.WithMatchSender(conn.Names()[0]),
); err != nil {
return ret, err
}
c := make(chan *dbus.Signal, 10)
conn.Signal(c)
type Item struct {
Index uint32
Filter string
}
type Filter struct {
Title string
Filters []Item
}
filters := []Filter{
{
"Comic Files",
[]Item{
Item{0, "*.rar"},
Item{0, "*.zip"},
Item{0, "*.7z"},
Item{0, "*.tar"},
Item{0, "*.cbr"},
Item{0, "*.cbz"},
Item{0, "*.cb7"},
Item{0, "*.cbt"},
Item{0, "*.pdf"},
Item{0, "*.epub"},
Item{0, "*.mobi"},
Item{0, "*.xps"},
},
},
}
opts := map[string]any{
"multiple": multiple,
"directory": directory,
}
if !directory {
opts["filters"] = filters
}
obj := conn.Object(dest, dbus.ObjectPath(path))
call := obj.Call("org.freedesktop.portal.FileChooser.OpenFile", 0, "", title, opts)
if call.Err != nil {
return ret, call.Err
}
for v := range c {
if v.Name != resp {
continue
}
status := v.Body[0].(uint32)
if status == 0 {
m := v.Body[1].(map[string]dbus.Variant)
uris := m["uris"].Value().([]string)
for _, uri := range uris {
u, err := url.ParseRequestURI(uri)
if err != nil {
return ret, err
}
ret = append(ret, u.Path)
}
}
break
}
return ret, nil
}
Binary file not shown.
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
GLIBC_x86_64="/usr/x86_64-pc-linux-gnu-static"
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 '1.0.0')"
BUILDDIR="cbconvert-gui-${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 -x -o "${BUILDDIR}"/cbconvert-gui -ldflags "-s -w -X main.appVersion=${VERSION}" && \
cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && tar -czf "${BUILDDIR}-linux-x86_64.tar.gz" "${BUILDDIR}"
rm -rf "${BUILDDIR}"
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 -lxcb -lICE -lXdmcp -lXau -lSM" \
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \
go build -trimpath -tags 'extlib pkgconfig motif' -v -o "${BUILDDIR}"/cbconvert-gui-motif -ldflags "-s -w -linkmode external -X main.appVersion=${VERSION} '-extldflags=-static'" && \
cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && tar -czf "${BUILDDIR}-linux-x86_64-motif.tar.gz" "${BUILDDIR}"
rm -rf "${BUILDDIR}"
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-gui.exe -ldflags "-s -w -X main.appVersion=${VERSION} -H=windowsgui '-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
mkdir -p "${BUILDDIR}"
cp -r dist/macos/CBconvert.app "${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.15" \
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o "${BUILDDIR}"/CBconvert.app/Contents/MacOS/cbconvert-gui -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
mkdir -p "${BUILDDIR}"
cp -r dist/macos/CBconvert.app "${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.15" \
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o "${BUILDDIR}"/CBconvert.app/Contents/MacOS/cbconvert-gui -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}"
+13
View File
@@ -0,0 +1,13 @@
## Screenshots
Windows
<img src="windows-01.jpg" width="700" title="Windows" alt="Windows" />
Linux
<img src="linux-02.jpg" width="700" title="Linux" alt="Linux" />
macOS
<img src="macos-01.jpg" width="700" title="macOS" alt="macOS" />
Linux Motif
<img src="motif-01.jpg" width="700" title="Linux Motif" alt="Linux Motif" />
Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

+21 -16
View File
@@ -1,29 +1,34 @@
module github.com/gen2brain/cbconvert/cmd/cbconvert module github.com/gen2brain/cbconvert/cmd/cbconvert
go 1.19 go 1.21
//replace github.com/gen2brain/cbconvert => ../../
require ( require (
github.com/gen2brain/cbconvert v0.0.0-20230602085208-16d01e292edd github.com/gen2brain/cbconvert v1.0.4-0.20240208144735-a8084ed89758
github.com/schollz/progressbar/v3 v3.10.0 github.com/schollz/progressbar/v3 v3.13.1
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
) )
require ( require (
github.com/chai2010/webp v1.1.1 // indirect git.sr.ht/~jackmordaunt/go-libwebp v1.1.0 // indirect
github.com/disintegration/imaging v1.6.2 // indirect github.com/disintegration/imaging v1.6.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.5.2 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/gen2brain/go-fitz v1.22.2 // indirect github.com/gen2brain/go-fitz v1.23.7 // indirect
github.com/gen2brain/go-unarr v0.1.7 // indirect github.com/gen2brain/go-unarr v0.2.0 // indirect
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.3.4 // indirect github.com/rivo/uniseg v0.3.4 // indirect
github.com/strukturag/libheif v1.13.0 // indirect golang.org/x/image v0.15.0 // indirect
golang.org/x/image v0.7.0 // indirect golang.org/x/sync v0.6.0 // indirect
golang.org/x/sync v0.2.0 // indirect golang.org/x/sys v0.17.0 // indirect
golang.org/x/sys v0.5.0 // indirect golang.org/x/term v0.6.0 // indirect
golang.org/x/term v0.5.0 // indirect gopkg.in/gographics/imagick.v3 v3.5.1 // indirect
gopkg.in/gographics/imagick.v3 v3.4.2 // indirect modernc.org/libc v1.41.0 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
) )
+43 -57
View File
@@ -1,80 +1,66 @@
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk= git.sr.ht/~jackmordaunt/go-libwebp v1.1.0 h1:rfDv89tb6OuNp8f1TyprOZWaeC/TxqaYvLCI6nHKBY8=
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU= git.sr.ht/~jackmordaunt/go-libwebp v1.1.0/go.mod h1:8557wZRj8KWRPBM+osAuAXVVR5nVURZ3SCG5rnACBdE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= 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/ebitengine/purego v0.5.2 h1:r2MQEtkGzZ4LRtFZVAg5bjYKnUbxxloaeuGxH0t7qfs=
github.com/ebitengine/purego v0.5.2/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= 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/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/gen2brain/cbconvert v0.0.0-20230602085208-16d01e292edd h1:vfoiB9k/XWPVwCK5Wu0F5U60L5zqDmdZO5br7tDGITw= github.com/gen2brain/cbconvert v1.0.4-0.20240208144735-a8084ed89758 h1:VXWir2Nq5qkXuIeoCTavOlQ7j2Yab0vIJe1mvKsLe3I=
github.com/gen2brain/cbconvert v0.0.0-20230602085208-16d01e292edd/go.mod h1:xxmaVGM48oWMKNp0Dwlb7XwN2dWx6Jp4DkjNuaTrAOo= github.com/gen2brain/cbconvert v1.0.4-0.20240208144735-a8084ed89758/go.mod h1:jtc/vKGuG66vIemtQc6Ge69FXo33hX+gFvGtEP/z/SM=
github.com/gen2brain/go-fitz v1.22.2 h1:pisRYS3x/tvsiS4UzdBoiStmOxYoisOGNCUB4+0RKhE= github.com/gen2brain/go-fitz v1.23.7 h1:HPhzEVzmOINvCKqQgB/DwMzYh4ArIgy3tMwq1eJTcbg=
github.com/gen2brain/go-fitz v1.22.2/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ= github.com/gen2brain/go-fitz v1.23.7/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ=
github.com/gen2brain/go-unarr v0.1.7 h1:mEE7bPShJIsmAX67t6BW2ibpEUO7j5WK152KgNM9NbQ= github.com/gen2brain/go-unarr v0.2.0 h1:sYKSjbeNSuZgudd59iGAbMbr113XRFoA7Rt9XWA+QVE=
github.com/gen2brain/go-unarr v0.1.7/go.mod h1:MK9a3hddpaIxjEtrE1f/LA5yJ7gA34cS7Oyr325sY9s= github.com/gen2brain/go-unarr v0.2.0/go.mod h1:hoHheVuf0KT8/hfvkEL7GMwj2h7fq0lF72NdyySdr3c=
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7 h1:NlUATi3cllRJhpM4mfR9BxiLRXT83bcSLcOa+S8lrME= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7/go.mod h1:Hku3FQ2laCEwSv7Z8YkC0er38jLaUycUCbsFkWMr+z4= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= 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-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/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 h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 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 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 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.13.1 h1:o8rySDYiQ59Mwzy2FELeHY5ZARXZTVJC7iHD6PEFUiE=
github.com/schollz/progressbar/v3 v3.10.0/go.mod h1:0N6zRwbDVLFCFy5chxuukVlRkoHWYFFLzlxQrw/sf3M= github.com/schollz/progressbar/v3 v3.13.1/go.mod h1:xvrbki8kfT1fzWzBT/UZd9L6GA+jdL7HAgq2RFnO6fQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 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/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/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 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/strukturag/libheif v1.13.0 h1:SuLo/Fl/Nzbw0ixOya1YZSl0Xd27X4fgofGnJdvOHqI=
github.com/strukturag/libheif v1.13.0/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.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw= golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg= golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
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.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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-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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= gopkg.in/gographics/imagick.v3 v3.5.1 h1:58JqK0UCx5RfvbRggF5FKuK6jHwAtTQopUxK8mzFa40=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= gopkg.in/gographics/imagick.v3 v3.5.1/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/gographics/imagick.v3 v3.4.2 h1:vk6oildvhRBVSBfQ4X3raJstApYSeK6CZsyzoSOZk58=
gopkg.in/gographics/imagick.v3 v3.4.2/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
+156 -78
View File
@@ -1,26 +1,63 @@
package main package main
import ( import (
"bufio"
"fmt" "fmt"
"io"
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"runtime/debug"
"syscall" "syscall"
"github.com/gen2brain/cbconvert" "github.com/gen2brain/cbconvert"
"github.com/schollz/progressbar/v3" pb "github.com/schollz/progressbar/v3"
flag "github.com/spf13/pflag" 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() { func main() {
opts, args := parseFlags() opts, args := parseFlags()
if opts.Version {
fmt.Println(filepath.Base(os.Args[0]), appVersion)
os.Exit(0)
}
conv := cbconvert.New(opts) conv := cbconvert.New(opts)
c := make(chan os.Signal, 2) c := make(chan os.Signal, 2)
signal.Notify(c, os.Interrupt, syscall.SIGTERM) signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() { go func() {
for range c { for range c {
fmt.Println("\naborting")
if err := os.RemoveAll(conv.Workdir); err != nil { if err := os.RemoveAll(conv.Workdir); err != nil {
fmt.Println(err) fmt.Println(err)
} }
@@ -28,8 +65,8 @@ func main() {
} }
}() }()
if _, err := os.Stat(opts.Outdir); err != nil { if _, err := os.Stat(opts.OutDir); err != nil {
if err := os.MkdirAll(opts.Outdir, 0775); err != nil { if err := os.MkdirAll(opts.OutDir, 0775); err != nil {
fmt.Println(err) fmt.Println(err)
} }
os.Exit(1) os.Exit(1)
@@ -44,26 +81,26 @@ func main() {
os.Exit(1) os.Exit(1)
} }
var bar *progressbar.ProgressBar var bar *pb.ProgressBar
if opts.Cover || opts.Thumbnail || opts.Meta { if opts.Cover || opts.Thumbnail || opts.Meta {
if !opts.Quiet { if !opts.Quiet {
bar = progressbar.NewOptions(conv.Nfiles, bar = pb.NewOptions(conv.Nfiles,
progressbar.OptionShowCount(), pb.OptionShowCount(),
progressbar.OptionClearOnFinish(), pb.OptionClearOnFinish(),
progressbar.OptionUseANSICodes(true), pb.OptionUseANSICodes(true),
progressbar.OptionSetPredictTime(false), pb.OptionSetPredictTime(false),
) )
} }
} }
conv.OnStart = func() { conv.OnStart = func() {
if !opts.Quiet { if !opts.Quiet {
bar = progressbar.NewOptions(conv.Ncontents, bar = pb.NewOptions(conv.Ncontents,
progressbar.OptionShowCount(), pb.OptionShowCount(),
progressbar.OptionClearOnFinish(), pb.OptionClearOnFinish(),
progressbar.OptionUseANSICodes(true), pb.OptionUseANSICodes(true),
progressbar.OptionSetDescription(fmt.Sprintf("Converting %d of %d:", conv.CurrFile, conv.Nfiles)), pb.OptionSetDescription(fmt.Sprintf("Converting %d of %d:", conv.CurrFile, conv.Nfiles)),
progressbar.OptionSetPredictTime(false), pb.OptionSetPredictTime(false),
) )
} }
} }
@@ -76,19 +113,14 @@ func main() {
conv.OnCompress = func() { conv.OnCompress = func() {
if !opts.Quiet { if !opts.Quiet {
_, _ = fmt.Fprintf(os.Stderr, "Compressing %d of %d...\r", conv.CurrFile, conv.Nfiles) fmt.Fprintf(os.Stderr, "Compressing %d of %d...\r", conv.CurrFile, conv.Nfiles)
} }
} }
for _, file := range files { for _, file := range files {
stat, err := os.Stat(file) switch {
if err != nil { case opts.Meta:
fmt.Println(err) ret, err := conv.Meta(file.Path)
os.Exit(1)
}
if opts.Meta {
ret, err := conv.Meta(file, stat)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
@@ -96,31 +128,37 @@ func main() {
if opts.Cover { if opts.Cover {
fmt.Println(ret) fmt.Println(ret)
} else if opts.Comment {
fmt.Println(ret)
} }
continue continue
} else if opts.Cover { case opts.Cover:
if err := conv.Cover(file, stat); err != nil { if err := conv.Cover(file.Path, file.Stat); err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
continue continue
} else if opts.Thumbnail { case opts.Thumbnail:
if err = conv.Thumbnail(file, stat); err != nil { if err = conv.Thumbnail(file.Path, file.Stat); err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
continue continue
} }
if err := conv.Convert(file, stat); err != nil { if err := conv.Convert(file.Path, file.Stat); err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
} }
fmt.Fprintf(os.Stderr, "\r")
} }
// parseFlags parses command line flags // parseFlags parses command line flags.
func parseFlags() (cbconvert.Options, []string) { func parseFlags() (cbconvert.Options, []string) {
opts := cbconvert.Options{} opts := cbconvert.Options{}
var args []string var args []string
@@ -130,9 +168,9 @@ func parseFlags() (cbconvert.Options, []string) {
convert.IntVar(&opts.Width, "width", 0, "Image width") convert.IntVar(&opts.Width, "width", 0, "Image width")
convert.IntVar(&opts.Height, "height", 0, "Image height") convert.IntVar(&opts.Height, "height", 0, "Image height")
convert.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and 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.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl")
convert.StringVar(&opts.Archive, "archive", "zip", "Archive format, valid values are zip, tar")
convert.IntVar(&opts.Quality, "quality", 75, "Image quality") 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.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.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.NoRGB, "no-rgb", false, "Do not convert images that have RGB colorspace")
@@ -140,17 +178,16 @@ func parseFlags() (cbconvert.Options, []string) {
convert.BoolVar(&opts.NoConvert, "no-convert", false, "Do not transform or convert images") 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.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.Rotate, "rotate", 0, "Rotate images, valid values are 0, 90, 180, 270")
convert.StringVar(&opts.Flip, "flip", "none", "Flip images, valid values are none, horizontal, vertical") convert.IntVar(&opts.Brightness, "brightness", 0, "Adjust the brightness of the images, must be in the range (-100, 100)")
convert.Float64Var(&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.Float64Var(&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.StringVar(&opts.Suffix, "suffix", "", "Add suffix to file basename")
convert.Float64Var(&opts.LevelsInMin, "levels-inmin", 0, "Shadow input value") convert.IntVar(&opts.LevelsInMin, "levels-inmin", 0, "Shadow input value")
convert.Float64Var(&opts.LevelsGamma, "levels-gamma", 1.0, "Midpoint/Gamma") convert.Float64Var(&opts.LevelsGamma, "levels-gamma", 1.0, "Midpoint/Gamma")
convert.Float64Var(&opts.LevelsInMax, "levels-inmax", 255, "Highlight input value") convert.IntVar(&opts.LevelsInMax, "levels-inmax", 255, "Highlight input value")
convert.Float64Var(&opts.LevelsOutMin, "levels-outmin", 0, "Shadow output value") convert.IntVar(&opts.LevelsOutMin, "levels-outmin", 0, "Shadow output value")
convert.Float64Var(&opts.LevelsOutMax, "levels-outmax", 255, "Highlight output value") convert.IntVar(&opts.LevelsOutMax, "levels-outmax", 255, "Highlight output value")
convert.StringVar(&opts.Outdir, "outdir", ".", "Output directory") convert.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
convert.Int64Var(&opts.Size, "size", 0, "Process only files larger than size (in MB)") 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.Recursive, "recursive", false, "Process subdirectories recursively")
convert.BoolVar(&opts.Quiet, "quiet", false, "Hide console output") convert.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
@@ -162,8 +199,8 @@ func parseFlags() (cbconvert.Options, []string) {
cover.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif") 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.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.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.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
cover.Int64Var(&opts.Size, "size", 0, "Process only files larger than size (in MB)") 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.Recursive, "recursive", false, "Process subdirectories recursively")
cover.BoolVar(&opts.Quiet, "quiet", false, "Hide console output") cover.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
@@ -173,78 +210,119 @@ func parseFlags() (cbconvert.Options, []string) {
thumbnail.IntVar(&opts.Height, "height", 0, "Image height") thumbnail.IntVar(&opts.Height, "height", 0, "Image height")
thumbnail.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and 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.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.OutDir, "outdir", ".", "Output directory")
thumbnail.StringVar(&opts.Outfile, "outfile", "", "Output file") thumbnail.StringVar(&opts.OutFile, "outfile", "", "Output file")
thumbnail.Int64Var(&opts.Size, "size", 0, "Process only files larger than size (in MB)") 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.Recursive, "recursive", false, "Process subdirectories recursively")
thumbnail.BoolVar(&opts.Quiet, "quiet", false, "Hide console output") thumbnail.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
meta := flag.NewFlagSet("meta", flag.ExitOnError) meta := flag.NewFlagSet("meta", flag.ExitOnError)
meta.SortFlags = false meta.SortFlags = false
meta.BoolVar(&opts.Cover, "cover", false, "Print cover name") 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)")
convert.Usage = func() { flag.NewFlagSet("version", flag.ExitOnError)
_, _ = fmt.Fprintf(os.Stderr, "Usage: %s <command> [<flags>] [file1 dir1 ... fileOrDirN]\n\n", filepath.Base(os.Args[0]))
_, _ = fmt.Fprintf(os.Stderr, "\nCommands:\n") flag.Usage = func() {
_, _ = fmt.Fprintf(os.Stderr, "\n convert*\n \tConvert archive or document (default command)\n\n") 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) { convert.VisitAll(func(f *flag.Flag) {
_, _ = fmt.Fprintf(os.Stderr, " --%s", f.Name) fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
_, _ = fmt.Fprintf(os.Stderr, "\n \t") fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
}) })
_, _ = fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n") fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n")
cover.VisitAll(func(f *flag.Flag) { cover.VisitAll(func(f *flag.Flag) {
_, _ = fmt.Fprintf(os.Stderr, " --%s", f.Name) fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
_, _ = fmt.Fprintf(os.Stderr, "\n \t") fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
_, _ = 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") fmt.Fprintf(os.Stderr, "\n thumbnail\n \tExtract cover thumbnail (freedesktop spec.)\n\n")
thumbnail.VisitAll(func(f *flag.Flag) { thumbnail.VisitAll(func(f *flag.Flag) {
_, _ = fmt.Fprintf(os.Stderr, " --%s", f.Name) fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
_, _ = fmt.Fprintf(os.Stderr, "\n \t") fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
}) })
_, _ = fmt.Fprintf(os.Stderr, "\n meta\n \tCBZ metadata\n\n") fmt.Fprintf(os.Stderr, "\n meta\n \tCBZ metadata\n\n")
meta.VisitAll(func(f *flag.Flag) { meta.VisitAll(func(f *flag.Flag) {
_, _ = fmt.Fprintf(os.Stderr, " --%s", f.Name) fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
_, _ = fmt.Fprintf(os.Stderr, "\n \t") fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
}) })
_, _ = fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "\n version\n \tPrint version\n\n")
} }
if len(os.Args) < 2 { if len(os.Args) < 2 {
convert.Usage() flag.Usage()
_, _ = fmt.Fprintf(os.Stderr, "no arguments\n") fmt.Fprintf(os.Stderr, "no command\n")
os.Exit(1) os.Exit(1)
} }
pipe := piped()
if pipe {
args = lines(os.Stdin)
}
switch os.Args[1] { switch os.Args[1] {
case "convert": case "convert":
_ = convert.Parse(os.Args[2:]) _ = convert.Parse(os.Args[2:])
args = convert.Args() if !pipe {
args = convert.Args()
}
case "cover": case "cover":
opts.Cover = true opts.Cover = true
_ = cover.Parse(os.Args[2:]) _ = cover.Parse(os.Args[2:])
args = cover.Args() if !pipe {
args = cover.Args()
}
case "thumbnail": case "thumbnail":
opts.Thumbnail = true opts.Thumbnail = true
_ = thumbnail.Parse(os.Args[2:]) _ = thumbnail.Parse(os.Args[2:])
args = thumbnail.Args() if !pipe {
args = thumbnail.Args()
}
case "meta": case "meta":
opts.Meta = true opts.Meta = true
_ = meta.Parse(os.Args[2:]) _ = meta.Parse(os.Args[2:])
args = meta.Args() if !pipe {
default: args = meta.Args()
_ = convert.Parse(os.Args[1:]) }
args = convert.Args() case "version":
opts.Version = true
} }
if len(args) == 0 { if len(args) == 0 && !opts.Version {
convert.Usage() flag.Usage()
_, _ = fmt.Fprintf(os.Stderr, "no arguments\n") _, _ = fmt.Fprintf(os.Stderr, "no arguments\n")
os.Exit(1) os.Exit(1)
} }
return opts, args 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
}
+22 -46
View File
@@ -1,15 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
GLIBC_x86_64="/usr/x86_64-pc-linux-gnu-static" GLIBC_x86_64="/usr/x86_64-pc-linux-gnu-static"
MUSL_x86_64="/usr/x86_64-pc-linux-musl"
MUSL_aarch64="/usr/aarch64-pc-linux-musl"
MINGW_x86_64="/usr/x86_64-w64-mingw32" MINGW_x86_64="/usr/x86_64-w64-mingw32"
MACOS_x86_64="/usr/x86_64-apple-darwin" MACOS_x86_64="/usr/x86_64-apple-darwin"
MACOS_aarch64="/usr/aarch64-apple-darwin" MACOS_aarch64="/usr/aarch64-apple-darwin"
VERSION="`git --git-dir ../../.git describe --tags --abbrev=0 2>/dev/null || echo '0.0.0'`" VERSION="$(git --git-dir ../../.git describe --tags --abbrev=0 2>/dev/null || echo '1.0.0')"
BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR} BUILDDIR="cbconvert-${VERSION}"
mkdir -p "${BUILDDIR}"
CC=x86_64-pc-linux-gnu-gcc \ CC=x86_64-pc-linux-gnu-gcc \
PKG_CONFIG="x86_64-pc-linux-gnu-pkg-config" \ PKG_CONFIG="x86_64-pc-linux-gnu-pkg-config" \
PKG_CONFIG_PATH="$GLIBC_x86_64/usr/lib64/pkgconfig" \ PKG_CONFIG_PATH="$GLIBC_x86_64/usr/lib64/pkgconfig" \
@@ -17,70 +17,46 @@ PKG_CONFIG_LIBDIR="$GLIBC_x86_64/usr/lib64/pkgconfig" \
CGO_CFLAGS="-I$GLIBC_x86_64/usr/include" \ CGO_CFLAGS="-I$GLIBC_x86_64/usr/include" \
CGO_LDFLAGS="-L$GLIBC_x86_64/usr/lib64" \ CGO_LDFLAGS="-L$GLIBC_x86_64/usr/lib64" \
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \ CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert -ldflags "-linkmode external -s -w '-extldflags=-static'" && \ 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} cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && tar -czf "${BUILDDIR}-linux-x86_64.tar.gz" "${BUILDDIR}"
rm -rf ${BUILDDIR} rm -rf "${BUILDDIR}"
#BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR} mkdir -p "${BUILDDIR}"
#CC=x86_64-pc-linux-musl-gcc \
#PKG_CONFIG="x86_64-pc-linux-musl-pkg-config" \
#PKG_CONFIG_PATH="$MUSL_x86_64/usr/lib/pkgconfig" \
#PKG_CONFIG_LIBDIR="$MUSL_x86_64/usr/lib/pkgconfig" \
#CGO_CFLAGS="-I$MUSL_x86_64/usr/include" \
#CGO_LDFLAGS="-L$MUSL_x86_64/usr/lib" \
#CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \
#go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert -ldflags "-linkmode external -s -w '-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 '-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 \ CC=x86_64-w64-mingw32-gcc \
PKG_CONFIG="/usr/bin/x86_64-w64-mingw32-pkg-config" \ PKG_CONFIG="/usr/bin/x86_64-w64-mingw32-pkg-config" \
PKG_CONFIG_PATH="$MINGW_x86_64/usr/lib/pkgconfig" \ PKG_CONFIG_PATH="$MINGW_x86_64/usr/lib/pkgconfig" \
PKG_CONFIG_LIBDIR="$MINGW_x86_64/usr/lib/pkgconfig" \ PKG_CONFIG_LIBDIR="$MINGW_x86_64/usr/lib/pkgconfig" \
CGO_CFLAGS="-I$MINGW_x86_64/usr/include" \ CGO_CFLAGS="-I$MINGW_x86_64/usr/include" \
CGO_LDFLAGS="-L$MINGW_x86_64/usr/lib" \ CGO_LDFLAGS="-L$MINGW_x86_64/usr/lib -ljxl -ljxl_dec -ljxl_profiler -ljxl_threads" \
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 \ CGO_ENABLED=1 GOOS=windows GOARCH=amd64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert.exe -ldflags "-s -w '-extldflags=-static -Wl,--allow-multiple-definition'" && \ 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} cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && zip -rq "${BUILDDIR}-windows-x86_64.zip" "${BUILDDIR}"
rm -rf ${BUILDDIR} rm -rf "${BUILDDIR}"
export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1 export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1
BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR} mkdir -p "${BUILDDIR}"
PATH=${PATH}:${MACOS_x86_64}/bin \ PATH=${PATH}:${MACOS_x86_64}/bin \
CC=x86_64-apple-darwin21.1-clang \ CC=x86_64-apple-darwin21.1-clang \
PKG_CONFIG="x86_64-apple-darwin21.1-pkg-config" \ PKG_CONFIG="x86_64-apple-darwin21.1-pkg-config" \
PKG_CONFIG_PATH="$MACOS_x86_64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \ 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" \ 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_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_LDFLAGS="-L$MACOS_x86_64/SDK/MacOSX12.1.sdk/usr/lib -L$MACOS_x86_64/macports/pkgs/opt/local/lib -mmacosx-version-min=10.15" \
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 \ CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert -ldflags "-linkmode external -s -w" && \ 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} cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && zip -rq "${BUILDDIR}-darwin-x86_64.zip" "${BUILDDIR}"
rm -rf ${BUILDDIR} rm -rf "${BUILDDIR}"
export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1 export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1
BUILDDIR="cbconvert-${VERSION}"; mkdir -p ${BUILDDIR} mkdir -p "${BUILDDIR}"
PATH=${PATH}:${MACOS_aarch64}/bin \ PATH=${PATH}:${MACOS_aarch64}/bin \
CC=aarch64-apple-darwin21.1-clang \ CC=aarch64-apple-darwin21.1-clang \
PKG_CONFIG="aarch64-apple-darwin21.1-pkg-config" \ PKG_CONFIG="aarch64-apple-darwin21.1-pkg-config" \
PKG_CONFIG_PATH="$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \ PKG_CONFIG_PATH="$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
PKG_CONFIG_LIBDIR="$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_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_LDFLAGS="-L$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib -L$MACOS_aarch64/macports/pkgs/opt/local/lib -mmacosx-version-min=10.15" \
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 \ CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o ${BUILDDIR}/cbconvert -ldflags "-linkmode external -s -w" && \ 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} cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && zip -rq "${BUILDDIR}-darwin-aarch64.zip" "${BUILDDIR}"
rm -rf ${BUILDDIR} rm -rf "${BUILDDIR}"
Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

+19 -9
View File
@@ -1,16 +1,26 @@
module github.com/gen2brain/cbconvert module github.com/gen2brain/cbconvert
go 1.19 go 1.21
require ( require (
github.com/chai2010/webp v1.1.1 git.sr.ht/~jackmordaunt/go-libwebp v1.1.0
github.com/disintegration/imaging v1.6.2 github.com/disintegration/imaging v1.6.2
github.com/dustin/go-humanize v1.0.1
github.com/fvbommel/sortorder v1.1.0 github.com/fvbommel/sortorder v1.1.0
github.com/gen2brain/go-fitz v1.22.2 github.com/gen2brain/go-fitz v1.23.7
github.com/gen2brain/go-unarr v0.1.7 github.com/gen2brain/go-unarr v0.2.0
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7 golang.org/x/image v0.15.0
github.com/strukturag/libheif v1.13.0 golang.org/x/sync v0.6.0
golang.org/x/image v0.7.0 gopkg.in/gographics/imagick.v3 v3.5.1
golang.org/x/sync v0.2.0 )
gopkg.in/gographics/imagick.v3 v3.4.2
require (
github.com/ebitengine/purego v0.5.1 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.13.0 // indirect
modernc.org/libc v1.24.1 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
) )
+31 -46
View File
@@ -1,52 +1,37 @@
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk= git.sr.ht/~jackmordaunt/go-libwebp v1.1.0 h1:rfDv89tb6OuNp8f1TyprOZWaeC/TxqaYvLCI6nHKBY8=
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU= git.sr.ht/~jackmordaunt/go-libwebp v1.1.0/go.mod h1:8557wZRj8KWRPBM+osAuAXVVR5nVURZ3SCG5rnACBdE=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= 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/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/ebitengine/purego v0.5.1 h1:hNunhThpOf1vzKl49v6YxIsXLhl92vbBEv1/2Ez3ZrY=
github.com/ebitengine/purego v0.5.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= 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/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/gen2brain/go-fitz v1.22.2 h1:pisRYS3x/tvsiS4UzdBoiStmOxYoisOGNCUB4+0RKhE= github.com/gen2brain/go-fitz v1.23.7 h1:HPhzEVzmOINvCKqQgB/DwMzYh4ArIgy3tMwq1eJTcbg=
github.com/gen2brain/go-fitz v1.22.2/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ= github.com/gen2brain/go-fitz v1.23.7/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ=
github.com/gen2brain/go-unarr v0.1.7 h1:mEE7bPShJIsmAX67t6BW2ibpEUO7j5WK152KgNM9NbQ= github.com/gen2brain/go-unarr v0.2.0 h1:sYKSjbeNSuZgudd59iGAbMbr113XRFoA7Rt9XWA+QVE=
github.com/gen2brain/go-unarr v0.1.7/go.mod h1:MK9a3hddpaIxjEtrE1f/LA5yJ7gA34cS7Oyr325sY9s= github.com/gen2brain/go-unarr v0.2.0/go.mod h1:hoHheVuf0KT8/hfvkEL7GMwj2h7fq0lF72NdyySdr3c=
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7 h1:NlUATi3cllRJhpM4mfR9BxiLRXT83bcSLcOa+S8lrME= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/hotei/bmp v0.0.0-20150430041436-f620cebab0c7/go.mod h1:Hku3FQ2laCEwSv7Z8YkC0er38jLaUycUCbsFkWMr+z4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/strukturag/libheif v1.13.0 h1:SuLo/Fl/Nzbw0ixOya1YZSl0Xd27X4fgofGnJdvOHqI= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/strukturag/libheif v1.13.0/go.mod h1:E/PNRlmVtrtj9j2AvBZlrO4dsBDu6KfwDZn7X1Ce8Ks= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
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.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw= golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg= golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= gopkg.in/gographics/imagick.v3 v3.5.1 h1:58JqK0UCx5RfvbRggF5FKuK6jHwAtTQopUxK8mzFa40=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= gopkg.in/gographics/imagick.v3 v3.5.1/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/gographics/imagick.v3 v3.4.2 h1:vk6oildvhRBVSBfQ4X3raJstApYSeK6CZsyzoSOZk58=
gopkg.in/gographics/imagick.v3 v3.4.2/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB