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; }