mitsu98xx: Implement proper gamma correction code in lib70x

- Bump version & API version
 - Move all table loading and manipulation out of mitsu9550 backend
 - Everything but sharpening is implemented
 - COMPLETELY UNTESTED!
master
Solomon Peachy 3 years ago
parent c8568147b4
commit 561eb90a61

@ -29,11 +29,11 @@
int mitsu_loadlib(struct mitsu_lib *lib, int type)
{
DL_INIT();
memset(lib, 0, sizeof(*lib));
#if defined(WITH_DYNAMIC)
DL_INIT();
DEBUG("Attempting to load image processing library\n");
lib->dl_handle = DL_OPEN(LIB_NAME_RE);
if (!lib->dl_handle)
@ -62,7 +62,12 @@ int mitsu_loadlib(struct mitsu_lib *lib, int type)
lib->DoImageEffect70 = DL_SYM(lib->dl_handle, "do_image_effect70");
lib->DoImageEffect80 = DL_SYM(lib->dl_handle, "do_image_effect80");
lib->SendImageData = DL_SYM(lib->dl_handle, "send_image_data");
lib->CP98xx_DoConvert = DL_SYM(lib->dl_handle, "CP98xx_DoConvert");
lib->CP98xx_GetData = DL_SYM(lib->dl_handle, "CP98xx_GetData");
lib->CP98xx_DestroyData = DL_SYM(lib->dl_handle, "CP98xx_DestroyData");
if (!lib->Load3DColorTable ||
!lib->CP98xx_DoConvert || !lib->CP98xx_GetData ||
!lib->CP98xx_DestroyData ||
!lib->Destroy3DColorTable || !lib->DoColorConv ||
!lib->GetCPCData || !lib->DestroyCPCData ||
!lib->DoImageEffect60 || !lib->DoImageEffect70 ||
@ -88,12 +93,16 @@ int mitsu_loadlib(struct mitsu_lib *lib, int type)
case P_FUJI_ASK300:
lib->DoImageEffect = lib->DoImageEffect70;
break;
case P_MITSU_9800:
case P_MITSU_9800S:
case P_MITSU_9810:
default:
lib->DoImageEffect = NULL;
}
return CUPS_BACKEND_OK;
#else
ERROR("Need dynamic library support for library loading!\n");
return CUPS_BACKEND_FAILED;
#endif
}

@ -28,6 +28,25 @@
#include "lib70x/libMitsuD70ImageReProcess.h"
/* If we don't have the libMitsu header */
#ifndef LUT_LEN
#define COLORCONV_RGB 0
#define COLORCONV_BGR 1
#define LUT_LEN 14739
struct BandImage {
void *imgbuf; // @0
int32_t bytes_per_row;// @4 bytes per row (respect 8bpp and 16bpp!)
uint16_t origin_cols; // @8 origin_cols
uint16_t origin_rows; // @12 origin_rows
uint16_t cols; // @16 cols
uint16_t rows; // @20 rows
// @24
};
struct mitsu98xx_data; /* Forward declaration */
#endif
typedef int (*lib70x_getapiversionFN)(void);
typedef int (*Get3DColorTableFN)(uint8_t *buf, const char *filename);
typedef struct CColorConv3D *(*Load3DColorTableFN)(const uint8_t *ptr);
@ -39,13 +58,20 @@ typedef int (*do_image_effectFN)(struct CPCData *cpc, struct CPCData *ecpc, stru
typedef int (*send_image_dataFN)(struct BandImage *out, void *context,
int (*callback_fn)(void *context, void *buffer, uint32_t len));
typedef int (*CP98xx_DoConvertFN)(const struct mitsu98xx_data *table,
const struct BandImage *input,
struct BandImage *output,
uint8_t type, int sharpness);
typedef struct mitsu98xx_data *(*CP98xx_GetDataFN)(const char *filename);
typedef void (*CP98xx_DestroyDataFN)(const struct mitsu98xx_data *data);
#ifndef WITH_DYNAMIC
#warning "No dynamic loading support!"
#endif
#define REQUIRED_LIB_APIVERSION 4
#define LIBMITSU_VER "0.01"
#define LIBMITSU_VER "0.03"
/* Image processing library function prototypes */
#define LIB_NAME_RE "libMitsuD70ImageReProcess" DLL_SUFFIX
@ -71,6 +97,9 @@ struct mitsu_lib {
do_image_effectFN DoImageEffect80;
do_image_effectFN DoImageEffect;
send_image_dataFN SendImageData;
CP98xx_DoConvertFN CP98xx_DoConvert;
CP98xx_GetDataFN CP98xx_GetData;
CP98xx_DestroyDataFN CP98xx_DestroyData;
struct CColorConv3D *lut;
struct CPCData *cpcdata;

@ -38,7 +38,6 @@
#define MITSU_M98xx_DATATABLE_FILE CORRTABLE_PATH "/M98TABLE.dat"
#define MITSU_M98xx_LUT_FILE CORRTABLE_PATH "/M98XXL01.lut"
#define LAMINATE_STRIDE 1868
#define DATATABLE_SIZE 42204
/* USB VIDs and PIDs */
@ -103,37 +102,6 @@ struct mitsu9550_plane {
uint16_t rows; /* BE */
} __attribute__((packed));
/* CP98xx Tabular Data, as stored in data file! */
struct mitsu98xx_data {
/* @ 0 */ uint16_t GNMby[256]; /* BGR Order uncertain */
/* @ 512 */ uint16_t GNMgm[256];
/* @ 1024 */ uint16_t GNMrc[256];
/* @ 1536 */ uint16_t unk_sharp[20]; /* Actual format is: u16, u16[9], u16, u16[9] */
/* @ 1576 */ double GammaAdj[3]; /* Assumed to be same order as tables (BGR?) */
/* @ 1600 */ struct {
/* @ 0 */ double unka[256];
/* @ 2048 */ double unkb[256];
/* @ 4096 */ double unkc[5]; /* Weight factors */
/* @ 4136 */ double unkd[256];
/* @ 6184 */ double unke[256]; // *= sharp->coef[X]
/* @ 8232 */ double unkf[5]; /* Weight factors */
/* @ 8272 */ double unkg[256];
/* @10320 */
} WMAM;
/* @11920 */ double sharp_coef[11]; /* 0 is off, 1-10 are the levels. Default is 5. [4 in settings] */
/* @12008 */ uint32_t KHStart;
/* @12012 */ uint32_t KHEnd;
/* @12016 */ uint32_t KHStep;
/* @12020 */ double KH[256];
/* @14068 */
} __attribute__((packed));
struct mitsu98xx_tables {
struct mitsu98xx_data superfine;
struct mitsu98xx_data fine_std;
struct mitsu98xx_data fine_hg;
} __attribute__((packed));
/* Command header */
struct mitsu9550_cmd {
uint8_t cmd[4];
@ -174,7 +142,7 @@ struct mitsu9550_ctx {
/* CP98xx stuff */
struct mitsu_lib lib;
struct mitsu98xx_tables *m98xxdata;
const struct mitsu98xx_data *m98xxdata;
};
/* Printer data structures */
@ -264,16 +232,6 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob);
} \
} while (0);
static void mitsu98xx_dogamma(uint8_t *src, uint16_t *dest, uint8_t plane,
uint16_t *table, uint32_t len)
{
src += plane;
while(len--) {
*dest++ = cpu_to_be16(table[*src]);
src += 3;
}
}
static int mitsu98xx_fillmatte(struct mitsu9550_printjob *job)
{
int ret;
@ -349,7 +307,7 @@ static int mitsu9550_attach(void *vctx, struct libusb_device_handle *dev, int ty
if (mitsu_loadlib(&ctx->lib, ctx->type))
return CUPS_BACKEND_FAILED;
#else
WARNING("Dynamic library support not enabled, using internal fallback code\n");
WARNING("Dynamic library support not enabled, will be unable to print.");
#endif
skip:
if (test_mode < TEST_MODE_NOATTACH) {
@ -391,7 +349,7 @@ static void mitsu9550_teardown(void *vctx) {
return;
if (ctx->m98xxdata)
free(ctx->m98xxdata);
ctx->lib.CP98xx_DestroyData(ctx->m98xxdata);
mitsu_destroylib(&ctx->lib);
@ -495,57 +453,11 @@ hdr_done:
/* Read in CP98xx data tables if necessary */
if (ctx->is_98xx && !job->is_raw && !ctx->m98xxdata) {
int ret;
ctx->m98xxdata = malloc(DATATABLE_SIZE);
if (!ctx->m98xxdata) {
ERROR("Memory allocation Failure!\n");
mitsu9550_cleanup_job(job);
return CUPS_BACKEND_RETRY_CURRENT;
}
DEBUG("Reading in 98xx data from disk\n");
if ((ret = dyesub_read_file(MITSU_M98xx_DATATABLE_FILE, ctx->m98xxdata, DATATABLE_SIZE, NULL))) {
ctx->m98xxdata = ctx->lib.CP98xx_GetData(MITSU_M98xx_DATATABLE_FILE);
if (!ctx->m98xxdata) {
ERROR("Unable to read 98xx data table file '%s'\n", MITSU_M98xx_DATATABLE_FILE);
free(ctx->m98xxdata);
return ret;
}
/* Byteswap data table to native endianness, if necessary */
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
int j;
struct mitsu98xx_data *ptr = &ctx->m98xxdata->superfine;
for (j = 0 ; j < 3 ; j++) {
ptr->KHStart = be32_to_cpu(ptr->KHStart);
ptr->KHEnd = be32_to_cpu(ptr->KHEnd);
ptr->KHStep = be32_to_cpu(ptr->KHStep);
for (i = 3 ; i < 3 ; i++) {
ptr->GammaAdj[i] = be64_to_cpu(ptr->GammaAdj[i]);
}
for (i = 0 ; i < 5 ; i++) {
ptr->WMAM.unkc[i] = be64_to_cpu(ptr->WMAM.unkc[i]);
ptr->WMAM.unkf[i] = be64_to_cpu(ptr->WMAM.unkf[i]);
}
for (i = 0 ; i < 11 ; i++) {
ptr->sharp_coef[i] = be64_to_cpu(ptr->sharp_coef[i]);
}
for (i = 0 ; i < 20 ; i++) {
ptr->unk_sharp[i] = be16_to_cpu(ptr->unk_sharp[i]);
}
for (i = 0 ; i < 256 ; i++) {
ptr->WMAM.unka[i] = be64_to_cpu(ptr->WMAM.unka[i]);
ptr->WMAM.unkb[i] = be64_to_cpu(ptr->WMAM.unkb[i]);
ptr->WMAM.unkd[i] = be64_to_cpu(ptr->WMAM.unkd[i]);
ptr->WMAM.unke[i] = be64_to_cpu(ptr->WMAM.unke[i]);
ptr->WMAM.unkg[i] = be64_to_cpu(ptr->WMAM.unkg[i]);
ptr->GNMby[i] = be16_to_cpu(ptr->GNMby[i]);
ptr->GNMgm[i] = be16_to_cpu(ptr->GNMgm[i]);
ptr->GNMrc[i] = be16_to_cpu(ptr->GNMrc[i]);
ptr->KH[i] = be64_to_cpu(ptr->KH[i]);
}
ptr++;
}
#endif
}
if (job->is_raw) {
@ -994,11 +906,11 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) {
/* Do the 98xx processing here */
if (!ctx->is_98xx || job->is_raw)
goto bypass;
goto non_98xx;
/* Special CP98xx handling code */
uint8_t *newbuf;
uint32_t newlen = 0;
struct mitsu98xx_data *table;
int i, remain, planelen;
planelen = job->rows * job->cols * 2;
@ -1008,58 +920,64 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) {
ERROR("Memory allocation Failure!\n");
return CUPS_BACKEND_RETRY_CURRENT;
}
switch (job->hdr2.mode) {
case 0x80:
table = &ctx->m98xxdata->superfine;
break;
case 0x11:
table = &ctx->m98xxdata->fine_hg;
job->hdr2.mode = 0x10;
break;
case 0x10:
default:
table = &ctx->m98xxdata->fine_std;
break;
DEBUG("Running print data through processing library\n");
/* Create band images for input and output */
struct BandImage input;
struct BandImage output;
uint8_t *convbuf = malloc(planelen * 3);
if (!convbuf) {
free(newbuf);
ERROR("Memory allocation Failure!\n");
return CUPS_BACKEND_RETRY_CURRENT;
}
DEBUG("Applying 8bpp->12bpp Gamma Correction\n");
#pragma GCC diagnostic push
#if (defined(__GNUC__) && (__GNUC__ >= 9))
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
#endif
/* For B/Y plane */
input.origin_rows = input.origin_cols = 0;
input.rows = job->rows;
input.cols = job->cols;
input.imgbuf = job->databuf + sizeof(struct mitsu9550_plane);
input.bytes_per_row = job->cols * 3;
output.origin_rows = output.origin_cols = 0;
output.rows = job->rows;
output.cols = job->cols;
output.imgbuf = convbuf;
output.bytes_per_row = job->cols * 3 * 2;
int sharpness = 4; // XXX make a parameter via hdr extension.
if (!ctx->lib.CP98xx_DoConvert(ctx->m98xxdata, &input, &output, job->hdr2.mode, sharpness)) {
free(convbuf);
free(newbuf);
ERROR("CP98xx_DoConvert() failed!\n");
return CUPS_BACKEND_FAILED;
}
if (job->hdr2.mode == 0x11)
job->hdr2.mode = 0x10;
/* We're done. Wrap YMC16 data with appropriate plane headers */
memcpy(newbuf + newlen, job->databuf, sizeof(struct mitsu9550_plane));
newbuf[newlen + 3] = 0x10; /* ie 16bpp data */
newlen += sizeof(struct mitsu9550_plane);
mitsu98xx_dogamma(job->databuf + sizeof(struct mitsu9550_plane),
(uint16_t*) (newbuf + newlen),
0,
table->GNMby,
planelen / 2);
memcpy(newbuf + newlen, convbuf + 0 * planelen, planelen);
newlen += planelen;
/* For G/M plane */
memcpy(newbuf + newlen, job->databuf, sizeof(struct mitsu9550_plane));
newbuf[newlen + 3] = 0x10; /* ie 16bpp data */
newlen += sizeof(struct mitsu9550_plane);
mitsu98xx_dogamma(job->databuf + sizeof(struct mitsu9550_plane),
(uint16_t*) (newbuf + newlen),
1,
table->GNMgm,
planelen / 2);
memcpy(newbuf + newlen, convbuf + 1 * planelen, planelen);
newlen += planelen;
/* For R/C plane */
memcpy(newbuf + newlen, job->databuf, sizeof(struct mitsu9550_plane));
newbuf[newlen + 3] = 0x10; /* ie 16bpp data */
newlen += sizeof(struct mitsu9550_plane);
mitsu98xx_dogamma(job->databuf + sizeof(struct mitsu9550_plane),
(uint16_t*) (newbuf + newlen),
2,
table->GNMrc,
planelen / 2);
memcpy(newbuf + newlen, convbuf + 2 * planelen, planelen);
newlen += planelen;
#pragma GCC diagnostic pop
/* All done with conversion buffer, nuke it */
free(convbuf);
/* And finally, the job footer. */
memcpy(newbuf + newlen, job->databuf + sizeof(struct mitsu9550_plane) + planelen/2 * 3, sizeof(struct mitsu9550_cmd));
@ -1078,7 +996,7 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) {
}
}
bypass:
non_98xx:
/* Bypass */
if (test_mode >= TEST_MODE_NOPRINT)
return CUPS_BACKEND_OK;
@ -1537,7 +1455,7 @@ static const char *mitsu9550_prefixes[] = {
/* Exported */
struct dyesub_backend mitsu9550_backend = {
.name = "Mitsubishi CP9xxx family",
.version = "0.50" " (lib " LIBMITSU_VER ")",
.version = "0.51" " (lib " LIBMITSU_VER ")",
.uri_prefixes = mitsu9550_prefixes,
.cmdline_usage = mitsu9550_cmdline,
.cmdline_arg = mitsu9550_cmdline_arg,

@ -1,7 +1,7 @@
/* LibMitsuD70ImageReProcess -- Re-implemented image processing library for
the Mitsubishi CP-D70 family of printers
Copyright (c) 2016-2019 Solomon Peachy <pizza@shaftnet.org>
Copyright (c) 2016-2020 Solomon Peachy <pizza@shaftnet.org>
** ** ** ** Do NOT contact Mitsubishi about this library! ** ** ** **
@ -26,6 +26,13 @@
* Kodak 305
* Fujifilm ASK-300
More recently, the CP98xx family now uses this library. These
models are expected to function:
* Mitsubishi CP9800DW
* Mitsubishi CP9810DW
* Mitsubishi CP9820DW-S
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
This program is free software; you can redistribute it and/or modify it
@ -45,7 +52,7 @@
*/
#define LIB_VERSION "0.7.3"
#define LIB_VERSION "0.8.0"
#include <stdio.h>
#include <stdint.h>
@ -1474,3 +1481,933 @@ void CImageUtility_CreateBandImage16(struct BandImage *img, uint32_t *a2, int32_
}
#endif
/* XXXX XXXX CP98XX */
struct CP98xx_WMAM {
/* @ 0 */ double unka[256];
/* @ 2048 */ double unkb[256];
/* @ 4096 */ double unkc[5]; /* Weight factors */
/* @ 4136 */ double unkd[256];
/* @ 6184 */ double unke[256]; // *= sharp->coef[X]
/* @ 8232 */ double unkf[5]; /* Weight factors */
/* @ 8272 */ double unkg[256];
/* @10320 */
};
/* CP98xx Tabular Data, as stored in data file! */
struct mitsu98xx_data {
/* @ 0 */ uint16_t GNMby[256]; /* BGR Order uncertain */
/* @ 512 */ uint16_t GNMgm[256];
/* @ 1024 */ uint16_t GNMrc[256];
/* @ 1536 */ int16_t sharp[20]; /* Actual format is: u16, u16[9], u16, u16[9] */
/* @ 1576 */ double GammaAdj[3]; /* Assumed to be same order as tables (BGR?) */
/* @ 1600 */ struct CP98xx_WMAM WMAM;
/* @11920 */ double sharp_coef[11]; /* 0 is off, 1-10 are the levels. Default is 5. [4 in settings] */
/* @12008 */ uint32_t KHStart;
/* @12012 */ uint32_t KHEnd;
/* @12016 */ uint32_t KHStep;
/* @12020 */ double KH[256];
/* @14068 */
} __attribute__((packed));
struct mitsu98xx_tables {
struct mitsu98xx_data superfine;
struct mitsu98xx_data fine_std;
struct mitsu98xx_data fine_hg;
} __attribute__((packed));
#define M98XX_DATATABLE_SIZE 42204
struct CP98xx_KHParams {
double KH[256];
int32_t Start;
int32_t End;
int32_t Step;
};
struct CP98xx_GammaParams {
uint16_t GNMby[256];
uint16_t GNMgm[256];
uint16_t GNMrc[256];
double GammaAdj[3];
};
struct CP98xx_AptParams {
int16_t mask[8][6]; // really is [8][6]
int unsharp;
int mpx10;
};
struct mitsu98xx_data *CP98xx_GetData(const char *filename)
{
struct mitsu98xx_data *data = NULL;
FILE *stream;
int rval;
if (!filename || !*filename)
return NULL;
data = malloc(M98XX_DATATABLE_SIZE);
if (!data)
return NULL;
stream = fopen(filename, "rb");
if (!stream) {
free(data);
return NULL;
}
fseek(stream, 0, SEEK_END);
if (ftell(stream) < M98XX_DATATABLE_SIZE) {
fclose(stream);
free(data);
return NULL;
}
fseek(stream, 0, SEEK_SET);
rval = fread(data, M98XX_DATATABLE_SIZE, 1, stream);
fclose(stream);
if (rval != 1) {
free(data);
return NULL;
}
/* Byteswap data table to native endianness, if necessary */
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
int i, j;
for (j = 0 ; j < 3 ; j++) {
data[j].KHStart = be32_to_cpu(data[j].KHStart);
data[j].KHEnd = be32_to_cpu(data[j].KHEnd);
data[j].KHStep = be32_to_cpu(data[j].KHStep);
for (i = 3 ; i < 3 ; i++) {
data[j].GammaAdj[i] = be64_to_cpu(data[j].GammaAdj[i]);
}
for (i = 0 ; i < 5 ; i++) {
data[j].WMAM.unkc[i] = be64_to_cpu(data[j].WMAM.unkc[i]);
data[j].WMAM.unkf[i] = be64_to_cpu(data[j].WMAM.unkf[i]);
}
for (i = 0 ; i < 11 ; i++) {
data[j].sharp_coef[i] = be64_to_cpu(data[j].sharp_coef[i]);
}
for (i = 0 ; i < 20 ; i++) {
data[j].sharp[i] = be16_to_cpu(data[j].sharp[i]);
}
for (i = 0 ; i < 256 ; i++) {
data[j].WMAM.unka[i] = be64_to_cpu(data[j].WMAM.unka[i]);
data[j].WMAM.unkb[i] = be64_to_cpu(data[j].WMAM.unkb[i]);
data[j].WMAM.unkd[i] = be64_to_cpu(data[j].WMAM.unkd[i]);
data[j].WMAM.unke[i] = be64_to_cpu(data[j].WMAM.unke[i]);
data[j].WMAM.unkg[i] = be64_to_cpu(data[j].WMAM.unkg[i]);
data[j].GNMby[i] = be16_to_cpu(data[j].GNMby[i]);
data[j].GNMgm[i] = be16_to_cpu(data[j].GNMgm[i]);
data[j].GNMrc[i] = be16_to_cpu(data[j].GNMrc[i]);
data[j].KH[i] = be64_to_cpu(data[j].KH[i]);
}
}
#endif
return data;
}
void CP98xx_DestroyData(const struct mitsu98xx_data *data)
{
free((void*)data);
}
/* return 1 if it's ok, 0 if bad */
static int CP98xx_DoCorrectGammaTbl(struct CP98xx_GammaParams *Gamma,
const struct CP98xx_KHParams *KH,
const struct BandImage *img)
{
int end, start, cols, rows, step, bytesPerRow;
int i, j;
int64_t elements, max;
int curCol, curRowBufOffset;
uint8_t *rowPtr;
int in_r9 = 0; // XXX
if (KH->Step < 1 || KH->End < KH->Start)
return 1;
if (KH->Start < 0 ||
img->cols <= KH->End ||
img->cols <= KH->Start ||
img->origin_cols ||
img->origin_rows)
return 0;
cols = img->cols - img->origin_cols;
rows = img->rows - img->origin_rows;
bytesPerRow = img->bytes_per_row;
if (bytesPerRow < 0) {
if (in_r9 == 0) {
bytesPerRow = -bytesPerRow;
rowPtr = img->imgbuf - -bytesPerRow * (rows - 1);
} else {
rowPtr = img->imgbuf;
}
} else {
if (in_r9 != 0) {
rowPtr = img->imgbuf - -bytesPerRow * (rows - 1);
} else {
bytesPerRow = -bytesPerRow;
rowPtr = img->imgbuf;
}
}
step = KH->Step;
end = KH->End;
start = KH->Start;
elements = step * ((end - start) + 1);
max = elements * 0xff;
for (j = 0 ; j < rows / step ; j++) {
int k;
int64_t sum1, sum2, sum3, sum4, sum5, sum6;
int iVar4 = (cols - end) -1;
sum6 = 0;
sum5 = 0;
sum4 = 0;
sum3 = 0;
sum2 = 0;
sum1 = 0;
for (k = 0 ; k < step ; k++) {
curRowBufOffset = start * 3;
curCol = start;
while (curCol < (end + 1)) {
int offset = curRowBufOffset;
sum3 += rowPtr[offset];
sum2 += rowPtr[offset + 1];
sum1 += rowPtr[offset + 2];
curRowBufOffset = offset + 3;
curCol++;
}
curRowBufOffset = iVar4 * 3;
curCol = iVar4;
while (curCol < (cols - start)) {
int offset2 = curRowBufOffset;
sum6 += rowPtr[offset2];
sum5 += rowPtr[offset2 + 1];
sum4 += rowPtr[offset2 + 2];
curRowBufOffset = offset2 + 3;
curCol++;
}
rowPtr -= bytesPerRow;
}
if (sum6 < max) {
max = sum6;
}
if (sum5 < max) {
max = sum5;
}
if (sum4 < max) {
max = sum4;
}
if (sum3 < max) {
max = sum3;
}
if (sum2 < max) {
max = sum2;
}
if (sum1 < max) {
max = sum1;
}
}
int gammaMaxCalc;
uint16_t baseRC, baseGM, baseBY;
double baseKH;
gammaMaxCalc = ((double)max / (double)elements) + 0.5;
baseRC = Gamma->GNMrc[255];
baseGM = Gamma->GNMgm[255];
baseBY = Gamma->GNMby[255];
baseKH = KH->KH[gammaMaxCalc];
for (i = 0; i < 256 ; i++) {
Gamma->GNMrc[i] = baseRC +
(baseKH * (Gamma->GNMrc[i] - baseRC)) + 0.5;
Gamma->GNMrc[i] = baseGM +
(baseKH * (Gamma->GNMgm[i] - baseGM)) + 0.5;
Gamma->GNMby[i] = baseGM +
(baseKH * (Gamma->GNMby[i] - baseBY)) + 0.5;
}
return 1;
}
static int CP98xx_DoGammaConv(struct CP98xx_GammaParams *Gamma,
const struct BandImage *inImage,
struct BandImage *outImage)
{
int cols, cols2, rows, inBytesPerRow, tmp, maxTank;
uint8_t *inRowPtr;
uint16_t *outRowPtr;
double gammaAdj0;
int pixelsPerRow;
int in_r8 = 0; // XXXX figure this one out..
cols = inImage->cols - inImage->origin_cols;
rows = inImage->rows - inImage->origin_rows;
tmp = inImage->bytes_per_row;
if ((cols < 1) || (rows < 1) || (tmp == 0))
return 0;
if (tmp < 0) {
if (in_r8 == 0) {
inBytesPerRow = -tmp;
pixelsPerRow = -outImage->bytes_per_row >> 1;
inRowPtr = ((rows + -1) * -tmp + inImage->imgbuf);
outRowPtr = (pixelsPerRow * (rows * 2 + -2) + outImage->imgbuf);
} else {
inBytesPerRow = tmp;
pixelsPerRow = outImage->bytes_per_row >> 1;
inRowPtr = inImage->imgbuf;
outRowPtr = outImage->imgbuf;
}
} else {
if (in_r8 != 0) {
inBytesPerRow = tmp;
pixelsPerRow = outImage->bytes_per_row >> 1;
outRowPtr = (pixelsPerRow * (rows * 2 + -2) + outImage->imgbuf);
inRowPtr = ((rows + -1) * inImage->bytes_per_row + inImage->imgbuf);
} else {
inBytesPerRow = -tmp;
pixelsPerRow = (-outImage->bytes_per_row) >> 1;
inRowPtr = inImage->imgbuf;
outRowPtr = outImage->imgbuf;
}
}
tmp = 0;
cols2 = cols;
maxTank = cols2 * 255;
gammaAdj0 = Gamma->GammaAdj[0];
int outVal;
double dVar2 = 0.0;
double calc2, calc1, calc0;
int curRowBufOffset, curCol;
while ((outVal = rows, tmp < outVal &&
(dVar2 = gammaAdj0, 0.50000000 <= dVar2))) {
calc1 = 0.00000000;
curRowBufOffset = 0;
curCol = 0;
calc2 = calc1;
calc0 = calc1;
while (curCol < cols2) {
calc2 += inRowPtr[2 + curRowBufOffset];
calc1 += inRowPtr[1 + curRowBufOffset];
calc0 += inRowPtr[0 + curRowBufOffset];
curRowBufOffset += 3;
curCol++;
}
double calcMax;
double calc3;
double gammaAdj2;
double gammaAdj1;
int col;
col = 0;
gammaAdj1 = Gamma->GammaAdj[1];
curRowBufOffset = 0;
curCol = 0;
gammaAdj2 = Gamma->GammaAdj[2];
calcMax = maxTank;
calc3 = ((calcMax - calc0) + (calcMax - calc2) + (calcMax - calc1)) / (cols * 3);
gammaAdj0 = ((dVar2 + (((calc3 * dVar2) / 255.00000000) * gammaAdj1) / -4095.00000000) * gammaAdj2) / 4095.00000000;
while (col < cols2) {
outVal = Gamma->GNMby[inRowPtr[curRowBufOffset + 2]] + gammaAdj0 + 0.50000000;
if (outVal < 0x1000) {
if (outVal < 0) {
outRowPtr[curRowBufOffset] = 0;
} else {
outRowPtr[curRowBufOffset] = outVal;
}
} else {
outRowPtr[curRowBufOffset] = 0xfff;
}
outVal = Gamma->GNMgm[inRowPtr[curRowBufOffset + 1]] + gammaAdj0 + 0.50000000;
if (outVal < 0x1000) {
if (outVal < 0) {
outRowPtr[curRowBufOffset + 1] = 0;
} else {
outRowPtr[curRowBufOffset + 1] = outVal;
}
} else {
outRowPtr[curRowBufOffset + 1] = 0xfff;
}
outVal = Gamma->GNMrc[inRowPtr[curRowBufOffset]] + gammaAdj0 + 0.50000000;
if (outVal < 0x1000) {
if (outVal < 0) {
outRowPtr[curRowBufOffset + 2] = 0;
} else {
outRowPtr[curRowBufOffset + 2] = (short)outVal;
}
} else {
outRowPtr[curRowBufOffset + 2] = 0xfff;
}
cols2 = cols;
col = curCol + 1;
curRowBufOffset += 3;
curCol = col;
}
tmp = inBytesPerRow + 1;
inRowPtr -= inBytesPerRow;
outRowPtr -= pixelsPerRow;
}
while (tmp < outVal) {
outVal = 0;
curRowBufOffset = 0;
while (curCol = outVal, outVal < cols2) {
outRowPtr[curRowBufOffset] = Gamma->GNMby[inRowPtr[curRowBufOffset + 2]];
outRowPtr[curRowBufOffset + 1] = Gamma->GNMgm[inRowPtr[curRowBufOffset + 1]];
outRowPtr[curRowBufOffset + 2] = Gamma->GNMrc[inRowPtr[curRowBufOffset]];
cols2 = cols;
outVal = curCol + 1;
curRowBufOffset += 3;
}
outVal = rows;
tmp ++;
inRowPtr -= inBytesPerRow;
outRowPtr -= pixelsPerRow;
}
return 1;
}
static void CP98xx_InitAptParams(const struct mitsu98xx_data *table, struct CP98xx_AptParams *APT, int sharpness)
{
int i, j;
double sharpCoef;
APT->unsharp = 0;
APT->mpx10 = 1;
sharpCoef = table->sharp_coef[sharpness];
for (i = 2, j = 0 ; j < 8 ; i++, j++) {
APT->mask[j][5] = table->sharp[1];
APT->mask[j][4] = sharpCoef * table->sharp[i] + 0.5;
APT->mask[j][3] = table->sharp[11];
APT->mask[j][2] = sharpCoef * table->sharp[i+10] + 0.5;
}
APT->mask[0][0] = -table->sharp[10];
APT->mask[0][1] = -table->sharp[0];
APT->mask[1][0] = 0;
APT->mask[1][1] = -table->sharp[0];
APT->mask[2][0] = table->sharp[10];
APT->mask[2][1] = -table->sharp[0];
APT->mask[3][0] = -table->sharp[10];
APT->mask[3][1] = 0;
APT->mask[4][0] = table->sharp[10];
APT->mask[4][1] = 0;
APT->mask[5][0] = -table->sharp[10];
APT->mask[5][1] = table->sharp[0];
APT->mask[6][0] = table->sharp[10];
APT->mask[6][1] = table->sharp[0];
APT->mask[7][0] = 0;
APT->mask[7][1] = table->sharp[0];
}
static void CP98xx_InitWMAM(struct CP98xx_WMAM *wmam, const struct CP98xx_WMAM *src)
{
int i;
for (i = 0 ; i < 255 ; i++) {
wmam->unka[i] = src->unka[i] / 255.0;
wmam->unkb[i] = src->unkb[i] / 255.0;
wmam->unkd[i] = src->unkd[i] / 255.0;
wmam->unke[i] = src->unke[i] / 64.0;
wmam->unkg[i] = src->unkg[i] / 64.0;
}
memcpy(wmam->unkc, src->unkc, sizeof(wmam->unkc));
memcpy(wmam->unkf, src->unkd, sizeof(wmam->unkc));
}
static int CP98xx_DoWMAM(struct CP98xx_WMAM *wmam, struct BandImage *img, int always_1)
{
uint16_t *imgBuf, *rowPtr;
int rows, col, cols, bytesPerRow, pixelCnt;
double *rowCalcBuf1, *rowCalcBuf2, *rowCalcBuf3, *rowCalcBuf4, *rowCalcBuf5;
double *pdVar3, *pdVar5, *pdVar6, *pdVar7, *pdVar8, *pdVar9, *pdVar11, *pdVar12;
int row;
int rowCalcBufLenB, rowCalcBufLen;
int doubleBufOffset, imgBufOffset;
cols = img->cols - img->origin_cols;
rows = img->rows - img->origin_rows;
bytesPerRow = img->bytes_per_row;
rowPtr = imgBuf = img->imgbuf;
if ((cols < 6) || (rows < 1) || (bytesPerRow == 0))
return 0;
if (bytesPerRow < 0) {
if (always_1 != 0) {
bytesPerRow = bytesPerRow >> 1;
} else {
bytesPerRow = -bytesPerRow;
bytesPerRow = bytesPerRow >> 1;
rowPtr += bytesPerRow * (rows -1);
imgBuf = (uint16_t *)rowPtr;
}
} else {
if (always_1 != 0) {
bytesPerRow = bytesPerRow >> 1;
rowPtr += bytesPerRow * (rows -1);
imgBuf = (uint16_t *)rowPtr;
} else {
bytesPerRow = (-bytesPerRow) >> 1;
}
}
pixelCnt = cols * 3;
rowCalcBufLen = cols * 3 * sizeof(double);
rowCalcBuf1 = malloc(rowCalcBufLen);
if (!rowCalcBuf1) {
return 0;
}
rowCalcBuf2 = malloc(rowCalcBufLen);
if (!rowCalcBuf2) {
free(rowCalcBuf1);
return 0;
}
rowCalcBufLenB = (pixelCnt + 24) * sizeof(double);
rowCalcBuf3 = malloc(rowCalcBufLenB);
if (!rowCalcBuf3) {
free(rowCalcBuf2);
free(rowCalcBuf1);
return 0;
}
pdVar8 = rowCalcBuf3 + 12;
rowCalcBuf4 = malloc(rowCalcBufLenB);
if (!rowCalcBuf4) {
free(rowCalcBuf3);
free(rowCalcBuf2);
free(rowCalcBuf1);
return 0;
}
pdVar7 = rowCalcBuf4 + 12;
rowCalcBuf5 = malloc(rowCalcBufLen);
if (!rowCalcBuf5) {
free(rowCalcBuf4);
free(rowCalcBuf3);
free(rowCalcBuf2);
free(rowCalcBuf1);
return 0;
}
memset(rowCalcBuf1, 0, cols * 3 * sizeof(double));
memset(rowCalcBuf2, 0, cols * 3 * sizeof(double));
row = 0;
pdVar5 = pdVar7 + (cols -1) * 3;
pdVar3 = pdVar8 + (cols -1) * 3;
for (row = 0 ; row < rows ; row++) {
col = pixelCnt + 1;
doubleBufOffset = 0;
imgBufOffset = 0;
if (pixelCnt < 0) {
col = 1;
}
for ( ; col > 0 ; col --) {
double dVar16, dVar17, dVar18, dVar19;
int iVar1;
int pixelVal;
dVar16 = rowPtr[imgBufOffset];
dVar17 = rowCalcBuf1[doubleBufOffset] - dVar16;
pixelVal = dVar17;
if (pixelVal < 0) {
iVar1 = -0x80;
if (-0xff0 < pixelVal) {
iVar1 = -((0x10 - pixelVal) >> 5);
}
} else {
iVar1 = 0x7f;
if (pixelVal < 0xfd0) {
iVar1 = (pixelVal + 0x10) >> 5;
}
}
dVar17 *= wmam->unka[128+iVar1];
pixelVal = dVar17;
pdVar8[doubleBufOffset] = dVar16 + dVar17;
if (pixelVal < 0) {
iVar1 = -0x80;
if (-0xff0 < pixelVal) {
iVar1 = -((0x10 - pixelVal) >> 5);
}
} else {
iVar1 = 0x7f;
if (pixelVal < 0xfd0) {
iVar1 = (pixelVal + 0x10) >> 5;
}
}
dVar19 = wmam->unkb[128+iVar1];
dVar18 = rowCalcBuf2[doubleBufOffset] - dVar16;
pixelVal = dVar18;
if (pixelVal < 0) {
iVar1 = -0x80;
if (-0xff0 < pixelVal) {
iVar1 = -((0x10 - pixelVal) >> 5);
}
} else {
iVar1 = 0x7f;
if (pixelVal < 0xfd0) {
iVar1 = (pixelVal + 0x10) >> 5;
}
}
dVar18 *= wmam->unkd[128+iVar1];
pdVar7[doubleBufOffset] = dVar16 + dVar18;
pixelVal = dVar18;
if (pixelVal < 0) {
iVar1 = -0x80;
if (-0xff0 < pixelVal) {
iVar1 = -((0x10 - pixelVal) >> 5);
}
} else {
iVar1 = 0x7f;
if (pixelVal < 0xfd0) {
iVar1 = (pixelVal + 0x10) >> 5;
}
}
dVar16 = (-(dVar17 * dVar19 - dVar16) +
-(dVar18 * (wmam->unke[iVar1 + 128]) - dVar16)) * 0.50000000;
if (row != 0) {
if (0.00000000 <= dVar16) {
if (dVar16 <= 4095.00000000) {
dVar17 = rowCalcBuf5[doubleBufOffset];
} else {
iVar1 = 0;
pixelVal = (dVar16 - 4095.00000000);
if ((-1 < pixelVal) && (iVar1 = 0x7f, pixelVal < 0xff0)) {
iVar1 = (pixelVal + 0x10) >> 5;
}
dVar17 = (dVar16 - 4095.00000000) * wmam->unkg[127+iVar1] +
rowCalcBuf5[doubleBufOffset];
}
} else {
pixelVal = dVar16;
iVar1 = 0x80;
if ((-0xff0 < pixelVal) && (iVar1 = 0xff, pixelVal < 1)) {
iVar1 = 0xff - ((0x10 - pixelVal) >> 5);
}
dVar17 = dVar16 * wmam->unkg[127+iVar1] +
rowCalcBuf5[doubleBufOffset];
}
pixelVal = dVar17 + 0.50000000;
if (pixelVal < 0x1000) {
if (pixelVal < 0) {
imgBuf[imgBufOffset] = 0;
} else {
imgBuf[imgBufOffset] = pixelVal;
}
} else {
imgBuf[imgBufOffset] = 0xfff;
}
}
rowCalcBuf5[doubleBufOffset] = dVar16;
imgBufOffset++;
doubleBufOffset++;
}
col = 0;
rowCalcBuf3[9] = rowCalcBuf3[15];
rowCalcBuf3[10] = rowCalcBuf3[16];
rowCalcBuf3[11] = rowCalcBuf3[17];
rowCalcBuf3[6] = rowCalcBuf3[18];
rowCalcBuf3[7] = rowCalcBuf3[19];
rowCalcBuf3[8] = rowCalcBuf3[20];
rowCalcBuf3[3] = rowCalcBuf3[21];
rowCalcBuf3[4] = rowCalcBuf3[22];
rowCalcBuf3[5] = rowCalcBuf3[23];
rowCalcBuf3[0] = rowCalcBuf3[24];
rowCalcBuf3[1] = rowCalcBuf3[25];
rowCalcBuf3[2] = rowCalcBuf3[26];
rowCalcBuf4[9] = rowCalcBuf4[15];
rowCalcBuf4[10] = rowCalcBuf4[16];
rowCalcBuf4[11] = rowCalcBuf4[17];
rowCalcBuf4[6] = rowCalcBuf4[18];
rowCalcBuf4[7] = rowCalcBuf4[19];
rowCalcBuf4[8] = rowCalcBuf4[20];
rowCalcBuf4[3] = rowCalcBuf4[21];
rowCalcBuf4[4] = rowCalcBuf4[22];
rowCalcBuf4[5] = rowCalcBuf4[23];
rowCalcBuf4[0] = rowCalcBuf4[24];
rowCalcBuf4[1] = rowCalcBuf4[25];
rowCalcBuf4[2] = rowCalcBuf4[26];
pdVar3[3] = pdVar3[-3];
pdVar3[4] = pdVar3[-2];
pdVar3[5] = pdVar3[-1];
pdVar3[6] = pdVar3[-6];
pdVar3[7] = pdVar3[-5];
pdVar3[8] = pdVar3[-4];
pdVar3[9] = pdVar3[-9];
pdVar3[10] = pdVar3[-8];
pdVar3[11] = pdVar3[-7];
pdVar3[12] = pdVar3[-12];
pdVar3[13] = pdVar3[-11];
pdVar3[14] = pdVar3[-10];
pdVar5[3] = pdVar5[-3];
pdVar5[4] = pdVar5[-2];
pdVar5[5] = pdVar5[-1];
pdVar5[6] = pdVar5[-6];
pdVar5[7] = pdVar5[-5];
pdVar5[8] = pdVar5[-4];
pdVar5[9] = pdVar5[-9];
pdVar5[10] = pdVar5[-8];
pdVar5[11] = pdVar5[-7];
pdVar5[12] = pdVar5[-12];
pdVar5[13] = pdVar5[-11];
pdVar5[14] = pdVar5[-10];
pdVar11 = rowCalcBuf2;
pdVar12 = pdVar8;
pdVar6 = pdVar7;
pdVar9 = rowCalcBuf1;
while( 1 ) {
double dVar16, dVar17, dVar18, dVar19;
double dVar20, dVar21, dVar22, dVar23, dVar24, dVar25;
double dVar26, dVar27, dVar28, dVar29, dVar30, dVar31;
double dVar32, dVar33, dVar34, dVar35, dVar36, dVar37;
double dVar38, dVar39, dVar40, dVar41, dVar42, dVar43;
double dVar44, dVar45, dVar46, dVar47, dVar48, dVar49;
double dVar50, dVar51, dVar52, dVar53, dVar54, dVar55;
double dVar56, dVar57, dVar58, dVar59, dVar60, dVar61;
double dVar62, dVar63, dVar64, dVar65, dVar66, dVar67;
double dVar68, dVar69, dVar70;
if (pixelCnt <= col) break;
col += 3;
dVar38 = pdVar12[-11];
dVar26 = pdVar12[-10];
dVar60 = pdVar12[-8];
dVar70 = pdVar12[-7];
dVar61 = pdVar12[-5];
dVar58 = pdVar12[-4];
dVar36 = pdVar12[-2];
dVar27 = pdVar12[-1];
dVar43 = pdVar12[1];
dVar25 = pdVar12[2];
dVar30 = pdVar12[4];
dVar42 = pdVar12[5];
dVar54 = pdVar12[7];
dVar59 = pdVar12[8];
dVar55 = pdVar12[10];
dVar28 = pdVar12[11];
dVar53 = pdVar12[13];
dVar56 = pdVar12[14];
dVar41 = pdVar6[-12];
dVar29 = pdVar6[-11];
dVar45 = pdVar6[-10];
dVar21 = pdVar6[-9];
dVar66 = pdVar6[-8];
dVar24 = pdVar6[-7];
dVar57 = pdVar6[-6];
dVar67 = pdVar6[-5];
dVar64 = pdVar6[-4];
dVar23 = pdVar6[-3];
dVar33 = pdVar6[-2];
dVar39 = pdVar6[-1];
dVar22 = pdVar6[0];
dVar47 = pdVar6[1];
dVar31 = pdVar6[2];
dVar46 = pdVar6[3];
dVar49 = pdVar6[4];
dVar16 = pdVar6[5];
dVar63 = pdVar6[6];
dVar65 = pdVar6[7];
dVar69 = pdVar6[8];
dVar40 = pdVar6[9];
dVar44 = pdVar6[10];
dVar48 = pdVar6[11];
dVar62 = pdVar6[12];
dVar68 = pdVar6[13];
dVar20 = pdVar6[14];
dVar37 = wmam->unkc[0];
dVar50 = wmam->unkc[1];
dVar18 = wmam->unkc[2];
dVar35 = wmam->unkc[3];
dVar19 = wmam->unkc[4];
dVar34 = wmam->unkf[0];
dVar17 = wmam->unkf[1];
dVar51 = wmam->unkf[2];
dVar32 = wmam->unkf[3];
dVar52 = wmam->unkf[4];
pdVar9[0] = (dVar19 * (pdVar12[-0xc] + pdVar12[0xc]) +
dVar35 * (pdVar12[-9] + pdVar12[9]) +
dVar18 * (pdVar12[-6] + pdVar12[6]) +
dVar37 * (*pdVar12 + *pdVar12) + dVar50 * (pdVar12[-3] + pdVar12[3])) / 1000.00000000;
pdVar9[1] = (dVar19 * (dVar38 + dVar53) +
dVar35 * (dVar60 + dVar55) +
dVar18 * (dVar61 + dVar54) +
dVar37 * (dVar43 + dVar43) + dVar50 * (dVar36 + dVar30)) / 1000.00000000;
pdVar9[2] = (dVar19 * (dVar26 + dVar56) +
dVar35 * (dVar70 + dVar28) +
dVar18 * (dVar58 + dVar59) +
dVar37 * (dVar25 + dVar25) + dVar50 * (dVar27 + dVar42)) / 1000.00000000;
pdVar11[0] = (dVar52 * (dVar41 + dVar62) +
dVar32 * (dVar21 + dVar40) +
dVar51 * (dVar57 + dVar63) +
dVar34 * (dVar22 + dVar22) + dVar17 * (dVar23 + dVar46)) / 1000.00000000;
pdVar11[1] = (dVar52 * (dVar29 + dVar68) +
dVar32 * (dVar66 + dVar44) +
dVar51 * (dVar67 + dVar65) +
dVar34 * (dVar47 + dVar47) + dVar17 * (dVar33 + dVar49)) / 1000.00000000;
pdVar11[2] = (dVar52 * (dVar45 + dVar20) +
dVar32 * (dVar24 + dVar48) +
dVar51 * (dVar64 + dVar69) +
dVar34 * (dVar31 + dVar31) + dVar17 * (dVar39 + dVar16)) / 1000.00000000;
pdVar11 += 3;
pdVar12 += 3;
pdVar6 += 3;
pdVar9 += 3;
}
rowPtr -= bytesPerRow;
if (row != 0) {
imgBuf -= bytesPerRow;
}
}
int iVar4 = pixelCnt + 1;
pdVar3 = rowCalcBuf5;
if (pixelCnt < 0) {
iVar4 = 1;
}
for ( ; iVar4 > 0 ; iVar4--) {
col = (*pdVar3 + 0.50000000);
if (col < 0) {
*imgBuf = 0;
} else {
if (col < 0x1000) {
*imgBuf = col;
}
else {
*imgBuf = 0xfff;
}
}
pdVar3 ++;
imgBuf ++;
}
/* Clean up, we're done! */
free(rowCalcBuf5);
free(rowCalcBuf4);
free(rowCalcBuf3);
free(rowCalcBuf2);
free(rowCalcBuf1);
return 1;
}
int CP98xx_DoConvert(const struct mitsu98xx_data *table,
const struct BandImage *input,
struct BandImage *output,
uint8_t type, int sharpness)
{
int i;
dump_announce();
/* Figure out which table to use */
switch (type) {
case 0x80:
table = &table[0]; /* Superfine */
break;
case 0x11:
table = &table[2]; /* Fine HG */
break;
case 0x10:
default:
table = &table[1]; /* Fine STD */
break;
}
/* We've already gone through 3D LUT */
/* Sharpen, as needed */
struct CP98xx_AptParams APT;
CP98xx_InitAptParams(table, &APT, sharpness);
// XXX DoAptMWithParams()
/* Set up gamma table and do the conversion */
struct CP98xx_GammaParams gamma;
struct CP98xx_KHParams kh;
struct CP98xx_WMAM wmam;
memcpy(gamma.GNMgm, table->GNMgm, sizeof(gamma.GNMgm));
memcpy(gamma.GNMby, table->GNMby, sizeof(gamma.GNMby));
memcpy(gamma.GNMrc, table->GNMrc, sizeof(gamma.GNMrc));
memcpy(gamma.GammaAdj, table->GammaAdj, sizeof(gamma.GammaAdj));
memcpy(kh.KH, table->KH, sizeof(kh.KH));
kh.Start = table->KHStart;
kh.End = table->KHEnd;
kh.Step = table->KHStep;
/* Run through gamma conversion */
if (CP98xx_DoCorrectGammaTbl(&gamma, &kh, input) != 1) {
return 0;
}
if (CP98xx_DoGammaConv(&gamma, input, output) != 1) {
return 0;
}
/* Run the WMAM flow */
#pragma GCC diagnostic push
#if (defined(__GNUC__) && (__GNUC__ >= 9))
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
#endif
CP98xx_InitWMAM(&wmam, &table->WMAM);
#pragma GCC diagnostic pop
if (CP98xx_DoWMAM(&wmam, output, 1) != 1) {
return 0;
}
/* Convert to printer's native BE16 */
for (i = 0; i < (output->rows * output->cols * 3 / 2) ; i++) {
((uint16_t*)output->imgbuf)[i] = cpu_to_be16(((uint16_t*)output->imgbuf)[i]);
}
return 1;
}

@ -1,7 +1,7 @@
/* LibMitsuD70ImageReProcess -- Re-implemented image processing library for
the Mitsubishi CP-D70 family of printers
Copyright (c) 2016-2017 Solomon Peachy <pizza@shaftnet.org>
Copyright (c) 2016-2020 Solomon Peachy <pizza@shaftnet.org>
** ** ** ** Do NOT contact Mitsubishi about this library! ** ** ** **
@ -26,6 +26,13 @@
* Kodak 305
* Fujifilm ASK-300
More recently, the CP98xx family now uses this library. These
models are expected to function:
* Mitsubishi CP9800DW
* Mitsubishi CP9810DW
* Mitsubishi CP9820DW-S
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
This program is free software; you can redistribute it and/or modify it
@ -51,7 +58,7 @@
#ifndef __MITSU_D70_H
#define __MITSU_D70_H
#define LIB_APIVERSION 4
#define LIB_APIVERSION 5
#include <stdint.h>
@ -91,7 +98,7 @@ int do_image_effect80(struct CPCData *cpc, struct CPCData *ecpc,
struct BandImage *input, struct BandImage *output,
int sharpen, int reverse, uint8_t rew[2]);
/* Converts the packed 16bpp YMC image into 16bpp YMC planes, with
/* Converts the packed 16bpp YMC image into 16bpp YMC planes, with
proper padding after each plane. Calls the callback function for each
block. */
int send_image_data(struct BandImage *out, void *context,
@ -116,4 +123,15 @@ void CColorConv3D_Destroy3DColorTable(struct CColorConv3D *this);
/* Run a packed 8bpp rgb or bgr image through the LUT */
void CColorConv3D_DoColorConv(struct CColorConv3D *this, uint8_t *data, uint16_t cols, uint16_t rows, uint32_t bytes_per_row, int rgb_bgr);
/* CP98xx family stuff */
struct mitsu98xx_data; /* Forward declaration */
struct mitsu98xx_data *CP98xx_GetData(const char *filename);
void CP98xx_DestroyData(const struct mitsu98xx_data *data);
int CP98xx_DoConvert(const struct mitsu98xx_data *table,
const struct BandImage *input,
struct BandImage *output,
uint8_t type, int sharpness);