hiti: Port over inteprolation algorithm, and include binary data files.
This commit is contained in:
parent
57bc5bfa5c
commit
27e96d4da8
4
Makefile
4
Makefile
|
@ -102,6 +102,8 @@ install:
|
|||
$(INSTALL) -o root -m 700 $(EXEC_NAME) $(CUPS_BACKEND_DIR)/$(BACKEND_NAME)
|
||||
$(MKDIR) -p $(CUPS_DATA_DIR)/usb
|
||||
$(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:
|
||||
$(RM) $(EXEC_NAME) $(BACKENDS) $(SOURCES:.c=.o) lib70x/*o lib6145/*o
|
||||
|
@ -116,4 +118,4 @@ release: clean
|
|||
# Backend-specific joy:
|
||||
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_shinko%.o: backend_shinko.h
|
||||
backend_hiti.o: CPPFLAGS += -DCORRTABLE_PATH=\"$(BACKEND_DATA_DIR)\"
|
||||
|
|
226
backend_hiti.c
226
backend_hiti.c
|
@ -31,6 +31,14 @@
|
|||
|
||||
#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 */
|
||||
struct hiti_cmd {
|
||||
uint8_t hdr; /* 0xa5 */
|
||||
|
@ -701,61 +709,61 @@ static const uint8_t *hiti_get_correction_data(struct hiti_ctx *ctx)
|
|||
switch (ctx->type)
|
||||
{
|
||||
case P_HITI_52X:
|
||||
fname = "P52x_CCPPri.bin";
|
||||
fname = CORRTABLE_PATH "/P52x_CCPPri.bin";
|
||||
break;
|
||||
case P_HITI_72X:
|
||||
if (!mediatype) {
|
||||
if (mode) {
|
||||
fname = "P72x_CMQPrd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CMQPrd.bin";
|
||||
break;
|
||||
} else {
|
||||
fname = "P72x_CMPPrd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CMPPrd.bin";
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (mode) {
|
||||
switch(mediaver) {
|
||||
case 0:
|
||||
fname = "P72x_CCQPrd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCQPrd.bin";
|
||||
break;
|
||||
case 1:
|
||||
fname = "P72x_CCQP1rd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCQP1rd.bin";
|
||||
break;
|
||||
case 2:
|
||||
fname = "P72x_CCQP2rd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCQP2rd.bin";
|
||||
break;
|
||||
case 3:
|
||||
fname = "P72x_CCQP3rd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCQP3rd.bin";
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
fname = "P72x_CCQP4rd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCQP4rd.bin";
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch(mediaver) {
|
||||
case 0:
|
||||
fname = "P72x_CCPPrd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCPPrd.bin";
|
||||
break;
|
||||
case 1:
|
||||
fname = "P72x_CCPP1rd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCPP1rd.bin";
|
||||
break;
|
||||
case 2:
|
||||
fname = "P72x_CCPP2rd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCPP2rd.bin";
|
||||
break;
|
||||
case 3:
|
||||
fname = "P72x_CCPP3rd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCPP3rd.bin";
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
fname = "P72x_CCPP4rd.bin";
|
||||
fname = CORRTABLE_PATH "/P72x_CCPP4rd.bin";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case P_HITI_75X:
|
||||
fname = "P75x_CCPPri.bin";
|
||||
fname = CORRTABLE_PATH "/P75x_CCPPri.bin";
|
||||
break;
|
||||
default:
|
||||
fname = NULL;
|
||||
|
@ -784,6 +792,174 @@ static const uint8_t *hiti_get_correction_data(struct hiti_ctx *ctx)
|
|||
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)
|
||||
|
||||
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 */
|
||||
const uint8_t *corrdata = hiti_get_correction_data(ctx);
|
||||
if (corrdata)
|
||||
hiti_interp_init();
|
||||
|
||||
/* 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;
|
||||
|
||||
for (i = 0 ; i < job->datalen ; i+= 3) {
|
||||
uint8_t B, G, R;
|
||||
uint8_t rgb[3];
|
||||
|
||||
B = job->databuf[i];
|
||||
G = job->databuf[i+1];
|
||||
R = job->databuf[i+2];
|
||||
/* Input data is BGR */
|
||||
rgb[2] = job->databuf[i];
|
||||
rgb[1] = job->databuf[i+1];
|
||||
rgb[0] = job->databuf[i+2];
|
||||
|
||||
if (corrdata) {
|
||||
// XXX if we have a mapping table,
|
||||
// run it through conversion here.
|
||||
// XXX optimize? No need to repeat
|
||||
// calculation if input repeats.
|
||||
hiti_interp33_256(rgb, rgb, corrdata);
|
||||
}
|
||||
|
||||
/* Finally convert to YMC */
|
||||
*dstY++ = 255 - B;
|
||||
*dstM++ = 255 - G;
|
||||
*dstC++ = 255 - R;
|
||||
*dstY++ = 255 - rgb[2];
|
||||
*dstM++ = 255 - rgb[1];
|
||||
*dstC++ = 255 - rgb[0];
|
||||
}
|
||||
/* Nuke the old BGR buffer and replace it with YMC */
|
||||
free(job->databuf);
|
||||
|
|
BIN
hiti_data/P110_CMPPsi.bin
Normal file
BIN
hiti_data/P110_CMPPsi.bin
Normal file
Binary file not shown.
BIN
hiti_data/P110_CMSPsi.bin
Normal file
BIN
hiti_data/P110_CMSPsi.bin
Normal file
Binary file not shown.
BIN
hiti_data/P52x_CCPPri.bin
Normal file
BIN
hiti_data/P52x_CCPPri.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCPP1rd.bin
Normal file
BIN
hiti_data/P72x_CCPP1rd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCPP2rd.bin
Normal file
BIN
hiti_data/P72x_CCPP2rd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCPP3rd.bin
Normal file
BIN
hiti_data/P72x_CCPP3rd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCPP4rd.bin
Normal file
BIN
hiti_data/P72x_CCPP4rd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCPPrd.bin
Normal file
BIN
hiti_data/P72x_CCPPrd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCQP1rd.bin
Normal file
BIN
hiti_data/P72x_CCQP1rd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCQP2rd.bin
Normal file
BIN
hiti_data/P72x_CCQP2rd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCQP3rd.bin
Normal file
BIN
hiti_data/P72x_CCQP3rd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCQP4rd.bin
Normal file
BIN
hiti_data/P72x_CCQP4rd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CCQPrd.bin
Normal file
BIN
hiti_data/P72x_CCQPrd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CMPPrd.bin
Normal file
BIN
hiti_data/P72x_CMPPrd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P72x_CMQPrd.bin
Normal file
BIN
hiti_data/P72x_CMQPrd.bin
Normal file
Binary file not shown.
BIN
hiti_data/P75x_CCPPri.bin
Normal file
BIN
hiti_data/P75x_CCPPri.bin
Normal file
Binary file not shown.
Loading…
Reference in a new issue