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

saitoha / libsixel / 19389365033

15 Nov 2025 11:44AM UTC coverage: 43.379% (-0.4%) from 43.821%
19389365033

push

github

saitoha
palette: refactor palette helpers into dedicated modules

8474 of 27744 branches covered (30.54%)

44 of 650 new or added lines in 4 files covered. (6.77%)

106 existing lines in 9 files now uncovered.

11581 of 26697 relevant lines covered (43.38%)

973309.3 hits per line

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

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

22
#include "config.h"
23

24
#include <math.h>
25
#include <stddef.h>
26

27
#include <sixel.h>
28

29
#include "colorspace.h"
30

31
#define SIXEL_COLORSPACE_LUT_SIZE 256
32
#define SIXEL_OKLAB_AB_OFFSET 0.5
33
#define SIXEL_OKLAB_AB_SCALE  255.0
34

35
static const double sixel_linear_srgb_to_smptec_matrix[3][3] = {
36
    { 1.0651944799343782, -0.05539144537002962, -0.009975616485882548 },
37
    { -0.019633066659433226,  1.0363870284433383, -0.016731961783904975 },
38
    { 0.0016324889176928742,  0.004413466273704836,  0.994192644808602 }
39
};
40

41
static const double sixel_linear_smptec_to_srgb_matrix[3][3] = {
42
    { 0.9397048483892231,  0.05018036042570272,  0.010273409684415205 },
43
    { 0.01777536262173348, 0.9657705626655305,  0.01643197976410589 },
44
    { -0.0016219271954016755, -0.00436969856687614,  1.0057514450874723 }
45
};
46

47
static unsigned char gamma_to_linear_lut[SIXEL_COLORSPACE_LUT_SIZE];
48
static unsigned char linear_to_gamma_lut[SIXEL_COLORSPACE_LUT_SIZE];
49
static int tables_initialized = 0;
50

51
static inline double
52
sixel_clamp_unit(double value)
×
53
{
54
    if (value < 0.0) {
×
55
        return 0.0;
×
56
    }
57
    if (value > 1.0) {
×
58
        return 1.0;
×
59
    }
60
    return value;
×
61
}
62

63
static unsigned char
64
sixel_colorspace_clamp(int value)
×
65
{
66
    if (value < 0) {
×
67
        return 0;
×
68
    }
69
    if (value > 255) {
×
70
        return 255;
×
71
    }
72
    return (unsigned char)value;
×
73
}
74

75
static inline double
76
sixel_srgb_to_linear_double(unsigned char v)
×
77
{
78
    double x = (double)v / 255.0;
×
79

80
    if (x <= 0.04045) {
×
81
        return x / 12.92;
×
82
    }
83

84
    return pow((x + 0.055) / 1.055, 2.4);
×
85
}
86

87
static inline unsigned char
88
sixel_linear_double_to_srgb(double v)
×
89
{
90
    double y;
91

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

99
    if (v <= 0.0031308) {
×
100
        y = v * 12.92;
×
101
    } else {
102
        y = 1.055 * pow(v, 1.0 / 2.4) - 0.055;
×
103
    }
104

105
    return sixel_colorspace_clamp((int)(y * 255.0 + 0.5));
×
106
}
107

108
static inline unsigned char
109
sixel_linear_double_to_byte(double v)
×
110
{
111
    if (v <= 0.0) {
×
112
        return 0;
×
113
    }
114
    if (v >= 1.0) {
×
115
        return 255;
×
116
    }
117

118
    return sixel_colorspace_clamp((int)(v * 255.0 + 0.5));
×
119
}
120

121
static inline double
122
sixel_smptec_to_linear_double(unsigned char v)
×
123
{
124
    double x = (double)v / 255.0;
×
125

126
    if (x <= 0.0) {
×
127
        return 0.0;
×
128
    }
129
    if (x >= 1.0) {
×
130
        return 1.0;
×
131
    }
132

133
    return pow(x, 2.2);
×
134
}
135

136
static inline unsigned char
137
sixel_linear_double_to_smptec(double v)
×
138
{
139
    double y;
140

141
    if (v <= 0.0) {
×
142
        return 0;
×
143
    }
144
    if (v >= 1.0) {
×
145
        return 255;
×
146
    }
147

148
    y = pow(v, 1.0 / 2.2);
×
149
    return sixel_colorspace_clamp((int)(y * 255.0 + 0.5));
×
150
}
151

152
static inline unsigned char
153
sixel_oklab_encode_L(double L)
×
154
{
155
    if (L < 0.0) {
×
156
        L = 0.0;
×
157
    } else if (L > 1.0) {
×
158
        L = 1.0;
×
159
    }
160

161
    return sixel_colorspace_clamp((int)(L * 255.0 + 0.5));
×
162
}
163

164
static inline unsigned char
165
sixel_oklab_encode_ab(double value)
×
166
{
167
    double encoded = value + SIXEL_OKLAB_AB_OFFSET;
×
168

169
    if (encoded < 0.0) {
×
170
        encoded = 0.0;
×
171
    } else if (encoded > 1.0) {
×
172
        encoded = 1.0;
×
173
    }
174

175
    return sixel_colorspace_clamp((int)(encoded * SIXEL_OKLAB_AB_SCALE + 0.5));
×
176
}
177

178
static inline double
179
sixel_oklab_decode_ab(unsigned char v)
×
180
{
181
    return (double)v / SIXEL_OKLAB_AB_SCALE - SIXEL_OKLAB_AB_OFFSET;
×
182
}
183

184
static void
185
sixel_linear_to_oklab(double r, double g, double b,
×
186
                      double *L, double *A, double *B)
187
{
188
    double l;
189
    double m;
190
    double s;
191
    double l_;
192
    double m_;
193
    double s_;
194

195
    l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
×
196
    m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
×
197
    s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
×
198

199
    l_ = cbrt(l);
×
200
    m_ = cbrt(m);
×
201
    s_ = cbrt(s);
×
202

203
    *L = 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_;
×
204
    *A = 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_;
×
205
    *B = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_;
×
206
}
×
207

208
static void
209
sixel_oklab_to_linear(double L, double A, double B,
×
210
                      double *r, double *g, double *b)
211
{
212
    double l_;
213
    double m_;
214
    double s_;
215
    double l;
216
    double m;
217
    double s;
218

219
    l_ = L + 0.3963377774 * A + 0.2158037573 * B;
×
220
    m_ = L - 0.1055613458 * A - 0.0638541728 * B;
×
221
    s_ = L - 0.0894841775 * A - 1.2914855480 * B;
×
222

223
    l = l_ * l_ * l_;
×
224
    m = m_ * m_ * m_;
×
225
    s = s_ * s_ * s_;
×
226

227
    *r = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
×
228
    *g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
×
229
    *b = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s;
×
230

231
    if (*r < 0.0) {
×
232
        *r = 0.0;
×
233
    }
234
    if (*g < 0.0) {
×
235
        *g = 0.0;
×
236
    }
237
    if (*b < 0.0) {
×
238
        *b = 0.0;
×
239
    }
240
}
×
241

242
static void
243
sixel_linear_srgb_to_smptec(double r, double g, double b,
×
244
                            double *rs, double *gs, double *bs)
245
{
246
    double sr;
247
    double sg;
248
    double sb;
249

250
    sr = sixel_linear_srgb_to_smptec_matrix[0][0] * r
×
251
       + sixel_linear_srgb_to_smptec_matrix[0][1] * g
×
252
       + sixel_linear_srgb_to_smptec_matrix[0][2] * b;
×
253
    sg = sixel_linear_srgb_to_smptec_matrix[1][0] * r
×
254
       + sixel_linear_srgb_to_smptec_matrix[1][1] * g
×
255
       + sixel_linear_srgb_to_smptec_matrix[1][2] * b;
×
256
    sb = sixel_linear_srgb_to_smptec_matrix[2][0] * r
×
257
       + sixel_linear_srgb_to_smptec_matrix[2][1] * g
×
258
       + sixel_linear_srgb_to_smptec_matrix[2][2] * b;
×
259

260
    *rs = sixel_clamp_unit(sr);
×
261
    *gs = sixel_clamp_unit(sg);
×
262
    *bs = sixel_clamp_unit(sb);
×
263
}
×
264

265
static void
266
sixel_linear_smptec_to_srgb(double rs, double gs, double bs,
×
267
                            double *r, double *g, double *b)
268
{
269
    double r_lin;
270
    double g_lin;
271
    double b_lin;
272

273
    r_lin = sixel_linear_smptec_to_srgb_matrix[0][0] * rs
×
274
          + sixel_linear_smptec_to_srgb_matrix[0][1] * gs
×
275
          + sixel_linear_smptec_to_srgb_matrix[0][2] * bs;
×
276
    g_lin = sixel_linear_smptec_to_srgb_matrix[1][0] * rs
×
277
          + sixel_linear_smptec_to_srgb_matrix[1][1] * gs
×
278
          + sixel_linear_smptec_to_srgb_matrix[1][2] * bs;
×
279
    b_lin = sixel_linear_smptec_to_srgb_matrix[2][0] * rs
×
280
          + sixel_linear_smptec_to_srgb_matrix[2][1] * gs
×
281
          + sixel_linear_smptec_to_srgb_matrix[2][2] * bs;
×
282

283
    *r = sixel_clamp_unit(r_lin);
×
284
    *g = sixel_clamp_unit(g_lin);
×
285
    *b = sixel_clamp_unit(b_lin);
×
286
}
×
287

288
static void
289
sixel_colorspace_init_tables(void)
×
290
{
291
    int i;
292
    double gamma_value;
293
    double linear_value;
294
    double converted;
295

296
    if (tables_initialized) {
×
297
        return;
×
298
    }
299

300
    for (i = 0; i < SIXEL_COLORSPACE_LUT_SIZE; ++i) {
×
301
        gamma_value = (double)i / 255.0;
×
302
        if (gamma_value <= 0.04045) {
×
303
            converted = gamma_value / 12.92;
×
304
        } else {
305
            converted = pow((gamma_value + 0.055) / 1.055, 2.4);
×
306
        }
307
        gamma_to_linear_lut[i] =
×
308
            sixel_colorspace_clamp((int)(converted * 255.0 + 0.5));
×
309
    }
310

311
    for (i = 0; i < SIXEL_COLORSPACE_LUT_SIZE; ++i) {
×
312
        linear_value = (double)i / 255.0;
×
313
        if (linear_value <= 0.0031308) {
×
314
            converted = linear_value * 12.92;
×
315
        } else {
316
            converted = 1.055 * pow(linear_value, 1.0 / 2.4) - 0.055;
×
317
        }
318
        linear_to_gamma_lut[i] =
×
319
            sixel_colorspace_clamp((int)(converted * 255.0 + 0.5));
×
320
    }
321

322
    tables_initialized = 1;
×
323
}
324

325
static void
326
sixel_decode_linear_from_colorspace(int colorspace,
×
327
                                    unsigned char r8,
328
                                    unsigned char g8,
329
                                    unsigned char b8,
330
                                    double *r_lin,
331
                                    double *g_lin,
332
                                    double *b_lin)
333
{
334
    switch (colorspace) {
×
UNCOV
335
    case SIXEL_COLORSPACE_GAMMA:
×
336
        *r_lin = sixel_srgb_to_linear_double(r8);
×
337
        *g_lin = sixel_srgb_to_linear_double(g8);
×
338
        *b_lin = sixel_srgb_to_linear_double(b8);
×
339
        break;
×
UNCOV
340
    case SIXEL_COLORSPACE_LINEAR:
×
341
        *r_lin = (double)r8 / 255.0;
×
342
        *g_lin = (double)g8 / 255.0;
×
343
        *b_lin = (double)b8 / 255.0;
×
344
        break;
×
UNCOV
345
    case SIXEL_COLORSPACE_OKLAB:
×
346
    {
347
        double L = (double)r8 / 255.0;
×
348
        double A = sixel_oklab_decode_ab(g8);
×
349
        double B = sixel_oklab_decode_ab(b8);
×
350
        sixel_oklab_to_linear(L, A, B, r_lin, g_lin, b_lin);
×
351
        break;
×
352
    }
UNCOV
353
    case SIXEL_COLORSPACE_SMPTEC:
×
354
    {
355
        double r_smptec = sixel_smptec_to_linear_double(r8);
×
356
        double g_smptec = sixel_smptec_to_linear_double(g8);
×
357
        double b_smptec = sixel_smptec_to_linear_double(b8);
×
358
        sixel_linear_smptec_to_srgb(r_smptec, g_smptec, b_smptec,
×
359
                                    r_lin, g_lin, b_lin);
360
        break;
×
361
    }
UNCOV
362
    default:
×
363
        *r_lin = (double)r8 / 255.0;
×
364
        *g_lin = (double)g8 / 255.0;
×
365
        *b_lin = (double)b8 / 255.0;
×
366
        break;
×
367
    }
368
}
×
369

370
static void
371
sixel_encode_linear_to_colorspace(int colorspace,
×
372
                                  double r_lin,
373
                                  double g_lin,
374
                                  double b_lin,
375
                                  unsigned char *r8,
376
                                  unsigned char *g8,
377
                                  unsigned char *b8)
378
{
379
    double L;
380
    double A;
381
    double B;
382

383
    switch (colorspace) {
×
UNCOV
384
    case SIXEL_COLORSPACE_GAMMA:
×
385
        *r8 = sixel_linear_double_to_srgb(r_lin);
×
386
        *g8 = sixel_linear_double_to_srgb(g_lin);
×
387
        *b8 = sixel_linear_double_to_srgb(b_lin);
×
388
        break;
×
UNCOV
389
    case SIXEL_COLORSPACE_LINEAR:
×
390
        *r8 = sixel_linear_double_to_byte(r_lin);
×
391
        *g8 = sixel_linear_double_to_byte(g_lin);
×
392
        *b8 = sixel_linear_double_to_byte(b_lin);
×
393
        break;
×
UNCOV
394
    case SIXEL_COLORSPACE_OKLAB:
×
395
        sixel_linear_to_oklab(r_lin, g_lin, b_lin, &L, &A, &B);
×
396
        *r8 = sixel_oklab_encode_L(L);
×
397
        *g8 = sixel_oklab_encode_ab(A);
×
398
        *b8 = sixel_oklab_encode_ab(B);
×
399
        break;
×
UNCOV
400
    case SIXEL_COLORSPACE_SMPTEC:
×
401
    {
402
        double r_smptec;
403
        double g_smptec;
404
        double b_smptec;
405

406
        sixel_linear_srgb_to_smptec(r_lin, g_lin, b_lin,
×
407
                                     &r_smptec, &g_smptec, &b_smptec);
408

409
        *r8 = sixel_linear_double_to_smptec(r_smptec);
×
410
        *g8 = sixel_linear_double_to_smptec(g_smptec);
×
411
        *b8 = sixel_linear_double_to_smptec(b_smptec);
×
412
        break;
×
413
    }
UNCOV
414
    default:
×
415
        *r8 = sixel_linear_double_to_byte(r_lin);
×
416
        *g8 = sixel_linear_double_to_byte(g_lin);
×
417
        *b8 = sixel_linear_double_to_byte(b_lin);
×
418
        break;
×
419
    }
420
}
×
421

422
static SIXELSTATUS
423
sixel_convert_pixels_via_linear(unsigned char *pixels,
×
424
                                size_t size,
425
                                int pixelformat,
426
                                int colorspace_src,
427
                                int colorspace_dst)
428
{
429
    size_t i;
430
    int step;
431
    int index_r;
432
    int index_g;
433
    int index_b;
434

435
    if (colorspace_src == colorspace_dst) {
×
436
        return SIXEL_OK;
×
437
    }
438

439
    switch (pixelformat) {
×
UNCOV
440
    case SIXEL_PIXELFORMAT_RGB888:
×
441
        step = 3;
×
442
        index_r = 0;
×
443
        index_g = 1;
×
444
        index_b = 2;
×
445
        break;
×
UNCOV
446
    case SIXEL_PIXELFORMAT_BGR888:
×
447
        step = 3;
×
448
        index_r = 2;
×
449
        index_g = 1;
×
450
        index_b = 0;
×
451
        break;
×
UNCOV
452
    case SIXEL_PIXELFORMAT_RGBA8888:
×
453
        step = 4;
×
454
        index_r = 0;
×
455
        index_g = 1;
×
456
        index_b = 2;
×
457
        break;
×
UNCOV
458
    case SIXEL_PIXELFORMAT_BGRA8888:
×
459
        step = 4;
×
460
        index_r = 2;
×
461
        index_g = 1;
×
462
        index_b = 0;
×
463
        break;
×
UNCOV
464
    case SIXEL_PIXELFORMAT_ARGB8888:
×
465
        step = 4;
×
466
        index_r = 1;
×
467
        index_g = 2;
×
468
        index_b = 3;
×
469
        break;
×
UNCOV
470
    case SIXEL_PIXELFORMAT_ABGR8888:
×
471
        step = 4;
×
472
        index_r = 3;
×
473
        index_g = 2;
×
474
        index_b = 1;
×
475
        break;
×
UNCOV
476
    case SIXEL_PIXELFORMAT_G8:
×
477
        step = 1;
×
478
        index_r = 0;
×
479
        index_g = 0;
×
480
        index_b = 0;
×
481
        break;
×
UNCOV
482
    case SIXEL_PIXELFORMAT_GA88:
×
483
        step = 2;
×
484
        index_r = 0;
×
485
        index_g = 0;
×
486
        index_b = 0;
×
487
        break;
×
UNCOV
488
    case SIXEL_PIXELFORMAT_AG88:
×
489
        step = 2;
×
490
        index_r = 1;
×
491
        index_g = 1;
×
492
        index_b = 1;
×
493
        break;
×
UNCOV
494
    default:
×
495
        return SIXEL_BAD_INPUT;
×
496
    }
497

498
    if (size % (size_t)step != 0) {
×
499
        return SIXEL_BAD_INPUT;
×
500
    }
501

502
    for (i = 0; i < size; i += (size_t)step) {
×
503
        unsigned char *pr = pixels + i + (size_t)index_r;
×
504
        unsigned char *pg = pixels + i + (size_t)index_g;
×
505
        unsigned char *pb = pixels + i + (size_t)index_b;
×
506
        double r_lin;
507
        double g_lin;
508
        double b_lin;
509

510
        sixel_decode_linear_from_colorspace(colorspace_src,
×
511
                                            *pr,
×
512
                                            *pg,
×
513
                                            *pb,
×
514
                                            &r_lin,
515
                                            &g_lin,
516
                                            &b_lin);
517

518
        sixel_encode_linear_to_colorspace(colorspace_dst,
×
519
                                          r_lin,
520
                                          g_lin,
521
                                          b_lin,
522
                                          pr,
523
                                          pg,
524
                                          pb);
525
    }
526

527
    return SIXEL_OK;
×
528
}
529

530
static unsigned char
531
sixel_colorspace_convert_component(unsigned char value,
×
532
                                   int colorspace_src,
533
                                   int colorspace_dst)
534
{
535
    if (colorspace_src == colorspace_dst) {
×
536
        return value;
×
537
    }
538

539
    if (colorspace_src == SIXEL_COLORSPACE_GAMMA &&
×
540
            colorspace_dst == SIXEL_COLORSPACE_LINEAR) {
541
        return gamma_to_linear_lut[value];
×
542
    }
543

544
    if (colorspace_src == SIXEL_COLORSPACE_LINEAR &&
×
545
            colorspace_dst == SIXEL_COLORSPACE_GAMMA) {
546
        return linear_to_gamma_lut[value];
×
547
    }
548

549
    return value;
×
550
}
551

552
int
553
sixel_colorspace_supports_pixelformat(int pixelformat)
×
554
{
555
    switch (pixelformat) {
×
UNCOV
556
    case SIXEL_PIXELFORMAT_RGB888:
×
557
    case SIXEL_PIXELFORMAT_BGR888:
558
    case SIXEL_PIXELFORMAT_RGBA8888:
559
    case SIXEL_PIXELFORMAT_ARGB8888:
560
    case SIXEL_PIXELFORMAT_BGRA8888:
561
    case SIXEL_PIXELFORMAT_ABGR8888:
562
    case SIXEL_PIXELFORMAT_G8:
563
    case SIXEL_PIXELFORMAT_GA88:
564
    case SIXEL_PIXELFORMAT_AG88:
565
        return 1;
×
UNCOV
566
    default:
×
567
        break;
×
568
    }
569

570
    return 0;
×
571
}
572

573
SIXELAPI SIXELSTATUS
574
sixel_helper_convert_colorspace(unsigned char *pixels,
346✔
575
                                size_t size,
576
                                int pixelformat,
577
                                int colorspace_src,
578
                                int colorspace_dst)
579
{
580
    size_t i;
581

582
    if (pixels == NULL) {
346!
583
        sixel_helper_set_additional_message(
×
584
            "sixel_helper_convert_colorspace: pixels is null.");
585
        return SIXEL_BAD_ARGUMENT;
×
586
    }
587

588
    if (colorspace_src == colorspace_dst) {
346!
589
        return SIXEL_OK;
346✔
590
    }
591

592
    if (!sixel_colorspace_supports_pixelformat(pixelformat)) {
×
593
        sixel_helper_set_additional_message(
×
594
            "sixel_helper_convert_colorspace: unsupported pixelformat.");
595
        return SIXEL_BAD_INPUT;
×
596
    }
597

598
    sixel_colorspace_init_tables();
×
599

600
    if (colorspace_src == SIXEL_COLORSPACE_OKLAB ||
×
601
            colorspace_dst == SIXEL_COLORSPACE_OKLAB ||
×
602
            colorspace_src == SIXEL_COLORSPACE_SMPTEC ||
×
603
            colorspace_dst == SIXEL_COLORSPACE_SMPTEC) {
604
        SIXELSTATUS status = sixel_convert_pixels_via_linear(pixels,
×
605
                                                             size,
606
                                                             pixelformat,
607
                                                             colorspace_src,
608
                                                             colorspace_dst);
609
        if (SIXEL_FAILED(status)) {
×
610
            sixel_helper_set_additional_message(
×
611
                "sixel_helper_convert_colorspace: unsupported pixelformat for conversion.");
612
        }
613
        return status;
×
614
    }
615

616
    switch (pixelformat) {
×
UNCOV
617
    case SIXEL_PIXELFORMAT_RGB888:
×
618
        if (size % 3 != 0) {
×
619
            sixel_helper_set_additional_message(
×
620
                "sixel_helper_convert_colorspace: invalid data size.");
621
            return SIXEL_BAD_INPUT;
×
622
        }
623
        for (i = 0; i + 2 < size; i += 3) {
×
624
            pixels[i + 0] = sixel_colorspace_convert_component(
×
625
                pixels[i + 0], colorspace_src, colorspace_dst);
×
626
            pixels[i + 1] = sixel_colorspace_convert_component(
×
627
                pixels[i + 1], colorspace_src, colorspace_dst);
×
628
            pixels[i + 2] = sixel_colorspace_convert_component(
×
629
                pixels[i + 2], colorspace_src, colorspace_dst);
×
630
        }
631
        break;
×
UNCOV
632
    case SIXEL_PIXELFORMAT_BGR888:
×
633
        if (size % 3 != 0) {
×
634
            sixel_helper_set_additional_message(
×
635
                "sixel_helper_convert_colorspace: invalid data size.");
636
            return SIXEL_BAD_INPUT;
×
637
        }
638
        for (i = 0; i + 2 < size; i += 3) {
×
639
            pixels[i + 0] = sixel_colorspace_convert_component(
×
640
                pixels[i + 0], colorspace_src, colorspace_dst);
×
641
            pixels[i + 1] = sixel_colorspace_convert_component(
×
642
                pixels[i + 1], colorspace_src, colorspace_dst);
×
643
            pixels[i + 2] = sixel_colorspace_convert_component(
×
644
                pixels[i + 2], colorspace_src, colorspace_dst);
×
645
        }
646
        break;
×
UNCOV
647
    case SIXEL_PIXELFORMAT_RGBA8888:
×
648
        if (size % 4 != 0) {
×
649
            sixel_helper_set_additional_message(
×
650
                "sixel_helper_convert_colorspace: invalid data size.");
651
            return SIXEL_BAD_INPUT;
×
652
        }
653
        for (i = 0; i + 3 < size; i += 4) {
×
654
            pixels[i + 0] = sixel_colorspace_convert_component(
×
655
                pixels[i + 0], colorspace_src, colorspace_dst);
×
656
            pixels[i + 1] = sixel_colorspace_convert_component(
×
657
                pixels[i + 1], colorspace_src, colorspace_dst);
×
658
            pixels[i + 2] = sixel_colorspace_convert_component(
×
659
                pixels[i + 2], colorspace_src, colorspace_dst);
×
660
        }
661
        break;
×
UNCOV
662
    case SIXEL_PIXELFORMAT_ARGB8888:
×
663
        if (size % 4 != 0) {
×
664
            sixel_helper_set_additional_message(
×
665
                "sixel_helper_convert_colorspace: invalid data size.");
666
            return SIXEL_BAD_INPUT;
×
667
        }
668
        for (i = 0; i + 3 < size; i += 4) {
×
669
            pixels[i + 1] = sixel_colorspace_convert_component(
×
670
                pixels[i + 1], colorspace_src, colorspace_dst);
×
671
            pixels[i + 2] = sixel_colorspace_convert_component(
×
672
                pixels[i + 2], colorspace_src, colorspace_dst);
×
673
            pixels[i + 3] = sixel_colorspace_convert_component(
×
674
                pixels[i + 3], colorspace_src, colorspace_dst);
×
675
        }
676
        break;
×
UNCOV
677
    case SIXEL_PIXELFORMAT_BGRA8888:
×
678
        if (size % 4 != 0) {
×
679
            sixel_helper_set_additional_message(
×
680
                "sixel_helper_convert_colorspace: invalid data size.");
681
            return SIXEL_BAD_INPUT;
×
682
        }
683
        for (i = 0; i + 3 < size; i += 4) {
×
684
            pixels[i + 0] = sixel_colorspace_convert_component(
×
685
                pixels[i + 0], colorspace_src, colorspace_dst);
×
686
            pixels[i + 1] = sixel_colorspace_convert_component(
×
687
                pixels[i + 1], colorspace_src, colorspace_dst);
×
688
            pixels[i + 2] = sixel_colorspace_convert_component(
×
689
                pixels[i + 2], colorspace_src, colorspace_dst);
×
690
        }
691
        break;
×
UNCOV
692
    case SIXEL_PIXELFORMAT_ABGR8888:
×
693
        if (size % 4 != 0) {
×
694
            sixel_helper_set_additional_message(
×
695
                "sixel_helper_convert_colorspace: invalid data size.");
696
            return SIXEL_BAD_INPUT;
×
697
        }
698
        for (i = 0; i + 3 < size; i += 4) {
×
699
            pixels[i + 1] = sixel_colorspace_convert_component(
×
700
                pixels[i + 1], colorspace_src, colorspace_dst);
×
701
            pixels[i + 2] = sixel_colorspace_convert_component(
×
702
                pixels[i + 2], colorspace_src, colorspace_dst);
×
703
            pixels[i + 3] = sixel_colorspace_convert_component(
×
704
                pixels[i + 3], colorspace_src, colorspace_dst);
×
705
        }
706
        break;
×
UNCOV
707
    case SIXEL_PIXELFORMAT_G8:
×
708
        for (i = 0; i < size; ++i) {
×
709
            pixels[i] = sixel_colorspace_convert_component(
×
710
                pixels[i], colorspace_src, colorspace_dst);
×
711
        }
712
        break;
×
UNCOV
713
    case SIXEL_PIXELFORMAT_GA88:
×
714
        if (size % 2 != 0) {
×
715
            sixel_helper_set_additional_message(
×
716
                "sixel_helper_convert_colorspace: invalid data size.");
717
            return SIXEL_BAD_INPUT;
×
718
        }
719
        for (i = 0; i + 1 < size; i += 2) {
×
720
            pixels[i + 0] = sixel_colorspace_convert_component(
×
721
                pixels[i + 0], colorspace_src, colorspace_dst);
×
722
        }
723
        break;
×
UNCOV
724
    case SIXEL_PIXELFORMAT_AG88:
×
725
        if (size % 2 != 0) {
×
726
            sixel_helper_set_additional_message(
×
727
                "sixel_helper_convert_colorspace: invalid data size.");
728
            return SIXEL_BAD_INPUT;
×
729
        }
730
        for (i = 0; i + 1 < size; i += 2) {
×
731
            pixels[i + 1] = sixel_colorspace_convert_component(
×
732
                pixels[i + 1], colorspace_src, colorspace_dst);
×
733
        }
734
        break;
×
UNCOV
735
    default:
×
736
        sixel_helper_set_additional_message(
×
737
            "sixel_helper_convert_colorspace: unsupported pixelformat.");
738
        return SIXEL_BAD_INPUT;
×
739
    }
740

741
    return SIXEL_OK;
×
742
}
743

744
/* emacs Local Variables:      */
745
/* emacs mode: c               */
746
/* emacs tab-width: 4          */
747
/* emacs indent-tabs-mode: nil */
748
/* emacs c-basic-offset: 4     */
749
/* emacs End:                  */
750
/* vim: set expandtab ts=4 sts=4 sw=4 : */
751
/* 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