#define USEEPSEWAVE 1
#ifdef __GNUC__
#define inline __inline__
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gimp-print/gimp-print.h>
#include "gimp-print-internal.h"
#include <gimp-print/gimp-print-intl-internal.h>
#include <string.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#define false 0
#define true 1
#define max(a, b) ((a > b) ? a : b)
#define INCH(x) (72 * x)
typedef enum Lex_model { m_lex7500, m_z52=10052, m_z42=10042, m_3200=3200 } Lex_model;
#define NCHANNELS (7)
typedef union {
unsigned long v[NCHANNELS];
struct {
unsigned long k;
unsigned long c;
unsigned long m;
unsigned long y;
unsigned long C;
unsigned long M;
unsigned long Y;
} p;
} lexmark_lineoff_t;
typedef union {
unsigned char *v[NCHANNELS];
struct {
unsigned char *k;
unsigned char *c;
unsigned char *m;
unsigned char *y;
unsigned char *C;
unsigned char *M;
unsigned char *Y;
} p;
} lexmark_linebufs_t;
#ifdef DEBUG
typedef struct testdata {
FILE *ifile;
int x, y, cols, deep;
char colchar[16];
char *input_line;
} testdata;
const stp_vars_t *dbgfileprn;
int lex_show_lcount, lex_show_length;
const stp_vars_t lex_open_tmp_file();
const stp_vars_t lex_write_tmp_file(const stp_vars_t ofile, void *data,int length);
static void testprint(testdata *td);
static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs);
#endif
static void
flush_pass(stp_softweave_t *sw, int passno, int model, int width,
int hoffset, int ydpi, int xdpi, int physical_xdpi,
int vertical_subpass);
#define DPI300 0
#define DPI600 1
#define DPI1200 2
#define DPI2400 3
#define DPItest 4
#define V_NOZZLE_MASK 0x3
#define H_NOZZLE_MASK 0xc
#define NOZZLE_MASK 0xf
#define PRINT_MODE_300 0x100
#define PRINT_MODE_600 0x200
#define PRINT_MODE_1200 0x300
#define PRINT_MODE_2400 0x400
#define COLOR_MODE_K 0x1000
#define COLOR_MODE_C 0x2000
#define COLOR_MODE_Y 0x4000
#define COLOR_MODE_M 0x8000
#define COLOR_MODE_LC 0x10000
#define COLOR_MODE_LY 0x20000
#define COLOR_MODE_LM 0x40000
#define COLOR_MODE_CMYK (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y | COLOR_MODE_K)
#define COLOR_MODE_CMY (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y)
#define COLOR_MODE_CcMcYK (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y | COLOR_MODE_K)
#define COLOR_MODE_CcMcY (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y)
#define COLOR_MODE_MASK 0x7f000
#define PRINT_MODE_MASK 0xf00
#define COLOR_MODE_PHOTO (COLOR_MODE_LC | COLOR_MODE_LM)
#define BWR 0
#define BWL 1
#define CR 2
#define CL 3
static const double standard_sat_adjustment[49] =
{
1.0,
1.1,
1.2,
1.3,
1.4,
1.5,
1.6,
1.7,
1.8,
1.9,
1.9,
1.9,
1.7,
1.5,
1.3,
1.1,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.1,
1.2,
1.3,
1.4,
1.5,
1.5,
1.4,
1.3,
1.2,
1.1,
1.0,
1.0,
1.0,
1.0
};
static const double standard_lum_adjustment[49] =
{
0.50,
0.6,
0.7,
0.8,
0.9,
0.86,
0.82,
0.79,
0.78,
0.8,
0.83,
0.87,
0.9,
0.95,
1.05,
1.15,
1.3,
1.25,
1.2,
1.15,
1.12,
1.09,
1.06,
1.03,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
0.9,
0.8,
0.7,
0.65,
0.6,
0.55,
0.52,
0.48,
0.47,
0.47,
0.49,
0.49,
0.49,
0.52,
0.51,
0.50
};
static const double standard_hue_adjustment[49] =
{
0.00,
0.05,
0.04,
0.01,
-0.03,
-0.10,
-0.18,
-0.26,
-0.35,
-0.43,
-0.40,
-0.32,
-0.25,
-0.18,
-0.10,
-0.07,
0.00,
-0.04,
-0.09,
-0.13,
-0.18,
-0.23,
-0.27,
-0.31,
-0.35,
-0.38,
-0.30,
-0.23,
-0.15,
-0.08,
0.00,
-0.02,
0.00,
0.08,
0.10,
0.08,
0.05,
0.03,
-0.03,
-0.12,
-0.20,
-0.17,
-0.20,
-0.17,
-0.15,
-0.12,
-0.10,
-0.08,
0.00,
};
static const double plain_paper_lum_adjustment[49] =
{
1.2,
1.22,
1.28,
1.34,
1.39,
1.42,
1.45,
1.48,
1.5,
1.4,
1.3,
1.25,
1.2,
1.1,
1.05,
1.05,
1.05,
1.05,
1.05,
1.05,
1.05,
1.05,
1.05,
1.05,
1.05,
1.05,
1.05,
1.1,
1.1,
1.1,
1.1,
1.1,
1.1,
1.15,
1.3,
1.45,
1.6,
1.75,
1.9,
2.0,
2.1,
2.0,
1.8,
1.7,
1.6,
1.5,
1.4,
1.3,
1.2
};
#define LEXMARK_INK_K 1
#define LEXMARK_INK_CMY 2
#define LEXMARK_INK_CMYK 4
#define LEXMARK_INK_CcMmYK 8
#define LEXMARK_INK_CcMmYy 16
#define LEXMARK_INK_CcMmYyK 32
#define LEXMARK_INK_BLACK_MASK (LEXMARK_INK_K|LEXMARK_INK_CMYK|\
LEXMARK_INK_CcMmYK|LEXMARK_INK_CcMmYyK)
#define LEXMARK_INK_PHOTO_MASK (LEXMARK_INK_CcMmYy|LEXMARK_INK_CcMmYK|\
LEXMARK_INK_CcMmYyK)
#define LEXMARK_SLOT_ASF1 1
#define LEXMARK_SLOT_ASF2 2
#define LEXMARK_SLOT_MAN1 4
#define LEXMARK_SLOT_MAN2 8
#define LEXMARK_CAP_DMT 1<<0
#define LEXMARK_CAP_MSB_FIRST 1<<1
#define LEXMARK_CAP_CMD61 1<<2
#define LEXMARK_CAP_CMD6d 1<<3
#define LEXMARK_CAP_CMD70 1<<4
#define LEXMARK_CAP_CMD72 1<<5
static const int lr_shift_color[10] = { 9, 18, 2*18 };
static const int lr_shift_black[10] = { 9, 18, 2*18 };
static int get_lr_shift(int mode)
{
const int *ptr_lr_shift;
if((mode & COLOR_MODE_K) == (mode & COLOR_MODE_MASK)) {
ptr_lr_shift = lr_shift_black;
} else {
ptr_lr_shift = lr_shift_color;
}
switch(mode & PRINT_MODE_MASK) {
case PRINT_MODE_300:
return ptr_lr_shift[0];
break;
case PRINT_MODE_600:
return ptr_lr_shift[1];
break;
case PRINT_MODE_1200:
return ptr_lr_shift[2];
break;
case PRINT_MODE_2400:
return ptr_lr_shift[2];
break;
}
return 0;
}
static const int head_offset_cmyk[] =
{70, 368, 184, 0, 368, 184, 0};
static const int head_offset_cmy[] =
{0, 368, 184, 0, 368, 184, 0};
static const int head_offset_cCmMyk[] =
{0, 368, 184, 0, 368, 184, 0};
typedef struct {
const char *name;
const char *text;
int hres;
int vres;
int softweave;
int vertical_passes;
int vertical_oversample;
int unidirectional;
int resid;
} lexmark_res_t;
#define LEXM_RES_COUNT 30
typedef lexmark_res_t lexmark_res_t_array[LEXM_RES_COUNT];
typedef struct {
unsigned int output_type;
int ncolors;
unsigned int used_colors;
unsigned int pass_length;
int v_top_head_offset;
int h_catridge_offset;
int h_direction_offset;
const int *head_offset;
} lexmark_inkparam_t;
typedef struct
{
const char *name;
const char *text;
lexmark_inkparam_t ink_parameter[4];
} lexmark_inkname_t;
typedef struct {
Lex_model model;
int max_paper_width;
int max_paper_height;
int min_paper_width;
int min_paper_height;
int max_xdpi;
int max_ydpi;
int max_quality;
int border_left;
int border_right;
int border_top;
int border_bottom;
int inks;
int slots;
int features;
int offset_left_border;
int offset_top_border;
int x_raster_res;
int y_raster_res;
const lexmark_res_t_array *res_parameters;
const lexmark_inkname_t *ink_types;
const double *lum_adjustment;
const double *hue_adjustment;
const double *sat_adjustment;
} lexmark_cap_t;
#define LX_Z52_300_DPI 1
#define LX_Z52_600_DPI 3
#define LX_Z52_1200_DPI 4
#define LX_Z52_2400_DPI 5
#define LX_Z52_COLOR_PRINT 0
#define LX_Z52_BLACK_PRINT 1
#define LX_PSHIFT 0x13
#define LX_Z52_COLOR_MODE_POS 0x9
#define LX_Z52_RESOLUTION_POS 0x7
#define LX_Z52_PRINT_DIRECTION_POS 0x8
static const int IDX_SEQLEN=3;
#define LXM_Z52_HEADERSIZE 34
static const unsigned char outbufHeader_z52[LXM_Z52_HEADERSIZE]=
{
0x1B,0x2A,0x24,0x00,0x00,0xFF,0xFF,
0x01,0x01,0x01,0x1a,0x03,0x01,
0x03,0x60,
0x04,0xe0,
0x19,0x5c,
0x0,0x0,
0x0,0x80,
0x0,0x0,0x0,0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x0
};
#define LXM_Z42_HEADERSIZE 34
static const unsigned char outbufHeader_z42[LXM_Z42_HEADERSIZE]=
{
0x1B,0x2A,0x24,0x00,0x00,0x00,0x00,
0x01,0x01,0x01,0x18,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00
};
static const lexmark_res_t_array lexmark_reslist_z52 =
{
{ "300x600dpi", N_ ("300 DPI x 600 DPI"), 300, 600, 0, 1, 1, 0, DPI300 },
{ "600dpi", N_ ("600 DPI"), 600, 600, 0, 1, 1, 0, DPI600 },
{ "600hq", N_ ("600 DPI high quality"), 600, 600, 1, 4, 1, 0, DPI600 },
{ "600uni", N_ ("600 DPI Unidirectional"), 600, 600, 0, 1, 1, 1, DPI600 },
{ "1200dpi", N_ ("1200 DPI"), 1200, 1200, 1, 1, 1, 0, DPI1200},
{ "1200hq", N_ ("1200 DPI high quality"), 1200, 1200, 1, 1, 1, 0, DPI300 },
{ "1200hq2", N_ ("1200 DPI highest quality"), 1200, 1200, 1, 1, 1, 0, DPI600 },
{ "1200uni", N_ ("1200 DPI Unidirectional"), 1200, 1200, 0, 1, 1, 1, DPI1200},
{ "2400x1200dpi", N_ ("2400 DPI x 1200 DPI"), 2400, 1200, 1, 1, 1, 0, DPI1200},
{ "2400x1200hq", N_ ("2400 DPI x 1200 DPI high quality"), 2400, 1200, 1, 1, 1, 0, DPI600 },
{ "2400x1200hq2", N_ ("2400 DPI x 1200 DPI highest quality"),2400, 1200, 1, 1, 1, 0, DPI300},
#ifdef DEBUG
{ "testprint", N_ ("test print"), 1200, 1200, 1, 1, 1, 0, DPItest},
#endif
{ "", "", 0, 0, 0, 0, 0, -1 }
};
static const lexmark_inkname_t ink_types_z52[] =
{
{ "CMYK", N_("Four Color Standard"),
{{ OUTPUT_GRAY, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ OUTPUT_COLOR, 4, COLOR_MODE_CMYK, 192/3, 0, 0, 10, head_offset_cmyk },
{ OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ OUTPUT_RAW_CMYK, 4, COLOR_MODE_CMYK, 192/3, 0, 0, 10, head_offset_cmyk }}},
{ "RGB", N_("Three Color Composite"),
{{ OUTPUT_GRAY, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ OUTPUT_COLOR, 4, COLOR_MODE_CMY, 192/3, 0, 0, 10, head_offset_cmy },
{ OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ OUTPUT_RAW_CMYK, 4, COLOR_MODE_CMY, 192/3, 0, 0, 10, head_offset_cmy }}},
{ "PhotoCMYK", N_("Six Color Photo"),
{{OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 192/3, 0, 0, 10, head_offset_cCmMyk },
{ OUTPUT_COLOR, 6, COLOR_MODE_CcMcYK, 192/3, 0, 0, 10, head_offset_cCmMyk },
{ OUTPUT_GRAY, 1, COLOR_MODE_K, 192/3, 0, 0, 10, head_offset_cCmMyk },
{ OUTPUT_RAW_CMYK, 6, COLOR_MODE_CcMcYK, 192/3, 0, 0, 10, head_offset_cCmMyk }}},
{ "PhotoCMY", N_("Five Color Photo Composite"),
{{ OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cCmMyk },
{ OUTPUT_COLOR, 5, COLOR_MODE_CcMcY, 192/3, 0, 0, 10, head_offset_cCmMyk },
{ OUTPUT_GRAY, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cCmMyk },
{ OUTPUT_RAW_CMYK, 5, COLOR_MODE_CcMcY, 192/3, 0, 0, 10, head_offset_cCmMyk }}},
{ "Gray", N_("Black"),
{{ OUTPUT_GRAY, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ OUTPUT_COLOR, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ OUTPUT_RAW_CMYK, 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk }}},
{ NULL, NULL }
};
#define LXM3200_LEFTOFFS 6254
#define LXM3200_RIGHTOFFS (LXM3200_LEFTOFFS-2120)
static int lxm3200_headpos = 0;
static int lxm3200_linetoeject = 0;
#define LXM_3200_HEADERSIZE 24
static const char outbufHeader_3200[LXM_3200_HEADERSIZE] =
{
0x1b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static inline int
lexmark_calc_3200_checksum(unsigned char *data)
{
int ck, i;
ck = 0;
for(i=1; i<7; i++)ck += data[i];
return(ck & 255);
}
static const lexmark_res_t_array lexmark_reslist_3200 =
{
{ "300x600dpi", N_ ("300 DPI x 600 DPI"), 300, 600, 0, 1, 1, 0, DPI300 },
{ "600dpi", N_ ("600 DPI"), 600, 600, 0, 1, 1, 0, DPI600 },
{ "600hq", N_ ("600 DPI high quality"), 600, 600, 1, 4, 1, 0, DPI600 },
{ "600uni", N_ ("600 DPI Unidirectional"), 600, 600, 0, 1, 1, 1, DPI600 },
{ "1200dpi", N_ ("1200 DPI"), 1200, 1200, 1, 1, 1, 0, DPI1200},
{ "1200hq", N_ ("1200 DPI high quality"), 1200, 1200, 1, 1, 1, 0, DPI300 },
{ "1200hq2", N_ ("1200 DPI highest quality"), 1200, 1200, 1, 1, 1, 0, DPI600 },
{ "1200uni", N_ ("1200 DPI Unidirectional"), 1200, 1200, 0, 1, 1, 1, DPI1200},
{ "", "", 0, 0, 0, 0, 0, -1 }
};
static const lexmark_inkname_t ink_types_3200[] =
{
{ "CMYK", N_("Four Color Standard"),
{{ OUTPUT_GRAY, 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cmyk },
{ OUTPUT_COLOR, 4, COLOR_MODE_CMYK, 192/3, 0, 0, 12, head_offset_cmyk },
{ OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cmyk },
{ OUTPUT_RAW_CMYK, 4, COLOR_MODE_CMYK, 192/3, 0, 0, 12, head_offset_cmyk }}},
{ "RGB", N_("Three Color Composite"),
{{ OUTPUT_GRAY, 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cmyk },
{ OUTPUT_COLOR, 4, COLOR_MODE_CMY, 192/3, 0, 0, 12, head_offset_cmy },
{ OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cmyk },
{ OUTPUT_RAW_CMYK, 4, COLOR_MODE_CMY, 192/3, 0, 0, 12, head_offset_cmy }}},
{ "PhotoCMYK", N_("Six Color Photo"),
{{OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 192/3, 0, 0, 12, head_offset_cCmMyk },
{ OUTPUT_COLOR, 6, COLOR_MODE_CcMcYK, 192/3, 0, 0, 12, head_offset_cCmMyk },
{ OUTPUT_GRAY, 1, COLOR_MODE_K, 192/3, 0, 0, 12, head_offset_cCmMyk },
{ OUTPUT_RAW_CMYK, 6, COLOR_MODE_CcMcYK, 192/3, 0, 0, 12, head_offset_cCmMyk }}},
{ "PhotoCMY", N_("Five Color Photo Composite"),
{{ OUTPUT_MONOCHROME, 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cCmMyk },
{ OUTPUT_COLOR, 5, COLOR_MODE_CcMcY, 192/3, 0, 0, 12, head_offset_cCmMyk },
{ OUTPUT_GRAY, 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cCmMyk },
{ OUTPUT_RAW_CMYK, 5, COLOR_MODE_CcMcY, 192/3, 0, 0, 12, head_offset_cCmMyk }}},
{ NULL, NULL }
};
static const lexmark_cap_t lexmark_model_capabilities[] =
{
{ (Lex_model)-1, 8*72,11*72,180,180,20,20,20,20, LEXMARK_INK_K, LEXMARK_SLOT_ASF1, 0 },
{
m_z52,
618, 936,
INCH(2), INCH(4),
2400, 1200, 2,
0, 0, 5, 15,
LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
LEXMARK_CAP_DMT,
20,
123,
2400,
1200,
&lexmark_reslist_z52,
ink_types_z52,
standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
},
{
m_z42,
618, 936,
INCH(2), INCH(4),
2400, 1200, 2,
0, 0, 5, 41,
LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
LEXMARK_CAP_DMT,
20,
123,
2400,
1200,
&lexmark_reslist_z52,
ink_types_z52,
standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
},
{
m_3200,
618, 936,
INCH(2), INCH(4),
1200, 1200, 2,
11, 9, 10, 18,
LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
LEXMARK_CAP_DMT,
0,
300,
1200,
1200,
&lexmark_reslist_3200,
ink_types_3200,
standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
},
{
m_lex7500,
618, 936,
INCH(2), INCH(4),
2400, 1200, 2,
11, 9, 10, 18,
LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
LEXMARK_CAP_DMT,
0,
300,
1200,
1200,
&lexmark_reslist_3200,
ink_types_3200,
standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
},
};
typedef struct lexm_privdata_weave {
const lexmark_inkparam_t *ink_parameter;
int bidirectional;
int direction;
unsigned char *outbuf;
} lexm_privdata_weave;
static int model_to_index(int model)
{
int i;
int models= sizeof(lexmark_model_capabilities) / sizeof(lexmark_cap_t);
for (i=0; i<models; i++) {
if (lexmark_model_capabilities[i].model == model) {
return i;
}
}
return -1;
}
static const lexmark_cap_t *
lexmark_get_model_capabilities(int model)
{
int i = model_to_index(model);
if (i != -1) {
return &(lexmark_model_capabilities[i]);
}
#ifdef DEBUG
stp_erprintf("lexmark: model %d not found in capabilities list.\n",model);
#endif
return &(lexmark_model_capabilities[0]);
}
typedef struct
{
const char *name;
const char *text;
int paper_feed_sequence;
int platen_gap;
double base_density;
double k_lower_scale;
double k_upper;
double cyan;
double magenta;
double yellow;
double p_cyan;
double p_magenta;
double p_yellow;
double saturation;
double gamma;
int feed_adjustment;
int vacuum_intensity;
int paper_thickness;
const double *hue_adjustment;
const double *lum_adjustment;
const double *sat_adjustment;
} paper_t;
static const paper_t lexmark_paper_list[] =
{
{ "Plain", N_("Plain Paper"),
1, 0, 0.80, .1, .5, 1.0, 1.0, 1.0, .9, 1.05, 1.15,
1, 1.0, 0x6b, 0x1a, 0x01, NULL, plain_paper_lum_adjustment, NULL},
{ "GlossyFilm", N_("Glossy Film"),
3, 0, 1.00 ,1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6d, 0x00, 0x01, NULL, plain_paper_lum_adjustment, NULL},
{ "Transparency", N_("Transparencies"),
3, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 0x6d, 0x00, 0x02, NULL, plain_paper_lum_adjustment, NULL},
{ "Envelope", N_("Envelopes"),
4, 0, 0.80, .125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6b, 0x1a, 0x01, NULL, plain_paper_lum_adjustment, NULL},
{ "Matte", N_("Matte Paper"),
7, 0, 0.85, 1.0, .999, 1.05, .9, 1.05, .9, 1.0, 1.1,
1, 1.0, 0x00, 0x00, 0x02, NULL, NULL, NULL},
{ "Inkjet", N_("Inkjet Paper"),
7, 0, 0.85, .25, .6, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6b, 0x1a, 0x01, NULL, plain_paper_lum_adjustment, NULL},
{ "Coated", N_("Photo Quality Inkjet Paper"),
7, 0, 1.00, 1.0, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6b, 0x1a, 0x01, NULL, NULL, NULL},
{ "Photo", N_("Photo Paper"),
8, 0, 1.00, 1.0, .9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x67, 0x00, 0x02, NULL, NULL, NULL},
{ "GlossyPhoto", N_("Premium Glossy Photo Paper"),
8, 0, 1.10, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.03, 1.0,
1, 1.0, 0x80, 0x00, 0x02, NULL, NULL, NULL},
{ "Luster", N_("Premium Luster Photo Paper"),
8, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 0x80, 0x00, 0x02, NULL, NULL, NULL},
{ "GlossyPaper", N_("Photo Quality Glossy Paper"),
6, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 0x6b, 0x1a, 0x01, NULL, NULL, NULL},
{ "Ilford", N_("Ilford Heavy Paper"),
8, 0, .85, .5, 1.35, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x80, 0x00, 0x02, NULL, NULL, NULL },
{ "Other", N_("Other"),
0, 0, 0.80, 0.125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6b, 0x1a, 0x01, NULL, plain_paper_lum_adjustment, NULL},
};
static const int paper_type_count = sizeof(lexmark_paper_list) / sizeof(paper_t);
static const lexmark_inkname_t *
lexmark_get_ink_type(const char *name, int output_type, const lexmark_cap_t * caps)
{
int i;
const lexmark_inkname_t *ink_type = caps->ink_types;
for (i=0; ((ink_type[i].name != NULL) &&
(strcmp(name, ink_type[i].name) != 0)); i++) ;
return &(ink_type[i]);
}
static const lexmark_inkparam_t *
lexmark_get_ink_parameter(const char *name, int output_type, const lexmark_cap_t * caps, stp_vars_t nv)
{
int i;
const lexmark_inkname_t *ink_type = lexmark_get_ink_type(name, output_type, caps);
if (ink_type->name == NULL) {
return (NULL);
}
for (i=0; (ink_type->ink_parameter[i].output_type != output_type); i++) ;
return &(ink_type->ink_parameter[i]);
}
static const paper_t *
get_media_type(const char *name, const lexmark_cap_t * caps)
{
int i;
for (i = 0; i < paper_type_count; i++)
{
if (!strcmp(name, lexmark_paper_list[i].name))
return &(lexmark_paper_list[i]);
}
return NULL;
}
static int
lexmark_source_type(const char *name, const lexmark_cap_t * caps)
{
if (!strcmp(name,"Auto")) return 4;
if (!strcmp(name,"Manual")) return 0;
if (!strcmp(name,"ManualNP")) return 1;
#ifdef DEBUG
stp_erprintf("lexmark: Unknown source type '%s' - reverting to auto\n",name);
#endif
return 4;
}
static const lexmark_lineoff_t *
lexmark_head_offset(int ydpi,
const char *ink_type,
const lexmark_cap_t * caps,
const lexmark_inkparam_t *ink_parameter,
lexmark_lineoff_t *lineoff_buffer)
{
int i;
#ifdef DEBUG
stp_erprintf(" sizie %d, size_v %d, size_v[0] %d\n", sizeof(*lineoff_buffer), sizeof(lineoff_buffer->v), sizeof(lineoff_buffer->v[0]));
#endif
memcpy(lineoff_buffer, ink_parameter->head_offset, sizeof(*lineoff_buffer));
for (i=0; i < (sizeof(lineoff_buffer->v) / sizeof(lineoff_buffer->v[0])); i++) {
lineoff_buffer->v[i] /= (caps->y_raster_res / ydpi);
}
return (lineoff_buffer);
}
#if 0
static unsigned char
lexmark_size_type(const stp_vars_t v, const lexmark_cap_t * caps)
{
const stp_papersize_t pp = stp_get_papersize_by_size(stp_get_page_height(v),
stp_get_page_width(v));
if (pp)
{
const char *name = stp_papersize_get_name(pp);
if (!strcmp(name,"A5")) return 0x01;
if (!strcmp(name,"A4")) return 0x03;
if (!strcmp(name,"B5")) return 0x08;
if (!strcmp(name,"Letter")) return 0x0d;
if (!strcmp(name,"Legal")) return 0x0f;
if (!strcmp(name,"COM10")) return 0x16;
if (!strcmp(name,"DL")) return 0x17;
if (!strcmp(name,"LetterExtra")) return 0x2a;
if (!strcmp(name,"A4Extra")) return 0x2b;
if (!strcmp(name,"w288h144")) return 0x2d;
#ifdef DEBUG
stp_erprintf("lexmark: Unknown paper size '%s' - using custom\n",name);
} else {
stp_erprintf("lexmark: Couldn't look up paper size %dx%d - "
"using custom\n",stp_get_page_height(v), stp_get_page_width(v));
#endif
}
return 0;
}
#endif
static int lexmark_get_phys_resolution_vertical(const stp_printer_t printer)
{
return 600;
}
#if 0
static int lexmark_get_phys_resolution_horizontal(const stp_printer_t printer)
{
return 1200;
}
#endif
static char *
c_strdup(const char *s)
{
char *ret = stp_malloc(strlen(s) + 1);
strcpy(ret, s);
return ret;
}
static const lexmark_res_t
*lexmark_get_resolution_para(const stp_printer_t printer,
const char *resolution)
{
const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_printer_get_model(printer));
const lexmark_res_t *res = *(caps->res_parameters);
while (res->hres)
{
if ((res->vres <= caps->max_ydpi) && (caps->max_ydpi != -1) &&
(res->hres <= caps->max_xdpi) && (caps->max_xdpi != -1) &&
(!strcmp(resolution, res->name)))
{
return res;
}
res++;
}
stp_erprintf("lexmark_get_resolution_para: resolution not found (%s)\n", resolution);
return NULL;
}
static int
lexmark_print_bidirectional(const stp_printer_t printer,
const char *resolution)
{
const lexmark_res_t *res_para = lexmark_get_resolution_para(printer, resolution);
return !res_para->unidirectional;
}
static const double *
lexmark_lum_adjustment(const lexmark_cap_t * caps, const stp_vars_t v)
{
return (caps->lum_adjustment);
}
static const double *
lexmark_hue_adjustment(const lexmark_cap_t * caps, const stp_vars_t v)
{
return (caps->hue_adjustment);
}
static const double *
lexmark_sat_adjustment(const lexmark_cap_t * caps, const stp_vars_t v)
{
return (caps->sat_adjustment);
}
static void
lexmark_describe_resolution(const stp_printer_t printer,
const char *resolution, int *x, int *y)
{
const lexmark_res_t *res = lexmark_get_resolution_para(printer, resolution);
if (res)
{
*x = res->hres;
*y = res->vres;
return;
}
*x = -1;
*y = -1;
}
static stp_param_t media_sources[] =
{
{ "Auto", N_("Auto Sheet Feeder") },
{ "Manual", N_("Manual with Pause") },
{ "ManualNP", N_("Manual without Pause") }
};
static stp_param_t *
lexmark_parameters(const stp_printer_t printer,
const char *ppd_file,
const char *name,
int *count)
{
int i;
stp_param_t *p= 0;
stp_param_t *valptrs= 0;
const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_printer_get_model(printer));
if (count == NULL)
return (NULL);
*count = 0;
if (name == NULL)
return (NULL);
if (strcmp(name, "PageSize") == 0)
{
unsigned int height_limit, width_limit;
unsigned int min_height_limit, min_width_limit;
int papersizes = stp_known_papersizes();
valptrs = stp_zalloc(sizeof(stp_param_t) * papersizes);
*count = 0;
width_limit = caps->max_paper_width;
height_limit = caps->max_paper_height;
min_width_limit = caps->min_paper_width;
min_height_limit = caps->min_paper_height;
for (i = 0; i < papersizes; i++) {
const stp_papersize_t pt = stp_get_papersize_by_index(i);
unsigned int pwidth = stp_papersize_get_width(pt);
unsigned int pheight = stp_papersize_get_height(pt);
if (strlen(stp_papersize_get_name(pt)) > 0 &&
pwidth <= width_limit && pheight <= height_limit &&
(pheight >= min_height_limit || pheight == 0) &&
(pwidth >= min_width_limit || pwidth == 0))
{
valptrs[*count].name = c_strdup(stp_papersize_get_name(pt));
valptrs[*count].text = c_strdup(stp_papersize_get_text(pt));
(*count)++;
}
}
return (valptrs);
}
else if (strcmp(name, "Resolution") == 0)
{
int c= 0;
const lexmark_res_t *res;
res = *(caps->res_parameters);
for (i=0; res[i].hres; i++);
valptrs = stp_zalloc(sizeof(stp_param_t) * i);
while (res->hres)
{
valptrs[c].name = c_strdup(res->name);
valptrs[c++].text = c_strdup(_(res->text));
res++;
}
*count= c;
return (valptrs);
}
else if (strcmp(name, "InkType") == 0)
{
for (i = 0; caps->ink_types[i].name != NULL; i++);
valptrs = stp_zalloc(sizeof(stp_param_t) * i);
*count = 0;
for (i = 0; caps->ink_types[i].name != NULL; i++)
{
valptrs[*count].name = c_strdup(caps->ink_types[i].name);
valptrs[*count].text = c_strdup(_(caps->ink_types[i].text));
(*count)++;
}
return valptrs;
}
else if (strcmp(name, "MediaType") == 0)
{
int nmediatypes = paper_type_count;
valptrs = stp_zalloc(sizeof(stp_param_t) * nmediatypes);
for (i = 0; i < nmediatypes; i++)
{
valptrs[i].name = c_strdup(lexmark_paper_list[i].name);
valptrs[i].text = c_strdup(_(lexmark_paper_list[i].text));
}
*count = nmediatypes;
return valptrs;
}
else if (strcmp(name, "InputSlot") == 0)
{
*count = 3;
p = media_sources;
}
else
return (NULL);
valptrs = stp_zalloc(*count * sizeof(stp_param_t));
for (i = 0; i < *count; i ++)
{
valptrs[i].name = c_strdup(p[i].name);
valptrs[i].text = c_strdup(_(p[i].text));
}
return (valptrs);
}
static const char *
lexmark_default_parameters(const stp_printer_t printer,
const char *ppd_file,
const char *name)
{
int i;
const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_printer_get_model(printer));
if (name == NULL)
return (NULL);
if (strcmp(name, "PageSize") == 0)
{
unsigned int height_limit, width_limit;
unsigned int min_height_limit, min_width_limit;
int papersizes = stp_known_papersizes();
width_limit = caps->max_paper_width;
height_limit = caps->max_paper_height;
min_width_limit = caps->min_paper_width;
min_height_limit = caps->min_paper_height;
for (i = 0; i < papersizes; i++)
{
const stp_papersize_t pt = stp_get_papersize_by_index(i);
if (strlen(stp_papersize_get_name(pt)) > 0 &&
stp_papersize_get_width(pt) >= min_width_limit &&
stp_papersize_get_height(pt) >= min_height_limit &&
stp_papersize_get_width(pt) <= width_limit &&
stp_papersize_get_height(pt) <= height_limit)
{
return (stp_papersize_get_name(pt));
}
}
return NULL;
}
else if (strcmp(name, "Resolution") == 0)
{
const lexmark_res_t *res = NULL;
res = *(caps->res_parameters);
if (res->hres)
{
return (res->name);
}
return NULL;
}
else if (strcmp(name, "InkType") == 0)
{
return (caps->ink_types[0].name);
}
else if (strcmp(name, "MediaType") == 0)
{
return (lexmark_paper_list[0].name);
}
else if (strcmp(name, "InputSlot") == 0)
{
return (media_sources[0].name);
}
else
return (NULL);
}
static void
lexmark_imageable_area(const stp_printer_t printer,
const stp_vars_t v,
int *left,
int *right,
int *bottom,
int *top)
{
int width, length;
const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_printer_get_model(printer));
stp_default_media_size(printer, v, &width, &length);
*left = caps->border_left;
*right = width - caps->border_right;
*top = length - caps->border_top;
*bottom = caps->border_bottom;
lxm3200_linetoeject = (length * 1200) / 72;
}
static void
lexmark_limit(const stp_printer_t printer,
const stp_vars_t v,
int *width,
int *height,
int *min_width,
int *min_height)
{
const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_printer_get_model(printer));
*width = caps->max_paper_width;
*height = caps->max_paper_height;
*min_width = caps->min_paper_width;
*min_height = caps->min_paper_height;
}
static int
lexmark_init_printer(const stp_vars_t v, const lexmark_cap_t * caps,
int output_type,
const char *source_str,
int xdpi, int ydpi,
int page_width, int page_height,
int top, int left,
int use_dmt)
{
#define LXM_Z52_STARTSIZE 0x35
unsigned char startHeader_z52[LXM_Z52_STARTSIZE]={0x1b,0x2a,0x81,0x00,0x1c,0x56,0x49,0x00,
0x01,0x00,0x2c,0x01,0x00,0x00,0x60,0x09,
0xe4,0x0c,0x01,0x00,0x34,0x00,0x00,0x00,
0x08,0x00,0x08,0x00,0x1b,0x2a,0x07,0x76,
0x01,0x1b,0x2a,0x07,0x73,0x30,0x1b,0x2a,
0x6d,0x00,0x14,0x01,0xf4,0x02,0x00,0x01,
0xf0,0x1b,0x2a,0x07,0x63};
#define LXM_Z42_STARTSIZE 0x30
unsigned char startHeader_z42[LXM_Z42_STARTSIZE]={0x1B,0x2A,0x81,0x00,0x1C,0x50,0x41,0x00,
0x01,0x00,0x58,0x02,0x04,0x00,0xC0,0x12,
0xC8,0x19,0x02,0x00,0x50,0x00,0x14,0x00,
0x07,0x00,0x08,0x00,0x1B,0x2A,0x07,0x73,
0x30,0x1B,0x2A,0x6D,0x00,0x14,0x01,0xC0,
0x02,0x00,0x01,0xBE,0x1B,0x2A,0x07,0x63};
#define ESC2a "\033\052"
#define LXM_3200_STARTSIZE 32
unsigned char startHeader_3200[LXM_3200_STARTSIZE] =
{
0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x1b, 0x30, 0x80, 0x0C, 0x02, 0x00, 0x00, 0xbe,
0x1b, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21
};
switch(caps->model)
{
case m_z52:
stp_zfwrite((const char *) startHeader_z52,
LXM_Z52_STARTSIZE,1,v);
#ifdef DEBUG
lex_write_tmp_file(dbgfileprn, (void *)startHeader_z52, LXM_Z52_STARTSIZE);
#endif
case m_z42:
stp_zfwrite((const char *) startHeader_z42,
LXM_Z42_STARTSIZE,1,v);
#ifdef DEBUG
lex_write_tmp_file(dbgfileprn, (void *)startHeader_z42, LXM_Z42_STARTSIZE);
#endif
break;
case m_3200:
stp_zfwrite((const char *) startHeader_3200,
LXM_3200_STARTSIZE, 1, v);
break;
default:
stp_erprintf("Unknown printer !! %i\n", caps->model);
return 0;
}
return 1;
}
static void lexmark_deinit_printer(const stp_vars_t v, const lexmark_cap_t * caps)
{
switch(caps->model) {
case m_z52:
{
char buffer[40];
memcpy(buffer, ESC2a, 2);
buffer[2] = 0x7;
buffer[3] = 0x65;
#ifdef DEBUG
stp_erprintf("lexmark: <<eject page.>> %x %x %x %x %lx\n", buffer[0], buffer[1], buffer[2], buffer[3], dbgfileprn);
lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 4);
#endif
stp_zfwrite(buffer, 1, 4, v);
}
break;
case m_z42:
{
unsigned char buffer[12] = {0x1B,0x2A,0x07,0x65,0x1B,0x2A,0x82,0x00,0x00,0x00,0x00,0xAC};
#ifdef DEBUG
stp_erprintf("lexmark: <<eject page.>>\n");
lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 12);
#endif
stp_zfwrite((char *)buffer, 1, 12, v);
}
break;
case m_3200:
{
unsigned char buffer[24] =
{
0x1b, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x31, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x33, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33
};
#ifdef DEBUG
stp_erprintf("Headpos: %d\n", lxm3200_headpos);
#endif
lxm3200_linetoeject += 2400;
buffer[3] = lxm3200_linetoeject >> 8;
buffer[4] = lxm3200_linetoeject & 0xff;
buffer[7] = lexmark_calc_3200_checksum(&buffer[0]);
buffer[11] = lxm3200_headpos >> 8;
buffer[12] = lxm3200_headpos & 0xff;
buffer[15] = lexmark_calc_3200_checksum(&buffer[8]);
stp_zfwrite((const char *)buffer, 24, 1, v);
}
break;
case m_lex7500:
break;
}
}
static void paper_shift(const stp_vars_t v, int offset, const lexmark_cap_t * caps)
{
switch(caps->model) {
case m_z52:
case m_z42:
{
unsigned char buf[5] = {0x1b, 0x2a, 0x3, 0x0, 0x0};
if(offset == 0)return;
buf[3] = (unsigned char)(offset >> 8);
buf[4] = (unsigned char)(offset & 0xFF);
stp_zfwrite((const char *)buf, 1, 5, v);
#ifdef DEBUG
lex_write_tmp_file(dbgfileprn, (void *)buf, 5);
#endif
}
break;
case m_3200:
{
unsigned char buf[8] = {0x1b, 0x23, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00};
if(offset == 0)return;
lxm3200_linetoeject -= offset;
buf[3] = (unsigned char)(offset >> 8);
buf[4] = (unsigned char)(offset & 0xff);
buf[7] = lexmark_calc_3200_checksum(buf);
stp_zfwrite((const char *)buf, 1, 8, v);
}
break;
case m_lex7500:
break;
}
#ifdef DEBUG
stp_erprintf("Lines to eject: %d\n", lxm3200_linetoeject);
#endif
}
#if 0
static void
lexmark_advance_buffer(unsigned char *buf, int len, int num)
{
if (!buf || !len) return;
if (num>0) memmove(buf+len,buf,len*num);
memset(buf,0,len);
}
#endif
static int
clean_color(unsigned char *line, int len)
{
return 0;
}
static void
lexmark_print(const stp_printer_t printer,
stp_image_t *image,
const stp_vars_t v)
{
int i;
int y;
int xdpi, ydpi;
int n;
unsigned short *out;
unsigned char *in;
int page_left,
page_right,
page_top,
page_bottom,
page_width,
page_height,
page_true_height,
out_width,
out_height,
out_bpp,
length,
buf_length,
errdiv,
errmod,
errval,
errline,
errlast;
stp_convert_t colorfunc = 0;
int zero_mask;
int image_height,
image_width,
image_bpp;
int use_dmt = 0;
void * dither;
int pass_length=0;
int add_top_offset=0;
int printMode = 0;
int source;
double densityDivisor;
double k_lower, k_upper;
int physical_xdpi = 0;
int physical_ydpi = 0;
double lum_adjustment[49], sat_adjustment[49], hue_adjustment[49];
lexmark_linebufs_t cols;
int nozzle_separation;
int horizontal_passes;
int ncolors;
lexm_privdata_weave privdata;
void * weave = NULL;
stp_dither_data_t *dt;
lexmark_lineoff_t lineoff_buffer;
int doTestPrint = 0;
#ifdef DEBUG
testdata td;
#endif
const unsigned char *cmap = stp_get_cmap(v);
int model = stp_printer_get_model(printer);
const char *resolution = stp_get_resolution(v);
const char *media_type = stp_get_media_type(v);
const char *media_source = stp_get_media_source(v);
int output_type = stp_get_output_type(v);
int orientation = stp_get_orientation(v);
const char *ink_type = stp_get_ink_type(v);
double scaling = stp_get_scaling(v);
int top = stp_get_top(v);
int left = stp_get_left(v);
stp_vars_t nv = stp_allocate_copy(v);
const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
const lexmark_res_t *res_para_ptr = lexmark_get_resolution_para(printer, resolution);
const paper_t *media = get_media_type(media_type,caps);
const lexmark_inkparam_t *ink_parameter = lexmark_get_ink_parameter(ink_type, output_type, caps, nv);
#ifdef DEBUG
dbgfileprn = lex_open_tmp_file();
#endif
if (ink_parameter == NULL)
{
stp_eprintf(nv, "Illegal Ink Type specified; cannot print.\n");
return;
}
if (!stp_get_verified(nv))
{
stp_eprintf(nv, "Print options not verified; cannot print.\n");
return;
}
image->init(image);
image_height = image->height(image);
image_width = image->width(image);
image_bpp = image->bpp(image);
source= lexmark_source_type(media_source,caps);
if ((ink_parameter->used_colors == COLOR_MODE_K) ||
((caps->inks == LEXMARK_INK_K) &&
output_type != OUTPUT_MONOCHROME))
{
output_type = OUTPUT_GRAY;
stp_set_output_type(nv, OUTPUT_GRAY);
}
stp_set_output_color_model(nv, COLOR_MODEL_CMY);
colorfunc = stp_choose_colorfunc(output_type, image_bpp, cmap, &out_bpp, nv);
ncolors = ink_parameter->ncolors;
printMode = ink_parameter->used_colors;
pass_length = ink_parameter->pass_length;
add_top_offset = ink_parameter->v_top_head_offset;
lexmark_describe_resolution(printer,
resolution, &xdpi,&ydpi);
#ifdef DEBUG
stp_erprintf("lexmark: resolution=%dx%d\n",xdpi,ydpi);
#endif
switch (res_para_ptr->resid) {
case DPI300:
physical_xdpi = 300;
physical_ydpi = lexmark_get_phys_resolution_vertical(printer);
break;
case DPI600:
physical_xdpi = 600;
physical_ydpi = lexmark_get_phys_resolution_vertical(printer);
break;
case DPI1200:
case DPItest:
physical_xdpi = 1200;
physical_ydpi = lexmark_get_phys_resolution_vertical(printer);
break;
default:
return;
break;
}
densityDivisor = ((xdpi / 300)*(ydpi/ 600));
#ifdef DEBUG
if (res_para_ptr->resid == DPItest) {
stp_erprintf("Start test print1\n");
doTestPrint = 1;
}
#endif
if ((printMode & COLOR_MODE_PHOTO) == COLOR_MODE_PHOTO) {
densityDivisor /= 1.2;
}
nozzle_separation = ydpi / physical_ydpi;
horizontal_passes = xdpi / physical_xdpi;
#ifdef DEBUG
stp_erprintf("lexmark: horizontal_passes %i, xdpi %i, physical_xdpi %i\n",
horizontal_passes, xdpi, physical_xdpi);
#endif
if (!strcmp(resolution+(strlen(resolution)-3),"DMT") &&
(caps->features & LEXMARK_CAP_DMT) &&
stp_get_output_type(nv) != OUTPUT_MONOCHROME &&
output_type != OUTPUT_MONOCHROME) {
use_dmt= 1;
#ifdef DEBUG
stp_erprintf("lexmark: using drop modulation technology\n");
#endif
}
lexmark_imageable_area(printer, nv, &page_left, &page_right,
&page_bottom, &page_top);
stp_compute_page_parameters(page_right, page_left, page_top, page_bottom,
scaling, image_width, image_height, image,
&orientation, &page_width, &page_height,
&out_width, &out_height, &left, &top);
#ifdef DEBUG
stp_erprintf("page_right %d, page_left %d, page_top %d, page_bottom %d, left %d, top %d\n",page_right, page_left, page_top, page_bottom,left, top);
#endif
image_height = image->height(image);
image_width = image->width(image);
stp_default_media_size(printer, nv, &n, &page_true_height);
image->progress_init(image);
if (!lexmark_init_printer(nv, caps, output_type,
media_source,
xdpi, ydpi, page_width, page_height,
top,left,use_dmt))
return;
out_width = xdpi * out_width / 72;
out_height = ydpi * out_height / 72;
#ifdef DEBUG
stp_erprintf("border: left %ld, x_raster_res %d, offser_left %ld\n", left, caps->x_raster_res, caps->offset_left_border);
#endif
left = ((caps->x_raster_res * left) / 72) + caps->offset_left_border;
#ifdef DEBUG
stp_erprintf("border: left %d\n", left);
#endif
#ifdef DEBUG
if (doTestPrint == 1) {
stp_erprintf("Start test print\n");
testprint(&td);
out_width = td.x;
out_height = td.y;
if (td.cols != 7) {
printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y;
} else {
printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_LM | COLOR_MODE_LC;
}
}
#endif
length = (out_width + 7) / 8;
if (use_dmt) {
buf_length= length;
} else {
buf_length= length;
}
#ifdef DEBUG
stp_erprintf("lexmark: buflength is %d!\n",buf_length);
#endif
cols.p.k = NULL;
cols.p.c = NULL;
cols.p.y = NULL;
cols.p.m = NULL;
cols.p.C = NULL;
cols.p.M = NULL;
cols.p.Y = NULL;
if ((printMode & COLOR_MODE_C) == COLOR_MODE_C) {
cols.p.c = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_Y) == COLOR_MODE_Y) {
cols.p.y = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_M) == COLOR_MODE_M) {
cols.p.m = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_K) == COLOR_MODE_K) {
cols.p.k = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_LC) == COLOR_MODE_LC) {
cols.p.C = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_LY) == COLOR_MODE_LY) {
cols.p.Y = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_LM) == COLOR_MODE_LM) {
cols.p.M = stp_zalloc(buf_length+10);
}
#ifdef DEBUG
stp_erprintf("lexmark: driver will use colors ");
if (cols.p.c) stp_erputc('c');
if (cols.p.C) stp_erputc('C');
if (cols.p.m) stp_erputc('m');
if (cols.p.M) stp_erputc('M');
if (cols.p.y) stp_erputc('y');
if (cols.p.Y) stp_erputc('Y');
if (cols.p.k) stp_erputc('k');
stp_erprintf("\n");
#endif
privdata.ink_parameter = ink_parameter;
privdata.bidirectional = lexmark_print_bidirectional(printer, resolution);
privdata.outbuf = stp_malloc((((((pass_length/8)*11))+40) * out_width)+2000);
stp_set_driver_data(nv, &privdata);
weave = stp_initialize_weave(pass_length,
nozzle_separation,
horizontal_passes,
res_para_ptr->vertical_passes,
res_para_ptr->vertical_oversample,
ncolors,
1,
out_width,
out_height,
((top * ydpi) / 72)+(((caps->offset_top_border+add_top_offset)*ydpi)
/caps->y_raster_res),
(page_height * ydpi) / 72,
1,
(int *)lexmark_head_offset(ydpi, ink_type, caps, ink_parameter, &lineoff_buffer),
nv, flush_pass,
stp_fill_uncompressed,
stp_pack_uncompressed,
stp_compute_uncompressed_linewidth);
#ifdef DEBUG
stp_erprintf("density is %f\n",stp_get_density(nv));
#endif
#ifdef DEBUG
stp_erprintf("density is %f and will be changed to %f (%f)\n",stp_get_density(nv), stp_get_density(nv)/densityDivisor, densityDivisor);
#endif
stp_set_density(nv, stp_get_density(nv) / densityDivisor);
if (ncolors > 4)
k_lower = .5;
else
k_lower = .25;
if (media)
{
stp_set_density(nv, stp_get_density(nv) * media->base_density);
stp_set_cyan(nv, stp_get_cyan(nv) * media->p_cyan);
stp_set_magenta(nv, stp_get_magenta(nv) * media->p_magenta);
stp_set_yellow(nv, stp_get_yellow(nv) * media->p_yellow);
k_lower *= media->k_lower_scale;
k_upper = media->k_upper;
}
else
{
stp_set_density(nv, stp_get_density(nv) * .8);
k_lower *= .1;
k_upper = .5;
}
if (stp_get_density(nv) > 1.0)
stp_set_density(nv, 1.0);
stp_compute_lut(nv, 256);
#ifdef DEBUG
stp_erprintf("density is %f\n",stp_get_density(nv));
#endif
if (xdpi > ydpi)
dither = stp_init_dither(image_width, out_width, 1, xdpi / ydpi, nv);
else
dither = stp_init_dither(image_width, out_width, ydpi / xdpi, 1, nv);
for (i = 0; i <= NCOLORS; i++)
stp_dither_set_black_level(dither, i, 1.0);
stp_dither_set_black_lower(dither, k_lower);
stp_dither_set_black_upper(dither, k_upper);
stp_dither_set_black_upper(dither, .8);
if (!use_dmt) {
if (cols.p.C)
stp_dither_set_light_ink(dither, ECOLOR_C, .3333, stp_get_density(nv));
if (cols.p.M)
stp_dither_set_light_ink(dither, ECOLOR_M, .3333, stp_get_density(nv));
if (cols.p.Y)
stp_dither_set_light_ink(dither, ECOLOR_Y, .3333, stp_get_density(nv));
}
switch (stp_get_image_type(nv))
{
case IMAGE_LINE_ART:
stp_dither_set_ink_spread(dither, 19);
break;
case IMAGE_SOLID_TONE:
stp_dither_set_ink_spread(dither, 15);
break;
case IMAGE_CONTINUOUS:
stp_dither_set_ink_spread(dither, 14);
break;
}
stp_dither_set_density(dither, stp_get_density(nv));
in = stp_malloc(image_width * image_bpp);
out = stp_malloc(image_width * out_bpp * 2);
#ifdef DEBUG
stp_erprintf("---------- buffer mem size = %d\n", (((((pass_length/8)*11)/10)+40) * out_width)+200);
#endif
errdiv = image_height / out_height;
errmod = image_height % out_height;
errval = 0;
errlast = -1;
errline = 0;
if (lexmark_lum_adjustment(caps, nv))
{
for (i = 0; i < 49; i++)
{
lum_adjustment[i] = lexmark_lum_adjustment(caps, nv)[i];
if (media && media->lum_adjustment) {
lum_adjustment[i] *= media->lum_adjustment[i];
}
}
}
if (lexmark_sat_adjustment(caps, nv))
{
for (i = 0; i < 49; i++)
{
sat_adjustment[i] = lexmark_sat_adjustment(caps, nv)[i];
if (media && media->sat_adjustment)
sat_adjustment[i] *= media->sat_adjustment[i];
}
}
if (lexmark_hue_adjustment(caps, nv))
{
for (i = 0; i < 49; i++)
{
hue_adjustment[i] = lexmark_hue_adjustment(caps, nv)[i];
if (media && media->hue_adjustment)
hue_adjustment[i] += media->hue_adjustment[i];
}
}
dt = stp_create_dither_data();
stp_add_channel(dt, cols.p.k, ECOLOR_K, 0);
stp_add_channel(dt, cols.p.c, ECOLOR_C, 0);
stp_add_channel(dt, cols.p.C, ECOLOR_C, 1);
stp_add_channel(dt, cols.p.m, ECOLOR_M, 0);
stp_add_channel(dt, cols.p.M, ECOLOR_M, 1);
stp_add_channel(dt, cols.p.y, ECOLOR_Y, 0);
stp_add_channel(dt, cols.p.Y, ECOLOR_Y, 1);
for (y = 0; y < out_height; y ++)
{
int duplicate_line = 1;
#ifdef DEBUGyy
stp_erprintf("print y %i\n", y);
#endif
if ((y & 63) == 0)
image->note_progress(image, y, out_height);
if (errline != errlast)
{
errlast = errline;
duplicate_line = 0;
if (image->get_row(image, in, errline) != STP_IMAGE_OK)
break;
#if 1
(*colorfunc)(nv, in, out, &zero_mask, image_width, image_bpp, cmap,
hue_adjustment, lum_adjustment, sat_adjustment);
#else
(*colorfunc)(nv, in, out, &zero_mask, image_width, image_bpp, cmap,
NULL, NULL, NULL);
#endif
}
if (doTestPrint == 0) {
stp_dither(out, y, dither, dt, duplicate_line, zero_mask);
} else {
#ifdef DEBUG
readtestprintline(&td, &cols);
#endif
}
clean_color(cols.p.c, length);
clean_color(cols.p.m, length);
clean_color(cols.p.y, length);
#ifdef DEBUGyy
stp_erprintf("Let's go stp_write_weave\n");
stp_erprintf("length %d\n", length);
#endif
stp_write_weave(weave, length, ydpi, model, out_width, left,
xdpi, physical_xdpi, (unsigned char **)cols.v);
errval += errmod;
errline += errdiv;
if (errval >= out_height)
{
errval -= out_height;
errline ++;
}
}
image->progress_conclude(image);
stp_flush_all(weave, model, out_width, left,
ydpi, xdpi, physical_xdpi);
lexmark_deinit_printer(nv, caps);
stp_free_dither_data(dt);
if (doTestPrint == 0) {
stp_free_dither(dither);
}
stp_free_lut(nv);
stp_free(in);
stp_free(out);
stp_destroy_weave(weave);
if (privdata.outbuf != NULL) {
stp_free(privdata.outbuf);
}
if (cols.p.k != NULL) stp_free(cols.p.k);
if (cols.p.c != NULL) stp_free(cols.p.c);
if (cols.p.m != NULL) stp_free(cols.p.m);
if (cols.p.y != NULL) stp_free(cols.p.y);
if (cols.p.C != NULL) stp_free(cols.p.C);
if (cols.p.M != NULL) stp_free(cols.p.M);
if (cols.p.Y != NULL) stp_free(cols.p.Y);
#ifdef DEBUG
lex_tmp_file_deinit(dbgfileprn);
#endif
stp_free_vars(nv);
}
const stp_printfuncs_t stp_lexmark_printfuncs =
{
lexmark_parameters,
stp_default_media_size,
lexmark_imageable_area,
lexmark_limit,
lexmark_print,
lexmark_default_parameters,
lexmark_describe_resolution,
stp_verify_printer_params,
stp_start_job,
stp_end_job
};
static unsigned char *
lexmark_init_line(int mode, unsigned char *prnBuf,
int pass_length,
int offset,
int width, int direction,
const lexmark_inkparam_t *ink_parameter,
const lexmark_cap_t * caps
)
{
int pos1 = 0;
int pos2 = 0;
int abspos, disp;
int hend = 0;
int header_size = 0;
switch(caps->model) {
case m_z52:
case m_z42:
if (caps->model == m_z52)
{
header_size = LXM_Z52_HEADERSIZE;
memcpy(prnBuf, outbufHeader_z52, header_size);
}
if (caps->model == m_z42)
{
header_size = LXM_Z42_HEADERSIZE;
memcpy(prnBuf, outbufHeader_z42, LXM_Z42_HEADERSIZE);
}
if ((mode & COLOR_MODE_K) || (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM))) {
#ifdef DEBUG
stp_erprintf("set photo/black catridge \n");
#endif
prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_BLACK_PRINT;
if (direction) {
} else {
offset += ink_parameter->h_direction_offset;
}
} else {
#ifdef DEBUG
stp_erprintf("set color cartridge \n");
#endif
prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_COLOR_PRINT;
if (direction) {
offset += ink_parameter->h_catridge_offset;
} else {
offset += ink_parameter->h_catridge_offset + ink_parameter->h_direction_offset;
}
}
switch (mode & PRINT_MODE_MASK) {
case PRINT_MODE_300:
prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_300_DPI;
break;
case PRINT_MODE_600:
prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_600_DPI;
break;
case PRINT_MODE_1200:
prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_1200_DPI;
break;
case PRINT_MODE_2400:
prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_2400_DPI;
break;
}
if (direction) {
prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 1;
} else {
prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 2;
}
prnBuf[13] = (unsigned char)((width) >> 8);
prnBuf[14] = (unsigned char)((width) & 0xFF);
prnBuf[15] =(unsigned char)(offset >> 8);
prnBuf[16] =(unsigned char)(offset & 0xFF);
if (caps->model == m_z42) {
switch(mode & PRINT_MODE_MASK) {
case PRINT_MODE_300:
hend = (width-1)*(2400/300);
break;
case PRINT_MODE_600:
hend = (width-1)*(2400/600);
break;
case PRINT_MODE_1200:
hend = (width-1)*(2400/1200);
break;
case PRINT_MODE_2400:
hend = (width-1)*(2400/2400);
break;
}
hend += offset;
prnBuf[17] = (unsigned char)(hend >> 8);
prnBuf[18] = (unsigned char)(hend & 0xFF);
prnBuf[10] = (pass_length==208 ? 0x1A : 0x18);
}
return prnBuf + header_size;
break;
case m_3200:
memcpy(prnBuf, outbufHeader_3200, LXM_3200_HEADERSIZE);
offset = (offset - 60) * 4;
if((mode & COLOR_MODE_K) ||
(mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM)))
{
disp = LXM3200_LEFTOFFS;
prnBuf[2] = 0x00;
}
else
{
disp = LXM3200_RIGHTOFFS;
prnBuf[2] = 0x80;
}
if(pass_length == 208)
{
prnBuf[2] |= 0x10;
}
switch(mode & PRINT_MODE_MASK) {
case PRINT_MODE_300:
prnBuf[2] |= 0x20;
pos1 = offset + disp;
pos2 = offset + (width * 4) + disp;
break;
case PRINT_MODE_600:
prnBuf[2] |= 0x00;
pos1 = offset + disp;
pos2 = offset + (width * 2) + disp;
break;
case PRINT_MODE_1200:
prnBuf[2] |= 0x40;
pos1 = offset + disp;
pos2 = (offset + width) + disp;
break;
}
if(direction)
prnBuf[2] |= 0x01;
else
prnBuf[2] |= 0x00;
prnBuf[3] = (unsigned char)((width) >> 8);
prnBuf[4] = (unsigned char)((width) & 0xff);
prnBuf[21] = (unsigned char)(pos1 >> 8);
prnBuf[22] = (unsigned char)(pos1 & 0xFF);
abspos = ((((pos2 - 3600) >> 3) & 0xfff0) + 9);
prnBuf[5] = (abspos-lxm3200_headpos) >> 8;
prnBuf[6] = (abspos-lxm3200_headpos) & 0xff;
lxm3200_headpos = abspos;
if(LXM3200_RIGHTOFFS > 4816)
abspos = (((LXM3200_RIGHTOFFS - 4800) >> 3) & 0xfff0);
else
abspos = (((LXM3200_RIGHTOFFS - 3600) >> 3) & 0xfff0);
prnBuf[11] = (lxm3200_headpos-abspos) >> 8;
prnBuf[12] = (lxm3200_headpos-abspos) & 0xff;
lxm3200_headpos = abspos;
prnBuf[7] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[0]);
prnBuf[15] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[8]);
prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
return prnBuf + LXM_3200_HEADERSIZE;
break;
case m_lex7500:
stp_erprintf("Lexmark 7500 not supported !\n");
return NULL;
break;
}
return NULL;
}
typedef struct Lexmark_head_colors {
int v_start;
unsigned char *line;
int head_nozzle_start;
int head_nozzle_end;
int used_jets;
} Lexmark_head_colors;
static int
lexmark_write(const stp_vars_t v,
unsigned char *prnBuf,
int *paperShift,
int direction,
int pass_length,
const lexmark_cap_t * caps,
const lexmark_inkparam_t *ink_parameter,
int xdpi,
int yCount,
Lexmark_head_colors *head_colors,
int length,
int mode,
int ydpi,
int width,
int offset,
int dmt)
{
unsigned char *tbits=NULL, *p=NULL;
int clen;
int x;
int y;
int dy;
int x1;
unsigned short pixelline;
unsigned int valid_bytes;
int xStart=0;
int xEnd=0;
int xIter=0;
int anyCol=0;
int colIndex;
int rwidth;
#ifdef DEBUG
stp_erprintf("pass length %d\n", pass_length);
#endif
if ((((width*caps->x_raster_res)/xdpi)+offset) > ((caps->max_paper_width*caps->x_raster_res)/72)) {
#ifdef DEBUG
stp_erprintf("!! Line too long !! reduce it from %d", width);
#endif
width = ((((caps->max_paper_width*caps->x_raster_res)/72) - offset)*xdpi)/caps->x_raster_res;
#ifdef DEBUG
stp_erprintf(" down to %d\n", width);
#endif
}
#ifdef DEBUG
stp_erprintf("lexmark: printer line initialized.\n");
#endif
if (direction) {
xStart = -get_lr_shift(mode);
xEnd = width-1;
xIter = 1;
rwidth = xEnd - xStart;
} else {
xStart = width-1;
xEnd = -get_lr_shift(mode);
rwidth = xStart - xEnd;
xIter = -1;
}
p = lexmark_init_line(mode, prnBuf, pass_length, offset, rwidth,
direction,
ink_parameter, caps);
#ifdef DEBUG
stp_erprintf("lexmark: xStart %d, xEnd %d, xIter %d.\n", xStart, xEnd, xIter);
#endif
yCount = 2;
for (x=xStart; x != xEnd; x+=xIter) {
int anyDots=0;
switch(caps->model) {
case m_z52:
tbits = p;
*(p++) = 0x3F;
tbits[1] = 0;
p++;
break;
case m_3200:
case m_z42:
tbits = p;
p += 4;
break;
case m_lex7500:
break;
}
pixelline =0;
valid_bytes = 0;
anyDots =0;
x1 = x+get_lr_shift(mode);
for (colIndex=0; colIndex < 3; colIndex++) {
for (dy=head_colors[colIndex].head_nozzle_start,y=head_colors[colIndex].v_start*yCount;
(dy < head_colors[colIndex].head_nozzle_end);
y+=yCount, dy++) {
if (head_colors[colIndex].line != NULL) {
pixelline = pixelline << 1;
if ((x >= 0) &&
((dy - head_colors[colIndex].head_nozzle_start) < (head_colors[colIndex].used_jets/2)))
pixelline = pixelline | ((head_colors[colIndex].line[(y*length)+(x/8)] >> (7-(x%8))) & 0x1);
pixelline = pixelline << 1;
if ((x1 < width) &&
(((dy - head_colors[colIndex].head_nozzle_start)+1) < (head_colors[colIndex].used_jets/2)))
pixelline = pixelline | ((head_colors[colIndex].line[(((yCount>>1)+y)*length)+ (x1/8)] >> (7-(x1%8))) & 0x1);
} else {
pixelline = pixelline << 2;
}
switch(caps->model) {
case m_z52:
if ((dy%8) == 7) {
anyDots |= pixelline;
if (pixelline) {
valid_bytes = valid_bytes >> 1;
*((p++)) = (unsigned char)(pixelline >> 8);
*((p++)) = (unsigned char)(pixelline & 0xff);
} else {
valid_bytes = valid_bytes >> 1;
valid_bytes |= 0x1000;
}
pixelline =0;
}
break;
case m_3200:
case m_z42:
if((dy % 4) == 3)
{
anyDots |= pixelline;
valid_bytes <<= 1;
if(pixelline)
*(p++) = (unsigned char)(pixelline & 0xff);
else
valid_bytes |= 0x01;
pixelline = 0;
}
break;
case m_lex7500:
break;
}
}
}
switch(caps->model) {
case m_z52:
if (pass_length != 208) {
valid_bytes = valid_bytes >> 1;
valid_bytes |= 0x1000;
}
tbits[0] = 0x20 | ((unsigned char)((valid_bytes >> 8) & 0x1f));
tbits[1] = (unsigned char)(valid_bytes & 0xff);
break;
case m_z42:
if ((p-tbits) & 1) *(p++)=0;
case m_3200:
tbits[0] = 0x80 | ((unsigned char)((valid_bytes >> 24) & 0x1f));
tbits[1] = (unsigned char)((valid_bytes >> 16) & 0xff);
tbits[2] = (unsigned char)((valid_bytes >> 8) & 0xff);
tbits[3] = (unsigned char)(valid_bytes & 0xff);
break;
case m_lex7500:
break;
}
if (anyDots) {
anyCol = 1;
} else {
#ifdef DEBUG
#endif
}
}
#ifdef DEBUG
stp_erprintf("lexmark: 4\n");
#endif
clen=((unsigned char *)p)-prnBuf;
switch(caps->model) {
case m_z52:
case m_z42:
prnBuf[IDX_SEQLEN] =(unsigned char)(clen >> 24);
prnBuf[IDX_SEQLEN+1] =(unsigned char)(clen >> 16);
prnBuf[IDX_SEQLEN+2] =(unsigned char)(clen >> 8);
prnBuf[IDX_SEQLEN+3]=(unsigned char)(clen & 0xFF);
break;
case m_3200:
prnBuf[18] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 16);
prnBuf[19] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 8);
prnBuf[20] = (unsigned char)((clen - LXM_3200_HEADERSIZE) & 0xff);
prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
break;
default:
break;
}
if (anyCol) {
paper_shift(v, (*paperShift), caps);
*paperShift=0;
stp_zfwrite((const char *)prnBuf,1,clen,v);
#ifdef DEBUG
lex_write_tmp_file(dbgfileprn, (void *)prnBuf,clen);
stp_erprintf("lexmark: line written.\n");
#endif
return 1;
} else {
#ifdef DEBUG
stp_erprintf("-- empty line\n");
#endif
return 0;
}
return 0;
}
#ifdef DEBUG
const stp_vars_t lex_open_tmp_file() {
int i;
const stp_vars_t ofile;
char tmpstr[256];
stp_erprintf(" create file !\n");
for (i=0, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r");
ofile != NULL;
i++, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r")) {
if (ofile != NULL)
{
fclose(ofile);
}
}
stp_erprintf("Create file %s !\n", tmpstr);
ofile = fopen(tmpstr, "wb");
if (ofile == NULL)
{
stp_erprintf("Can't create file !\n");
exit(2);
}
return ofile;
}
void lex_tmp_file_deinit(const stp_vars_t file) {
stp_erprintf("Close file %lx\n", file);
fclose(file);
}
const stp_vars_t lex_write_tmp_file(const stp_vars_t ofile, void *data,int length) {
fwrite(data, 1, length, ofile);
}
#endif
static void
flush_pass(stp_softweave_t *sw, int passno, int model, int width,
int hoffset, int ydpi, int xdpi, int physical_xdpi,
int vertical_subpass)
{
const stp_vars_t nv = (sw->v);
stp_lineoff_t *lineoffs = stp_get_lineoffsets_by_pass(sw, passno);
stp_lineactive_t *lineactive = stp_get_lineactive_by_pass(sw, passno);
const stp_linebufs_t *bufs = stp_get_linebases_by_pass(sw, passno);
stp_pass_t *pass = stp_get_pass_by_pass(sw, passno);
stp_linecount_t *linecount = stp_get_linecount_by_pass(sw, passno);
int lwidth = (width + (sw->horizontal_weave - 1)) / sw->horizontal_weave;
int microoffset = vertical_subpass & (sw->horizontal_weave - 1);
int prn_mode;
int j;
lexm_privdata_weave *privdata_weave = stp_get_driver_data(nv);
const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
int paperShift;
Lexmark_head_colors head_colors[3]={{0, NULL, 0, 64/2, 64},
{0, NULL, 64/2, 128/2, 64},
{0, NULL, 128/2, 192/2, 64}};
#ifdef DEBUG
stp_erprintf("Lexmark: flush_pass, here we are !\n");
stp_erprintf(" passno %i, sw->ncolors %i, width %d, lwidth %d, linecount k % d, linecount m % d, bitwidth %d\n",
passno, sw->ncolors, width, lwidth, sw->bitwidth);
stp_erprintf("microoffset %d, vertical_subpass %d, sw->horizontal_weave %d\n", microoffset,vertical_subpass, sw->horizontal_weave);
stp_erprintf("Lexmark: last_pass_offset %d, last_pass %d, logicalpassstart %d\n", sw->last_pass_offset, sw->last_pass, pass->logicalpassstart);
stp_erprintf("Lexmark: vertical adapt: caps->y_raster_res %d, ydpi %d, \n", caps->y_raster_res, ydpi);
#endif
if (1) {
#ifdef DEBUG
stp_erprintf("1\n");
stp_erprintf("\n");
stp_erprintf("lineoffs[0].v[j] %d\n", lineoffs[0].v[0]);
stp_erprintf("lineoffs[0].v[j] %d\n", lineoffs[0].v[1]);
#endif
switch (physical_xdpi) {
case 300:
prn_mode = PRINT_MODE_300;
break;
case 600:
prn_mode = PRINT_MODE_600;
break;
case 1200:
prn_mode = PRINT_MODE_1200;
break;
default:
#ifdef DEBUG
stp_erprintf("Eror: Unsupported phys resolution (%d)\n", physical_xdpi);
#endif
return;
break;
}
paperShift = (pass->logicalpassstart - sw->last_pass_offset) * (caps->y_raster_res/ydpi);
if ((ECOLOR_C < sw->ncolors) && (lineactive[0].v[ECOLOR_C] > 0))
{
head_colors[0].line = bufs[0].v[ECOLOR_C];
head_colors[0].used_jets = linecount[0].v[ECOLOR_C];
}
else
{
head_colors[0].line = NULL;
head_colors[0].used_jets = 0;
}
if ((ECOLOR_M < sw->ncolors) && (lineactive[0].v[ECOLOR_M] > 0))
{
head_colors[1].line = bufs[0].v[ECOLOR_M];
head_colors[1].used_jets = linecount[0].v[ECOLOR_M];
}
else
{
head_colors[1].line = 0;
head_colors[1].used_jets = 0;
}
if ((ECOLOR_Y < sw->ncolors) && (lineactive[0].v[ECOLOR_Y] > 0))
{
head_colors[2].line = bufs[0].v[ECOLOR_Y];
head_colors[2].used_jets = linecount[0].v[ECOLOR_Y];
}
else
{
head_colors[2].line = 0;
head_colors[2].used_jets = 0;
}
if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
#ifdef DEBUG
stp_erprintf("lexmark_write: lwidth %d\n", lwidth);
#endif
lexmark_write(nv,
privdata_weave->outbuf,
&paperShift,
privdata_weave->direction,
sw->jets,
caps,
privdata_weave->ink_parameter,
xdpi,
2,
head_colors,
(lwidth+7)/8,
prn_mode | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_M,
ydpi,
lwidth,
hoffset+microoffset,
0 );
if (privdata_weave->bidirectional)
privdata_weave->direction = (privdata_weave->direction +1) & 1;
}
if (sw->jets != 208)
{
if ((ECOLOR_LC < sw->ncolors) && (lineactive[0].v[ECOLOR_LC] > 0))
{
head_colors[0].line = bufs[0].v[ECOLOR_LC];
head_colors[0].used_jets = linecount[0].v[ECOLOR_LC];
}
else
{
head_colors[0].line = 0;
head_colors[0].used_jets = 0;
}
if ((ECOLOR_LM < sw->ncolors) && (lineactive[0].v[ECOLOR_LM] > 0))
{
head_colors[1].line = bufs[0].v[ECOLOR_LM];
head_colors[1].used_jets = linecount[0].v[ECOLOR_LM];
}
else
{
head_colors[1].line = 0;
head_colors[1].used_jets = 0;
}
if ((ECOLOR_K < sw->ncolors) && (lineactive[0].v[ECOLOR_K] > 0))
{
head_colors[2].line = bufs[0].v[ECOLOR_K];
head_colors[2].used_jets = linecount[0].v[ECOLOR_K];
}
else
{
head_colors[2].line = 0;
head_colors[2].used_jets = 0;
}
}
else
{
if ((ECOLOR_K < sw->ncolors) && (lineactive[0].v[ECOLOR_K] > 0))
{
head_colors[0].line = bufs[0].v[ECOLOR_K];
head_colors[0].used_jets = linecount[0].v[ECOLOR_K];
head_colors[0].head_nozzle_start = 0;
head_colors[0].head_nozzle_end = sw->jets/2;
head_colors[2].line = NULL;
head_colors[2].used_jets = 0;
head_colors[2].head_nozzle_start = 0;
head_colors[2].head_nozzle_end = 0;
head_colors[1].line = NULL;
head_colors[1].used_jets = 0;
head_colors[1].head_nozzle_start = 0;
head_colors[1].head_nozzle_end = 0;
}
else
{
head_colors[2].line = NULL;
head_colors[2].used_jets = 0;
head_colors[2].head_nozzle_start = 0;
head_colors[2].head_nozzle_end = 0;
head_colors[1].line = NULL;
head_colors[1].used_jets = 0;
head_colors[1].head_nozzle_start = 0;
head_colors[1].head_nozzle_end = 0;
head_colors[0].line = NULL;
head_colors[0].used_jets = 0;
head_colors[0].head_nozzle_start = 0;
head_colors[0].head_nozzle_end = 0;
}
}
if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
lexmark_write(nv,
privdata_weave->outbuf,
&paperShift,
privdata_weave->direction,
sw->jets,
caps,
privdata_weave->ink_parameter,
xdpi,
2,
head_colors,
(lwidth+7)/8,
prn_mode | COLOR_MODE_LC | COLOR_MODE_LM | COLOR_MODE_K,
ydpi,
lwidth,
hoffset+microoffset,
0 );
if (privdata_weave->bidirectional)
{
privdata_weave->direction = (privdata_weave->direction +1) & 1;
}
}
sw->last_pass_offset = pass->logicalpassstart - (paperShift / (caps->y_raster_res/ydpi));
}
for (j = 0; j < sw->ncolors; j++)
{
lineoffs[0].v[j] = 0;
linecount[0].v[j] = 0;
}
#ifdef DEBUG
stp_erprintf("lexmark_write finished\n");
#endif
sw->last_pass = pass->pass;
pass->pass = -1;
}
#ifdef DEBUG
static void testprint(testdata *td)
{
int icol, i;
char dummy1[256], dummy2[256];
lexmark_linebufs_t linebufs;
for (i=0; i < (sizeof(linebufs.v)/sizeof(linebufs.v[0])); i++) {
linebufs.v[i] = NULL;
}
td->ifile = fopen("/t1.ppm", "rb");
if (td->ifile != NULL) {
fscanf(td->ifile, "%[^{]{%[^\"]\"%d %d %d %d\",", dummy1, dummy2, &(td->x), &(td->y), &(td->cols), &(td->deep));
td->cols -= 1;
td->input_line = (char *)malloc(td->x+10);
stp_erprintf("<%s> <%s>\n", dummy1, dummy2);
stp_erprintf("%d %d %d %d\n", td->x, td->y, td->cols, td->deep);
if (td->cols > 16) {
stp_erprintf("too many colors !!\n");
return;
}
fscanf(td->ifile, "%[^\"]\"%c c %[^\"]\",", dummy1, dummy2, dummy2);
for (icol=0; icol < td->cols; icol++) {
fscanf(td->ifile, "%[^\"]\"%c c %[^\"]\",", dummy1, &(td->colchar[icol]), dummy2);
stp_erprintf("colchar %d <%c>\n", i, td->colchar[icol]);
}
if (td->cols > 5) {
td->cols = 7;
for (icol=0; icol < td->cols; icol++) {
linebufs.v[icol] = (char *)malloc((td->x+7)/8);
}
} else if (td->cols > 4) {
td->cols = 5;
for (icol=0; icol < td->cols; icol++) {
linebufs.v[icol] = (char *)malloc((td->x+7)/8);
}
} else {
td->cols = 1;
linebufs.v[0] = (char *)malloc((td->x+7)/8);
}
} else {
stp_erprintf("can't open file !\n");
}
}
static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs)
{
char dummy1[256];
int icol, ix;
stp_erprintf("start readtestprintline\n");
for (icol=0; icol < 7; icol++) {
if (linebufs->v[icol] != NULL) {
memset(linebufs->v[icol], 0, (td->x+7)/8);
}
}
stp_erprintf("1 readtestprintline cols %d\n", td->cols);
fscanf(td->ifile, "%[^\"]\"%[^\"]\",", dummy1, td->input_line);
for (icol=0; icol < td->cols; icol++) {
for (ix=0; ix < td->x; ix++) {
if (td->input_line[ix] == td->colchar[icol]) {
if (icol != 0) {
linebufs->v[icol-1][ix/8] |= 1 << (ix%8);
} else {
linebufs->p.y[ix/8] |= 1 << (ix%8);
linebufs->p.m[ix/8] |= 1 << (ix%8);
linebufs->p.c[ix/8] |= 1 << (ix%8);
}
}
}
}
}
#endif