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

saitoha / libsixel / 20564600453

29 Dec 2025 03:58AM UTC coverage: 57.322% (-0.6%) from 57.909%
20564600453

push

github

saitoha
Merge branch 'tests/add_missing_tests' into develop

14331 of 44427 branches covered (32.26%)

4 of 9 new or added lines in 2 files covered. (44.44%)

3037 existing lines in 16 files now uncovered.

25159 of 43891 relevant lines covered (57.32%)

4506872.13 hits per line

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

90.29
/src/filter-encode.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 of
7
 * this software and associated documentation files (the "Software"), to deal in
8
 * the Software without restriction, including without limitation the rights to
9
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10
 * the Software, and to permit persons to whom the Software is furnished to do so,
11
 * subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in all
14
 * 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, FITNESS
18
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 */
23

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

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

31
#include <sixel.h>
32

33
#include "filter-encode.h"
34
#include "filter.h"
35
#include "output.h"
36
#include "pixelformat.h"
37
#include "status.h"
38

39
/*
40
 * Internal snapshot of the encode configuration. The filter copies the config
41
 * so the planner can build graphs without keeping caller-owned structs alive.
42
 */
43
typedef struct sixel_filter_encode_state {
44
    sixel_filter_encode_config_t config;
45
} sixel_filter_encode_state_t;
46

47
SIXELSTATUS
48
sixel_filter_encode_frame(const sixel_filter_encode_config_t *config,
6✔
49
                          sixel_frame_t *frame,
50
                          sixel_logger_t *logger)
51
{
52
    SIXELSTATUS status;
6✔
53
    sixel_output_t *output;
6✔
54
    int width;
6✔
55
    int height;
6✔
56
    int pixelformat;
6✔
57
    int depth;
6✔
58
    int frame_colorspace;
6✔
59
    unsigned char *pixels;
6✔
60

61
    status = SIXEL_FALSE;
6✔
62
    output = NULL;
6✔
63
    width = 0;
6✔
64
    height = 0;
6✔
65
    pixelformat = 0;
6✔
66
    depth = 0;
6✔
67
    frame_colorspace = SIXEL_COLORSPACE_GAMMA;
6✔
68
    pixels = NULL;
6✔
69

70
    if (config == NULL || frame == NULL) {
6!
71
        return SIXEL_BAD_ARGUMENT;
72
    }
73

74
    if (config->dither == NULL || config->output == NULL) {
6!
75
        return SIXEL_BAD_ARGUMENT;
76
    }
77

78
    output = config->output;
6✔
79
    pixelformat = sixel_frame_get_pixelformat(frame);
6✔
80
    frame_colorspace = sixel_frame_get_colorspace(frame);
6✔
81
    output->pixelformat = pixelformat;
6✔
82
    sixel_dither_set_pixelformat(config->dither, pixelformat);
6✔
83

84
    depth = sixel_helper_compute_depth(pixelformat);
6✔
85
    if (depth < 0) {
6!
UNCOV
86
        sixel_helper_set_additional_message(
×
87
            "sixel_filter_encode_frame: invalid pixelformat depth.");
88
        return SIXEL_LOGIC_ERROR;
×
89
    }
90

91
    width = sixel_frame_get_width(frame);
6✔
92
    height = sixel_frame_get_height(frame);
6✔
93
    if (width < 1 || height < 1) {
6!
UNCOV
94
        sixel_helper_set_additional_message(
×
95
            "sixel_filter_encode_frame: non-positive frame dimensions.");
96
        return SIXEL_BAD_ARGUMENT;
×
97
    }
98

99
    pixels = sixel_frame_get_pixels(frame);
6✔
100
    if (pixels == NULL) {
6!
UNCOV
101
        sixel_helper_set_additional_message(
×
102
            "sixel_filter_encode_frame: frame pixels are null.");
103
        return SIXEL_BAD_ARGUMENT;
×
104
    }
105

106
    if (logger != NULL) {
6!
UNCOV
107
        sixel_logger_logf(logger,
×
108
                          "filter",
109
                          "worker",
110
                          "encode-start",
111
                          -1,
112
                          -1,
113
                          0,
114
                          0,
115
                          width,
116
                          height,
117
                          "fmt=%08x depth=%d dst_cs=%d",
118
                          pixelformat,
119
                          depth,
120
                          frame_colorspace);
121
    }
122

123
    status = sixel_encode(pixels,
12✔
124
                          width,
1✔
125
                          height,
1✔
126
                          depth,
1✔
127
                          config->dither,
6✔
128
                          output);
1✔
129

130
    if (logger != NULL && SIXEL_SUCCEEDED(status)) {
6!
UNCOV
131
        sixel_logger_logf(logger,
×
132
                          "filter",
133
                          "worker",
134
                          "encode-finish",
135
                          -1,
136
                          -1,
137
                          0,
138
                          0,
139
                          width,
140
                          height,
141
                          "fmt=%08x depth=%d dst_cs=%d",
142
                          pixelformat,
143
                          depth,
144
                          frame_colorspace);
145
    }
146

147
    return status;
1✔
148
}
1✔
149

150
static SIXELSTATUS
151
sixel_filter_encode_apply(sixel_filter_t *filter,
6✔
152
                          sixel_allocator_t *allocator,
153
                          sixel_logger_t *logger)
154
{
155
    SIXELSTATUS status;
6✔
156
    sixel_filter_encode_state_t *state;
6✔
157
    sixel_frame_t *frame;
6✔
158
    int height;
6✔
159

160
    (void)allocator;
6✔
161

162
    status = SIXEL_FALSE;
6✔
163
    state = NULL;
6✔
164
    frame = NULL;
6✔
165
    height = 0;
6✔
166

167
    if (filter == NULL) {
6!
168
        return SIXEL_BAD_ARGUMENT;
169
    }
170

171
    state = (sixel_filter_encode_state_t *)filter->userdata;
6✔
172
    if (state == NULL) {
6!
173
        return SIXEL_BAD_ARGUMENT;
174
    }
175

176
    if (filter->input.slot == NULL || filter->input.slot[0] == NULL) {
6!
177
        return SIXEL_BAD_ARGUMENT;
178
    }
179

180
    frame = filter->input.slot[0];
6✔
181
    height = sixel_frame_get_height(frame);
6✔
182
    if (height < 0) {
6!
183
        height = 0;
184
    }
185

186
    status = sixel_filter_encode_frame(&state->config, frame, logger);
6✔
187
    if (SIXEL_SUCCEEDED(status)) {
6!
188
        filter->progress.total_units = height;
6✔
189
        filter->progress.completed_units = height;
6✔
190
        (void)sixel_filter_update_progress(filter, height);
6✔
191
    }
1✔
192

193
    return status;
1✔
194
}
1✔
195

196
static void
197
sixel_filter_encode_dispose(sixel_filter_t *filter)
6✔
198
{
199
    sixel_filter_encode_state_t *state;
6✔
200

201
    state = NULL;
6✔
202
    if (filter == NULL) {
6!
203
        return;
204
    }
205

206
    state = (sixel_filter_encode_state_t *)filter->userdata;
6✔
207
    if (state != NULL) {
6!
208
        free(state);
6✔
209
        filter->userdata = NULL;
6✔
210
    }
1✔
211
}
1!
212

213
SIXELSTATUS
214
sixel_filter_encode_init(sixel_filter_t *filter,
6✔
215
                         const sixel_filter_encode_config_t *config)
216
{
217
    SIXELSTATUS status;
6✔
218
    sixel_filter_encode_state_t *state;
6✔
219

220
    status = SIXEL_FALSE;
6✔
221
    state = NULL;
6✔
222

223
    if (filter == NULL || config == NULL) {
6!
224
        return SIXEL_BAD_ARGUMENT;
225
    }
226

227
    state = (sixel_filter_encode_state_t *)calloc(
6✔
228
        1u, sizeof(sixel_filter_encode_state_t));
229
    if (state == NULL) {
6!
230
        return SIXEL_BAD_ALLOCATION;
231
    }
232

233
    state->config = *config;
6✔
234

235
    status = sixel_filter_init(filter,
7✔
236
                               "encode",
237
                               SIXEL_FILTER_KIND_ENCODE,
238
                               sixel_filter_encode_apply,
239
                               sixel_filter_encode_dispose,
240
                               state);
1✔
241
    if (SIXEL_FAILED(status)) {
6!
UNCOV
242
        free(state);
×
UNCOV
243
        return status;
×
244
    }
245

246
    filter->flags |= SIXEL_FILTER_FLAG_PIPELINED;
6✔
247
    filter->progress.total_units = 0;
6✔
248
    filter->progress.completed_units = 0;
6✔
249

250
    return SIXEL_OK;
6✔
251
}
1✔
252

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

© 2025 Coveralls, Inc