-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathheic.go
More file actions
92 lines (75 loc) · 2.28 KB
/
heic.go
File metadata and controls
92 lines (75 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package main
import (
"bytes"
"fmt"
"image"
"io"
)
// HEICDecoder provides an interface for HEIC decoding functionality
type HEICDecoder interface {
// IsAvailable returns true if HEIC decoding is available on this platform
IsAvailable() bool
// Decode decodes HEIC image data and returns a standard Go image
Decode(r io.Reader) (image.Image, error)
}
// Global HEIC decoder instance
var globalHEICDecoder HEICDecoder
// Default availability flag - overridden by heic_pillow.go init()
var isHEICAvailableDefault = false
// GetHEICDecoder returns the global HEIC decoder instance
func GetHEICDecoder() HEICDecoder {
if globalHEICDecoder == nil {
globalHEICDecoder = createHEICDecoder()
}
return globalHEICDecoder
}
// IsHEICAvailable returns true if HEIC decoding is available
func IsHEICAvailable() bool {
return GetHEICDecoder().IsAvailable()
}
// HEIC magic bytes detection
// HEIC/HEIF files have "ftyp" at offset 4, followed by brand identifier
// Common brands: "heic", "heix", "hevc", "hevx", "mif1", "msf1"
var heicBrands = [][]byte{
[]byte("heic"),
[]byte("heix"),
[]byte("hevc"),
[]byte("hevx"),
[]byte("mif1"),
[]byte("msf1"),
}
// IsHEICData checks if the given data appears to be HEIC/HEIF format
// Returns true if the data has HEIC magic bytes
func IsHEICData(data []byte) bool {
// Minimum HEIC header size
if len(data) < 12 {
return false
}
// Check for "ftyp" at offset 4
if !bytes.Equal(data[4:8], []byte("ftyp")) {
return false
}
// Check brand identifier at offset 8
brandBytes := data[8:12]
for _, brand := range heicBrands {
if bytes.Equal(brandBytes, brand) {
return true
}
}
return false
}
// ShowHEICNotAvailableMessage returns a user-friendly message
func ShowHEICNotAvailableMessage() string {
return fmt.Sprintf("%sHEIC format not supported (requires CGO with libheif or .venv with pillow-heif)%s", YELLOW_BG, RESET)
}
// StubHEICDecoder provides a no-op implementation for platforms without HEIC support
type StubHEICDecoder struct{}
func (s *StubHEICDecoder) IsAvailable() bool {
return false
}
func (s *StubHEICDecoder) Decode(r io.Reader) (image.Image, error) {
return nil, fmt.Errorf("HEIC decoding not available (requires CGO with libheif or .venv with pillow-heif)")
}
func createStubHEICDecoder() HEICDecoder {
return &StubHEICDecoder{}
}