From ab57c6b35edde0bd137d8b91e9863194f0e557d7 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Tue, 19 Jan 2010 18:31:55 +0000 Subject: [PATCH] - cairo backend, scale images correctly (#556549, fdo#5589) --- poppler-0.12.3-fdo#5589.patch | 153 ++++++++++++++++++++++++++++++++++ poppler.spec | 9 +- 2 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 poppler-0.12.3-fdo#5589.patch diff --git a/poppler-0.12.3-fdo#5589.patch b/poppler-0.12.3-fdo#5589.patch new file mode 100644 index 0000000..7b2439b --- /dev/null +++ b/poppler-0.12.3-fdo#5589.patch @@ -0,0 +1,153 @@ +diff -up poppler-0.12.3/poppler/CairoOutputDev.cc.rex poppler-0.12.3/poppler/CairoOutputDev.cc +--- poppler-0.12.3/poppler/CairoOutputDev.cc.rex 2009-12-24 04:41:22.000000000 -0600 ++++ poppler-0.12.3/poppler/CairoOutputDev.cc 2010-01-19 12:14:33.210386122 -0600 +@@ -97,6 +97,69 @@ void CairoImage::setImage (cairo_surface + this->image = cairo_surface_reference (image); + } + ++// basic 2D box filter ++void PrescaleARGB(unsigned int * source,int width,int height,int stride,unsigned int * dest,int scaledWidth,int scaledHeight,int scaledStride) ++{ ++ stride/=4; ++ scaledStride/=4; ++ // sanity check ++ if (scaledHeight>height || scaledWidth>width || scaledHeight<=0 || scaledWidth<=0 || stride>8)&0xFF; ++ sum3+=(pLine[sx]>>16)&0xFF; ++ sum4+=pLine[sx]>>24; ++ } // sum x ++ pLine+=stride; ++ } // sum y ++ pLine=pt+dx; ++ count=dx*dy; ++ dest[z++]=sum1/count+(sum2/count<<8)+(sum3/count<<16)+(sum4/count<<24); ++ } // row ++ oy+=dy; ++ } ++ ++ delete [] pixelwidth; ++} ++ ++ ++ + //------------------------------------------------------------------------ + // CairoOutputDev + //------------------------------------------------------------------------ +@@ -1975,13 +2038,40 @@ void CairoOutputDev::drawImage(GfxState + ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB); + #endif + ++ int scaledWidth,scaledHeight,scaledStride; ++ unsigned char * scaledBuffer; ++ ++ cairo_get_matrix(cairo, &matrix); ++ scaledWidth=fabs(matrix.xx+matrix.yx)+0.5; ++ scaledHeight=fabs(matrix.xy+matrix.yy)+0.5; ++ ++ if (printing || scaledWidth>=width || scaledHeight>=height) ++ { // no prescaling => render directly to cairo_image ++ scaledWidth=width; ++ scaledHeight=height; ++ } ++ else ++ { // first render to ARGB buffer then downsample to cairo_image ++ stride = width*4; ++ buffer = new unsigned char [stride*height]; ++ } ++ + image = cairo_image_surface_create (maskColors ? + CAIRO_FORMAT_ARGB32 : + CAIRO_FORMAT_RGB24, +- width, height); ++ scaledWidth, scaledHeight); + if (cairo_surface_status (image)) + goto cleanup; ++ ++ scaledBuffer = cairo_image_surface_get_data (image); ++ scaledStride = cairo_image_surface_get_stride (image); + ++ if (scaledWidth>=width || scaledHeight>=height) ++ { // no prescaling => render directly to cairo_image ++ stride = scaledStride; ++ buffer = scaledBuffer; ++ } ++ + // special case for one-channel (monochrome/gray/separation) images: + // build a lookup table here + if (colorMap->getNumPixelComps() == 1) { +@@ -1994,11 +2084,9 @@ void CairoOutputDev::drawImage(GfxState + pix = (Guchar)i; + + colorMap->getRGB(&pix, &lookup[i]); +- } +- } ++ } ++ } + +- buffer = cairo_image_surface_get_data (image); +- stride = cairo_image_surface_get_stride (image); + for (int y = 0; y < height; y++) { + uint32_t *dest = (uint32_t *) (buffer + y * stride); + Guchar *pix = imgStr->getLine(); +@@ -2040,6 +2128,12 @@ void CairoOutputDev::drawImage(GfxState + } + gfree(lookup); + ++ if (scaledWidth - 0.12.3-5 +- cairo backend, scale images correctly (#556549, fdo#5589) + * Fri Jan 15 2010 Rex Dieter - 0.12.3-4 - Sanitize versioned Obsoletes/Provides