00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifdef HAVE_CONFIG_H
00032 #include <config.h>
00033 #endif
00034 #include <gimp-print/gimp-print.h>
00035 #include "gimp-print-internal.h"
00036 #include <gimp-print/gimp-print-intl-internal.h>
00037 #include <string.h>
00038 #include <stdio.h>
00039
00040 #ifdef __GNUC__
00041 #define inline __inline__
00042 #endif
00043
00044 #define OLYMPUS_INTERLACE_NONE 0
00045 #define OLYMPUS_INTERLACE_LINE 1
00046 #define OLYMPUS_INTERLACE_PLANE 2
00047
00048 #define OLYMPUS_FEATURE_NONE 0x00000000
00049 #define OLYMPUS_FEATURE_FULL_WIDTH 0x00000001
00050 #define OLYMPUS_FEATURE_FULL_HEIGHT 0x00000002
00051 #define OLYMPUS_FEATURE_BLOCK_ALIGN 0x00000004
00052 #define OLYMPUS_FEATURE_BORDERLESS 0x00000008
00053 #define OLYMPUS_FEATURE_WHITE_BORDER 0x00000010
00054
00055 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
00056 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
00057
00058 static const char *zero = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
00059
00060 typedef struct
00061 {
00062 const char *output_type;
00063 int output_channels;
00064 const char *name;
00065 const char *channel_order;
00066 } ink_t;
00067
00068 typedef struct {
00069 const ink_t *item;
00070 size_t n_items;
00071 } ink_list_t;
00072
00073 typedef struct {
00074 const char* name;
00075 int xdpi;
00076 int ydpi;
00077 } olymp_resolution_t;
00078
00079 typedef struct {
00080 const olymp_resolution_t *item;
00081 size_t n_items;
00082 } olymp_resolution_list_t;
00083
00084 typedef struct {
00085 const char* name;
00086 const char* text;
00087 int width_pt;
00088 int height_pt;
00089 int border_pt_left;
00090 int border_pt_right;
00091 int border_pt_top;
00092 int border_pt_bottom;
00093 } olymp_pagesize_t;
00094
00095 typedef struct {
00096 const olymp_pagesize_t *item;
00097 size_t n_items;
00098 } olymp_pagesize_list_t;
00099
00100 typedef struct {
00101 const char* res_name;
00102 const char* pagesize_name;
00103 int width_px;
00104 int height_px;
00105 } olymp_printsize_t;
00106
00107 typedef struct {
00108 const olymp_printsize_t *item;
00109 size_t n_items;
00110 } olymp_printsize_list_t;
00111
00112
00113 typedef struct {
00114 const char *name;
00115 const char *text;
00116 const stp_raw_t seq;
00117 } laminate_t;
00118
00119 typedef struct {
00120 const laminate_t *item;
00121 size_t n_items;
00122 } laminate_list_t;
00123
00124 typedef struct
00125 {
00126 int xdpi, ydpi;
00127 int xsize, ysize;
00128 char plane;
00129 int block_min_x, block_min_y;
00130 int block_max_x, block_max_y;
00131 const char* pagesize;
00132 const laminate_t* laminate;
00133 } olympus_privdata_t;
00134
00135 static olympus_privdata_t privdata;
00136
00137 typedef struct
00138 {
00139 int model;
00140 const ink_list_t *inks;
00141 const olymp_resolution_list_t *resolution;
00142 const olymp_pagesize_list_t *pages;
00143 const olymp_printsize_list_t *printsize;
00144 int interlacing;
00145 int block_size;
00146 int features;
00147 void (*printer_init_func)(stp_vars_t *);
00148 void (*printer_end_func)(stp_vars_t *);
00149 void (*plane_init_func)(stp_vars_t *);
00150 void (*plane_end_func)(stp_vars_t *);
00151 void (*block_init_func)(stp_vars_t *);
00152 void (*block_end_func)(stp_vars_t *);
00153 const char *adj_cyan;
00154 const char *adj_magenta;
00155 const char *adj_yellow;
00156 const laminate_list_t *laminate;
00157 } olympus_cap_t;
00158
00159
00160 static const olympus_cap_t* olympus_get_model_capabilities(int model);
00161 static const laminate_t* olympus_get_laminate_pattern(stp_vars_t *v);
00162
00163
00164 static const ink_t cmy_inks[] =
00165 {
00166 { "CMY", 3, "CMY", "\1\2\3" },
00167 };
00168
00169 static const ink_list_t cmy_ink_list =
00170 {
00171 cmy_inks, sizeof(cmy_inks) / sizeof(ink_t)
00172 };
00173
00174 static const ink_t ymc_inks[] =
00175 {
00176 { "CMY", 3, "CMY", "\3\2\1" },
00177 };
00178
00179 static const ink_list_t ymc_ink_list =
00180 {
00181 ymc_inks, sizeof(ymc_inks) / sizeof(ink_t)
00182 };
00183
00184 static const ink_t rgb_inks[] =
00185 {
00186 { "RGB", 3, "RGB", "\1\2\3" },
00187 };
00188
00189 static const ink_list_t rgb_ink_list =
00190 {
00191 rgb_inks, sizeof(rgb_inks) / sizeof(ink_t)
00192 };
00193
00194 static const ink_t bgr_inks[] =
00195 {
00196 { "RGB", 3, "RGB", "\3\2\1" },
00197 };
00198
00199 static const ink_list_t bgr_ink_list =
00200 {
00201 bgr_inks, sizeof(bgr_inks) / sizeof(ink_t)
00202 };
00203
00204
00205
00206 static const olymp_resolution_t res_320dpi[] =
00207 {
00208 { "320x320", 320, 320},
00209 };
00210
00211 static const olymp_resolution_list_t res_320dpi_list =
00212 {
00213 res_320dpi, sizeof(res_320dpi) / sizeof(olymp_resolution_t)
00214 };
00215
00216 static const olymp_pagesize_t p10_page[] =
00217 {
00218 { "w288h432", "4 x 6", -1, -1, 0, 0, 16, 0},
00219 { "B7", "3.5 x 5", -1, -1, 0, 0, 4, 0},
00220 { "Custom", NULL, -1, -1, 28, 28, 48, 48},
00221 };
00222
00223 static const olymp_pagesize_list_t p10_page_list =
00224 {
00225 p10_page, sizeof(p10_page) / sizeof(olymp_pagesize_t)
00226 };
00227
00228 static const olymp_printsize_t p10_printsize[] =
00229 {
00230 { "320x320", "w288h432", 1280, 1848},
00231 { "320x320", "B7", 1144, 1591},
00232 { "320x320", "Custom", 1280, 1848},
00233 };
00234
00235 static const olymp_printsize_list_t p10_printsize_list =
00236 {
00237 p10_printsize, sizeof(p10_printsize) / sizeof(olymp_printsize_t)
00238 };
00239
00240 static void p10_printer_init_func(stp_vars_t *v)
00241 {
00242 stp_zfwrite("\033R\033M\033S\2\033N\1\033D\1\033Y", 1, 15, v);
00243 stp_zfwrite((privdata.laminate->seq).data, 1,
00244 (privdata.laminate->seq).bytes, v);
00245 stp_zfwrite("\033Z\0", 1, 3, v);
00246 }
00247
00248 static void p10_printer_end_func(stp_vars_t *v)
00249 {
00250 stp_zfwrite("\033P", 1, 2, v);
00251 }
00252
00253 static void p10_block_init_func(stp_vars_t *v)
00254 {
00255 stp_zprintf(v, "\033T%c", privdata.plane);
00256 stp_put16_le(privdata.block_min_x, v);
00257 stp_put16_le(privdata.block_min_y, v);
00258 stp_put16_le(privdata.block_max_x + 1, v);
00259 stp_put16_le(privdata.block_max_y + 1, v);
00260 }
00261
00262 static const laminate_t p10_laminate[] =
00263 {
00264 {"Coated", N_("Coated"), {1, "\x00"}},
00265 {"None", N_("None"), {1, "\x02"}},
00266 };
00267
00268 static const laminate_list_t p10_laminate_list =
00269 {
00270 p10_laminate, sizeof(p10_laminate) / sizeof(laminate_t)
00271 };
00272
00273
00274
00275 static const olymp_pagesize_t p200_page[] =
00276 {
00277 { "ISOB7", "80x125mm", -1, -1, 16, 17, 33, 33},
00278 { "Custom", NULL, -1, -1, 16, 17, 33, 33},
00279 };
00280
00281 static const olymp_pagesize_list_t p200_page_list =
00282 {
00283 p200_page, sizeof(p200_page) / sizeof(olymp_pagesize_t)
00284 };
00285
00286 static const olymp_printsize_t p200_printsize[] =
00287 {
00288 { "320x320", "ISOB7", 960, 1280},
00289 { "320x320", "Custom", 960, 1280},
00290 };
00291
00292 static const olymp_printsize_list_t p200_printsize_list =
00293 {
00294 p200_printsize, sizeof(p200_printsize) / sizeof(olymp_printsize_t)
00295 };
00296
00297 static void p200_printer_init_func(stp_vars_t *v)
00298 {
00299 stp_zfwrite("S000001\0S010001\1", 1, 16, v);
00300 }
00301
00302 static void p200_plane_init_func(stp_vars_t *v)
00303 {
00304 stp_zprintf(v, "P0%d9999", 3 - privdata.plane+1 );
00305 stp_put32_be(privdata.xsize * privdata.ysize, v);
00306 }
00307
00308 static void p200_printer_end_func(stp_vars_t *v)
00309 {
00310 stp_zprintf(v, "P000001\1");
00311 }
00312
00313 static const char p200_adj_any[] =
00314 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00315 "<gimp-print>\n"
00316 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00317 "<sequence count=\"33\" lower-bound=\"0\" upper-bound=\"1\">\n"
00318 "0.000000 0.039216 0.078431 0.117647 0.152941 0.192157 0.231373 0.266667\n"
00319 "0.301961 0.341176 0.376471 0.411765 0.447059 0.482353 0.513725 0.549020\n"
00320 "0.580392 0.615686 0.647059 0.678431 0.709804 0.741176 0.768627 0.796078\n"
00321 "0.827451 0.854902 0.878431 0.905882 0.929412 0.949020 0.972549 0.988235\n"
00322 "1.000000\n"
00323 "</sequence>\n"
00324 "</curve>\n"
00325 "</gimp-print>\n";
00326
00327
00328
00329 static const olymp_resolution_t p300_res[] =
00330 {
00331 { "306x306", 306, 306},
00332 { "153x153", 153, 153},
00333 };
00334
00335 static const olymp_resolution_list_t p300_res_list =
00336 {
00337 p300_res, sizeof(p300_res) / sizeof(olymp_resolution_t)
00338 };
00339
00340 static const olymp_pagesize_t p300_page[] =
00341 {
00342 { "A6", NULL, -1, -1, 28, 28, 48, 48},
00343 { "Custom", NULL, -1, -1, 28, 28, 48, 48},
00344 };
00345
00346 static const olymp_pagesize_list_t p300_page_list =
00347 {
00348 p300_page, sizeof(p300_page) / sizeof(olymp_pagesize_t)
00349 };
00350
00351 static const olymp_printsize_t p300_printsize[] =
00352 {
00353 { "306x306", "A6", 1024, 1376},
00354 { "153x153", "A6", 512, 688},
00355 { "306x306", "Custom", 1024, 1376},
00356 { "153x153", "Custom", 1024, 1376},
00357 };
00358
00359 static const olymp_printsize_list_t p300_printsize_list =
00360 {
00361 p300_printsize, sizeof(p300_printsize) / sizeof(olymp_printsize_t)
00362 };
00363
00364 static void p300_printer_init_func(stp_vars_t *v)
00365 {
00366 stp_zfwrite("\033\033\033C\033N\1\033F\0\1\033MS\xff\xff\xff"
00367 "\033Z", 1, 19, v);
00368 stp_put16_be(privdata.xdpi, v);
00369 stp_put16_be(privdata.ydpi, v);
00370 }
00371
00372 static void p300_plane_end_func(stp_vars_t *v)
00373 {
00374 const char *c = "CMY";
00375 stp_zprintf(v, "\033\033\033P%cS", c[privdata.plane-1]);
00376 stp_deprintf(STP_DBG_OLYMPUS, "olympus: p300_plane_end_func: %c\n",
00377 c[privdata.plane-1]);
00378 }
00379
00380 static void p300_block_init_func(stp_vars_t *v)
00381 {
00382 const char *c = "CMY";
00383 stp_zprintf(v, "\033\033\033W%c", c[privdata.plane-1]);
00384 stp_put16_be(privdata.block_min_y, v);
00385 stp_put16_be(privdata.block_min_x, v);
00386 stp_put16_be(privdata.block_max_y, v);
00387 stp_put16_be(privdata.block_max_x, v);
00388
00389 stp_deprintf(STP_DBG_OLYMPUS, "olympus: p300_block_init_func: %d-%dx%d-%d\n",
00390 privdata.block_min_x, privdata.block_max_x,
00391 privdata.block_min_y, privdata.block_max_y);
00392 }
00393
00394 static const char p300_adj_cyan[] =
00395 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00396 "<gimp-print>\n"
00397 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00398 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00399 "0.078431 0.211765 0.250980 0.282353 0.309804 0.333333 0.352941 0.368627\n"
00400 "0.388235 0.403922 0.427451 0.443137 0.458824 0.478431 0.498039 0.513725\n"
00401 "0.529412 0.545098 0.556863 0.576471 0.592157 0.611765 0.627451 0.647059\n"
00402 "0.666667 0.682353 0.701961 0.713725 0.725490 0.729412 0.733333 0.737255\n"
00403 "</sequence>\n"
00404 "</curve>\n"
00405 "</gimp-print>\n";
00406
00407 static const char p300_adj_magenta[] =
00408 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00409 "<gimp-print>\n"
00410 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00411 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00412 "0.047059 0.211765 0.250980 0.278431 0.305882 0.333333 0.349020 0.364706\n"
00413 "0.380392 0.396078 0.415686 0.435294 0.450980 0.466667 0.482353 0.498039\n"
00414 "0.513725 0.525490 0.541176 0.556863 0.572549 0.592157 0.611765 0.631373\n"
00415 "0.650980 0.670588 0.694118 0.705882 0.721569 0.741176 0.745098 0.756863\n"
00416 "</sequence>\n"
00417 "</curve>\n"
00418 "</gimp-print>\n";
00419
00420 static const char p300_adj_yellow[] =
00421 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00422 "<gimp-print>\n"
00423 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00424 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00425 "0.047059 0.117647 0.203922 0.250980 0.274510 0.301961 0.321569 0.337255\n"
00426 "0.352941 0.364706 0.380392 0.396078 0.407843 0.423529 0.439216 0.450980\n"
00427 "0.466667 0.482353 0.498039 0.513725 0.533333 0.552941 0.572549 0.596078\n"
00428 "0.615686 0.635294 0.650980 0.666667 0.682353 0.690196 0.701961 0.713725\n"
00429 "</sequence>\n"
00430 "</curve>\n"
00431 "</gimp-print>\n";
00432
00433
00434
00435 static const olymp_resolution_t res_314dpi[] =
00436 {
00437 { "314x314", 314, 314},
00438 };
00439
00440 static const olymp_resolution_list_t res_314dpi_list =
00441 {
00442 res_314dpi, sizeof(res_314dpi) / sizeof(olymp_resolution_t)
00443 };
00444
00445 static const olymp_pagesize_t p400_page[] =
00446 {
00447 { "A4", NULL, -1, -1, 22, 22, 54, 54},
00448 { "c8x10", "A5 wide", -1, -1, 58, 59, 84, 85},
00449 { "C6", "2 Postcards (A4)", -1, -1, 9, 9, 9, 9},
00450 { "Custom", NULL, -1, -1, 22, 22, 54, 54},
00451 };
00452
00453 static const olymp_pagesize_list_t p400_page_list =
00454 {
00455 p400_page, sizeof(p400_page) / sizeof(olymp_pagesize_t)
00456 };
00457
00458 static const olymp_printsize_t p400_printsize[] =
00459 {
00460 { "314x314", "A4", 2400, 3200},
00461 { "314x314", "c8x10", 2000, 2400},
00462 { "314x314", "C6", 1328, 1920},
00463 { "314x314", "Custom", 2400, 3200},
00464 };
00465
00466 static const olymp_printsize_list_t p400_printsize_list =
00467 {
00468 p400_printsize, sizeof(p400_printsize) / sizeof(olymp_printsize_t)
00469 };
00470
00471 static void p400_printer_init_func(stp_vars_t *v)
00472 {
00473 int wide = (strcmp(privdata.pagesize, "c8x10") == 0
00474 || strcmp(privdata.pagesize, "C6") == 0);
00475
00476 stp_zprintf(v, "\033ZQ"); stp_zfwrite(zero, 1, 61, v);
00477 stp_zprintf(v, "\033FP"); stp_zfwrite(zero, 1, 61, v);
00478 stp_zprintf(v, "\033ZF");
00479 stp_putc((wide ? '\x40' : '\x00'), v); stp_zfwrite(zero, 1, 60, v);
00480 stp_zprintf(v, "\033ZS");
00481 if (wide)
00482 {
00483 stp_put16_be(privdata.ysize, v);
00484 stp_put16_be(privdata.xsize, v);
00485 }
00486 else
00487 {
00488 stp_put16_be(privdata.xsize, v);
00489 stp_put16_be(privdata.ysize, v);
00490 }
00491 stp_zfwrite(zero, 1, 57, v);
00492 stp_zprintf(v, "\033ZP"); stp_zfwrite(zero, 1, 61, v);
00493 }
00494
00495 static void p400_plane_init_func(stp_vars_t *v)
00496 {
00497 stp_zprintf(v, "\033ZC"); stp_zfwrite(zero, 1, 61, v);
00498 }
00499
00500 static void p400_plane_end_func(stp_vars_t *v)
00501 {
00502 stp_zprintf(v, "\033P"); stp_zfwrite(zero, 1, 62, v);
00503 }
00504
00505 static void p400_block_init_func(stp_vars_t *v)
00506 {
00507 int wide = (strcmp(privdata.pagesize, "c8x10") == 0
00508 || strcmp(privdata.pagesize, "C6") == 0);
00509
00510 stp_zprintf(v, "\033Z%c", '3' - privdata.plane + 1);
00511 if (wide)
00512 {
00513 stp_put16_be(privdata.ysize - privdata.block_max_y - 1, v);
00514 stp_put16_be(privdata.xsize - privdata.block_max_x - 1, v);
00515 stp_put16_be(privdata.block_max_y - privdata.block_min_y + 1, v);
00516 stp_put16_be(privdata.block_max_x - privdata.block_min_x + 1, v);
00517 }
00518 else
00519 {
00520 stp_put16_be(privdata.block_min_x, v);
00521 stp_put16_be(privdata.block_min_y, v);
00522 stp_put16_be(privdata.block_max_x - privdata.block_min_x + 1, v);
00523 stp_put16_be(privdata.block_max_y - privdata.block_min_y + 1, v);
00524 }
00525 stp_zfwrite(zero, 1, 53, v);
00526 }
00527
00528 static const char p400_adj_cyan[] =
00529 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00530 "<gimp-print>\n"
00531 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00532 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00533 "0.003922 0.031373 0.058824 0.090196 0.125490 0.156863 0.184314 0.219608\n"
00534 "0.250980 0.278431 0.309804 0.341176 0.376471 0.403922 0.439216 0.470588\n"
00535 "0.498039 0.517647 0.533333 0.545098 0.564706 0.576471 0.596078 0.615686\n"
00536 "0.627451 0.647059 0.658824 0.678431 0.690196 0.705882 0.721569 0.737255\n"
00537 "</sequence>\n"
00538 "</curve>\n"
00539 "</gimp-print>\n";
00540
00541 static const char p400_adj_magenta[] =
00542 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00543 "<gimp-print>\n"
00544 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00545 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00546 "0.003922 0.031373 0.062745 0.098039 0.125490 0.156863 0.188235 0.215686\n"
00547 "0.250980 0.282353 0.309804 0.345098 0.376471 0.407843 0.439216 0.470588\n"
00548 "0.501961 0.521569 0.549020 0.572549 0.592157 0.619608 0.643137 0.662745\n"
00549 "0.682353 0.713725 0.737255 0.756863 0.784314 0.807843 0.827451 0.850980\n"
00550 "</sequence>\n"
00551 "</curve>\n"
00552 "</gimp-print>\n";
00553
00554 static const char p400_adj_yellow[] =
00555 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00556 "<gimp-print>\n"
00557 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00558 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00559 "0.003922 0.027451 0.054902 0.090196 0.121569 0.156863 0.184314 0.215686\n"
00560 "0.250980 0.282353 0.309804 0.345098 0.372549 0.400000 0.435294 0.466667\n"
00561 "0.498039 0.525490 0.552941 0.580392 0.607843 0.631373 0.658824 0.678431\n"
00562 "0.698039 0.725490 0.760784 0.784314 0.811765 0.839216 0.866667 0.890196\n"
00563 "</sequence>\n"
00564 "</curve>\n"
00565 "</gimp-print>\n";
00566
00567
00568
00569 static const olymp_pagesize_t p440_page[] =
00570 {
00571 { "A4", NULL, -1, -1, 10, 9, 54, 54},
00572 { "c8x10", "A5 wide", -1, -1, 58, 59, 72, 72},
00573 { "C6", "2 Postcards (A4)", -1, -1, 9, 9, 9, 9},
00574 { "w255h581", "A6 wide", -1, -1, 25, 25, 25, 24},
00575 { "Custom", NULL, -1, -1, 22, 22, 54, 54},
00576 };
00577
00578 static const olymp_pagesize_list_t p440_page_list =
00579 {
00580 p440_page, sizeof(p440_page) / sizeof(olymp_pagesize_t)
00581 };
00582
00583 static const olymp_printsize_t p440_printsize[] =
00584 {
00585 { "314x314", "A4", 2508, 3200},
00586 { "314x314", "c8x10", 2000, 2508},
00587 { "314x314", "C6", 1328, 1920},
00588 { "314x314", "w255h581", 892, 2320},
00589 { "314x314", "Custom", 2508, 3200},
00590 };
00591
00592 static const olymp_printsize_list_t p440_printsize_list =
00593 {
00594 p440_printsize, sizeof(p440_printsize) / sizeof(olymp_printsize_t)
00595 };
00596
00597 static void p440_printer_init_func(stp_vars_t *v)
00598 {
00599 int wide = ! (strcmp(privdata.pagesize, "A4") == 0
00600 || strcmp(privdata.pagesize, "Custom") == 0);
00601
00602 stp_zprintf(v, "\033FP"); stp_zfwrite(zero, 1, 61, v);
00603 stp_zprintf(v, "\033Y");
00604 stp_zfwrite((privdata.laminate->seq).data, 1,
00605 (privdata.laminate->seq).bytes, v);
00606 stp_zfwrite(zero, 1, 61, v);
00607 stp_zprintf(v, "\033FC"); stp_zfwrite(zero, 1, 61, v);
00608 stp_zprintf(v, "\033ZF");
00609 stp_putc((wide ? '\x40' : '\x00'), v); stp_zfwrite(zero, 1, 60, v);
00610 stp_zprintf(v, "\033N\1"); stp_zfwrite(zero, 1, 61, v);
00611 stp_zprintf(v, "\033ZS");
00612 if (wide)
00613 {
00614 stp_put16_be(privdata.ysize, v);
00615 stp_put16_be(privdata.xsize, v);
00616 }
00617 else
00618 {
00619 stp_put16_be(privdata.xsize, v);
00620 stp_put16_be(privdata.ysize, v);
00621 }
00622 stp_zfwrite(zero, 1, 57, v);
00623 if (strcmp(privdata.pagesize, "C6") == 0)
00624 {
00625 stp_zprintf(v, "\033ZC"); stp_zfwrite(zero, 1, 61, v);
00626 }
00627 }
00628
00629 static void p440_printer_end_func(stp_vars_t *v)
00630 {
00631 stp_zprintf(v, "\033P"); stp_zfwrite(zero, 1, 62, v);
00632 }
00633
00634 static void p440_block_init_func(stp_vars_t *v)
00635 {
00636 int wide = ! (strcmp(privdata.pagesize, "A4") == 0
00637 || strcmp(privdata.pagesize, "Custom") == 0);
00638
00639 stp_zprintf(v, "\033ZT");
00640 if (wide)
00641 {
00642 stp_put16_be(privdata.ysize - privdata.block_max_y - 1, v);
00643 stp_put16_be(privdata.xsize - privdata.block_max_x - 1, v);
00644 stp_put16_be(privdata.block_max_y - privdata.block_min_y + 1, v);
00645 stp_put16_be(privdata.block_max_x - privdata.block_min_x + 1, v);
00646 }
00647 else
00648 {
00649 stp_put16_be(privdata.block_min_x, v);
00650 stp_put16_be(privdata.block_min_y, v);
00651 stp_put16_be(privdata.block_max_x - privdata.block_min_x + 1, v);
00652 stp_put16_be(privdata.block_max_y - privdata.block_min_y + 1, v);
00653 }
00654 stp_zfwrite(zero, 1, 53, v);
00655 }
00656
00657 static void p440_block_end_func(stp_vars_t *v)
00658 {
00659 int pad = (64 - (((privdata.block_max_x - privdata.block_min_x + 1)
00660 * (privdata.block_max_y - privdata.block_min_y + 1) * 3) % 64)) % 64;
00661 stp_deprintf(STP_DBG_OLYMPUS,
00662 "olympus: max_x %d min_x %d max_y %d min_y %d\n",
00663 privdata.block_max_x, privdata.block_min_x,
00664 privdata.block_max_y, privdata.block_min_y);
00665 stp_deprintf(STP_DBG_OLYMPUS, "olympus: olympus-p440 padding=%d\n", pad);
00666 stp_zfwrite(zero, 1, pad, v);
00667 }
00668
00669
00670
00671 static const olymp_pagesize_t cpx00_page[] =
00672 {
00673 { "Postcard", "Postcard 148x100mm", -1, -1, 13, 13, 16, 18},
00674 { "w253h337", "CP_L 89x119mm", -1, -1, 13, 13, 15, 15},
00675 { "w244h155", "Card 54x86mm", -1, -1, 15, 15, 13, 13},
00676 { "Custom", NULL, -1, -1, 13, 13, 16, 18},
00677 };
00678
00679 static const olymp_pagesize_list_t cpx00_page_list =
00680 {
00681 cpx00_page, sizeof(cpx00_page) / sizeof(olymp_pagesize_t)
00682 };
00683
00684 static const olymp_printsize_t cpx00_printsize[] =
00685 {
00686 { "314x314", "Postcard", 1232, 1808},
00687 { "314x314", "w253h337", 1100, 1456},
00688 { "314x314", "w244h155", 1040, 672},
00689 { "314x314", "Custom", 1232, 1808},
00690 };
00691
00692 static const olymp_printsize_list_t cpx00_printsize_list =
00693 {
00694 cpx00_printsize, sizeof(cpx00_printsize) / sizeof(olymp_printsize_t)
00695 };
00696
00697 static void cpx00_printer_init_func(stp_vars_t *v)
00698 {
00699 char pg = (strcmp(privdata.pagesize, "Postcard") == 0 ? '\1' :
00700 (strcmp(privdata.pagesize, "w253h337") == 0 ? '\2' :
00701 (strcmp(privdata.pagesize, "w244h155") == 0 ? '\3' :
00702 (strcmp(privdata.pagesize, "w283h566") == 0 ? '\4' :
00703 '\1' ))));
00704
00705 stp_put16_be(0x4000, v);
00706 stp_putc('\0', v);
00707 stp_putc(pg, v);
00708 stp_zfwrite(zero, 1, 8, v);
00709 }
00710
00711 static void cpx00_plane_init_func(stp_vars_t *v)
00712 {
00713 stp_put16_be(0x4001, v);
00714 stp_put16_le(3 - privdata.plane, v);
00715 stp_put32_le(privdata.xsize * privdata.ysize, v);
00716 stp_zfwrite(zero, 1, 4, v);
00717 }
00718
00719 static const char cpx00_adj_cyan[] =
00720 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00721 "<gimp-print>\n"
00722 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00723 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00724 "0.000000 0.035294 0.070588 0.101961 0.117647 0.168627 0.180392 0.227451\n"
00725 "0.258824 0.286275 0.317647 0.341176 0.376471 0.411765 0.427451 0.478431\n"
00726 "0.505882 0.541176 0.576471 0.611765 0.654902 0.678431 0.705882 0.737255\n"
00727 "0.764706 0.792157 0.811765 0.839216 0.862745 0.894118 0.909804 0.925490\n"
00728 "</sequence>\n"
00729 "</curve>\n"
00730 "</gimp-print>\n";
00731
00732 static const char cpx00_adj_magenta[] =
00733 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00734 "<gimp-print>\n"
00735 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00736 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00737 "0.011765 0.019608 0.035294 0.047059 0.054902 0.101961 0.133333 0.156863\n"
00738 "0.192157 0.235294 0.274510 0.321569 0.360784 0.403922 0.443137 0.482353\n"
00739 "0.521569 0.549020 0.584314 0.619608 0.658824 0.705882 0.749020 0.792157\n"
00740 "0.831373 0.890196 0.933333 0.964706 0.988235 0.992157 0.992157 0.996078\n"
00741 "</sequence>\n"
00742 "</curve>\n"
00743 "</gimp-print>\n";
00744
00745 static const char cpx00_adj_yellow[] =
00746 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00747 "<gimp-print>\n"
00748 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00749 "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n"
00750 "0.003922 0.015686 0.015686 0.023529 0.027451 0.054902 0.094118 0.129412\n"
00751 "0.180392 0.219608 0.250980 0.286275 0.317647 0.341176 0.388235 0.427451\n"
00752 "0.470588 0.509804 0.552941 0.596078 0.627451 0.682353 0.768627 0.796078\n"
00753 "0.890196 0.921569 0.949020 0.968627 0.984314 0.992157 0.992157 1.000000\n"
00754 "</sequence>\n"
00755 "</curve>\n"
00756 "</gimp-print>\n";
00757
00758
00759
00760 static const olymp_pagesize_t cp220_page[] =
00761 {
00762 { "Postcard", "Postcard 148x100mm", -1, -1, 13, 13, 16, 18},
00763 { "w253h337", "CP_L 89x119mm", -1, -1, 13, 13, 15, 15},
00764 { "w244h155", "Card 54x86mm", -1, -1, 15, 15, 13, 13},
00765 { "w283h566", "Wide 200x100mm", -1, -1, 13, 13, 20, 20},
00766 { "Custom", NULL, -1, -1, 13, 13, 16, 18},
00767 };
00768
00769 static const olymp_pagesize_list_t cp220_page_list =
00770 {
00771 cp220_page, sizeof(cp220_page) / sizeof(olymp_pagesize_t)
00772 };
00773
00774 static const olymp_printsize_t cp220_printsize[] =
00775 {
00776 { "314x314", "Postcard", 1232, 1808},
00777 { "314x314", "w253h337", 1100, 1456},
00778 { "314x314", "w244h155", 1040, 672},
00779 { "314x314", "w283h566", 1232, 2416},
00780 { "314x314", "Custom", 1232, 1808},
00781 };
00782
00783 static const olymp_printsize_list_t cp220_printsize_list =
00784 {
00785 cp220_printsize, sizeof(cp220_printsize) / sizeof(olymp_printsize_t)
00786 };
00787
00788
00789
00790 static const olymp_resolution_t updp10_res[] =
00791 {
00792 { "300x300", 300, 300},
00793 };
00794
00795 static const olymp_resolution_list_t updp10_res_list =
00796 {
00797 updp10_res, sizeof(updp10_res) / sizeof(olymp_resolution_t)
00798 };
00799
00800 static const olymp_pagesize_t updp10_page[] =
00801 {
00802 { "w288h432", "UPC-10P23 (2:3)", -1, -1, 12, 12, 18, 18},
00803 { "w288h387", "UPC-10P34 (3:4)", -1, -1, 12, 12, 16, 16},
00804 { "w288h432", "UPC-10S01 (Sticker)", -1, -1, 12, 12, 18, 18},
00805 { "Custom", NULL, -1, -1, 12, 12, 0, 0},
00806 };
00807
00808 static const olymp_pagesize_list_t updp10_page_list =
00809 {
00810 updp10_page, sizeof(updp10_page) / sizeof(olymp_pagesize_t)
00811 };
00812
00813 static const olymp_printsize_t updp10_printsize[] =
00814 {
00815 { "300x300", "w288h432", 1200, 1800},
00816 { "300x300", "w288h387", 1200, 1600},
00817 { "300x300", "Custom", 1200, 1800},
00818 };
00819
00820 static const olymp_printsize_list_t updp10_printsize_list =
00821 {
00822 updp10_printsize, sizeof(updp10_printsize) / sizeof(olymp_printsize_t)
00823 };
00824
00825 static void updp10_printer_init_func(stp_vars_t *v)
00826 {
00827 stp_zfwrite("\x98\xff\xff\xff\xff\xff\xff\xff"
00828 "\x14\x00\x00\x00\x1b\x15\x00\x00"
00829 "\x00\x0d\x00\x00\x00\x00\x00\xc7"
00830 "\x00\x00\x00\x00", 1, 28, v);
00831 stp_put16_be(privdata.xsize, v);
00832 stp_put16_be(privdata.ysize, v);
00833 stp_put32_le(privdata.xsize*privdata.ysize*3+11, v);
00834 stp_zfwrite("\x1b\xea\x00\x00\x00\x00", 1, 6, v);
00835 stp_put32_be(privdata.xsize*privdata.ysize*3, v);
00836 stp_zfwrite("\x00", 1, 1, v);
00837 }
00838
00839 static void updp10_printer_end_func(stp_vars_t *v)
00840 {
00841 stp_zfwrite("\x12\x00\x00\x00\x1b\xe1\x00\x00"
00842 "\x00\xb0\x00\x00\04", 1, 13, v);
00843 stp_zfwrite((privdata.laminate->seq).data, 1,
00844 (privdata.laminate->seq).bytes, v);
00845 stp_zfwrite("\x00\x00\x00\x00" , 1, 4, v);
00846 stp_put16_be(privdata.ysize, v);
00847 stp_put16_be(privdata.xsize, v);
00848 stp_zfwrite("\xff\xff\xff\xff\x09\x00\x00\x00"
00849 "\x1b\xee\x00\x00\x00\x02\x00\x00"
00850 "\x01\x07\x00\x00\x00\x1b\x0a\x00"
00851 "\x00\x00\x00\x00\xfd\xff\xff\xff"
00852 "\xff\xff\xff\xff\xf8\xff\xff\xff"
00853 , 1, 40, v);
00854 }
00855
00856 static const laminate_t updp10_laminate[] =
00857 {
00858 {"Glossy", N_("Glossy"), {1, "\x00"}},
00859 {"Texture", N_("Texture"), {1, "\x08"}},
00860 {"Matte", N_("Matte"), {1, "\x0c"}},
00861 };
00862
00863 static const laminate_list_t updp10_laminate_list =
00864 {
00865 updp10_laminate, sizeof(updp10_laminate) / sizeof(laminate_t)
00866 };
00867
00868 static const char updp10_adj_cyan[] =
00869 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00870 "<gimp-print>\n"
00871 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00872 "<sequence count=\"33\" lower-bound=\"0\" upper-bound=\"1\">\n"
00873 "0.113725 0.188235 0.247059 0.286275 0.317647 0.345098 0.368627 0.384314\n"
00874 "0.400000 0.407843 0.423529 0.439216 0.450980 0.466667 0.482353 0.498039\n"
00875 "0.509804 0.525490 0.545098 0.560784 0.580392 0.596078 0.619608 0.643137\n"
00876 "0.662745 0.686275 0.709804 0.729412 0.756863 0.780392 0.811765 0.843137\n"
00877 "1.000000\n"
00878 "</sequence>\n"
00879 "</curve>\n"
00880 "</gimp-print>\n";
00881
00882 static const char updp10_adj_magenta[] =
00883 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00884 "<gimp-print>\n"
00885 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00886 "<sequence count=\"33\" lower-bound=\"0\" upper-bound=\"1\">\n"
00887 "0.105882 0.211765 0.286275 0.333333 0.364706 0.388235 0.403922 0.415686\n"
00888 "0.427451 0.439216 0.450980 0.462745 0.478431 0.494118 0.505882 0.521569\n"
00889 "0.537255 0.552941 0.568627 0.584314 0.600000 0.619608 0.643137 0.662745\n"
00890 "0.682353 0.709804 0.733333 0.760784 0.792157 0.823529 0.858824 0.890196\n"
00891 "1.000000\n"
00892 "</sequence>\n"
00893 "</curve>\n"
00894 "</gimp-print>\n";
00895
00896 static const char updp10_adj_yellow[] =
00897 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00898 "<gimp-print>\n"
00899 "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n"
00900 "<sequence count=\"33\" lower-bound=\"0\" upper-bound=\"1\">\n"
00901 "0.101961 0.160784 0.196078 0.227451 0.243137 0.254902 0.266667 0.286275\n"
00902 "0.309804 0.337255 0.368627 0.396078 0.423529 0.443137 0.462745 0.478431\n"
00903 "0.501961 0.517647 0.537255 0.556863 0.576471 0.596078 0.619608 0.643137\n"
00904 "0.666667 0.690196 0.709804 0.737255 0.760784 0.780392 0.796078 0.803922\n"
00905 "1.000000\n"
00906 "</sequence>\n"
00907 "</curve>\n"
00908 "</gimp-print>\n";
00909
00910
00911
00912 static const olymp_resolution_t cx400_res[] =
00913 {
00914 { "317x316", 317, 316},
00915 };
00916
00917 static const olymp_resolution_list_t cx400_res_list =
00918 {
00919 cx400_res, sizeof(cx400_res) / sizeof(olymp_resolution_t)
00920 };
00921
00922 static const olymp_pagesize_t cx400_page[] =
00923 {
00924 { "w288h432", NULL, -1, -1, 23, 23, 28, 28},
00925 { "w288h387", "4x5 3/8 (Digital Camera 3:4)", -1, -1, 23, 23, 27, 26},
00926 { "w288h504", NULL, -1, -1, 23, 23, 23, 22},
00927 { "Custom", NULL, -1, -1, 0, 0, 0, 0},
00928 };
00929
00930 static const olymp_pagesize_list_t cx400_page_list =
00931 {
00932 cx400_page, sizeof(cx400_page) / sizeof(olymp_pagesize_t)
00933 };
00934
00935 static const olymp_printsize_t cx400_printsize[] =
00936 {
00937 { "317x316", "w288h387", 1268, 1658},
00938 { "317x316", "w288h432", 1268, 1842},
00939 { "317x316", "w288h504", 1268, 2208},
00940 { "317x316", "Custom", 1268, 1842},
00941 };
00942
00943 static const olymp_printsize_list_t cx400_printsize_list =
00944 {
00945 cx400_printsize, sizeof(cx400_printsize) / sizeof(olymp_printsize_t)
00946 };
00947
00948 static void cx400_printer_init_func(stp_vars_t *v)
00949 {
00950 char pg = '\0';
00951 const char *pname = "XXXXXX";
00952
00953 stp_deprintf(STP_DBG_OLYMPUS,
00954 "olympus: fuji driver %s\n", stp_get_driver(v));
00955 if (strcmp(stp_get_driver(v),"fujifilm-cx400") == 0)
00956 pname = "NX1000";
00957 else if (strcmp(stp_get_driver(v),"fujifilm-cx550") == 0)
00958 pname = "QX200\0";
00959
00960 stp_zfwrite("FUJIFILM", 1, 8, v);
00961 stp_zfwrite(pname, 1, 6, v);
00962 stp_putc('\0', v);
00963 stp_put16_le(privdata.xsize, v);
00964 stp_put16_le(privdata.ysize, v);
00965 if (strcmp(privdata.pagesize,"w288h504") == 0)
00966 pg = '\x0d';
00967 else if (strcmp(privdata.pagesize,"w288h432") == 0)
00968 pg = '\x0c';
00969 else if (strcmp(privdata.pagesize,"w288h387") == 0)
00970 pg = '\x0b';
00971 stp_putc(pg, v);
00972 stp_zfwrite("\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00"
00973 "\x00\x00\x2d\x00\x00\x00\x00", 1, 19, v);
00974 stp_zfwrite("FUJIFILM", 1, 8, v);
00975 stp_zfwrite(pname, 1, 6, v);
00976 stp_putc('\1', v);
00977 }
00978
00979 static const olymp_resolution_t all_resolutions[] =
00980 {
00981 { "306x306", 306, 306},
00982 { "153x153", 153, 153},
00983 { "314x314", 314, 314},
00984 { "300x300", 300, 300},
00985 { "317x316", 317, 316},
00986 { "320x320", 320, 320},
00987 };
00988
00989 static const olymp_resolution_list_t all_res_list =
00990 {
00991 all_resolutions, sizeof(all_resolutions) / sizeof(olymp_resolution_t)
00992 };
00993
00994 static const olympus_cap_t olympus_model_capabilities[] =
00995 {
00996 {
00997 2,
00998 &rgb_ink_list,
00999 &res_320dpi_list,
01000 &p10_page_list,
01001 &p10_printsize_list,
01002 OLYMPUS_INTERLACE_PLANE,
01003 1848,
01004 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_FULL_HEIGHT,
01005 &p10_printer_init_func, &p10_printer_end_func,
01006 NULL, NULL,
01007 &p10_block_init_func, NULL,
01008 NULL, NULL, NULL,
01009 &p10_laminate_list,
01010 },
01011 {
01012 4,
01013 &ymc_ink_list,
01014 &res_320dpi_list,
01015 &p200_page_list,
01016 &p200_printsize_list,
01017 OLYMPUS_INTERLACE_PLANE,
01018 1280,
01019 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_BLOCK_ALIGN,
01020 &p200_printer_init_func, &p200_printer_end_func,
01021 &p200_plane_init_func, NULL,
01022 NULL, NULL,
01023 p200_adj_any, p200_adj_any, p200_adj_any,
01024 NULL,
01025 },
01026 {
01027 0,
01028 &ymc_ink_list,
01029 &p300_res_list,
01030 &p300_page_list,
01031 &p300_printsize_list,
01032 OLYMPUS_INTERLACE_PLANE,
01033 16,
01034 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_BLOCK_ALIGN,
01035 &p300_printer_init_func, NULL,
01036 NULL, &p300_plane_end_func,
01037 &p300_block_init_func, NULL,
01038 p300_adj_cyan, p300_adj_magenta, p300_adj_yellow,
01039 NULL,
01040 },
01041 {
01042 1,
01043 &ymc_ink_list,
01044 &res_314dpi_list,
01045 &p400_page_list,
01046 &p400_printsize_list,
01047 OLYMPUS_INTERLACE_PLANE,
01048 180,
01049 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_FULL_HEIGHT,
01050 &p400_printer_init_func, NULL,
01051 &p400_plane_init_func, &p400_plane_end_func,
01052 &p400_block_init_func, NULL,
01053 p400_adj_cyan, p400_adj_magenta, p400_adj_yellow,
01054 NULL,
01055 },
01056 {
01057 3,
01058 &bgr_ink_list,
01059 &res_314dpi_list,
01060 &p440_page_list,
01061 &p440_printsize_list,
01062 OLYMPUS_INTERLACE_NONE,
01063 128,
01064 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_FULL_HEIGHT,
01065 &p440_printer_init_func, &p440_printer_end_func,
01066 NULL, NULL,
01067 &p440_block_init_func, &p440_block_end_func,
01068 NULL, NULL, NULL,
01069 &p10_laminate_list,
01070 },
01071 {
01072 1000,
01073 &ymc_ink_list,
01074 &res_314dpi_list,
01075 &cpx00_page_list,
01076 &cpx00_printsize_list,
01077 OLYMPUS_INTERLACE_PLANE,
01078 1808,
01079 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_FULL_HEIGHT
01080 | OLYMPUS_FEATURE_BORDERLESS | OLYMPUS_FEATURE_WHITE_BORDER,
01081 &cpx00_printer_init_func, NULL,
01082 &cpx00_plane_init_func, NULL,
01083 NULL, NULL,
01084 cpx00_adj_cyan, cpx00_adj_magenta, cpx00_adj_yellow,
01085 NULL,
01086 },
01087 {
01088 1001,
01089 &ymc_ink_list,
01090 &res_314dpi_list,
01091 &cp220_page_list,
01092 &cp220_printsize_list,
01093 OLYMPUS_INTERLACE_PLANE,
01094 1808,
01095 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_FULL_HEIGHT
01096 | OLYMPUS_FEATURE_BORDERLESS | OLYMPUS_FEATURE_WHITE_BORDER,
01097 &cpx00_printer_init_func, NULL,
01098 &cpx00_plane_init_func, NULL,
01099 NULL, NULL,
01100 cpx00_adj_cyan, cpx00_adj_magenta, cpx00_adj_yellow,
01101 NULL,
01102 },
01103 {
01104 2000,
01105 &cmy_ink_list,
01106 &updp10_res_list,
01107 &updp10_page_list,
01108 &updp10_printsize_list,
01109 OLYMPUS_INTERLACE_NONE,
01110 1800,
01111 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_FULL_HEIGHT
01112 | OLYMPUS_FEATURE_BORDERLESS,
01113 &updp10_printer_init_func, &updp10_printer_end_func,
01114 NULL, NULL,
01115 NULL, NULL,
01116 updp10_adj_cyan, updp10_adj_magenta, updp10_adj_yellow,
01117 &updp10_laminate_list,
01118 },
01119 {
01120 3000,
01121 &rgb_ink_list,
01122 &cx400_res_list,
01123 &cx400_page_list,
01124 &cx400_printsize_list,
01125 OLYMPUS_INTERLACE_NONE,
01126 2208,
01127 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_FULL_HEIGHT
01128 | OLYMPUS_FEATURE_BORDERLESS,
01129 &cx400_printer_init_func, NULL,
01130 NULL, NULL,
01131 NULL, NULL,
01132 NULL, NULL, NULL,
01133 NULL,
01134 },
01135 {
01136 3001,
01137 &rgb_ink_list,
01138 &cx400_res_list,
01139 &cx400_page_list,
01140 &cx400_printsize_list,
01141 OLYMPUS_INTERLACE_NONE,
01142 2208,
01143 OLYMPUS_FEATURE_FULL_WIDTH | OLYMPUS_FEATURE_FULL_HEIGHT
01144 | OLYMPUS_FEATURE_BORDERLESS,
01145 &cx400_printer_init_func, NULL,
01146 NULL, NULL,
01147 NULL, NULL,
01148 NULL, NULL, NULL,
01149 NULL,
01150 },
01151 };
01152
01153 static const stp_parameter_t the_parameters[] =
01154 {
01155 {
01156 "PageSize", N_("Page Size"), N_("Basic Printer Setup"),
01157 N_("Size of the paper being printed to"),
01158 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
01159 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01160 },
01161 {
01162 "MediaType", N_("Media Type"), N_("Basic Printer Setup"),
01163 N_("Type of media (plain paper, photo paper, etc.)"),
01164 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01165 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01166 },
01167 {
01168 "InputSlot", N_("Media Source"), N_("Basic Printer Setup"),
01169 N_("Source (input slot) of the media"),
01170 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01171 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01172 },
01173 {
01174 "Resolution", N_("Resolution"), N_("Basic Printer Setup"),
01175 N_("Resolution and quality of the print"),
01176 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01177 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01178 },
01179 {
01180 "InkType", N_("Ink Type"), N_("Advanced Printer Setup"),
01181 N_("Type of ink in the printer"),
01182 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01183 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01184 },
01185 {
01186 "Laminate", N_("Laminate Pattern"), N_("Advanced Printer Setup"),
01187 N_("Laminate Pattern"),
01188 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01189 STP_PARAMETER_LEVEL_BASIC, 1, 0, -1, 1, 0
01190 },
01191 {
01192 "Borderless", N_("Borderless"), N_("Advanced Printer Setup"),
01193 N_("Print without borders"),
01194 STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE,
01195 STP_PARAMETER_LEVEL_BASIC, 1, 0, -1, 1, 0
01196 },
01197 {
01198 "PrintingMode", N_("Printing Mode"), N_("Core Parameter"),
01199 N_("Printing Output Mode"),
01200 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
01201 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01202 },
01203 };
01204
01205 static int the_parameter_count =
01206 sizeof(the_parameters) / sizeof(const stp_parameter_t);
01207
01208 typedef struct
01209 {
01210 const stp_parameter_t param;
01211 double min;
01212 double max;
01213 double defval;
01214 int color_only;
01215 } float_param_t;
01216
01217 static const float_param_t float_parameters[] =
01218 {
01219 {
01220 {
01221 "CyanDensity", N_("Cyan Balance"), N_("Output Level Adjustment"),
01222 N_("Adjust the cyan balance"),
01223 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01224 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 1, 1, 0
01225 }, 0.0, 2.0, 1.0, 1
01226 },
01227 {
01228 {
01229 "MagentaDensity", N_("Magenta Balance"), N_("Output Level Adjustment"),
01230 N_("Adjust the magenta balance"),
01231 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01232 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 2, 1, 0
01233 }, 0.0, 2.0, 1.0, 1
01234 },
01235 {
01236 {
01237 "YellowDensity", N_("Yellow Balance"), N_("Output Level Adjustment"),
01238 N_("Adjust the yellow balance"),
01239 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01240 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 3, 1, 0
01241 }, 0.0, 2.0, 1.0, 1
01242 },
01243 {
01244 {
01245 "BlackDensity", N_("Black Balance"), N_("Output Level Adjustment"),
01246 N_("Adjust the black balance"),
01247 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01248 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 0, 1, 0
01249 }, 0.0, 2.0, 1.0, 1
01250 },
01251 };
01252
01253 static const int float_parameter_count =
01254 sizeof(float_parameters) / sizeof(const float_param_t);
01255
01256 static const olympus_cap_t* olympus_get_model_capabilities(int model)
01257 {
01258 int i;
01259 int models = sizeof(olympus_model_capabilities) / sizeof(olympus_cap_t);
01260
01261 for (i=0; i<models; i++)
01262 {
01263 if (olympus_model_capabilities[i].model == model)
01264 return &(olympus_model_capabilities[i]);
01265 }
01266 stp_deprintf(STP_DBG_OLYMPUS,
01267 "olympus: model %d not found in capabilities list.\n", model);
01268 return &(olympus_model_capabilities[0]);
01269 }
01270
01271 static const laminate_t* olympus_get_laminate_pattern(stp_vars_t *v)
01272 {
01273 const char *lpar = stp_get_string_parameter(v, "Laminate");
01274 const olympus_cap_t *caps = olympus_get_model_capabilities(
01275 stp_get_model_id(v));
01276 const laminate_list_t *llist = caps->laminate;
01277 const laminate_t *l = NULL;
01278 int i;
01279
01280 for (i = 0; i < llist->n_items; i++)
01281 {
01282 l = &(llist->item[i]);
01283 if (strcmp(l->name, lpar) == 0)
01284 break;
01285 }
01286 return l;
01287 }
01288
01289 static void
01290 olympus_printsize(const stp_vars_t *v,
01291 int *width,
01292 int *height)
01293 {
01294 int i;
01295 const char *page = stp_get_string_parameter(v, "PageSize");
01296 const char *resolution = stp_get_string_parameter(v, "Resolution");
01297 const olympus_cap_t *caps = olympus_get_model_capabilities(
01298 stp_get_model_id(v));
01299 const olymp_printsize_list_t *p = caps->printsize;
01300
01301 for (i = 0; i < p->n_items; i++)
01302 {
01303 if (strcmp(p->item[i].res_name,resolution) == 0 &&
01304 strcmp(p->item[i].pagesize_name,page) == 0)
01305 {
01306 *width = p->item[i].width_px;
01307 *height = p->item[i].height_px;
01308 return;
01309 }
01310 }
01311 stp_erprintf("olympus_printsize: printsize not found (%s, %s)\n",
01312 page, resolution);
01313 }
01314
01315 static int
01316 olympus_feature(const olympus_cap_t *caps, int feature)
01317 {
01318 return ((caps->features & feature) == feature);
01319 }
01320
01321 static stp_parameter_list_t
01322 olympus_list_parameters(const stp_vars_t *v)
01323 {
01324 stp_parameter_list_t *ret = stp_parameter_list_create();
01325 int i;
01326
01327 for (i = 0; i < the_parameter_count; i++)
01328 stp_parameter_list_add_param(ret, &(the_parameters[i]));
01329 for (i = 0; i < float_parameter_count; i++)
01330 stp_parameter_list_add_param(ret, &(float_parameters[i].param));
01331 return ret;
01332 }
01333
01334 static void
01335 olympus_parameters(const stp_vars_t *v, const char *name,
01336 stp_parameter_t *description)
01337 {
01338 int i;
01339 const olympus_cap_t *caps = olympus_get_model_capabilities(
01340 stp_get_model_id(v));
01341
01342 description->p_type = STP_PARAMETER_TYPE_INVALID;
01343 if (name == NULL)
01344 return;
01345
01346 description->deflt.str = NULL;
01347 for (i = 0; i < float_parameter_count; i++)
01348 if (strcmp(name, float_parameters[i].param.name) == 0)
01349 {
01350 stp_fill_parameter_settings(description,
01351 &(float_parameters[i].param));
01352 description->deflt.dbl = float_parameters[i].defval;
01353 description->bounds.dbl.upper = float_parameters[i].max;
01354 description->bounds.dbl.lower = float_parameters[i].min;
01355 }
01356
01357 for (i = 0; i < the_parameter_count; i++)
01358 if (strcmp(name, the_parameters[i].name) == 0)
01359 {
01360 stp_fill_parameter_settings(description, &(the_parameters[i]));
01361 break;
01362 }
01363 if (strcmp(name, "PageSize") == 0)
01364 {
01365 int default_specified = 0;
01366 const olymp_pagesize_list_t *p = caps->pages;
01367 const char* text;
01368
01369 description->bounds.str = stp_string_list_create();
01370 for (i = 0; i < p->n_items; i++)
01371 {
01372 const stp_papersize_t *pt = stp_get_papersize_by_name(
01373 p->item[i].name);
01374
01375 text = (p->item[i].text ? p->item[i].text : pt->text);
01376 stp_string_list_add_string(description->bounds.str,
01377 p->item[i].name, text);
01378 if (! default_specified && pt && pt->width > 0 && pt->height > 0)
01379 {
01380 description->deflt.str = p->item[i].name;
01381 default_specified = 1;
01382 }
01383 }
01384 if (!default_specified)
01385 description->deflt.str =
01386 stp_string_list_param(description->bounds.str, 0)->name;
01387 }
01388 else if (strcmp(name, "MediaType") == 0)
01389 {
01390 description->bounds.str = stp_string_list_create();
01391 description->is_active = 0;
01392 }
01393 else if (strcmp(name, "InputSlot") == 0)
01394 {
01395 description->bounds.str = stp_string_list_create();
01396 description->is_active = 0;
01397 }
01398 else if (strcmp(name, "Resolution") == 0)
01399 {
01400 char res_text[24];
01401 const olymp_resolution_list_t *r = caps->resolution;
01402
01403 description->bounds.str = stp_string_list_create();
01404 for (i = 0; i < r->n_items; i++)
01405 {
01406 sprintf(res_text, "%s DPI", r->item[i].name);
01407 stp_string_list_add_string(description->bounds.str,
01408 r->item[i].name, _(res_text));
01409 }
01410 if (r->n_items < 1)
01411 description->is_active = 0;
01412 description->deflt.str =
01413 stp_string_list_param(description->bounds.str, 0)->name;
01414 }
01415 else if (strcmp(name, "InkType") == 0)
01416 {
01417 description->bounds.str = stp_string_list_create();
01418 for (i = 0; i < caps->inks->n_items; i++)
01419 stp_string_list_add_string(description->bounds.str,
01420 caps->inks->item[i].name, caps->inks->item[i].name);
01421 description->deflt.str =
01422 stp_string_list_param(description->bounds.str, 0)->name;
01423 if (caps->inks->n_items < 2)
01424 description->is_active = 0;
01425 }
01426 else if (strcmp(name, "Laminate") == 0)
01427 {
01428 description->bounds.str = stp_string_list_create();
01429 if (caps->laminate)
01430 {
01431 const laminate_list_t *llist = caps->laminate;
01432
01433 for (i = 0; i < llist->n_items; i++)
01434 {
01435 const laminate_t *l = &(llist->item[i]);
01436 stp_string_list_add_string(description->bounds.str,
01437 l->name, l->text);
01438 }
01439 description->deflt.str =
01440 stp_string_list_param(description->bounds.str, 0)->name;
01441 description->is_active = 1;
01442 }
01443 }
01444 else if (strcmp(name, "Borderless") == 0)
01445 {
01446 if (olympus_feature(caps, OLYMPUS_FEATURE_BORDERLESS))
01447 description->is_active = 1;
01448 }
01449 else if (strcmp(name, "PrintingMode") == 0)
01450 {
01451 description->bounds.str = stp_string_list_create();
01452 stp_string_list_add_string
01453 (description->bounds.str, "Color", _("Color"));
01454 description->deflt.str =
01455 stp_string_list_param(description->bounds.str, 0)->name;
01456 }
01457 else
01458 description->is_active = 0;
01459 }
01460
01461
01462 static void
01463 olympus_imageable_area(const stp_vars_t *v,
01464 int *left,
01465 int *right,
01466 int *bottom,
01467 int *top)
01468 {
01469 int width, height;
01470 int i;
01471 const char *page = stp_get_string_parameter(v, "PageSize");
01472 const stp_papersize_t *pt = stp_get_papersize_by_name(page);
01473 const olympus_cap_t *caps = olympus_get_model_capabilities(
01474 stp_get_model_id(v));
01475 const olymp_pagesize_list_t *p = caps->pages;
01476
01477 for (i = 0; i < p->n_items; i++)
01478 {
01479 if (strcmp(p->item[i].name,pt->name) == 0)
01480 {
01481
01482
01483
01484
01485
01486
01487
01488 stp_default_media_size(v, &width, &height);
01489
01490
01491 if (olympus_feature(caps, OLYMPUS_FEATURE_BORDERLESS)
01492 && stp_get_boolean_parameter(v, "Borderless"))
01493 {
01494 *left = 0;
01495 *top = 0;
01496 *right = width;
01497 *bottom = height;
01498 }
01499 else
01500 {
01501 *left = p->item[i].border_pt_left;
01502 *top = p->item[i].border_pt_top;
01503 *right = width - p->item[i].border_pt_right;
01504 *bottom = height - p->item[i].border_pt_bottom;
01505 }
01506 break;
01507 }
01508 }
01509 }
01510
01511 static void
01512 olympus_limit(const stp_vars_t *v,
01513 int *width, int *height,
01514 int *min_width, int *min_height)
01515 {
01516 *width = 65535;
01517 *height = 65535;
01518 *min_width = 1;
01519 *min_height = 1;
01520 }
01521
01522 static void
01523 olympus_describe_resolution(const stp_vars_t *v, int *x, int *y)
01524 {
01525 const char *resolution = stp_get_string_parameter(v, "Resolution");
01526 int i;
01527
01528 *x = -1;
01529 *y = -1;
01530 if (resolution)
01531 {
01532 for (i = 0; i < all_res_list.n_items; i++)
01533 {
01534 if (strcmp(resolution, all_res_list.item[i].name) == 0)
01535 {
01536 *x = all_res_list.item[i].xdpi;
01537 *y = all_res_list.item[i].ydpi;
01538 }
01539 }
01540 }
01541 return;
01542 }
01543
01544 static const char *
01545 olympus_describe_output(const stp_vars_t *v)
01546 {
01547 return "CMY";
01548 }
01549
01550 static unsigned short *
01551 olympus_get_cached_output(stp_vars_t *v,
01552 stp_image_t *image,
01553 unsigned short **cache,
01554 int line, int size)
01555 {
01556 unsigned zero_mask;
01557
01558 stp_deprintf(STP_DBG_OLYMPUS, "olympus: get row %d", line);
01559 if (cache[line] == NULL)
01560 {
01561 stp_deprintf(STP_DBG_OLYMPUS, " (calling stp_color_get_row())\n");
01562 if (!stp_color_get_row(v, image, line, &zero_mask))
01563 {
01564 cache[line] = stp_malloc(size);
01565 memcpy(cache[line], stp_channel_get_output(v), size);
01566 }
01567 }
01568 else
01569 {
01570 stp_deprintf(STP_DBG_OLYMPUS, " (cached)\n");
01571 }
01572 return cache[line];
01573 }
01574
01575
01576
01577
01578 static int
01579 olympus_do_print(stp_vars_t *v, stp_image_t *image)
01580 {
01581 int i, j;
01582 int y, min_y, max_y;
01583 int min_x, max_x;
01584 int out_channels, out_bytes;
01585 unsigned short *final_out = NULL;
01586 unsigned char *char_out = NULL;
01587 unsigned short *real_out = NULL;
01588 unsigned short *err_out = NULL;
01589 unsigned short **rows = NULL;
01590 int char_out_width;
01591 int status = 1;
01592 int ink_channels = 1;
01593 const char *ink_order = NULL;
01594 stp_curve_t *adjustment = NULL;
01595
01596 int r_errdiv, r_errmod;
01597 int r_errval = 0;
01598 int r_errlast = -1;
01599 int r_errline = 0;
01600 int c_errdiv, c_errmod;
01601 int c_errval = 0;
01602 int c_errlast = -1;
01603 int c_errcol = 0;
01604
01605 const int model = stp_get_model_id(v);
01606 const char *ink_type = stp_get_string_parameter(v, "InkType");
01607 const olympus_cap_t *caps = olympus_get_model_capabilities(model);
01608 int max_print_px_width, max_print_px_height;
01609 int xdpi, ydpi;
01610
01611
01612 int image_px_width;
01613 int image_px_height;
01614
01615
01616 int out_pt_width = stp_get_width(v);
01617 int out_pt_height = stp_get_height(v);
01618 int out_pt_left = stp_get_left(v);
01619 int out_pt_top = stp_get_top(v);
01620
01621
01622 int out_px_width, out_px_height;
01623 int out_px_left, out_px_right, out_px_top, out_px_bottom;
01624
01625
01626 int page_pt_width = stp_get_page_width(v);
01627 int page_pt_height = stp_get_page_height(v);
01628 int page_pt_left = 0;
01629 int page_pt_right = 0;
01630 int page_pt_top = 0;
01631 int page_pt_bottom = 0;
01632
01633
01634 int print_px_width;
01635 int print_px_height;
01636
01637 int pl;
01638 unsigned char *zeros = NULL;
01639
01640 if (!stp_verify(v))
01641 {
01642 stp_eprintf(v, _("Print options not verified; cannot print.\n"));
01643 return 0;
01644 }
01645
01646 stp_image_init(image);
01647 image_px_width = stp_image_width(image);
01648 image_px_height = stp_image_height(image);
01649
01650 stp_describe_resolution(v, &xdpi, &ydpi);
01651 olympus_printsize(v, &max_print_px_width, &max_print_px_height);
01652
01653 privdata.pagesize = stp_get_string_parameter(v, "PageSize");
01654 if (caps->laminate)
01655 privdata.laminate = olympus_get_laminate_pattern(v);
01656
01657 if (olympus_feature(caps, OLYMPUS_FEATURE_WHITE_BORDER))
01658 stp_default_media_size(v, &page_pt_right, &page_pt_bottom);
01659 else
01660 olympus_imageable_area(v, &page_pt_left, &page_pt_right,
01661 &page_pt_bottom, &page_pt_top);
01662
01663 print_px_width = MIN(max_print_px_width,
01664 (page_pt_right - page_pt_left) * xdpi / 72);
01665 print_px_height = MIN(max_print_px_height,
01666 (page_pt_bottom - page_pt_top) * ydpi / 72);
01667 out_px_width = out_pt_width * xdpi / 72;
01668 out_px_height = out_pt_height * ydpi / 72;
01669
01670
01671
01672 if (out_px_width - image_px_width > -5
01673 && out_px_width - image_px_width < 5
01674 && out_px_height - image_px_height > -5
01675 && out_px_height - image_px_height < 5)
01676 {
01677 out_px_width = image_px_width;
01678 out_px_height = image_px_height;
01679 }
01680
01681 out_px_width = MIN(out_px_width, print_px_width);
01682 out_px_height = MIN(out_px_height, print_px_height);
01683 out_px_left = MIN(((out_pt_left - page_pt_left) * xdpi / 72),
01684 print_px_width - out_px_width);
01685 out_px_top = MIN(((out_pt_top - page_pt_top) * ydpi / 72),
01686 print_px_height - out_px_height);
01687 out_px_right = out_px_left + out_px_width;
01688 out_px_bottom = out_px_top + out_px_height;
01689
01690
01691 stp_deprintf(STP_DBG_OLYMPUS,
01692 "paper (pt) %d x %d\n"
01693 "image (px) %d x %d\n"
01694 "image (pt) %d x %d\n"
01695 "* out (pt) %d x %d\n"
01696 "* out (px) %d x %d\n"
01697 "* left x top (pt) %d x %d\n"
01698 "* left x top (px) %d x %d\n"
01699 "border (pt) (%d - %d) = %d x (%d - %d) = %d\n"
01700 "printable pixels (px) %d x %d\n"
01701 "res (dpi) %d x %d\n",
01702 page_pt_width, page_pt_height,
01703 image_px_width, image_px_height,
01704 image_px_width * 72 / xdpi, image_px_height * 72 / ydpi,
01705 out_pt_width, out_pt_height,
01706 out_px_width, out_px_height,
01707 out_pt_left, out_pt_top,
01708 out_px_left, out_px_top,
01709 page_pt_right, page_pt_left, page_pt_right - page_pt_left,
01710 page_pt_bottom, page_pt_top, page_pt_bottom - page_pt_top,
01711 print_px_width, print_px_height,
01712 xdpi, ydpi
01713 );
01714
01715 privdata.xdpi = xdpi;
01716 privdata.ydpi = ydpi;
01717 privdata.xsize = print_px_width;
01718 privdata.ysize = print_px_height;
01719
01720 stp_set_string_parameter(v, "STPIOutputType", "CMY");
01721
01722 if (caps->adj_cyan &&
01723 !stp_check_curve_parameter(v, "CyanCurve", STP_PARAMETER_ACTIVE))
01724 {
01725 adjustment = stp_curve_create_from_string(caps->adj_cyan);
01726 stp_set_curve_parameter(v, "CyanCurve", adjustment);
01727 stp_set_curve_parameter_active(v, "CyanCurve", STP_PARAMETER_ACTIVE);
01728 stp_curve_destroy(adjustment);
01729 }
01730 if (caps->adj_magenta &&
01731 !stp_check_curve_parameter(v, "MagentaCurve", STP_PARAMETER_ACTIVE))
01732 {
01733 adjustment = stp_curve_create_from_string(caps->adj_magenta);
01734 stp_set_curve_parameter(v, "MagentaCurve", adjustment);
01735 stp_set_curve_parameter_active(v, "MagentaCurve", STP_PARAMETER_ACTIVE);
01736 stp_curve_destroy(adjustment);
01737 }
01738 if (caps->adj_yellow &&
01739 !stp_check_curve_parameter(v, "YellowCurve", STP_PARAMETER_ACTIVE))
01740 {
01741 adjustment = stp_curve_create_from_string(caps->adj_yellow);
01742 stp_set_curve_parameter(v, "YellowCurve", adjustment);
01743 stp_set_curve_parameter_active(v, "YellowCurve", STP_PARAMETER_ACTIVE);
01744 stp_curve_destroy(adjustment);
01745 }
01746
01747 if (ink_type)
01748 {
01749 for (i = 0; i < caps->inks->n_items; i++)
01750 if (strcmp(ink_type, caps->inks->item[i].name) == 0)
01751 {
01752 stp_set_string_parameter(v, "STPIOutputType",
01753 caps->inks->item[i].output_type);
01754 ink_channels = caps->inks->item[i].output_channels;
01755 ink_order = caps->inks->item[i].channel_order;
01756 break;
01757 }
01758 }
01759
01760 stp_channel_reset(v);
01761 for (i = 0; i < ink_channels; i++)
01762 stp_channel_add(v, i, 0, 1.0);
01763
01764 out_channels = stp_color_init(v, image, 65536);
01765
01766 #if 0
01767 if (out_channels != ink_channels && out_channels != 1 && ink_channels != 1)
01768 {
01769 stp_eprintf(v, "Internal error! Output channels or input channels must be 1\n");
01770 return 0;
01771 }
01772 #endif
01773
01774 rows = stp_zalloc(image_px_height * sizeof(unsigned short *));
01775 err_out = stp_malloc(print_px_width * ink_channels * 2);
01776 if (out_channels != ink_channels)
01777 final_out = stp_malloc(print_px_width * ink_channels * 2);
01778
01779 stp_set_float_parameter(v, "Density", 1.0);
01780
01781 if (ink_type &&
01782 (strcmp(ink_type, "RGB") == 0 || strcmp(ink_type, "BGR") == 0))
01783 {
01784 zeros = stp_malloc(ink_channels * print_px_width + 1);
01785 (void) memset(zeros, '\xff', ink_channels * print_px_width + 1);
01786 }
01787 else
01788 zeros = stp_zalloc(ink_channels * print_px_width + 1);
01789
01790 out_bytes = (caps->interlacing == OLYMPUS_INTERLACE_PLANE ? 1 : ink_channels);
01791
01792
01793 if (caps->printer_init_func)
01794 {
01795 stp_deprintf(STP_DBG_OLYMPUS, "olympus: caps->printer_init\n");
01796 (*(caps->printer_init_func))(v);
01797 }
01798
01799 if (olympus_feature(caps, OLYMPUS_FEATURE_FULL_HEIGHT))
01800 {
01801 min_y = 0;
01802 max_y = print_px_height - 1;
01803 }
01804 else if (olympus_feature(caps, OLYMPUS_FEATURE_BLOCK_ALIGN))
01805 {
01806 min_y = out_px_top - (out_px_top % caps->block_size);
01807
01808 max_y = (out_px_bottom - 1) + (caps->block_size - 1)
01809 - ((out_px_bottom - 1) % caps->block_size);
01810
01811 }
01812 else
01813 {
01814 min_y = out_px_top;
01815 max_y = out_px_bottom - 1;
01816 }
01817
01818 if (olympus_feature(caps, OLYMPUS_FEATURE_FULL_WIDTH))
01819 {
01820 min_x = 0;
01821 max_x = print_px_width - 1;
01822 }
01823 else
01824 {
01825 min_x = out_px_left;
01826 max_x = out_px_right;
01827 }
01828
01829 r_errdiv = image_px_height / out_px_height;
01830 r_errmod = image_px_height % out_px_height;
01831 c_errdiv = image_px_width / out_px_width;
01832 c_errmod = image_px_width % out_px_width;
01833
01834 for (pl = 0; pl < (caps->interlacing == OLYMPUS_INTERLACE_PLANE
01835 ? ink_channels : 1); pl++)
01836 {
01837 r_errval = 0;
01838 r_errlast = -1;
01839 r_errline = 0;
01840
01841 privdata.plane = ink_order[pl];
01842 stp_deprintf(STP_DBG_OLYMPUS, "olympus: plane %d\n", privdata.plane);
01843
01844
01845 if (caps->plane_init_func)
01846 {
01847 stp_deprintf(STP_DBG_OLYMPUS, "olympus: caps->plane_init\n");
01848 (*(caps->plane_init_func))(v);
01849 }
01850
01851 for (y = min_y; y <= max_y; y++)
01852 {
01853 unsigned short *out;
01854 int duplicate_line = 1;
01855
01856
01857 if (((y - min_y) % caps->block_size) == 0)
01858 {
01859
01860 privdata.block_min_y = y;
01861 privdata.block_min_x = min_x;
01862 privdata.block_max_y = MIN(y + caps->block_size - 1, max_y);
01863 privdata.block_max_x = max_x;
01864
01865 if (caps->block_init_func)
01866 {
01867 stp_deprintf(STP_DBG_OLYMPUS,
01868 "olympus: caps->block_init\n");
01869 (*(caps->block_init_func))(v);
01870 }
01871 }
01872
01873 if (y < out_px_top || y >= out_px_bottom)
01874 stp_zfwrite((char *) zeros, out_bytes, print_px_width, v);
01875 else
01876 {
01877 if (olympus_feature(caps, OLYMPUS_FEATURE_FULL_WIDTH)
01878 && out_px_left > 0)
01879 {
01880 stp_zfwrite((char *) zeros, out_bytes, out_px_left, v);
01881
01882 }
01883
01884 #if 0
01885 if (r_errline != r_errlast)
01886 {
01887 r_errlast = r_errline;
01888 duplicate_line = 0;
01889
01890
01891 if (stp_color_get_row(v, image, r_errline, &zero_mask))
01892 {
01893 status = 2;
01894 break;
01895 }
01896 }
01897
01898 out = stp_channel_get_output(v);
01899 #endif
01900 if (r_errline != r_errlast)
01901 {
01902 r_errlast = r_errline;
01903 duplicate_line = 0;
01904 }
01905
01906 out = olympus_get_cached_output(v, image, rows, r_errline,
01907 image_px_width * ink_channels * 2);
01908 if (out == NULL)
01909 {
01910 status = 2;
01911 break;
01912 }
01913
01914 c_errval = 0;
01915 c_errlast = -1;
01916 c_errcol = 0;
01917 for (i = 0; i < out_px_width; i++)
01918 {
01919 if (c_errcol != c_errlast)
01920 c_errlast = c_errcol;
01921 for (j = 0; j < ink_channels; j++)
01922 err_out[i * ink_channels + j] =
01923 out[c_errcol * ink_channels + ink_order[j]-1];
01924
01925 c_errval += c_errmod;
01926 c_errcol += c_errdiv;
01927 if (c_errval >= out_px_width)
01928 {
01929 c_errval -= out_px_width;
01930 c_errcol ++;
01931 }
01932 }
01933
01934 real_out = err_out;
01935 if (out_channels != ink_channels)
01936 {
01937 real_out = final_out;
01938 if (out_channels < ink_channels)
01939 {
01940 for (i = 0; i < out_px_width; i++)
01941 {
01942 for (j = 0; j < ink_channels; j++)
01943 final_out[i * ink_channels + j] = err_out[i];
01944 }
01945 }
01946 else
01947 {
01948 for (i = 0; i < out_px_width; i++)
01949 {
01950 int avg = 0;
01951 for (j = 0; j < out_channels; j++)
01952 avg += err_out[i * out_channels + j];
01953 final_out[i] = avg / out_channels;
01954 }
01955 }
01956 }
01957 char_out = (unsigned char *) real_out;
01958 char_out_width = (caps->interlacing == OLYMPUS_INTERLACE_PLANE ?
01959 out_px_width : out_px_width * out_channels);
01960 for (i = 0; i < char_out_width; i++)
01961 {
01962 if (caps->interlacing == OLYMPUS_INTERLACE_PLANE)
01963 j = i * ink_channels + pl;
01964 else if (caps->interlacing == OLYMPUS_INTERLACE_LINE)
01965 j = (i % out_px_width) + (i / out_px_width);
01966 else
01967 j = i;
01968
01969 char_out[i] = real_out[j] / 257;
01970 }
01971
01972 stp_zfwrite((char *) real_out, 1, char_out_width, v);
01973
01974 if (olympus_feature(caps, OLYMPUS_FEATURE_FULL_WIDTH)
01975 && out_px_right < print_px_width)
01976 {
01977 stp_zfwrite((char *) zeros, out_bytes,
01978 print_px_width - out_px_right, v);
01979
01980 }
01981
01982
01983 r_errval += r_errmod;
01984 r_errline += r_errdiv;
01985 if (r_errval >= out_px_height)
01986 {
01987 r_errval -= out_px_height;
01988 r_errline ++;
01989 }
01990 }
01991
01992 if (y == privdata.block_max_y)
01993 {
01994
01995 if (caps->block_end_func)
01996 {
01997 stp_deprintf(STP_DBG_OLYMPUS, "olympus: caps->block_end\n");
01998 (*(caps->block_end_func))(v);
01999 }
02000 }
02001 }
02002
02003
02004 if (caps->plane_end_func) {
02005 stp_deprintf(STP_DBG_OLYMPUS, "olympus: caps->plane_end\n");
02006 (*(caps->plane_end_func))(v);
02007 }
02008 }
02009
02010
02011 if (caps->printer_end_func)
02012 {
02013 stp_deprintf(STP_DBG_OLYMPUS, "olympus: caps->printer_end\n");
02014 (*(caps->printer_end_func))(v);
02015 }
02016 stp_image_conclude(image);
02017 if (final_out)
02018 stp_free(final_out);
02019 if (err_out)
02020 stp_free(err_out);
02021 if (zeros)
02022 stp_free(zeros);
02023 if (rows)
02024 {
02025 for (i = 0; i <image_px_height; i++)
02026 stp_free(rows[i]);
02027 stp_free(rows);
02028 }
02029 return status;
02030 }
02031
02032 static int
02033 olympus_print(const stp_vars_t *v, stp_image_t *image)
02034 {
02035 int status;
02036 stp_vars_t *nv = stp_vars_create_copy(v);
02037 stp_prune_inactive_options(nv);
02038 status = olympus_do_print(nv, image);
02039 stp_vars_destroy(nv);
02040 return status;
02041 }
02042
02043 static const stp_printfuncs_t print_olympus_printfuncs =
02044 {
02045 olympus_list_parameters,
02046 olympus_parameters,
02047 stp_default_media_size,
02048 olympus_imageable_area,
02049 olympus_limit,
02050 olympus_print,
02051 olympus_describe_resolution,
02052 olympus_describe_output,
02053 stp_verify_printer_params,
02054 NULL,
02055 NULL
02056 };
02057
02058
02059
02060
02061 static stp_family_t print_olympus_module_data =
02062 {
02063 &print_olympus_printfuncs,
02064 NULL
02065 };
02066
02067
02068 static int
02069 print_olympus_module_init(void)
02070 {
02071 return stp_family_register(print_olympus_module_data.printer_list);
02072 }
02073
02074
02075 static int
02076 print_olympus_module_exit(void)
02077 {
02078 return stp_family_unregister(print_olympus_module_data.printer_list);
02079 }
02080
02081
02082
02083 #define stp_module_version print_olympus_LTX_stp_module_version
02084 #define stp_module_data print_olympus_LTX_stp_module_data
02085
02086 stp_module_version_t stp_module_version = {0, 0};
02087
02088 stp_module_t stp_module_data =
02089 {
02090 "olympus",
02091 VERSION,
02092 "Olympus family driver",
02093 STP_MODULE_CLASS_FAMILY,
02094 NULL,
02095 print_olympus_module_init,
02096 print_olympus_module_exit,
02097 (void *) &print_olympus_module_data
02098 };
02099