1/* 2 * "$Id: pcl-unprint.c,v 1.11 2004/09/17 18:38:28 rleigh Exp $" 3 * 4 * pclunprint.c - convert an HP PCL file into an image file for viewing. 5 * 6 * Copyright 2000 Dave Hill (dave@minnie.demon.co.uk) 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the Free 10 * Software Foundation; either version 2 of the License, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 * 22 * Revision History: 23 * 24 * See ChangeLog 25 */ 26 27#ifdef HAVE_CONFIG_H 28#include <config.h> 29#endif 30#include <gutenprint/util.h> 31#include<stdio.h> 32#include<stdlib.h> 33#include<ctype.h> 34#include<string.h> 35 36static const char *id="@(#) $Id: pcl-unprint.c,v 1.11 2004/09/17 18:38:28 rleigh Exp $"; 37 38/* 39 * Size of buffer used to read file 40 */ 41#define READ_SIZE 1024 42 43/* 44 * Largest data attached to a command. 1024 means that we can have up to 8192 45 * pixels in a row 46 */ 47#define MAX_DATA 1024 48 49FILE *read_fd,*write_fd; 50char read_buffer[READ_SIZE]; 51char data_buffer[MAX_DATA]; 52char initial_command[3]; 53int initial_command_index; 54char final_command; 55int numeric_arg; 56 57int read_pointer; 58int read_size; 59int eof; 60int combined_command = 0; 61int skip_output = 0; 62 63/* 64 * Data about the image 65 */ 66 67typedef struct { 68 int colour_type; /* Mono, 3/4 colour */ 69 int black_depth; /* 2 level, 4 level */ 70 int cyan_depth; /* 2 level, 4 level */ 71 int magenta_depth; /* 2 level, 4 level */ 72 int yellow_depth; /* 2 level, 4 level */ 73 int lcyan_depth; /* 2 level, 4 level */ 74 int lmagenta_depth; /* 2 level, 4 level */ 75 int image_width; 76 int image_height; 77 int compression_type; /* Uncompressed or TIFF */ 78} image_t; 79 80/* 81 * collected data read from file 82 */ 83 84typedef struct { 85 char **black_bufs; /* Storage for black rows */ 86 int black_data_rows_per_row; /* Number of black rows */ 87 char **cyan_bufs; 88 int cyan_data_rows_per_row; 89 char **magenta_bufs; 90 int magenta_data_rows_per_row; 91 char **yellow_bufs; 92 int yellow_data_rows_per_row; 93 char **lcyan_bufs; 94 int lcyan_data_rows_per_row; 95 char **lmagenta_bufs; 96 int lmagenta_data_rows_per_row; 97 int buffer_length; 98 int active_length; /* Length of output data */ 99 int output_depth; 100} output_t; 101 102#define PCL_MONO 1 103#define PCL_CMY 3 104#define PCL_CMYK 4 105#define PCL_CMYKcm 6 106 107#define PCL_COMPRESSION_NONE 0 108#define PCL_COMPRESSION_RUNLENGTH 1 109#define PCL_COMPRESSION_TIFF 2 110#define PCL_COMPRESSION_DELTA 3 111#define PCL_COMPRESSION_CRDR 9 /* Compressed row delta replacement */ 112 113/* PCL COMMANDS */ 114 115typedef enum { 116 PCL_RESET = 1,PCL_MEDIA_SIZE,PCL_PERF_SKIP,PCL_TOP_MARGIN,PCL_MEDIA_TYPE, 117 PCL_MEDIA_SOURCE,PCL_SHINGLING,PCL_RASTERGRAPHICS_QUALITY,PCL_DEPLETION, 118 PCL_CONFIGURE,PCL_RESOLUTION,PCL_COLOURTYPE,PCL_COMPRESSIONTYPE, 119 PCL_LEFTRASTER_POS,PCL_TOPRASTER_POS,PCL_RASTER_WIDTH,PCL_RASTER_HEIGHT, 120 PCL_START_RASTER,PCL_END_RASTER,PCL_END_COLOUR_RASTER,PCL_DATA,PCL_DATA_LAST, 121 PCL_PRINT_QUALITY,PCL_ENTER_PJL,PCL_GRAY_BALANCE,PCL_DRIVER_CONFIG, 122 PCL_PAGE_ORIENTATION,PCL_VERTICAL_CURSOR_POSITIONING_BY_DOTS, 123 PCL_HORIZONTAL_CURSOR_POSITIONING_BY_DOTS,PCL_UNIT_OF_MEASURE, 124 PCL_RELATIVE_VERTICAL_PIXEL_MOVEMENT,PCL_PALETTE_CONFIGURATION, 125 PCL_LPI,PCL_CPI,PCL_PAGE_LENGTH,PCL_NUM_COPIES,PCL_DUPLEX, 126 PCL_MEDIA_SIDE,RTL_CONFIGURE,PCL_ENTER_PCL,PCL_ENTER_HPGL2, 127 PCL_NEGATIVE_MOTION,PCL_MEDIA_DEST,PCL_JOB_SEPARATION, 128 PCL_LEFT_OFFSET_REGISTRATION,PCL_TOP_OFFSET_REGISTRATION, 129 PCL_PRINT_DIRECTION,PCL_LEFT_MARGIN,PCL_RIGHT_MARGIN, 130 PCL_RESET_MARGINS,PCL_TEXT_LENGTH 131} command_t; 132 133typedef struct { 134 const char initial_command[3]; /* First part of command */ 135 const char final_command; /* Last part of command */ 136 int has_data; /* Data follows */ 137 command_t command; /* Command name */ 138 const char *description; /* Text for printing */ 139} commands_t; 140 141const commands_t pcl_commands[] = 142 { 143/* Two-character sequences ESC <x> */ 144 { "E", '\0', 0, PCL_RESET, "PCL RESET" }, 145 { "9", '\0', 0, PCL_RESET_MARGINS, "Reset Margins" }, 146 { "%", 'A', 0, PCL_ENTER_PCL, "PCL mode" }, 147 { "%", 'B', 0, PCL_ENTER_HPGL2, "HPGL/2 mode" }, 148 { "%", 'X', 0, PCL_ENTER_PJL, "UEL/Enter PJL mode" }, 149/* Parameterised sequences */ 150/* Raster positioning */ 151 { "&a", 'G', 0, PCL_MEDIA_SIDE, "Set Media Side" }, 152 { "&a", 'H', 0, PCL_LEFTRASTER_POS, "Left Raster Position" }, 153 { "&a", 'L', 0, PCL_LEFT_MARGIN, "Left Margin by Column" }, 154 { "&a", 'M', 0, PCL_RIGHT_MARGIN, "Right Margin by Column" }, 155 { "&a", 'N', 0, PCL_NEGATIVE_MOTION, "Negative Motion" }, 156 { "&a", 'P', 0, PCL_PRINT_DIRECTION, "Print Direction" }, 157 { "&a", 'V', 0, PCL_TOPRASTER_POS, "Top Raster Position" }, 158/* Characters */ 159 { "&k", 'H', 0, PCL_CPI, "Characters per Inch" }, 160/* Media */ 161 { "&l", 'A', 0, PCL_MEDIA_SIZE , "Media Size" }, 162 { "&l", 'D', 0, PCL_LPI , "Lines per Inch" }, 163 { "&l", 'E', 0, PCL_TOP_MARGIN , "Top Margin" }, 164 { "&l", 'F', 0, PCL_TEXT_LENGTH , "Text Length" }, 165 { "&l", 'G', 0, PCL_MEDIA_DEST, "Media Destination" }, 166 { "&l", 'H', 0, PCL_MEDIA_SOURCE, "Media Source" }, 167 { "&l", 'L', 0, PCL_PERF_SKIP , "Perf. Skip" }, 168 { "&l", 'M', 0, PCL_MEDIA_TYPE , "Media Type" }, 169 { "&l", 'O', 0, PCL_PAGE_ORIENTATION, "Page Orientation" }, 170 { "&l", 'P', 0, PCL_PAGE_LENGTH, "Page Length in Lines" }, 171 { "&l", 'S', 0, PCL_DUPLEX, "Duplex mode" }, 172 { "&l", 'T', 0, PCL_JOB_SEPARATION, "Job Separation" }, 173 { "&l", 'U', 0, PCL_LEFT_OFFSET_REGISTRATION, "Left Offset Registration" }, 174 { "&l", 'X', 0, PCL_NUM_COPIES, "Number of copies" }, 175 { "&l", 'Z', 0, PCL_TOP_OFFSET_REGISTRATION, "Top Offset Registration" }, 176/* Units */ 177 { "&u", 'D', 0, PCL_UNIT_OF_MEASURE, "Unit of Measure" }, /* from bpd05446 */ 178/* Raster data */ 179 { "*b", 'B', 0, PCL_GRAY_BALANCE, "Gray Balance" }, /* from PCL Developer's Guide 6.0 */ 180 { "*b", 'M', 0, PCL_COMPRESSIONTYPE, "Compression Type" }, 181 { "*b", 'V', 1, PCL_DATA, "Data, intermediate" }, 182 { "*b", 'W', 1, PCL_DATA_LAST, "Data, last" }, 183 { "*b", 'Y', 0, PCL_RELATIVE_VERTICAL_PIXEL_MOVEMENT, "Relative Vertical Pixel Movement" }, 184/* Palette */ 185 { "*d", 'W', 1, PCL_PALETTE_CONFIGURATION, "Palette Configuration" }, 186/* Plane configuration */ 187 { "*g", 'W', 1, PCL_CONFIGURE, "Configure Raster Data" }, 188/* Raster Graphics */ 189 { "*o", 'D', 0, PCL_DEPLETION, "Depletion" }, 190 { "*o", 'M', 0, PCL_PRINT_QUALITY, "Print Quality" }, 191 { "*o", 'Q', 0, PCL_SHINGLING, "Raster Graphics Shingling" }, 192 { "*o", 'W', 1, PCL_DRIVER_CONFIG, "Driver Configuration Command" }, 193/* Cursor Positioning */ 194 { "*p", 'X', 0, PCL_HORIZONTAL_CURSOR_POSITIONING_BY_DOTS, "Horizontal Cursor Positioning by Dots" }, 195 { "*p", 'Y', 0, PCL_VERTICAL_CURSOR_POSITIONING_BY_DOTS, "Vertical Cursor Positioning by Dots" }, 196/* Raster graphics */ 197 { "*r", 'A', 0, PCL_START_RASTER, "Start Raster Graphics" }, 198 { "*r", 'B', 0, PCL_END_RASTER, "End Raster Graphics"}, 199 { "*r", 'C', 0, PCL_END_COLOUR_RASTER, "End Colour Raster Graphics" }, 200 { "*r", 'Q', 0, PCL_RASTERGRAPHICS_QUALITY, "Raster Graphics Quality" }, 201 { "*r", 'S', 0, PCL_RASTER_WIDTH, "Raster Width" }, 202 { "*r", 'T', 0, PCL_RASTER_HEIGHT, "Raster Height" }, 203 { "*r", 'U', 0, PCL_COLOURTYPE, "Colour Type" }, 204/* Resolution */ 205 { "*t", 'R', 0, PCL_RESOLUTION, "Resolution" }, 206/* RTL/PCL5 */ 207 { "*v", 'W', 1, RTL_CONFIGURE, "RTL Configure Image Data" }, 208 }; 209 210int pcl_find_command (void); 211void fill_buffer (void); 212void pcl_read_command (void); 213void write_grey (output_t *output, image_t *image); 214void write_colour (output_t *output, image_t *image); 215int decode_tiff (char *in_buffer, int data_length, char *decode_buf, 216 int maxlen); 217void pcl_reset (image_t *i); 218int depth_to_rows (int depth); 219 220 221/* 222 * pcl_find_command(). Search the commands table for the command. 223 */ 224 225int pcl_find_command(void) 226{ 227 228 int num_commands = sizeof(pcl_commands) / sizeof(commands_t); 229 int i; 230 231 for (i=0; i < num_commands; i++) { 232 if ((strcmp(initial_command, pcl_commands[i].initial_command) == 0) && 233 (final_command == pcl_commands[i].final_command)) 234 return(i); 235 } 236 237 return (-1); 238} 239 240/* 241 * fill_buffer() - Read a new chunk from the input file 242 */ 243 244void fill_buffer(void) 245{ 246 247 if ((read_pointer == -1) || (read_pointer >= read_size)) { 248 read_size = (int) fread(&read_buffer, sizeof(char), READ_SIZE, read_fd); 249 250#ifdef DEBUG 251 fprintf(stderr, "Read %d characters\n", read_size); 252#endif 253 254 if (read_size == 0) { 255#ifdef DEBUG 256 fprintf(stderr, "No More to read!\n"); 257#endif 258 eof = 1; 259 return; 260 } 261 read_pointer = 0; 262 } 263} 264 265/* 266 * pcl_read_command() - Read the data stream and parse the next PCL 267 * command. 268 */ 269 270void pcl_read_command(void) 271{ 272 273 char c; 274 int minus; 275 int skipped_chars; 276 277/* 278 Precis from the PCL Developer's Guide 6.0:- 279 280 There are two formats for PCL commands; "Two Character" and 281 "Parameterised". 282 283 A "Two Character" command is: ESC <x>, where <x> has a decimal 284 value between 48 and 126 (inclusive). 285 286 A "Parameterised" command is: ESC <x> <y> [n] <z> 287 where x, y and z are characters, and [n] is an optional number. 288 The character <x> has a decimal value between 33 and 47 (incl). 289 The character <y> has a decimal value between 96 and 126 (incl). 290 291 Some commands are followed by data, in this case, [n] is the 292 number of bytes to read, otherwise <n> is a numeric argument. 293 The number <n> can consist of +, - and 0-9 (and .). 294 295 The character <z> is either in the range 64-94 for a termination 296 or 96-126 for a combined command. (The ref guide gives these 297 as "96-126" and "64-96" which cannot be right as 96 appears twice!) 298 299 It is possible to combine parameterised commands if the 300 command prefix is the same, e.g. ESC & l 26 a 0 L is the same as 301 ESC & l 26 A ESC & l 0 L. The key to this is that the terminator for 302 the first command is in the range 96-126 (lower case). 303 304 There is a problem with the "escape command" (ESC %) as it does not 305 conform to this specification, so we have to check for it specifically! 306*/ 307 308#define PCL_DIGIT(c) (((unsigned int) c >= 48) && ((unsigned int) c <= 57)) 309#define PCL_TWOCHAR(c) (((unsigned int) c >= 48) && ((unsigned int) c <= 126)) 310#define PCL_PARAM(c) (((unsigned int) c >= 33) && ((unsigned int) c <= 47)) 311#define PCL_PARAM2(c) (((unsigned int) c >= 96) && ((unsigned int) c <= 126)) 312#define PCL_COMBINED_TERM(c) (((unsigned int) c >= 96) && ((unsigned int) c <= 126)) 313#define PCL_TERM(c) (((unsigned int) c >= 64) && ((unsigned int) c <= 94)) 314#define PCL_CONVERT_TERM(c) (c - (char) 32) 315 316 numeric_arg=0; 317 minus = 0; 318 final_command = '\0'; 319 320 fill_buffer(); 321 if (eof == 1) 322 return; 323 324 c = read_buffer[read_pointer++]; 325#ifdef DEBUG 326 fprintf(stderr, "Got %c\n", c); 327#endif 328 329/* 330 * If we are not in a "combined command", we are looking for ESC 331 */ 332 333 if (combined_command == 0) { 334 335 if(c != (char) 0x1b) { 336 337 fprintf(stderr, "ERROR: No ESC found (out of sync?) searching... "); 338 339/* 340 * all we can do is to chew through the file looking for another ESC. 341 */ 342 343 skipped_chars = 0; 344 while (c != (char) 0x1b) { 345 if (c == (char) 0x0c) 346 fprintf(stderr, "FF "); 347 skipped_chars++; 348 fill_buffer(); 349 if (eof == 1) { 350 fprintf(stderr, "ERROR: EOF looking for ESC!\n"); 351 return; 352 } 353 c = read_buffer[read_pointer++]; 354 } 355 fprintf(stderr, "%d characters skipped.\n", skipped_chars); 356 } 357 358/* 359 * We got an ESC, process normally 360 */ 361 362 initial_command_index=0; 363 initial_command[initial_command_index] = '\0'; 364 fill_buffer(); 365 if (eof == 1) { 366 fprintf(stderr, "ERROR: EOF after ESC!\n"); 367 return; 368 } 369 370/* Get first command letter */ 371 372 c = read_buffer[read_pointer++]; 373 initial_command[initial_command_index++] = c; 374 375#ifdef DEBUG 376 fprintf(stderr, "Got %c\n", c); 377#endif 378 379/* Check to see if this character forms a "two character" command, 380 or is a special command. */ 381 382 if (PCL_TWOCHAR(c)) { 383#ifdef DEBUG 384 fprintf(stderr, "Two character command\n"); 385#endif 386 initial_command[initial_command_index] = '\0'; 387 return; 388 } /* two character check */ 389 390/* Now check for a "parameterised" sequence. */ 391 392 else if (PCL_PARAM(c)) { 393#ifdef DEBUG 394 fprintf(stderr, "Parameterised command\n"); 395#endif 396 397/* Get the next character in the command */ 398 399 fill_buffer(); 400 if (eof == 1) { 401 402#ifdef DEBUG 403 fprintf(stderr, "EOF in middle of command!\n"); 404#endif 405 eof = 0; /* Ignore it */ 406 initial_command[initial_command_index] = '\0'; 407 return; 408 } 409 c = read_buffer[read_pointer++]; 410#ifdef DEBUG 411 fprintf(stderr, "Got %c\n", c); 412#endif 413 414/* Check that it is legal and store it */ 415 416 if (PCL_PARAM2(c)) { 417 initial_command[initial_command_index++] = c; 418 initial_command[initial_command_index] = '\0'; 419 420/* Get the next character in the command then fall into the numeric part */ 421 422 fill_buffer(); 423 if (eof == 1) { 424 425#ifdef DEBUG 426 fprintf(stderr, "EOF in middle of command!\n"); 427#endif 428 eof = 0; /* Ignore it */ 429 return; 430 } 431 c = read_buffer[read_pointer++]; 432#ifdef DEBUG 433 fprintf(stderr, "Got %c\n", c); 434#endif 435 436 } 437 else { 438/* The second character is not legal. If the first character is '%' then allow it 439 * through */ 440 441 if (initial_command[0] == '%') { 442#ifdef DEBUG 443 fprintf(stderr, "ESC%% commmand\n"); 444#endif 445 initial_command[initial_command_index] = '\0'; 446 } 447 else { 448 fprintf(stderr, "ERROR: Illegal second character %c in parameterised command.\n", 449 c); 450 initial_command[initial_command_index] = '\0'; 451 return; 452 } 453 } 454 } /* Parameterised check */ 455 456/* If we get here, the command is illegal */ 457 458 else { 459 fprintf(stderr, "ERROR: Illegal first character %c in command.\n", 460 c); 461 initial_command[initial_command_index] = '\0'; 462 return; 463 } 464 } /* End of (combined_command) */ 465 466/* 467 We get here if either this is a combined sequence, or we have processed 468 the beginning of a parameterised sequence. There is an optional number 469 next, which may be preceeded by "+" or "-". FIXME We should also handle 470 decimal points. 471*/ 472 473 if ((c == '-') || (c == '+') || (PCL_DIGIT(c))) { 474 if (c == '-') 475 minus = 1; 476 else if (c == '+') 477 minus = 0; 478 else 479 numeric_arg = (int) (c - '0'); 480 481/* Continue until non-numeric seen */ 482 483 while (1) { 484 fill_buffer(); 485 if (eof == 1) { 486 fprintf(stderr, "ERROR: EOF in middle of command!\n"); 487 return; 488 } 489 c = read_buffer[read_pointer++]; 490 491#ifdef DEBUG 492 fprintf(stderr, "Got %c\n", c); 493#endif 494 495 if (! PCL_DIGIT(c)) { 496 break; /* End of loop */ 497 } 498 numeric_arg = (10 * numeric_arg) + (int) (c - '0'); 499 } 500 } 501 502/* 503 We fell out of the loop when we read a non-numeric character. 504 Treat this as the terminating character and check for a combined 505 command. We should check that the letter is a valid terminator, 506 but it doesn't matter as we'll just not recognize the command! 507 */ 508 509 combined_command = (PCL_COMBINED_TERM(c) != 0); 510 if (combined_command == 1) { 511#ifdef DEBUG 512 fprintf(stderr, "Combined command\n"); 513#endif 514 final_command = PCL_CONVERT_TERM(c); 515 } 516 else 517 final_command = c; 518 519 if (minus == 1) 520 numeric_arg = -numeric_arg; 521 522 return; 523} 524 525/* 526 * write_grey() - write out one line of mono PNM image 527 */ 528 529/* FIXME - multiple levels */ 530 531void write_grey(output_t *output, /* I: data */ 532 image_t *image) /* I: Image data */ 533{ 534 int wholebytes = image->image_width / 8; 535 int crumbs = image->image_width - (wholebytes * 8); 536 char *buf = output->black_bufs[0]; 537 538 int i, j; 539 char tb[8]; 540 541#ifdef DEBUG 542 fprintf(stderr, "Data Length: %d, wholebytes: %d, crumbs: %d\n", 543 output->active_length, wholebytes, crumbs); 544#endif 545 546 for (i=0; i < wholebytes; i++) { 547 for (j=0; j < 8; j++) { 548 tb[j] = (((buf[i] >> (7-j)) & 1)); 549 tb[j] = output->output_depth - tb[j]; 550 } 551 (void) fwrite(&tb[0], sizeof(char), 8, write_fd); 552 } 553 for (j=0; j < crumbs; j++) { 554 tb[j] = (((buf[wholebytes] >> (7-j)) & 1)); 555 tb[j] = output->output_depth - tb[j]; 556 } 557 (void) fwrite(&tb[0], sizeof(char), (size_t) crumbs, write_fd); 558} 559 560/* 561 * write_colour() - Write out one row of RGB PNM data. 562 */ 563 564/* FIXME - multiple levels and CMYK/CMYKcm */ 565 566void write_colour(output_t *output, /* I: Data buffers */ 567 image_t *image) /* I: Image data */ 568{ 569 int wholebytes = image->image_width / 8; 570 int crumbs = image->image_width - (wholebytes * 8); 571 572 int i, j, jj; 573 char tb[8*3]; 574 575 char *cyan_buf; 576 char *magenta_buf; 577 char *yellow_buf; 578 char *black_buf; 579 580 cyan_buf = output->cyan_bufs[0]; 581 magenta_buf = output->magenta_bufs[0]; 582 yellow_buf = output->yellow_bufs[0]; 583 if (image->colour_type != PCL_CMY) 584 black_buf = output->black_bufs[0]; 585 else 586 black_buf = NULL; 587 588#ifdef DEBUG 589 fprintf(stderr, "Data Length: %d, wholebytes: %d, crumbs: %d, planes: %d\n", 590 output->active_length, wholebytes, crumbs, image->colour_type); 591 592 fprintf(stderr, "Cyan: "); 593 for (i=0; i < output->active_length; i++) { 594 fprintf(stderr, "%02x ", (unsigned char) cyan_buf[i]); 595 } 596 fprintf(stderr, "\n"); 597 fprintf(stderr, "Magenta: "); 598 for (i=0; i < output->active_length; i++) { 599 fprintf(stderr, "%02x ", (unsigned char) magenta_buf[i]); 600 } 601 fprintf(stderr, "\n"); 602 fprintf(stderr, "Yellow: "); 603 for (i=0; i < output->active_length; i++) { 604 fprintf(stderr, "%02x ", (unsigned char) yellow_buf[i]); 605 } 606 fprintf(stderr, "\n"); 607 if (image->colour_type == PCL_CMYK) { 608 fprintf(stderr, "Black: "); 609 for (i=0; i < output->active_length; i++) { 610 fprintf(stderr, "%02x ", (unsigned char) black_buf[i]); 611 } 612 fprintf(stderr, "\n"); 613 } 614#endif 615 616 if (image->colour_type == PCL_CMY) { 617 for (i=0; i < wholebytes; i++) { 618 for (j=0,jj=0; j < 8; j++,jj+=3) { 619 tb[jj] = (((cyan_buf[i] >> (7-j)) & 1)); 620 tb[jj] = output->output_depth - tb[jj]; 621 tb[jj+1] = (((magenta_buf[i] >> (7-j)) & 1)); 622 tb[jj+1] = output->output_depth - tb[jj+1]; 623 tb[jj+2] = (((yellow_buf[i] >> (7-j)) & 1)); 624 tb[jj+2] = output->output_depth - tb[jj+2]; 625 } 626 (void) fwrite(&tb[0], sizeof(char), (size_t) (8*3), write_fd); 627 } 628 for (j=0,jj=0; j < crumbs; j++,jj+=3) { 629 tb[jj] = (((cyan_buf[wholebytes] >> (7-j)) & 1)); 630 tb[jj] = output->output_depth - tb[jj]; 631 tb[jj+1] = (((magenta_buf[wholebytes] >> (7-j)) & 1)); 632 tb[jj+1] = output->output_depth - tb[jj+1]; 633 tb[jj+2] = (((yellow_buf[wholebytes] >> (7-j)) & 1)); 634 tb[jj+2] = output->output_depth - tb[jj+2]; 635 } 636 (void) fwrite(&tb[0], sizeof(char), (size_t) crumbs*3, write_fd); 637 } 638 else { 639 for (i=0; i < wholebytes; i++) { 640 for (j=0,jj=0; j < 8; j++,jj+=3) { 641#if !defined OUTPUT_CMYK_ONLY_K && !defined OUTPUT_CMYK_ONLY_CMY 642 tb[jj] = ((((cyan_buf[i]|black_buf[i]) >> (7-j)) & 1)); 643 tb[jj+1] = ((((magenta_buf[i]|black_buf[i]) >> (7-j)) & 1)); 644 tb[jj+2] = ((((yellow_buf[i]|black_buf[i]) >> (7-j)) & 1)); 645#endif 646#ifdef OUTPUT_CMYK_ONLY_K 647 tb[jj] = (((black_buf[i] >> (7-j)) & 1)); 648 tb[jj+1] = (((black_buf[i] >> (7-j)) & 1)); 649 tb[jj+2] = (((black_buf[i] >> (7-j)) & 1)); 650#endif 651#ifdef OUTPUT_CMYK_ONLY_CMY 652 tb[jj] = (((cyan_buf[i] >> (7-j)) & 1)); 653 tb[jj+1] = (((magenta_buf[i] >> (7-j)) & 1)); 654 tb[jj+2] = (((yellow_buf[i] >> (7-j)) & 1)); 655#endif 656 tb[jj] = output->output_depth - tb[jj]; 657 tb[jj+1] = output->output_depth - tb[jj+1]; 658 tb[jj+2] = output->output_depth - tb[jj+2]; 659 } 660 (void) fwrite(&tb[0], sizeof(char), (size_t) (8*3), write_fd); 661 } 662 for (j=0,jj=0; j < crumbs; j++,jj+=3) { 663#if !defined OUTPUT_CMYK_ONLY_K && !defined OUTPUT_CMYK_ONLY_CMY 664 tb[jj] = ((((cyan_buf[wholebytes]|black_buf[wholebytes]) >> (7-j)) & 1)); 665 tb[jj+1] = ((((magenta_buf[wholebytes]|black_buf[wholebytes]) >> (7-j)) & 1)); 666 tb[jj+2] = ((((yellow_buf[wholebytes]|black_buf[wholebytes]) >> (7-j)) & 1)); 667#endif 668#ifdef OUTPUT_CMYK_ONLY_K 669 tb[jj] = (((black_buf[wholebytes] >> (7-j)) & 1)); 670 tb[jj+1] = (((black_buf[wholebytes] >> (7-j)) & 1)); 671 tb[jj+2] = (((black_buf[wholebytes] >> (7-j)) & 1)); 672#endif 673#ifdef OUTPUT_CMYK_ONLY_CMY 674 tb[jj] = (((cyan_buf[wholebytes] >> (7-j)) & 1)); 675 tb[jj+1] = (((magenta_buf[wholebytes] >> (7-j)) & 1)); 676 tb[jj+2] = (((yellow_buf[wholebytes] >> (7-j)) & 1)); 677#endif 678 tb[jj] = output->output_depth - tb[jj]; 679 tb[jj+1] = output->output_depth - tb[jj+1]; 680 tb[jj+2] = output->output_depth - tb[jj+2]; 681 } 682 (void) fwrite(&tb[0], sizeof(char), (size_t) crumbs*3, write_fd); 683 } 684} 685 686/* 687 * decode_tiff() - Uncompress a TIFF encoded buffer 688 */ 689 690int decode_tiff(char *in_buffer, /* I: Data buffer */ 691 int data_length, /* I: Length of data */ 692 char *decode_buf, /* O: decoded data */ 693 int maxlen) /* I: Max length of decode_buf */ 694{ 695/* The TIFF coding consists of either:- 696 * 697 * (0 <= count <= 127) (count+1 bytes of data) for non repeating data 698 * or 699 * (-127 <= count <= -1) (data) for 1-count bytes of repeating data 700 */ 701 702 int count; 703 int pos = 0; 704 int dpos = 0; 705#ifdef DEBUG 706 int i; 707#endif 708 709 while(pos < data_length ) { 710 711 count = in_buffer[pos]; 712 713 if ((count >= 0) && (count <= 127)) { 714#ifdef DEBUG 715 fprintf(stderr, "%d bytes of nonrepeated data\n", count+1); 716 fprintf(stderr, "DATA: "); 717 for (i=0; i< (count+1); i++) { 718 fprintf(stderr, "%02x ", (unsigned char) in_buffer[pos + 1 + i]); 719 } 720 fprintf(stderr, "\n"); 721#endif 722 if ((dpos + count + 1) > maxlen) { 723 fprintf(stderr, "ERROR: Too much expanded data (%d)!\n", dpos + count + 1); 724 exit(EXIT_FAILURE); 725 } 726 memcpy(&decode_buf[dpos], &in_buffer[pos+1], (size_t) (count + 1)); 727 dpos += count + 1; 728 pos += count + 2; 729 } 730 else if ((count >= -127) && (count < 0)) { 731#ifdef DEBUG 732 fprintf(stderr, "%02x repeated %d times\n", (unsigned char) in_buffer[pos + 1], 1 - count); 733#endif 734 if ((dpos + 1 - count) > maxlen) { 735 fprintf(stderr, "ERROR: Too much expanded data (%d)!\n", dpos + 1 - count); 736 exit(EXIT_FAILURE); 737 } 738 memset(&decode_buf[dpos], in_buffer[pos + 1], (size_t) (1 - count)); 739 dpos += 1 - count; 740 pos += 2; 741 } 742 else { 743 fprintf(stderr, "ERROR: Illegal TIFF count: %d, skipped\n", count); 744 pos += 2; 745 } 746 } 747 748#ifdef DEBUG 749 fprintf(stderr, "TIFFOUT: "); 750 for (i=0; i< dpos; i++) { 751 fprintf(stderr, "%02x ", (unsigned char) decode_buf[i]); 752 } 753 fprintf(stderr, "\n"); 754#endif 755 return(dpos); 756} 757 758/* 759 * pcl_reset() - Rest image parameters to default 760 */ 761 762void pcl_reset(image_t *i) 763{ 764 i->colour_type = PCL_MONO; 765 i->black_depth = 2; /* Assume mono */ 766 i->cyan_depth = 0; 767 i->magenta_depth = 0; 768 i->yellow_depth = 0; 769 i->lcyan_depth = 0; 770 i->lmagenta_depth = 0; 771 i->image_width = -1; 772 i->image_height = -1; 773 i->compression_type = 0; /* should this be NONE? */ 774} 775 776/* 777 * depth_to_rows() - convert the depth of the colour into the number 778 * of data rows needed to represent it. Assumes that depth is a power 779 * of 2, FIXME if not! 780 */ 781 782int depth_to_rows(int depth) 783{ 784 int rows; 785 786 if (depth == 0) 787 return(0); 788 789 for (rows = 1; rows < 8; rows++) { 790 if ((depth >> rows) == 1) 791 return(rows); 792 } 793 fprintf(stderr, "ERROR: depth %d too big to handle in depth_to_rows()!\n", 794 depth); 795 return(0); /* ?? */ 796} 797 798/* 799 * Main 800 */ 801 802int main(int argc, char *argv[]) 803{ 804 805 int command_index; 806 command_t command; 807 int i, j; /* Loop/general variables */ 808 int image_row_counter = -1; /* Count of current row */ 809 int current_data_row = -1; /* Count of data rows received for this output row */ 810 int expected_data_rows_per_row = -1; 811 /* Expected no of data rows per output row */ 812 image_t image_data; /* Data concerning image */ 813 long filepos = -1; 814 815/* 816 * Holders for the decoded lines 817 */ 818 819 output_t output_data; 820 821/* 822 * The above pointers (when allocated) are then copied into this 823 * variable in the correct order so that the received data can 824 * be stored. 825 */ 826 827 char **received_rows; 828 829 output_data.black_bufs = NULL; /* Storage for black rows */ 830 output_data.black_data_rows_per_row = 0; /* Number of black rows */ 831 output_data.cyan_bufs = NULL; 832 output_data.cyan_data_rows_per_row = 0; 833 output_data.magenta_bufs = NULL; 834 output_data.magenta_data_rows_per_row = 0; 835 output_data.yellow_bufs = NULL; 836 output_data.yellow_data_rows_per_row = 0; 837 output_data.lcyan_bufs = NULL; 838 output_data.lcyan_data_rows_per_row = 0; 839 output_data.lmagenta_bufs = NULL; 840 output_data.lmagenta_data_rows_per_row = 0; 841 output_data.buffer_length = 0; 842 output_data.active_length = 0; 843 output_data.output_depth = 0; 844 845 id = id; /* Remove compiler warning */ 846 received_rows = NULL; 847 848 if(argc == 1){ 849 read_fd = stdin; 850 write_fd = stdout; 851 } 852 else if(argc == 2){ 853 read_fd = fopen(argv[1],"r"); 854 write_fd = stdout; 855 } 856 else { 857 if(*argv[1] == '-'){ 858 read_fd = stdin; 859 write_fd = fopen(argv[2],"w"); 860 } 861 else { 862 read_fd = fopen(argv[1],"r"); 863 write_fd = fopen(argv[2],"w"); 864 } 865 } 866 867 if (read_fd == (FILE *)NULL) { 868 fprintf(stderr, "ERROR: Error Opening input file.\n"); 869 exit (EXIT_FAILURE); 870 } 871 872 if (write_fd == (FILE *)NULL) { 873 fprintf(stderr, "ERROR: Error Opening output file.\n"); 874 exit (EXIT_FAILURE); 875 } 876 877 read_pointer=-1; 878 eof=0; 879 initial_command_index=0; 880 initial_command[initial_command_index] = '\0'; 881 numeric_arg=0; 882 final_command = '\0'; 883 884 885 pcl_reset(&image_data); 886 887 while (1) { 888 pcl_read_command(); 889 if (eof == 1) { 890/* #ifdef DEBUG */ 891 fprintf(stderr, "EOF while reading command.\n"); 892/* #endif */ 893 (void) fclose(read_fd); 894 (void) fclose(write_fd); 895 exit(EXIT_SUCCESS); 896 } 897 898#ifdef DEBUG 899 fprintf(stderr, "initial_command: %s, numeric_arg: %d, final_command: %c\n", 900 initial_command, numeric_arg, final_command); 901#endif 902 903 command_index = pcl_find_command(); 904 if (command_index == -1) { 905 fprintf(stderr, "ERROR: Unknown (and unhandled) command: %s%d%c\n", initial_command, 906 numeric_arg, final_command); 907/* We may have to skip some data here */ 908 } 909 else { 910 command = pcl_commands[command_index].command; 911 if (pcl_commands[command_index].has_data == 1) { 912 913/* Read the data into data_buffer */ 914 915#ifdef DEBUG 916 fprintf(stderr, "Data: "); 917#endif 918 919 if (numeric_arg > MAX_DATA) { 920 fprintf(stderr, "ERROR: Too much data (%d), increase MAX_DATA!\n", numeric_arg); 921 exit(EXIT_FAILURE); 922 } 923 924 for (i=0; i < numeric_arg; i++) { 925 fill_buffer(); 926 if (eof == 1) { 927 fprintf(stderr, "ERROR: Unexpected EOF whilst reading data\n"); 928 exit(EXIT_FAILURE); 929 } 930 data_buffer[i] = read_buffer[read_pointer++]; 931 932#ifdef DEBUG 933 fprintf(stderr, "%02x ", (unsigned char) data_buffer[i]); 934#endif 935 936 } 937 938#ifdef DEBUG 939 fprintf(stderr, "\n"); 940#endif 941 942 } 943 switch(command) { 944 case PCL_RESET : 945 fprintf(stderr, "%s\n", pcl_commands[command_index].description); 946 pcl_reset(&image_data); 947 break; 948 949 case PCL_RESET_MARGINS : 950 fprintf(stderr, "%s\n", pcl_commands[command_index].description); 951 break; 952 953 case PCL_START_RASTER : 954 fprintf(stderr, "%s\n", pcl_commands[command_index].description); 955 956/* Make sure we have all the stuff needed to work out what we are going 957 to write out. */ 958 959 i = 0; /* use as error indicator */ 960 961 if (image_data.image_width == -1) { 962 fprintf(stderr, "ERROR: Image width not set!\n"); 963 i++; 964 } 965 if (image_data.image_height == -1) { 966 fprintf(stderr, "WARNING: Image height not set!\n"); 967 } 968 969 if ((image_data.black_depth != 0) && 970 (image_data.black_depth != 2)) { 971 fprintf(stderr, "WARNING: Only 2 level black dithers handled.\n"); 972 } 973 if ((image_data.cyan_depth != 0) && 974 (image_data.cyan_depth != 2)) { 975 fprintf(stderr, "WARNING: Only 2 level cyan dithers handled.\n"); 976 } 977 if ((image_data.magenta_depth != 0) && 978 (image_data.magenta_depth != 2)) { 979 fprintf(stderr, "WARNING: Only 2 level magenta dithers handled.\n"); 980 } 981 if ((image_data.yellow_depth != 0) && 982 (image_data.yellow_depth != 2)) { 983 fprintf(stderr, "WARNING: only 2 level yellow dithers handled.\n"); 984 } 985 if (image_data.lcyan_depth != 0) { 986 fprintf(stderr, "WARNING: Light cyan dithers not yet handled.\n"); 987 } 988 if (image_data.lmagenta_depth != 0) { 989 fprintf(stderr, "WARNING: Light magenta dithers not yet handled.\n"); 990 } 991 992 if ((image_data.compression_type != PCL_COMPRESSION_NONE) && 993 (image_data.compression_type != PCL_COMPRESSION_TIFF)) { 994 fprintf(stderr, 995 "Sorry, only 'no compression' or 'tiff compression' handled.\n"); 996 i++; 997 } 998 999 if (i != 0) { 1000 fprintf(stderr, "PNM output suppressed, will continue diagnostic output.\n"); 1001 skip_output = 1; 1002 } 1003 1004 if (skip_output == 0) { 1005 if (image_data.colour_type == PCL_MONO) 1006 (void) fputs("P5\n", write_fd); /* Raw, Grey */ 1007 else 1008 (void) fputs("P6\n", write_fd); /* Raw, RGB */ 1009 1010 (void) fputs("# Written by pclunprint.\n", write_fd); 1011 1012/* 1013 * Remember the file position where we wrote the image width and height 1014 * (you don't want to know why!) 1015 */ 1016 1017 filepos = ftell(write_fd); 1018 1019 fprintf(write_fd, "%10d %10d\n", image_data.image_width, 1020 image_data.image_height); 1021 1022/* 1023 * Write the depth of the image 1024 */ 1025 1026 if (image_data.black_depth != 0) 1027 output_data.output_depth = image_data.black_depth - 1; 1028 else 1029 output_data.output_depth = image_data.cyan_depth - 1; 1030 fprintf(write_fd, "%d\n", output_data.output_depth); 1031 1032 image_row_counter = 0; 1033 current_data_row = 0; 1034 1035 output_data.black_data_rows_per_row = depth_to_rows(image_data.black_depth); 1036 output_data.cyan_data_rows_per_row = depth_to_rows(image_data.cyan_depth); 1037 output_data.magenta_data_rows_per_row = depth_to_rows(image_data.magenta_depth); 1038 output_data.yellow_data_rows_per_row = depth_to_rows(image_data.yellow_depth); 1039 output_data.lcyan_data_rows_per_row = depth_to_rows(image_data.lcyan_depth); 1040 output_data.lmagenta_data_rows_per_row = depth_to_rows(image_data.lmagenta_depth); 1041 1042/* 1043 * Allocate some storage for the expected planes 1044 */ 1045 1046 output_data.buffer_length = (image_data.image_width + 7) / 8; 1047 1048 if (output_data.black_data_rows_per_row != 0) { 1049 output_data.black_bufs = stp_malloc(output_data.black_data_rows_per_row * sizeof (char *)); 1050 for (i=0; i < output_data.black_data_rows_per_row; i++) { 1051 output_data.black_bufs[i] = stp_malloc(output_data.buffer_length * sizeof (char)); 1052 } 1053 } 1054 if (output_data.cyan_data_rows_per_row != 0) { 1055 output_data.cyan_bufs = stp_malloc(output_data.cyan_data_rows_per_row * sizeof (char *)); 1056 for (i=0; i < output_data.cyan_data_rows_per_row; i++) { 1057 output_data.cyan_bufs[i] = stp_malloc(output_data.buffer_length * sizeof (char)); 1058 } 1059 } 1060 if (output_data.magenta_data_rows_per_row != 0) { 1061 output_data.magenta_bufs = stp_malloc(output_data.magenta_data_rows_per_row * sizeof (char *)); 1062 for (i=0; i < output_data.magenta_data_rows_per_row; i++) { 1063 output_data.magenta_bufs[i] = stp_malloc(output_data.buffer_length * sizeof (char)); 1064 } 1065 } 1066 if (output_data.yellow_data_rows_per_row != 0) { 1067 output_data.yellow_bufs = stp_malloc(output_data.yellow_data_rows_per_row * sizeof (char *)); 1068 for (i=0; i < output_data.yellow_data_rows_per_row; i++) { 1069 output_data.yellow_bufs[i] = stp_malloc(output_data.buffer_length * sizeof (char)); 1070 } 1071 } 1072 if (output_data.lcyan_data_rows_per_row != 0) { 1073 output_data.lcyan_bufs = stp_malloc(output_data.lcyan_data_rows_per_row * sizeof (char *)); 1074 for (i=0; i < output_data.lcyan_data_rows_per_row; i++) { 1075 output_data.lcyan_bufs[i] = stp_malloc(output_data.buffer_length * sizeof (char)); 1076 } 1077 } 1078 if (output_data.lmagenta_data_rows_per_row != 0) { 1079 output_data.lmagenta_bufs = stp_malloc(output_data.lmagenta_data_rows_per_row * sizeof (char *)); 1080 for (i=0; i < output_data.lmagenta_data_rows_per_row; i++) { 1081 output_data.lmagenta_bufs[i] = stp_malloc(output_data.buffer_length * sizeof (char)); 1082 } 1083 } 1084 1085/* 1086 * Now store the pointers in the right order to make life easier in the 1087 * decoding phase 1088 */ 1089 1090 expected_data_rows_per_row = output_data.black_data_rows_per_row + 1091 output_data.cyan_data_rows_per_row + output_data.magenta_data_rows_per_row + 1092 output_data.yellow_data_rows_per_row + output_data.lcyan_data_rows_per_row + 1093 output_data.lmagenta_data_rows_per_row; 1094 1095 received_rows = stp_malloc(expected_data_rows_per_row * sizeof(char *)); 1096 j = 0; 1097 for (i = 0; i < output_data.black_data_rows_per_row; i++) 1098 received_rows[j++] = output_data.black_bufs[i]; 1099 for (i = 0; i < output_data.cyan_data_rows_per_row; i++) 1100 received_rows[j++] = output_data.cyan_bufs[i]; 1101 for (i = 0; i < output_data.magenta_data_rows_per_row; i++) 1102 received_rows[j++] = output_data.magenta_bufs[i]; 1103 for (i = 0; i < output_data.yellow_data_rows_per_row; i++) 1104 received_rows[j++] = output_data.yellow_bufs[i]; 1105 for (i = 0; i < output_data.lcyan_data_rows_per_row; i++) 1106 received_rows[j++] = output_data.lcyan_bufs[i]; 1107 for (i = 0; i < output_data.lmagenta_data_rows_per_row; i++) 1108 received_rows[j++] = output_data.lmagenta_bufs[i]; 1109 } 1110 break; 1111 1112 case PCL_END_RASTER : 1113 case PCL_END_COLOUR_RASTER : 1114 fprintf(stderr, "%s\n", pcl_commands[command_index].description); 1115 1116 if (skip_output == 0) { 1117 1118/* 1119 * Check that we got the correct number of rows of data. If the expected number is 1120 * -1, we have to go back and fill in the PNM parameters (which is why we remembered 1121 * where they were in the file!) 1122 */ 1123 1124 if (image_data.image_height == -1) { 1125 image_data.image_height = image_row_counter; 1126 if (fseek(write_fd, filepos, SEEK_SET) != -1) { 1127 fprintf(write_fd, "%10d %10d\n", image_data.image_width, 1128 image_data.image_height); 1129 fseek(write_fd, 0L, SEEK_END); 1130 } 1131 } 1132 1133 if (image_row_counter != image_data.image_height) 1134 fprintf(stderr, "ERROR: Row count mismatch. Expected %d rows, got %d rows.\n", 1135 image_data.image_height, image_row_counter); 1136 else 1137 fprintf(stderr, "\t%d rows processed.\n", image_row_counter); 1138 1139 image_data.image_height = -1; 1140 image_row_counter = -1; 1141 1142 if (output_data.black_data_rows_per_row != 0) { 1143 for (i=0; i < output_data.black_data_rows_per_row; i++) { 1144 stp_free(output_data.black_bufs[i]); 1145 } 1146 stp_free(output_data.black_bufs); 1147 output_data.black_bufs = NULL; 1148 } 1149 output_data.black_data_rows_per_row = 0; 1150 if (output_data.cyan_data_rows_per_row != 0) { 1151 for (i=0; i < output_data.cyan_data_rows_per_row; i++) { 1152 stp_free(output_data.cyan_bufs[i]); 1153 } 1154 stp_free(output_data.cyan_bufs); 1155 output_data.cyan_bufs = NULL; 1156 } 1157 output_data.cyan_data_rows_per_row = 0; 1158 if (output_data.magenta_data_rows_per_row != 0) { 1159 for (i=0; i < output_data.magenta_data_rows_per_row; i++) { 1160 stp_free(output_data.magenta_bufs[i]); 1161 } 1162 stp_free(output_data.magenta_bufs); 1163 output_data.magenta_bufs = NULL; 1164 } 1165 output_data.magenta_data_rows_per_row = 0; 1166 if (output_data.yellow_data_rows_per_row != 0) { 1167 for (i=0; i < output_data.yellow_data_rows_per_row; i++) { 1168 stp_free(output_data.yellow_bufs[i]); 1169 } 1170 stp_free(output_data.yellow_bufs); 1171 output_data.yellow_bufs = NULL; 1172 } 1173 output_data.yellow_data_rows_per_row = 0; 1174 if (output_data.lcyan_data_rows_per_row != 0) { 1175 for (i=0; i < output_data.lcyan_data_rows_per_row; i++) { 1176 stp_free(output_data.lcyan_bufs[i]); 1177 } 1178 stp_free(output_data.lcyan_bufs); 1179 output_data.lcyan_bufs = NULL; 1180 } 1181 output_data.lcyan_data_rows_per_row = 0; 1182 if (output_data.lmagenta_data_rows_per_row != 0) { 1183 for (i=0; i < output_data.lmagenta_data_rows_per_row; i++) { 1184 stp_free(output_data.lmagenta_bufs[i]); 1185 } 1186 stp_free(output_data.lmagenta_bufs); 1187 output_data.lmagenta_bufs = NULL; 1188 } 1189 output_data.lmagenta_data_rows_per_row = 0; 1190 stp_free(received_rows); 1191 received_rows = NULL; 1192 } 1193 break; 1194 1195 case PCL_MEDIA_SIZE : 1196 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1197 switch (numeric_arg) { 1198 case 2 : 1199 fprintf(stderr, "Letter\n"); 1200 break; 1201 case 3 : 1202 fprintf(stderr, "Legal\n"); 1203 break; 1204 case 6 : 1205 fprintf(stderr, "Tabloid\n"); 1206 break; 1207 case 26 : 1208 fprintf(stderr, "A4\n"); 1209 break; 1210 case 27 : 1211 fprintf(stderr, "A3\n"); 1212 break; 1213 case 101 : 1214 fprintf(stderr, "Custom\n"); 1215 break; 1216 default : 1217 fprintf(stderr, "Unknown (%d)\n", numeric_arg); 1218 break; 1219 } 1220 break; 1221 1222 case PCL_MEDIA_TYPE : 1223 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1224 switch (numeric_arg) { 1225 case 0 : 1226 fprintf(stderr, "Plain\n"); 1227 break; 1228 case 1 : 1229 fprintf(stderr, "Bond\n"); 1230 break; 1231 case 2 : 1232 fprintf(stderr, "Premium\n"); 1233 break; 1234 case 3 : 1235 fprintf(stderr, "Glossy/Photo\n"); 1236 break; 1237 case 4 : 1238 fprintf(stderr, "Transparency\n"); 1239 break; 1240 case 5 : 1241 fprintf(stderr, "Quick-dry Photo\n"); 1242 break; 1243 case 6 : 1244 fprintf(stderr, "Quick-dry Transparency\n"); 1245 break; 1246 default : 1247 fprintf(stderr, "Unknown (%d)\n", numeric_arg); 1248 break; 1249 } 1250 break; 1251 1252 case PCL_MEDIA_SOURCE : 1253 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1254 switch (numeric_arg) { 1255 case -2 : 1256 fprintf(stderr, "FEED CURRENT\n"); 1257 break; 1258 case 0 : 1259 fprintf(stderr, "EJECT\n"); 1260 break; 1261 case 1 : 1262 fprintf(stderr, "LJ Tray 2 or Portable CSF or DJ Tray\n"); 1263 break; 1264 case 2 : 1265 fprintf(stderr, "Manual\n"); 1266 break; 1267 case 3 : 1268 fprintf(stderr, "Envelope\n"); 1269 break; 1270 case 4 : 1271 fprintf(stderr, "LJ Tray 3 or Desktop CSF or DJ Tray 2\n"); 1272 break; 1273 case 5 : 1274 fprintf(stderr, "LJ Tray 4 or DJ optional\n"); 1275 break; 1276 case 7 : 1277 fprintf(stderr, "DJ Autosource\n"); 1278 break; 1279 case 8 : 1280 fprintf(stderr, "LJ Tray 1\n"); 1281 break; 1282 default : 1283 fprintf(stderr, "Unknown (%d)\n", numeric_arg); 1284 break; 1285 } 1286 break; 1287 1288 case PCL_SHINGLING : 1289 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1290 switch (numeric_arg) { 1291 case 0 : 1292 fprintf(stderr, "None\n"); 1293 break; 1294 case 1 : 1295 fprintf(stderr, "2 passes\n"); 1296 break; 1297 case 2 : 1298 fprintf(stderr, "4 passes\n"); 1299 break; 1300 default : 1301 fprintf(stderr, "Unknown (%d)\n", numeric_arg); 1302 break; 1303 } 1304 break; 1305 1306 case PCL_RASTERGRAPHICS_QUALITY : 1307 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1308 switch (numeric_arg) { 1309 case 0 : 1310 fprintf(stderr, "(set by printer controls)\n"); 1311 case 1 : 1312 fprintf(stderr, "Draft\n"); 1313 break; 1314 case 2 : 1315 fprintf(stderr, "High\n"); 1316 break; 1317 default : 1318 fprintf(stderr, "Unknown (%d)\n", numeric_arg); 1319 break; 1320 } 1321 break; 1322 1323 case PCL_DEPLETION : 1324 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1325 switch (numeric_arg) { 1326 case 1 : 1327 fprintf(stderr, "None\n"); 1328 break; 1329 case 2 : 1330 fprintf(stderr, "25%%\n"); 1331 break; 1332 case 3 : 1333 fprintf(stderr, "50%%\n"); 1334 break; 1335 case 5 : 1336 fprintf(stderr, "50%% with gamma correction\n"); 1337 break; 1338 default : 1339 fprintf(stderr, "Unknown (%d)\n", numeric_arg); 1340 break; 1341 } 1342 break; 1343 1344 case PCL_PRINT_QUALITY : 1345 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1346 switch (numeric_arg) { 1347 case -1 : 1348 fprintf(stderr, "Draft\n"); 1349 break; 1350 case 0 : 1351 fprintf(stderr, "Normal\n"); 1352 break; 1353 case 1 : 1354 fprintf(stderr, "Presentation\n"); 1355 break; 1356 default : 1357 fprintf(stderr, "Unknown (%d)\n", numeric_arg); 1358 break; 1359 } 1360 break; 1361 1362 case PCL_RELATIVE_VERTICAL_PIXEL_MOVEMENT : 1363 fprintf(stderr, "%s: %d\n", pcl_commands[command_index].description, numeric_arg); 1364 1365 if (skip_output == 0) { 1366 1367/* Check that we are in raster mode */ 1368 1369 if (expected_data_rows_per_row == -1) 1370 fprintf(stderr, "ERROR: raster data without start raster!\n"); 1371 1372/* 1373 What we need to do now is to write out "N" rows of all-white data to 1374 simulate the vertical slew 1375*/ 1376 1377 for (i=0; i<expected_data_rows_per_row; i++) 1378 { 1379 memset(received_rows[i], 0, (size_t) output_data.buffer_length * sizeof(char)); 1380 } 1381 for (i=0; i<numeric_arg; i++) 1382 { 1383 if (image_data.colour_type == PCL_MONO) 1384 write_grey(&output_data, &image_data); 1385 else 1386 write_colour(&output_data, &image_data); 1387 image_row_counter++; 1388 } 1389 } 1390 break; 1391 1392 case PCL_DUPLEX : 1393 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1394 switch (numeric_arg) { 1395 case 0 : 1396 fprintf(stderr, "None\n"); 1397 break; 1398 case 1 : 1399 fprintf(stderr, "Duplex No Tumble (Long Edge)\n"); 1400 break; 1401 case 2 : 1402 fprintf(stderr, "Duplex Tumble (Short Edge)\n"); 1403 break; 1404 default : 1405 fprintf(stderr, "Unknown (%d)\n", numeric_arg); 1406 break; 1407 } 1408 break; 1409 1410 case PCL_PERF_SKIP : 1411 case PCL_TOP_MARGIN : 1412 case PCL_RESOLUTION : 1413 case PCL_LEFTRASTER_POS : 1414 case PCL_TOPRASTER_POS : 1415 case PCL_VERTICAL_CURSOR_POSITIONING_BY_DOTS : 1416 case PCL_HORIZONTAL_CURSOR_POSITIONING_BY_DOTS : 1417 case PCL_PALETTE_CONFIGURATION : 1418 case PCL_UNIT_OF_MEASURE : 1419 case PCL_GRAY_BALANCE : 1420 case PCL_DRIVER_CONFIG : 1421 case PCL_LPI : 1422 case PCL_CPI : 1423 case PCL_PAGE_LENGTH : 1424 case PCL_NUM_COPIES : 1425 case RTL_CONFIGURE : 1426 case PCL_ENTER_PCL : 1427 case PCL_NEGATIVE_MOTION : 1428 case PCL_JOB_SEPARATION : 1429 case PCL_LEFT_OFFSET_REGISTRATION : 1430 case PCL_TOP_OFFSET_REGISTRATION : 1431 case PCL_PRINT_DIRECTION : 1432 case PCL_LEFT_MARGIN : 1433 case PCL_RIGHT_MARGIN : 1434 case PCL_TEXT_LENGTH : 1435 fprintf(stderr, "%s: %d (ignored)", pcl_commands[command_index].description, numeric_arg); 1436 if (pcl_commands[command_index].has_data == 1) { 1437 fprintf(stderr, " Data: "); 1438 for (i=0; i < numeric_arg; i++) { 1439 fprintf(stderr, "%02x ", (unsigned char) data_buffer[i]); 1440 } 1441 } 1442 fprintf(stderr, "\n"); 1443 break; 1444 1445 case PCL_COLOURTYPE : 1446 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1447 image_data.colour_type = -numeric_arg; 1448 switch (image_data.colour_type) { 1449 case PCL_MONO : 1450 fprintf(stderr, "MONO\n"); 1451 break; 1452 case PCL_CMY : 1453 fprintf(stderr, "CMY (one cart)\n"); 1454 image_data.black_depth = 0; /* Black levels */ 1455 image_data.cyan_depth = 2; /* Cyan levels */ 1456 image_data.magenta_depth = 2; /* Magenta levels */ 1457 image_data.yellow_depth = 2; /* Yellow levels */ 1458 break; 1459 case PCL_CMYK : 1460 fprintf(stderr, "CMYK (two cart)\n"); 1461 image_data.black_depth = 2; /* Black levels */ 1462 image_data.cyan_depth = 2; /* Cyan levels */ 1463 image_data.magenta_depth = 2; /* Magenta levels */ 1464 image_data.yellow_depth = 2; /* Yellow levels */ 1465 break; 1466 default : 1467 fprintf(stderr, "Unknown (%d)\n", -numeric_arg); 1468 break; 1469 } 1470 break; 1471 1472 case PCL_COMPRESSIONTYPE : 1473 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1474 image_data.compression_type = numeric_arg; 1475 switch (image_data.compression_type) { 1476 case PCL_COMPRESSION_NONE : 1477 fprintf(stderr, "NONE\n"); 1478 break; 1479 case PCL_COMPRESSION_RUNLENGTH : 1480 fprintf(stderr, "Runlength\n"); 1481 break; 1482 case PCL_COMPRESSION_TIFF : 1483 fprintf(stderr, "TIFF\n"); 1484 break; 1485 case PCL_COMPRESSION_CRDR : 1486 fprintf(stderr, "Compressed Row Delta Replacement\n"); 1487 break; 1488 default : 1489 fprintf(stderr, "Unknown (%d)\n", image_data.compression_type); 1490 break; 1491 } 1492 break; 1493 1494 case PCL_RASTER_WIDTH : 1495 fprintf(stderr, "%s: %d\n", pcl_commands[command_index].description, numeric_arg); 1496 image_data.image_width = numeric_arg; 1497 break; 1498 1499 case PCL_RASTER_HEIGHT : 1500 fprintf(stderr, "%s: %d\n", pcl_commands[command_index].description, numeric_arg); 1501 image_data.image_height = numeric_arg; 1502 break; 1503 1504 case PCL_CONFIGURE : 1505 fprintf(stderr, "%s (size=%d)\n", pcl_commands[command_index].description, 1506 numeric_arg); 1507 fprintf(stderr, "\tFormat: %d\n", data_buffer[0]); 1508 if (data_buffer[0] == 2) { 1509 1510/* 1511 * the data that follows depends on the colour type (buffer[1]). The size 1512 * of the data should be 2 + (6 * number of planes). 1513 */ 1514 1515 fprintf(stderr, "\tOutput Planes: "); 1516 image_data.colour_type = data_buffer[1]; /* # output planes */ 1517 switch (image_data.colour_type) { 1518 case PCL_MONO : 1519 fprintf(stderr, "MONO\n"); 1520 1521/* Size should be 8 */ 1522 1523 if (numeric_arg != 8) 1524 fprintf(stderr, "ERROR: Expected 8 bytes of data, got %d\n", numeric_arg); 1525 1526 fprintf(stderr, "\tBlack: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[2]<<8)+(unsigned char)data_buffer[3], 1527 ((unsigned char) data_buffer[4]<<8)+(unsigned char) data_buffer[5], data_buffer[7]); 1528 image_data.black_depth = data_buffer[7]; /* Black levels */ 1529 break; 1530 case PCL_CMY : 1531 fprintf(stderr, "CMY (one cart)\n"); 1532 1533/* Size should be 20 */ 1534 1535 if (numeric_arg != 20) 1536 fprintf(stderr, "ERROR: Expected 20 bytes of data, got %d\n", numeric_arg); 1537 1538 fprintf(stderr, "\tCyan: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[2]<<8)+(unsigned char) data_buffer[3], 1539 ((unsigned char) data_buffer[4]<<8)+(unsigned char) data_buffer[5], data_buffer[7]); 1540 fprintf(stderr, "\tMagenta: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[8]<<8)+(unsigned char) data_buffer[9], 1541 ((unsigned char) data_buffer[10]<<8)+(unsigned char) data_buffer[11], data_buffer[13]); 1542 fprintf(stderr, "\tYellow: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[14]<<8)+(unsigned char) data_buffer[15], 1543 ((unsigned char) data_buffer[16]<<8)+(unsigned char) data_buffer[17], data_buffer[19]); 1544 image_data.black_depth = 0; 1545 image_data.cyan_depth = data_buffer[7]; /* Cyan levels */ 1546 image_data.magenta_depth = data_buffer[13]; /* Magenta levels */ 1547 image_data.yellow_depth = data_buffer[19]; /* Yellow levels */ 1548 break; 1549 case PCL_CMYK : 1550 fprintf(stderr, "CMYK (two cart)\n"); 1551 1552/* Size should be 26 */ 1553 1554 if (numeric_arg != 26) 1555 fprintf(stderr, "ERROR: Expected 26 bytes of data, got %d\n", numeric_arg); 1556 1557 fprintf(stderr, "\tBlack: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[2]<<8)+(unsigned char) data_buffer[3], 1558 ((unsigned char) data_buffer[4]<<8)+(unsigned char) data_buffer[5], data_buffer[7]); 1559 fprintf(stderr, "\tCyan: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[8]<<8)+(unsigned char) data_buffer[9], 1560 ((unsigned char) data_buffer[10]<<8)+(unsigned char) data_buffer[11], data_buffer[13]); 1561 fprintf(stderr, "\tMagenta: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[14]<<8)+(unsigned char) data_buffer[15], 1562 ((unsigned char) data_buffer[16]<<8)+(unsigned char) data_buffer[17], data_buffer[19]); 1563 fprintf(stderr, "\tYellow: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[20]<<8)+(unsigned char) data_buffer[21], 1564 ((unsigned char) data_buffer[22]<<8)+(unsigned char) data_buffer[23], data_buffer[25]); 1565 image_data.black_depth = data_buffer[7]; /* Black levels */ 1566 image_data.cyan_depth = data_buffer[13]; /* Cyan levels */ 1567 image_data.magenta_depth = data_buffer[19]; /* Magenta levels */ 1568 image_data.yellow_depth = data_buffer[25]; /* Yellow levels */ 1569 break; 1570 case PCL_CMYKcm : 1571 fprintf(stderr, "CMYKcm (two cart photo)\n"); 1572 1573/* Size should be 38 */ 1574 1575 if (numeric_arg != 38) 1576 fprintf(stderr, "ERROR: Expected 38 bytes of data, got %d\n", numeric_arg); 1577 1578 fprintf(stderr, "\tBlack: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[2]<<8)+(unsigned char) data_buffer[3], 1579 ((unsigned char) data_buffer[4]<<8)+(unsigned char) data_buffer[5], data_buffer[7]); 1580 fprintf(stderr, "\tCyan: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[8]<<8)+(unsigned char) data_buffer[9], 1581 ((unsigned char) data_buffer[10]<<8)+(unsigned char) data_buffer[11], data_buffer[13]); 1582 fprintf(stderr, "\tMagenta: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[14]<<8)+(unsigned char) data_buffer[15], 1583 ((unsigned char) data_buffer[16]<<8)+(unsigned char) data_buffer[17], data_buffer[19]); 1584 fprintf(stderr, "\tYellow: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[20]<<8)+(unsigned char) data_buffer[21], 1585 ((unsigned char) data_buffer[22]<<8)+(unsigned char) data_buffer[23], data_buffer[25]); 1586 fprintf(stderr, "\tLight Cyan: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[26]<<8)+(unsigned char) data_buffer[27], 1587 ((unsigned char) data_buffer[28]<<8)+(unsigned char) data_buffer[29], data_buffer[31]); 1588 fprintf(stderr, "\tLight Magenta: X dpi: %d, Y dpi: %d, Levels: %d\n", ((unsigned char) data_buffer[32]<<8)+(unsigned char) data_buffer[33], 1589 ((unsigned char) data_buffer[34]<<8)+(unsigned char) data_buffer[35], data_buffer[37]); 1590 image_data.black_depth = data_buffer[7]; /* Black levels */ 1591 image_data.cyan_depth = data_buffer[13]; /* Cyan levels */ 1592 image_data.magenta_depth = data_buffer[19]; /* Magenta levels */ 1593 image_data.yellow_depth = data_buffer[25]; /* Yellow levels */ 1594 image_data.lcyan_depth = data_buffer[31]; /* Cyan levels */ 1595 image_data.lmagenta_depth = data_buffer[37]; /* Magenta levels */ 1596 break; 1597 default : 1598 fprintf(stderr, "Unknown (%d)\n", data_buffer[1]); 1599 break; 1600 } 1601 } 1602 else { 1603 fprintf(stderr, "Unknown format %d\n", data_buffer[0]); 1604 fprintf(stderr, "Data: "); 1605 for (i=0; i < numeric_arg; i++) { 1606 fprintf(stderr, "%02x ", (unsigned char) data_buffer[i]); 1607 } 1608 fprintf(stderr, "\n"); 1609 } 1610 break; 1611 1612 case PCL_DATA : 1613 case PCL_DATA_LAST : 1614 if (skip_output == 1) { 1615 fprintf(stderr, "%s, length: %d\n", pcl_commands[command_index].description, numeric_arg); 1616 } 1617 else { 1618 1619/* 1620 * Make sure that we have enough data to process this command! 1621 */ 1622 1623 if (expected_data_rows_per_row == -1) 1624 fprintf(stderr, "ERROR: raster data without start raster!\n"); 1625 1626/* 1627 * The last flag indicates that this is the end of the planes for a row 1628 * so we check it against the number of planes we have seen and are 1629 * expecting. 1630 */ 1631 1632 if (command == PCL_DATA_LAST) { 1633 if (current_data_row != (expected_data_rows_per_row - 1)) 1634 fprintf(stderr, "ERROR: 'Last Plane' set on plane %d of %d!\n", 1635 current_data_row, expected_data_rows_per_row); 1636 } 1637 else { 1638 if (current_data_row == (expected_data_rows_per_row - 1)) 1639 fprintf(stderr, "ERROR: Expected 'last plane', but not set!\n"); 1640 } 1641 1642/* 1643 * Accumulate the data rows for each output row,then write the image. 1644 */ 1645 1646 if (image_data.compression_type == PCL_COMPRESSION_NONE) { 1647 memcpy(received_rows[current_data_row], &data_buffer, (size_t) numeric_arg); 1648 output_data.active_length = numeric_arg; 1649 } 1650 else 1651 output_data.active_length = decode_tiff(data_buffer, numeric_arg, received_rows[current_data_row], output_data.buffer_length); 1652 1653 if (command == PCL_DATA_LAST) { 1654 if (image_data.colour_type == PCL_MONO) 1655 write_grey(&output_data, &image_data); 1656 else 1657 write_colour(&output_data, &image_data); 1658 current_data_row = 0; 1659 image_row_counter++; 1660 } 1661 else 1662 current_data_row++; 1663 } 1664 break; 1665 1666 case PCL_ENTER_HPGL2 : 1667 case PCL_ENTER_PJL : { 1668 int c; 1669 fprintf(stderr, "%s %d\n", pcl_commands[command_index].description, numeric_arg); 1670 1671/* 1672 * This is a special command. Read up to the next ESC and output it. 1673 */ 1674 1675 c = 0; 1676 while (1) { 1677 fill_buffer(); 1678 if (eof == 1) { 1679 fprintf(stderr, "\n"); 1680 break; 1681 } 1682 c = read_buffer[read_pointer++]; 1683 if (c == '\033') 1684 break; 1685 fprintf(stderr, "%c", c); 1686 } 1687 1688/* 1689 * Now we are sitting at the "ESC" that is the start of the next command. 1690 */ 1691 read_pointer--; 1692 fprintf(stderr, "\n"); 1693 fprintf(stderr, "End of %s\n", pcl_commands[command_index].description); 1694 } 1695 break; 1696 1697 case PCL_PAGE_ORIENTATION : 1698 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1699 switch (numeric_arg) { 1700 case 0 : 1701 fprintf(stderr, "Portrait"); 1702 break; 1703 case 1 : 1704 fprintf(stderr, "Landscape"); 1705 break; 1706 case 2 : 1707 fprintf(stderr, "Reverse Portrait"); 1708 break; 1709 case 3 : 1710 fprintf(stderr, "Reverse Landscape"); 1711 break; 1712 default : 1713 fprintf(stderr, "Unknown (%d)", numeric_arg); 1714 break; 1715 } 1716 fprintf(stderr, " (ignored)\n"); 1717 break; 1718 1719 case PCL_MEDIA_SIDE : 1720 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1721 switch (numeric_arg) { 1722 case 0 : 1723 fprintf(stderr, "Next side"); 1724 break; 1725 case 1 : 1726 fprintf(stderr, "Front side"); 1727 break; 1728 case 2 : 1729 fprintf(stderr, "Back side"); 1730 break; 1731 default : 1732 fprintf(stderr, "Unknown (%d)", numeric_arg); 1733 break; 1734 } 1735 fprintf(stderr, " (ignored)\n"); 1736 break; 1737 1738 case PCL_MEDIA_DEST : 1739 fprintf(stderr, "%s: ", pcl_commands[command_index].description); 1740 switch (numeric_arg) { 1741 case 1 : 1742 fprintf(stderr, "Upper Output bin"); 1743 break; 1744 case 2 : 1745 fprintf(stderr, "Lower (Rear) Output bin"); 1746 break; 1747 default : 1748 fprintf(stderr, "Unknown (%d)", numeric_arg); 1749 break; 1750 } 1751 fprintf(stderr, " (ignored)\n"); 1752 break; 1753 1754 default : 1755 fprintf(stderr, "ERROR: No handler for %s!\n", pcl_commands[command_index].description); 1756 break; 1757 } 1758 } 1759 } 1760} 1761