summaryrefslogtreecommitdiff
path: root/src/cups/backend_sonyupdr150.c
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2018-09-25 08:33:05 +0200
committerDidier Raboud <odyx@debian.org>2018-09-25 08:33:05 +0200
commite50542121e724e851fc5d6c68bb773f80c0bc12c (patch)
tree655c3f6331a6e8fd8b09ceb4da8f5896484ae16a /src/cups/backend_sonyupdr150.c
parent9dd97a029bf391c42b1dc76f2f7c5e386bb8f466 (diff)
New upstream version 5.3.1
Diffstat (limited to 'src/cups/backend_sonyupdr150.c')
-rw-r--r--src/cups/backend_sonyupdr150.c396
1 files changed, 278 insertions, 118 deletions
diff --git a/src/cups/backend_sonyupdr150.c b/src/cups/backend_sonyupdr150.c
index dae8bf1..5e8ae2e 100644
--- a/src/cups/backend_sonyupdr150.c
+++ b/src/cups/backend_sonyupdr150.c
@@ -1,7 +1,7 @@
/*
* Sony UP-DR150 Photo Printer CUPS backend -- libusb-1.0 version
*
- * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2018 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -18,11 +18,12 @@
* for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* [http://www.gnu.org/licenses/gpl-2.0.html]
*
+ * SPDX-License-Identifier: GPL-2.0+
+ *
*/
#include <stdio.h>
@@ -39,23 +40,20 @@
#include "backend_common.h"
-/* Exported */
-#define USB_VID_SONY 0x054C
-#define USB_PID_SONY_UPDR150 0x01E8
-#define USB_PID_SONY_UPDR200 0x035F
-#define USB_PID_SONY_UPCR10 0x0226
-
/* Private data structure */
+struct updr150_printjob {
+ uint8_t *databuf;
+ int datalen;
+ int copies;
+};
+
struct updr150_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
- uint8_t *databuf;
- int datalen;
-
- uint32_t copies_offset;
+ struct marker marker;
};
static void* updr150_init(void)
@@ -69,26 +67,34 @@ static void* updr150_init(void)
return ctx;
}
-static void updr150_attach(void *vctx, struct libusb_device_handle *dev,
- uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
+static int updr150_attach(void *vctx, struct libusb_device_handle *dev, int type,
+ uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
{
struct updr150_ctx *ctx = vctx;
- struct libusb_device *device;
- struct libusb_device_descriptor desc;
UNUSED(jobid);
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
+ ctx->type = type;
+
+ ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
+ ctx->marker.name = "Unknown";
+ ctx->marker.levelmax = -1;
+ ctx->marker.levelnow = -2;
+
+ return CUPS_BACKEND_OK;
+}
- device = libusb_get_device(dev);
- libusb_get_device_descriptor(device, &desc);
+static void updr150_cleanup_job(const void *vjob)
+{
+ const struct updr150_printjob *job = vjob;
- ctx->type = lookup_printer_type(&updr150_backend,
- desc.idVendor, desc.idProduct);
+ if (job->databuf)
+ free(job->databuf);
- ctx->copies_offset = 0;
+ free((void*)job);
}
static void updr150_teardown(void *vctx) {
@@ -97,147 +103,164 @@ static void updr150_teardown(void *vctx) {
if (!ctx)
return;
- if (ctx->databuf)
- free(ctx->databuf);
free(ctx);
}
#define MAX_PRINTJOB_LEN 16736455
-static int updr150_read_parse(void *vctx, int data_fd) {
+static int updr150_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct updr150_ctx *ctx = vctx;
int len, run = 1;
+ uint32_t copies_offset = 0;
+
+ struct updr150_printjob *job = NULL;
if (!ctx)
return CUPS_BACKEND_FAILED;
- if (ctx->databuf) {
- free(ctx->databuf);
- ctx->databuf = NULL;
+ job = malloc(sizeof(*job));
+ if (!job) {
+ ERROR("Memory allocation failure!\n");
+ return CUPS_BACKEND_RETRY_CURRENT;
}
+ memset(job, 0, sizeof(*job));
+ job->copies = copies;
- ctx->datalen = 0;
- ctx->databuf = malloc(MAX_PRINTJOB_LEN);
- if (!ctx->databuf) {
+ job->datalen = 0;
+ job->databuf = malloc(MAX_PRINTJOB_LEN);
+ if (!job->databuf) {
ERROR("Memory allocation failure!\n");
- return CUPS_BACKEND_FAILED;
+ updr150_cleanup_job(job);
+ return CUPS_BACKEND_RETRY_CURRENT;
}
while(run) {
int i;
int keep = 0;
- i = read(data_fd, ctx->databuf + ctx->datalen, 4);
- if (i < 0)
+ i = read(data_fd, job->databuf + job->datalen, 4);
+ if (i < 0) {
+ updr150_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
+ }
if (i == 0)
break;
- memcpy(&len, ctx->databuf + ctx->datalen, sizeof(len));
+ memcpy(&len, job->databuf + job->datalen, sizeof(len));
len = le32_to_cpu(len);
/* Filter out chunks we don't send to the printer */
- switch (len) {
- case 0xffffff60:
- case 0xffffff6a:
- case 0xffffffeb:
- case 0xffffffec:
- case 0xffffffed:
- case 0xfffffff4:
- case 0xfffffff8:
- case 0xfffffff9:
- case 0xfffffffa:
- case 0xfffffffb:
- case 0xfffffffc:
- case 0xffffffff:
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 0);
- len = 0;
- break;
- case 0xfffffff3:
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 0);
- len = 0;
- if (ctx->type == P_SONY_UPDR150)
- run = 0;
- break;
- case 0xfffffff7:
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 0);
- len = 0;
- if (ctx->type == P_SONY_UPCR10)
- run = 0;
- break;
- case 0xffffffef:
- case 0xfffffff5:
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 4);
- len = 4;
- break;
- default:
- if (len & 0xff000000) {
- ERROR("Unknown block ID '%08x', aborting!\n", len);
- return CUPS_BACKEND_CANCEL;
- } else {
- /* Only keep these chunks */
+ if (len & 0xf0000000) {
+ switch (len) {
+ case 0xfffffff3:
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ if (ctx->type == P_SONY_UPDR150)
+ run = 0;
+ break;
+ case 0xfffffff7:
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ if (ctx->type == P_SONY_UPCR10)
+ run = 0;
+ break;
+ case 0xfffffff8: // 895
+ case 0xfffffff4: // 897
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ if (ctx->type == P_SONY_UPD89x)
+ run = 0;
+ break;
+ case 0xffffffeb:
+ case 0xffffffec:
+ case 0xffffffed:
+ case 0xffffffee:
+ case 0xffffffef:
+ case 0xfffffff5:
if(dyesub_debug)
- DEBUG("Data block (len %d)\n", len);
- keep = 1;
+ DEBUG("Block ID '%08x' (len %d)\n", len, 4);
+ len = 4;
+ break;
+ default:
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ break;
}
- break;
+ } else {
+ /* Only keep these chunks */
+ if(dyesub_debug)
+ DEBUG("Data block (len %d)\n", len);
+ keep = 1;
}
if (keep)
- ctx->datalen += sizeof(uint32_t);
+ job->datalen += sizeof(uint32_t);
/* Read in the data chunk */
while(len > 0) {
- i = read(data_fd, ctx->databuf + ctx->datalen, len);
- if (i < 0)
+ i = read(data_fd, job->databuf + job->datalen, len);
+ if (i < 0) {
+ updr150_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
+ }
if (i == 0)
break;
- if (ctx->databuf[ctx->datalen] == 0x1b &&
- ctx->databuf[ctx->datalen + 1] == 0xee) {
+ if (job->databuf[job->datalen] == 0x1b &&
+ job->databuf[job->datalen + 1] == 0xee) {
if (ctx->type == P_SONY_UPCR10)
- ctx->copies_offset = ctx->datalen + 8;
+ copies_offset = job->datalen + 8;
else
- ctx->copies_offset = ctx->datalen + 12;
+ copies_offset = job->datalen + 12;
}
if (keep)
- ctx->datalen += i;
+ job->datalen += i;
len -= i;
}
}
- if (!ctx->datalen)
+ if (!job->datalen) {
+ updr150_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Some models specify copies in the print job */
+ if (copies_offset) {
+ job->databuf[copies_offset] = job->copies;
+ job->copies = 1;
+ }
+
+ *vjob = job;
return CUPS_BACKEND_OK;
}
-static int updr150_main_loop(void *vctx, int copies) {
+static int updr150_main_loop(void *vctx, const void *vjob) {
struct updr150_ctx *ctx = vctx;
int i, ret;
+ int copies;
+
+ const struct updr150_printjob *job = vjob;
if (!ctx)
return CUPS_BACKEND_FAILED;
+ if (!job)
+ return CUPS_BACKEND_FAILED;
- /* Some models specify copies in the print job */
- if (ctx->copies_offset) {
- ctx->databuf[ctx->copies_offset] = copies;
- copies = 1;
- }
+ copies = job->copies;
top:
i = 0;
- while (i < ctx->datalen) {
+ while (i < job->datalen) {
uint32_t len;
- memcpy(&len, ctx->databuf + i, sizeof(len));
+ memcpy(&len, job->databuf + i, sizeof(len));
len = le32_to_cpu(len);
i += sizeof(uint32_t);
if ((ret = send_data(ctx->dev, ctx->endp_down,
- ctx->databuf + i, len)))
+ job->databuf + i, len)))
return CUPS_BACKEND_FAILED;
i += len;
@@ -275,21 +298,54 @@ static int updr150_cmdline_arg(void *vctx, int argc, char **argv)
return 0;
}
+static int updr150_query_markers(void *vctx, struct marker **markers, int *count)
+{
+ struct updr150_ctx *ctx = vctx;
+
+ *markers = &ctx->marker;
+ *count = 1;
+
+ return CUPS_BACKEND_OK;
+}
+
+static const char *sonyupdr150_prefixes[] = {
+ "sonyupdr150", // Family name.
+ "sony-updr150", "sony-updr200", "sony-upcr10",
+ // Backwards compatibility
+ "sonyupdr200", "sonyupcr10",
+// "sonyupd895", "sonyupd897", "sonyupd898",
+ NULL
+};
+
+/* Exported */
+#define USB_VID_SONY 0x054C
+#define USB_PID_SONY_UPDR150 0x01E8
+#define USB_PID_SONY_UPDR200 0x035F
+#define USB_PID_SONY_UPCR10 0x0226
+//#define USB_PID_SONY_UPD895 XXXXX // 0x7ea6?
+//#define USB_PID_SONY_UPD897 XXXXX // 0xbce7?
+//#define USB_PID_SONY_UPD898 XXXXX // 0x589a?
+
struct dyesub_backend updr150_backend = {
.name = "Sony UP-DR150/UP-DR200/UP-CR10",
- .version = "0.19",
- .uri_prefix = "sonyupdr150",
+ .version = "0.26",
+ .uri_prefixes = sonyupdr150_prefixes,
.cmdline_arg = updr150_cmdline_arg,
.init = updr150_init,
.attach = updr150_attach,
.teardown = updr150_teardown,
+ .cleanup_job = updr150_cleanup_job,
.read_parse = updr150_read_parse,
.main_loop = updr150_main_loop,
+ .query_markers = updr150_query_markers,
.devices = {
- { USB_VID_SONY, USB_PID_SONY_UPDR150, P_SONY_UPDR150, ""},
- { USB_VID_SONY, USB_PID_SONY_UPDR200, P_SONY_UPDR150, ""},
- { USB_VID_SONY, USB_PID_SONY_UPCR10, P_SONY_UPCR10, ""},
- { 0, 0, 0, ""}
+ { USB_VID_SONY, USB_PID_SONY_UPDR150, P_SONY_UPDR150, NULL, "sony-updr150"},
+ { USB_VID_SONY, USB_PID_SONY_UPDR200, P_SONY_UPDR150, NULL, "sony-updr200"},
+ { USB_VID_SONY, USB_PID_SONY_UPCR10, P_SONY_UPCR10, NULL, "sony-upcr10"},
+// { USB_VID_SONY, USB_PID_SONY_UPD895MD, P_SONY_UPD89x, NULL, "sonyupd895"},
+// { USB_VID_SONY, USB_PID_SONY_UPD897MD, P_SONY_UPD89x, NULL, "sonyupd897"},
+// { USB_VID_SONY, USB_PID_SONY_UPD898MD, P_SONY_UPD89x, NULL, "sonyupd898"},
+ { 0, 0, 0, NULL, NULL}
}
};
@@ -299,25 +355,18 @@ struct dyesub_backend updr150_backend = {
arguments. The purpose of the commands is unknown, but they presumably
instruct the driver to perform certain things.
- If you treat these 4 bytes as a 32-bit little-endian number, if the
- most significant four bits are bits are non-zero, the value is is to
+ If you treat these 4 bytes as a 32-bit little-endian number, if any of the
+ most significant 4 bits are non-zero, the value is is to
be interpreted as a driver command. If the most significant bits are
zero, the value signifies that the following N bytes of data should be
sent to the printer as-is.
Known driver "commands":
- 6a ff ff ff
- fc ff ff ff
- fb ff ff ff
- f4 ff ff ff
- ed ff ff ff
- f9 ff ff ff
- f8 ff ff ff
- ec ff ff ff
- eb ff ff ff
- fa ff ff ff
- f3 ff ff ff
+ eb ff ff ff ?? 00 00 00
+ ec ff ff ff ?? 00 00 00
+ ed ff ff ff ?? 00 00 00
+ ee ff ff ff ?? 00 00 00
ef ff ff ff XX 00 00 00 # XX == print size (0x01/0x02/0x03/0x04)
f5 ff ff ff YY 00 00 00 # YY == ??? (seen 0x01)
@@ -403,6 +452,117 @@ f7 ff ff ff
SH SH SH SH == Plane size, Big Endian (Rows * Cols * 3)
NN == Copies
+ **************
+
+ Sony UP-D895 spool format:
+
+ XX XX == cols, BE (fixed at 1280/0x500)
+ YY YY == rows, BE (798/0x031e,1038/0x040e,1475/0x05c3, 2484/09b4) @ 960/1280/1920/3840+4096
+ SS SS SS SS == data len (rows * cols, LE)
+ S' S' S' S' == data len (rows * cols, BE)
+ NN == copies (1 -> ??)
+ GG GG == ??? 0000/0050/011b/04aa/05aa at each resolution.
+ G' == Gamma 01 (soft), 03 (hard), 02 (normal)
+
+ 9c ff ff ff 97 ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff
+
+ 14 00 00 00
+ 1b 15 00 00 00 0d 00 00 00 00 00 01 GG GG 00 00 YY YY XX XX
+ 0b 00 00 00
+ 1b ea 00 00 00 00 S' S' S' S' 00
+ SS SS SS SS
+ ...DATA... (rows * cols)
+ ff ff ff ff
+ 09 00 00 00
+ 1b ee 00 00 00 02 00 00 NN
+ 0f 00 00 00
+ 1b e5 00 00 00 08 00 00 00 00 00 00 00 00 00
+ 0c 00 00 00
+ 1b c0 00 00 00 05 00 02 00 00 01 G'
+ 11 00 00 00
+ 1b c0 00 01 00 0a 00 02 01 00 06 00 00 00 00 00 00
+ 12 00 00 00
+ 1b e1 00 00 00 0b 00 00 08 00 GG GG 00 00 YY YY XX XX
+ 07 00 00 00
+ 1b 0a 00 00 00 00 00
+ fd ff ff ff f7 ff ff ff f8 ff ff ff
+
+ **************
+
+ Sony UP-D897 spool format:
+
+ NN NN == copies (00 for printer selected)
+ XX XX == cols (fixed @ 1280)
+ YY YY == rows
+ GG == gamma -- Table 2 == 2, Table 1 == 3, Table 3 == 1, Table 4 == 4
+ DD == "dark" +- 64.
+ LL == "light" +- 64.
+ AA == "advanced" +- 32.
+ SS == Sharpness 0-14
+ ZZ ZZ ZZ ZZ == Data length (BE)
+ Z` Z` Z` Z` == Data length (LE)
+
+
+ 83 ff ff ff fc ff ff ff fb ff ff ff f5 ff ff ff f1 ff ff ff f0 ff ff ff ef ff ff ff
+
+ 07 00 00 00
+ 1b 15 00 00 00 0d 00
+ 0d 00 00 00
+ 00 00 00 00 01 00 a2 00 00 YY YY XX XX
+
+ 0b 00 00 00
+ 1b ea 00 00 00 00 ZZ ZZ ZZ ZZ 00
+
+ Z` Z` Z` Z`
+ ...DATA...
+
+ ea ff ff ff
+
+ 07 00 00 00
+ 1b ee 00 00 00 02 00
+ 02 00 00 00
+ 00 NN
+
+ ee ff ff ff 01 00 00 00
+
+ 07 00 00 00
+ 1b e5 00 00 00 08 00
+ 08 00 00 00
+ 00 00 00 00 DD LL SS AA
+
+ eb ff ff ff ?? 00 00 00 <--- 02/05 5 at #3, 2 otherwise. Sharpness?
+
+ 07 00 00 00
+ 1b c0 00 00 00 05 00
+ 05 00 00 00
+ 02 00 00 01 GG
+
+ ec ff ff ff ?? 00 00 00 <--- 01/00/02/01/01 Seen. Unknown.
+
+ 07 00 00 00
+ 1b c0 00 01 00 0a 00
+ 0a 00 00 00
+ 02 01 00 06 00 00 00 00 00 00
+
+ ed ff ff ff 00 00 00 00
+
+ 07 00 00 00
+ 1b e1 00 00 00 0b 00
+ 0b 00 00 00
+ 00 08 00 00 a2 00 00 YY YY XX XX
+
+ fa ff ff ff
+
+ 07 00 00 00
+ 1b 0a 00 00 00 00 00
+
+ fc ff ff ff
+ fd ff ff ff
+ ff ff ff ff
+
+ 07 00 00 00
+ 1b 17 00 00 00 00 00
+ f4 ff ff ff
*/