mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-26 10:12:17 +02:00
Use an explicit APNG identifier for apng files with ImageMagick
Required as per Imagemgick docs: https://imagemagick.org/script/formats.php
This commit is contained in:
@@ -12,9 +12,9 @@ import (
|
|||||||
|
|
||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
|
|
||||||
func Render(path string, ro *images.RenderOptions, frames []images.IdentifyRecord) (ans []*image_frame, err error) {
|
func Render(path, original_file_path string, ro *images.RenderOptions, frames []images.IdentifyRecord) (ans []*image_frame, err error) {
|
||||||
ro.TempfilenameTemplate = shm_template
|
ro.TempfilenameTemplate = shm_template
|
||||||
image_frames, filenames, err := images.RenderWithMagick(path, ro, frames)
|
image_frames, filenames, err := images.RenderWithMagick(path, original_file_path, ro, frames)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ans = make([]*image_frame, len(image_frames))
|
ans = make([]*image_frame, len(image_frames))
|
||||||
for i, x := range image_frames {
|
for i, x := range image_frames {
|
||||||
@@ -41,7 +41,7 @@ func render_image_with_magick(imgd *image_data, src *opened_input) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
frames, err := images.IdentifyWithMagick(src.FileSystemName())
|
frames, err := images.IdentifyWithMagick(src.FileSystemName(), imgd.source_name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ func render_image_with_magick(imgd *image_data, src *opened_input) (err error) {
|
|||||||
if scale_image(imgd) {
|
if scale_image(imgd) {
|
||||||
ro.ResizeTo.X, ro.ResizeTo.Y = imgd.canvas_width, imgd.canvas_height
|
ro.ResizeTo.X, ro.ResizeTo.Y = imgd.canvas_width, imgd.canvas_height
|
||||||
}
|
}
|
||||||
imgd.frames, err = Render(src.FileSystemName(), &ro, frames)
|
imgd.frames, err = Render(src.FileSystemName(), imgd.source_name, &ro, frames)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,9 +302,13 @@ func check_resize(frame *ImageFrame, filename string) error {
|
|||||||
}
|
}
|
||||||
expected_size := bytes_per_pixel * frame.Width * frame.Height
|
expected_size := bytes_per_pixel * frame.Width * frame.Height
|
||||||
if sz < expected_size {
|
if sz < expected_size {
|
||||||
|
if bytes_per_pixel == 4 && sz == 3*frame.Width*frame.Height {
|
||||||
|
frame.Is_opaque = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
missing := expected_size - sz
|
missing := expected_size - sz
|
||||||
if missing%(bytes_per_pixel*frame.Width) != 0 {
|
if missing%(bytes_per_pixel*frame.Width) != 0 {
|
||||||
return fmt.Errorf("ImageMagick failed to resize correctly. It generated %d < %d of data (w=%d h=%d bpp=%d)", sz, expected_size, frame.Width, frame.Height, bytes_per_pixel)
|
return fmt.Errorf("ImageMagick failed to resize correctly. It generated %d < %d of data (w=%d h=%d bpp=%d frame-number: %d)", sz, expected_size, frame.Width, frame.Height, bytes_per_pixel, frame.Number)
|
||||||
}
|
}
|
||||||
frame.Height -= missing / (bytes_per_pixel * frame.Width)
|
frame.Height -= missing / (bytes_per_pixel * frame.Width)
|
||||||
}
|
}
|
||||||
@@ -439,11 +443,16 @@ func parse_identify_record(ans *IdentifyRecord, raw *IdentifyOutput) (err error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func IdentifyWithMagick(path string) (ans []IdentifyRecord, err error) {
|
func IdentifyWithMagick(path, original_file_path string) (ans []IdentifyRecord, err error) {
|
||||||
cmd := []string{"identify"}
|
cmd := []string{"identify"}
|
||||||
q := `{"fmt":"%m","canvas":"%g","transparency":"%A","gap":"%T","index":"%p","size":"%wx%h",` +
|
q := `{"fmt":"%m","canvas":"%g","transparency":"%A","gap":"%T","index":"%p","size":"%wx%h",` +
|
||||||
`"dpi":"%xx%y","dispose":"%D","orientation":"%[EXIF:Orientation]"},`
|
`"dpi":"%xx%y","dispose":"%D","orientation":"%[EXIF:Orientation]"},`
|
||||||
cmd = append(cmd, "-format", q, "--", path)
|
ext := filepath.Ext(original_file_path)
|
||||||
|
ipath := path
|
||||||
|
if strings.ToLower(ext) == ".apng" {
|
||||||
|
ipath = "APNG:" + path
|
||||||
|
}
|
||||||
|
cmd = append(cmd, "-format", q, "--", ipath)
|
||||||
output, err := RunMagick(path, cmd)
|
output, err := RunMagick(path, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to identify image at path: %s with error: %w", path, err)
|
return nil, fmt.Errorf("Failed to identify image at path: %s with error: %w", path, err)
|
||||||
@@ -476,10 +485,15 @@ type RenderOptions struct {
|
|||||||
TempfilenameTemplate string
|
TempfilenameTemplate string
|
||||||
}
|
}
|
||||||
|
|
||||||
func RenderWithMagick(path string, ro *RenderOptions, frames []IdentifyRecord) (ans []*ImageFrame, fmap map[int]string, err error) {
|
func RenderWithMagick(path, original_file_path string, ro *RenderOptions, frames []IdentifyRecord) (ans []*ImageFrame, fmap map[int]string, err error) {
|
||||||
cmd := []string{"convert"}
|
cmd := []string{"convert"}
|
||||||
ans = make([]*ImageFrame, 0, len(frames))
|
ans = make([]*ImageFrame, 0, len(frames))
|
||||||
fmap = make(map[int]string, len(frames))
|
fmap = make(map[int]string, len(frames))
|
||||||
|
ext := filepath.Ext(original_file_path)
|
||||||
|
ipath := path
|
||||||
|
if strings.ToLower(ext) == ".apng" {
|
||||||
|
ipath = "APNG:" + path
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -500,7 +514,7 @@ func RenderWithMagick(path string, ro *RenderOptions, frames []IdentifyRecord) (
|
|||||||
if ro.Flop {
|
if ro.Flop {
|
||||||
cmd = append(cmd, "-flop")
|
cmd = append(cmd, "-flop")
|
||||||
}
|
}
|
||||||
cpath := path
|
cpath := ipath
|
||||||
if ro.OnlyFirstFrame {
|
if ro.OnlyFirstFrame {
|
||||||
cpath += "[0]"
|
cpath += "[0]"
|
||||||
}
|
}
|
||||||
@@ -621,11 +635,11 @@ func RenderWithMagick(path string, ro *RenderOptions, frames []IdentifyRecord) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func OpenImageFromPathWithMagick(path string) (ans *ImageData, err error) {
|
func OpenImageFromPathWithMagick(path string) (ans *ImageData, err error) {
|
||||||
identify_records, err := IdentifyWithMagick(path)
|
identify_records, err := IdentifyWithMagick(path, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to identify image at %#v with error: %w", path, err)
|
return nil, fmt.Errorf("Failed to identify image at %#v with error: %w", path, err)
|
||||||
}
|
}
|
||||||
frames, filenames, err := RenderWithMagick(path, &RenderOptions{}, identify_records)
|
frames, filenames, err := RenderWithMagick(path, path, &RenderOptions{}, identify_records)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to render image at %#v with error: %w", path, err)
|
return nil, fmt.Errorf("Failed to render image at %#v with error: %w", path, err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user