use MuPDF instead of Poppler

This commit is contained in:
Milan Nikolic
2015-11-02 05:40:40 +01:00
parent 14bfaf7b6e
commit b1e9763b0b
3 changed files with 93 additions and 75 deletions

View File

@@ -6,11 +6,10 @@ Introduction
CBconvert is a [Comic Book](http://en.wikipedia.org/wiki/Comic_Book_Archive_file) convert tool. CBconvert is a [Comic Book](http://en.wikipedia.org/wiki/Comic_Book_Archive_file) convert tool.
Features Features
-------- --------
- reads rar, zip, 7z, gz, bz2, cbr, cbz, cb7, cbt, pdf and plain directory - reads rar, zip, 7z, gz, bz2, cbr, cbz, cb7, cbt, pdf, epub, xps and plain directory
- always saves processed comic in cbz (zip) format - always saves processed comic in cbz (zip) format
- images can be converted to JPEG, PNG or 4-Bit BMP (16 colors) format - images can be converted to JPEG, PNG or 4-Bit BMP (16 colors) format
- choose resize algorithm (NearestNeighbor, Bilinear, Bicubic, MitchellNetravali, Lanczos2/3) - choose resize algorithm (NearestNeighbor, Bilinear, Bicubic, MitchellNetravali, Lanczos2/3)
@@ -23,31 +22,6 @@ Download
- [Windows static build](https://github.com/gen2brain/cbconvert/releases/download/0.2.0/cbconvert-0.2.0.zip) - [Windows static build](https://github.com/gen2brain/cbconvert/releases/download/0.2.0/cbconvert-0.2.0.zip)
- [Linux 64bit build](https://github.com/gen2brain/cbconvert/releases/download/0.2.0/cbconvert-0.2.0.tar.gz) - [Linux 64bit build](https://github.com/gen2brain/cbconvert/releases/download/0.2.0/cbconvert-0.2.0.tar.gz)
Compile
-------
Install poppler, poppler-glib, cairo and imagemagick dev packages:
apt-get install libpoppler-glib-dev libcairo2-dev libmagickcore-dev libmagickwand-dev
Install go package:
go get github.com/gen2brain/cbconvert
go install github.com/gen2brain/cbconvert && cbconvert
Dependencies
------------
go get github.com/cheggaaa/go-poppler
go get github.com/cheggaaa/pb
go get github.com/gen2brain/go-unarr
go get github.com/gographics/imagick/imagick
go get github.com/hotei/bmp
go get github.com/nfnt/resize
go get github.com/skarademir/naturalsort
go get github.com/ungerik/go-cairo
go get gopkg.in/alecthomas/kingpin.v2
Using Using
----- -----
@@ -93,3 +67,42 @@ Convert all images in archive to 4bit BMP image and save result in ~/comics dire
Generate thumbnails by freedesktop specification in ~/.thumbnails/normal directory, Lanczos3 algorithm is used for resizing: Generate thumbnails by freedesktop specification in ~/.thumbnails/normal directory, Lanczos3 algorithm is used for resizing:
cbconvert --interpolation=5 --outdir ~/.thumbnails/normal --thumbnail /media/comics/GrooTheWanderer/ cbconvert --interpolation=5 --outdir ~/.thumbnails/normal --thumbnail /media/comics/GrooTheWanderer/
Compile
-------
Install imagemagick dev packages:
apt-get install libmagickcore-dev libmagickwand-dev
Compile latest MuPDF:
git clone git://git.ghostscript.com/mupdf.git && cd mupdf
git submodule update --init --recursive
HAVE_X11=no HAVE_GLFW=no HAVE_GLUT=no WANT_CURL=no make && make install
Compile unarr library:
git clone https://github.com/zeniko/unarr && cd unarr
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:
go get github.com/cheggaaa/pb
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/nfnt/resize
go get github.com/skarademir/naturalsort
go get gopkg.in/alecthomas/kingpin.v2
Install go package:
go get github.com/gen2brain/cbconvert
go install github.com/gen2brain/cbconvert

View File

@@ -39,8 +39,8 @@ import (
"sync" "sync"
"syscall" "syscall"
"github.com/cheggaaa/go-poppler"
"github.com/cheggaaa/pb" "github.com/cheggaaa/pb"
"github.com/gen2brain/go-fitz"
"github.com/gen2brain/go-unarr" "github.com/gen2brain/go-unarr"
"github.com/gographics/imagick/imagick" "github.com/gographics/imagick/imagick"
_ "github.com/hotei/bmp" _ "github.com/hotei/bmp"
@@ -154,17 +154,17 @@ func convertImage(img image.Image, index int, pathName string) {
<-throttle <-throttle
} }
// Converts pdf file to cbz // Converts PDF/EPUB/XPS document to CBZ
func convertPDF(file string) { func convertDocument(file string) {
workdir, _ = ioutil.TempDir(os.TempDir(), "cbc") workdir, _ = ioutil.TempDir(os.TempDir(), "cbc")
doc, err := poppler.Open(file) doc, err := fitz.NewDocument(file)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Skipping %s, error: %v", file, err.Error()) fmt.Fprintf(os.Stderr, "Skipping %s, error: %v", file, err.Error())
return return
} }
npages := doc.GetNPages() npages := doc.Pages()
var bar *pb.ProgressBar var bar *pb.ProgressBar
if !opts.Quiet { if !opts.Quiet {
@@ -179,23 +179,19 @@ func convertPDF(file string) {
bar.Increment() bar.Increment()
} }
page := doc.GetPage(n) img, err := doc.Image(n)
images := page.Images()
if len(images) == 1 { if err == nil && img != nil {
throttle <- 1 throttle <- 1
wg.Add(1) wg.Add(1)
surface := images[0].GetSurface() go convertImage(img, n, "")
go convertImage(surface.GetImage(), page.Index(), "")
} else {
// FIXME merge images?
} }
} }
wg.Wait() wg.Wait()
} }
// Converts archive to cbz // Converts archive to CBZ
func convertArchive(file string) { func convertArchive(file string) {
workdir, _ = ioutil.TempDir(os.TempDir(), "cbc") workdir, _ = ioutil.TempDir(os.TempDir(), "cbc")
@@ -271,7 +267,7 @@ func convertArchive(file string) {
wg.Wait() wg.Wait()
} }
// Converts directory to cbz // Converts directory to CBZ
func convertDirectory(path string) { func convertDirectory(path string) {
workdir, _ = ioutil.TempDir(os.TempDir(), "cbc") workdir, _ = ioutil.TempDir(os.TempDir(), "cbc")
@@ -318,7 +314,7 @@ func convertDirectory(path string) {
wg.Wait() wg.Wait()
} }
// Saves workdir to cbz archive // Saves workdir to CBZ archive
func saveArchive(file string) { func saveArchive(file string) {
defer os.RemoveAll(workdir) defer os.RemoveAll(workdir)
@@ -435,28 +431,23 @@ func coverArchive(file string) (image.Image, error) {
return img, nil return img, nil
} }
// Extracts cover from pdf // Extracts cover from document
func coverPDF(file string) (image.Image, error) { func coverDocument(file string) (image.Image, error) {
doc, err := poppler.Open(file) doc, err := fitz.NewDocument(file)
if err != nil { if err != nil {
return nil, err return nil, err
} }
page := doc.GetPage(0) img, err := doc.Image(0)
images := page.Images() if err != nil {
return nil, err
if len(images) == 1 {
surface := images[0].GetSurface()
img := surface.GetImage()
if img == nil {
return nil, errors.New("Image is nil")
}
return img, nil
} }
return nil, nil if img == nil {
return nil, errors.New("Image is nil")
}
return img, nil
} }
// Extracts cover from directory // Extracts cover from directory
@@ -489,7 +480,7 @@ func getFiles() []string {
walkFiles := func(fp string, f os.FileInfo, err error) error { walkFiles := func(fp string, f os.FileInfo, err error) error {
if !f.IsDir() { if !f.IsDir() {
if isComic(fp) { if isArchive(fp) || isDocument(fp) {
if isSize(f.Size()) { if isSize(f.Size()) {
files = append(files, fp) files = append(files, fp)
} }
@@ -507,7 +498,7 @@ func getFiles() []string {
} }
if !stat.IsDir() { if !stat.IsDir() {
if isComic(path) { if isArchive(path) || isDocument(path) {
if isSize(stat.Size()) { if isSize(stat.Size()) {
files = append(files, path) files = append(files, path)
} }
@@ -518,7 +509,7 @@ func getFiles() []string {
} else { } else {
fs, _ := ioutil.ReadDir(path) fs, _ := ioutil.ReadDir(path)
for _, f := range fs { for _, f := range fs {
if isComic(f.Name()) { if isArchive(f.Name()) || isArchive(f.Name()) {
if isSize(f.Size()) { if isSize(f.Size()) {
files = append(files, f.Name()) files = append(files, f.Name())
} }
@@ -580,9 +571,20 @@ func getCover(images []string) string {
} }
// Checks if file is comic // Checks if file is comic
func isComic(f string) bool { func isArchive(f string) bool {
var types = []string{".rar", ".zip", ".7z", ".gz", ".bz2", var types = []string{".rar", ".zip", ".7z", ".gz",
".cbr", ".cbz", ".cb7", ".cbt", ".pdf"} ".bz2", ".cbr", ".cbz", ".cb7", ".cbt"}
for _, t := range types {
if strings.ToLower(filepath.Ext(f)) == t {
return true
}
}
return false
}
// Checks if file is document
func isDocument(f string) bool {
var types = []string{".pdf", ".epub", ".xps"}
for _, t := range types { for _, t := range types {
if strings.ToLower(filepath.Ext(f)) == t { if strings.ToLower(filepath.Ext(f)) == t {
return true return true
@@ -665,8 +667,8 @@ func extractCover(file string, info os.FileInfo) {
var cover image.Image var cover image.Image
if info.IsDir() { if info.IsDir() {
cover, err = coverDirectory(file) cover, err = coverDirectory(file)
} else if strings.ToLower(filepath.Ext(file)) == ".pdf" { } else if isDocument(file) {
cover, err = coverPDF(file) cover, err = coverDocument(file)
} else { } else {
cover, err = coverArchive(file) cover, err = coverArchive(file)
} }
@@ -698,8 +700,8 @@ func extractThumbnail(file string, info os.FileInfo) {
var cover image.Image var cover image.Image
if info.IsDir() { if info.IsDir() {
cover, err = coverDirectory(file) cover, err = coverDirectory(file)
} else if strings.ToLower(filepath.Ext(file)) == ".pdf" { } else if isDocument(file) {
cover, err = coverPDF(file) cover, err = coverDocument(file)
} else { } else {
cover, err = coverArchive(file) cover, err = coverArchive(file)
} }
@@ -749,8 +751,8 @@ func convertComic(file string, info os.FileInfo) {
if info.IsDir() { if info.IsDir() {
convertDirectory(file) convertDirectory(file)
saveArchive(file) saveArchive(file)
} else if strings.ToLower(filepath.Ext(file)) == ".pdf" { } else if isDocument(file) {
convertPDF(file) convertDocument(file)
saveArchive(file) saveArchive(file)
} else { } else {
convertArchive(file) convertArchive(file)
@@ -761,7 +763,7 @@ func convertComic(file string, info os.FileInfo) {
// Parses command line flags // Parses command line flags
func parseFlags() { func parseFlags() {
opts = options{} opts = options{}
kingpin.Version("CBconvert 0.2.0") kingpin.Version("CBconvert 0.3.0")
kingpin.CommandLine.Help = "Comic Book convert tool." kingpin.CommandLine.Help = "Comic Book convert tool."
kingpin.Flag("png", "encode images to PNG instead of JPEG").Short('p').BoolVar(&opts.ToPNG) kingpin.Flag("png", "encode images to PNG instead of JPEG").Short('p').BoolVar(&opts.ToPNG)
kingpin.Flag("bmp", "encode images to 4-Bit BMP instead of JPEG").Short('b').BoolVar(&opts.ToBMP) kingpin.Flag("bmp", "encode images to 4-Bit BMP instead of JPEG").Short('b').BoolVar(&opts.ToBMP)

View File

@@ -5,14 +5,17 @@ mkdir -p build
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o build/cbconvert CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o build/cbconvert
strip build/cbconvert strip build/cbconvert
#CGO_LDFLAGS="-lm -lz -ldl -lltdl -lfreetype -static-libgcc" CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -v -x -o build/cbconvert-static --ldflags '-extldflags "-static"'
#strip build/cbconvert-static
CGO_LDFLAGS="-L/usr/i686-pc-mingw32/usr/lib" \ CGO_LDFLAGS="-L/usr/i686-pc-mingw32/usr/lib" \
CGO_CFLAGS="-I/usr/i686-pc-mingw32/usr/include -I/usr/i686-pc-mingw32/usr/include/poppler/glib -I/usr/i686-pc-mingw32/usr/include/glib-2.0 -I/usr/i686-pc-mingw32/usr/include/cairo" \ CGO_CFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
CGO_CXXFLAGS="-I/usr/i686-pc-mingw32/usr/include -I/usr/i686-pc-mingw32/usr/include/poppler/glib -I/usr/i686-pc-mingw32/usr/include/glib-2.0 -I/usr/i686-pc-mingw32/usr/include/cairo" \ CGO_CXXFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
CGO_CPPFLAGS="-I/usr/i686-pc-mingw32/usr/include -I/usr/i686-pc-mingw32/usr/include/poppler/glib -I/usr/i686-pc-mingw32/usr/include/glib-2.0 -I/usr/i686-pc-mingw32/usr/include/cairo" \ CGO_CPPFLAGS="-I/usr/i686-pc-mingw32/usr/include -Wno-poison-system-directories" \
PKG_CONFIG=/usr/bin/i686-pc-mingw32-pkg-config \ PKG_CONFIG=/usr/bin/i686-pc-mingw32-pkg-config \
PKG_CONFIG_PATH=/usr/i686-pc-mingw32/usr/lib/pkgconfig \ PKG_CONFIG_PATH=/usr/i686-pc-mingw32/usr/lib/pkgconfig \
PKG_CONFIG_LIBDIR=/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="i686-pc-mingw32-gcc" CXX="i686-pc-mingw32-g++" \
CC_FOR_TARGET=i686-pc-mingw32-gcc CXX_FOR_TARGET=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 -x -work -o build/cbconvert.exe -ldflags "-linkmode external -extldflags -static" 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 i686-pc-mingw32-strip build/cbconvert.exe