hiti: Port over inteprolation algorithm, and include binary data files.

This commit is contained in:
Solomon Peachy 2019-09-28 17:44:09 -04:00
parent 57bc5bfa5c
commit 27e96d4da8
18 changed files with 206 additions and 24 deletions

View File

@ -102,6 +102,8 @@ install:
$(INSTALL) -o root -m 700 $(EXEC_NAME) $(CUPS_BACKEND_DIR)/$(BACKEND_NAME) $(INSTALL) -o root -m 700 $(EXEC_NAME) $(CUPS_BACKEND_DIR)/$(BACKEND_NAME)
$(MKDIR) -p $(CUPS_DATA_DIR)/usb $(MKDIR) -p $(CUPS_DATA_DIR)/usb
$(INSTALL) -o root -m 644 blacklist $(CUPS_DATA_DIR)/usb/net.sf.gimp-print.usb-quirks $(INSTALL) -o root -m 644 blacklist $(CUPS_DATA_DIR)/usb/net.sf.gimp-print.usb-quirks
$(MKDIR) -p $(BACKEND_DATA_DIR)
$(INSTALL) -o root -m 644 hiti_data/*bin $(BACKEND_DATA_DIR)
clean: clean:
$(RM) $(EXEC_NAME) $(BACKENDS) $(SOURCES:.c=.o) lib70x/*o lib6145/*o $(RM) $(EXEC_NAME) $(BACKENDS) $(SOURCES:.c=.o) lib70x/*o lib6145/*o
@ -116,4 +118,4 @@ release: clean
# Backend-specific joy: # Backend-specific joy:
backend_mitsu70x.o: CPPFLAGS += -DCORRTABLE_PATH=\"$(BACKEND_DATA_DIR)\" -include lib70x/libMitsuD70ImageReProcess.h backend_mitsu70x.o: CPPFLAGS += -DCORRTABLE_PATH=\"$(BACKEND_DATA_DIR)\" -include lib70x/libMitsuD70ImageReProcess.h
backend_mitsu9550.o: CPPFLAGS += -DCORRTABLE_PATH=\"$(BACKEND_DATA_DIR)\" -include lib70x/libMitsuD70ImageReProcess.h backend_mitsu9550.o: CPPFLAGS += -DCORRTABLE_PATH=\"$(BACKEND_DATA_DIR)\" -include lib70x/libMitsuD70ImageReProcess.h
#backend_shinko%.o: backend_shinko.h backend_hiti.o: CPPFLAGS += -DCORRTABLE_PATH=\"$(BACKEND_DATA_DIR)\"

View File

@ -31,6 +31,14 @@
#include "backend_common.h" #include "backend_common.h"
#ifndef CORRTABLE_PATH
#ifdef PACKAGE_DATA_DIR
#define CORRTABLE_PATH PACKAGE_DATA_DIR "/backend_data"
#else
#error "Must define CORRTABLE_PATH or PACKAGE_DATA_DIR!"
#endif
#endif
/* Private structures */ /* Private structures */
struct hiti_cmd { struct hiti_cmd {
uint8_t hdr; /* 0xa5 */ uint8_t hdr; /* 0xa5 */
@ -701,61 +709,61 @@ static const uint8_t *hiti_get_correction_data(struct hiti_ctx *ctx)
switch (ctx->type) switch (ctx->type)
{ {
case P_HITI_52X: case P_HITI_52X:
fname = "P52x_CCPPri.bin"; fname = CORRTABLE_PATH "/P52x_CCPPri.bin";
break; break;
case P_HITI_72X: case P_HITI_72X:
if (!mediatype) { if (!mediatype) {
if (mode) { if (mode) {
fname = "P72x_CMQPrd.bin"; fname = CORRTABLE_PATH "/P72x_CMQPrd.bin";
break; break;
} else { } else {
fname = "P72x_CMPPrd.bin"; fname = CORRTABLE_PATH "/P72x_CMPPrd.bin";
break; break;
} }
} else { } else {
if (mode) { if (mode) {
switch(mediaver) { switch(mediaver) {
case 0: case 0:
fname = "P72x_CCQPrd.bin"; fname = CORRTABLE_PATH "/P72x_CCQPrd.bin";
break; break;
case 1: case 1:
fname = "P72x_CCQP1rd.bin"; fname = CORRTABLE_PATH "/P72x_CCQP1rd.bin";
break; break;
case 2: case 2:
fname = "P72x_CCQP2rd.bin"; fname = CORRTABLE_PATH "/P72x_CCQP2rd.bin";
break; break;
case 3: case 3:
fname = "P72x_CCQP3rd.bin"; fname = CORRTABLE_PATH "/P72x_CCQP3rd.bin";
break; break;
case 4: case 4:
default: default:
fname = "P72x_CCQP4rd.bin"; fname = CORRTABLE_PATH "/P72x_CCQP4rd.bin";
break; break;
} }
} else { } else {
switch(mediaver) { switch(mediaver) {
case 0: case 0:
fname = "P72x_CCPPrd.bin"; fname = CORRTABLE_PATH "/P72x_CCPPrd.bin";
break; break;
case 1: case 1:
fname = "P72x_CCPP1rd.bin"; fname = CORRTABLE_PATH "/P72x_CCPP1rd.bin";
break; break;
case 2: case 2:
fname = "P72x_CCPP2rd.bin"; fname = CORRTABLE_PATH "/P72x_CCPP2rd.bin";
break; break;
case 3: case 3:
fname = "P72x_CCPP3rd.bin"; fname = CORRTABLE_PATH "/P72x_CCPP3rd.bin";
break; break;
case 4: case 4:
default: default:
fname = "P72x_CCPP4rd.bin"; fname = CORRTABLE_PATH "/P72x_CCPP4rd.bin";
break; break;
} }
} }
} }
break; break;
case P_HITI_75X: case P_HITI_75X:
fname = "P75x_CCPPri.bin"; fname = CORRTABLE_PATH "/P75x_CCPPri.bin";
break; break;
default: default:
fname = NULL; fname = NULL;
@ -784,6 +792,174 @@ static const uint8_t *hiti_get_correction_data(struct hiti_ctx *ctx)
return buf; return buf;
} }
/* HiTi's funky interpolation table processing */
struct rgb {
uint8_t r;
uint8_t g;
uint8_t b;
};
static uint32_t interp1089[33];
static uint32_t interp33[33];
static uint16_t interp256[256*9];
static void hiti_interp_init(void)
{
int i;
uint16_t *pre, *cur;
for (i = 0 ; i < 33 ; i++) {
interp1089[i] = i * 1089;
interp33[i] = i * 33;
}
memset(interp256, 0, sizeof(interp256));
pre = &interp256[0];
cur = &interp256[256];
for (i = 1 ; i < 9 ; i++) {
int j;
for (j = 0 ; i < 256 ; j++) {
cur[j] = pre[j] + j;
};
pre += 256;
cur += 256;
}
}
static void hiti_interp33_256(uint8_t *dst, uint8_t *src, const uint8_t *pTable)
{
struct rgb p1_pos, p2_pos, p3_pos, p4_pos;
struct rgb p1_val, p2_val, p3_val, p4_val;
uint8_t r_weight, g_weight, b_weight;
uint16_t w1, w2, w3, w4;
uint16_t *pw1, *pw2, *pw3, *pw4;
uint32_t pos;
/* Get Grid position */
p1_pos.r = src[0] >> 3;
p1_pos.g = src[1] >> 3;
p1_pos.b = src[2] >> 3;
p4_pos.r = p1_pos.r + 1;
p4_pos.g = p1_pos.g + 1;
p4_pos.b = p1_pos.b + 1;
/* Weights */
r_weight = src[0] & 0x7;
g_weight = src[1] & 0x7;
b_weight = src[2] & 0x7;
if (src[0] == 255) r_weight = 8;
if (src[1] == 255) g_weight = 8;
if (src[2] == 255) b_weight = 8;
/* Work out relative weights and offsets */
if (r_weight >= g_weight) {
if (g_weight >= b_weight) { /* R > G > B */
w1 = 8 - r_weight;
w2 = r_weight - g_weight;
w3 = g_weight - b_weight;
w4 = b_weight;
p2_pos.r = p1_pos.r + 1;
p2_pos.g = p1_pos.g;
p2_pos.b = p1_pos.b;
p3_pos.r = p1_pos.r + 1;
p3_pos.g = p1_pos.g + 1;
p3_pos.b = p1_pos.b;
} else {
if (r_weight >= b_weight) { /* R > B > G */
w1 = 8 - r_weight;
w2 = r_weight - b_weight;
w3 = b_weight - g_weight;
w4 = g_weight;
p2_pos.r = p1_pos.r + 1;
p2_pos.g = p1_pos.g;
p2_pos.b = p1_pos.b;
p3_pos.r = p1_pos.r + 1;
p3_pos.g = p1_pos.g;
p3_pos.b = p1_pos.b + 1;
} else { /* B > R > G */
w1 = 8 - b_weight;
w2 = b_weight - r_weight;
w3 = r_weight - g_weight;
w4 = g_weight;
p2_pos.r = p1_pos.r;
p2_pos.g = p1_pos.g;
p2_pos.b = p1_pos.b + 1;
p3_pos.r = p1_pos.r + 1;
p3_pos.g = p1_pos.g;
p3_pos.b = p1_pos.b + 1;
}
}
} else {
if (r_weight >= b_weight) { /* G > R > B */
w1 = 8 - g_weight;
w2 = g_weight - r_weight;
w3 = r_weight - b_weight;
w4 = b_weight;
p2_pos.r = p1_pos.r;
p2_pos.g = p1_pos.g + 1;
p2_pos.b = p1_pos.b;
p3_pos.r = p1_pos.r + 1;
p3_pos.g = p1_pos.g + 1;
p3_pos.b = p1_pos.b;
} else {
if (g_weight >= b_weight) { /* G > B > R */
w1 = 8 - g_weight;
w2 = g_weight - b_weight;
w3 = b_weight - r_weight;
w4 = r_weight;
p2_pos.r = p1_pos.r;
p2_pos.g = p1_pos.g + 1;
p2_pos.b = p1_pos.b;
p3_pos.r = p1_pos.r;
p3_pos.g = p1_pos.g + 1;
p3_pos.b = p1_pos.b + 1;
} else { /* B > G > R */
w1 = 8 - b_weight;
w2 = b_weight - g_weight;
w3 = g_weight - r_weight;
w4 = r_weight;
p2_pos.r = p1_pos.r;
p2_pos.g = p1_pos.g;
p2_pos.b = p1_pos.b + 1;
p3_pos.r = p1_pos.r;
p3_pos.g = p1_pos.g + 1;
p3_pos.b = p1_pos.b + 1;
}
}
}
/* Work out values */
pos = (interp1089[p1_pos.b] + interp33[p1_pos.g] + p1_pos.r) * 3;
p1_val.r = pTable[pos];
p1_val.g = pTable[pos + 1];
p1_val.b = pTable[pos + 2];
pos = (interp1089[p2_pos.b] + interp33[p2_pos.g] + p2_pos.r) * 3;
p2_val.r = pTable[pos];
p2_val.g = pTable[pos + 1];
p2_val.b = pTable[pos + 2];
pos = (interp1089[p3_pos.b] + interp33[p3_pos.g] + p3_pos.r) * 3;
p3_val.r = pTable[pos];
p3_val.g = pTable[pos + 1];
p3_val.b = pTable[pos + 2];
pos = (interp1089[p4_pos.b] + interp33[p4_pos.g] + p4_pos.r) * 3;
p4_val.r = pTable[pos];
p4_val.g = pTable[pos + 1];
p4_val.b = pTable[pos + 2];
/* Final offsets into interpolation table */
pw1 = &interp256[w1 << 8];
pw2 = &interp256[w2 << 8];
pw3 = &interp256[w3 << 8];
pw4 = &interp256[w4 << 8];
/* And at long last.. final values */
dst[0] = (pw1[p1_val.r] + pw2[p2_val.r] + pw3[p3_val.r] + pw4[p4_val.r]) >> 3;
dst[1] = (pw1[p1_val.g] + pw2[p2_val.g] + pw3[p3_val.g] + pw4[p4_val.g]) >> 3;
dst[0] = (pw1[p1_val.b] + pw2[p2_val.b] + pw3[p3_val.b] + pw4[p4_val.b]) >> 3;
}
#define MAX_JOB_LEN (1844*2730*3+10480) #define MAX_JOB_LEN (1844*2730*3+10480)
static int hiti_read_parse(void *vctx, const void **vjob, int data_fd, int copies) static int hiti_read_parse(void *vctx, const void **vjob, int data_fd, int copies)
@ -905,6 +1081,8 @@ static int hiti_read_parse(void *vctx, const void **vjob, int data_fd, int copie
/* Load up correction data */ /* Load up correction data */
const uint8_t *corrdata = hiti_get_correction_data(ctx); const uint8_t *corrdata = hiti_get_correction_data(ctx);
if (corrdata)
hiti_interp_init();
/* Convert input packed BGR data into YMC planar */ /* Convert input packed BGR data into YMC planar */
{ {
@ -921,21 +1099,23 @@ static int hiti_read_parse(void *vctx, const void **vjob, int data_fd, int copie
uint32_t i; uint32_t i;
for (i = 0 ; i < job->datalen ; i+= 3) { for (i = 0 ; i < job->datalen ; i+= 3) {
uint8_t B, G, R; uint8_t rgb[3];
B = job->databuf[i]; /* Input data is BGR */
G = job->databuf[i+1]; rgb[2] = job->databuf[i];
R = job->databuf[i+2]; rgb[1] = job->databuf[i+1];
rgb[0] = job->databuf[i+2];
if (corrdata) { if (corrdata) {
// XXX if we have a mapping table, // XXX optimize? No need to repeat
// run it through conversion here. // calculation if input repeats.
hiti_interp33_256(rgb, rgb, corrdata);
} }
/* Finally convert to YMC */ /* Finally convert to YMC */
*dstY++ = 255 - B; *dstY++ = 255 - rgb[2];
*dstM++ = 255 - G; *dstM++ = 255 - rgb[1];
*dstC++ = 255 - R; *dstC++ = 255 - rgb[0];
} }
/* Nuke the old BGR buffer and replace it with YMC */ /* Nuke the old BGR buffer and replace it with YMC */
free(job->databuf); free(job->databuf);

BIN
hiti_data/P110_CMPPsi.bin Normal file

Binary file not shown.

BIN
hiti_data/P110_CMSPsi.bin Normal file

Binary file not shown.

BIN
hiti_data/P52x_CCPPri.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCPP1rd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCPP2rd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCPP3rd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCPP4rd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCPPrd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCQP1rd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCQP2rd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCQP3rd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCQP4rd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CCQPrd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CMPPrd.bin Normal file

Binary file not shown.

BIN
hiti_data/P72x_CMQPrd.bin Normal file

Binary file not shown.

BIN
hiti_data/P75x_CCPPri.bin Normal file

Binary file not shown.