• 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

74.49
/src/output.c
1
/*
2
 * Copyright (c) 2014-2019 Hayaki Saito
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
/* STDC_HEADERS */
25
# include <stdio.h>
26
# include <stdlib.h>
27

28
#if 0
29
#if HAVE_ASSERT_H
30
# include <assert.h>
31
#endif  /* HAVE_ASSERT_H */
32
#endif
33

34
#include <sixel.h>
35
#include "output.h"
36

37

38
/* create new output context object */
39
SIXELAPI SIXELSTATUS
40
sixel_output_new(
346✔
41
    sixel_output_t          /* out */ **output,
42
    sixel_write_function    /* in */  fn_write,
43
    void                    /* in */  *priv,
44
    sixel_allocator_t       /* in */  *allocator)
45
{
46
    SIXELSTATUS status = SIXEL_FALSE;
346✔
47
    size_t size;
48

49
    if (allocator == NULL) {
346!
50
        status = sixel_allocator_new(&allocator, NULL, NULL, NULL, NULL);
×
51
        if (SIXEL_FAILED(status)) {
×
52
            goto end;
×
53
        }
54
    } else {
55
        sixel_allocator_ref(allocator);
346✔
56
    }
57
    size = sizeof(sixel_output_t) + SIXEL_OUTPUT_PACKET_SIZE * 2;
346✔
58

59
    *output = (sixel_output_t *)sixel_allocator_malloc(allocator, size);
346✔
60
    if (*output == NULL) {
346!
61
        sixel_helper_set_additional_message(
×
62
            "sixel_output_new: sixel_allocator_malloc() failed.");
63
        status = SIXEL_BAD_ALLOCATION;
×
64
        goto end;
×
65
    }
66

67
    (*output)->ref = 1;
346✔
68
    (*output)->has_8bit_control = 0;
346✔
69
    (*output)->has_sdm_glitch = 0;
346✔
70
    (*output)->has_gri_arg_limit = 1;
346✔
71
    (*output)->skip_dcs_envelope = 0;
346✔
72
    (*output)->skip_header = 0;
346✔
73
    (*output)->palette_type = SIXEL_PALETTETYPE_AUTO;
346✔
74
    (*output)->colorspace = SIXEL_COLORSPACE_GAMMA;
346✔
75
    (*output)->source_colorspace = SIXEL_COLORSPACE_GAMMA;
346✔
76
    (*output)->pixelformat = SIXEL_PIXELFORMAT_RGB888;
346✔
77
    (*output)->fn_write = fn_write;
346✔
78
    (*output)->save_pixel = 0;
346✔
79
    (*output)->save_count = 0;
346✔
80
    (*output)->active_palette = (-1);
346✔
81
    (*output)->node_top = NULL;
346✔
82
    (*output)->node_free = NULL;
346✔
83
    (*output)->priv = priv;
346✔
84
    (*output)->pos = 0;
346✔
85
    (*output)->penetrate_multiplexer = 0;
346✔
86
    (*output)->encode_policy = SIXEL_ENCODEPOLICY_AUTO;
346✔
87
    (*output)->ormode = 0;
346✔
88
    (*output)->last_clock = 0;
346✔
89
    (*output)->allocator = allocator;
346✔
90

91
    status = SIXEL_OK;
346✔
92

93
end:
346✔
94
    return status;
346✔
95
}
96

97

98
/* deprecated: create an output object */
99
SIXELAPI sixel_output_t *
100
sixel_output_create(sixel_write_function fn_write, void *priv)
×
101
{
102
    SIXELSTATUS status = SIXEL_FALSE;
×
103
    sixel_output_t *output = NULL;
×
104

105
    status = sixel_output_new(&output, fn_write, priv, NULL);
×
106
    if (SIXEL_FAILED(status)) {
×
107
        goto end;
×
108
    }
109

UNCOV
110
end:
×
111
    return output;
×
112
}
113

114

115
/* destroy output context object */
116
SIXELAPI void
117
sixel_output_destroy(sixel_output_t *output)
346✔
118
{
119
    sixel_allocator_t *allocator;
120

121
    if (output) {
346!
122
        allocator = output->allocator;
346✔
123
        sixel_allocator_free(allocator, output);
346✔
124
        sixel_allocator_unref(allocator);
346✔
125
    }
126
}
346✔
127

128

129
/* increase reference count of output context object (thread-unsafe) */
130
SIXELAPI void
131
sixel_output_ref(sixel_output_t *output)
326✔
132
{
133
    /* TODO: be thread-safe */
134
    ++output->ref;
326✔
135
}
326✔
136

137

138
/* decrease reference count of output context object (thread-unsafe) */
139
SIXELAPI void
140
sixel_output_unref(sixel_output_t *output)
672✔
141
{
142
    /* TODO: be thread-safe */
143
    if (output) {
672!
144
#if 0
145
        assert(output->ref > 0);
146
#endif
147
        output->ref--;
672✔
148
        if (output->ref == 0) {
672✔
149
            sixel_output_destroy(output);
346✔
150
        }
151
    }
152
}
672✔
153

154

155
/* get 8bit output mode which indicates whether it uses C1 control characters */
156
SIXELAPI int
157
sixel_output_get_8bit_availability(sixel_output_t *output)
×
158
{
159
    return output->has_8bit_control;
×
160
}
161

162

163
/* set 8bit output mode state */
164
SIXELAPI void
165
sixel_output_set_8bit_availability(sixel_output_t *output, int availability)
346✔
166
{
167
    output->has_8bit_control = availability;
346✔
168
}
346✔
169

170

171
/* set whether limit arguments of DECGRI('!') to 255 */
172
SIXELAPI void
173
sixel_output_set_gri_arg_limit(
346✔
174
    sixel_output_t /* in */ *output, /* output context */
175
    int            /* in */ value)   /* 0: don't limit arguments of DECGRI
176
                                        1: limit arguments of DECGRI to 255 */
177
{
178
    output->has_gri_arg_limit = value;
346✔
179
}
346✔
180

181

182
/* set GNU Screen penetration feature enable or disable */
183
SIXELAPI void
184
sixel_output_set_penetrate_multiplexer(sixel_output_t *output, int penetrate)
346✔
185
{
186
    output->penetrate_multiplexer = penetrate;
346✔
187
}
346✔
188

189

190
/* set whether we skip DCS envelope */
191
SIXELAPI void
192
sixel_output_set_skip_dcs_envelope(sixel_output_t *output, int skip)
×
193
{
194
    output->skip_dcs_envelope = skip;
×
195
}
×
196

197

198
SIXELAPI void
199
sixel_output_set_skip_header(sixel_output_t *output, int skip)
×
200
{
201
    output->skip_header = skip;
×
202
}
×
203

204

205
/* set palette type: RGB or HLS */
206
SIXELAPI void
207
sixel_output_set_palette_type(sixel_output_t *output, int palettetype)
346✔
208
{
209
    output->palette_type = palettetype;
346✔
210
}
346✔
211

212

213
SIXELAPI void
214
sixel_output_set_ormode(sixel_output_t *output, int ormode)
346✔
215
{
216
    output->ormode = ormode;
346✔
217
}
346✔
218

219

220
/* set encodeing policy: auto, fast or size */
221
SIXELAPI void
222
sixel_output_set_encode_policy(sixel_output_t *output, int encode_policy)
346✔
223
{
224
    output->encode_policy = encode_policy;
346✔
225
}
346✔
226

227

228
SIXELAPI SIXELSTATUS
229
sixel_output_convert_colorspace(sixel_output_t *output,
346✔
230
                                unsigned char *pixels,
231
                                size_t size)
232
{
233
    SIXELSTATUS status = SIXEL_FALSE;
346✔
234

235
    if (output == NULL || pixels == NULL) {
346!
236
        sixel_helper_set_additional_message(
×
237
            "sixel_output_convert_colorspace: invalid argument.");
238
        return SIXEL_BAD_ARGUMENT;
×
239
    }
240

241
    status = sixel_helper_convert_colorspace(pixels,
346✔
242
                                             size,
243
                                             output->pixelformat,
244
                                             output->source_colorspace,
245
                                             output->colorspace);
246
    if (SIXEL_FAILED(status)) {
346!
247
        return status;
×
248
    }
249

250
    output->source_colorspace = output->colorspace;
346✔
251

252
    return SIXEL_OK;
346✔
253
}
254

255
/* emacs Local Variables:      */
256
/* emacs mode: c               */
257
/* emacs tab-width: 4          */
258
/* emacs indent-tabs-mode: nil */
259
/* emacs c-basic-offset: 4     */
260
/* emacs End:                  */
261
/* vim: set expandtab ts=4 sts=4 sw=4 : */
262
/* 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