1 // After editing this file, run "go generate" in the parent directory.
2 
3 // Copyright 2017 The Wuffs Authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //    https://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 static inline wuffs_base__empty_struct  //
wuffs_base__ignore_status(wuffs_base__status z)18 wuffs_base__ignore_status(wuffs_base__status z) {
19   return wuffs_base__make_empty_struct();
20 }
21 
22 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
23 // It's not foolproof, given C doesn't automatically zero memory before use,
24 // but it should catch 99.99% of cases.
25 //
26 // Its (non-zero) value is arbitrary, based on md5sum("wuffs").
27 #define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
28 
29 // WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
30 // error was previously encountered.
31 //
32 // Its (non-zero) value is arbitrary, based on md5sum("disabled").
33 #define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
34 
35 // Denote intentional fallthroughs for -Wimplicit-fallthrough.
36 //
37 // The order matters here. Clang also defines "__GNUC__".
38 #if defined(__clang__) && defined(__cplusplus) && (__cplusplus >= 201103L)
39 #define WUFFS_BASE__FALLTHROUGH [[clang::fallthrough]]
40 #elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 7)
41 #define WUFFS_BASE__FALLTHROUGH __attribute__((fallthrough))
42 #else
43 #define WUFFS_BASE__FALLTHROUGH
44 #endif
45 
46 // Use switch cases for coroutine suspension points, similar to the technique
47 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
48 //
49 // We use trivial macros instead of an explicit assignment and case statement
50 // so that clang-format doesn't get confused by the unusual "case"s.
51 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
52 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
53   coro_susp_point = n;                            \
54   WUFFS_BASE__FALLTHROUGH;                        \
55   case n:;
56 
57 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
58   if (!status) {                                                \
59     goto ok;                                                    \
60   } else if (*status != '$') {                                  \
61     goto exit;                                                  \
62   }                                                             \
63   coro_susp_point = n;                                          \
64   goto suspend;                                                 \
65   case n:;
66 
67 // Clang also defines "__GNUC__".
68 #if defined(__GNUC__)
69 #define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
70 #define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
71 #else
72 #define WUFFS_BASE__LIKELY(expr) (expr)
73 #define WUFFS_BASE__UNLIKELY(expr) (expr)
74 #endif
75 
76 // The helpers below are functions, instead of macros, because their arguments
77 // can be an expression that we shouldn't evaluate more than once.
78 //
79 // They are static, so that linking multiple wuffs .o files won't complain about
80 // duplicate function definitions.
81 //
82 // They are explicitly marked inline, even if modern compilers don't use the
83 // inline attribute to guide optimizations such as inlining, to avoid the
84 // -Wunused-function warning, and we like to compile with -Wall -Werror.
85 
86 // ---------------- Numeric Types
87 
88 static inline uint8_t  //
wuffs_base__load_u8be(uint8_t * p)89 wuffs_base__load_u8be(uint8_t* p) {
90   return p[0];
91 }
92 
93 static inline uint16_t  //
wuffs_base__load_u16be(uint8_t * p)94 wuffs_base__load_u16be(uint8_t* p) {
95   return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
96 }
97 
98 static inline uint16_t  //
wuffs_base__load_u16le(uint8_t * p)99 wuffs_base__load_u16le(uint8_t* p) {
100   return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
101 }
102 
103 static inline uint32_t  //
wuffs_base__load_u24be(uint8_t * p)104 wuffs_base__load_u24be(uint8_t* p) {
105   return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
106          ((uint32_t)(p[2]) << 0);
107 }
108 
109 static inline uint32_t  //
wuffs_base__load_u24le(uint8_t * p)110 wuffs_base__load_u24le(uint8_t* p) {
111   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
112          ((uint32_t)(p[2]) << 16);
113 }
114 
115 static inline uint32_t  //
wuffs_base__load_u32be(uint8_t * p)116 wuffs_base__load_u32be(uint8_t* p) {
117   return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
118          ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
119 }
120 
121 static inline uint32_t  //
wuffs_base__load_u32le(uint8_t * p)122 wuffs_base__load_u32le(uint8_t* p) {
123   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
124          ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
125 }
126 
127 static inline uint64_t  //
wuffs_base__load_u40be(uint8_t * p)128 wuffs_base__load_u40be(uint8_t* p) {
129   return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
130          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
131          ((uint64_t)(p[4]) << 0);
132 }
133 
134 static inline uint64_t  //
wuffs_base__load_u40le(uint8_t * p)135 wuffs_base__load_u40le(uint8_t* p) {
136   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
137          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
138          ((uint64_t)(p[4]) << 32);
139 }
140 
141 static inline uint64_t  //
wuffs_base__load_u48be(uint8_t * p)142 wuffs_base__load_u48be(uint8_t* p) {
143   return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
144          ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
145          ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
146 }
147 
148 static inline uint64_t  //
wuffs_base__load_u48le(uint8_t * p)149 wuffs_base__load_u48le(uint8_t* p) {
150   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
151          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
152          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
153 }
154 
155 static inline uint64_t  //
wuffs_base__load_u56be(uint8_t * p)156 wuffs_base__load_u56be(uint8_t* p) {
157   return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
158          ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
159          ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
160          ((uint64_t)(p[6]) << 0);
161 }
162 
163 static inline uint64_t  //
wuffs_base__load_u56le(uint8_t * p)164 wuffs_base__load_u56le(uint8_t* p) {
165   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
166          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
167          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
168          ((uint64_t)(p[6]) << 48);
169 }
170 
171 static inline uint64_t  //
wuffs_base__load_u64be(uint8_t * p)172 wuffs_base__load_u64be(uint8_t* p) {
173   return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
174          ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
175          ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
176          ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
177 }
178 
179 static inline uint64_t  //
wuffs_base__load_u64le(uint8_t * p)180 wuffs_base__load_u64le(uint8_t* p) {
181   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
182          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
183          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
184          ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
185 }
186 
187 // --------
188 
189 static inline void  //
wuffs_base__store_u8be(uint8_t * p,uint8_t x)190 wuffs_base__store_u8be(uint8_t* p, uint8_t x) {
191   p[0] = x;
192 }
193 
194 static inline void  //
wuffs_base__store_u16be(uint8_t * p,uint16_t x)195 wuffs_base__store_u16be(uint8_t* p, uint16_t x) {
196   p[0] = (uint8_t)(x >> 8);
197   p[1] = (uint8_t)(x >> 0);
198 }
199 
200 static inline void  //
wuffs_base__store_u16le(uint8_t * p,uint16_t x)201 wuffs_base__store_u16le(uint8_t* p, uint16_t x) {
202   p[0] = (uint8_t)(x >> 0);
203   p[1] = (uint8_t)(x >> 8);
204 }
205 
206 static inline void  //
wuffs_base__store_u24be(uint8_t * p,uint32_t x)207 wuffs_base__store_u24be(uint8_t* p, uint32_t x) {
208   p[0] = (uint8_t)(x >> 16);
209   p[1] = (uint8_t)(x >> 8);
210   p[2] = (uint8_t)(x >> 0);
211 }
212 
213 static inline void  //
wuffs_base__store_u24le(uint8_t * p,uint32_t x)214 wuffs_base__store_u24le(uint8_t* p, uint32_t x) {
215   p[0] = (uint8_t)(x >> 0);
216   p[1] = (uint8_t)(x >> 8);
217   p[2] = (uint8_t)(x >> 16);
218 }
219 
220 static inline void  //
wuffs_base__store_u32be(uint8_t * p,uint32_t x)221 wuffs_base__store_u32be(uint8_t* p, uint32_t x) {
222   p[0] = (uint8_t)(x >> 24);
223   p[1] = (uint8_t)(x >> 16);
224   p[2] = (uint8_t)(x >> 8);
225   p[3] = (uint8_t)(x >> 0);
226 }
227 
228 static inline void  //
wuffs_base__store_u32le(uint8_t * p,uint32_t x)229 wuffs_base__store_u32le(uint8_t* p, uint32_t x) {
230   p[0] = (uint8_t)(x >> 0);
231   p[1] = (uint8_t)(x >> 8);
232   p[2] = (uint8_t)(x >> 16);
233   p[3] = (uint8_t)(x >> 24);
234 }
235 
236 static inline void  //
wuffs_base__store_u40be(uint8_t * p,uint64_t x)237 wuffs_base__store_u40be(uint8_t* p, uint64_t x) {
238   p[0] = (uint8_t)(x >> 32);
239   p[1] = (uint8_t)(x >> 24);
240   p[2] = (uint8_t)(x >> 16);
241   p[3] = (uint8_t)(x >> 8);
242   p[4] = (uint8_t)(x >> 0);
243 }
244 
245 static inline void  //
wuffs_base__store_u40le(uint8_t * p,uint64_t x)246 wuffs_base__store_u40le(uint8_t* p, uint64_t x) {
247   p[0] = (uint8_t)(x >> 0);
248   p[1] = (uint8_t)(x >> 8);
249   p[2] = (uint8_t)(x >> 16);
250   p[3] = (uint8_t)(x >> 24);
251   p[4] = (uint8_t)(x >> 32);
252 }
253 
254 static inline void  //
wuffs_base__store_u48be(uint8_t * p,uint64_t x)255 wuffs_base__store_u48be(uint8_t* p, uint64_t x) {
256   p[0] = (uint8_t)(x >> 40);
257   p[1] = (uint8_t)(x >> 32);
258   p[2] = (uint8_t)(x >> 24);
259   p[3] = (uint8_t)(x >> 16);
260   p[4] = (uint8_t)(x >> 8);
261   p[5] = (uint8_t)(x >> 0);
262 }
263 
264 static inline void  //
wuffs_base__store_u48le(uint8_t * p,uint64_t x)265 wuffs_base__store_u48le(uint8_t* p, uint64_t x) {
266   p[0] = (uint8_t)(x >> 0);
267   p[1] = (uint8_t)(x >> 8);
268   p[2] = (uint8_t)(x >> 16);
269   p[3] = (uint8_t)(x >> 24);
270   p[4] = (uint8_t)(x >> 32);
271   p[5] = (uint8_t)(x >> 40);
272 }
273 
274 static inline void  //
wuffs_base__store_u56be(uint8_t * p,uint64_t x)275 wuffs_base__store_u56be(uint8_t* p, uint64_t x) {
276   p[0] = (uint8_t)(x >> 48);
277   p[1] = (uint8_t)(x >> 40);
278   p[2] = (uint8_t)(x >> 32);
279   p[3] = (uint8_t)(x >> 24);
280   p[4] = (uint8_t)(x >> 16);
281   p[5] = (uint8_t)(x >> 8);
282   p[6] = (uint8_t)(x >> 0);
283 }
284 
285 static inline void  //
wuffs_base__store_u56le(uint8_t * p,uint64_t x)286 wuffs_base__store_u56le(uint8_t* p, uint64_t x) {
287   p[0] = (uint8_t)(x >> 0);
288   p[1] = (uint8_t)(x >> 8);
289   p[2] = (uint8_t)(x >> 16);
290   p[3] = (uint8_t)(x >> 24);
291   p[4] = (uint8_t)(x >> 32);
292   p[5] = (uint8_t)(x >> 40);
293   p[6] = (uint8_t)(x >> 48);
294 }
295 
296 static inline void  //
wuffs_base__store_u64be(uint8_t * p,uint64_t x)297 wuffs_base__store_u64be(uint8_t* p, uint64_t x) {
298   p[0] = (uint8_t)(x >> 56);
299   p[1] = (uint8_t)(x >> 48);
300   p[2] = (uint8_t)(x >> 40);
301   p[3] = (uint8_t)(x >> 32);
302   p[4] = (uint8_t)(x >> 24);
303   p[5] = (uint8_t)(x >> 16);
304   p[6] = (uint8_t)(x >> 8);
305   p[7] = (uint8_t)(x >> 0);
306 }
307 
308 static inline void  //
wuffs_base__store_u64le(uint8_t * p,uint64_t x)309 wuffs_base__store_u64le(uint8_t* p, uint64_t x) {
310   p[0] = (uint8_t)(x >> 0);
311   p[1] = (uint8_t)(x >> 8);
312   p[2] = (uint8_t)(x >> 16);
313   p[3] = (uint8_t)(x >> 24);
314   p[4] = (uint8_t)(x >> 32);
315   p[5] = (uint8_t)(x >> 40);
316   p[6] = (uint8_t)(x >> 48);
317   p[7] = (uint8_t)(x >> 56);
318 }
319 
320 // --------
321 
322 extern const uint8_t wuffs_base__low_bits_mask__u8[9];
323 extern const uint16_t wuffs_base__low_bits_mask__u16[17];
324 extern const uint32_t wuffs_base__low_bits_mask__u32[33];
325 extern const uint64_t wuffs_base__low_bits_mask__u64[65];
326 
327 #define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])
328 #define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])
329 #define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])
330 #define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])
331 
332 // --------
333 
334 static inline void  //
wuffs_base__u8__sat_add_indirect(uint8_t * x,uint8_t y)335 wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
336   *x = wuffs_base__u8__sat_add(*x, y);
337 }
338 
339 static inline void  //
wuffs_base__u8__sat_sub_indirect(uint8_t * x,uint8_t y)340 wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
341   *x = wuffs_base__u8__sat_sub(*x, y);
342 }
343 
344 static inline void  //
wuffs_base__u16__sat_add_indirect(uint16_t * x,uint16_t y)345 wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
346   *x = wuffs_base__u16__sat_add(*x, y);
347 }
348 
349 static inline void  //
wuffs_base__u16__sat_sub_indirect(uint16_t * x,uint16_t y)350 wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
351   *x = wuffs_base__u16__sat_sub(*x, y);
352 }
353 
354 static inline void  //
wuffs_base__u32__sat_add_indirect(uint32_t * x,uint32_t y)355 wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
356   *x = wuffs_base__u32__sat_add(*x, y);
357 }
358 
359 static inline void  //
wuffs_base__u32__sat_sub_indirect(uint32_t * x,uint32_t y)360 wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
361   *x = wuffs_base__u32__sat_sub(*x, y);
362 }
363 
364 static inline void  //
wuffs_base__u64__sat_add_indirect(uint64_t * x,uint64_t y)365 wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
366   *x = wuffs_base__u64__sat_add(*x, y);
367 }
368 
369 static inline void  //
wuffs_base__u64__sat_sub_indirect(uint64_t * x,uint64_t y)370 wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
371   *x = wuffs_base__u64__sat_sub(*x, y);
372 }
373 
374 // ---------------- Slices and Tables
375 
376 // wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s.
377 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s,uint64_t up_to)378 wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
379   if ((uint64_t)(s.len) > up_to) {
380     s.len = up_to;
381   }
382   return s;
383 }
384 
385 // wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s.
386 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s,uint64_t up_to)387 wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
388   if ((uint64_t)(s.len) > up_to) {
389     s.ptr += (uint64_t)(s.len) - up_to;
390     s.len = up_to;
391   }
392   return s;
393 }
394 
395 // wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len)
396 // where len is the minimum of dst.len and src.len.
397 //
398 // Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
399 // slice) is valid and results in a no-op.
400 static inline uint64_t  //
wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src)401 wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
402                                       wuffs_base__slice_u8 src) {
403   size_t len = dst.len < src.len ? dst.len : src.len;
404   if (len > 0) {
405     memmove(dst.ptr, src.ptr, len);
406   }
407   return len;
408 }
409 
410 // --------
411 
412 static inline wuffs_base__slice_u8  //
wuffs_base__table_u8__row(wuffs_base__table_u8 t,uint32_t y)413 wuffs_base__table_u8__row(wuffs_base__table_u8 t, uint32_t y) {
414   if (y < t.height) {
415     return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
416   }
417   return wuffs_base__make_slice_u8(NULL, 0);
418 }
419 
420 // ---------------- Slices and Tables (Utility)
421 
422 #define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8
423