Discussion:
[PATCH 2/3] Add ICC profile embedding for PNG output.
Add Reply
Aaron Muir Hamilton
2017-04-17 12:07:39 UTC
Reply
Permalink
Raw Message
---
frontend/scanimage.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/frontend/scanimage.c b/frontend/scanimage.c
index 77c22883..0f71422c 100644
--- a/frontend/scanimage.c
+++ b/frontend/scanimage.c
@@ -56,6 +56,7 @@
#include "../include/sane/sanei.h"
#include "../include/sane/saneopts.h"

+#include "sicc.h"
#include "stiff.h"

#include "../include/md5.h"
@@ -1165,9 +1166,11 @@ write_pnm_header (SANE_Frame format, int width, int height, int depth, FILE *ofp

#ifdef HAVE_LIBPNG
static void
-write_png_header (SANE_Frame format, int width, int height, int depth, FILE *ofp, png_structp* png_ptr, png_infop* info_ptr)
+write_png_header (SANE_Frame format, int width, int height, int depth, const char * icc_profile, FILE *ofp, png_structp* png_ptr, png_infop* info_ptr)
{
int color_type;
+ size_t icc_size = 0;
+ void *icc_buffer;

*png_ptr = png_create_write_struct
(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
@@ -1200,6 +1203,16 @@ write_png_header (SANE_Frame format, int width, int height, int depth, FILE *ofp
depth, color_type, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

+ if (icc_profile)
+ {
+ icc_buffer = sanei_load_icc_profile(icc_profile, &icc_size);
+ if (icc_size > 0)
+ {
+ png_set_iCCP(*png_ptr, *info_ptr, basename(icc_profile), PNG_COMPRESSION_TYPE_BASE, icc_buffer, icc_size);
+ free(icc_buffer);
+ }
+ }
+
png_write_info(*png_ptr, *info_ptr);
}
#endif
@@ -1379,7 +1392,8 @@ scan_it (FILE *ofp)
#ifdef HAVE_LIBPNG
case OUTPUT_PNG:
write_png_header (parm.format, parm.pixels_per_line,
- parm.lines, parm.depth, ofp, &png_ptr, &info_ptr);
+ parm.lines, parm.depth, icc_profile,
+ ofp, &png_ptr, &info_ptr);
break;
#endif
#ifdef HAVE_LIBJPEG
@@ -1635,7 +1649,8 @@ scan_it (FILE *ofp)
#ifdef HAVE_LIBPNG
case OUTPUT_PNG:
write_png_header (parm.format, parm.pixels_per_line,
- image.height, parm.depth, ofp, &png_ptr, &info_ptr);
+ image.height, parm.depth, icc_profile,
+ ofp, &png_ptr, &info_ptr);
break;
#endif
#ifdef HAVE_LIBJPEG
--
2.12.2
--
sane-devel mailing list: sane-***@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/sane-devel
Unsubscribe: Send mail with subject "unsubscribe your_password"
to sane-devel-***@lists.alioth.debian.org
Aaron Muir Hamilton
2017-04-17 12:07:40 UTC
Reply
Permalink
Raw Message
If the ICC profile added does not match the colour format of the
image, libpng will abort. This can leave the scanner motors in an
incorrect state and possibly cause permanent damage.
---
frontend/scanimage.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/frontend/scanimage.c b/frontend/scanimage.c
index 0f71422c..74546763 100644
--- a/frontend/scanimage.c
+++ b/frontend/scanimage.c
@@ -1208,7 +1208,27 @@ write_png_header (SANE_Frame format, int width, int height, int depth, const cha
icc_buffer = sanei_load_icc_profile(icc_profile, &icc_size);
if (icc_size > 0)
{
- png_set_iCCP(*png_ptr, *info_ptr, basename(icc_profile), PNG_COMPRESSION_TYPE_BASE, icc_buffer, icc_size);
+ /* libpng will abort if the profile and image colour spaces do not match*/
+ /* The data colour space field is at bytes 16 to 20 in an ICC profile */
+ /* see: ICC.1:2010 § 7.2.6 */
+ int is_gray_profile = strncmp(icc_buffer + 16, "GRAY", 4) == 0;
+ int is_rgb_profile = strncmp(icc_buffer + 16, "RGB ", 4) == 0;
+ if ((is_gray_profile && color_type == PNG_COLOR_TYPE_GRAY) ||
+ (is_rgb_profile && color_type == PNG_COLOR_TYPE_RGB))
+ {
+ png_set_iCCP(*png_ptr, *info_ptr, basename(icc_profile), PNG_COMPRESSION_TYPE_BASE, icc_buffer, icc_size);
+ }
+ else
+ {
+ if (is_gray_profile)
+ {
+ fprintf(stderr, "Ignoring 'GRAY' space ICC profile because the image is RGB.\n");
+ }
+ if (is_rgb_profile)
+ {
+ fprintf(stderr, "Ignoring 'RGB ' space ICC profile because the image is Grayscale.\n");
+ }
+ }
free(icc_buffer);
}
}
--
2.12.2
--
sane-devel mailing list: sane-***@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/sane-devel
Unsubscribe: Send mail with subject "unsubscribe your_password"
to sane-devel-***@lists.alioth.debia
thierry
2017-04-17 17:54:59 UTC
Reply
Permalink
Raw Message
Hello,

This little patch add support to Canon MF230 Series scanner.
Tested OK (network only) on my MF232w :
[bjnp] get_scanner_id: Scanner identity string =
MFG:CANON;CMD:MFNP1,MultiPASS 2.1;MDL:Canon MF230
Series;CLS:IMG;DES:Canon MF230 Series; - length = 88
[bjnp] get_scanner_id: Scanner model = Canon MF230 Series

Please commit.
Best regards
Peter Talbott
2017-04-19 19:47:16 UTC
Reply
Permalink
Raw Message
Hello,

I also have a Canon ImageClass MF232.

I added that patch into the pixma_imageclass.c file, recompiled the sane backeneds and it seems to work perfectly.

Thank You!


On 04/17/2017 01:54 PM, thierry wrote:

Hello,

This little patch add support to Canon MF230 Series scanner.
Tested OK (network only) on my MF232w :
[bjnp] get_scanner_id: Scanner identity string =
MFG:CANON;CMD:MFNP1,MultiPASS 2.1;MDL:Canon MF230
Series;CLS:IMG;DES:Canon MF230 Series; - length = 88
[bjnp] get_scanner_id: Scanner model = Canon MF230 Series

Please commit.
Best regards

Loading...