sane.ds: Implement grayscale and B&W scanning for native image transfers.

This commit is contained in:
Jeremy White 2009-03-02 17:08:11 -06:00 committed by Alexandre Julliard
parent 1d58b7e1cc
commit 2c0fea94e8
2 changed files with 47 additions and 11 deletions

View File

@ -685,9 +685,11 @@ static TW_UINT16 SANE_ICAPResolution (pTW_CAPABILITY pCapability, TW_UINT16 acti
/* ICAP_PIXELFLAVOR */ /* ICAP_PIXELFLAVOR */
static TW_UINT16 SANE_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 action) static TW_UINT16 SANE_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 action)
{ {
TW_UINT16 twCC = TWCC_BADCAP;
#ifdef SONAME_LIBSANE
static const TW_UINT32 possible_values[] = { TWPF_CHOCOLATE, TWPF_VANILLA }; static const TW_UINT32 possible_values[] = { TWPF_CHOCOLATE, TWPF_VANILLA };
TW_UINT32 val; TW_UINT32 val;
TW_UINT16 twCC = TWCC_BADCAP; TW_UINT32 flavor = activeDS.sane_param.depth == 1 ? TWPF_VANILLA : TWPF_CHOCOLATE;
TRACE("ICAP_PIXELFLAVOR\n"); TRACE("ICAP_PIXELFLAVOR\n");
@ -700,7 +702,7 @@ static TW_UINT16 SANE_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 act
case MSG_GET: case MSG_GET:
twCC = msg_get_enum(pCapability, possible_values, sizeof(possible_values) / sizeof(possible_values[0]), twCC = msg_get_enum(pCapability, possible_values, sizeof(possible_values) / sizeof(possible_values[0]),
TWTY_UINT16, TWPF_CHOCOLATE, TWPF_CHOCOLATE); TWTY_UINT16, flavor, flavor);
break; break;
case MSG_SET: case MSG_SET:
@ -712,16 +714,17 @@ static TW_UINT16 SANE_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 act
break; break;
case MSG_GETDEFAULT: case MSG_GETDEFAULT:
twCC = set_onevalue(pCapability, TWTY_UINT16, TWPF_CHOCOLATE); twCC = set_onevalue(pCapability, TWTY_UINT16, flavor);
break; break;
case MSG_RESET: case MSG_RESET:
/* .. fall through intentional .. */ /* .. fall through intentional .. */
case MSG_GETCURRENT: case MSG_GETCURRENT:
twCC = set_onevalue(pCapability, TWTY_UINT16, TWPF_CHOCOLATE); twCC = set_onevalue(pCapability, TWTY_UINT16, flavor);
break; break;
} }
#endif
return twCC; return twCC;
} }

View File

@ -142,7 +142,10 @@ TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin,
pImageInfo->Planar = TRUE; pImageInfo->Planar = TRUE;
pImageInfo->SamplesPerPixel = 1; pImageInfo->SamplesPerPixel = 1;
pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth; pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
pImageInfo->PixelType = TWPT_GRAY; if (activeDS.sane_param.depth == 1)
pImageInfo->PixelType = TWPT_BW;
else
pImageInfo->PixelType = TWPT_GRAY;
} }
else else
{ {
@ -366,7 +369,10 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
int dib_bytes; int dib_bytes;
int dib_bytes_per_line; int dib_bytes_per_line;
BYTE *line; BYTE *line;
RGBQUAD *colors;
int color_size = 0;
int i; int i;
BYTE *p;
TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n"); TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
@ -397,9 +403,23 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
return TWRC_FAILURE; return TWRC_FAILURE;
} }
if (activeDS.sane_param.format != SANE_FRAME_RGB) if (activeDS.sane_param.format == SANE_FRAME_GRAY)
{ {
FIXME("For NATIVE, we support only RGB, not %d\n", activeDS.sane_param.format); if (activeDS.sane_param.depth == 8)
color_size = (1 << 8) * sizeof(*colors);
else if (activeDS.sane_param.depth == 1)
;
else
{
FIXME("For NATIVE, we support only 1 bit monochrome and 8 bit Grayscale, not %d\n", activeDS.sane_param.depth);
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_OPERATIONERROR;
return TWRC_FAILURE;
}
}
else if (activeDS.sane_param.format != SANE_FRAME_RGB)
{
FIXME("For NATIVE, we support only GRAY and RGB, not %d\n", activeDS.sane_param.format);
psane_cancel (activeDS.deviceHandle); psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_OPERATIONERROR; activeDS.twCC = TWCC_OPERATIONERROR;
return TWRC_FAILURE; return TWRC_FAILURE;
@ -413,7 +433,7 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
dib_bytes_per_line = ((activeDS.sane_param.bytes_per_line + 3) / 4) * 4; dib_bytes_per_line = ((activeDS.sane_param.bytes_per_line + 3) / 4) * 4;
dib_bytes = activeDS.sane_param.lines * dib_bytes_per_line; dib_bytes = activeDS.sane_param.lines * dib_bytes_per_line;
hDIB = GlobalAlloc(GMEM_ZEROINIT, dib_bytes + sizeof(*header)); hDIB = GlobalAlloc(GMEM_ZEROINIT, dib_bytes + sizeof(*header) + color_size);
if (hDIB) if (hDIB)
header = GlobalLock(hDIB); header = GlobalLock(hDIB);
@ -430,18 +450,31 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
header->biWidth = activeDS.sane_param.pixels_per_line; header->biWidth = activeDS.sane_param.pixels_per_line;
header->biHeight = activeDS.sane_param.lines; header->biHeight = activeDS.sane_param.lines;
header->biPlanes = 1; header->biPlanes = 1;
header->biBitCount = activeDS.sane_param.depth * 3;
header->biCompression = BI_RGB; header->biCompression = BI_RGB;
if (activeDS.sane_param.format == SANE_FRAME_RGB)
header->biBitCount = activeDS.sane_param.depth * 3;
if (activeDS.sane_param.format == SANE_FRAME_GRAY)
header->biBitCount = activeDS.sane_param.depth;
header->biSizeImage = dib_bytes; header->biSizeImage = dib_bytes;
header->biXPelsPerMeter = 0; header->biXPelsPerMeter = 0;
header->biYPelsPerMeter = 0; header->biYPelsPerMeter = 0;
header->biClrUsed = 0; header->biClrUsed = 0;
header->biClrImportant = 0; header->biClrImportant = 0;
p = (BYTE *)(header + 1);
if (color_size > 0)
{
colors = (RGBQUAD *) p;
p += color_size;
for (i = 0; i < (color_size / sizeof(*colors)); i++)
colors[i].rgbBlue = colors[i].rgbRed = colors[i].rgbGreen = i;
}
/* Sane returns data in top down order. Acrobat does best with /* Sane returns data in top down order. Acrobat does best with
a bottom up DIB being returned. */ a bottom up DIB being returned. */
line = (BYTE *)(header + 1) + line = p + (activeDS.sane_param.lines - 1) * dib_bytes_per_line;
(activeDS.sane_param.lines - 1) * dib_bytes_per_line;
for (i = activeDS.sane_param.lines - 1; i >= 0; i--) for (i = activeDS.sane_param.lines - 1; i >= 0; i--)
{ {
activeDS.progressWnd = ScanningDialogBox(activeDS.progressWnd, activeDS.progressWnd = ScanningDialogBox(activeDS.progressWnd,