mitsu70x: Parse the CPC data files at runtime!

This commit is contained in:
Solomon Peachy 2016-09-13 20:58:16 -04:00
parent 886c47a55f
commit f8ae72472c
16 changed files with 44 additions and 1537 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2,8 +2,14 @@ There are three sets of files here:
*.lut -- Color Lookup tables
*.raw -- Matte lamination data
*.h -- Data tables derived from *.cpc
*.cpc -- Data tables
All files were directly copied from the data files bundled with the
Windows drivers of the following printers:
Mitsubishi CP-D70DW/D707-DW
Mitsubishi CP-K60DW-S
Mitsubishi CP-D80DW
Kodak 305
Fuji ASK-300
All files were directly copied or derived from the 'cpc' files bundled
with the Windows drivers of the various members of the Mitsubishi CP-D70
family. The header files were generated using the perl script here.

View file

@ -1,120 +0,0 @@
#!/usr/bin/perl -w
##################
# This script converts the D70 family's 'CPC' correction tables into
# C headers for the selphy_print backend.
use strict;
use Text::CSV;
my $csv = Text::CSV->new();
my @rows;
my $fname = $ARGV[0];
$fname =~ s/(.*).cpc/$1/;
open my $fh, "<$fname.cpc" or die "Can't open file: $!";
while (my $row = $csv->getline($fh)) {
push @rows, $row;
}
close $fh;
my $ref = shift(@rows);
my @names = @$ref;
$ref = shift(@rows);
my @lens = @$ref;
my @cols;
for (my $i = 1 ; $i < scalar @names ; $i++) {
my $col = $names[$i];
$col =~ tr/[]()* //d;
$col =~ tr/A-Z/a-z/;
$col =~ s/yb/by/;
$col =~ s/mg$/gm/;
$col =~ s/cr/rc/;
$names[$i] = $col;
$cols[$i] = [ ];
}
if (scalar @names < 20){ # Not present on D70/D707. All printers identical, Can fill in with defaults.
$names[19] = "rolk";
$lens[19] = 13;
}
if (scalar @names < 21){ # Not present on ASK300 or D70/D707. Only some D80 different, can fill in with defaults.
$names[20] = "rev";
$lens[20] = 76;
}
foreach $ref (@rows) {
my @row = @$ref;
for (my $i = 1; $i < scalar(@row) ; $i++) {
push(@{$cols[$i]}, $row[$i]);
}
}
open $fh, ">$fname.h" or die "Can't open file: $!";
print $fh "#include <stdint.h>\n";
print $fh "\n\n";
print $fh "#ifndef CORRDATA_DEF\n";
print $fh "#define CORRDATA_DEF\n";
print $fh "struct mitsu70x_corrdata {\n";
for (my $i = 1 ; $i < scalar(@names) ; $i++) {
my $type = "double";
if ($i <= 6 || $i == 15 || $i == 19) {
$type = "uint16_t";
} elsif ($i == 20) {
$type = "uint32_t";
}
print $fh "\t$type " . $names[$i] . "[$lens[$i]];\n";
}
print $fh "};\n";
print $fh "\n\n";
print $fh "struct mitsu70x_corrdatalens {\n";
for (my $i = 1 ; $i < scalar(@names) ; $i++) {
print $fh "\tsize_t " . $names[$i] . ";\n";
}
print $fh "};\n";
print $fh "\n\n";
print $fh "#endif\n";
print $fh "\n\n";
print $fh "static struct mitsu70x_corrdatalens ${fname}_lengths = {\n";
for (my $i = 1 ; $i < scalar(@names) ; $i++) {
print $fh "\t." . $names[$i] . " = $lens[$i],\n";
}
print $fh "};\n";
print $fh "\n\n";
print $fh "static struct mitsu70x_corrdata ${fname}_data = {\n";
for (my $i = 1 ; $i < scalar(@names) ; $i++) {
if (exists $cols[$i]) {
print $fh "\t." . $names[$i] . " = {";
for (my $j = 0 ; $j < $lens[$i] ; $j++) {
print $fh " $cols[$i][$j],";
}
print $fh " },\n";
}
}
print $fh "};\n";
close $fh;

View file

@ -79,12 +79,14 @@ struct mitsu70x_ctx {
int num_decks;
#ifdef ENABLE_CORRTABLES
struct mitsu70x_corrdata *corrdata;
struct mitsu70x_corrdatalens *corrdatalens;
char *laminatefname;
char *lutfname;
char *cpcfname;
struct CColorConv3D lut;
struct CPCData cpcdata;
char *last_cpcfname;
int raw_format;
#endif
@ -277,70 +279,6 @@ struct mitsu70x_hdr {
uint8_t pad[448];
} __attribute__((packed));
#ifdef ENABLE_CORRTABLES
/* Correction data definitions */
#define CORRDATA_DEF
struct mitsu70x_corrdata {
uint16_t liney[2730];
uint16_t linem[2730];
uint16_t linec[2730];
uint16_t gnmby[256]; // B->Y conversion matrix
uint16_t gnmgm[256]; // G->M conversion matrix
uint16_t gnmrc[256]; // R->C conversion matrix
double fm[256];
double ksp[128];
double ksm[128];
double osp[128];
double osm[128];
double kp[11];
double km[11];
double hk[4];
uint16_t speed[3];
double fh[5]; /* only 4 in length on D70 Normal/Superfine */
double shk[72];
double uh[101];
uint16_t rolk[13]; /* Missing on D70x family */
uint32_t rev[76]; /* Missing on D70x and ASK300 */
};
struct mitsu70x_corrdatalens {
size_t liney;
size_t linem;
size_t linec;
size_t gnmby;
size_t gnmgm;
size_t gnmrc;
size_t fm;
size_t ksp;
size_t ksm;
size_t osp;
size_t osm;
size_t kp;
size_t km;
size_t hk;
size_t speed;
size_t fh;
size_t shk;
size_t uh;
size_t rolk;
size_t rev;
};
#include "D70/CPD70N01.h" // Normal/Fine
#include "D70/CPD70S01.h" // Superfine
#include "D70/CPD70U01.h" // Ultrafine
//#include "D70/CPD80E01.h" // ???
#include "D70/CPD80N01.h" // Normal/Fine
#include "D70/CPD80S01.h" // Superfine
#include "D70/CPD80U01.h" // Ultrafine
#include "D70/ASK300T1.h" // Normal/Fine
#include "D70/ASK300T3.h" // Superfine/Ultrafine
#include "D70/CPS60T01.h" // Normal/Fine
#include "D70/CPS60T03.h" // Superfine/Ultrafine
#include "D70/EK305T01.h" // Normal/Fine
#include "D70/EK305T03.h" // Superfine/Ultrafine
#endif
/* Error dumps, etc */
static char *mitsu70x_mechastatus(uint8_t *sts)
@ -685,28 +623,22 @@ repeat:
ctx->lutfname = CORRTABLE_PATH "/CPD70L01.lut";
if (mhdr.speed == 3) {
ctx->corrdata = &CPD70S01_data;
ctx->corrdatalens = &CPD70S01_lengths;
ctx->cpcfname = CORRTABLE_PATH "/CPD70S01.cpc";
} else if (mhdr.speed == 4) {
ctx->corrdata = &CPD70U01_data;
ctx->corrdatalens = &CPD70U01_lengths;
ctx->cpcfname = CORRTABLE_PATH "/CPD70U01.cpc";
} else {
ctx->corrdata = &CPD70N01_data;
ctx->corrdatalens = &CPD70N01_lengths;
ctx->cpcfname = CORRTABLE_PATH "/CPD70N01.cpc";
}
} else if (ctx->type == P_MITSU_D80) {
ctx->laminatefname = CORRTABLE_PATH "/D80MAT01.raw";
ctx->lutfname = CORRTABLE_PATH "/CPD80L01.lut";
if (mhdr.speed == 3) {
ctx->corrdata = &CPD80S01_data;
ctx->corrdatalens = &CPD80S01_lengths;
ctx->cpcfname = CORRTABLE_PATH "/CPD80S01.cpc";
} else if (mhdr.speed == 4) {
ctx->corrdata = &CPD80U01_data;
ctx->corrdatalens = &CPD80U01_lengths;
ctx->cpcfname = CORRTABLE_PATH "/CPD80U01.cpc";
} else {
ctx->corrdata = &CPD80N01_data;
ctx->corrdatalens = &CPD80N01_lengths;
ctx->cpcfname = CORRTABLE_PATH "/CPD80N01.cpc";
}
// XXX what about CPD80**E**01?
} else if (ctx->type == P_MITSU_K60) {
@ -714,11 +646,9 @@ repeat:
ctx->lutfname = CORRTABLE_PATH "/CPS60L01.lut";
if (mhdr.speed == 3 || mhdr.speed == 4) {
ctx->corrdata = &CPS60T03_data;
ctx->corrdatalens = &CPS60T03_lengths;
ctx->cpcfname = CORRTABLE_PATH "/CPS60T03.cpc";
} else {
ctx->corrdata = &CPS60T01_data;
ctx->corrdatalens = &CPS60T01_lengths;
ctx->cpcfname = CORRTABLE_PATH "/CPS60T01.cpc";
}
} else if (ctx->type == P_KODAK_305) {
@ -726,22 +656,18 @@ repeat:
ctx->lutfname = CORRTABLE_PATH "/EK305L01.lut";
if (mhdr.speed == 3 || mhdr.speed == 4) {
ctx->corrdata = &EK305T03_data;
ctx->corrdatalens = &EK305T03_lengths;
ctx->cpcfname = CORRTABLE_PATH "/EK305T03.cpc";
} else {
ctx->corrdata = &EK305T01_data;
ctx->corrdatalens = &EK305T01_lengths;
ctx->cpcfname = CORRTABLE_PATH "/EK305T03.cpc";
}
} else if (ctx->type == P_FUJI_ASK300) {
ctx->laminatefname = CORRTABLE_PATH "/ASK300M2.raw"; // Same as D70
ctx->lutfname = CORRTABLE_PATH "/CPD70L01.lut"; // XXX guess, driver did not come with external LUT.
ctx->lutfname = CORRTABLE_PATH "/CPD70L01.lut"; // XXX guess, driver did not come with external LUT!
if (mhdr.speed == 3 || mhdr.speed == 4) {
ctx->corrdata = &ASK300T3_data;
ctx->corrdatalens = &ASK300T3_lengths;
ctx->cpcfname = CORRTABLE_PATH "/ASK300T3.cpc";
} else {
ctx->corrdata = &ASK300T1_data;
ctx->corrdatalens = &ASK300T1_lengths;
ctx->cpcfname = CORRTABLE_PATH "/ASK300T1.cpc";
}
}
if (!mhdr.use_lut)
@ -835,8 +761,20 @@ repeat:
// XXX proprietary lib also does gamma+contrast+brightness
}
/* Convert to YMC using corrtables */
/* Load in the CPC file, if needed! */
if (ctx->cpcfname && ctx->cpcfname != ctx->last_cpcfname) {
ctx->last_cpcfname = ctx->cpcfname;
if (load_CPCData(&ctx->cpcdata, ctx->cpcfname)) {
ERROR("Unable to load CPC file '%s'\n", ctx->cpcfname);
return CUPS_BACKEND_CANCEL;
}
}
// XXX INSERT ALGORITHM HERE...
// XXX optionally CreateInkCorrectGammaTable(...)
/* Convert to YMC using corrtables (aka CImageEffect70::DoGamma) */
{
uint32_t r, c;
uint32_t in = 0, out = 0;
@ -849,14 +787,15 @@ repeat:
DEBUG("Running print data through BGR->YMC table (crude)\n");
for(r = 0 ; r < ctx->rows; r++) {
for (c = 0 ; c < ctx->cols ; c++) {
offset_y[out] = cpu_to_be16(ctx->corrdata->gnmby[spoolbuf[in]]);
offset_m[out] = cpu_to_be16(ctx->corrdata->gnmgm[spoolbuf[in + 1]]);
offset_c[out] = cpu_to_be16(ctx->corrdata->gnmrc[spoolbuf[in + 2]]);
offset_y[out] = cpu_to_be16(ctx->cpcdata.GNMby[spoolbuf[in]]);
offset_m[out] = cpu_to_be16(ctx->cpcdata.GNMgm[spoolbuf[in + 1]]);
offset_c[out] = cpu_to_be16(ctx->cpcdata.GNMrc[spoolbuf[in + 2]]);
in += 3;
out++;
}
}
}
// XXX then call CImageEffect70::DoConv(...) to do the final corrections..
/* Move up the pointer */
ctx->datalen += 3*planelen;