forked from davidbyttow/govips
-
Notifications
You must be signed in to change notification settings - Fork 0
/
govips.go
146 lines (119 loc) · 3.26 KB
/
govips.go
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Package vips provides a library for transforming images that is built on lipvips. Libvips
// is an extremely fast C-library. Therefore, govips requires that libvips 8+ be installed
// and available on the target environment.
package vips
//go:generate scripts/codegen.sh
// #cgo pkg-config: vips
// #include "vips/vips.h"
import "C"
import (
"fmt"
"runtime"
"sync"
)
const (
defaultConcurrencyLevel = 1
defaultMaxCacheMem = 100 * 1024 * 1024
defaultMaxCacheSize = 500
)
// VipsVersion if the primary version of libvips
const VipsVersion = string(C.VIPS_VERSION)
// VipsMajorVersion is the major version of libvips
const VipsMajorVersion = int(C.VIPS_MAJOR_VERSION)
// VipsMinorVersion if the minor vesrion of libvips
const VipsMinorVersion = int(C.VIPS_MINOR_VERSION)
var (
running = false
initLock sync.Mutex
)
// Config allows fine-tuning of libvips library
type Config struct {
ConcurrencyLevel int
MaxCacheFiles int
MaxCacheMem int
MaxCacheSize int
ReportLeaks bool
}
// Startup sets up the libvips support and ensures the versions are correct. Pass in nil for
// default configuration.
func Startup(config *Config) {
initLock.Lock()
runtime.LockOSThread()
defer initLock.Unlock()
defer runtime.UnlockOSThread()
if running {
debug("warning libvips already started")
return
}
if C.VIPS_MAJOR_VERSION < 8 {
panic("Requires libvips version 8+")
}
cName := C.CString("govips")
defer freeCString(cName)
err := C.vips_init(cName)
if err != 0 {
panic(fmt.Sprintf("Failed to start vips code=%d", err))
}
running = true
C.vips_concurrency_set(defaultConcurrencyLevel)
C.vips_cache_set_max(defaultMaxCacheSize)
C.vips_cache_set_max_mem(defaultMaxCacheMem)
if config != nil {
C.vips_leak_set(toGboolean(config.ReportLeaks))
if config.ConcurrencyLevel > 0 {
C.vips_concurrency_set(C.int(config.ConcurrencyLevel))
}
if config.MaxCacheFiles > 0 {
C.vips_cache_set_max_files(C.int(config.MaxCacheFiles))
}
if config.MaxCacheMem > 0 {
C.vips_cache_set_max_mem(C.size_t(config.MaxCacheMem))
}
if config.MaxCacheSize > 0 {
C.vips_cache_set_max(C.int(config.MaxCacheSize))
}
}
initTypes()
}
// PrintObjectReport outputs all of the current internal objects in libvips
func PrintObjectReport(label string) {
fmt.Printf("\n=======================================\nMemory leaks: %s...\n", label)
C.vips_object_print_all()
fmt.Printf("=======================================\n\n")
}
func startupIfNeeded() {
if !running {
debug("libvips was forcibly started automatically, consider calling Startup/Shutdown yourself")
Startup(nil)
}
}
// Shutdown libvips
func Shutdown() {
initLock.Lock()
runtime.LockOSThread()
defer initLock.Unlock()
defer runtime.UnlockOSThread()
if !running {
debug("warning libvips not started")
return
}
C.vips_shutdown()
running = false
}
// ShutdownThread clears the cache for for the given thread
func ShutdownThread() {
C.vips_thread_shutdown()
}
type VipsMemoryStats struct {
Mem int64
MemHigh int64
Allocs int64
}
func ReadVipsMemStats(stats *VipsMemoryStats) {
stats.Mem = int64(C.vips_tracked_get_mem())
stats.MemHigh = int64(C.vips_tracked_get_mem_highwater())
stats.Allocs = int64(C.vips_tracked_get_allocs())
}
func VipsClearCache() {
C.vips_cache_drop_all()
}