#include <stdio.h>
#include <stdbool.h>
#define BYTES_IN_PRINT_LINE 5
#define IMAGE_WIDTH_IN_PIXELS 16
char readChar();
bool readPixelByte(unsigned char *pixelByte);
void DrivePrintHead(unsigned char *printLine);
unsigned char printLine[BYTES_IN_PRINT_LINE];
int main()
{
int imageWidthInBytes;
unsigned char byte;
int byteCount;
char chr;
char *charRead;
// image widths in pixels do not need to be a multiple of 8
// If the image width does not match a multiple of 8, the extra bits in the last byte of each row are ignored
imageWidthInBytes=(IMAGE_WIDTH_IN_PIXELS+7)/8;
// Set line forprinting to blank
for(int i=0;i<BYTES_IN_PRINT_LINE;++i)
{
printLine[i]=0;
}
byteCount=0;
while(readPixelByte(&byte))// while image bytes can be read
{
printLine[byteCount]=byte;// store the byte
++byteCount;
if(byteCount==imageWidthInBytes)
{
// print the line of pixels
DrivePrintHead(&printLine[0]);
byteCount=0;// get ready to read and print next line
}
}
return 0;
}
void DrivePrintHead(unsigned char *printLine)
{
// This prints the data
// the Arduino would actually use the data to drive the printhead
for(int i=0;i<BYTES_IN_PRINT_LINE;++i)
{
printf("%02X ",*printLine);
++printLine;
}
printf("\n");
return;
}
bool readPixelByte(unsigned char *pixelByte)
{
// Read each byte to be printed.
// return true if a byte has been sucessfully read otherwise return false.
static bool startOfDataFound=false;
bool passed;
char chr;
unsigned char value;
if(!startOfDataFound)
{
// Discard all characters until '{' is read or the end of string is reached.
// Really the program should use these characters to find the image size
do
{
chr=readChar();
if(chr=='{')
{
startOfDataFound=true;
}
}while(chr&&!startOfDataFound);
}
do
{
chr=readChar();
}while(chr&&chr!='x');// read through data until an 'x' is found.
passed=true;
for(int i=0;i<2;++i)// read the next two characters which should be the hexadecimal representation of a byte for printing
{
chr=readChar();
if(chr>='0'&&chr<='9')
{
chr=chr-'0';
}
else if(chr>='A'&&chr<='F')
{
chr=chr-'A'+10;
}
else
{
passed=false;
}
if(i==0)
{
// First nibble
value=chr<<4;
}
else
{ //Second nibble
value=value|chr;
}
}
if(passed)
{
*pixelByte=value;
}
return(passed);
}
char readChar()
{
/*
This function simulates reading a file one character at a time.
It is actually getting the characters from a null terminated string.
The function will not return character beyond the terminating null.
*/
static bool firstCall=true;
static bool endOfData=false;
static char *chrPntr;
static char contentsXBM[]="#define 16x16_width 16\n#define 16x16_height 16\nstatic unsigned char 16x16_bits[] =\n{\n\t0x00,0x01,\n\t0x02,0x03,\n\t0x04,0x05,\n\t0x06,0x07,\n\t0x08,0x09,\n\t0x0A,0x0B,\n\t0x0C,0x4D,\n\t0x0E,0x0F,\n\t0x10,0x11,\n\t0x12,0x13,\n\t0x14,0x15,\n\t0x16,0x17,\n\t0x18,0x19,\n\t0x1A,0x1B,\n\t0x1C,0x1D,\n\t0x1E,0x1F\n};\n";
if(firstCall)
{
firstCall=false;
chrPntr=&contentsXBM[0];
printf("\n\n%s\n\n",chrPntr);// display the full file contents to aid debugging
}
else if(!endOfData)
{
++chrPntr;
}
if(*chrPntr=='\0')
{
endOfData=true;// do not permit reading beyond the end of the string.
}
// printf("%c",*chrPntr);// display returned character for debugging
return(*chrPntr);
}
Output;
$gcc -o main *.c
$main
#define 16x16_width 16
#define 16x16_height 16
static unsigned char 16x16_bits[] =
{
0x00,0x01,
0x02,0x03,
0x04,0x05,
0x06,0x07,
0x08,0x09,
0x0A,0x0B,
0x0C,0x4D,
0x0E,0x0F,
0x10,0x11,
0x12,0x13,
0x14,0x15,
0x16,0x17,
0x18,0x19,
0x1A,0x1B,
0x1C,0x1D,
0x1E,0x1F
};
00 01 00 00 00
02 03 00 00 00
04 05 00 00 00
06 07 00 00 00
08 09 00 00 00
0A 0B 00 00 00
0C 4D 00 00 00
0E 0F 00 00 00
10 11 00 00 00
12 13 00 00 00
14 15 00 00 00
16 17 00 00 00
18 19 00 00 00
1A 1B 00 00 00
1C 1D 00 00 00
1E 1F 00 00 00