1 /****************************************************************************
2 * Copyright (c) 2017 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
29 * $Id: picsmap.c,v 1.8 2017/05/14 01:26:30 tom Exp $
31 * Author: Thomas E. Dickey
33 * A little more interesting than "dots", read a simple image into memory and
34 * measure the time taken to paint it normally vs randomly.
37 * TODO read "convert" via pipe (from ImageMagick)
38 * TODO write cells/second to stderr (or log)
39 * TODO write picture left-to-right/top-to-bottom
40 * TODO write picture randomly
41 * TODO add one-shot option vs repeat-count before exiting
42 * TODO add option for assumed palette of terminal
43 * TODO add option for init_color
44 * TODO use pad to allow pictures larger than screen
46 #include <test.priv.h>
48 #include <sys/types.h>
55 int ch; /* nominal character to display */
56 int fg; /* foreground color */
73 static bool in_curses = FALSE;
76 * Simplify reading xbm/xpm files by first making an array of lines. Blank
77 * lines are filtered out.
80 read_file(const char *filename)
85 printf("** %s\n", filename);
86 if (stat(filename, &sb) == 0
87 && (sb.st_mode & S_IFMT) == S_IFREG
89 size_t size = (size_t) sb.st_size;
90 char *blob = typeMalloc(char, size + 1);
95 result = typeCalloc(char *, size + 1);
96 if (blob != 0 && result != 0) {
97 FILE *fp = fopen(filename, "r");
99 if (fread(blob, sizeof(char), size, fp) == size) {
100 for (j = 0; (size_t) j < size; ++j) {
101 if (blob[j] == '\n') {
104 } else if (had_line) {
106 result[k++] = blob + j;
126 static const char *msg[] =
128 "Usage: picsmap [xbm-file [...]]"
133 for (n = 0; n < SIZEOF(msg); n++)
134 fprintf(stderr, "%s\n", msg[n]);
135 ExitProgram(EXIT_FAILURE);
139 giveup(const char *fmt,...)
146 vfprintf(stderr, fmt, ap);
155 int r = (value & 0xff0000) >> 16;
156 int g = (value & 0x00ff00) >> 8;
157 int b = (value & 0x0000ff) >> 0;
158 /* TODO simple mapping into COLOR_BLACK .. COLOR_WHITE */
159 int result = ((r >= 128) << 2) + ((g >= 128) << 1) + (b >= 128);
174 parse_xbm(char **data)
183 PICS_HEAD *result = typeCalloc(PICS_HEAD, 1);
187 for (n = 0; data[n] != 0; ++n) {
188 if (strlen(s = data[n]) >= sizeof(buf) - 1)
194 if (sscanf(s, "#define %s %d%c", buf, &num, &ch) >= 2) {
195 if ((t = strstr(buf, "_width")) != 0) {
197 result->wide = bytes_of(num);
198 } else if ((t = strstr(buf, "_height")) != 0) {
204 if (strcmp(result->name, buf)) {
208 result->name = strdup(buf);
213 if (sscanf(s, "static char %[^_ ]_bits[]%c", buf, &ch) >= 1) {
214 if (strcmp(result->name, buf)) {
218 cells = (size_t) (result->wide * result->high);
219 result->cells = typeCalloc(PICS_CELL, cells);
220 if ((s = strchr(s, L_CURL)) == 0)
228 while (isspace(UChar(*s))) {
231 if (isdigit(UChar(*s))) {
232 long value = strtol(s, &t, 0);
234 if (t != s || value > 255 || value < 0) {
240 /* TODO: which order? */
241 for (b = 0; b < 8; ++b) {
242 if (((1L << b) & value) != 0) {
243 result->cells[which].ch = '*';
244 result->cells[which].fg = 1;
246 result->cells[which].ch = ' ';
247 result->cells[which].fg = 0;
249 if (++which > cells) {
258 } else if (*s == ',') {
277 result->pairs = typeCalloc(PICS_PAIR, 2);
278 result->pairs[1].fg = 0xffffff;
284 dump_picture(PICS_HEAD * pics)
288 printf("Name %s\n", pics->name);
289 printf("Size %dx%d\n", pics->high, pics->wide);
290 for (y = 0; y < pics->high; ++y) {
291 for (x = 0; x < pics->wide; ++x) {
292 putchar(pics->cells[y * pics->wide + x].ch);
299 show_picture(PICS_HEAD * pics)
312 scrollok(stdscr, FALSE);
314 for (n = 0; n < pics->colors; ++n) {
315 init_pair((short) (n + 1),
316 (short) map_color(pics->pairs[n].fg),
319 attrset(COLOR_PAIR(1));
322 for (y = 0; y < pics->high; ++y) {
326 for (x = 0; x < pics->wide; ++x) {
329 n = (y * pics->wide + x);
330 attrset(COLOR_PAIR(pics->cells[n].fg + 1));
331 addch((chtype) pics->cells[n].ch);
339 main(int argc, char *argv[])
344 for (n = 1; n < argc; ++n) {
345 char **data = read_file(argv[n]);
348 giveup("cannot read \"%s\"", argv[n]);
349 } else if ((pics = parse_xbm(data)) == 0) {
350 giveup("unexpected file-format for \"%s\"", argv[n]);
351 } else if (isatty(fileno(stdout))) {
360 ExitProgram(EXIT_SUCCESS);