libansilove

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

artworx.c (1864B)


      1 /*
      2  * artworx.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 "ansilove.h"
     17 #include "config.h"
     18 #include "drawchar.h"
     19 #include "output.h"
     20 
     21 #define ADF_HEADER_LENGTH 4289 /* 192 + 4096 + 1 */
     22 
     23 int
     24 ansilove_artworx(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 	if (ctx->length < ADF_HEADER_LENGTH) {
     34 		ctx->error = ANSILOVE_FORMAT_ERROR;
     35 		return -1;
     36 	}
     37 
     38 	/* libgd image pointers */
     39 	gdImagePtr canvas;
     40 
     41 	/* create ADF instance */
     42 	canvas = gdImageCreate(640, (((ctx->length - ADF_HEADER_LENGTH) / 2) / 80) * 16);
     43 	if (!canvas) {
     44 		ctx->error = ANSILOVE_GD_ERROR;
     45 		return -1;
     46 	}
     47 
     48 	size_t index, loop;
     49 
     50 	/* process ADF palette */
     51 	for (loop = 0; loop < 16; loop++) {
     52 		index = (adf_colors[loop] * 3) + 1;
     53 		gdImageColorAllocate(canvas, (ctx->buffer[index] << 2 | ctx->buffer[index] >> 4),
     54 		    (ctx->buffer[index + 1] << 2 | ctx->buffer[index + 1] >> 4),
     55 		    (ctx->buffer[index + 2] << 2 | ctx->buffer[index + 2] >> 4));
     56 	}
     57 
     58 	/* process ADF */
     59 	uint32_t column = 0, row = 0;
     60 	uint32_t character, attribute, foreground, background;
     61 	loop = ADF_HEADER_LENGTH;
     62 
     63 	while (loop < ctx->length) {
     64 		if (column == 80) {
     65 			column = 0;
     66 			row++;
     67 		}
     68 
     69 		character = ctx->buffer[loop];
     70 		attribute = ctx->buffer[loop+1];
     71 
     72 		background = (attribute & 240) >> 4;
     73 		foreground = attribute & 15;
     74 
     75 		drawchar(canvas, ctx->buffer+193, 8, 16, column, row, background, foreground, character);
     76 
     77 		column++;
     78 		loop += 2;
     79 	}
     80 
     81 	/* create output file */
     82 	return output(ctx, options, canvas);
     83 }