From c14dc23de39458e6dbc6d32a4d62b84ec487df00 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Sat, 5 Dec 2020 18:14:33 -0500 Subject: [PATCH] lib70x: Library enhancements for CP30D family * 3D LUT processed in planar format * Sharpening support (not implemented yet) --- README | 7 +++- backend_mitsu.c | 54 +++++++++++++++++++++++++-- backend_mitsu.h | 29 ++++++++++++--- backend_mitsu70x.c | 8 ++-- backend_mitsu9550.c | 39 +++++++++++++++----- backend_mitsud90.c | 10 ++--- lib70x/libMitsuD70ImageReProcess.c | 59 +++++++++++++++++++++++++++++- lib70x/libMitsuD70ImageReProcess.h | 21 ++++++++++- testjobs/mitsu_cp30-l.raw | 2 +- 9 files changed, 196 insertions(+), 33 deletions(-) diff --git a/README b/README index 0633ce0..67f7216 100644 --- a/README +++ b/README @@ -1058,7 +1058,7 @@ Mitsubishi CP9000D/DW Mitsubishi CP9500D/DW - Mitsubishi CP30DW + Mitsubishi CP30DW [2] Mitsubishi CP9600DW-S/DZ/DZ-S Valid commands: @@ -1087,6 +1087,11 @@ not responsible in any way for the library or any deficiencies in its output. They will provide no support if it is used. + [2] **** VERY IMPORTANT **** + + The CPD30 family also relies on the lib70x library in order to do the + 3D LUT and sharpening transforms. All of the above disclaimers apply. + *************************************************************************** BACKEND=mitsup9x diff --git a/backend_mitsu.c b/backend_mitsu.c index 9f0deca..a33e437 100644 --- a/backend_mitsu.c +++ b/backend_mitsu.c @@ -58,6 +58,7 @@ int mitsu_loadlib(struct mitsu_lib *lib, int type) lib->Load3DColorTable = DL_SYM(lib->dl_handle, "CColorConv3D_Load3DColorTable"); lib->Destroy3DColorTable = DL_SYM(lib->dl_handle, "CColorConv3D_Destroy3DColorTable"); lib->DoColorConv = DL_SYM(lib->dl_handle, "CColorConv3D_DoColorConv"); + lib->DoColorConvPlane = DL_SYM(lib->dl_handle, "CColorConv3D_DoColorConvPlane"); lib->GetCPCData = DL_SYM(lib->dl_handle, "get_CPCData"); lib->DestroyCPCData = DL_SYM(lib->dl_handle, "destroy_CPCData"); lib->DoImageEffect60 = DL_SYM(lib->dl_handle, "do_image_effect60"); @@ -74,6 +75,9 @@ int mitsu_loadlib(struct mitsu_lib *lib, int type) lib->M1_CalcRGBRate = DL_SYM(lib->dl_handle, "M1_CalcRGBRate"); lib->M1_CalcOpRateMatte = DL_SYM(lib->dl_handle, "M1_CalcOpRateMatte"); lib->M1_CalcOpRateGloss = DL_SYM(lib->dl_handle, "M1_CalcOpRateGloss"); + lib->CPD30_GetData = DL_SYM(lib->dl_handle, "CPD30_GetData"); + lib->CPD30_DestroyData = DL_SYM(lib->dl_handle, "CPD30_DestroyData"); + lib->CPD30_DoConvert = DL_SYM(lib->dl_handle, "CPD30_DoConvert"); if (!lib->Get3DColorTable || !lib->Load3DColorTable || !lib->CP98xx_DoConvert || !lib->CP98xx_GetData || @@ -82,7 +86,10 @@ int mitsu_loadlib(struct mitsu_lib *lib, int type) !lib->M1_Gamma8to14 || !lib->M1_CLocalEnhancer || !lib->M1_CalcOpRateMatte || !lib->M1_CalcOpRateGloss || !lib->M1_CalcRGBRate || + !lib->CPD30_GetData || !lib->CPD30_DestroyData || + !lib->CPD30_DoConvert || !lib->Destroy3DColorTable || !lib->DoColorConv || + !lib->DoColorConvPlane || !lib->GetCPCData || !lib->DestroyCPCData || !lib->DoImageEffect60 || !lib->DoImageEffect70 || !lib->DoImageEffect80 || !lib->SendImageData) { @@ -143,9 +150,9 @@ int mitsu_destroylib(struct mitsu_lib *lib) return CUPS_BACKEND_OK; } -int mitsu_apply3dlut(struct mitsu_lib *lib, const char *lutfname, uint8_t *databuf, - uint16_t cols, uint16_t rows, uint16_t stride, - int rgb_bgr) +int mitsu_apply3dlut_packed(struct mitsu_lib *lib, const char *lutfname, uint8_t *databuf, + uint16_t cols, uint16_t rows, uint16_t stride, + int rgb_bgr) { #if defined(WITH_DYNAMIC) char full[2048]; @@ -153,6 +160,8 @@ int mitsu_apply3dlut(struct mitsu_lib *lib, const char *lutfname, uint8_t *datab if (!lutfname) return CUPS_BACKEND_OK; + if (!lib->dl_handle) + return CUPS_BACKEND_OK; snprintf(full, sizeof(full), "%s/%s", corrtable_path, lutfname); @@ -180,6 +189,45 @@ int mitsu_apply3dlut(struct mitsu_lib *lib, const char *lutfname, uint8_t *datab return CUPS_BACKEND_OK; } +int mitsu_apply3dlut_plane(struct mitsu_lib *lib, const char *lutfname, + uint8_t *data_r, uint8_t *data_g, uint8_t *data_b, + uint16_t cols, uint16_t rows) +{ +#if defined(WITH_DYNAMIC) + char full[2048]; + int i; + + if (!lutfname) + return CUPS_BACKEND_OK; + if (!lib->dl_handle) + return CUPS_BACKEND_OK; + + snprintf(full, sizeof(full), "%s/%s", corrtable_path, lutfname); + + if (!lib->lut) { + uint8_t *buf = malloc(LUT_LEN); + if (!buf) { + ERROR("Memory allocation failure!\n"); + return CUPS_BACKEND_RETRY_CURRENT; + } + if ((i = dyesub_read_file(full, buf, LUT_LEN, NULL))) + return i; + lib->lut = lib->Load3DColorTable(buf); + free(buf); + if (!lib->lut) { + ERROR("Unable to parse LUT file '%s'!\n", full); + return CUPS_BACKEND_CANCEL; + } + } + + if (lib->lut) { + DEBUG("Running print data through 3D LUT\n"); + lib->DoColorConvPlane(lib->lut, data_r, data_g, data_b, cols * rows); + } +#endif + return CUPS_BACKEND_OK; +} + int mitsu_readlamdata(const char *fname, uint16_t lamstride, uint8_t *databuf, uint32_t *datalen, uint16_t rows, uint16_t cols, uint8_t bpp) diff --git a/backend_mitsu.h b/backend_mitsu.h index 724fbdb..423940c 100644 --- a/backend_mitsu.h +++ b/backend_mitsu.h @@ -45,8 +45,10 @@ struct BandImage { // @24 }; -struct mitsu98xx_data; /* Forward declaration */ +/* Forward declarations */ +struct mitsu98xx_data; struct M1CPCData; +struct mitsu_cpd30_data; #endif typedef void (*dump_announceFN)(FILE *fp); @@ -55,6 +57,7 @@ typedef int (*Get3DColorTableFN)(uint8_t *buf, const char *filename); typedef struct CColorConv3D *(*Load3DColorTableFN)(const uint8_t *ptr); typedef void (*Destroy3DColorTableFN)(struct CColorConv3D *this); typedef void (*DoColorConvFN)(struct CColorConv3D *this, uint8_t *data, uint16_t cols, uint16_t rows, uint32_t bytes_per_row, int rgb_bgr); +typedef void (*DoColorConvPlaneFN)(struct CColorConv3D *this, uint8_t *data_r, uint8_t *data_g, uint8_t *data_b, uint32_t planelen); typedef struct CPCData *(*get_CPCDataFN)(const char *filename); typedef void (*destroy_CPCDataFN)(struct CPCData *data); typedef int (*do_image_effectFN)(struct CPCData *cpc, struct CPCData *ecpc, struct BandImage *input, struct BandImage *output, int sharpen, int reverse, uint8_t rew[2]); @@ -80,13 +83,20 @@ typedef int (*M1_CalcRGBRateFN)(uint16_t rows, uint16_t cols, uint8_t *data); typedef uint8_t (*M1_CalcOpRateMatteFN)(uint16_t rows, uint16_t cols, uint8_t *data); typedef uint8_t (*M1_CalcOpRateGlossFN)(uint16_t rows, uint16_t cols); +typedef struct mitsu_cpd30_data *(*CPD30_GetDataFN)(const char *filename); +typedef void (*CPD30_DestroyDataFN)(const struct mitsu_cpd30_data *data); +typedef int (*CPD30_DoConvertFN)(const struct mitsu_cpd30_data *table, + const struct BandImage *input, + struct BandImage *output, + uint8_t type, int sharpness); + #ifndef WITH_DYNAMIC #warning "No dynamic loading support!" #endif -#define REQUIRED_LIB_APIVERSION 7 +#define REQUIRED_LIB_APIVERSION 8 -#define LIBMITSU_VER "0.06" +#define LIBMITSU_VER "0.08" /* Image processing library function prototypes */ #define LIB_NAME_RE "libMitsuD70ImageReProcess" DLL_SUFFIX @@ -99,6 +109,7 @@ struct mitsu_lib { Load3DColorTableFN Load3DColorTable; Destroy3DColorTableFN Destroy3DColorTable; DoColorConvFN DoColorConv; + DoColorConvPlaneFN DoColorConvPlane; get_CPCDataFN GetCPCData; destroy_CPCDataFN DestroyCPCData; do_image_effectFN DoImageEffect60; @@ -116,6 +127,9 @@ struct mitsu_lib { M1_CalcRGBRateFN M1_CalcRGBRate; M1_CalcOpRateGlossFN M1_CalcOpRateGloss; M1_CalcOpRateMatteFN M1_CalcOpRateMatte; + CPD30_GetDataFN CPD30_GetData; + CPD30_DestroyDataFN CPD30_DestroyData; + CPD30_DoConvertFN CPD30_DoConvert; struct CColorConv3D *lut; struct CPCData *cpcdata; struct CPCData *ecpcdata; @@ -123,9 +137,12 @@ struct mitsu_lib { int mitsu_loadlib(struct mitsu_lib *lib, int type); int mitsu_destroylib(struct mitsu_lib *lib); -int mitsu_apply3dlut(struct mitsu_lib *lib, const char *lutfname, uint8_t *databuf, - uint16_t cols, uint16_t rows, uint16_t stride, - int rgb_bgr); +int mitsu_apply3dlut_packed(struct mitsu_lib *lib, const char *lutfname, uint8_t *databuf, + uint16_t cols, uint16_t rows, uint16_t stride, + int rgb_bgr); +int mitsu_apply3dlut_plane(struct mitsu_lib *lib, const char *lutfname, + uint8_t *data_r, uint8_t *data_g, uint8_t *data_b, + uint16_t cols, uint16_t rows); int mitsu_readlamdata(const char *fname, uint16_t lamstride, uint8_t *databuf, uint32_t *datalen, uint16_t rows, uint16_t cols, uint8_t bpp); diff --git a/backend_mitsu70x.c b/backend_mitsu70x.c index 39b6566..762fd13 100644 --- a/backend_mitsu70x.c +++ b/backend_mitsu70x.c @@ -1099,10 +1099,10 @@ repeat: /* Run through basic LUT, if present and enabled */ if (job->lutfname) { - int ret = mitsu_apply3dlut(&ctx->lib, job->lutfname, - job->spoolbuf, job->cols, - job->rows, job->cols * 3, - COLORCONV_BGR); + int ret = mitsu_apply3dlut_packed(&ctx->lib, job->lutfname, + job->spoolbuf, job->cols, + job->rows, job->cols * 3, + COLORCONV_BGR); if (ret) { mitsu70x_cleanup_job(job); return ret; diff --git a/backend_mitsu9550.c b/backend_mitsu9550.c index b330db3..69b7b83 100644 --- a/backend_mitsu9550.c +++ b/backend_mitsu9550.c @@ -133,6 +133,7 @@ struct mitsu9550_ctx { int is_s; int is_98xx; + int need_lib; int footer_len; const char *lut_fname; @@ -359,10 +360,14 @@ static int mitsu9550_attach(void *vctx, struct dyesub_connection *conn, uint8_t ctx->conn->type == P_MITSU_9800S || ctx->conn->type == P_MITSU_9810) { ctx->is_98xx = 1; + ctx->need_lib = 1; ctx->lut_fname = MITSU_M98xx_LUT_FILE; } - if (ctx->is_98xx) { + if (ctx->conn->type == P_MITSU_CP30D) { + ctx->need_lib = 1; + } + if (ctx->need_lib) { #if defined(WITH_DYNAMIC) /* Attempt to open the library */ if (mitsu_loadlib(&ctx->lib, ctx->conn->type)) @@ -556,10 +561,10 @@ hdr_done: if (job->is_raw) { /* We have three planes + headers and the final terminator to read */ - remain = 3 * (planelen + sizeof(struct mitsu9550_plane)) + sizeof(struct mitsu9550_cmd); + remain = 3 * (planelen + sizeof(struct mitsu9550_plane)) + ctx->footer_len; } else { /* We have one plane + header and the final terminator to read */ - remain = planelen * 3 + sizeof(struct mitsu9550_plane) + sizeof(struct mitsu9550_cmd); + remain = planelen * 3 + sizeof(struct mitsu9550_plane) + ctx->footer_len; } /* Mitsu9600 windows spool uses more, smaller blocks, but plane data is the same */ @@ -686,12 +691,26 @@ hdr_done: } } + /* One bit of fixup */ + if (ctx->conn->type == P_MITSU_CP30D) + job->is_raw = 0; + /* Apply LUT, if job calls for it.. */ if (ctx->lut_fname && !job->is_raw && job->hdr2.unkc[9]) { - int ret = mitsu_apply3dlut(&ctx->lib, ctx->lut_fname, - job->databuf + sizeof(struct mitsu9550_plane), - job->cols, job->rows, - job->cols * 3, COLORCONV_BGR); + int ret; + if (ctx->conn->type == P_MITSU_CP30D) { + uint32_t planelen = job->rows * job->cols + sizeof(struct mitsu9550_plane); + ret = mitsu_apply3dlut_plane(&ctx->lib, ctx->lut_fname, + job->databuf + sizeof(struct mitsu9550_plane), + job->databuf + (planelen + sizeof(struct mitsu9550_plane)), + job->databuf + (planelen * 2 + sizeof(struct mitsu9550_plane)), + job->cols, job->rows); + } else { + ret = mitsu_apply3dlut_packed(&ctx->lib, ctx->lut_fname, + job->databuf + sizeof(struct mitsu9550_plane), + job->cols, job->rows, + job->cols * 3, COLORCONV_BGR); + } if (ret) { mitsu9550_cleanup_job(job); return ret; @@ -1003,6 +1022,9 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) { /* Okay, let's do this thing */ ptr = job->databuf; + int sharpness = job->hdr2.unkc[7]; + job->hdr2.unkc[7] = 0; /* Clear "sharpness" parameter */ + /* Do the 98xx processing here */ if (!ctx->is_98xx || job->is_raw) goto non_98xx; @@ -1045,8 +1067,6 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) { output.imgbuf = convbuf; output.bytes_per_row = job->cols * 3 * sizeof(uint16_t); - int sharpness = job->hdr2.unkc[7]; - if (!ctx->lib.CP98xx_DoConvert(ctx->m98xxdata, &input, &output, job->hdr2.mode, sharpness, job->hdr2.unkc[8])) { free(convbuf); free(newbuf); @@ -1058,7 +1078,6 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) { 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 */ /* Library is done, but its output is packed YMC16. We need to convert this to planar YMC16, with a header for diff --git a/backend_mitsud90.c b/backend_mitsud90.c index 10789e9..70a38da 100644 --- a/backend_mitsud90.c +++ b/backend_mitsud90.c @@ -842,11 +842,11 @@ static int mitsud90_read_parse(void *vctx, const void **vjob, int data_fd, int c job->hdr.colorcorr = 1; if (job->m1_colormode == 0) { - int ret = mitsu_apply3dlut(&ctx->lib, CPM1_LUT_FNAME, - job->databuf + sizeof(struct mitsud90_plane_hdr), - be16_to_cpu(job->hdr.cols), - be16_to_cpu(job->hdr.rows), - be16_to_cpu(job->hdr.cols) * 3, COLORCONV_RGB); + int ret = mitsu_apply3dlut_packed(&ctx->lib, CPM1_LUT_FNAME, + job->databuf + sizeof(struct mitsud90_plane_hdr), + be16_to_cpu(job->hdr.cols), + be16_to_cpu(job->hdr.rows), + be16_to_cpu(job->hdr.cols) * 3, COLORCONV_RGB); if (ret) { mitsud90_cleanup_job(job); return ret; diff --git a/lib70x/libMitsuD70ImageReProcess.c b/lib70x/libMitsuD70ImageReProcess.c index 261f79d..80e3d26 100644 --- a/lib70x/libMitsuD70ImageReProcess.c +++ b/lib70x/libMitsuD70ImageReProcess.c @@ -34,6 +34,10 @@ * Mitsubishi CP9810DW * Mitsubishi CP9820DW-S + Finally, the CP30D family uses this library too. This includes tehse models: + + * Mitsubishi CP30D/DW + ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** This program is free software; you can redistribute it and/or modify it @@ -53,7 +57,7 @@ */ -#define LIB_VERSION "0.9.4" +#define LIB_VERSION "0.10.0" #include #include @@ -301,7 +305,7 @@ static void CColorConv3D_DoColorConvPixel(struct CColorConv3D *this, uint8_t *re + 2048) >> 12; } -/* Perform a total conversion on an entire image */ +/* Perform a total conversion on an entire image, packed rgb/bgr */ void CColorConv3D_DoColorConv(struct CColorConv3D *this, uint8_t *data, uint16_t cols, uint16_t rows, uint32_t stride, int rgb_bgr) { uint16_t i, j; @@ -324,6 +328,18 @@ void CColorConv3D_DoColorConv(struct CColorConv3D *this, uint8_t *data, uint16_t } } +/* Perform a total conversion on an entire image, planar */ +void CColorConv3D_DoColorConvPlane(struct CColorConv3D *this, uint8_t *data_r, uint8_t *data_g, uint8_t *data_b, + uint32_t planelen) +{ + uint32_t i; + + for ( i = 0; i < planelen ; i++ ) + { + CColorConv3D_DoColorConvPixel(this, &data_r[i], &data_g[i], &data_b[i]); + } +} + /*** CPC Data ***/ /* Load and parse the CPC data */ @@ -2931,3 +2947,42 @@ done_free: free(data); return NULL; } + +/* CP-D30 family */ + +struct mitsu_cpd30_data { /* XXX All of these are PLACEHOLDERS! */ + int16_t mask[8][6]; + int unsharp; + int mpx10; +}; + +struct mitsu_cpd30_data *CPD30_GetData(const char *filename) +{ + UNUSED(filename); + return NULL; +} + +void CPD30_DestroyData(const struct mitsu_cpd30_data *data) +{ + if (data) free((void*)data); +} + +int CPD30_DoConvert(const struct mitsu_cpd30_data *table, + const struct BandImage *input, + struct BandImage *output, + uint8_t type, int sharpness) +{ + UNUSED(table); + UNUSED(input); + UNUSED(output); + UNUSED(type); + + /* Sharpen, as needed */ + if (sharpness > 0) { +// struct CP98xx_AptParams APT; +// CP98xx_InitAptParams(table, &APT, sharpness); + // XXX DoAptMWithParams(); + } + + return 0; /* 1 if successful */ +} diff --git a/lib70x/libMitsuD70ImageReProcess.h b/lib70x/libMitsuD70ImageReProcess.h index 0cfbf53..9b82903 100644 --- a/lib70x/libMitsuD70ImageReProcess.h +++ b/lib70x/libMitsuD70ImageReProcess.h @@ -37,6 +37,11 @@ * Mitsubishi CP-M1 + Finally, the CP-D30 family utilizes this library. This includes these + models: + + * Mitsubishi CP-D30DW + ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** This program is free software; you can redistribute it and/or modify it @@ -62,7 +67,7 @@ #ifndef __MITSU_D70_H #define __MITSU_D70_H -#define LIB_APIVERSION 7 +#define LIB_APIVERSION 8 #include @@ -129,6 +134,8 @@ void CColorConv3D_Destroy3DColorTable(struct CColorConv3D *this); /* Run a packed 8bpp rgb or bgr image through the LUT */ void CColorConv3D_DoColorConv(struct CColorConv3D *this, uint8_t *data, uint16_t cols, uint16_t rows, uint32_t bytes_per_row, int rgb_bgr); +/* Run a planar rgb image through the LUT */ +void CColorConv3D_DoColorConvPlane(struct CColorConv3D *this, uint8_t *data_r, uint8_t *data_g, uint8_t *data_b, uint32_t planelen); /* CP98xx family stuff */ struct mitsu98xx_data; /* Forward declaration */ @@ -159,4 +166,16 @@ struct M1CPCData *M1_GetCPCData(const char *corrtable_path, const char *gammafilename); void M1_DestroyCPCData(struct M1CPCData *dat); + +/* CPD30 family stuff */ +struct mitsu_cpd30_data; /* Forward declaration */ + +struct mitsu_cpd30_data *CPD30_GetData(const char *filename); +void CPD30_DestroyData(const struct mitsu_cpd30_data *data); + +int CPD30_DoConvert(const struct mitsu_cpd30_data *table, + const struct BandImage *input, + struct BandImage *output, + uint8_t type, int sharpness); + #endif /* __MITSU_D70_H */ diff --git a/testjobs/mitsu_cp30-l.raw b/testjobs/mitsu_cp30-l.raw index 700fb51..ddb0dcd 100644 --- a/testjobs/mitsu_cp30-l.raw +++ b/testjobs/mitsu_cp30-l.raw @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f26db7c466bde8da38da5dab668adb6a47663a20be502b8679ad851cde4265c6 +oid sha256:a942356ba4b6105f616eb0adc306e01a89c20658d3ccee19d2413515fa4ec498 size 10080242