DNP: Continuous & Discrete Panorama Processing
* Image must be submitted as a single, full-sized page (eg 6x14/6x20 on DS620) * Backend splits image into the necessary 2 or 3 panels w/ 2" overlap * Backend blends the overlapping areas together * Discrete panoramas work the same way, only no overlap and are larger Successfully tested on the DS620!
This commit is contained in:
parent
581602539f
commit
e74960ad84
7
Makefile
7
Makefile
|
@ -110,7 +110,8 @@ BACKENDS = canonselphy canonselphyneo dnpds40 hiti kodak605 kodak1400 kodak6800
|
|||
# List of data files
|
||||
DATAFILES = $(wildcard hiti_data/*bin) $(wildcard lib70x/data/*raw) \
|
||||
$(wildcard lib70x/data/*cpc) $(wildcard lib70x/data/*lut) \
|
||||
$(wildcard lib70x/data/*dat) $(wildcard lib70x/data/*csv)
|
||||
$(wildcard lib70x/data/*dat) $(wildcard lib70x/data/*csv) \
|
||||
$(wildcard dnp_data/*csv)
|
||||
|
||||
# For the s6145, mitsu70x, mitsud90, and mitsu9550 backends
|
||||
ifneq (,$(findstring mingw,$(CC)))
|
||||
|
@ -201,6 +202,10 @@ $(DATAFILES_TMP)/%: hiti_data/% | $(DATAFILES_TMP)
|
|||
@$(E) " LN " $@
|
||||
$(Q)$(LN) -sf ../$< $@
|
||||
|
||||
$(DATAFILES_TMP)/%: dnp_data/% | $(DATAFILES_TMP)
|
||||
@$(E) " LN " $@
|
||||
$(Q)$(LN) -sf ../$< $@
|
||||
|
||||
$(DATAFILES_TMP)/%: lib70x/data/% | $(DATAFILES_TMP)
|
||||
@$(E) " LN " $@
|
||||
$(Q)$(LN) -sf ../$< $@
|
||||
|
|
|
@ -60,16 +60,24 @@ struct dnpds40_printjob {
|
|||
int can_rewind;
|
||||
int buffcntrl;
|
||||
|
||||
int rows;
|
||||
int is_pano;
|
||||
|
||||
int buf_needed;
|
||||
int cut_paper;
|
||||
};
|
||||
|
||||
#define MAX_PRINTJOB_LEN (((ctx->native_width*ctx->max_height+1024+54+10))*3+1024) /* Worst-case, YMC */
|
||||
#define MAX_PANOPRINTJOB_LEN ((((ctx->native_width*ctx->max_height+1024+54+10))*3+1024)*3) /* Worst-case, YMC */
|
||||
|
||||
#define MFG_DNP 0
|
||||
#define MFG_CITIZEN 1
|
||||
#define MFG_MITSUBISHI 2
|
||||
#define MFG_FUJIFILM 3
|
||||
#define MFG_OTHER 4
|
||||
|
||||
#define USE_PANODATA_FILES
|
||||
|
||||
struct dnpds40_ctx {
|
||||
struct dyesub_connection *conn;
|
||||
|
||||
|
@ -230,6 +238,25 @@ struct dnpds40_cmd {
|
|||
#define MULTICUT_S_8x10_75 26
|
||||
#define MULTICUT_S_8x4X3 28 // different than roll type.
|
||||
|
||||
/* Special panorama sizes */
|
||||
#define MULTICUT_PANO_6x14 9000
|
||||
#define MULTICUT_PANO_6x20 9001
|
||||
#define MULTICUT_PANO_8x18 9010
|
||||
#define MULTICUT_PANO_8x26 9011
|
||||
#define MULTICUT_PANO_8x22 9012
|
||||
#define MULTICUT_PANO_8x32 9013
|
||||
#define MULTICUT_PANO_A4x21 9014
|
||||
#define MULTICUT_PANO_A4x31 9015
|
||||
|
||||
#define MULTICUT_PANO_6x16 9020
|
||||
#define MULTICUT_PANO_6x24 9021
|
||||
#define MULTICUT_PANO_8x20 9030
|
||||
#define MULTICUT_PANO_8x30 9031
|
||||
#define MULTICUT_PANO_8x24 9032
|
||||
#define MULTICUT_PANO_8x36 9033
|
||||
#define MULTICUT_PANO_A4x2 9034
|
||||
#define MULTICUT_PANO_A4x3 9035
|
||||
|
||||
#ifndef min
|
||||
#define min(__x, __y) ((__x) < (__y)) ? __x : __y
|
||||
#endif
|
||||
|
@ -244,6 +271,510 @@ static int legacy_qw410_read_parse(struct dnpds40_printjob *job, int data_fd, in
|
|||
static void dnpds40_cleanup_job(const void *vjob);
|
||||
static int dnpds40_query_markers(void *vctx, struct marker **markers, int *count);
|
||||
|
||||
/* Panorama crap */
|
||||
struct panodata_row {
|
||||
uint16_t start_row;
|
||||
double rhYMC[3];
|
||||
double lhYMC[3];
|
||||
};
|
||||
|
||||
#define DNP_PANO_MAXROWS 64
|
||||
struct dnp_panodata {
|
||||
uint16_t elements;
|
||||
struct panodata_row rows[DNP_PANO_MAXROWS];
|
||||
};
|
||||
|
||||
#ifdef USE_PANODATA_FILES
|
||||
#define PANODATA_DS620 "LUTData_0010.csv"
|
||||
#define PANODATA_DS820 "LUTData820_0010.csv"
|
||||
|
||||
static struct dnp_panodata *dnp_read_panodata(const char *filename)
|
||||
{
|
||||
struct dnp_panodata *pano = NULL;
|
||||
|
||||
FILE *f;
|
||||
char buf[4096];
|
||||
int line;
|
||||
char *ptr;
|
||||
|
||||
const char *delim = " ,\t\n";
|
||||
|
||||
if (!filename)
|
||||
return NULL;
|
||||
pano = malloc(sizeof(struct dnp_panodata));
|
||||
if (!pano)
|
||||
return NULL;
|
||||
|
||||
pano->elements = 0;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/%s", corrtable_path, filename);
|
||||
|
||||
f = fopen(buf, "r");
|
||||
if (!f)
|
||||
goto done_free;
|
||||
|
||||
/* Skip the first four lines */
|
||||
for (line = 0; line < DNP_PANO_MAXROWS ; line++) {
|
||||
if (fgets(buf, sizeof(buf), f) == NULL)
|
||||
break;
|
||||
|
||||
ptr = strtok(buf, delim);
|
||||
if (!ptr)
|
||||
goto abort;
|
||||
|
||||
if (strcmp("REC", ptr))
|
||||
continue;
|
||||
|
||||
ptr = strtok(NULL, delim);
|
||||
if (!ptr)
|
||||
goto abort;
|
||||
pano->rows[pano->elements].start_row = strtol(ptr, NULL, 10);
|
||||
|
||||
ptr = strtok(NULL, delim);
|
||||
if (!ptr)
|
||||
goto abort;
|
||||
pano->rows[pano->elements].rhYMC[0] = strtod(ptr,NULL);
|
||||
|
||||
ptr = strtok(NULL, delim);
|
||||
if (!ptr)
|
||||
goto abort;
|
||||
pano->rows[pano->elements].rhYMC[1] = strtod(ptr,NULL);
|
||||
|
||||
ptr = strtok(NULL, delim);
|
||||
if (!ptr)
|
||||
goto abort;
|
||||
pano->rows[pano->elements].rhYMC[2] = strtod(ptr,NULL);
|
||||
|
||||
ptr = strtok(NULL, delim);
|
||||
if (!ptr)
|
||||
goto abort;
|
||||
pano->rows[pano->elements].lhYMC[0] = strtod(ptr,NULL);
|
||||
|
||||
ptr = strtok(NULL, delim);
|
||||
if (!ptr)
|
||||
goto abort;
|
||||
pano->rows[pano->elements].lhYMC[1] = strtod(ptr,NULL);
|
||||
|
||||
ptr = strtok(NULL, delim);
|
||||
if (!ptr)
|
||||
goto abort;
|
||||
pano->rows[pano->elements].lhYMC[2] = strtod(ptr,NULL);
|
||||
|
||||
pano->elements++;
|
||||
}
|
||||
if (pano->elements < 20)
|
||||
goto abort;
|
||||
|
||||
fclose(f);
|
||||
|
||||
#if 0
|
||||
f = fopen("/tmp/panodata.h", "w");
|
||||
fprintf(f, "static struct dnp_panodata panodata = {\n");
|
||||
fprintf(f, "\t.elements = %d,\n", pano->elements);
|
||||
for (int i = 0 ; i < pano->elements ; i++) {
|
||||
fprintf(f, "\t.rows[%2u] = { %4u, { %1.10f, %1.10f, %1.10f }, { %1.10f, %1.10f, %1.10f} },\n",
|
||||
i,
|
||||
pano->rows[i].start_row,
|
||||
pano->rows[i].rhYMC[0],
|
||||
pano->rows[i].rhYMC[1],
|
||||
pano->rows[i].rhYMC[2],
|
||||
pano->rows[i].lhYMC[0],
|
||||
pano->rows[i].lhYMC[1],
|
||||
pano->rows[i].lhYMC[2]);
|
||||
}
|
||||
fprintf(f, "};\n");
|
||||
fclose(f);
|
||||
exit(1);
|
||||
#endif
|
||||
|
||||
return pano;
|
||||
|
||||
abort:
|
||||
fclose(f);
|
||||
|
||||
done_free:
|
||||
free(pano);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void dnp_free_panodata (struct dnp_panodata *pano)
|
||||
{
|
||||
if (pano)
|
||||
free(pano);
|
||||
}
|
||||
#else /* !USE_PANODATA_FILES */
|
||||
|
||||
#include "backend_panodata.h"
|
||||
|
||||
#define dnp_read_panodata(__fname) &panodata
|
||||
#define dnp_free_panodata(__pano)
|
||||
|
||||
#endif
|
||||
|
||||
#define PROCESS_PIXEL(__corr) \
|
||||
outdata[r * cols + c] = 255 - ((255 - (double)indata[r * cols + c]) * (__corr))
|
||||
|
||||
static void dnp_applypano_plane(const struct dnp_panodata *pano,
|
||||
const uint8_t *indata, uint8_t *outdata,
|
||||
uint16_t rows, const uint16_t cols, const uint16_t pad_rows,
|
||||
const uint16_t dpi, int overlap, const int plane,
|
||||
const int rh, const int lh)
|
||||
{
|
||||
uint16_t r, c;
|
||||
|
||||
/* Fill the start margin with white */
|
||||
if (pad_rows) {
|
||||
memset(outdata, 0xff, pad_rows * cols);
|
||||
outdata += pad_rows * cols;
|
||||
}
|
||||
|
||||
for (r = 0 ; r < rows; r++) {
|
||||
const struct panodata_row *lhc = pano ? &pano->rows[0] : NULL;
|
||||
const struct panodata_row *rhc = pano ? &pano->rows[pano->elements - 1] : NULL;
|
||||
|
||||
if (rh && r < overlap) {
|
||||
/* Row is in RH overlap portion of panel */
|
||||
int i;
|
||||
int row = (overlap - r);
|
||||
if (dpi == 600)
|
||||
row /= 2;
|
||||
for (i = 0 ; i < pano->elements-1 ; i++) {
|
||||
if (row >= pano->rows[i].start_row && row < pano->rows[i+1].start_row)
|
||||
break;
|
||||
}
|
||||
rhc = &pano->rows[i];
|
||||
} else if (lh && (rows -r) < overlap) {
|
||||
/* Row is in LH overlap portion of panel */
|
||||
int i;
|
||||
int row = (rows -r);
|
||||
if (dpi == 600)
|
||||
row /= 2;
|
||||
|
||||
for (i = 0 ; i < pano->elements-1 ; i++) {
|
||||
if (row >= pano->rows[i].start_row && row < pano->rows[i+1].start_row)
|
||||
break;
|
||||
}
|
||||
lhc = &pano->rows[i];
|
||||
} else {
|
||||
/* No processing on row, pass through as-is */
|
||||
memcpy(&outdata[r * cols], &indata[r * cols], cols);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rh && rhc && r < overlap) {
|
||||
/* Fade RH row */
|
||||
if (plane == 'Y')
|
||||
for (c = 0 ; c < cols ; c++) {
|
||||
PROCESS_PIXEL(rhc->rhYMC[0]);
|
||||
}
|
||||
else if (plane == 'M') {
|
||||
for (c = 0 ; c < cols ; c++) {
|
||||
PROCESS_PIXEL(rhc->rhYMC[1]);
|
||||
}
|
||||
} else {
|
||||
for (c = 0 ; c < cols ; c++) {
|
||||
PROCESS_PIXEL(rhc->rhYMC[2]);
|
||||
}
|
||||
}
|
||||
} else if (lh && lhc && (rows -r) < overlap) {
|
||||
/* Fade LH row */
|
||||
if (plane == 'Y')
|
||||
for (c = 0 ; c < cols ; c++) {
|
||||
PROCESS_PIXEL(lhc->lhYMC[0]);
|
||||
}
|
||||
else if (plane == 'M') {
|
||||
for (c = 0 ; c < cols ; c++) {
|
||||
PROCESS_PIXEL(lhc->lhYMC[1]);
|
||||
}
|
||||
} else {
|
||||
for (c = 0 ; c < cols ; c++) {
|
||||
PROCESS_PIXEL(lhc->lhYMC[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill the tail margin with white */
|
||||
if (pad_rows)
|
||||
memset(&outdata[rows * cols], 0xff, pad_rows * cols);
|
||||
}
|
||||
|
||||
static int dnp_panorama_splitjob(struct dnpds40_ctx *ctx,
|
||||
const struct dnpds40_printjob *injob,
|
||||
struct dnpds40_printjob **newjobs)
|
||||
{
|
||||
struct dnp_panodata *pano = NULL;
|
||||
int overlap = injob->dpi * 2;
|
||||
|
||||
uint16_t out_rows = 0;
|
||||
uint16_t in_rows = 0;
|
||||
uint8_t num_panels = 0;
|
||||
uint32_t new_multicut = 0;
|
||||
uint16_t pad_rows = 0;
|
||||
|
||||
in_rows = injob->dpi == 600 ? injob->rows / 2 : injob->rows;
|
||||
if (ctx->conn->type == P_DNP_DS620) {
|
||||
out_rows = 2436;
|
||||
new_multicut = MULTICUT_6x8;
|
||||
|
||||
if (in_rows == 4236) {
|
||||
num_panels = 2;
|
||||
pad_rows = 18;
|
||||
} else if (in_rows == 6036) {
|
||||
num_panels = 3;
|
||||
pad_rows = 18;
|
||||
} else if (in_rows == 2436*2) {
|
||||
num_panels = 2;
|
||||
overlap = 0;
|
||||
} else if (in_rows == 2436*3) {
|
||||
num_panels = 3;
|
||||
overlap = 0;
|
||||
} else {
|
||||
ERROR("Invalid panorama size (%d rows)\n", injob->rows);
|
||||
goto bail;
|
||||
}
|
||||
} else if (ctx->conn->type == P_DNP_DS820) {
|
||||
if (ctx->media == 600) { /* A4 */
|
||||
if (in_rows == 5436) {
|
||||
new_multicut = MULTICUT_A4x10;
|
||||
out_rows = 3036;
|
||||
pad_rows = 18;
|
||||
num_panels = 2;
|
||||
} else if (in_rows == 7836) {
|
||||
new_multicut = MULTICUT_A4x10;
|
||||
out_rows = 3036;
|
||||
pad_rows = 18;
|
||||
num_panels = 3;
|
||||
} else if (in_rows == 3036*2) {
|
||||
new_multicut = MULTICUT_A4x10;
|
||||
num_panels = 2;
|
||||
out_rows = 3036;
|
||||
overlap = 0;
|
||||
} else if (in_rows == 3036*3) {
|
||||
new_multicut = MULTICUT_A4x10;
|
||||
num_panels = 3;
|
||||
out_rows = 3036;
|
||||
overlap = 0;
|
||||
} else if (in_rows == 6452) {
|
||||
new_multicut = MULTICUT_A4;
|
||||
num_panels = 2;
|
||||
pad_rows = 18;
|
||||
out_rows = 3544;
|
||||
} else if (in_rows == 9360) {
|
||||
new_multicut = MULTICUT_A4;
|
||||
num_panels = 3;
|
||||
pad_rows = 18;
|
||||
out_rows = 3544;
|
||||
} else if (in_rows == 3544*2) {
|
||||
new_multicut = MULTICUT_A4;
|
||||
num_panels = 3;
|
||||
out_rows = 3544;
|
||||
overlap = 0;
|
||||
} else if (in_rows == 3544*3) {
|
||||
new_multicut = MULTICUT_A4;
|
||||
num_panels = 3;
|
||||
out_rows = 3544;
|
||||
overlap = 0;
|
||||
} else {
|
||||
ERROR("Invalid panorama size (%d rows)\n", injob->rows);
|
||||
goto bail;
|
||||
}
|
||||
} else { // 8x10/8x12
|
||||
if (in_rows == 5436) {
|
||||
new_multicut = MULTICUT_8x10;
|
||||
num_panels = 2;
|
||||
pad_rows = 18;
|
||||
out_rows = 3036;
|
||||
} else if (in_rows == 7836) {
|
||||
new_multicut = MULTICUT_8x10;
|
||||
num_panels = 3;
|
||||
pad_rows = 18;
|
||||
out_rows = 3036;
|
||||
} else if (in_rows == 3036*2) {
|
||||
new_multicut = MULTICUT_8x10;
|
||||
num_panels = 2;
|
||||
overlap = 0;
|
||||
out_rows = 3036;
|
||||
} else if (in_rows == 3036*3) {
|
||||
new_multicut = MULTICUT_8x10;
|
||||
num_panels = 3;
|
||||
overlap = 0;
|
||||
out_rows = 3036;
|
||||
} else if (in_rows == 6636) {
|
||||
new_multicut = MULTICUT_8x12;
|
||||
num_panels = 2;
|
||||
pad_rows = 18;
|
||||
out_rows = 3636;
|
||||
} else if (in_rows == 9636) {
|
||||
new_multicut = MULTICUT_8x12;
|
||||
num_panels = 3;
|
||||
pad_rows = 18;
|
||||
out_rows = 3636;
|
||||
} else if (in_rows == 3636*2) {
|
||||
new_multicut = MULTICUT_8x12;
|
||||
num_panels = 2;
|
||||
out_rows = 3636;
|
||||
overlap = 0;
|
||||
} else if (in_rows == 3636*3) {
|
||||
new_multicut = MULTICUT_8x12;
|
||||
num_panels = 3;
|
||||
out_rows = 3636;
|
||||
overlap = 0;
|
||||
} else {
|
||||
ERROR("Invalid panorama size (%d rows)\n", injob->rows);
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Double everything up for >300dpi */
|
||||
if (injob->dpi == 600) {
|
||||
out_rows *= 2;
|
||||
overlap *= 2;
|
||||
pad_rows *= 2;
|
||||
}
|
||||
|
||||
if (overlap) {
|
||||
#ifdef USE_PANODATA_FILES
|
||||
const char *filename = NULL;
|
||||
|
||||
if (ctx->conn->type == P_DNP_DS620)
|
||||
filename = PANODATA_DS620;
|
||||
else if (ctx->conn->type == P_DNP_DS820)
|
||||
filename = PANODATA_DS820;
|
||||
|
||||
if (!filename || !(pano = dnp_read_panodata(filename))) {
|
||||
ERROR("Failure to load panorama LUT file (%s)\n", filename);
|
||||
goto bail;
|
||||
}
|
||||
#else
|
||||
pano = dnp_read_panodata(NULL);
|
||||
#endif
|
||||
|
||||
DEBUG("Splitting continuous panorama job... (%d panels of %d+%d rows, %d overlap)\n", num_panels, out_rows - 2*pad_rows, 2*pad_rows, overlap);
|
||||
} else {
|
||||
DEBUG("Splitting discrete panel panorama job...(%d panels of %d rows)\n", num_panels, out_rows);
|
||||
}
|
||||
|
||||
for (int panel = 0 ; panel < num_panels ; panel++) {
|
||||
int lh = (panel < (num_panels -1));
|
||||
int rh = (panel > 0);
|
||||
|
||||
/* Create new job */
|
||||
newjobs[panel] = malloc(sizeof(struct dnpds40_printjob));
|
||||
if (!newjobs[panel]) {
|
||||
ERROR("Memory allocation failure");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
struct dnpds40_printjob *newjob = newjobs[panel];
|
||||
memcpy(newjob, injob, sizeof(struct dnpds40_printjob));
|
||||
|
||||
newjob->common.copies = 1;
|
||||
newjob->is_pano = lh; /* All but last */
|
||||
newjob->databuf = malloc(MAX_PRINTJOB_LEN);
|
||||
if (!newjob->databuf) {
|
||||
dnpds40_cleanup_job(newjob);
|
||||
newjobs[panel] = NULL;
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
newjob->datalen = 0;
|
||||
|
||||
newjob->multicut = new_multicut;
|
||||
newjob->rows = out_rows;
|
||||
|
||||
uint32_t plane_len = out_rows * ctx->native_width + 1088;
|
||||
|
||||
/* Copy data blocks from injob */
|
||||
uint8_t *ptr = injob->databuf;
|
||||
while(ptr && ptr < (injob->databuf + injob->datalen)) {
|
||||
uint32_t i;
|
||||
int copy = 1;
|
||||
if(!memcmp("IMAGE YPLANE", ptr +2, 12) ||
|
||||
!memcmp("IMAGE MPLANE", ptr +2, 12) ||
|
||||
!memcmp("IMAGE CPLANE", ptr +2, 12) ) {
|
||||
|
||||
if (ptr[8] == 'Y') {
|
||||
/* Insert CONT_PANORAMA _before_ the image data */
|
||||
int cont = (panel == num_panels-1) ? 0 : 1;
|
||||
int lap = overlap;
|
||||
if (injob->dpi == 600)
|
||||
lap /= 2;
|
||||
lap /= 3; /* Convert pixels into inches * 100 */
|
||||
|
||||
if (overlap) {
|
||||
/* Continuous panorama */
|
||||
newjob->datalen += sprintf((char*)newjob->databuf + newjob->datalen, "\033PCNTRL CONT_PANORAMA 00000008%04u%04u", cont, lap);
|
||||
} else {
|
||||
/* Discrete panel */
|
||||
newjob->cutter = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *bmp_hdr;
|
||||
DEBUG("Panel %d plane %c\n", panel, ptr[8]);
|
||||
newjob->datalen += sprintf((char*)newjob->databuf + newjob->datalen,
|
||||
"\033PIMAGE %cPLANE %08u", ptr[8], plane_len);
|
||||
|
||||
/* Copy over old bitmap header*/
|
||||
memcpy(newjob->databuf + newjob->datalen, ptr + 32, 1088);
|
||||
bmp_hdr = newjob->databuf + newjob->datalen;
|
||||
|
||||
/* Mangle BMP header for new size and row count */
|
||||
i = cpu_to_le32(plane_len);
|
||||
memcpy(bmp_hdr + 2, &i, sizeof(i));
|
||||
i = cpu_to_le32(out_rows);
|
||||
memcpy(bmp_hdr + 22, &i, sizeof(i));
|
||||
|
||||
/* Split panorama */
|
||||
dnp_applypano_plane(pano,
|
||||
ptr + 32 + 1088 + (pad_rows * ctx->native_width) + (panel * (out_rows - pad_rows*2 - overlap) * ctx->native_width),
|
||||
newjob->databuf + newjob->datalen + 1088,
|
||||
out_rows - pad_rows*2, ctx->native_width, pad_rows, injob->dpi, overlap, ptr[8], rh, lh);
|
||||
newjob->datalen += plane_len;
|
||||
|
||||
/* Don't copy anything else from source */
|
||||
copy = 0;
|
||||
} else if(!memcmp("CNTRL QTY", ptr + 2, 9)) {
|
||||
/* Ignore copy count */
|
||||
copy = 0;
|
||||
} else if(!memcmp("CNTRL CUTTER", ptr + 2, 12) ||
|
||||
!memcmp("CNTRL FULL_CUTTER_SET", ptr + 2, 21)) {
|
||||
/* Ignore all cutter commands */
|
||||
copy = 0;
|
||||
} else if (!memcmp("CNTRL START", ptr + 2, 11)) {
|
||||
}
|
||||
|
||||
/* Work out how much to copy from source, and increment source pointer */
|
||||
char buf[10];
|
||||
buf[8] = 0;
|
||||
memcpy(buf, ptr + 24, 8);
|
||||
i = atoi(buf) + 32;
|
||||
if (copy) {
|
||||
memcpy(newjob->databuf + newjob->datalen, ptr, i);
|
||||
newjob->datalen += i;
|
||||
}
|
||||
ptr += i;
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
char buf[32];
|
||||
sprintf(buf, "/tmp/dump%d.raw", panel);
|
||||
FILE *f = fopen(buf, "wb");
|
||||
fwrite(newjob->databuf, newjob->datalen, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
dnp_free_panodata(pano);
|
||||
return CUPS_BACKEND_OK;
|
||||
|
||||
bail:
|
||||
dnp_free_panodata(pano);
|
||||
return CUPS_BACKEND_FAILED;
|
||||
}
|
||||
|
||||
#define JOB_EQUIV(__x) if (job1->__x != job2->__x) goto done
|
||||
|
||||
/* NOTE: Does _not_ free the input jobs */
|
||||
|
@ -1562,8 +2093,6 @@ static int dnpds40_query_status(struct dnpds40_ctx *ctx)
|
|||
return count;
|
||||
}
|
||||
|
||||
#define MAX_PRINTJOB_LEN (((ctx->native_width*ctx->max_height+1024+54+10))*3+1024) /* Worst-case, YMC */
|
||||
|
||||
static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
|
||||
struct dnpds40_ctx *ctx = vctx;
|
||||
int run = 1;
|
||||
|
@ -1593,7 +2122,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
the end of the job.
|
||||
*/
|
||||
|
||||
job->databuf = malloc(MAX_PRINTJOB_LEN);
|
||||
job->databuf = malloc(MAX_PANOPRINTJOB_LEN);
|
||||
if (!job->databuf) {
|
||||
dnpds40_cleanup_job(job);
|
||||
ERROR("Memory allocation failure!\n");
|
||||
|
@ -1605,7 +2134,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
uint32_t remain;
|
||||
|
||||
/* Make sure we won't overflow... */
|
||||
if (job->datalen + sizeof(struct dnpds40_cmd) > MAX_PRINTJOB_LEN) {
|
||||
if (job->datalen + sizeof(struct dnpds40_cmd) > MAX_PANOPRINTJOB_LEN) {
|
||||
ERROR("Buffer overflow when parsing printjob! (%d+%lu)\n",
|
||||
job->datalen, sizeof(struct dnpds40_cmd));
|
||||
dnpds40_cleanup_job(job);
|
||||
|
@ -1678,7 +2207,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
remain = j;
|
||||
|
||||
/* Make sure we won't overflow... */
|
||||
if (job->datalen + remain > MAX_PRINTJOB_LEN) {
|
||||
if (job->datalen + remain > MAX_PANOPRINTJOB_LEN) {
|
||||
ERROR("Buffer overflow when parsing printjob! (%d+%d)\n",
|
||||
job->datalen, remain);
|
||||
dnpds40_cleanup_job(job);
|
||||
|
@ -1689,7 +2218,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
i = read(data_fd, job->databuf + job->datalen + sizeof(struct dnpds40_cmd),
|
||||
remain);
|
||||
if (i < 0) {
|
||||
ERROR("Data Read Error: %d (%d/%d @%d/%d)\n", i, remain, j, job->datalen,MAX_PRINTJOB_LEN);
|
||||
ERROR("Data Read Error: %d (%d/%d @%d/%d)\n", i, remain, j, job->datalen,MAX_PANOPRINTJOB_LEN);
|
||||
dnpds40_cleanup_job(job);
|
||||
return i;
|
||||
}
|
||||
|
@ -1712,6 +2241,10 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
memcpy(buf, job->databuf + job->datalen + 32, 8);
|
||||
job->cutter = atoi(buf);
|
||||
/* We'll insert it ourselves later */
|
||||
|
||||
if (job->cutter == 1000)
|
||||
job->is_pano = 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
if(!memcmp("CNTRL BUFFCNTRL", job->databuf + job->datalen+2, 15)) {
|
||||
|
@ -1740,7 +2273,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
job->multicut = atoi(buf);
|
||||
/* Backend automatically handles rewind support, so
|
||||
ignore application requests to use it. */
|
||||
if (job->multicut > 400)
|
||||
if (job->multicut > 400 && job->multicut < 1000)
|
||||
job->multicut -= 400;
|
||||
|
||||
/* We'll insert this ourselves later. */
|
||||
|
@ -1804,6 +2337,10 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
dnpds40_cleanup_job(job);
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
/* Capture number of rows */
|
||||
memcpy(&y_ppm, job->databuf + job->datalen + 32 + 22, sizeof(y_ppm));
|
||||
job->rows = le32_to_cpu(y_ppm);
|
||||
}
|
||||
if(!memcmp("CNTRL PRINTSPEED", job->databuf + job->datalen + 2, 16)) {
|
||||
if (!ctx->supports_printspeed) {
|
||||
|
@ -1821,6 +2358,8 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
ERROR("Printer does not support Continuous Panorama, aborting!\n");
|
||||
continue;
|
||||
}
|
||||
memcpy(buf, job->databuf + job->datalen + 32 + 4, 4);
|
||||
job->is_pano = atoi(buf);
|
||||
}
|
||||
|
||||
/* This is the last block.. */
|
||||
|
@ -1830,6 +2369,85 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
|
|||
/* Add in the size of this chunk */
|
||||
job->datalen += sizeof(struct dnpds40_cmd) + j;
|
||||
}
|
||||
|
||||
/* Figure out the number of buffers we need. */
|
||||
job->buf_needed = 1;
|
||||
|
||||
if (job->dpi == 600) {
|
||||
switch(ctx->conn->type) {
|
||||
case P_DNP_DS620:
|
||||
if (job->multicut == MULTICUT_6x9 ||
|
||||
job->multicut == MULTICUT_6x4_5X2)
|
||||
job->buf_needed = 2;
|
||||
break;
|
||||
case P_DNP_DS80: /* DS80/CX-W */
|
||||
if (job->matte && (job->multicut == MULTICUT_8xA4LEN ||
|
||||
job->multicut == MULTICUT_8x4X3 ||
|
||||
job->multicut == MULTICUT_8x8_8x4 ||
|
||||
job->multicut == MULTICUT_8x6X2 ||
|
||||
job->multicut == MULTICUT_8x12))
|
||||
job->buf_needed = 2;
|
||||
break;
|
||||
case P_DNP_DS80D:
|
||||
if (job->matte) {
|
||||
int mcut = job->multicut;
|
||||
|
||||
if (mcut > MULTICUT_S_BACK)
|
||||
mcut -= MULTICUT_S_BACK;
|
||||
else if (mcut > MULTICUT_S_FRONT)
|
||||
mcut -= MULTICUT_S_FRONT;
|
||||
|
||||
if (mcut == MULTICUT_8xA4LEN ||
|
||||
mcut == MULTICUT_8x4X3 ||
|
||||
mcut == MULTICUT_8x8_8x4 ||
|
||||
mcut == MULTICUT_8x6X2 ||
|
||||
mcut == MULTICUT_8x12)
|
||||
job->buf_needed = 2;
|
||||
|
||||
if (mcut == MULTICUT_S_8x12 ||
|
||||
mcut == MULTICUT_S_8x6X2 ||
|
||||
mcut == MULTICUT_S_8x4X3)
|
||||
job->buf_needed = 2;
|
||||
}
|
||||
break;
|
||||
case P_DNP_DS820:
|
||||
// Nothing; all sizes only need 1 buffer
|
||||
break;
|
||||
case P_CITIZEN_CW01:
|
||||
job->buf_needed = 2;
|
||||
break;
|
||||
default: /* DS40/CX/RX1/CY/everything else */
|
||||
if (job->matte) {
|
||||
if (job->multicut == MULTICUT_6x8 ||
|
||||
job->multicut == MULTICUT_6x9 ||
|
||||
job->multicut == MULTICUT_6x4X2 ||
|
||||
job->multicut == MULTICUT_5x7 ||
|
||||
job->multicut == MULTICUT_5x3_5X2)
|
||||
job->buf_needed = 2;
|
||||
|
||||
} else {
|
||||
if (job->multicut == MULTICUT_6x8 ||
|
||||
job->multicut == MULTICUT_6x9 ||
|
||||
job->multicut == MULTICUT_6x4X2)
|
||||
job->buf_needed = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (job->multicut >= MULTICUT_PANO_6x14)
|
||||
{
|
||||
int rval = dnp_panorama_splitjob(ctx, job, (struct dnpds40_printjob**)vjob);
|
||||
|
||||
/* Clean up original job regardless */
|
||||
dnpds40_cleanup_job(job);
|
||||
if (rval)
|
||||
return rval;
|
||||
|
||||
/* And continue validating everything based on the 1st job */
|
||||
job = (struct dnpds40_printjob*) *vjob;
|
||||
}
|
||||
|
||||
parsed:
|
||||
/* If we have no data.. don't bother */
|
||||
if (!job->datalen) {
|
||||
|
@ -1838,7 +2456,7 @@ parsed:
|
|||
}
|
||||
|
||||
/* Use the larger of the copy arguments */
|
||||
if (job->common.copies < copies)
|
||||
if (!job->is_pano && job->common.copies < copies)
|
||||
job->common.copies = copies;
|
||||
|
||||
/* Make sure advanced matte modes are supported */
|
||||
|
@ -1919,70 +2537,6 @@ parsed:
|
|||
}
|
||||
}
|
||||
|
||||
/* Figure out the number of buffers we need. */
|
||||
job->buf_needed = 1;
|
||||
|
||||
if (job->dpi == 600) {
|
||||
switch(ctx->conn->type) {
|
||||
case P_DNP_DS620:
|
||||
if (job->multicut == MULTICUT_6x9 ||
|
||||
job->multicut == MULTICUT_6x4_5X2)
|
||||
job->buf_needed = 2;
|
||||
break;
|
||||
case P_DNP_DS80: /* DS80/CX-W */
|
||||
if (job->matte && (job->multicut == MULTICUT_8xA4LEN ||
|
||||
job->multicut == MULTICUT_8x4X3 ||
|
||||
job->multicut == MULTICUT_8x8_8x4 ||
|
||||
job->multicut == MULTICUT_8x6X2 ||
|
||||
job->multicut == MULTICUT_8x12))
|
||||
job->buf_needed = 2;
|
||||
break;
|
||||
case P_DNP_DS80D:
|
||||
if (job->matte) {
|
||||
int mcut = job->multicut;
|
||||
|
||||
if (mcut > MULTICUT_S_BACK)
|
||||
mcut -= MULTICUT_S_BACK;
|
||||
else if (mcut > MULTICUT_S_FRONT)
|
||||
mcut -= MULTICUT_S_FRONT;
|
||||
|
||||
if (mcut == MULTICUT_8xA4LEN ||
|
||||
mcut == MULTICUT_8x4X3 ||
|
||||
mcut == MULTICUT_8x8_8x4 ||
|
||||
mcut == MULTICUT_8x6X2 ||
|
||||
mcut == MULTICUT_8x12)
|
||||
job->buf_needed = 2;
|
||||
|
||||
if (mcut == MULTICUT_S_8x12 ||
|
||||
mcut == MULTICUT_S_8x6X2 ||
|
||||
mcut == MULTICUT_S_8x4X3)
|
||||
job->buf_needed = 2;
|
||||
}
|
||||
break;
|
||||
case P_DNP_DS820:
|
||||
// Nothing; all sizes only need 1 buffer
|
||||
break;
|
||||
case P_CITIZEN_CW01:
|
||||
job->buf_needed = 2;
|
||||
break;
|
||||
default: /* DS40/CX/RX1/CY/everything else */
|
||||
if (job->matte) {
|
||||
if (job->multicut == MULTICUT_6x8 ||
|
||||
job->multicut == MULTICUT_6x9 ||
|
||||
job->multicut == MULTICUT_6x4X2 ||
|
||||
job->multicut == MULTICUT_5x7 ||
|
||||
job->multicut == MULTICUT_5x3_5X2)
|
||||
job->buf_needed = 2;
|
||||
|
||||
} else {
|
||||
if (job->multicut == MULTICUT_6x8 ||
|
||||
job->multicut == MULTICUT_6x9 ||
|
||||
job->multicut == MULTICUT_6x4X2)
|
||||
job->buf_needed = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (job->dpi == 334 && ctx->conn->type != P_CITIZEN_CW01)
|
||||
{
|
||||
ERROR("Illegal resolution (%u) for printer!\n", job->dpi);
|
||||
|
@ -2246,7 +2800,7 @@ skip_multicut:
|
|||
}
|
||||
|
||||
/* Panorama sanity checking */
|
||||
if (job->cutter == 1000 || ctx->pano) {
|
||||
if (job->is_pano) {
|
||||
if (!ctx->supports_pano) {
|
||||
ERROR("Printer does not support panorama printing, aborting!\n");
|
||||
dnpds40_cleanup_job(job);
|
||||
|
@ -2268,13 +2822,6 @@ skip_multicut:
|
|||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
}
|
||||
ctx->pano++;
|
||||
|
||||
/* Hard limit of 3 panels */
|
||||
if (job->cutter == 1000 && ctx->pano >= 3) {
|
||||
WARNING("Panoramas limited to three panels!\n");
|
||||
job->cutter = 0;
|
||||
}
|
||||
|
||||
if (job->fullcut) {
|
||||
ERROR("Cannot use full cutter control in panorama mode!\n");
|
||||
|
@ -2501,6 +3048,33 @@ top:
|
|||
WARNING("Printer does not have sufficient remaining media (%d) to complete job (%d)\n", copies, count);
|
||||
}
|
||||
|
||||
/* Ensure we can complete panorama */
|
||||
if (ctx->pano && (count < 3)) {
|
||||
ERROR("Printer does not have sufficent media for panorama job, aborting job!\n");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
/* If we're printing a panorama, query state before _first_ page */
|
||||
if (job->is_pano && ctx->pano == 0) {
|
||||
int i;
|
||||
dnpds40_build_cmd(&cmd, "INFO", "PANORAMA_PRINT", 0);
|
||||
|
||||
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
|
||||
if (!resp)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
dnpds40_cleanup_string((char*)resp, len);
|
||||
i = atoi((char*)resp);
|
||||
free(resp);
|
||||
if (i != 0) {
|
||||
INFO("Printer Not ready for panorama printing, waiting.. (%d)\n", i);
|
||||
sleep(1);
|
||||
goto top;
|
||||
}
|
||||
}
|
||||
if (job->is_pano)
|
||||
ctx->pano++;
|
||||
|
||||
/* Work around a bug in older gutenprint releases. */
|
||||
if (ctx->last_multicut >= 200 && ctx->last_multicut < 300 &&
|
||||
multicut >= 200 && multicut < 300) {
|
||||
|
@ -2511,13 +3085,17 @@ top:
|
|||
/* Store our last multicut state */
|
||||
ctx->last_multicut = multicut;
|
||||
|
||||
/* For continuous panorama jobs we only want to send this stuff on the FIRST page */
|
||||
if (ctx->pano > 1 && !job->cutter)
|
||||
goto skip_pageparams;
|
||||
|
||||
/* Tell printer how many copies to make */
|
||||
snprintf(buf, sizeof(buf), "%07d\r", manual_copies || ctx->pano ? 1 : copies);
|
||||
snprintf(buf, sizeof(buf), "%07d\r", manual_copies ? 1 : copies);
|
||||
dnpds40_build_cmd(&cmd, "CNTRL", "QTY", 8);
|
||||
if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
if (!manual_copies || ctx->pano)
|
||||
if (!manual_copies)
|
||||
copies = 1;
|
||||
|
||||
/* Job resumption on correctable errors */
|
||||
|
@ -2573,13 +3151,16 @@ top:
|
|||
}
|
||||
|
||||
/* Program in the multicut setting, if one exists */
|
||||
if (multicut) {
|
||||
/* Do _NOT_ send for continuous panoramas! */
|
||||
if ((!job->is_pano || job->cutter) && multicut) {
|
||||
snprintf(buf, sizeof(buf), "%08d", multicut);
|
||||
dnpds40_build_cmd(&cmd, "IMAGE", "MULTICUT", 8);
|
||||
if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
}
|
||||
|
||||
skip_pageparams:
|
||||
|
||||
/* Finally, send the stream over as individual data chunks */
|
||||
ptr = job->databuf;
|
||||
while(ptr && ptr < (job->databuf + job->datalen)) {
|
||||
|
@ -2597,7 +3178,7 @@ top:
|
|||
sleep(1); /* Give things a moment */
|
||||
|
||||
/* Reset panorama state if we've sent the last panel in the set */
|
||||
if (job->cutter != 1000 && ctx->pano)
|
||||
if (!job->is_pano && ctx->pano)
|
||||
ctx->pano = 0;
|
||||
|
||||
/* Reset partial matte state if necessary */
|
||||
|
@ -4018,7 +4599,7 @@ static const char *dnpds40_prefixes[] = {
|
|||
|
||||
const struct dyesub_backend dnpds40_backend = {
|
||||
.name = "DNP DS-series / Citizen C-series",
|
||||
.version = "0.152",
|
||||
.version = "0.153",
|
||||
.uri_prefixes = dnpds40_prefixes,
|
||||
.cmdline_usage = dnpds40_cmdline,
|
||||
.cmdline_arg = dnpds40_cmdline_arg,
|
||||
|
|
24
backend_panodata.h
Normal file
24
backend_panodata.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
static struct dnp_panodata panodata = {
|
||||
.elements = 21,
|
||||
.rows[ 0] = { 0, { 1.0000000000, 1.0000000000, 1.0000000000 }, { 0.2000000000, 0.2000000000, 0.2000000000} },
|
||||
.rows[ 1] = { 30, { 0.9933580000, 0.9963060000, 0.9946110000 }, { 0.2950650000, 0.2950650000, 0.2950650000} },
|
||||
.rows[ 2] = { 60, { 0.9800000000, 0.9850000000, 0.9850000000 }, { 0.3900000000, 0.3900000000, 0.3900000000} },
|
||||
.rows[ 3] = { 90, { 0.9540200000, 0.9602540000, 0.9677210000 }, { 0.4879980000, 0.4879980000, 0.4879980000} },
|
||||
.rows[ 4] = { 120, { 0.9182812500, 0.9282812500, 0.9460937500 }, { 0.5800000000, 0.5800000000, 0.5800000000} },
|
||||
.rows[ 5] = { 150, { 0.8730900000, 0.8920840000, 0.9206270000 }, { 0.6683700000, 0.6683700000, 0.6683700000} },
|
||||
.rows[ 6] = { 180, { 0.8276562500, 0.8543750000, 0.8910937500 }, { 0.7400000000, 0.7400000000, 0.7400000000} },
|
||||
.rows[ 7] = { 210, { 0.7800400000, 0.8030000000, 0.8550000000 }, { 0.8004440000, 0.8004440000, 0.8004440000} },
|
||||
.rows[ 8] = { 240, { 0.7348437500, 0.7550000000, 0.8160000000 }, { 0.8450000000, 0.8450000000, 0.8450000000} },
|
||||
.rows[ 9] = { 270, { 0.6750000000, 0.7020000000, 0.7785180000 }, { 0.8855640000, 0.8855640000, 0.8855640000} },
|
||||
.rows[10] = { 300, { 0.6120000000, 0.6450000000, 0.7321875000 }, { 0.9150000000, 0.9150000000, 0.9150000000} },
|
||||
.rows[11] = { 330, { 0.5617422160, 0.5950000000, 0.6879300400 }, { 0.9359207970, 0.9359207970, 0.9359207970} },
|
||||
.rows[12] = { 360, { 0.5112158120, 0.5430000000, 0.6430933460 }, { 0.9533652920, 0.9533652920, 0.9533652920} },
|
||||
.rows[13] = { 390, { 0.4626856430, 0.4970173200, 0.5963030420 }, { 0.9663907840, 0.9663907840, 0.9663907840} },
|
||||
.rows[14] = { 420, { 0.4104687500, 0.4482812500, 0.5496875000 }, { 0.9770000000, 0.9770000000, 0.9770000000} },
|
||||
.rows[15] = { 450, { 0.3518815000, 0.3938775000, 0.4979980000 }, { 0.9847240000, 0.9847240000, 0.9847240000} },
|
||||
.rows[16] = { 480, { 0.2965625000, 0.3413281250, 0.4407812500 }, { 0.9900000000, 0.9900000000, 0.9900000000} },
|
||||
.rows[17] = { 510, { 0.2393955000, 0.2762305000, 0.3738025000 }, { 0.9956110000, 0.9956110000, 0.9956110000} },
|
||||
.rows[18] = { 540, { 0.1855468750, 0.2163281250, 0.3063281250 }, { 1.0000000000, 1.0000000000, 1.0000000000} },
|
||||
.rows[19] = { 570, { 0.1243430000, 0.1441130000, 0.2241130000 }, { 1.0000000000, 1.0000000000, 1.0000000000} },
|
||||
.rows[20] = { 600, { 0.0800000000, 0.0800000000, 0.1450000000 }, { 1.0000000000, 1.0000000000, 1.0000000000} },
|
||||
};
|
25
dnp_data/LUTData820_0010.csv
Normal file
25
dnp_data/LUTData820_0010.csv
Normal file
|
@ -0,0 +1,25 @@
|
|||
#FORMAT ,Major,Minor,,,,,
|
||||
FORMAT,1,0,,,,,
|
||||
RECNUM,64,,,,,,
|
||||
#Header,,(Rh)Y, (Rh)M, (Rh)C, (Lh)Y, (Lh)M, (Lh)C
|
||||
REC,0,1,1,1,0.2,0.2,0.2
|
||||
REC,30,0.993358,0.996306,0.994611,0.295065,0.295065,0.295065
|
||||
REC,60,0.98,0.985,0.985,0.39,0.39,0.39
|
||||
REC,90,0.95402,0.960254,0.967721,0.487998,0.487998,0.487998
|
||||
REC,120,0.91828125,0.92828125,0.94609375,0.58,0.58,0.58
|
||||
REC,150,0.87309,0.892084,0.920627,0.66837,0.66837,0.66837
|
||||
REC,180,0.82765625,0.854375,0.89109375,0.74,0.74,0.74
|
||||
REC,210,0.78004,0.803,0.855,0.800444,0.800444,0.800444
|
||||
REC,240,0.73484375,0.755,0.816,0.845,0.845,0.845
|
||||
REC,270,0.675,0.702,0.778518,0.885564,0.885564,0.885564
|
||||
REC,300,0.612,0.645,0.7321875,0.915,0.915,0.915
|
||||
REC,330,0.561742216,0.595,0.68793004,0.935920797,0.935920797,0.935920797
|
||||
REC,360,0.511215812,0.543,0.643093346,0.953365292,0.953365292,0.953365292
|
||||
REC,390,0.462685643,0.49701732,0.596303042,0.966390784,0.966390784,0.966390784
|
||||
REC,420,0.41046875,0.44828125,0.5496875,0.977,0.977,0.977
|
||||
REC,450,0.3518815,0.3938775,0.497998,0.984724,0.984724,0.984724
|
||||
REC,480,0.2965625,0.341328125,0.44078125,0.99,0.99,0.99
|
||||
REC,510,0.2393955,0.2762305,0.3738025,0.995611,0.995611,0.995611
|
||||
REC,540,0.185546875,0.216328125,0.306328125,1,1,1
|
||||
REC,570,0.124343,0.144113,0.224113,1,1,1
|
||||
REC,600,0.08,0.08,0.145,1,1,1
|
|
25
dnp_data/LUTData_0010.csv
Normal file
25
dnp_data/LUTData_0010.csv
Normal file
|
@ -0,0 +1,25 @@
|
|||
#FORMAT ,Major,Minor,,,,,
|
||||
FORMAT,1,0,,,,,
|
||||
RECNUM,64,,,,,,
|
||||
#Header,,(Rh)Y, (Rh)M, (Rh)C, (Lh)Y, (Lh)M, (Lh)C
|
||||
REC,0,1,1,1,0.2,0.2,0.2
|
||||
REC,30,0.993358,0.996306,0.994611,0.295065,0.295065,0.295065
|
||||
REC,60,0.98,0.985,0.985,0.39,0.39,0.39
|
||||
REC,90,0.95402,0.960254,0.967721,0.487998,0.487998,0.487998
|
||||
REC,120,0.91828125,0.92828125,0.94609375,0.58,0.58,0.58
|
||||
REC,150,0.87309,0.892084,0.920627,0.66837,0.66837,0.66837
|
||||
REC,180,0.82765625,0.854375,0.89109375,0.74,0.74,0.74
|
||||
REC,210,0.78004,0.803,0.855,0.800444,0.800444,0.800444
|
||||
REC,240,0.73484375,0.755,0.816,0.845,0.845,0.845
|
||||
REC,270,0.675,0.702,0.778518,0.885564,0.885564,0.885564
|
||||
REC,300,0.612,0.645,0.7321875,0.915,0.915,0.915
|
||||
REC,330,0.561742216,0.595,0.68793004,0.935920797,0.935920797,0.935920797
|
||||
REC,360,0.511215812,0.543,0.643093346,0.953365292,0.953365292,0.953365292
|
||||
REC,390,0.462685643,0.49701732,0.596303042,0.966390784,0.966390784,0.966390784
|
||||
REC,420,0.41046875,0.44828125,0.5496875,0.977,0.977,0.977
|
||||
REC,450,0.3518815,0.3938775,0.497998,0.984724,0.984724,0.984724
|
||||
REC,480,0.2965625,0.341328125,0.44078125,0.99,0.99,0.99
|
||||
REC,510,0.2393955,0.2762305,0.3738025,0.995611,0.995611,0.995611
|
||||
REC,540,0.185546875,0.216328125,0.306328125,1,1,1
|
||||
REC,570,0.124343,0.144113,0.224113,1,1,1
|
||||
REC,600,0.08,0.08,0.145,1,1,1
|
|
|
@ -23,7 +23,8 @@ fi
|
|||
# D90
|
||||
case "${model}" in
|
||||
kodak-6900|kodak-6950)
|
||||
overlap=636 # 100 + 36
|
||||
pad=36
|
||||
overlap=600
|
||||
if [ "${printsize}" eq "6x20" ] ; then
|
||||
cols=1844
|
||||
inrows=6036
|
||||
|
@ -59,6 +60,7 @@ case "${model}" in
|
|||
;;
|
||||
kodak-8810)
|
||||
cols=2464
|
||||
pad=24
|
||||
overlap=360 ### XXX probably wrong?
|
||||
if [ "${printsize}" eq "8x14" ] ; then
|
||||
inrows=4224
|
||||
|
@ -85,8 +87,9 @@ case "${model}" in
|
|||
;;
|
||||
mitsubishi-d90dw)
|
||||
cols=1852
|
||||
pad=28
|
||||
drows=2428
|
||||
overlap=628 # 600 + 28
|
||||
overlap=600
|
||||
if [ "${printsize}" eq "6x20" ] ; then
|
||||
inrows=6028
|
||||
elif [ "${printsize}" eq "6x14" ] ; then
|
||||
|
@ -99,11 +102,12 @@ case "${model}" in
|
|||
dnp-ds620)
|
||||
cols=1844
|
||||
drows=2436
|
||||
pad=36
|
||||
overlap=600
|
||||
if [ "${printsize}" eq "6x20" ] ; then
|
||||
inrows=6108
|
||||
inrows=6036
|
||||
elif [ "${printsize}" eq "6x14" ] ; then
|
||||
inrows=4272
|
||||
inrows=4236
|
||||
else
|
||||
echo "DS620 supportx 6x20 and 6x14 only"
|
||||
exit 1
|
||||
|
@ -111,21 +115,28 @@ case "${model}" in
|
|||
;;
|
||||
dnp-ds820)
|
||||
overlap=600
|
||||
pad=36
|
||||
cols=2448
|
||||
if [ "${printsize}" eq "8x18" ] ; then
|
||||
drows=3036
|
||||
inrows=5472
|
||||
inrows=5436
|
||||
elif [ "${printsize}" eq "8x26" ] ; then
|
||||
drows=3036
|
||||
inrows=7908
|
||||
inrows=7836
|
||||
elif [ "${printsize}" eq "8x22" ] ; then
|
||||
drows=3636
|
||||
inrows=6672
|
||||
inrows=6636
|
||||
elif [ "${printsize}" eq "8x32" ] ; then
|
||||
drows=3636
|
||||
inrows=9708
|
||||
inrows=9636
|
||||
elif [ "${printsize}" eq "A4x2" ] ; then
|
||||
drows=3544
|
||||
inrows=6452
|
||||
elif [ "${printsize}" eq "A4x3" ] ; then
|
||||
drows=3544
|
||||
inrows=9360
|
||||
else
|
||||
echo "DS820 supportx 8x18, 8x26, 8x22, and 8x32 only"
|
||||
echo "DS820 supportx 8x18, 8x26, 8x22, 8x32, A4x21, A4x31 only"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
|
@ -135,11 +146,12 @@ case "${model}" in
|
|||
esac
|
||||
|
||||
# For 600dpi, double everything!
|
||||
if [ ${dpi} == 600 ] ; then
|
||||
if [ ${dpi} -gt 300 ] ; then
|
||||
overlap=`expr ${overlap} * 2`
|
||||
cols=`expr ${cols} * 2`
|
||||
drows=`expr ${drows} * 2`
|
||||
inrows=`expr ${inrows} * 2`
|
||||
pad=`expr ${pad} * 2`
|
||||
fi
|
||||
|
||||
# Calculate page count XXX is this sane?
|
||||
|
@ -153,8 +165,11 @@ fadeoutname=fade_out_${cols}.pgm
|
|||
gm convert -size ${cols}x${overlap} gradient:white-black ${fadeinname}
|
||||
gm convert -size ${cols}x${overlap} gradient:black-white ${fadeoutname}
|
||||
|
||||
# Subtract off padding from rows.
|
||||
drows=`expr ${drows} - ${pad} - ${pad}`
|
||||
|
||||
# Generate panels
|
||||
src_offset=0
|
||||
src_offset=`expr $pad / 2`
|
||||
panels=''
|
||||
for panel in `seq 1 ${pages}` ; do
|
||||
echo "generating $panel / $pages"
|
||||
|
@ -163,34 +178,26 @@ for panel in `seq 1 ${pages}` ; do
|
|||
panels="${panels} ${panelname}"
|
||||
|
||||
# Generate panel
|
||||
gm convert ${infile} -crop ${cols}x${drows}+0+${src_offset} ${panelname}
|
||||
rows=`expr ${drows} + ${pad} + ${pad}`
|
||||
gm convert ${infile} -crop ${cols}x${rows}+0+${src_offset} ${panelname}
|
||||
|
||||
## XXX panel needs to have WHITE margin of ${pad rows} on either end
|
||||
# perhaps add to fades?
|
||||
# need a tail too.
|
||||
|
||||
# Increment offset
|
||||
src_offset=`expr ${src_offset} + ${drows}`;
|
||||
src_offset=`expr ${src_offset} - ${overlap}`;
|
||||
|
||||
# First page fades out only
|
||||
if [ ${panel} == 1 ] ; then
|
||||
# All but last panel fades out
|
||||
if [ ${panel} -lt ${pages} ] ; then
|
||||
gm composite -compose screen -gravity south ${fadeoutname} ${panelname} ${panelname}
|
||||
fi
|
||||
|
||||
# Middle pages fade in and out
|
||||
# All but first panel fades in
|
||||
if [ ${panel} -gt 1 ] ; then
|
||||
if [ ${panel} -lt ${pages} ] ; then
|
||||
gm composite -compose screen -gravity south ${fadeoutname} ${panelname} ${panelname}
|
||||
fi
|
||||
fi
|
||||
if [ ${panel} -gt 1 ] ; then
|
||||
if [ ${panel} -lt ${pages} ] ; then
|
||||
gm composite -compose screen -gravity north ${fadeinname} ${panelname} ${panelname}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Last page fades in only
|
||||
if [ ${panel} == ${pages} ] ; then
|
||||
gm composite -compose screen -gravity north ${fadeinname} ${panelname} ${panelname}
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Clean up templates
|
||||
|
|
Loading…
Reference in a new issue