/* * Photo Image Print System * Copyright (C) 2000-2004 EPSON KOWA Corporation. * Copyright (C) SEIKO EPSON CORPORATION 2000-2004. * * 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 "pips.h" #include "pipsError.h" #include "prtOpt.h" #define LINE_BUFFER 1024 #define ARRAY_MAX 14 #define SUB_MAX 3 #define GLOBAL_OPTIONS_NOMBER 3 #define PIPS_UI_MODE 0 #define PIPS_LANG 1 #define PIPS_INPUT_FILE_TYPE 2 const char *gopts[] = { "ui" /* select UI */ }; const char *opts[] = { "sc", "scale", /* id = 0 */ "in", "ink", /* id = 1 */ "ms", "mediasize", /* id = 2 */ "re", "resolution", /* id = 3 */ "mt", "mediatipe", /* id = 4 */ "cc", "colorcorrection", /* id = 5 */ "br", "brightness", /* id = 6 */ "co", "contrast", /* id = 7 */ "sa", "saturation", /* id = 8 */ "st", "strength", /* id = 9 */ "ht", "halftone", /* id = 10 */ "hs", "highspeed", /* id = 11 */ "ql", "qualitylevel", /* id = 12 */ "mg", "margin", /* id = 13 */ #ifdef ROLL_PAPER "ps", "papersource", /* id = 14 */ #endif /* ROLL_PAPER */ NULL }; extern void *opt_address[EX_N_OPT]; static int globalInitOpts(char*, int, PIPS_INIT_PARAM*); static int getRscError(SEP_INIT_PARAM*, int, int, FILE*); static int scanRscFile(FILE*); static char* existsp(char*); static int checkConf(SEP_INIT_PARAM*); static void defSet(SEP_INIT_PARAM *); static int setConf(int id, SEP_INIT_PARAM *sepip, char sub[SUB_MAX][ARRAY_MAX]); static int valueCheck(int id, char sub[SUB_MAX][ARRAY_MAX]); /*--------------------------------------------------*/ /* globalInitOpts */ /*--------------------------------------------------*/ static int globalInitOpts (char *strv, int opt_id, PIPS_INIT_PARAM *pip) { int value; switch (opt_id) { case PIPS_UI_MODE: if (!strncmp (strv, "X", 1)) value = 0; else if (!strncmp (strv, "C", 1)) value = 1; else return 1; pip->action_mode = value; break; default: return 1; } return 0; } /*##################################################*/ /* xMode */ /*##################################################*/ #if USE_GTK int xMode (int argc, char *argv[], char *filename, SEP_INIT_PARAM *sepip, PIPS_INIT_PARAM *pip) { confWinInit (&argc, &argv, filename, sepip, pip); if (confWinShow (sepip, PRINTER_MODEL)) { confWinFinalize (); return pipsError ((char *)NULL, UNEXPECTED_ERROR); } confWinFinalize (); return 0; } #endif /*##################################################*/ /* cMode */ /*##################################################*/ int cMode (char *filename, SEP_INIT_PARAM *sepip, PIPS_INIT_PARAM *pip) { #ifdef CONV_VERSION2 return graphics_converter_version2 (sepip, filename, NULL); #else FILE *fp = stdout; return printLoop (filename, fp, sepip); #endif } /*##################################################*/ /* databasesCall */ /*##################################################*/ /* 値からデータベースを呼び出せるよう変更 Mon Aug 28 2000 sk */ OPTION_DATA* databasesCall (int frag, int id, void *entry) { int i; OPTION_DATA *data; data = NULL; for (i = 0; opt_all[i].id != END_ARRAY; i++) if (opt_all[i].id == id) { data = opt_all[i].data; break; } if (data == NULL) return NULL; if (frag == CALL_FOR_RSC_NAME) { for (i = 0; data[i].value != END_ARRAY; i++) { if (!strcmp ((char*)entry, data[i].rsc_name)) return (data + i); } } else if (frag == CALL_FOR_X_NAME) { for (i = 0; data[i].value != END_ARRAY; i++) { if(!strcmp ((char*)entry, data[i].x_name)) return (data + i); } } /* add Mon Aug 28 2000 sk */ else if (frag == CALL_FOR_VALUE) { for (i = 0; data[i].rsc_name != NULL; i++) { if (data[i].value == *((int*)entry)) return (data + i); } } return NULL; } /*##################################################*/ /* getRsc */ /*##################################################*/ int getRsc (SEP_INIT_PARAM *sepip) { FILE *fp; char lin[LINE_BUFFER]; int lin_No; defSet (sepip); if ((fp = fopen (RSC_PATH, "rb")) == NULL) { return -1; } lin_No = scanRscFile (fp); switch (lin_No) { case -1: getRscError (sepip, lin_No, NO_ERROR, fp); return -1; case 0: fclose (fp); return -1; } lin_No++; for (; fgets (lin, LINE_BUFFER - 1, fp) != NULL; lin_No++) { int p_id, size, i; char p_name[ARRAY_MAX], p_sub[ARRAY_MAX + 1]; char sub_arg[SUB_MAX][ARRAY_MAX]; existsp (lin); switch (*lin) { case '\0': break; case '[': fclose (fp); return 0; default: if (sscanf (lin, "%[^=]s", p_name) != 1) { getRscError (sepip, lin_No, RESOURCE_FORM_ERROR, fp); return NO_ERROR; } size = strlen (p_name); for (p_id = 0; p_id < N_OPT; p_id++) { if (!strncmp(lin, opts[p_id * 2 + 1], size)) { size++; if (sscanf (lin + size, "%s", p_sub) != 1) { getRscError (sepip, lin_No, RESOURCE_FORM_ERROR, fp); return NO_ERROR; } strcat (p_sub, ","); size = 0; for (i = 0; (sscanf (p_sub + size, "%[^,]s", sub_arg[i]) == 1) && (i < SUB_MAX); i++) size += strlen (sub_arg[i]) + 1; if (setConf (p_id, sepip, sub_arg)) { getRscError (sepip, lin_No, RESOURCE_VALUES_ERROR, fp); return NO_ERROR; } break; } } if (p_id == N_OPT) { getRscError (sepip, lin_No, RESOURCE_VALUES_ERROR, fp); return NO_ERROR; } } } if (fp != NULL) fclose (fp); return 0; } /*--------------------------------------------------*/ /* getRscError */ /*--------------------------------------------------*/ static int getRscError (SEP_INIT_PARAM *sepip, int lin_No, int error_code, FILE *fp) { if (fp != NULL) fclose(fp); if (lin_No != -1) { char lin_No_c[128]; memset (lin_No_c, '\0', 127); sprintf (lin_No_c, "%d", lin_No); pipsError (lin_No_c, RESOURCE_ERROR); pipsError (NULL, error_code); } fprintf (stderr, "PIPS Warning : default set\n"); defSet (sepip); return lin_No; } /*##################################################*/ /* saveRsc */ /*##################################################*/ void saveRsc (void *save_options[]) { FILE *fp; char *before_buffer, *back_buffer, lin[LINE_BUFFER]; int user_id, file_len, first_save, i; long insert_pos, protect_pos; before_buffer = back_buffer = 0; first_save = 0; user_id = geteuid (); if ((fp = fopen (RSC_PATH, "a+b")) == NULL) { fprintf (stderr, "PIPS Warning : Resource file not found or resource not set. Do save with root.\n"); return; } fclose (fp); if ((fp = fopen (RSC_PATH, "rb")) == NULL) return; switch (scanRscFile (fp)) { case -1: fclose (fp); return; case 0: first_save = 1; default: break; } insert_pos = ftell (fp); if (insert_pos != 0) { fseek (fp, 0, SEEK_SET); before_buffer = (char *)calloc (insert_pos + 1, sizeof (char)); fread (before_buffer, sizeof (char), insert_pos, fp); } for (; fgets (lin, LINE_BUFFER, fp) != NULL;) { int line_size; line_size = strlen (lin); existsp (lin); if (*lin == '[') { fseek (fp, line_size * -1, SEEK_CUR); break; } } protect_pos = ftell (fp); fseek (fp, 0, SEEK_END); file_len = ftell (fp); if (file_len != 0) { back_buffer = (char *)calloc (file_len - insert_pos + 1, sizeof (char)); fseek (fp, protect_pos, SEEK_SET); fread (back_buffer, sizeof (char), file_len, fp); } fclose (fp); fp = fopen (RSC_PATH, "wb"); if (before_buffer != 0) { fwrite (before_buffer, sizeof (char), strlen (before_buffer), fp); free (before_buffer); } if (first_save) { fprintf (fp, "[ %s ]\n", PRINTER_MODEL); } for (i = 0; i < N_OPT; i++) { fprintf (fp, "%s = ", opts[i * 2 + 1]); switch (i) { case P_SCALE: case P_BRIGHTNESS: case P_CONTRAST: case P_SATURATION: fprintf (fp, "%d\n", *((int*)save_options[i])); break; case P_INK: case P_MEDIA_SIZE: case P_RESOLUTION: case P_MEDIA_TYPE: case P_HALF_TONE: case P_COLOR_MODE: case P_QUALITY_LEVEL: case P_BIN: fprintf (fp, "%s\n", (char*)save_options[i]); break; case P_STRENGTH: fprintf (fp, "%d, ", *((int*)save_options[P_STRENGTH_CYAN])); fprintf (fp, "%d, ", *((int*)save_options[P_STRENGTH_MAGENTA])); fprintf (fp, "%d\n", *((int*)save_options[P_STRENGTH_YELLOW])); break; case P_HIGH_SPEED: if ((char*)save_options[i] == NULL) fprintf (fp, "%s\n", "OFF"); else fprintf (fp, "%s\n", (char*)save_options[i]); break; #ifdef CONV_VERSION2 case P_MARGIN: fprintf (fp, "%d, ", *((int*)save_options[P_MARGIN_X])); fprintf (fp, "%d\n", *((int*)save_options[P_MARGIN_Y])); break; #endif /* CONV_VERSION2 */ default: break; } } fprintf (fp, "\n"); if (back_buffer != 0) { fwrite (back_buffer, sizeof (char), strlen(back_buffer), fp); free (back_buffer); } fclose(fp); if(!user_id) chmod(RSC_PATH, 438); } /*--------------------------------------------------*/ /* scanRscFile */ /*--------------------------------------------------*/ static int scanRscFile (FILE *fp) { int lin_No, flag = 0; char lin[LINE_BUFFER], ep_name[ARRAY_MAX]; char printer[] = PRINTER_MODEL; for (lin_No = 1; fgets (lin, LINE_BUFFER - 1, fp) != NULL; lin_No++) { existsp (lin); switch (*lin) { case '\0': break; case '[': flag = 1; if (sscanf (lin, "[%[^]]s", ep_name) == EOF) return -1; if (!strncmp (existsp (printer), ep_name, strlen(ep_name))) return lin_No; break; default: if (flag == 0) return -1; } } return 0; } /*--------------------------------------------------*/ /* getOpts */ /*--------------------------------------------------*/ int getOpts (int nargc, char **nargv, char **filename, SEP_INIT_PARAM *sepip, PIPS_INIT_PARAM *pip) { int arg_count, opt_id, i, ni, size; char error_data[1024]; for (arg_count = 1; arg_count < nargc; arg_count++) { if (nargv[arg_count][0] == '-') { char sub_arg[SUB_MAX][ARRAY_MAX]; strncpy (error_data, nargv[arg_count], 1023); for (opt_id = 0; opt_id < N_OPT; opt_id++) { size = strlen (opts[opt_id * 2]); if (!strncmp (nargv[arg_count] + 1, opts[opt_id * 2], size)) { if (opt_id == P_STRENGTH) ni = 3; else if (opt_id == P_MARGIN) ni = 2; else ni = 1; for (i = 0; i < ni; i++) { /* error check */ strcat (error_data, " "); strcat (error_data, nargv[arg_count + 1]); if ((++arg_count <= nargc) && ((nargv[arg_count][0] != '-') || (isdigit(nargv[arg_count][1])))) { strcpy (sub_arg[i], nargv[arg_count]); } else { return pipsError (error_data, OPTION_LESS_ERROR); } } if (setConf (opt_id, sepip, sub_arg)) { return pipsError (error_data, OPTION_VALUES_ERROR); } goto OPT_SET_END; } } for (opt_id = 0; opt_id < GLOBAL_OPTIONS_NOMBER; opt_id++) { size = strlen (gopts[opt_id]); if (!strncmp (nargv[arg_count] + 1, gopts[opt_id], size)) { /* error check */ if ((++arg_count <= nargc) && (nargv[arg_count][0] != '-')) { strcat (error_data, " "); strcat (error_data, nargv[arg_count]); } else { return pipsError (error_data, OPTION_LESS_ERROR); } if (globalInitOpts (nargv[arg_count], opt_id, pip)) { return pipsError (error_data, OPTION_VALUES_ERROR); } goto OPT_SET_END; } } return pipsError (error_data, NO_OPTION_ERROR); OPT_SET_END:; } else if (*filename == 0) { *filename = (char *)malloc (strlen ( nargv[arg_count]) + 1 ); strcpy (*filename, nargv[arg_count]); } else if (strcmp (*filename, nargv[arg_count])) { sprintf (error_data,"\"%s\" \"%s\"", *filename, nargv[arg_count]); return pipsError (error_data, DUB_FILENAME_ERROR); } } if (checkConf (sepip)) { return pipsError (NULL , CONNECTION_ERROR); } return 0; } /*##################################################*/ /* getOptsForX */ /*##################################################*/ int getOptsForX (void *options[], SEP_INIT_PARAM *sepip) { char sub_arg[SUB_MAX][ARRAY_MAX]; int i, *val; for (i = 0; i < N_OPT; i++) { switch (i) { case P_SCALE: case P_BRIGHTNESS: case P_CONTRAST: case P_SATURATION: val = (int*)options[i]; sprintf (sub_arg[0], "%d", *val); break; case P_STRENGTH: val = (int*)options[P_STRENGTH_CYAN]; sprintf (sub_arg[0], "%d", *val); val = (int*)options[P_STRENGTH_MAGENTA]; sprintf (sub_arg[1], "%d", *val); val = (int*)options[P_STRENGTH_YELLOW]; sprintf (sub_arg[2], "%d", *val); break; case P_INK: case P_MEDIA_SIZE: case P_RESOLUTION: case P_MEDIA_TYPE: case P_COLOR_MODE: case P_HALF_TONE: case P_QUALITY_LEVEL: case P_BIN: strcpy (sub_arg[0], (char *)options[i]); break; case P_HIGH_SPEED: if(options[P_HIGH_SPEED] != NULL) strcpy (sub_arg[0], (char *)options[P_HIGH_SPEED]); else strcpy (sub_arg[0], "OFF"); break; #ifdef CONV_VERSION2 case P_MARGIN: val = (int*)options[P_MARGIN_X]; sprintf (sub_arg[0], "%d", *val); val = (int*)options[P_MARGIN_Y]; sprintf (sub_arg[1], "%d", *val); break; #endif /* CONV_VERSION2 */ default: break; } if (setConf (i, sepip, sub_arg)) { return pipsError ((char *)NULL, OPTION_VALUES_ERROR); } } if (checkConf (sepip)) { /* error check */ return pipsError ((char *)NULL, CONNECTION_ERROR); } return 0; } /*--------------------------------------------------*/ /* checkConf */ /*--------------------------------------------------*/ static int checkConf (SEP_INIT_PARAM *sepip) { int i, level_count; const short *mode; if (sepip->prt_format) mode = pModeCol; else mode = pModeMono; level_count = sepip->qlevel; for (i = 0; i < mode[0]; i++) { if (!printModeCheck (mode, i, sepip)) { #ifdef ROLL_PAPER int check; char **msizeEntry; switch (sepip->bin_id) { case PIPS_BIN_AUTO: msizeEntry = mediaSizeEntry; break; case PIPS_BIN_USER: msizeEntry = mediaSizeEntry_R; break; #if !(PM820_3300C) case PIPS_BIN_TRIMBANNER: msizeEntry = mediaSizeEntry_TR; break; #else case PIPS_BIN_TB_PM3300C: msizeEntry = mediaSizeEntry_TR_PM3300C; break; case PIPS_BIN_TB_PM820C: msizeEntry = mediaSizeEntry_TR_PM820C; break; #endif /* PM820_3300C */ #if (PM820C) case PIPS_BIN_AUTO_TRIM: msizeEntry = mediaSizeEntry_TA; break; #endif /* PM820C */ default: return 1; } check = 0; for (i = 0; msizeEntry[i] != NULL; i++) { if (!strcmp (getRscName (P_MEDIA_SIZE, sepip->paper_id), msizeEntry[i])) { check = 1; break; } } if (!check) return pipsError ((char *)NULL, OPTION_VALUES_ERROR); #endif /* ROLL_PAPER */ return 0; } } return 1; } /*--------------------------------------------------*/ /* printModeCheck */ /*--------------------------------------------------*/ int printModeCheck (const short *mode, int count, SEP_INIT_PARAM *sepip) { int ofs; ofs = count * MODE_ITEM + 1; if (sepip->media_type != mode[ofs]) return 1; if (sepip->src_resolution.x >= 0) { int bit = 0; switch (sepip->src_resolution.x) { case 120: case 180: bit = 1; break; case 360: bit = 2; break; case 720: bit = 4; break; } if (!(mode[ofs + 1] & bit)) return 1; } if (sepip->qlevel < 0) return 0; else { unsigned int bit = mode[ofs + 4]; switch (sepip->src_resolution.x) { case 120: case 180: if (bit != 0) return 1; break; case 720: bit = bit >> 4; case 360: bit = bit >> 4; bit &= 0x0f; if (bit != sepip->qlevel) return 1; break; default: return 1; } } if (sepip->halftone_type >= 0) { int bit = 0; switch (sepip->halftone_type) { case PIPS_HT_QUALITY: bit = 1; break; case PIPS_HT_SPEED: bit = 2; break; case PIPS_HT_NONE: bit = 4; break; } if (!(mode[ofs + 2] & bit)) return 1; } if(sepip->high_speed >= 0) if(mode[ofs + 3] != 2) if(mode[ofs + 3] != sepip->high_speed) return 1; return 0; } /*--------------------------------------------------*/ /* existsp */ /*--------------------------------------------------*/ static char* existsp(char *lin) { char tmp_lin[LINE_BUFFER]; int i, j; j = 0; for (i = 0; lin[i] != '\0' || lin[i]; i++) if (!isspace (lin[i])) tmp_lin[j++] = lin[i]; if (tmp_lin[j - 1] != '\0') { tmp_lin[j] = '\0'; } strcpy (lin, tmp_lin); return lin; } /*--------------------------------------------------*/ /* setConf */ /*--------------------------------------------------*/ static int setConf (int id, SEP_INIT_PARAM *sepip, char sub[SUB_MAX][ARRAY_MAX]) { if (valueCheck(id, sub)) return 1; switch (id) { case P_SCALE: sepip->mag = atoi (sub[0]); break; case P_INK: sepip->prt_format = getValueOfDatabases (id, sub[0]); break; case P_MEDIA_SIZE: sepip->paper_id = getValueOfDatabases (id, sub[0]); break; case P_RESOLUTION: sepip->src_resolution.x = sepip->src_resolution.y = atoi (sub[0]); break; case P_MEDIA_TYPE: sepip->media_type = getValueOfDatabases (id, sub[0]); break; case P_HIGH_SPEED: sepip->high_speed = getValueOfDatabases (id, sub[0]); break; case P_COLOR_MODE: sepip->color_correction = getValueOfDatabases (id, sub[0]); break; case P_BRIGHTNESS: sepip->brightness = atoi (sub[0]); break; case P_CONTRAST: sepip->contrast = atoi (sub[0]); break; case P_SATURATION: sepip->saturation = atoi (sub[0]); break; case P_STRENGTH: sepip->r_strength = -(atoi (sub[0])); sepip->g_strength = -(atoi (sub[1])); sepip->b_strength = -(atoi (sub[2])); break; case P_HALF_TONE: sepip->halftone_type = getValueOfDatabases (id, sub[0]); break; case P_QUALITY_LEVEL: sepip->qlevel = getValueOfDatabases (id, sub[0]); break; case P_BIN: sepip->bin_id = getValueOfDatabases (id, sub[0]); break; #ifdef CONV_VERSION2 case P_MARGIN: sepip->margin.x = atoi (sub[0]); sepip->margin.y = atoi (sub[1]); break; #endif /* CONV_VERSION2 */ default: return 1; } return 0; } /*##################################################*/ /* getValueOfDatabases */ /*##################################################*/ int getValueOfDatabases (int id, char *entry) { OPTION_DATA *data; char off[] = "OFF"; if (entry == NULL) entry = off; if ((data = databasesCall (CALL_FOR_RSC_NAME, id, (void*)entry)) == NULL) return -1; return data->value; } /*--------------------------------------------------*/ /* defSet */ /*--------------------------------------------------*/ static void defSet (SEP_INIT_PARAM *sepip) { sepip->mag = 100; sepip->paper_id = PIPS_PAPER_A4; sepip->prt_format = PIPS_OUTPUT_CMYKcm; sepip->src_resolution.x = 360; sepip->src_resolution.y = 360; sepip->media_type = PIPS_MED_PLAIN; sepip->high_speed = PIPS_HS_ON; sepip->color_correction = PIPS_CMM_PHOTO; #if defined(PM770C) || defined(PM3000C) sepip->halftone_type = PIPS_HT_SPEED; #else sepip->halftone_type = PIPS_HT_QUALITY; #endif sepip->brightness = 0; sepip->contrast = 0; sepip->saturation = 0; sepip->r_strength = 0; sepip->g_strength = 0; sepip->b_strength = 0; sepip->bin_id = PIPS_BIN_AUTO; sepip->qlevel = PIPS_LV_STD; #ifdef CONV_VERSION2 sepip->margin.x = 3; sepip->margin.y = 3; #endif /* CONV_VERSION2 */ checkConf(sepip); } /*--------------------------------------------------*/ /* valueCheck */ /*--------------------------------------------------*/ static int valueCheck (int id, char sub[SUB_MAX][ARRAY_MAX]) { int i, j; int value; int count = 0; char **entry; switch (id) { case P_STRENGTH: count ++; #ifdef CONV_VERSION2 case P_MARGIN: #endif /* CONV_VERSION2 */ count ++; case P_SCALE: case P_BRIGHTNESS: case P_CONTRAST: case P_SATURATION: count++; for (i = 0; i < count; i++) { for (j = 0; sub[i][j] != (char)NULL; j++) { if ((sub[i][j] < '0') || (sub[i][j] > '9')) { if ((sub[i][j] != '-') && (j != 0)) return 1; } } value = (int)atoi (sub[i]); if (id == P_SCALE) { if ((value < 10) || (value > 400)) return 1; } #ifdef CONV_VERSION2 else if (id == P_MARGIN) { if ((value < 0) || (value > 1000)) return 1; } #endif /* CONV_VERSION2 */ else { if ((value < -50) || (value > 50)) return 1; } } return 0; default: break; } switch (id) { #ifndef ROLL_PAPER case P_MEDIA_SIZE: entry = mediaSizeEntry; break; #else/* not ROLL_PAPER */ case P_BIN: entry = binEntry; break; #endif /* ROLL_PAPER */ case P_INK: entry = inkEntry; break; case P_RESOLUTION: entry = resolutionEntry; break; case P_MEDIA_TYPE: entry = mediaTypeEntry; break; case P_COLOR_MODE: entry = colorModeEntry; break; case P_HALF_TONE: entry = halftoneEntry; break; case P_QUALITY_LEVEL: entry = levelEntry; break; case P_HIGH_SPEED: if (!strcmp (sub[0], "ON") || !strcmp (sub[0], "OFF")) return 0; else return 1; default: return 0; } for (i = 0; entry[i] != (char)NULL; i++) { if (!strcmp (sub[0], entry[i])) return 0; } return 1; }