go-comic-converter/internal/epub/zip/epub_zip_image.go

71 lines
1.4 KiB
Go

package epubzip
import (
"archive/zip"
"bytes"
"compress/flate"
"fmt"
"hash/crc32"
"image"
"image/jpeg"
"os"
"time"
)
type ZipImage struct {
Header *zip.FileHeader
Data []byte
}
// compressed size of the image with the header
func (img *ZipImage) CompressedSize() uint64 {
return img.Header.CompressedSize64 + 30 + uint64(len(img.Header.Name))
}
func exitWithError(err error) {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// create gzip encoded jpeg
func CompressImage(filename string, img image.Image, quality int) *ZipImage {
var (
data, cdata bytes.Buffer
err error
)
err = jpeg.Encode(&data, img, &jpeg.Options{Quality: quality})
if err != nil {
exitWithError(err)
}
wcdata, err := flate.NewWriter(&cdata, flate.BestCompression)
if err != nil {
exitWithError(err)
}
_, err = wcdata.Write(data.Bytes())
if err != nil {
exitWithError(err)
}
err = wcdata.Close()
if err != nil {
exitWithError(err)
}
t := time.Now()
return &ZipImage{
&zip.FileHeader{
Name: filename,
CompressedSize64: uint64(cdata.Len()),
UncompressedSize64: uint64(data.Len()),
CRC32: crc32.Checksum(data.Bytes(), crc32.IEEETable),
Method: zip.Deflate,
ModifiedTime: uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11),
ModifiedDate: uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9),
},
cdata.Bytes(),
}
}