107 Commits

Author SHA1 Message Date
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
Milan Nikolic dfea3dc6a3 Update dependencies 2023-06-02 10:55:02 +02:00
Milan Nikolic 16d01e292e Update dependencies 2023-06-02 10:52:08 +02:00
Milan Nikolic 6fe10f5bdb Update README.md 2023-06-02 10:46:38 +02:00
Milan Nikolic 547a3937a8 Update dependencies 2023-06-02 10:43:36 +02:00
Milan Nikolic d47c1c1464 Use ToSlash for cover, issue #19 2023-06-02 10:32:09 +02:00
Milan Nikolic 5befff07ae Handle all errors 2023-03-08 06:21:57 +01:00
Milan Nikolic d4abc99239 Add meta command 2023-03-08 05:42:49 +01:00
Milan Nikolic f1804ce13c Refactor 2023-03-04 11:30:11 +01:00
Milan Nikolic a74034d669 Update modules 2023-03-04 10:35:41 +01:00
Milan Nikolic 64fb152c36 Cover format, issue #18 2023-03-04 10:27:01 +01:00
Milan Nikolic 7082e3db90 Initialize IM 2023-01-14 10:52:04 +01:00
Milan Nikolic 943cd9bb95 Close file 2023-01-14 10:39:20 +01:00
Milan Nikolic ec2c321ff3 Expose IM functions 2023-01-14 10:37:17 +01:00
Milan Nikolic a0ed277971 Update README.md 2023-01-13 18:37:40 +01:00
Milan Nikolic b5b4457088 Update build 2023-01-13 18:33:57 +01:00
Milan Nikolic c24d7b7e18 Update README.md 2023-01-12 13:36:20 +01:00
Milan Nikolic 8ba065e68b Use pkgconfig 2023-01-12 13:18:42 +01:00
Milan Nikolic 9cd5616b48 Build linux/arm64 binary 2023-01-12 13:08:21 +01:00
Milan Nikolic 13a3b6e23e Update README.md 2023-01-12 10:06:09 +01:00
Milan Nikolic 9a047d1977 Fallback to IM decoding for broken images, issue #15 2023-01-12 10:03:45 +01:00
Milan Nikolic d6e7248112 Case-insensitive for coverName, issue #13 2023-01-12 09:10:24 +01:00
Milan Nikolic 9eb20db167 Handle errors 2023-01-12 08:45:32 +01:00
Milan Nikolic 04d2dd79d5 Handle no-convert for directories, issue #9 2023-01-12 08:44:00 +01:00
Milan Nikolic 2b2788ed6e Update modules 2022-12-08 12:38:38 +01:00
Milan Nikolic 164e7bfd75 Update modules 2022-12-08 12:35:53 +01:00
Milan Nikolic 27da60ed76 Update modules 2022-12-08 12:28:08 +01:00
Milan Nikolic 0963cb1762 Update README.md 2022-09-09 10:01:14 +02:00
Milan Nikolic 443c4e6aaa Update README.md 2022-09-08 23:44:56 +02:00
Milan Nikolic 9da5b97f15 Add support for AVIF 2022-09-08 23:38:58 +02:00
Milan Nikolic adbb86f9f7 Add more architectures 2022-09-08 23:36:47 +02:00
Milan Nikolic efb8b776fb Fixes 2022-09-07 19:55:59 +02:00
Milan Nikolic fa954fce1a Fixes 2022-09-07 12:16:50 +02:00
Milan Nikolic 7d80f5238e Update README.md 2022-09-05 18:45:43 +02:00
Milan Nikolic 56e07aae23 Update version 2022-09-05 18:45:30 +02:00
Milan Nikolic 3c3123a50d Update README.md 2022-09-05 18:32:46 +02:00
Milan Nikolic 2e03350437 Update README.md 2022-09-05 18:16:27 +02:00
Milan Nikolic 1fdc1610f5 Update README.md 2022-09-05 18:13:03 +02:00
Milan Nikolic a5e796d017 Remove actions 2022-09-05 18:12:48 +02:00
Milan Nikolic cffd119eba Add actions 2022-09-05 18:04:18 +02:00
Milan Nikolic cda03e0122 Big update 2022-09-05 18:03:58 +02:00
Milan Nikolic 6a73f6f20e Remove defunct GUI 2022-09-05 18:01:45 +02:00
Milan Nikolic 5df10a58ee Update README.md 2017-01-24 15:30:08 +01:00
Milan Nikolic 081736ee04 new release 2016-01-22 17:28:02 +01:00
Milan Nikolic 50f1edb843 Merge branch 'master' of github.com:gen2brain/cbconvert 2016-01-22 17:17:59 +01:00
Milan Nikolic 2c5bc9e21d support thumbnails in file managers 2016-01-22 17:17:43 +01:00
Milan Nikolic d9cdf2e197 Update README.md 2015-12-02 23:57:10 +01:00
Milan Nikolic 68e868944b Update README.md 2015-12-02 21:48:51 +01:00
Milan Nikolic 3a84012005 Update README.md 2015-12-02 21:24:21 +01:00
Milan Nikolic 23802d2d00 Update README.md 2015-12-02 20:53:26 +01:00
Milan Nikolic 17e598bb3b Update README.md 2015-12-02 20:53:01 +01:00
Milan Nikolic 2fd32c30e3 Update README.md 2015-12-02 20:52:30 +01:00
Milan Nikolic b930b06a7d add GUI 2015-12-02 20:46:42 +01:00
Milan Nikolic c8d472e576 Update README.md 2015-11-05 10:22:30 +01:00
Milan Nikolic 6701bfcfb0 rename cmd 2015-11-05 10:17:39 +01:00
Milan Nikolic 6cea1aa441 rename cmd 2015-11-05 10:14:41 +01:00
Milan Nikolic a05b46e6b8 move main to cmd dir 2015-11-05 10:09:44 +01:00
Milan Nikolic d77d2c0ce7 convertor struct 2015-11-05 09:54:21 +01:00
Milan Nikolic bc8520d825 Update README.md 2015-11-05 08:03:56 +01:00
Milan Nikolic 3619ed6c0d Update README.md 2015-11-05 07:59:07 +01:00
57 changed files with 4642 additions and 958 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
+164 -112
View File
@@ -1,156 +1,208 @@
CBconvert ## CBconvert
=========
Introduction ### Introduction
------------
CBconvert is a [Comic Book](http://en.wikipedia.org/wiki/Comic_Book_Archive_file) converter. CBconvert is a [Comic Book](http://en.wikipedia.org/wiki/Comic_Book_Archive_file) converter.
It allows you to convert individual comics or bulk convert comics to different formats to fit your various devices.
Features It can convert comics to different formats to fit your various devices.
--------
- reads RAR, ZIP, 7Z, GZ, BZ2, CBR, CBZ, CB7, CBT, PDF, EPUB, XPS and plain directory <img src="cmd/cbconvert-gui/screenshots/linux-01.jpg" width="700" alt="screenshot" />
- always saves processed comic in CBZ (ZIP) archive format
- images can be converted to JPEG, PNG, GIF, TIFF or 4-Bit BMP (16 colors) file format
- choose resize algorithm (NearestNeighbor, Box, Linear, MitchellNetravali, CatmullRom, Gaussian, Lanczos)
- rotate, flip, adjust brightness/contrast or grayscale images
- export covers from comics
- create thumbnails from covers by [freedesktop](http://www.freedesktop.org/wiki/) specification
Download See more [screnshots](https://github.com/gen2brain/cbconvert/blob/master/cmd/cbconvert-gui/screenshots/).
--------
- [Windows binary](https://github.com/gen2brain/cbconvert/releases/download/0.4.0/cbconvert-0.4.0.zip) ### Features
- [Linux 64bit binary](https://github.com/gen2brain/cbconvert/releases/download/0.4.0/cbconvert-0.4.0.tar.gz) * reads CBR (RAR), CBZ (ZIP), CB7 (7Z), CBT (TAR), PDF, XPS, EPUB, MOBI and plain directory
- [Linux 64bit static binary](https://github.com/gen2brain/cbconvert/releases/download/0.4.0/cbconvert-0.4.0-static.tar.gz) * saves processed files in ZIP archive format or TAR
* images can be converted to JPEG, PNG, TIFF, WEBP, AVIF, JXL, or 4-Bit BMP (16 colors) image format
* rotate, adjust brightness/contrast, adjust levels (Photoshop-like) or grayscale images
* resize filters (NearestNeighbor, Box, Linear, MitchellNetravali, CatmullRom, Gaussian, Lanczos)
* export covers from comics
* create thumbnails from covers by [FreeDesktop](http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html) specification
Using ### Download
-----
usage: cbconvert [<flags>] <command> [<args> ...] * [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/latest/download/cbconvert-1.0.0-linux-x86_64.tar.gz)
* [macOS x86_64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-1.0.0-darwin-x86_64.zip)
* [macOS aarch64](https://github.com/gen2brain/cbconvert/releases/latest/download/cbconvert-1.0.0-darwin-aarch64.zip)
Comic Book convert tool. ### Using cbconvert in file managers to generate FreeDesktop thumbnails
Flags: Copy `cbconvert` cli binary to your PATH and create file `~/.local/share/thumbnailers/cbconvert.thumbnailer`:
--help Show context-sensitive help (also try --help-long and --help-man).
--version Show application version.
--outdir="." Output directory
--size=0 Process only files larger then size (in MB)
--recursive Process subdirectories recursively
--quiet Hide console output
Args: ```
<args> filename or directory [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;
```
Commands: This is what it looks like in the PCManFM file manager:
help [<command>...]
Show help. <img src="cmd/cbconvert/screenshots/thumbnails.jpg" width="700" alt="thumbnails" />
convert [<flags>] <args>... ### Using command line app
Convert archive or document (default command)
--width=0 Image width ```
--height=0 Image height     Usage: cbconvert <command> [<flags>] [file1 dir1 ... fileOrDirN]
--fit Best fit for required width and height
--quality=75 JPEG image quality
--filter=2 0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos
--png Encode images to PNG instead of JPEG
--bmp Encode images to 4-Bit BMP (16 colors) instead of JPEG
--gif Encode images to GIF instead of JPEG
--tiff Encode images to TIFF instead of JPEG
--rgb Convert images that have RGB colorspace (use --no-rgb if you only want to convert grayscale images)
--nonimage Leave non image files in archive (use --no-nonimage to remove non image files from archive)
--grayscale Convert images to grayscale (monochromatic)
--rotate=0 Rotate images, valid values are 0, 90, 180, 270
--flip="none" Flip images, valid values are none, horizontal, vertical
--brightness=0 Adjust brightness of the images, must be in range (-100, 100)
--contrast=0 Adjust contrast of the images, must be in range (-100, 100)
--suffix=SUFFIX Add suffix to file basename
cover [<flags>] <args>...
Extract cover
--width=0 Image width     Commands:
--height=0 Image height
--fit Best fit for required width and height
--quality=75 JPEG image quality
--filter=2 0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos
thumbnail [<flags>] <args>...       convert
Extract cover thumbnail (freedesktop spec.)             Convert archive or document
--width=0 Image width         --width
--height=0 Image height             Image width (default "0")
--fit Best fit for required width and height         --height
--filter=2 0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos             Image height (default "0")
        --fit
            Best fit for required width and height (default "false")
        --format
            Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl (default "jpeg")
--archive
Archive format, valid values are zip, tar (default "zip")
        --quality
            Image quality (default "75")
        --filter
            0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos (default "2")
        --no-cover
            Do not convert the cover image (default "false")
        --no-rgb
            Do not convert images that have RGB colorspace (default "false")
        --no-nonimage
            Remove non-image files from the archive (default "false")
        --no-convert
       Do not transform or convert images (default "false")
        --grayscale
            Convert images to grayscale (monochromatic) (default "false")
        --rotate
            Rotate images, valid values are 0, 90, 180, 270 (default "0")
        --brightness
            Adjust the brightness of the images, must be in the range (-100, 100) (default "0")
        --contrast
            Adjust the contrast of the images, must be in the range (-100, 100) (default "0")
        --suffix
            Add suffix to file basename (default "")
        --levels-inmin
            Shadow input value (default "0")
        --levels-gamma
            Midpoint/Gamma (default "1")
        --levels-inmax
            Highlight input value (default "255")
        --levels-outmin
            Shadow output value (default "0")
        --levels-outmax
            Highlight output value (default "255")
        --outdir
            Output directory (default ".")
        --size
            Process only files larger than size (in MB) (default "0")
        --recursive
            Process subdirectories recursively (default "false")
        --quiet
            Hide console output (default "false")
[man page](https://en.wikipedia.org/wiki/Man_page) is also available:       cover
            Extract cover
cbconvert --help-man | man /dev/stdin         --width
            Image width (default "0")
        --height
            Image height (default "0")
        --fit
            Best fit for required width and height (default "false")
        --format
            Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl (default "jpeg")
        --quality
            Image quality (default "75")
        --filter
            0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos (default "2")
        --outdir
            Output directory (default ".")
        --size
            Process only files larger than size (in MB) (default "0")
        --recursive
            Process subdirectories recursively (default "false")
        --quiet
            Hide console output (default "false")
Examples       thumbnail
--------             Extract cover thumbnail (freedesktop spec.)
Rescale images to 1200px for all supported files found in directory with size larger then 60MB:         --width
            Image width (default "0")
        --height
            Image height (default "0")
        --fit
            Best fit for required width and height (default "false")
        --filter
            0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos (default "2")
        --outdir
            Output directory (default ".")
        --outfile
            Output file (default "")
        --size
            Process only files larger than size (in MB) (default "0")
        --recursive
            Process subdirectories recursively (default "false")
        --quiet
            Hide console output (default "false")
cbconvert --recursive --width 1200 --size 60 /media/comics/Thorgal/ meta
CBZ metadata
Convert all images in pdf to 4bit BMP image and save result in ~/comics directory: --cover
Print cover name (default "false")
--comment
Print zip comment (default "false")
--comment-body
Set zip comment (default "")
--file-add
Add file to archive (default "")
--file-remove
Remove file(s) from archive (glob pattern, i.e. *.xml) (default "")
cbconvert --bmp --outdir ~/comics /media/comics/Garfield/Garfield_01.pdf ```
[BMP](http://en.wikipedia.org/wiki/BMP_file_format) format is very good choice for black&white pages. Archive size can be smaller 2-3x and file will be readable by comic readers. ### Examples
Generate thumbnails by freedesktop specification in ~/.thumbnails/normal directory with width 512: * Rescale images to 1200px for all supported files found in a directory with a size larger than 60MB:
cbconvert thumbnail --width 512 --outdir ~/.thumbnails/normal /media/comics/GrooTheWanderer/ `cbconvert --recursive --width 1200 --size 60 /media/comics/Thorgal/`
Extract covers to ~/covers dir for all supported files found in directory, Lanczos algorithm is used for resizing: * Convert all images in pdf to 4bit BMP images and save the result in ~/comics directory:
cbconvert cover --outdir ~/covers --filter=7 /media/comics/GrooTheWanderer/ `cbconvert --format bmp --outdir ~/comics /media/comics/Garfield/Garfield_01.pdf`
Compile [BMP](http://en.wikipedia.org/wiki/BMP_file_format) format is a very good choice for black&white pages. Archive size can be smaller 2-3x and the file will be readable by comic readers.
-------
Install imagemagick dev packages: * Extract covers to ~/covers dir for all supported files found in the directory, Lanczos algorithm is used for resizing:
apt-get install libmagickcore-dev libmagickwand-dev `cbconvert cover --outdir ~/covers --filter=7 /media/comics/GrooTheWanderer/`
Compile latest MuPDF: * Convert all images to AVIF format:
git clone git://git.ghostscript.com/mupdf.git && cd mupdf `cbconvert --format avif --quality 50 --width 1280 --outdir ~/comics /media/comics/Misc/`
git submodule update --init --recursive
curl -L https://gist.githubusercontent.com/gen2brain/7869ac4c6db5933f670f/raw/1619394dc957ae10bcd73c713760993466b4bfea/mupdf-openssl-curl.patch | patch -p1
sed -e "1iHAVE_X11 = no" -e "1iWANT_OPENSSL = no" -e "1iWANT_CURL = no" -i Makerules
HAVE_X11=no HAVE_GLFW=no HAVE_GLUT=no WANT_OPENSSL=no WANT_CURL=no HAVE_MUJS=yes HAVE_JSCORE=no HAVE_V8=no make && make install
Compile unarr library: ### Quality settings
git clone https://github.com/zeniko/unarr && cd unarr This table maps quality settings for JPEG to the respective AVIF and WEBP quality settings:
mkdir lzma920 && cd lzma920 && curl -L http://www.7-zip.org/a/lzma920.tar.bz2 | tar -xjvp && cd ..
curl -L http://zlib.net/zlib-1.2.8.tar.gz | tar -xzvp
curl -L http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz | tar -xzvp
curl -L https://gist.githubusercontent.com/gen2brain/89fe506863be3fb139e8/raw/8783a7d81e22ad84944d146c5e33beab6dffc641/unarr-makefile.patch | patch -p1
CFLAGS="-DHAVE_7Z -DHAVE_ZLIB -DHAVE_BZIP2 -I./lzma920/C -I./zlib-1.2.8 -I./bzip2-1.0.6" make
cp build/debug/libunarr.a /usr/lib64/ && cp unarr.h /usr/include
Install dependencies: | | | | | |
|--------------|----|----|----|----|
| JPEG quality | 50 | 60 | 70 | 80 |
| AVIF quality | 48 | 51 | 56 | 64 |
| WEBP quality | 55 | 64 | 72 | 82 |
go get github.com/cheggaaa/pb ### Compile
go get github.com/disintegration/imaging
go get github.com/gen2brain/go-fitz
go get github.com/gen2brain/go-unarr
go get github.com/gographics/imagick/imagick
go get github.com/hotei/bmp
go get github.com/skarademir/naturalsort
go get golang.org/x/image/tiff
go get golang.org/x/image/webp
go get gopkg.in/alecthomas/kingpin.v2
Install go package: Install ImageMagick7 (with libheif/libjxl support) and MuPDF libraries and headers and then install to GOBIN:
go get github.com/gen2brain/cbconvert `go install -tags extlib github.com/gen2brain/cbconvert/cmd/cbconvert@latest`
go install github.com/gen2brain/cbconvert
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`
+1106 -840
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 *Convertor) 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 *Convertor) 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 *Convertor) 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 *Convertor) 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 *Convertor) 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 *Convertor) 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 *Convertor) 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 *Convertor) 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,60 @@
diff -ur mupdf-1.23.3-source.orig/Makefile mupdf-1.23.3-source/Makefile
--- mupdf-1.23.3-source.orig/Makefile 2023-09-05 13:51:19.000000000 +0200
+++ mupdf-1.23.3-source/Makefile 2023-09-08 09:28:01.165486441 +0200
@@ -3,7 +3,7 @@
-include user.make
ifndef build
- build := release
+ build := debug
endif
default: all
@@ -290,17 +290,19 @@
$(THREAD_LIB) : $(THREAD_OBJ)
$(PKCS7_LIB) : $(PKCS7_OBJ)
else
-MUPDF_LIB = $(OUT)/libmupdf.a
+MUPDF_LIB = libmupdf.so
LIBS_TO_INSTALL_IN_LIB = $(MUPDF_LIB) $(THIRD_LIB)
-THIRD_LIB = $(OUT)/libmupdf-third.a
+THIRD_LIB =
+MUPDF_STATIC = $(OUT)/libmupdf.a
ifneq ($(USE_SYSTEM_GLUT),yes)
THIRD_GLUT_LIB = $(OUT)/libmupdf-glut.a
endif
THREAD_LIB = $(OUT)/libmupdf-threads.a
PKCS7_LIB = $(OUT)/libmupdf-pkcs7.a
-$(MUPDF_LIB) : $(MUPDF_OBJ)
-$(THIRD_LIB) : $(THIRD_OBJ)
+$(MUPDF_LIB) : $(MUPDF_OBJ) $(THIRD_OBJ)
+ $(QUIET_LINK) $(CC) $(LDFLAGS) --shared -Wl,-soname -Wl,$(MUPDF_LIB) -o $@ $^ $(THIRD_LIBS) $(LIBS)
+$(MUPDF_STATIC): $(MUPDF_OBJ) $(THIRD_OBJ)
$(THIRD_GLUT_LIB) : $(THIRD_GLUT_OBJ)
$(THREAD_LIB) : $(THREAD_OBJ)
$(PKCS7_LIB) : $(PKCS7_OBJ)
diff -ur mupdf-1.23.3-source.orig/Makethird mupdf-1.23.3-source/Makethird
--- mupdf-1.23.3-source.orig/Makethird 2023-09-05 13:51:19.000000000 +0200
+++ mupdf-1.23.3-source/Makethird 2023-09-08 01:16:56.785811250 +0200
@@ -2,16 +2,16 @@
ifeq ($(USE_SYSTEM_LIBS),yes)
USE_SYSTEM_FREETYPE := yes
- USE_SYSTEM_GUMBO := yes
+ USE_SYSTEM_GUMBO := no
USE_SYSTEM_HARFBUZZ := yes
- USE_SYSTEM_JBIG2DEC := yes
+ USE_SYSTEM_JBIG2DEC := no
USE_SYSTEM_JPEGXR := no # not available
USE_SYSTEM_LCMS2 := no # lcms2mt is strongly preferred
USE_SYSTEM_LIBJPEG := yes
USE_SYSTEM_MUJS := no # not available
- USE_SYSTEM_OPENJPEG := yes
+ USE_SYSTEM_OPENJPEG := no
USE_SYSTEM_ZLIB := yes
- USE_SYSTEM_GLUT := yes
+ USE_SYSTEM_GLUT := no
USE_SYSTEM_CURL := yes
USE_SYSTEM_LEPTONICA := yes
USE_SYSTEM_TESSERACT := yes
@@ -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=io.github.gen2brain.cbconvert
Terminal=false
Type=Application
StartupNotify=true
Categories=Graphics;
@@ -0,0 +1,44 @@
<?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>
<releases>
<release version="1.0.0" date="2023-09-14" type="stable">
<description>
<ul>
<li>Added new GUI</li>
<li>Added support for JPEG XL</li>
</ul>
</description>
<url type="details">https://github.com/gen2brain/cbconvert/releases/tag/v1.0.0</url>
</release>
</releases>
</component>
@@ -0,0 +1,369 @@
app-id: io.github.gen2brain.cbconvert
runtime: org.freedesktop.Platform
runtime-version: '23.08'
sdk: org.freedesktop.Sdk
sdk-extensions:
- org.freedesktop.Sdk.Extension.golang
command: cbconvert-gui
finish-args:
- --share=ipc
- --socket=x11
build-options:
env:
- GOROOT=/usr/lib/sdk/golang
cleanup:
- '*.a'
- '*.la'
- '/bin/Magick*'
- '/etc'
- '/include'
- '/lib/cmake'
- '/lib/pkgconfig'
- '/lib/ImageMagick*'
- '/share'
modules:
- name: libheif
buildsystem: autotools
config-opts:
- --enable-shared
- --disable-static
- --disable-libde265
- --disable-dav1d
- --disable-go
- --disable-gdk-pixbuf
- --disable-rav1e
- --disable-x265
- --disable-tests
- --disable-examples
sources:
- type: archive
url: https://github.com/strukturag/libheif/releases/download/v1.15.2/libheif-1.15.2.tar.gz
sha256: 7a4c6077f45180926583e2087571371bdd9cb21b6e6fada85a6fbd544f26a0e2
- name: highway
buildsystem: cmake
config-opts:
- -DBUILD_SHARED_LIBS=ON
- -DHWY_ENABLE_TESTS=OFF
- -DHWY_ENABLE_EXAMPLES=OFF
- -DHWY_WARNINGS_ARE_ERRORS=OFF
sources:
- type: archive
url: https://github.com/google/highway/archive/refs/tags/1.0.7.tar.gz
sha256: 5434488108186c170a5e2fca5e3c9b6ef59a1caa4d520b008a9b8be6b8abe6c5
- name: libjxl
buildsystem: cmake
config-opts:
- -DBUILD_SHARED_LIBS=ON
- -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
- -DJPEGXL_FORCE_SYSTEM_BROTLI=ON
- -DJPEGXL_FORCE_SYSTEM_LCMS2=ON
sources:
- type: archive
url: https://github.com/libjxl/libjxl/archive/refs/tags/v0.8.2.tar.gz
sha256: c70916fb3ed43784eb840f82f05d390053a558e2da106e40863919238fa7b420
- name: ImageMagick
buildsystem: autotools
config-opts:
- --enable-shared
- --disable-static
- --enable-zero-configuration
- --without-frozenpaths
- --without-utilities
- --without-modules
- --without-magick-plus-plus
- --without-perl
- --without-bzlib
- --without-x
- --without-zip
- --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-hdri
- --disable-opencl
- --disable-openmp
- --with-jpeg
- --with-png
- --with-tiff
- --with-webp
- --with-heic
- --with-jxl
sources:
- type: archive
url: https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.1-15.tar.gz
sha256: 2372192a76af9be43c0543dd7ae6dfbf34b11fc0203583453ce3f9f707c36bcc
- name: MuPDF
buildsystem: simple
build-commands:
- HAVE_X11=no HAVE_LIBCRYPTO=no HAVE_GLUT=no HAVE_OBJCOPY=no USE_SYSTEM_LIBS=yes build=debug shared=yes tofu=yes tofu_cjk=yes make libs
- install -Dm00755 build/shared-debug-tofu-tofu_cjk/libmupdf.so $FLATPAK_DEST/lib/debug/lib/libmupdf.so.debug
- install -dm00755 $FLATPAK_DEST/lib/debug/source/mupdf/source
- cp -r source $FLATPAK_DEST/lib/debug/source/mupdf
- cp -r include/mupdf $FLATPAK_DEST/include/
- install -Dsm00755 build/shared-debug-tofu-tofu_cjk/libmupdf.so $FLATPAK_DEST/lib/libmupdf.so
sources:
- type: archive
url: https://mupdf.com/downloads/archive/mupdf-1.23.3-source.tar.gz
sha256: 1ef9a6409bc0a3271586e1b16f78eb156a579521cd212a124b57c4da8b940aad
- type: patch
path: 01-mupdf-shared.patch
- name: CBconvert
buildsystem: simple
build-commands:
- cp cmd/cbconvert-gui/dist/linux/flatpak/modules.txt cmd/cbconvert-gui/vendor/
- cd cmd/cbconvert-gui && $GOROOT/bin/go build -mod=vendor -trimpath -tags "extlib portal" -ldflags "-s -w -X main.appVersion=1.0.0"
- install -Dm00755 cmd/cbconvert-gui/cbconvert-gui $FLATPAK_DEST/bin/cbconvert-gui
- install -Dm00644 cmd/cbconvert-gui/dist/linux/cbconvert.png $FLATPAK_DEST/share/icons/hicolor/256x256/apps/$FLATPAK_ID.png
- install -Dm00644 cmd/cbconvert-gui/dist/linux/flatpak/$FLATPAK_ID.desktop $FLATPAK_DEST/share/applications/$FLATPAK_ID.desktop
- install -Dm00644 cmd/cbconvert-gui/dist/linux/flatpak/$FLATPAK_ID.metainfo.xml $FLATPAK_DEST/share/metainfo/$FLATPAK_ID.metainfo.xml
sources:
- type: archive
url: https://github.com/gen2brain/cbconvert/archive/refs/tags/v1.0.0.tar.gz
sha256: d628bb06020f50e57c879794652c1533eee18814e3b9a223cdb11ed9fe88bc01
- type: archive
url: https://proxy.golang.org/github.com/gen2brain/cbconvert/@v/v1.0.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/gen2brain/cbconvert
sha256: d628bb06020f50e57c879794652c1533eee18814e3b9a223cdb11ed9fe88bc01
- type: archive
url: https://proxy.golang.org/github.com/chai2010/webp/@v/v1.1.1.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/chai2010/webp
sha256: f42fe1697007ea12155a5d1342d61787e1f34ca396192e4995dc4f2b350552ac
- type: archive
url: https://proxy.golang.org/github.com/davecgh/go-spew/@v/v1.1.1.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/davecgh/go-spew
sha256: 6b44a843951f371b7010c754ecc3cabefe815d5ced1c5b9409fb2d697e8a890d
- type: archive
url: https://proxy.golang.org/github.com/disintegration/imaging/@v/v1.6.2.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/disintegration/imaging
sha256: 2934e7bace3c8c0b1b4a07144197e8720b9ffbe922600e3a3c764f77792ac7c4
- type: archive
url: https://proxy.golang.org/github.com/dustin/go-humanize/@v/v1.0.1.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/dustin/go-humanize
sha256: 319404ea84c8a4e2d3d83f30988b006e7dd04976de3e1a1a90484ad94679fa46
- type: archive
url: https://proxy.golang.org/github.com/fvbommel/sortorder/@v/v1.1.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/fvbommel/sortorder
sha256: a4dbc58d2f72212474a7b5e1894b11d6712b687f4cc66ca1f6e202a375d252f7
- type: archive
url: https://proxy.golang.org/github.com/gen2brain/go-fitz/@v/v1.23.1.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/gen2brain/go-fitz
sha256: 60fc98c3420d7f7347e7a454fdfd66bca960accc8ed0ac582f4b4d82b38513c8
- type: archive
url: https://proxy.golang.org/github.com/gen2brain/go-unarr/@v/v0.1.7.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/gen2brain/go-unarr
sha256: 6f3418edef461c2e1ce5ba77141d402b04d4cf86e89b27c5dc20c922ac63ca4e
- type: archive
url: https://proxy.golang.org/github.com/gen2brain/iup-go/iup/@v/v0.0.0-20230906093706-8b037fe6a7bd.zip
strip-components: 4
dest: cmd/cbconvert-gui/vendor/github.com/gen2brain/iup-go/iup
sha256: a75dbec0ce228214533ee971771233f8b57653828af04bc012f72b624b76be5d
- type: archive
url: https://proxy.golang.org/github.com/godbus/dbus/v5/@v/v5.1.0.zip
strip-components: 4
dest: cmd/cbconvert-gui/vendor/github.com/godbus/dbus/v5
sha256: 03dfa8e71089a6f477310d15c4d3a036d82d028532881b50fee254358e782ad9
- type: archive
url: https://proxy.golang.org/github.com/google/uuid/@v/v1.3.1.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/google/uuid
sha256: 9d9d6cfb28ce6dbe4b518c42c6bccd67bb531a106859808f36e82a5c3fb8c64d
- type: archive
url: https://proxy.golang.org/github.com/k0kubun/go-ansi/@v/v0.0.0-20180517002512-3bf9e2903213.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/k0kubun/go-ansi
sha256: 28366085f1787eaf9d6589f050455855f01caf559f2c6d1c4f4e590cd0abbdef
- type: archive
url: https://proxy.golang.org/github.com/mattn/go-isatty/@v/v0.0.16.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/mattn/go-isatty
sha256: 3d5ff19c4b2a2a164feb84f5cc38af349380c0c4a03d0443dce40bbd6ec3fd2b
- type: archive
url: https://proxy.golang.org/github.com/mattn/go-runewidth/@v/v0.0.13.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/mattn/go-runewidth
sha256: c104e14c1612a6d736bd109fe5fec9749a8146e1f7d37844d8a0a1296e00d4e9
- type: archive
url: https://proxy.golang.org/github.com/mitchellh/colorstring/@v/v0.0.0-20190213212951-d06e56a500db.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/mitchellh/colorstring
sha256: d0733284b20567055e374b420373f5508fa47e95204e59e4b8a66834e7e3964d
- type: archive
url: https://proxy.golang.org/github.com/pmezard/go-difflib/@v/v1.0.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/pmezard/go-difflib
sha256: de04cecc1a4b8d53e4357051026794bcbc54f2e6a260cfac508ce69d5d6457a0
- type: archive
url: https://proxy.golang.org/github.com/rivo/uniseg/@v/v0.3.4.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/rivo/uniseg
sha256: 410ba5034e1683946d68e7fd50ad793c2ad72b157f2959fe4719449666d1e63f
- type: archive
url: https://proxy.golang.org/github.com/schollz/progressbar/v3/@v/v3.10.0.zip
strip-components: 4
dest: cmd/cbconvert-gui/vendor/github.com/schollz/progressbar/v3
sha256: 2cdbf5e4bc314bf140911a923f22d5d9401d73f3b2c7311f6df5c2837d2743ba
- type: archive
url: https://proxy.golang.org/github.com/spf13/pflag/@v/v1.0.5.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/spf13/pflag
sha256: fc6e704f2f6a84ddcdce6de0404e5340fa20c8676181bf5d381b17888107ba84
- type: archive
url: https://proxy.golang.org/github.com/stretchr/objx/@v/v0.1.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/stretchr/objx
sha256: 1fa10dab404ed7fc8ed2a033f8784187d5df3513ced3841ce39e46d37850eb1d
- type: archive
url: https://proxy.golang.org/github.com/stretchr/testify/@v/v1.3.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/stretchr/testify
sha256: 8c935aed71cc334d5bfdf04b34909d9965cf28f80198dec13fb954dc292e6588
- type: archive
url: https://proxy.golang.org/github.com/strukturag/libheif/@v/v1.15.2.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/strukturag/libheif
sha256: bec8ad8e81d33d96b9ea8d11036a14ff4501b62f2cb79dbe49147a701c5c1d38
- type: archive
url: https://proxy.golang.org/github.com/yuin/goldmark/@v/v1.4.13.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/github.com/yuin/goldmark
sha256: bb41a602b174345fda392c8ad83fcc93217c285c763699677630be90feb7a5e3
- type: archive
url: https://proxy.golang.org/golang.org/x/crypto/@v/v0.0.0-20210921155107-089bfa567519.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/crypto
sha256: eb2426a7891915213cc5da1da7b6fc6e9e2cf253d518d8e169e038e287f414e3
- type: archive
url: https://proxy.golang.org/golang.org/x/image/@v/v0.12.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/image
sha256: eee2ea2f688c5bbe2a8ce36ba57f37573f5b63828560cd34f8621f0f8d07e6bd
- type: archive
url: https://proxy.golang.org/golang.org/x/mod/@v/v0.8.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/mod
sha256: 4ae8176799d8cda819e70731ba6855735003e7e4930436e34584c75c96c496e0
- type: archive
url: https://proxy.golang.org/golang.org/x/net/@v/v0.6.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/net
sha256: 7ff2f50b1f3a58833f867d1646421569a91d8c19a0999793c5af79b10c16b8b8
- type: archive
url: https://proxy.golang.org/golang.org/x/sync/@v/v0.3.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/sync
sha256: 1870e7a196f7119d4c6edba7de9cdfc49ee13c8cb7921f3a947568171c6152e0
- type: archive
url: https://proxy.golang.org/golang.org/x/sys/@v/v0.5.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/sys
sha256: cf47336ac1bf675fa6d6dd5ac5399b0143c513404c449fa3f3380a58123c7908
- type: archive
url: https://proxy.golang.org/golang.org/x/term/@v/v0.5.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/term
sha256: 7d89c49ab41306950128a0f4b7c67fb8e2d2f637ece8e024e6cf38d17a33193b
- type: archive
url: https://proxy.golang.org/golang.org/x/text/@v/v0.13.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/text
sha256: ed544fb017e967c053892df7b068612fce707ba32b57f35824cb041e31c6ae0f
- type: archive
url: https://proxy.golang.org/golang.org/x/tools/@v/v0.6.0.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/tools
sha256: 9a29c8904c2acd4b65825e916cbdaf417086f35bb68c54af9a6283a0e1341e85
- type: archive
url: https://proxy.golang.org/golang.org/x/xerrors/@v/v0.0.0-20190717185122-a985d3407aa7.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/golang.org/x/xerrors
sha256: c4e9f063cfed546c90f00a9657deac4f915a8994f8cbe6dbd3f18e79eb8302cf
- type: archive
url: https://proxy.golang.org/gopkg.in/gographics/imagick.v3/@v/v3.4.3.zip
strip-components: 3
dest: cmd/cbconvert-gui/vendor/gopkg.in/gographics/imagick.v3
sha256: ae0a425a2ffcbe92447c5da005deff2c0aac1e25995c443b86ae4bd48861d9e1
+45
View File
@@ -0,0 +1,45 @@
# github.com/chai2010/webp v1.1.1
## explicit; go 1.17
github.com/chai2010/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/fvbommel/sortorder v1.1.0
## explicit; go 1.13
github.com/fvbommel/sortorder
# github.com/gen2brain/cbconvert v0.0.0-20230913113913-6400ae14d89a
## explicit; go 1.21
github.com/gen2brain/cbconvert
# github.com/gen2brain/go-fitz v1.23.1
## explicit; go 1.20
github.com/gen2brain/go-fitz
# github.com/gen2brain/go-unarr v0.1.7
## explicit; go 1.18
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.3.1
## explicit
github.com/google/uuid
# golang.org/x/image v0.12.0
## explicit; go 1.12
golang.org/x/image/bmp
golang.org/x/image/ccitt
golang.org/x/image/tiff
golang.org/x/image/tiff/lzw
# golang.org/x/sync v0.3.0
## explicit; go 1.17
golang.org/x/sync/errgroup
# gopkg.in/gographics/imagick.v3 v3.4.3
## explicit; go 1.13
gopkg.in/gographics/imagick.v3/imagick
gopkg.in/gographics/imagick.v3/imagick/types
@@ -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

+22
View File
@@ -0,0 +1,22 @@
module github.com/gen2brain/cbconvert/cmd/cbconvert-gui
go 1.21
require (
github.com/gen2brain/cbconvert v0.0.0-20230914012707-e14aa6baabb7
github.com/gen2brain/iup-go/iup v0.0.0-20230906093706-8b037fe6a7bd
github.com/godbus/dbus/v5 v5.1.0
)
require (
github.com/chai2010/webp v1.1.1 // indirect
github.com/disintegration/imaging v1.6.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/gen2brain/go-fitz v1.23.1 // indirect
github.com/gen2brain/go-unarr v0.1.7 // indirect
github.com/google/uuid v1.3.1 // indirect
golang.org/x/image v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
gopkg.in/gographics/imagick.v3 v3.4.3 // indirect
)
+58
View File
@@ -0,0 +1,58 @@
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/gen2brain/cbconvert v0.0.0-20230914012707-e14aa6baabb7 h1:v2T43QRyJY4EuZQQaBlvHH+igzBntRloYJ6cWn45F7U=
github.com/gen2brain/cbconvert v0.0.0-20230914012707-e14aa6baabb7/go.mod h1:3zoSNHGpunxvS5cXpge9XwU585Zxsr4ly13dryeQCGk=
github.com/gen2brain/go-fitz v1.23.1 h1:x69/szWZXpI3jZ57mMqCg7WqqvtYnQG0lXts3L6M1Fc=
github.com/gen2brain/go-fitz v1.23.1/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ=
github.com/gen2brain/go-unarr v0.1.7 h1:mEE7bPShJIsmAX67t6BW2ibpEUO7j5WK152KgNM9NbQ=
github.com/gen2brain/go-unarr v0.1.7/go.mod h1:MK9a3hddpaIxjEtrE1f/LA5yJ7gA34cS7Oyr325sY9s=
github.com/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.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ=
golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/gographics/imagick.v3 v3.4.3 h1:9plKFE/Us913jBN6KohtLG9FNW8LPvfpjiGAORIiEHg=
gopkg.in/gographics/imagick.v3 v3.4.3/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
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

+26
View File
@@ -0,0 +1,26 @@
module github.com/gen2brain/cbconvert/cmd/cbconvert
go 1.21
require (
github.com/gen2brain/cbconvert v0.0.0-20230914012707-e14aa6baabb7
github.com/schollz/progressbar/v3 v3.13.1
github.com/spf13/pflag v1.0.5
)
require (
github.com/chai2010/webp v1.1.1 // indirect
github.com/disintegration/imaging v1.6.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/gen2brain/go-fitz v1.23.1 // indirect
github.com/gen2brain/go-unarr v0.1.7 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/rivo/uniseg v0.3.4 // indirect
golang.org/x/image v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
gopkg.in/gographics/imagick.v3 v3.4.3 // indirect
)
+79
View File
@@ -0,0 +1,79 @@
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/gen2brain/cbconvert v0.0.0-20230914012707-e14aa6baabb7 h1:v2T43QRyJY4EuZQQaBlvHH+igzBntRloYJ6cWn45F7U=
github.com/gen2brain/cbconvert v0.0.0-20230914012707-e14aa6baabb7/go.mod h1:3zoSNHGpunxvS5cXpge9XwU585Zxsr4ly13dryeQCGk=
github.com/gen2brain/go-fitz v1.23.1 h1:x69/szWZXpI3jZ57mMqCg7WqqvtYnQG0lXts3L6M1Fc=
github.com/gen2brain/go-fitz v1.23.1/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ=
github.com/gen2brain/go-unarr v0.1.7 h1:mEE7bPShJIsmAX67t6BW2ibpEUO7j5WK152KgNM9NbQ=
github.com/gen2brain/go-unarr v0.1.7/go.mod h1:MK9a3hddpaIxjEtrE1f/LA5yJ7gA34cS7Oyr325sY9s=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
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/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/schollz/progressbar/v3 v3.13.1 h1:o8rySDYiQ59Mwzy2FELeHY5ZARXZTVJC7iHD6PEFUiE=
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/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/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.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ=
golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.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/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/gographics/imagick.v3 v3.4.3 h1:9plKFE/Us913jBN6KohtLG9FNW8LPvfpjiGAORIiEHg=
gopkg.in/gographics/imagick.v3 v3.4.3/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
+328
View File
@@ -0,0 +1,328 @@
package main
import (
"bufio"
"fmt"
"io"
"os"
"os/signal"
"path/filepath"
"runtime/debug"
"syscall"
"github.com/gen2brain/cbconvert"
pb "github.com/schollz/progressbar/v3"
flag "github.com/spf13/pflag"
)
var appVersion string
func init() {
if appVersion != "" {
return
}
info, ok := debug.ReadBuildInfo()
if !ok {
return
}
if info.Main.Version != "" {
appVersion = info.Main.Version
}
for _, kv := range info.Settings {
if kv.Value == "" {
continue
}
if kv.Key == "vcs.revision" {
appVersion = kv.Value
if len(appVersion) > 10 {
appVersion = kv.Value[:10]
}
}
}
}
func main() {
opts, args := parseFlags()
if opts.Version {
fmt.Println(filepath.Base(os.Args[0]), appVersion)
os.Exit(0)
}
conv := cbconvert.New(opts)
c := make(chan os.Signal, 2)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
for range c {
if err := os.RemoveAll(conv.Workdir); err != nil {
fmt.Println(err)
}
os.Exit(1)
}
}()
if _, err := os.Stat(opts.OutDir); err != nil {
if err := os.MkdirAll(opts.OutDir, 0775); err != nil {
fmt.Println(err)
}
os.Exit(1)
}
conv.Initialize()
defer conv.Terminate()
files, err := conv.Files(args)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
var bar *pb.ProgressBar
if opts.Cover || opts.Thumbnail || opts.Meta {
if !opts.Quiet {
bar = pb.NewOptions(conv.Nfiles,
pb.OptionShowCount(),
pb.OptionClearOnFinish(),
pb.OptionUseANSICodes(true),
pb.OptionSetPredictTime(false),
)
}
}
conv.OnStart = func() {
if !opts.Quiet {
bar = pb.NewOptions(conv.Ncontents,
pb.OptionShowCount(),
pb.OptionClearOnFinish(),
pb.OptionUseANSICodes(true),
pb.OptionSetDescription(fmt.Sprintf("Converting %d of %d:", conv.CurrFile, conv.Nfiles)),
pb.OptionSetPredictTime(false),
)
}
}
conv.OnProgress = func() {
if !opts.Quiet {
_ = bar.Add(1)
}
}
conv.OnCompress = func() {
if !opts.Quiet {
fmt.Fprintf(os.Stderr, "Compressing %d of %d...\r", conv.CurrFile, conv.Nfiles)
}
}
for _, file := range files {
switch {
case opts.Meta:
ret, err := conv.Meta(file.Path)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if opts.Cover {
fmt.Println(ret)
} else if opts.Comment {
fmt.Println(ret)
}
continue
case opts.Cover:
if err := conv.Cover(file.Path, file.Stat); err != nil {
fmt.Println(err)
os.Exit(1)
}
continue
case opts.Thumbnail:
if err = conv.Thumbnail(file.Path, file.Stat); err != nil {
fmt.Println(err)
os.Exit(1)
}
continue
}
if err := conv.Convert(file.Path, file.Stat); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
fmt.Fprintf(os.Stderr, "\r")
}
// parseFlags parses command line flags.
func parseFlags() (cbconvert.Options, []string) {
opts := cbconvert.Options{}
var args []string
convert := flag.NewFlagSet("convert", flag.ExitOnError)
convert.SortFlags = false
convert.IntVar(&opts.Width, "width", 0, "Image width")
convert.IntVar(&opts.Height, "height", 0, "Image height")
convert.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
convert.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif, 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.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
convert.BoolVar(&opts.NoCover, "no-cover", false, "Do not convert the cover image")
convert.BoolVar(&opts.NoRGB, "no-rgb", false, "Do not convert images that have RGB colorspace")
convert.BoolVar(&opts.NoNonImage, "no-nonimage", false, "Remove non-image files from the archive")
convert.BoolVar(&opts.NoConvert, "no-convert", false, "Do not transform or convert images")
convert.BoolVar(&opts.Grayscale, "grayscale", false, "Convert images to grayscale (monochromatic)")
convert.IntVar(&opts.Rotate, "rotate", 0, "Rotate images, valid values are 0, 90, 180, 270")
convert.IntVar(&opts.Brightness, "brightness", 0, "Adjust the brightness of the images, must be in the range (-100, 100)")
convert.IntVar(&opts.Contrast, "contrast", 0, "Adjust the contrast of the images, must be in the range (-100, 100)")
convert.StringVar(&opts.Suffix, "suffix", "", "Add suffix to file basename")
convert.IntVar(&opts.LevelsInMin, "levels-inmin", 0, "Shadow input value")
convert.Float64Var(&opts.LevelsGamma, "levels-gamma", 1.0, "Midpoint/Gamma")
convert.IntVar(&opts.LevelsInMax, "levels-inmax", 255, "Highlight input value")
convert.IntVar(&opts.LevelsOutMin, "levels-outmin", 0, "Shadow output value")
convert.IntVar(&opts.LevelsOutMax, "levels-outmax", 255, "Highlight output value")
convert.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
convert.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
convert.BoolVar(&opts.Recursive, "recursive", false, "Process subdirectories recursively")
convert.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
cover := flag.NewFlagSet("cover", flag.ExitOnError)
cover.SortFlags = false
cover.IntVar(&opts.Width, "width", 0, "Image width")
cover.IntVar(&opts.Height, "height", 0, "Image height")
cover.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
cover.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif")
cover.IntVar(&opts.Quality, "quality", 75, "Image quality")
cover.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
cover.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
cover.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
cover.BoolVar(&opts.Recursive, "recursive", false, "Process subdirectories recursively")
cover.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
thumbnail := flag.NewFlagSet("thumbnail", flag.ExitOnError)
thumbnail.SortFlags = false
thumbnail.IntVar(&opts.Width, "width", 0, "Image width")
thumbnail.IntVar(&opts.Height, "height", 0, "Image height")
thumbnail.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
thumbnail.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
thumbnail.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
thumbnail.StringVar(&opts.OutFile, "outfile", "", "Output file")
thumbnail.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
thumbnail.BoolVar(&opts.Recursive, "recursive", false, "Process subdirectories recursively")
thumbnail.BoolVar(&opts.Quiet, "quiet", false, "Hide console output")
meta := flag.NewFlagSet("meta", flag.ExitOnError)
meta.SortFlags = false
meta.BoolVar(&opts.Cover, "cover", false, "Print cover name")
meta.BoolVar(&opts.Comment, "comment", false, "Print zip comment")
meta.StringVar(&opts.CommentBody, "comment-body", "", "Set zip comment")
meta.StringVar(&opts.FileAdd, "file-add", "", "Add file to archive")
meta.StringVar(&opts.FileRemove, "file-remove", "", "Remove file from archive (glob pattern, i.e. *.xml)")
flag.NewFlagSet("version", flag.ExitOnError)
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s <command> [<flags>] [file1 dir1 ... fileOrDirN]\n\n", filepath.Base(os.Args[0]))
fmt.Fprintf(os.Stderr, "\nCommands:\n")
fmt.Fprintf(os.Stderr, "\n convert\n \tConvert archive or document\n\n")
convert.VisitAll(func(f *flag.Flag) {
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
})
fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n")
cover.VisitAll(func(f *flag.Flag) {
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
})
fmt.Fprintf(os.Stderr, "\n thumbnail\n \tExtract cover thumbnail (freedesktop spec.)\n\n")
thumbnail.VisitAll(func(f *flag.Flag) {
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
})
fmt.Fprintf(os.Stderr, "\n meta\n \tCBZ metadata\n\n")
meta.VisitAll(func(f *flag.Flag) {
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
})
fmt.Fprintf(os.Stderr, "\n version\n \tPrint version\n\n")
}
if len(os.Args) < 2 {
flag.Usage()
fmt.Fprintf(os.Stderr, "no command\n")
os.Exit(1)
}
pipe := piped()
if pipe {
args = lines(os.Stdin)
}
switch os.Args[1] {
case "convert":
_ = convert.Parse(os.Args[2:])
if !pipe {
args = convert.Args()
}
case "cover":
opts.Cover = true
_ = cover.Parse(os.Args[2:])
if !pipe {
args = cover.Args()
}
case "thumbnail":
opts.Thumbnail = true
_ = thumbnail.Parse(os.Args[2:])
if !pipe {
args = thumbnail.Args()
}
case "meta":
opts.Meta = true
_ = meta.Parse(os.Args[2:])
if !pipe {
args = meta.Args()
}
case "version":
opts.Version = true
}
if len(args) == 0 && !opts.Version {
flag.Usage()
_, _ = fmt.Fprintf(os.Stderr, "no arguments\n")
os.Exit(1)
}
return opts, args
}
// piped checks if we have a piped stdin.
func piped() bool {
f, err := os.Stdin.Stat()
if err != nil {
return false
}
if f.Mode()&os.ModeNamedPipe == 0 {
return false
}
return true
}
// lines returns slice of lines from reader.
func lines(r io.Reader) []string {
data := make([]string, 0)
scanner := bufio.NewScanner(r)
for scanner.Scan() {
text := scanner.Text()
data = append(data, text)
}
return data
}
+62
View File
@@ -0,0 +1,62 @@
#!/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-${VERSION}"
mkdir -p "${BUILDDIR}"
CC=x86_64-pc-linux-gnu-gcc \
PKG_CONFIG="x86_64-pc-linux-gnu-pkg-config" \
PKG_CONFIG_PATH="$GLIBC_x86_64/usr/lib64/pkgconfig" \
PKG_CONFIG_LIBDIR="$GLIBC_x86_64/usr/lib64/pkgconfig" \
CGO_CFLAGS="-I$GLIBC_x86_64/usr/include" \
CGO_LDFLAGS="-L$GLIBC_x86_64/usr/lib64" \
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o "${BUILDDIR}"/cbconvert -ldflags "-linkmode external -s -w -X main.appVersion=${VERSION} '-extldflags=-static'" && \
cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && tar -czf "${BUILDDIR}-linux-x86_64.tar.gz" "${BUILDDIR}"
rm -rf "${BUILDDIR}"
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 -ljxl -ljxl_dec -ljxl_profiler -ljxl_threads" \
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o "${BUILDDIR}"/cbconvert.exe -ldflags "-s -w -X main.appVersion=${VERSION} '-extldflags=-static -Wl,--allow-multiple-definition'" && \
cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && zip -rq "${BUILDDIR}-windows-x86_64.zip" "${BUILDDIR}"
rm -rf "${BUILDDIR}"
export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1
mkdir -p "${BUILDDIR}"
PATH=${PATH}:${MACOS_x86_64}/bin \
CC=x86_64-apple-darwin21.1-clang \
PKG_CONFIG="x86_64-apple-darwin21.1-pkg-config" \
PKG_CONFIG_PATH="$MACOS_x86_64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
PKG_CONFIG_LIBDIR="$MACOS_x86_64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
CGO_CFLAGS="-I$MACOS_x86_64/usr/include -I$MACOS_x86_64/macports/pkgs/opt/local/include" \
CGO_LDFLAGS="-L$MACOS_x86_64/SDK/MacOSX12.1.sdk/usr/lib -L$MACOS_x86_64/macports/pkgs/opt/local/lib -mmacosx-version-min=10.15" \
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o "${BUILDDIR}"/cbconvert -ldflags "-linkmode external -s -w -X main.appVersion=${VERSION}" && \
cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && zip -rq "${BUILDDIR}-darwin-x86_64.zip" "${BUILDDIR}"
rm -rf "${BUILDDIR}"
export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1
mkdir -p "${BUILDDIR}"
PATH=${PATH}:${MACOS_aarch64}/bin \
CC=aarch64-apple-darwin21.1-clang \
PKG_CONFIG="aarch64-apple-darwin21.1-pkg-config" \
PKG_CONFIG_PATH="$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
PKG_CONFIG_LIBDIR="$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib/pkgconfig" \
CGO_CFLAGS="-I$MACOS_aarch64/usr/include -I$MACOS_aarch64/macports/pkgs/opt/local/include" \
CGO_LDFLAGS="-L$MACOS_aarch64/SDK/MacOSX12.1.sdk/usr/lib -L$MACOS_aarch64/macports/pkgs/opt/local/lib -mmacosx-version-min=10.15" \
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 \
go build -trimpath -tags 'extlib pkgconfig' -v -o "${BUILDDIR}"/cbconvert -ldflags "-linkmode external -s -w -X main.appVersion=${VERSION}" && \
cp ../../README.md ../../AUTHORS ../../COPYING "${BUILDDIR}" && zip -rq "${BUILDDIR}-darwin-aarch64.zip" "${BUILDDIR}"
rm -rf "${BUILDDIR}"
Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

+15
View File
@@ -0,0 +1,15 @@
module github.com/gen2brain/cbconvert
go 1.21
require (
github.com/chai2010/webp v1.1.1
github.com/disintegration/imaging v1.6.2
github.com/dustin/go-humanize v1.0.1
github.com/fvbommel/sortorder v1.1.0
github.com/gen2brain/go-fitz v1.23.1
github.com/gen2brain/go-unarr v0.1.7
golang.org/x/image v0.12.0
golang.org/x/sync v0.3.0
gopkg.in/gographics/imagick.v3 v3.4.3
)
+50
View File
@@ -0,0 +1,50 @@
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/gen2brain/go-fitz v1.23.1 h1:x69/szWZXpI3jZ57mMqCg7WqqvtYnQG0lXts3L6M1Fc=
github.com/gen2brain/go-fitz v1.23.1/go.mod h1:HU04vc+RisUh/kvEd2pB0LAxmK1oyXdN4ftyshUr9rQ=
github.com/gen2brain/go-unarr v0.1.7 h1:mEE7bPShJIsmAX67t6BW2ibpEUO7j5WK152KgNM9NbQ=
github.com/gen2brain/go-unarr v0.1.7/go.mod h1:MK9a3hddpaIxjEtrE1f/LA5yJ7gA34cS7Oyr325sY9s=
github.com/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.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ=
golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/gographics/imagick.v3 v3.4.3 h1:9plKFE/Us913jBN6KohtLG9FNW8LPvfpjiGAORIiEHg=
gopkg.in/gographics/imagick.v3 v3.4.3/go.mod h1:+Q9nyA2xRZXrDyTtJ/eko+8V/5E7bWYs08ndkZp8UmA=
-21
View File
@@ -1,21 +0,0 @@
#!/usr/bin/env bash
mkdir -p build
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o build/cbconvert
strip build/cbconvert
CGO_LDFLAGS="-ldl -lltdl -lfreetype -lm -lz -static-libgcc" CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o build/cbconvert-static --ldflags '-extldflags "-static"'
strip build/cbconvert-static
CGO_LDFLAGS="-L/usr/i686-pc-mingw32/usr/lib" \
CGO_CFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
CGO_CXXFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
CGO_CPPFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
PKG_CONFIG=/usr/bin/i686-pc-mingw32-pkg-config \
PKG_CONFIG_PATH=/usr/i686-pc-mingw32/usr/lib/pkgconfig \
PKG_CONFIG_LIBDIR=/usr/i686-pc-mingw32/usr/lib/pkgconfig \
CC="i686-pc-mingw32-gcc" CXX="i686-pc-mingw32-g++" \
CC_FOR_TARGET=i686-pc-mingw32-gcc CXX_FOR_TARGET=i686-pc-mingw32-g++ \
CGO_ENABLED=1 GOOS=windows GOARCH=386 go build -o build/cbconvert.exe -ldflags "-linkmode external -extldflags -static"
i686-pc-mingw32-strip build/cbconvert.exe
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