master ohmu/fastfetch-openbsd / src / 3rdparty / sixel / output.c
ohmu  ·  2026-10-15
  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 HAVE_ASSERT_H
 29# include <assert.h>
 30#endif  /* HAVE_ASSERT_H */
 31
 32#include <sixel.h>
 33#include "output.h"
 34
 35
 36/* create new output context object */
 37SIXELAPI SIXELSTATUS
 38sixel_output_new(
 39    sixel_output_t          /* out */ **output,
 40    sixel_write_function    /* in */  fn_write,
 41    void                    /* in */  *priv,
 42    sixel_allocator_t       /* in */  *allocator)
 43{
 44    SIXELSTATUS status = SIXEL_FALSE;
 45    size_t size;
 46
 47    if (allocator == NULL) {
 48        status = sixel_allocator_new(&allocator, NULL, NULL, NULL, NULL);
 49        if (SIXEL_FAILED(status)) {
 50            goto end;
 51        }
 52    } else {
 53        sixel_allocator_ref(allocator);
 54    }
 55    size = sizeof(sixel_output_t) + SIXEL_OUTPUT_PACKET_SIZE * 2;
 56
 57    *output = (sixel_output_t *)sixel_allocator_malloc(allocator, size);
 58    if (*output == NULL) {
 59        sixel_helper_set_additional_message(
 60            "sixel_output_new: sixel_allocator_malloc() failed.");
 61        status = SIXEL_BAD_ALLOCATION;
 62        sixel_allocator_unref(allocator);
 63        goto end;
 64    }
 65
 66    (*output)->ref = 1;
 67    (*output)->has_8bit_control = 0;
 68    (*output)->has_sdm_glitch = 0;
 69    (*output)->has_gri_arg_limit = 1;
 70    (*output)->skip_dcs_envelope = 0;
 71    (*output)->palette_type = SIXEL_PALETTETYPE_AUTO;
 72    (*output)->fn_write = fn_write;
 73    (*output)->save_pixel = 0;
 74    (*output)->save_count = 0;
 75    (*output)->active_palette = (-1);
 76    (*output)->node_top = NULL;
 77    (*output)->node_free = NULL;
 78    (*output)->priv = priv;
 79    (*output)->pos = 0;
 80    (*output)->penetrate_multiplexer = 0;
 81    (*output)->encode_policy = SIXEL_ENCODEPOLICY_AUTO;
 82    (*output)->allocator = allocator;
 83
 84    status = SIXEL_OK;
 85
 86end:
 87    return status;
 88}
 89
 90
 91/* deprecated: create an output object */
 92SIXELAPI sixel_output_t *
 93sixel_output_create(sixel_write_function fn_write, void *priv)
 94{
 95    SIXELSTATUS status = SIXEL_FALSE;
 96    sixel_output_t *output = NULL;
 97
 98    status = sixel_output_new(&output, fn_write, priv, NULL);
 99    if (SIXEL_FAILED(status)) {
100        goto end;
101    }
102
103end:
104    return output;
105}
106
107
108/* destroy output context object */
109SIXELAPI void
110sixel_output_destroy(sixel_output_t *output)
111{
112    sixel_allocator_t *allocator;
113
114    if (output) {
115        allocator = output->allocator;
116        sixel_allocator_free(allocator, output);
117        sixel_allocator_unref(allocator);
118    }
119}
120
121
122/* increase reference count of output context object (thread-unsafe) */
123SIXELAPI void
124sixel_output_ref(sixel_output_t *output)
125{
126    /* TODO: be thread-safe */
127    ++output->ref;
128}
129
130
131/* decrease reference count of output context object (thread-unsafe) */
132SIXELAPI void
133sixel_output_unref(sixel_output_t *output)
134{
135    /* TODO: be thread-safe */
136    if (output) {
137        assert(output->ref > 0);
138        output->ref--;
139        if (output->ref == 0) {
140            sixel_output_destroy(output);
141        }
142    }
143}
144
145
146/* get 8bit output mode which indicates whether it uses C1 control characters */
147SIXELAPI int
148sixel_output_get_8bit_availability(sixel_output_t *output)
149{
150    return output->has_8bit_control;
151}
152
153
154/* set 8bit output mode state */
155SIXELAPI void
156sixel_output_set_8bit_availability(sixel_output_t *output, int availability)
157{
158    output->has_8bit_control = availability;
159}
160
161
162/* set whether limit arguments of DECGRI('!') to 255 */
163SIXELAPI void
164sixel_output_set_gri_arg_limit(
165    sixel_output_t /* in */ *output, /* output context */
166    int            /* in */ value)   /* 0: don't limit arguments of DECGRI
167                                        1: limit arguments of DECGRI to 255 */
168{
169    output->has_gri_arg_limit = value;
170}
171
172
173/* set GNU Screen penetration feature enable or disable */
174SIXELAPI void
175sixel_output_set_penetrate_multiplexer(sixel_output_t *output, int penetrate)
176{
177    output->penetrate_multiplexer = penetrate;
178}
179
180
181/* set whether we skip DCS envelope */
182SIXELAPI void
183sixel_output_set_skip_dcs_envelope(sixel_output_t *output, int skip)
184{
185    output->skip_dcs_envelope = skip;
186}
187
188
189/* set palette type: RGB or HLS */
190SIXELAPI void
191sixel_output_set_palette_type(sixel_output_t *output, int palettetype)
192{
193    output->palette_type = palettetype;
194}
195
196
197/* set encodeing policy: auto, fast or size */
198SIXELAPI void
199sixel_output_set_encode_policy(sixel_output_t *output, int encode_policy)
200{
201    output->encode_policy = encode_policy;
202}
203
204/* emacs Local Variables:      */
205/* emacs mode: c               */
206/* emacs tab-width: 4          */
207/* emacs indent-tabs-mode: nil */
208/* emacs c-basic-offset: 4     */
209/* emacs End:                  */
210/* vim: set expandtab ts=4 sts=4 sw=4 : */
211/* EOF */