1 /*
2  *   Kodak Professional 1400/805 CUPS backend -- libusb-1.0 version
3  *
4  *   (c) 2013-2019 Solomon Peachy <pizza@shaftnet.org>
5  *
6  *   The latest version of this program can be found at:
7  *
8  *     http://git.shaftnet.org/cgit/selphy_print.git
9  *
10  *   This program is free software; you can redistribute it and/or modify it
11  *   under the terms of the GNU General Public License as published by the Free
12  *   Software Foundation; either version 2 of the License, or (at your option)
13  *   any later version.
14  *
15  *   This program is distributed in the hope that it will be useful, but
16  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18  *   for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
22  *
23  *          [http://www.gnu.org/licenses/gpl-2.0.html]
24  *
25  *   SPDX-License-Identifier: GPL-2.0+
26  *
27  */
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <signal.h>
38 
39 #define BACKEND kodak1400_backend
40 
41 #include "backend_common.h"
42 
43 /* Program states */
44 enum {
45 	S_IDLE = 0,
46 	S_PRINTER_READY_Y,
47 	S_PRINTER_SENT_Y,
48 	S_PRINTER_READY_M,
49 	S_PRINTER_SENT_M,
50 	S_PRINTER_READY_C,
51 	S_PRINTER_SENT_C,
52 	S_PRINTER_READY_L,
53 	S_PRINTER_SENT_L,
54 	S_PRINTER_DONE,
55 	S_FINISHED,
56 };
57 
58 #define CMDBUF_LEN 96
59 #define READBACK_LEN 8
60 
61 /* File header */
62 struct kodak1400_hdr {
63 	uint8_t  hdr[4];
64 	uint16_t columns;
65 	uint16_t null1;
66 	uint16_t rows;
67 	uint16_t null2;
68 	uint32_t planesize;
69 	uint32_t null3;
70 	uint8_t  matte;
71 	uint8_t  laminate;
72 	uint8_t  unk1;  /* Always 0x01 */
73 	uint8_t  lam_strength;
74 	uint8_t  null4[12];
75 } __attribute__((packed));
76 
77 
78 /* Private data structure */
79 struct kodak1400_printjob {
80 	struct kodak1400_hdr hdr;
81 	uint8_t *plane_r;
82 	uint8_t *plane_g;
83 	uint8_t *plane_b;
84 
85 	int copies;
86 };
87 
88 struct kodak1400_ctx {
89 	struct libusb_device_handle *dev;
90 	uint8_t endp_up;
91 	uint8_t endp_down;
92 	int type;
93 
94 	struct marker marker;
95 };
96 
send_plane(struct kodak1400_ctx * ctx,const struct kodak1400_printjob * job,uint8_t planeno,uint8_t * planedata,uint8_t * cmdbuf)97 static int send_plane(struct kodak1400_ctx *ctx,
98 		      const struct kodak1400_printjob *job,
99 		      uint8_t planeno, uint8_t *planedata,
100 		      uint8_t *cmdbuf)
101 {
102 	uint16_t temp16;
103 	int ret;
104 
105 	if (planeno != 1) {
106 		memset(cmdbuf, 0, CMDBUF_LEN);
107 		cmdbuf[0] = 0x1b;
108 		cmdbuf[1] = 0x74;
109 		cmdbuf[2] = 0x00;
110 		cmdbuf[3] = 0x50;
111 
112 		if ((ret = send_data(ctx->dev, ctx->endp_down,
113 				     cmdbuf, CMDBUF_LEN)))
114 			return ret;
115 	}
116 
117 	memset(cmdbuf, 0, CMDBUF_LEN);
118 	cmdbuf[0] = 0x1b;
119 	cmdbuf[1] = 0x5a;
120 	cmdbuf[2] = 0x54;
121 	cmdbuf[3] = planeno;
122 
123 	if (planedata) {
124 		temp16 = htons(job->hdr.columns);
125 		memcpy(cmdbuf+7, &temp16, 2);
126 		temp16 = htons(job->hdr.rows);
127 		memcpy(cmdbuf+9, &temp16, 2);
128 	}
129 
130 	if ((ret = send_data(ctx->dev, ctx->endp_down,
131 			     cmdbuf, CMDBUF_LEN)))
132 		return ret;
133 
134 	if (planedata) {
135 		int i;
136 		for (i = 0 ; i < job->hdr.rows ; i++) {
137 			if ((ret = send_data(ctx->dev, ctx->endp_down,
138 					     planedata + i * job->hdr.columns,
139 					     job->hdr.columns)))
140 				return ret;
141 		}
142 	}
143 
144 	memset(cmdbuf, 0, CMDBUF_LEN);
145 	cmdbuf[0] = 0x1b;
146 	cmdbuf[1] = 0x74;
147 	cmdbuf[2] = 0x01;
148 	cmdbuf[3] = 0x50;
149 
150 	if ((ret = send_data(ctx->dev, ctx->endp_down,
151 			     cmdbuf, CMDBUF_LEN)))
152 		return ret;
153 
154 	return 0;
155 }
156 
157 #define TONE_CURVE_SIZE 1552
kodak1400_set_tonecurve(struct kodak1400_ctx * ctx,char * fname)158 static int kodak1400_set_tonecurve(struct kodak1400_ctx *ctx, char *fname)
159 {
160 	libusb_device_handle *dev = ctx->dev;
161 	uint8_t endp_down = ctx->endp_down;
162 	uint8_t endp_up = ctx->endp_up;
163 
164 	uint8_t cmdbuf[8];
165 	uint8_t respbuf[64];
166 	int ret = 0, num = 0;
167 
168 	INFO("Set Tone Curve from '%s'\n", fname);
169 
170 	uint16_t *data = malloc(TONE_CURVE_SIZE);
171 
172 	if (!data) {
173 		ERROR("Memory Allocation Failure!\n");
174 		return -1;
175 	}
176 
177 	/* Read in file */
178 	if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE, NULL))) {
179 		ERROR("Failed to read Tone Curve file\n");
180 		goto done;
181 	}
182 
183 	/* Byteswap data to printer's format */
184 	for (ret = 0; ret < (TONE_CURVE_SIZE-16)/2 ; ret++) {
185 		data[ret] = cpu_to_le16(be16_to_cpu(data[ret]));
186 	}
187 	/* Null-terminate */
188 	memset(data + (TONE_CURVE_SIZE-16)/2, 0, 16);
189 
190 	/* Clear tables */
191 	memset(cmdbuf, 0, sizeof(cmdbuf));
192 	cmdbuf[0] = 0x1b;
193 	cmdbuf[1] = 0xa2;
194 	if ((ret = send_data(dev, endp_down,
195 			     cmdbuf, 2))) {
196 		ret = -3;
197 		goto done;
198 	}
199 
200 	ret = read_data(dev, endp_up,
201 			respbuf, sizeof(respbuf), &num);
202 
203 	if (ret < 0)
204 		goto done;
205 	if (num != 8) {
206 		ERROR("Short Read! (%d/%d)\n", num, 8);
207 		ret = -4;
208 		goto done;
209 	}
210 	if (respbuf[1] != 0x01) {
211 		ERROR("Received unexpected response\n");
212 		ret = -5;
213 		goto done;
214 	}
215 
216 	/* Set up the update command */
217 	memset(cmdbuf, 0, sizeof(cmdbuf));
218 	cmdbuf[0] = 0x1b;
219 	cmdbuf[1] = 0xa0;
220 	cmdbuf[2] = 0x02;
221 	cmdbuf[3] = 0x03;
222 	cmdbuf[4] = 0x06;
223 	cmdbuf[5] = 0x10;   /* 06 10 == TONE_CURVE_SIZE */
224 	if ((ret = send_data(dev, endp_down,
225 			     cmdbuf, 6)))
226 		goto done;
227 
228 	/* Send the payload over */
229 	if ((ret = send_data(dev, endp_down,
230 			     (uint8_t *) data, TONE_CURVE_SIZE)))
231 		goto done;
232 
233 	/* get the response */
234 	ret = read_data(dev, endp_up,
235 			respbuf, sizeof(respbuf), &num);
236 
237 	if (ret < 0)
238 		goto done;
239 	if (num != 8) {
240 		ERROR("Short Read! (%d/%d)\n", num, 8);
241 		ret = -6;
242 		goto done;
243 	}
244 	if (respbuf[1] != 0x00) {
245 		ERROR("Received unexpected response!\n");
246 		ret = -7;
247 		goto done;
248 	}
249 
250 done:
251 	free(data);
252 
253 	return ret;
254 }
255 
kodak1400_cmdline(void)256 static void kodak1400_cmdline(void)
257 {
258 	DEBUG("\t\t[ -C filename ]  # Set tone curve\n");
259 }
260 
kodak1400_cmdline_arg(void * vctx,int argc,char ** argv)261 int kodak1400_cmdline_arg(void *vctx, int argc, char **argv)
262 {
263 	struct kodak1400_ctx *ctx = vctx;
264 	int i, j = 0;
265 
266 	if (!ctx)
267 		return -1;
268 
269 	while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "C:")) >= 0) {
270 		switch(i) {
271 		GETOPT_PROCESS_GLOBAL
272 		case 'C':
273 			j = kodak1400_set_tonecurve(ctx, optarg);
274 			break;
275 		default:
276 			break;  /* Ignore completely */
277 		}
278 
279 		if (j) return j;
280 	}
281 
282 	return 0;
283 }
284 
kodak1400_init(void)285 static void *kodak1400_init(void)
286 {
287 	struct kodak1400_ctx *ctx = malloc(sizeof(struct kodak1400_ctx));
288 	if (!ctx) {
289 		ERROR("Memory Allocation Failure!\n");
290 		return NULL;
291 	}
292 	memset(ctx, 0, sizeof(struct kodak1400_ctx));
293 
294 	return ctx;
295 }
296 
kodak1400_attach(void * vctx,struct libusb_device_handle * dev,int type,uint8_t endp_up,uint8_t endp_down,uint8_t jobid)297 static int kodak1400_attach(void *vctx, struct libusb_device_handle *dev, int type,
298 			    uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
299 {
300 	struct kodak1400_ctx *ctx = vctx;
301 
302 	UNUSED(jobid);
303 
304 	ctx->dev = dev;
305 	ctx->endp_up = endp_up;
306 	ctx->endp_down = endp_down;
307 	ctx->type = type;
308 
309 	ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
310 	ctx->marker.name = "Unknown";
311 	ctx->marker.levelmax = -1;
312 	ctx->marker.levelnow = -2;
313 
314 	return CUPS_BACKEND_OK;
315 }
316 
kodak1400_cleanup_job(const void * vjob)317 static void kodak1400_cleanup_job(const void *vjob)
318 {
319 	const struct kodak1400_printjob *job = vjob;
320 
321 	if (job->plane_r)
322 		free(job->plane_r);
323 	if (job->plane_g)
324 		free(job->plane_g);
325 	if (job->plane_b)
326 		free(job->plane_b);
327 
328 	free((void*)job);
329 }
330 
kodak1400_read_parse(void * vctx,const void ** vjob,int data_fd,int copies)331 static int kodak1400_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
332 	struct kodak1400_ctx *ctx = vctx;
333 	int i, ret;
334 
335 	struct kodak1400_printjob *job = NULL;
336 
337 	if (!ctx)
338 		return CUPS_BACKEND_FAILED;
339 
340 	job = malloc(sizeof(*job));
341 	if (!job) {
342 		ERROR("Memory allocation failure!\n");
343 		return CUPS_BACKEND_RETRY_CURRENT;
344 	}
345 	memset(job, 0, sizeof(*job));
346 	job->copies = copies;
347 
348 	/* Read in then validate header */
349 	ret = read(data_fd, &job->hdr, sizeof(job->hdr));
350 	if (ret < 0 || ret != sizeof(job->hdr)) {
351 		if (ret == 0)
352 			return CUPS_BACKEND_CANCEL;
353 		ERROR("Read failed (%d/%d/%d)\n",
354 		      ret, 0, (int)sizeof(job->hdr));
355 		perror("ERROR: Read failed");
356 		return CUPS_BACKEND_CANCEL;
357 	}
358 	if (job->hdr.hdr[0] != 'P' ||
359 	    job->hdr.hdr[1] != 'G' ||
360 	    job->hdr.hdr[2] != 'H' ||
361 	    job->hdr.hdr[3] != 'D') {
362 		ERROR("Unrecognized data format!\n");
363 		return CUPS_BACKEND_CANCEL;
364 	}
365 	job->hdr.planesize = le32_to_cpu(job->hdr.planesize);
366 	job->hdr.rows = le16_to_cpu(job->hdr.rows);
367 	job->hdr.columns = le16_to_cpu(job->hdr.columns);
368 
369 	/* Set up plane data */
370 	job->plane_r = malloc(job->hdr.planesize);
371 	job->plane_g = malloc(job->hdr.planesize);
372 	job->plane_b = malloc(job->hdr.planesize);
373 	if (!job->plane_r || !job->plane_g || !job->plane_b) {
374 		ERROR("Memory allocation failure!\n");
375 		return CUPS_BACKEND_RETRY_CURRENT;
376 	}
377 	for (i = 0 ; i < job->hdr.rows ; i++) {
378 		int j;
379 		uint8_t *ptr;
380 		for (j = 0 ; j < 3 ; j++) {
381 			int remain;
382 			if (j == 0)
383 				ptr = job->plane_r + i * job->hdr.columns;
384 			else if (j == 1)
385 				ptr = job->plane_g + i * job->hdr.columns;
386 			else if (j == 2)
387 				ptr = job->plane_b + i * job->hdr.columns;
388 			else
389 				ptr = NULL;
390 
391 			remain = job->hdr.columns;
392 			do {
393 				ret = read(data_fd, ptr, remain);
394 				if (ret < 0) {
395 					ERROR("Read failed (%d/%d/%u) (%d/%u @ %d)\n",
396 					      ret, remain, job->hdr.columns,
397 					      i, job->hdr.rows, j);
398 					perror("ERROR: Read failed");
399 					return CUPS_BACKEND_CANCEL;
400 				}
401 				ptr += ret;
402 				remain -= ret;
403 			} while (remain);
404 		}
405 	}
406 
407 	*vjob = job;
408 
409 	return CUPS_BACKEND_OK;
410 }
411 
412 static uint8_t idle_data[READBACK_LEN] = { 0xe4, 0x72, 0x00, 0x00,
413 					   0x00, 0x00, 0x00, 0x00 };
414 
kodak1400_main_loop(void * vctx,const void * vjob)415 static int kodak1400_main_loop(void *vctx, const void *vjob) {
416 	struct kodak1400_ctx *ctx = vctx;
417 
418 	uint8_t rdbuf[READBACK_LEN], rdbuf2[READBACK_LEN];
419 	uint8_t cmdbuf[CMDBUF_LEN];
420 	int last_state = -1, state = S_IDLE;
421 	int num, ret;
422 	uint16_t temp16;
423 	int copies;
424 
425 	const struct kodak1400_printjob *job = vjob;
426 
427 	if (!ctx)
428 		return CUPS_BACKEND_FAILED;
429 	if (!job)
430 		return CUPS_BACKEND_FAILED;
431 
432 	copies = job->copies;
433 
434 top:
435 	if (state != last_state) {
436 		if (dyesub_debug)
437 			DEBUG("last_state %d new %d\n", last_state, state);
438 	}
439 
440 	/* Send Status Query */
441 	memset(cmdbuf, 0, CMDBUF_LEN);
442 	cmdbuf[0] = 0x1b;
443 	cmdbuf[1] = 0x72;
444 
445 	if ((ret = send_data(ctx->dev, ctx->endp_down,
446 			    cmdbuf, CMDBUF_LEN)))
447 		return CUPS_BACKEND_FAILED;
448 
449 	/* Read in the printer status */
450 	ret = read_data(ctx->dev, ctx->endp_up,
451 			rdbuf, READBACK_LEN, &num);
452 
453 	if (ret < 0)
454 		return CUPS_BACKEND_FAILED;
455 	if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) {
456 		memcpy(rdbuf2, rdbuf, READBACK_LEN);
457 	} else if (state == last_state) {
458 		sleep(1);
459 	}
460 	last_state = state;
461 
462 	/* Error handling */
463 	if (rdbuf[4] || rdbuf[5]) {
464 		ERROR("Error code reported by printer (%02x/%02x), terminating print\n",
465 		      rdbuf[4], rdbuf[5]);
466 		return CUPS_BACKEND_STOP;  // HOLD/CANCEL/FAILED?  XXXX parse error!
467 	}
468 
469 	fflush(stderr);
470 
471 	switch (state) {
472 	case S_IDLE:
473 		INFO("Printing started\n");
474 
475 		/* Send reset/attention */
476 		memset(cmdbuf, 0, CMDBUF_LEN);
477 		cmdbuf[0] = 0x1b;
478 
479 		if ((ret = send_data(ctx->dev, ctx->endp_down,
480 				     cmdbuf, CMDBUF_LEN)))
481 			return CUPS_BACKEND_FAILED;
482 
483 		/* Send page setup */
484 		memset(cmdbuf, 0, CMDBUF_LEN);
485 		cmdbuf[0] = 0x1b;
486 		cmdbuf[1] = 0x5a;
487 		cmdbuf[2] = 0x53;
488 		temp16 = be16_to_cpu(job->hdr.columns);
489 		memcpy(cmdbuf+3, &temp16, 2);
490 		temp16 = be16_to_cpu(job->hdr.rows);
491 		memcpy(cmdbuf+5, &temp16, 2);
492 
493 		if ((ret = send_data(ctx->dev, ctx->endp_down,
494 				    cmdbuf, CMDBUF_LEN)))
495 			return CUPS_BACKEND_FAILED;
496 
497 		/* Send lamination toggle? */
498 		memset(cmdbuf, 0, CMDBUF_LEN);
499 		cmdbuf[0] = 0x1b;
500 		cmdbuf[1] = 0x59;
501 		cmdbuf[2] = job->hdr.matte; // ???
502 
503 		if ((ret = send_data(ctx->dev, ctx->endp_down,
504 				    cmdbuf, CMDBUF_LEN)))
505 			return CUPS_BACKEND_FAILED;
506 
507 		/* Send matte toggle */
508 		memset(cmdbuf, 0, CMDBUF_LEN);
509 		cmdbuf[0] = 0x1b;
510 		cmdbuf[1] = 0x60;
511 		cmdbuf[2] = job->hdr.laminate;
512 
513 		if (send_data(ctx->dev, ctx->endp_down,
514 			     cmdbuf, CMDBUF_LEN))
515 			return CUPS_BACKEND_FAILED;
516 
517 		/* Send lamination strength */
518 		memset(cmdbuf, 0, CMDBUF_LEN);
519 		cmdbuf[0] = 0x1b;
520 		cmdbuf[1] = 0x62;
521 		cmdbuf[2] = job->hdr.lam_strength;
522 
523 		if ((ret = send_data(ctx->dev, ctx->endp_down,
524 				    cmdbuf, CMDBUF_LEN)))
525 			return CUPS_BACKEND_FAILED;
526 
527 		/* Send unknown */
528 		memset(cmdbuf, 0, CMDBUF_LEN);
529 		cmdbuf[0] = 0x1b;
530 		cmdbuf[1] = 0x61;
531 		cmdbuf[2] = job->hdr.unk1; // ???
532 
533 		if ((ret = send_data(ctx->dev, ctx->endp_down,
534 				    cmdbuf, CMDBUF_LEN)))
535 			return CUPS_BACKEND_FAILED;
536 
537 		state = S_PRINTER_READY_Y;
538 		break;
539 	case S_PRINTER_READY_Y:
540 		INFO("Sending YELLOW plane\n");
541 		if ((ret = send_plane(ctx, job, 1, job->plane_b, cmdbuf)))
542 			return CUPS_BACKEND_FAILED;
543 		state = S_PRINTER_SENT_Y;
544 		break;
545 	case S_PRINTER_SENT_Y:
546 		if (!memcmp(rdbuf, idle_data, READBACK_LEN))
547 			state = S_PRINTER_READY_M;
548 		break;
549 	case S_PRINTER_READY_M:
550 		INFO("Sending MAGENTA plane\n");
551 		if ((ret = send_plane(ctx, job, 2, job->plane_g, cmdbuf)))
552 			return CUPS_BACKEND_FAILED;
553 		state = S_PRINTER_SENT_M;
554 		break;
555 	case S_PRINTER_SENT_M:
556 		if (!memcmp(rdbuf, idle_data, READBACK_LEN))
557 			state = S_PRINTER_READY_C;
558 		break;
559 	case S_PRINTER_READY_C:
560 		INFO("Sending CYAN plane\n");
561 		if ((ret = send_plane(ctx, job, 3, job->plane_r, cmdbuf)))
562 			return CUPS_BACKEND_FAILED;
563 		state = S_PRINTER_SENT_C;
564 		break;
565 	case S_PRINTER_SENT_C:
566 		if (!memcmp(rdbuf, idle_data, READBACK_LEN)) {
567 			if (job->hdr.laminate)
568 				state = S_PRINTER_READY_L;
569 			else
570 				state = S_PRINTER_DONE;
571 		}
572 		break;
573 	case S_PRINTER_READY_L:
574 		INFO("Laminating page\n");
575 		if ((ret = send_plane(ctx, job, 4, NULL, cmdbuf)))
576 			return CUPS_BACKEND_FAILED;
577 		state = S_PRINTER_SENT_L;
578 		break;
579 	case S_PRINTER_SENT_L:
580 		if (!memcmp(rdbuf, idle_data, READBACK_LEN))
581 			state = S_PRINTER_DONE;
582 		break;
583 	case S_PRINTER_DONE:
584 		INFO("Cleaning up\n");
585 		/* Cleanup */
586 		memset(cmdbuf, 0, CMDBUF_LEN);
587 		cmdbuf[0] = 0x1b;
588 		cmdbuf[1] = 0x74;
589 		cmdbuf[2] = 0x00;
590 		cmdbuf[3] = 0x50;
591 
592 		if ((ret = send_data(ctx->dev, ctx->endp_down,
593 				    cmdbuf, CMDBUF_LEN)))
594 			return CUPS_BACKEND_FAILED;
595 
596 		state = S_FINISHED;
597 		break;
598 	default:
599 		break;
600 	};
601 
602 	if (state != S_FINISHED)
603 		goto top;
604 
605 	/* Clean up */
606 	if (terminate)
607 		copies = 1;
608 
609 	INFO("Print complete (%d copies remaining)\n", copies - 1);
610 
611 	if (copies && --copies) {
612 		state = S_IDLE;
613 		goto top;
614 	}
615 
616 	return CUPS_BACKEND_OK;
617 }
618 
kodak1400_query_markers(void * vctx,struct marker ** markers,int * count)619 static int kodak1400_query_markers(void *vctx, struct marker **markers, int *count)
620 {
621 	struct kodak1400_ctx *ctx = vctx;
622 
623 	*markers = &ctx->marker;
624 	*count = 1;
625 
626 	return CUPS_BACKEND_OK;
627 }
628 
629 /* Exported */
630 #define USB_VID_KODAK       0x040A
631 #define USB_PID_KODAK_1400  0x4022
632 #define USB_PID_KODAK_805   0x4034
633 #define USB_VID_MITSU        0x06D3
634 #define USB_PID_MITSU_3020D  0x038B
635 #define USB_PID_MITSU_3020DA 0x03AA
636 
637 static const char *kodak1400_prefixes[] = {
638 	"kodak1400", // Family driver, do NOT nuke!
639 	"kodak-1400", "kodak-805", "mitsubishi-3020d", "mitsubishi-3020da",
640 	// backwards compatibility
641 	"kodak805", "mitsu3020d", "mitsu3020da",
642 	// Extras.
643 	"mitsubishi-3020dae", "mitsubishi-3020de", "mitsubishi-3020du",
644 	NULL,
645 };
646 
647 struct dyesub_backend kodak1400_backend = {
648 	.name = "Kodak 1400/805",
649 	.version = "0.40",
650 	.uri_prefixes = kodak1400_prefixes,
651 	.cmdline_usage = kodak1400_cmdline,
652 	.cmdline_arg = kodak1400_cmdline_arg,
653 	.init = kodak1400_init,
654 	.attach = kodak1400_attach,
655 	.cleanup_job = kodak1400_cleanup_job,
656 	.read_parse = kodak1400_read_parse,
657 	.main_loop = kodak1400_main_loop,
658 	.query_markers = kodak1400_query_markers,
659 	.devices = {
660 		{ USB_VID_KODAK, USB_PID_KODAK_1400, P_KODAK_1400_805, "Kodak", "kodak-1400"},
661 		{ USB_VID_KODAK, USB_PID_KODAK_805, P_KODAK_1400_805, "Kodak", "kodak-805"},
662 		{ USB_VID_MITSU, USB_PID_MITSU_3020D, P_KODAK_1400_805, NULL, "mitsubishi-3020d"},
663 		{ USB_VID_MITSU, USB_PID_MITSU_3020DA, P_KODAK_1400_805, NULL, "mitsubishi-3020da" },
664 		{ 0, 0, 0, NULL, NULL}
665 	}
666 };
667 
668 /* Kodak 1400/805 data format
669 
670   Spool file consists of 36-byte header followed by row-interleaved BGR data.
671   Native printer resolution is 2560 pixels per row, and 3010 or 3612 rows.
672 
673   Header:
674 
675   50 47 48 44     "PGHD"
676   XX XX           Number of columns, Little endian.  Fixed at 2560.
677   00 00           NULL
678   XX XX           Number of rows, Little Endian
679   00 00           NULL
680   XX XX XX XX     Number of bytes per plane, Little Endian
681   00 00 00 00     NULL
682   XX              00 Glossy, 01 Matte   (Note: Kodak805 only supports Glossy)
683   XX              01 to laminate, 00 to not.
684   01              Unknown, always set to 01
685   XX              Lamination Strength:
686 
687                   3c  Glossy
688                   28  Matte +5
689                   2e  Matte +4
690                   34  Matte +3
691                   3a  Matte +2
692                   40  Matte +1
693                   46  Matte
694                   52  Matte -1
695                   5e  Matte -2
696                   6a  Matte -3
697                   76  Matte -4
698                   82  Matte -5
699 
700   00 00 00 00 00 00 00 00 00 00 00 00       NULL
701 
702   ************************************************************************
703 
704   The data format actually sent to the Kodak 1400 is rather different.
705 
706     All commands are null-padded to 96 bytes.
707     All readback values are 8 bytes long.
708 
709     Multi-byte numbers are sent BIG ENDIAN.
710 
711     Image data is sent via planes, one scanline per URB.
712 
713  <-- 1b 72                           # Status query
714  --> e4 72 00 00  00 00 00 00        # Idle response
715 
716  <-- 1b 00                           # Reset/attention?
717  <-- 1b 5a 53  0a 00  0b c2          # Setup (ie hdr.columns and hdr.rows)
718  <-- 1b 59 01                        # ?? hdr.matte ?
719  <-- 1b 60 XX                        # hdr.lamination
720  <-- 1b 62 XX                        # hdr.lam_strength
721  <-- 1b 61 01                        # ?? hdr.unk1 ?
722 
723  <-- 1b 5a 54 01  00 00 00  0a 00  0b c2  # start of plane 1 data
724  <-- row 1
725  <-- row 2
726  <-- row last
727 
728  <-- 1b 74 01 50                     # ??
729 
730  <-- 1b 72                           # Status query
731  --> e4 72 00 00  00 00 50 59        # Printing plane 1
732   [ repeats until...]
733  <-- 1b 72                           # Status query
734  --> e4 72 00 00  40 00 50 59        # Paper loaded?
735   [ repeats until...]
736  <-- 1b 72                           # Status query
737  --> e4 72 00 00  00 00 50 59        # Printing plane 1
738   [ repeats until...]
739  <-- 1b 72                           # Status query
740  --> e4 72 00 00  00 00 00 00        # Idle response
741 
742  <-- 1b 74 00 50                     # ??
743  <-- 1b 5a 54 02  00 00 00  0a 00  0b c2  # start of plane 2 data
744  <-- row 1
745  <-- row 2
746  <-- row last
747  <-- 1b 74 01 50                     # ??
748 
749  <-- 1b 72                           # Status query
750  --> e4 72 00 00  00 00 50 4d        # Printing plane 2
751   [ repeats until...]
752  <-- 1b 72                           # Status query
753  --> e4 72 00 00  00 00 00 00        # Idle response
754 
755  <-- 1b 74 00 50                     # ??
756  <-- 1b 5a 54 03  00 00 00  0a 00  0b c2  # start of plane 3 data
757  <-- row 1
758  <-- row 2
759  <-- row last
760  <-- 1b 74 01 50                     # ??
761 
762  <-- 1b 72                           # Status query
763  --> e4 72 00 00  00 00 50 43        # Printing plane 3
764   [ repeats until...]
765  <-- 1b 72                           # Status query
766  --> e4 72 00 00  00 00 00 00        # Idle response
767 
768  ## this block is only present if lamination is used
769 
770  <-- 1b 74 00 50                     # ??
771  <-- 1b 5a 54 04                     # start of lamination
772  <-- 1b 74 01 50                     # ??
773 
774  <-- 1b 72                           # Status query
775  --> e4 72 00 00  00 00 50 50        # Laminating
776   [ repeats until...]
777  <-- 1b 72                           # Status query
778  --> e4 72 00 00  00 00 00 00        # Idle response
779 
780  ## end lamination block
781 
782  <-- 1b 74 00 50                     # ??
783 
784  [[ DONE ]]
785 
786  Other readback codes seen:
787 
788  e4 72 00 00  40 00 50 59  -- ?? paper jam?
789  e4 72 00 00  10 00 50 59  -- media red blink, error red blink, [media mismatch]]
790  e4 72 00 00  10 01 50 59  -- ???
791  e4 72 00 00  00 04 50 59  -- media red blink, error red  [media too small for image ?]
792  e4 72 00 00  02 00 50 59  -- media off, error red. [out of paper]
793  e4 72 00 00  02 01 00 00  -- media off, error red. [out of paper]
794  e4 72 00 00  02 00 00 00  -- media off, error red. [out of paper]
795  e4 72 00 00  02 00 50 50  -- media on, error red. [paper jam while laminating]
796 
797  *********************************************
798   Calibration data:
799 
800  <-- 1b a2                           # ?? Reset cal tables?
801  --> 00 01 00 00  00 00 00 00
802 
803  <-- 1b a0 02 03 06 10               # 06 10 == 1552 bytes aka the CAL data.
804  <-- cal data
805 
806   [[ Data is organized as three blocks of 512 bytes followed by
807      16 NULL bytes.
808 
809      Each block appears to be 256 entries of 16-bit LE data,
810      so each input value is translated into a 16-bit number in the printer.
811 
812      Assuming blocks are ordered BGR.
813 
814   ]]
815 
816  --> 00 00 00 00  00 00 00 00
817 
818 */
819