Hi!

First, an admission. When introducing the original pdftohtml's "mask
extraction as PNG" patch, it seems I got the colors wrong. Yeah, masks
have only two of them - and I got them wrong. Both. :)

But just to be sure let me ask: 0.0 is black? and 1.0 is white?

As per recommendation of Leonard Rosenthol, who kindly quoted some
documentation for me and hinted where to look further, I have tried to
come up with a method to detect the mask inversion.

Note that it is a mask inversion different from the decode array
inversion. It is not even a real inversion. Simpler example (as I have
it in my documents) is that mask itself looks like negative, and the
background/foreground colors in the document are swapped. Negative
mask is used to paint white on black background, while the rest of the
document has white background.

Since in case of pdftohtml, it is impossible to know the background, I
use simple heuristic: if getFillGray() is greater than 0.5, I assume
the mask is painted with light color over dark and thus mask's
inversion flag (as indicated by the decode array) should be inverted.
(Relies on the  presumption that background of most documents is
light.)

Attached are two different (and conflicting) patches.

- proper-mask-color-001.diff
   One-liner to clear my conscience. Use proper non-inverted colors
for PNG. My original error stemmed from me reading libpng
documentation. Indeed, libpng requires bit flip for the special case
of monochrome images. But. PNGWriter doesn't use monochrome PNGs - it
uses the grayscale instead, which doesn't require bit/byte flip.

- invert-mask-001.diff
  Implement inversion of the mask, if that is required by the decode
array or background/foreground colors appear to be swapped. The
heuristic is just 4 lines, probably unreliable but "works for me" -
and thus I will not object for the 4 lines to be removed.

Thanks and have a nice weekend!
diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
index 3d8836b..72dd5cc 100644
--- a/utils/HtmlOutputDev.cc
+++ b/utils/HtmlOutputDev.cc
@@ -1351,7 +1351,8 @@ void HtmlOutputDev::drawJpegImage(GfxState *state, Stream *str)
 }
 
 void HtmlOutputDev::drawPngImage(GfxState *state, Stream *str, int width, int height,
-                                 GfxImageColorMap *colorMap, GBool isMask)
+                                 GfxImageColorMap *colorMap, GBool isMask,
+                                 GBool invertMask)
 {
 #ifdef ENABLE_LIBPNG
   FILE *f1;
@@ -1426,9 +1427,14 @@ void HtmlOutputDev::drawPngImage(GfxState *state, Stream *str, int width, int he
       // read the row of the mask
       Guchar *bit_row = imgStr->getLine();
 
-      // invert for PNG
-      for(int i = 0; i < width; i++)
-        png_row[i] = bit_row[i] ? 0x00 : 0xff ;
+      // convert and invert, if needed
+      if (invertMask) {
+        for(int i = 0; i < width; i++)
+          png_row[i] = bit_row[i] ? 0x00 : 0xff ;
+      } else {
+        for(int i = 0; i < width; i++)
+          png_row[i] = bit_row[i] ? 0xff : 0x00 ;
+      }
 
       if (!writer->writeRow( &png_row ))
       {
@@ -1479,14 +1485,24 @@ void HtmlOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
     OutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg);
     return;
   }
+
+  // Heuristic: invert the invert flag, depending on the foreground color. 
+  // If mask is painted with light color, we assume it is used against 
+  // the dark background and thus have to invert it.
+  GfxGray gray;
+  state->getFillGray(&gray);
+  if (colToDbl(gray) > 0.5)
+    invert = !invert;
   
   // dump JPEG file
   if (dumpJPEG  && str->getKind() == strDCT) {
+    if (invert)
+      error(errUnimplemented,-1,"Inversion of mask image is needed, but not implemented for JPEGs.");
     drawJpegImage(state, str);
   }
   else {
 #ifdef ENABLE_LIBPNG
-    drawPngImage(state, str, width, height, NULL, gTrue);
+    drawPngImage(state, str, width, height, NULL, gTrue, invert);
 #else
     OutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg);
 #endif
diff --git a/utils/HtmlOutputDev.h b/utils/HtmlOutputDev.h
index 2f35759..654e5b1 100644
--- a/utils/HtmlOutputDev.h
+++ b/utils/HtmlOutputDev.h
@@ -324,7 +324,8 @@ private:
 #endif
   void drawJpegImage(GfxState *state, Stream *str);
   void drawPngImage(GfxState *state, Stream *str, int width, int height,
-                    GfxImageColorMap *colorMap, GBool isMask = gFalse);
+                    GfxImageColorMap *colorMap, GBool isMask = gFalse,
+                    GBool invertMask = gFalse);
   GooString *createImageFileName(const char *ext);
 
   FILE *fContentsFrame;
diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
index 3d8836b..70a1637 100644
--- a/utils/HtmlOutputDev.cc
+++ b/utils/HtmlOutputDev.cc
@@ -1428,7 +1428,7 @@ void HtmlOutputDev::drawPngImage(GfxState *state, Stream *str, int width, int he
 
       // invert for PNG
       for(int i = 0; i < width; i++)
-        png_row[i] = bit_row[i] ? 0x00 : 0xff ;
+        png_row[i] = bit_row[i] ? 0xff : 0x00 ;
 
       if (!writer->writeRow( &png_row ))
       {
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to