From ef666ba37ec8729d475d8b39daf9cdca511e422b Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Wed, 12 Feb 2020 20:07:03 -0500 Subject: [PATCH] mitsu98xx: Significant fixes * Cleanup library code loop conditionals * Reverse row data if needed * Convert packed YMC16 to planar YMC16 * Send data to printer last row first (ie matching processing flow) --- backend_mitsu.h | 2 +- backend_mitsu9550.c | 60 ++++++++----- lib70x/libMitsuD70ImageReProcess.c | 133 +++++++++++++---------------- lib70x/libMitsuD70ImageReProcess.h | 2 +- regression-gp.csv | 5 ++ 5 files changed, 103 insertions(+), 99 deletions(-) diff --git a/backend_mitsu.h b/backend_mitsu.h index 3bf99cf..9f796b4 100644 --- a/backend_mitsu.h +++ b/backend_mitsu.h @@ -61,7 +61,7 @@ typedef int (*send_image_dataFN)(struct BandImage *out, void *context, typedef int (*CP98xx_DoConvertFN)(const struct mitsu98xx_data *table, const struct BandImage *input, struct BandImage *output, - uint8_t type, int sharpness); + uint8_t type, int sharpness, int reversed); typedef struct mitsu98xx_data *(*CP98xx_GetDataFN)(const char *filename); typedef void (*CP98xx_DestroyDataFN)(const struct mitsu98xx_data *data); diff --git a/backend_mitsu9550.c b/backend_mitsu9550.c index bcc1ffd..1ceb251 100644 --- a/backend_mitsu9550.c +++ b/backend_mitsu9550.c @@ -947,37 +947,53 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) { output.rows = job->rows; output.cols = job->cols; output.imgbuf = convbuf; - output.bytes_per_row = job->cols * 3 * 2; + output.bytes_per_row = job->cols * 3 * sizeof(uint16_t); - int sharpness = 4; // XXX make a parameter via hdr extension. + int sharpness = job->hdr2.unkc[7]; - if (!ctx->lib.CP98xx_DoConvert(ctx->m98xxdata, &input, &output, job->hdr2.mode, sharpness)) { + if (!ctx->lib.CP98xx_DoConvert(ctx->m98xxdata, &input, &output, job->hdr2.mode, sharpness, job->hdr2.unkc[8])) { free(convbuf); free(newbuf); ERROR("CP98xx_DoConvert() failed!\n"); return CUPS_BACKEND_FAILED; } + + /* Clear special extension flags used by our backend */ if (job->hdr2.mode == 0x11) job->hdr2.mode = 0x10; + job->hdr2.unkc[8] = 0; /* Clear "already reversed" flag */ + job->hdr2.unkc[7] = 0; /* Clear "sharpness" parameter */ - /* We're done. Wrap YMC16 data with appropriate plane headers */ - memcpy(newbuf + newlen, job->databuf, sizeof(struct mitsu9550_plane)); - newbuf[newlen + 3] = 0x10; /* ie 16bpp data */ - newlen += sizeof(struct mitsu9550_plane); - memcpy(newbuf + newlen, convbuf + 0 * planelen, planelen); - newlen += planelen; + /* Library is now done, but output is packed YMC16 format. We need to + convert it to a planar YMC16, plus appropriate plane headers */ + uint8_t *yPtr, *mPtr, *cPtr; + int j, offset; - memcpy(newbuf + newlen, job->databuf, sizeof(struct mitsu9550_plane)); - newbuf[newlen + 3] = 0x10; /* ie 16bpp data */ - newlen += sizeof(struct mitsu9550_plane); - memcpy(newbuf + newlen, convbuf + 1 * planelen, planelen); - newlen += planelen; + yPtr = newbuf + newlen; + memcpy(yPtr, job->databuf, sizeof(struct mitsu9550_plane)); + yPtr[3] = 0x10; /* ie 16bpp data */ + yPtr += sizeof(struct mitsu9550_plane); + newlen += sizeof(struct mitsu9550_plane) + planelen; - memcpy(newbuf + newlen, job->databuf, sizeof(struct mitsu9550_plane)); - newbuf[newlen + 3] = 0x10; /* ie 16bpp data */ - newlen += sizeof(struct mitsu9550_plane); - memcpy(newbuf + newlen, convbuf + 2 * planelen, planelen); - newlen += planelen; + mPtr = newbuf + newlen; + memcpy(mPtr, job->databuf, sizeof(struct mitsu9550_plane)); + mPtr[3] = 0x10; /* ie 16bpp data */ + mPtr += sizeof(struct mitsu9550_plane); + newlen += sizeof(struct mitsu9550_plane) + planelen; + + cPtr = newbuf + newlen; + memcpy(cPtr, job->databuf, sizeof(struct mitsu9550_plane)); + cPtr[3] = 0x10; /* ie 16bpp data */ + cPtr += sizeof(struct mitsu9550_plane); + newlen += sizeof(struct mitsu9550_plane) + planelen; + + for (offset = 0, i = output.cols - 1; i >= 0 ; i--) { + for (j = 0 ; j < output.rows ; j ++) { + yPtr[i*output.cols + j] = convbuf[offset++]; + mPtr[i*output.cols + j] = convbuf[offset++]; + cPtr[i*output.cols + j] = convbuf[offset++]; + } + } /* All done with conversion buffer, nuke it */ free(convbuf); @@ -1458,7 +1474,7 @@ static const char *mitsu9550_prefixes[] = { /* Exported */ struct dyesub_backend mitsu9550_backend = { .name = "Mitsubishi CP9xxx family", - .version = "0.51" " (lib " LIBMITSU_VER ")", + .version = "0.52" " (lib " LIBMITSU_VER ")", .uri_prefixes = mitsu9550_prefixes, .cmdline_usage = mitsu9550_cmdline, .cmdline_arg = mitsu9550_cmdline_arg, @@ -1510,9 +1526,11 @@ struct dyesub_backend mitsu9550_backend = { 1b 57 21 2e 00 80 00 22 QQ QQ 00 00 00 00 00 00 :: ZZ ZZ = num copies (>= 0x01) 00 00 00 00 00 00 00 00 00 00 00 00 ZZ ZZ 00 00 :: YY = 00/80 Fine/SuperFine (9550), 10/80 Fine/Superfine (98x0), 00 (9600) - XX 00 00 00 00 00 YY 00 00 00 00 00 00 00 00 00 :: XX = 00 normal, 83 Cut 2x6 (9550 only!) + XX 00 00 00 00 00 YY 00 00 00 00 00 00 00 SS TT :: XX = 00 normal, 83 Cut 2x6 (9550 only!) RR 01 :: QQ QQ = 0x0803 on 9550, 0x0801 on 98x0, 0x0003 on 9600, 0xa803 on 9500 :: RR = 01 for "use LUT" on 98xx, 0x00 otherwise. Extension to stock. + :: TT = 01 for "already reversed". Extension to stock. + :: SS == sharpening level, 0 for off, 1-10 otherwise. Extesion to stock. ~~~ Header 3 (9550 and 9800-S only..) diff --git a/lib70x/libMitsuD70ImageReProcess.c b/lib70x/libMitsuD70ImageReProcess.c index 4a4bda3..13e48f5 100644 --- a/lib70x/libMitsuD70ImageReProcess.c +++ b/lib70x/libMitsuD70ImageReProcess.c @@ -52,7 +52,7 @@ */ -#define LIB_VERSION "0.8.0" +#define LIB_VERSION "0.8.1" #include #include @@ -1668,33 +1668,24 @@ static int CP98xx_DoCorrectGammaTbl(struct CP98xx_GammaParams *Gamma, int64_t sum1, sum2, sum3, sum4, sum5, sum6; int iVar4 = (cols - end) -1; - sum6 = 0; - sum5 = 0; - sum4 = 0; - sum3 = 0; - sum2 = 0; - sum1 = 0; + sum6 = sum5 = sum4 = sum3 = sum2 = sum1 = 0; for (k = 0 ; k < step ; k++) { curRowBufOffset = start * 3; curCol = start; - while (curCol < (end + 1)) { - int offset = curRowBufOffset; - sum3 += rowPtr[offset]; - sum2 += rowPtr[offset + 1]; - sum1 += rowPtr[offset + 2]; - curRowBufOffset = offset + 3; - curCol++; + for (curCol = start ; curCol < (end + 1) ; curCol++) { + sum3 += rowPtr[curRowBufOffset]; + sum2 += rowPtr[curRowBufOffset + 1]; + sum1 += rowPtr[curRowBufOffset + 2]; + curRowBufOffset += 3; } curRowBufOffset = iVar4 * 3; curCol = iVar4; - while (curCol < (cols - start)) { - int offset2 = curRowBufOffset; - sum6 += rowPtr[offset2]; - sum5 += rowPtr[offset2 + 1]; - sum4 += rowPtr[offset2 + 2]; - curRowBufOffset = offset2 + 3; - curCol++; + for (curCol = start ; curCol < (cols - start); curCol++) { + sum6 += rowPtr[curRowBufOffset]; + sum5 += rowPtr[curRowBufOffset + 1]; + sum4 += rowPtr[curRowBufOffset + 2]; + curRowBufOffset += 3; } rowPtr -= bytesPerRow; } @@ -1743,12 +1734,12 @@ static int CP98xx_DoCorrectGammaTbl(struct CP98xx_GammaParams *Gamma, static int CP98xx_DoGammaConv(struct CP98xx_GammaParams *Gamma, const struct BandImage *inImage, - struct BandImage *outImage) + struct BandImage *outImage, + int already_reversed) { - int cols, cols2, rows, inBytesPerRow, tmp, maxTank; + int cols, rows, inBytesPerRow, tmp, maxTank; uint8_t *inRowPtr; uint16_t *outRowPtr; - double gammaAdj0; int pixelsPerRow; int in_r8 = 0; // XXXX figure this one out.. @@ -1785,49 +1776,32 @@ static int CP98xx_DoGammaConv(struct CP98xx_GammaParams *Gamma, } } - tmp = 0; - cols2 = cols; - maxTank = cols2 * 255; - gammaAdj0 = Gamma->GammaAdj[0]; + maxTank = cols * 255; int outVal; - double dVar2 = 0.0; - double calc2, calc1, calc0; - int curRowBufOffset, curCol; + int row, col; + int curRowBufOffset; - while ((outVal = rows, tmp < outVal && - (dVar2 = gammaAdj0, 0.50000000 <= dVar2))) { - calc1 = 0.00000000; - curRowBufOffset = 0; - curCol = 0; - calc2 = calc1; - calc0 = calc1; + double gammaAdj2 = Gamma->GammaAdj[2]; + double gammaAdj1 = Gamma->GammaAdj[1]; + double gammaAdj0 = Gamma->GammaAdj[0]; - while (curCol < cols2) { + for (row = 0 ; row < rows && gammaAdj0 >= 0.5 ; row++) { + double calc3, calc2, calc1, calc0; + calc0 = calc1 = calc2 = 0.00000000; + + for (col = 0, curRowBufOffset = 0 ; col < cols ; col++) { calc2 += inRowPtr[2 + curRowBufOffset]; calc1 += inRowPtr[1 + curRowBufOffset]; calc0 += inRowPtr[0 + curRowBufOffset]; curRowBufOffset += 3; - curCol++; } - double calcMax; - double calc3; - double gammaAdj2; - double gammaAdj1; - int col; - col = 0; - gammaAdj1 = Gamma->GammaAdj[1]; - curRowBufOffset = 0; - curCol = 0; - gammaAdj2 = Gamma->GammaAdj[2]; - calcMax = maxTank; + calc3 = ((maxTank - calc0) + (maxTank - calc2) + (maxTank - calc1)) / (cols * 3); - calc3 = ((calcMax - calc0) + (calcMax - calc2) + (calcMax - calc1)) / (cols * 3); + gammaAdj0 = ((gammaAdj0 + (((calc3 * gammaAdj0) / 255.00000000) * gammaAdj1) / -4095.00000000) * gammaAdj2) / 4095.00000000; - gammaAdj0 = ((dVar2 + (((calc3 * dVar2) / 255.00000000) * gammaAdj1) / -4095.00000000) * gammaAdj2) / 4095.00000000; - - while (col < cols2) { + for (col = 0, curRowBufOffset = 0; col < cols ; col++) { outVal = Gamma->GNMby[inRowPtr[curRowBufOffset + 2]] + gammaAdj0 + 0.50000000; if (outVal < 0x1000) { if (outVal < 0) { @@ -1855,35 +1829,40 @@ static int CP98xx_DoGammaConv(struct CP98xx_GammaParams *Gamma, if (outVal < 0) { outRowPtr[curRowBufOffset + 2] = 0; } else { - outRowPtr[curRowBufOffset + 2] = (short)outVal; + outRowPtr[curRowBufOffset + 2] = outVal; } } else { outRowPtr[curRowBufOffset + 2] = 0xfff; } - cols2 = cols; - col = curCol + 1; curRowBufOffset += 3; - curCol = col; } - tmp = inBytesPerRow + 1; inRowPtr -= inBytesPerRow; outRowPtr -= pixelsPerRow; } - while (tmp < outVal) { - outVal = 0; - curRowBufOffset = 0; - while (curCol = outVal, outVal < cols2) { - outRowPtr[curRowBufOffset] = Gamma->GNMby[inRowPtr[curRowBufOffset + 2]]; - outRowPtr[curRowBufOffset + 1] = Gamma->GNMgm[inRowPtr[curRowBufOffset + 1]]; - outRowPtr[curRowBufOffset + 2] = Gamma->GNMrc[inRowPtr[curRowBufOffset]]; - cols2 = cols; - outVal = curCol + 1; + if (!already_reversed) { + // XXX reverse each row. See D70 for how. + } + + /* Write gamma corrected data to output buffer, last row first */ + for (row = 0 ; row < rows ; row++) { + int outRowBufOffset = 0; + + if (!already_reversed) + outRowBufOffset += (cols - 1) * 3; + + for (col = 0, curRowBufOffset = 0 ; col < cols ; col ++) { + // XXX is this order correct? output is YMC but this treats input as RGB? + outRowPtr[outRowBufOffset] = Gamma->GNMby[inRowPtr[curRowBufOffset + 2]]; + outRowPtr[outRowBufOffset + 1] = Gamma->GNMgm[inRowPtr[curRowBufOffset + 1]]; + outRowPtr[outRowBufOffset + 2] = Gamma->GNMrc[inRowPtr[curRowBufOffset]]; curRowBufOffset += 3; + if (already_reversed) + outRowBufOffset += 3; + else + outRowBufOffset -= 3; } - outVal = rows; - tmp ++; inRowPtr -= inBytesPerRow; outRowPtr -= pixelsPerRow; } @@ -2341,7 +2320,7 @@ static int CP98xx_DoWMAM(struct CP98xx_WMAM *wmam, struct BandImage *img, int al int CP98xx_DoConvert(const struct mitsu98xx_data *table, const struct BandImage *input, struct BandImage *output, - uint8_t type, int sharpness) + uint8_t type, int sharpness, int already_reversed) { int i; @@ -2364,9 +2343,11 @@ int CP98xx_DoConvert(const struct mitsu98xx_data *table, /* We've already gone through 3D LUT */ /* Sharpen, as needed */ - struct CP98xx_AptParams APT; - CP98xx_InitAptParams(table, &APT, sharpness); - // XXX DoAptMWithParams() + if (sharpness > 0) { + struct CP98xx_AptParams APT; + CP98xx_InitAptParams(table, &APT, sharpness); + // XXX DoAptMWithParams(); + } /* Set up gamma table and do the conversion */ struct CP98xx_GammaParams gamma; @@ -2387,7 +2368,7 @@ int CP98xx_DoConvert(const struct mitsu98xx_data *table, if (CP98xx_DoCorrectGammaTbl(&gamma, &kh, input) != 1) { return 0; } - if (CP98xx_DoGammaConv(&gamma, input, output) != 1) { + if (CP98xx_DoGammaConv(&gamma, input, output, already_reversed) != 1) { return 0; } diff --git a/lib70x/libMitsuD70ImageReProcess.h b/lib70x/libMitsuD70ImageReProcess.h index 244ff5a..3a720b6 100644 --- a/lib70x/libMitsuD70ImageReProcess.h +++ b/lib70x/libMitsuD70ImageReProcess.h @@ -132,6 +132,6 @@ void CP98xx_DestroyData(const struct mitsu98xx_data *data); int CP98xx_DoConvert(const struct mitsu98xx_data *table, const struct BandImage *input, struct BandImage *output, - uint8_t type, int sharpness); + uint8_t type, int sharpness, int already_reversed); #endif /* __MITSU_D70_H */ diff --git a/regression-gp.csv b/regression-gp.csv index 679ebd4..b46ef27 100644 --- a/regression-gp.csv +++ b/regression-gp.csv @@ -291,11 +291,14 @@ mitsubishi-9800dw,0x06d3,0x03ad,0x5,PageSize=w432h612 mitsubishi-9800dw,0x06d3,0x03ad,0x5,PageSize=w432h648 mitsubishi-9800dw,0x06d3,0x03ad,0x5,PageSize=w432h648;StpUseLUT=True mitsubishi-9800dw,0x06d3,0x03ad,0x5,PageSize=w432h648;StpUseLUT=False +mitsubishi-9800dw,0x06d3,0x03ad,0x5,PageSize=w432h648;StpSharpen=0 +mitsubishi-9800dw,0x06d3,0x03ad,0x5,PageSize=w432h648;StpSharpen=9 mitsubishi-9800dw,0x06d3,0x03ad,0x4,PageSize=B7 mitsubishi-9800dw,0x06d3,0x03ad,0x4,PageSize=B7;StpPrintSpeed=Fine mitsubishi-9800dw,0x06d3,0x03ad,0x4,PageSize=B7;StpPrintSpeed=FineHG mitsubishi-9800dw,0x06d3,0x03ad,0x4,PageSize=B7;StpPrintSpeed=SuperFine mitsubishi-9800dw,0x06d3,0x03ad,0x4,PageSize=w360h504 +# mitsubishi-9800dw-s,0x06d3,0x03ae,0x2,PageSize=w288h432 mitsubishi-9800dw-s,0x06d3,0x03ae,0x5,PageSize=w432h576 mitsubishi-9800dw-s,0x06d3,0x03ae,0x5,PageSize=w432h612 @@ -309,6 +312,8 @@ mitsubishi-9810dw,0x06d3,0x3b21,0x5,PageSize=w432h612 mitsubishi-9810dw,0x06d3,0x3b21,0x5,PageSize=w432h648 mitsubishi-9810dw,0x06d3,0x3b21,0x5,PageSize=w432h648;StpUseLUT=True mitsubishi-9810dw,0x06d3,0x3b21,0x5,PageSize=w432h648;StpUseLUT=False +mitsubishi-9810dw,0x06d3,0x3b21,0x5,PageSize=w432h648;StpSharpen=0 +mitsubishi-9810dw,0x06d3,0x3b21,0x5,PageSize=w432h648;StpSharpen=9 mitsubishi-9810dw,0x06d3,0x3b21,0x4,PageSize=B7 mitsubishi-9810dw,0x06d3,0x3b21,0x4,PageSize=w360h504 mitsubishi-9810dw,0x06d3,0x3b21,0x2,PageSize=w288h432;StpLaminate=Matte