Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions converters/img2sixel.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ void show_help(void)
" pass-through sequence\n"
"-D, --pipe-mode [[deprecated]] read source images from\n"
" stdin continuously\n"
"-O, --ormode output ormode sixel image\n"
"-v, --verbose show debugging info\n"
"-V, --version show version and license info\n"
"-H, --help show this help\n"
Expand Down Expand Up @@ -347,7 +348,7 @@ main(int argc, char *argv[])
int long_opt;
int option_index;
#endif /* HAVE_GETOPT_LONG */
char const *optstring = "o:78Rp:m:eb:Id:f:s:c:w:h:r:q:kil:t:ugvSn:PE:B:C:DVH";
char const *optstring = "o:78ORp:m:eb:Id:f:s:c:w:h:r:q:kil:t:ugvSn:PE:B:C:DVH";
#if HAVE_GETOPT_LONG
struct option long_options[] = {
{"outfile", no_argument, &long_opt, 'o'},
Expand Down Expand Up @@ -381,6 +382,7 @@ main(int argc, char *argv[])
{"bgcolor", required_argument, &long_opt, 'B'},
{"complexion-score", required_argument, &long_opt, 'C'},
{"pipe-mode", no_argument, &long_opt, 'D'}, /* deprecated */
{"ormode", no_argument, &long_opt, 'O'},
{"version", no_argument, &long_opt, 'V'},
{"help", no_argument, &long_opt, 'H'},
{0, 0, 0, 0}
Expand Down Expand Up @@ -467,7 +469,7 @@ main(int argc, char *argv[])

argerr:
fprintf(stderr,
"usage: img2sixel [-78eIkiugvSPDVH] [-p colors] [-m file] [-d diffusiontype]\n"
"usage: img2sixel [-78eIkiugvSPDOVH] [-p colors] [-m file] [-d diffusiontype]\n"
" [-f findtype] [-s selecttype] [-c geometory] [-w width]\n"
" [-h height] [-r resamplingtype] [-q quality] [-l loopmode]\n"
" [-t palettetype] [-n macronumber] [-C score] [-b palette]\n"
Expand Down
8 changes: 8 additions & 0 deletions include/sixel.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ typedef int SIXELSTATUS;
size -> encode to as small sixel
sequence as possible
*/
#define SIXEL_OPTFLAG_ORMODE ('O') /* -O, --ormode:
output ormode sixel image
*/
#define SIXEL_OPTFLAG_BGCOLOR ('B') /* -B BGCOLOR, --bgcolor=BGCOLOR:
specify background color
BGCOLOR is represented by the
Expand Down Expand Up @@ -645,6 +648,11 @@ sixel_output_set_palette_type(
int /* in */ palettetype); /* PALETTETYPE_RGB: RGB palette
PALETTETYPE_HLS: HLS palette */

SIXELAPI void
sixel_output_set_ormode(
sixel_output_t /* in */ *output, /* output context */
int /* in */ ormode);

/* set encodeing policy: auto, fast or size */
SIXELAPI void
sixel_output_set_encode_policy(
Expand Down
5 changes: 5 additions & 0 deletions src/encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,7 @@ sixel_encoder_encode_frame(
sixel_output_set_penetrate_multiplexer(
output, encoder->penetrate_multiplexer);
sixel_output_set_encode_policy(output, encoder->encode_policy);
sixel_output_set_ormode(output, encoder->ormode);

if (sixel_frame_get_multiframe(frame) && !encoder->fstatic) {
if (sixel_frame_get_loop_no(frame) != 0 || sixel_frame_get_frame_no(frame) != 0) {
Expand Down Expand Up @@ -1147,6 +1148,7 @@ sixel_encoder_new(
(*ppencoder)->verbose = 0;
(*ppencoder)->penetrate_multiplexer = 0;
(*ppencoder)->encode_policy = SIXEL_ENCODEPOLICY_AUTO;
(*ppencoder)->ormode = 0;
(*ppencoder)->pipe_mode = 0;
(*ppencoder)->bgcolor = NULL;
(*ppencoder)->outfd = STDOUT_FILENO;
Expand Down Expand Up @@ -1605,6 +1607,9 @@ sixel_encoder_setopt(
goto end;
}
break;
case SIXEL_OPTFLAG_ORMODE: /* O */
encoder->ormode = 1;
break;
case SIXEL_OPTFLAG_COMPLEXION_SCORE: /* C */
encoder->complexion = atoi(value);
if (encoder->complexion < 1) {
Expand Down
1 change: 1 addition & 0 deletions src/encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct sixel_encoder {
int macro_number;
int penetrate_multiplexer;
int encode_policy;
int ormode;
int pipe_mode;
int verbose;
int has_gri_arg_limit;
Expand Down
8 changes: 8 additions & 0 deletions src/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ sixel_output_new(
(*output)->pos = 0;
(*output)->penetrate_multiplexer = 0;
(*output)->encode_policy = SIXEL_ENCODEPOLICY_AUTO;
(*output)->ormode = 0;
(*output)->allocator = allocator;

status = SIXEL_OK;
Expand Down Expand Up @@ -193,6 +194,13 @@ sixel_output_set_palette_type(sixel_output_t *output, int palettetype)
}


SIXELAPI void
sixel_output_set_ormode(sixel_output_t *output, int ormode)
{
output->ormode = ormode;
}


/* set encodeing policy: auto, fast or size */
SIXELAPI void
sixel_output_set_encode_policy(sixel_output_t *output, int encode_policy)
Expand Down
1 change: 1 addition & 0 deletions src/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct sixel_output {

int penetrate_multiplexer;
int encode_policy;
int ormode;

void *priv;
int pos;
Expand Down
142 changes: 131 additions & 11 deletions src/tosixel.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,11 @@ sixel_encode_header(int width, int height, sixel_output_t *output)
int pcount = 3;
int use_raster_attributes = 1;

if (output->ormode) {
p[0] = 7;
p[1] = 5;
}

output->pos = 0;

if (!output->skip_dcs_envelope) {
Expand Down Expand Up @@ -508,7 +513,6 @@ sixel_encode_body(
int sx;
int mx;
int len;
int pix;
char *map = NULL;
int check_integer_overflow;
sixel_node_t *np, *tp, top;
Expand Down Expand Up @@ -550,6 +554,8 @@ sixel_encode_body(
}

for (y = i = 0; y < height; y++) {
int pix;

if (output->encode_policy != SIXEL_ENCODEPOLICY_SIZE) {
fillable = 0;
} else if (palstate) {
Expand Down Expand Up @@ -780,6 +786,109 @@ sixel_encode_footer(sixel_output_t *output)
return status;
}

static SIXELSTATUS
sixel_encode_body_ormode(
uint8_t /* in */ *pixels,
int /* in */ width,
int /* in */ height,
unsigned char /* in */ *palette,
int /* in */ ncolors,
int /* in */ keycolor,
sixel_output_t /* in */ *output)
{
SIXELSTATUS status;
int n;
int nplanes;
uint8_t *buf = pixels;
uint8_t *buf_p;
int x;
int cur_h;
int nwrite;
int plane;

for (n = 0; n < ncolors; n++) {
status = output_rgb_palette_definition(output, palette, n, keycolor);
if (SIXEL_FAILED(status)) {
return status;
}
}

for (nplanes = 8; nplanes > 1; nplanes--) {
if (ncolors > (1 << (nplanes - 1))) {
break;
}
}

for (cur_h = 6; cur_h <= height; cur_h += 6) {
for (plane = 0; plane < nplanes; plane++) {
sixel_putc(output->buffer + output->pos, '#');
sixel_advance(output, 1);
nwrite = sixel_putnum((char *)output->buffer + output->pos, 1 << plane);
sixel_advance(output, nwrite);

buf_p = buf;
for (x = 0; x < width; x++, buf_p++) {
sixel_put_pixel(output,
((buf_p[0] >> plane) & 0x1) |
(((buf_p[width] >> plane) << 1) & 0x2) |
(((buf_p[width * 2] >> plane) << 2) & 0x4) |
(((buf_p[width * 3] >> plane) << 3) & 0x8) |
(((buf_p[width * 4] >> plane) << 4) & 0x10) |
(((buf_p[width * 5] >> plane) << 5) & 0x20));
}
status = sixel_put_flash(output);
if (SIXEL_FAILED(status)) {
return status;
}
sixel_putc(output->buffer + output->pos, '$');
sixel_advance(output, 1);
}
sixel_putc(output->buffer + output->pos, '-');
sixel_advance(output, 1);
buf += (width * 6);
}

if (cur_h > height) {
for (plane = 0; plane < nplanes; plane++) {
sixel_putc(output->buffer + output->pos, '#');
sixel_advance(output, 1);
nwrite = sixel_putnum((char *)output->buffer + output->pos, 1 << plane);
sixel_advance(output, nwrite);

buf_p = buf;
for (x = 0; x < width; x++) {
int pix = ((buf_p[0] >> plane) & 0x1);

switch(cur_h - height) {
case 1:
pix |= (((buf_p[width * 4] >> plane) << 4) & 0x10);
/* Fall through */
case 2:
pix |= (((buf_p[width * 3] >> plane) << 3) & 0x8);
/* Fall through */
case 3:
pix |= (((buf_p[width * 2] >> plane) << 2) & 0x4);
/* Fall through */
case 4:
pix |= (((buf_p[width] >> plane) << 1) & 0x2);
/* Fall through */
}

sixel_put_pixel(output, pix);
}
status = sixel_put_flash(output);
if (SIXEL_FAILED(status)) {
return status;
}

sixel_putc(output->buffer + output->pos, '$');
sixel_advance(output, 1);
}
}

return 0;
}


static SIXELSTATUS
sixel_encode_dither(
Expand Down Expand Up @@ -842,16 +951,27 @@ sixel_encode_dither(
goto end;
}

status = sixel_encode_body(input_pixels,
width,
height,
dither->palette,
dither->ncolors,
dither->keycolor,
dither->bodyonly,
output,
NULL,
dither->allocator);
if (output->ormode) {
status = sixel_encode_body_ormode(input_pixels,
width,
height,
dither->palette,
dither->ncolors,
dither->keycolor,
output);
} else {
status = sixel_encode_body(input_pixels,
width,
height,
dither->palette,
dither->ncolors,
dither->keycolor,
dither->bodyonly,
output,
NULL,
dither->allocator);
}

if (SIXEL_FAILED(status)) {
goto end;
}
Expand Down