Compare commits

...

2 commits

Author SHA1 Message Date
Solomon Peachy f4ebf1ac62 lib2245: Basic handling of the Kodak 6900 IPP data.
IPP data is now parsed and validated, and we can successfully complete
an ip_imageProc() run.  Unfortunately this is still insufficient:

 * Additional fields in IppConf header not yet handled
   (some are recognized/known)
 * Printer requires additonal data to be sent over:
   * 12 additional rows per plane (beyond the size in the print cmd)
   * 9856 bytes of additional info (partial IPP headers plus ???)
   * ip_getMemorySize() needs to take all of this into account
 * Panorama processing adds another layer of fun on top of that.
2024-08-29 12:46:20 -04:00
Solomon Peachy 2414d3c8ac kodak6900: Printer doesn't return a list of legal print sizes
...so don't check.
2024-08-29 12:46:10 -04:00
3 changed files with 170 additions and 54 deletions

View file

@ -46,6 +46,8 @@
#warning "No dynamic loading support!"
#endif
#define NATIVE_KA6900
/* Image processing library function prototypes */
typedef void (*dump_announceFN)(FILE *fp);
@ -654,7 +656,9 @@ struct shinkos6145_ctx {
static const char *s2245_drivermodes(uint8_t val);
static int shinkos2245_get_imagecorr(struct shinkos6145_ctx *ctx, uint8_t options);
#ifdef NATIVE_KA6900
static int kodak6900_get_imagecorr(struct shinkos6145_ctx *ctx, uint8_t options, uint16_t rows);
#endif
static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx);
static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx);
@ -806,9 +810,12 @@ static int shinkos6145_dump_corrdata(struct shinkos6145_ctx *ctx, const char *fn
{
int ret;
#ifdef NATIVE_KA6900
if (ctx->dev.conn->type == P_KODAK_6900) {
ret = kodak6900_get_imagecorr(ctx, 0x0a, 2436); // XXX have to supply something.. this is HQ matte.
} else if (ctx->is_2245) {
} else
#endif
if (ctx->is_2245) {
ret = shinkos2245_get_imagecorr(ctx, 0x0a); // XXX have to supply something.. this is HQ matte.
} else {
ret = shinkos6145_get_imagecorr(ctx);
@ -983,6 +990,8 @@ static int shinkos2245_get_imagecorr(struct shinkos6145_ctx *ctx, uint8_t option
done:
return ret;
}
#ifdef NATIVE_KA6900
static int kodak6900_get_imagecorr(struct shinkos6145_ctx *ctx, uint8_t options, uint16_t rows)
{
struct s2245_imagecorr_req cmd;
@ -1048,6 +1057,7 @@ static int kodak6900_get_imagecorr(struct shinkos6145_ctx *ctx, uint8_t options,
done:
return ret;
}
#endif
static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx)
{
@ -1636,7 +1646,8 @@ static int shinkos6145_main_loop(void *vctx, const void *vjob, int wait_for_retu
ctx->media.items[i].code == job->jp.media)
break;
}
if (i == ctx->media.count) {
if (i == ctx->media.count &&
ctx->dev.conn->type != P_KODAK_6900) {
ERROR("Incorrect media loaded for print!\n");
return CUPS_BACKEND_HOLD;
}
@ -1772,9 +1783,12 @@ top:
/* Get image correction parameters if necessary */
if (updated || !ctx->corrdata || !ctx->corrdatalen) {
#ifdef NATIVE_KA6900
if (ctx->dev.conn->type == P_KODAK_6900) {
ret = kodak6900_get_imagecorr(ctx, oc_mode, job->jp.rows);
} else if (ctx->is_2245) {
} else
#endif
if (ctx->is_2245) {
ret = shinkos2245_get_imagecorr(ctx, oc_mode);
} else {
ret = shinkos6145_get_imagecorr(ctx);
@ -1891,8 +1905,10 @@ top:
print.ipp = 0; /* Not used */
print.method = cpu_to_le32(job->jp.method | SINFONIA_PRINT28_METHOD_ERR_RECOVERY | SINFONIA_PRINT28_METHOD_PREHEAT);
#ifdef NATIVE_KA6900
if (ctx->dev.conn->type == P_KODAK_6900)
print.method |= cpu_to_le32(SINFONIA_PRINT28_METHOD_IPPHDR);
#endif
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&print, sizeof(print),
@ -2100,7 +2116,7 @@ static const struct device_id shinkos6145_devices[] = {
const struct dyesub_backend shinkos6145_backend = {
.name = "Shinko/Sinfonia CHC-S6145/CS2/S2245/S3",
.version = "0.54" " (lib " LIBSINFONIA_VER ")",
.version = "0.55" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = shinkos6145_prefixes,
.devices = shinkos6145_devices,
.cmdline_usage = shinkos6145_cmdline,

View file

@ -646,6 +646,7 @@ struct kodak8810_cutlist {
#define CODE_6x8 0x06
#define CODE_2x6 0x07
#define CODE_6x6 0x08
// XXX 09, 10, 11 om 5/6" sizes?
#define CODE_8x10 0x10
#define CODE_8x12 0x11

View file

@ -2,7 +2,7 @@
libS2245ImageReProcess -- Re-implemented Image Processing library for
the Sinfonia CHC-S2245 printer family
Copyright (c) 2021 Solomon Peachy <pizza@shaftnet.org>
Copyright (c) 2021-2024 Solomon Peachy <pizza@shaftnet.org>
** ** ** ** Do NOT contact Sinfonia about this library! ** ** ** **
@ -39,7 +39,7 @@
*/
#define LIB_VERSION "0.1.2"
#define LIB_VERSION "0.1.3"
#include <stdbool.h>
#include <stdio.h>
@ -83,6 +83,8 @@ bool ip_getMemorySize(uint32_t *szMemory,
//-------------------------------------------------------------------------
// External data formats
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
struct ippHeatCorr {
int32_t tankDivisor[4];
int32_t tankRowInitVals[4];
@ -118,6 +120,8 @@ struct SIppData {
uint8_t sideEdgeCorrectionTable[256];
} __attribute__((packed));
STATIC_ASSERT(sizeof(struct SIppData) == 2524);
struct ippHeader {
char model[16];
char ipp[4];
@ -125,6 +129,8 @@ struct ippHeader {
uint8_t pad_0x15[43];
} __attribute__((packed));
STATIC_ASSERT(sizeof(struct ippHeader) == 64);
struct ippConf {
uint16_t width; /* Overridden at runtime */
uint16_t height; /* Overridden at runtime */
@ -136,19 +142,58 @@ struct ippConf {
uint8_t borderCapable; // 0x02 if we can do 5x7-on-6x8
uint8_t pad_0xb[21];
uint8_t planeOrder[16];
uint8_t pad_0x30[16];
uint8_t pad_0x20[16];
} __attribute__((packed));
STATIC_ASSERT(sizeof(struct ippConf) == 64);
struct ippData {
struct ippHeader header;
struct ippConf conf;
struct SIppData plane_rc;
/*@00*/ struct ippHeader header;
/*@40*/ struct ippConf conf;
/*@80*/ struct SIppData plane_rc;
struct SIppData plane_gm;
struct SIppData plane_by;
struct SIppData plane_oc;
// Can have up to 16 planes, think about this.
} __attribute__((packed));
STATIC_ASSERT(sizeof(struct ippData) == 10224);
struct ippConfKA {
uint16_t width; /* Overridden at runtime */
uint16_t height; /* Overridden at runtime */
uint16_t headWidth; // Always 1920
uint8_t planes; // 3 or 4, can be up to 16!
uint8_t printmode; // Corresponds to corrdata_req field 1
uint8_t corrections1; // Corresponds to corrdata_req field 2
uint8_t corrections2; // B0,B1,B2
uint8_t borderCapable; // 0x02 if we can do 5x7-on-6x8
uint8_t pad_0xb[21];
uint8_t planeOrder[16];
uint8_t num_panels; /* 0x01-0x03 ? */
uint8_t unk_0x21; /* 0x06 in IPP, 0x00 or 0x01 in cmd */
uint16_t unk_0x22; /* 0x0032 */
uint16_t max_panel_overlap; /* 0x0258 == 600d */
uint16_t panel_rows[3]; /* */
uint16_t lam_rows[3]; /* */
uint16_t unk_0x42[31];
} __attribute__((packed));
STATIC_ASSERT(sizeof(struct ippConfKA) == 128); /* KA6900 */
struct ippDataKA {
/*@00*/ struct ippHeader header;
/*@40*/ struct ippConfKA conf;
/*@c0*/ struct SIppData plane_rc;
struct SIppData plane_gm;
struct SIppData plane_by;
struct SIppData plane_oc;
uint8_t pad[7680]; /* @ 10288 */
} __attribute__((packed));
STATIC_ASSERT(sizeof(struct ippDataKA) == 17968);
#undef STATIC_ASSERT
//-------------------------------------------------------------------------
// Private Structures
@ -173,14 +218,15 @@ struct CHeatCorrProc {
struct CIppMng {
struct ippHeader header;
struct ippConf conf;
struct ippConfKA conf;
struct SIppData *ippData;
uint8_t initialized;
uint8_t ka6900;
};
struct CImageProc {
struct CIppMng *ippMng;
struct ippConf conf;
struct ippConfKA conf;
struct SIppData planeIPPdata;
uint32_t pixelsOCG; // width*height*3
uint32_t pixelsOCM; // width*height*4
@ -228,13 +274,6 @@ struct pic_data {
uint8_t bytes_pp;
};
// Data format Sanity checks
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
STATIC_ASSERT(sizeof(struct ippData) == 10224);
#undef STATIC_ASSERT
//-------------------------------------------------------------------------
// Private data declarations
@ -257,30 +296,47 @@ static void CIppMng_Cleanup(struct CIppMng *this)
}
static const char s2245HeaderModel[] = "CHC-S2245 ";
static const char s2245IppStr[] = "IPP=";
static const char ka6900HeaderModel[] = "KA6900 ";
static const char ippStr[] = "IPP=";
static bool CIppMng_CheckHeader(struct CIppMng *this, struct ippData *ippData)
static bool CIppMng_CheckHeader(struct CIppMng *this, void *ippData)
{
memcpy(&this->header, &ippData->header, sizeof(this->header));
memcpy(&this->header, ippData, sizeof(this->header));
if (memcmp(this->header.model, s2245HeaderModel, 16))
return 0;
if (memcmp(this->header.ipp, s2245IppStr, 4))
return 0;
if (this->header.version != 0x3)
if (this->ka6900) {
if (memcmp(this->header.model, ka6900HeaderModel, 16))
return 0;
} else {
if (memcmp(this->header.model, s2245HeaderModel, 16))
return 0;
}
if (memcmp(this->header.ipp, ippStr, 4))
return 0;
if (this->ka6900) {
if (this->header.version != 0x7)
return 0;
} else {
if (this->header.version != 0x3)
return 0;
}
return 1;
}
static bool CIppMng_CheckConf(struct CIppMng *this, struct ippData *ippData)
static bool CIppMng_CheckConf(struct CIppMng *this, void *ippData)
{
uint8_t tmp;
#ifndef USE_EXTRA_STUFF
memcpy(&this->conf, &ippData->conf, sizeof(this->conf));
if (this->ka6900) {
struct ippDataKA *data = ippData;
memcpy(&this->conf, &data->conf, sizeof(this->conf));
} else {
struct ippData *data = ippData;
memcpy(&this->conf, &data->conf, sizeof(this->conf));
}
#else
(void)ippData;
#endif
@ -298,40 +354,62 @@ static bool CIppMng_CheckConf(struct CIppMng *this, struct ippData *ippData)
if (tmp > 1)
return 0;
// XXX anything else for KA6900?
return 1;
}
static bool CIppMng_CheckIpp(struct CIppMng *this, struct ippData *ippData)
static bool CIppMng_CheckIpp(struct CIppMng *this, void *ippData)
{
bool rval;
rval = CIppMng_CheckHeader(this, ippData);
if (rval)
rval = CIppMng_CheckConf(this, ippData);
return rval;
}
static bool CIppMng_SetConf(struct CIppMng *this, struct ippData *ippData,
static bool CIppMng_SetConf(struct CIppMng *this, void *ippData,
uint16_t width, uint16_t height)
{
memcpy(&this->conf, &ippData->conf, sizeof(this->conf));
if (!memcmp(ippData, ka6900HeaderModel, sizeof(ka6900HeaderModel)-1))
this->ka6900 = 1;
if (!width || !height)
return 0;
if (this->ka6900) {
struct ippDataKA *data = ippData;
memcpy(&this->conf, &data->conf, sizeof(this->conf));
} else {
struct ippData *data = ippData;
memcpy(&this->conf, &data->conf, sizeof(this->conf));
memset(&this->conf + sizeof(data->conf), 0, sizeof(this->conf) - sizeof(data->conf));
}
this->conf.width = width;
this->conf.height = height;
#if (__BYTE_ORDER != __LITTLE_ENDIAN)
this->conf.headWidth = le16_to_cpu(this->conf.headWidth);
#endif
if (this->ka6900) {
this->conf.max_panel_overlap = le16_to_cpu(this->conf.max_panel_overlap);
this->conf.unk_0x22 = le16_to_cpu(this->conf.unk_0x22); // XXX
for (int i = 0 ; i < 3 ; i++) {
this->conf.panel_rows[i] = le16_to_cpu(this->conf.panel_rows[i]);
this->conf.lam_rows[i] = le16_to_cpu(this->conf.lam_rows[i]);
}
// XXX additional fields.
}
return 1;
}
static bool CIppMng_SetData(struct CIppMng *this, struct ippData *ippData)
static bool CIppMng_SetData(struct CIppMng *this, void *ippData)
{
if (this->ippData)
@ -344,19 +422,26 @@ static bool CIppMng_SetData(struct CIppMng *this, struct ippData *ippData)
if (!this->ippData)
return 0;
memcpy(this->ippData, &ippData->plane_rc, this->conf.planes * sizeof(*this->ippData));
if (this->ka6900) {
struct ippDataKA *data = ippData;
memcpy(this->ippData, &data->plane_rc, this->conf.planes * sizeof(*this->ippData));
} else {
struct ippData *data = ippData;
memcpy(this->ippData, &data->plane_rc, this->conf.planes * sizeof(*this->ippData));
}
#if (__BYTE_ORDER != __LITTLE_ENDIAN)
#define SWAP16(__x) __x = le16_to_cpu(ippBlock->__x)
#define SWAP32(__x) __x = le32_to_cpu(ippBlock->__x)
#define swap16(__x) ippBlock->__x = le16_to_cpu(ippBlock->__x)
#define swap32(__x) ippBlock->__x = le32_to_cpu(ippBlock->__x)
int i, j;
for (i = 0 ; i < this->conf.planes ; i++) {
struct SIppData *ippBlock = &ippData->plane_rc + i;
struct SIppData *ippBlock = &this->ippData[i];
swap16(field_0x0);
swap16(field_0x2);
swap16(maxLineSum);
swap16(minRowSum);
swap16(maxLineCorrecitonFactor);
swap16(maxLineCorrectionFactor);
swap16(nextWeight);
swap16(prevWeight);
swap16(mtfPreCalcCutoff);
@ -365,7 +450,7 @@ static bool CIppMng_SetData(struct CIppMng *this, struct ippData *ippData)
swap16(pulseExMap[j]);
swap16(heatCorrectionMinusTable[j]);
swap16(heatCorrectionPlusTable[j]);
swap16(lineCorrection);
swap16(lineCorrection[j]);
}
for (j = 0 ; j < 4 ; j++) {
swap32(heatCorrection.tankDivisor[j]);
@ -375,20 +460,20 @@ static bool CIppMng_SetData(struct CIppMng *this, struct ippData *ippData)
for (j = 0 ; j < 5 ; j++) {
swap32(heatCorrection.tankCoef[j]);
}
swap32(tankPlusParam);
swap32(tankMinusParam);
swap32(tankPlusLimit);
swap32(tankMinusLimit);
swap32(useHeatCorrection);
swap32(heatCorrection.tankPlusParam);
swap32(heatCorrection.tankMinusParam);
swap32(heatCorrection.tankPlusLimit);
swap32(heatCorrection.tankMinusLimit);
swap32(heatCorrection.useHeatCorrection);
}
#undef SWAP16
#undef SWAP32
#undef swap16
#undef swap32
#endif
return 1;
}
static bool CIppMng_SetIPP(struct CIppMng *this, struct ippData *ippData,
static bool CIppMng_SetIPP(struct CIppMng *this, void *ippData,
uint16_t width, uint16_t height)
{
@ -418,7 +503,7 @@ static bool CIppMng_GetNumOfColor(struct CIppMng *this, uint8_t *planesOCG, uint
return 1;
}
static bool CIppMng_GetIppConf(struct CIppMng *this, struct ippConf *conf,
static bool CIppMng_GetIppConf(struct CIppMng *this, struct ippConfKA *conf,
uint8_t *planesOCG, uint8_t *planesOCM)
{
@ -1707,22 +1792,36 @@ bool ip_getMemorySize(uint32_t *szMemory,
uint16_t width, uint16_t height,
void *srcIpp)
{
struct ippData *ippData;
struct CIppMng ippMng;
uint32_t pixels;
if (!width || !height || !szMemory || !srcIpp)
return 0;
ippData = srcIpp;
CIppMng_Init(&ippMng);
if ((ippData->conf.borderCapable == 0x02) &&
#ifdef USE_EXTRA_STUFF
int rval = CIppMng_SetConf(&ippMng, srcIpp, width, height);
#else
int rval = CIppMng_CheckIpp(&ippMng, srcIpp);
#endif
if (!rval) {
CIppMng_Cleanup(&ippMng);
return 0;
}
// XXX KA6900 needs this to be rewritten heavily.
if ((ippMng.conf.borderCapable == 0x02) &&
(width == 1548) && (height == 2140)) {
pixels = 2434*1844; /* ie 8x6 */
} else {
pixels = height * width;
}
*szMemory = pixels * 2 * ippData->conf.planes;
*szMemory = pixels * 2 * ippMng.conf.planes;
CIppMng_Cleanup(&ippMng);
if (!*szMemory)
return 0;