Commits
David Strubbe authored 374ac29b5fe
1 + | # HG changeset patch |
2 + | # User Vin Shelton <acs@xemacs.org> |
3 + | # Date 1323317837 18000 |
4 + | # Node ID 51ced9b8fb63e4be59ea611b58128c400e3df987 |
5 + | # Parent 032a91928d47b36ae3dd98885767d9e0202892f7 |
6 + | Clean up PNG handling. Fix crash in issue570. |
7 + | |
8 + | diff -r 032a91928d47b36ae3dd98885767d9e0202892f7 -r 51ced9b8fb63e4be59ea611b58128c400e3df987 src/glyphs-eimage.c |
9 + | --- a/src/glyphs-eimage.c Sat Dec 03 20:04:12 2011 -0500 |
10 + | +++ b/src/glyphs-eimage.c Wed Dec 07 23:17:17 2011 -0500 |
11 + | |
12 + | png_read_info (png_ptr, info_ptr); |
13 + | |
14 + | { |
15 + | - int y; |
16 + | + int y, padding; |
17 + | unsigned char **row_pointers; |
18 + | height = info_ptr->height; |
19 + | width = info_ptr->width; |
20 + | |
21 + | - /* Wow, allocate all the memory. Truly, exciting. */ |
22 + | - unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3); |
23 + | + /* Wow, allocate all the memory. Truly, exciting. |
24 + | + Well, yes, there's excitement to be had. It turns out that libpng |
25 + | + strips in place, so the last row overruns the buffer if depth is 16 |
26 + | + or there's an alpha channel. This is a crash on Linux. So we need |
27 + | + to add padding. |
28 + | + The worst case is reducing 8 bytes (16-bit RGBA) to 3 (8-bit RGB). */ |
29 + | + |
30 + | + padding = 5 * width; |
31 + | + unwind.eimage = xnew_array_and_zero (unsigned char, |
32 + | + width * height * 3 + padding); |
33 + | + |
34 + | /* libpng expects that the image buffer passed in contains a |
35 + | picture to draw on top of if the png has any transparencies. |
36 + | This could be a good place to pass that in... */ |
37 + | |
38 + | if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || |
39 + | info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
40 + | png_set_gray_to_rgb (png_ptr); |
41 + | - /* we can't handle alpha values */ |
42 + | - if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) |
43 + | - png_set_strip_alpha (png_ptr); |
44 + | /* tell libpng to strip 16 bit depth files down to 8 bits */ |
45 + | if (info_ptr->bit_depth == 16) |
46 + | png_set_strip_16 (png_ptr); |
47 + | |
48 + | png_set_packing (png_ptr); |
49 + | } |
50 + | |
51 + | + /* we can't handle alpha values |
52 + | + png_read_update_info ensures the alpha flag is set when one of |
53 + | + the transforms above causes an alpha channel to be generated */ |
54 + | + png_read_update_info (png_ptr, info_ptr); |
55 + | + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) |
56 + | + png_set_strip_alpha (png_ptr); |
57 + | + |
58 + | png_read_image (png_ptr, row_pointers); |
59 + | png_read_end (png_ptr, info_ptr); |
60 + |