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)
|
$(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)\"
|
||||||
|
|
226
backend_hiti.c
226
backend_hiti.c
|
@ -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);
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue