From b20b7a3d78262fee595048c9a7aedb408c80ec86 Mon Sep 17 00:00:00 2001 From: Vikrant Date: Wed, 8 Jul 2020 16:37:52 +0530 Subject: [PATCH] Add convertbits functions in cupsfilters library --- Makefile.am | 4 + cupsfilters/bitmap.c | 262 ++++++++++++++++++++++++++++++++++++++++ cupsfilters/bitmap.h | 69 +++++++++++ filter/pclmtoraster.cxx | 206 ++++++++++++++++++++++--------- filter/pdftoraster.cxx | 237 ++---------------------------------- 5 files changed, 493 insertions(+), 285 deletions(-) create mode 100644 cupsfilters/bitmap.c create mode 100644 cupsfilters/bitmap.h diff --git a/Makefile.am b/Makefile.am index c17cec6de..cc8f2718a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 index 000000000..d299bae2c --- /dev/null +++ b/cupsfilters/bitmap.c @@ -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 + +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 index 000000000..bc2689b38 --- /dev/null +++ b/cupsfilters/bitmap.h @@ -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 */ + diff --git a/filter/pclmtoraster.cxx b/filter/pclmtoraster.cxx index 7839d95ea..74bee9b99 100644 --- a/filter/pclmtoraster.cxx +++ b/filter/pclmtoraster.cxx @@ -27,17 +27,22 @@ #include #include #include +#include #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; } } diff --git a/filter/pdftoraster.cxx b/filter/pdftoraster.cxx index 9878e8531..38311b659 100644 --- a/filter/pdftoraster.cxx +++ b/filter/pdftoraster.cxx @@ -47,6 +47,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #include #include #include @@ -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; } -- 2.47.3