Tiger: A Stylish Cat

Okay, this is one of the stupidest programs I've written, but once I had the idea I couldn't not do it.

Here's what it does:

$ xxd tiger | ./tiger -i | head -n96
0000   0: 7f45 4  6 0201 010   000 000    00 0000  .ELF.....    ...
0000   0: 0300 3  0 0100 000   007 000     0 0000  ..>.......   ...
0000   0: 4000 00 0 0000 0000   24 000     0 0000  @ .......$.  ...
000   30: 0000 0000 4000 3800   00 400     0 1c00  .  .@.8...@   ..
000   40: 0600 0000 0400 0000   00 000       0000  .  .....@...  ..
000   50: 4000 0000 0000 0000   00 000       0000  @.  ....@...   .
00   060: f801 0000 0000 0000 f  1 0000      0000  ..   ........  .
00   070: 0800 00 0 0000 0000 0  0 0000       000  ...   .......   
00   080: 3802 00 0 0000 0000 3  2 0000 0     000  8...  ..8....   
00  0090: 3802 00   0000 0000 1  0 0000 0     000  8...  .......   
00  00a0: 1c00 00   0000 0000    0 0000 0    0000  ....   .......  
00  00b0: 0100 0    0500 0000    0 0000      0000  ....  ........  
00  00c0: 0000 0    0000 000    00 0000    0 0000  ....  ......... 
00 000d0: 480d      0000 00     0d 000    00 0000  H...  ..H...... 
000000e0: 000     0 0000 00    100 000    00 0000  .. .   .........
000000f0: 800     0 0000 0     00d 20     00 0000  ...   .... .....
00000100: 80     00 0000      a00b 00    000  000  .. .  ..........
00000110: b0     00 0000      0000 2     000   00  ...  ..... .....
00000120: 0      00 060     0 900d 0    0000   00  ..  ............
00000130: 9     000 00      0 900d      0000   00  ..   ..... .....
00 00140:       000 00     00 f001    0 0000   00  ..  ............
00 00150:      0000 0      00 0400    0 0400   00  .   ............
00 00160:      0000 0     000 540    00 0000   00  T    ...T.  ....
00 00170:      0000 0     000 440    00 000    00  T    ...D.  ....
00 00180:    0 0000 0     000 040    00 000    00  D    .....  ....
00  0190     5 7464 0    0000 dc    000 000   000  P   ......   ...
0   01a0    0b 0000 0    0000 dc    000 000   000  .   ......   ...
0   01b0    00 0000 0    0000 44    000 00    000  D   ....D.   ...
0   01c0    00 0000 0    0000 5     464 06    000  .   ....Q.   ...
0   01d0    00 0000      0000 0    0000 00   0000  .   ......   ...
0   01e0    00 0000    0 0000 0    0000 0    0000  .  .......   ...
    01f0    00 000     0 0000    0 0000 0  0 0000  .  ........   ..
    0200:   e5 746    00 0000   0d 0000    0 0000  R  d.......   ..
    0210:   0d 200    00 000    0d 2000    0 0000      ...... ..   
    0220:   02 00    000 00    002 0000    0 0000     ........    .
0   0230:    0 00   0000      2f6c 6962   34 2f6c     ...../lib   l
0   0240:    d 6c   6e75    d 783   62d   34 2e7      inux-x86-   s
0   0250:    e 32 0 040     0 100   000   00 000      .........    
00  0260:   4e 5  0 00     00 03   0000   00 000      .........    
00  0270:   00 0  0 04    000 14   0000 0 00 00       ........     
00  0280    4e 5 00 7    d9e0 d    9e7f 4  2 be       .p......     
000 0290   8e8   5f 2  e 6a70    0 0000 0  0 00       _%.jp..      
000 0 a0   100   00   00 000    00 2000 80 0 00      ........      
00000 b0   000   00  e00 00    755 6110 0000 00      ......gU      
0000  c0   000   00  000 00   0000 0000 0000 00      .........     
0000  d0: 000    00 0000 0    1500 0000 1200 00      .........     
0000  e0: 000    00 0000 0  0 0000 0000 0000 0       .........    .
0000  f0: 860   000 2000 0  0 0000 0000 0000 0       .. .......    
0000  00: 000   000 0000 0  0 1000 0000 1200 0       .........    .
0000  10: 000   000 0000 0    0000 0000 0000 0       .........   ..
0000  20: 230   000 1200 00    000 0000 0000 0       ........    ..
0000   0: 000    00 0000 000     0 0000 1200 0       ......^.   ...
0000   0: 000    00 0000 0000       000 0000 0       .......   ....
00000  0: a20    00 2000 0000 0      00 0000 0       .. .....   ...
00000  0: 0000   00 00 0 0000 55      0 1200 00      ......    ....
000003  : 0000    0 00    000 000     0 0000 00      ......   .....
000003    3100    0 120     0 0000      0000 00       ....    .....
0000039   0000 0  0 0000      0b00 0     200 000      ....    .....
00 003a0  0000 0  0 0000 0     000 00     00 000      ....    .....
00  03b0   100 0  0 2000 00    000 000    00 000        ...    ....
000   c0: 0000 0  0 0000 000   600 0000    0 0000       ...   ."...
000    0: 0000 0  0 0000 0000   00 0000    0 0000       ...   .....
0000   0: 2a00 0  0 1200 0000   00 0000      0000  *     ..   .....
00000   : 0000 0    0000 0000   00 0000 1     000  .     ..8  .... 
000004  : 0000 00   0000 0000 0  0 0000 00     00  ..    ...  .... 
0000041   1d00 00   1100 1800 2  9 2000 000    00  ..    .. .   ...
0000042   0800 00    000 0000 0  c 6962 632     f  ..    ...l bc.s 
000 0430   e36 006    69 7400 70 5 7473 0070       .6.   t.pu s.pu 
000  440    68 617    73 7464 69 e 0070 7269 6      ha   tdin prin 
0000 450:    0 7374    3 7472 00 7 6574 6f70 7      .s    r.getopt 
0000  60: 5    6374 7    655f 62 f 6c6f 6300 5f     _ct   _b_loc._ 
00000  0: 63    15f 66    e61 6c69 7a65 005f 494    xa_    lize._I 
00000   : 5f6   574 63    f5f 6c69 6263 5f73 746    get    libc_st 
00000   : 7274   6d 616    00 474c 4942 435f 322     _ma   GLIBC_2.
000004    3300    c 4942    f 322e 3    3500 5f49    GLI   2.2.5._I
000004    544d 5  4 6572    7 6973 74    254 4d43    _de   isterTMC
000004    6c6f 6e   5461 6    6500 5f5    6d 6f6e     eT   e.__gmon
000004    5f73 746   274 5f    05f 4954    f 7265  _  ar   ._ITM_re
000004    6769 7374  572 54    36c 6f6e 6    6162  g  te   CloneTab
000004    6c65 0000 0000 020    00 0200 02    200  l  ..   ........
000005    0000 0200 0200 020     0 0200 020    00  .. ..   ........
000005  : 0200 00 0 0000 0000      0200 010     0  .. ..  . .......
000005  : 1000 00   0000 0000 1     90d 0000    0  .....  .  i.....
000005  : 7000 00   1000 0000 7      09 0000 0     p....  .  i.....
00000   : 7a00 00   0000 0000 80      0 0000 0     z..... .   .....
00000   : 0800 00    000 0000 a00     0 0000 0     ........   .....
00000   : 880d 20   0000 0000 080       0000 00     . ......   ....
00000   : 6008 00   0000 0000 0810      0000 00     ........   ....
00000   : 0800 0    0000 0000 0810      0000 000     .......   ....
00000   : d80f 2    0000 0000 0600 0    0200 000      .......  ....
00000   : 0000 0    0000 0000 e00f 2    0000 0000     ......   ....
00000   : 0600      0500 000  0000 00    000 0000  .  ......  .....
00000   : e80f      0000 000  0600 00    600 0000  ..   .....  ....
00000   : 0000 0  0 0000 000  f00f 20    000 0000  ... .....    ...
00000   : 0600 0  0 0a00 000   000 00     00 0000  .........   ....
0000    : f80f 2  0 0000 000   600 00     00 0000  .. .......   ...

Here's the source (tiger.c):

/* tiger -- Tiger print standard input to standard output.
   Copyright (C) 2022 Remington Furman
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <getopt.h>
#include "tiger.h"
#include "leopard.h"

void usage(char *name) {
    printf("usage: cat file | %s [-i] [-h] \n", name);
    printf("  -i    invert pattern\n");
    printf("  -h    print this help\n");
}

int main(int argc, char **argv) {
    int width  = tiger_width;
    int height = tiger_height;
    unsigned char *image = tiger_bits;

    int opt_invert = 0;

    if (strstr(argv[0], "tiger") != NULL) {
        width  = tiger_width;
        height = tiger_height;
        image  = tiger_bits;
    }
    else if (strstr(argv[0], "leopard") != NULL) {
        width  = leopard_width;
        height = leopard_height;
        image  = leopard_bits;
    }

    int opt;
    while ((opt = getopt(argc, argv, "ih")) != -1) {
        switch (opt) {
            case 'i':
                opt_invert = 0x1;
                break;
            case 'h':
                usage(argv[0]);
                exit(EXIT_SUCCESS);
                break;
            default:
                usage(argv[0]);
                exit(EXIT_FAILURE);
        }
    }

    int x = 0;
    int y = 0;
    char c;
    while ((c = getc(stdin)) != EOF) {
        if (c == '\n') {
            x = 0;
            y = (y+1) % height;
        }
        else if (c == '\t') {
            x = (x+8) % width;
        }
        else if (isgraph(c)) {
            x = (x+1) % width;
            unsigned char byte  = image[y*width + x>>3];
            unsigned char pixel = (byte >> (x&7)) & 1;
            pixel ^= opt_invert;
            c = pixel ? c : ' ';
        }
        putchar(c);
    }
}

All the code (including a Makefile and even a manpage) can be found here:

tiger.tar.gz

© Copyright 2024, Remington Furman

blog@remcycles.net

@remcycles@subdued.social