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