]> git.ipfire.org Git - thirdparty/cups-filters.git/commitdiff
Add convertbits functions in cupsfilters library
authorVikrant <vikrantmalik051@gmail.com>
Wed, 8 Jul 2020 11:07:52 +0000 (16:37 +0530)
committerVikrant <vikrantmalik051@gmail.com>
Thu, 16 Jul 2020 09:58:37 +0000 (15:28 +0530)
Makefile.am
cupsfilters/bitmap.c [new file with mode: 0644]
cupsfilters/bitmap.h [new file with mode: 0644]
filter/pclmtoraster.cxx
filter/pdftoraster.cxx

index c17cec6de25278c2cbe77b8019bbc29ec902336c..cc8f2718a66d235e3b53754ed732d12efd05e8c3 100644 (file)
@@ -228,6 +228,7 @@ EXTRA_DIST += \
 # ====================
 pkgfiltersincludedir = $(includedir)/cupsfilters
 pkgfiltersinclude_DATA = \
+       cupsfilters/bitmap.h \
        cupsfilters/colord.h \
        cupsfilters/colormanager.h \
        cupsfilters/driver.h \
@@ -262,6 +263,7 @@ TESTS += \
 
 libcupsfilters_la_SOURCES = \
        cupsfilters/attr.c \
+       cupsfilters/bitmap.c \
        cupsfilters/check.c \
        cupsfilters/cmyk.c \
        cupsfilters/colord.c \
@@ -850,6 +852,7 @@ urftopdf_LDADD = \
 
 pclmtoraster_SOURCES = \
        filter/pclmtoraster.cxx \
+       cupsfilters/bitmap.h \
        cupsfilters/raster.h \
        filter/unirast.h
 pclmtoraster_CXXFLAGS = \
@@ -947,6 +950,7 @@ pdftops_LDADD = \
 pdftops_DEPENDENCIES = $(STRCASESTR)
 
 pdftoraster_SOURCES = \
+ cupsfilters/bitmap.h \
        filter/pdftoraster.cxx
 pdftoraster_CFLAGS = \
        -I$(srcdir)/cupsfilters/ \
diff --git a/cupsfilters/bitmap.c b/cupsfilters/bitmap.c
new file mode 100644 (file)
index 0000000..d299bae
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+Copyright (c) 2020, Vikrant Malik
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+MIT Open Source License  -  http://www.opensource.org/
+
+*/
+
+#include <stdio.h>
+
+unsigned int dither1[16][16] = {
+  {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},
+  {255,127,223,95,247,119,215,87,253,125,221,93,245,117,213,85}
+};
+unsigned int dither2[8][8] = {
+  {0,32,8,40,2,34,10,42},
+  {48,16,56,24,50,18,58,26},
+  {12,44,4,36,14,46,6,38},
+  {60,28,52,20,62,30,54,22},
+  {3,35,11,43,1,33,9,41},
+  {51,19,59,27,49,17,57,25},
+  {15,47,7,39,13,45,5,37},
+  {63,31,55,23,61,29,53,21}
+};
+unsigned int dither4[4][4] = {
+  {0,8,2,10},
+  {12,4,14,6},
+  {3,11,1,9},
+  {15,7,13,5}
+};
+
+
+unsigned char *convertBitsNoop(unsigned char *src, unsigned char *dst,
+    unsigned int x, unsigned int y, unsigned int cupsNumColors)
+{
+  return src;
+}
+
+unsigned char *convert8to1(unsigned char *src, unsigned char *dst,
+    unsigned int x, unsigned int y, unsigned int cupsNumColors)
+{
+  unsigned char c = 0;
+  /* assumed that max number of colors is 4 */
+  for (unsigned int i = 0;i < cupsNumColors; i++) {
+    c <<= 1;
+    /* ordered dithering */
+    if (src[i] > dither1[y & 0xf][x & 0xf]) {
+      c |= 0x1;
+    }
+  }
+  *dst = c;
+  return dst;
+}
+
+unsigned char *convert8to2(unsigned char *src, unsigned char *dst,
+    unsigned int x, unsigned int y, unsigned int cupsNumColors)
+{
+  unsigned char c = 0;
+  /* assumed that max number of colors is 4 */
+  for (unsigned int i = 0;i < cupsNumColors;i++) {
+    unsigned int d;
+
+    c <<= 2;
+    /* ordered dithering */
+    d = src[i] + dither2[y & 0x7][x & 0x7];
+    if (d > 255) d = 255;
+    c |= d >> 6;
+  }
+  *dst = c;
+  return dst;
+}
+
+unsigned char *convert8to4(unsigned char *src, unsigned char *dst,
+    unsigned int x, unsigned int y, unsigned int cupsNumColors)
+{
+  unsigned short c = 0;
+
+  /* assumed that max number of colors is 4 */
+  for (unsigned int i = 0;i < cupsNumColors;i++) {
+    unsigned int d;
+
+    c <<= 4;
+    /* ordered dithering */
+    d = src[i] + dither4[y & 0x3][x & 0x3];
+    if (d > 255) d = 255;
+    c |= d >> 4;
+  }
+  if (cupsNumColors < 3) {
+    dst[0] = c;
+  } else {
+    dst[0] = c >> 8;
+    dst[1] = c;
+  }
+  return dst;
+}
+
+unsigned char *convert8to16(unsigned char *src, unsigned char *dst,
+    unsigned int x, unsigned int y, unsigned int cupsNumColors)
+{
+  /* assumed that max number of colors is 4 */
+  for (unsigned int i = 0;i < cupsNumColors;i++) {
+    dst[i*2] = src[i];
+    dst[i*2+1] = src[i];
+  }
+  return dst;
+}
+
+void writePixel1(unsigned char *dst,
+    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  switch (cupsNumColors) {
+  case 1:
+    {
+      unsigned int bo = pixeli & 0x7;
+      if ((pixeli & 7) == 0) dst[pixeli/8] = 0;
+      dst[pixeli/8] |= *pixelBuf << (7-bo);
+    }
+    break;
+  case 6:
+    dst[pixeli] = *pixelBuf;
+    break;
+  case 3:
+  case 4:
+  default:
+    {
+      unsigned int qo = (pixeli & 0x1)*4;
+      if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
+      dst[pixeli/2] |= *pixelBuf << (4-qo);
+    }
+    break;
+  }
+}
+
+void writePlanePixel1(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  unsigned int bo = pixeli & 0x7;
+  unsigned char so = cupsNumColors - plane - 1;
+  if ((pixeli & 7) == 0) dst[pixeli/8] = 0;
+  dst[pixeli/8] |= ((*pixelBuf >> so) & 1) << (7-bo);
+}
+
+void writePixel2(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  switch (cupsNumColors) {
+  case 1:
+    {
+      unsigned int bo = (pixeli & 0x3)*2;
+      if ((pixeli & 3) == 0) dst[pixeli/4] = 0;
+      dst[pixeli/4] |= *pixelBuf << (6-bo);
+    }
+    break;
+  case 3:
+  case 4:
+  default:
+    dst[pixeli] = *pixelBuf;
+    break;
+  }
+}
+
+void writePlanePixel2(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  unsigned int bo = (pixeli & 0x3)*2;
+  unsigned char so = (cupsNumColors - plane - 1)*2;
+  if ((pixeli & 3) == 0) dst[pixeli/4] = 0;
+  dst[pixeli/4] |= ((*pixelBuf >> so) & 3) << (6-bo);
+}
+
+void writePixel4(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  switch (cupsNumColors) {
+  case 1:
+    {
+      unsigned int bo = (pixeli & 0x1)*4;
+      if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
+      dst[pixeli/2] |= *pixelBuf << (4-bo);
+    }
+    break;
+  case 3:
+  case 4:
+  default:
+    dst[pixeli*2] = pixelBuf[0];
+    dst[pixeli*2+1] = pixelBuf[1];
+    break;
+  }
+}
+
+void writePlanePixel4(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  unsigned short c = (pixelBuf[0] << 8) | pixelBuf[1];
+  unsigned int bo = (pixeli & 0x1)*4;
+  unsigned char so = (cupsNumColors - plane - 1)*4;
+  if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
+  dst[pixeli/2] |= ((c >> so) & 0xf) << (4-bo);
+}
+
+void writePixel8(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  unsigned char *dp = dst + pixeli*cupsNumColors;
+  for (unsigned int i = 0;i < cupsNumColors;i++) {
+    dp[i] = pixelBuf[i];
+  }
+}
+
+void writePlanePixel8(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  dst[pixeli] = pixelBuf[plane];
+}
+
+void writePixel16(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  unsigned char *dp = dst + pixeli*cupsNumColors*2;
+  for (unsigned int i = 0;i < cupsNumColors*2;i++) {
+    dp[i] = pixelBuf[i];
+  }
+}
+
+void writePlanePixel16(unsigned char *dst, unsigned int plane, 
+    unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors)
+{
+  dst[pixeli*2] = pixelBuf[plane*2];
+  dst[pixeli*2+1] = pixelBuf[plane*2+1];
+}
diff --git a/cupsfilters/bitmap.h b/cupsfilters/bitmap.h
new file mode 100644 (file)
index 0000000..bc2689b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+Copyright (c) 2020, Vikrant Malik
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+MIT Open Source License  -  http://www.opensource.org/
+
+*/
+
+
+
+#  ifdef __cplusplus
+extern "C" {
+#  endif /* __cplusplus */
+
+/* Common routines for accessing the colord CMS framework */
+
+unsigned char  *convertBitsNoop                        (unsigned char *src, unsigned char *dst,
+                                                       unsigned int x, unsigned int y, unsigned int cupsNumColors);
+unsigned char  *convert8to1                            (unsigned char *src, unsigned char *dst,
+                                                       unsigned int x, unsigned int y, unsigned int cupsNumColors);
+unsigned char  *convert8to2                            (unsigned char *src, unsigned char *dst,
+                                                       unsigned int x, unsigned int y, unsigned int cupsNumColors);
+unsigned char  *convert8to4                            (unsigned char *src, unsigned char *dst,
+                                                       unsigned int x, unsigned int y, unsigned int cupsNumColors);
+unsigned char  *convert8to16                           (unsigned char *src, unsigned char *dst,
+                                                       unsigned int x, unsigned int y, unsigned int cupsNumColors);
+void           writePixel1                             (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePlanePixel1                        (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePixel2                             (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePlanePixel2                        (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePixel4                             (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePlanePixel4                        (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePixel8                             (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePlanePixel8                        (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePixel16                            (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+void           writePlanePixel16                       (unsigned char *dst, unsigned int plane, 
+                                                       unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+
+#  ifdef __cplusplus
+}
+#  endif /* __cplusplus */
+
index 7839d95ead3c9bf39b11eee2e44f15cb846e4fce..74bee9b9910da0836c775319b9d3b8b3a64a4805 100644 (file)
 #include <qpdf/QPDFObjectHandle.hh>
 #include <cupsfilters/raster.h>
 #include <cupsfilters/image.h>
+#include <cupsfilters/bitmap.h>
 
 #if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
 #define HAVE_CUPS_1_7 1
 #endif
-#define MAX_CHECK_COMMENT_LINES        20
 #define MAX_BYTES_PER_PIXEL 32
 
 namespace {
   typedef unsigned char *(*ConvertCSpace)(unsigned char *src, unsigned char *dst, unsigned int row, unsigned int pixels);
+  typedef void (*WritePixelFunc)(unsigned char *dst, unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf, unsigned int cupsNumColors);
+  typedef unsigned char *(*ConvertBitsFunc)(unsigned char *src, unsigned char *dst, unsigned int x, unsigned int y, unsigned int cupsNumColors);
   ConvertCSpace convertcspace;
+  ConvertBitsFunc convertbits;
+  WritePixelFunc writePixel;
   int pwgraster = 0;
+  int numcolors = 0;
   cups_page_header2_t header;
   ppd_file_t *ppd = 0;
   char pageSizeRequested[64];
@@ -365,7 +370,14 @@ static unsigned char *RGBtoCMYLine(unsigned char *src, unsigned char *dst, unsig
 
 static unsigned char *RGBtoWhiteLine(unsigned char *src, unsigned char *dst, unsigned int row, unsigned int pixels)
 {
-  cupsImageRGBToWhite(src,dst,pixels);
+  // cupsImageRGBToWhite(src,dst,pixels);
+  if (header.cupsBitsPerColor != 1) {
+    cupsImageRGBToWhite(src,dst,pixels);
+  } else {
+    cupsImageRGBToWhite(src,src,pixels);
+    onebitpixel(src, dst, header.cupsWidth, header.cupsHeight, row, pixels);
+  }
+
   return dst;
 }
 
@@ -396,7 +408,13 @@ static unsigned char *CMYKtoCMYLine(unsigned char *src, unsigned char *dst, unsi
 
 static unsigned char *CMYKtoWhiteLine(unsigned char *src, unsigned char *dst, unsigned int row, unsigned int pixels)
 {
-  cupsImageCMYKToWhite(src,dst,pixels);
+  // cupsImageCMYKToWhite(src,dst,pixels);
+  if (header.cupsBitsPerColor != 1) {
+    cupsImageCMYKToWhite(src,dst,pixels);
+  } else {
+    cupsImageCMYKToWhite(src,src,pixels);
+    onebitpixel(src, dst, header.cupsWidth, header.cupsHeight, row, pixels);
+  }
   return dst;
 }
 
@@ -405,7 +423,7 @@ static unsigned char *CMYKtoBlackLine(unsigned char *src, unsigned char *dst, un
   if (header.cupsBitsPerColor != 1) {
     cupsImageCMYKToBlack(src,dst,pixels);
   } else {
-    cupsImageCMYKToWhite(src,src,pixels);
+    cupsImageCMYKToBlack(src,src,pixels);
     onebitpixel(src, dst, header.cupsWidth, header.cupsHeight, row, pixels);
   }
   return dst;
@@ -447,45 +465,138 @@ static unsigned char *convertcspaceNoop(unsigned char *src, unsigned char *dst,
 static unsigned char *convertLine(unsigned char *src, unsigned char *dst,
      unsigned int row, unsigned int plane, unsigned int pixels)
 {
-  /* Assumed that BitsPerColor is 8 */
-  unsigned char pixelBuf1[MAX_BYTES_PER_PIXEL];
-  unsigned char *pb;
-
-  switch (header.cupsColorOrder)
-  {
-  case CUPS_ORDER_BANDED:
-  case CUPS_ORDER_PLANAR:
-   pb = convertcspace(src, pixelBuf1, row, pixels);
-   for (unsigned int i = 0; i < pixels; i++, pb += header.cupsNumColors)
-     dst[i] = pb[plane];
-   break;
-  case CUPS_ORDER_CHUNKED:
-  default:
-    pb = convertcspace(src, dst, row, pixels);
-    dst = pb;
-   break;
+  if (header.cupsBitsPerColor == 1 && header.cupsNumColors == 1) {
+    convertcspace(src, dst, row, pixels);
+  } else {
+    for (unsigned int i = 0;i < pixels;i++) {
+      unsigned char pixelBuf1[MAX_BYTES_PER_PIXEL];
+      unsigned char pixelBuf2[MAX_BYTES_PER_PIXEL];
+      unsigned char *pb;
+      pb = convertcspace(src + i*numcolors, pixelBuf1, row, 1);
+      pb = convertbits(pb, pixelBuf2, i, row, header.cupsNumColors);
+      writePixel(dst, plane, i, pb, header.cupsNumColors);
+    }
   }
   return dst;
 }
 
+static void selectConvertFunc(std::string colorspace) {
+
+  switch (header.cupsColorSpace) {
+    case CUPS_CSPACE_K:
+     if (colorspace == "/DeviceRGB") convertcspace = RGBtoBlackLine;
+     else if (colorspace == "/DeviceCMYK") convertcspace = CMYKtoBlackLine;
+     else if (colorspace == "/DeviceGray") convertcspace = GraytoBlackLine;
+     break;
+    case CUPS_CSPACE_SW:
+     if (colorspace == "/DeviceRGB") convertcspace = RGBtoWhiteLine;
+     else if (colorspace == "/DeviceCMYK") convertcspace = CMYKtoWhiteLine;
+     break;
+    case CUPS_CSPACE_CMY:
+     if (colorspace == "/DeviceRGB") convertcspace = RGBtoCMYLine;
+     else if (colorspace == "/DeviceCMYK") convertcspace = CMYKtoCMYLine;
+     else if (colorspace == "/DeviceGray") convertcspace = GraytoCMYLine;
+     break;
+    case CUPS_CSPACE_CMYK:
+     if (colorspace == "/DeviceRGB") convertcspace = RGBtoCMYKLine;
+     else if (colorspace == "/DeviceGray") convertcspace = GraytoCMYKLine;
+     break;
+    case CUPS_CSPACE_RGB:
+    case CUPS_CSPACE_ADOBERGB:
+    case CUPS_CSPACE_SRGB:
+    default:
+     if (colorspace == "/DeviceCMYK") convertcspace = CMYKtoRGBLine;
+     else if (colorspace == "/DeviceGray") convertcspace = GraytoRGBLine;
+     break;
+   }
+
+  switch (header.cupsBitsPerColor) {
+    case 2:
+      convertbits = convert8to2;
+      break;
+    case 4:
+      convertbits = convert8to4;
+      break;
+    case 16:
+      convertbits = convert8to16;
+      break;
+    case 1:
+      if (header.cupsNumColors == 1) {
+          convertbits = convertBitsNoop;
+      } else {
+          convertbits = convert8to1;
+      }
+      break;
+    case 8:
+    default:
+      convertbits = convertBitsNoop;
+      break;
+    }
+
+  switch (header.cupsBitsPerColor) {
+  case 2:
+    if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+        || header.cupsNumColors == 1) {
+      writePixel = writePixel2;
+    } else {
+      writePixel = writePlanePixel2;
+    }
+    break;
+  case 4:
+    if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+        || header.cupsNumColors == 1) {
+      writePixel = writePixel4;
+    } else {
+      writePixel = writePlanePixel4;
+    }
+    break;
+  case 16:
+    if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+        || header.cupsNumColors == 1) {
+      writePixel = writePixel16;
+    } else {
+      writePixel = writePlanePixel16;
+    }
+    break;
+  case 1:
+    if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+        || header.cupsNumColors == 1) {
+      writePixel = writePixel1;
+    } else {
+      writePixel = writePlanePixel1;
+    }
+    break;
+  case 8:
+  default:
+    if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+        || header.cupsNumColors == 1) {
+      writePixel = writePixel8;
+    } else {
+      writePixel = writePlanePixel8;
+    }
+    break;
+  }
+}
+
 static void outPage(cups_raster_t *raster, QPDFObjectHandle page, int pgno) {
   long long        rotate = 0,
                    height,
                    width;
   double           l;
+  int              rowsize = 0, bufsize = 0, pixel_count = 0, temp = 0;
+  float            mediaBox[4];
+  unsigned char    *bitmap = NULL,
+                   *colordata = NULL,
+                   *lineBuf = NULL,
+                   *dp = NULL;
+  std::string      colorspace;
   QPDFObjectHandle image;
   QPDFObjectHandle imgdict;
-  int              rowsize = 0, bufsize = 0, pixel_count = 0, temp;
-  float            mediaBox[4];
-  unsigned char    *bitmap = NULL;
-  unsigned char    *colordata = NULL;
   QPDFObjectHandle colorspace_obj;
-  unsigned char    *lineBuf = NULL;
-  unsigned char    *dp = NULL;
-  std::string      colorspace;
 
 
   convertcspace = convertcspaceNoop;
+  convertbits = convertBitsNoop;
 
   if (page.getKey("/Rotate").isInteger())
     rotate = page.getKey("/Rotate").getIntValueAsInt();
@@ -552,14 +663,17 @@ static void outPage(cups_raster_t *raster, QPDFObjectHandle page, int pgno) {
     exit(1);
   }
 
-  colorspace = (colorspace_obj.isName() ? colorspace_obj.getName() : std::string());
+  colorspace = (colorspace_obj.isName() ? colorspace_obj.getName() : "/DeviceRGB"); /* Default for pclm files in DeviceRGB */
 
   if (colorspace == "/DeviceRGB") {
     rowsize = header.cupsWidth*3;
+    numcolors = 3;
   } else if (colorspace == "/DeviceCMYK") {
-     rowsize = header.cupsWidth*4;
+    rowsize = header.cupsWidth*4;
+    numcolors = 4;
   } else if (colorspace == "/DeviceGray") {
-     rowsize = header.cupsWidth;
+    rowsize = header.cupsWidth;
+    numcolors = 1;
   } else {
     fprintf(stderr, "ERROR: Colorspace %s not supported\n", colorspace.c_str());
     exit(1);
@@ -574,33 +688,7 @@ static void outPage(cups_raster_t *raster, QPDFObjectHandle page, int pgno) {
 
   colordata = bitmap;
 
-  switch (header.cupsColorSpace) {
-    case CUPS_CSPACE_K:
-     if (colorspace == "/DeviceRGB") convertcspace = RGBtoBlackLine;
-     else if (colorspace == "/DeviceCMYK") convertcspace = CMYKtoBlackLine;
-     else if (colorspace == "/DeviceGray") convertcspace = GraytoBlackLine;
-     break;
-    case CUPS_CSPACE_SW:
-     if (colorspace == "/DeviceRGB") convertcspace = RGBtoWhiteLine;
-     else if (colorspace == "/DeviceCMYK") convertcspace = CMYKtoWhiteLine;
-     break;
-    case CUPS_CSPACE_CMY:
-     if (colorspace == "/DeviceRGB") convertcspace = RGBtoCMYLine;
-     else if (colorspace == "/DeviceCMYK") convertcspace = CMYKtoCMYLine;
-     else if (colorspace == "/DeviceGray") convertcspace = GraytoCMYLine;
-     break;
-    case CUPS_CSPACE_CMYK:
-     if (colorspace == "/DeviceRGB") convertcspace = RGBtoCMYKLine;
-     else if (colorspace == "/DeviceGray") convertcspace = GraytoCMYKLine;
-     break;
-    case CUPS_CSPACE_RGB:
-    case CUPS_CSPACE_ADOBERGB:
-    case CUPS_CSPACE_SRGB:
-    default:
-     if (colorspace == "/DeviceCMYK") convertcspace = CMYKtoRGBLine;
-     else if (colorspace == "/DeviceGray") convertcspace = GraytoRGBLine;
-     break;
-   }
+  selectConvertFunc(colorspace);
 
   lineBuf = new unsigned char [bytesPerLine];
   for (unsigned int plane = 0; plane < nplanes ; plane++) {
@@ -610,7 +698,7 @@ static void outPage(cups_raster_t *raster, QPDFObjectHandle page, int pgno) {
        dp = convertLine(bp, lineBuf, h, plane + band, header.cupsWidth);
        cupsRasterWritePixels(raster, dp, bytesPerLine);
       }
-    bp += rowsize;
+     bp += rowsize;
     }
   }
 
index 9878e853185f6f990756d87be33d1cc988eed3fc..38311b6597e8917b5fb8a15358050044eca9b4ba 100644 (file)
@@ -47,6 +47,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <cupsfilters/image.h>
 #include <cupsfilters/raster.h>
 #include <cupsfilters/colormanager.h>
+#include <cupsfilters/bitmap.h>
 #include <strings.h>
 #include <math.h>
 #include <poppler/cpp/poppler-document.h>
@@ -99,9 +100,9 @@ namespace {
   typedef unsigned char *(*ConvertCSpaceFunc)(unsigned char *src,
     unsigned char *pixelBuf, unsigned int x, unsigned int y);
   typedef unsigned char *(*ConvertBitsFunc)(unsigned char *src,
-    unsigned char *dst, unsigned int x, unsigned int y);
+    unsigned char *dst, unsigned int x, unsigned int y, unsigned int numcolors);
   typedef void (*WritePixelFunc)(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf);
+    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf, unsigned int numcolors);
 
   int exitCode = 0;
   int pwgraster = 0;
@@ -166,23 +167,6 @@ namespace {
     {63,191,31,159,55,183,23,151,61,189,29,157,53,181,21,149},
     {255,127,223,95,247,119,215,87,253,125,221,93,245,117,213,85}
   };
-  unsigned int dither2[8][8] = {
-    {0,32,8,40,2,34,10,42},
-    {48,16,56,24,50,18,58,26},
-    {12,44,4,36,14,46,6,38},
-    {60,28,52,20,62,30,54,22},
-    {3,35,11,43,1,33,9,41},
-    {51,19,59,27,49,17,57,25},
-    {15,47,7,39,13,45,5,37},
-    {63,31,55,23,61,29,53,21}
-  };
-  unsigned int dither4[4][4] = {
-    {0,8,2,10},
-    {12,4,14,6},
-    {3,11,1,9},
-    {15,7,13,5}
-  };
-
   /* for color profiles */
   cmsHPROFILE colorProfile = NULL;
   cmsHPROFILE popplerColorProfile = NULL;
@@ -940,205 +924,6 @@ static unsigned char *W8toK8(unsigned char *src, unsigned char *pixelBuf,
   return pixelBuf;
 }
 
-static unsigned char *convertBitsNoop(unsigned char *src, unsigned char *dst,
-    unsigned int x, unsigned int y)
-{
-    return src;
-}
-
-static unsigned char *convert8to1(unsigned char *src, unsigned char *dst,
-    unsigned int x, unsigned int y)
-{
-  unsigned char c = 0;
-  /* assumed that max number of colors is 4 */
-  for (unsigned int i = 0;i < header.cupsNumColors;i++) {
-    c <<= 1;
-    /* ordered dithering */
-    if (src[i] > dither1[y & 0xf][x & 0xf]) {
-      c |= 0x1;
-    }
-  }
-  *dst = c;
-  return dst;
-}
-
-static unsigned char *convert8to2(unsigned char *src, unsigned char *dst,
-    unsigned int x, unsigned int y)
-{
-  unsigned char c = 0;
-  /* assumed that max number of colors is 4 */
-  for (unsigned int i = 0;i < header.cupsNumColors;i++) {
-    unsigned int d;
-
-    c <<= 2;
-    /* ordered dithering */
-    d = src[i] + dither2[y & 0x7][x & 0x7];
-    if (d > 255) d = 255;
-    c |= d >> 6;
-  }
-  *dst = c;
-  return dst;
-}
-
-static unsigned char *convert8to4(unsigned char *src, unsigned char *dst,
-    unsigned int x, unsigned int y)
-{
-  unsigned short c = 0;
-
-  /* assumed that max number of colors is 4 */
-  for (unsigned int i = 0;i < header.cupsNumColors;i++) {
-    unsigned int d;
-
-    c <<= 4;
-    /* ordered dithering */
-    d = src[i] + dither4[y & 0x3][x & 0x3];
-    if (d > 255) d = 255;
-    c |= d >> 4;
-  }
-  if (header.cupsNumColors < 3) {
-    dst[0] = c;
-  } else {
-    dst[0] = c >> 8;
-    dst[1] = c;
-  }
-  return dst;
-}
-
-static unsigned char *convert8to16(unsigned char *src, unsigned char *dst,
-    unsigned int x, unsigned int y)
-{
-  /* assumed that max number of colors is 4 */
-  for (unsigned int i = 0;i < header.cupsNumColors;i++) {
-    dst[i*2] = src[i];
-    dst[i*2+1] = src[i];
-  }
-  return dst;
-}
-
-static void writePixel1(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  switch (header.cupsNumColors) {
-  case 1:
-    {
-      unsigned int bo = pixeli & 0x7;
-      if ((pixeli & 7) == 0) dst[pixeli/8] = 0;
-      dst[pixeli/8] |= *pixelBuf << (7-bo);
-    }
-    break;
-  case 6:
-    dst[pixeli] = *pixelBuf;
-    break;
-  case 3:
-  case 4:
-  default:
-    {
-      unsigned int qo = (pixeli & 0x1)*4;
-      if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
-      dst[pixeli/2] |= *pixelBuf << (4-qo);
-    }
-    break;
-  }
-}
-
-static void writePlanePixel1(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  unsigned int bo = pixeli & 0x7;
-  unsigned char so = header.cupsNumColors - plane - 1;
-  if ((pixeli & 7) == 0) dst[pixeli/8] = 0;
-  dst[pixeli/8] |= ((*pixelBuf >> so) & 1) << (7-bo);
-}
-
-static void writePixel2(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  switch (header.cupsNumColors) {
-  case 1:
-    {
-      unsigned int bo = (pixeli & 0x3)*2;
-      if ((pixeli & 3) == 0) dst[pixeli/4] = 0;
-      dst[pixeli/4] |= *pixelBuf << (6-bo);
-    }
-    break;
-  case 3:
-  case 4:
-  default:
-    dst[pixeli] = *pixelBuf;
-    break;
-  }
-}
-
-static void writePlanePixel2(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  unsigned int bo = (pixeli & 0x3)*2;
-  unsigned char so = (header.cupsNumColors - plane - 1)*2;
-  if ((pixeli & 3) == 0) dst[pixeli/4] = 0;
-  dst[pixeli/4] |= ((*pixelBuf >> so) & 3) << (6-bo);
-}
-
-static void writePixel4(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  switch (header.cupsNumColors) {
-  case 1:
-    {
-      unsigned int bo = (pixeli & 0x1)*4;
-      if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
-      dst[pixeli/2] |= *pixelBuf << (4-bo);
-    }
-    break;
-  case 3:
-  case 4:
-  default:
-    dst[pixeli*2] = pixelBuf[0];
-    dst[pixeli*2+1] = pixelBuf[1];
-    break;
-  }
-}
-
-static void writePlanePixel4(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  unsigned short c = (pixelBuf[0] << 8) | pixelBuf[1];
-  unsigned int bo = (pixeli & 0x1)*4;
-  unsigned char so = (header.cupsNumColors - plane - 1)*4;
-  if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
-  dst[pixeli/2] |= ((c >> so) & 0xf) << (4-bo);
-}
-
-static void writePixel8(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  unsigned char *dp = dst + pixeli*header.cupsNumColors;
-  for (unsigned int i = 0;i < header.cupsNumColors;i++) {
-    dp[i] = pixelBuf[i];
-  }
-}
-
-static void writePlanePixel8(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  dst[pixeli] = pixelBuf[plane];
-}
-
-static void writePixel16(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  unsigned char *dp = dst + pixeli*header.cupsNumColors*2;
-  for (unsigned int i = 0;i < header.cupsNumColors*2;i++) {
-    dp[i] = pixelBuf[i];
-  }
-}
-
-static void writePlanePixel16(unsigned char *dst,
-    unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
-{
-  dst[pixeli*2] = pixelBuf[plane*2];
-  dst[pixeli*2+1] = pixelBuf[plane*2+1];
-}
-
 static unsigned char *convertLineChunked(unsigned char *src, unsigned char *dst,
      unsigned int row, unsigned int plane, unsigned int pixels,
      unsigned int size)
@@ -1150,8 +935,8 @@ static unsigned char *convertLineChunked(unsigned char *src, unsigned char *dst,
       unsigned char *pb;
 
       pb = convertCSpace(src+i*popplerNumColors,pixelBuf1,i,row);
-      pb = convertBits(pb,pixelBuf2,i,row);
-      writePixel(dst,0,i,pb);
+      pb = convertBits(pb,pixelBuf2,i,row,header.cupsNumColors);
+      writePixel(dst,0,i,pb,header.cupsNumColors);
   }
   return dst;
 }
@@ -1167,8 +952,8 @@ static unsigned char *convertLineChunkedSwap(unsigned char *src,
       unsigned char *pb;
 
       pb = convertCSpace(src+(pixels-i-1)*popplerNumColors,pixelBuf1,i,row);
-      pb = convertBits(pb,pixelBuf2,i,row);
-      writePixel(dst,0,i,pb);
+      pb = convertBits(pb,pixelBuf2,i,row,header.cupsNumColors);
+      writePixel(dst,0,i,pb,header.cupsNumColors);
   }
   return dst;
 }
@@ -1184,8 +969,8 @@ static unsigned char *convertLinePlane(unsigned char *src, unsigned char *dst,
       unsigned char *pb;
 
       pb = convertCSpace(src+i*popplerNumColors,pixelBuf1,i,row);
-      pb = convertBits(pb,pixelBuf2,i,row);
-      writePixel(dst,plane,i,pb);
+      pb = convertBits(pb,pixelBuf2,i,row,header.cupsNumColors);
+      writePixel(dst,plane,i,pb,header.cupsNumColors);
   }
   return dst;
 }
@@ -1200,8 +985,8 @@ static unsigned char *convertLinePlaneSwap(unsigned char *src,
       unsigned char *pb;
 
       pb = convertCSpace(src+(pixels-i-1)*popplerNumColors,pixelBuf1,i,row);
-      pb = convertBits(pb,pixelBuf2,i,row);
-      writePixel(dst,plane,i,pb);
+      pb = convertBits(pb,pixelBuf2,i,row,header.cupsNumColors);
+      writePixel(dst,plane,i,pb,header.cupsNumColors);
   }
   return dst;
 }