1 |
yngwin 10/02/08 23:37:36 |
2 |
|
3 |
Added: poppler-0.12.3-cairo-image-downscale.patch |
4 |
Removed: poppler-CVE-2009-1188.patch |
5 |
poppler-0.8.3-page-init.patch |
6 |
poppler-0.10.5-xpdf-3.02pl3.patch |
7 |
poppler-0.6.1-xpdf-3.02pl2.patch |
8 |
Log: |
9 |
Remove obsoleted versions. Add cairo image downscale issue patch, which has been applied to upstream git (bug 303817). |
10 |
(Portage version: 2.2_rc62/cvs/Linux x86_64) |
11 |
|
12 |
Revision Changes Path |
13 |
1.1 app-text/poppler/files/poppler-0.12.3-cairo-image-downscale.patch |
14 |
|
15 |
file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/app-text/poppler/files/poppler-0.12.3-cairo-image-downscale.patch?rev=1.1&view=markup |
16 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/app-text/poppler/files/poppler-0.12.3-cairo-image-downscale.patch?rev=1.1&content-type=text/plain |
17 |
|
18 |
Index: poppler-0.12.3-cairo-image-downscale.patch |
19 |
=================================================================== |
20 |
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc |
21 |
index 9a0f3be..42ac3a8 100644 |
22 |
--- a/poppler/CairoOutputDev.cc |
23 |
+++ b/poppler/CairoOutputDev.cc |
24 |
@@ -58,6 +58,7 @@ |
25 |
#include <splash/SplashBitmap.h> |
26 |
#include "CairoOutputDev.h" |
27 |
#include "CairoFontEngine.h" |
28 |
+#include "CairoRescaleBox.h" |
29 |
//------------------------------------------------------------------------ |
30 |
|
31 |
// #define LOG_CAIRO |
32 |
@@ -1331,6 +1332,82 @@ void CairoOutputDev::endMaskClip(GfxState *state) { |
33 |
clearSoftMask(state); |
34 |
} |
35 |
|
36 |
+cairo_surface_t *CairoOutputDev::downscaleSurface(cairo_surface_t *orig_surface) { |
37 |
+ cairo_surface_t *dest_surface; |
38 |
+ unsigned char *dest_buffer; |
39 |
+ int dest_stride; |
40 |
+ unsigned char *orig_buffer; |
41 |
+ int orig_width, orig_height; |
42 |
+ int orig_stride; |
43 |
+ GBool res; |
44 |
+ |
45 |
+ if (printing) |
46 |
+ return NULL; |
47 |
+ |
48 |
+ cairo_matrix_t matrix; |
49 |
+ cairo_get_matrix(cairo, &matrix); |
50 |
+ |
51 |
+ /* this whole computation should be factored out */ |
52 |
+ double xScale = matrix.xx; |
53 |
+ double yScale = matrix.yy; |
54 |
+ int tx, tx2, ty, ty2; /* the integer co-oridinates of the resulting image */ |
55 |
+ int scaledHeight; |
56 |
+ int scaledWidth; |
57 |
+ if (xScale >= 0) { |
58 |
+ tx = splashRound(matrix.x0 - 0.01); |
59 |
+ tx2 = splashRound(matrix.x0 + xScale + 0.01) - 1; |
60 |
+ } else { |
61 |
+ tx = splashRound(matrix.x0 + 0.01) - 1; |
62 |
+ tx2 = splashRound(matrix.x0 + xScale - 0.01); |
63 |
+ } |
64 |
+ scaledWidth = abs(tx2 - tx) + 1; |
65 |
+ //scaledWidth = splashRound(fabs(xScale)); |
66 |
+ if (scaledWidth == 0) { |
67 |
+ // technically, this should draw nothing, but it generally seems |
68 |
+ // better to draw a one-pixel-wide stripe rather than throwing it |
69 |
+ // away |
70 |
+ scaledWidth = 1; |
71 |
+ } |
72 |
+ if (yScale >= 0) { |
73 |
+ ty = splashFloor(matrix.y0 + 0.01); |
74 |
+ ty2 = splashCeil(matrix.y0 + yScale - 0.01); |
75 |
+ } else { |
76 |
+ ty = splashCeil(matrix.y0 - 0.01); |
77 |
+ ty2 = splashFloor(matrix.y0 + yScale + 0.01); |
78 |
+ } |
79 |
+ scaledHeight = abs(ty2 - ty); |
80 |
+ if (scaledHeight == 0) { |
81 |
+ scaledHeight = 1; |
82 |
+ } |
83 |
+ |
84 |
+ orig_width = cairo_image_surface_get_width (orig_surface); |
85 |
+ orig_height = cairo_image_surface_get_height (orig_surface); |
86 |
+ if (scaledWidth >= orig_width || scaledHeight >= orig_height) |
87 |
+ return NULL; |
88 |
+ |
89 |
+ dest_surface = cairo_surface_create_similar (orig_surface, |
90 |
+ cairo_surface_get_content (orig_surface), |
91 |
+ scaledWidth, scaledHeight); |
92 |
+ dest_buffer = cairo_image_surface_get_data (dest_surface); |
93 |
+ dest_stride = cairo_image_surface_get_stride (dest_surface); |
94 |
+ |
95 |
+ orig_buffer = cairo_image_surface_get_data (orig_surface); |
96 |
+ orig_stride = cairo_image_surface_get_stride (orig_surface); |
97 |
+ |
98 |
+ res = downscale_box_filter((uint32_t *)orig_buffer, |
99 |
+ orig_stride, orig_width, orig_height, |
100 |
+ scaledWidth, scaledHeight, 0, 0, |
101 |
+ scaledWidth, scaledHeight, |
102 |
+ (uint32_t *)dest_buffer, dest_stride); |
103 |
+ if (!res) { |
104 |
+ cairo_surface_destroy (dest_surface); |
105 |
+ return NULL; |
106 |
+ } |
107 |
+ |
108 |
+ return dest_surface; |
109 |
+ |
110 |
+} |
111 |
+ |
112 |
void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, |
113 |
int width, int height, GBool invert, |
114 |
GBool interpolate, GBool inlineImg) { |
115 |
@@ -2094,6 +2171,18 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, |
116 |
} |
117 |
gfree(lookup); |
118 |
|
119 |
+ cairo_surface_t *scaled_surface; |
120 |
+ |
121 |
+ scaled_surface = downscaleSurface (image); |
122 |
+ if (scaled_surface) { |
123 |
+ if (cairo_surface_status (scaled_surface)) |
124 |
+ goto cleanup; |
125 |
+ cairo_surface_destroy (image); |
126 |
+ image = scaled_surface; |
127 |
+ width = cairo_image_surface_get_width (image); |
128 |
+ height = cairo_image_surface_get_height (image); |
129 |
+ } |
130 |
+ |
131 |
cairo_surface_mark_dirty (image); |
132 |
pattern = cairo_pattern_create_for_surface (image); |
133 |
cairo_surface_destroy (image); |
134 |
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h |
135 |
index fb9c0d7..266f0cb 100644 |
136 |
--- a/poppler/CairoOutputDev.h |
137 |
+++ b/poppler/CairoOutputDev.h |
138 |
@@ -268,6 +268,7 @@ public: |
139 |
|
140 |
protected: |
141 |
void doPath(cairo_t *cairo, GfxState *state, GfxPath *path); |
142 |
+ cairo_surface_t *downscaleSurface(cairo_surface_t *orig_surface); |
143 |
|
144 |
GfxRGB fill_color, stroke_color; |
145 |
cairo_pattern_t *fill_pattern, *stroke_pattern; |
146 |
diff --git a/poppler/CairoRescaleBox.cc b/poppler/CairoRescaleBox.cc |
147 |
new file mode 100644 |
148 |
index 0000000..dce5ddd |
149 |
--- /dev/null |
150 |
+++ b/poppler/CairoRescaleBox.cc |
151 |
@@ -0,0 +1,352 @@ |
152 |
+/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ |
153 |
+/* |
154 |
+ * Copyright © 2009 Mozilla Corporation |
155 |
+ * |
156 |
+ * Permission to use, copy, modify, distribute, and sell this software and its |
157 |
+ * documentation for any purpose is hereby granted without fee, provided that |
158 |
+ * the above copyright notice appear in all copies and that both that |
159 |
+ * copyright notice and this permission notice appear in supporting |
160 |
+ * documentation, and that the name of Mozilla Corporation not be used in |
161 |
+ * advertising or publicity pertaining to distribution of the software without |
162 |
+ * specific, written prior permission. Mozilla Corporation makes no |
163 |
+ * representations about the suitability of this software for any purpose. It |
164 |
+ * is provided "as is" without express or implied warranty. |
165 |
+ * |
166 |
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
167 |
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT |
168 |
+ * SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
169 |
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
170 |
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
171 |
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
172 |
+ * OF THIS SOFTWARE. |
173 |
+ * |
174 |
+ * Author: Jeff Muizelaar, Mozilla Corp. |
175 |
+ */ |
176 |
+ |
177 |
+/* This implements a box filter that supports non-integer box sizes */ |
178 |
+ |
179 |
+#ifdef HAVE_CONFIG_H |
180 |
+#include <config.h> |
181 |
+#endif |
182 |
+ |
183 |
+#include <stdint.h> |
184 |
+#include <stdio.h> |
185 |
+#include <assert.h> |
186 |
+#include <stdlib.h> |
187 |
+#include <math.h> |
188 |
+#include "goo/gmem.h" |
189 |
+#include "CairoRescaleBox.h" |
190 |
+ |
191 |
+typedef unsigned short int uint16_t; |
192 |
+typedef unsigned int uint32_t; |
193 |
+ |
194 |
+/* we work in fixed point where 1. == 1 << 24 */ |
195 |
+#define FIXED_SHIFT 24 |
196 |
+ |
197 |
+static void downsample_row_box_filter ( |
198 |
+ int start, int width, |
199 |
+ uint32_t *src, uint32_t *dest, |
200 |
+ int coverage[], int pixel_coverage) |
201 |
+{ |
202 |
+ /* we need an array of the pixel contribution of each destination pixel on the boundaries. |
203 |
+ * we invert the value to get the value on the other size of the box */ |
204 |
+ /* |
205 |
+ |
206 |
+ value = a * contribution * 1/box_size |
207 |
+ value += a * 1/box_size |
208 |
+ value += a * 1/box_size |
209 |
+ value += a * 1/box_size |
210 |
+ value += a * (1 - contribution) * 1/box_size |
211 |
+ a * (1/box_size - contribution * 1/box_size) |
212 |
+ |
213 |
+ box size is constant |
214 |
+ |
215 |
+ |
216 |
+ value = a * contribtion_a * 1/box_size + b * contribution_b * 1/box_size |
217 |
+ contribution_b = (1 - contribution_a) |
218 |
+ = (1 - contribution_a_next) |
219 |
+ */ |
220 |
+ |
221 |
+ /* box size = ceil(src_width/dest_width) */ |
222 |
+ int x = 0; |
223 |
+ |
224 |
+ /* skip to start */ |
225 |
+ /* XXX: it might be possible to do this directly instead of iteratively, however |
226 |
+ * the iterative solution is simple */ |
227 |
+ while (x < start) |
228 |
+ { |
229 |
+ int box = 1 << FIXED_SHIFT; |
230 |
+ int start_coverage = coverage[x]; |
231 |
+ box -= start_coverage; |
232 |
+ src++; |
233 |
+ while (box >= pixel_coverage) |
234 |
+ { |
235 |
+ src++; |
236 |
+ box -= pixel_coverage; |
237 |
+ } |
238 |
+ x++; |
239 |
+ } |
240 |
+ |
241 |
+ while (x < start + width) |
242 |
+ { |
243 |
+ uint32_t a = 0; |
244 |
+ uint32_t r = 0; |
245 |
+ uint32_t g = 0; |
246 |
+ uint32_t b = 0; |
247 |
+ int box = 1 << FIXED_SHIFT; |
248 |
+ int start_coverage = coverage[x]; |
249 |
+ |
250 |
+ a = ((*src >> 24) & 0xff) * start_coverage; |
251 |
+ r = ((*src >> 16) & 0xff) * start_coverage; |
252 |
+ g = ((*src >> 8) & 0xff) * start_coverage; |
253 |
+ b = ((*src >> 0) & 0xff) * start_coverage; |
254 |
+ src++; |
255 |
+ x++; |
256 |
+ box -= start_coverage; |
257 |
+ |
258 |
+ while (box >= pixel_coverage) |
259 |
+ { |
260 |
+ a += ((*src >> 24) & 0xff) * pixel_coverage; |
261 |
+ r += ((*src >> 16) & 0xff) * pixel_coverage; |
262 |
+ g += ((*src >> 8) & 0xff) * pixel_coverage; |
263 |
+ b += ((*src >> 0) & 0xff) * pixel_coverage; |
264 |
+ src++; |
265 |
+ |
266 |
+ box -= pixel_coverage; |
267 |
+ } |
268 |
+ |
269 |
+ /* multiply by whatever is leftover |
270 |
+ * this ensures that we don't bias down. |
271 |
+ * i.e. start_coverage + n*pixel_coverage + box == 1 << 24 */ |
272 |
+ if (box > 0) |
273 |
+ { |
274 |
+ a += ((*src >> 24) & 0xff) * box; |
275 |
+ r += ((*src >> 16) & 0xff) * box; |
276 |
+ g += ((*src >> 8) & 0xff) * box; |
277 |
+ b += ((*src >> 0) & 0xff) * box; |
278 |
+ } |
279 |
+ |
280 |
+ a >>= FIXED_SHIFT; |
281 |
+ r >>= FIXED_SHIFT; |
282 |
+ g >>= FIXED_SHIFT; |
283 |
+ b >>= FIXED_SHIFT; |
284 |
+ |
285 |
+ *dest = (a << 24) | (r << 16) | (g << 8) | b; |
286 |
+ dest++; |
287 |
+ } |
288 |
+} |
289 |
+ |
290 |
+static void downsample_columns_box_filter ( |
291 |
+ int n, |
292 |
+ int start_coverage, |
293 |
+ int pixel_coverage, |
294 |
+ uint32_t *src, uint32_t *dest) |
295 |
+{ |
296 |
+ int stride = n; |
297 |
+ while (n--) { |
298 |
+ uint32_t a = 0; |
299 |
+ uint32_t r = 0; |
300 |
+ uint32_t g = 0; |
301 |
+ uint32_t b = 0; |
302 |
+ uint32_t *column_src = src; |
303 |
+ int box = 1 << FIXED_SHIFT; |
304 |
+ |
305 |
+ a = ((*column_src >> 24) & 0xff) * start_coverage; |
306 |
+ r = ((*column_src >> 16) & 0xff) * start_coverage; |
307 |
+ g = ((*column_src >> 8) & 0xff) * start_coverage; |
308 |
+ b = ((*column_src >> 0) & 0xff) * start_coverage; |
309 |
+ column_src += stride; |
310 |
+ box -= start_coverage; |
311 |
+ |
312 |
+ while (box >= pixel_coverage) |
313 |
+ { |
314 |
+ a += ((*column_src >> 24) & 0xff) * pixel_coverage; |
315 |
+ r += ((*column_src >> 16) & 0xff) * pixel_coverage; |
316 |
+ g += ((*column_src >> 8) & 0xff) * pixel_coverage; |
317 |
+ b += ((*column_src >> 0) & 0xff) * pixel_coverage; |
318 |
+ column_src += stride; |
319 |
+ box -= pixel_coverage; |
320 |
+ } |
321 |
+ |
322 |
+ if (box > 0) { |
323 |
+ a += ((*column_src >> 24) & 0xff) * box; |
324 |
+ r += ((*column_src >> 16) & 0xff) * box; |
325 |
+ g += ((*column_src >> 8) & 0xff) * box; |
326 |
+ b += ((*column_src >> 0) & 0xff) * box; |
327 |
+ } |
328 |
+ |
329 |
+ a >>= FIXED_SHIFT; |
330 |
+ r >>= FIXED_SHIFT; |
331 |
+ g >>= FIXED_SHIFT; |
332 |
+ b >>= FIXED_SHIFT; |
333 |
+ |
334 |
+ *dest = (a << 24) | (r << 16) | (g << 8) | b; |
335 |
+ dest++; |
336 |
+ src++; |
337 |
+ } |
338 |
+} |
339 |
+ |
340 |
+static int compute_coverage (int coverage[], int src_length, int dest_length) |
341 |
+{ |
342 |
+ int i; |
343 |
+ /* num = src_length/dest_length |
344 |
+ total = sum(pixel) / num |
345 |
+ |
346 |
+ pixel * 1/num == pixel * dest_length / src_length |
347 |
+ */ |
348 |
+ /* the average contribution of each source pixel */ |
349 |
+ int ratio = ((1 << 24)*(long long int)dest_length)/src_length; |
350 |
+ /* because ((1 << 24)*(long long int)dest_length) won't always be divisible by src_length |
351 |
+ * we'll need someplace to put the other bits. |
352 |
+ * |
353 |
+ * We want to ensure a + n*ratio < 1<<24 |
354 |
+ * |
355 |
+ * 1<<24 |
356 |
+ * */ |
357 |
+ |
358 |
+ double scale = (double)src_length/dest_length; |
359 |
+ |
360 |
+ /* for each destination pixel compute the coverage of the left most pixel included in the box */ |
361 |
+ /* I have a proof of this, which this margin is too narrow to contain */ |
362 |
+ for (i=0; i<dest_length; i++) |
363 |
+ { |
364 |
+ float left_side = i*scale; |
365 |
+ float right_side = (i+1)*scale; |
366 |
+ float right_fract = right_side - floor (right_side); |
367 |
+ float left_fract = ceil (left_side) - left_side; |
368 |
+ int overage; |
369 |
+ /* find out how many source pixels will be used to fill the box */ |
370 |
+ int count = floor (right_side) - ceil (left_side); |
371 |
+ /* what's the maximum value this expression can become? |
372 |
+ floor((i+1)*scale) - ceil(i*scale) |
373 |
+ |
374 |
+ (i+1)*scale - i*scale == scale |
375 |
+ |
376 |
+ since floor((i+1)*scale) <= (i+1)*scale |
377 |
+ and ceil(i*scale) >= i*scale |
378 |
+ |
379 |
+ floor((i+1)*scale) - ceil(i*scale) <= scale |
380 |
+ |
381 |
+ further since: floor((i+1)*scale) - ceil(i*scale) is an integer |
382 |
+ |
383 |
+ therefore: |
384 |
+ floor((i+1)*scale) - ceil(i*scale) <= floor(scale) |
385 |
+ */ |
386 |
+ |
387 |
+ if (left_fract == 0.) |
388 |
+ count--; |
389 |
+ |
390 |
+ /* compute how much the right-most pixel contributes */ |
391 |
+ overage = ratio*(right_fract); |
392 |
+ |
393 |
+ /* the remainder is the the amount that the left-most pixel |
394 |
+ * contributes */ |
395 |
+ coverage[i] = (1<<24) - (count * ratio + overage); |
396 |
+ } |
397 |
+ |
398 |
+ return ratio; |
399 |
+} |
400 |
+ |
401 |
+GBool downscale_box_filter(uint32_t *orig, int orig_stride, unsigned orig_width, unsigned orig_height, |
402 |
+ signed scaled_width, signed scaled_height, |
403 |
+ uint16_t start_column, uint16_t start_row, |
404 |
+ uint16_t width, uint16_t height, |
405 |
+ uint32_t *dest, int dst_stride) |
406 |
+{ |
407 |
+ int pixel_coverage_x, pixel_coverage_y; |
408 |
+ int dest_y; |
409 |
+ int src_y = 0; |
410 |
+ uint32_t *scanline = orig; |
411 |
+ int *x_coverage = NULL; |
412 |
+ int *y_coverage = NULL; |
413 |
+ uint32_t *temp_buf = NULL; |
414 |
+ GBool retval = gFalse; |
415 |
+ |
416 |
+ x_coverage = (int *)gmallocn3 (orig_width, 1, sizeof(int)); |
417 |
+ y_coverage = (int *)gmallocn3 (orig_height, 1, sizeof(int)); |
418 |
+ |
419 |
+ /* we need to allocate enough room for ceil(src_height/dest_height)+1 |
420 |
+ Example: |
421 |
+ src_height = 140 |
422 |
+ dest_height = 50 |
423 |
+ src_height/dest_height = 2.8 |
424 |
+ |
425 |
+ |-------------| 2.8 pixels |
426 |
+ |----|----|----|----| 4 pixels |
427 |
+ need to sample 3 pixels |
428 |
+ |
429 |
+ |-------------| 2.8 pixels |
430 |
+ |----|----|----|----| 4 pixels |
431 |
+ need to sample 4 pixels |
432 |
+ */ |
433 |
+ |
434 |
+ temp_buf = (uint32_t *)gmallocn3 ((orig_height + scaled_height-1)/scaled_height+1, scaled_width, sizeof(uint32_t)); |
435 |
+ |
436 |
+ if (!x_coverage || !y_coverage || !scanline || !temp_buf) |
437 |
+ goto cleanup; |
438 |
+ |
439 |
+ pixel_coverage_x = compute_coverage (x_coverage, orig_width, scaled_width); |
440 |
+ pixel_coverage_y = compute_coverage (y_coverage, orig_height, scaled_height); |
441 |
+ |
442 |
+ assert (width + start_column <= scaled_width); |
443 |
+ |
444 |
+ /* skip the rows at the beginning */ |
445 |
+ for (dest_y = 0; dest_y < start_row; dest_y++) |
446 |
+ { |
447 |
+ int box = 1 << FIXED_SHIFT; |
448 |
+ int start_coverage_y = y_coverage[dest_y]; |
449 |
+ box -= start_coverage_y; |
450 |
+ src_y++; |
451 |
+ while (box >= pixel_coverage_y) |
452 |
+ { |
453 |
+ box -= pixel_coverage_y; |
454 |
+ src_y++; |
455 |
+ } |
456 |
+ } |
457 |
+ |
458 |
+ for (; dest_y < start_row + height; dest_y++) |
459 |
+ { |
460 |
+ int columns = 0; |
461 |
+ int box = 1 << FIXED_SHIFT; |
462 |
+ int start_coverage_y = y_coverage[dest_y]; |
463 |
+ |
464 |
+ scanline = orig + src_y * orig_stride / 4; |
465 |
+ downsample_row_box_filter (start_column, width, scanline, temp_buf + width * columns, x_coverage, pixel_coverage_x); |
466 |
+ columns++; |
467 |
+ src_y++; |
468 |
+ box -= start_coverage_y; |
469 |
+ |
470 |
+ while (box >= pixel_coverage_y) |
471 |
+ { |
472 |
+ scanline = orig + src_y * orig_stride / 4; |
473 |
+ downsample_row_box_filter (start_column, width, scanline, temp_buf + width * columns, x_coverage, pixel_coverage_x); |
474 |
+ columns++; |
475 |
+ src_y++; |
476 |
+ box -= pixel_coverage_y; |
477 |
+ } |
478 |
+ |
479 |
+ /* downsample any leftovers */ |
480 |
+ if (box > 0) |
481 |
+ { |
482 |
+ scanline = orig + src_y * orig_stride / 4; |
483 |
+ downsample_row_box_filter (start_column, width, scanline, temp_buf + width * columns, x_coverage, pixel_coverage_x); |
484 |
+ columns++; |
485 |
+ } |
486 |
+ |
487 |
+ /* now scale the rows we just downsampled in the y direction */ |
488 |
+ downsample_columns_box_filter (width, start_coverage_y, pixel_coverage_y, temp_buf, dest); |
489 |
+ dest += dst_stride / 4; |
490 |
+ |
491 |
+// assert(width*columns <= ((orig_height + scaled_height-1)/scaled_height+1) * width); |
492 |
+ } |
493 |
+// assert (src_y<=orig_height); |
494 |
+ |
495 |
+ retval = gTrue; |
496 |
+ |
497 |
+cleanup: |
498 |
+ free (x_coverage); |
499 |
+ free (y_coverage); |
500 |
+ free (temp_buf); |
501 |
+ |
502 |
+ return gTrue; |
503 |
+} |
504 |
diff --git a/poppler/CairoRescaleBox.h b/poppler/CairoRescaleBox.h |
505 |
new file mode 100644 |
506 |
index 0000000..5349c87 |
507 |
--- /dev/null |
508 |
+++ b/poppler/CairoRescaleBox.h |
509 |
@@ -0,0 +1,12 @@ |
510 |
+#ifndef CAIRO_RESCALE_BOX_H |
511 |
+#define CAIRO_RESCALE_BOX_H |
512 |
+ |
513 |
+#include "goo/gtypes.h" |
514 |
+ |
515 |
+GBool downscale_box_filter(unsigned int *orig, int orig_stride, unsigned orig_width, unsigned orig_height, |
516 |
+ signed scaled_width, signed scaled_height, |
517 |
+ unsigned short int start_column, unsigned short int start_row, |
518 |
+ unsigned short int width, unsigned short int height, |
519 |
+ unsigned int *dest, int dst_stride); |
520 |
+ |
521 |
+#endif /* CAIRO_RESCALE_BOX_H */ |
522 |
diff --git a/poppler/Makefile.am b/poppler/Makefile.am |
523 |
index ec79e31..096ea76 100644 |
524 |
--- a/poppler/Makefile.am |
525 |
+++ b/poppler/Makefile.am |
526 |
@@ -47,7 +47,9 @@ libpoppler_cairo_la_SOURCES = \ |
527 |
CairoFontEngine.cc \ |
528 |
CairoFontEngine.h \ |
529 |
CairoOutputDev.cc \ |
530 |
- CairoOutputDev.h |
531 |
+ CairoOutputDev.h \ |
532 |
+ CairoRescaleBox.cc \ |
533 |
+ CairoRescaleBox.h |
534 |
|
535 |
endif |