Bug Summary

File:src/eoc-transform.c
Warning:line 423, column 10
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eoc-transform.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-14/lib/clang/14.0.6 -D HAVE_CONFIG_H -I . -I .. -I . -I .. -I ../jpegutils -I ../cut-n-paste/toolbar-editor -D G_LOG_DOMAIN="EOC" -D EOC_DATA_DIR="/usr/local/share/eoc" -D EOC_LOCALE_DIR="/usr/local/share/locale" -D EOC_PLUGIN_DIR="/usr/local/lib/eoc/plugins" -D LIBDIR="/usr/local/lib" -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/ctk-3.0/unix-print -I /usr/local/include/libbean-1.0 -I /usr/include/gobject-introspection-1.0 -I /usr/include/exempi-2.0 -I /usr/include/librsvg-2.0 -D PIC -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.6/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/src -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-06-09-093339-31414-1 -x c eoc-transform.c
1/* Eye Of CAFE -- Affine Transformations
2 *
3 * Copyright (C) 2003-2009 The Free Software Foundation
4 *
5 * Portions based on code from libart_lgpl by Raph Levien.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#ifdef HAVE_CONFIG_H1
23#include <config.h>
24#endif
25
26#include <time.h>
27#include <stdlib.h>
28#include <math.h>
29#include <ctk/ctk.h>
30#include <cairo/cairo.h>
31
32#include "eoc-transform.h"
33#include "eoc-jobs.h"
34
35/* The number of progress updates per transformation */
36#define EOC_TRANSFORM_N_PROG_UPDATES20 20
37
38struct _EocTransformPrivate {
39 cairo_matrix_t affine;
40};
41
42typedef struct {
43 gdouble x;
44 gdouble y;
45} EocPoint;
46
47/* Convert degrees into radians */
48#define EOC_DEG_TO_RAD(degree)((degree) * (3.1415926535897932384626433832795028841971693993751
/180.0))
((degree) * (G_PI3.1415926535897932384626433832795028841971693993751/180.0))
49
50G_DEFINE_TYPE_WITH_PRIVATE (EocTransform, eoc_transform, G_TYPE_OBJECT)static void eoc_transform_init (EocTransform *self); static void
eoc_transform_class_init (EocTransformClass *klass); static GType
eoc_transform_get_type_once (void); static gpointer eoc_transform_parent_class
= ((void*)0); static gint EocTransform_private_offset; static
void eoc_transform_class_intern_init (gpointer klass) { eoc_transform_parent_class
= g_type_class_peek_parent (klass); if (EocTransform_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &EocTransform_private_offset
); eoc_transform_class_init ((EocTransformClass*) klass); } __attribute__
((__unused__)) static inline gpointer eoc_transform_get_instance_private
(EocTransform *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (EocTransform_private_offset)))); } GType eoc_transform_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = eoc_transform_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType eoc_transform_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("EocTransform"
), sizeof (EocTransformClass), (GClassInitFunc)(void (*)(void
)) eoc_transform_class_intern_init, sizeof (EocTransform), (GInstanceInitFunc
)(void (*)(void)) eoc_transform_init, (GTypeFlags) 0); { {{ EocTransform_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (EocTransformPrivate
)); };} } return g_define_type_id; }
51
52static void
53eoc_transform_init (EocTransform *trans)
54{
55 trans->priv = eoc_transform_get_instance_private (trans);
56}
57
58static void
59eoc_transform_class_init (EocTransformClass *klass)
60{
61
62}
63
64/**
65 * eoc_transform_apply:
66 * @trans: a #EocTransform
67 * @pixbuf: a #GdkPixbuf
68 * @job: a #EocJob
69 *
70 * Applies the transformation in @trans to @pixbuf, setting its progress in @job.
71 *
72 * Returns: (transfer full): A new #GdkPixbuf with the transformation applied.
73 **/
74GdkPixbuf*
75eoc_transform_apply (EocTransform *trans, GdkPixbuf *pixbuf, EocJob *job)
76{
77 EocPoint dest_top_left;
78 EocPoint dest_bottom_right;
79 EocPoint vertices[4] = { {0, 0}, {1, 0}, {1, 1}, {0, 1} };
80 double r_det;
81 int inverted [6];
82 EocPoint dest;
83
84 int src_width;
85 int src_height;
86 int src_rowstride;
87 int src_n_channels;
88 guchar *src_buffer;
89
90 GdkPixbuf *dest_pixbuf;
91 int dest_width;
92 int dest_height;
93 int dest_rowstride;
94 int dest_n_channels;
95 guchar *dest_buffer;
96
97 guchar *src_pos;
98 guchar *dest_pos;
99 int dx, dy, sx, sy;
100 int i, x, y;
101
102 int progress_delta;
103
104 g_return_val_if_fail (pixbuf != NULL, NULL)do { if ((pixbuf != ((void*)0))) { } else { g_return_if_fail_warning
("EOC", ((const char*) (__func__)), "pixbuf != NULL"); return
(((void*)0)); } } while (0)
;
105
106 g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf));
107
108 src_width = gdk_pixbuf_get_width (pixbuf);
109 src_height = gdk_pixbuf_get_height (pixbuf);
110 src_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
111 src_n_channels = gdk_pixbuf_get_n_channels (pixbuf);
112 src_buffer = gdk_pixbuf_get_pixels (pixbuf);
113
114 /* find out the dimension of the destination pixbuf */
115 dest_top_left.x = 100000;
116 dest_top_left.y = 100000;
117 dest_bottom_right.x = -100000;
118 dest_bottom_right.y = -100000;
119
120 for (i = 0; i < 4; i++) {
121 dest.x = vertices[i].x * (src_width - 1);
122 dest.y = vertices[i].y * (src_height -1);
123
124 cairo_matrix_transform_point (&trans->priv->affine,
125 &dest.x, &dest.y);
126
127 dest_top_left.x = MIN (dest_top_left.x, dest.x)(((dest_top_left.x) < (dest.x)) ? (dest_top_left.x) : (dest
.x))
;
128 dest_top_left.y = MIN (dest_top_left.y, dest.y)(((dest_top_left.y) < (dest.y)) ? (dest_top_left.y) : (dest
.y))
;
129
130 dest_bottom_right.x = MAX (dest_bottom_right.x, dest.x)(((dest_bottom_right.x) > (dest.x)) ? (dest_bottom_right.x
) : (dest.x))
;
131 dest_bottom_right.y = MAX (dest_bottom_right.y, dest.y)(((dest_bottom_right.y) > (dest.y)) ? (dest_bottom_right.y
) : (dest.y))
;
132 }
133
134 /* create the resulting pixbuf */
135 dest_width = abs ((int) (dest_bottom_right.x - dest_top_left.x + 1));
136 dest_height = abs ((int) (dest_bottom_right.y - dest_top_left.y + 1));
137
138 dest_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
139 gdk_pixbuf_get_has_alpha (pixbuf),
140 gdk_pixbuf_get_bits_per_sample (pixbuf),
141 dest_width,
142 dest_height);
143 dest_rowstride = gdk_pixbuf_get_rowstride (dest_pixbuf);
144 dest_n_channels = gdk_pixbuf_get_n_channels (dest_pixbuf);
145 dest_buffer = gdk_pixbuf_get_pixels (dest_pixbuf);
146
147 /* invert the matrix so that we can compute the source pixel
148 from the target pixel and convert the values to integer
149 ones (faster!) FIXME: Maybe we can do some more
150 improvements by using special mmx/3dnow features if
151 available.
152 */
153 r_det = 1.0 / (trans->priv->affine.xx * trans->priv->affine.yy - trans->priv->affine.yx * trans->priv->affine.xy);
154 inverted[0] = trans->priv->affine.yy * r_det;
155 inverted[1] = -trans->priv->affine.yx * r_det;
156 inverted[2] = -trans->priv->affine.xy * r_det;
157 inverted[3] = trans->priv->affine.xx * r_det;
158 inverted[4] = -trans->priv->affine.x0 * inverted[0] - trans->priv->affine.y0 * inverted[2];
159 inverted[5] = -trans->priv->affine.x0 * inverted[1] - trans->priv->affine.y0 * inverted[3];
160
161 progress_delta = MAX (1, dest_height / EOC_TRANSFORM_N_PROG_UPDATES)(((1) > (dest_height / 20)) ? (1) : (dest_height / 20));
162
163 /*
164 * for every destination pixel (dx,dy) compute the source pixel (sx, sy)
165 * and copy the color values
166 */
167 for (y = 0, dy = dest_top_left.y; y < dest_height; y++, dy++) {
168 for (x = 0, dx = dest_top_left.x; x < dest_width; x++, dx++) {
169
170 sx = dx * inverted[0] + dy * inverted[2] + inverted[4];
171 sy = dx * inverted[1] + dy * inverted[3] + inverted[5];
172
173 if (sx >= 0 && sx < src_width && sy >= 0 && sy < src_height) {
174 src_pos = src_buffer + sy * src_rowstride + sx * src_n_channels;
175 dest_pos = dest_buffer + y * dest_rowstride + x * dest_n_channels;
176
177 for (i = 0; i < src_n_channels; i++) {
178 dest_pos[i] = src_pos[i];
179 }
180 }
181 }
182
183 if (job != NULL((void*)0) && y % progress_delta == 0) {
184 gfloat progress;
185
186 progress = (gfloat) (y + 1.0) / (gfloat) dest_height;
187
188 eoc_job_set_progress (job, progress);
189 }
190 }
191
192 g_object_unref (pixbuf);
193
194 if (job != NULL((void*)0)) {
195 eoc_job_set_progress (job, 1.0);
196 }
197
198 return dest_pixbuf;
199}
200
201static void
202_eoc_cairo_matrix_copy (const cairo_matrix_t *src, cairo_matrix_t *dest)
203{
204 cairo_matrix_init (dest, src->xx, src->yx, src->xy, src->yy, src->x0, src->y0);
205}
206
207#define DOUBLE_EQUAL_MAX_DIFF1e-6 1e-6
208#define DOUBLE_EQUAL(a,b)(fabs (a - b) < 1e-6) (fabs (a - b) < DOUBLE_EQUAL_MAX_DIFF1e-6)
209/* art_affine_equal modified to work with cairo_matrix_t */
210static gboolean
211_eoc_cairo_matrix_equal (const cairo_matrix_t *a, const cairo_matrix_t *b)
212{
213 return (DOUBLE_EQUAL (a->xx, b->xx)(fabs (a->xx - b->xx) < 1e-6) && DOUBLE_EQUAL (a->yx, b->yx)(fabs (a->yx - b->yx) < 1e-6) &&
214 DOUBLE_EQUAL (a->xy, b->xy)(fabs (a->xy - b->xy) < 1e-6) && DOUBLE_EQUAL (a->yy, b->yy)(fabs (a->yy - b->yy) < 1e-6) &&
215 DOUBLE_EQUAL (a->x0, b->x0)(fabs (a->x0 - b->x0) < 1e-6) && DOUBLE_EQUAL (a->y0, b->y0)(fabs (a->y0 - b->y0) < 1e-6) );
216}
217
218/* art_affine_flip modified to work with cairo_matrix_t */
219static void
220_eoc_cairo_matrix_flip (cairo_matrix_t *dst, const cairo_matrix_t *src, gboolean horiz, gboolean vert)
221{
222 dst->xx = horiz ? -src->xx : src->xx;
223 dst->yx = horiz ? -src->yx : src->yx;
224 dst->xy = vert ? -src->xy : src->xy;
225 dst->yy = vert ? -src->yy : src->yy;
226 dst->x0 = horiz ? -src->x0 : src->x0;
227 dst->y0 = vert ? -src->y0 : src->y0;
228}
229
230/**
231 * eoc_transform_reverse:
232 * @trans: a #EocTransform
233 *
234 * Creates the reverse transformation of @trans
235 *
236 * Returns: (transfer full): a new transformation
237 **/
238EocTransform*
239eoc_transform_reverse (EocTransform *trans)
240{
241 EocTransform *reverse;
242
243 g_return_val_if_fail (EOC_IS_TRANSFORM (trans), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((trans)); GType __t = ((eoc_transform_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("EOC", ((const char*) (__func__
)), "EOC_IS_TRANSFORM (trans)"); return (((void*)0)); } } while
(0)
;
244
245 reverse = EOC_TRANSFORM (g_object_new (EOC_TYPE_TRANSFORM, NULL))((((EocTransform*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((eoc_transform_get_type ()), ((void*)0))))
, ((eoc_transform_get_type ()))))))
;
246
247 _eoc_cairo_matrix_copy (&trans->priv->affine, &reverse->priv->affine);
248
249 g_return_val_if_fail (cairo_matrix_invert (&reverse->priv->affine) == CAIRO_STATUS_SUCCESS, reverse)do { if ((cairo_matrix_invert (&reverse->priv->affine
) == CAIRO_STATUS_SUCCESS)) { } else { g_return_if_fail_warning
("EOC", ((const char*) (__func__)), "cairo_matrix_invert (&reverse->priv->affine) == CAIRO_STATUS_SUCCESS"
); return (reverse); } } while (0)
;
250
251 return reverse;
252}
253
254/**
255 * eoc_transform_compose:
256 * @trans: a #EocTransform
257 * @compose: another #EocTransform
258 *
259 *
260 *
261 * Returns: (transfer full): a new transform
262 **/
263EocTransform*
264eoc_transform_compose (EocTransform *trans, EocTransform *compose)
265{
266 EocTransform *composition;
267
268 g_return_val_if_fail (EOC_IS_TRANSFORM (trans), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((trans)); GType __t = ((eoc_transform_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("EOC", ((const char*) (__func__
)), "EOC_IS_TRANSFORM (trans)"); return (((void*)0)); } } while
(0)
;
269 g_return_val_if_fail (EOC_IS_TRANSFORM (compose), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((compose)); GType __t = ((eoc_transform_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("EOC", ((const char*) (__func__
)), "EOC_IS_TRANSFORM (compose)"); return (((void*)0)); } } while
(0)
;
270
271 composition = EOC_TRANSFORM (g_object_new (EOC_TYPE_TRANSFORM, NULL))((((EocTransform*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((eoc_transform_get_type ()), ((void*)0))))
, ((eoc_transform_get_type ()))))))
;
272
273 cairo_matrix_multiply (&composition->priv->affine,
274 &trans->priv->affine,
275 &compose->priv->affine);
276
277 return composition;
278}
279
280gboolean
281eoc_transform_is_identity (EocTransform *trans)
282{
283 static const cairo_matrix_t identity = { 1, 0, 0, 1, 0, 0 };
284
285 g_return_val_if_fail (EOC_IS_TRANSFORM (trans), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((trans)); GType __t = ((eoc_transform_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("EOC", ((const char*) (__func__
)), "EOC_IS_TRANSFORM (trans)"); return ((0)); } } while (0)
;
286
287 return _eoc_cairo_matrix_equal (&identity, &trans->priv->affine);
288}
289
290EocTransform*
291eoc_transform_identity_new (void)
292{
293 EocTransform *trans;
294
295 trans = EOC_TRANSFORM (g_object_new (EOC_TYPE_TRANSFORM, NULL))((((EocTransform*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((eoc_transform_get_type ()), ((void*)0))))
, ((eoc_transform_get_type ()))))))
;
296
297 cairo_matrix_init_identity (&trans->priv->affine);
298
299 return trans;
300}
301
302EocTransform*
303eoc_transform_rotate_new (int degree)
304{
305 EocTransform *trans;
306
307 trans = EOC_TRANSFORM (g_object_new (EOC_TYPE_TRANSFORM, NULL))((((EocTransform*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((eoc_transform_get_type ()), ((void*)0))))
, ((eoc_transform_get_type ()))))))
;
308
309 cairo_matrix_init_rotate (&trans->priv->affine, EOC_DEG_TO_RAD(degree)((degree) * (3.1415926535897932384626433832795028841971693993751
/180.0))
);
310
311 return trans;
312}
313
314EocTransform*
315eoc_transform_flip_new (EocTransformType type)
316{
317 EocTransform *trans;
318 gboolean horiz, vert;
319
320 trans = EOC_TRANSFORM (g_object_new (EOC_TYPE_TRANSFORM, NULL))((((EocTransform*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((eoc_transform_get_type ()), ((void*)0))))
, ((eoc_transform_get_type ()))))))
;
321
322 cairo_matrix_init_identity (&trans->priv->affine);
323
324 horiz = (type == EOC_TRANSFORM_FLIP_HORIZONTAL);
325 vert = (type == EOC_TRANSFORM_FLIP_VERTICAL);
326
327 _eoc_cairo_matrix_flip (&trans->priv->affine,
328 &trans->priv->affine,
329 horiz, vert);
330
331 return trans;
332}
333
334EocTransform*
335eoc_transform_new (EocTransformType type)
336{
337 EocTransform *trans = NULL((void*)0);
338 EocTransform *temp1 = NULL((void*)0), *temp2 = NULL((void*)0);
339
340 switch (type) {
341 case EOC_TRANSFORM_NONE:
342 trans = eoc_transform_identity_new ();
343 break;
344 case EOC_TRANSFORM_FLIP_HORIZONTAL:
345 trans = eoc_transform_flip_new (EOC_TRANSFORM_FLIP_HORIZONTAL);
346 break;
347 case EOC_TRANSFORM_ROT_180:
348 trans = eoc_transform_rotate_new (180);
349 break;
350 case EOC_TRANSFORM_FLIP_VERTICAL:
351 trans = eoc_transform_flip_new (EOC_TRANSFORM_FLIP_VERTICAL);
352 break;
353 case EOC_TRANSFORM_TRANSPOSE:
354 temp1 = eoc_transform_rotate_new (90);
355 temp2 = eoc_transform_flip_new (EOC_TRANSFORM_FLIP_HORIZONTAL);
356 trans = eoc_transform_compose (temp1, temp2);
357 g_object_unref (temp1);
358 g_object_unref (temp2);
359 break;
360 case EOC_TRANSFORM_ROT_90:
361 trans = eoc_transform_rotate_new (90);
362 break;
363 case EOC_TRANSFORM_TRANSVERSE:
364 temp1 = eoc_transform_rotate_new (90);
365 temp2 = eoc_transform_flip_new (EOC_TRANSFORM_FLIP_VERTICAL);
366 trans = eoc_transform_compose (temp1, temp2);
367 g_object_unref (temp1);
368 g_object_unref (temp2);
369 break;
370 case EOC_TRANSFORM_ROT_270:
371 trans = eoc_transform_rotate_new (270);
372 break;
373 default:
374 trans = eoc_transform_identity_new ();
375 break;
376 }
377
378 return trans;
379}
380
381EocTransformType
382eoc_transform_get_transform_type (EocTransform *trans)
383{
384 cairo_matrix_t affine, a1, a2;
385 EocTransformPrivate *priv;
386
387 g_return_val_if_fail (EOC_IS_TRANSFORM (trans), EOC_TRANSFORM_NONE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((trans)); GType __t = ((eoc_transform_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("EOC", ((const char*) (__func__
)), "EOC_IS_TRANSFORM (trans)"); return (EOC_TRANSFORM_NONE);
} } while (0)
;
388
389 priv = trans->priv;
390
391 cairo_matrix_init_rotate (&affine, EOC_DEG_TO_RAD(90)((90) * (3.1415926535897932384626433832795028841971693993751/
180.0))
);
392 if (_eoc_cairo_matrix_equal (&affine, &priv->affine)) {
393 return EOC_TRANSFORM_ROT_90;
394 }
395
396 cairo_matrix_init_rotate (&affine, EOC_DEG_TO_RAD(180)((180) * (3.1415926535897932384626433832795028841971693993751
/180.0))
);
397 if (_eoc_cairo_matrix_equal (&affine, &priv->affine)) {
398 return EOC_TRANSFORM_ROT_180;
399 }
400
401 cairo_matrix_init_rotate (&affine, EOC_DEG_TO_RAD(270)((270) * (3.1415926535897932384626433832795028841971693993751
/180.0))
);
402 if (_eoc_cairo_matrix_equal (&affine, &priv->affine)) {
403 return EOC_TRANSFORM_ROT_270;
404 }
405
406 cairo_matrix_init_identity (&affine);
407 _eoc_cairo_matrix_flip (&affine, &affine, TRUE(!(0)), FALSE(0));
408 if (_eoc_cairo_matrix_equal (&affine, &priv->affine)) {
409 return EOC_TRANSFORM_FLIP_HORIZONTAL;
410 }
411
412 cairo_matrix_init_identity (&affine);
413 _eoc_cairo_matrix_flip (&affine, &affine, FALSE(0), TRUE(!(0)));
414 if (_eoc_cairo_matrix_equal (&affine, &priv->affine)) {
415 return EOC_TRANSFORM_FLIP_VERTICAL;
416 }
417
418 cairo_matrix_init_rotate (&a1, EOC_DEG_TO_RAD(90)((90) * (3.1415926535897932384626433832795028841971693993751/
180.0))
);
419 cairo_matrix_init_identity (&a2);
420 _eoc_cairo_matrix_flip (&a2, &a2, TRUE(!(0)), FALSE(0));
421 cairo_matrix_multiply(&affine, &a1, &a2);
422 if (_eoc_cairo_matrix_equal (&affine, &priv->affine)) {
423 return EOC_TRANSFORM_TRANSPOSE;
This statement is never executed
424 }
425
426 /* A transversion is a 180° rotation followed by a transposition */
427 /* Reuse the transposition from the previous step for this. */
428 cairo_matrix_init_rotate (&a1, EOC_DEG_TO_RAD(180)((180) * (3.1415926535897932384626433832795028841971693993751
/180.0))
);
429 cairo_matrix_multiply(&a2, &a1, &affine);
430 if (_eoc_cairo_matrix_equal (&a2, &priv->affine)) {
431 return EOC_TRANSFORM_TRANSVERSE;
432 }
433
434 return EOC_TRANSFORM_NONE;
435}
436
437gboolean
438eoc_transform_get_affine (EocTransform *trans, cairo_matrix_t *affine)
439{
440 g_return_val_if_fail (EOC_IS_TRANSFORM (trans), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((trans)); GType __t = ((eoc_transform_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("EOC", ((const char*) (__func__
)), "EOC_IS_TRANSFORM (trans)"); return ((0)); } } while (0)
;
441
442 _eoc_cairo_matrix_copy (&trans->priv->affine, affine);
443
444 return TRUE(!(0));
445}
446