A few weeks ago I found these in an old backup of mine. There's four
utilies, three of them using a compiled C heler tool and the fourth
based on awk. Combined they provide a way to rotate ASCII art 90
degrees, 180 degrees, 270 degrees, and to left-right flip an image.
The left-right flip is by Jef Poskanzer ( www.acme.com ) and clearly
licensed. The others are of ambitious origin and have no clear license.
I suspect the authors would be 100% okay with my sharing this old code
for the purpose of hobbyists to use non-commercially.
Code distributed in the old-school shell archive format. You can extract
by hand easily enough or use `sh` to do it automatically. There was no
makefile when I got this, but "make asciitool" worked for me. My only
changes to the code were to add the #include lines above the comment
in the C file and add line breaks to the C file usage message.
Elijah
------
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# notes
# asciitool.c
# ccw90
# cw90
# tb
# lr
#
echo x - notes
sed 's/^X//' >notes << 'END-of-notes'
XDownloaded from
X
gopher://samuell.com:70/
Xsometime in June 2006
END-of-notes
echo x - asciitool.c
sed 's/^X//' >asciitool.c << 'END-of-asciitool.c'
X#include <stdlib.h>
X#include <stdio.h>
X/* **********************************************************************
X asciitool.c An ASCII Rotation and Mirroring tool
X
Xcompile with: cc -o asciitool asciitool.c
X
XNot my code! (Joshua Bell,
jsbell@acs.ucalgary.ca)
X
XWell, some of it is, but not much.
XChanges: - changed if/else if/else if/else if... to a switch
X - fixed bug with -r270 (no longer requires rectangular images)
X - made Infile and Outfile default to STDIN and STDOUT (for pipes) X - made incorrect calling syntax quit program
X - reformatted the source to be more concise
X
Xasciitool -{mh|mv|r90|r180|r270} [Infile [Outfile]]
X -mh Mirror horizontally
X -mv Mirror vertically
X -r90 Rotate 90 degrees counterclockwise
X -r180 Rotate 90 degrees counterclockwise
X -r270 Rotate 90 degrees counterclockwise
X
X********************************************************************** */
X
X#include <stdio.h>
X#include <string.h>
X
X#define NUM_FLAGS 5
X
Xchar *FlagStrings[NUM_FLAGS] = { "-mv", "-mh", "-r90", "-r180", "-r270" }; Xenum { V_MIRROR, H_MIRROR, R90, R180, R270 };
X
Xchar **GetFile(FilePtr, NumberOfLinesPtr, ErrorString)
X FILE *FilePtr;
X int *NumberOfLinesPtr;
X char *ErrorString;
X{
X char **FileLines;
X char Buffer[255];
X int CurrentLine, c, Error;
X
X ErrorString[0] = '\0';
X
X CurrentLine = 0;
X Error = 0;
X
X while((c = fgetc(FilePtr)) != EOF) {
X ungetc(c, FilePtr);
X fgets(Buffer, sizeof(Buffer), FilePtr);
X
X if(CurrentLine == 0) {
X if((FileLines = (char **)malloc(sizeof(char *))) == NULL) {
X strcpy(ErrorString, "Memory Allocation Error: <malloc>");
X return(NULL);
X }
X
X } else {
X if((FileLines =
X (char **)realloc(FileLines,(1 + CurrentLine) * sizeof(char *)))
X == NULL) {
X strcpy(ErrorString, "Memory Allocation Error: <realloc>\n");
X return(NULL);
X }
X }
X
X if((FileLines[CurrentLine] = (char *)malloc(strlen(Buffer) + 1)) == NULL) {
X strcpy(ErrorString, "Memory Allocation Error: <malloc>\n");
X return(NULL);
X }
X
X strcpy(FileLines[CurrentLine++], Buffer);
X }
X
X *NumberOfLinesPtr = CurrentLine;
X
X return(FileLines);
X
X} /* GetFile */
X
Xint main(argc, argv)
X int argc;
X char **argv;
X{
X int i, j, k, Flag, NumberOfLines, Length, MaxLength;
X FILE *Infile, *Outfile;
X char String[255];
X char **FileLines, **NewFileLines, *CharPtr;
X
X if((argc < 2) | (argc > 4)) {
X printf("Usage: %s -{mh|mv|r90|r180|r270} [Infile [Outfile]]\n", argv[0]); X printf(" -mh Mirror horizontally\n");
X printf(" -mv Mirror vertically\n");
X printf(" -r90 Rotate 90 degrees counterclockwise\n");
X printf(" -r180 Rotate 90 degrees counterclockwise\n");
X printf(" -r270 Rotate 90 degrees counterclockwise\n");
X return(-1);
X }
X
X switch (argc) {
X case 2:
X Infile = stdin;
X Outfile = stdout;
X break;
X case 3:
X if((Infile = fopen(argv[2], "r")) == NULL)
X {
X printf("Could not open input file: %s\n", argv[1]);
X return(-1);
X }
X Outfile = stdout;
X break;
X case 4:
X if((Outfile = fopen(argv[3], "w")) == NULL)
X {
X printf("Could not open output file: %s\n", argv[2]);
X return(-1);
X }
X break;
X }
X
X
X strcpy(String, argv[1]);
X
X for(i = 0; String[i]; i ++)
X if(String[i] >= 'A' && String[i] <= 'Z')
X String[i] += ('a' - 'A');
X
X for(i = 0; i < NUM_FLAGS; i ++)
X if(!strcmp(String, FlagStrings[i]))
X break;
X
X if(i == NUM_FLAGS)
X {
X printf("Illegal flag: %s\n", argv[3]);
X return(-1);
X }
X else
X Flag = i;
X
X if((FileLines = GetFile(Infile, &NumberOfLines, String)) == NULL) {
X printf("%s\n", String);
X return(-1);
X }
X
X for(i = 0; i < NumberOfLines; i ++) {
X if((CharPtr = strrchr(FileLines[i], '\n')) != NULL)
X *CharPtr = '\0';
X
X Length = strlen(FileLines[i]);
X
X if(i == 0 || (Length > MaxLength))
X MaxLength = Length;
X }
X
X switch (Flag) {
X
X case V_MIRROR:
X for(i = NumberOfLines - 1; i >= 0; i --)
X fprintf(Outfile, "%s\n", FileLines[i]);
X break;
X
X case H_MIRROR:
X for(i = 0; i < NumberOfLines; i ++) {
X Length = strlen(FileLines[i]);
X
X for(j = 0; j < Length; j ++)
X String[Length - j - 1] = FileLines[i][j];
X
X String[j] = '\0';
X fprintf(Outfile, "%*s%s\n", MaxLength - Length, "", String);
X }
X break;
X
X case R180:
X for(i = NumberOfLines - 1; i >= 0; i --) {
X Length = strlen(FileLines[i]);
X
X for(j = 0; j < Length; j ++)
X String[Length - j - 1] = FileLines[i][j];
X
X String[j] = '\0';
X fprintf(Outfile, "%*s%s\n", MaxLength - Length, "", String);
X }
X break;
X
X/*** For "real" rotations, need extra code ***/
X
X default:
X
X if((NewFileLines =
X (char **)malloc(MaxLength * sizeof(char *))) == NULL) {
X printf("Memory Allocation Error: <malloc>");
X return(-1);
X }
X
X for(i = 0; i < MaxLength; i ++) {
X if((NewFileLines[i] =
X (char *)malloc((NumberOfLines + 1) * sizeof(char))) == NULL) {
X printf("Memory Allocation Error: <malloc>");
X return(-1);
X }
X }
X
X switch (Flag) {
X
X case R90:
X
X for(i = 0; i < NumberOfLines; i ++)
X {
X for(j = 0; FileLines[i][j]; j ++)
X NewFileLines[MaxLength - 1 - j][i] = FileLines[i][j];
X
X while(j < MaxLength) {
X NewFileLines[MaxLength - 1 - j][i] = ' ';
X j++;
X }
X }
X break;
X
X case R270:
X
X for(i = 0; i < NumberOfLines; i ++) {
X Length = strlen(FileLines[i]);
X
X for(k = 0, j = MaxLength - 1; j >= 0; j --, k ++)
X if (j >= Length)
X NewFileLines[MaxLength - k - 1][NumberOfLines - i - 1] = ' ';
X else
X NewFileLines[MaxLength - k - 1][NumberOfLines - i - 1] =
X FileLines[i][j];
X
X while(k < MaxLength) {
X NewFileLines[MaxLength - k - 1][NumberOfLines - i - 1] = ' ';
X k++;
X }
X }
X
X break;
X }
X
X for(j = 0; j < MaxLength; j ++) {
X NewFileLines[j][NumberOfLines] = '\0';
X fprintf(Outfile, "%s\n", NewFileLines[j]);
X }
X }
X
X
X for(i = 0; i < NumberOfLines; i ++)
X free((void *)FileLines[i]);
X
X free((void *)FileLines);
X
X fclose(Infile), fclose(Outfile);
X
X return(0);
X
X} /* main */
END-of-asciitool.c
echo x - ccw90
sed 's/^X//' >ccw90 << 'END-of-ccw90'
X#!/bin/sh
X#
X# ccw90 - rotates ASCII pictures by 90 degrees counter clockwise
X#
X# by Joshua Bell <
jsbell@acs.ucalgary.ca>, July 1994
X#
X# Requires the asciitool program is present in your search path.
X#
X# Inspiration from Jef Poskanzer's "lr" utility for left/right flips.
X#
X# Mapping is: _-~^<>v/\NZ!]|[()nu:;{}"'`,CUciIl17t=H
X# to: |||<v^>\/ZN-~-_un()""_~:\/\U)u----r+H=
X
Xcat $* |
X ./asciitool -r90 |
X tr '_\-~^<>v/\\NZ!]|[()nu:;{}"'\''`,CUciIl17t=H' \
X '|||<v^>\\/ZN\-~\-_un()""_~:\\/\\U)u\-\-\-\-r+H=' |
X sed 's/ *$//'
X
END-of-ccw90
echo x - cw90
sed 's/^X//' >cw90 << 'END-of-cw90'
X#!/bin/sh
X#
X# cw90 - rotates ASCII pictures by 90 degrees clockwise
X#
X# by Joshua Bell <
jsbell@acs.ucalgary.ca>, July 1994
X#
X# Requires the asciitool program is present in your search path.
X#
X# Inspiration from Jef Poskanzer's "lr" utility for left/right flips.
X#
X# Mapping is: _-~^<>v/\NZ!]|[()nu:;{}"'`,CUciIl1rt=H
X# to: |||>^v<\/ZN-_-~nu)(""~_:\/\nCn----7+H=
X
Xcat $* |
X ./asciitool -r270 |
X tr '_\-~^<>v/\\NZ!]|[()nu:;{}"'\''`,CUciIl1rt=H' \
X '|||>^v<\\/ZN\-_\-~nu)(""~_:\\/\\nCn\-\-\-\-7+H=' |
X sed 's/ *$//'
X
END-of-cw90
echo x - tb
sed 's/^X//' >tb << 'END-of-tb'
X#!/bin/sh
X#
X# tb - flips ASCII pictures top for bottom
X#
X# by Joshua Bell <
jsbell@acs.ucalgary.ca>, Feb 1994
X#
X# Requires the asciitool program is present in your search path.
X#
X# Inspiration from Jef Poskanzer's "lr" utility for left/right flips.
X#
X# Mapping is: ;!~_`,.'"^/\AFJLMPSTUVWYZbfghimnpqrstuvwyz257
X# to: :i_~,`'..v\/VL7TWb2LAAMASPt6y!wubdtzfn^mhsSZJ
X
Xcat $* |
X ./asciitool -mv |
X tr ';!~_\140,.\047"^/\\AFJLMPSTUVWYZbfghimnpqrstuvwyz257' \
X ':i_~,\140\047..v\\/VL7TWb2LAAMASPt6y!wubdtzfn^mhsSZJ' |
X sed 's/ *$//'
X
END-of-tb
echo x - lr
sed 's/^X//' >lr << 'END-of-lr'
X#!/bin/sh
X#
X# lr - reverse ASCII pictures left for right
X#
X# Copyright (C) 1994 by Jef Poskanzer.
X#
X# Permission to use, copy, modify, and distribute this software and its
X# documentation for any purpose and without fee is hereby granted, provided
X# that the above copyright notice appear in all copies and that both that
X# copyright notice and this permission notice appear in supporting
X# documentation. This software is provided "as is" without express or
X# implied warranty.
X
X# Translation of . -> , changed removed. Better to lose some symmetry than
X# induce asymmetry, IMHO. (jsbell@acs)
X
Xcat $* |
X expand |
X awk '{printf "%s%s\n", $0, substr(" ", length)}' |
X rev |
X tr '()<>{}\[]/\\.,\140\047LJZSE3dbqp' ')(><}{]\[\\/..\047\140JLSZ3Ebdpq' |
X sed 's/ *$//'
END-of-lr
exit
--- PyGate Linux v1.5.14
* Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)