dnp-rx1: Parse the windows spool file format.

This allows printing via a Windows system.

(FWIW, The "native" gutenprint format is more featureful)
This commit is contained in:
Solomon Peachy 2019-07-14 09:20:17 -04:00
parent 2e7378604d
commit 2d0b7e250f
3 changed files with 188 additions and 39 deletions

View File

@ -199,29 +199,10 @@ struct dnpds40_cmd {
#define min(__x, __y) ((__x) < (__y)) ? __x : __y
/* Legacy CW-01 spool file support */
struct cw01_spool_hdr {
uint8_t type; /* 0x00 -> 0x06 */
uint8_t res; /* vertical resolution; 0x00 == 334dpi, 0x01 == 600dpi */
uint8_t copies; /* number of prints */
uint8_t null0;
uint32_t plane_len; /* LE */
uint8_t null1[4];
};
#define DPI_334 0
#define DPI_600 1
#define TYPE_DSC 0
#define TYPE_L 1
#define TYPE_PC 2
#define TYPE_2DSC 3
#define TYPE_3L 4
#define TYPE_A5 5
#define TYPE_A6 6
/* Legacy CW-01 spool file support */
/* Legacy spool file support */
static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data);
static int rx1_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data);
static void dnpds40_cleanup_job(const void *vjob);
static int dnpds40_query_markers(void *vctx, struct marker **markers, int *count);
@ -1306,6 +1287,13 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
dnpds40_cleanup_job(job);
return i;
}
case P_DNP_DSRX1:
{
i = rx1_read_parse(job, data_fd, i);
if (i == CUPS_BACKEND_OK) {
goto parsed;
}
}
default:
break;
}
@ -1413,6 +1401,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
job->dpi = 334;
break;
case 23615:
case 23616:
job->dpi = 600;
break;
default:
@ -3105,7 +3094,26 @@ struct dyesub_backend dnpds40_backend = {
}
};
/* Legacy CW-01 spool file support */
/* Legacy spool file support */
struct cw01_spool_hdr {
uint8_t type; /* TYPE_??? */
uint8_t res; /* DPI_??? */
uint8_t copies; /* number of prints */
uint8_t null0;
uint32_t plane_len; /* LE */
uint8_t null1[4];
};
#define DPI_334 0
#define DPI_600 1
#define TYPE_DSC 0
#define TYPE_L 1
#define TYPE_PC 2
#define TYPE_2DSC 3
#define TYPE_3L 4
#define TYPE_A5 5
#define TYPE_A6 6
static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data)
{
@ -3113,7 +3121,7 @@ static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_d
int i, remain;
uint32_t j;
uint8_t *buf;
uint8_t plane_hdr[14];
uint8_t bmp_hdr[14];
/* get original header out of structure */
memcpy(&hdr, job->databuf + job->datalen, sizeof(hdr));
@ -3121,13 +3129,14 @@ static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_d
/* Early parsing and sanity checking */
hdr.plane_len = le32_to_cpu(hdr.plane_len);
if (hdr.type > 0x06 ||
hdr.res > 0x01 ||
if (hdr.type > TYPE_A6 ||
hdr.res > DPI_600 ||
hdr.null1[0] || hdr.null1[1] || hdr.null1[2] || hdr.null1[3]) {
ERROR("Unrecognized header data format @%d!\n", job->datalen);
return CUPS_BACKEND_CANCEL;
}
job->dpi = (hdr.res == DPI_600) ? 600 : 334;
job->cutter = 0;
/* Allocate a temp processing buffer */
remain = hdr.plane_len * 3;
@ -3157,23 +3166,22 @@ static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_d
/* Generate bitmap file header (same for all planes) */
j = cpu_to_le32(hdr.plane_len + 24);
memset(plane_hdr, 0, sizeof(plane_hdr));
plane_hdr[0] = 0x42;
plane_hdr[1] = 0x4d;
memcpy(plane_hdr + 2, &j, sizeof(j));
plane_hdr[10] = 0x40;
plane_hdr[11] = 0x04;
memset(bmp_hdr, 0, sizeof(bmp_hdr));
bmp_hdr[0] = 0x42;
bmp_hdr[1] = 0x4d;
memcpy(bmp_hdr + 2, &j, sizeof(j));
bmp_hdr[10] = 0x40;
bmp_hdr[11] = 0x04;
/* Okay, generate a new stream into job->databuf! */
job->cutter = 0;
j = 0;
/* Y plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
"\033PIMAGE YPLANE %08u", hdr.plane_len + 24);
memcpy(job->databuf + job->datalen, plane_hdr, sizeof(plane_hdr));
job->datalen += sizeof(plane_hdr);
memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
job->datalen += sizeof(bmp_hdr);
memcpy(job->databuf + job->datalen, buf + j, hdr.plane_len);
job->datalen += hdr.plane_len;
j += hdr.plane_len;
@ -3183,8 +3191,8 @@ static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_d
/* M plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
"\033PIMAGE MPLANE %08u", hdr.plane_len + 24);
memcpy(job->databuf + job->datalen, plane_hdr, sizeof(plane_hdr));
job->datalen += sizeof(plane_hdr);
memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
job->datalen += sizeof(bmp_hdr);
memcpy(job->databuf + job->datalen, buf + j, hdr.plane_len);
job->datalen += hdr.plane_len;
j += hdr.plane_len;
@ -3194,8 +3202,145 @@ static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_d
/* C plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
"\033PIMAGE CPLANE %08u", hdr.plane_len + 24);
memcpy(job->databuf + job->datalen, plane_hdr, sizeof(plane_hdr));
job->datalen += sizeof(plane_hdr);
memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
job->datalen += sizeof(bmp_hdr);
memcpy(job->databuf + job->datalen, buf + j, hdr.plane_len);
job->datalen += hdr.plane_len;
j += hdr.plane_len;
memset(job->databuf + job->datalen, 0, 10);
job->datalen += 10;
/* Start */
job->datalen += sprintf((char*)job->databuf + job->datalen,
"\033PCNTRL START ");
/* We're done */
free(buf);
return CUPS_BACKEND_OK;
}
struct rx1_spool_hdr {
uint8_t type; /* equals MULTICUT_?? - 1 */
uint8_t null0;
uint8_t copies; /* number of copies */
uint8_t null1;
uint32_t plane_len; /* LE */
uint8_t flags; /* combination of FLAG_?? */
uint8_t null2[3];
};
#define FLAG_MATTE 0x02
#define FLAG_NORETRY 0x08
#define FLAG_2INCH 0x10
static int rx1_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data)
{
struct rx1_spool_hdr hdr;
int i, remain;
uint32_t j;
uint8_t *buf;
uint8_t bmp_hdr[14];
/* get original header out of structure */
memcpy(&hdr, job->databuf + job->datalen, sizeof(hdr));
/* Early parsing and sanity checking */
hdr.plane_len = le32_to_cpu(hdr.plane_len);
if (hdr.type > 0x1a ||
hdr.null2[0] || hdr.null2[1] || hdr.null2[2]) {
ERROR("Unrecognized header data format @%d!\n", job->datalen);
return CUPS_BACKEND_CANCEL;
}
/* Don't bother with FW version checks for legacy stuff */
job->multicut = hdr.type + 1;
job->matte = (hdr.flags & FLAG_MATTE) ? 1 : 0;
job->cutter = (hdr.flags & FLAG_2INCH) ? 120 : 0;
/* Allocate a temp processing buffer */
remain = hdr.plane_len * 3;
buf = malloc(remain);
if (!buf) {
ERROR("Memory allocation failure!\n");
return CUPS_BACKEND_RETRY_CURRENT;
}
/* Copy over the post-jobhdr crap into our processing buffer */
j = read_data - sizeof(hdr);
memcpy(buf, job->databuf + sizeof(hdr), j);
remain -= j;
/* Read in the remaining spool data */
while (remain) {
i = read(data_fd, buf + j, remain);
if (i < 0) {
free(buf);
return i;
}
remain -= i;
j += i;
}
/* Parse out Y DPI */
memcpy(&j, buf + 28, sizeof(j));
j = le32_to_cpu(j);
switch(j) {
case 11808:
job->dpi = 300;
break;
case 23615:
case 23616:
job->dpi = 600;
break;
default:
ERROR("Unrecognized printjob resolution (%u ppm)\n", j);
free(buf);
return CUPS_BACKEND_CANCEL;
}
/* Generate bitmap file header (same for all planes) */
j = cpu_to_le32(hdr.plane_len + 24);
memset(bmp_hdr, 0, sizeof(bmp_hdr));
bmp_hdr[0] = 0x42;
bmp_hdr[1] = 0x4d;
memcpy(bmp_hdr + 2, &j, sizeof(j));
bmp_hdr[10] = 0x40;
bmp_hdr[11] = 0x04;
/* Set up planes */
j = 0;
/* Y plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
"\033PIMAGE YPLANE %08u", hdr.plane_len + 24);
memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
job->datalen += sizeof(bmp_hdr);
memcpy(job->databuf + job->datalen, buf + j, hdr.plane_len);
job->datalen += hdr.plane_len;
j += hdr.plane_len;
memset(job->databuf + job->datalen, 0, 10);
job->datalen += 10;
/* M plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
"\033PIMAGE MPLANE %08u", hdr.plane_len + 24);
memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
job->datalen += sizeof(bmp_hdr);
memcpy(job->databuf + job->datalen, buf + j, hdr.plane_len);
job->datalen += hdr.plane_len;
j += hdr.plane_len;
memset(job->databuf + job->datalen, 0, 10);
job->datalen += 10;
/* C plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
"\033PIMAGE CPLANE %08u", hdr.plane_len + 24);
memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
job->datalen += sizeof(bmp_hdr);
memcpy(job->databuf + job->datalen, buf + j, hdr.plane_len);
job->datalen += hdr.plane_len;
j += hdr.plane_len;

View File

@ -174,6 +174,7 @@ dnpds820,0x1452,0x9001,dnp_ds80_8x12.raw,510
dnprx1,0x1343,0x0005,dnp_ds40_4x6.raw,300
dnprx1,0x1343,0x0005,dnp_ds40_4x6.raw,310
dnprx1,0x1343,0x0005,dnp_ds40_6x8-600.raw,400
dnprx1,0x1343,0x0005,dnp_dsrx1-4x6c.raw,400
citizencw02,0x1343,0x0006,dnp_ds40_4x6.raw,300
citizencw02,0x1343,0x0006,dnp_ds40_4x6.raw,310
citizencw02,0x1343,0x0006,dnp_ds40_6x8-600.raw,400

1 #backend,vid,pid,filename,mediatype
174 dnprx1,0x1343,0x0005,dnp_ds40_4x6.raw,300
175 dnprx1,0x1343,0x0005,dnp_ds40_4x6.raw,310
176 dnprx1,0x1343,0x0005,dnp_ds40_6x8-600.raw,400
177 dnprx1,0x1343,0x0005,dnp_dsrx1-4x6c.raw,400
178 citizencw02,0x1343,0x0006,dnp_ds40_4x6.raw,300
179 citizencw02,0x1343,0x0006,dnp_ds40_4x6.raw,310
180 citizencw02,0x1343,0x0006,dnp_ds40_6x8-600.raw,400

BIN
testjobs/dnp_dsrx1-4x6c.raw (Stored with Git LFS) Normal file

Binary file not shown.