libansilove

Library for converting ANSI, ASCII, and other formats to PNG
Log | Files | Refs | README | LICENSE

binary.c (2101B)


      1 /*
      2  * binary.c
      3  * libansilove 1.2.4
      4  * https://www.ansilove.org
      5  *
      6  * Copyright (c) 2011-2020 Stefan Vogt, Brian Cassidy, and Frederic Cambus
      7  * All rights reserved.
      8  *
      9  * libansilove is licensed under the BSD 2-Clause License.
     10  * See LICENSE file for details.
     11  */
     12 
     13 #include <gd.h>
     14 #include <stddef.h>
     15 #include <stdint.h>
     16 #include <string.h>
     17 #include "ansilove.h"
     18 #include "config.h"
     19 #include "drawchar.h"
     20 #include "fonts.h"
     21 #include "output.h"
     22 
     23 int
     24 ansilove_binary(struct ansilove_ctx *ctx, struct ansilove_options *options)
     25 {
     26 	if (ctx == NULL || options == NULL) {
     27 		if (ctx)
     28 			ctx->error = ANSILOVE_INVALID_PARAM;
     29 
     30 		return -1;
     31 	}
     32 
     33 	struct fontStruct fontData;
     34 
     35 	/* font selection */
     36 	memset(&fontData, 0, sizeof(struct fontStruct));
     37 	select_font(&fontData, options->font);
     38 
     39 	/* libgd image pointers */
     40 	gdImagePtr canvas;
     41 
     42 	/* Default to 160 columns if columns option wasn't set */
     43 	options->columns = options->columns ? options->columns : 160;
     44 
     45 	/* allocate buffer image memory */
     46 	canvas = gdImageCreate(options->columns * options->bits,
     47 	    ((ctx->length / 2) / options->columns * fontData.height));
     48 
     49 	if (!canvas) {
     50 		ctx->error = ANSILOVE_GD_ERROR;
     51 		return -1;
     52 	}
     53 
     54 	/* allocate color palette */
     55 	uint32_t colors[16];
     56 
     57 	for (size_t i = 0; i < 16; i++) {
     58 		colors[i] = gdImageColorAllocate(canvas, vga_palette_red[i],
     59 		    vga_palette_green[i], vga_palette_blue[i]);
     60 	}
     61 
     62 	/* process binary */
     63 	uint32_t character, attribute, background, foreground;
     64 	size_t loop = 0;
     65 	int32_t column = 0, row = 0;
     66 
     67 	while (loop < ctx->length) {
     68 		if (column == options->columns) {
     69 			column = 0;
     70 			row++;
     71 		}
     72 
     73 		character = ctx->buffer[loop];
     74 
     75 		if (ctx->length > loop) {
     76 			attribute = ctx->buffer[loop+1];
     77 
     78 			background = (attribute & 240) >> 4;
     79 			foreground = (attribute & 15);
     80 
     81 			if (background > 8 && !options->icecolors)
     82 				background -= 8;
     83 
     84 			drawchar(canvas, fontData.font_data, options->bits,
     85 			    fontData.height, column, row, colors[background],
     86 			    colors[foreground], character);
     87 
     88 			column++;
     89 			loop += 2;
     90 		}
     91 	}
     92 
     93 	/* create output image */
     94 	return output(ctx, options, canvas);
     95 }