# ====================
pkgfiltersincludedir = $(includedir)/cupsfilters
pkgfiltersinclude_DATA = \
+ cupsfilters/bitmap.h \
cupsfilters/colord.h \
cupsfilters/colormanager.h \
cupsfilters/driver.h \
libcupsfilters_la_SOURCES = \
cupsfilters/attr.c \
+ cupsfilters/bitmap.c \
cupsfilters/check.c \
cupsfilters/cmyk.c \
cupsfilters/colord.c \
pclmtoraster_SOURCES = \
filter/pclmtoraster.cxx \
+ cupsfilters/bitmap.h \
cupsfilters/raster.h \
filter/unirast.h
pclmtoraster_CXXFLAGS = \
pdftops_DEPENDENCIES = $(STRCASESTR)
pdftoraster_SOURCES = \
+ cupsfilters/bitmap.h \
filter/pdftoraster.cxx
pdftoraster_CFLAGS = \
-I$(srcdir)/cupsfilters/ \
--- /dev/null
+/*
+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];
+}
--- /dev/null
+/*
+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 */
+
#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];
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;
}
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;
}
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;
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();
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);
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++) {
dp = convertLine(bp, lineBuf, h, plane + band, header.cupsWidth);
cupsRasterWritePixels(raster, dp, bytesPerLine);
}
- bp += rowsize;
+ bp += rowsize;
}
}
#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>
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;
{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;
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)
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;
}
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;
}
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;
}
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;
}