[gimp/gimp-2-10] Issue #4941 - TWAIN 16-bit greyscale/rgb scan always loaded as 8-bit
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] Issue #4941 - TWAIN 16-bit greyscale/rgb scan always loaded as 8-bit
- Date: Thu, 4 Jun 2020 17:41:48 +0000 (UTC)
commit f35df5503d32b3594a0896da717073aeff3e43d6
Author: Ell <ell_se yahoo com>
Date: Thu Jun 4 20:36:48 2020 +0300
Issue #4941 - TWAIN 16-bit greyscale/rgb scan always loaded as 8-bit
Simplify data transfer in the twain plug-in, and add support for
16-bit RGB/grayscale images.
(cherry picked from commit 30f65bb6c5fdbbb48edd3d07d764763d6a2477c4)
plug-ins/twain/twain.c | 145 +++++++++++++++++++------------------------------
1 file changed, 56 insertions(+), 89 deletions(-)
---
diff --git a/plug-ins/twain/twain.c b/plug-ins/twain/twain.c
index a50e740095..ea26d4f746 100644
--- a/plug-ins/twain/twain.c
+++ b/plug-ins/twain/twain.c
@@ -517,9 +517,13 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo,
{
pClientDataStruct theClientData = g_new (ClientDataStruct, 1);
- const Babl *format;
- int imageType;
- int layerType;
+ const Babl *format;
+ GimpImageBaseType imageType;
+ GimpImageType layerType;
+ GimpPrecision precision;
+
+ gint bpc = imageInfo->BitsPerPixel /
+ imageInfo->SamplesPerPixel;
#ifdef _DEBUG
@@ -530,12 +534,33 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo,
switch (imageInfo->PixelType)
{
case TWPT_BW:
+ /* Set up the image and layer types */
+ imageType = GIMP_GRAY;
+ layerType = GIMP_GRAY_IMAGE;
+ precision = GIMP_PRECISION_U8_GAMMA;
+ format = babl_format ("Y' u8");
+ break;
+
case TWPT_GRAY:
/* Set up the image and layer types */
imageType = GIMP_GRAY;
layerType = GIMP_GRAY_IMAGE;
- format = babl_format ("Y' u8");
+ switch (bpc)
+ {
+ case 8:
+ precision = GIMP_PRECISION_U8_GAMMA;
+ format = babl_format ("Y' u8");
+ break;
+
+ case 16:
+ precision = GIMP_PRECISION_U16_GAMMA;
+ format = babl_format ("Y' u16");
+ break;
+
+ default:
+ return FALSE;
+ }
break;
case TWPT_RGB:
@@ -543,7 +568,21 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo,
imageType = GIMP_RGB;
layerType = GIMP_RGB_IMAGE;
- format = babl_format ("R'G'B' u8");
+ switch (bpc)
+ {
+ case 8:
+ precision = GIMP_PRECISION_U8_GAMMA;
+ format = babl_format ("R'G'B' u8");
+ break;
+
+ case 16:
+ precision = GIMP_PRECISION_U16_GAMMA;
+ format = babl_format ("R'G'B' u16");
+ break;
+
+ default:
+ return FALSE;
+ }
break;
case TWPT_PALETTE:
@@ -588,9 +627,11 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo,
}
/* Create the GIMP image */
- theClientData->image_id = gimp_image_new (imageInfo->ImageWidth,
- imageInfo->ImageLength,
- imageType);
+ theClientData->image_id = gimp_image_new_with_precision (
+ imageInfo->ImageWidth,
+ imageInfo->ImageLength,
+ imageType,
+ precision);
/* Set the actual resolution */
gimp_image_set_resolution (theClientData->image_id,
@@ -703,40 +744,16 @@ oneBytePerSampleTransferCallback (pTW_IMAGEINFO imageInfo,
pTW_IMAGEMEMXFER imageMemXfer,
void *clientData)
{
- int row;
- char *srcBuf;
- char *destBuf;
- int bytesPerPixel = imageInfo->BitsPerPixel / 8;
- int rows = imageMemXfer->Rows;
- int cols = imageMemXfer->Columns;
+ int rows = imageMemXfer->Rows;
+ int cols = imageMemXfer->Columns;
pClientDataStruct theClientData = (pClientDataStruct) clientData;
- /* Allocate a buffer as necessary */
- destBuf = gegl_scratch_new (char, rows * cols * bytesPerPixel);
-
- /* The bytes coming from the source may not be padded in
- * a way that GIMP is terribly happy with. It is
- * possible to transfer row by row, but that is particularly
- * expensive in terms of performance. It is much cheaper
- * to rearrange the data and transfer it in one large chunk.
- * The next chunk of code rearranges the incoming data into
- * a non-padded chunk for GIMP.
- */
- srcBuf = (char *) imageMemXfer->Memory.TheMem;
- for (row = 0; row < rows; row++)
- {
- /* Copy the current row */
- memcpy ((destBuf + (row * bytesPerPixel * cols)),
- (srcBuf + (row * imageMemXfer->BytesPerRow)),
- (bytesPerPixel * cols));
- }
-
/* Update the complete chunk */
gegl_buffer_set (theClientData->buffer,
GEGL_RECTANGLE (imageMemXfer->XOffset, imageMemXfer->YOffset,
cols, rows), 0,
- theClientData->format, destBuf,
- GEGL_AUTO_ROWSTRIDE);
+ theClientData->format, imageMemXfer->Memory.TheMem,
+ imageMemXfer->BytesPerRow);
/* Free the buffer */
gegl_scratch_free (destBuf);
@@ -761,68 +778,18 @@ twoBytesPerSampleTransferCallback (pTW_IMAGEINFO imageInfo,
pTW_IMAGEMEMXFER imageMemXfer,
void *clientData)
{
- static float ratio = 0.00390625;
- int row, col, sample;
- char *destBuf;
- char *destByte;
- int rows = imageMemXfer->Rows;
- int cols = imageMemXfer->Columns;
- TW_UINT16 *samplePtr;
+ int rows = imageMemXfer->Rows;
+ int cols = imageMemXfer->Columns;
pClientDataStruct theClientData = (pClientDataStruct) clientData;
- /* Allocate a buffer as necessary */
- destBuf = gegl_scratch_new (char, rows * cols * imageInfo->SamplesPerPixel);
-
- /* The bytes coming from the source may not be padded in
- * a way that GIMP is terribly happy with. It is
- * possible to transfer row by row, but that is particularly
- * expensive in terms of performance. It is much cheaper
- * to rearrange the data and transfer it in one large chunk.
- * The next chunk of code rearranges the incoming data into
- * a non-padded chunk for GIMP. This function must also
- * reduce from multiple bytes per sample down to single byte
- * per sample.
- */
- /* Work through the rows */
- for (row = 0; row < rows; row++)
- {
- /* The start of this source row */
- samplePtr = (TW_UINT16 *)
- ((char *) imageMemXfer->Memory.TheMem + (row * imageMemXfer->BytesPerRow));
-
- /* The start of this dest row */
- destByte = destBuf + (row * imageInfo->SamplesPerPixel * cols);
-
- /* Work through the columns */
- for (col = 0; col < cols; col++)
- {
- /* Finally, work through each of the samples */
- for (sample = 0; sample < imageInfo->SamplesPerPixel; sample++)
- {
- /* Get the value */
- TW_UINT16 value = *samplePtr;
-
- /* Move the sample pointer */
- samplePtr++;
-
- /* Place in the destination */
- *destByte = (char) ((float) value * (float) ratio);
- destByte++;
- }
- }
- }
-
/* Send the complete chunk */
gegl_buffer_set (theClientData->buffer,
GEGL_RECTANGLE (imageMemXfer->XOffset, imageMemXfer->YOffset,
cols, rows), 0,
- theClientData->format, destBuf,
+ theClientData->format, imageMemXfer->Memory.TheMem,
GEGL_AUTO_ROWSTRIDE);
- /* Free the buffer */
- gegl_scratch_free (destBuf);
-
/* Update the user on our progress */
theClientData->completedPixels += (cols * rows);
gimp_progress_update ((double) theClientData->completedPixels /
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]