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

saitoha / libsixel / 19918707358

04 Dec 2025 05:12AM UTC coverage: 38.402% (-4.0%) from 42.395%
19918707358

push

github

saitoha
tests: fix meson msys dll lookup

9738 of 38220 branches covered (25.48%)

12841 of 33438 relevant lines covered (38.4%)

782420.02 hits per line

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

57.83
/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
#include "config.h"
31

32
#include <stdio.h>
33
#include <stdlib.h>
34

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

48
#include <sixel.h>
49

50
#include "loader-common.h"
51
#include "logger.h"
52

53
static int loader_trace_enabled;
54
static int thumbnailer_default_size_hint = SIXEL_THUMBNAILER_DEFAULT_SIZE;
55
static int thumbnailer_size_hint = SIXEL_THUMBNAILER_DEFAULT_SIZE;
56
static int thumbnailer_size_hint_initialized;
57

58
void
59
loader_thumbnailer_initialize_size_hint(void)
453✔
60
{
61
    char const *env_value;
453✔
62
    char *endptr;
453✔
63
    long parsed;
453✔
64

65
    if (thumbnailer_size_hint_initialized) {
453✔
66
        return;
453✔
67
    }
68

69
    thumbnailer_size_hint_initialized = 1;
432✔
70
    thumbnailer_default_size_hint = SIXEL_THUMBNAILER_DEFAULT_SIZE;
432✔
71
    thumbnailer_size_hint = thumbnailer_default_size_hint;
432✔
72

73
    env_value = getenv("SIXEL_THUMBNAILER_HINT_SIZE");
432✔
74
    if (env_value == NULL || env_value[0] == '\0') {
432!
75
        return;
76
    }
77

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

93
    thumbnailer_default_size_hint = (int)parsed;
×
94
    thumbnailer_size_hint = thumbnailer_default_size_hint;
×
95
}
1!
96

97
int
98
loader_thumbnailer_get_size_hint(void)
×
99
{
100
    loader_thumbnailer_initialize_size_hint();
×
101

102
    return thumbnailer_size_hint;
×
103
}
104

105
int
106
loader_thumbnailer_get_default_size_hint(void)
×
107
{
108
    loader_thumbnailer_initialize_size_hint();
×
109

110
    return thumbnailer_default_size_hint;
×
111
}
112

113
void
114
sixel_helper_set_loader_trace(int enable)
462✔
115
{
116
    loader_trace_enabled = enable ? 1 : 0;
462✔
117
}
462✔
118

119
void
120
sixel_helper_set_thumbnail_size_hint(int size)
453✔
121
{
122
    loader_thumbnailer_initialize_size_hint();
453✔
123

124
    if (size > 0) {
453✔
125
        thumbnailer_size_hint = size;
93✔
126
    } else {
127
        thumbnailer_size_hint = thumbnailer_default_size_hint;
360✔
128
    }
129
}
453✔
130

131
void
132
loader_trace_message(char const *format, ...)
18✔
133
{
134
    va_list args;
18✔
135

136
    if (!loader_trace_enabled) {
18✔
137
        return;
15✔
138
    }
139

140
    fprintf(stderr, "libsixel: ");
3✔
141

142
    va_start(args, format);
3✔
143
#if HAVE_DIAGNOSTIC_FORMAT_NONLITERAL
144
# if defined(__clang__)
145
#  pragma clang diagnostic push
146
#  pragma clang diagnostic ignored "-Wformat-nonliteral"
147
# elif defined(__GNUC__)
148
#  pragma GCC diagnostic push
149
#  pragma GCC diagnostic ignored "-Wformat-nonliteral"
150
# endif
151
#endif
152
    vfprintf(stderr, format, args);
3✔
153
#if HAVE_DIAGNOSTIC_FORMAT_NONLITERAL
154
# if defined(__clang__)
155
#  pragma clang diagnostic pop
156
# elif defined(__GNUC__)
157
#  pragma GCC diagnostic pop
158
# endif
159
#endif
160
    va_end(args);
3✔
161

162
    fprintf(stderr, "\n");
3✔
163
}
1!
164

165
void
166
loader_trace_try(char const *name)
450✔
167
{
168
    if (loader_trace_enabled) {
450✔
169
        fprintf(stderr, "libsixel: trying %s loader\n", name);
9✔
170
    }
171
}
450✔
172

173
void
174
loader_trace_result(char const *name, SIXELSTATUS status)
450✔
175
{
176
    if (!loader_trace_enabled) {
450✔
177
        return;
178
    }
179
    if (SIXEL_SUCCEEDED(status)) {
9!
180
        fprintf(stderr, "libsixel: loader %s succeeded\n", name);
9✔
181
    } else {
182
        fprintf(stderr, "libsixel: loader %s failed (%s)\n",
×
183
                name, sixel_helper_format_error(status));
184
    }
185
}
186

187
int
188
loader_trace_is_enabled(void)
156✔
189
{
190
    return loader_trace_enabled;
156✔
191
}
192

193
int
194
chunk_is_png(sixel_chunk_t const *chunk)
×
195
{
196
    if (chunk == NULL || chunk->size < 8) {
×
197
        return 0;
198
    }
199

200
    /*
201
     * PNG streams begin with an 8-byte signature.  Checking the fixed magic
202
     * sequence keeps the detection fast and avoids depending on libpng
203
     * helpers when only the signature is needed.
204
     */
205
    if (chunk->buffer[0] == (unsigned char)0x89 &&
×
206
        chunk->buffer[1] == 'P' &&
×
207
        chunk->buffer[2] == 'N' &&
×
208
        chunk->buffer[3] == 'G' &&
×
209
        chunk->buffer[4] == (unsigned char)0x0d &&
×
210
        chunk->buffer[5] == (unsigned char)0x0a &&
×
211
        chunk->buffer[6] == (unsigned char)0x1a &&
×
212
        chunk->buffer[7] == (unsigned char)0x0a) {
×
213
        return 1;
×
214
    }
215

216
    return 0;
217
}
218

219
int
220
chunk_is_jpeg(sixel_chunk_t const *chunk)
×
221
{
222
    if (chunk == NULL || chunk->size < 2) {
×
223
        return 0;
224
    }
225

226
    /*
227
     * JPEG files start with SOI (Start of Image) marker 0xFF 0xD8.  The GD
228
     * loader uses this to decide whether libgd should attempt JPEG decoding.
229
     */
230
    if (chunk->buffer[0] == (unsigned char)0xff &&
×
231
        chunk->buffer[1] == (unsigned char)0xd8) {
×
232
        return 1;
×
233
    }
234

235
    return 0;
236
}
237

238
int
239
chunk_is_bmp(sixel_chunk_t const *chunk)
×
240
{
241
    if (chunk == NULL || chunk->size < 2) {
×
242
        return 0;
243
    }
244

245
    /* BMP headers begin with the literal characters 'B' 'M'. */
246
    if (chunk->buffer[0] == 'B' && chunk->buffer[1] == 'M') {
×
247
        return 1;
×
248
    }
249

250
    return 0;
251
}
252

253
int
254
chunk_is_gif(sixel_chunk_t const *chunk)
264✔
255
{
256
    if (chunk->size < 6) {
264✔
257
        return 0;
258
    }
259
    if (chunk->buffer[0] == 'G' &&
261!
260
        chunk->buffer[1] == 'I' &&
21!
261
        chunk->buffer[2] == 'F' &&
21!
262
        chunk->buffer[3] == '8' &&
21!
263
        (chunk->buffer[4] == '7' || chunk->buffer[4] == '9') &&
21!
264
        chunk->buffer[5] == 'a') {
21!
265
        return 1;
21✔
266
    }
267
    return 0;
268
}
269

270
/* emacs Local Variables:      */
271
/* emacs mode: c               */
272
/* emacs tab-width: 4          */
273
/* emacs indent-tabs-mode: nil */
274
/* emacs c-basic-offset: 4     */
275
/* emacs End:                  */
276
/* vim: set expandtab ts=4 sts=4 sw=4 : */
277
/* 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