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

saitoha / libsixel / 20208829175

14 Dec 2025 11:18AM UTC coverage: 43.574% (-7.0%) from 50.557%
20208829175

push

github

saitoha
wic: add wic_sources to src/probe.c

11725 of 42140 branches covered (27.82%)

16506 of 37880 relevant lines covered (43.57%)

3210498.67 hits per line

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

2.29
/src/pixelformat.c
1
/*
2
 * SPDX-License-Identifier: MIT
3
 *
4
 * Copyright (c) 2021-2025 libsixel developers. See `AUTHORS`.
5
 * Copyright (c) 2014-2019 Hayaki Saito
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8
 * this software and associated documentation files (the "Software"), to deal in
9
 * the Software without restriction, including without limitation the rights to
10
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
 * the Software, and to permit persons to whom the Software is furnished to do so,
12
 * subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in all
15
 * copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 */
24

25
#include "config.h"
26

27
/* STDC_HEADERS */
28
#include <stdio.h>
29
#include <stdlib.h>
30

31
#if HAVE_MATH_H
32
# include <math.h>
33
#endif  /* HAVE_MATH_H */
34

35
#if HAVE_MEMORY_H
36
# include <memory.h>
37
#endif  /* HAVE_MEMORY_H */
38

39
#include <sixel.h>
40

41
#include "pixelformat.h"
42

43
#define SIXEL_OKLAB_AB_FLOAT_MIN (-0.5f)
44
#define SIXEL_OKLAB_AB_FLOAT_MAX (0.5f)
45
#define SIXEL_CIELAB_AB_FLOAT_MIN (-1.5f)
46
#define SIXEL_CIELAB_AB_FLOAT_MAX (1.5f)
47
#define SIXEL_CIELAB_L_FLOAT_MIN  (0.0f)
48
#define SIXEL_CIELAB_L_FLOAT_MAX  (1.0f)
49
#define SIXEL_DIN99D_L_FLOAT_MIN  (0.0f)
50
#define SIXEL_DIN99D_L_FLOAT_MAX  (1.0f)
51
#define SIXEL_DIN99D_AB_FLOAT_MIN (-1.0f)
52
#define SIXEL_DIN99D_AB_FLOAT_MAX (1.0f)
53
#define SIXEL_YUV_Y_FLOAT_MIN     (0.0f)
54
#define SIXEL_YUV_Y_FLOAT_MAX     (1.0f)
55
#define SIXEL_YUV_U_FLOAT_MIN     (-0.436f)
56
#define SIXEL_YUV_U_FLOAT_MAX     (0.436f)
57
#define SIXEL_YUV_V_FLOAT_MIN     (-0.615f)
58
#define SIXEL_YUV_V_FLOAT_MAX     (0.615f)
59

60
/*
61
 * Normalize a float32 channel stored in the 0.0-1.0 range and convert
62
 * the value to an 8-bit sample. Out-of-range or NaN inputs are clamped
63
 * to sane defaults so downstream conversions always receive valid bytes.
64
 */
65
static unsigned char
66
sixel_pixelformat_float_to_byte(float value)
×
67
{
68
#if HAVE_MATH_H
69
    if (!isfinite(value)) {
×
70
        value = 0.0f;
71
    }
72
#endif  /* HAVE_MATH_H */
73

74
    if (value <= 0.0f) {
×
75
        return 0;
76
    }
77
    if (value >= 1.0f) {
×
78
        return 255;
79
    }
80

81
    return (unsigned char)(value * 255.0f + 0.5f);
×
82
}
83

84
static unsigned char
85
sixel_pixelformat_oklab_L_to_byte(float value)
×
86
{
87
#if HAVE_MATH_H
88
    if (!isfinite(value)) {
×
89
        value = 0.0f;
90
    }
91
#endif  /* HAVE_MATH_H */
92

93
    if (value <= 0.0f) {
×
94
        return 0;
95
    }
96
    if (value >= 1.0f) {
×
97
        return 255;
98
    }
99

100
    return (unsigned char)(value * 255.0f + 0.5f);
×
101
}
102

103
static unsigned char
104
sixel_pixelformat_oklab_ab_to_byte(float value)
×
105
{
106
    float encoded;
×
107

108
#if HAVE_MATH_H
109
    if (!isfinite(value)) {
×
110
        value = 0.0f;
111
    }
112
#endif  /* HAVE_MATH_H */
113

114
    encoded = value + 0.5f;
×
115
    if (encoded <= 0.0f) {
×
116
        return 0;
117
    }
118
    if (encoded >= 1.0f) {
×
119
        return 255;
120
    }
121

122
    return (unsigned char)(encoded * 255.0f + 0.5f);
×
123
}
124

125
static unsigned char
126
sixel_pixelformat_cielab_L_to_byte(float value)
×
127
{
128
#if HAVE_MATH_H
129
    if (!isfinite(value)) {
×
130
        value = 0.0f;
131
    }
132
#endif  /* HAVE_MATH_H */
133

134
    if (value <= 0.0f) {
×
135
        return 0;
136
    }
137
    if (value >= 1.0f) {
×
138
        return 255;
139
    }
140

141
    return (unsigned char)(value * 255.0f + 0.5f);
×
142
}
143

144
static unsigned char
145
sixel_pixelformat_cielab_ab_to_byte(float value)
×
146
{
147
    float encoded;
×
148

149
#if HAVE_MATH_H
150
    if (!isfinite(value)) {
×
151
        value = 0.0f;
×
152
    }
153
#endif  /* HAVE_MATH_H */
154

155
    encoded = (value / (2.0f * SIXEL_CIELAB_AB_FLOAT_MAX)) + 0.5f;
×
156
    if (encoded <= 0.0f) {
×
157
        return 0;
158
    }
159
    if (encoded >= 1.0f) {
×
160
        return 255;
161
    }
162

163
    return (unsigned char)(encoded * 255.0f + 0.5f);
×
164
}
165

166
static unsigned char
167
sixel_pixelformat_din99d_L_to_byte(float value)
×
168
{
169
#if HAVE_MATH_H
170
    if (!isfinite(value)) {
×
171
        value = 0.0f;
172
    }
173
#endif  /* HAVE_MATH_H */
174

175
    if (value <= 0.0f) {
×
176
        return 0;
177
    }
178
    if (value >= 1.0f) {
×
179
        return 255;
180
    }
181

182
    return (unsigned char)(value * 255.0f + 0.5f);
×
183
}
184

185
static unsigned char
186
sixel_pixelformat_din99d_ab_to_byte(float value)
×
187
{
188
    float encoded;
×
189

190
#if HAVE_MATH_H
191
    if (!isfinite(value)) {
×
192
        value = 0.0f;
×
193
    }
194
#endif  /* HAVE_MATH_H */
195

196
    encoded = (value / (2.0f * SIXEL_DIN99D_AB_FLOAT_MAX)) + 0.5f;
×
197
    if (encoded <= 0.0f) {
×
198
        return 0;
199
    }
200
    if (encoded >= 1.0f) {
×
201
        return 255;
202
    }
203

204
    return (unsigned char)(encoded * 255.0f + 0.5f);
×
205
}
206

207
static unsigned char
208
sixel_pixelformat_yuv_chroma_to_byte(float value, float range)
×
209
{
210
    float encoded;
×
211

212
#if HAVE_MATH_H
213
    if (!isfinite(value)) {
×
214
        value = 0.0f;
×
215
    }
216
#endif  /* HAVE_MATH_H */
217

218
    encoded = (value / (2.0f * range)) + 0.5f;
×
219
    if (encoded <= 0.0f) {
×
220
        return 0;
221
    }
222
    if (encoded >= 1.0f) {
×
223
        return 255;
224
    }
225

226
    return (unsigned char)(encoded * 255.0f + 0.5f);
×
227
}
228

229
static float
230
sixel_pixelformat_yuv_chroma_from_byte(unsigned char value, float range)
×
231
{
232
    float encoded;
×
233

234
    encoded = (float)value / 255.0f;
×
235
    return (encoded - 0.5f) * (2.0f * range);
×
236
}
237

238
static float
239
sixel_pixelformat_float_channel_min_internal(int pixelformat,
×
240
                                             int channel)
241
{
242
    (void)channel;
×
243
    if (pixelformat == SIXEL_PIXELFORMAT_OKLABFLOAT32) {
×
244
        if (channel == 0) {
×
245
            return 0.0f;
246
        }
247
        return SIXEL_OKLAB_AB_FLOAT_MIN;
×
248
    }
249
    if (pixelformat == SIXEL_PIXELFORMAT_CIELABFLOAT32) {
×
250
        if (channel == 0) {
×
251
            return SIXEL_CIELAB_L_FLOAT_MIN;
252
        }
253
        return SIXEL_CIELAB_AB_FLOAT_MIN;
×
254
    }
255
    if (pixelformat == SIXEL_PIXELFORMAT_DIN99DFLOAT32) {
×
256
        if (channel == 0) {
×
257
            return SIXEL_DIN99D_L_FLOAT_MIN;
258
        }
259
        return SIXEL_DIN99D_AB_FLOAT_MIN;
×
260
    }
261
    if (pixelformat == SIXEL_PIXELFORMAT_YUVFLOAT32) {
×
262
        if (channel == 0) {
×
263
            return SIXEL_YUV_Y_FLOAT_MIN;
264
        }
265
        if (channel == 1) {
×
266
            return SIXEL_YUV_U_FLOAT_MIN;
267
        }
268
        return SIXEL_YUV_V_FLOAT_MIN;
×
269
    }
270
    return 0.0f;
271
}
272

273
static float
274
sixel_pixelformat_float_channel_max_internal(int pixelformat,
×
275
                                             int channel)
276
{
277
    (void)channel;
×
278
    if (pixelformat == SIXEL_PIXELFORMAT_OKLABFLOAT32) {
×
279
        if (channel == 0) {
×
280
            return 1.0f;
281
        }
282
        return SIXEL_OKLAB_AB_FLOAT_MAX;
×
283
    }
284
    if (pixelformat == SIXEL_PIXELFORMAT_CIELABFLOAT32) {
×
285
        if (channel == 0) {
×
286
            return SIXEL_CIELAB_L_FLOAT_MAX;
287
        }
288
        return SIXEL_CIELAB_AB_FLOAT_MAX;
×
289
    }
290
    if (pixelformat == SIXEL_PIXELFORMAT_DIN99DFLOAT32) {
×
291
        if (channel == 0) {
×
292
            return SIXEL_DIN99D_L_FLOAT_MAX;
293
        }
294
        return SIXEL_DIN99D_AB_FLOAT_MAX;
295
    }
296
    if (pixelformat == SIXEL_PIXELFORMAT_YUVFLOAT32) {
×
297
        if (channel == 0) {
×
298
            return SIXEL_YUV_Y_FLOAT_MAX;
299
        }
300
        if (channel == 1) {
×
301
            return SIXEL_YUV_U_FLOAT_MAX;
302
        }
303
        return SIXEL_YUV_V_FLOAT_MAX;
×
304
    }
305
    return 1.0f;
306
}
307

308
float
309
sixel_pixelformat_float_channel_clamp(int pixelformat,
×
310
                                      int channel,
311
                                      float value)
312
{
313
    float minimum;
×
314
    float maximum;
×
315

316
#if HAVE_MATH_H
317
    if (!isfinite(value)) {
×
318
        value = 0.0f;
×
319
    }
320
#endif  /* HAVE_MATH_H */
321

322
    minimum = sixel_pixelformat_float_channel_min_internal(pixelformat,
×
323
                                                           channel);
324
    maximum = sixel_pixelformat_float_channel_max_internal(pixelformat,
×
325
                                                           channel);
326
    if (value < minimum) {
×
327
        return minimum;
328
    }
329
    if (value > maximum) {
×
330
        return maximum;
331
    }
332

333
    return value;
334
}
335

336
unsigned char
337
sixel_pixelformat_float_channel_to_byte(int pixelformat,
×
338
                                        int channel,
339
                                        float value)
340
{
341
    float clamped;
×
342

343
    clamped = sixel_pixelformat_float_channel_clamp(pixelformat,
×
344
                                                    channel,
345
                                                    value);
346
    if (pixelformat == SIXEL_PIXELFORMAT_OKLABFLOAT32) {
×
347
        if (channel == 0) {
×
348
            return sixel_pixelformat_oklab_L_to_byte(clamped);
×
349
        }
350
        return sixel_pixelformat_oklab_ab_to_byte(clamped);
×
351
    }
352
    if (pixelformat == SIXEL_PIXELFORMAT_CIELABFLOAT32) {
×
353
        if (channel == 0) {
×
354
            return sixel_pixelformat_cielab_L_to_byte(clamped);
×
355
        }
356
        return sixel_pixelformat_cielab_ab_to_byte(clamped);
×
357
    }
358
    if (pixelformat == SIXEL_PIXELFORMAT_DIN99DFLOAT32) {
×
359
        if (channel == 0) {
×
360
            return sixel_pixelformat_din99d_L_to_byte(clamped);
×
361
        }
362
        return sixel_pixelformat_din99d_ab_to_byte(clamped);
×
363
    }
364
    if (pixelformat == SIXEL_PIXELFORMAT_YUVFLOAT32) {
×
365
        if (channel == 0) {
×
366
            return sixel_pixelformat_float_to_byte(clamped);
×
367
        }
368
        if (channel == 1) {
×
369
            return sixel_pixelformat_yuv_chroma_to_byte(
×
370
                clamped,
371
                SIXEL_YUV_U_FLOAT_MAX);
372
        }
373
        return sixel_pixelformat_yuv_chroma_to_byte(clamped,
×
374
                                                    SIXEL_YUV_V_FLOAT_MAX);
375
    }
376

377
    (void)channel;
×
378
    return sixel_pixelformat_float_to_byte(clamped);
×
379
}
380

381
float
382
sixel_pixelformat_byte_to_float(int pixelformat,
×
383
                                int channel,
384
                                unsigned char value)
385
{
386
    float decoded;
×
387

388
    if (pixelformat == SIXEL_PIXELFORMAT_OKLABFLOAT32) {
×
389
        if (channel == 0) {
×
390
            return (float)value / 255.0f;
×
391
        }
392
        decoded = (float)value / 255.0f;
×
393
        return decoded - 0.5f;
×
394
    }
395
    if (pixelformat == SIXEL_PIXELFORMAT_CIELABFLOAT32) {
×
396
        if (channel == 0) {
×
397
            return (float)value / 255.0f;
×
398
        }
399
        decoded = (float)value / 255.0f;
×
400
        decoded = (decoded - 0.5f)
×
401
                 * (2.0f * SIXEL_CIELAB_AB_FLOAT_MAX);
402
        return decoded;
×
403
    }
404
    if (pixelformat == SIXEL_PIXELFORMAT_DIN99DFLOAT32) {
×
405
        if (channel == 0) {
×
406
            return (float)value / 255.0f;
×
407
        }
408
        decoded = (float)value / 255.0f;
×
409
        decoded = (decoded - 0.5f)
×
410
                 * (2.0f * SIXEL_DIN99D_AB_FLOAT_MAX);
411
        return decoded;
×
412
    }
413
    if (pixelformat == SIXEL_PIXELFORMAT_YUVFLOAT32) {
×
414
        if (channel == 0) {
×
415
            return (float)value / 255.0f;
×
416
        }
417
        if (channel == 1) {
×
418
            return sixel_pixelformat_yuv_chroma_from_byte(
×
419
                value,
420
                SIXEL_YUV_U_FLOAT_MAX);
421
        }
422
        return sixel_pixelformat_yuv_chroma_from_byte(value,
×
423
                                                      SIXEL_YUV_V_FLOAT_MAX);
424
    }
425

426
    (void)channel;
×
427
    return (float)value / 255.0f;
×
428
}
429

430
static void
431
get_rgb(unsigned char const *data,
×
432
        int const pixelformat,
433
        int depth,
434
        unsigned char *r,
435
        unsigned char *g,
436
        unsigned char *b)
437
{
438
    unsigned int pixels = 0;
×
439
#if SWAP_BYTES
440
    unsigned int low;
441
    unsigned int high;
442
#endif
443
    int count = 0;
×
444

445
    if (pixelformat == SIXEL_PIXELFORMAT_RGBFLOAT32
×
446
            || pixelformat == SIXEL_PIXELFORMAT_LINEARRGBFLOAT32) {
×
447
        float const *fpixels = (float const *)(void const *)data;
×
448

449
        *r = sixel_pixelformat_float_to_byte(fpixels[0]);
×
450
        *g = sixel_pixelformat_float_to_byte(fpixels[1]);
×
451
        *b = sixel_pixelformat_float_to_byte(fpixels[2]);
×
452
        return;
×
453
    }
454
    if (pixelformat == SIXEL_PIXELFORMAT_OKLABFLOAT32) {
1!
455
        float const *fpixels = (float const *)(void const *)data;
×
456

457
        *r = sixel_pixelformat_oklab_L_to_byte(fpixels[0]);
×
458
        *g = sixel_pixelformat_oklab_ab_to_byte(fpixels[1]);
×
459
        *b = sixel_pixelformat_oklab_ab_to_byte(fpixels[2]);
×
460
        return;
×
461
    }
462
    if (pixelformat == SIXEL_PIXELFORMAT_CIELABFLOAT32) {
1!
463
        float const *fpixels = (float const *)(void const *)data;
×
464

465
        *r = sixel_pixelformat_cielab_L_to_byte(fpixels[0]);
×
466
        *g = sixel_pixelformat_cielab_ab_to_byte(fpixels[1]);
×
467
        *b = sixel_pixelformat_cielab_ab_to_byte(fpixels[2]);
×
468
        return;
×
469
    }
470
    if (pixelformat == SIXEL_PIXELFORMAT_DIN99DFLOAT32) {
1!
471
        float const *fpixels = (float const *)(void const *)data;
×
472

473
        *r = sixel_pixelformat_din99d_L_to_byte(fpixels[0]);
×
474
        *g = sixel_pixelformat_din99d_ab_to_byte(fpixels[1]);
×
475
        *b = sixel_pixelformat_din99d_ab_to_byte(fpixels[2]);
×
476
        return;
×
477
    }
478
    if (pixelformat == SIXEL_PIXELFORMAT_YUVFLOAT32) {
1!
479
        float const *fpixels = (float const *)(void const *)data;
×
480

481
        *r = sixel_pixelformat_float_to_byte(fpixels[0]);
×
482
        *g = sixel_pixelformat_yuv_chroma_to_byte(fpixels[1],
×
483
                                                  SIXEL_YUV_U_FLOAT_MAX);
484
        *b = sixel_pixelformat_yuv_chroma_to_byte(fpixels[2],
×
485
                                                  SIXEL_YUV_V_FLOAT_MAX);
486
        return;
×
487
    }
488

489
    while (count < depth) {
×
490
        pixels = *(data + count) | (pixels << 8);
×
491
        count++;
×
492
    }
493

494
    /* TODO: we should swap bytes (only necessary on LSByte first hardware?) */
495
#if SWAP_BYTES
496
    if (depth == 2) {
497
        low    = pixels & 0xff;
498
        high   = (pixels >> 8) & 0xff;
499
        pixels = (low << 8) | high;
500
    }
501
#endif
502

503
    switch (pixelformat) {
×
504
    case SIXEL_PIXELFORMAT_RGB555:
×
505
        *r = ((pixels >> 10) & 0x1f) << 3;
×
506
        *g = ((pixels >>  5) & 0x1f) << 3;
×
507
        *b = ((pixels >>  0) & 0x1f) << 3;
×
508
        break;
×
509
    case SIXEL_PIXELFORMAT_RGB565:
×
510
        *r = ((pixels >> 11) & 0x1f) << 3;
×
511
        *g = ((pixels >>  5) & 0x3f) << 2;
×
512
        *b = ((pixels >>  0) & 0x1f) << 3;
×
513
        break;
×
514
    case SIXEL_PIXELFORMAT_RGB888:
×
515
        *r = (pixels >> 16) & 0xff;
×
516
        *g = (pixels >>  8) & 0xff;
×
517
        *b = (pixels >>  0) & 0xff;
×
518
        break;
×
519
    case SIXEL_PIXELFORMAT_BGR555:
×
520
        *r = ((pixels >>  0) & 0x1f) << 3;
×
521
        *g = ((pixels >>  5) & 0x1f) << 3;
×
522
        *b = ((pixels >> 10) & 0x1f) << 3;
×
523
        break;
×
524
    case SIXEL_PIXELFORMAT_BGR565:
×
525
        *r = ((pixels >>  0) & 0x1f) << 3;
×
526
        *g = ((pixels >>  5) & 0x3f) << 2;
×
527
        *b = ((pixels >> 11) & 0x1f) << 3;
×
528
        break;
×
529
    case SIXEL_PIXELFORMAT_BGR888:
×
530
        *r = (pixels >>  0) & 0xff;
×
531
        *g = (pixels >>  8) & 0xff;
×
532
        *b = (pixels >> 16) & 0xff;
×
533
        break;
×
534
    case SIXEL_PIXELFORMAT_RGBA8888:
×
535
        *r = (pixels >> 24) & 0xff;
×
536
        *g = (pixels >> 16) & 0xff;
×
537
        *b = (pixels >>  8) & 0xff;
×
538
        break;
×
539
    case SIXEL_PIXELFORMAT_ARGB8888:
×
540
        *r = (pixels >> 16) & 0xff;
×
541
        *g = (pixels >>  8) & 0xff;
×
542
        *b = (pixels >>  0) & 0xff;
×
543
        break;
×
544
    case SIXEL_PIXELFORMAT_BGRA8888:
×
545
        *r = (pixels >>  8) & 0xff;
×
546
        *g = (pixels >> 16) & 0xff;
×
547
        *b = (pixels >> 24) & 0xff;
×
548
        break;
×
549
    case SIXEL_PIXELFORMAT_ABGR8888:
×
550
        *r = (pixels >>  0) & 0xff;
×
551
        *g = (pixels >>  8) & 0xff;
×
552
        *b = (pixels >> 16) & 0xff;
×
553
        break;
×
554
    case SIXEL_PIXELFORMAT_GA88:
×
555
        *r = *g = *b = (pixels >> 8) & 0xff;
×
556
        break;
×
557
    case SIXEL_PIXELFORMAT_G8:
×
558
    case SIXEL_PIXELFORMAT_AG88:
559
        *r = *g = *b = pixels & 0xff;
×
560
        break;
×
561
    default:
×
562
        *r = *g = *b = 0;
×
563
        break;
×
564
    }
565
}
1!
566

567

568
SIXELAPI int
569
sixel_helper_compute_depth(int pixelformat)
2,283✔
570
{
571
    int depth = (-1);  /* unknown */
2,283✔
572

573
    switch (pixelformat) {
2,283!
574
    case SIXEL_PIXELFORMAT_ARGB8888:
×
575
    case SIXEL_PIXELFORMAT_RGBA8888:
576
    case SIXEL_PIXELFORMAT_ABGR8888:
577
    case SIXEL_PIXELFORMAT_BGRA8888:
578
        depth = 4;
×
579
        break;
×
580
    case SIXEL_PIXELFORMAT_RGB888:
1,572✔
581
    case SIXEL_PIXELFORMAT_BGR888:
582
        depth = 3;
1,572✔
583
        break;
1,572✔
584
    case SIXEL_PIXELFORMAT_RGB555:
×
585
    case SIXEL_PIXELFORMAT_RGB565:
586
    case SIXEL_PIXELFORMAT_BGR555:
587
    case SIXEL_PIXELFORMAT_BGR565:
588
    case SIXEL_PIXELFORMAT_AG88:
589
    case SIXEL_PIXELFORMAT_GA88:
590
        depth = 2;
×
591
        break;
×
592
    case SIXEL_PIXELFORMAT_G1:
231✔
593
    case SIXEL_PIXELFORMAT_G2:
594
    case SIXEL_PIXELFORMAT_G4:
595
    case SIXEL_PIXELFORMAT_G8:
596
    case SIXEL_PIXELFORMAT_PAL1:
597
    case SIXEL_PIXELFORMAT_PAL2:
598
    case SIXEL_PIXELFORMAT_PAL4:
599
    case SIXEL_PIXELFORMAT_PAL8:
600
        depth = 1;
231✔
601
        break;
231✔
602
    case SIXEL_PIXELFORMAT_RGBFLOAT32:
480✔
603
    case SIXEL_PIXELFORMAT_LINEARRGBFLOAT32:
604
    case SIXEL_PIXELFORMAT_OKLABFLOAT32:
605
    case SIXEL_PIXELFORMAT_CIELABFLOAT32:
606
    case SIXEL_PIXELFORMAT_DIN99DFLOAT32:
607
    case SIXEL_PIXELFORMAT_YUVFLOAT32:
608
        depth = (int)(sizeof(float) * 3);
480✔
609
        break;
480✔
610
    default:
611
        break;
612
    }
613

614
    return depth;
2,283✔
615
}
616

617

618
static void
619
expand_rgb(unsigned char *dst,
×
620
           unsigned char const *src,
621
           int width, int height,
622
           int pixelformat, int depth)
623
{
624
    int x;
×
625
    int y;
×
626
    int dst_offset;
×
627
    int src_offset;
×
628
    unsigned char r, g, b;
×
629

630
    for (y = 0; y < height; y++) {
×
631
        for (x = 0; x < width; x++) {
×
632
            src_offset = depth * (y * width + x);
×
633
            dst_offset = 3 * (y * width + x);
×
634
            get_rgb(src + src_offset, pixelformat, depth, &r, &g, &b);
×
635

636
            *(dst + dst_offset + 0) = r;
×
637
            *(dst + dst_offset + 1) = g;
×
638
            *(dst + dst_offset + 2) = b;
×
639
        }
640
    }
641
}
×
642

643

644
static SIXELSTATUS
645
expand_palette(unsigned char *dst, unsigned char const *src,
×
646
               int width, int height, int const pixelformat)
647
{
648
    SIXELSTATUS status = SIXEL_FALSE;
×
649
    int x;
×
650
    int y;
×
651
    int i;
×
652
    int bpp;  /* bit per plane */
×
653

654
    switch (pixelformat) {
×
655
    case SIXEL_PIXELFORMAT_PAL1:
656
    case SIXEL_PIXELFORMAT_G1:
657
        bpp = 1;
658
        break;
659
    case SIXEL_PIXELFORMAT_PAL2:
×
660
    case SIXEL_PIXELFORMAT_G2:
661
        bpp = 2;
×
662
        break;
×
663
    case SIXEL_PIXELFORMAT_PAL4:
×
664
    case SIXEL_PIXELFORMAT_G4:
665
        bpp = 4;
×
666
        break;
×
667
    case SIXEL_PIXELFORMAT_PAL8:
668
    case SIXEL_PIXELFORMAT_G8:
669
        for (i = 0; i < width * height; ++i, ++src) {
×
670
            *dst++ = *src;
×
671
        }
672
        status = SIXEL_OK;
×
673
        goto end;
×
674
    default:
×
675
        status = SIXEL_BAD_ARGUMENT;
×
676
        sixel_helper_set_additional_message(
×
677
            "expand_palette: invalid pixelformat.");
678
        goto end;
×
679
    }
680

681
#if HAVE_DEBUG
682
    fprintf(stderr, "expanding PAL%d to PAL8...\n", bpp);
×
683
#endif
684

685
    for (y = 0; y < height; ++y) {
×
686
        for (x = 0; x < width * bpp / 8; ++x) {
×
687
            for (i = 0; i < 8 / bpp; ++i) {
×
688
                *dst++ = *src >> (8 / bpp - 1 - i) * bpp & ((1 << bpp) - 1);
×
689
            }
690
            src++;
×
691
        }
692
        x = width - x * 8 / bpp;
×
693
        if (x > 0) {
×
694
            for (i = 0; i < x; ++i) {
×
695
                *dst++ = *src >> (8 - (i + 1) * bpp) & ((1 << bpp) - 1);
×
696
            }
697
            src++;
×
698
        }
699
    }
700

701
    status = SIXEL_OK;
702

703
end:
×
704
    return status;
×
705
}
706

707

708
SIXELAPI SIXELSTATUS
709
sixel_helper_normalize_pixelformat(
×
710
    unsigned char       /* out */ *dst,             /* destination buffer */
711
    int                 /* out */ *dst_pixelformat, /* converted pixelformat */
712
    unsigned char const /* in */  *src,             /* source pixels */
713
    int                 /* in */  src_pixelformat,  /* format of source image */
714
    int                 /* in */  width,            /* width of source image */
715
    int                 /* in */  height)           /* height of source image */
716
{
717
    SIXELSTATUS status = SIXEL_FALSE;
×
718
    int depth;
×
719

720
    switch (src_pixelformat) {
×
721
    case SIXEL_PIXELFORMAT_G8:
×
722
        expand_rgb(dst, src, width, height, src_pixelformat, 1);
×
723
        *dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
724
        break;
×
725
    case SIXEL_PIXELFORMAT_RGB565:
×
726
    case SIXEL_PIXELFORMAT_RGB555:
727
    case SIXEL_PIXELFORMAT_BGR565:
728
    case SIXEL_PIXELFORMAT_BGR555:
729
    case SIXEL_PIXELFORMAT_GA88:
730
    case SIXEL_PIXELFORMAT_AG88:
731
        expand_rgb(dst, src, width, height, src_pixelformat, 2);
×
732
        *dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
733
        break;
×
734
    case SIXEL_PIXELFORMAT_RGB888:
×
735
    case SIXEL_PIXELFORMAT_BGR888:
736
        expand_rgb(dst, src, width, height, src_pixelformat, 3);
×
737
        *dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
738
        break;
×
739
    case SIXEL_PIXELFORMAT_RGBFLOAT32:
×
740
    case SIXEL_PIXELFORMAT_LINEARRGBFLOAT32:
741
    case SIXEL_PIXELFORMAT_OKLABFLOAT32:
742
    case SIXEL_PIXELFORMAT_CIELABFLOAT32:
743
    case SIXEL_PIXELFORMAT_DIN99DFLOAT32:
744
        depth = sixel_helper_compute_depth(src_pixelformat);
×
745
        if (depth <= 0) {
×
746
            status = SIXEL_BAD_ARGUMENT;
×
747
            goto end;
×
748
        }
749
        expand_rgb(dst, src, width, height, src_pixelformat, depth);
×
750
        *dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
751
        break;
×
752
    case SIXEL_PIXELFORMAT_RGBA8888:
×
753
    case SIXEL_PIXELFORMAT_ARGB8888:
754
    case SIXEL_PIXELFORMAT_BGRA8888:
755
    case SIXEL_PIXELFORMAT_ABGR8888:
756
        expand_rgb(dst, src, width, height, src_pixelformat, 4);
×
757
        *dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
758
        break;
×
759
    case SIXEL_PIXELFORMAT_PAL1:
×
760
    case SIXEL_PIXELFORMAT_PAL2:
761
    case SIXEL_PIXELFORMAT_PAL4:
762
        *dst_pixelformat = SIXEL_PIXELFORMAT_PAL8;
×
763
        status = expand_palette(dst, src, width, height, src_pixelformat);
×
764
        if (SIXEL_FAILED(status)) {
×
765
            goto end;
×
766
        }
767
        break;
768
    case SIXEL_PIXELFORMAT_G1:
×
769
    case SIXEL_PIXELFORMAT_G2:
770
    case SIXEL_PIXELFORMAT_G4:
771
        *dst_pixelformat = SIXEL_PIXELFORMAT_G8;
×
772
        status = expand_palette(dst, src, width, height, src_pixelformat);
×
773
        if (SIXEL_FAILED(status)) {
×
774
            goto end;
×
775
        }
776
        break;
777
    case SIXEL_PIXELFORMAT_PAL8:
×
778
        memcpy(dst, src, (size_t)(width * height));
×
779
        *dst_pixelformat = src_pixelformat;
×
780
        break;
×
781
    default:
×
782
        status = SIXEL_BAD_ARGUMENT;
×
783
        goto end;
×
784
    }
785

786
    status = SIXEL_OK;
787

788
end:
×
789
    return status;
×
790
}
791

792

793
/* Normalize RGB888 input without modification. */
794
#if HAVE_TESTS
795
static int
796
pixelformat_test_rgb888_passthrough(void)
×
797
{
798
    unsigned char dst[3];
×
799
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
800
    int src_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
801
    unsigned char src[] = { 0x46, 0xf3, 0xe5 };
×
802
    int ret = 0;
×
803

804
    int nret = EXIT_FAILURE;
×
805

806
    ret = sixel_helper_normalize_pixelformat(dst,
×
807
                                             &dst_pixelformat,
808
                                             src,
809
                                             src_pixelformat,
810
                                             1,
811
                                             1);
812
    if (ret != 0) {
×
813
        goto error;
×
814
    }
815
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
816
        goto error;
×
817
    }
818
    if ((dst[0] << 16 | dst[1] << 8 | dst[2])
×
819
            != (src[0] << 16 | src[1] << 8 | src[2])) {
×
820
        goto error;
×
821
    }
822
    return EXIT_SUCCESS;
823

824
error:
×
825
    perror("pixelformat_test_rgb888_passthrough");
×
826
    return nret;
×
827
}
828

829

830
/* Convert RGB555 packed data into RGB888 output. */
831
static int
832
pixelformat_test_from_rgb555(void)
×
833
{
834
    unsigned char dst[3];
×
835
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
836
    int src_pixelformat = SIXEL_PIXELFORMAT_RGB555;
×
837
    unsigned char src[] = { 0x47, 0x9c };
×
838
    int ret = 0;
×
839

840
    int nret = EXIT_FAILURE;
×
841

842
    ret = sixel_helper_normalize_pixelformat(dst,
×
843
                                             &dst_pixelformat,
844
                                             src,
845
                                             src_pixelformat,
846
                                             1,
847
                                             1);
848
    if (ret != 0) {
×
849
        goto error;
×
850
    }
851
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
852
        goto error;
×
853
    }
854
    if ((dst[0] >> 3 << 10 | dst[1] >> 3 << 5 | dst[2] >> 3)
×
855
            != (src[0] << 8 | src[1])) {
×
856
        goto error;
×
857
    }
858
    return EXIT_SUCCESS;
859

860
error:
×
861
    perror("pixelformat_test_from_rgb555");
×
862
    return nret;
×
863
}
864

865

866
/* Convert RGB565 packed data into RGB888 output. */
867
static int
868
pixelformat_test_from_rgb565(void)
×
869
{
870
    unsigned char dst[3];
×
871
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
872
    int src_pixelformat = SIXEL_PIXELFORMAT_RGB565;
×
873
    unsigned char src[] = { 0x47, 0x9c };
×
874
    int ret = 0;
×
875

876
    int nret = EXIT_FAILURE;
×
877

878
    ret = sixel_helper_normalize_pixelformat(dst,
×
879
                                             &dst_pixelformat,
880
                                             src,
881
                                             src_pixelformat,
882
                                             1,
883
                                             1);
884
    if (ret != 0) {
×
885
        goto error;
×
886
    }
887
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
888
        goto error;
×
889
    }
890
    if ((dst[0] >> 3 << 11 | dst[1] >> 2 << 5 | dst[2] >> 3)
×
891
            != (src[0] << 8 | src[1])) {
×
892
        goto error;
×
893
    }
894
    return EXIT_SUCCESS;
895

896
error:
×
897
    perror("pixelformat_test_from_rgb565");
×
898
    return nret;
×
899
}
900

901

902
/* Swap channels from BGR888 to RGB888. */
903
static int
904
pixelformat_test_from_bgr888(void)
×
905
{
906
    unsigned char dst[3];
×
907
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
908
    int src_pixelformat = SIXEL_PIXELFORMAT_BGR888;
×
909
    unsigned char src[] = { 0x46, 0xf3, 0xe5 };
×
910
    int ret = 0;
×
911

912
    int nret = EXIT_FAILURE;
×
913

914
    ret = sixel_helper_normalize_pixelformat(dst,
×
915
                                             &dst_pixelformat,
916
                                             src,
917
                                             src_pixelformat,
918
                                             1,
919
                                             1);
920
    if (ret != 0) {
×
921
        goto error;
×
922
    }
923
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
924
        goto error;
×
925
    }
926
    if ((dst[2] << 16 | dst[1] << 8 | dst[0])
×
927
            != (src[0] << 16 | src[1] << 8 | src[2])) {
×
928
        goto error;
×
929
    }
930
    return EXIT_SUCCESS;
931

932
error:
×
933
    perror("pixelformat_test_from_bgr888");
×
934
    return nret;
×
935
}
936

937

938
/* Convert BGR555 packed data into RGB888 output. */
939
static int
940
pixelformat_test_from_bgr555(void)
×
941
{
942
    unsigned char dst[3];
×
943
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
944
    int src_pixelformat = SIXEL_PIXELFORMAT_BGR555;
×
945
    unsigned char src[] = { 0x23, 0xc8 };
×
946
    int ret = 0;
×
947

948
    int nret = EXIT_FAILURE;
×
949

950
    ret = sixel_helper_normalize_pixelformat(dst,
×
951
                                             &dst_pixelformat,
952
                                             src,
953
                                             src_pixelformat,
954
                                             1,
955
                                             1);
956
    if (ret != 0) {
×
957
        goto error;
×
958
    }
959
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
960
        goto error;
×
961
    }
962
    if ((dst[2] >> 3 << 10 | dst[1] >> 3 << 5 | dst[0] >> 3)
×
963
            != (src[0] << 8 | src[1])) {
×
964
        goto error;
×
965
    }
966
    return EXIT_SUCCESS;
967

968
error:
×
969
    perror("pixelformat_test_from_bgr555");
×
970
    return nret;
×
971
}
972

973

974
/* Convert BGR565 packed data into RGB888 output. */
975
static int
976
pixelformat_test_from_bgr565(void)
×
977
{
978
    unsigned char dst[3];
×
979
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
980
    int src_pixelformat = SIXEL_PIXELFORMAT_BGR565;
×
981
    unsigned char src[] = { 0x47, 0x88 };
×
982
    int ret = 0;
×
983

984
    int nret = EXIT_FAILURE;
×
985

986
    ret = sixel_helper_normalize_pixelformat(dst,
×
987
                                             &dst_pixelformat,
988
                                             src,
989
                                             src_pixelformat,
990
                                             1,
991
                                             1);
992
    if (ret != 0) {
×
993
        goto error;
×
994
    }
995
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
996
        goto error;
×
997
    }
998
    if ((dst[2] >> 3 << 11 | dst[1] >> 2 << 5 | dst[0] >> 3)
×
999
            != (src[0] << 8 | src[1])) {
×
1000
        goto error;
×
1001
    }
1002
    return EXIT_SUCCESS;
1003

1004
error:
×
1005
    perror("pixelformat_test_from_bgr565");
×
1006
    return nret;
×
1007
}
1008

1009

1010
/* Convert AG88 data by discarding alpha and keeping gray. */
1011
static int
1012
pixelformat_test_from_ag88(void)
×
1013
{
1014
    unsigned char dst[3];
×
1015
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
1016
    int src_pixelformat = SIXEL_PIXELFORMAT_AG88;
×
1017
    unsigned char src[] = { 0x47, 0x88 };
×
1018
    int ret = 0;
×
1019

1020
    int nret = EXIT_FAILURE;
×
1021

1022
    ret = sixel_helper_normalize_pixelformat(dst,
×
1023
                                             &dst_pixelformat,
1024
                                             src,
1025
                                             src_pixelformat,
1026
                                             1,
1027
                                             1);
1028
    if (ret != 0) {
×
1029
        goto error;
×
1030
    }
1031
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
1032
        goto error;
×
1033
    }
1034
    if (dst[0] != src[1]) {
×
1035
        goto error;
×
1036
    }
1037
    return EXIT_SUCCESS;
1038

1039
error:
×
1040
    perror("pixelformat_test_from_ag88");
×
1041
    return nret;
×
1042
}
1043

1044

1045
/* Convert GA88 data by duplicating gray channel into RGB. */
1046
static int
1047
pixelformat_test_from_ga88(void)
×
1048
{
1049
    unsigned char dst[3];
×
1050
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
1051
    int src_pixelformat = SIXEL_PIXELFORMAT_GA88;
×
1052
    unsigned char src[] = { 0x47, 0x88 };
×
1053
    int ret = 0;
×
1054

1055
    int nret = EXIT_FAILURE;
×
1056

1057
    ret = sixel_helper_normalize_pixelformat(dst,
×
1058
                                             &dst_pixelformat,
1059
                                             src,
1060
                                             src_pixelformat,
1061
                                             1,
1062
                                             1);
1063
    if (ret != 0) {
×
1064
        goto error;
×
1065
    }
1066
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
1067
        goto error;
×
1068
    }
1069
    if (dst[0] != src[0]) {
×
1070
        goto error;
×
1071
    }
1072
    return EXIT_SUCCESS;
1073

1074
error:
×
1075
    perror("pixelformat_test_from_ga88");
×
1076
    return nret;
×
1077
}
1078

1079

1080
/* Normalize RGBA8888 by dropping alpha. */
1081
static int
1082
pixelformat_test_from_rgba8888(void)
×
1083
{
1084
    unsigned char dst[3];
×
1085
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
1086
    int src_pixelformat = SIXEL_PIXELFORMAT_RGBA8888;
×
1087
    unsigned char src[] = { 0x46, 0xf3, 0xe5, 0xf0 };
×
1088
    int ret = 0;
×
1089

1090
    int nret = EXIT_FAILURE;
×
1091

1092
    ret = sixel_helper_normalize_pixelformat(dst,
×
1093
                                             &dst_pixelformat,
1094
                                             src,
1095
                                             src_pixelformat,
1096
                                             1,
1097
                                             1);
1098
    if (ret != 0) {
×
1099
        goto error;
×
1100
    }
1101
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
1102
        goto error;
×
1103
    }
1104
    if (dst[0] != src[0]) {
×
1105
        goto error;
×
1106
    }
1107
    if (dst[1] != src[1]) {
×
1108
        goto error;
×
1109
    }
1110
    if (dst[2] != src[2]) {
×
1111
        goto error;
×
1112
    }
1113
    return EXIT_SUCCESS;
1114

1115
error:
×
1116
    perror("pixelformat_test_from_rgba8888");
×
1117
    return nret;
×
1118
}
1119

1120

1121
/* Normalize ARGB8888 while skipping the leading alpha byte. */
1122
static int
1123
pixelformat_test_from_argb8888(void)
×
1124
{
1125
    unsigned char dst[3];
×
1126
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
1127
    int src_pixelformat = SIXEL_PIXELFORMAT_ARGB8888;
×
1128
    unsigned char src[] = { 0x46, 0xf3, 0xe5, 0xf0 };
×
1129
    int ret = 0;
×
1130

1131
    int nret = EXIT_FAILURE;
×
1132

1133
    ret = sixel_helper_normalize_pixelformat(dst,
×
1134
                                             &dst_pixelformat,
1135
                                             src,
1136
                                             src_pixelformat,
1137
                                             1,
1138
                                             1);
1139
    if (ret != 0) {
×
1140
        goto error;
×
1141
    }
1142
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
1143
        goto error;
×
1144
    }
1145
    if (dst[0] != src[1]) {
×
1146
        goto error;
×
1147
    }
1148
    if (dst[1] != src[2]) {
×
1149
        goto error;
×
1150
    }
1151
    if (dst[2] != src[3]) {
×
1152
        goto error;
×
1153
    }
1154
    return EXIT_SUCCESS;
1155

1156
error:
×
1157
    perror("pixelformat_test_from_argb8888");
×
1158
    return nret;
×
1159
}
1160

1161

1162
/* Convert floating point RGB data to normalized 8-bit output. */
1163
static int
1164
pixelformat_test_from_rgbfloat32(void)
×
1165
{
1166
    unsigned char dst[3];
×
1167
    int dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
×
1168
    int src_pixelformat = SIXEL_PIXELFORMAT_RGBFLOAT32;
×
1169
    float srcf[] = { 0.0f, 0.5f, 1.0f };
×
1170
    unsigned char const *src = (unsigned char const *)srcf;
×
1171
    int ret = 0;
×
1172
    int depth;
×
1173

1174
    int nret = EXIT_FAILURE;
×
1175

1176
    ret = sixel_helper_normalize_pixelformat(dst,
×
1177
                                             &dst_pixelformat,
1178
                                             src,
1179
                                             src_pixelformat,
1180
                                             1,
1181
                                             1);
1182
    if (ret != 0) {
×
1183
        goto error;
×
1184
    }
1185
    if (dst_pixelformat != SIXEL_PIXELFORMAT_RGB888) {
×
1186
        goto error;
×
1187
    }
1188
    if (dst[0] != 0 || dst[1] != 128 || dst[2] != 255) {
×
1189
        goto error;
×
1190
    }
1191
    depth = sixel_helper_compute_depth(src_pixelformat);
×
1192
    if (depth != (int)(sizeof(float) * 3)) {
×
1193
        goto error;
×
1194
    }
1195
    return EXIT_SUCCESS;
1196

1197
error:
×
1198
    perror("pixelformat_test_from_rgbfloat32");
×
1199
    return nret;
×
1200
}
1201

1202

1203
SIXELAPI int
1204
sixel_pixelformat_tests_main(void)
×
1205
{
1206
    int nret = EXIT_FAILURE;
×
1207
    size_t i;
×
1208
    typedef int (* testcase)(void);
×
1209

1210
    static testcase const testcases[] = {
×
1211
        pixelformat_test_rgb888_passthrough,
1212
        pixelformat_test_from_rgb555,
1213
        pixelformat_test_from_rgb565,
1214
        pixelformat_test_from_bgr888,
1215
        pixelformat_test_from_bgr555,
1216
        pixelformat_test_from_bgr565,
1217
        pixelformat_test_from_ag88,
1218
        pixelformat_test_from_ga88,
1219
        pixelformat_test_from_rgba8888,
1220
        pixelformat_test_from_argb8888,
1221
        pixelformat_test_from_rgbfloat32,
1222
    };
1223

1224
    for (i = 0; i < sizeof(testcases) / sizeof(testcase); ++i) {
×
1225
        nret = testcases[i]();
×
1226
        if (nret != EXIT_SUCCESS) {
×
1227
            goto error;
×
1228
        }
1229
    }
1230

1231
    nret = EXIT_SUCCESS;
1232

1233
error:
×
1234
    return nret;
×
1235
}
1236
#endif  /* HAVE_TESTS */
1237

1238
/* emacs Local Variables:      */
1239
/* emacs mode: c               */
1240
/* emacs tab-width: 4          */
1241
/* emacs indent-tabs-mode: nil */
1242
/* emacs c-basic-offset: 4     */
1243
/* emacs End:                  */
1244
/* vim: set expandtab ts=4 sts=4 sw=4 : */
1245
/* EOF */
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