Code:
/*
* Filename: pcltool.c
*
* Author: Osvaldo Marques Junior <osvaldo@dis-rj.com.br>
* Rio de Janeiro, june, 30, 2006.
*
* This program may read a PCL5 image file and creates a text file
* with the pcl commands that can be edited with a text editor like
* vi, vim, mcedit, notepad, etc.
* It also reads the generated and/or edited text file to rebuild the
* PCL image file.
*
* Original commands can be commented to change the behavior of the
* image to be printed by placing a '#' on the beginning of the
* line.
* New commands can be inserted, text position can be edited.
*
* This program was originally developed for SCO C compiler almost 15
* years ago. For the last 10 years, it is running on GNU/Linux with
* the GCC compiler. I believe it's not too hard to compile it with
* Borland and MS compilers.
*
* For instance, here is an excerpt of a converted pcl file:
*
* 0x1b, "E",
* 0x1b, "&l6D",
* 0x1b, "&k12H",
* 0x1b, "&l0O",
* 0x1b, "&l2A",
* 0x1b, "&l66P",
* 0x1b, "&l0L",
* 0x1b, "&l0E",
* 0x1b, "*t600R",
*
* To compile it, just enter:
* cc -o pcltool pcltool.c
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
void compose_pcl_file(FILE *in, FILE *out)
{
int chr
,digit
;
char buffer[1024]
,*p1
;
while (fgets(buffer, sizeof(buffer), in) != NULL)
{
for (p1 = buffer + strlen(buffer); p1 >= buffer; p1--)
{
if (*p1 <= ' ')
*p1 = '\0';
else
break;
}
for (p1 = buffer; *p1; p1++)
{
if (*p1 == '0' && *(p1 + 1) == 'x')
{
p1 += 2;
digit = toupper(*p1) - '0';
if (digit > 9)
digit -= 7;
chr = digit * 16;
p1++;
digit = toupper(*p1) - '0';
if (digit > 9)
digit -= 7;
chr += digit;
fputc(chr, out);
}
else
if (*p1 == '\\' && toupper(*(p1 + 1)) == 'E')
{
fputc(0x1b, out);
p1++;
continue;
}
else
if (*p1 == '"')
{
for (p1++; *p1; p1++)
{
if (*p1 == '"' &&
(*(p1 + 1) == ',' || *(p1 + 1) == '\0') &&
(*(p1 + 2) == ' ' || *(p1 + 2) == '\0'))
break;
switch(*p1)
{
case '\\':
if (*(p1 + 1) == 'n')
{
fputc('\n', out);
p1++;
break;
}
else
if (toupper(*(p1 + 1)) == 'E')
{
fputc(0x1b, out);
p1++;
break;
}
default:
fputc(*p1, out);
}
}
}
else
if (*p1 == '#')
break;
}
}
}
void unload_parsed_buffer(int buffer_length, char *buffer, FILE *out)
{
int index
,output_active
;
output_active = 0;
for (index = 0; index < buffer_length; index++)
{
if (*(buffer + index) >= ' ' &&
*(buffer + index) <= 0x7e)
{
if (!output_active)
{
fprintf(out, "\"");
output_active = 1;
}
fprintf(out, "%c", *(buffer + index));
}
else
{
if (output_active)
{
fprintf(out, "\", ");
output_active = 0;
}
if (*(buffer + index) == 0x0a)
fprintf(out, "\"\\n\"\n");
else
fprintf(out, "0x%02x, ", *(buffer + index));
}
}
if (output_active)
{
fprintf(out, "\", ");
output_active = 0;
}
fprintf(out, "\n");
}
void disassemble_pcl_file(FILE *in, FILE *out)
{
int chr
,parm
,group
,state
,input_index
,graphic_length
,format_control
;
char buffer[4096]
,*tmp_inx
;
state =
input_index = 0;
chr = getc(in);
while (!feof(in))
{
switch (state)
{
case 0:
if (chr == 0x1b) /* Esc */
{
if (input_index) /* There is something left on the buffer */
{
unload_parsed_buffer(input_index, buffer, out);
input_index = 0;
}
state = 1;
*(buffer + input_index++) = chr;
}
else
{
*(buffer + input_index++) = chr;
if (chr == '\n' || input_index >= sizeof(buffer))
{
unload_parsed_buffer(input_index, buffer, out);
input_index = 0;
}
}
break;
case 1: /* PCL Escape sequence */
*(buffer + input_index++) = chr;
if ((chr == '9' && input_index == 1) ||
chr == '@' ||
chr == '=' ||
(chr >= 'A' && chr <= 'Z'))
{
unload_parsed_buffer(input_index, buffer, out);
parm = *(buffer + 1);
group = *(buffer + 2);
if ((parm == '*' && group == 'b' && chr == 'V') ||
(parm == '&' && group == 'p' && chr == 'X') ||
(chr == 'W' &&
((parm == '*' && (group == 'b' || group == 'c' ||
group == 'l' || group == 'v' ||
group == 'i')) ||
(parm == '(' && (group == 's' || group == 'f')) ||
(parm == ')' && group == 's') ||
(parm == '&' && (group == 'b' || group == 'n')))))
{
state = 2;
format_control = 99;
graphic_length = 0;
for (tmp_inx = buffer + input_index - 2;
tmp_inx > buffer && *tmp_inx >= '0' && *tmp_inx <= '9';
tmp_inx--);
for (tmp_inx++;
*tmp_inx >= '0' && *tmp_inx <= '9';
tmp_inx++)
{
graphic_length *= 10;
graphic_length += *tmp_inx - '0';
}
if (graphic_length == 0)
state = 0;
*(buffer + input_index) = 0;
}
else
state = 0;
input_index = 0;
}
break;
case 2:
if (format_control >= 8)
{
if (format_control < 99)
fprintf(out, "\n");
fprintf(out, " ");
format_control = 0;
}
format_control++;
fprintf(out, "0x%02x, ", chr);
graphic_length--;
if (graphic_length == 0)
{
state = 0;
fprintf(out, "\n");
}
break;
}
chr = getc(in);
}
}
int main(int argc, char **argv)
{
FILE *in
,*out
;
if (argc < 4 ||
(strcmp(argv[1], "pcltotext") != 0 &&
strcmp(argv[1], "texttopcl") != 0))
{
printf("Usage: %s pcltotext <pcl input file> <parsed output file>\n", argv[0]);
printf(" or: %s texttopcl <parsed input file> <pcl output file>\n", argv[0]);
return 1;
}
if (strcmp(argv[2], "-") == 0) /* Standard input */
in = stdin;
else
if ((in = fopen(argv[2], "r")) == NULL)
{
printf("Couldn't open file \"%s\"\n", argv[1]);
return 1;
}
if (strcmp(argv[3], "-") == 0) /* Standard output */
out = stdout;
else
if ((out = fopen(argv[3], "w")) == NULL)
{
printf("Couldn't open output file \"%s\"\n", argv[2]);
return 1;
}
if (strcmp(argv[1], "pcltotext") == 0)
disassemble_pcl_file(in, out);
else
compose_pcl_file(in, out);
fclose(in);
fclose(out);
return 0;
}