separate passthrough from processor

This commit is contained in:
Celogeek 2025-02-17 09:22:42 +01:00
parent 506cd1ad6c
commit dfb9a6fff3
Signed by: celogeek
GPG Key ID: 850295F3747870DD
4 changed files with 55 additions and 32 deletions

View File

@ -1,8 +1,9 @@
package epubimageprocessor package epubimagepassthrough
import ( import (
"archive/zip" "archive/zip"
"bytes" "bytes"
"errors"
"fmt" "fmt"
"image" "image"
"image/jpeg" "image/jpeg"
@ -18,33 +19,48 @@ import (
"github.com/nwaples/rardecode/v2" "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/epubimageprocessor"
"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" "github.com/celogeek/go-comic-converter/v3/internal/pkg/sortpath"
"github.com/celogeek/go-comic-converter/v3/pkg/epuboptions"
) )
func (e EPUBImageProcessor) PassThrough() (images []epubimage.EPUBImage, err error) { type ePUBImagePassthrough struct {
epuboptions.EPUBOptions
}
func (e ePUBImagePassthrough) Load() (images []epubimage.EPUBImage, err error) {
fi, err := os.Stat(e.Input) fi, err := os.Stat(e.Input)
if err != nil { if err != nil {
return return
} }
if fi.IsDir() { if fi.IsDir() {
return e.passThroughDir() return e.loadDir()
} else { } else {
switch ext := strings.ToLower(filepath.Ext(e.Input)); ext { switch ext := strings.ToLower(filepath.Ext(e.Input)); ext {
case ".cbz", ".zip": case ".cbz", ".zip":
return e.passThroughCbz() return e.loadCbz()
case ".cbr", ".rar": case ".cbr", ".rar":
return e.passThroughCbr() return e.loadCbr()
default: default:
return nil, fmt.Errorf("unknown file format (%s): support .cbz, .zip, .cbr, .rar", ext) return nil, fmt.Errorf("unknown file format (%s): support .cbz, .zip, .cbr, .rar", ext)
} }
} }
} }
func (e EPUBImageProcessor) passThroughDir() (images []epubimage.EPUBImage, err error) { func (e ePUBImagePassthrough) CoverTitleData(o epubimageprocessor.CoverTitleDataOptions) (epubzip.Image, error) {
return epubimageprocessor.New(e.EPUBOptions).CoverTitleData(o)
}
var errNoImagesFound = errors.New("no images found")
func New(o epuboptions.EPUBOptions) epubimageprocessor.EPUBImageProcessor {
return ePUBImagePassthrough{o}
}
func (e ePUBImagePassthrough) loadDir() (images []epubimage.EPUBImage, err error) {
imagesPath := make([]string, 0) imagesPath := make([]string, 0)
input := filepath.Clean(e.Input) input := filepath.Clean(e.Input)
@ -127,7 +143,7 @@ func (e EPUBImageProcessor) passThroughDir() (images []epubimage.EPUBImage, err
} }
func (e EPUBImageProcessor) passThroughCbz() (images []epubimage.EPUBImage, err error) { func (e ePUBImagePassthrough) loadCbz() (images []epubimage.EPUBImage, err error) {
images = make([]epubimage.EPUBImage, 0) images = make([]epubimage.EPUBImage, 0)
input := filepath.Clean(e.Input) input := filepath.Clean(e.Input)
@ -221,7 +237,7 @@ func (e EPUBImageProcessor) passThroughCbz() (images []epubimage.EPUBImage, err
return return
} }
func (e EPUBImageProcessor) passThroughCbr() (images []epubimage.EPUBImage, err error) { func (e ePUBImagePassthrough) loadCbr() (images []epubimage.EPUBImage, err error) {
images = make([]epubimage.EPUBImage, 0) images = make([]epubimage.EPUBImage, 0)
var isSolid bool var isSolid bool

View File

@ -43,7 +43,7 @@ type task struct {
var errNoImagesFound = errors.New("no images found") var errNoImagesFound = errors.New("no images found")
// only accept jpg, png and webp as source file // only accept jpg, png and webp as source file
func (e EPUBImageProcessor) isSupportedImage(path string) bool { func (e ePUBImageProcessor) isSupportedImage(path string) bool {
switch strings.ToLower(filepath.Ext(path)) { switch strings.ToLower(filepath.Ext(path)) {
case ".jpg", ".jpeg", ".png", ".webp", ".tiff": case ".jpg", ".jpeg", ".png", ".webp", ".tiff":
{ {
@ -54,7 +54,7 @@ func (e EPUBImageProcessor) isSupportedImage(path string) bool {
} }
// load images from input // load images from input
func (e EPUBImageProcessor) load() (totalImages int, output chan task, err error) { func (e ePUBImageProcessor) load() (totalImages int, output chan task, err error) {
fi, err := os.Stat(e.Input) fi, err := os.Stat(e.Input)
if err != nil { if err != nil {
return return
@ -78,7 +78,7 @@ func (e EPUBImageProcessor) load() (totalImages int, output chan task, err error
} }
} }
func (e EPUBImageProcessor) corruptedImage(path, name string) image.Image { func (e ePUBImageProcessor) corruptedImage(path, name string) image.Image {
var w, h float64 = 1200, 1920 var w, h float64 = 1200, 1920
f, _ := truetype.Parse(gomonobold.TTF) f, _ := truetype.Parse(gomonobold.TTF)
face := truetype.NewFace(f, &truetype.Options{Size: 64, DPI: 72}) face := truetype.NewFace(f, &truetype.Options{Size: 64, DPI: 72})
@ -102,7 +102,7 @@ func (e EPUBImageProcessor) corruptedImage(path, name string) image.Image {
} }
// load a directory of images // load a directory of images
func (e EPUBImageProcessor) loadDir() (totalImages int, output chan task, err error) { func (e ePUBImageProcessor) loadDir() (totalImages int, output chan task, err error) {
images := make([]string, 0) images := make([]string, 0)
input := filepath.Clean(e.Input) input := filepath.Clean(e.Input)
@ -191,7 +191,7 @@ func (e EPUBImageProcessor) loadDir() (totalImages int, output chan task, err er
} }
// load a zip file that include images // load a zip file that include images
func (e EPUBImageProcessor) loadCbz() (totalImages int, output chan task, err error) { func (e ePUBImageProcessor) loadCbz() (totalImages int, output chan task, err error) {
r, err := zip.OpenReader(e.Input) r, err := zip.OpenReader(e.Input)
if err != nil { if err != nil {
return return
@ -277,7 +277,7 @@ func (e EPUBImageProcessor) loadCbz() (totalImages int, output chan task, err er
} }
// load a rar file that include images // load a rar file that include images
func (e EPUBImageProcessor) loadCbr() (totalImages int, output chan task, err error) { func (e ePUBImageProcessor) loadCbr() (totalImages int, output chan task, err error) {
var isSolid bool var isSolid bool
files, err := rardecode.List(e.Input) files, err := rardecode.List(e.Input)
if err != nil { if err != nil {
@ -393,7 +393,7 @@ func (e EPUBImageProcessor) loadCbr() (totalImages int, output chan task, err er
} }
// extract image from a pdf // extract image from a pdf
func (e EPUBImageProcessor) loadPdf() (totalImages int, output chan task, err error) { func (e ePUBImageProcessor) loadPdf() (totalImages int, output chan task, err error) {
pdf := pdfread.Load(e.Input) pdf := pdfread.Load(e.Input)
if pdf == nil { if pdf == nil {
err = fmt.Errorf("can't read pdf") err = fmt.Errorf("can't read pdf")

View File

@ -17,16 +17,21 @@ import (
"github.com/celogeek/go-comic-converter/v3/pkg/epuboptions" "github.com/celogeek/go-comic-converter/v3/pkg/epuboptions"
) )
type EPUBImageProcessor struct { type EPUBImageProcessor interface {
Load() (images []epubimage.EPUBImage, err error)
CoverTitleData(o CoverTitleDataOptions) (epubzip.Image, error)
}
type ePUBImageProcessor struct {
epuboptions.EPUBOptions epuboptions.EPUBOptions
} }
func New(o epuboptions.EPUBOptions) EPUBImageProcessor { func New(o epuboptions.EPUBOptions) EPUBImageProcessor {
return EPUBImageProcessor{o} return ePUBImageProcessor{o}
} }
// Load extract and convert images // Load extract and convert images
func (e EPUBImageProcessor) Load() (images []epubimage.EPUBImage, err error) { func (e ePUBImageProcessor) Load() (images []epubimage.EPUBImage, err error) {
images = make([]epubimage.EPUBImage, 0) images = make([]epubimage.EPUBImage, 0)
imageCount, imageInput, err := e.load() imageCount, imageInput, err := e.load()
if err != nil { if err != nil {
@ -136,7 +141,7 @@ func (e EPUBImageProcessor) Load() (images []epubimage.EPUBImage, err error) {
return images, nil return images, nil
} }
func (e EPUBImageProcessor) createImage(src image.Image, r image.Rectangle) draw.Image { func (e ePUBImageProcessor) createImage(src image.Image, r image.Rectangle) draw.Image {
if e.EPUBOptions.Image.GrayScale { if e.EPUBOptions.Image.GrayScale {
return image.NewGray(r) return image.NewGray(r)
} }
@ -169,7 +174,7 @@ func (e EPUBImageProcessor) createImage(src image.Image, r image.Rectangle) draw
// transform image into 1 or 3 images // transform image into 1 or 3 images
// only doublepage with autosplit has 3 versions // only doublepage with autosplit has 3 versions
func (e EPUBImageProcessor) transformImage(input task, part int, right bool) epubimage.EPUBImage { func (e ePUBImageProcessor) transformImage(input task, part int, right bool) epubimage.EPUBImage {
g := gift.New() g := gift.New()
src := input.Image src := input.Image
srcBounds := src.Bounds() srcBounds := src.Bounds()
@ -286,7 +291,7 @@ type CoverTitleDataOptions struct {
BorderSize int BorderSize int
} }
func (e EPUBImageProcessor) Cover16LevelOfGray(bounds image.Rectangle) draw.Image { func (e ePUBImageProcessor) cover16LevelOfGray(bounds image.Rectangle) draw.Image {
return image.NewPaletted(bounds, color.Palette{ return image.NewPaletted(bounds, color.Palette{
color.Gray{}, color.Gray{},
color.Gray{Y: 0x11}, color.Gray{Y: 0x11},
@ -308,12 +313,12 @@ func (e EPUBImageProcessor) Cover16LevelOfGray(bounds image.Rectangle) draw.Imag
} }
// CoverTitleData create a title page with the cover // CoverTitleData create a title page with the cover
func (e EPUBImageProcessor) CoverTitleData(o CoverTitleDataOptions) (epubzip.Image, error) { func (e ePUBImageProcessor) CoverTitleData(o CoverTitleDataOptions) (epubzip.Image, error) {
// Create a blur version of the cover // Create a blur version of the cover
g := gift.New(epubimagefilters.CoverTitle(o.Text, o.Align, o.PctWidth, o.PctMargin, o.MaxFontSize, o.BorderSize)) g := gift.New(epubimagefilters.CoverTitle(o.Text, o.Align, o.PctWidth, o.PctMargin, o.MaxFontSize, o.BorderSize))
var dst draw.Image var dst draw.Image
if o.Name == "cover" && e.Image.GrayScale { if o.Name == "cover" && e.Image.GrayScale {
dst = e.Cover16LevelOfGray(o.Src.Bounds()) dst = e.cover16LevelOfGray(o.Src.Bounds())
} else { } else {
dst = e.createImage(o.Src, g.Bounds(o.Src.Bounds())) dst = e.createImage(o.Src, g.Bounds(o.Src.Bounds()))
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
"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/epubimagepassthrough"
"github.com/celogeek/go-comic-converter/v3/internal/pkg/epubimageprocessor" "github.com/celogeek/go-comic-converter/v3/internal/pkg/epubimageprocessor"
"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/epubtemplates" "github.com/celogeek/go-comic-converter/v3/internal/pkg/epubtemplates"
@ -52,13 +53,20 @@ func New(options epuboptions.EPUBOptions) EPUB {
"zoom": func(s int, z float32) int { return int(float32(s) * z) }, "zoom": func(s int, z float32) int { return int(float32(s) * z) },
}) })
var imageProcessor epubimageprocessor.EPUBImageProcessor
if options.Image.Format == "copy" {
imageProcessor = epubimagepassthrough.New(options)
} else {
imageProcessor = epubimageprocessor.New(options)
}
return epub{ return epub{
EPUBOptions: options, EPUBOptions: options,
UID: uid.String(), UID: uid.String(),
Publisher: "GO Comic Converter", Publisher: "GO Comic Converter",
UpdatedAt: time.Now().UTC().Format("2006-01-02T15:04:05Z"), UpdatedAt: time.Now().UTC().Format("2006-01-02T15:04:05Z"),
templateProcessor: tmpl, templateProcessor: tmpl,
imageProcessor: epubimageprocessor.New(options), imageProcessor: imageProcessor,
} }
} }
@ -202,13 +210,7 @@ func (e epub) writeTitleImage(wz epubzip.EPUBZip, img epubimage.EPUBImage, title
// extract image and split it into part // extract image and split it into part
func (e epub) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReader, err error) { func (e epub) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReader, err error) {
images, err := func() ([]epubimage.EPUBImage, error) { images, err := e.imageProcessor.Load()
if e.EPUBOptions.Image.Format == "copy" {
return e.imageProcessor.PassThrough()
} else {
return e.imageProcessor.Load()
}
}()
if err != nil { if err != nil {
return return