lib70x: Library enhancements for CP30D family

* 3D LUT processed in planar format
 * Sharpening support (not implemented yet)
This commit is contained in:
Solomon Peachy 2020-12-05 18:14:33 -05:00
parent 62032a4e61
commit c14dc23de3
9 changed files with 196 additions and 33 deletions

7
README
View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 <stdio.h>
#include <stdint.h>
@ -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 */
}

View File

@ -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 <stdint.h>
@ -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 */

BIN
testjobs/mitsu_cp30-l.raw (Stored with Git LFS)

Binary file not shown.