sinfonia: Common header/job parsing code for Sinfonia models.
Covers: S2145, S6145, S6245
This commit is contained in:
parent
ff2dda1c97
commit
ce0fa508f0
|
@ -1460,64 +1460,70 @@ static void shinkos2145_teardown(void *vctx) {
|
|||
free(ctx);
|
||||
}
|
||||
|
||||
static int shinkos2145_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
|
||||
struct shinkos2145_ctx *ctx = vctx;
|
||||
int ret;
|
||||
#define SINFONIA_HDR1_LEN 0x10
|
||||
#define SINFONIA_HDR2_LEN 0x64
|
||||
#define SINFONIA_HDR_LEN (SINFONIA_HDR1_LEN + SINFONIA_HDR2_LEN)
|
||||
#define SINFONIA_DPI 300
|
||||
|
||||
int sinfonia_read_parse(int data_fd, uint32_t model, void *vhdr, uint8_t **data, int *datalen)
|
||||
{
|
||||
uint32_t *hdr = vhdr;
|
||||
int ret, i;
|
||||
uint8_t tmpbuf[4];
|
||||
|
||||
struct shinkos2145_printjob *job = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
job = malloc(sizeof(*job));
|
||||
if (!job) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
memset(job, 0, sizeof(*job));
|
||||
job->copies = copies; // XXX hdr.copies
|
||||
|
||||
/* Read in then validate header */
|
||||
ret = read(data_fd, &job->hdr, sizeof(job->hdr));
|
||||
if (ret < 0 || ret != sizeof(job->hdr)) {
|
||||
/* Read in header */
|
||||
ret = read(data_fd, hdr, SINFONIA_HDR_LEN);
|
||||
if (ret < 0 || ret != SINFONIA_HDR_LEN) {
|
||||
if (ret == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 0, (int)sizeof(job->hdr));
|
||||
ERROR("Read failed (%d/%d)\n",
|
||||
ret, SINFONIA_HDR_LEN);
|
||||
perror("ERROR: Read failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(job->hdr.len1) != 0x10 ||
|
||||
le32_to_cpu(job->hdr.len2) != 0x64 ||
|
||||
le32_to_cpu(job->hdr.dpi) != 300) {
|
||||
/* Byteswap everything */
|
||||
for (i = 0 ; i < (SINFONIA_HDR_LEN / 4) ; i++) {
|
||||
hdr[i] = le32_to_cpu(hdr[i]);
|
||||
}
|
||||
|
||||
/* Sanity-check headers */
|
||||
if (hdr[0] != SINFONIA_HDR1_LEN ||
|
||||
hdr[4] != SINFONIA_HDR2_LEN ||
|
||||
hdr[22] != SINFONIA_DPI) {
|
||||
ERROR("Unrecognized header data format!\n");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(job->hdr.model) != 2145) {
|
||||
ERROR("Unrecognized printer (%u)!\n", le32_to_cpu(job->hdr.model));
|
||||
|
||||
if (hdr[1] != model) {
|
||||
ERROR("job/printer mismatch (%u/%u)!\n", hdr[1], model);
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
job->datalen = le32_to_cpu(job->hdr.rows) * le32_to_cpu(job->hdr.columns) * 3;
|
||||
job->databuf = malloc(job->datalen);
|
||||
if (!job->databuf) {
|
||||
if (!hdr[13] || !hdr[14]) {
|
||||
ERROR("Bad job parameters!\n");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
/* Work out data length */
|
||||
*datalen = hdr[13] * hdr[14] * 3;
|
||||
*data = malloc(*datalen);
|
||||
if (!*data) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
|
||||
/* Read in payload data */
|
||||
{
|
||||
int remain = job->datalen;
|
||||
uint8_t *ptr = job->databuf;
|
||||
uint32_t remain = *datalen;
|
||||
uint8_t *ptr = *data;
|
||||
do {
|
||||
ret = read(data_fd, ptr, remain);
|
||||
if (ret < 0) {
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, remain, job->datalen);
|
||||
ret, remain, *datalen);
|
||||
perror("ERROR: Read failed");
|
||||
free(*data);
|
||||
*data = NULL;
|
||||
return ret;
|
||||
}
|
||||
ptr += ret;
|
||||
|
@ -1528,9 +1534,10 @@ static int shinkos2145_read_parse(void *vctx, const void **vjob, int data_fd, in
|
|||
/* Make sure footer is sane too */
|
||||
ret = read(data_fd, tmpbuf, 4);
|
||||
if (ret != 4) {
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 4, 4);
|
||||
ERROR("Read failed (%d/%d)\n", ret, 4);
|
||||
perror("ERROR: Read failed");
|
||||
free(*data);
|
||||
*data = NULL;
|
||||
return ret;
|
||||
}
|
||||
if (tmpbuf[0] != 0x04 ||
|
||||
|
@ -1538,9 +1545,41 @@ static int shinkos2145_read_parse(void *vctx, const void **vjob, int data_fd, in
|
|||
tmpbuf[2] != 0x02 ||
|
||||
tmpbuf[3] != 0x01) {
|
||||
ERROR("Unrecognized footer data format!\n");
|
||||
return CUPS_BACKEND_FAILED;
|
||||
free (*data);
|
||||
*data = NULL;
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static int shinkos2145_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
|
||||
struct shinkos2145_ctx *ctx = vctx;
|
||||
struct shinkos2145_printjob *job = NULL;
|
||||
int ret;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
job = malloc(sizeof(*job));
|
||||
if (!job) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
memset(job, 0, sizeof(*job));
|
||||
|
||||
/* Common read/parse code */
|
||||
ret = sinfonia_read_parse(data_fd, 2145, &job->hdr, &job->databuf, &job->datalen);
|
||||
if (ret) {
|
||||
free(job);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (job->hdr.copies > 1)
|
||||
job->copies = job->hdr.copies;
|
||||
else
|
||||
job->copies = copies;
|
||||
|
||||
*vjob = job;
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
|
@ -1564,9 +1603,9 @@ static int shinkos2145_main_loop(void *vctx, const void *vjob) {
|
|||
/* Validate print sizes */
|
||||
for (i = 0; i < ctx->media.count ; i++) {
|
||||
/* Look for matching media */
|
||||
if (le16_to_cpu(ctx->media.items[i].columns) == cpu_to_le16(le32_to_cpu(job->hdr.columns)) &&
|
||||
le16_to_cpu(ctx->media.items[i].rows) == cpu_to_le16(le32_to_cpu(job->hdr.rows)) &&
|
||||
ctx->media.items[i].print_type == le32_to_cpu(job->hdr.method))
|
||||
if (le16_to_cpu(ctx->media.items[i].columns) == cpu_to_le16(job->hdr.columns) &&
|
||||
le16_to_cpu(ctx->media.items[i].rows) == cpu_to_le16(job->hdr.rows) &&
|
||||
ctx->media.items[i].print_type == job->hdr.method)
|
||||
break;
|
||||
}
|
||||
if (i == ctx->media.count) {
|
||||
|
@ -1647,11 +1686,11 @@ top:
|
|||
|
||||
print->id = ctx->jobid;
|
||||
print->count = cpu_to_le16(job->copies);
|
||||
print->columns = cpu_to_le16(le32_to_cpu(job->hdr.columns));
|
||||
print->rows = cpu_to_le16(le32_to_cpu(job->hdr.rows));
|
||||
print->media = le32_to_cpu(job->hdr.media);
|
||||
print->mode = le32_to_cpu(job->hdr.mode);
|
||||
print->method = le32_to_cpu(job->hdr.method);
|
||||
print->columns = cpu_to_le16(job->hdr.columns);
|
||||
print->rows = cpu_to_le16(job->hdr.rows);
|
||||
print->media = job->hdr.media;
|
||||
print->mode = job->hdr.mode;
|
||||
print->method = job->hdr.method;
|
||||
|
||||
if ((ret = s2145_do_cmd(ctx,
|
||||
cmdbuf, sizeof(*print),
|
||||
|
@ -1799,7 +1838,7 @@ static const char *shinkos2145_prefixes[] = {
|
|||
|
||||
struct dyesub_backend shinkos2145_backend = {
|
||||
.name = "Shinko/Sinfonia CHC-S2145/S2",
|
||||
.version = "0.56",
|
||||
.version = "0.57",
|
||||
.uri_prefixes = shinkos2145_prefixes,
|
||||
.cmdline_usage = shinkos2145_cmdline,
|
||||
.cmdline_arg = shinkos2145_cmdline_arg,
|
||||
|
|
|
@ -1001,7 +1001,7 @@ static const char *print_ribbons (uint8_t v) {
|
|||
return "6x8";
|
||||
case RIBBON_6x9:
|
||||
return "6x9";
|
||||
// XXX 89x??? rubbons.
|
||||
// XXX 89x??? ribbons.
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
@ -1083,7 +1083,7 @@ struct s6145_imagecorr_data {
|
|||
/* Private data structure */
|
||||
struct shinkos6145_printjob {
|
||||
uint8_t *databuf;
|
||||
size_t datalen;
|
||||
int datalen;
|
||||
|
||||
struct s6145_printjob_hdr hdr;
|
||||
|
||||
|
@ -2074,13 +2074,13 @@ static void lib6145_process_image(uint8_t *src, uint16_t *dest,
|
|||
}
|
||||
}
|
||||
|
||||
int sinfonia_read_parse(int data_fd, uint32_t model, void *vhdr, uint8_t **data, int *datalen);
|
||||
|
||||
static int shinkos6145_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
|
||||
struct shinkos6145_ctx *ctx = vctx;
|
||||
int ret;
|
||||
uint8_t tmpbuf[4];
|
||||
uint8_t input_ymc;
|
||||
|
||||
struct shinkos6145_printjob *job = NULL;
|
||||
int ret;
|
||||
uint8_t input_ymc;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
@ -2091,57 +2091,18 @@ static int shinkos6145_read_parse(void *vctx, const void **vjob, int data_fd, in
|
|||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
memset(job, 0, sizeof(*job));
|
||||
job->copies = copies; // XXX hdr.copies?
|
||||
|
||||
/* Read in then validate header */
|
||||
ret = read(data_fd, &job->hdr, sizeof(job->hdr));
|
||||
if (ret < 0 || ret != sizeof(job->hdr)) {
|
||||
shinkos6145_cleanup_job(job);
|
||||
if (ret == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 0, (int)sizeof(job->hdr));
|
||||
perror("ERROR: Read failed");
|
||||
/* Common read/parse code */
|
||||
ret = sinfonia_read_parse(data_fd, 6145, &job->hdr, &job->databuf, &job->datalen);
|
||||
if (ret) {
|
||||
free(job);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SWAP_HDR(__x) job->hdr.__x = le32_to_cpu(job->hdr.__x)
|
||||
|
||||
SWAP_HDR(len1);
|
||||
SWAP_HDR(model);
|
||||
SWAP_HDR(media_w);
|
||||
SWAP_HDR(len2);
|
||||
SWAP_HDR(media);
|
||||
SWAP_HDR(method);
|
||||
SWAP_HDR(qual);
|
||||
SWAP_HDR(oc_mode);
|
||||
SWAP_HDR(columns);
|
||||
SWAP_HDR(rows);
|
||||
SWAP_HDR(copies);
|
||||
SWAP_HDR(dpi);
|
||||
SWAP_HDR(ext_flags);
|
||||
|
||||
#undef SWAP_HDR
|
||||
|
||||
if (job->hdr.len1 != 0x10 ||
|
||||
job->hdr.len2 != 0x64 ||
|
||||
job->hdr.dpi != 300) {
|
||||
ERROR("Unrecognized header data format!\n");
|
||||
shinkos6145_cleanup_job(job);
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
if (job->hdr.model != 6145) {
|
||||
ERROR("Unrecognized printer (%u)!\n", job->hdr.model);
|
||||
shinkos6145_cleanup_job(job);
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
if (!job->hdr.rows || !job->hdr.columns) {
|
||||
ERROR("Bad print job header!\n");
|
||||
shinkos6145_cleanup_job(job);
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
if (job->hdr.copies > 1)
|
||||
job->copies = job->hdr.copies;
|
||||
else
|
||||
job->copies = copies;
|
||||
|
||||
/* Extended spool format to re-purpose an unused header field.
|
||||
When bit 0 is set, this tells the backend that the data is
|
||||
|
@ -2149,49 +2110,6 @@ static int shinkos6145_read_parse(void *vctx, const void **vjob, int data_fd, in
|
|||
to do the conversion ourselves. Saves some processing overhead */
|
||||
input_ymc = job->hdr.ext_flags & 0x01;
|
||||
|
||||
job->datalen = job->hdr.rows * job->hdr.columns * 3;
|
||||
job->databuf = malloc(job->datalen);
|
||||
if (!job->databuf) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
shinkos6145_cleanup_job(job);
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
|
||||
{
|
||||
int remain = job->datalen;
|
||||
uint8_t *ptr = job->databuf;
|
||||
do {
|
||||
ret = read(data_fd, ptr, remain);
|
||||
if (ret < 0) {
|
||||
ERROR("Read failed (%d/%d/%zu)\n",
|
||||
ret, remain, job->datalen);
|
||||
perror("ERROR: Read failed");
|
||||
shinkos6145_cleanup_job(job);
|
||||
return ret;
|
||||
}
|
||||
ptr += ret;
|
||||
remain -= ret;
|
||||
} while (remain);
|
||||
}
|
||||
|
||||
/* Make sure footer is sane too */
|
||||
ret = read(data_fd, tmpbuf, 4);
|
||||
if (ret != 4) {
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 4, 4);
|
||||
perror("ERROR: Read failed");
|
||||
shinkos6145_cleanup_job(job);
|
||||
return ret;
|
||||
}
|
||||
if (tmpbuf[0] != 0x04 ||
|
||||
tmpbuf[1] != 0x03 ||
|
||||
tmpbuf[2] != 0x02 ||
|
||||
tmpbuf[3] != 0x01) {
|
||||
ERROR("Unrecognized footer data format!\n");
|
||||
shinkos6145_cleanup_job(job);
|
||||
return CUPS_BACKEND_FAILED;
|
||||
}
|
||||
|
||||
/* Convert packed RGB to planar YMC if necessary */
|
||||
if (!input_ymc) {
|
||||
INFO("Converting Packed RGB to Planar YMC\n");
|
||||
|
@ -2569,7 +2487,7 @@ static const char *shinkos6145_prefixes[] = {
|
|||
|
||||
struct dyesub_backend shinkos6145_backend = {
|
||||
.name = "Shinko/Sinfonia CHC-S6145/CS2",
|
||||
.version = "0.31",
|
||||
.version = "0.32",
|
||||
.uri_prefixes = shinkos6145_prefixes,
|
||||
.cmdline_usage = shinkos6145_cmdline,
|
||||
.cmdline_arg = shinkos6145_cmdline_arg,
|
||||
|
|
|
@ -1530,12 +1530,12 @@ static void shinkos6245_teardown(void *vctx) {
|
|||
free(ctx);
|
||||
}
|
||||
|
||||
int sinfonia_read_parse(int data_fd, uint32_t model, void *vhdr, uint8_t **data, int *datalen);
|
||||
|
||||
static int shinkos6245_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
|
||||
struct shinkos6245_ctx *ctx = vctx;
|
||||
int ret;
|
||||
uint8_t tmpbuf[4];
|
||||
|
||||
struct shinkos6245_printjob *job = NULL;
|
||||
int ret;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
@ -1546,75 +1546,18 @@ static int shinkos6245_read_parse(void *vctx, const void **vjob, int data_fd, in
|
|||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
memset(job, 0, sizeof(*job));
|
||||
job->copies = copies; // XXX hdr.copies
|
||||
|
||||
/* Read in then validate header */
|
||||
ret = read(data_fd, &job->hdr, sizeof(job->hdr));
|
||||
if (ret < 0 || ret != sizeof(job->hdr)) {
|
||||
if (ret == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 0, (int)sizeof(job->hdr));
|
||||
perror("ERROR: Read failed");
|
||||
/* Common read/parse code */
|
||||
ret = sinfonia_read_parse(data_fd, 6245, &job->hdr, &job->databuf, &job->datalen);
|
||||
if (ret) {
|
||||
free(job);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(job->hdr.len1) != 0x10 ||
|
||||
le32_to_cpu(job->hdr.len2) != 0x64 ||
|
||||
le32_to_cpu(job->hdr.dpi) != 300) {
|
||||
ERROR("Unrecognized header data format!\n");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(job->hdr.model) != 6245) {
|
||||
ERROR("Unrecognized printer (%u)!\n", le32_to_cpu(job->hdr.model));
|
||||
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
if (job->databuf) {
|
||||
free(job->databuf);
|
||||
job->databuf = NULL;
|
||||
}
|
||||
|
||||
job->datalen = le32_to_cpu(job->hdr.rows) * le32_to_cpu(job->hdr.columns) * 3;
|
||||
job->databuf = malloc(job->datalen);
|
||||
if (!job->databuf) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
|
||||
{
|
||||
int remain = job->datalen;
|
||||
uint8_t *ptr = job->databuf;
|
||||
do {
|
||||
ret = read(data_fd, ptr, remain);
|
||||
if (ret < 0) {
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, remain, job->datalen);
|
||||
perror("ERROR: Read failed");
|
||||
return ret;
|
||||
}
|
||||
ptr += ret;
|
||||
remain -= ret;
|
||||
} while (remain);
|
||||
}
|
||||
|
||||
/* Make sure footer is sane too */
|
||||
ret = read(data_fd, tmpbuf, 4);
|
||||
if (ret != 4) {
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 4, 4);
|
||||
perror("ERROR: Read failed");
|
||||
return ret;
|
||||
}
|
||||
if (tmpbuf[0] != 0x04 ||
|
||||
tmpbuf[1] != 0x03 ||
|
||||
tmpbuf[2] != 0x02 ||
|
||||
tmpbuf[3] != 0x01) {
|
||||
ERROR("Unrecognized footer data format!\n");
|
||||
return CUPS_BACKEND_FAILED;
|
||||
}
|
||||
if (job->hdr.copies > 1)
|
||||
job->copies = job->hdr.copies;
|
||||
else
|
||||
job->copies = copies;
|
||||
|
||||
*vjob = job;
|
||||
|
||||
|
@ -1647,7 +1590,7 @@ static int shinkos6245_main_loop(void *vctx, const void *vjob) {
|
|||
copies = 120;
|
||||
|
||||
/* Set up mcut */
|
||||
switch (le32_to_cpu(job->hdr.media)) {
|
||||
switch (job->hdr.media) {
|
||||
case MEDIA_8x4_2:
|
||||
case MEDIA_8x5_2:
|
||||
case MEDIA_8x6_2:
|
||||
|
@ -1664,8 +1607,8 @@ static int shinkos6245_main_loop(void *vctx, const void *vjob) {
|
|||
/* Validate print sizes */
|
||||
for (i = 0; i < ctx->media.count ; i++) {
|
||||
/* Look for matching media */
|
||||
if (le16_to_cpu(ctx->media.items[i].columns) == cpu_to_le16(le32_to_cpu(job->hdr.columns)) &&
|
||||
le16_to_cpu(ctx->media.items[i].rows) == cpu_to_le16(le32_to_cpu(job->hdr.rows)))
|
||||
if (le16_to_cpu(ctx->media.items[i].columns) == cpu_to_le16(job->hdr.columns) &&
|
||||
le16_to_cpu(ctx->media.items[i].rows) == cpu_to_le16(job->hdr.rows))
|
||||
break;
|
||||
}
|
||||
if (i == ctx->media.count) {
|
||||
|
@ -1776,9 +1719,9 @@ top:
|
|||
|
||||
print->id = ctx->jobid;
|
||||
print->count = cpu_to_le16(copies);
|
||||
print->columns = cpu_to_le16(le32_to_cpu(job->hdr.columns));
|
||||
print->rows = cpu_to_le16(le32_to_cpu(job->hdr.rows));
|
||||
print->mode = le32_to_cpu(job->hdr.oc_mode);
|
||||
print->columns = cpu_to_le16(job->hdr.columns);
|
||||
print->rows = cpu_to_le16(job->hdr.rows);
|
||||
print->mode = job->hdr.oc_mode;
|
||||
print->method = mcut;
|
||||
|
||||
if ((ret = s6245_do_cmd(ctx,
|
||||
|
@ -1917,7 +1860,7 @@ static const char *shinkos6245_prefixes[] = {
|
|||
|
||||
struct dyesub_backend shinkos6245_backend = {
|
||||
.name = "Shinko/Sinfonia CHC-S6245",
|
||||
.version = "0.15WIP",
|
||||
.version = "0.16WIP",
|
||||
.uri_prefixes = shinkos6245_prefixes,
|
||||
.cmdline_usage = shinkos6245_cmdline,
|
||||
.cmdline_arg = shinkos6245_cmdline_arg,
|
||||
|
|
Loading…
Reference in a new issue