lib70x: Fix multiple errors in the CP98xx gamma code.

master
Solomon Peachy 3 years ago
parent 3bf185e60c
commit 3fd61640e4
  1. 77
      lib70x/libMitsuD70ImageReProcess.c

@ -56,7 +56,7 @@
*/
#define LIB_VERSION "0.9.1"
#define LIB_VERSION "0.9.2"
#include <stdio.h>
#include <stdint.h>
@ -66,6 +66,7 @@
#include "libMitsuD70ImageReProcess.h"
#define UNUSED(expr) do { (void)(expr); } while (0)
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
//-------------------------------------------------------------------------
// Endian Manipulation macros
@ -1452,7 +1453,7 @@ void CImageUtility_CreateBandImage16(struct BandImage *img, uint32_t *a2, int32_
#endif
/* XXXX XXXX CP98XX */
/* CP98xx family */
struct CP98xx_WMAM {
/* @ 0 */ double unka[256];
@ -1463,7 +1464,7 @@ struct CP98xx_WMAM {
/* @ 8232 */ double unkf[5]; /* Weight factors */
/* @ 8272 */ double unkg[256];
/* @10320 */
};
} __attribute__((packed));
/* CP98xx Tabular Data, as stored in data file! */
struct mitsu98xx_data {
@ -1477,10 +1478,11 @@ struct mitsu98xx_data {
/* @12008 */ int32_t KHStart;
/* @12012 */ int32_t KHEnd;
/* @12016 */ int32_t KHStep;
/* @12020 */ double KH[256];
/* @12020 */ double KH[256];
/* @14068 */
} __attribute__((packed));
/* Informational purposes only */
struct mitsu98xx_tables {
struct mitsu98xx_data superfine;
struct mitsu98xx_data fine_std;
@ -1489,6 +1491,9 @@ struct mitsu98xx_tables {
#define M98XX_DATATABLE_SIZE 42204
STATIC_ASSERT(sizeof(struct mitsu98xx_data) *3 == M98XX_DATATABLE_SIZE);
/* Cooked versions for local state & manipulation */
struct CP98xx_KHParams {
double KH[256];
int32_t Start;
@ -1504,7 +1509,7 @@ struct CP98xx_GammaParams {
};
struct CP98xx_AptParams {
int16_t mask[8][6]; // really is [8][6]
int16_t mask[8][6];
int unsharp;
int mpx10;
};
@ -1679,7 +1684,7 @@ static int CP98xx_DoCorrectGammaTbl(struct CP98xx_GammaParams *Gamma,
for (i = 0; i < 256 ; i++) {
Gamma->GNMrc[i] = baseRC +
(baseKH * (Gamma->GNMrc[i] - baseRC)) + 0.5;
Gamma->GNMrc[i] = baseGM +
Gamma->GNMgm[i] = baseGM +
(baseKH * (Gamma->GNMgm[i] - baseGM)) + 0.5;
Gamma->GNMby[i] = baseBY +
(baseKH * (Gamma->GNMby[i] - baseBY)) + 0.5;
@ -1700,18 +1705,34 @@ static int CP98xx_DoGammaConv(struct CP98xx_GammaParams *Gamma,
cols = inImage->cols - inImage->origin_cols;
rows = inImage->rows - inImage->origin_rows;
inBytesPerRow = inImage->bytes_per_row;
/* Output always starts at end and works back */
pixelsPerRow = outImage->bytes_per_row >> 1;
outRowPtr = (uint16_t*)((uint8_t*)outImage->imgbuf + (pixelsPerRow * (rows-1) * sizeof(uint16_t)));
/* Input is another matter.. */
inBytesPerRow = inImage->bytes_per_row;
if ((cols < 1) || (rows < 1) || (inBytesPerRow == 0))
return 0;
if (inBytesPerRow < 0) {
inRowPtr = inImage->imgbuf;
outRowPtr = outImage->imgbuf;
} else {
outRowPtr = (uint16_t*)((uint8_t*)outImage->imgbuf + (pixelsPerRow * (rows-1) * sizeof(uint16_t)));
inRowPtr = (uint8_t*)inImage->imgbuf + (inBytesPerRow * (rows-1));
if (inBytesPerRow < 0) { /* First row of input is at the beginning */
if (reverse) {
/* count backwards from end of buffer */
inBytesPerRow = -inBytesPerRow;
inRowPtr = (uint8_t*)inImage->imgbuf + (inBytesPerRow * (rows-1));
} else {
/* Count forward from start of buffer */
inRowPtr = inImage->imgbuf;
}
} else { /* First row of input is at the end */
if (reverse) {
/* Count forwards from start of buffer */
inBytesPerRow = -inBytesPerRow;
inRowPtr = (uint8_t*)inImage->imgbuf;
} else {
/* Count backwards from end of buffer */
inRowPtr = (uint8_t*)inImage->imgbuf + (inBytesPerRow * (rows-1));
}
}
maxTank = cols * 255;
@ -1724,6 +1745,7 @@ static int CP98xx_DoGammaConv(struct CP98xx_GammaParams *Gamma,
double gammaAdj1 = Gamma->GammaAdj[1];
double gammaAdj0 = Gamma->GammaAdj[0];
/* Do gamma mapping with correction/adjustments... */
for (row = 0 ; row < rows && gammaAdj0 >= 0.5 ; row++) {
double calc3, calc2, calc1, calc0;
double gammaAdjX;
@ -1782,24 +1804,13 @@ static int CP98xx_DoGammaConv(struct CP98xx_GammaParams *Gamma,
outRowPtr -= pixelsPerRow;
}
/* HACK: Reverse the row data when we perform gamma correction,
because Old Gutenprint sends it in the wrong order. */
for (row = 0 ; row < rows ; row++) {
int outRowBufOffset = 0;
if (reverse)
outRowBufOffset += (cols - 1) * 3;
for (col = 0, curRowBufOffset = 0 ; col < cols ; col ++) {
/* ...and pick up where the first loop left off, if we don't need adjustments */
for ( ; row < rows ; row++) {
for (col = 0, curRowBufOffset = 0 ; col < cols ; col ++, curRowBufOffset += 3) {
/* Mitsu code treats input as RGB, we always use BGR. */
outRowPtr[outRowBufOffset] = Gamma->GNMby[inRowPtr[curRowBufOffset]];
outRowPtr[outRowBufOffset + 1] = Gamma->GNMgm[inRowPtr[curRowBufOffset + 1]];
outRowPtr[outRowBufOffset + 2] = Gamma->GNMrc[inRowPtr[curRowBufOffset + 2]];
curRowBufOffset += 3;
if (!reverse)
outRowBufOffset += 3;
else
outRowBufOffset -= 3;
outRowPtr[curRowBufOffset] = Gamma->GNMby[inRowPtr[curRowBufOffset]];
outRowPtr[curRowBufOffset + 1] = Gamma->GNMgm[inRowPtr[curRowBufOffset + 1]];
outRowPtr[curRowBufOffset + 2] = Gamma->GNMrc[inRowPtr[curRowBufOffset + 2]];
}
inRowPtr -= inBytesPerRow;
outRowPtr -= pixelsPerRow;
@ -1845,7 +1856,7 @@ static void CP98xx_InitAptParams(const struct mitsu98xx_data *table, struct CP98
static void CP98xx_InitWMAM(struct CP98xx_WMAM *wmam, const struct CP98xx_WMAM *src)
{
int i;
for (i = 0 ; i < 255 ; i++) {
for (i = 0 ; i < 256 ; 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;
@ -2303,7 +2314,7 @@ int CP98xx_DoConvert(const struct mitsu98xx_data *table,
if (CP98xx_DoCorrectGammaTbl(&gamma, &kh, input) != 1) {
return 0;
}
if (CP98xx_DoGammaConv(&gamma, input, output, !already_reversed) != 1) {
if (CP98xx_DoGammaConv(&gamma, input, output, already_reversed) != 1) {
return 0;
}
@ -2315,7 +2326,7 @@ int CP98xx_DoConvert(const struct mitsu98xx_data *table,
CP98xx_InitWMAM(&wmam, &table->WMAM);
#pragma GCC diagnostic pop
if (CP98xx_DoWMAM(&wmam, output, !already_reversed) != 1) {
if (CP98xx_DoWMAM(&wmam, output, 1) != 1) {
return 0;
}

Loading…
Cancel
Save