• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

qmuntal / gltf / 10632933835

30 Aug 2024 12:46PM UTC coverage: 91.286% (-0.1%) from 91.412%
10632933835

Pull #90

github

qmuntal
fix castSlice
Pull Request #90: Reduce modeler.Read helpers allocations

26 of 76 new or added lines in 1 file covered. (34.21%)

1 existing line in 1 file now uncovered.

2556 of 2800 relevant lines covered (91.29%)

63.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.62
/binary/slice.go
1
package binary
2

3
import (
4
        "fmt"
5
        "image/color"
6
        "reflect"
7
        "unsafe"
8

9
        "github.com/qmuntal/gltf"
10
)
11

12
func reslice[T any](v []byte, length, rem int) []T {
24✔
13
        var ptr unsafe.Pointer
24✔
14
        if len(v) != 0 {
48✔
15
                ptr = unsafe.Pointer(&v[0])
24✔
16
        }
24✔
17
        s := unsafe.Slice((*T)(unsafe.Pointer(ptr)), length)
24✔
18
        if rem > 0 {
30✔
19
                return append(s, make([]T, rem)...)
6✔
20
        }
6✔
21
        return s
18✔
22
}
23

24
func castSlice(c gltf.ComponentType, t gltf.AccessorType, count int, v []byte) any {
24✔
25
        l := len(v) / (c.ByteSize() * t.Components())
24✔
26
        var rem int
24✔
27
        if count < l {
36✔
28
                l = count
12✔
29
        } else if count > l {
30✔
30
                rem = count - l
6✔
31
        }
6✔
32

33
        switch c {
24✔
34
        case gltf.ComponentUbyte:
24✔
35
                switch t {
24✔
36
                case gltf.AccessorScalar:
×
NEW
37
                        return reslice[uint8](v, l, rem)
×
38
                case gltf.AccessorVec2:
24✔
39
                        return reslice[[2]uint8](v, l, rem)
24✔
40
                case gltf.AccessorVec3:
×
NEW
41
                        return reslice[[3]uint8](v, l, rem)
×
42
                case gltf.AccessorVec4:
×
NEW
43
                        return reslice[[4]uint8](v, l, rem)
×
44
                case gltf.AccessorMat2:
×
NEW
45
                        return reslice[[2][2]uint8](v, l, rem)
×
46
                case gltf.AccessorMat3:
×
NEW
47
                        return reslice[[3][3]uint8](v, l, rem)
×
48
                case gltf.AccessorMat4:
×
NEW
49
                        return reslice[[4][4]uint8](v, l, rem)
×
50
                }
51
        case gltf.ComponentByte:
×
52
                switch t {
×
53
                case gltf.AccessorScalar:
×
NEW
54
                        return reslice[int8](v, l, rem)
×
55
                case gltf.AccessorVec2:
×
NEW
56
                        return reslice[[2]int8](v, l, rem)
×
57
                case gltf.AccessorVec3:
×
NEW
58
                        return reslice[[3]int8](v, l, rem)
×
59
                case gltf.AccessorVec4:
×
NEW
60
                        return reslice[[4]int8](v, l, rem)
×
61
                case gltf.AccessorMat2:
×
NEW
62
                        return reslice[[2][2]int8](v, l, rem)
×
63
                case gltf.AccessorMat3:
×
NEW
64
                        return reslice[[3][3]int8](v, l, rem)
×
65
                case gltf.AccessorMat4:
×
NEW
66
                        return reslice[[4][4]int8](v, l, rem)
×
67
                }
68
        case gltf.ComponentUshort:
×
69
                switch t {
×
70
                case gltf.AccessorScalar:
×
NEW
71
                        return reslice[uint16](v, l, rem)
×
72
                case gltf.AccessorVec2:
×
NEW
73
                        return reslice[[2]uint16](v, l, rem)
×
74
                case gltf.AccessorVec3:
×
NEW
75
                        return reslice[[3]uint16](v, l, rem)
×
76
                case gltf.AccessorVec4:
×
NEW
77
                        return reslice[[4]uint16](v, l, rem)
×
78
                case gltf.AccessorMat2:
×
NEW
79
                        return reslice[[2][2]uint16](v, l, rem)
×
80
                case gltf.AccessorMat3:
×
NEW
81
                        return reslice[[3][3]uint16](v, l, rem)
×
82
                case gltf.AccessorMat4:
×
NEW
83
                        return reslice[[4][4]uint16](v, l, rem)
×
84
                }
85
        case gltf.ComponentShort:
×
86
                switch t {
×
87
                case gltf.AccessorScalar:
×
NEW
88
                        return reslice[int16](v, l, rem)
×
89
                case gltf.AccessorVec2:
×
NEW
90
                        return reslice[[2]int16](v, l, rem)
×
91
                case gltf.AccessorVec3:
×
NEW
92
                        return reslice[[3]int16](v, l, rem)
×
93
                case gltf.AccessorVec4:
×
NEW
94
                        return reslice[[4]int16](v, l, rem)
×
95
                case gltf.AccessorMat2:
×
NEW
96
                        return reslice[[2][2]int16](v, l, rem)
×
97
                case gltf.AccessorMat3:
×
NEW
98
                        return reslice[[3][3]int16](v, l, rem)
×
99
                case gltf.AccessorMat4:
×
NEW
100
                        return reslice[[4][4]int16](v, l, rem)
×
101
                }
102
        case gltf.ComponentUint:
×
103
                switch t {
×
104
                case gltf.AccessorScalar:
×
NEW
105
                        return reslice[uint32](v, l, rem)
×
106
                case gltf.AccessorVec2:
×
NEW
107
                        return reslice[[2]uint32](v, l, rem)
×
108
                case gltf.AccessorVec3:
×
NEW
109
                        return reslice[[3]uint32](v, l, rem)
×
110
                case gltf.AccessorVec4:
×
NEW
111
                        return reslice[[4]uint32](v, l, rem)
×
112
                case gltf.AccessorMat2:
×
NEW
113
                        return reslice[[2][2]uint32](v, l, rem)
×
114
                case gltf.AccessorMat3:
×
115

116
                case gltf.AccessorMat4:
×
NEW
117
                        return reslice[[4][4]uint32](v, l, rem)
×
118
                }
119
        case gltf.ComponentFloat:
×
120
                switch t {
×
121
                case gltf.AccessorScalar:
×
NEW
122
                        return reslice[float32](v, l, rem)
×
123
                case gltf.AccessorVec2:
×
NEW
124
                        return reslice[[2]float32](v, l, rem)
×
125
                case gltf.AccessorVec3:
×
NEW
126
                        return reslice[[3]float32](v, l, rem)
×
127
                case gltf.AccessorVec4:
×
NEW
128
                        return reslice[[4]float32](v, l, rem)
×
129
                case gltf.AccessorMat2:
×
NEW
130
                        return reslice[[2][2]float32](v, l, rem)
×
131
                case gltf.AccessorMat3:
×
NEW
132
                        return reslice[[3][3]float32](v, l, rem)
×
133
                case gltf.AccessorMat4:
×
NEW
134
                        return reslice[[4][4]float32](v, l, rem)
×
135
                }
136
        }
NEW
137
        panic(fmt.Errorf("gltf: unsupported component type %d or accessor type %d", c, t))
×
138
}
139

140
// MakeSliceBuffer returns the slice type associated with c and t and with the given element count.
141
// If the buffer is an slice which type matches with the expected by the acr then it will
142
// be used as backing slice.
143
func MakeSliceBuffer(c gltf.ComponentType, t gltf.AccessorType, count int, buffer []byte) (any, error) {
36✔
144
        if err := checkAccessorType(c, t); err != nil {
36✔
NEW
145
                return nil, err
×
UNCOV
146
        }
×
147
        buffer = buffer[:cap(buffer)] // Extend the slice to its capacity.
36✔
148
        if len(buffer) == 0 {
48✔
149
                return MakeSlice(c, t, count)
12✔
150
        }
12✔
151
        return castSlice(c, t, count, buffer), nil
24✔
152
}
153

154
// MakeSlice returns the slice type associated with c and t and with the given element count.
155
// For example, if c is gltf.ComponentFloat and t is gltf.AccessorVec3
156
// then MakeSlice(c, t, 5) is equivalent to make([][3]float32, 5).
157
func MakeSlice(c gltf.ComponentType, t gltf.AccessorType, count int) (any, error) {
264✔
158
        if err := checkAccessorType(c, t); err != nil {
264✔
NEW
159
                return nil, err
×
NEW
160
        }
×
161
        var tp reflect.Type
264✔
162
        switch c {
264✔
163
        case gltf.ComponentUbyte:
54✔
164
                tp = reflect.TypeOf((*uint8)(nil))
54✔
165
        case gltf.ComponentByte:
42✔
166
                tp = reflect.TypeOf((*int8)(nil))
42✔
167
        case gltf.ComponentUshort:
42✔
168
                tp = reflect.TypeOf((*uint16)(nil))
42✔
169
        case gltf.ComponentShort:
42✔
170
                tp = reflect.TypeOf((*int16)(nil))
42✔
171
        case gltf.ComponentUint:
42✔
172
                tp = reflect.TypeOf((*uint32)(nil))
42✔
173
        case gltf.ComponentFloat:
42✔
174
                tp = reflect.TypeOf((*float32)(nil))
42✔
175
        default:
×
NEW
176
                panic(fmt.Errorf("gltf: unsupported component type %d", c))
×
177
        }
178
        tp = tp.Elem()
264✔
179
        switch t {
264✔
180
        case gltf.AccessorScalar:
36✔
181
                // Nothing to do.
182
        case gltf.AccessorVec2:
48✔
183
                tp = reflect.ArrayOf(2, tp)
48✔
184
        case gltf.AccessorVec3:
36✔
185
                tp = reflect.ArrayOf(3, tp)
36✔
186
        case gltf.AccessorVec4:
36✔
187
                tp = reflect.ArrayOf(4, tp)
36✔
188
        case gltf.AccessorMat2:
36✔
189
                tp = reflect.ArrayOf(2, reflect.ArrayOf(2, tp))
36✔
190
        case gltf.AccessorMat3:
36✔
191
                tp = reflect.ArrayOf(3, reflect.ArrayOf(3, tp))
36✔
192
        case gltf.AccessorMat4:
36✔
193
                tp = reflect.ArrayOf(4, reflect.ArrayOf(4, tp))
36✔
194
        default:
×
NEW
195
                panic(fmt.Errorf("gltf: unsupported accessor type %d", t))
×
196
        }
197
        return reflect.MakeSlice(reflect.SliceOf(tp), count, count).Interface(), nil
264✔
198
}
199

200
// Type returns the associated glTF type data.
201
// It panics if data is not an slice.
202
func Type(data any) (c gltf.ComponentType, t gltf.AccessorType, count int) {
648✔
203
        v := reflect.ValueOf(data)
648✔
204
        if v.Kind() != reflect.Slice {
648✔
205
                panic(fmt.Sprintf("gltf: binary.Type expecting a slice but got %s", v.Kind()))
×
206
        }
207
        count = v.Len()
648✔
208
        switch data.(type) {
648✔
209
        case []int8:
48✔
210
                c, t = gltf.ComponentByte, gltf.AccessorScalar
48✔
211
        case [][2]int8:
12✔
212
                c, t = gltf.ComponentByte, gltf.AccessorVec2
12✔
213
        case [][3]int8:
12✔
214
                c, t = gltf.ComponentByte, gltf.AccessorVec3
12✔
215
        case [][4]int8:
12✔
216
                c, t = gltf.ComponentByte, gltf.AccessorVec4
12✔
217
        case [][2][2]int8:
12✔
218
                c, t = gltf.ComponentByte, gltf.AccessorMat2
12✔
219
        case [][3][3]int8:
12✔
220
                c, t = gltf.ComponentByte, gltf.AccessorMat3
12✔
221
        case [][4][4]int8:
12✔
222
                c, t = gltf.ComponentByte, gltf.AccessorMat4
12✔
223
        case []uint8:
36✔
224
                c, t = gltf.ComponentUbyte, gltf.AccessorScalar
36✔
225
        case [][2]uint8:
12✔
226
                c, t = gltf.ComponentUbyte, gltf.AccessorVec2
12✔
227
        case [][3]uint8:
12✔
228
                c, t = gltf.ComponentUbyte, gltf.AccessorVec3
12✔
229
        case []color.RGBA, [][4]uint8:
24✔
230
                c, t = gltf.ComponentUbyte, gltf.AccessorVec4
24✔
231
        case [][2][2]uint8:
12✔
232
                c, t = gltf.ComponentUbyte, gltf.AccessorMat2
12✔
233
        case [][3][3]uint8:
12✔
234
                c, t = gltf.ComponentUbyte, gltf.AccessorMat3
12✔
235
        case [][4][4]uint8:
12✔
236
                c, t = gltf.ComponentUbyte, gltf.AccessorMat4
12✔
237
        case []int16:
24✔
238
                c, t = gltf.ComponentShort, gltf.AccessorScalar
24✔
239
        case [][2]int16:
12✔
240
                c, t = gltf.ComponentShort, gltf.AccessorVec2
12✔
241
        case [][3]int16:
12✔
242
                c, t = gltf.ComponentShort, gltf.AccessorVec3
12✔
243
        case [][4]int16:
12✔
244
                c, t = gltf.ComponentShort, gltf.AccessorVec4
12✔
245
        case [][2][2]int16:
12✔
246
                c, t = gltf.ComponentShort, gltf.AccessorMat2
12✔
247
        case [][3][3]int16:
12✔
248
                c, t = gltf.ComponentShort, gltf.AccessorMat3
12✔
249
        case [][4][4]int16:
12✔
250
                c, t = gltf.ComponentShort, gltf.AccessorMat4
12✔
251
        case []uint16:
24✔
252
                c, t = gltf.ComponentUshort, gltf.AccessorScalar
24✔
253
        case [][2]uint16:
12✔
254
                c, t = gltf.ComponentUshort, gltf.AccessorVec2
12✔
255
        case [][3]uint16:
12✔
256
                c, t = gltf.ComponentUshort, gltf.AccessorVec3
12✔
257
        case []color.RGBA64, [][4]uint16:
24✔
258
                c, t = gltf.ComponentUshort, gltf.AccessorVec4
24✔
259
        case [][2][2]uint16:
12✔
260
                c, t = gltf.ComponentUshort, gltf.AccessorMat2
12✔
261
        case [][3][3]uint16:
12✔
262
                c, t = gltf.ComponentUshort, gltf.AccessorMat3
12✔
263
        case [][4][4]uint16:
12✔
264
                c, t = gltf.ComponentUshort, gltf.AccessorMat4
12✔
265
        case []uint32:
24✔
266
                c, t = gltf.ComponentUint, gltf.AccessorScalar
24✔
267
        case [][2]uint32:
12✔
268
                c, t = gltf.ComponentUint, gltf.AccessorVec2
12✔
269
        case [][3]uint32:
12✔
270
                c, t = gltf.ComponentUint, gltf.AccessorVec3
12✔
271
        case [][4]uint32:
12✔
272
                c, t = gltf.ComponentUint, gltf.AccessorVec4
12✔
273
        case [][2][2]uint32:
12✔
274
                c, t = gltf.ComponentUint, gltf.AccessorMat2
12✔
275
        case [][3][3]uint32:
12✔
276
                c, t = gltf.ComponentUint, gltf.AccessorMat3
12✔
277
        case [][4][4]uint32:
12✔
278
                c, t = gltf.ComponentUint, gltf.AccessorMat4
12✔
279
        case []float32:
24✔
280
                c, t = gltf.ComponentFloat, gltf.AccessorScalar
24✔
281
        case [][2]float32:
12✔
282
                c, t = gltf.ComponentFloat, gltf.AccessorVec2
12✔
283
        case [][3]float32:
24✔
284
                c, t = gltf.ComponentFloat, gltf.AccessorVec3
24✔
285
        case [][4]float32:
12✔
286
                c, t = gltf.ComponentFloat, gltf.AccessorVec4
12✔
287
        case [][2][2]float32:
12✔
288
                c, t = gltf.ComponentFloat, gltf.AccessorMat2
12✔
289
        case [][3][3]float32:
12✔
290
                c, t = gltf.ComponentFloat, gltf.AccessorMat3
12✔
291
        case [][4][4]float32:
12✔
292
                c, t = gltf.ComponentFloat, gltf.AccessorMat4
12✔
293
        default:
×
294
                panic(fmt.Sprintf("gltf: binary.Type expecting a glTF supported type but got %s", v.Kind()))
×
295
        }
296
        return
648✔
297
}
298

299
func checkAccessorType(c gltf.ComponentType, t gltf.AccessorType) error {
300✔
300
        switch c {
300✔
301
        case gltf.ComponentUbyte, gltf.ComponentByte, gltf.ComponentUshort,
302
                gltf.ComponentShort, gltf.ComponentUint, gltf.ComponentFloat:
300✔
NEW
303
        default:
×
NEW
304
                return fmt.Errorf("gltf: unsupported component type %d", c)
×
305
        }
306
        switch t {
300✔
307
        case gltf.AccessorScalar, gltf.AccessorVec2, gltf.AccessorVec3,
308
                gltf.AccessorVec4, gltf.AccessorMat2, gltf.AccessorMat3, gltf.AccessorMat4:
300✔
NEW
309
        default:
×
NEW
310
                return fmt.Errorf("gltf: unsupported accessor type %d", t)
×
311
        }
312
        return nil
300✔
313
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc