1 package exifcommon
2
3 import (
4 "bytes"
5 "math"
6 "reflect"
7 "time"
8
9 "encoding/binary"
10
11 "github.com/dsoprea/go-logging"
12 )
13
14 var (
15 typeEncodeLogger = log.NewLogger("exif.type_encode")
16 )
17
18
19 type EncodedData struct {
20 Type TagTypePrimitive
21 Encoded []byte
22
23
24 UnitCount uint32
25 }
26
27
28 type ValueEncoder struct {
29 byteOrder binary.ByteOrder
30 }
31
32
33 func NewValueEncoder(byteOrder binary.ByteOrder) *ValueEncoder {
34 return &ValueEncoder{
35 byteOrder: byteOrder,
36 }
37 }
38
39 func (ve *ValueEncoder) encodeBytes(value []uint8) (ed EncodedData, err error) {
40 ed.Type = TypeByte
41 ed.Encoded = []byte(value)
42 ed.UnitCount = uint32(len(value))
43
44 return ed, nil
45 }
46
47 func (ve *ValueEncoder) encodeAscii(value string) (ed EncodedData, err error) {
48 ed.Type = TypeAscii
49
50 ed.Encoded = []byte(value)
51 ed.Encoded = append(ed.Encoded, 0)
52
53 ed.UnitCount = uint32(len(ed.Encoded))
54
55 return ed, nil
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 func (ve *ValueEncoder) encodeAsciiNoNul(value string) (ed EncodedData, err error) {
72 ed.Type = TypeAsciiNoNul
73 ed.Encoded = []byte(value)
74 ed.UnitCount = uint32(len(ed.Encoded))
75
76 return ed, nil
77 }
78
79 func (ve *ValueEncoder) encodeShorts(value []uint16) (ed EncodedData, err error) {
80 defer func() {
81 if state := recover(); state != nil {
82 err = log.Wrap(state.(error))
83 }
84 }()
85
86 ed.UnitCount = uint32(len(value))
87 ed.Encoded = make([]byte, ed.UnitCount*2)
88
89 for i := uint32(0); i < ed.UnitCount; i++ {
90 ve.byteOrder.PutUint16(ed.Encoded[i*2:(i+1)*2], value[i])
91 }
92
93 ed.Type = TypeShort
94
95 return ed, nil
96 }
97
98 func (ve *ValueEncoder) encodeLongs(value []uint32) (ed EncodedData, err error) {
99 defer func() {
100 if state := recover(); state != nil {
101 err = log.Wrap(state.(error))
102 }
103 }()
104
105 ed.UnitCount = uint32(len(value))
106 ed.Encoded = make([]byte, ed.UnitCount*4)
107
108 for i := uint32(0); i < ed.UnitCount; i++ {
109 ve.byteOrder.PutUint32(ed.Encoded[i*4:(i+1)*4], value[i])
110 }
111
112 ed.Type = TypeLong
113
114 return ed, nil
115 }
116
117 func (ve *ValueEncoder) encodeFloats(value []float32) (ed EncodedData, err error) {
118 defer func() {
119 if state := recover(); state != nil {
120 err = log.Wrap(state.(error))
121 }
122 }()
123
124 ed.UnitCount = uint32(len(value))
125 ed.Encoded = make([]byte, ed.UnitCount*4)
126
127 for i := uint32(0); i < ed.UnitCount; i++ {
128 ve.byteOrder.PutUint32(ed.Encoded[i*4:(i+1)*4], math.Float32bits(value[i]))
129 }
130
131 ed.Type = TypeFloat
132
133 return ed, nil
134 }
135
136 func (ve *ValueEncoder) encodeDoubles(value []float64) (ed EncodedData, err error) {
137 defer func() {
138 if state := recover(); state != nil {
139 err = log.Wrap(state.(error))
140 }
141 }()
142
143 ed.UnitCount = uint32(len(value))
144 ed.Encoded = make([]byte, ed.UnitCount*8)
145
146 for i := uint32(0); i < ed.UnitCount; i++ {
147 ve.byteOrder.PutUint64(ed.Encoded[i*8:(i+1)*8], math.Float64bits(value[i]))
148 }
149
150 ed.Type = TypeDouble
151
152 return ed, nil
153 }
154
155 func (ve *ValueEncoder) encodeRationals(value []Rational) (ed EncodedData, err error) {
156 defer func() {
157 if state := recover(); state != nil {
158 err = log.Wrap(state.(error))
159 }
160 }()
161
162 ed.UnitCount = uint32(len(value))
163 ed.Encoded = make([]byte, ed.UnitCount*8)
164
165 for i := uint32(0); i < ed.UnitCount; i++ {
166 ve.byteOrder.PutUint32(ed.Encoded[i*8+0:i*8+4], value[i].Numerator)
167 ve.byteOrder.PutUint32(ed.Encoded[i*8+4:i*8+8], value[i].Denominator)
168 }
169
170 ed.Type = TypeRational
171
172 return ed, nil
173 }
174
175 func (ve *ValueEncoder) encodeSignedLongs(value []int32) (ed EncodedData, err error) {
176 defer func() {
177 if state := recover(); state != nil {
178 err = log.Wrap(state.(error))
179 }
180 }()
181
182 ed.UnitCount = uint32(len(value))
183
184 b := bytes.NewBuffer(make([]byte, 0, 8*ed.UnitCount))
185
186 for i := uint32(0); i < ed.UnitCount; i++ {
187 err := binary.Write(b, ve.byteOrder, value[i])
188 log.PanicIf(err)
189 }
190
191 ed.Type = TypeSignedLong
192 ed.Encoded = b.Bytes()
193
194 return ed, nil
195 }
196
197 func (ve *ValueEncoder) encodeSignedRationals(value []SignedRational) (ed EncodedData, err error) {
198 defer func() {
199 if state := recover(); state != nil {
200 err = log.Wrap(state.(error))
201 }
202 }()
203
204 ed.UnitCount = uint32(len(value))
205
206 b := bytes.NewBuffer(make([]byte, 0, 8*ed.UnitCount))
207
208 for i := uint32(0); i < ed.UnitCount; i++ {
209 err := binary.Write(b, ve.byteOrder, value[i].Numerator)
210 log.PanicIf(err)
211
212 err = binary.Write(b, ve.byteOrder, value[i].Denominator)
213 log.PanicIf(err)
214 }
215
216 ed.Type = TypeSignedRational
217 ed.Encoded = b.Bytes()
218
219 return ed, nil
220 }
221
222
223
224
225 func (ve *ValueEncoder) Encode(value interface{}) (ed EncodedData, err error) {
226 defer func() {
227 if state := recover(); state != nil {
228 err = log.Wrap(state.(error))
229 }
230 }()
231
232 switch t := value.(type) {
233 case []byte:
234 ed, err = ve.encodeBytes(t)
235 log.PanicIf(err)
236 case string:
237 ed, err = ve.encodeAscii(t)
238 log.PanicIf(err)
239 case []uint16:
240 ed, err = ve.encodeShorts(t)
241 log.PanicIf(err)
242 case []uint32:
243 ed, err = ve.encodeLongs(t)
244 log.PanicIf(err)
245 case []float32:
246 ed, err = ve.encodeFloats(t)
247 log.PanicIf(err)
248 case []float64:
249 ed, err = ve.encodeDoubles(t)
250 log.PanicIf(err)
251 case []Rational:
252 ed, err = ve.encodeRationals(t)
253 log.PanicIf(err)
254 case []int32:
255 ed, err = ve.encodeSignedLongs(t)
256 log.PanicIf(err)
257 case []SignedRational:
258 ed, err = ve.encodeSignedRationals(t)
259 log.PanicIf(err)
260 case time.Time:
261
262
263
264 s := ExifFullTimestampString(t)
265
266 ed, err = ve.encodeAscii(s)
267 log.PanicIf(err)
268 default:
269 log.Panicf("value not encodable: [%s] [%v]", reflect.TypeOf(value), value)
270 }
271
272 return ed, nil
273 }
274
View as plain text