selphy_print/lib6145/libS6145ImageReProcess.c

1790 lines
56 KiB
C

/*
libS6145ImageReProcess -- Re-implemented Image Processing library for
the Sinfonia CHC-S6145 printer family
Copyright (c) 2015-2023 Solomon Peachy <pizza@shaftnet.org>
** ** ** ** Do NOT contact Sinfonia about this library! ** ** ** **
This is intended to be a drop-in replacement for Sinfonia's proprietary
libS6145ImageProcess library, which is necessary in order to utilize
their CHC-S6145 printer family.
Sinfonia Inc was not involved in the creation of this library, and
is not responsible in any way for the library or any deficiencies in
its output. They will provide no support if it is used.
If you have the appropriate permission fron Sinfonia, we recommend
you use their official libS6145ImageProcess library instead, as it
will generate the highest quality output. However, it is only
available for x86/x86_64 targets on Linux. Please contact your local
Sinfonia distributor to obtain the official library.
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: GPL-3.0+
*/
//#define S6145_UNUSED
#define LIB_VERSION "0.5.3"
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//-------------------------------------------------------------------------
// Structures
struct tankParam {
int32_t trdTankSize;
int32_t sndTankSize;
int32_t fstTankSize;
int32_t trdTankIniEnergy;
int32_t sndTankIniEnergy;
int32_t fstTankIniEnergy;
int32_t trdTrdConductivity;
int32_t sndSndConductivity;
int32_t fstFstConductivity;
int32_t outTrdConductivity;
int32_t trdSndConductivity;
int32_t sndFstConductivity;
int32_t fstOutConductivity;
int32_t plusMaxEnergy;
int32_t minusMaxEnergy;
int32_t plusMaxEnergyPreRead;
int32_t minusMaxEnergyPreRead;
int32_t preReadLevelDiff;
int32_t rsvd[14]; // null or unused?
} __attribute__((packed));
struct imageCorrParam {
uint16_t pulseTransTable_Y[256]; // @0
uint16_t pulseTransTable_M[256]; // @512
uint16_t pulseTransTable_C[256]; // @1024
uint16_t pulseTransTable_O[256]; // @1536
uint16_t lineHistCoefTable_Y[256]; // @2048
uint16_t lineHistCoefTable_M[256]; // @2560
uint16_t lineHistCoefTable_C[256]; // @3072
uint16_t lineHistCoefTable_O[256]; // @3584
uint16_t lineCorrectEnvA_Y; // @4096
uint16_t lineCorrectEnvA_M; // @4098
uint16_t lineCorrectEnvA_C; // @4100
uint16_t lineCorrectEnvA_O; // @4102
uint16_t lineCorrectEnvB_Y; // @4104
uint16_t lineCorrectEnvB_M; // @4106
uint16_t lineCorrectEnvB_C; // @4108
uint16_t lineCorrectEnvB_O; // @4110
uint16_t lineCorrectEnvC_Y; // @4112
uint16_t lineCorrectEnvC_M; // @4114
uint16_t lineCorrectEnvC_C; // @4116
uint16_t lineCorrectEnvC_O; // @4118
uint32_t lineCorrectSlice_Y; // @4120
uint32_t lineCorrectSlice_M; // @4124
uint32_t lineCorrectSlice_C; // @4128
uint32_t lineCorrectSlice_O; // @4132
uint32_t lineCorrectSlice1Line_Y; // @4136
uint32_t lineCorrectSlice1Line_M; // @4140
uint32_t lineCorrectSlice1Line_C; // @4144
uint32_t lineCorrectSlice1Line_O; // @4148
int32_t lineCorrectPulseMax_Y; // @4152
int32_t lineCorrectPulseMax_M; // @4156
int32_t lineCorrectPulseMax_C; // @4160
int32_t lineCorrectPulseMax_O; // @4164
struct tankParam tableTankParam_Y; // @4168
struct tankParam tableTankParam_M; // @4296
struct tankParam tableTankParam_C; // @4424
struct tankParam tableTankParam_O; // @4552
uint16_t tankPlusMaxEnergyTable_Y[256]; // @4680
uint16_t tankPlusMaxEnergyTable_M[256]; // @5192
uint16_t tankPlusMaxEnergyTable_C[256]; // @5704
uint16_t tankPlusMaxEnergyTable_O[256]; // @6216
uint16_t tankMinusMaxEnergy_Y[256]; // @6728
uint16_t tankMinusMaxEnergy_M[256]; // @7240
uint16_t tankMinusMaxEnergy_C[256]; // @7752
uint16_t tankMinusMaxEnergy_O[256]; // @8264
uint16_t printMaxPulse_Y; // @8776
uint16_t printMaxPulse_M; // @8778
uint16_t printMaxPulse_C; // @8780
uint16_t printMaxPulse_O; // @8782
uint16_t mtfWeightH_Y; // @8784
uint16_t mtfWeightH_M; // @8786
uint16_t mtfWeightH_C; // @8788
uint16_t mtfWeightH_O; // @8790
uint16_t mtfWeightV_Y; // @8792
uint16_t mtfWeightV_M; // @8794
uint16_t mtfWeightV_C; // @8796
uint16_t mtfWeightV_O; // @8798
uint16_t mtfSlice_Y; // @8800
uint16_t mtfSlice_M; // @8802
uint16_t mtfSlice_C; // @8804
uint16_t mtfSlice_O; // @8806
uint16_t val_1; // @8808 // 1 enables linepreprintprocess
uint16_t val_2; // @8810 // 1 enables ctankprocess
uint16_t printOpLevel; // @8812
uint16_t matteMode; // @8814 // 1 for matte
uint16_t randomBase[4]; // @8816 [use lower byte of each]
uint16_t matteSize; // @8824
uint16_t matteGloss; // @8826
uint16_t matteDeglossBlk; // @8828
uint16_t matteDeglossWht; // @8830
int16_t printSideOffset; // @8832
uint16_t headDots; // @8834 [always 0x0780, ie 1920. print width
uint16_t SideEdgeCoefTable[128]; // @8836
uint8_t rsvd_2[256]; // @9092, null?
uint16_t SideEdgeLvCoefTable[256]; // @9348
uint8_t rsvd_3[2572]; // @9860, null?
/* User-supplied data */
uint16_t width; // @12432
uint16_t height; // @12434
uint8_t pad[3948]; // @12436, null.
} __attribute__((packed)); /* 16384 bytes */
//-------------------------------------------------------------------------
// Function declarations
#define ASSERT(__COND, __TXT) if ((!__COND)) { printf(__TXT " @ %d\n", __LINE__); exit(1); }
struct lib6145_ctx; /* Forward-declaration */
static void SetTableData(const void *src, void *dest, uint16_t words);
static int32_t CheckPrintParam(struct imageCorrParam *corrdata);
static uint16_t LinePrintCalcBit(uint16_t val);
static void GetInfo(struct lib6145_ctx *ctx);
static void Global_Init(struct lib6145_ctx *ctx);
static void SetTableColor(struct lib6145_ctx *ctx, uint8_t plane);
static void LinePrintPreProcess(struct lib6145_ctx *ctx);
static void CTankResetParameter(struct lib6145_ctx *ctx, const int32_t *params);
static void CTankResetTank(struct lib6145_ctx *ctx);
static void PagePrintPreProcess(struct lib6145_ctx *ctx);
static void PagePrintProcess(struct lib6145_ctx *ctx);
static void CTankProcess(struct lib6145_ctx *ctx);
static void SendData(struct lib6145_ctx *ctx);
static void PulseTrans(struct lib6145_ctx *ctx);
static void CTankUpdateTankVolumeInterDot(struct lib6145_ctx *ctx, uint8_t tank);
static void CTankUpdateTankVolumeInterRay(struct lib6145_ctx *ctx);
static void CTankHoseiPreread(struct lib6145_ctx *ctx);
static void CTankHosei(struct lib6145_ctx *ctx);
static void LineCorrection(struct lib6145_ctx *ctx);
static void PulseTransPreReadOP(struct lib6145_ctx *ctx);
static void PulseTransPreReadYMC(struct lib6145_ctx *ctx);
static void CTankProcessPreRead(struct lib6145_ctx *ctx);
static void CTankProcessPreReadDummy(struct lib6145_ctx *ctx);
static void RecieveDataOP_GLOSS(struct lib6145_ctx *ctx);
static void RecieveDataYMC(struct lib6145_ctx *ctx);
static void RecieveDataOP_MATTE(struct lib6145_ctx *ctx);
#ifdef S6145_UNUSED
static void SetTable(struct lib6145_ctx *ctx);
static void ImageLevelAddition(struct lib6145_ctx *ctx);
static void ImageLevelAdditionEx(struct lib6145_ctx *ctx, uint32_t *a1, uint32_t a2, int32_t a3);
static void RecieveDataOP_Post(struct lib6145_ctx *ctx);
static void RecieveDataYMC_Post(struct lib6145_ctx *ctx);
static void RecieveDataOPLevel_Post(struct lib6145_ctx *ctx);
static void RecieveDataOPMatte_Post(struct lib6145_ctx *ctx);
static void SideEdgeCorrection(struct lib6145_ctx *ctx);
static void LeadEdgeCorrection(struct lib6145_ctx *ctx);
#endif
//-------------------------------------------------------------------------
// Endian Manipulation macros
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
#define le16_to_cpu(__x) __x
#define le32_to_cpu(__x) __x
#define be16_to_cpu(__x) __builtin_bswap16(__x)
#define be32_to_cpu(__x) __builtin_bswap32(__x)
#else
#define le16_to_cpu(__x) __builtin_bswap16(__x)
#define le32_to_cpu(__x) __builtin_bswap32(__x)
#define be16_to_cpu(__x) __x
#define be32_to_cpu(__x) __x
#endif
#define cpu_to_le16 le16_to_cpu
#define cpu_to_le32 le32_to_cpu
#define cpu_to_be16 be16_to_cpu
#define cpu_to_be32 be32_to_cpu
//-------------------------------------------------------------------------
// Data declarations
#define BUF_SIZE 2048
#define TANK_SIZE 2052
#define MAX_PULSE 1023
#define MIN_ROWS 100
#define MIN_COLS 100
#define MAX_ROWS 2492
#define MAX_COLS 1844
/* global context */
struct lib6145_ctx {
void (*pfRecieveData)(struct lib6145_ctx *ctx);
void (*pfPulseTransPreRead)(struct lib6145_ctx *ctx);
void (*pfTankProcessPreRead)(struct lib6145_ctx *ctx);
uint8_t pusInLineBuf0[BUF_SIZE];
uint8_t pusInLineBuf1[BUF_SIZE];
uint8_t pusInLineBuf2[BUF_SIZE];
uint8_t pusInLineBuf3[BUF_SIZE];
uint8_t pusInLineBuf4[BUF_SIZE];
uint8_t pusInLineBuf5[BUF_SIZE];
uint8_t pusInLineBuf6[BUF_SIZE];
uint8_t pusInLineBuf7[BUF_SIZE];
uint8_t pusInLineBuf8[BUF_SIZE];
uint8_t pusInLineBuf9[BUF_SIZE];
uint8_t pusInLineBufA[BUF_SIZE];
uint16_t pusOutLineBuf1[BUF_SIZE];
uint16_t *pusOutLineBufTab[2]; // XXX actually [1]
uint8_t *pusPreReadLineBufTab[12]; // XXX actually [11]
uint8_t *pusPulseTransLineBufTab[4];
uint16_t pusPreReadOutLineBuf[BUF_SIZE];
int16_t psMtfPreCalcTable[512];
uint16_t pusTankMinusMaxEnegyTable[256];
uint16_t pusTankPlusMaxEnegyTable[256];
uint16_t pusPulseTransTable[256];
uint16_t pusLineHistCoefTable[256];
int32_t piTankParam[128]; // should be struct tankParam[4]
int32_t pulRandomTable[32]; // should be u32
uint8_t *pucInputImageBuf;
struct imageCorrParam *pSPrintParam;
uint16_t *pusOutputImageBuf;
uint8_t ucRandomBaseLevel[4];
int16_t sPrintSideOffset;
uint16_t usHeadDots;
int32_t iLineCorrectPulse;
uint32_t uiMtfSlice; // really u16?
uint32_t uiMtfWeightV; // really u16?
uint32_t uiMtfWeightH; // really u16?
uint16_t usLineCorrect_Env_A;
uint16_t usLineCorrect_Env_B;
uint16_t usLineCorrect_Env_C;
uint32_t uiOutputImageIndex;
uint32_t uiInputImageIndex;
int32_t iMaxPulseValue;
uint32_t uiMaxPulseBit;
uint16_t usPrintMaxPulse;
uint16_t usPrintOpLevel;
uint16_t usMatteSize;
uint32_t uiLineCorrectSlice;
uint32_t uiLineCorrectSlice1Line;
uint16_t usPrintSizeHeight;
uint32_t uiLineCorrectBase1Line;
uint32_t uiLineCorrectSum;
uint32_t uiLineCorrectBase;
int16_t sCorrectSw;
uint16_t usMatteMode;
int32_t iLineCorrectPulseMax;
uint16_t usSheetSizeWidth;
uint16_t usPrintSizeWidth;
uint16_t usPrintColor;
uint32_t uiSendToHeadCounter;
uint32_t uiLineCopyCounter;
/* Not sure the significance of 'm_' */
int32_t m_piTrdTankArray[TANK_SIZE];
int32_t m_piFstTankArray[TANK_SIZE];
int32_t m_piSndTankArray[TANK_SIZE];
int32_t m_iTrdTankSize;
int32_t m_iTrdSndConductivity;
int32_t m_iSndTankSize;
int32_t m_iTankKeisuSndFstDivFst;
int32_t m_iSndSndConductivity;
int32_t m_iTrdTrdConductivity;
int32_t m_iTankKeisuTrdSndDivSnd;
int32_t m_iTankKeisuTrdSndDivTrd;
int32_t m_iSndFstConductivity;
int32_t m_iFstTankSize;
int32_t m_iTrdTankIniEnergy;
int32_t m_iFstTankIniEnergy;
int32_t m_iTankKeisuSndFstDivSnd;
int32_t m_iSndTankIniEnergy;
int32_t m_iPreReadLevelDiff;
int32_t m_iMinusMaxEnergyPreRead;
int32_t m_iOutTrdConductivity;
int32_t m_iFstOutConductivity;
int32_t m_iFstFstConductivity;
int32_t m_iTankKeisuFstOutDivFst;
int32_t m_iTankKeisuOutTrdDivTrd;
#ifdef S6145_UNUSED
void (*pfRecieveData_Post)(struct lib6145_ctx *ctx); /* all users are no-ops */
/* Set but never referenced */
uint32_t uiDataTransCounter;
uint32_t uiTudenLineCounter;
/* Only ever set to 0 */
uint16_t usPrintDummyLevel;
uint16_t usPrintDummyLine;
uint16_t usRearDummyPrintLine;
uint16_t usRearDeleteLine;
/* Appear unused */
uint16_t usCancelCheckLinesForPRec;
uint16_t usPrintSizeLHeight;
uint16_t usPrintSizeLWidth;
uint16_t pusSideEdgeLvCoefTable[256];
uint16_t pusSideEdgeCoefTable[128];
int32_t iLeadEdgeCorrectPulse;
int32_t m_iMinusMaxEnergy;
int32_t m_iPlusMaxEnergy;
int32_t m_iPlusMaxEnergyPreRead;
uint16_t usCenterHeadToColSen;
uint16_t usThearmEnv;
uint16_t usThearmHead;
uint16_t usMatteGloss;
uint16_t usMatteDeglossBlk;
uint16_t usMatteDeglossWht;
uint16_t usPrintOffsetWidth;
uint16_t usCancelCheckDotsForPRec;
uint32_t uiOffsetCancelCheckPRec;
uint32_t uiLevelAveCounter;
uint32_t uiLevelAveCounter2;
uint32_t uiLevelAveAddtion;
uint32_t uiLevelAveAddtion2;
uint32_t uiDummyPrintCounter;
uint16_t usRearDummyPrintLevel;
uint16_t usLastPrintSizeHeight;
uint16_t usLastPrintSizeWidth;
uint16_t usLastSheetSizeWidth;
uint16_t *pusLamiCompInLineBufTab[4];
uint16_t pusOutLineBuf2[BUF_SIZE];
#endif
};
/* **************************** */
int ImageAvrCalc(const uint8_t *input, uint16_t cols, uint16_t rows, uint8_t *avg)
{
uint64_t sum;
uint32_t offset;
uint32_t planesize;
uint32_t j;
uint8_t plane;
if ( !input )
return 1;
if ( !avg )
return 4;
if ( cols <= MIN_COLS || cols > MAX_COLS )
return 2;
if ( rows <= MIN_ROWS || rows > MAX_ROWS )
return 3;
planesize = rows * cols;
offset = 0;
for ( plane = 0; plane < 3; plane++ )
{
sum = 0;
for ( j = 0; j < planesize; ++j )
sum += input[offset++];
avg[plane] = sum / planesize;
}
return 0;
}
void dump_announce(FILE *fp)
{
fprintf(fp, "INFO: libS6145ImageReProcess version '%s'\n", LIB_VERSION);
fprintf(fp, "INFO: Copyright (c) 2015-2020 Solomon Peachy\n");
fprintf(fp, "INFO: This free software comes with ABSOLUTELY NO WARRANTY!\n");
fprintf(fp, "INFO: Licensed under the GNU GPLv3.\n");
fprintf(fp, "INFO: *** This code is NOT supported or endorsed by Sinfonia! ***\n");
}
int ImageProcessing(unsigned char *in, unsigned short *out, void *corrdata)
{
uint8_t i;
struct lib6145_ctx *ctx;
if (!in)
return 1;
if (!out)
return 2;
if (!corrdata)
return 3;
ctx = malloc(sizeof(struct lib6145_ctx));
if (!ctx)
return 4;
memset(ctx, 0, sizeof(struct lib6145_ctx));
ctx->pucInputImageBuf = in;
ctx->pusOutputImageBuf = out;
ctx->pSPrintParam = (struct imageCorrParam *) corrdata;
i = CheckPrintParam(corrdata);
if (i) {
free(ctx);
return i;
}
Global_Init(ctx);
#ifdef S6145_UNUSED
SetTable(ctx);
#endif
for ( i = 0; i < 4; i++ ) { /* Full YMCO */
int32_t lines;
SetTableColor(ctx, i);
LinePrintPreProcess(ctx);
PagePrintPreProcess(ctx);
lines = ctx->usPrintSizeHeight;
while ( lines-- ) {
PagePrintProcess(ctx);
}
ctx->usPrintColor++;
}
free(ctx);
return 0;
}
/* **************************** */
static void SetTableData(const void *src, void *dest, uint16_t words)
{
const uint16_t *in = src;
uint16_t *out = dest;
while (words--) {
out[words] = le16_to_cpu(in[words]);
}
}
static void GetInfo(struct lib6145_ctx *ctx)
{
uint32_t tmp;
#ifdef S6145_UNUSED
ctx->usLastPrintSizeWidth = ctx->usPrintSizeWidth;
ctx->usLastPrintSizeHeight = ctx->usPrintSizeHeight;
ctx->usLastSheetSizeWidth = ctx->usSheetSizeWidth;
ctx->usPrintOffsetWidth = 0;
#endif
ctx->usPrintSizeWidth = le16_to_cpu(ctx->pSPrintParam->width);
ctx->usPrintSizeHeight = le16_to_cpu(ctx->pSPrintParam->height);
ctx->usSheetSizeWidth = ctx->usPrintSizeWidth;
ctx->sPrintSideOffset = le16_to_cpu(ctx->pSPrintParam->printSideOffset);
if ( ctx->pSPrintParam->val_1 )
ctx->sCorrectSw |= 1;
if ( ctx->pSPrintParam->val_2 )
ctx->sCorrectSw |= 2;
ctx->usPrintOpLevel = le16_to_cpu(ctx->pSPrintParam->printOpLevel);
tmp = le16_to_cpu(ctx->pSPrintParam->randomBase[0]);
ctx->ucRandomBaseLevel[0] = tmp & 0xff;
tmp = le16_to_cpu(ctx->pSPrintParam->randomBase[1]);
ctx->ucRandomBaseLevel[1] = tmp & 0xff;
tmp = le16_to_cpu(ctx->pSPrintParam->randomBase[2]);
ctx->ucRandomBaseLevel[2] = tmp & 0xff;
tmp = le16_to_cpu(ctx->pSPrintParam->randomBase[3]);
ctx->ucRandomBaseLevel[3] = tmp & 0xff;
ctx->usMatteSize = le16_to_cpu(ctx->pSPrintParam->matteSize);
ctx->usMatteMode = le16_to_cpu(ctx->pSPrintParam->matteMode);
#ifdef S6145_UNUSED
ctx->usMatteGloss = le16_to_cpu(ctx->pSPrintParam->matteGloss);
ctx->usMatteDeglossBlk = le16_to_cpu(ctx->pSPrintParam->matteDeglossBlk);
ctx->usMatteDeglossWht = le16_to_cpu(ctx->pSPrintParam->matteDeglossWht);
#endif
switch (ctx->usPrintColor) {
case 0:
ctx->usPrintMaxPulse = le16_to_cpu(ctx->pSPrintParam->printMaxPulse_Y);
ctx->uiMtfWeightH = le16_to_cpu(ctx->pSPrintParam->mtfWeightH_Y);
ctx->uiMtfWeightV = le16_to_cpu(ctx->pSPrintParam->mtfWeightV_Y);
ctx->uiMtfSlice = le16_to_cpu(ctx->pSPrintParam->mtfSlice_Y);
ctx->usLineCorrect_Env_A = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvA_Y);
ctx->usLineCorrect_Env_B = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvB_Y);
ctx->usLineCorrect_Env_C = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvC_Y);
ctx->uiLineCorrectSlice = le32_to_cpu(ctx->pSPrintParam->lineCorrectSlice_Y);
ctx->uiLineCorrectSlice1Line = le32_to_cpu(ctx->pSPrintParam->lineCorrectSlice1Line_Y);
ctx->iLineCorrectPulseMax = le32_to_cpu(ctx->pSPrintParam->lineCorrectPulseMax_Y);
break;
case 1:
ctx->usPrintMaxPulse = le16_to_cpu(ctx->pSPrintParam->printMaxPulse_M);
ctx->uiMtfWeightH = le16_to_cpu(ctx->pSPrintParam->mtfWeightH_M);
ctx->uiMtfWeightV = le16_to_cpu(ctx->pSPrintParam->mtfWeightV_M);
ctx->uiMtfSlice = le16_to_cpu(ctx->pSPrintParam->mtfSlice_M);
ctx->usLineCorrect_Env_A = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvA_M);
ctx->usLineCorrect_Env_B = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvB_M);
ctx->usLineCorrect_Env_C = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvC_M);
ctx->uiLineCorrectSlice = le32_to_cpu(ctx->pSPrintParam->lineCorrectSlice_M);
ctx->uiLineCorrectSlice1Line = le32_to_cpu(ctx->pSPrintParam->lineCorrectSlice1Line_M);
ctx->iLineCorrectPulseMax = le32_to_cpu(ctx->pSPrintParam->lineCorrectPulseMax_M);
break;
case 2:
ctx->usPrintMaxPulse = le16_to_cpu(ctx->pSPrintParam->printMaxPulse_C);
ctx->uiMtfWeightH = le16_to_cpu(ctx->pSPrintParam->mtfWeightH_C);
ctx->uiMtfWeightV = le16_to_cpu(ctx->pSPrintParam->mtfWeightV_C);
ctx->uiMtfSlice = le16_to_cpu(ctx->pSPrintParam->mtfSlice_C);
ctx->usLineCorrect_Env_A = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvA_C);
ctx->usLineCorrect_Env_B = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvB_C);
ctx->usLineCorrect_Env_C = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvC_C);
ctx->uiLineCorrectSlice = le32_to_cpu(ctx->pSPrintParam->lineCorrectSlice_C);
ctx->uiLineCorrectSlice1Line = le32_to_cpu(ctx->pSPrintParam->lineCorrectSlice1Line_C);
ctx->iLineCorrectPulseMax = le32_to_cpu(ctx->pSPrintParam->lineCorrectPulseMax_C);
break;
case 3:
ctx->usPrintMaxPulse = le16_to_cpu(ctx->pSPrintParam->printMaxPulse_O);
ctx->uiMtfWeightH = le16_to_cpu(ctx->pSPrintParam->mtfWeightH_O);
ctx->uiMtfWeightV = le16_to_cpu(ctx->pSPrintParam->mtfWeightV_O);
ctx->uiMtfSlice = le16_to_cpu(ctx->pSPrintParam->mtfSlice_O);;
ctx->usLineCorrect_Env_A = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvA_O);
ctx->usLineCorrect_Env_B = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvB_O);
ctx->usLineCorrect_Env_C = le16_to_cpu(ctx->pSPrintParam->lineCorrectEnvC_O);
ctx->uiLineCorrectSlice = le32_to_cpu(ctx->pSPrintParam->lineCorrectSlice_O);
ctx->uiLineCorrectSlice1Line = le32_to_cpu(ctx->pSPrintParam->lineCorrectSlice1Line_O);
ctx->iLineCorrectPulseMax = le32_to_cpu(ctx->pSPrintParam->lineCorrectPulseMax_O);
break;
default:
break;
}
ctx->usHeadDots = le16_to_cpu(ctx->pSPrintParam->headDots);
}
static void Global_Init(struct lib6145_ctx *ctx)
{
ctx->usPrintColor = 0;
ctx->usPrintSizeWidth = 0;
ctx->usPrintSizeHeight = 0;
ctx->usSheetSizeWidth = 0;
ctx->sPrintSideOffset = 0;
ctx->sCorrectSw = 0;
ctx->usPrintOpLevel = 0;
ctx->uiMtfWeightH = 0;
ctx->uiMtfWeightV = 0;
ctx->uiMtfSlice = 0;
ctx->usPrintMaxPulse = MAX_PULSE;
ctx->usMatteMode = 0;
ctx->usLineCorrect_Env_A = 0;
ctx->usLineCorrect_Env_B = 0;
ctx->usLineCorrect_Env_C = 0;
ctx->uiLineCorrectSum = 0;
ctx->uiLineCorrectBase = 0;
ctx->uiLineCorrectBase1Line = 0;
ctx->iLineCorrectPulse = 0;
ctx->iLineCorrectPulseMax = MAX_PULSE;
ctx->pulRandomTable[0] = 3;
ctx->pulRandomTable[1] = -1708027847;
ctx->pulRandomTable[2] = 853131300;
ctx->pulRandomTable[3] = -1687801470;
ctx->pulRandomTable[4] = 1570894658;
ctx->pulRandomTable[5] = -566525472;
ctx->pulRandomTable[6] = -552964171;
ctx->pulRandomTable[7] = -251413502;
ctx->pulRandomTable[8] = 1223901435;
ctx->pulRandomTable[9] = 1950999915;
ctx->pulRandomTable[10] = -1095640144;
ctx->pulRandomTable[11] = -1420011240;
ctx->pulRandomTable[12] = -1805298435;
ctx->pulRandomTable[13] = -1943115761;
ctx->pulRandomTable[14] = -348292705;
ctx->pulRandomTable[15] = -1323376457;
ctx->pulRandomTable[16] = 759393158;
ctx->pulRandomTable[17] = -630772182;
ctx->pulRandomTable[18] = 361286280;
ctx->pulRandomTable[19] = -479628451;
ctx->pulRandomTable[20] = -1873857033;
ctx->pulRandomTable[21] = -686452778;
ctx->pulRandomTable[22] = 1873211473;
ctx->pulRandomTable[23] = 1634626454;
ctx->pulRandomTable[24] = -1399525412;
ctx->pulRandomTable[25] = 910245779;
ctx->pulRandomTable[26] = -970800488;
ctx->pulRandomTable[27] = -173790536;
ctx->pulRandomTable[28] = -1970743429;
ctx->pulRandomTable[29] = -173171442;
ctx->pulRandomTable[30] = -1986452981;
ctx->pulRandomTable[31] = 670779321;
ctx->uiInputImageIndex = 0;
ctx->uiOutputImageIndex = 0;
ctx->usHeadDots = 0;
#ifdef S6145_UNUSED
ctx->usPrintDummyLevel = 0;
ctx->usPrintDummyLine = 0;
ctx->usRearDummyPrintLine = 0;
ctx->usRearDeleteLine = 0;
ctx->usPrintSizeLWidth = 0;
ctx->usPrintSizeLHeight = 0;
ctx->usThearmHead = 0;
ctx->usThearmEnv = 0;
ctx->usRearDummyPrintLevel = 0;
ctx->usLastPrintSizeWidth = 0;
ctx->usLastPrintSizeHeight = 0;
ctx->usLastSheetSizeWidth = 0;
ctx->iLeadEdgeCorrectPulse = 0;
ctx->usCancelCheckLinesForPRec = 118;
ctx->pusLamiCompInLineBufTab[0] = (uint16_t*)ctx->pusInLineBuf0;
ctx->pusLamiCompInLineBufTab[1] = (uint16_t*)ctx->pusInLineBuf2;
ctx->pusLamiCompInLineBufTab[2] = ctx->pusOutLineBuf1;
ctx->pusLamiCompInLineBufTab[3] = ctx->pusOutLineBuf2;
ctx->usMatteGloss = 105;
ctx->usMatteDeglossBlk = 150;
ctx->usMatteDeglossWht = 175;
ctx->usPrintOffsetWidth = 0;
ctx->usCenterHeadToColSen = 268;
ctx->uiLevelAveAddtion = 0;
ctx->uiLevelAveCounter = 0;
ctx->uiLevelAveCounter2 = 0;
ctx->uiLevelAveAddtion2 = 0;
ctx->usCancelCheckDotsForPRec = 236;
#endif
}
#ifdef S6145_UNUSED
static void SetTable(struct lib6145_ctx *ctx)
{
SetTableData(ctx->pSPrintParam->SideEdgeCoefTable, ctx->pusSideEdgeCoefTable, 128);
SetTableData(ctx->pSPrintParam->SideEdgeLvCoefTable, ctx->pusSideEdgeLvCoefTable, 256);
}
#endif
static void SetTableColor(struct lib6145_ctx *ctx, uint8_t plane)
{
switch (plane) {
case 0:
SetTableData(ctx->pSPrintParam->pulseTransTable_Y, ctx->pusPulseTransTable, 256);
SetTableData(ctx->pSPrintParam->lineHistCoefTable_Y, ctx->pusLineHistCoefTable, 256);
SetTableData(ctx->pSPrintParam->tankPlusMaxEnergyTable_Y, ctx->pusTankPlusMaxEnegyTable, 256);
SetTableData(ctx->pSPrintParam->tankMinusMaxEnergy_Y, ctx->pusTankMinusMaxEnegyTable, 256);
memcpy(ctx->piTankParam, &ctx->pSPrintParam->tableTankParam_Y, 128);
break;
case 1:
SetTableData(ctx->pSPrintParam->pulseTransTable_M, ctx->pusPulseTransTable, 256);
SetTableData(ctx->pSPrintParam->lineHistCoefTable_M, ctx->pusLineHistCoefTable, 256);
SetTableData(ctx->pSPrintParam->tankPlusMaxEnergyTable_M, ctx->pusTankPlusMaxEnegyTable, 256);
SetTableData(ctx->pSPrintParam->tankMinusMaxEnergy_M, ctx->pusTankMinusMaxEnegyTable, 256);
memcpy(&ctx->piTankParam[32], &ctx->pSPrintParam->tableTankParam_M, 128);
break;
case 2:
SetTableData(ctx->pSPrintParam->pulseTransTable_C, ctx->pusPulseTransTable, 256);
SetTableData(ctx->pSPrintParam->lineHistCoefTable_C, ctx->pusLineHistCoefTable, 256);
SetTableData(ctx->pSPrintParam->tankPlusMaxEnergyTable_C, ctx->pusTankPlusMaxEnegyTable, 256);
SetTableData(ctx->pSPrintParam->tankMinusMaxEnergy_C, ctx->pusTankMinusMaxEnegyTable, 256);
memcpy(&ctx->piTankParam[64], &ctx->pSPrintParam->tableTankParam_C, 128);
break;
case 3:
SetTableData(ctx->pSPrintParam->pulseTransTable_O, ctx->pusPulseTransTable, 256);
SetTableData(ctx->pSPrintParam->lineHistCoefTable_O, ctx->pusLineHistCoefTable, 256);
SetTableData(ctx->pSPrintParam->tankPlusMaxEnergyTable_O, ctx->pusTankPlusMaxEnegyTable, 256);
SetTableData(ctx->pSPrintParam->tankMinusMaxEnergy_O, ctx->pusTankMinusMaxEnegyTable, 256);
memcpy(&ctx->piTankParam[96], &ctx->pSPrintParam->tableTankParam_O, 128);
break;
default:
break;
}
}
static int32_t CheckPrintParam(struct imageCorrParam *corrdata)
{
int i;
for (i = 0 ; i < 256 ; i++) {
if (le16_to_cpu(corrdata->pulseTransTable_Y[i]) > le16_to_cpu(corrdata->printMaxPulse_Y) ||
le16_to_cpu(corrdata->pulseTransTable_M[i]) > le16_to_cpu(corrdata->printMaxPulse_M) ||
le16_to_cpu(corrdata->pulseTransTable_C[i]) > le16_to_cpu(corrdata->printMaxPulse_C) ||
le16_to_cpu(corrdata->pulseTransTable_O[i]) > le16_to_cpu(corrdata->printMaxPulse_O)) {
return 10;
}
}
if (!corrdata->tableTankParam_Y.trdTankSize ||
!corrdata->tableTankParam_M.trdTankSize ||
!corrdata->tableTankParam_C.trdTankSize ||
!corrdata->tableTankParam_O.trdTankSize) {
return 14;
}
if (!corrdata->tableTankParam_Y.sndTankSize ||
!corrdata->tableTankParam_M.sndTankSize ||
!corrdata->tableTankParam_C.sndTankSize ||
!corrdata->tableTankParam_O.sndTankSize) {
return 15;
}
if (!corrdata->tableTankParam_Y.fstTankSize ||
!corrdata->tableTankParam_M.fstTankSize ||
!corrdata->tableTankParam_C.fstTankSize ||
!corrdata->tableTankParam_O.fstTankSize) {
return 16;
}
if (le16_to_cpu(corrdata->val_1) > 1 ||
le16_to_cpu(corrdata->val_2) > 1 ||
le16_to_cpu(corrdata->printOpLevel) > 0xff ||
le16_to_cpu(corrdata->matteMode) > 1) {
return 17;
}
if (le16_to_cpu(corrdata->randomBase[0]) > 0xff ||
le16_to_cpu(corrdata->randomBase[1]) > 0xff ||
le16_to_cpu(corrdata->randomBase[2]) > 0xff ||
le16_to_cpu(corrdata->randomBase[3]) > 0xff) {
return 18;
}
if (!corrdata->matteSize ||
corrdata->matteSize > 2) {
return 19;
}
if ( le16_to_cpu(corrdata->width) <= MIN_ROWS ||
le16_to_cpu(corrdata->width) > MAX_ROWS )
return 20;
if ( le16_to_cpu(corrdata->height) <= MIN_ROWS ||
le16_to_cpu(corrdata->height) > MAX_ROWS )
return 21;
return 0;
}
/* This resets the preprocess pipeline at the start of a new image
plane. */
static void LinePrintPreProcess(struct lib6145_ctx *ctx)
{
int16_t i;
GetInfo(ctx);
if ( !(ctx->sCorrectSw & 1) )
{
ctx->uiMtfWeightH = 0;
ctx->uiMtfWeightV = 0;
ctx->uiMtfSlice = 0;
}
for ( i = -256; i < 256; i++ )
{
if ( (uint32_t)(i * i) >= (uint32_t)(ctx->uiMtfSlice * ctx->uiMtfSlice) )
ctx->psMtfPreCalcTable[i+256] = i;
else
ctx->psMtfPreCalcTable[i+256] = -i;
}
ctx->pusPreReadLineBufTab[0] = ctx->pusInLineBuf0;
ctx->pusPreReadLineBufTab[1] = ctx->pusInLineBuf1;
ctx->pusPreReadLineBufTab[2] = ctx->pusInLineBuf2;
ctx->pusPreReadLineBufTab[3] = ctx->pusInLineBuf3;
ctx->pusPreReadLineBufTab[4] = ctx->pusInLineBuf4;
ctx->pusPreReadLineBufTab[5] = ctx->pusInLineBuf5;
ctx->pusPreReadLineBufTab[6] = ctx->pusInLineBuf6;
ctx->pusPreReadLineBufTab[7] = ctx->pusInLineBuf7;
ctx->pusPreReadLineBufTab[8] = ctx->pusInLineBuf8;
ctx->pusPreReadLineBufTab[9] = ctx->pusInLineBuf9;
ctx->pusPreReadLineBufTab[10] = ctx->pusInLineBufA;
memset(ctx->pusInLineBuf0, 0, sizeof(ctx->pusInLineBuf0));
memset(ctx->pusInLineBuf1, 0, sizeof(ctx->pusInLineBuf1));
memset(ctx->pusInLineBuf2, 0, sizeof(ctx->pusInLineBuf2));
memset(ctx->pusInLineBuf3, 0, sizeof(ctx->pusInLineBuf3));
memset(ctx->pusInLineBuf4, 0, sizeof(ctx->pusInLineBuf4));
memset(ctx->pusInLineBuf5, 0, sizeof(ctx->pusInLineBuf5));
memset(ctx->pusInLineBuf6, 0, sizeof(ctx->pusInLineBuf6));
memset(ctx->pusInLineBuf7, 0, sizeof(ctx->pusInLineBuf7));
memset(ctx->pusInLineBuf8, 0, sizeof(ctx->pusInLineBuf8));
memset(ctx->pusInLineBuf9, 0, sizeof(ctx->pusInLineBuf9));
memset(ctx->pusInLineBufA, 0, sizeof(ctx->pusInLineBufA));
ctx->pusPulseTransLineBufTab[0] = ctx->pusInLineBuf0;
ctx->pusPulseTransLineBufTab[1] = ctx->pusInLineBuf1;
ctx->pusPulseTransLineBufTab[2] = ctx->pusInLineBuf2;
ctx->pusPulseTransLineBufTab[3] = ctx->pusInLineBuf3;
memset(ctx->pusOutLineBuf1, 0, sizeof(ctx->pusOutLineBuf1));
ctx->pusOutLineBufTab[0] = ctx->pusOutLineBuf1;
#ifdef S6145_UNUSED
memset(ctx->pusInLineBuf3, ctx->usPrintDummyLevel, sizeof(ctx->pusInLineBuf3)); // XXX redundant with memset above, printDummyLevel is always 0 anyway.
#endif
ctx->uiSendToHeadCounter = ctx->usPrintSizeHeight;
ctx->uiLineCopyCounter = ctx->usPrintSizeHeight;
#ifdef S6145_UNUSED
ctx->uiDataTransCounter = ctx->usPrintSizeHeight;
ctx->uiDataTransCounter += ctx->usPrintDummyLine;
ctx->uiDataTransCounter -= ctx->usRearDeleteLine;
ctx->uiDataTransCounter += ctx->usRearDummyPrintLine;
ctx->uiSendToHeadCounter += ctx->usPrintDummyLine;
ctx->uiSendToHeadCounter -= ctx->usRearDeleteLine;
ctx->uiSendToHeadCounter += ctx->usRearDummyPrintLine;
ctx->uiTudenLineCounter = ctx->usPrintSizeHeight;
ctx->uiTudenLineCounter += ctx->usRearDummyPrintLine;
ctx->uiTudenLineCounter -= ctx->usRearDeleteLine;
ctx->uiLineCopyCounter -= ctx->usRearDeleteLine;
if ( ctx->usPrintColor != 3 )
ctx->usRearDummyPrintLevel = 255;
ctx->iLeadEdgeCorrectPulse = 0;
#endif
switch (ctx->usPrintColor) {
case 0:
CTankResetParameter(ctx, &ctx->piTankParam[0]);
ctx->iMaxPulseValue = ctx->usPrintMaxPulse;
ctx->uiMaxPulseBit = LinePrintCalcBit(ctx->usPrintMaxPulse);
ctx->pfRecieveData = RecieveDataYMC;
#ifdef S6145_UNUSED
ctx->pfRecieveData_Post = RecieveDataYMC_Post;
#endif
ctx->pfPulseTransPreRead = PulseTransPreReadYMC;
ctx->pfTankProcessPreRead = CTankProcessPreRead;
break;
case 1:
CTankResetParameter(ctx, &ctx->piTankParam[32]);
ctx->iMaxPulseValue = ctx->usPrintMaxPulse;
ctx->uiMaxPulseBit = LinePrintCalcBit(ctx->usPrintMaxPulse);
ctx->pfRecieveData = RecieveDataYMC;
#ifdef S6145_UNUSED
ctx->pfRecieveData_Post = RecieveDataYMC_Post;
#endif
ctx->pfPulseTransPreRead = PulseTransPreReadYMC;
ctx->pfTankProcessPreRead = CTankProcessPreRead;
break;
case 2:
CTankResetParameter(ctx, &ctx->piTankParam[64]);
ctx->iMaxPulseValue = ctx->usPrintMaxPulse;
ctx->uiMaxPulseBit = LinePrintCalcBit(ctx->usPrintMaxPulse);
ctx->pfRecieveData = RecieveDataYMC;
#ifdef S6145_UNUSED
ctx->pfRecieveData_Post = RecieveDataYMC_Post;
#endif
ctx->pfPulseTransPreRead = PulseTransPreReadYMC;
ctx->pfTankProcessPreRead = CTankProcessPreRead;
break;
case 3:
CTankResetParameter(ctx, &ctx->piTankParam[96]);
ctx->iMaxPulseValue = ctx->usPrintMaxPulse;
ctx->uiMaxPulseBit = LinePrintCalcBit(ctx->usPrintMaxPulse);
if ( ctx->usMatteMode ) {
ctx->pfRecieveData = RecieveDataOP_MATTE;
#ifdef S6145_UNUSED
ctx->pfRecieveData_Post = RecieveDataOPMatte_Post;
#endif
} else {
ctx->pfRecieveData = RecieveDataOP_GLOSS;
#ifdef S6145_UNUSED
ctx->pfRecieveData_Post = RecieveDataOPLevel_Post;
#endif
}
ctx->pfPulseTransPreRead = PulseTransPreReadOP;
ctx->pfTankProcessPreRead = CTankProcessPreReadDummy;
#ifdef S6145_UNUSED
if ( ctx->usMatteMode )
ctx->iLeadEdgeCorrectPulse = 120;
#endif
break;
default:
return;
}
ctx->uiLineCorrectSum = 0;
ctx->iLineCorrectPulse = 0;
if ( ctx->uiLineCorrectSlice ) {
ctx->uiLineCorrectBase = ctx->uiLineCorrectSlice * ctx->usLineCorrect_Env_A;
ctx->uiLineCorrectBase >>= 15;
ctx->uiLineCorrectBase *= ctx->usSheetSizeWidth;
} else {
ctx->uiLineCorrectBase = -1;
}
if ( ctx->uiLineCorrectSlice1Line ) {
ctx->uiLineCorrectBase1Line = ctx->uiLineCorrectSlice1Line * ctx->usLineCorrect_Env_B;
ctx->uiLineCorrectBase1Line >>= 15;
ctx->uiLineCorrectBase1Line *= ctx->usSheetSizeWidth;
}
if ( ctx->iLineCorrectPulseMax ) {
ctx->iLineCorrectPulseMax *= ctx->usLineCorrect_Env_C;
ctx->iLineCorrectPulseMax /= 1024;
} else {
ctx->iLineCorrectPulseMax = MAX_PULSE;
}
CTankResetTank(ctx);
#ifdef S6145_UNUSED
ctx->uiDummyPrintCounter = 0;
#endif
}
static void CTankResetParameter(struct lib6145_ctx *ctx, const int32_t *params)
{
ctx->m_iTrdTankSize = le32_to_cpu(params[0]);
ctx->m_iSndTankSize = le32_to_cpu(params[1]);
ctx->m_iFstTankSize = le32_to_cpu(params[2]);
ctx->m_iTrdTankIniEnergy = le32_to_cpu(params[3]);
ctx->m_iSndTankIniEnergy = le32_to_cpu(params[4]);
ctx->m_iFstTankIniEnergy = le32_to_cpu(params[5]);
ctx->m_iTrdTrdConductivity = le32_to_cpu(params[6]);
ctx->m_iSndSndConductivity = le32_to_cpu(params[7]);
ctx->m_iFstFstConductivity = le32_to_cpu(params[8]);
ctx->m_iOutTrdConductivity = le32_to_cpu(params[9]);
ctx->m_iTrdSndConductivity = le32_to_cpu(params[10]);
ctx->m_iSndFstConductivity = le32_to_cpu(params[11]);
ctx->m_iFstOutConductivity = le32_to_cpu(params[12]);
#ifdef S6145_UNUSED
ctx->m_iPlusMaxEnergy = le32_to_cpu(params[13]);
ctx->m_iMinusMaxEnergy = le32_to_cpu(params[14]);
ctx->m_iPlusMaxEnergyPreRead = le32_to_cpu(params[15]);
#endif
ctx->m_iMinusMaxEnergyPreRead = le32_to_cpu(params[16]);
ctx->m_iPreReadLevelDiff = le32_to_cpu(params[17]);
ctx->m_iTankKeisuOutTrdDivTrd = (int64_t)ctx->m_iOutTrdConductivity * (int64_t)0x10000 / (int64_t)ctx->m_iTrdTankSize;
ctx->m_iTankKeisuTrdSndDivTrd = (int64_t)ctx->m_iTrdSndConductivity * (int64_t)0x10000 / (int64_t)ctx->m_iTrdTankSize;
ctx->m_iTankKeisuTrdSndDivSnd = (int64_t)ctx->m_iTrdSndConductivity * (int64_t)0x10000 / (int64_t)ctx->m_iSndTankSize;
ctx->m_iTankKeisuSndFstDivSnd = (int64_t)ctx->m_iSndFstConductivity * (int64_t)0x10000 / (int64_t)ctx->m_iSndTankSize;
ctx->m_iTankKeisuSndFstDivFst = (int64_t)ctx->m_iSndFstConductivity * (int64_t)0x10000 / (int64_t)ctx->m_iFstTankSize;
ctx->m_iTankKeisuFstOutDivFst = (int64_t)ctx->m_iFstOutConductivity * (int64_t)0x10000 / (int64_t)ctx->m_iFstTankSize;
return;
}
static void CTankResetTank(struct lib6145_ctx *ctx)
{
int i;
for (i = 0 ; i < TANK_SIZE; i++) {
ctx->m_piTrdTankArray[i] = ctx->m_iTrdTankIniEnergy;
ctx->m_piSndTankArray[i] = ctx->m_iSndTankIniEnergy;
ctx->m_piFstTankArray[i] = ctx->m_iFstTankIniEnergy;
}
}
/* This primes the preprocessing pipeline prior to starting the first
actual row of image data */
static void PagePrintPreProcess(struct lib6145_ctx *ctx)
{
uint32_t i;
ctx->pusPulseTransLineBufTab[3] = ctx->pusPreReadLineBufTab[1];
ctx->pfRecieveData(ctx);
ctx->pusPulseTransLineBufTab[1] = ctx->pusPulseTransLineBufTab[3];
ctx->uiLineCopyCounter++;
ctx->uiInputImageIndex -= ctx->usPrintSizeWidth;
ctx->pusPulseTransLineBufTab[3] = ctx->pusPreReadLineBufTab[2];
ctx->pfRecieveData(ctx);
ctx->pusPulseTransLineBufTab[2] = ctx->pusPulseTransLineBufTab[3];
ctx->pusPulseTransLineBufTab[3] = ctx->pusPreReadLineBufTab[3];
ctx->pfRecieveData(ctx);
for ( i = 0; i < 7; i++ )
{
ctx->pusPulseTransLineBufTab[3] = ctx->pusPreReadLineBufTab[i + 4];
ctx->pfRecieveData(ctx);
}
ctx->pusPulseTransLineBufTab[0] = ctx->pusPreReadLineBufTab[0];
}
/* Process a single scanline,
From reading the input data to writing the output.
*/
static void PagePrintProcess(struct lib6145_ctx *ctx)
{
uint32_t i;
/* First, rotate the input buffers... */
if ( ctx->usPrintColor != 3 || ctx->usMatteMode != 1 || ctx->usMatteSize != 2 ) {
/* If we're not printing a matte layer... */
uint8_t *v4 = ctx->pusPreReadLineBufTab[0];
for ( i = 0; i < 10; i++ )
ctx->pusPreReadLineBufTab[i] = ctx->pusPreReadLineBufTab[i + 1];
ctx->pusPreReadLineBufTab[10] = v4;
ctx->pusPulseTransLineBufTab[0] = ctx->pusPreReadLineBufTab[0];
ctx->pusPulseTransLineBufTab[1] = ctx->pusPreReadLineBufTab[1];
ctx->pusPulseTransLineBufTab[2] = ctx->pusPreReadLineBufTab[2];
ctx->pusPulseTransLineBufTab[3] = ctx->pusPreReadLineBufTab[10];
} else if ( ctx->uiLineCopyCounter & 1 ) {
/* in other words, every other line when printing a matte layer.. */
uint8_t *v4 = ctx->pusPreReadLineBufTab[0];
for ( i = 0; i < 10; i++ )
ctx->pusPreReadLineBufTab[i] = ctx->pusPreReadLineBufTab[i + 1];
ctx->pusPreReadLineBufTab[10] = v4;
ctx->pusPulseTransLineBufTab[0] = ctx->pusPreReadLineBufTab[0];
ctx->pusPulseTransLineBufTab[1] = ctx->pusPreReadLineBufTab[1];
ctx->pusPulseTransLineBufTab[2] = ctx->pusPreReadLineBufTab[2];
ctx->pusPulseTransLineBufTab[3] = ctx->pusPreReadLineBufTab[10];
}
#ifdef S6145_UNUSED
ctx->uiTudenLineCounter--;
#endif
ctx->pfRecieveData(ctx); /* Read another scanline */
PulseTrans(ctx);
ctx->pfPulseTransPreRead(ctx);
#ifdef S6145_UNUSED
ctx->pfRecieveData_Post(); /* Clean up after the receive */
#endif
CTankProcess(ctx); /* Update thermal tank state */
ctx->pfTankProcessPreRead(ctx);
LineCorrection(ctx); /* Final output compensation */
SendData(ctx); /* Write scanline output */
return;
}
static uint16_t LinePrintCalcBit(uint16_t val)
{
uint16_t bit = 0;
while (val) {
val >>= 1;
bit++;
}
return bit;
}
/* Update thermal tank state */
static void CTankProcess(struct lib6145_ctx *ctx)
{
if ( ctx->sCorrectSw & 2 ) {
CTankHosei(ctx);
CTankUpdateTankVolumeInterRay(ctx);
CTankUpdateTankVolumeInterDot(ctx, 0);
CTankUpdateTankVolumeInterDot(ctx, 1);
CTankUpdateTankVolumeInterDot(ctx, 2);
}
return;
}
static void CTankProcessPreRead(struct lib6145_ctx *ctx)
{
if (ctx->sCorrectSw & 2)
CTankHoseiPreread(ctx);
}
static void CTankProcessPreReadDummy(struct lib6145_ctx *ctx)
{
(void)ctx;
return;
}
/* This will generate one line worth of "gloss" OC data.
It only covers the imageable area, rather than the head width */
static void RecieveDataOP_GLOSS(struct lib6145_ctx *ctx)
{
if ( ctx->uiLineCopyCounter ) {
memset(ctx->pusPulseTransLineBufTab[3] + ((ctx->usHeadDots - ctx->usSheetSizeWidth) / 2),
ctx->usPrintOpLevel,
ctx->usSheetSizeWidth);
ctx->uiLineCopyCounter--;
}
return;
}
/* This reads a single line worth of input image data.
*/
static void RecieveDataYMC(struct lib6145_ctx *ctx)
{
uint8_t *v1;
int16_t i;
v1 = ctx->pusPulseTransLineBufTab[3] + ((ctx->usHeadDots - ctx->usSheetSizeWidth) / 2);
if ( ctx->uiLineCopyCounter ) {
/* Read the next line */
for ( i = 0; i < ctx->usPrintSizeWidth; i++ )
v1[i] = ctx->pucInputImageBuf[ctx->uiInputImageIndex++];
--ctx->uiLineCopyCounter;
} else {
/* Re-read the previous line */
ctx->uiInputImageIndex -= ctx->usPrintSizeWidth;
for ( i = 0; i < ctx->usPrintSizeWidth ; i++ )
v1[i] = ctx->pucInputImageBuf[ctx->uiInputImageIndex++];
}
}
/* this will generate one scanline (ie 16b * BUF_SIZE) worth of
"random" data for the matte overcoat */
static void RecieveDataOP_MATTE(struct lib6145_ctx *ctx)
{
if ( ctx->uiLineCopyCounter ) {
int32_t v1;
uint32_t v5;
int32_t v6;
int16_t matteCtr;
uint8_t *outPtr = ctx->pusPulseTransLineBufTab[3];
if ( ctx->usMatteSize == 2 )
matteCtr = 256;
else
matteCtr = 512;
while ( matteCtr-- ) {
if ( ctx->pulRandomTable[0] >= 31 )
v6 = 1;
else
v6 = ctx->pulRandomTable[0] + 1;
ctx->pulRandomTable[0] = v6;
if ( v6 <= 3 )
v1 = ctx->pulRandomTable[v6 + 28];
else
v1 = ctx->pulRandomTable[v6 - 3];
ctx->pulRandomTable[v6] += v1;
v5 = (uint32_t)ctx->pulRandomTable[v6] >> 1;
if ( ctx->usMatteSize == 2 ) {
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 1) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 1) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 5) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 5) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 9) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 9) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 13) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 13) & 3];
} else {
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 1) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 5) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 9) & 3];
*outPtr++ = ctx->ucRandomBaseLevel[(v5 >> 13) & 3];
}
}
--ctx->uiLineCopyCounter;
}
}
/* This writes a single scanline to the output buffer */
static void SendData(struct lib6145_ctx *ctx)
{
uint16_t i;
if ( ctx->uiSendToHeadCounter ) {
for ( i = 0; i < ctx->usHeadDots; i++ )
ctx->pusOutputImageBuf[ctx->uiOutputImageIndex++] = cpu_to_le16(ctx->pusOutLineBufTab[0][i]);
--ctx->uiSendToHeadCounter;
}
}
/* Use the previous two rows to generate the needed impulse for
the current row. */
static void PulseTrans(struct lib6145_ctx *ctx)
{
int32_t overHang;
int32_t sheetSizeWidth;
uint8_t *prevPrevRow;
uint8_t *prevRow;
uint8_t *currentRow;
uint16_t *out;
sheetSizeWidth = ctx->usSheetSizeWidth;
overHang = (ctx->usHeadDots - ctx->usSheetSizeWidth) / 2;
currentRow = ctx->pusPulseTransLineBufTab[0] + overHang;
prevRow = ctx->pusPulseTransLineBufTab[1] + overHang;
prevPrevRow = ctx->pusPulseTransLineBufTab[2] + overHang;
out = ctx->pusOutLineBufTab[0] + ctx->sPrintSideOffset + overHang;
if ( out >= ctx->pusOutLineBufTab[0] ) {
int32_t offset = ctx->sPrintSideOffset
+ ctx->usSheetSizeWidth
+ overHang;
if ( offset > BUF_SIZE )
sheetSizeWidth = ctx->usSheetSizeWidth - (offset - BUF_SIZE);
} else {
int32_t offset = (ctx->pusOutLineBufTab[0] - out);
out = ctx->pusOutLineBufTab[0];
sheetSizeWidth = ctx->usSheetSizeWidth - offset;
currentRow += offset;
prevRow += offset;
prevPrevRow += offset;
// fprintf(stderr, "WARN: PulseTrans() alt path\n");
}
while ( sheetSizeWidth-- ) {
int32_t tableOffset;
uint16_t compVal;
uint8_t *v2;
int32_t v3;
int32_t v4;
int32_t v6;
int32_t v12;
v2 = prevRow - 1;
v3 = *v2++;
v12 = *v2;
prevRow = v2 + 1;
v4 = ctx->psMtfPreCalcTable[256 + v12 - *prevRow] + ctx->psMtfPreCalcTable[256 + v12 - v3];
v6 = ctx->psMtfPreCalcTable[256 + v12 - *currentRow++];
tableOffset = v12 + ((v4 * ctx->uiMtfWeightH + (ctx->psMtfPreCalcTable[256 + v12 - *prevPrevRow++] + v6) * ctx->uiMtfWeightV) >> 7);
if ( tableOffset > 255 )
tableOffset = 255;
if ( tableOffset <= 0 )
tableOffset = 1;
if ( !v12 )
tableOffset = 0;
compVal = ctx->pusPulseTransTable[tableOffset];
if ( compVal > MAX_PULSE )
compVal = MAX_PULSE;
*out++ = compVal;
}
#ifdef S6145_UNUSED
ctx->uiDataTransCounter--;
#endif
}
static void PulseTransPreReadOP(struct lib6145_ctx *ctx)
{
(void)ctx;
}
static void PulseTransPreReadYMC(struct lib6145_ctx *ctx)
{
uint16_t overHang;
uint16_t printSizeWidth;
uint16_t *out;
#ifdef S6145_UNUSED
uint8_t *v1;
uint8_t *v2;
uint8_t *v3;
uint8_t *v4;
#endif
uint8_t *v14;
uint8_t *v15;
uint8_t *v16;
uint8_t *v17;
printSizeWidth = ctx->usPrintSizeWidth;
overHang = (ctx->usHeadDots - ctx->usPrintSizeWidth) / 2;
v17 = ctx->pusPreReadLineBufTab[2] + overHang;
v16 = ctx->pusPreReadLineBufTab[3] + overHang;
v15 = ctx->pusPreReadLineBufTab[4] + overHang;
v14 = ctx->pusPreReadLineBufTab[5] + overHang;
#ifdef S6145_UNUSED
v1 = ctx->pusPreReadLineBufTab[6] + overHang;
v2 = ctx->pusPreReadLineBufTab[7] + overHang;
v3 = ctx->pusPreReadLineBufTab[8] + overHang;
v4 = ctx->pusPreReadLineBufTab[9] + overHang;
#endif
out = ctx->pusPreReadOutLineBuf + overHang + ctx->sPrintSideOffset;
if ( out < ctx->pusPreReadOutLineBuf ) {
int32_t offset = (ctx->pusPreReadOutLineBuf - out);
out = ctx->pusPreReadOutLineBuf;
printSizeWidth = ctx->usPrintSizeWidth - offset;
v17 += offset;
v16 += offset;
v15 += offset;
v14 += offset;
// fprintf(stderr, "WARN: PulseTransPreReadYMC alt path!\n");
}
while ( printSizeWidth-- ) {
int32_t v6 = *v17++;
int32_t v7 = *v16++ + v6;
int32_t v8 = *v15++ + v7;
int32_t v9 = *v14++ + v8;
int32_t pixel = ctx->pusPulseTransTable[v9 / 4];
if ( pixel > MAX_PULSE )
pixel = MAX_PULSE;
*out++ = pixel;
}
}
static void CTankUpdateTankVolumeInterDot(struct lib6145_ctx *ctx, uint8_t tank)
{
int32_t *tankIn;
int32_t *tankOut;
int32_t conductivity;
uint16_t sheetSizeWidth;
uint16_t v1;
int32_t v2;
int32_t v4;
int32_t v5;
int32_t v8;
int32_t v17;
int32_t v18;
int32_t v19;
int32_t v20;
switch (tank) {
case 0:
tankIn = ctx->m_piFstTankArray;
tankOut = ctx->m_piFstTankArray + 2;
conductivity = ctx->m_iFstFstConductivity / 2;
break;
case 1:
tankIn = ctx->m_piSndTankArray;
tankOut = ctx->m_piSndTankArray + 2;
conductivity = ctx->m_iSndSndConductivity / 2;
break;
case 2:
tankIn = ctx->m_piTrdTankArray;
tankOut = ctx->m_piTrdTankArray + 2;
conductivity = ctx->m_iTrdTrdConductivity / 2;
break;
default:
return;
}
/* This code basically takes a running average of three running
averages, and uses that as the basis for the output */
tankIn[0] = tankIn[1] = tankIn[2];
v1 = ctx->usSheetSizeWidth + 1;
tankIn[v1+1] = tankIn[v1+2] = tankIn[v1];
v2 = *tankIn++;
v4 = *tankIn++;
v5 = *tankIn++;
v8 = *tankIn++;
v20 = *tankIn++;
v19 = conductivity * (v5 + v2 - 2 * v4);
v18 = conductivity * (v8 + v4 - 2 * v5);
v17 = conductivity * (v20 + v5 - 2 * v8);
sheetSizeWidth = ctx->usSheetSizeWidth;
while ( sheetSizeWidth-- ) {
int32_t pixel = (v18 >> 6) + v5 - (conductivity * ((2 * v18 - v19 - v17) >> 7) >> 7);
if ( pixel < 0 )
pixel = 0;
*tankOut++ = pixel;
v5 = v8;
v8 = v20;
v20 = *tankIn++;
v19 = v18;
v18 = v17;
v17 = conductivity * (v20 + v5 - 2 * v8);
}
}
static void CTankUpdateTankVolumeInterRay(struct lib6145_ctx *ctx)
{
uint16_t sheetWidth = ctx->usSheetSizeWidth;
int32_t *fstTankPtr = ctx->m_piFstTankArray + 2;
int32_t *sndTankPtr = ctx->m_piSndTankArray + 2;
int32_t *trdTankPtr = ctx->m_piTrdTankArray + 2;
while ( sheetWidth-- ) {
int32_t v2, v3;
v2 = (*sndTankPtr * ctx->m_iTankKeisuSndFstDivSnd - *fstTankPtr * ctx->m_iTankKeisuSndFstDivFst) >> 17;
*fstTankPtr = v2 + *fstTankPtr - (*fstTankPtr * ctx->m_iTankKeisuFstOutDivFst >> 17);
fstTankPtr++;
v3 = (*trdTankPtr * ctx->m_iTankKeisuTrdSndDivTrd - *sndTankPtr * ctx->m_iTankKeisuTrdSndDivSnd) >> 17;
*sndTankPtr = v3 + *sndTankPtr - v2;
sndTankPtr++;
*trdTankPtr = *trdTankPtr - v3 - (*trdTankPtr * ctx->m_iTankKeisuOutTrdDivTrd >> 17);
trdTankPtr++;
}
}
static void CTankHoseiPreread(struct lib6145_ctx *ctx)
{
uint16_t sheetWidth;
int16_t overHang;
int32_t *fstTankPtr;
uint16_t *outPtr;
int16_t *inPtr; /* Must treat this as SIGNED! */
int32_t v4;
overHang = (ctx->usHeadDots - ctx->usSheetSizeWidth) / 2;
inPtr = (int16_t*)ctx->pusPreReadOutLineBuf + overHang + ctx->sPrintSideOffset;
outPtr = ctx->pusOutLineBufTab[0] + overHang + ctx->sPrintSideOffset;
if ( outPtr < ctx->pusOutLineBufTab[0] )
outPtr = ctx->pusOutLineBufTab[0];
fstTankPtr = ctx->m_piFstTankArray + 2;
v4 = (1 << (ctx->uiMaxPulseBit + 20)) / ctx->m_iFstTankSize;
/* Walk forward through the line to compute the necessary delta */
sheetWidth = ctx->usSheetSizeWidth;
while ( sheetWidth-- ) {
int32_t v5 = *inPtr - (v4 * (*inPtr + *fstTankPtr++) >> 20);
int32_t v6 = 0;
if ( v5 < ctx->m_iPreReadLevelDiff )
v6 = -(ctx->m_iMinusMaxEnergyPreRead * v5 * v5) >> ctx->uiMaxPulseBit;
*inPtr++ = v6;
}
/* Now walk backwards through the line to derive the desired pixel
values, adding the actual value with the necessary delta.. */
outPtr += ctx->usSheetSizeWidth;
sheetWidth = ctx->usSheetSizeWidth;
while ( sheetWidth-- ) {
int32_t pixel;
inPtr--;
outPtr--;
pixel = *inPtr + *outPtr;
if ( pixel < 0 )
pixel = 0;
if ( pixel > ctx->iMaxPulseValue )
pixel = ctx->iMaxPulseValue;
*outPtr = pixel;
}
}
/* Apply the correction needed based on the thermal tanks */
static void CTankHosei(struct lib6145_ctx *ctx)
{
uint16_t overHang;
uint16_t sheetSizeWidth;
int32_t *tankPtr;
uint8_t *in;
uint16_t *out;
int32_t v4;
#ifdef S6145_UNUSED
int32_t v2;
int32_t *v12;
#endif
sheetSizeWidth = ctx->usSheetSizeWidth;
overHang = (ctx->usHeadDots - ctx->usSheetSizeWidth) / 2;
out = ctx->pusOutLineBufTab[0] + (overHang + ctx->sPrintSideOffset);
in = ctx->pusPulseTransLineBufTab[1] + overHang;
if ( out >= ctx->pusOutLineBufTab[0] ) {
int32_t offset = ctx->sPrintSideOffset + sheetSizeWidth + overHang;
if ( offset > BUF_SIZE ) {
offset -= BUF_SIZE;
sheetSizeWidth -= offset;
}
} else {
int32_t offset = (ctx->pusOutLineBufTab[0] - out);
sheetSizeWidth -= offset;
in += (out - ctx->pusOutLineBufTab[0]); // XXX was: in += out;
out = ctx->pusOutLineBufTab[0];
// fprintf(stderr, "WARN: CTankHosei() alt path\n");
}
tankPtr = ctx->m_piFstTankArray + 2;
#ifdef S6145_UNUSED
v2 = ctx->m_iPlusMaxEnergy;
v12 = &v2;
#endif
v4 = (1 << (ctx->uiMaxPulseBit + 20)) / ctx->m_iFstTankSize;
while ( sheetSizeWidth-- ) {
int32_t v5;
int32_t v8;
uint16_t v11;
uint32_t v3 = *in++;
v5 = *out - ((v4 * (*out + *tankPtr)) >> 20);
if ( v5 < 0 )
v11 = ctx->pusTankMinusMaxEnegyTable[v3];
else
v11 = ctx->pusTankPlusMaxEnegyTable[v3];
v8 = *out + ((v5 * v11) >> ctx->uiMaxPulseBit);
if ( v8 < 0 )
v8 = 0;
if ( v8 > ctx->iMaxPulseValue )
v8 = ctx->iMaxPulseValue;
*out++ = v8;
*tankPtr++ += v8;
}
}
/* Apply final corrections to the output. */
#define LINECORR_BUCKETS 4
static void LineCorrection(struct lib6145_ctx *ctx)
{
uint16_t sheetSizeWidth;
uint16_t overHang;
uint8_t *in;
uint16_t *out;
uint32_t bucket[LINECORR_BUCKETS];
uint32_t correct;
uint8_t i;
sheetSizeWidth = ctx->usSheetSizeWidth;
overHang = (ctx->usHeadDots - ctx->usSheetSizeWidth) / 2;
in = ctx->pusPulseTransLineBufTab[1] + overHang;
out = ctx->pusOutLineBufTab[0] + overHang + ctx->sPrintSideOffset;
if ( out >= ctx->pusOutLineBufTab[0] ) {
uint32_t tmp = ctx->sPrintSideOffset + sheetSizeWidth + overHang;
if ( tmp > BUF_SIZE ) {
tmp -= BUF_SIZE;
sheetSizeWidth -= tmp;
}
} else {
uint32_t tmp = ctx->pusOutLineBufTab[0] - out;
sheetSizeWidth -= tmp;
in += (out - ctx->pusOutLineBufTab[0]); // XXX was: in += out;
out = ctx->pusOutLineBufTab[0];
// fprintf(stderr, "WARN: LineCorrection() alt path\n");
}
/* Apply the correction compensation */
bucket[0] = bucket[1] = bucket[2] = bucket[3] = 0;
for ( i = 0; i < LINECORR_BUCKETS; i++ ) {
uint16_t j = sheetSizeWidth / LINECORR_BUCKETS;
while ( j-- ) {
int32_t pixel = *out;
bucket[i] += pixel;
pixel -= ctx->pusLineHistCoefTable[*in++] * ctx->iLineCorrectPulse / 1024;
if ( pixel < 0 )
pixel = 0;
*out++ = pixel;
}
}
/* See if we need to increase the correction compensation */
correct = 0;
for ( i = 0; i < LINECORR_BUCKETS; i++ ) {
if ( ctx->uiLineCorrectBase1Line / LINECORR_BUCKETS <= bucket[i] )
correct++;
}
if ( correct ) {
for ( i = 0; i < LINECORR_BUCKETS; i++ )
ctx->uiLineCorrectSum += bucket[i];
}
if ( ctx->uiLineCorrectSum > ctx->uiLineCorrectBase ) {
ctx->uiLineCorrectSum -= ctx->uiLineCorrectBase;
if ( ctx->iLineCorrectPulse < ctx->iLineCorrectPulseMax )
ctx->iLineCorrectPulse++;
}
}
#ifdef S6145_UNUSED
/* XXX all of these functions are present in the library, but not actually
referenced by anything, so there's no point in worrying about them. */
static void SideEdgeCorrection(struct lib6145_ctx *ctx)
{
int32_t v0;
uint32_t v1;
uint8_t *v4;
uint16_t *v5;
uint8_t *v6;
uint8_t *v7;
uint16_t *out;
uint16_t *v9;
uint32_t v10;
uint32_t v11;
int32_t v12;
int32_t v13;
int32_t v14;
int32_t v15;
int32_t v16;
v16 = ctx->usSheetSizeWidth;
v0 = (ctx->usHeadDots - ctx->usSheetSizeWidth) / 2;
v6 = ctx->pusPulseTransLineBufTab[1] + v0;
out = ctx->pusOutLineBufTab[0] + ctx->sPrintSideOffset + v0;
v11 = 0;
if ( out >= ctx->pusOutLineBufTab[0] ) {
v10 = ctx->sPrintSideOffset
+ ctx->usSheetSizeWidth
+ v0;
if ( v10 > BUF_SIZE )
{
v10 -= BUF_SIZE;
v16 = ctx->usSheetSizeWidth - v10;
}
} else {
v1 = ctx->pusOutLineBufTab[0] - out;
out = ctx->pusOutLineBufTab[0];
v16 = ctx->usSheetSizeWidth - v1;
v10 = v11;
}
v5 = out + 2 * v16;
v4 = v16 + v6;
v14 = 128 - v11;
while ( v14 ) {
v12 = (((1024 - ctx->pusSideEdgeLvCoefTable[*v6++] * (uint32_t)ctx->pusSideEdgeCoefTable[128 - v14--]) >> 10) * *out) >> 10;
if ( v12 > ctx->iMaxPulseValue )
v12 = ctx->iMaxPulseValue;
*out++ = v12;
}
v9 = v5;
v7 = v4;
v15 = 128 - v10;
while ( v15 ) {
v9--;
--v7;
v13 = ((1024 - (ctx->pusSideEdgeLvCoefTable[*v7] * (uint32_t)ctx->pusSideEdgeCoefTable[128 - v15--]) >> 10) * *v9) >> 10;
if ( ctx->iMaxPulseValue < v13 )
v13 = ctx->iMaxPulseValue;
*v9 = v13;
}
}
static void LeadEdgeCorrection(struct lib6145_ctx *ctx)
{
uint32_t v0;
uint16_t *out;
int32_t v4;
uint32_t v5;
int32_t v6;
if ( ctx->iLeadEdgeCorrectPulse ) {
v6 = ctx->usSheetSizeWidth;
out = ctx->pusOutLineBufTab[0] + ctx->sPrintSideOffset
+ ((ctx->usHeadDots - ctx->usSheetSizeWidth) / 2);
if ( out >= ctx->pusOutLineBufTab[0] ) {
v5 = ctx->sPrintSideOffset
+ ctx->usSheetSizeWidth
+ ((ctx->usHeadDots - ctx->usSheetSizeWidth) / 2);
if ( v5 > BUF_SIZE )
v6 = ctx->usSheetSizeWidth - (v5 - BUF_SIZE);
} else {
v0 = ctx->pusOutLineBufTab[0] - out;
out = ctx->pusOutLineBufTab[0];
v6 = ctx->usSheetSizeWidth - v0;
}
while ( v6-- ) {
v4 = (ctx->iLeadEdgeCorrectPulse / 4) + *out;
if ( v4 > ctx->iMaxPulseValue )
v4 = ctx->iMaxPulseValue;
*out++ = v4;
}
--ctx->iLeadEdgeCorrectPulse;
}
}
static void RecieveDataOP_Post(struct lib6145_ctx *ctx)
{
return;
}
static void RecieveDataYMC_Post(struct lib6145_ctx *ctx)
{
return;
}
static void RecieveDataOPLevel_Post(struct lib6145_ctx *ctx)
{
return;
}
static void RecieveDataOPMatte_Post(struct lib6145_ctx *ctx)
{
return;
}
static void ImageLevelAddition(struct lib6145_ctx *ctx)
{
if ( ctx->uiLevelAveCounter < ctx->usPrintSizeHeight )
{
ImageLevelAdditionEx(ctx, &ctx->uiLevelAveAddtion, 0, ctx->usSheetSizeWidth);
ctx->uiLevelAveCounter++;
if ( ctx->uiLevelAveCounter2-- == 0 )
{
ImageLevelAdditionEx(ctx,
&ctx->uiLevelAveAddtion2,
ctx->uiOffsetCancelCheckPRec,
ctx->usCancelCheckDotsForPRec);
++ctx->uiLevelAveCounter2;
}
}
}
static void ImageLevelAdditionEx(struct lib6145_ctx *ctx, uint32_t *a1, uint32_t a2, int32_t a3)
{
int32_t v3;
uint8_t *v6;
int32_t i;
int32_t v8;
v6 = ctx->pusPulseTransLineBufTab[1] + a2 +
((ctx->usHeadDots - ctx->usSheetSizeWidth) / 2);
v8 = a3;
for ( i = 0; v8-- ; i += v3 ) {
v3 = *v6++;
}
*a1 += i;
}
#endif /* S6145_UNUSED */