about summary refs log tree commit diff
path: root/converter/pbm/pbmtoppa/pbmtoppa.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/pbm/pbmtoppa/pbmtoppa.c')
-rw-r--r--converter/pbm/pbmtoppa/pbmtoppa.c449
1 files changed, 449 insertions, 0 deletions
diff --git a/converter/pbm/pbmtoppa/pbmtoppa.c b/converter/pbm/pbmtoppa/pbmtoppa.c
new file mode 100644
index 00000000..85a98529
--- /dev/null
+++ b/converter/pbm/pbmtoppa/pbmtoppa.c
@@ -0,0 +1,449 @@
+/* pbmtoppa.c
+ * program to print a 600 dpi PBM file on the HP DJ820Cse or the HP720 series.
+ * Copyright (c) 1998 Tim Norman.  See LICENSE for details
+ * 2-24-98
+ */
+
+#define _BSD_SOURCE
+    /* This makes sure strcasecmp() is in string.h */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "pbm.h"
+#include "ppa.h"
+#include "ppapbm.h"
+#include "cutswath.h"
+
+#include "defaults.h"
+
+/* Paper sizes in 600ths of an inch. */
+
+/* US is 8.5 in by 11 in */
+
+#define USWIDTH  (5100)
+#define USHEIGHT (6600)
+
+/* A4 is 210 mm by 297 mm == 8.27 in by 11.69 in */
+
+#define A4WIDTH  (4960)
+#define A4HEIGHT (7016)
+
+int Width;      /* width and height in 600ths of an inch */
+int Height;
+int Pwidth;     /* width in bytes */
+
+#define MAX_LINES 300
+
+ppa_stat printer;
+
+static int 
+print_pbm(FILE * const in) {
+
+    char line[1024];
+    pbm_stat pbm;
+    int done_page, numpages = 0;
+    ppa_sweep_data sweeps[2];
+    int current_sweep, previous_sweep;
+
+    ppa_init_job(&printer);
+
+    while(make_pbm_stat(&pbm, in)) {
+        if (pbm.width != Width || pbm.height != Height) 
+            pm_error("print_pbm(): Input image is not the size "
+                    "of a page for Page %d.  "
+                    "The input is %dW x %dH, "
+                     "while a page is %dW x %dH pixels.\n"
+                    "Page size is controlled by options and the configuration "
+                    "file.",
+                     numpages+1, pbm.width, pbm.height, Width, Height);
+
+        ppa_init_page(&printer);
+        ppa_load_page(&printer);
+
+        sweeps[0].direction = right_to_left;
+        sweeps[0].next=&sweeps[1];
+        sweeps[1].direction = left_to_right;
+        sweeps[1].next=&sweeps[0];
+
+        current_sweep=0;
+        previous_sweep=-1;
+
+        done_page=0;
+        while(!done_page) {
+            int rc;
+            rc = cut_pbm_swath(&pbm, &printer, MAX_LINES,
+                               &sweeps[current_sweep]);
+            switch(rc) {
+            case 0:
+                pm_error("print_pbm(): cut_pbm_swath() failed.");
+                break;
+            case 1:
+                done_page=1;
+                break;
+            case 2:
+                if (previous_sweep >= 0) {
+                    ppa_print_sweep(&printer, &sweeps[previous_sweep]);
+                    free(sweeps[previous_sweep].image_data);
+                    free(sweeps[previous_sweep].nozzle_data);
+                }
+                previous_sweep=current_sweep;
+                current_sweep= current_sweep==0 ? 1 : 0;
+                break;
+            default:
+                pm_error("print_pbm(): unknown return code from "
+                         "cut_pbm_swath()");
+            }
+        }
+        if (previous_sweep >= 0) {
+            sweeps[previous_sweep].next=NULL;
+            ppa_print_sweep(&printer,&sweeps[previous_sweep]);
+        }
+
+        free(sweeps[0].image_data);
+        free(sweeps[0].nozzle_data);
+        free(sweeps[1].image_data);
+        free(sweeps[1].nozzle_data);
+
+        ppa_eject_page(&printer);
+
+        /* eat any remaining whitespace */
+        if(pbm.version==P1)
+            fgets (line, 1024, in);
+
+        ++numpages;
+    }
+
+    if (numpages == 0)
+        pm_error("No pages printed!");
+
+    ppa_end_print(&printer);
+
+    fclose (pbm.fptr);
+    fclose (printer.fptr);
+
+    return 0;
+}
+
+
+
+static void 
+set_printer_specific_defaults()
+{
+    switch(printer.version)
+    {
+    case HP720:
+        printer.marg_diff     = HP720_MARG_DIFF;
+        printer.bufsize       = HP720_BUFSIZE;
+
+        printer.x_offset      = HP720_X_OFFSET;
+        printer.y_offset      = HP720_Y_OFFSET;
+        printer.top_margin    = HP720_TOP_MARGIN;
+        printer.left_margin   = HP720_LEFT_MARGIN;
+        printer.right_margin  = HP720_RIGHT_MARGIN;
+        printer.bottom_margin = HP720_BOTTOM_MARGIN;
+        break;
+    case HP820:
+        printer.marg_diff     = HP820_MARG_DIFF;
+        printer.bufsize       = HP820_BUFSIZE;
+
+        printer.x_offset      = HP820_X_OFFSET;
+        printer.y_offset      = HP820_Y_OFFSET;
+        printer.top_margin    = HP820_TOP_MARGIN;
+        printer.left_margin   = HP820_LEFT_MARGIN;
+        printer.right_margin  = HP820_RIGHT_MARGIN;
+        printer.bottom_margin = HP820_BOTTOM_MARGIN;
+        break;
+    case HP1000:
+        printer.marg_diff     = HP1000_MARG_DIFF;
+        printer.bufsize       = HP1000_BUFSIZE;
+
+        printer.x_offset      = HP1000_X_OFFSET;
+        printer.y_offset      = HP1000_Y_OFFSET;
+        printer.top_margin    = HP1000_TOP_MARGIN;
+        printer.left_margin   = HP1000_LEFT_MARGIN;
+        printer.right_margin  = HP1000_RIGHT_MARGIN;
+        printer.bottom_margin = HP1000_BOTTOM_MARGIN;
+        break;
+    default:
+        pm_error("set_printer_defaults(): unknown printer version");
+    }
+}
+
+
+
+static void 
+show_usage(const char* const prog)
+{
+    printf("usage: %s [ options ] [ <infile> [ <outfile> ] ]\n\n",prog);
+    printf("  Prints a pbm- or pbmraw-format <infile> to HP720/820/1000-format <outfile>.\n\n");
+    printf("    -v <version>    printer version (720, 820, or 1000)\n");
+    printf("    -x <xoff>       vertical offset adjustment in 1\"/600\n");
+    printf("    -y <yoff>       horizontal offset adjustment in 1\"/600\n");
+    printf("    -t <topmarg>    top margin in 1\"/600    (default: 150 = 0.25\")\n");
+    printf("    -l <leftmarg>   left margin in 1\"/600   (default: 150 = 0.25\")\n");
+    printf("    -r <rightmarg>  right margin in 1\"/600  (default: 150 = 0.25\")\n");
+    printf("    -b <botmarg>    bottom margin in 1\"/600 (default: 150 = 0.25\")\n");
+    printf("    -s <paper>      paper size (us, a4, default: us)\n");
+    printf("    -f <cfgfile>    read <cfgfile> as parameters\n\n");
+    printf("  The -x and -y options accumulate.  The -v option resets the horizontal and\n");
+    printf("  vertical adjustments to an internal default.  <infile> and <outfile> default\n");
+    printf("  to stdin and stdout.  '-' is a synonym for stdin and stdout.\n\n");
+    printf("  Configuration files specified with the '-f' parameter have the following\n  format:\n\n");
+    printf("    # Comment\n");
+    printf("    <key1> <value1>\n");
+    printf("    <key2> <value2>\n");
+    printf("    [etc.]\n\n");
+    printf("  Valid keys are 'version', 'xoffset', 'yoffset', 'topmargin', 'leftmargin',\n");
+    printf("  'rightmargin', 'bottommargin', 'papersize', or any non-null truncated\n");
+    printf("  version of these words.  Valid values are the same as with the corresponding\n");
+    printf("  command-line parameters.  Parameters in the configuration file act as though\n");
+    printf("  the corresponding parameters were substituted, in order, for the '-f'\n");
+    printf("  parameter which specified the file.\n\n");
+    printf("  The file /etc/pbmtoppa.conf, if it exists, is processed as a configuration\n");
+    printf("  file before any command-line parameters are processed.\n\n");
+}
+
+
+
+static void 
+parm_version(char* arg)
+{
+    if(!strcasecmp(arg,"hp720") || !strcmp(arg,"720"))
+        printer.version=HP720;
+    else if(!strcasecmp(arg,"hp820") || !strcmp(arg,"820"))
+        printer.version=HP820;
+    else if(!strcasecmp(arg,"hp1000") || !strcmp(arg,"1000"))
+        printer.version=HP1000;
+    else
+        pm_error("parm_version(): unknown printer version '%s'",arg);
+    set_printer_specific_defaults();
+}
+
+
+
+static void 
+parm_iversion(int arg)
+{
+    switch(arg)
+    {
+    case 720:
+        printer.version=HP720;
+        break;
+    case 820:
+        printer.version=HP820;
+        break;
+    case 1000:
+        printer.version=HP1000;
+        break;
+    default:
+        pm_error("parm_iversion(): unknown printer version '%d'", arg);
+    }
+    set_printer_specific_defaults();
+}
+
+
+
+static void 
+dump_config()
+{
+    printf("version:  ");
+    switch(printer.version)
+    {
+    case HP710:  printf("HP710\n");  break;
+    case HP720:  printf("HP720\n");  break;
+    case HP820:  printf("HP820\n");  break;
+    case HP1000: printf("HP1000\n"); break;
+    }
+    printf("x-offset: %d\ny-offset: %d\nmargins:\n top:    %d\n"
+           " left:   %d\n right:  %d\n bottom: %d\n",printer.x_offset,
+           printer.y_offset,printer.top_margin,printer.left_margin,
+           printer.right_margin,printer.bottom_margin);
+    exit(0);
+}
+
+
+
+static void 
+read_config_file(const char* const fname)
+{
+    FILE* cfgfile=fopen(fname,"r");
+    char line[1024],key[14],buf[10];
+    int len,value,lineno=1;
+
+    if(!cfgfile)
+        pm_error("read_config_file(): couldn't open file '%s'", fname);
+
+    while(fgets(line,1024,cfgfile))
+    {
+        if(strchr(line,'#'))
+            *strchr(line,'#')=0;
+        switch(sscanf(line,"%13s%9s",key,buf))
+        {
+        case 2:
+            value=atoi(buf);
+            len=strlen(key);
+            if(!strncmp(key,"version",len))
+                parm_iversion(value);
+            else if(!strncmp(key,"xoffset",len))
+                printer.x_offset=value;
+            else if(!strncmp(key,"yoffset",len))
+                printer.y_offset=value;
+            else if(!strncmp(key,"topmargin",len))
+                printer.top_margin=value;
+            else if(!strncmp(key,"leftmargin",len))
+                printer.left_margin=value;
+            else if(!strncmp(key,"rightmargin",len))
+                printer.right_margin=value;
+            else if(!strncmp(key,"bottommargin",len))
+                printer.bottom_margin=value;
+            else if(!strncmp(key,"papersize",len))
+            {
+                if(!strcmp(buf,"us"))
+                {
+                    Width = USWIDTH;
+                    Height = USHEIGHT;
+                }
+                else if(!strcmp(buf,"a4"))
+                {
+                    Width = A4WIDTH;
+                    Height = A4HEIGHT;
+                }
+                else
+                    pm_error("read_config_file(): unknown paper size %s", buf);
+            }
+            else if(!strcmp(key,"dump"))
+                dump_config();
+            else 
+                pm_error("read_config_file(): unrecognized parameter '%s' "
+                         "(line %d)", key, lineno);
+        case EOF:
+        case 0: 
+            break;
+        default:
+            pm_error("read_config_file(): error parsing config file "
+                     "(line %d)", lineno);
+        }
+        lineno++;
+    }
+
+    if(feof(cfgfile))
+    {
+        fclose(cfgfile);
+        return;
+    }
+
+    pm_error("read_config_file(): error parsing config file");
+}
+
+
+
+const char* const defaultcfgfile="/etc/pbmtoppa.conf";
+
+
+
+int 
+main(int argc, char *argv[]) {
+
+    int argn;
+    int got_in=0, got_out=0, do_continue=1;
+    FILE *in=stdin, *out=stdout;
+    struct stat tmpstat;
+
+    pbm_init(&argc, argv);
+
+    printer.version       = DEFAULT_PRINTER;
+    printer.x_offset      = DEFAULT_X_OFFSET;
+    printer.y_offset      = DEFAULT_Y_OFFSET;
+    printer.top_margin    = DEFAULT_TOP_MARGIN;
+    printer.left_margin   = DEFAULT_LEFT_MARGIN;
+    printer.right_margin  = DEFAULT_RIGHT_MARGIN;
+    printer.bottom_margin = DEFAULT_BOTTOM_MARGIN;
+    printer.DPI           = DEFAULT_DPI;
+    Width = USWIDTH;
+    Height = USHEIGHT;
+    set_printer_specific_defaults();
+
+    if(!stat(defaultcfgfile,&tmpstat))
+        read_config_file(defaultcfgfile);
+
+    for(argn=1; argn<argc; argn++)
+    {
+        if(!strcmp(argv[argn],"-h"))
+        {
+            show_usage(*argv);
+            return 0;
+        }
+        else if(!strcmp(argv[argn],"-d"))
+            dump_config();
+        else if(argn+1<argc)
+        {
+            do_continue=1;
+            if(!strcmp(argv[argn],"-v"))
+                parm_version(argv[++argn]);
+            else if(!strcmp(argv[argn],"-x"))
+                printer.x_offset+=atoi(argv[++argn]);
+            else if(!strcmp(argv[argn],"-y"))
+                printer.y_offset+=atoi(argv[++argn]);
+            else if(!strcmp(argv[argn],"-t"))
+                printer.top_margin=atoi(argv[++argn]);
+            else if(!strcmp(argv[argn],"-l"))
+                printer.left_margin=atoi(argv[++argn]);
+            else if(!strcmp(argv[argn],"-r"))
+                printer.right_margin=atoi(argv[++argn]);
+            else if(!strcmp(argv[argn],"-b"))
+                printer.bottom_margin=atoi(argv[++argn]);
+            else if(!strcmp(argv[argn],"-d"))
+                printer.DPI=atoi(argv[++argn]);
+            else if(!strcmp(argv[argn],"-s"))
+            {
+                argn++;
+                if(!strcmp(argv[argn],"us"))
+                {
+                    Width = USWIDTH;
+                    Height = USHEIGHT;
+                }
+                else if(!strcmp(argv[argn],"a4"))
+                {
+                    Width = A4WIDTH;
+                    Height = A4HEIGHT;
+                }
+                else
+                    pm_error("unknown paper size %s",argv[argn]);
+            }
+            else if(!strcmp(argv[argn],"-f"))
+                read_config_file(argv[++argn]);
+            else do_continue=0;
+            if(do_continue) continue;
+        }
+
+        if(!got_in)
+        {
+            if (strcmp (argv[argn], "-") == 0)
+                in = stdin;
+            else if ((in = fopen (argv[argn], "rb")) == NULL)
+                pm_error("main(): couldn't open file '%s'", 
+                         argv[argn]);
+            got_in=1;
+        }
+        else if(!got_out)
+        {
+            if (strcmp (argv[argn], "-") == 0)
+                out = stdout;
+            else if ((out = fopen (argv[argn], "wb")) == NULL)
+                pm_error("main(): couldn't open file '%s'", 
+                         argv[argn]);
+            got_out=1;
+        }
+        else
+            pm_error("main(): unrecognized parameter '%s'", argv[argn]);
+    }
+
+    Pwidth=(Width+7)/8;
+    printer.fptr=out;
+
+    return print_pbm (in);
+}
+