summaryrefslogtreecommitdiff
path: root/src/cups/backend_mitsu70x.c
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2016-11-01 18:45:10 +0100
committerDidier Raboud <odyx@debian.org>2016-11-01 18:45:10 +0100
commit54a135b87201e48d4da4894a61b81a8c6fe46d26 (patch)
tree74b42137b1e3eb634c01cb593469dddc727cd124 /src/cups/backend_mitsu70x.c
parentd69d392d8c45cdcc93e58f0e1bdbb2b66d6b9566 (diff)
New upstream version 5.2.12~pre4
Diffstat (limited to 'src/cups/backend_mitsu70x.c')
-rw-r--r--src/cups/backend_mitsu70x.c522
1 files changed, 280 insertions, 242 deletions
diff --git a/src/cups/backend_mitsu70x.c b/src/cups/backend_mitsu70x.c
index 9a94a32..16099ba 100644
--- a/src/cups/backend_mitsu70x.c
+++ b/src/cups/backend_mitsu70x.c
@@ -35,10 +35,76 @@
#include <fcntl.h>
#include <signal.h>
+/* For Integration into gutenprint */
+#if defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#if defined(USE_DLOPEN)
+#define WITH_DYNAMIC
+#include <dlfcn.h>
+#define DL_INIT() do {} while(0)
+#define DL_OPEN(__x) dlopen(__x, RTLD_NOW)
+#define DL_SYM(__x, __y) dlsym(__x, __y)
+#define DL_CLOSE(__x) dlclose(__x)
+#define DL_EXIT() do {} while(0)
+#elif defined(USE_LTDL)
+#define WITH_DYNAMIC
+#include <ltdl.h>
+#define DL_INIT() lt_dlinit()
+#define DL_OPEN(__x) lt_dlopen(__x)
+#define DL_SYM(__x, __y) lt_dlsym(__x, __y)
+#define DL_CLOSE(__x) do {} while(0)
+#define DL_EXIT() lt_dlexit()
+#else
+#define DL_INIT() do {} while(0)
+#define DL_CLOSE(__x) do {} while(0)
+#define DL_EXIT() do {} while(0)
+#warning "No dynamic loading support!"
+#endif
+
#define BACKEND mitsu70x_backend
#include "backend_common.h"
+// #include "lib70x/libMitsuD70ImageReProcess.h"
+
+#ifndef LUT_LEN
+#define COLORCONV_RGB 0
+#define COLORCONV_BGR 1
+
+#define LUT_LEN 14739
+struct BandImage {
+ void *imgbuf;
+ int32_t bytes_per_row;
+ uint16_t origin_cols;
+ uint16_t origin_rows;
+ uint16_t cols;
+ uint16_t rows;
+};
+#endif
+
+/* Image processing library function prototypes */
+#define LIB_NAME_RE "libMitsuD70ImageReProcess.so" // Reimplemented library
+
+typedef int (*Get3DColorTableFN)(uint8_t *buf, const char *filename);
+typedef struct CColorConv3D *(*Load3DColorTableFN)(const uint8_t *ptr);
+typedef void (*Destroy3DColorTableFN)(struct CColorConv3D *this);
+typedef void (*DoColorConvFN)(struct CColorConv3D *this, uint8_t *data, uint16_t cols, uint16_t rows, uint32_t bytes_per_row, int rgb_bgr);
+typedef struct CPCData *(*get_CPCDataFN)(const char *filename);
+typedef void (*destroy_CPCDataFN)(struct CPCData *data);
+typedef int (*do_image_effectFN)(struct CPCData *cpc, struct BandImage *input, struct BandImage *output, int sharpen, uint8_t rew[2]);
+typedef int (*send_image_dataFN)(struct BandImage *out, void *context,
+ int (*callback_fn)(void *context, void *buffer, uint32_t len));
+
+#ifndef CORRTABLE_PATH
+#ifdef PACKAGE_DATA_DIR
+#define CORRTABLE_PATH PACKAGE_DATA_DIR "/backend_data"
+#else
+#error "Must define CORRTABLE_PATH or PACKAGE_DATA_DIR!"
+#endif
+#endif
+
#define USB_VID_MITSU 0x06D3
#define USB_PID_MITSU_D70X 0x3B30
#define USB_PID_MITSU_K60 0x3B31
@@ -48,15 +114,8 @@
//#define USB_VID_FUJIFILM XXXXXX
//#define USB_PID_FUJI_ASK300 XXXXXX
-//#define ENABLE_CORRTABLES
-
-#ifndef CORRTABLE_PATH
-#define CORRTABLE_PATH "D70"
-#endif
-
-#ifdef ENABLE_CORRTABLES
-#include "D70/Mitsu_D70.c"
-#endif
+/* Width of the laminate data file */
+#define LAMINATE_STRIDE 1864
/* Private data stucture */
struct mitsu70x_ctx {
@@ -80,18 +139,31 @@ struct mitsu70x_ctx {
int supports_jobs_query;
-#ifdef ENABLE_CORRTABLES
char *laminatefname;
char *lutfname;
char *cpcfname;
- struct CColorConv3D lut;
- struct CPCData cpcdata;
+ void *dl_handle;
+ Get3DColorTableFN Get3DColorTable;
+ Load3DColorTableFN Load3DColorTable;
+ Destroy3DColorTableFN Destroy3DColorTable;
+ DoColorConvFN DoColorConv;
+ get_CPCDataFN GetCPCData;
+ destroy_CPCDataFN DestroyCPCData;
+ do_image_effectFN DoImageEffect;
+ send_image_dataFN SendImageData;
+
+ struct CColorConv3D *lut;
+ struct CPCData *cpcdata;
char *last_cpcfname;
int raw_format;
-#endif
+ int sharpen; /* ie mhdr.sharpen - 1 */
+
+ uint8_t rew[2]; /* 1 for rewind ok (default!) */
+
+ struct BandImage output;
};
/* Printer data structures */
@@ -257,10 +329,13 @@ struct mitsu70x_memorystatus_resp {
uint8_t rsvd;
} __attribute__((packed));
+// XXX also seen commands 0x67, 0x72, 0x54, 0x6e
+
struct mitsu70x_hdr {
- uint8_t hdr[4]; /* 1b 5a 54 XX */
+ uint8_t hdr[4]; /* 1b 5a 54 XX */ // XXX also, seen 1b 5a 43!
uint16_t jobid;
- uint8_t zero0[10];
+ uint8_t rewind[2]; /* XXX K60/EK305/D80 only, 0 normally, 1 for "skip" ??? */
+ uint8_t zero0[8];
uint16_t cols;
uint16_t rows;
@@ -272,11 +347,12 @@ struct mitsu70x_hdr {
uint8_t deck; /* 0 = default, 1 = lower, 2 = upper */
uint8_t zero2[7];
uint8_t laminate; /* 00 == on, 01 == off */
- uint8_t laminate_mode;
+ uint8_t laminate_mode; /* 00 == glossy, 02 == matte */
uint8_t zero3[6];
uint8_t multicut;
- uint8_t zero4[13];
+ uint8_t zero4[12];
+ uint8_t sharpen; /* 0-9. 5 is "normal", 0 is "off" */
uint8_t mode; /* 0 for cooked YMC planar, 1 for packed BGR */
uint8_t use_lut; /* in BGR mode, 0 disables, 1 enables */
@@ -536,6 +612,8 @@ static void *mitsu70x_init(void)
}
memset(ctx, 0, sizeof(struct mitsu70x_ctx));
+ DL_INIT();
+
return ctx;
}
@@ -567,6 +645,36 @@ static void mitsu70x_attach(void *vctx, struct libusb_device_handle *dev,
ctx->supports_jobs_query = 0;
else
ctx->supports_jobs_query = 1;
+
+ /* Attempt to open the library */
+#if defined(WITH_DYNAMIC)
+ INFO("Attempting to load image processing library\n");
+ ctx->dl_handle = DL_OPEN(LIB_NAME_RE);
+ if (!ctx->dl_handle)
+ WARNING("Image processing library not found, using internal fallback code\n");
+ if (ctx->dl_handle) {
+ ctx->Get3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Get3DColorTable");
+ ctx->Load3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Load3DColorTable");
+ ctx->Destroy3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Destroy3DColorTable");
+ ctx->DoColorConv = DL_SYM(ctx->dl_handle, "CColorConv3D_DoColorConv");
+ ctx->GetCPCData = DL_SYM(ctx->dl_handle, "get_CPCData");
+ ctx->DestroyCPCData = DL_SYM(ctx->dl_handle, "destroy_CPCData");
+ ctx->DoImageEffect = DL_SYM(ctx->dl_handle, "do_image_effect");
+ ctx->SendImageData = DL_SYM(ctx->dl_handle, "send_image_data");
+ if (!ctx->Get3DColorTable || !ctx->Load3DColorTable ||
+ !ctx->Destroy3DColorTable || !ctx->DoColorConv ||
+ !ctx->GetCPCData || !ctx->DestroyCPCData ||
+ !ctx->DoImageEffect || !ctx->SendImageData) {
+ WARNING("Problem resolving symbols in imaging processing library\n");
+ DL_CLOSE(ctx->dl_handle);
+ ctx->dl_handle = NULL;
+ } else {
+ INFO("Image processing library successfully loaded\n");
+ }
+ }
+#else
+ WARNING("Dynamic library support not enabled, using internal fallback code\n");
+#endif
}
static void mitsu70x_teardown(void *vctx) {
@@ -578,6 +686,16 @@ static void mitsu70x_teardown(void *vctx) {
if (ctx->databuf)
free(ctx->databuf);
+ if (ctx->dl_handle) {
+ if (ctx->cpcdata)
+ ctx->DestroyCPCData(ctx->cpcdata);
+ if (ctx->lut)
+ ctx->Destroy3DColorTable(ctx->lut);
+ DL_CLOSE(ctx->dl_handle);
+ }
+
+ DL_EXIT();
+
free(ctx);
}
@@ -596,6 +714,8 @@ static int mitsu70x_read_parse(void *vctx, int data_fd) {
}
ctx->matte = 0;
+ ctx->rew[0] = 1;
+ ctx->rew[1] = 1;
repeat:
/* Read in initial header */
@@ -625,7 +745,6 @@ repeat:
return CUPS_BACKEND_CANCEL;
}
-#ifdef ENABLE_CORRTABLES
ctx->raw_format = !mhdr.mode;
/* Figure out the correction data table to use */
@@ -640,6 +759,10 @@ repeat:
} else {
ctx->cpcfname = CORRTABLE_PATH "/CPD70N01.cpc";
}
+ if (mhdr.hdr[3] != 0x01) {
+ WARNING("Print job has wrong submodel specifier (%x)\n", mhdr.hdr[3]);
+ mhdr.hdr[3] = 0x01;
+ }
} else if (ctx->type == P_MITSU_D80) {
ctx->laminatefname = CORRTABLE_PATH "/D80MAT01.raw";
ctx->lutfname = CORRTABLE_PATH "/CPD80L01.lut";
@@ -652,6 +775,10 @@ repeat:
ctx->cpcfname = CORRTABLE_PATH "/CPD80N01.cpc";
}
// XXX what about CPD80**E**01?
+ if (mhdr.hdr[3] != 0x01) {
+ WARNING("Print job has wrong submodel specifier (%x)\n", mhdr.hdr[3]);
+ mhdr.hdr[3] = 0x01;
+ }
} else if (ctx->type == P_MITSU_K60) {
ctx->laminatefname = CORRTABLE_PATH "/S60MAT02.raw";
ctx->lutfname = CORRTABLE_PATH "/CPS60L01.lut";
@@ -662,6 +789,10 @@ repeat:
} else {
ctx->cpcfname = CORRTABLE_PATH "/CPS60T01.cpc";
}
+ if (mhdr.hdr[3] != 0x00) {
+ WARNING("Print job has wrong submodel specifier (%x)\n", mhdr.hdr[3]);
+ mhdr.hdr[3] = 0x00;
+ }
} else if (ctx->type == P_KODAK_305) {
ctx->laminatefname = CORRTABLE_PATH "/EK305MAT.raw"; // Same as K60
ctx->lutfname = CORRTABLE_PATH "/EK305L01.lut";
@@ -672,7 +803,11 @@ repeat:
} else {
ctx->cpcfname = CORRTABLE_PATH "/EK305T01.cpc";
}
-
+ // XXX what about using K60 media if we read back the proper code?
+ if (mhdr.hdr[3] != 0x90) {
+ WARNING("Print job has wrong submodel specifier (%x)\n", mhdr.hdr[3]);
+ mhdr.hdr[3] = 0x90;
+ }
} else if (ctx->type == P_FUJI_ASK300) {
ctx->laminatefname = CORRTABLE_PATH "/ASK300M2.raw"; // Same as D70
ctx->lutfname = CORRTABLE_PATH "/CPD70L01.lut"; // XXX guess, driver did not come with external LUT!
@@ -682,14 +817,20 @@ repeat:
} else {
ctx->cpcfname = CORRTABLE_PATH "/ASK300T1.cpc";
}
+ if (mhdr.hdr[3] != 0x01) {
+ WARNING("Print job has wrong submodel specifier (%x)\n", mhdr.hdr[3]);
+ mhdr.hdr[3] = 0x01;
+ }
}
if (!mhdr.use_lut)
ctx->lutfname = NULL;
+ ctx->sharpen = mhdr.sharpen - 1;
+
/* Clean up header back to pristine. */
mhdr.use_lut = 0;
mhdr.mode = 0;
-#endif
+ mhdr.sharpen = 0;
/* Work out total printjob size */
ctx->cols = be16_to_cpu(mhdr.cols);
@@ -707,7 +848,8 @@ repeat:
remain = 3 * planelen + ctx->matte;
ctx->datalen = 0;
- ctx->databuf = malloc(sizeof(mhdr) + remain);
+ ctx->databuf = malloc(sizeof(mhdr) + remain + LAMINATE_STRIDE*2); /* Give us a bit extra */
+
if (!ctx->databuf) {
ERROR("Memory allocation failure!\n");
return CUPS_BACKEND_FAILED;
@@ -716,9 +858,7 @@ repeat:
memcpy(ctx->databuf + ctx->datalen, &mhdr, sizeof(mhdr));
ctx->datalen += sizeof(mhdr);
-#ifdef ENABLE_CORRTABLES
if (ctx->raw_format) { /* RAW MODE */
-#endif
DEBUG("Reading in %d bytes of 16bpp YMCL data\n", remain);
/* Read in the spool data */
@@ -731,7 +871,6 @@ repeat:
ctx->datalen += i;
remain -= i;
}
-#ifdef ENABLE_CORRTABLES
} else { /* RAW MODE OFF */
int spoolbuflen = 0;
uint8_t *spoolbuf;
@@ -757,90 +896,109 @@ repeat:
}
/* Run through basic LUT, if present and enabled */
- if (ctx->lutfname) {
+ if (ctx->dl_handle && ctx->lutfname && !ctx->lut) { /* printer-specific, it is fixed per-job */
DEBUG("Running print data through LUT\n");
uint8_t *buf = malloc(LUT_LEN);
if (!buf) {
ERROR("Memory allocation failure!\n");
return CUPS_BACKEND_FAILED;
}
- if (CColorConv3D_Get3DColorTable(buf, ctx->lutfname)) {
+ if (ctx->Get3DColorTable(buf, ctx->lutfname)) {
ERROR("Unable to open LUT file '%s'\n", ctx->lutfname);
return CUPS_BACKEND_CANCEL;
}
- CColorConv3D_Load3DColorTable(&ctx->lut, buf);
+ ctx->lut = ctx->Load3DColorTable(buf);
free(buf);
- CColorConv3D_DoColorConv(&ctx->lut, spoolbuf, ctx->cols, ctx->rows, ctx->cols * 3, 1);
- // XXX proprietary lib also does gamma+contrast+brightness
+ if (!ctx->lut) {
+ ERROR("Unable to parse LUT file '%s'!\n", ctx->lutfname);
+ return CUPS_BACKEND_CANCEL;
+ }
+ ctx->DoColorConv(ctx->lut, spoolbuf, ctx->cols, ctx->rows, ctx->cols * 3, COLORCONV_BGR);
}
/* Load in the CPC file, if needed! */
- if (ctx->cpcfname && ctx->cpcfname != ctx->last_cpcfname) {
- ctx->last_cpcfname = ctx->cpcfname;
- if (load_CPCData(&ctx->cpcdata, ctx->cpcfname)) {
- ERROR("Unable to load CPC file '%s'\n", ctx->cpcfname);
- return CUPS_BACKEND_CANCEL;
+ if (ctx->dl_handle) {
+ struct BandImage input;
+
+ if (ctx->cpcfname && ctx->cpcfname != ctx->last_cpcfname) {
+ ctx->last_cpcfname = ctx->cpcfname;
+ if (ctx->cpcdata)
+ ctx->DestroyCPCData(ctx->cpcdata);
+ ctx->cpcdata = ctx->GetCPCData(ctx->cpcfname);
+ if (!ctx->cpcdata) {
+ ERROR("Unable to load CPC file '%s'\n", ctx->cpcfname);
+ return CUPS_BACKEND_CANCEL;
+ }
}
- }
- // XXX INSERT ALGORITHM HERE...
+ /* Convert using image processing library */
- // XXX optionally CreateInkCorrectGammaTable(...)
+ input.origin_rows = input.origin_cols = 0;
+ input.rows = ctx->rows;
+ input.cols = ctx->cols;
+ input.imgbuf = spoolbuf;
+ input.bytes_per_row = ctx->cols * 3;
- /* Convert to YMC using corrtables (aka CImageEffect70::DoGamma) */
- {
- uint32_t r, c;
- uint32_t in = 0, out = 0;
+ ctx->output.origin_rows = ctx->output.origin_cols = 0;
+ ctx->output.rows = ctx->rows;
+ ctx->output.cols = ctx->cols;
+ ctx->output.imgbuf = ctx->databuf + ctx->datalen;
+ ctx->output.bytes_per_row = ctx->cols * 3 * 2;
- uint16_t *offset_y = (uint16_t*)(ctx->databuf + ctx->datalen);
- uint16_t *offset_m = offset_y + planelen/2;
- uint16_t *offset_c = offset_m + planelen/2;
-// uint16_t *offset_l = offset_c + planelen/2;
- DEBUG("Running print data through BGR->YMC table (crude)\n");
- for(r = 0 ; r < ctx->rows; r++) {
- for (c = 0 ; c < ctx->cols ; c++) {
- offset_y[out] = cpu_to_be16(ctx->cpcdata.GNMby[spoolbuf[in]]);
- offset_m[out] = cpu_to_be16(ctx->cpcdata.GNMgm[spoolbuf[in + 1]]);
- offset_c[out] = cpu_to_be16(ctx->cpcdata.GNMrc[spoolbuf[in + 2]]);
- in += 3;
- out++;
- }
+ DEBUG("Running print data through processing library\n");
+ if (ctx->DoImageEffect(ctx->cpcdata, &input, &ctx->output, ctx->sharpen, ctx->rew)) {
+ ERROR("Image Processing failed, aborting!\n");
+ return CUPS_BACKEND_CANCEL;
}
+ } else {
+ // XXXFALLBACK write fallback code?
+ ERROR("!!! Image Processing Library not found, aborting!\n");
+ return CUPS_BACKEND_CANCEL;
}
- // XXX then call CImageEffect70::DoConv(...) to do the final corrections..
- /* Move up the pointer */
+ /* Move up the pointer to after the image data */
ctx->datalen += 3*planelen;
/* Clean up */
free(spoolbuf);
- /* Now that we've filled everything in, read latte from file */
+ /* Now that we've filled everything in, read matte from file */
if (ctx->matte) {
int fd;
- DEBUG("Reading %d bytes of matte data from disk\n", ctx->matte);
+ uint32_t j;
+ DEBUG("Reading %d bytes of matte data from disk (%d/%d)\n", ctx->matte, ctx->cols, LAMINATE_STRIDE);
fd = open(ctx->laminatefname, O_RDONLY);
if (fd < 0) {
ERROR("Unable to open matte lamination data file '%s'\n", ctx->laminatefname);
return CUPS_BACKEND_CANCEL;
}
- remain = ctx->matte;
- while (remain) {
- i = read(fd, ctx->databuf + ctx->datalen, remain);
- if (i == 0) {
- /* We hit EOF, restart from beginning */
- lseek(fd, 0, SEEK_SET);
- continue;
+
+ for (j = 0 ; j < be16_to_cpu(mhdr.lamrows) ; j++) {
+ remain = LAMINATE_STRIDE * 2;
+
+ /* Read one row of lamination data at a time */
+ while (remain) {
+ i = read(fd, ctx->databuf + ctx->datalen, remain);
+ if (i < 0)
+ return CUPS_BACKEND_CANCEL;
+ if (i == 0) {
+ /* We hit EOF, restart from beginning */
+ lseek(fd, 0, SEEK_SET);
+ continue;
+ }
+ ctx->datalen += i;
+ remain -= i;
}
- if (i < 0)
- return CUPS_BACKEND_CANCEL;
- ctx->datalen += i;
- remain -= i;
+ /* Back off the buffer so we "wrap" on the print row. */
+ ctx->datalen -= ((LAMINATE_STRIDE - ctx->cols) * 2);
}
+
+ /* Zero out the tail end of the buffer. */
+ j = be16_to_cpu(mhdr.lamcols) * be16_to_cpu(mhdr.lamrows) * 2;
+ memset(ctx->databuf + ctx->datalen, 0, ctx->matte - j);
}
}
-#endif
return CUPS_BACKEND_OK;
}
@@ -1014,7 +1172,7 @@ static int mitsu70x_set_sleeptime(struct mitsu70x_ctx *ctx, uint8_t time)
memset(cmdbuf, 0, 4);
cmdbuf[0] = 0x1b;
cmdbuf[1] = 0x53;
- cmdbuf[2] = 0x53;
+ cmdbuf[2] = 0x53; // XXX also, 0x4e and 0x50 are other params.
cmdbuf[3] = time;
if ((ret = send_data(ctx->dev, ctx->endp_down,
@@ -1032,7 +1190,7 @@ static int mitsu70x_wakeup(struct mitsu70x_ctx *ctx)
memset(buf, 0, sizeof(buf));
buf[0] = 0x1b;
buf[1] = 0x45;
- buf[2] = 0x57;
+ buf[2] = 0x57; // XXX also, 0x53, 0x54 seen.
buf[3] = 0x55;
INFO("Waking up printer...\n");
@@ -1043,6 +1201,13 @@ static int mitsu70x_wakeup(struct mitsu70x_ctx *ctx)
return 0;
}
+static int d70_library_callback(void *context, void *buffer, uint32_t len)
+{
+ struct mitsu70x_ctx *ctx = context;
+
+ return send_data(ctx->dev, ctx->endp_down, buffer, len);
+}
+
static int mitsu70x_main_loop(void *vctx, int copies)
{
struct mitsu70x_ctx *ctx = vctx;
@@ -1175,23 +1340,34 @@ skip_status:
hdr->deck = 1; /* All others only have a "lower" deck. */
}
+
+ /* Twiddle rewind stuff if needed */
+ if (ctx->type != P_MITSU_D70X) {
+ hdr->rewind[0] = !ctx->rew[0];
+ hdr->rewind[1] = !ctx->rew[1];
+ }
+
/* Matte operation requires Ultrafine/superfine */
if (ctx->matte) {
if (ctx->type != P_MITSU_D70X) {
- hdr->speed = 0x04; /* Force UltraFine */
+ if (hdr->speed != 0x03 && hdr->speed != 0x04) {
+ WARNING("Forcing Ultrafine mode for matte printing!\n");
+ hdr->speed = 0x04; /* Force UltraFine */
+ }
} else {
- hdr->speed = 0x03; /* Force SuperFine */
+ if (hdr->speed != 0x03) {
+ hdr->speed = 0x03; /* Force SuperFine */
+ WARNING("Forcing Ultrafine mode for matte printing!\n");
+ }
}
}
/* Any other fixups? */
-#if 1 // XXX is this actually needed?
if ((ctx->type == P_MITSU_K60 || ctx->type == P_KODAK_305) &&
ctx->cols == 0x0748 &&
- ctx->rows == 0x04c2) {
- hdr->multicut = 1; // XXX only if print count even?
+ ctx->rows == 0x04c2 && !hdr->multicut) {
+ hdr->multicut = 1;
}
-#endif
/* We're clear to send data over! */
INFO("Sending Print Job (internal id %u)\n", ctx->jobid);
@@ -1201,11 +1377,17 @@ skip_status:
sizeof(struct mitsu70x_hdr))))
return CUPS_BACKEND_FAILED;
- {
- /* K60 and 305 need data sent in 256K chunks, but the first
- chunk needs to subtract the length of the 512-byte header */
+ if (ctx->dl_handle && !ctx->raw_format) {
+ if (ctx->SendImageData(&ctx->output, ctx, d70_library_callback))
+ return CUPS_BACKEND_FAILED;
+
+ if (ctx->matte)
+ if (d70_library_callback(ctx, ctx->databuf + ctx->datalen - ctx->matte, ctx->matte))
+ return CUPS_BACKEND_FAILED;
+ } else { // Fallback code..
+ /* K60 and 305 need data sent in 256K chunks, but the first
+ chunk needs to subtract the length of the 512-byte header */
- // XXX is this special case actually needed?
int chunk = 256*1024 - sizeof(struct mitsu70x_hdr);
int sent = 512;
while (chunk > 0) {
@@ -1217,7 +1399,7 @@ skip_status:
if (chunk > 256*1024)
chunk = 256*1024;
}
- }
+ }
/* Then wait for completion, if so desired.. */
INFO("Waiting for printer to acknowledge completion\n");
@@ -1277,9 +1459,9 @@ skip_status:
jobstatus.job_status[2] ||
jobstatus.job_status[3]) {
ERROR("Abnormal exit: %02x/%02x/%02x\n",
- jobstatus.error_status[0],
- jobstatus.error_status[1],
- jobstatus.error_status[2]);
+ jobstatus.job_status[1],
+ jobstatus.job_status[2],
+ jobstatus.job_status[3]);
return CUPS_BACKEND_STOP;
}
/* Job complete */
@@ -1476,7 +1658,7 @@ static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv)
/* Exported */
struct dyesub_backend mitsu70x_backend = {
.name = "Mitsubishi CP-D70/D707/K60/D80",
- .version = "0.43WIP",
+ .version = "0.51",
.uri_prefix = "mitsu70x",
.cmdline_usage = mitsu70x_cmdline,
.cmdline_arg = mitsu70x_cmdline_arg,
@@ -1496,7 +1678,8 @@ struct dyesub_backend mitsu70x_backend = {
}
};
-/* Mitsubish CP-D70DW/CP-D707DW/CP-K60DW-S/CP-D80DW/Kodak 305 data format
+/* Mitsubish CP-D70DW/D707DW/K60DW-S/D80DW, Kodak 305, Fuji ASK-300
+ data format:
Spool file consists of two headers followed by three image planes
and an optional lamination data plane. All blocks are rounded up to
@@ -1504,30 +1687,32 @@ struct dyesub_backend mitsu70x_backend = {
All multi-byte numbers are big endian, ie MSB first.
- Header 1: (Init) (AKA Wake Up)
+ Header 1: (AKA Wake Up)
1b 45 57 55 00 00 00 00 00 00 00 00 00 00 00 00
(padded by NULLs to a 512-byte boundary)
- Header 2: (Header)
+ Header 2: (Print Header)
- 1b 5a 54 PP JJ JJ 00 00 00 00 00 00 00 00 00 00
+ 1b 5a 54 PP JJ JJ RR RR 00 00 00 00 00 00 00 00
XX XX YY YY QQ QQ ZZ ZZ SS 00 00 00 00 00 00 00
- UU 00 00 00 00 00 00 00 00 TT 00 00 00 00 00 00
+ UU 00 00 00 00 00 00 00 LL TT 00 00 00 00 00 00
RR 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
(padded by NULLs to a 512-byte boundary)
- PP == 0x01 on D70x/D80, 0x02 on K60, 0x90 on K305
+ PP == 0x01 on D70x/D80/ASK300, 0x00 on K60, 0x90 on K305
JJ JJ == Job ID, can leave at 00 00
XX XX == columns
YY YY == rows
QQ QQ == lamination columns (equal to XX XX)
- ZZ ZZ == lamination rows (YY YY + 12)
+ ZZ ZZ == lamination rows (YY YY + 12 on D70x/D80/ASK300, YY YY on others)
+ RR RR == "rewind inhibit", 01 01 enabled, normally 00 00
SS == Print mode: 00 = Fine, 03 = SuperFine (D70x/D80 only), 04 = UltraFine
(Matte requires Superfine or Ultrafine)
UU == 00 = Auto, 01 = Lower Deck (required for !D70x), 02 = Upper Deck
- TT == lamination: 00 glossy, 02 matte.
+ LL == lamination enable, 00 == on, 01 == off
+ TT == lamination mode: 00 glossy, 02 matte.
RR == 00 (normal), 01 = (Double-cut 4x6), 05 = (double-cut 2x6)
Data planes:
@@ -1536,151 +1721,4 @@ struct dyesub_backend mitsu70x_backend = {
Lamination plane: (only present if QQ and ZZ are nonzero)
16-byte data, rounded up to 512-byte block (QQ * ZZ * 2 bytes)
- ********************************************************************
-
- Command format:
-
- -> 1b 56 32 30
- <- [256 byte payload]
-
- PRINTER STATUS
-
- e4 56 32 30 00 00 00 00 00 00 00 00 00 00 00 00 .V20............
- 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 ................
- 44 80 00 00 5f 00 00 3d 43 00 50 00 44 00 37 00 D..._..=C.P.D.7.
- 30 00 44 00 30 00 30 00 31 00 31 00 31 00 37 00 0.D.0.0.1.1.1.7.
- 33 31 36 54 31 33 21 a3 33 31 35 42 31 32 f5 e5 316T13!.315B12..
- 33 31 39 42 31 31 a3 fb 33 31 38 45 31 32 50 0d 319B11..318E12P.
- 33 31 37 41 32 32 a3 82 44 55 4d 4d 59 40 00 00 317A22..DUMMY@..
- 44 55 4d 4d 59 40 00 00 00 00 00 00 00 00 00 00 DUMMY@..........
-
- LOWER DECK STATUS
-
- 00 00 00 00 00 00 02 04 3f 00 00 04 96 00 00 00 MM MM: media capacity
- ff 0f 01 00 MM MM NN NN 00 00 00 00 05 28 75 80 NN NN: prints remaining
- 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00
- 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00
-
- alt (some sort of error state)
-
- 00 00 00 0a 05 05 01 d5 38 00 00 00 14 00 00 00
- ff ff ff ff ff ff ff ff ff ff 00 00 00 27 72 80
- 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00
- 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00
-
- UPPER DECK STATUS (if present)
-
- XX XX 00 00 00 00 01 ee 3d 00 00 06 39 00 00 00 MM MM: media capacity
- ff 02 00 00 MM MM NN NN 00 00 00 00 06 67 78 00 NN NN: prints remaining
- 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 XX XX: 0x80 00 if no deck
- 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00
-
- alt (no deck present)
-
- 80 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00
- ff ff ff ff ff ff ff ff ff ff 00 00 00 00 80 00
- 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00
- 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00
-
- -> 1b 56 31 30 00 00
- <- [26 byte payload]
-
- CP-D707DW:
-
- e4 56 31 30 00 00 00 XX YY ZZ 00 00 TT 00 00 00
- 00 00 00 00 WW 00 00 00 00 00
-
- XX/YY/ZZ and WW/TT are unknown. Observed values:
-
- 00 00 00 00/00
- 40 80 a0 80/0f
- 80 80 a0
- 40 80 90
- 40 80 00
-
- also seen:
-
- e4 56 31 30 00 00 00 00 00 00 00 00 0f 00 00 00
- 00 0a 05 05 80 00 00 00 00 00
-
- e4 56 31 30 00 00 00 40 80 90 10 00 0f 00 00 00
- 00 0a 05 05 80 00 00 00 00 00
-
- e4 56 31 30 00 00 00 00 40 80 00 00 00 ff 40 00
- 00 00 00 00 80 00 00 00 00 00
-
- print just submitted:
-
- e4 56 31 30 00 00 00 00 40 20 00 00 00 8c 00 00
- 00 00 00 00 80 00 00 00 00 00
-
- prints running...
-
- e4 56 31 30 00 00 00 00 40 20 00 00 00 cf 00 20
- 00 00 00 00 80 00 00 00 00 00
-
- CP-K60DW-S:
-
- e4 56 31 30 00 00 00 XX YY 00 00 00 0f 00 00 00
- 00 00 00 00 80 00 00 00 00 00
-
- XX/YY are unknown, observed values:
-
- 40/80
- 00/00
-
- Memory status query:
-
- -> 1b 56 33 00 XX XX YY YY UU 00
-
- XX XX == columns
- YY YY == rows
- UU == 0x00 glossy, 0x80 matte
-
- <- [ 6 byte payload ]
-
- e4 56 33 00 00 00
- e4 56 33 00 00 01
- e4 56 33 ff 01 01
-
- |--- Size check, 00 ok, 01 fail
- |------ Memory check, 00 ok, 01 fail, ff bad size
-
- ** ** ** ** ** **
-
- The windows drivers seem to send the id and status queries before
- and in between each of the chunks sent to the printer. There doesn't
- appear to be any particular intelligence in the protocol, but it didn't
- work when the raw dump was submitted as-is.
-
- ** ** ** ** ** **
-
-Various deck status dumps:
-
-0080 00 00 00 00 00 00 01 d2 39 00 00 00 07 00 00 00 ........9.......
-0090 61 8f 00 00 01 40 01 36 00 00 00 00 00 17 79 80 a....@.6......y.
-
-0080 00 00 00 00 00 00 01 c6 39 00 00 00 08 00 00 00 ........9.......
-0090 61 8f 00 00 01 40 01 35 00 00 00 00 00 18 79 80 a....@.5......y.
-
-0080 00 00 00 00 00 00 02 19 50 00 00 00 19 00 00 01 ........P.......
-0090 6c 8f 00 00 01 40 01 22 00 00 00 00 00 27 83 80 l....@.".....'..
-
-0080 00 00 00 00 00 00 02 00 3e 00 00 04 96 00 00 00 ........>.......
-0090 ff 0f 01 00 00 c8 00 52 00 00 00 00 05 28 75 80 .......R.....(u.
-
-00c0 00 00 00 00 00 00 01 f3 3d 00 00 06 39 00 00 00 ........=...9...
-00d0 ff 02 00 00 01 90 00 c3 00 00 00 00 06 67 78 00 .............gx.
-
-0080 00 00 00 00 00 00 01 d0 38 00 00 03 70 00 00 00 ........8...p...
-0090 ff 02 00 00 01 90 00 1e 01 00 00 00 03 83 72 80 ..............r.
-
-0080 00 00 00 00 00 00 01 d6 39 00 00 00 20 00 00 00 ........9... ...
-0090 ff 02 00 00 01 90 01 7c 01 00 00 00 00 33 72 80 .......|.....3r.
-
- 00 00 00 0a 05 05 01 d5 38 00 00 00 14 00 00 00
- ff ff ff ff ff ff ff ff ff ff 00 00 00 27 72 80 ?? Error ??
-
- 80 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00
- ff ff ff ff ff ff ff ff ff ff 00 00 00 00 80 00 NO DECK PRESENT
*/