mirror of
https://github.com/celogeek/go-comic-converter.git
synced 2025-05-25 16:22:37 +02:00
Compare commits
No commits in common. "506cd1ad6cff001bf35a136d1f3341ba69eb4bbd" and "ad614d09b4378496834ec9d1c7b4dacbc4152530" have entirely different histories.
506cd1ad6c
...
ad614d09b4
@ -1,26 +1,20 @@
|
|||||||
package epubimageprocessor
|
package epubimageprocessor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/zip"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
"image/png"
|
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
"slices"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/nwaples/rardecode/v2"
|
|
||||||
|
|
||||||
"github.com/celogeek/go-comic-converter/v3/internal/pkg/epubimage"
|
"github.com/celogeek/go-comic-converter/v3/internal/pkg/epubimage"
|
||||||
"github.com/celogeek/go-comic-converter/v3/internal/pkg/epubprogress"
|
"github.com/celogeek/go-comic-converter/v3/internal/pkg/epubprogress"
|
||||||
"github.com/celogeek/go-comic-converter/v3/internal/pkg/epubzip"
|
"github.com/celogeek/go-comic-converter/v3/internal/pkg/epubzip"
|
||||||
"github.com/celogeek/go-comic-converter/v3/internal/pkg/sortpath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e EPUBImageProcessor) PassThrough() (images []epubimage.EPUBImage, err error) {
|
func (e EPUBImageProcessor) PassThrough() (images []epubimage.EPUBImage, err error) {
|
||||||
@ -53,10 +47,18 @@ func (e EPUBImageProcessor) passThroughDir() (images []epubimage.EPUBImage, err
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if filterCopyPath(d.IsDir(), path) {
|
// skip hidden files
|
||||||
imagesPath = append(imagesPath, path)
|
if strings.HasPrefix(filepath.Base(path), ".") {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if slices.Contains([]string{".jpeg", ".jpg"}, strings.ToLower(filepath.Ext(path))) {
|
||||||
|
imagesPath = append(imagesPath, path)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -69,14 +71,11 @@ func (e EPUBImageProcessor) passThroughDir() (images []epubimage.EPUBImage, err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(sortpath.By(imagesPath, e.SortPathMode))
|
|
||||||
|
|
||||||
var imgStorage epubzip.StorageImageWriter
|
var imgStorage epubzip.StorageImageWriter
|
||||||
imgStorage, err = epubzip.NewStorageImageWriter(e.ImgStorage(), e.Image.Format)
|
imgStorage, err = epubzip.NewStorageImageWriter(e.ImgStorage(), e.Image.Format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer imgStorage.Close()
|
|
||||||
|
|
||||||
// processing
|
// processing
|
||||||
bar := epubprogress.New(epubprogress.Options{
|
bar := epubprogress.New(epubprogress.Options{
|
||||||
@ -87,7 +86,6 @@ func (e EPUBImageProcessor) passThroughDir() (images []epubimage.EPUBImage, err
|
|||||||
CurrentJob: 1,
|
CurrentJob: 1,
|
||||||
TotalJob: 2,
|
TotalJob: 2,
|
||||||
})
|
})
|
||||||
defer bar.Close()
|
|
||||||
|
|
||||||
for i, imgPath := range imagesPath {
|
for i, imgPath := range imagesPath {
|
||||||
var f *os.File
|
var f *os.File
|
||||||
@ -101,16 +99,48 @@ func (e EPUBImageProcessor) passThroughDir() (images []epubimage.EPUBImage, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f.Close()
|
|
||||||
|
|
||||||
var img epubimage.EPUBImage
|
err = f.Close()
|
||||||
img, err = copyRawDataToStorage(
|
if err != nil {
|
||||||
imgStorage,
|
return
|
||||||
uncompressedData,
|
}
|
||||||
i,
|
|
||||||
input,
|
var config image.Config
|
||||||
imgPath,
|
config, err = jpeg.DecodeConfig(bytes.NewReader(uncompressedData))
|
||||||
)
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var rawImage image.Image
|
||||||
|
if i == 0 {
|
||||||
|
rawImage, err = jpeg.Decode(bytes.NewReader(uncompressedData))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p, fn := filepath.Split(imgPath)
|
||||||
|
if p == input {
|
||||||
|
p = ""
|
||||||
|
} else {
|
||||||
|
p = p[len(input)+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
img := epubimage.EPUBImage{
|
||||||
|
Id: i,
|
||||||
|
Part: 0,
|
||||||
|
Raw: rawImage,
|
||||||
|
Width: config.Width,
|
||||||
|
Height: config.Height,
|
||||||
|
IsBlank: false,
|
||||||
|
DoublePage: config.Width > config.Height,
|
||||||
|
Path: p,
|
||||||
|
Name: fn,
|
||||||
|
Format: "jpeg",
|
||||||
|
OriginalAspectRatio: float64(config.Height) / float64(config.Width),
|
||||||
|
}
|
||||||
|
|
||||||
|
err = imgStorage.AddRaw(img.EPUBImgPath(), uncompressedData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -119,6 +149,13 @@ func (e EPUBImageProcessor) passThroughDir() (images []epubimage.EPUBImage, err
|
|||||||
_ = bar.Add(1)
|
_ = bar.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = imgStorage.Close()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = bar.Close()
|
||||||
|
|
||||||
if len(images) == 0 {
|
if len(images) == 0 {
|
||||||
err = errNoImagesFound
|
err = errNoImagesFound
|
||||||
}
|
}
|
||||||
@ -129,299 +166,12 @@ func (e EPUBImageProcessor) passThroughDir() (images []epubimage.EPUBImage, err
|
|||||||
|
|
||||||
func (e EPUBImageProcessor) passThroughCbz() (images []epubimage.EPUBImage, err error) {
|
func (e EPUBImageProcessor) passThroughCbz() (images []epubimage.EPUBImage, err error) {
|
||||||
images = make([]epubimage.EPUBImage, 0)
|
images = make([]epubimage.EPUBImage, 0)
|
||||||
|
err = errNoImagesFound
|
||||||
input := filepath.Clean(e.Input)
|
|
||||||
r, err := zip.OpenReader(input)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
imagesZip := make([]*zip.File, 0)
|
|
||||||
for _, f := range r.File {
|
|
||||||
if filterCopyPath(f.FileInfo().IsDir(), f.Name) {
|
|
||||||
imagesZip = append(imagesZip, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(imagesZip) == 0 {
|
|
||||||
err = errNoImagesFound
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var names []string
|
|
||||||
for _, img := range imagesZip {
|
|
||||||
names = append(names, img.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(sortpath.By(names, e.SortPathMode))
|
|
||||||
|
|
||||||
indexedNames := make(map[string]int)
|
|
||||||
for i, name := range names {
|
|
||||||
indexedNames[name] = i
|
|
||||||
}
|
|
||||||
|
|
||||||
var imgStorage epubzip.StorageImageWriter
|
|
||||||
imgStorage, err = epubzip.NewStorageImageWriter(e.ImgStorage(), e.Image.Format)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer imgStorage.Close()
|
|
||||||
|
|
||||||
// processing
|
|
||||||
bar := epubprogress.New(epubprogress.Options{
|
|
||||||
Quiet: e.Quiet,
|
|
||||||
Json: e.Json,
|
|
||||||
Max: len(imagesZip),
|
|
||||||
Description: "Copying",
|
|
||||||
CurrentJob: 1,
|
|
||||||
TotalJob: 2,
|
|
||||||
})
|
|
||||||
defer bar.Close()
|
|
||||||
|
|
||||||
for _, imgZip := range imagesZip {
|
|
||||||
if _, ok := indexedNames[imgZip.Name]; !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var f io.ReadCloser
|
|
||||||
f, err = imgZip.Open()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var uncompressedData []byte
|
|
||||||
uncompressedData, err = io.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
|
|
||||||
var img epubimage.EPUBImage
|
|
||||||
img, err = copyRawDataToStorage(
|
|
||||||
imgStorage,
|
|
||||||
uncompressedData,
|
|
||||||
indexedNames[imgZip.Name],
|
|
||||||
"",
|
|
||||||
imgZip.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
images = append(images, img)
|
|
||||||
_ = bar.Add(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(images) == 0 {
|
|
||||||
err = errNoImagesFound
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e EPUBImageProcessor) passThroughCbr() (images []epubimage.EPUBImage, err error) {
|
func (e EPUBImageProcessor) passThroughCbr() (images []epubimage.EPUBImage, err error) {
|
||||||
images = make([]epubimage.EPUBImage, 0)
|
images = make([]epubimage.EPUBImage, 0)
|
||||||
|
err = errNoImagesFound
|
||||||
var isSolid bool
|
|
||||||
files, err := rardecode.List(e.Input)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
names := make([]string, 0)
|
|
||||||
for _, f := range files {
|
|
||||||
if filterCopyPath(f.IsDir, f.Name) {
|
|
||||||
if f.Solid {
|
|
||||||
isSolid = true
|
|
||||||
}
|
|
||||||
names = append(names, f.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(names) == 0 {
|
|
||||||
err = errNoImagesFound
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(sortpath.By(names, e.SortPathMode))
|
|
||||||
|
|
||||||
indexedNames := make(map[string]int)
|
|
||||||
for i, name := range names {
|
|
||||||
indexedNames[name] = i
|
|
||||||
}
|
|
||||||
|
|
||||||
var imgStorage epubzip.StorageImageWriter
|
|
||||||
imgStorage, err = epubzip.NewStorageImageWriter(e.ImgStorage(), e.Image.Format)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer imgStorage.Close()
|
|
||||||
|
|
||||||
// processing
|
|
||||||
bar := epubprogress.New(epubprogress.Options{
|
|
||||||
Quiet: e.Quiet,
|
|
||||||
Json: e.Json,
|
|
||||||
Max: len(names),
|
|
||||||
Description: "Copying",
|
|
||||||
CurrentJob: 1,
|
|
||||||
TotalJob: 2,
|
|
||||||
})
|
|
||||||
defer bar.Close()
|
|
||||||
|
|
||||||
if isSolid {
|
|
||||||
var r *rardecode.ReadCloser
|
|
||||||
r, err = rardecode.OpenReader(e.Input)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
for {
|
|
||||||
f, rerr := r.Next()
|
|
||||||
if rerr != nil {
|
|
||||||
if rerr == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
err = rerr
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := indexedNames[f.Name]; !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var uncompressedData []byte
|
|
||||||
uncompressedData, err = io.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var img epubimage.EPUBImage
|
|
||||||
img, err = copyRawDataToStorage(
|
|
||||||
imgStorage,
|
|
||||||
uncompressedData,
|
|
||||||
indexedNames[f.Name],
|
|
||||||
"",
|
|
||||||
f.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
images = append(images, img)
|
|
||||||
_ = bar.Add(1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for _, file := range files {
|
|
||||||
if i, ok := indexedNames[file.Name]; ok {
|
|
||||||
var f io.ReadCloser
|
|
||||||
f, err = file.Open()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var uncompressedData []byte
|
|
||||||
uncompressedData, err = io.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
|
|
||||||
var img epubimage.EPUBImage
|
|
||||||
img, err = copyRawDataToStorage(
|
|
||||||
imgStorage,
|
|
||||||
uncompressedData,
|
|
||||||
i,
|
|
||||||
"",
|
|
||||||
file.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
images = append(images, img)
|
|
||||||
_ = bar.Add(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(images) == 0 {
|
|
||||||
err = errNoImagesFound
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func filterCopyPath(isDir bool, filename string) bool {
|
|
||||||
return !isDir &&
|
|
||||||
!strings.HasPrefix(filepath.Base(filename), ".") &&
|
|
||||||
slices.Contains([]string{".jpeg", ".jpg", ".png"}, strings.ToLower(filepath.Ext(filename)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyRawDataToStorage(
|
|
||||||
imgStorage epubzip.StorageImageWriter,
|
|
||||||
uncompressedData []byte,
|
|
||||||
id int,
|
|
||||||
dirname string,
|
|
||||||
filename string,
|
|
||||||
) (img epubimage.EPUBImage, err error) {
|
|
||||||
p, fn := filepath.Split(filepath.Clean(filename))
|
|
||||||
if p == dirname {
|
|
||||||
p = ""
|
|
||||||
} else {
|
|
||||||
p = p[len(dirname)+1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
format string
|
|
||||||
decodeConfig func(r io.Reader) (image.Config, error)
|
|
||||||
decode func(r io.Reader) (image.Image, error)
|
|
||||||
)
|
|
||||||
|
|
||||||
switch filepath.Ext(fn) {
|
|
||||||
case ".png":
|
|
||||||
format = "png"
|
|
||||||
decodeConfig = png.DecodeConfig
|
|
||||||
decode = png.Decode
|
|
||||||
case ".jpg", ".jpeg":
|
|
||||||
format = "jpeg"
|
|
||||||
decodeConfig = jpeg.DecodeConfig
|
|
||||||
decode = jpeg.Decode
|
|
||||||
}
|
|
||||||
|
|
||||||
var config image.Config
|
|
||||||
config, err = decodeConfig(bytes.NewReader(uncompressedData))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var rawImage image.Image
|
|
||||||
if id == 0 {
|
|
||||||
rawImage, err = decode(bytes.NewReader(uncompressedData))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img = epubimage.EPUBImage{
|
|
||||||
Id: id,
|
|
||||||
Part: 0,
|
|
||||||
Raw: rawImage,
|
|
||||||
Width: config.Width,
|
|
||||||
Height: config.Height,
|
|
||||||
IsBlank: false,
|
|
||||||
DoublePage: config.Width > config.Height,
|
|
||||||
Path: p,
|
|
||||||
Name: fn,
|
|
||||||
Format: format,
|
|
||||||
OriginalAspectRatio: float64(config.Height) / float64(config.Width),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = imgStorage.AddRaw(img.EPUBImgPath(), uncompressedData)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user