aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-06-29 16:46:16 -0700
committerPaul Eggert2019-06-29 16:49:19 -0700
commitf5b2fd5e46505d68850fb8532357d4218f067c48 (patch)
tree42ed471fc063a552e84a49a42d31e192b1d4fa21 /src
parent0b2841f9fb0ffd8514b0fb99c5673adad6b07abb (diff)
downloademacs-f5b2fd5e46505d68850fb8532357d4218f067c48.tar.gz
emacs-f5b2fd5e46505d68850fb8532357d4218f067c48.zip
Pacify gcc and other image rotation tweaks
* src/image.c: No need to include <float.h> as lisp.h does that. (matrix3x3_copy): Remove; no longer needed. (divide_double): New function, to avoid undefined behavior when dividing by zero on non-IEEE hosts. (image_set_transform): Simplify transformation computation by avoiding the need to copy a matrix. Pacify gcc 9 -Wdouble-promotion and -Wmaybe-uninitialized. Avoid unnecessary assignment of width and height. Improve error reporting for unsupported native image rotation.
Diffstat (limited to 'src')
-rw-r--r--src/image.c153
1 files changed, 79 insertions, 74 deletions
diff --git a/src/image.c b/src/image.c
index 02dd95caeda..5b02c6a9534 100644
--- a/src/image.c
+++ b/src/image.c
@@ -57,10 +57,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
57#include <sys/types.h> 57#include <sys/types.h>
58#endif /* HAVE_SYS_TYPES_H */ 58#endif /* HAVE_SYS_TYPES_H */
59 59
60#ifdef HAVE_NATIVE_TRANSFORMS
61#include <float.h> /* for FLT_MIN */
62#endif
63
64#ifdef HAVE_WINDOW_SYSTEM 60#ifdef HAVE_WINDOW_SYSTEM
65#include TERM_HEADER 61#include TERM_HEADER
66#endif /* HAVE_WINDOW_SYSTEM */ 62#endif /* HAVE_WINDOW_SYSTEM */
@@ -2054,12 +2050,6 @@ compute_image_size (size_t width, size_t height,
2054typedef double matrix3x3[3][3]; 2050typedef double matrix3x3[3][3];
2055 2051
2056static void 2052static void
2057matrix3x3_copy (matrix3x3 a, matrix3x3 b)
2058{
2059 memcpy (b, a, sizeof (matrix3x3));
2060}
2061
2062static void
2063matrix3x3_mult (matrix3x3 a, matrix3x3 b, matrix3x3 result) 2053matrix3x3_mult (matrix3x3 a, matrix3x3 b, matrix3x3 result)
2064{ 2054{
2065 for (int i = 0; i < 3; i++) 2055 for (int i = 0; i < 3; i++)
@@ -2089,6 +2079,16 @@ compute_image_rotation (struct image *img, double *rotation)
2089 *rotation = XFIXNUM (reduced_angle); 2079 *rotation = XFIXNUM (reduced_angle);
2090} 2080}
2091 2081
2082static double
2083divide_double (double a, double b)
2084{
2085#if !IEEE_FLOATING_POINT
2086 if (b == 0)
2087 return DBL_MAX;
2088#endif
2089 return a / b;
2090}
2091
2092static void 2092static void
2093image_set_transform (struct frame *f, struct image *img) 2093image_set_transform (struct frame *f, struct image *img)
2094{ 2094{
@@ -2103,8 +2103,6 @@ image_set_transform (struct frame *f, struct image *img)
2103 return; 2103 return;
2104# endif 2104# endif
2105 2105
2106 matrix3x3 matrix = { [0][0] = 1, [1][1] = 1, [2][2] = 1 };
2107
2108 /* Determine size. */ 2106 /* Determine size. */
2109 int width, height; 2107 int width, height;
2110 compute_image_size (img->width, img->height, img->spec, &width, &height); 2108 compute_image_size (img->width, img->height, img->spec, &width, &height);
@@ -2115,99 +2113,106 @@ image_set_transform (struct frame *f, struct image *img)
2115 2113
2116 /* Perform scale transformation. */ 2114 /* Perform scale transformation. */
2117 2115
2118 double xscale = (double) width / img->width; 2116 matrix3x3 matrix
2119 double yscale = (double) height / img->height; 2117 = {
2120
2121# if defined USE_CAIRO || defined HAVE_XRENDER 2118# if defined USE_CAIRO || defined HAVE_XRENDER
2122 /* Avoid division by zero. */ 2119 [0][0] = divide_double (img->width, width),
2123 xscale = max (xscale, FLT_MIN); 2120 [1][1] = divide_double (img->height, height),
2124 matrix3x3 tmp, rm =
2125 { [0][0] = 1.0 / xscale, [1][1] = 1.0 / yscale, [2][2] = 1 };
2126 matrix3x3_mult (rm, matrix, tmp);
2127# elif defined HAVE_NTGUI || defined HAVE_NS 2121# elif defined HAVE_NTGUI || defined HAVE_NS
2128 matrix3x3 tmp, rm = { [0][0] = xscale, [1][1] = yscale, [2][2] = 1 }; 2122 [0][0] = divide_double (width, img->width),
2129 matrix3x3_mult (matrix, rm, tmp); 2123 [1][1] = divide_double (height, img->height),
2124# else
2125 [0][0] = 1, [1][1] = 1,
2130# endif 2126# endif
2127 [2][2] = 1 };
2131 img->width = width; 2128 img->width = width;
2132 img->height = height; 2129 img->height = height;
2133 2130
2134 /* Perform rotation transformation. */ 2131 /* Perform rotation transformation. */
2135 2132
2136 int cos_r, sin_r; 2133 int rotate_flag = -1;
2137 if (rotation == 0) 2134 if (rotation == 0)
2138 matrix3x3_copy (tmp, matrix); 2135 rotate_flag = 0;
2139 else if (rotation == 90 || rotation == 180 || rotation == 270) 2136 else
2140 { 2137 {
2138# if (defined USE_CAIRO || defined HAVE_XRENDER \
2139 || defined HAVE_NTGUI || defined HAVE_NS)
2140 int cos_r, sin_r;
2141 if (rotation == 90) 2141 if (rotation == 90)
2142 { 2142 {
2143 width = img->height; 2143 width = img->height;
2144 height = img->width; 2144 height = img->width;
2145
2146 cos_r = 0; 2145 cos_r = 0;
2147 sin_r = 1; 2146 sin_r = 1;
2147 rotate_flag = 1;
2148 } 2148 }
2149 else if (rotation == 180) 2149 else if (rotation == 180)
2150 { 2150 {
2151 width = img->width;
2152 height = img->height;
2153
2154 cos_r = -1; 2151 cos_r = -1;
2155 sin_r = 0; 2152 sin_r = 0;
2153 rotate_flag = 1;
2156 } 2154 }
2157 else if (rotation == 270) 2155 else if (rotation == 270)
2158 { 2156 {
2159 width = img->height; 2157 width = img->height;
2160 height = img->width; 2158 height = img->width;
2161
2162 cos_r = 0; 2159 cos_r = 0;
2163 sin_r = -1; 2160 sin_r = -1;
2161 rotate_flag = 1;
2162 }
2163
2164 if (0 < rotate_flag)
2165 {
2166# if defined USE_CAIRO || defined HAVE_XRENDER
2167 /* 1. Translate so (0, 0) is in the center of the image. */
2168 matrix3x3 t
2169 = { [0][0] = 1,
2170 [1][1] = 1,
2171 [2][0] = img->width*.5, [2][1] = img->height*.5, [2][2] = 1 };
2172 matrix3x3 u;
2173 matrix3x3_mult (t, matrix, u);
2174
2175 /* 2. Rotate. */
2176 matrix3x3 rot = { [0][0] = cos_r, [0][1] = -sin_r,
2177 [1][0] = sin_r, [1][1] = cos_r,
2178 [2][2] = 1 };
2179 matrix3x3 v;
2180 matrix3x3_mult (rot, u, v);
2181
2182 /* 3. Translate back. */
2183 t[2][0] = width * -.5;
2184 t[2][1] = height * -.5;
2185 matrix3x3_mult (t, v, matrix);
2186# else
2187 /* 1. Translate so (0, 0) is in the center of the image. */
2188 matrix3x3 t
2189 = { [0][0] = 1,
2190 [1][1] = 1,
2191 [2][0] = img->width*-.5, [2][1] = img->height*-.5, [2][2] = 1 };
2192 matrix3x3 u;
2193 matrix3x3_mult (matrix, t, u);
2194
2195 /* 2. Rotate. */
2196 matrix3x3 rot = { [0][0] = cos_r, [0][1] = sin_r,
2197 [1][0] = -sin_r, [1][1] = cos_r,
2198 [2][2] = 1 };
2199 matrix3x3 v;
2200 matrix3x3_mult (u, rot, v);
2201
2202 /* 3. Translate back. */
2203 t[2][0] = width * .5;
2204 t[2][1] = height * .5;
2205 matrix3x3_mult (v, t, matrix);
2206# endif
2207 img->width = width;
2208 img->height = height;
2164 } 2209 }
2165# if defined USE_CAIRO || defined HAVE_XRENDER
2166 /* 1. Translate so (0, 0) is in the center of the image. */
2167 matrix3x3 t
2168 = { [0][0] = 1,
2169 [1][1] = 1,
2170 [2][0] = img->width * .5, [2][1] = img->height * .5, [2][2] = 1 };
2171 matrix3x3 tmp2;
2172 matrix3x3_mult (t, tmp, tmp2);
2173
2174 /* 2. Rotate. */
2175 matrix3x3 rot = { [0][0] = cos_r, [0][1] = -sin_r,
2176 [1][0] = sin_r, [1][1] = cos_r,
2177 [2][2] = 1 };
2178 matrix3x3 tmp3;
2179 matrix3x3_mult (rot, tmp2, tmp3);
2180
2181 /* 3. Translate back. */
2182 t[2][0] = width * -.5;
2183 t[2][1] = height * -.5;
2184 matrix3x3_mult (t, tmp3, matrix);
2185# elif defined HAVE_NTGUI || defined HAVE_NS
2186 /* 1. Translate so (0, 0) is in the center of the image. */
2187 matrix3x3 t
2188 = { [0][0] = 1,
2189 [1][1] = 1,
2190 [2][0] = -img->width * .5, [2][1] = -img->height * .5, [2][2] = 1 };
2191 matrix3x3 tmp2;
2192 matrix3x3_mult (tmp, t, tmp2);
2193
2194 /* 2. Rotate. */
2195 matrix3x3 rot = { [0][0] = cos_r, [0][1] = sin_r,
2196 [1][0] = -sin_r, [1][1] = cos_r,
2197 [2][2] = 1 };
2198 matrix3x3 tmp3;
2199 matrix3x3_mult (tmp2, rot, tmp3);
2200
2201 /* 3. Translate back. */
2202 t[2][0] = width * .5;
2203 t[2][1] = height * .5;
2204 matrix3x3_mult (tmp3, t, matrix);
2205# endif 2210# endif
2206 img->width = width;
2207 img->height = height;
2208 } 2211 }
2209 else 2212
2210 image_error ("Native image rotation supports only multiples of 90 degrees"); 2213 if (rotate_flag < 0)
2214 image_error ("No native support for rotation by %g degrees",
2215 make_float (rotation));
2211 2216
2212# if defined (HAVE_NS) 2217# if defined (HAVE_NS)
2213 /* Under NS the transform is applied to the drawing surface at 2218 /* Under NS the transform is applied to the drawing surface at