Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 218765 Details for
Bug 303817
app-text/poppler-0.12.3-r3 image scaling with cairo is poor quality
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch fixes scaling problem
poppler-0.12.3-fdo#5589.patch (text/plain), 4.63 KB, created by
Marcin Rybarski
on 2010-02-06 23:48:57 UTC
(
hide
)
Description:
Patch fixes scaling problem
Filename:
MIME Type:
Creator:
Marcin Rybarski
Created:
2010-02-06 23:48:57 UTC
Size:
4.63 KB
patch
obsolete
>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<width || scaledStride<scaledWidth) return; >+ if (source==NULL || dest==NULL) return; >+ >+ unsigned int * pLine,*pt; >+ >+ int x,y,z; >+ unsigned int sum1,sum2,sum3,sum4; >+ int sx,sy,oy; >+ int count,dx,dy; >+ >+ // calculate pixelwidths >+ int * pixelwidth=new int[scaledWidth]; >+ int n,l=0; >+ for(x=0;x<scaledWidth;x++) >+ { >+ n=((x+1)*width-1)/scaledWidth; >+ pixelwidth[x]=n-l; >+ // assert(pixelwidth[x]); >+ l=n; >+ } >+ >+ pLine=source; >+ oy=0; >+ for(y=0;y<scaledHeight;y++) >+ { // column >+ z=y*scaledStride; >+ pLine=source+oy*stride; >+ n=((y+1)*height-1)/scaledHeight; >+ dy=n-oy; >+ for(x=0;x<scaledWidth;x++) >+ { // row >+ dx=pixelwidth[x]; >+ pt=pLine; // temp storage line pointer >+ sum1=sum2=sum3=sum4=0; >+ for(sy=0;sy<dy;sy++) >+ { // sum y >+ for(sx=0;sx<dx;sx++) >+ { // sum x >+ sum1+=pLine[sx]&0xFF; >+ sum2+=(pLine[sx]>>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<width) >+ { >+ PrescaleARGB((unsigned int *)buffer,width,height,stride,(unsigned int *)scaledBuffer,scaledWidth,scaledHeight,scaledStride); >+ delete [] buffer; >+ } >+ > cairo_surface_mark_dirty (image); > pattern = cairo_pattern_create_for_surface (image); > cairo_surface_destroy (image); >@@ -2053,8 +2147,8 @@ void CairoOutputDev::drawImage(GfxState > CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST); > cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); > >- cairo_matrix_init_translate (&matrix, 0, height); >- cairo_matrix_scale (&matrix, width, -height); >+ cairo_matrix_init_translate (&matrix, 0, scaledHeight); >+ cairo_matrix_scale (&matrix, scaledWidth, -scaledHeight); > cairo_pattern_set_matrix (pattern, &matrix); > > if (!mask && fill_opacity != 1.0) {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 303817
: 218765