SIXELSTATUS sixel_chunk_new( sixel_chunk_t /* out */ **ppchunk, char const /* in */ *filename, int /* in */ finsecure, int const /* in */ *cancel_flag, sixel_allocator_t /* in */ *allocator) { SIXELSTATUS status = SIXEL_FALSE; if (ppchunk == NULL) { sixel_helper_set_additional_message( "sixel_chunk_new: ppchunk is null."); status = SIXEL_BAD_ARGUMENT; goto end; } if (allocator == NULL) { sixel_helper_set_additional_message( "sixel_chunk_new: allocator is null."); status = SIXEL_BAD_ARGUMENT; goto end; } *ppchunk = (sixel_chunk_t *)sixel_allocator_malloc(allocator, sizeof(sixel_chunk_t)); if (*ppchunk == NULL) { sixel_helper_set_additional_message( "sixel_chunk_new: sixel_allocator_malloc() failed."); status = SIXEL_BAD_ALLOCATION; goto end; } /* set allocator to chunk object */ (*ppchunk)->allocator = allocator; status = sixel_chunk_init(*ppchunk, 1024 * 32); if (SIXEL_FAILED(status)) { sixel_allocator_free(allocator, *ppchunk); *ppchunk = NULL; goto end; } sixel_allocator_ref(allocator); if (filename != NULL && strstr(filename, "://")) { status = sixel_chunk_from_url(filename, *ppchunk, finsecure); } else { status = sixel_chunk_from_file(filename, *ppchunk, cancel_flag); } if (SIXEL_FAILED(status)) { sixel_chunk_destroy(*ppchunk); *ppchunk = NULL; goto end; } status = SIXEL_OK; end: return status; }
static SIXELSTATUS output_sixel(unsigned char *pixbuf, int width, int height, int ncolors, int pixelformat) { sixel_output_t *context; sixel_dither_t *dither; SIXELSTATUS status; #if USE_OSMESA pixelformat = SIXEL_PIXELFORMAT_RGBA8888; #endif context = sixel_output_create(sixel_write, stdout); dither = sixel_dither_create(ncolors); status = sixel_dither_initialize(dither, pixbuf, width, height, pixelformat, SIXEL_LARGE_AUTO, SIXEL_REP_AUTO, SIXEL_QUALITY_AUTO); if (SIXEL_FAILED(status)) return status; status = sixel_encode(pixbuf, width, height, pixelformat, dither, context); if (SIXEL_FAILED(status)) return status; sixel_output_unref(context); sixel_dither_unref(dither); return status; }
static int test3(void) { int nret = EXIT_FAILURE; sixel_chunk_t *chunk; sixel_allocator_t *allocator = NULL; SIXELSTATUS status = SIXEL_FALSE; sixel_debug_malloc_counter = 1; status = sixel_allocator_new(&allocator, sixel_bad_malloc, NULL, NULL, NULL); if (SIXEL_FAILED(status)) { goto error; } status = sixel_chunk_new(&chunk, "../images/map8.six", 0, NULL, allocator); if (status != SIXEL_BAD_ALLOCATION) { goto error; } nret = EXIT_SUCCESS; error: return nret; }
/* create new output context object */ SIXELAPI SIXELSTATUS sixel_output_new( sixel_output_t /* out */ **output, sixel_write_function /* in */ fn_write, void /* in */ *priv, sixel_allocator_t /* in */ *allocator) { SIXELSTATUS status = SIXEL_FALSE; size_t size; if (allocator == NULL) { status = sixel_allocator_new(&allocator, NULL, NULL, NULL, NULL); if (SIXEL_FAILED(status)) { goto end; } } else { sixel_allocator_ref(allocator); } size = sizeof(sixel_output_t) + SIXEL_OUTPUT_PACKET_SIZE * 2; *output = (sixel_output_t *)sixel_allocator_malloc(allocator, size); if (*output == NULL) { sixel_helper_set_additional_message( "sixel_output_new: sixel_allocator_malloc() failed."); status = SIXEL_BAD_ALLOCATION; goto end; } (*output)->ref = 1; (*output)->has_8bit_control = 0; (*output)->has_sdm_glitch = 0; (*output)->has_gri_arg_limit = 1; (*output)->skip_dcs_envelope = 0; (*output)->palette_type = SIXEL_PALETTETYPE_AUTO; (*output)->fn_write = fn_write; (*output)->save_pixel = 0; (*output)->save_count = 0; (*output)->active_palette = (-1); (*output)->node_top = NULL; (*output)->node_free = NULL; (*output)->priv = priv; (*output)->pos = 0; (*output)->penetrate_multiplexer = 0; (*output)->encode_policy = SIXEL_ENCODEPOLICY_AUTO; (*output)->allocator = allocator; status = SIXEL_OK; end: return status; }
/* deprecated: create an output object */ SIXELAPI sixel_output_t * sixel_output_create(sixel_write_function fn_write, void *priv) { SIXELSTATUS status = SIXEL_FALSE; sixel_output_t *output = NULL; status = sixel_output_new(&output, fn_write, priv, NULL); if (SIXEL_FAILED(status)) { goto end; } end: return output; }
/* create dither context object (deprecated) */ SIXELAPI sixel_dither_t * sixel_dither_create( int /* in */ ncolors) { SIXELSTATUS status = SIXEL_FALSE; sixel_dither_t *dither = NULL; status = sixel_dither_new(&dither, ncolors, NULL); if (SIXEL_FAILED(status)) { goto end; } end: return dither; }
static VALUE sixel_ruby_encoder_alloc(VALUE klass) { sixel_encoder_t *encoder; SIXELSTATUS status; status = sixel_encoder_new(&encoder, NULL); if (SIXEL_FAILED(status)) { rb_raise(rb_eRuntimeError, "sixel_encoder_new() failed: %s / %s", sixel_helper_format_error(status), sixel_helper_get_additional_message()); } return Data_Wrap_Struct(klass, NULL, sixel_ruby_encoder_free, encoder); }
static VALUE sixel_ruby_encoder_encode(VALUE self, VALUE filename) { sixel_encoder_t *encoder; SIXELSTATUS status; Data_Get_Struct(self, sixel_encoder_t, encoder); status = sixel_encoder_encode(encoder, StringValueCStr(filename)); if (SIXEL_FAILED(status)) { rb_raise(rb_eRuntimeError, "sixel_encoder_encode() failed: %s / %s", sixel_helper_format_error(status), sixel_helper_get_additional_message()); } return Qnil; }
static VALUE sixel_ruby_decoder_decode(VALUE self) { sixel_decoder_t *decoder; SIXELSTATUS status; Data_Get_Struct(self, sixel_decoder_t, decoder); status = sixel_decoder_decode(decoder); if (SIXEL_FAILED(status)) { rb_raise(rb_eRuntimeError, "sixel_decoder_decode() failed: %s / %s", sixel_helper_format_error(status), sixel_helper_get_additional_message()); } return Qnil; }
/* get chunk date from specified local file path */ static SIXELSTATUS sixel_chunk_from_file( char const /* in */ *filename, sixel_chunk_t /* in */ *pchunk, int const /* in */ *cancel_flag ) { SIXELSTATUS status = SIXEL_FALSE; int ret; FILE *f; int n; size_t const bucket_size = 4096; status = open_binary_file(&f, filename); if (SIXEL_FAILED(status)) { goto end; } for (;;) { if (pchunk->max_size - pchunk->size < bucket_size) { pchunk->max_size *= 2; pchunk->buffer = (unsigned char *)sixel_allocator_realloc(pchunk->allocator, pchunk->buffer, pchunk->max_size); if (pchunk->buffer == NULL) { sixel_helper_set_additional_message( "sixel_chunk_from_file: sixel_allocator_realloc() failed."); status = SIXEL_BAD_ALLOCATION; goto end; } } if (isatty(fileno(f))) { for (;;) { if (*cancel_flag) { status = SIXEL_INTERRUPTED; goto end; } ret = wait_file(fileno(f), 10000); if (ret < 0) { sixel_helper_set_additional_message( "sixel_chunk_from_file: wait_file() failed."); status = SIXEL_RUNTIME_ERROR; goto end; } if (ret == 0) { break; } } } n = fread(pchunk->buffer + pchunk->size, 1, 4096, f); if (n <= 0) { break; } pchunk->size += n; } if (f != stdin) { fclose(f); } status = SIXEL_OK; end: return status; }
int main(int argc, char** argv) { SIXELSTATUS status; unsigned char *pixbuf; int width = 400; int height = 300; int ncolors = 16; (void) argc; (void) argv; if (signal(SIGINT, sighandler) == SIG_ERR) return (-1); if (setup(width, height) != 0) return (-1); scroll_on_demand(height); glShadeModel(GL_SMOOTH); glClearColor(0, 0, 0, 0); glClearDepth(1); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glViewport(0, 0, (GLsizei)width, (GLsizei)height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); GLfloat fovy = 45; GLfloat aspect = (GLfloat)width / (GLfloat)height; GLfloat znear = 0.1; GLfloat zfar = 100; GLfloat radian= 2 * M_PI * fovy / 360.0; GLfloat t = (GLfloat)(1.0 / tan(radian / 2)); GLfloat matrix[]={ t / aspect, 0, 0, 0, 0, t, 0, 0, 0, 0, (zfar + znear) / (znear - zfar), -1, 0, 0, (2 * zfar * znear) / (znear - zfar), 0 }; glLoadMatrixf(matrix); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); #if !defined(USE_OSMESA) pixbuf = malloc(width * height * 3); #endif while (!signaled) { glPushMatrix(); glScalef(1, -1, 1); draw_scene(); glPopMatrix(); if (signaled) break; printf("\0338"); #if USE_OSMESA pixbuf = pbuffer; #else glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixbuf); #endif status = output_sixel(pixbuf, width, height, ncolors, SIXEL_PIXELFORMAT_RGB888); if (SIXEL_FAILED(status)) { fprintf(stderr, "%s\n%s\n", sixel_helper_format_error(status), sixel_helper_get_additional_message()); break; } } #if !defined(USE_OSMESA) free(pixbuf); #endif printf("\033\\"); if (cleanup() != 0) return (-1); return 0; }
SIXELAPI unsigned char * sixel_dither_apply_palette( sixel_dither_t /* in */ *dither, unsigned char /* in */ *pixels, int /* in */ width, int /* in */ height) { SIXELSTATUS status = SIXEL_FALSE; int bufsize; unsigned char *dest = NULL; int ncolors; unsigned char *normalized_pixels = NULL; unsigned char *input_pixels; if (dither == NULL) { sixel_helper_set_additional_message( "sixel_dither_apply_palette: dither is null."); status = SIXEL_BAD_ARGUMENT; goto end; } sixel_dither_ref(dither); bufsize = width * height * sizeof(unsigned char); dest = (unsigned char *)sixel_allocator_malloc(dither->allocator, bufsize); if (dest == NULL) { sixel_helper_set_additional_message( "sixel_dither_new: sixel_allocator_malloc() failed."); status = SIXEL_BAD_ALLOCATION; goto end; } /* if quality_mode is full, do not use palette caching */ if (dither->quality_mode == SIXEL_QUALITY_FULL) { dither->optimized = 0; } if (dither->cachetable == NULL && dither->optimized) { if (dither->palette != pal_mono_dark && dither->palette != pal_mono_light) { dither->cachetable = (unsigned short *)sixel_allocator_calloc(dither->allocator, 1 << 3 * 5, sizeof(unsigned short)); if (dither->cachetable == NULL) { sixel_helper_set_additional_message( "sixel_dither_new: sixel_allocator_calloc() failed."); status = SIXEL_BAD_ALLOCATION; goto end; } } } if (dither->pixelformat != SIXEL_PIXELFORMAT_RGB888) { /* normalize pixelformat */ normalized_pixels = (unsigned char *)sixel_allocator_malloc(dither->allocator, width * height * 3); if (normalized_pixels == NULL) { sixel_helper_set_additional_message( "sixel_dither_new: sixel_allocator_malloc() failed."); status = SIXEL_BAD_ALLOCATION; goto end; } status = sixel_helper_normalize_pixelformat(normalized_pixels, &dither->pixelformat, pixels, dither->pixelformat, width, height); if (SIXEL_FAILED(status)) { goto end; } input_pixels = normalized_pixels; } else { input_pixels = pixels; } status = sixel_quant_apply_palette(dest, input_pixels, width, height, 3, dither->palette, dither->ncolors, dither->method_for_diffuse, dither->optimized, dither->optimize_palette, dither->complexion, dither->cachetable, &ncolors, dither->allocator); if (SIXEL_FAILED(status)) { free(dest); dest = NULL; goto end; } dither->ncolors = ncolors; end: free(normalized_pixels); sixel_dither_unref(dither); return dest; }
SIXELAPI SIXELSTATUS sixel_dither_initialize( sixel_dither_t /* in */ *dither, unsigned char /* in */ *data, int /* in */ width, int /* in */ height, int /* in */ pixelformat, int /* in */ method_for_largest, int /* in */ method_for_rep, int /* in */ quality_mode) { unsigned char *buf = NULL; unsigned char *normalized_pixels = NULL; unsigned char *input_pixels; SIXELSTATUS status = SIXEL_FALSE; if (dither == NULL) { sixel_helper_set_additional_message( "sixel_dither_new: dither is null."); status = SIXEL_BAD_ARGUMENT; goto end; } sixel_dither_ref(dither); sixel_dither_set_pixelformat(dither, pixelformat); if (pixelformat != SIXEL_PIXELFORMAT_RGB888) { /* normalize pixelformat */ normalized_pixels = (unsigned char *)sixel_allocator_malloc(dither->allocator, width * height * 3); if (normalized_pixels == NULL) { sixel_helper_set_additional_message( "sixel_dither_initialize: sixel_allocator_malloc() failed."); status = SIXEL_BAD_ALLOCATION; goto end; } status = sixel_helper_normalize_pixelformat( normalized_pixels, &pixelformat, data, pixelformat, width, height); if (SIXEL_FAILED(status)) { goto end; } input_pixels = normalized_pixels; } else { input_pixels = data; } sixel_dither_set_method_for_largest(dither, method_for_largest); sixel_dither_set_method_for_rep(dither, method_for_rep); sixel_dither_set_quality_mode(dither, quality_mode); status = sixel_quant_make_palette(&buf, input_pixels, width * height * 3, SIXEL_PIXELFORMAT_RGB888, dither->reqcolors, &dither->ncolors, &dither->origcolors, dither->method_for_largest, dither->method_for_rep, dither->quality_mode, dither->allocator); if (SIXEL_FAILED(status)) { goto end; } memcpy(dither->palette, buf, dither->ncolors * 3); dither->optimized = 1; if (dither->origcolors <= dither->ncolors) { dither->method_for_diffuse = SIXEL_DIFFUSE_NONE; } sixel_quant_free_palette(buf, dither->allocator); status = SIXEL_OK; end: free(normalized_pixels); sixel_dither_unref(dither); return status; }
SIXELAPI sixel_dither_t * sixel_dither_get( int /* in */ builtin_dither) { SIXELSTATUS status = SIXEL_FALSE; unsigned char *palette; int ncolors; int keycolor; sixel_dither_t *dither = NULL; switch (builtin_dither) { case SIXEL_BUILTIN_MONO_DARK: ncolors = 2; palette = (unsigned char *)pal_mono_dark; keycolor = 0; break; case SIXEL_BUILTIN_MONO_LIGHT: ncolors = 2; palette = (unsigned char *)pal_mono_light; keycolor = 0; break; case SIXEL_BUILTIN_XTERM16: ncolors = 16; palette = (unsigned char *)pal_xterm256; keycolor = (-1); break; case SIXEL_BUILTIN_XTERM256: ncolors = 256; palette = (unsigned char *)pal_xterm256; keycolor = (-1); break; case SIXEL_BUILTIN_VT340_MONO: ncolors = 16; palette = (unsigned char *)pal_vt340_mono; keycolor = (-1); break; case SIXEL_BUILTIN_VT340_COLOR: ncolors = 16; palette = (unsigned char *)pal_vt340_color; keycolor = (-1); break; case SIXEL_BUILTIN_G1: ncolors = 2; palette = (unsigned char *)pal_gray_1bit; keycolor = (-1); break; case SIXEL_BUILTIN_G2: ncolors = 4; palette = (unsigned char *)pal_gray_2bit; keycolor = (-1); break; case SIXEL_BUILTIN_G4: ncolors = 16; palette = (unsigned char *)pal_gray_4bit; keycolor = (-1); break; case SIXEL_BUILTIN_G8: ncolors = 256; palette = (unsigned char *)pal_gray_8bit; keycolor = (-1); break; default: goto end; } status = sixel_dither_new(&dither, ncolors, NULL); if (SIXEL_FAILED(status)) { dither = NULL; goto end; } dither->palette = palette; dither->keycolor = keycolor; dither->optimized = 1; dither->optimize_palette = 0; end: return dither; }
/* create dither context object */ SIXELAPI SIXELSTATUS sixel_dither_new( sixel_dither_t /* out */ **ppdither, /* dither object to be created */ int /* in */ ncolors, /* required colors */ sixel_allocator_t /* in */ *allocator) /* allocator, null if you use default allocator */ { SIXELSTATUS status = SIXEL_FALSE; int headsize; int datasize; int wholesize; int quality_mode; if (ppdither == NULL) { sixel_helper_set_additional_message( "sixel_dither_new: ppdither is null."); status = SIXEL_BAD_ARGUMENT; goto end; } if (allocator == NULL) { status = sixel_allocator_new(&allocator, NULL, NULL, NULL, NULL); if (SIXEL_FAILED(status)) { *ppdither = NULL; goto end; } } else { sixel_allocator_ref(allocator); } if (ncolors == (-1)) { ncolors = 256; quality_mode = SIXEL_QUALITY_HIGHCOLOR; } else { if (ncolors > SIXEL_PALETTE_MAX) { ncolors = 256; } else if (ncolors < 2) { ncolors = 2; } quality_mode = SIXEL_QUALITY_LOW; } headsize = sizeof(sixel_dither_t); datasize = ncolors * 3; wholesize = headsize + datasize; *ppdither = (sixel_dither_t *)sixel_allocator_malloc(allocator, wholesize); if (*ppdither == NULL) { sixel_allocator_unref(allocator); sixel_helper_set_additional_message( "sixel_dither_new: sixel_allocator_malloc() failed."); status = SIXEL_BAD_ALLOCATION; goto end; } (*ppdither)->ref = 1; (*ppdither)->palette = (unsigned char*)(*ppdither + 1); (*ppdither)->cachetable = NULL; (*ppdither)->reqcolors = ncolors; (*ppdither)->ncolors = ncolors; (*ppdither)->origcolors = (-1); (*ppdither)->keycolor = (-1); (*ppdither)->optimized = 0; (*ppdither)->optimize_palette = 0; (*ppdither)->complexion = 1; (*ppdither)->bodyonly = 0; (*ppdither)->method_for_largest = SIXEL_LARGE_NORM; (*ppdither)->method_for_rep = SIXEL_REP_CENTER_BOX; (*ppdither)->method_for_diffuse = SIXEL_DIFFUSE_FS; (*ppdither)->quality_mode = quality_mode; (*ppdither)->pixelformat = SIXEL_PIXELFORMAT_RGB888; (*ppdither)->allocator = allocator; status = SIXEL_OK; end: return status; }