From: byron@garfield.cs.mun.ca (Mr. Subliminal)
Subject: pbmtoascii converter
Organization: CS Dept., Memorial University of Newfoundland
Distribution: na
Date: Tue, 10 Nov 1992 19:15:34 GMT

Here is the code for a pbmtoascii converter that does more along the lines of
what I want. Just compile it and run it with the name of a pbm file and
redirect the output to a file.  I use it on unix, I didn't try it on the amiga
so some playing around with it may be necessary to get it to work on the amiga
end.  One idea you might try is reading in different fonts, I am using the
topaz font, characters 32-126. It could use some speeding up as well.

Example: (I uploaded a deluxe paint 640x200 2 color ilbm and converted it to 
	  pbm format with pbmplus then ran it through my program here.)
                                                               __
                                                               `0q_
  _                                                             `LL
  #^,                                              p         __  5F
  `_7LqL__                    __   *n, ,_          "   __mg_jND j0L
   ^F`0FXD*u       QP"^       #5L   #`L P    ___g_ j# J5F 9qEJ@" "
      D  E ]L ___  `L___      JLQ   ]WF   j*pP3F #_AD" @
     d  jF JLjFQF   """"#   g  B@J#n#F jLJ"J" !  "" 
        "  Abf 0    _  jFj__D_p0_/" GW^!"  
                    P^^" ""~   ~                                                

 Byron...
 ___________________________________________________________________________
|     ///    "Byron Montgomerie"  Internet: byron@odie.cs.mun.ca       ///  |
| \\\///      "Does anybody here remember Vera Lynn?               \\\///   |
|  \///        How she said that we would meet again,               \///    |
|  Amiga       some sunny day..." -- Pink Floyd --                 Amiga    |
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----cut here----
#include <stdio.h>

#define MAXBITMAP 100000

int convert (char *buffer);
int percentage (char *v1, char *v2);

int main (int argc, char **argv)
{
	char *inputfile, bitmap[MAXBITMAP], magicstr[2], buffer[8];
	int file, bytes, character, i, width, height,
	bwidth, bheight, row, col, datastart, enddata;

	if (argc < 2) {
		printf("Usage: %s pgmfile\n", argv[0]);
		return 0;
	}

	inputfile = argv[1];

	if (!(file = open(inputfile, "r")))
	{
		printf("Can't open file.\n");
		return 0;
	};

/*	printf("Reading %s...\n\n", inputfile); */
	bytes = read(file, bitmap, MAXBITMAP);

	sscanf(bitmap, "%s %d %d %n", magicstr, &width, &height,
	    &datastart);

	if (strcasecmp(magicstr, "P4"))
	{
		printf("Wrong file type, must be binary pgm file.\n");
		return 0;
	}

	bwidth = (width / 8) + ((width % 8) != 0);
	bheight = (height / 8) + ((height % 8) != 0);

	enddata = datastart + bwidth * bheight;
	for (i = datastart + bwidth * height; i < enddata; i++)
		bitmap[i] = '\0';

/*	printf("Magic:%s, Width:%d Height:%d Size:%d\n\n", magicstr,
	    width, height, bytes-datastart);
	    */

	for (row = 0; row < bheight; row++) {
		for (col = 0; col < bwidth; col++) {
			for (i=0; i<8; i++)
				buffer[i] = bitmap[datastart + col + bwidth * (i+row*8)] & 255;
			character = convert(buffer);
			printf("%c", character);
		}
		printf("\n");
	}

/*	printf("Ok.\n");*/
	close(file);
}

int convert (char *buffer)
{

	/* The font data: */
	static long font[768]=
	{
		/* Row 0: */
		0x0018,0x6C6C,0x1800,0x3818,0x0C30,0x0000,0x0000,0x0003,
		0x7C18,0x7C7C,0x1CFE,0x38FE,0x7C7C,0x0000,0x0C00,0x303C,
		0x7C18,0xFC3C,0xF8FE,0xFE3C,0xC63C,0x06C6,0xC082,0xC638,
		0xFC38,0xFC7C,0x7EC6,0xC3C6,0xC3C3,0xFE3C,0xC03C,0x1000,
		0x1800,0xC000,0x0600,0x1C00,0xC018,0x06C0,0x3800,0x0000,
		0x0000,0x0000,0x1000,0x0000,0x0000,0x000E,0x1870,0x72CC,
		/* Row 1: */
		0x003C,0x6C6C,0x7EC6,0x6C18,0x1818,0x6618,0x0000,0x0006,
		0xC638,0xC6C6,0x3CC0,0x6006,0xC6C6,0x1818,0x1800,0x1866,
		0xC63C,0xC666,0xCCC0,0xC066,0xC618,0x06C6,0xC0C6,0xE66C,
		0xC66C,0xC6C6,0x18C6,0xC3C6,0x66C3,0x0630,0x600C,0x3800,
		0x1800,0xC000,0x0600,0x3600,0xC000,0x00C0,0x1800,0x0000,
		0x0000,0x0000,0x3000,0x0000,0x0000,0x0018,0x1818,0x9C33,
		/* Row 2: */
		0x003C,0x00FE,0xC0CC,0x6830,0x300C,0x3C18,0x0000,0x000C,
		0xCE18,0x0606,0x6CFC,0xC006,0xC6C6,0x1818,0x307E,0x0C06,
		0xDE3C,0xC6C0,0xC6C0,0xC0C0,0xC618,0x06CC,0xC0EE,0xF6C6,
		0xC6C6,0xC6E0,0x18C6,0x66C6,0x3C66,0x0C30,0x300C,0x6C00,
		0x0C7C,0xDC7C,0x767C,0x3076,0xDC18,0x06C6,0x18CC,0xFC7C,
		0xFC7E,0xDC7E,0xFEC6,0xC6C6,0xC6C6,0xFC18,0x1818,0x00CC,
		/* Row 3: */
		0x0018,0x006C,0x7C18,0x7600,0x300C,0xFF7E,0x007E,0x0018,
		0xDE18,0x1C3C,0xCC06,0xFC0C,0x7C7E,0x0000,0x6000,0x060C,
		0xDE66,0xFCC0,0xC6F8,0xF8C6,0xFE18,0x06F8,0xC0FE,0xDEC6,
		0xFCC6,0xFC38,0x18C6,0x66D6,0x183C,0x1830,0x180C,0xC600,
		0x0006,0xE6C6,0xCEC6,0xFCCC,0xE618,0x06CC,0x18FE,0xC6C6,
		0xC6C6,0xE6C0,0x30C6,0xC6D6,0x6CC6,0x1870,0x180E,0x0033,
		/* Row 4: */
		0x0018,0x00FE,0x0630,0xDC00,0x300C,0x3C18,0x0000,0x0030,
		0xF618,0x7006,0xFE06,0xC618,0xC606,0x0000,0x3000,0x0C18,
		0xDE7E,0xC6C0,0xC6C0,0xC0C6,0xC618,0xC6CC,0xC0D6,0xCEC6,
		0xC0C6,0xD80E,0x18C6,0x3CFE,0x3C18,0x3030,0x0C0C,0x0000,
		0x007E,0xC6C0,0xC6FE,0x30CC,0xC618,0x06F8,0x18D6,0xC6C6,
		0xC6C6,0xC07C,0x30C6,0xC6D6,0x38C6,0x3018,0x1818,0x00CC,
		/* Row 5: */
		0x0000,0x006C,0xFC66,0xCC00,0x1818,0x6618,0x1800,0x1860,
		0xC618,0xC0C6,0x0CC6,0xC630,0xC60C,0x1818,0x187E,0x1800,
		0xC0C3,0xC666,0xCCC0,0xC066,0xC618,0xC6C6,0xC0C6,0xC66C,
		0xC06C,0xCCC6,0x18C6,0x3CEE,0x6618,0x6030,0x060C,0x0000,
		0x00C6,0xC6C6,0xC6C0,0x3078,0xC618,0x06CC,0x18C6,0xC6C6,
		0xC6C6,0xC006,0x34C6,0x6C6C,0x6C7C,0x6018,0x1818,0x0033,
		/* Row 6: */
		0x0018,0x006C,0x18C6,0x7600,0x0C30,0x0000,0x1800,0x18C0,
		0x7C3C,0xFE7C,0x0C7C,0x7C30,0x7C38,0x1818,0x0C00,0x3018,
		0x78C3,0xFC3C,0xF8FE,0xC03E,0xC63C,0x7CC6,0xFEC6,0xC638,
		0xC03C,0xC67C,0x187E,0x18C6,0xC318,0xFE3C,0x033C,0x0000,
		0x007E,0xFC7C,0x7E7C,0x30C6,0xC618,0xC6C6,0x18C6,0xC67C,
		0xFC7E,0xC0FC,0x187E,0x386C,0xC618,0xFE0E,0x1870,0x00CC,
		/* Row 7: */
		0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x0000,
		0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,
		0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
		0x0006,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00FE,
		0x0000,0x0000,0x0000,0x007C,0x0000,0x7C00,0x0000,0x0000,
		0xC007,0x0000,0x0000,0x0000,0x00F0,0x0000,0x0000,0x0033
	};

	char character[8];
	int row, col, c=' ', match, omatch=0;
	if (buffer == "\0\0\0\0\0\0\0\0")
		return ' ';

	for (col = 0; col <= 47; col++) {
		for (row = 0; row < 8; row++)
			character[row] = font[col + row * 48] / 256;

		match = percentage(character, buffer);
		if (match > omatch) {
			c = 32 + col*2;
			omatch = match;
		};

		for (row = 0; row < 8; row++)
			character[row] = font[col + row * 48] % 256;

		match = percentage(character, buffer);
		if (match > omatch && col != 47) {
			c = 33 + col*2;
			omatch = match;
		};

	};
        return c;
}

int percentage (char *v1, char *v2)
{
	int byte, num1, num2, hits=0;
	int bits[8]={128,64,32,16,8,4,2,1}, bit, slice;

	for (byte = 0; byte < 8; byte++) {
		for (bit = 0; bit < 8; bit++) {
			num1 = v1[byte];
			num2 = v2[byte];
			slice = bits[bit];
			num1 = num1 & slice;
			num2 = num2 & slice;
			hits = hits + (num1 == num2);
		};
	};

	return hits;
}