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

saitoha / libsixel / 20070897793

09 Dec 2025 04:31PM UTC coverage: 41.32% (-8.1%) from 49.384%
20070897793

push

github

saitoha
Merge branch 'perf/vpte' into develop

10821 of 40782 branches covered (26.53%)

18 of 1086 new or added lines in 6 files covered. (1.66%)

1395 existing lines in 42 files now uncovered.

14850 of 35939 relevant lines covered (41.32%)

2731560.64 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 "compat_stub.h"
51
#include "loader-common.h"
52
#include "logger.h"
53

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

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

66
    if (thumbnailer_size_hint_initialized) {
450✔
67
        return;
450✔
68
    }
69

70
    thumbnailer_size_hint_initialized = 1;
429✔
71
    thumbnailer_default_size_hint = SIXEL_THUMBNAILER_DEFAULT_SIZE;
429✔
72
    thumbnailer_size_hint = thumbnailer_default_size_hint;
429✔
73

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

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

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

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

UNCOV
103
    return thumbnailer_size_hint;
×
104
}
105

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

111
    return thumbnailer_default_size_hint;
×
112
}
113

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

120
void
121
sixel_helper_set_thumbnail_size_hint(int size)
450✔
122
{
123
    loader_thumbnailer_initialize_size_hint();
450✔
124

125
    if (size > 0) {
450✔
126
        thumbnailer_size_hint = size;
93✔
127
    } else {
128
        thumbnailer_size_hint = thumbnailer_default_size_hint;
357✔
129
    }
130
}
450✔
131

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

137
    if (!loader_trace_enabled) {
67✔
138
        return;
55✔
139
    }
140

141
    fprintf(stderr, "libsixel: ");
12✔
142

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

163
    fprintf(stderr, "\n");
12✔
164
}
1!
165

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

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

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

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

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

217
    return 0;
218
}
219

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

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

236
    return 0;
237
}
238

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

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

251
    return 0;
252
}
253

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

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