More work on diffing images
This commit is contained in:
parent
c745961f47
commit
508a61bd1c
@ -18,6 +18,7 @@ var _ = fmt.Print
|
|||||||
var path_name_map, remote_dirs map[string]string
|
var path_name_map, remote_dirs map[string]string
|
||||||
|
|
||||||
var mimetypes_cache, data_cache, hash_cache *utils.LRUCache[string, string]
|
var mimetypes_cache, data_cache, hash_cache *utils.LRUCache[string, string]
|
||||||
|
var size_cache *utils.LRUCache[string, int64]
|
||||||
var lines_cache *utils.LRUCache[string, []string]
|
var lines_cache *utils.LRUCache[string, []string]
|
||||||
var highlighted_lines_cache *utils.LRUCache[string, []string]
|
var highlighted_lines_cache *utils.LRUCache[string, []string]
|
||||||
var is_text_cache *utils.LRUCache[string, bool]
|
var is_text_cache *utils.LRUCache[string, bool]
|
||||||
@ -26,6 +27,7 @@ func init_caches() {
|
|||||||
path_name_map = make(map[string]string, 32)
|
path_name_map = make(map[string]string, 32)
|
||||||
remote_dirs = make(map[string]string, 32)
|
remote_dirs = make(map[string]string, 32)
|
||||||
const sz = 4096
|
const sz = 4096
|
||||||
|
size_cache = utils.NewLRUCache[string, int64](sz)
|
||||||
mimetypes_cache = utils.NewLRUCache[string, string](sz)
|
mimetypes_cache = utils.NewLRUCache[string, string](sz)
|
||||||
data_cache = utils.NewLRUCache[string, string](sz)
|
data_cache = utils.NewLRUCache[string, string](sz)
|
||||||
is_text_cache = utils.NewLRUCache[string, bool](sz)
|
is_text_cache = utils.NewLRUCache[string, bool](sz)
|
||||||
@ -67,6 +69,16 @@ func data_for_path(path string) (string, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_for_path(path string) (int64, error) {
|
||||||
|
return size_cache.GetOrCreate(path, func(path string) (int64, error) {
|
||||||
|
s, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return s.Size(), nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func is_image(path string) bool {
|
func is_image(path string) bool {
|
||||||
return strings.HasPrefix(mimetype_for_path(path), "image/")
|
return strings.HasPrefix(mimetype_for_path(path), "image/")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -210,12 +210,7 @@ func (self *LogicalLines) IncrementScrollPosBy(pos *ScrollPos, amt int) (delta i
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func image_lines(left_path, right_path string, columns, margin_size int, ans []*LogicalLine) ([]*LogicalLine, error) {
|
func human_readable(size int64) string {
|
||||||
// TODO: Implement this
|
|
||||||
return ans, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func human_readable(size int) string {
|
|
||||||
divisor, suffix := 1, "B"
|
divisor, suffix := 1, "B"
|
||||||
for i, candidate := range []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"} {
|
for i, candidate := range []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"} {
|
||||||
if size < (1 << ((i + 1) * 10)) {
|
if size < (1 << ((i + 1) * 10)) {
|
||||||
@ -253,33 +248,79 @@ func render_diff_line(number, text, ltype string, margin_size int, available_col
|
|||||||
return margin + content
|
return margin + content
|
||||||
}
|
}
|
||||||
|
|
||||||
func binary_lines(left_path, right_path string, columns, margin_size int, ans []*LogicalLine) (ans2 []*LogicalLine, err error) {
|
func image_lines(left_path, right_path string, columns, margin_size int, ans []*LogicalLine) ([]*LogicalLine, error) {
|
||||||
available_cols := columns/2 - margin_size
|
available_cols := columns/2 - margin_size
|
||||||
fl := func(path string, formatter func(...any) string) string {
|
ll, err := first_binary_line(left_path, right_path, columns, margin_size, func(path string, formatter func(...any) string) (string, error) {
|
||||||
if err == nil {
|
sz, err := size_for_path(path)
|
||||||
var data string
|
if err != nil {
|
||||||
data, err = data_for_path(path)
|
return "", err
|
||||||
text := fmt.Sprintf("Binary file: %s", human_readable(len(data)))
|
}
|
||||||
|
text := fmt.Sprintf("Size: %s", human_readable(sz))
|
||||||
|
res := image_collection.ResolutionOf(path)
|
||||||
|
if res.X > -1 {
|
||||||
|
text = fmt.Sprintf("Dimensions: %dx%d %s", res.X, res.Y, text)
|
||||||
|
}
|
||||||
text = place_in(text, available_cols)
|
text = place_in(text, available_cols)
|
||||||
return margin_format(strings.Repeat(` `, margin_size)) + formatter(text)
|
return formatter(strings.Repeat(` `, margin_size) + text), err
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return ""
|
return append(ans, ll), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func first_binary_line(left_path, right_path string, columns, margin_size int, renderer func(path string, formatter func(...any) string) (string, error)) (*LogicalLine, error) {
|
||||||
|
available_cols := columns/2 - margin_size
|
||||||
line := ""
|
line := ""
|
||||||
if left_path == "" {
|
if left_path == "" {
|
||||||
filler := render_diff_line(``, ``, `filler`, margin_size, available_cols)
|
filler := render_diff_line(``, ``, `filler`, margin_size, available_cols)
|
||||||
line = filler + fl(right_path, added_format)
|
r, err := renderer(right_path, added_format)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line = filler + r
|
||||||
} else if right_path == "" {
|
} else if right_path == "" {
|
||||||
filler := render_diff_line(``, ``, `filler`, margin_size, available_cols)
|
filler := render_diff_line(``, ``, `filler`, margin_size, available_cols)
|
||||||
line = fl(left_path, removed_format) + filler
|
l, err := renderer(left_path, removed_format)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line = l + filler
|
||||||
} else {
|
} else {
|
||||||
line = fl(left_path, removed_format) + fl(right_path, added_format)
|
l, err := renderer(left_path, removed_format)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r, err := renderer(right_path, added_format)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line = l + r
|
||||||
}
|
}
|
||||||
ll := LogicalLine{is_change_start: true, line_type: CHANGE_LINE, src: Reference{path: left_path, linenum: 0}, screen_lines: []string{line}}
|
ll := LogicalLine{is_change_start: true, line_type: CHANGE_LINE, src: Reference{path: left_path, linenum: 0}, screen_lines: []string{line}}
|
||||||
if left_path == "" {
|
if left_path == "" {
|
||||||
ll.src.path = right_path
|
ll.src.path = right_path
|
||||||
}
|
}
|
||||||
return append(ans, &ll), err
|
return &ll, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func binary_lines(left_path, right_path string, columns, margin_size int, ans []*LogicalLine) (ans2 []*LogicalLine, err error) {
|
||||||
|
available_cols := columns/2 - margin_size
|
||||||
|
ll, err := first_binary_line(left_path, right_path, columns, margin_size, func(path string, formatter func(...any) string) (string, error) {
|
||||||
|
sz, err := size_for_path(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
text := fmt.Sprintf("Binary file: %s", human_readable(sz))
|
||||||
|
text = place_in(text, available_cols)
|
||||||
|
return formatter(strings.Repeat(` `, margin_size) + text), err
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return append(ans, ll), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiffData struct {
|
type DiffData struct {
|
||||||
|
|||||||
@ -25,6 +25,7 @@ const (
|
|||||||
COLLECTION ResultType = iota
|
COLLECTION ResultType = iota
|
||||||
DIFF
|
DIFF
|
||||||
HIGHLIGHT
|
HIGHLIGHT
|
||||||
|
IMAGE_LOAD
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScrollPos struct {
|
type ScrollPos struct {
|
||||||
@ -46,10 +47,11 @@ type AsyncResult struct {
|
|||||||
diff_map map[string]*Patch
|
diff_map map[string]*Patch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var image_collection *graphics.ImageCollection
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
async_results chan AsyncResult
|
async_results chan AsyncResult
|
||||||
shortcut_tracker config.ShortcutTracker
|
shortcut_tracker config.ShortcutTracker
|
||||||
pending_keys []string
|
|
||||||
left, right string
|
left, right string
|
||||||
collection *Collection
|
collection *Collection
|
||||||
diff_map map[string]*Patch
|
diff_map map[string]*Patch
|
||||||
@ -78,8 +80,8 @@ func (self *Handler) calculate_statistics() {
|
|||||||
var DebugPrintln = tty.DebugPrintln
|
var DebugPrintln = tty.DebugPrintln
|
||||||
|
|
||||||
func (self *Handler) initialize() {
|
func (self *Handler) initialize() {
|
||||||
self.pending_keys = make([]string, 0, 4)
|
|
||||||
self.rl = readline.New(self.lp, readline.RlInit{DontMarkPrompts: true, Prompt: "/"})
|
self.rl = readline.New(self.lp, readline.RlInit{DontMarkPrompts: true, Prompt: "/"})
|
||||||
|
image_collection = graphics.NewImageCollection()
|
||||||
self.current_context_count = opts.Context
|
self.current_context_count = opts.Context
|
||||||
if self.current_context_count < 0 {
|
if self.current_context_count < 0 {
|
||||||
self.current_context_count = int(conf.Num_context_lines)
|
self.current_context_count = int(conf.Num_context_lines)
|
||||||
@ -154,12 +156,42 @@ func (self *Handler) highlight_all() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Handler) load_all_images() {
|
||||||
|
self.collection.Apply(func(path, item_type, changed_path string) error {
|
||||||
|
if path != "" && is_image(path) {
|
||||||
|
image_collection.AddPaths(path)
|
||||||
|
}
|
||||||
|
if changed_path != "" && is_image(changed_path) {
|
||||||
|
image_collection.AddPaths(changed_path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
go func() {
|
||||||
|
r := AsyncResult{rtype: IMAGE_LOAD}
|
||||||
|
image_collection.LoadAll()
|
||||||
|
self.async_results <- r
|
||||||
|
self.lp.WakeupMainThread()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Handler) rerender_diff() error {
|
||||||
|
if self.diff_map != nil && self.collection != nil {
|
||||||
|
err := self.render_diff()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
self.draw_screen()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Handler) handle_async_result(r AsyncResult) error {
|
func (self *Handler) handle_async_result(r AsyncResult) error {
|
||||||
switch r.rtype {
|
switch r.rtype {
|
||||||
case COLLECTION:
|
case COLLECTION:
|
||||||
self.collection = r.collection
|
self.collection = r.collection
|
||||||
self.generate_diff()
|
self.generate_diff()
|
||||||
self.highlight_all()
|
self.highlight_all()
|
||||||
|
self.load_all_images()
|
||||||
case DIFF:
|
case DIFF:
|
||||||
self.diff_map = r.diff_map
|
self.diff_map = r.diff_map
|
||||||
self.calculate_statistics()
|
self.calculate_statistics()
|
||||||
@ -176,14 +208,8 @@ func (self *Handler) handle_async_result(r AsyncResult) error {
|
|||||||
self.restore_position = nil
|
self.restore_position = nil
|
||||||
}
|
}
|
||||||
self.draw_screen()
|
self.draw_screen()
|
||||||
case HIGHLIGHT:
|
case HIGHLIGHT, IMAGE_LOAD:
|
||||||
if self.diff_map != nil && self.collection != nil {
|
return self.rerender_diff()
|
||||||
err := self.render_diff()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
self.draw_screen()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import (
|
|||||||
"kitty/tools/tui/graphics"
|
"kitty/tools/tui/graphics"
|
||||||
"kitty/tools/tui/loop"
|
"kitty/tools/tui/loop"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
|
"kitty/tools/utils/images"
|
||||||
"kitty/tools/utils/shm"
|
"kitty/tools/utils/shm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ func DetectSupport(timeout time.Duration) (memory, files, direct bool, err error
|
|||||||
}
|
}
|
||||||
|
|
||||||
direct_query_id = g(graphics.GRT_transmission_direct, "123")
|
direct_query_id = g(graphics.GRT_transmission_direct, "123")
|
||||||
tf, err := graphics.CreateTempInRAM()
|
tf, err := images.CreateTempInRAM()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
file_query_id = g(graphics.GRT_transmission_tempfile, tf.Name())
|
file_query_id = g(graphics.GRT_transmission_tempfile, tf.Name())
|
||||||
temp_files_to_delete = append(temp_files_to_delete, tf.Name())
|
temp_files_to_delete = append(temp_files_to_delete, tf.Name())
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import (
|
|||||||
"kitty/tools/tty"
|
"kitty/tools/tty"
|
||||||
"kitty/tools/tui/graphics"
|
"kitty/tools/tui/graphics"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
|
"kitty/tools/utils/images"
|
||||||
"kitty/tools/utils/shm"
|
"kitty/tools/utils/shm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -142,7 +143,7 @@ func (self *opened_input) PutOnFilesystem() (err error) {
|
|||||||
if self.name_to_unlink != "" {
|
if self.name_to_unlink != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f, err := graphics.CreateTempInRAM()
|
f, err := images.CreateTempInRAM()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create a temporary file to store input data with error: %w", err)
|
return fmt.Errorf("Failed to create a temporary file to store input data with error: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -152,7 +152,7 @@ func transmit_file(imgd *image_data, frame_num int, frame *image_frame) (err err
|
|||||||
frame.shm.Close()
|
frame.shm.Close()
|
||||||
frame.shm = nil
|
frame.shm = nil
|
||||||
} else {
|
} else {
|
||||||
f, err := graphics.CreateTempInRAM()
|
f, err := images.CreateTempInRAM()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create a temp file for image data transmission: %w", err)
|
return fmt.Errorf("Failed to create a temp file for image data transmission: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
86
tools/tui/graphics/collection.go
Normal file
86
tools/tui/graphics/collection.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
package graphics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
"kitty/tools/utils/images"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = fmt.Print
|
||||||
|
|
||||||
|
type Image struct {
|
||||||
|
src struct {
|
||||||
|
path string
|
||||||
|
data *images.ImageData
|
||||||
|
size image.Point
|
||||||
|
loaded bool
|
||||||
|
}
|
||||||
|
renderings map[image.Point]*images.ImageData
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageCollection struct {
|
||||||
|
Shm_supported, Files_supported atomic.Bool
|
||||||
|
mutex sync.Mutex
|
||||||
|
|
||||||
|
images map[string]*Image
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *ImageCollection) ResolutionOf(key string) image.Point {
|
||||||
|
if !self.mutex.TryLock() {
|
||||||
|
return image.Point{-1, -1}
|
||||||
|
}
|
||||||
|
defer self.mutex.Unlock()
|
||||||
|
i := self.images[key]
|
||||||
|
if i == nil {
|
||||||
|
return image.Point{-2, -2}
|
||||||
|
}
|
||||||
|
return i.src.size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *ImageCollection) AddPaths(paths ...string) {
|
||||||
|
self.mutex.Lock()
|
||||||
|
defer self.mutex.Unlock()
|
||||||
|
for _, path := range paths {
|
||||||
|
if self.images[path] == nil {
|
||||||
|
i := &Image{}
|
||||||
|
i.src.path = path
|
||||||
|
self.images[path] = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *ImageCollection) LoadAll() {
|
||||||
|
self.mutex.Lock()
|
||||||
|
defer self.mutex.Unlock()
|
||||||
|
ctx := images.Context{}
|
||||||
|
all := maps.Values(self.images)
|
||||||
|
ctx.Parallel(0, len(self.images), func(nums <-chan int) {
|
||||||
|
for i := range nums {
|
||||||
|
img := all[i]
|
||||||
|
if !img.src.loaded {
|
||||||
|
img.src.data, img.err = images.OpenImageFromPath(img.src.path)
|
||||||
|
if img.err == nil {
|
||||||
|
img.src.size.X, img.src.size.Y = img.src.data.Width, img.src.data.Height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewImageCollection(paths ...string) *ImageCollection {
|
||||||
|
items := make(map[string]*Image, len(paths))
|
||||||
|
for _, path := range paths {
|
||||||
|
i := &Image{}
|
||||||
|
i.src.path = path
|
||||||
|
items[path] = i
|
||||||
|
}
|
||||||
|
return &ImageCollection{images: items}
|
||||||
|
}
|
||||||
@ -8,33 +8,15 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"kitty/tools/tui/loop"
|
"kitty/tools/tui/loop"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
"kitty/tools/utils/shm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
|
|
||||||
const TempTemplate = "kitty-tty-graphics-protocol-*"
|
|
||||||
|
|
||||||
func CreateTemp() (*os.File, error) {
|
|
||||||
return os.CreateTemp("", TempTemplate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateTempInRAM() (*os.File, error) {
|
|
||||||
if shm.SHM_DIR != "" {
|
|
||||||
f, err := os.CreateTemp(shm.SHM_DIR, TempTemplate)
|
|
||||||
if err == nil {
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CreateTemp()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enums {{{
|
// Enums {{{
|
||||||
type GRT_a int
|
type GRT_a int
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"kitty/tools/tui/graphics"
|
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
"kitty/tools/utils/shm"
|
"kitty/tools/utils/shm"
|
||||||
|
|
||||||
@ -27,6 +26,22 @@ import (
|
|||||||
|
|
||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
|
|
||||||
|
const TempTemplate = "kitty-tty-graphics-protocol-*"
|
||||||
|
|
||||||
|
func CreateTemp() (*os.File, error) {
|
||||||
|
return os.CreateTemp("", TempTemplate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateTempInRAM() (*os.File, error) {
|
||||||
|
if shm.SHM_DIR != "" {
|
||||||
|
f, err := os.CreateTemp(shm.SHM_DIR, TempTemplate)
|
||||||
|
if err == nil {
|
||||||
|
return f, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CreateTemp()
|
||||||
|
}
|
||||||
|
|
||||||
type ImageFrame struct {
|
type ImageFrame struct {
|
||||||
Width, Height, Left, Top int
|
Width, Height, Left, Top int
|
||||||
Number int // 1-based number
|
Number int // 1-based number
|
||||||
@ -189,7 +204,7 @@ type IdentifyRecord struct {
|
|||||||
Width, Height int
|
Width, Height int
|
||||||
Dpi struct{ X, Y float64 }
|
Dpi struct{ X, Y float64 }
|
||||||
Index int
|
Index int
|
||||||
Mode graphics.GRT_f
|
Is_opaque bool
|
||||||
Needs_blend bool
|
Needs_blend bool
|
||||||
Disposal int
|
Disposal int
|
||||||
Dimensions_swapped bool
|
Dimensions_swapped bool
|
||||||
@ -258,9 +273,9 @@ func parse_identify_record(ans *IdentifyRecord, raw *IdentifyOutput) (err error)
|
|||||||
}
|
}
|
||||||
q := strings.ToLower(raw.Transparency)
|
q := strings.ToLower(raw.Transparency)
|
||||||
if q == "blend" || q == "true" {
|
if q == "blend" || q == "true" {
|
||||||
ans.Mode = graphics.GRT_format_rgba
|
ans.Is_opaque = false
|
||||||
} else {
|
} else {
|
||||||
ans.Mode = graphics.GRT_format_rgb
|
ans.Is_opaque = true
|
||||||
}
|
}
|
||||||
ans.Needs_blend = q == "blend"
|
ans.Needs_blend = q == "blend"
|
||||||
switch strings.ToLower(raw.Dispose) {
|
switch strings.ToLower(raw.Dispose) {
|
||||||
@ -376,7 +391,7 @@ func RenderWithMagick(path string, ro *RenderOptions, frames []IdentifyRecord) (
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tdir)
|
defer os.RemoveAll(tdir)
|
||||||
mode := "rgba"
|
mode := "rgba"
|
||||||
if frames[0].Mode == graphics.GRT_format_rgb {
|
if frames[0].Is_opaque {
|
||||||
mode = "rgb"
|
mode = "rgb"
|
||||||
}
|
}
|
||||||
cmd = append(cmd, filepath.Join(tdir, "im-%[filename:f]."+mode))
|
cmd = append(cmd, filepath.Join(tdir, "im-%[filename:f]."+mode))
|
||||||
@ -431,7 +446,7 @@ func RenderWithMagick(path string, ro *RenderOptions, frames []IdentifyRecord) (
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
identify_data := frames[index]
|
identify_data := frames[index]
|
||||||
df, cerr := os.CreateTemp(base_dir, graphics.TempTemplate+"."+mode)
|
df, cerr := os.CreateTemp(base_dir, TempTemplate+"."+mode)
|
||||||
if cerr != nil {
|
if cerr != nil {
|
||||||
err = fmt.Errorf("Failed to create a temporary file in %s with error: %w", base_dir, cerr)
|
err = fmt.Errorf("Failed to create a temporary file in %s with error: %w", base_dir, cerr)
|
||||||
return
|
return
|
||||||
@ -444,7 +459,7 @@ func RenderWithMagick(path string, ro *RenderOptions, frames []IdentifyRecord) (
|
|||||||
df.Close()
|
df.Close()
|
||||||
fmap[index+1] = df.Name()
|
fmap[index+1] = df.Name()
|
||||||
frame := ImageFrame{
|
frame := ImageFrame{
|
||||||
Number: index + 1, Width: width, Height: height, Left: x, Top: y, Is_opaque: identify_data.Mode == graphics.GRT_format_rgb,
|
Number: index + 1, Width: width, Height: height, Left: x, Top: y, Is_opaque: identify_data.Is_opaque,
|
||||||
}
|
}
|
||||||
frame.set_delay(min_gap, identify_data.Gap)
|
frame.set_delay(min_gap, identify_data.Gap)
|
||||||
err = check_resize(&frame, df.Name())
|
err = check_resize(&frame, df.Name())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user