kopia lustrzana https://gitlab.com/sane-project/backends
Remove histogram stretching for negative images.
rodzic
4962b35abd
commit
74effd61fd
|
@ -122,9 +122,6 @@ static const Scanner_Model mustek_A2nu2_model = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static SANE_Byte * g_pNegImageData = NULL;
|
|
||||||
static unsigned int g_dwAlreadyGetNegLines;
|
|
||||||
|
|
||||||
static SANE_Bool IsTAConnected (void);
|
static SANE_Bool IsTAConnected (void);
|
||||||
|
|
||||||
|
|
||||||
|
@ -485,83 +482,6 @@ SetParameters (TARGETIMAGE * pSetParameters)
|
||||||
return SANE_TRUE;
|
return SANE_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short
|
|
||||||
AdjustColorComponent (SANE_Byte c, SANE_Byte min, SANE_Byte max,
|
|
||||||
SANE_Byte range)
|
|
||||||
{
|
|
||||||
if (range == 0)
|
|
||||||
c = max;
|
|
||||||
else if (c < min)
|
|
||||||
c = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float fmax = (float) ((c - min) * 255) / range;
|
|
||||||
c = (unsigned short) fmax;
|
|
||||||
if ((fmax - c) >= 0.5)
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
AutoLevel (SANE_Byte * pSource, unsigned short ScanLines,
|
|
||||||
unsigned int BytesPerLine)
|
|
||||||
{
|
|
||||||
unsigned int i, j;
|
|
||||||
unsigned int tLines;
|
|
||||||
SANE_Byte R, G, B;
|
|
||||||
SANE_Byte max_R = 0, max_G = 0, max_B = 0;
|
|
||||||
SANE_Byte min_R = 255, min_G = 255, min_B = 255;
|
|
||||||
SANE_Byte range_R, range_G, range_B;
|
|
||||||
unsigned int iWidth = BytesPerLine / 3;
|
|
||||||
|
|
||||||
DBG (DBG_FUNC, "AutoLevel: start\n");
|
|
||||||
|
|
||||||
/* find min and max values for each color component */
|
|
||||||
for (j = 0, tLines = 0; j < ScanLines; j++, tLines += BytesPerLine)
|
|
||||||
{
|
|
||||||
for (i = 0; i < iWidth; i++)
|
|
||||||
{
|
|
||||||
R = pSource[tLines + i * 3 + 2];
|
|
||||||
G = pSource[tLines + i * 3 + 1];
|
|
||||||
B = pSource[tLines + i * 3];
|
|
||||||
|
|
||||||
max_R = _MAX (R, max_R);
|
|
||||||
max_G = _MAX (G, max_G);
|
|
||||||
max_B = _MAX (B, max_B);
|
|
||||||
|
|
||||||
min_R = _MIN (R, min_R);
|
|
||||||
min_G = _MIN (G, min_G);
|
|
||||||
min_B = _MIN (B, min_B);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
range_R = max_R - min_R;
|
|
||||||
range_G = max_G - min_G;
|
|
||||||
range_B = max_B - min_B;
|
|
||||||
|
|
||||||
/* stretch histogram */
|
|
||||||
for (j = 0, tLines = 0; j < ScanLines; j++, tLines += BytesPerLine)
|
|
||||||
{
|
|
||||||
for (i = 0; i < iWidth; i++)
|
|
||||||
{
|
|
||||||
R = pSource[tLines + i * 3 + 2];
|
|
||||||
G = pSource[tLines + i * 3 + 1];
|
|
||||||
B = pSource[tLines + i * 3];
|
|
||||||
|
|
||||||
R = AdjustColorComponent (R, min_R, max_R, range_R);
|
|
||||||
G = AdjustColorComponent (G, min_G, max_G, range_G);
|
|
||||||
B = AdjustColorComponent (B, min_B, max_B, range_B);
|
|
||||||
|
|
||||||
pSource[tLines + i * 3 + 2] = R;
|
|
||||||
pSource[tLines + i * 3 + 1] = G;
|
|
||||||
pSource[tLines + i * 3] = B;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG (DBG_FUNC, "AutoLevel: exit\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static SANE_Bool
|
static SANE_Bool
|
||||||
ReadScannedData (IMAGEROWS * pImageRows, TARGETIMAGE * pTarget)
|
ReadScannedData (IMAGEROWS * pImageRows, TARGETIMAGE * pTarget)
|
||||||
{
|
{
|
||||||
|
@ -575,58 +495,15 @@ ReadScannedData (IMAGEROWS * pImageRows, TARGETIMAGE * pTarget)
|
||||||
Rows = pImageRows->wWantedLineNum;
|
Rows = pImageRows->wWantedLineNum;
|
||||||
DBG (DBG_INFO, "ReadScannedData: wanted rows = %d\n", Rows);
|
DBG (DBG_INFO, "ReadScannedData: wanted rows = %d\n", Rows);
|
||||||
|
|
||||||
if (pTarget->ssScanSource == SS_NEGATIVE)
|
if (!MustScanner_GetRows (pImageRows->pBuffer, &Rows, isRGBInvert))
|
||||||
|
return SANE_FALSE;
|
||||||
|
pImageRows->wXferedLineNum = Rows;
|
||||||
|
|
||||||
|
if ((pTarget->cmColorMode == CM_TEXT) ||
|
||||||
|
(pTarget->ssScanSource == SS_NEGATIVE))
|
||||||
{
|
{
|
||||||
DBG (DBG_INFO, "ReadScannedData: deal with the Negative\n");
|
for (i = 0; i < (Rows * pTarget->dwBytesPerRow); i++)
|
||||||
|
pImageRows->pBuffer[i] ^= 0xff;
|
||||||
if (pTarget->cmColorMode != CM_RGB24)
|
|
||||||
return SANE_FALSE;
|
|
||||||
|
|
||||||
if (!g_pNegImageData)
|
|
||||||
{
|
|
||||||
unsigned int TotalImageSize = g_SWHeight * pTarget->dwBytesPerRow;
|
|
||||||
g_dwAlreadyGetNegLines = 0;
|
|
||||||
g_pNegImageData = malloc (TotalImageSize);
|
|
||||||
if (!g_pNegImageData)
|
|
||||||
{
|
|
||||||
DBG (DBG_ERR, "ReadScannedData: error allocating memory\n");
|
|
||||||
return SANE_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!MustScanner_GetRows (g_pNegImageData, &g_SWHeight, isRGBInvert))
|
|
||||||
return SANE_FALSE;
|
|
||||||
DBG (DBG_INFO, "ReadScannedData: get image data is over!\n");
|
|
||||||
|
|
||||||
for (i = 0; i < TotalImageSize; i++)
|
|
||||||
g_pNegImageData[i] ^= 0xff;
|
|
||||||
AutoLevel (g_pNegImageData, g_SWHeight, pTarget->dwBytesPerRow);
|
|
||||||
DBG (DBG_INFO, "ReadScannedData: autolevel is ok\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (pImageRows->pBuffer, g_pNegImageData +
|
|
||||||
(pTarget->dwBytesPerRow * g_dwAlreadyGetNegLines),
|
|
||||||
pTarget->dwBytesPerRow * Rows);
|
|
||||||
pImageRows->wXferedLineNum = Rows;
|
|
||||||
DBG (DBG_INFO, "ReadScannedData: copy the data over!\n");
|
|
||||||
|
|
||||||
g_dwAlreadyGetNegLines += Rows;
|
|
||||||
if (g_dwAlreadyGetNegLines >= g_SWHeight)
|
|
||||||
{
|
|
||||||
free (g_pNegImageData);
|
|
||||||
g_pNegImageData = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!MustScanner_GetRows (pImageRows->pBuffer, &Rows, isRGBInvert))
|
|
||||||
return SANE_FALSE;
|
|
||||||
pImageRows->wXferedLineNum = Rows;
|
|
||||||
|
|
||||||
if (pTarget->cmColorMode == CM_TEXT)
|
|
||||||
{
|
|
||||||
for (i = 0; i < (Rows * pTarget->dwBytesPerRow); i++)
|
|
||||||
pImageRows->pBuffer[i] ^= 0xff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_FUNC, "ReadScannedData: exit\n");
|
DBG (DBG_FUNC, "ReadScannedData: exit\n");
|
||||||
|
|
Ładowanie…
Reference in New Issue