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

saitoha / libsixel / 21342373226

26 Jan 2026 12:31AM UTC coverage: 76.212%. First build
21342373226

push

github

saitoha
build: fix unity build symbol collisions in dither

20001 of 44992 branches covered (44.45%)

0 of 56 new or added lines in 2 files covered. (0.0%)

36354 of 47701 relevant lines covered (76.21%)

13392422.44 hits per line

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

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

25
#if defined(HAVE_CONFIG_H)
26
#include "config.h"
27
#endif
28

29
#if HAVE_MATH_H
30
# include <math.h>
31
#endif  /* HAVE_MATH_H */
32
#include <ctype.h>
33
#include <limits.h>
34
#include <stdlib.h>
35
#include <string.h>
36

37
#include "compat_stub.h"
38
#include "dither-positional-float32.h"
39
#include "dither-common-pipeline.h"
40
#include "pixelformat.h"
41
#include "lookup-common.h"
42
#include "bluenoise_64x64.h"
43

44
static void
45
sixel_dither_scanline_params_positional_float32(int serpentine,
6,168✔
46
                             int index,
47
                             int limit,
48
                             int *start,
49
                             int *end,
50
                             int *step,
51
                             int *direction)
52
{
53
    if (serpentine && (index & 1)) {
5,784!
54
        *start = limit - 1;
2,700✔
55
        *end = -1;
2,700✔
56
        *step = -1;
2,700✔
57
        *direction = -1;
2,700✔
58
    } else {
675✔
59
        *start = 0;
1,734✔
60
        *end = limit;
1,734✔
61
        *step = 1;
1,734✔
62
        *direction = 1;
4,818✔
63
    }
64
}
3,084✔
65

66
static float
67
positional_mask_a_float32(int x, int y, int c)
147,456✔
68
{
69
    return ((((x + c * 67) + y * 236) * 119) & 255) / 128.0f - 1.0f;
147,456✔
70
}
71

72
static float
73
positional_mask_x_float32(int x, int y, int c)
9,720,000✔
74
{
75
    return ((((x + c * 29) ^ (y * 149)) * 1234) & 511) / 256.0f - 1.0f;
9,720,000✔
76
}
77

78
static float positional_mask_blue_float32(int x, int y, int c);
79

80
/*
81
 * Keep per-file suffixes so unity builds do not merge identical static
82
 * helper symbols from other positional dither sources.
83
 */
84
typedef struct {
85
    float strength;
86
    int ox;
87
    int oy;
88
    int per_channel;
89
    int size;
90
} sixel_bluenoise_conf_float32_t;
91

92
static sixel_bluenoise_conf_float32_t g_sixel_bn_conf_float32;
93
static int g_sixel_bn_inited_float32 = 0;
94

95
static int
NEW
96
sixel_bn_parse_int_float32(char const *text, int *out_value)
×
97
{
98
    char *endptr;
99
    long value;
100

101
    if (text == NULL || text[0] == '\0') {
×
102
        return 0;
103
    }
104

105
    value = strtol(text, &endptr, 10);
×
106
    if (endptr == text || *endptr != '\0') {
×
107
        return 0;
108
    }
109
    if (value > INT_MAX || value < INT_MIN) {
×
110
        return 0;
111
    }
112

113
    *out_value = (int)value;
×
114
    return 1;
×
115
}
116

117
static int
NEW
118
sixel_bn_parse_float_float32(char const *text, float *out_value)
×
119
{
120
    char *endptr;
121
    double value;
122

123
    if (text == NULL || text[0] == '\0') {
×
124
        return 0;
125
    }
126

127
    value = strtod(text, &endptr);
×
128
    if (endptr == text || *endptr != '\0') {
×
129
        return 0;
130
    }
131

132
    *out_value = (float)value;
×
133
    return 1;
×
134
}
135

136
static int
NEW
137
sixel_bn_parse_phase_float32(char const *text, int *out_ox, int *out_oy)
×
138
{
139
    char *endptr;
140
    char const *comma;
141
    long ox;
142
    long oy;
143

144
    if (text == NULL || text[0] == '\0') {
×
145
        return 0;
146
    }
147

148
    comma = strchr(text, ',');
×
149
    if (comma == NULL) {
×
150
        return 0;
151
    }
152

153
    ox = strtol(text, &endptr, 10);
×
154
    if (endptr == text || endptr != comma) {
×
155
        return 0;
156
    }
157

158
    oy = strtol(comma + 1, &endptr, 10);
×
159
    if (endptr == comma + 1 || *endptr != '\0') {
×
160
        return 0;
161
    }
162
    if (ox > INT_MAX || ox < INT_MIN || oy > INT_MAX || oy < INT_MIN) {
×
163
        return 0;
164
    }
165

166
    *out_ox = (int)ox;
×
167
    *out_oy = (int)oy;
×
168
    return 1;
×
169
}
170

171
static unsigned int
NEW
172
sixel_bn_hash32_float32(unsigned int value)
×
173
{
174
    value += 0x9e3779b9U;
×
175
    value ^= value >> 16;
×
176
    value *= 0x85ebca6bU;
×
177
    value ^= value >> 13;
×
178
    value *= 0xc2b2ae35U;
×
179
    value ^= value >> 16;
×
180
    return value;
×
181
}
182

183
static int
NEW
184
sixel_bn_str_equal_nocase_float32(char const *left, char const *right)
×
185
{
186
    unsigned char lc;
187
    unsigned char rc;
188

189
    if (left == NULL || right == NULL) {
×
190
        return 0;
191
    }
192

193
    while (*left != '\0' && *right != '\0') {
×
194
        lc = (unsigned char)tolower((unsigned char)*left);
×
195
        rc = (unsigned char)tolower((unsigned char)*right);
×
196
        if (lc != rc) {
×
197
            return 0;
198
        }
199
        ++left;
×
200
        ++right;
×
201
    }
202

203
    return (*left == '\0' && *right == '\0');
×
204
}
205

206
/*
207
 * Cache bluenoise configuration at first use so we do not hit getenv()
208
 * inside pixel loops. Invalid values fall back to defaults.
209
 */
210
static void
NEW
211
sixel_bluenoise_conf_init_from_env_float32(void)
×
212
{
213
    char const *text;
214
    float strength;
215
    int size;
216
    int ox;
217
    int oy;
218
    int seed;
219
    int phase_set;
220
    int parsed;
221
    int per_channel;
222
    unsigned int hash;
223

NEW
224
    if (g_sixel_bn_inited_float32 != 0) {
×
225
        return;
×
226
    }
227

228
    strength = 1.0f;
×
229
    text = sixel_compat_getenv("SIXEL_DITHER_BLUENOISE_STRENGTH");
×
230
    if (text != NULL) {
×
NEW
231
        parsed = sixel_bn_parse_float_float32(text, &strength);
×
232
        if (parsed == 0) {
×
233
            strength = 1.0f;
×
234
        }
235
    } else {
236
        text = sixel_compat_getenv("SIXEL_DITHER_STRENGTH");
×
237
        if (text != NULL) {
×
NEW
238
            parsed = sixel_bn_parse_float_float32(text, &strength);
×
239
            if (parsed == 0) {
×
240
                strength = 1.0f;
×
241
            }
242
        }
243
    }
244

245
    ox = 0;
×
246
    oy = 0;
×
247
    phase_set = 0;
×
248
    text = sixel_compat_getenv("SIXEL_DITHER_BLUENOISE_PHASE");
×
249
    if (text != NULL) {
×
250
        phase_set = 1;
×
NEW
251
        parsed = sixel_bn_parse_phase_float32(text, &ox, &oy);
×
252
        if (parsed == 0) {
×
253
            ox = 0;
×
254
            oy = 0;
×
255
        }
256
    }
257
    if (phase_set == 0) {
×
258
        text = sixel_compat_getenv("SIXEL_DITHER_BLUENOISE_SEED");
×
259
        if (text != NULL) {
×
NEW
260
            parsed = sixel_bn_parse_int_float32(text, &seed);
×
261
            if (parsed != 0) {
×
NEW
262
                hash = sixel_bn_hash32_float32((unsigned int)seed);
×
263
                ox = (int)(hash & 63U);
×
264
                oy = (int)((hash >> 8) & 63U);
×
265
            }
266
        }
267
    }
268

269
    per_channel = 0;
×
270
    text = sixel_compat_getenv("SIXEL_DITHER_BLUENOISE_CHANNEL");
×
271
    if (text != NULL) {
×
NEW
272
        if (sixel_bn_str_equal_nocase_float32(text, "rgb") != 0) {
×
273
            per_channel = 1;
NEW
274
        } else if (sixel_bn_str_equal_nocase_float32(text, "mono") != 0) {
×
275
            per_channel = 0;
×
276
        }
277
    }
278

279
    size = SIXEL_BN_W;
×
280
    text = sixel_compat_getenv("SIXEL_DITHER_BLUENOISE_SIZE");
×
281
    if (text != NULL) {
×
NEW
282
        parsed = sixel_bn_parse_int_float32(text, &size);
×
283
        if (parsed == 0 || size != SIXEL_BN_W) {
×
284
            size = SIXEL_BN_W;
×
285
        }
286
    }
287

NEW
288
    g_sixel_bn_conf_float32.strength = strength;
×
NEW
289
    g_sixel_bn_conf_float32.ox = ox;
×
NEW
290
    g_sixel_bn_conf_float32.oy = oy;
×
NEW
291
    g_sixel_bn_conf_float32.per_channel = per_channel;
×
NEW
292
    g_sixel_bn_conf_float32.size = size;
×
NEW
293
    g_sixel_bn_inited_float32 = 1;
×
294
}
×
295

296
static float
NEW
297
sixel_bluenoise_tri_float32(int x, int y, int c)
×
298
{
299
    /* Triangular noise blends two samples from the same tile. */
300
    static int const channel_offset_x[3] = { 17, 34, 51 };
301
    static int const channel_offset_y[3] = { 31, 62, 93 };
302
    int ox;
303
    int oy;
304
    int per_channel;
305
    int channel_x;
306
    int channel_y;
307
    int ix0;
308
    int iy0;
309
    int ix1;
310
    int iy1;
311
    float u;
312
    float v;
313

NEW
314
    ox = g_sixel_bn_conf_float32.ox;
×
NEW
315
    oy = g_sixel_bn_conf_float32.oy;
×
NEW
316
    per_channel = g_sixel_bn_conf_float32.per_channel;
×
317
    channel_x = 0;
×
318
    channel_y = 0;
×
319
    if (per_channel != 0 && c >= 0 && c < 3) {
×
320
        channel_x = channel_offset_x[c];
×
321
        channel_y = channel_offset_y[c];
×
322
    }
323

324
    ix0 = x + ox + channel_x;
×
325
    iy0 = y + oy + channel_y;
×
326
    ix1 = ix0 + 13;
×
327
    iy1 = iy0 + 29;
×
328
    u = (sixel_bn_mask(ix0, iy0) + 1.0f) * 0.5f;
×
329
    v = (sixel_bn_mask(ix1, iy1) + 1.0f) * 0.5f;
×
330

331
    return (u + v) - 1.0f;
×
332
}
333

334
static float
335
positional_mask_blue_float32(int x, int y, int c)
×
336
{
NEW
337
    sixel_bluenoise_conf_init_from_env_float32();
×
NEW
338
    return sixel_bluenoise_tri_float32(x, y, c)
×
NEW
339
        * g_sixel_bn_conf_float32.strength;
×
340
}
341

342
SIXELSTATUS
343
sixel_dither_apply_positional_float32(sixel_dither_t *dither,
24✔
344
                                      sixel_dither_context_t *context)
345
{
18✔
346
#if _MSC_VER
347
    enum { max_channels = 4 };
348
#else
349
    const int max_channels = 4;
24✔
350
#endif
351
    int serpentine;
14✔
352
    int y;
14✔
353
    int absolute_y;
14✔
354
    float (*f_mask)(int x, int y, int c);
14✔
355
    float jitter_scale;
14✔
356
    float *palette_float;
14✔
357
    float *new_palette_float;
14✔
358
    int float_depth;
14✔
359
    int float_index;
14✔
360
    unsigned char *quantized;
14✔
361
    float lookup_pixel_float[max_channels];
24✔
362
    unsigned char const *lookup_pixel;
14✔
363
    sixel_lut_t *fast_lut;
14✔
364
    int use_fast_lut;
14✔
365
    int lookup_wants_float;
14✔
366
    int use_palette_float_lookup;
14✔
367
    int need_float_pixel;
14✔
368

369
    palette_float = NULL;
24✔
370
    new_palette_float = NULL;
24✔
371
    float_depth = 0;
24✔
372
    quantized = NULL;
24✔
373
    lookup_wants_float = 0;
24✔
374

375
    if (dither == NULL || context == NULL) {
24!
376
        return SIXEL_BAD_ARGUMENT;
377
    }
378
    if (context->pixels_float == NULL || context->scratch == NULL) {
24!
379
        return SIXEL_BAD_ARGUMENT;
380
    }
381
    if (context->palette == NULL || context->result == NULL) {
24!
382
        return SIXEL_BAD_ARGUMENT;
383
    }
384

385
    switch (context->method_for_diffuse) {
24!
386
    case SIXEL_DIFFUSE_A_DITHER:
3✔
387
        f_mask = positional_mask_a_float32;
6✔
388
        break;
6✔
389
    case SIXEL_DIFFUSE_X_DITHER:
3✔
390
        f_mask = positional_mask_x_float32;
12✔
391
        break;
6✔
392
    case SIXEL_DIFFUSE_BLUENOISE_DITHER:
393
        f_mask = positional_mask_blue_float32;
×
394
        break;
×
395
    default:
396
        f_mask = positional_mask_x_float32;
6✔
397
        break;
398
    }
399

400
    serpentine = (context->method_for_scan == SIXEL_SCAN_SERPENTINE);
24✔
401
    jitter_scale = 32.0f / 255.0f;
24✔
402
    palette_float = context->palette_float;
24✔
403
    new_palette_float = context->new_palette_float;
24✔
404
    float_depth = context->float_depth;
24✔
405
    quantized = context->scratch;
24✔
406
    fast_lut = context->lut;
24✔
407
    use_fast_lut = (fast_lut != NULL);
24✔
408
    lookup_wants_float = (context->lookup_source_is_float != 0);
24✔
409
    use_palette_float_lookup = 0;
24✔
410
    if (context->prefer_palette_float_lookup != 0
24!
411
            && palette_float != NULL
6!
412
            && float_depth >= context->depth) {
×
413
        use_palette_float_lookup = 1;
12✔
414
    }
415
    need_float_pixel = lookup_wants_float || use_palette_float_lookup;
24!
416

417
    if (context->optimize_palette) {
24!
418
        int x;
14✔
419

420
        *context->ncolors = 0;
24✔
421
        memset(context->new_palette, 0x00,
26✔
422
               (size_t)SIXEL_PALETTE_MAX * (size_t)context->depth);
20!
423
        if (new_palette_float != NULL && float_depth > 0) {
24!
424
            memset(new_palette_float, 0x00,
×
425
                   (size_t)SIXEL_PALETTE_MAX
426
                       * (size_t)float_depth * sizeof(float));
427
        }
428
        memset(context->migration_map, 0x00,
24✔
429
               sizeof(unsigned short) * (size_t)SIXEL_PALETTE_MAX);
430
        for (y = 0; y < context->height; ++y) {
6,192✔
431
            absolute_y = context->band_origin + y;
6,168✔
432
            int start;
3,598✔
433
            int end;
3,598✔
434
            int step;
3,598✔
435
            int direction;
3,598✔
436

437
            sixel_dither_scanline_params_positional_float32(serpentine, absolute_y,
7,710✔
438
                                         context->width,
1,542✔
439
                                         &start, &end, &step, &direction);
440
            (void)direction;
4,626✔
441
            for (x = start; x != end; x += step) {
3,295,320✔
442
                int pos;
1,918,672✔
443
                int d;
1,918,672✔
444
                int color_index;
1,918,672✔
445

446
                pos = y * context->width + x;
3,289,152✔
447
                for (d = 0; d < context->depth; ++d) {
13,156,608✔
448
                    float val;
5,756,016✔
449

450
                    val = context->pixels_float[pos * context->depth + d]
19,734,912✔
451
                        + f_mask(x, y, d) * jitter_scale;
9,867,456✔
452
                    val = sixel_pixelformat_float_channel_clamp(
9,867,456✔
453
                        context->pixelformat,
2,466,864✔
454
                        d,
2,466,864✔
455
                        val);
2,466,864✔
456
                    if (need_float_pixel) {
9,867,456!
457
                        lookup_pixel_float[d] = val;
9,867,456✔
458
                    }
2,466,864✔
459
                    if (!lookup_wants_float && !use_palette_float_lookup) {
9,867,456!
460
                        quantized[d]
×
461
                            = sixel_pixelformat_float_channel_to_byte(
×
462
                                  context->pixelformat,
463
                                  d,
464
                                  val);
465
                    }
466
                }
2,466,864✔
467
                if (lookup_wants_float) {
3,289,152!
468
                    lookup_pixel = (unsigned char const *)(void const *)
3,289,152✔
469
                        lookup_pixel_float;
470
                    if (use_fast_lut) {
3,289,152!
471
                        color_index = sixel_lut_map_pixel(fast_lut,
4,111,440✔
472
                                                         lookup_pixel);
822,288✔
473
                    } else {
822,288✔
474
                        color_index = context->lookup(lookup_pixel,
×
475
                                                      context->depth,
476
                                                      context->palette,
×
477
                                                      context->reqcolor,
478
                                                      context->indextable,
479
                                                      context->complexion);
480
                    }
481
                } else if (use_palette_float_lookup) {
822,288!
482
                    color_index = sixel_dither_lookup_palette_float32(
×
483
                        lookup_pixel_float,
484
                        context->depth,
485
                        palette_float,
486
                        context->reqcolor,
487
                        context->complexion,
488
                        0);
489
                } else {
490
                    lookup_pixel = quantized;
×
491
                    if (use_fast_lut) {
×
492
                        color_index = sixel_lut_map_pixel(fast_lut,
×
493
                                                         lookup_pixel);
494
                    } else {
495
                        color_index = context->lookup(lookup_pixel,
×
496
                                                      context->depth,
497
                                                      context->palette,
×
498
                                                      context->reqcolor,
499
                                                      context->indextable,
500
                                                      context->complexion);
501
                    }
502
                }
503
                if (context->migration_map[color_index] == 0) {
3,289,152✔
504
                    if (absolute_y >= context->output_start) {
2,564!
505
                        /*
506
                         * Palette indices never exceed SIXEL_PALETTE_MAX, so
507
                         * the cast to sixel_index_t (unsigned char) is safe.
508
                         */
509
                        context->result[pos]
2,564✔
510
                            = (sixel_index_t)(*context->ncolors);
3,193✔
511
                    }
629✔
512
                    for (d = 0; d < context->depth; ++d) {
10,256✔
513
                        context->new_palette[*context->ncolors
9,579✔
514
                                             * context->depth + d]
7,692✔
515
                            = context->palette[color_index
11,466✔
516
                                               * context->depth + d];
7,692✔
517
                    }
1,887✔
518
                    if (palette_float != NULL
2,564!
519
                            && new_palette_float != NULL
1,919!
520
                            && float_depth > 0) {
×
521
                        for (float_index = 0;
×
522
                                float_index < float_depth;
×
523
                                ++float_index) {
×
524
                            new_palette_float[*context->ncolors
×
525
                                               * float_depth
×
526
                                               + float_index]
×
527
                                = palette_float[color_index * float_depth
×
528
                                                + float_index];
×
529
                        }
530
                    }
531
                    ++*context->ncolors;
2,564✔
532
                    /*
533
                     * Migration map entries are limited to the palette size
534
                     * (<= 256), so storing them as unsigned short is safe.
535
                     */
536
                    context->migration_map[color_index]
2,564✔
537
                        = (unsigned short)(*context->ncolors);
3,193✔
538
                } else {
629✔
539
                    if (absolute_y >= context->output_start) {
3,286,588!
540
                        context->result[pos]
3,286,588✔
541
                            = (sixel_index_t)(context->migration_map[
5,751,565✔
542
                                  color_index] - 1);
1,643,318✔
543
                    }
821,659✔
544
                }
545
            }
822,288✔
546
            if (absolute_y >= context->output_start) {
6,168!
547
                sixel_dither_pipeline_row_notify(dither, absolute_y);
6,168✔
548
            }
1,542✔
549
        }
1,542✔
550
        memcpy(context->palette, context->new_palette,
26✔
551
               (size_t)(*context->ncolors * context->depth));
20!
552
        if (palette_float != NULL
24!
553
                && new_palette_float != NULL
18!
554
                && float_depth > 0) {
×
555
            memcpy(palette_float,
×
556
                   new_palette_float,
557
                   (size_t)(*context->ncolors * float_depth)
558
                       * sizeof(float));
559
        }
560
    } else {
6✔
561
        int x;
562

563
        for (y = 0; y < context->height; ++y) {
×
564
            absolute_y = context->band_origin + y;
×
565
            int start;
566
            int end;
567
            int step;
568
            int direction;
569

570
            sixel_dither_scanline_params_positional_float32(serpentine, absolute_y,
×
571
                                         context->width,
572
                                         &start, &end, &step, &direction);
573
            (void)direction;
574
            for (x = start; x != end; x += step) {
×
575
                int pos;
576
                int d;
577

578
                pos = y * context->width + x;
×
579
                for (d = 0; d < context->depth; ++d) {
×
580
                    float val;
581

582
                    val = context->pixels_float[pos * context->depth + d]
×
583
                        + f_mask(x, y, d) * jitter_scale;
×
584
                    val = sixel_pixelformat_float_channel_clamp(
×
585
                        context->pixelformat,
586
                        d,
587
                        val);
588
                    if (need_float_pixel) {
×
589
                        lookup_pixel_float[d] = val;
×
590
                    }
591
                    if (!lookup_wants_float && !use_palette_float_lookup) {
×
592
                        quantized[d]
×
593
                            = sixel_pixelformat_float_channel_to_byte(
×
594
                                  context->pixelformat,
595
                                  d,
596
                                  val);
597
                    }
598
                }
599
                if (absolute_y >= context->output_start) {
×
600
                    /*
601
                     * Palette indices never exceed SIXEL_PALETTE_MAX, so
602
                     * narrowing to sixel_index_t (unsigned char) is safe.
603
                     */
604
                    if (lookup_wants_float) {
×
605
                        lookup_pixel = (unsigned char const *)(void const *)
×
606
                            lookup_pixel_float;
607
                        context->result[pos] = (sixel_index_t)
×
608
                            context->lookup(
×
609
                                lookup_pixel,
610
                                context->depth,
611
                                context->palette,
×
612
                                context->reqcolor,
613
                                context->indextable,
614
                                context->complexion);
615
                    } else if (use_palette_float_lookup) {
×
616
                        context->result[pos] = (sixel_index_t)
×
617
                            sixel_dither_lookup_palette_float32(
×
618
                                lookup_pixel_float,
619
                                context->depth,
620
                                palette_float,
621
                                context->reqcolor,
622
                                context->complexion,
623
                                0);
624
                    } else {
625
                        lookup_pixel = quantized;
×
626
                        context->result[pos] = (sixel_index_t)
×
627
                            context->lookup(
×
628
                                lookup_pixel,
629
                                context->depth,
630
                                context->palette,
×
631
                                context->reqcolor,
632
                                context->indextable,
633
                                context->complexion);
634
                    }
635
                }
636
            }
637
            if (absolute_y >= context->output_start) {
×
638
                sixel_dither_pipeline_row_notify(dither, absolute_y);
×
639
            }
640
        }
641
        *context->ncolors = context->reqcolor;
×
642
    }
643

644
    return SIXEL_OK;
12✔
645
}
6✔
646

647
/* emacs Local Variables:      */
648
/* emacs mode: c               */
649
/* emacs tab-width: 4          */
650
/* emacs indent-tabs-mode: nil */
651
/* emacs c-basic-offset: 4     */
652
/* emacs End:                  */
653
/* vim: set expandtab ts=4 sts=4 sw=4 : */
654
/* 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