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

saitoha / libsixel / 21595936620

02 Feb 2026 03:21PM UTC coverage: 77.477% (+0.02%) from 77.455%
21595936620

push

github

saitoha
fix: fix msvc warning C4702 unreachable code

23670 of 50520 branches covered (46.85%)

37666 of 48616 relevant lines covered (77.48%)

40018921.43 hits per line

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

83.33
/src/loader-common.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
8
 * of this software and associated documentation files (the "Software"), to
9
 * deal in the Software without restriction, including without limitation the
10
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11
 * sell copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all 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,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
 * DEALINGS IN THE SOFTWARE.
24
 *
25
 * Shared loader helpers used across backend implementations.  This module
26
 * centralizes trace logging, thumbnail size hints, and small detection
27
 * helpers so backend files stay narrow and platform headers remain isolated.
28
 */
29

30
#if defined(HAVE_CONFIG_H)
31
#include "config.h"
32
#endif
33

34
#include <stdio.h>
35
#include <stdlib.h>
36

37
#if HAVE_STRING_H
38
# include <string.h>
39
#endif
40
#if HAVE_STDARG_H
41
# include <stdarg.h>
42
#endif
43
#if HAVE_LIMITS_H
44
# include <limits.h>
45
#endif
46
#if HAVE_ERRNO_H
47
# include <errno.h>
48
#endif
49

50
#include <sixel.h>
51

52
#include "compat_stub.h"
53
#include "loader-common.h"
54
#include "logger.h"
55

56
static int loader_trace_enabled;
57
static int thumbnailer_default_size_hint = SIXEL_THUMBNAILER_DEFAULT_SIZE;
58
static int thumbnailer_size_hint = SIXEL_THUMBNAILER_DEFAULT_SIZE;
59
static int thumbnailer_size_hint_initialized;
60

61
void
62
loader_thumbnailer_initialize_size_hint(void)
4,067✔
63
{
64
    char const *env_value;
3,031✔
65
    char *endptr;
3,031✔
66
    long parsed;
3,031✔
67

68
    if (thumbnailer_size_hint_initialized) {
4,067✔
69
        return;
2,252✔
70
    }
71

72
    thumbnailer_size_hint_initialized = 1;
3,768✔
73
    thumbnailer_default_size_hint = SIXEL_THUMBNAILER_DEFAULT_SIZE;
3,768✔
74
    thumbnailer_size_hint = thumbnailer_default_size_hint;
3,768✔
75

76
    env_value = sixel_compat_getenv("SIXEL_THUMBNAILER_HINT_SIZE");
3,768✔
77
    if (env_value == NULL || env_value[0] == '\0') {
3,768!
78
        return;
1,815✔
79
    }
80

81
    errno = 0;
×
82
    parsed = strtol(env_value, &endptr, 10);
×
83
    if (errno != 0) {
×
84
        return;
85
    }
86
    if (endptr == env_value || *endptr != '\0') {
×
87
        return;
88
    }
89
    if (parsed <= 0) {
×
90
        return;
91
    }
92
    if (parsed > (long)INT_MAX) {
×
93
        parsed = (long)INT_MAX;
94
    }
95

96
    thumbnailer_default_size_hint = (int)parsed;
×
97
    thumbnailer_size_hint = thumbnailer_default_size_hint;
×
98
}
2,002!
99

100
int
101
loader_thumbnailer_get_size_hint(void)
47✔
102
{
103
    loader_thumbnailer_initialize_size_hint();
47✔
104

105
    return thumbnailer_size_hint;
47✔
106
}
107

108
int
109
loader_thumbnailer_get_default_size_hint(void)
×
110
{
111
    loader_thumbnailer_initialize_size_hint();
×
112

113
    return thumbnailer_default_size_hint;
×
114
}
115

116
void
117
sixel_helper_set_loader_trace(int enable)
4,142✔
118
{
119
    loader_trace_enabled = enable ? 1 : 0;
4,142✔
120
}
4,142✔
121

122
void
123
sixel_helper_set_thumbnail_size_hint(int size)
3,967✔
124
{
125
    loader_thumbnailer_initialize_size_hint();
3,967✔
126

127
    if (size > 0) {
3,967✔
128
        thumbnailer_size_hint = size;
560✔
129
    } else {
279✔
130
        thumbnailer_size_hint = thumbnailer_default_size_hint;
3,407✔
131
    }
132
}
3,967✔
133

134
void
135
loader_trace_message(char const *format, ...)
578✔
136
{
137
    va_list args;
419✔
138

139
    if (!loader_trace_enabled) {
578✔
140
        return;
365✔
141
    }
142

143
    fprintf(stderr, "libsixel: ");
213✔
144

145
    va_start(args, format);
213✔
146
    sixel_compat_vfprintf(stderr, format, args);
213✔
147
    va_end(args);
213✔
148

149
    fprintf(stderr, "\n");
213✔
150
}
348!
151

152
void
153
loader_trace_try(char const *name)
7,935✔
154
{
155
    if (loader_trace_enabled) {
7,935✔
156
        fprintf(stderr, "libsixel: trying %s loader\n", name);
169✔
157
    }
78✔
158
}
7,935✔
159

160
void
161
loader_trace_result(char const *name, SIXELSTATUS status)
7,935✔
162
{
163
    if (!loader_trace_enabled) {
7,935✔
164
        return;
3,734✔
165
    }
166
    if (SIXEL_SUCCEEDED(status)) {
169!
167
        fprintf(stderr, "libsixel: loader %s succeeded\n", name);
169✔
168
    } else {
78✔
169
        fprintf(stderr, "libsixel: loader %s failed (%s)\n",
×
170
                name, sixel_helper_format_error(status));
171
    }
172
}
3,770✔
173

174
int
175
loader_trace_is_enabled(void)
6,332✔
176
{
177
    return loader_trace_enabled;
6,332✔
178
}
179

180
int
181
chunk_is_png(sixel_chunk_t const *chunk)
3,222✔
182
{
183
    if (chunk == NULL || chunk->size < 8) {
3,222!
184
        return 0;
15✔
185
    }
186

187
    /*
188
     * PNG streams begin with an 8-byte signature.  Checking the fixed magic
189
     * sequence keeps the detection fast and avoids depending on libpng
190
     * helpers when only the signature is needed.
191
     */
192
    if (chunk->buffer[0] == (unsigned char)0x89 &&
4,574!
193
        chunk->buffer[1] == 'P' &&
2,401!
194
        chunk->buffer[2] == 'N' &&
2,401!
195
        chunk->buffer[3] == 'G' &&
2,401!
196
        chunk->buffer[4] == (unsigned char)0x0d &&
2,401!
197
        chunk->buffer[5] == (unsigned char)0x0a &&
2,401!
198
        chunk->buffer[6] == (unsigned char)0x1a &&
2,401!
199
        chunk->buffer[7] == (unsigned char)0x0a) {
2,401!
200
        return 1;
2,401✔
201
    }
202

203
    return 0;
625✔
204
}
2,019✔
205

206
int
207
chunk_is_jpeg(sixel_chunk_t const *chunk)
503✔
208
{
209
    if (chunk == NULL || chunk->size < 2) {
503!
210
        return 0;
211
    }
212

213
    /*
214
     * JPEG files start with SOI (Start of Image) marker 0xFF 0xD8.  The GD
215
     * loader uses this to decide whether libgd should attempt JPEG decoding.
216
     */
217
    if (chunk->buffer[0] == (unsigned char)0xff &&
503!
218
        chunk->buffer[1] == (unsigned char)0xd8) {
47!
219
        return 1;
47✔
220
    }
221

222
    return 0;
456✔
223
}
503✔
224

225
int
226
chunk_is_webp(sixel_chunk_t const *chunk)
1,146✔
227
{
228
    if (chunk == NULL || chunk->size < 12) {
1,146!
229
        return 0;
3✔
230
    }
231

232
    /*
233
     * WebP files use a RIFF container.  The stream starts with \"RIFF\",
234
     * followed by a 32-bit size field, and then the literal \"WEBP\" tag.
235
     */
236
    if (chunk->buffer[0] == 'R' &&
1,143!
237
        chunk->buffer[1] == 'I' &&
×
238
        chunk->buffer[2] == 'F' &&
×
239
        chunk->buffer[3] == 'F' &&
×
240
        chunk->buffer[8] == 'W' &&
×
241
        chunk->buffer[9] == 'E' &&
×
242
        chunk->buffer[10] == 'B' &&
×
243
        chunk->buffer[11] == 'P') {
×
244
        return 1;
×
245
    }
246

247
    return 0;
1,143✔
248
}
1,146✔
249

250
int
251
chunk_is_bmp(sixel_chunk_t const *chunk)
18✔
252
{
253
    if (chunk == NULL || chunk->size < 2) {
18!
254
        return 0;
255
    }
256

257
    /* BMP headers begin with the literal characters 'B' 'M'. */
258
    if (chunk->buffer[0] == 'B' && chunk->buffer[1] == 'M') {
18!
259
        return 1;
1✔
260
    }
261

262
    return 0;
17✔
263
}
18✔
264

265
int
266
chunk_is_gif(sixel_chunk_t const *chunk)
4,672✔
267
{
268
    if (chunk->size < 6) {
4,672✔
269
        return 0;
12✔
270
    }
271
    if (chunk->buffer[0] == 'G' &&
4,722!
272
        chunk->buffer[1] == 'I' &&
187!
273
        chunk->buffer[2] == 'F' &&
187!
274
        chunk->buffer[3] == '8' &&
187!
275
        (chunk->buffer[4] == '7' || chunk->buffer[4] == '9') &&
187!
276
        chunk->buffer[5] == 'a') {
187!
277
        return 1;
187✔
278
    }
279
    return 0;
1,703✔
280
}
1,751✔
281

282
/* emacs Local Variables:      */
283
/* emacs mode: c               */
284
/* emacs tab-width: 4          */
285
/* emacs indent-tabs-mode: nil */
286
/* emacs c-basic-offset: 4     */
287
/* emacs End:                  */
288
/* vim: set expandtab ts=4 sts=4 sw=4 : */
289
/* 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