Decoding stream containing hex-values received on Serial port.

#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