/
epeg.go
160 lines (130 loc) · 3.32 KB
/
epeg.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package goepeg
import (
"fmt"
"unsafe"
)
/*
#cgo linux LDFLAGS: ${SRCDIR}/libepeg_linux_amd64.a ${SRCDIR}/libjpeg_linux_amd64.a
#cgo darwin LDFLAGS: ${SRCDIR}/libepeg_darwin_amd64.a ${SRCDIR}/libjpeg_darwin_amd64.a
#include <stdlib.h>
#include "Epeg.h"
*/
import "C"
type TransformType int
const (
TransformNone TransformType = iota
TransformFlipH = iota
TransformFlipV = iota
TransformTranspose = iota
TransformTransverse = iota
TransformRot90 = iota
TransformRot180 = iota
TransformRot270 = iota
)
type ScaleType int
const (
ScaleTypeFitMax ScaleType = iota
ScaleTypeFitMin = iota
)
func Thumbnail(input string, output string, size int, quality int, scaleType ScaleType) error {
inputCString := C.CString(input)
defer C.free(unsafe.Pointer(inputCString))
outputCString := C.CString(output)
defer C.free(unsafe.Pointer(outputCString))
img := C.epeg_file_open(inputCString)
if img == nil {
return fmt.Errorf("epeg could not open image %s", input)
}
defer C.epeg_close(img)
var cw C.int
var ch C.int
C.epeg_size_get(img, &cw, &ch)
w := int(cw)
h := int(ch)
var thumbWidth int
var thumbHeight int
if scaleType == ScaleTypeFitMin {
if w > h {
if w > size {
thumbWidth = size * w / h
thumbHeight = size
} else {
thumbWidth = w
thumbHeight = h
}
} else {
if h > size {
thumbWidth = size
thumbHeight = size * h / w
} else {
thumbWidth = w
thumbHeight = h
}
}
} else {
if w > h {
if w > size {
thumbWidth = size
thumbHeight = size * h / w
} else {
thumbWidth = w
thumbHeight = h
}
} else {
if h > size {
thumbWidth = size * w / h
thumbHeight = size
} else {
thumbWidth = w
thumbHeight = h
}
}
}
C.epeg_decode_size_set(img, C.int(thumbWidth), C.int(thumbHeight))
C.epeg_quality_set(img, C.int(quality))
C.epeg_file_output_set(img, outputCString)
if C.epeg_encode(img) != 0 {
return fmt.Errorf("epeg encode error")
}
return nil
}
func Transform(input string, output string, transform TransformType) error {
var trans int
switch transform {
case TransformNone:
trans = C.EPEG_TRANSFORM_NONE
case TransformFlipH:
trans = C.EPEG_TRANSFORM_FLIP_H
case TransformFlipV:
trans = C.EPEG_TRANSFORM_FLIP_V
case TransformTranspose:
trans = C.EPEG_TRANSFORM_TRANSPOSE
case TransformTransverse:
trans = C.EPEG_TRANSFORM_TRANSVERSE
case TransformRot90:
trans = C.EPEG_TRANSFORM_ROT_90
case TransformRot180:
trans = C.EPEG_TRANSFORM_ROT_180
case TransformRot270:
trans = C.EPEG_TRANSFORM_ROT_270
default:
return fmt.Errorf("epeg invalid transformation")
}
inputCString := C.CString(input)
defer C.free(unsafe.Pointer(inputCString))
outputCString := C.CString(output)
defer C.free(unsafe.Pointer(outputCString))
img := C.epeg_file_open(inputCString)
if img == nil {
return fmt.Errorf("epeg could not open image %s", input)
}
defer C.epeg_close(img)
C.epeg_transform_set(img, C.Epeg_Transform(trans))
C.epeg_file_output_set(img, outputCString)
if code := int(C.epeg_transform(img)); code != 0 {
buf := [1024]byte{}
C.epeg_error(img, (*C.char)((unsafe.Pointer(&buf[0]))))
return fmt.Errorf("epeg transform error: error %d: %s", code, buf)
}
return nil
}