From b1e9763b0be0ef16bdb228256cb63a16fa594480 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 2 Nov 2015 05:40:40 +0100 Subject: [PATCH] use MuPDF instead of Poppler --- README.md | 67 ++++++++++++++++++++++---------------- cbconvert.go | 90 +++++++++++++++++++++++++++------------------------- make.bash | 11 ++++--- 3 files changed, 93 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 16e269f..f67d378 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,10 @@ Introduction CBconvert is a [Comic Book](http://en.wikipedia.org/wiki/Comic_Book_Archive_file) convert tool. - 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 - images can be converted to JPEG, PNG or 4-Bit BMP (16 colors) format - 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) - [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 ----- @@ -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: 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 diff --git a/cbconvert.go b/cbconvert.go index ace68ba..c3995bc 100644 --- a/cbconvert.go +++ b/cbconvert.go @@ -39,8 +39,8 @@ import ( "sync" "syscall" - "github.com/cheggaaa/go-poppler" "github.com/cheggaaa/pb" + "github.com/gen2brain/go-fitz" "github.com/gen2brain/go-unarr" "github.com/gographics/imagick/imagick" _ "github.com/hotei/bmp" @@ -154,17 +154,17 @@ func convertImage(img image.Image, index int, pathName string) { <-throttle } -// Converts pdf file to cbz -func convertPDF(file string) { +// Converts PDF/EPUB/XPS document to CBZ +func convertDocument(file string) { workdir, _ = ioutil.TempDir(os.TempDir(), "cbc") - doc, err := poppler.Open(file) + doc, err := fitz.NewDocument(file) if err != nil { fmt.Fprintf(os.Stderr, "Skipping %s, error: %v", file, err.Error()) return } - npages := doc.GetNPages() + npages := doc.Pages() var bar *pb.ProgressBar if !opts.Quiet { @@ -179,23 +179,19 @@ func convertPDF(file string) { bar.Increment() } - page := doc.GetPage(n) - images := page.Images() + img, err := doc.Image(n) - if len(images) == 1 { + if err == nil && img != nil { throttle <- 1 wg.Add(1) - surface := images[0].GetSurface() - go convertImage(surface.GetImage(), page.Index(), "") - } else { - // FIXME merge images? + go convertImage(img, n, "") } } wg.Wait() } -// Converts archive to cbz +// Converts archive to CBZ func convertArchive(file string) { workdir, _ = ioutil.TempDir(os.TempDir(), "cbc") @@ -271,7 +267,7 @@ func convertArchive(file string) { wg.Wait() } -// Converts directory to cbz +// Converts directory to CBZ func convertDirectory(path string) { workdir, _ = ioutil.TempDir(os.TempDir(), "cbc") @@ -318,7 +314,7 @@ func convertDirectory(path string) { wg.Wait() } -// Saves workdir to cbz archive +// Saves workdir to CBZ archive func saveArchive(file string) { defer os.RemoveAll(workdir) @@ -435,28 +431,23 @@ func coverArchive(file string) (image.Image, error) { return img, nil } -// Extracts cover from pdf -func coverPDF(file string) (image.Image, error) { - doc, err := poppler.Open(file) +// Extracts cover from document +func coverDocument(file string) (image.Image, error) { + doc, err := fitz.NewDocument(file) if err != nil { return nil, err } - page := doc.GetPage(0) - images := page.Images() - - if len(images) == 1 { - surface := images[0].GetSurface() - img := surface.GetImage() - - if img == nil { - return nil, errors.New("Image is nil") - } - - return img, nil + img, err := doc.Image(0) + if err != nil { + return nil, err } - return nil, nil + if img == nil { + return nil, errors.New("Image is nil") + } + + return img, nil } // Extracts cover from directory @@ -489,7 +480,7 @@ func getFiles() []string { walkFiles := func(fp string, f os.FileInfo, err error) error { if !f.IsDir() { - if isComic(fp) { + if isArchive(fp) || isDocument(fp) { if isSize(f.Size()) { files = append(files, fp) } @@ -507,7 +498,7 @@ func getFiles() []string { } if !stat.IsDir() { - if isComic(path) { + if isArchive(path) || isDocument(path) { if isSize(stat.Size()) { files = append(files, path) } @@ -518,7 +509,7 @@ func getFiles() []string { } else { fs, _ := ioutil.ReadDir(path) for _, f := range fs { - if isComic(f.Name()) { + if isArchive(f.Name()) || isArchive(f.Name()) { if isSize(f.Size()) { files = append(files, f.Name()) } @@ -580,9 +571,20 @@ func getCover(images []string) string { } // Checks if file is comic -func isComic(f string) bool { - var types = []string{".rar", ".zip", ".7z", ".gz", ".bz2", - ".cbr", ".cbz", ".cb7", ".cbt", ".pdf"} +func isArchive(f string) bool { + var types = []string{".rar", ".zip", ".7z", ".gz", + ".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 { if strings.ToLower(filepath.Ext(f)) == t { return true @@ -665,8 +667,8 @@ func extractCover(file string, info os.FileInfo) { var cover image.Image if info.IsDir() { cover, err = coverDirectory(file) - } else if strings.ToLower(filepath.Ext(file)) == ".pdf" { - cover, err = coverPDF(file) + } else if isDocument(file) { + cover, err = coverDocument(file) } else { cover, err = coverArchive(file) } @@ -698,8 +700,8 @@ func extractThumbnail(file string, info os.FileInfo) { var cover image.Image if info.IsDir() { cover, err = coverDirectory(file) - } else if strings.ToLower(filepath.Ext(file)) == ".pdf" { - cover, err = coverPDF(file) + } else if isDocument(file) { + cover, err = coverDocument(file) } else { cover, err = coverArchive(file) } @@ -749,8 +751,8 @@ func convertComic(file string, info os.FileInfo) { if info.IsDir() { convertDirectory(file) saveArchive(file) - } else if strings.ToLower(filepath.Ext(file)) == ".pdf" { - convertPDF(file) + } else if isDocument(file) { + convertDocument(file) saveArchive(file) } else { convertArchive(file) @@ -761,7 +763,7 @@ func convertComic(file string, info os.FileInfo) { // Parses command line flags func parseFlags() { opts = options{} - kingpin.Version("CBconvert 0.2.0") + kingpin.Version("CBconvert 0.3.0") kingpin.CommandLine.Help = "Comic Book convert tool." 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) diff --git a/make.bash b/make.bash index f45569a..9798cc2 100755 --- a/make.bash +++ b/make.bash @@ -5,14 +5,17 @@ mkdir -p build CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o 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_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_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_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_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 -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