Attached are two patches to fix this bug backported from 1.8.24.
The first one is a minimal patch which just corrects the segfault but
doesn't get the images to display properly in the PDF.  The second is
more comprehensive (and includes the first) and makes PNGs appear
properly in the output.

Mark
-- 
Mark Hymers, University of Newcastle Medical School
Intercalating Medical Student (MBBS / PhD)
--- htmldoc/image.cxx   2005-04-03 13:43:51.000000000 +0100
+++ ../htmldoc-1.8.24/htmldoc/image.cxx 2004-05-09 16:04:38.000000000 +0100
@@ -1539,15 +1568,7 @@
     return (0);
   }
 
-  img->pixels = (uchar *)malloc(img->width * img->height * info->bit_depth);
-
-  if ((info->color_type & PNG_COLOR_MASK_PALETTE) || info->bit_depth < 8)
-  {
-    png_set_packing(pp);
-    png_set_expand(pp);
-  }
-  else if (info->bit_depth == 16)
-    png_set_strip_16(pp);
+  img->pixels = (uchar *)malloc(img->width * img->height * depth);
 
  /*
   * Allocate pointers...
--- htmldoc/image.cxx   2005-04-03 13:43:51.000000000 +0100
+++ ../htmldoc-1.8.24/htmldoc/image.cxx 2004-05-09 16:04:38.000000000 +0100
@@ -1499,6 +1506,23 @@
 
   png_read_info(pp, info);
 
+  if (info->color_type & PNG_COLOR_MASK_PALETTE)
+  {
+    png_set_expand(pp);
+
+    // If we are writing an encrypted PDF file, bump the use count so we create
+    // an image object (Acrobat 6 bug workaround)
+    if (Encryption)
+      img->use ++;
+  }
+  else if (info->bit_depth < 8)
+  {
+    png_set_packing(pp);
+    png_set_expand(pp);
+  }
+  else if (info->bit_depth == 16)
+    png_set_strip_16(pp);
+
   if (info->color_type & PNG_COLOR_MASK_COLOR)
   {
     depth      = 3;
@@ -1513,9 +1537,14 @@
   img->width  = info->width;
   img->height = info->height;
 
-  if (info->color_type & PNG_COLOR_MASK_ALPHA)
+  if ((info->color_type & PNG_COLOR_MASK_ALPHA) || info->num_trans)
   {
-    image_need_mask(img, PSLevel == 0 && PDFVersion >= 13 ? 4 : 2);
+    if ((PSLevel == 0 && PDFVersion >= 14) || PSLevel == 3)
+      image_need_mask(img, 8);
+    else if (PSLevel == 0 && PDFVersion == 13)
+      image_need_mask(img, 2);
+    else
+      image_need_mask(img);
 
     depth ++;
   }
@@ -1527,7 +1556,7 @@
     puts("    COLOR");
   else
     puts("    GRAYSCALE");
-  if (info->color_type & PNG_COLOR_MASK_ALPHA)
+  if ((info->color_type & PNG_COLOR_MASK_ALPHA) || info->num_trans)
     puts("    ALPHA");
   if (info->color_type & PNG_COLOR_MASK_PALETTE)
     puts("    PALETTE");
@@ -1539,15 +1568,7 @@
     return (0);
   }
 
-  img->pixels = (uchar *)malloc(img->width * img->height * info->bit_depth);
-
-  if ((info->color_type & PNG_COLOR_MASK_PALETTE) || info->bit_depth < 8)
-  {
-    png_set_packing(pp);
-    png_set_expand(pp);
-  }
-  else if (info->bit_depth == 16)
-    png_set_strip_16(pp);
+  img->pixels = (uchar *)malloc(img->width * img->height * depth);
 
  /*
   * Allocate pointers...
@@ -1569,7 +1590,7 @@
   * Generate the alpha mask as necessary...
   */
 
-  if (info->color_type & PNG_COLOR_MASK_ALPHA)
+  if ((info->color_type & PNG_COLOR_MASK_ALPHA) || info->num_trans)
   {
 #ifdef DEBUG
     for (inptr = img->pixels, i = 0; i < img->height; i ++)
@@ -1668,9 +1689,20 @@
   */
 
   img->maskscale = scaling;
-  img->maskwidth = (img->width * scaling + 7) / 8;
-  size           = img->maskwidth * img->height * scaling;
-  
+
+  if (scaling == 8)
+  {
+    // Alpha image
+    img->maskwidth = img->width;
+    size           = img->width * img->height;
+  }
+  else
+  {
+    // Alpha mask
+    img->maskwidth = (img->width * scaling + 7) / 8;
+    size           = img->maskwidth * img->height * scaling;
+  }
+
   img->mask = (uchar *)calloc(size, 1);
 }
 
@@ -1692,57 +1724,42 @@
                  0x80, 0x40, 0x20, 0x10,
                  0x08, 0x04, 0x02, 0x01
                };
-  static uchar dither[16][16] = // Simple 16x16 Floyd dither
+  static uchar dither[4][4] = // Simple 4x4 clustered-dot dither
                {
-                { 0,   128, 32,  160, 8,   136, 40,  168,
-                  2,   130, 34,  162, 10,  138, 42,  170 },
-                { 192, 64,  224, 96,  200, 72,  232, 104,
-                  194, 66,  226, 98,  202, 74,  234, 106 },
-                { 48,  176, 16,  144, 56,  184, 24,  152,
-                  50,  178, 18,  146, 58,  186, 26,  154 },
-                { 240, 112, 208, 80,  248, 120, 216, 88,
-                  242, 114, 210, 82,  250, 122, 218, 90 },
-                { 12,  140, 44,  172, 4,   132, 36,  164,
-                  14,  142, 46,  174, 6,   134, 38,  166 },
-                { 204, 76,  236, 108, 196, 68,  228, 100,
-                  206, 78,  238, 110, 198, 70,  230, 102 },
-                { 60,  188, 28,  156, 52,  180, 20,  148,
-                  62,  190, 30,  158, 54,  182, 22,  150 },
-                { 252, 124, 220, 92,  244, 116, 212, 84,
-                  254, 126, 222, 94,  246, 118, 214, 86 },
-                { 3,   131, 35,  163, 11,  139, 43,  171,
-                  1,   129, 33,  161, 9,   137, 41,  169 },
-                { 195, 67,  227, 99,  203, 75,  235, 107,
-                  193, 65,  225, 97,  201, 73,  233, 105 },
-                { 51,  179, 19,  147, 59,  187, 27,  155,
-                  49,  177, 17,  145, 57,  185, 25,  153 },
-                { 243, 115, 211, 83,  251, 123, 219, 91,
-                  241, 113, 209, 81,  249, 121, 217, 89 },
-                { 15,  143, 47,  175, 7,   135, 39,  167,
-                  13,  141, 45,  173, 5,   133, 37,  165 },
-                { 207, 79,  239, 111, 199, 71,  231, 103,
-                  205, 77,  237, 109, 197, 69,  229, 101 },
-                { 63,  191, 31,  159, 55,  183, 23,  151,
-                  61,  189, 29,  157, 53,  181, 21,  149 },
-                { 254, 127, 223, 95,  247, 119, 215, 87,
-                  253, 125, 221, 93,  245, 117, 213, 85 }
-              };
+                 { 0,  2,  15, 6 },
+                 { 4,  12, 9,  11 },
+                 { 14, 7,  1,  3 },
+                 { 8,  10, 5,  13 }
+               };
 
 
   if (img == NULL || img->mask == NULL || x < 0 || x >= img->width ||
       y < 0 || y > img->height)
     return;
 
-  x *= img->maskscale;
-  y *= img->maskscale;
+  if (img->maskscale == 8)
+  {
+    // Store the alpha value directly...
+    if (PSLevel)
+      img->mask[y * img->maskwidth + x] = 255 - alpha;
+    else
+      img->mask[y * img->maskwidth + x] = alpha;
+  }
+  else
+  {
+    // Store an alpha mask...
+    x *= img->maskscale;
+    y *= img->maskscale;
+    alpha >>= 4;
 
-  for (i = 0; i < img->maskscale; i ++, y ++, x -= img->maskscale)
-    for (j = 0; j < img->maskscale; j ++, x ++)
-    {
-      maskptr  = img->mask + y * img->maskwidth + x / 8;
-      if (alpha <= dither[x & 15][y & 15])
-       *maskptr |= masks[x & 7];
-    }
+    for (i = 0; i < img->maskscale; i ++, y ++, x -= img->maskscale)
+      for (j = 0; j < img->maskscale; j ++, x ++)
+      {
+       maskptr  = img->mask + y * img->maskwidth + x / 8;
+       if (alpha <= dither[x & 3][y & 3])
+         *maskptr |= masks[x & 7];
+      }
+  }
 }
 
 

Reply via email to