/* * Photo Image Print System * Copyright (C) 2002 EPSON KOWA Corporation. * Copyright (C) SEIKO EPSON CORPORATION 2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * As a special exception, EPSON KOWA Corporation gives permission to * link the code of this program with libraries which are covered by * the EPSON KOWA PUBLIC LICENCE and distribute their linked * combinations. You must obey the GNU General Public License in all * respects for all of the code used other than the libraries which * are covered by EPSON KOWA PUBLIC LICENCE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PATH_MAX 256 #define NAME_MAX 41 #define WIDTH_BYTES(bits) (((bits) + 31) / 32 * 4) /* rtp_list_opts is offsets of value for option list. */ typedef enum rtp_list_opts { MEDIA_TYPE = 0, RESOLUTION, QUALITY, HIGH_SPEED, MICRO_WEAVE, HALFTONE, INTENT, CLEARINK /* 2004.01.26 Add Clear Ink */ } list_opts_t; typedef struct rtp_filter_option { char model[NAME_MAX]; char model_low[NAME_MAX]; char ink[NAME_MAX]; char media[NAME_MAX]; char quality[NAME_MAX]; char inkset[NAME_MAX]; } filter_option_t; static char rtp_datapath[] = "/usr/local/EPKowa"; /* static functions */ static int set_pips_parameter (filter_option_t *, LIBPRT_INIT *, LIBPRT_PAGE *); static int get_page_size (LIBPRT_INIT *, const char *, const char *, int); /* Useage: pipstoprinter model width_pixel height_pixel Ink PageSize Quality InkSet */ int main (int argc, char *argv[]) { filter_option_t fopt; char libfile[PATH_MAX + 1]; /* Name of PIPS library file */ long width_pixel, height_pixel; long bytes_per_line; int byte_par_pixel; double x_mag, y_mag; char *image_raw; unsigned char *band; long read_size = 0; int band_line; int err = 0; int i, j; /* 2004.04.15 added for 'cancel page' */ int cancel = 0; /* library handles */ lt_dlhandle lib_h; handle_t prt_h; /* library functions */ INIT_FUNC dl_init; PINIT_FUNC dl_page_init; OUT_FUNC dl_out; PEND_FUNC dl_page_end; END_FUNC dl_end; /* library options */ LIBPRT_INIT init_str; LIBPRT_PAGE page_str; LIBPRT_BAND band_str; /* attach point */ #ifdef USE_DEBUGGER int flag = 1; while (flag) sleep (3); #endif /* USE_DEBUGGER */ DEBUG_START; err_init (argv[0]); if (argc < 7 || argc > 8) { fprintf (stderr, "Usage: pipstoprinter model width_pixel height_pixel Ink PageSize Quality [InkSet]\n"); return 1; } /* set filter options */ memset (&fopt, 0, sizeof (filter_option_t)); strncpy (fopt.model, argv[1], NAME_MAX); for (i = 0; fopt.model[i] != '\0' && i < NAME_MAX - 1; i ++) fopt.model_low[i] = tolower (fopt.model[i]); fopt.model_low[i] = '\0'; width_pixel = atol (argv[2]); height_pixel = atol (argv[3]); strncpy (fopt.ink, argv[4], NAME_MAX); strncpy (fopt.media, argv[5], NAME_MAX); strncpy (fopt.quality, argv[6], NAME_MAX); if (argc == 8) { strncpy (fopt.inkset, argv[7], NAME_MAX); } else { fopt.inkset[0] = '\0'; } if (set_pips_parameter (&fopt, &init_str, &page_str)) err_fatal ("Cannot get option of PIPS."); /* exit */ if (get_page_size (&init_str, init_str.paper, init_str.bin_id, atoi (init_str.resol))) err_fatal ("Cannot get page size of PIPS."); band_line = 2; if (strcmp (fopt.ink, "COLOR") == 0) byte_par_pixel = 3; else byte_par_pixel = 1; /* setup band struct */ band_str.width_pixel = init_str.paper_area.x; band_str.width_bytes = WIDTH_BYTES (init_str.paper_area.x * byte_par_pixel * 8); band_str.line_number = band_line; band_str.lp_atbmp_band = NULL; band = mem_new (char, band_str.width_bytes * band_line); memset (band, 0xff, band_str.width_bytes * band_line); band_str.byte_data = band; /* debug */ DEBUG_INIT_STRUCT (init_str); DEBUG_PAGE_STRUCT (page_str); DEBUG_BAND_STRUCT (band_str); /* library open */ sprintf (libfile, "lib%s.so", fopt.model_low); err = lt_dlinit(); if (err) { err_fatal (lt_dlerror ()); /* exit */ } lib_h = lt_dlopenext (libfile); if (lib_h == NULL) err_fatal (lt_dlerror ()); /* exit */ /* setting of library function */ dl_init = (INIT_FUNC) lt_dlsym (lib_h, DLL_PRT_INIT); dl_page_init = (PINIT_FUNC) lt_dlsym (lib_h, DLL_PAGE_INIT); dl_out = (OUT_FUNC) lt_dlsym (lib_h, DLL_BAND_OUT); dl_page_end = (PEND_FUNC) lt_dlsym (lib_h, DLL_PAGE_END); dl_end = (END_FUNC) lt_dlsym (lib_h, DLL_PRT_END); if (! dl_init || ! dl_page_init || ! dl_out || ! dl_page_end || ! dl_end) { err_fatal ("The symbols to function was not found."); /* exit */ } err = dl_init (&prt_h, &init_str); if (err) err_fatal ("Error occurred in \"INIT_FUNC\"."); /* exit */ x_mag = (double)init_str.paper_area.x / width_pixel; y_mag = (double)init_str.paper_area.y / height_pixel; band_line = 2; bytes_per_line = WIDTH_BYTES(width_pixel * byte_par_pixel * 8); image_raw = mem_new0 (char, bytes_per_line); while ((read_size = read (STDIN_FILENO, image_raw, bytes_per_line)) > 0) { long x_count, y_count; int band_line_count; y_count = 0; band_line_count = 0; band_str.line_number = band_line; err = dl_page_init (prt_h, &page_str); if (err) err_fatal ("Error occurred in \"PINIT_FUNC\"."); /* exit */ for (i = 0; i < init_str.paper_area.y; i ++) { char *line; line = band + (band_str.width_bytes * band_line_count); while ((0 == y_count) || ((i > (y_mag * y_count) - 1) && (y_count < height_pixel))) { while ((0 == err) && (read_size < bytes_per_line)) { size_t rsize; rsize = read(STDIN_FILENO, image_raw + read_size, bytes_per_line - read_size); if (rsize < 0) { if ((errno != EINTR) && (errno != EAGAIN) && (errno != EIO)) { err = -1; /* 2004.04.15 */ /* error then quit */ /* don't care err = -1 */ cancel = 1; goto quit; /* not reached */ break; } usleep(50000); } else { read_size += rsize; } } /* 2004.04.01 */ /* for "skip reading" */ /* modified y_count count up condition and clear read_size */ if( read_size == bytes_per_line ){ y_count++; /* need to clear read_size */ /* not clear, data still remains on pipe */ read_size = 0; } } read_size = 0; if (x_mag == 1) { memcpy (line, image_raw, bytes_per_line); } else { x_count = 0; for (j = 0; j < init_str.paper_area.x; j ++) { while ( x_count == 0 || j > x_mag * x_count) x_count ++; memcpy (line + (j * byte_par_pixel), image_raw + ((x_count - 1) * byte_par_pixel), byte_par_pixel); } } band_line_count ++; if (band_line_count >= band_line) { if (dl_out (prt_h, &band_str)) err_fatal ("Error occurred in \"OUT_FUNC\"."); /* exit */ band_line_count = 0; } } if (band_line_count > 0) { band_str.line_number = band_line_count; if (dl_out (prt_h, &band_str)) err_fatal ("Error occurred in \"OUT_FUNC\"."); /* exit */ } if (dl_page_end (prt_h, 0)) err_fatal ("Error occurred in \"PEND_FUNC\"."); /* exit */ } DEDBUG_END; /* 2004.04.15 for 'error' */ quit:; if( cancel ){ dl_page_end (prt_h, cancel) ; } /**/ if (dl_end (prt_h)) err_fatal ("Error occurred in \"END_FUNC\"."); /* exit */ lt_dlclose (lib_h); lt_dlexit(); return 0; } static int set_pips_parameter (filter_option_t *filter_opt_p, LIBPRT_INIT *init_str_p, LIBPRT_PAGE *page_str_p) { char path[PATH_MAX]; /* Path of PIPS option list */ size_t size; /* Temporary value (buffer size) */ char *point; /* Temporary pointer */ int i; /* loop value */ csvlist_t *csv_p; int pos; if (strlen (filter_opt_p->media) == 0 || strlen (filter_opt_p->ink) == 0 || strlen (filter_opt_p->quality) == 0) return 1; /* Ink */ init_str_p->format = str_clone (filter_opt_p->ink, strlen (filter_opt_p->ink)); /* PageSize */ size = strcspn (filter_opt_p->media, "_"); init_str_p->paper = str_clone (filter_opt_p->media, size); if (!init_str_p->paper) err_fatal (" PPD file is broken."); /* SheetFeeder */ point = strchr (filter_opt_p->media, '_'); if (point) { point ++; size = strlen (point); init_str_p->bin_id = str_clone (point, size); } else { init_str_p->bin_id = str_clone ("AUTO", strlen ("AUTO")); } /* Load option of PIPS. */ sprintf (path, "%s/%s/cupsopt.csv", rtp_datapath, filter_opt_p->model); csv_p = csvlist_open (path); if (!csv_p) err_fatal ("%s : List file is broken.", path); pos = csvlist_search_keyword (csv_p, 0, filter_opt_p->quality); if (pos < 0) err_fatal ("%s : List file is broken.", path); /* Set options. */ pos ++; #if CLEAR_INK for (i = 0; i < 8; i++) /* 8 = option number add CLEAR_INK */ #else for (i = 0; i < 7; i++) /* 7 = option number */ #endif { char *to; char *from; from = csvlist_get_word (csv_p, pos + i); if (!from) err_fatal ("%s : List file is broken.", path); to = str_clone (from, strlen (from)); switch (i) { case MEDIA_TYPE: init_str_p->media_type = to; break; case RESOLUTION: init_str_p->resol = to; break; case QUALITY: init_str_p->qlevel = to; break; case HIGH_SPEED: init_str_p->high_speed = to; break; case MICRO_WEAVE: init_str_p->mw_type = to; break; case HALFTONE: page_str_p->halftone_type = to; break; case INTENT: page_str_p->color_mode = to; break; case CLEARINK: init_str_p->clear_ink = to; break; default: return 1; } } init_str_p->inkset = get_inkset_str (); if (strcmp(init_str_p->inkset, "DEFAULT") == 0 && filter_opt_p->inkset[0] != '\0') { init_str_p->inkset = str_clone (filter_opt_p->inkset, strlen(filter_opt_p->inkset)); } init_str_p->output = stdout; init_str_p->auto_cut = str_clone ("NONE", strlen ("NONE")); page_str_p->brightness = 0; page_str_p->contrast = 0; page_str_p->saturation = 0; page_str_p->r_strength = 0; page_str_p->g_strength = 0; page_str_p->b_strength = 0; return 0; } /* Get PageSize for PIPS */ static int get_page_size (LIBPRT_INIT *init_str_p, const char *paper, const char *bin_id, int resol) { csvlist_t *csv_p; char path[PATH_MAX]; int pos; long l_margin, r_margin, t_margin, b_margin; sprintf (path, "%s/printer/paper_list.csv", rtp_datapath); csv_p = csvlist_open (path); if (!csv_p) err_fatal ("%s : List file is broken.", path); pos = csvlist_search_keyword (csv_p, 0, paper); if (pos < 0) err_fatal ("%s : List file is broken.", path); init_str_p->paper_size.x = atol (csvlist_get_word (csv_p, pos + 2)); init_str_p->paper_size.y = atol (csvlist_get_word (csv_p, pos + 3)); l_margin = atol (csvlist_get_word (csv_p, pos + 4)); r_margin = atol (csvlist_get_word (csv_p, pos + 5)); t_margin = atol (csvlist_get_word (csv_p, pos + 6)); b_margin = atol (csvlist_get_word (csv_p, pos + 7)); if (!strcmp (bin_id, "AUTO")) { init_str_p->paper_area.x = init_str_p->paper_size.x - l_margin - r_margin; init_str_p->paper_area.y = init_str_p->paper_size.y - t_margin - b_margin; init_str_p->margin.x = l_margin; init_str_p->margin.y = t_margin; } else if (!strcmp (bin_id, "ROLL")) { init_str_p->paper_area.x = init_str_p->paper_size.x - l_margin - r_margin; init_str_p->paper_area.y = init_str_p->paper_size.y; init_str_p->margin.x = l_margin; init_str_p->margin.y = 0; } else if (!strcmp (bin_id, "TROLL")) { init_str_p->paper_area.x = init_str_p->paper_size.x; init_str_p->paper_area.y = init_str_p->paper_size.y; init_str_p->margin.x = 0; init_str_p->margin.y = 0; } else if (!strcmp (bin_id, "T4AUTO")) { init_str_p->paper_area.x = init_str_p->paper_size.x + 71; init_str_p->paper_area.y = init_str_p->paper_size.y + 113; init_str_p->margin.x = 0; init_str_p->margin.y = 0; } else { err_fatal ("%s : This sheet feeder is not supported."); } init_str_p->paper_size.x = init_str_p->paper_size.x * resol / 360; init_str_p->paper_size.y = init_str_p->paper_size.y * resol / 360; init_str_p->paper_area.x = init_str_p->paper_area.x * resol / 360; init_str_p->paper_area.y = init_str_p->paper_area.y * resol / 360; init_str_p->margin.x = init_str_p->margin.x * resol / 360; init_str_p->margin.y = init_str_p->margin.y * resol / 360; return 0; }