Bug Summary

File:src/eoc-image.c
Warning:line 966, column 8
Null pointer passed to 1st parameter expecting 'nonnull'

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-image.c -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 -fdebug-compilation-dir=/rootdir/src -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -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/share/eoc" -D EOC_LOCALE_DIR="/usr/share/locale" -D EOC_PLUGIN_DIR="/usr/lib/eoc/plugins" -D LIBDIR="/usr/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/sysprof-6 -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/webp -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-2.0 -I /usr/include/gobject-introspection-1.0 -I /usr/include/exempi-2.0 -I /usr/include/librsvg-2.0 -I /usr/include/libxml2 -D PIC -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -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.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/2025-07-17-100451-31381-1 -x c eoc-image.c
1/* Eye Of Cafe - Image
2 *
3 * Copyright (C) 2006 The Free Software Foundation
4 *
5 * Author: Lucas Rocha <lucasr@gnome.org>
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
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#ifdef HAVE_CONFIG_H1
23#include "config.h"
24#endif
25
26#define GDK_PIXBUF_ENABLE_BACKEND
27#include <cdk/cdkx.h>
28
29#include "eoc-image.h"
30#include "eoc-image-private.h"
31#include "eoc-debug.h"
32
33#ifdef HAVE_JPEG1
34#include "eoc-image-jpeg.h"
35#endif
36
37#include "eoc-marshal.h"
38#include "eoc-pixbuf-util.h"
39#include "eoc-metadata-reader.h"
40#include "eoc-image-save-info.h"
41#include "eoc-transform.h"
42#include "eoc-util.h"
43#include "eoc-jobs.h"
44#include "eoc-thumbnail.h"
45
46#include <unistd.h>
47#include <string.h>
48
49#include <glib.h>
50#include <glib-object.h>
51#include <glib/gi18n.h>
52#include <ctk/ctk.h>
53#include <gdk-pixbuf/gdk-pixbuf.h>
54
55#ifdef HAVE_EXIF1
56#include "eoc-exif-util.h"
57#include <libexif/exif-data.h>
58#include <libexif/exif-utils.h>
59#include <libexif/exif-loader.h>
60#endif
61
62#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
63#include <lcms2.h>
64#ifndef EXIF_TAG_GAMMA0xa500
65#define EXIF_TAG_GAMMA0xa500 0xa500
66#endif
67#endif
68
69#ifdef HAVE_RSVG1
70#include <librsvg/rsvg.h>
71#endif
72
73G_DEFINE_TYPE_WITH_PRIVATE (EocImage, eoc_image, G_TYPE_OBJECT)static void eoc_image_init (EocImage *self); static void eoc_image_class_init
(EocImageClass *klass); static GType eoc_image_get_type_once
(void); static gpointer eoc_image_parent_class = ((void*)0);
static gint EocImage_private_offset; static void eoc_image_class_intern_init
(gpointer klass) { eoc_image_parent_class = g_type_class_peek_parent
(klass); if (EocImage_private_offset != 0) g_type_class_adjust_private_offset
(klass, &EocImage_private_offset); eoc_image_class_init (
(EocImageClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer eoc_image_get_instance_private (EocImage *self
) { return (((gpointer) ((guint8*) (self) + (glong) (EocImage_private_offset
)))); } GType eoc_image_get_type (void) { static GType 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_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= eoc_image_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_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType eoc_image_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple (((GType
) ((20) << (2))), g_intern_static_string ("EocImage"), sizeof
(EocImageClass), (GClassInitFunc)(void (*)(void)) eoc_image_class_intern_init
, sizeof (EocImage), (GInstanceInitFunc)(void (*)(void)) eoc_image_init
, (GTypeFlags) 0); { {{ EocImage_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (EocImagePrivate)); };} } return g_define_type_id
; }
74
75enum {
76 SIGNAL_CHANGED,
77 SIGNAL_SIZE_PREPARED,
78 SIGNAL_THUMBNAIL_CHANGED,
79 SIGNAL_SAVE_PROGRESS,
80 SIGNAL_NEXT_FRAME,
81 SIGNAL_FILE_CHANGED,
82 SIGNAL_LAST
83};
84
85static guint signals[SIGNAL_LAST] = { 0 };
86
87static GList *supported_mime_types = NULL((void*)0);
88
89#define EOC_IMAGE_READ_BUFFER_SIZE65535 65535
90
91static void
92eoc_image_free_mem_private (EocImage *image)
93{
94 EocImagePrivate *priv;
95
96 priv = image->priv;
97
98 if (priv->status == EOC_IMAGE_STATUS_LOADING) {
99 eoc_image_cancel_load (image);
100 } else {
101 if (priv->anim_iter != NULL((void*)0)) {
102 g_object_unref (priv->anim_iter);
103 priv->anim_iter = NULL((void*)0);
104 }
105
106 if (priv->anim != NULL((void*)0)) {
107 g_object_unref (priv->anim);
108 priv->anim = NULL((void*)0);
109 }
110
111 priv->is_playing = FALSE(0);
112
113 if (priv->image != NULL((void*)0)) {
114 g_object_unref (priv->image);
115 priv->image = NULL((void*)0);
116 }
117
118#ifdef HAVE_RSVG1
119 if (priv->svg != NULL((void*)0)) {
120 g_object_unref (priv->svg);
121 priv->svg = NULL((void*)0);
122 }
123#endif
124
125#ifdef HAVE_EXIF1
126 if (priv->exif != NULL((void*)0)) {
127 exif_data_unref (priv->exif);
128 priv->exif = NULL((void*)0);
129 }
130#endif
131
132 if (priv->exif_chunk != NULL((void*)0)) {
133 g_free (priv->exif_chunk);
134 priv->exif_chunk = NULL((void*)0);
135 }
136
137 priv->exif_chunk_len = 0;
138
139#ifdef HAVE_EXEMPI1
140 if (priv->xmp != NULL((void*)0)) {
141 xmp_free (priv->xmp);
142 priv->xmp = NULL((void*)0);
143 }
144#endif
145
146#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
147 if (priv->profile != NULL((void*)0)) {
148 if (CDK_IS_X11_DISPLAY (cdk_display_get_default ())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_display_get_default ())); GType __t = ((cdk_x11_display_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; }))))
) {
149 cmsCloseProfile (priv->profile);
150 }
151 priv->profile = NULL((void*)0);
152 }
153#endif
154
155 priv->status = EOC_IMAGE_STATUS_UNKNOWN;
156 priv->metadata_status = EOC_IMAGE_METADATA_NOT_READ;
157 }
158}
159
160static void
161eoc_image_dispose (GObject *object)
162{
163 EocImagePrivate *priv;
164
165 priv = EOC_IMAGE (object)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((eoc_image_get_type ()))))))
->priv;
166
167 eoc_image_free_mem_private (EOC_IMAGE (object)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((eoc_image_get_type ()))))))
);
168
169 if (priv->file) {
170 g_object_unref (priv->file);
171 priv->file = NULL((void*)0);
172 }
173
174 if (priv->caption) {
175 g_free (priv->caption);
176 priv->caption = NULL((void*)0);
177 }
178
179 if (priv->collate_key) {
180 g_free (priv->collate_key);
181 priv->collate_key = NULL((void*)0);
182 }
183
184 if (priv->file_type) {
185 g_free (priv->file_type);
186 priv->file_type = NULL((void*)0);
187 }
188
189 g_mutex_clear (&priv->status_mutex);
190
191 if (priv->trans) {
192 g_object_unref (priv->trans);
193 priv->trans = NULL((void*)0);
194 }
195
196 if (priv->trans_autorotate) {
197 g_object_unref (priv->trans_autorotate);
198 priv->trans_autorotate = NULL((void*)0);
199 }
200
201 if (priv->undo_stack) {
202 g_slist_foreach (priv->undo_stack, (GFunc) g_object_unref, NULL((void*)0));
203 g_slist_free (priv->undo_stack);
204 priv->undo_stack = NULL((void*)0);
205 }
206
207 G_OBJECT_CLASS (eoc_image_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((eoc_image_parent_class)), (((GType) ((20) << (2)))
)))))
->dispose (object);
208}
209
210static void
211eoc_image_class_init (EocImageClass *klass)
212{
213 GObjectClass *object_class = (GObjectClass*) klass;
214
215 object_class->dispose = eoc_image_dispose;
216
217 signals[SIGNAL_SIZE_PREPARED] =
218 g_signal_new ("size-prepared",
219 EOC_TYPE_IMAGE(eoc_image_get_type ()),
220 G_SIGNAL_RUN_LAST,
221 G_STRUCT_OFFSET (EocImageClass, size_prepared)((glong) __builtin_offsetof(EocImageClass, size_prepared)),
222 NULL((void*)0), NULL((void*)0),
223 eoc_marshal_VOID__INT_INT,
224 G_TYPE_NONE((GType) ((1) << (2))), 2,
225 G_TYPE_INT((GType) ((6) << (2))),
226 G_TYPE_INT((GType) ((6) << (2))));
227
228 signals[SIGNAL_CHANGED] =
229 g_signal_new ("changed",
230 EOC_TYPE_IMAGE(eoc_image_get_type ()),
231 G_SIGNAL_RUN_LAST,
232 G_STRUCT_OFFSET (EocImageClass, changed)((glong) __builtin_offsetof(EocImageClass, changed)),
233 NULL((void*)0), NULL((void*)0),
234 g_cclosure_marshal_VOID__VOID,
235 G_TYPE_NONE((GType) ((1) << (2))), 0);
236
237 signals[SIGNAL_THUMBNAIL_CHANGED] =
238 g_signal_new ("thumbnail-changed",
239 EOC_TYPE_IMAGE(eoc_image_get_type ()),
240 G_SIGNAL_RUN_LAST,
241 G_STRUCT_OFFSET (EocImageClass, thumbnail_changed)((glong) __builtin_offsetof(EocImageClass, thumbnail_changed)
)
,
242 NULL((void*)0), NULL((void*)0),
243 g_cclosure_marshal_VOID__VOID,
244 G_TYPE_NONE((GType) ((1) << (2))), 0);
245
246 signals[SIGNAL_SAVE_PROGRESS] =
247 g_signal_new ("save-progress",
248 EOC_TYPE_IMAGE(eoc_image_get_type ()),
249 G_SIGNAL_RUN_LAST,
250 G_STRUCT_OFFSET (EocImageClass, save_progress)((glong) __builtin_offsetof(EocImageClass, save_progress)),
251 NULL((void*)0), NULL((void*)0),
252 g_cclosure_marshal_VOID__FLOAT,
253 G_TYPE_NONE((GType) ((1) << (2))), 1,
254 G_TYPE_FLOAT((GType) ((14) << (2))));
255 /**
256 * EocImage::next-frame:
257 * @img: the object which received the signal.
258 * @delay: number of milliseconds the current frame will be displayed.
259 *
260 * The ::next-frame signal will be emitted each time an animated image
261 * advances to the next frame.
262 */
263 signals[SIGNAL_NEXT_FRAME] =
264 g_signal_new ("next-frame",
265 EOC_TYPE_IMAGE(eoc_image_get_type ()),
266 G_SIGNAL_RUN_LAST,
267 G_STRUCT_OFFSET (EocImageClass, next_frame)((glong) __builtin_offsetof(EocImageClass, next_frame)),
268 NULL((void*)0), NULL((void*)0),
269 g_cclosure_marshal_VOID__INT,
270 G_TYPE_NONE((GType) ((1) << (2))), 1,
271 G_TYPE_INT((GType) ((6) << (2))));
272
273 signals[SIGNAL_FILE_CHANGED] = g_signal_new ("file-changed",
274 EOC_TYPE_IMAGE(eoc_image_get_type ()),
275 G_SIGNAL_RUN_LAST,
276 G_STRUCT_OFFSET (EocImageClass, file_changed)((glong) __builtin_offsetof(EocImageClass, file_changed)),
277 NULL((void*)0), NULL((void*)0),
278 g_cclosure_marshal_VOID__VOID,
279 G_TYPE_NONE((GType) ((1) << (2))), 0);
280}
281
282static void
283eoc_image_init (EocImage *img)
284{
285 img->priv = eoc_image_get_instance_private (img);
286
287 img->priv->file = NULL((void*)0);
288 img->priv->image = NULL((void*)0);
289 img->priv->anim = NULL((void*)0);
290 img->priv->anim_iter = NULL((void*)0);
291 img->priv->is_playing = FALSE(0);
292 img->priv->thumbnail = NULL((void*)0);
293 img->priv->width = -1;
294 img->priv->height = -1;
295 img->priv->modified = FALSE(0);
296 img->priv->file_is_changed = FALSE(0);
297 g_mutex_init (&img->priv->status_mutex);
298 img->priv->status = EOC_IMAGE_STATUS_UNKNOWN;
299 img->priv->metadata_status = EOC_IMAGE_METADATA_NOT_READ;
300 img->priv->undo_stack = NULL((void*)0);
301 img->priv->trans = NULL((void*)0);
302 img->priv->trans_autorotate = NULL((void*)0);
303 img->priv->data_ref_count = 0;
304#ifdef HAVE_EXIF1
305 img->priv->orientation = 0;
306 img->priv->autorotate = FALSE(0);
307 img->priv->exif = NULL((void*)0);
308#endif
309#ifdef HAVE_EXEMPI1
310 img->priv->xmp = NULL((void*)0);
311#endif
312#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
313 img->priv->profile = NULL((void*)0);
314#endif
315#ifdef HAVE_RSVG1
316 img->priv->svg = NULL((void*)0);
317#endif
318}
319
320EocImage *
321eoc_image_new_file (GFile *file, const gchar *caption)
322{
323 EocImage *img;
324
325 img = EOC_IMAGE (g_object_new (EOC_TYPE_IMAGE, NULL))((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((eoc_image_get_type ()), ((void*)0)))), ((
eoc_image_get_type ()))))))
;
326
327 img->priv->file = g_object_ref (file)((__typeof__ (file)) (g_object_ref) (file));
328 img->priv->caption = g_strdup (caption)g_strdup_inline (caption);
329
330 return img;
331}
332
333GQuark
334eoc_image_error_quark (void)
335{
336 static GQuark q = 0;
337
338 if (q == 0) {
339 q = g_quark_from_static_string ("eoc-image-error-quark");
340 }
341
342 return q;
343}
344
345static void
346eoc_image_update_exif_data (EocImage *image)
347{
348#ifdef HAVE_EXIF1
349 EocImagePrivate *priv;
350 ExifEntry *entry;
351 ExifByteOrder bo;
352
353 eoc_debug (DEBUG_IMAGE_DATAEOC_DEBUG_IMAGE_DATA, "eoc-image.c", 353, ((const char*) (__func__
))
);
354
355 g_return_if_fail (EOC_IS_IMAGE (image))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((image)); GType __t = ((eoc_image_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_IMAGE (image)"); return; } } while (0)
;
356
357 priv = image->priv;
358
359 if (priv->exif == NULL((void*)0)) return;
360
361 bo = exif_data_get_byte_order (priv->exif);
362
363 /* Update image width */
364 entry = exif_data_get_entry (priv->exif, EXIF_TAG_PIXEL_X_DIMENSION)(exif_content_get_entry(priv->exif->ifd[EXIF_IFD_0],EXIF_TAG_PIXEL_X_DIMENSION
) ? exif_content_get_entry(priv->exif->ifd[EXIF_IFD_0],
EXIF_TAG_PIXEL_X_DIMENSION) : exif_content_get_entry(priv->
exif->ifd[EXIF_IFD_1],EXIF_TAG_PIXEL_X_DIMENSION) ? exif_content_get_entry
(priv->exif->ifd[EXIF_IFD_1],EXIF_TAG_PIXEL_X_DIMENSION
) : exif_content_get_entry(priv->exif->ifd[EXIF_IFD_EXIF
],EXIF_TAG_PIXEL_X_DIMENSION) ? exif_content_get_entry(priv->
exif->ifd[EXIF_IFD_EXIF],EXIF_TAG_PIXEL_X_DIMENSION) : exif_content_get_entry
(priv->exif->ifd[EXIF_IFD_GPS],EXIF_TAG_PIXEL_X_DIMENSION
) ? exif_content_get_entry(priv->exif->ifd[EXIF_IFD_GPS
],EXIF_TAG_PIXEL_X_DIMENSION) : exif_content_get_entry(priv->
exif->ifd[EXIF_IFD_INTEROPERABILITY],EXIF_TAG_PIXEL_X_DIMENSION
) ? exif_content_get_entry(priv->exif->ifd[EXIF_IFD_INTEROPERABILITY
],EXIF_TAG_PIXEL_X_DIMENSION) : ((void*)0))
;
365 if (entry != NULL((void*)0) && (priv->width >= 0)) {
366 if (entry->format == EXIF_FORMAT_LONG)
367 exif_set_long (entry->data, bo, priv->width);
368 else if (entry->format == EXIF_FORMAT_SHORT)
369 exif_set_short (entry->data, bo, priv->width);
370 else
371 g_warning ("Exif entry has unsupported size");
372 }
373
374 /* Update image height */
375 entry = exif_data_get_entry (priv->exif, EXIF_TAG_PIXEL_Y_DIMENSION)(exif_content_get_entry(priv->exif->ifd[EXIF_IFD_0],EXIF_TAG_PIXEL_Y_DIMENSION
) ? exif_content_get_entry(priv->exif->ifd[EXIF_IFD_0],
EXIF_TAG_PIXEL_Y_DIMENSION) : exif_content_get_entry(priv->
exif->ifd[EXIF_IFD_1],EXIF_TAG_PIXEL_Y_DIMENSION) ? exif_content_get_entry
(priv->exif->ifd[EXIF_IFD_1],EXIF_TAG_PIXEL_Y_DIMENSION
) : exif_content_get_entry(priv->exif->ifd[EXIF_IFD_EXIF
],EXIF_TAG_PIXEL_Y_DIMENSION) ? exif_content_get_entry(priv->
exif->ifd[EXIF_IFD_EXIF],EXIF_TAG_PIXEL_Y_DIMENSION) : exif_content_get_entry
(priv->exif->ifd[EXIF_IFD_GPS],EXIF_TAG_PIXEL_Y_DIMENSION
) ? exif_content_get_entry(priv->exif->ifd[EXIF_IFD_GPS
],EXIF_TAG_PIXEL_Y_DIMENSION) : exif_content_get_entry(priv->
exif->ifd[EXIF_IFD_INTEROPERABILITY],EXIF_TAG_PIXEL_Y_DIMENSION
) ? exif_content_get_entry(priv->exif->ifd[EXIF_IFD_INTEROPERABILITY
],EXIF_TAG_PIXEL_Y_DIMENSION) : ((void*)0))
;
376 if (entry != NULL((void*)0) && (priv->height >= 0)) {
377 if (entry->format == EXIF_FORMAT_LONG)
378 exif_set_long (entry->data, bo, priv->height);
379 else if (entry->format == EXIF_FORMAT_SHORT)
380 exif_set_short (entry->data, bo, priv->height);
381 else
382 g_warning ("Exif entry has unsupported size");
383 }
384
385 /* Update image orientation */
386 entry = exif_data_get_entry (priv->exif, EXIF_TAG_ORIENTATION)(exif_content_get_entry(priv->exif->ifd[EXIF_IFD_0],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(priv->exif->ifd[EXIF_IFD_0],
EXIF_TAG_ORIENTATION) : exif_content_get_entry(priv->exif->
ifd[EXIF_IFD_1],EXIF_TAG_ORIENTATION) ? exif_content_get_entry
(priv->exif->ifd[EXIF_IFD_1],EXIF_TAG_ORIENTATION) : exif_content_get_entry
(priv->exif->ifd[EXIF_IFD_EXIF],EXIF_TAG_ORIENTATION) ?
exif_content_get_entry(priv->exif->ifd[EXIF_IFD_EXIF],
EXIF_TAG_ORIENTATION) : exif_content_get_entry(priv->exif->
ifd[EXIF_IFD_GPS],EXIF_TAG_ORIENTATION) ? exif_content_get_entry
(priv->exif->ifd[EXIF_IFD_GPS],EXIF_TAG_ORIENTATION) : exif_content_get_entry
(priv->exif->ifd[EXIF_IFD_INTEROPERABILITY],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(priv->exif->ifd[EXIF_IFD_INTEROPERABILITY
],EXIF_TAG_ORIENTATION) : ((void*)0))
;
387 if (entry != NULL((void*)0)) {
388 if (entry->format == EXIF_FORMAT_LONG)
389 exif_set_long (entry->data, bo, 1);
390 else if (entry->format == EXIF_FORMAT_SHORT)
391 exif_set_short (entry->data, bo, 1);
392 else
393 g_warning ("Exif entry has unsupported size");
394
395 priv->orientation = 1;
396 }
397#endif
398}
399
400static void
401eoc_image_real_transform (EocImage *img,
402 EocTransform *trans,
403 gboolean is_undo,
404 EocJob *job)
405{
406 EocImagePrivate *priv;
407 GdkPixbuf *transformed;
408 gboolean modified = FALSE(0);
409
410 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
411 g_return_if_fail (EOC_IS_TRANSFORM (trans))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; } } while (0)
;
412
413 priv = img->priv;
414
415 if (priv->image != NULL((void*)0)) {
416 transformed = eoc_transform_apply (trans, priv->image, job);
417
418 g_object_unref (priv->image);
419 priv->image = transformed;
420
421 priv->width = gdk_pixbuf_get_width (transformed);
422 priv->height = gdk_pixbuf_get_height (transformed);
423
424 modified = TRUE(!(0));
425 }
426
427 if (priv->thumbnail != NULL((void*)0)) {
428 transformed = eoc_transform_apply (trans, priv->thumbnail, NULL((void*)0));
429
430 g_object_unref (priv->thumbnail);
431 priv->thumbnail = transformed;
432
433 modified = TRUE(!(0));
434 }
435
436 if (modified) {
437 priv->modified = TRUE(!(0));
438 eoc_image_update_exif_data (img);
439 }
440
441 if (priv->trans == NULL((void*)0)) {
442 g_object_ref (trans)((__typeof__ (trans)) (g_object_ref) (trans));
443 priv->trans = trans;
444 } else {
445 EocTransform *composition;
446
447 composition = eoc_transform_compose (priv->trans, trans);
448
449 g_object_unref (priv->trans);
450
451 priv->trans = composition;
452 }
453
454 if (!is_undo) {
455 g_object_ref (trans)((__typeof__ (trans)) (g_object_ref) (trans));
456 priv->undo_stack = g_slist_prepend (priv->undo_stack, trans);
457 }
458}
459
460static gboolean
461do_emit_size_prepared_signal (EocImage *img)
462{
463 g_signal_emit (img, signals[SIGNAL_SIZE_PREPARED], 0,
464 img->priv->width, img->priv->height);
465 return FALSE(0);
466}
467
468static void
469eoc_image_emit_size_prepared (EocImage *img)
470{
471 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE200,
472 (GSourceFunc) do_emit_size_prepared_signal,
473 g_object_ref (img)((__typeof__ (img)) (g_object_ref) (img)), g_object_unref);
474}
475
476static void
477eoc_image_size_prepared (GdkPixbufLoader *loader G_GNUC_UNUSED__attribute__ ((__unused__)),
478 gint width,
479 gint height,
480 gpointer data)
481{
482 EocImage *img;
483
484 eoc_debug (DEBUG_IMAGE_LOADEOC_DEBUG_IMAGE_LOAD, "eoc-image.c", 484, ((const char*) (__func__
))
);
485
486 g_return_if_fail (EOC_IS_IMAGE (data))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((data)); GType __t = ((eoc_image_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_IMAGE (data)"); return; } } while (0)
;
487
488 img = EOC_IMAGE (data)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((eoc_image_get_type ()))))))
;
489
490 g_mutex_lock (&img->priv->status_mutex);
491
492 img->priv->width = width;
493 img->priv->height = height;
494
495 g_mutex_unlock (&img->priv->status_mutex);
496
497#ifdef HAVE_EXIF1
498 if (!img->priv->autorotate || img->priv->exif)
499#endif
500 eoc_image_emit_size_prepared (img);
501}
502
503static EocMetadataReader*
504check_for_metadata_img_format (EocImage *img G_GNUC_UNUSED__attribute__ ((__unused__)),
505 guchar *buffer,
506 guint bytes_read)
507{
508 EocMetadataReader *md_reader = NULL((void*)0);
509
510 eoc_debug_message (DEBUG_IMAGE_DATAEOC_DEBUG_IMAGE_DATA, "eoc-image.c", 510, ((const char*) (__func__
))
, "Check image format for jpeg: %x%x - length: %i",
511 buffer[0], buffer[1], bytes_read);
512
513 if (bytes_read >= 2) {
514 /* SOI (start of image) marker for JPEGs is 0xFFD8 */
515 if ((buffer[0] == 0xFF) && (buffer[1] == 0xD8)) {
516 md_reader = eoc_metadata_reader_new (EOC_METADATA_JPEG);
517 }
518 if (bytes_read >= 8 &&
519 memcmp (buffer, "\x89PNG\x0D\x0A\x1a\x0A", 8) == 0) {
520 md_reader = eoc_metadata_reader_new (EOC_METADATA_PNG);
521 }
522 }
523
524 return md_reader;
525}
526
527static gboolean
528eoc_image_needs_transformation (EocImage *img)
529{
530 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
531
532 return (img->priv->trans != NULL((void*)0) || img->priv->trans_autorotate != NULL((void*)0));
533}
534
535static gboolean
536eoc_image_apply_transformations (EocImage *img, GError **error)
537{
538 GdkPixbuf *transformed = NULL((void*)0);
539 EocTransform *composition = NULL((void*)0);
540 EocImagePrivate *priv;
541
542 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
543
544 priv = img->priv;
545
546 if (priv->trans == NULL((void*)0) && priv->trans_autorotate == NULL((void*)0)) {
547 return TRUE(!(0));
548 }
549
550 if (priv->image == NULL((void*)0)) {
551 g_set_error (error,
552 EOC_IMAGE_ERROReoc_image_error_quark (),
553 EOC_IMAGE_ERROR_NOT_LOADED,
554 _("Transformation on unloaded image.")gettext ("Transformation on unloaded image."));
555
556 return FALSE(0);
557 }
558
559 if (priv->trans != NULL((void*)0) && priv->trans_autorotate != NULL((void*)0)) {
560 composition = eoc_transform_compose (priv->trans,
561 priv->trans_autorotate);
562 } else if (priv->trans != NULL((void*)0)) {
563 composition = g_object_ref (priv->trans)((__typeof__ (priv->trans)) (g_object_ref) (priv->trans
))
;
564 } else if (priv->trans_autorotate != NULL((void*)0)) {
565 composition = g_object_ref (priv->trans_autorotate)((__typeof__ (priv->trans_autorotate)) (g_object_ref) (priv
->trans_autorotate))
;
566 }
567
568 if (composition != NULL((void*)0)) {
569 transformed = eoc_transform_apply (composition, priv->image, NULL((void*)0));
570 }
571
572 g_object_unref (priv->image);
573 priv->image = transformed;
574
575 if (transformed != NULL((void*)0)) {
576 priv->width = gdk_pixbuf_get_width (priv->image);
577 priv->height = gdk_pixbuf_get_height (priv->image);
578 } else {
579 g_set_error (error,
580 EOC_IMAGE_ERROReoc_image_error_quark (),
581 EOC_IMAGE_ERROR_GENERIC,
582 _("Transformation failed.")gettext ("Transformation failed."));
583 }
584
585 g_object_unref (composition);
586
587 return (transformed != NULL((void*)0));
588}
589
590static void
591eoc_image_get_file_info (EocImage *img,
592 goffset *bytes,
593 gchar **mime_type,
594 GError **error)
595{
596 GFileInfo *file_info;
597
598 file_info = g_file_query_info (img->priv->file,
599 G_FILE_ATTRIBUTE_STANDARD_SIZE"standard::size" ","
600 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE"standard::content-type",
601 0, NULL((void*)0), error);
602
603 if (file_info == NULL((void*)0)) {
9
Assuming 'file_info' is equal to NULL
10
Taking true branch
604 if (bytes
10.1
'bytes' is non-null
)
11
Taking true branch
605 *bytes = 0;
606
607 if (mime_type
11.1
'mime_type' is non-null
)
12
Taking true branch
608 *mime_type = NULL((void*)0);
13
Null pointer value stored to 'mime_type'
609
610 g_set_error (error,
611 EOC_IMAGE_ERROReoc_image_error_quark (),
612 EOC_IMAGE_ERROR_VFS,
613 "Error in getting image file info");
614 } else {
615 if (bytes)
616 *bytes = g_file_info_get_size (file_info);
617
618 if (mime_type)
619 *mime_type = g_strdup (g_file_info_get_content_type (file_info))g_strdup_inline (g_file_info_get_content_type (file_info));
620 g_object_unref (file_info);
621 }
622}
623
624#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
625void
626eoc_image_apply_display_profile (EocImage *img, cmsHPROFILE screen)
627{
628 EocImagePrivate *priv;
629 cmsHTRANSFORM transform;
630 gint row, width, rows, stride;
631 guchar *p;
632
633 g_return_if_fail (img != NULL)do { if ((img != ((void*)0))) { } else { g_return_if_fail_warning
("EOC", ((const char*) (__func__)), "img != NULL"); return; }
} while (0)
;
634
635 priv = img->priv;
636
637 if (screen == NULL((void*)0)) return;
638 if (!CDK_IS_X11_DISPLAY(cdk_display_get_default())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_display_get_default())); GType __t = ((cdk_x11_display_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; }))))
) {
639 return;
640 }
641
642 if (priv->profile == NULL((void*)0)) {
643 /* Check whether GdkPixbuf was able to extract a profile */
644 const char* data = gdk_pixbuf_get_option (priv->image,
645 "icc-profile");
646
647 if(data) {
648 gsize profile_size = 0;
649 guchar *profile_data = g_base64_decode(data,
650 &profile_size);
651
652 if (profile_data && profile_size > 0) {
653 eoc_debug_message (DEBUG_LCMSEOC_DEBUG_LCMS, "eoc-image.c", 653, ((const char*) (__func__)
)
,
654 "Using ICC profile "
655 "extracted by GdkPixbuf");
656 priv->profile =
657 cmsOpenProfileFromMem(profile_data,
658 profile_size);
659 g_free(profile_data);
660 }
661 }
662
663 if(priv->profile == NULL((void*)0)) {
664 /* Assume sRGB color space for images without ICC profile */
665 eoc_debug_message (DEBUG_LCMSEOC_DEBUG_LCMS, "eoc-image.c", 665, ((const char*) (__func__)
)
, "Image has no ICC profile. "
666 "Assuming sRGB.");
667 priv->profile = cmsCreate_sRGBProfile ();
668 }
669 }
670
671 /* TODO: support other colorspaces than RGB */
672 if (cmsGetColorSpace (priv->profile) != cmsSigRgbData ||
673 cmsGetColorSpace (screen) != cmsSigRgbData) {
674 eoc_debug_message (DEBUG_LCMSEOC_DEBUG_LCMS, "eoc-image.c", 674, ((const char*) (__func__)
)
, "One or both ICC profiles not in RGB colorspace; not correcting");
675 return;
676 }
677
678 cmsUInt32Number color_type = TYPE_RGB_8(((4) << 16)|((3) << 3)|(1));
679
680 if (gdk_pixbuf_get_has_alpha (priv->image))
681 color_type = TYPE_RGBA_8(((4) << 16)|((1) << 7)|((3) << 3)|(1));
682
683 transform = cmsCreateTransform (priv->profile,
684 color_type,
685 screen,
686 color_type,
687 INTENT_PERCEPTUAL0,
688 0);
689
690 if (G_LIKELY (transform != NULL)(transform != ((void*)0))) {
691 rows = gdk_pixbuf_get_height (priv->image);
692 width = gdk_pixbuf_get_width (priv->image);
693 stride = gdk_pixbuf_get_rowstride (priv->image);
694 p = gdk_pixbuf_get_pixels (priv->image);
695
696 for (row = 0; row < rows; ++row) {
697 cmsDoTransform (transform, p, p, width);
698 p += stride;
699 }
700 cmsDeleteTransform (transform);
701 }
702}
703
704static void
705eoc_image_set_icc_data (EocImage *img, EocMetadataReader *md_reader)
706{
707 EocImagePrivate *priv = img->priv;
708
709 priv->profile = eoc_metadata_reader_get_icc_profile (md_reader);
710
711
712}
713#endif
714
715static void
716eoc_image_set_orientation (EocImage *img)
717{
718 EocImagePrivate *priv;
719#ifdef HAVE_EXIF1
720 ExifData* exif;
721#endif
722
723 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
724
725 priv = img->priv;
726
727#ifdef HAVE_EXIF1
728 exif = (ExifData*) eoc_image_get_exif_info (img);
729
730 if (exif != NULL((void*)0)) {
731 ExifByteOrder o = exif_data_get_byte_order (exif);
732
733 ExifEntry *entry = exif_data_get_entry (exif,(exif_content_get_entry(exif->ifd[EXIF_IFD_0],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(exif->ifd[EXIF_IFD_0],EXIF_TAG_ORIENTATION
) : exif_content_get_entry(exif->ifd[EXIF_IFD_1],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(exif->ifd[EXIF_IFD_1],EXIF_TAG_ORIENTATION
) : exif_content_get_entry(exif->ifd[EXIF_IFD_EXIF],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(exif->ifd[EXIF_IFD_EXIF],EXIF_TAG_ORIENTATION
) : exif_content_get_entry(exif->ifd[EXIF_IFD_GPS],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(exif->ifd[EXIF_IFD_GPS],EXIF_TAG_ORIENTATION
) : exif_content_get_entry(exif->ifd[EXIF_IFD_INTEROPERABILITY
],EXIF_TAG_ORIENTATION) ? exif_content_get_entry(exif->ifd
[EXIF_IFD_INTEROPERABILITY],EXIF_TAG_ORIENTATION) : ((void*)0
))
734 EXIF_TAG_ORIENTATION)(exif_content_get_entry(exif->ifd[EXIF_IFD_0],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(exif->ifd[EXIF_IFD_0],EXIF_TAG_ORIENTATION
) : exif_content_get_entry(exif->ifd[EXIF_IFD_1],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(exif->ifd[EXIF_IFD_1],EXIF_TAG_ORIENTATION
) : exif_content_get_entry(exif->ifd[EXIF_IFD_EXIF],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(exif->ifd[EXIF_IFD_EXIF],EXIF_TAG_ORIENTATION
) : exif_content_get_entry(exif->ifd[EXIF_IFD_GPS],EXIF_TAG_ORIENTATION
) ? exif_content_get_entry(exif->ifd[EXIF_IFD_GPS],EXIF_TAG_ORIENTATION
) : exif_content_get_entry(exif->ifd[EXIF_IFD_INTEROPERABILITY
],EXIF_TAG_ORIENTATION) ? exif_content_get_entry(exif->ifd
[EXIF_IFD_INTEROPERABILITY],EXIF_TAG_ORIENTATION) : ((void*)0
))
;
735
736 if (entry && entry->data != NULL((void*)0)) {
737 priv->orientation = exif_get_short (entry->data, o);
738 }
739 exif_data_unref (exif);
740 } else
741#endif
742 {
743 GdkPixbuf *pbuf;
744
745 pbuf = eoc_image_get_pixbuf (img);
746
747 if (pbuf) {
748 const gchar *o_str;
749
750 o_str = gdk_pixbuf_get_option (pbuf, "orientation");
751 if (o_str) {
752 short t = (short) g_ascii_strtoll (o_str,
753 NULL((void*)0), 10);
754 if (t >= 0 && t < 9)
755 priv->orientation = t;
756 }
757 g_object_unref (pbuf);
758 }
759 }
760
761 if (priv->orientation > 4 &&
762 priv->orientation < 9) {
763 gint tmp;
764
765 tmp = priv->width;
766 priv->width = priv->height;
767 priv->height = tmp;
768 }
769}
770
771static void
772eoc_image_real_autorotate (EocImage *img)
773{
774 static const EocTransformType lookup[8] = {EOC_TRANSFORM_NONE,
775 EOC_TRANSFORM_FLIP_HORIZONTAL,
776 EOC_TRANSFORM_ROT_180,
777 EOC_TRANSFORM_FLIP_VERTICAL,
778 EOC_TRANSFORM_TRANSPOSE,
779 EOC_TRANSFORM_ROT_90,
780 EOC_TRANSFORM_TRANSVERSE,
781 EOC_TRANSFORM_ROT_270};
782 EocImagePrivate *priv;
783 EocTransformType type;
784
785 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
786
787 priv = img->priv;
788
789 type = (priv->orientation >= 1 && priv->orientation <= 8 ?
790 lookup[priv->orientation - 1] : EOC_TRANSFORM_NONE);
791
792 if (type != EOC_TRANSFORM_NONE) {
793 img->priv->trans_autorotate = eoc_transform_new (type);
794 }
795
796 /* Disable auto orientation for next loads */
797 priv->autorotate = FALSE(0);
798}
799
800void
801eoc_image_autorotate (EocImage *img)
802{
803 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
804
805 /* Schedule auto orientation */
806 img->priv->autorotate = TRUE(!(0));
807}
808
809#ifdef HAVE_EXEMPI1
810static void
811eoc_image_set_xmp_data (EocImage *img, EocMetadataReader *md_reader)
812{
813 EocImagePrivate *priv;
814
815 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
816
817 priv = img->priv;
818
819 if (priv->xmp) {
820 xmp_free (priv->xmp);
821 }
822 priv->xmp = eoc_metadata_reader_get_xmp_data (md_reader);
823}
824#endif
825
826static void
827eoc_image_set_exif_data (EocImage *img, EocMetadataReader *md_reader)
828{
829 EocImagePrivate *priv;
830
831 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
832
833 priv = img->priv;
834
835#ifdef HAVE_EXIF1
836 g_mutex_lock (&priv->status_mutex);
837 if (priv->exif) {
838 exif_data_unref (priv->exif);
839 }
840 priv->exif = eoc_metadata_reader_get_exif_data (md_reader);
841 g_mutex_unlock (&priv->status_mutex);
842
843 priv->exif_chunk = NULL((void*)0);
844 priv->exif_chunk_len = 0;
845
846 /* EXIF data is already available, set the image orientation */
847 if (priv->autorotate) {
848 eoc_image_set_orientation (img);
849
850 /* Emit size prepared signal if we have the size */
851 if (priv->width > 0 &&
852 priv->height > 0) {
853 eoc_image_emit_size_prepared (img);
854 }
855 }
856#else
857 if (priv->exif_chunk) {
858 g_free (priv->exif_chunk);
859 }
860 eoc_metadata_reader_get_exif_chunk (md_reader,
861 &priv->exif_chunk,
862 &priv->exif_chunk_len);
863#endif
864}
865
866/*
867 * Attempts to get the image dimensions from the thumbnail.
868 * Returns FALSE if this information is not found.
869 **/
870static gboolean
871eoc_image_get_dimension_from_thumbnail (EocImage *image,
872 gint *width,
873 gint *height)
874{
875 if (image->priv->thumbnail == NULL((void*)0))
876 return FALSE(0);
877
878 *width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (image->priv->thumbnail),((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((image->priv->thumbnail)), (((GType
) ((20) << (2)))))))), "eoc-thumbnail-orig-width")))
879 EOC_THUMBNAIL_ORIGINAL_WIDTH))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((image->priv->thumbnail)), (((GType
) ((20) << (2)))))))), "eoc-thumbnail-orig-width")))
;
880 *height = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (image->priv->thumbnail),((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((image->priv->thumbnail)), (((GType
) ((20) << (2)))))))), "eoc-thumbnail-orig-height")))
881 EOC_THUMBNAIL_ORIGINAL_HEIGHT))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((image->priv->thumbnail)), (((GType
) ((20) << (2)))))))), "eoc-thumbnail-orig-height")))
;
882
883 return (*width || *height);
884}
885
886static gboolean
887eoc_image_real_load (EocImage *img,
888 guint data2read,
889 EocJob *job,
890 GError **error)
891{
892 EocImagePrivate *priv;
893 GFileInputStream *input_stream;
894 EocMetadataReader *md_reader = NULL((void*)0);
895 GdkPixbufFormat *format;
896 gchar *mime_type;
897 GdkPixbufLoader *loader = NULL((void*)0);
898 guchar *buffer;
899 goffset bytes_read, bytes_read_total = 0;
900 gboolean failed = FALSE(0);
901 gboolean first_run = TRUE(!(0));
902 gboolean set_metadata = TRUE(!(0));
903 gboolean use_rsvg = FALSE(0);
904 gboolean read_image_data = (data2read & EOC_IMAGE_DATA_IMAGE);
905 gboolean read_only_dimension = (data2read & EOC_IMAGE_DATA_DIMENSION) &&
1
Assuming the condition is false
906 ((data2read ^ EOC_IMAGE_DATA_DIMENSION) == 0);
907
908
909 priv = img->priv;
910
911 g_assert (!read_image_data || priv->image == NULL)do { if (!read_image_data || priv->image == ((void*)0)) ; else
g_assertion_message_expr ("EOC", "eoc-image.c", 911, ((const
char*) (__func__)), "!read_image_data || priv->image == NULL"
); } while (0)
;
2
Assuming 'read_image_data' is not equal to 0
3
Assuming field 'image' is equal to null
4
Taking true branch
912
913 if (read_image_data
5.1
'read_image_data' is not equal to 0
&& priv->file_type != NULL((void*)0)) {
5
Loop condition is false. Exiting loop
6
Assuming field 'file_type' is equal to NULL
7
Taking false branch
914 g_free (priv->file_type);
915 priv->file_type = NULL((void*)0);
916 }
917
918 eoc_image_get_file_info (img, &priv->bytes, &mime_type, error);
8
Calling 'eoc_image_get_file_info'
14
Returning from 'eoc_image_get_file_info'
919
920 if (error && *error) {
15
Assuming 'error' is null
921 g_free (mime_type);
922 return FALSE(0);
923 }
924
925 if (read_only_dimension
15.1
'read_only_dimension' is 0
) {
16
Taking false branch
926 gint width, height;
927 gboolean done;
928
929 done = eoc_image_get_dimension_from_thumbnail (img,
930 &width,
931 &height);
932
933 if (done) {
934 priv->width = width;
935 priv->height = height;
936
937 g_free (mime_type);
938 return TRUE(!(0));
939 }
940 }
941
942 input_stream = g_file_read (priv->file, NULL((void*)0), error);
943
944 if (input_stream == NULL((void*)0)) {
17
Assuming 'input_stream' is not equal to NULL
18
Taking false branch
945 g_free (mime_type);
946
947 if (error != NULL((void*)0)) {
948 g_clear_error (error);
949 g_set_error (error,
950 EOC_IMAGE_ERROReoc_image_error_quark (),
951 EOC_IMAGE_ERROR_VFS,
952 "Failed to open input stream for file");
953 }
954 return FALSE(0);
955 }
956
957 buffer = g_new0 (guchar, EOC_IMAGE_READ_BUFFER_SIZE)((guchar *) g_malloc0_n ((65535), sizeof (guchar)));
958
959 if (read_image_data
18.1
'read_image_data' is not equal to 0
|| read_only_dimension) {
960#ifdef HAVE_RSVG1
961 if (priv->svg != NULL((void*)0)) {
19
Assuming field 'svg' is equal to NULL
962 g_object_unref (priv->svg);
963 priv->svg = NULL((void*)0);
964 }
965
966 if (!strcmp (mime_type, "image/svg+xml")
20
Null pointer passed to 1st parameter expecting 'nonnull'
967#if LIBRSVG_CHECK_FEATURE(SVGZ)(((!(0))))
968 || !strcmp (mime_type, "image/svg+xml-compressed")
969#endif
970 ) {
971 gchar *file_path;
972 /* Keep the object for rendering */
973 priv->svg = rsvg_handle_new ();
974 use_rsvg = (priv->svg != NULL((void*)0));
975 file_path = g_file_get_path (priv->file);
976 rsvg_handle_set_base_uri (priv->svg, file_path);
977 g_free (file_path);
978 }
979#endif
980
981 if (!use_rsvg) {
982 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error);
983
984 if (error && *error) {
985 g_error_free (*error);
986 *error = NULL((void*)0);
987
988 loader = gdk_pixbuf_loader_new ();
989 }
990
991 g_signal_connect_object (G_OBJECT (loader)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((loader)), (((GType) ((20) << (2))))))))
,
992 "size-prepared",
993 G_CALLBACK (eoc_image_size_prepared)((GCallback) (eoc_image_size_prepared)),
994 img,
995 0);
996 }
997 }
998 g_free (mime_type);
999
1000 while (!priv->cancel_loading) {
1001 /* FIXME: make this async */
1002 bytes_read = g_input_stream_read (G_INPUT_STREAM (input_stream)((((GInputStream*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((input_stream)), ((g_input_stream_get_type ()))))))
,
1003 buffer,
1004 EOC_IMAGE_READ_BUFFER_SIZE65535,
1005 NULL((void*)0), error);
1006
1007 if (bytes_read == 0) {
1008 /* End of the file */
1009 break;
1010 } else if (bytes_read == -1) {
1011 failed = TRUE(!(0));
1012
1013 g_set_error (error,
1014 EOC_IMAGE_ERROReoc_image_error_quark (),
1015 EOC_IMAGE_ERROR_VFS,
1016 "Failed to read from input stream");
1017
1018 break;
1019 }
1020
1021 if ((read_image_data || read_only_dimension)) {
1022#ifdef HAVE_RSVG1
1023 if (use_rsvg) {
1024 gboolean res;
1025
1026 res = rsvg_handle_write (priv->svg, buffer,
1027 bytes_read, error);
1028
1029 if (G_UNLIKELY (!res)(!res)) {
1030 failed = TRUE(!(0));
1031 break;
1032 }
1033 } else
1034#endif
1035 if (!gdk_pixbuf_loader_write (loader, buffer, bytes_read, error)) {
1036 failed = TRUE(!(0));
1037 break;
1038 }
1039 }
1040
1041 bytes_read_total += bytes_read;
1042
1043 if (job != NULL((void*)0)) {
1044 float progress = (float) bytes_read_total / (float) priv->bytes;
1045 eoc_job_set_progress (job, progress);
1046 }
1047
1048 if (first_run) {
1049 md_reader = check_for_metadata_img_format (img, buffer, bytes_read);
1050
1051 if (md_reader == NULL((void*)0)) {
1052 if (data2read == EOC_IMAGE_DATA_EXIF) {
1053 g_set_error (error,
1054 EOC_IMAGE_ERROReoc_image_error_quark (),
1055 EOC_IMAGE_ERROR_GENERIC,
1056 _("EXIF not supported for this file format.")gettext ("EXIF not supported for this file format."));
1057 break;
1058 }
1059
1060 priv->metadata_status = EOC_IMAGE_METADATA_NOT_AVAILABLE;
1061 }
1062
1063 first_run = FALSE(0);
1064 }
1065
1066 if (md_reader != NULL((void*)0)) {
1067 eoc_metadata_reader_consume (md_reader, buffer, bytes_read);
1068
1069 if (eoc_metadata_reader_finished (md_reader)) {
1070 if (set_metadata) {
1071 eoc_image_set_exif_data (img, md_reader);
1072
1073#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
1074 eoc_image_set_icc_data (img, md_reader);
1075#endif
1076
1077#ifdef HAVE_EXEMPI1
1078 eoc_image_set_xmp_data (img, md_reader);
1079#endif
1080 set_metadata = FALSE(0);
1081 priv->metadata_status = EOC_IMAGE_METADATA_READY;
1082 }
1083
1084 if (data2read == EOC_IMAGE_DATA_EXIF)
1085 break;
1086 }
1087 }
1088
1089 if (read_only_dimension &&
1090 eoc_image_has_data (img, EOC_IMAGE_DATA_DIMENSION)) {
1091 break;
1092 }
1093 }
1094
1095 if (read_image_data || read_only_dimension) {
1096#ifdef HAVE_RSVG1
1097 if (use_rsvg) {
1098 /* Ignore the error if loading failed earlier
1099 * as the error will already be set in that case */
1100 rsvg_handle_close (priv->svg,
1101 (failed ? NULL((void*)0) : error));
1102 } else
1103#endif
1104 if (failed) {
1105 gdk_pixbuf_loader_close (loader, NULL((void*)0));
1106 } else if (!gdk_pixbuf_loader_close (loader, error)) {
1107 if (gdk_pixbuf_loader_get_pixbuf (loader) != NULL((void*)0)) {
1108 /* Clear error in order to support partial
1109 * images as well. */
1110 g_clear_error (error);
1111 }
1112 }
1113 }
1114
1115 g_free (buffer);
1116
1117 g_object_unref (G_OBJECT (input_stream)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((input_stream)), (((GType) ((20) << (2))))))))
);
1118
1119 failed = (failed ||
1120 priv->cancel_loading ||
1121 bytes_read_total == 0 ||
1122 (error && *error != NULL((void*)0)));
1123
1124 if (failed) {
1125 if (priv->cancel_loading) {
1126 priv->cancel_loading = FALSE(0);
1127 priv->status = EOC_IMAGE_STATUS_UNKNOWN;
1128 } else {
1129 priv->status = EOC_IMAGE_STATUS_FAILED;
1130 }
1131 } else if (read_image_data) {
1132 if (priv->image != NULL((void*)0)) {
1133 g_object_unref (priv->image);
1134 }
1135
1136#ifdef HAVE_RSVG1
1137 if (use_rsvg) {
1138 priv->image = rsvg_handle_get_pixbuf (priv->svg);
1139 } else
1140#endif
1141
1142 {
1143
1144 priv->anim = gdk_pixbuf_loader_get_animation (loader);
1145
1146 if (gdk_pixbuf_animation_is_static_image (priv->anim)) {
1147 priv->image = gdk_pixbuf_animation_get_static_image (priv->anim);
1148 priv->anim = NULL((void*)0);
1149 } else {
1150 priv->anim_iter = gdk_pixbuf_animation_get_iter (priv->anim,NULL((void*)0));
1151 priv->image = gdk_pixbuf_animation_iter_get_pixbuf (priv->anim_iter);
1152 }
1153
1154 }
1155
1156 if (G_LIKELY (priv->image != NULL)(priv->image != ((void*)0))) {
1157 if (!use_rsvg)
1158 g_object_ref (priv->image)((__typeof__ (priv->image)) (g_object_ref) (priv->image
))
;
1159
1160 priv->width = gdk_pixbuf_get_width (priv->image);
1161 priv->height = gdk_pixbuf_get_height (priv->image);
1162
1163 if (use_rsvg) {
1164 format = NULL((void*)0);
1165 priv->file_type = g_strdup ("svg")g_strdup_inline ("svg");
1166 } else {
1167 format = gdk_pixbuf_loader_get_format (loader);
1168 }
1169
1170 if (format != NULL((void*)0)) {
1171 priv->file_type = gdk_pixbuf_format_get_name (format);
1172 }
1173
1174 priv->file_is_changed = FALSE(0);
1175
1176 /* Set orientation again for safety, eg. if we don't
1177 * have Exif data or HAVE_EXIF is undefined. */
1178 if (priv->autorotate) {
1179 eoc_image_set_orientation (img);
1180 eoc_image_emit_size_prepared (img);
1181 }
1182
1183 } else {
1184 /* Some loaders don't report errors correctly.
1185 * Error will be set below. */
1186 failed = TRUE(!(0));
1187 priv->status = EOC_IMAGE_STATUS_FAILED;
1188 }
1189 }
1190
1191 if (loader != NULL((void*)0)) {
1192 g_object_unref (loader);
1193 }
1194
1195 if (md_reader != NULL((void*)0)) {
1196 g_object_unref (md_reader);
1197 md_reader = NULL((void*)0);
1198 }
1199
1200 /* Catch-all in case of poor-error reporting */
1201 if (failed && error && *error == NULL((void*)0)) {
1202 g_set_error (error,
1203 EOC_IMAGE_ERROReoc_image_error_quark (),
1204 EOC_IMAGE_ERROR_GENERIC,
1205 _("Image loading failed.")gettext ("Image loading failed."));
1206 }
1207
1208 return !failed;
1209}
1210
1211gboolean
1212eoc_image_has_data (EocImage *img, EocImageData req_data)
1213{
1214 EocImagePrivate *priv;
1215 gboolean has_data = TRUE(!(0));
1216
1217 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
1218
1219 priv = img->priv;
1220
1221 if ((req_data & EOC_IMAGE_DATA_IMAGE) > 0) {
1222 req_data = (req_data & ~EOC_IMAGE_DATA_IMAGE);
1223 has_data = has_data && (priv->image != NULL((void*)0));
1224 }
1225
1226 if ((req_data & EOC_IMAGE_DATA_DIMENSION) > 0 ) {
1227 req_data = (req_data & ~EOC_IMAGE_DATA_DIMENSION);
1228 has_data = has_data && (priv->width >= 0) && (priv->height >= 0);
1229 }
1230
1231 if ((req_data & EOC_IMAGE_DATA_EXIF) > 0) {
1232 req_data = (req_data & ~EOC_IMAGE_DATA_EXIF);
1233#ifdef HAVE_EXIF1
1234 has_data = has_data && (priv->exif != NULL((void*)0));
1235#else
1236 has_data = has_data && (priv->exif_chunk != NULL((void*)0));
1237#endif
1238 }
1239
1240 if ((req_data & EOC_IMAGE_DATA_XMP) > 0) {
1241 req_data = (req_data & ~EOC_IMAGE_DATA_XMP);
1242#ifdef HAVE_EXEMPI1
1243 has_data = has_data && (priv->xmp != NULL((void*)0));
1244#endif
1245 }
1246
1247 if (req_data != 0) {
1248 g_warning ("Asking for unknown data, remaining: %i\n", req_data);
1249 has_data = FALSE(0);
1250 }
1251
1252 return has_data;
1253}
1254
1255gboolean
1256eoc_image_load (EocImage *img, EocImageData data2read, EocJob *job, GError **error)
1257{
1258 EocImagePrivate *priv;
1259 gboolean success = FALSE(0);
1260
1261 eoc_debug (DEBUG_IMAGE_LOADEOC_DEBUG_IMAGE_LOAD, "eoc-image.c", 1261, ((const char*) (__func__
))
);
1262
1263 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
1264
1265 priv = EOC_IMAGE (img)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((img)), ((eoc_image_get_type ()))))))
->priv;
1266
1267 if (data2read == 0) {
1268 return TRUE(!(0));
1269 }
1270
1271 if (eoc_image_has_data (img, data2read)) {
1272 return TRUE(!(0));
1273 }
1274
1275 priv->status = EOC_IMAGE_STATUS_LOADING;
1276
1277 success = eoc_image_real_load (img, data2read, job, error);
1278
1279 /* Check that the metadata was loaded at least once before
1280 * trying to autorotate. Also only an imatge load job should try to
1281 * autorotate and image */
1282 if (priv->autorotate &&
1283#ifdef HAVE_EXIF1
1284 priv->metadata_status != EOC_IMAGE_METADATA_NOT_READ &&
1285#endif
1286 data2read & EOC_IMAGE_DATA_IMAGE) {
1287 eoc_image_real_autorotate (img);
1288 }
1289
1290 if (success && eoc_image_needs_transformation (img)) {
1291 success = eoc_image_apply_transformations (img, error);
1292 }
1293
1294 if (success) {
1295 priv->status = EOC_IMAGE_STATUS_LOADED;
1296 } else {
1297 priv->status = EOC_IMAGE_STATUS_FAILED;
1298 }
1299
1300 return success;
1301}
1302
1303void
1304eoc_image_set_thumbnail (EocImage *img, GdkPixbuf *thumbnail)
1305{
1306 EocImagePrivate *priv;
1307
1308 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
1309 g_return_if_fail (GDK_IS_PIXBUF (thumbnail) || thumbnail == NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((thumbnail)); GType __t = ((gdk_pixbuf_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; })))) || thumbnail
== ((void*)0))) { } else { g_return_if_fail_warning ("EOC", (
(const char*) (__func__)), "GDK_IS_PIXBUF (thumbnail) || thumbnail == NULL"
); return; } } while (0)
;
1310
1311 priv = img->priv;
1312
1313 if (priv->thumbnail != NULL((void*)0)) {
1314 g_object_unref (priv->thumbnail);
1315 priv->thumbnail = NULL((void*)0);
1316 }
1317
1318 if (thumbnail != NULL((void*)0) && priv->trans != NULL((void*)0)) {
1319 priv->thumbnail = eoc_transform_apply (priv->trans, thumbnail, NULL((void*)0));
1320 } else {
1321 priv->thumbnail = thumbnail;
1322
1323 if (thumbnail != NULL((void*)0)) {
1324 g_object_ref (priv->thumbnail)((__typeof__ (priv->thumbnail)) (g_object_ref) (priv->thumbnail
))
;
1325 }
1326 }
1327
1328 if (priv->thumbnail != NULL((void*)0)) {
1329 g_signal_emit (img, signals[SIGNAL_THUMBNAIL_CHANGED], 0);
1330 }
1331}
1332
1333/**
1334 * eoc_image_get_pixbuf:
1335 * @img: a #EocImage
1336 *
1337 * Gets the #GdkPixbuf of the image
1338 *
1339 * Returns: (transfer full): a #GdkPixbuf
1340 **/
1341GdkPixbuf *
1342eoc_image_get_pixbuf (EocImage *img)
1343{
1344 GdkPixbuf *image = NULL((void*)0);
1345
1346 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
1347
1348 g_mutex_lock (&img->priv->status_mutex);
1349 image = img->priv->image;
1350 g_mutex_unlock (&img->priv->status_mutex);
1351
1352 if (image != NULL((void*)0)) {
1353 g_object_ref (image)((__typeof__ (image)) (g_object_ref) (image));
1354 }
1355
1356 return image;
1357}
1358
1359#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
1360cmsHPROFILE
1361eoc_image_get_profile (EocImage *img)
1362{
1363 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
1364
1365 return img->priv->profile;
1366}
1367#endif
1368
1369/**
1370 * eoc_image_get_thumbnail:
1371 * @img: a #EocImage
1372 *
1373 * Gets the thumbnail pixbuf for @img
1374 *
1375 * Returns: (transfer full): a #GdkPixbuf with a thumbnail
1376 **/
1377GdkPixbuf *
1378eoc_image_get_thumbnail (EocImage *img)
1379{
1380 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
1381
1382 if (img->priv->thumbnail != NULL((void*)0)) {
1383 return g_object_ref (img->priv->thumbnail)((__typeof__ (img->priv->thumbnail)) (g_object_ref) (img
->priv->thumbnail))
;
1384 }
1385
1386 return NULL((void*)0);
1387}
1388
1389void
1390eoc_image_get_size (EocImage *img, int *width, int *height)
1391{
1392 EocImagePrivate *priv;
1393
1394 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
1395
1396 priv = img->priv;
1397
1398 *width = priv->width;
1399 *height = priv->height;
1400}
1401
1402void
1403eoc_image_transform (EocImage *img, EocTransform *trans, EocJob *job)
1404{
1405 eoc_image_real_transform (img, trans, FALSE(0), job);
1406}
1407
1408void
1409eoc_image_undo (EocImage *img)
1410{
1411 EocImagePrivate *priv;
1412 EocTransform *trans;
1413 EocTransform *inverse;
1414
1415 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
1416
1417 priv = img->priv;
1418
1419 if (priv->undo_stack != NULL((void*)0)) {
1420 trans = EOC_TRANSFORM (priv->undo_stack->data)((((EocTransform*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->undo_stack->data)), ((eoc_transform_get_type
()))))))
;
1421
1422 inverse = eoc_transform_reverse (trans);
1423
1424 eoc_image_real_transform (img, inverse, TRUE(!(0)), NULL((void*)0));
1425
1426 priv->undo_stack = g_slist_delete_link (priv->undo_stack, priv->undo_stack);
1427
1428 g_object_unref (trans);
1429 g_object_unref (inverse);
1430
1431 if (eoc_transform_is_identity (priv->trans)) {
1432 g_object_unref (priv->trans);
1433 priv->trans = NULL((void*)0);
1434 }
1435 }
1436
1437 priv->modified = (priv->undo_stack != NULL((void*)0));
1438}
1439
1440static GFile *
1441tmp_file_get (void)
1442{
1443 GFile *tmp_file;
1444 char *tmp_file_path;
1445 gint fd;
1446
1447 tmp_file_path = g_build_filename (g_get_tmp_dir (), "eoc-save-XXXXXX", NULL((void*)0));
1448 fd = g_mkstemp (tmp_file_path);
1449 if (fd == -1) {
1450 g_free (tmp_file_path);
1451 return NULL((void*)0);
1452 }
1453 else {
1454 tmp_file = g_file_new_for_path (tmp_file_path);
1455 g_free (tmp_file_path);
1456 return tmp_file;
1457 }
1458}
1459
1460static void
1461transfer_progress_cb (goffset cur_bytes,
1462 goffset total_bytes,
1463 gpointer user_data)
1464{
1465 EocImage *image = EOC_IMAGE (user_data)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_image_get_type ()))))))
;
1466
1467 if (cur_bytes > 0) {
1468 g_signal_emit (G_OBJECT(image)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((image)), (((GType) ((20) << (2))))))))
,
1469 signals[SIGNAL_SAVE_PROGRESS],
1470 0,
1471 (gfloat) cur_bytes / (gfloat) total_bytes);
1472 }
1473}
1474
1475static void
1476tmp_file_restore_unix_attributes (GFile *temp_file,
1477 GFile *target_file)
1478{
1479 GFileInfo *file_info;
1480 guint uid;
1481 guint gid;
1482 guint mode;
1483 guint mode_mask = 00600;
1484
1485 GError *error = NULL((void*)0);
1486
1487 g_return_if_fail (G_IS_FILE (temp_file))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((temp_file)); GType __t = ((g_file_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__
)), "G_IS_FILE (temp_file)"); return; } } while (0)
;
1488 g_return_if_fail (G_IS_FILE (target_file))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((target_file)); GType __t = ((g_file_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__
)), "G_IS_FILE (target_file)"); return; } } while (0)
;
1489
1490 /* check if file exists */
1491 if (!g_file_query_exists (target_file, NULL((void*)0))) {
1492 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1492, ((const char*) (__func__
))
,
1493 "Target file doesn't exist. Setting default attributes.");
1494 return;
1495 }
1496
1497 /* retrieve UID, GID, and MODE of the original file info */
1498 file_info = g_file_query_info (target_file,
1499 "unix::uid,unix::gid,unix::mode",
1500 G_FILE_QUERY_INFO_NONE,
1501 NULL((void*)0),
1502 &error);
1503
1504 /* check that there aren't any error */
1505 if (error != NULL((void*)0)) {
1506 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1506, ((const char*) (__func__
))
,
1507 "File information not available. Setting default attributes.");
1508
1509 /* free objects */
1510 g_object_unref (file_info);
1511 g_clear_error (&error);
1512
1513 return;
1514 }
1515
1516 /* save UID, GID and MODE values */
1517 uid = g_file_info_get_attribute_uint32 (file_info,
1518 G_FILE_ATTRIBUTE_UNIX_UID"unix::uid");
1519
1520 gid = g_file_info_get_attribute_uint32 (file_info,
1521 G_FILE_ATTRIBUTE_UNIX_GID"unix::gid");
1522
1523 mode = g_file_info_get_attribute_uint32 (file_info,
1524 G_FILE_ATTRIBUTE_UNIX_MODE"unix::mode");
1525
1526 /* apply default mode mask to file mode */
1527 mode |= mode_mask;
1528
1529 /* restore original UID, GID, and MODE into the temporal file */
1530 g_file_set_attribute_uint32 (temp_file,
1531 G_FILE_ATTRIBUTE_UNIX_UID"unix::uid",
1532 uid,
1533 G_FILE_QUERY_INFO_NONE,
1534 NULL((void*)0),
1535 &error);
1536
1537 /* check that there aren't any error */
1538 if (error != NULL((void*)0)) {
1539 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1539, ((const char*) (__func__
))
,
1540 "You do not have the permissions necessary to change the file UID.");
1541
1542 g_clear_error (&error);
1543 }
1544
1545 g_file_set_attribute_uint32 (temp_file,
1546 G_FILE_ATTRIBUTE_UNIX_GID"unix::gid",
1547 gid,
1548 G_FILE_QUERY_INFO_NONE,
1549 NULL((void*)0),
1550 &error);
1551
1552 /* check that there aren't any error */
1553 if (error != NULL((void*)0)) {
1554 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1554, ((const char*) (__func__
))
,
1555 "You do not have the permissions necessary to change the file GID. Setting user default GID.");
1556
1557 g_clear_error (&error);
1558 }
1559
1560 g_file_set_attribute_uint32 (temp_file,
1561 G_FILE_ATTRIBUTE_UNIX_MODE"unix::mode",
1562 mode,
1563 G_FILE_QUERY_INFO_NONE,
1564 NULL((void*)0),
1565 &error);
1566
1567 /* check that there aren't any error */
1568 if (error != NULL((void*)0)) {
1569 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1569, ((const char*) (__func__
))
,
1570 "You do not have the permissions necessary to change the file MODE.");
1571
1572 g_clear_error (&error);
1573 }
1574
1575 /* free objects */
1576 g_object_unref (file_info);
1577}
1578
1579static gboolean
1580tmp_file_move_to_uri (EocImage *image,
1581 GFile *tmpfile,
1582 GFile *file,
1583 gboolean overwrite,
1584 GError **error)
1585{
1586 gboolean result;
1587 GError *ioerror = NULL((void*)0);
1588
1589 /* try to restore target file unix attributes */
1590 tmp_file_restore_unix_attributes (tmpfile, file);
1591
1592 /* replace target file with temporal file */
1593 result = g_file_move (tmpfile,
1594 file,
1595 (overwrite ? G_FILE_COPY_OVERWRITE : 0) |
1596 G_FILE_COPY_ALL_METADATA,
1597 NULL((void*)0),
1598 (GFileProgressCallback) transfer_progress_cb,
1599 image,
1600 &ioerror);
1601
1602 if (result == FALSE(0)) {
1603 if (g_error_matches (ioerror, G_IO_ERRORg_io_error_quark(),
1604 G_IO_ERROR_EXISTS)) {
1605 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1606 EOC_IMAGE_ERROR_FILE_EXISTS,
1607 "File exists");
1608 } else {
1609 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1610 EOC_IMAGE_ERROR_VFS,
1611 "VFS error moving the temp file");
1612 }
1613 g_clear_error (&ioerror);
1614 }
1615
1616 return result;
1617}
1618
1619static gboolean
1620tmp_file_delete (GFile *tmpfile)
1621{
1622 gboolean result;
1623 GError *err = NULL((void*)0);
1624
1625 if (tmpfile == NULL((void*)0)) return FALSE(0);
1626
1627 result = g_file_delete (tmpfile, NULL((void*)0), &err);
1628 if (result == FALSE(0)) {
1629 char *tmpfile_path;
1630 if (err != NULL((void*)0)) {
1631 if (err->code == G_IO_ERROR_NOT_FOUND) {
1632 g_error_free (err);
1633 return TRUE(!(0));
1634 }
1635 g_error_free (err);
1636 }
1637 tmpfile_path = g_file_get_path (tmpfile);
1638 g_warning ("Couldn't delete temporary file: %s", tmpfile_path);
1639 g_free (tmpfile_path);
1640 }
1641
1642 return result;
1643}
1644
1645static void
1646eoc_image_reset_modifications (EocImage *image)
1647{
1648 EocImagePrivate *priv;
1649
1650 g_return_if_fail (EOC_IS_IMAGE (image))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((image)); GType __t = ((eoc_image_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_IMAGE (image)"); return; } } while (0)
;
1651
1652 priv = image->priv;
1653
1654 g_slist_foreach (priv->undo_stack, (GFunc) g_object_unref, NULL((void*)0));
1655 g_slist_free (priv->undo_stack);
1656 priv->undo_stack = NULL((void*)0);
1657
1658 if (priv->trans != NULL((void*)0)) {
1659 g_object_unref (priv->trans);
1660 priv->trans = NULL((void*)0);
1661 }
1662
1663 if (priv->trans_autorotate != NULL((void*)0)) {
1664 g_object_unref (priv->trans_autorotate);
1665 priv->trans_autorotate = NULL((void*)0);
1666 }
1667
1668 priv->modified = FALSE(0);
1669}
1670
1671static void
1672eoc_image_link_with_target (EocImage *image, EocImageSaveInfo *target)
1673{
1674 EocImagePrivate *priv;
1675
1676 g_return_if_fail (EOC_IS_IMAGE (image))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((image)); GType __t = ((eoc_image_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_IMAGE (image)"); return; } } while (0)
;
1677 g_return_if_fail (EOC_IS_IMAGE_SAVE_INFO (target))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((target)); GType __t = ((eoc_image_save_info_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_IMAGE_SAVE_INFO (target)"); return
; } } while (0)
;
1678
1679 priv = image->priv;
1680
1681 /* update file location */
1682 if (priv->file != NULL((void*)0)) {
1683 g_object_unref (priv->file);
1684 }
1685 priv->file = g_object_ref (target->file)((__typeof__ (target->file)) (g_object_ref) (target->file
))
;
1686
1687 /* Clear caption and caption key, these will be
1688 * updated on next eoc_image_get_caption call.
1689 */
1690 if (priv->caption != NULL((void*)0)) {
1691 g_free (priv->caption);
1692 priv->caption = NULL((void*)0);
1693 }
1694 if (priv->collate_key != NULL((void*)0)) {
1695 g_free (priv->collate_key);
1696 priv->collate_key = NULL((void*)0);
1697 }
1698
1699 /* update file format */
1700 if (priv->file_type != NULL((void*)0)) {
1701 g_free (priv->file_type);
1702 }
1703 priv->file_type = g_strdup (target->format)g_strdup_inline (target->format);
1704}
1705
1706gboolean
1707eoc_image_save_by_info (EocImage *img, EocImageSaveInfo *source, GError **error)
1708{
1709 EocImagePrivate *priv;
1710 EocImageStatus prev_status;
1711 gboolean success = FALSE(0);
1712 GFile *tmp_file;
1713 char *tmp_file_path;
1714
1715 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
1716 g_return_val_if_fail (EOC_IS_IMAGE_SAVE_INFO (source), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((source)); GType __t = ((eoc_image_save_info_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_IMAGE_SAVE_INFO (source)"); return
((0)); } } while (0)
;
1717
1718 priv = img->priv;
1719
1720 prev_status = priv->status;
1721
1722 /* Image is now being saved */
1723 priv->status = EOC_IMAGE_STATUS_SAVING;
1724
1725 /* see if we need any saving at all */
1726 if (source->exists && !source->modified) {
1727 return TRUE(!(0));
1728 }
1729
1730 /* fail if there is no image to save */
1731 if (priv->image == NULL((void*)0)) {
1732 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1733 EOC_IMAGE_ERROR_NOT_LOADED,
1734 _("No image loaded.")gettext ("No image loaded."));
1735 return FALSE(0);
1736 }
1737
1738 /* generate temporary file */
1739 tmp_file = tmp_file_get ();
1740
1741 if (tmp_file == NULL((void*)0)) {
1742 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1743 EOC_IMAGE_ERROR_TMP_FILE_FAILED,
1744 _("Temporary file creation failed.")gettext ("Temporary file creation failed."));
1745 return FALSE(0);
1746 }
1747
1748 tmp_file_path = g_file_get_path (tmp_file);
1749
1750#ifdef HAVE_JPEG1
1751 /* determine kind of saving */
1752 if ((g_ascii_strcasecmp (source->format, EOC_FILE_FORMAT_JPEG"jpeg") == 0) &&
1753 source->exists && source->modified)
1754 {
1755 success = eoc_image_jpeg_save_file (img, tmp_file_path, source, NULL((void*)0), error);
1756 }
1757#endif
1758
1759 if (!success && (*error == NULL((void*)0))) {
1760 success = gdk_pixbuf_save (priv->image, tmp_file_path, source->format, error, NULL((void*)0));
1761 }
1762
1763 if (success) {
1764 /* try to move result file to target uri */
1765 success = tmp_file_move_to_uri (img, tmp_file, priv->file, TRUE(!(0)) /*overwrite*/, error);
1766 }
1767
1768 if (success) {
1769 eoc_image_reset_modifications (img);
1770 }
1771
1772 tmp_file_delete (tmp_file);
1773
1774 g_free (tmp_file_path);
1775 g_object_unref (tmp_file);
1776
1777 priv->status = prev_status;
1778
1779 return success;
1780}
1781
1782static gboolean
1783eoc_image_copy_file (EocImage *image, EocImageSaveInfo *source, EocImageSaveInfo *target, GError **error)
1784{
1785 gboolean result;
1786 GError *ioerror = NULL((void*)0);
1787
1788 g_return_val_if_fail (EOC_IS_IMAGE_SAVE_INFO (source), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((source)); GType __t = ((eoc_image_save_info_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_IMAGE_SAVE_INFO (source)"); return
((0)); } } while (0)
;
1789 g_return_val_if_fail (EOC_IS_IMAGE_SAVE_INFO (target), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((target)); GType __t = ((eoc_image_save_info_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_IMAGE_SAVE_INFO (target)"); return
((0)); } } while (0)
;
1790
1791 result = g_file_copy (source->file,
1792 target->file,
1793 (target->overwrite ? G_FILE_COPY_OVERWRITE : 0) |
1794 G_FILE_COPY_ALL_METADATA,
1795 NULL((void*)0),
1796 EOC_IS_IMAGE (image)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(image)); GType __t = ((eoc_image_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; }))))
? transfer_progress_cb :NULL((void*)0),
1797 image,
1798 &ioerror);
1799
1800 if (result == FALSE(0)) {
1801 if (ioerror->code == G_IO_ERROR_EXISTS) {
1802 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1803 EOC_IMAGE_ERROR_FILE_EXISTS,
1804 "%s", ioerror->message);
1805 } else {
1806 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1807 EOC_IMAGE_ERROR_VFS,
1808 "%s", ioerror->message);
1809 }
1810 g_error_free (ioerror);
1811 }
1812
1813 return result;
1814}
1815
1816gboolean
1817eoc_image_save_as_by_info (EocImage *img, EocImageSaveInfo *source, EocImageSaveInfo *target, GError **error)
1818{
1819 EocImagePrivate *priv;
1820 gboolean success = FALSE(0);
1821 char *tmp_file_path;
1822 GFile *tmp_file;
1823 gboolean direct_copy = FALSE(0);
1824
1825 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
1826 g_return_val_if_fail (EOC_IS_IMAGE_SAVE_INFO (source), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((source)); GType __t = ((eoc_image_save_info_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_IMAGE_SAVE_INFO (source)"); return
((0)); } } while (0)
;
1827 g_return_val_if_fail (EOC_IS_IMAGE_SAVE_INFO (target), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((target)); GType __t = ((eoc_image_save_info_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_IMAGE_SAVE_INFO (target)"); return
((0)); } } while (0)
;
1828
1829 priv = img->priv;
1830
1831 /* fail if there is no image to save */
1832 if (priv->image == NULL((void*)0)) {
1833 g_set_error (error,
1834 EOC_IMAGE_ERROReoc_image_error_quark (),
1835 EOC_IMAGE_ERROR_NOT_LOADED,
1836 _("No image loaded.")gettext ("No image loaded."));
1837
1838 return FALSE(0);
1839 }
1840
1841 /* generate temporary file name */
1842 tmp_file = tmp_file_get ();
1843
1844 if (tmp_file == NULL((void*)0)) {
1845 g_set_error (error,
1846 EOC_IMAGE_ERROReoc_image_error_quark (),
1847 EOC_IMAGE_ERROR_TMP_FILE_FAILED,
1848 _("Temporary file creation failed.")gettext ("Temporary file creation failed."));
1849
1850 return FALSE(0);
1851 }
1852 tmp_file_path = g_file_get_path (tmp_file);
1853
1854 /* determine kind of saving */
1855 if (g_ascii_strcasecmp (source->format, target->format) == 0 && !source->modified) {
1856 success = eoc_image_copy_file (img, source, target, error);
1857 direct_copy = success;
1858 }
1859
1860#ifdef HAVE_JPEG1
1861 else if ((g_ascii_strcasecmp (source->format, EOC_FILE_FORMAT_JPEG"jpeg") == 0 && source->exists) ||
1862 (g_ascii_strcasecmp (target->format, EOC_FILE_FORMAT_JPEG"jpeg") == 0))
1863 {
1864 success = eoc_image_jpeg_save_file (img, tmp_file_path, source, target, error);
1865 }
1866#endif
1867
1868 if (!success && (*error == NULL((void*)0))) {
1869 success = gdk_pixbuf_save (priv->image, tmp_file_path, target->format, error, NULL((void*)0));
1870 }
1871
1872 if (success && !direct_copy) { /* not required if we alredy copied the file directly */
1873 /* try to move result file to target uri */
1874 success = tmp_file_move_to_uri (img, tmp_file, target->file, target->overwrite, error);
1875 }
1876
1877 if (success) {
1878 /* update image information to new uri */
1879 eoc_image_reset_modifications (img);
1880 eoc_image_link_with_target (img, target);
1881 }
1882
1883 tmp_file_delete (tmp_file);
1884 g_object_unref (tmp_file);
1885 g_free (tmp_file_path);
1886
1887 priv->status = EOC_IMAGE_STATUS_UNKNOWN;
1888
1889 return success;
1890}
1891
1892
1893/*
1894 * This function is extracted from
1895 * File: baul/libbaul-private/baul-file.c
1896 * Revision: 1.309
1897 * Author: Darin Adler <darin@bentspoon.com>
1898 */
1899static gboolean
1900have_broken_filenames (void)
1901{
1902 static gboolean initialized = FALSE(0);
1903 static gboolean broken;
1904
1905 if (initialized) {
1906 return broken;
1907 }
1908
1909 broken = g_getenv ("G_BROKEN_FILENAMES") != NULL((void*)0);
1910
1911 initialized = TRUE(!(0));
1912
1913 return broken;
1914}
1915
1916/*
1917 * This function is inspired by
1918 * baul/libbaul-private/baul-file.c:baul_file_get_display_name_nocopy
1919 * Revision: 1.309
1920 * Author: Darin Adler <darin@bentspoon.com>
1921 */
1922const gchar*
1923eoc_image_get_caption (EocImage *img)
1924{
1925 EocImagePrivate *priv;
1926 char *name;
1927 char *utf8_name;
1928 char *scheme;
1929 gboolean validated = FALSE(0);
1930 gboolean broken_filenames;
1931
1932 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
1933
1934 priv = img->priv;
1935
1936 if (priv->file == NULL((void*)0)) return NULL((void*)0);
1937
1938 if (priv->caption != NULL((void*)0))
1939 /* Use cached caption string */
1940 return priv->caption;
1941
1942 name = g_file_get_basename (priv->file);
1943 scheme = g_file_get_uri_scheme (priv->file);
1944
1945 if (name != NULL((void*)0) && g_ascii_strcasecmp (scheme, "file") == 0) {
1946 /* Support the G_BROKEN_FILENAMES feature of
1947 * glib by using g_filename_to_utf8 to convert
1948 * local filenames to UTF-8. Also do the same
1949 * thing with any local filename that does not
1950 * validate as good UTF-8.
1951 */
1952 broken_filenames = have_broken_filenames ();
1953
1954 if (broken_filenames || !g_utf8_validate (name, -1, NULL((void*)0))) {
1955 utf8_name = g_locale_to_utf8 (name, -1, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1956 if (utf8_name != NULL((void*)0)) {
1957 g_free (name);
1958 name = utf8_name;
1959 /* Guaranteed to be correct utf8 here */
1960 validated = TRUE(!(0));
1961 }
1962 } else if (!broken_filenames) {
1963 /* name was valid, no need to re-validate */
1964 validated = TRUE(!(0));
1965 }
1966 }
1967
1968 if (!validated && !g_utf8_validate (name, -1, NULL((void*)0))) {
1969 if (name == NULL((void*)0)) {
1970 name = g_strdup ("[Invalid Unicode]")g_strdup_inline ("[Invalid Unicode]");
1971 } else {
1972 utf8_name = eoc_util_make_valid_utf8 (name);
1973 g_free (name);
1974 name = utf8_name;
1975 }
1976 }
1977
1978 priv->caption = name;
1979
1980 if (priv->caption == NULL((void*)0)) {
1981 char *short_str;
1982
1983 short_str = g_file_get_basename (priv->file);
1984 if (g_utf8_validate (short_str, -1, NULL((void*)0))) {
1985 priv->caption = g_strdup (short_str)g_strdup_inline (short_str);
1986 } else {
1987 priv->caption = g_filename_to_utf8 (short_str, -1, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1988 }
1989 g_free (short_str);
1990 }
1991 g_free (scheme);
1992
1993 return priv->caption;
1994}
1995
1996const gchar*
1997eoc_image_get_collate_key (EocImage *img)
1998{
1999 EocImagePrivate *priv;
2000
2001 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
2002
2003 priv = img->priv;
2004
2005 if (priv->collate_key == NULL((void*)0)) {
2006 const char *caption;
2007
2008 caption = eoc_image_get_caption (img);
2009
2010 priv->collate_key = g_utf8_collate_key_for_filename (caption, -1);
2011 }
2012
2013 return priv->collate_key;
2014}
2015
2016void
2017eoc_image_cancel_load (EocImage *img)
2018{
2019 EocImagePrivate *priv;
2020
2021 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
2022
2023 priv = img->priv;
2024
2025 g_mutex_lock (&priv->status_mutex);
2026
2027 if (priv->status == EOC_IMAGE_STATUS_LOADING) {
2028 priv->cancel_loading = TRUE(!(0));
2029 }
2030
2031 g_mutex_unlock (&priv->status_mutex);
2032}
2033
2034#ifdef HAVE_EXIF1
2035ExifData *
2036eoc_image_get_exif_info (EocImage *img)
2037{
2038 EocImagePrivate *priv;
2039 ExifData *data = NULL((void*)0);
2040
2041 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
2042
2043 priv = img->priv;
2044
2045 g_mutex_lock (&priv->status_mutex);
2046
2047 exif_data_ref (priv->exif);
2048 data = priv->exif;
2049
2050 g_mutex_unlock (&priv->status_mutex);
2051
2052 return data;
2053}
2054#endif
2055
2056/**
2057 * eoc_image_get_xmp_info:
2058 * @img: a #EocImage
2059 *
2060 * Gets the XMP info for @img or NULL if compiled without
2061 * libexempi support.
2062 *
2063 * Returns: (transfer full): the xmp data
2064 **/
2065gpointer
2066eoc_image_get_xmp_info (EocImage *img)
2067{
2068 gpointer data = NULL((void*)0);
2069
2070 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
2071
2072#ifdef HAVE_EXEMPI1
2073 EocImagePrivate *priv;
2074 priv = img->priv;
2075
2076 g_mutex_lock (&priv->status_mutex);
2077 data = (gpointer) xmp_copy (priv->xmp);
2078 g_mutex_unlock (&priv->status_mutex);
2079#endif
2080
2081 return data;
2082}
2083
2084
2085/**
2086 * eoc_image_get_file:
2087 * @img: a #EocImage
2088 *
2089 * Gets the #GFile associated with @img
2090 *
2091 * Returns: (transfer full): a #GFile
2092 **/
2093GFile *
2094eoc_image_get_file (EocImage *img)
2095{
2096 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
2097
2098 return g_object_ref (img->priv->file)((__typeof__ (img->priv->file)) (g_object_ref) (img->
priv->file))
;
2099}
2100
2101gboolean
2102eoc_image_is_modified (EocImage *img)
2103{
2104 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
2105
2106 return img->priv->modified;
2107}
2108
2109goffset
2110eoc_image_get_bytes (EocImage *img)
2111{
2112 g_return_val_if_fail (EOC_IS_IMAGE (img), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (0); } } while (0)
;
2113
2114 return img->priv->bytes;
2115}
2116
2117void
2118eoc_image_modified (EocImage *img)
2119{
2120 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
2121
2122 g_signal_emit (G_OBJECT (img)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((img)), (((GType) ((20) << (2))))))))
, signals[SIGNAL_CHANGED], 0);
2123}
2124
2125gchar*
2126eoc_image_get_uri_for_display (EocImage *img)
2127{
2128 EocImagePrivate *priv;
2129 gchar *uri_str = NULL((void*)0);
2130 gchar *str = NULL((void*)0);
2131
2132 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
2133
2134 priv = img->priv;
2135
2136 if (priv->file != NULL((void*)0)) {
2137 uri_str = g_file_get_uri (priv->file);
2138
2139 if (uri_str != NULL((void*)0)) {
2140 str = g_uri_unescape_string (uri_str, NULL((void*)0));
2141 g_free (uri_str);
2142 }
2143 }
2144
2145 return str;
2146}
2147
2148EocImageStatus
2149eoc_image_get_status (EocImage *img)
2150{
2151 g_return_val_if_fail (EOC_IS_IMAGE (img), EOC_IMAGE_STATUS_UNKNOWN)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (EOC_IMAGE_STATUS_UNKNOWN);
} } while (0)
;
2152
2153 return img->priv->status;
2154}
2155
2156/**
2157 * eoc_image_get_metadata_status:
2158 * @img: a #EocImage
2159 *
2160 * Returns the current status of the image metadata, that is,
2161 * whether the metadata has not been read yet, is ready, or not available at all.
2162 *
2163 * Returns: one of #EocImageMetadataStatus
2164 **/
2165EocImageMetadataStatus
2166eoc_image_get_metadata_status (EocImage *img)
2167{
2168 g_return_val_if_fail (EOC_IS_IMAGE (img), EOC_IMAGE_METADATA_NOT_AVAILABLE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (EOC_IMAGE_METADATA_NOT_AVAILABLE
); } } while (0)
;
2169
2170 return img->priv->metadata_status;
2171}
2172
2173void
2174eoc_image_data_ref (EocImage *img)
2175{
2176 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
2177
2178 g_object_ref (G_OBJECT (img))((__typeof__ (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((img)), (((GType) ((20) << (2))))))
)))) (g_object_ref) (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((img)), (((GType) ((20) << (2))))))
))))
;
2179 img->priv->data_ref_count++;
2180
2181 g_assert (img->priv->data_ref_count <= G_OBJECT (img)->ref_count)do { if (img->priv->data_ref_count <= ((((GObject*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((img)),
(((GType) ((20) << (2))))))))->ref_count) ; else g_assertion_message_expr
("EOC", "eoc-image.c", 2181, ((const char*) (__func__)), "img->priv->data_ref_count <= G_OBJECT (img)->ref_count"
); } while (0)
;
2182}
2183
2184void
2185eoc_image_data_unref (EocImage *img)
2186{
2187 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
2188
2189 if (img->priv->data_ref_count > 0) {
2190 img->priv->data_ref_count--;
2191 } else {
2192 g_warning ("More image data unrefs than refs.");
2193 }
2194
2195 if (img->priv->data_ref_count == 0) {
2196 eoc_image_free_mem_private (img);
2197 }
2198
2199 g_object_unref (G_OBJECT (img)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((img)), (((GType) ((20) << (2))))))))
);
2200
2201 g_assert (img->priv->data_ref_count <= G_OBJECT (img)->ref_count)do { if (img->priv->data_ref_count <= ((((GObject*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((img)),
(((GType) ((20) << (2))))))))->ref_count) ; else g_assertion_message_expr
("EOC", "eoc-image.c", 2201, ((const char*) (__func__)), "img->priv->data_ref_count <= G_OBJECT (img)->ref_count"
); } while (0)
;
2202}
2203
2204static gint
2205compare_quarks (gconstpointer a, gconstpointer b)
2206{
2207 GQuark quark;
2208
2209 quark = g_quark_from_string ((const gchar *) a);
2210
2211 return quark - GPOINTER_TO_INT (b)((gint) (glong) (b));
2212}
2213
2214/**
2215 * eoc_image_get_supported_mime_types:
2216 *
2217 * Gets the list of supported mimetypes
2218 *
2219 * Returns: (transfer none)(element-type utf8): a #GList of supported mimetypes
2220 **/
2221GList *
2222eoc_image_get_supported_mime_types (void)
2223{
2224 GSList *format_list, *it;
2225 gchar **mime_types;
2226 int i;
2227
2228 if (!supported_mime_types) {
2229 format_list = gdk_pixbuf_get_formats ();
2230
2231 for (it = format_list; it != NULL((void*)0); it = it->next) {
2232 mime_types =
2233 gdk_pixbuf_format_get_mime_types ((GdkPixbufFormat *) it->data);
2234
2235 for (i = 0; mime_types[i] != NULL((void*)0); i++) {
2236 supported_mime_types =
2237 g_list_prepend (supported_mime_types,
2238 g_strdup (mime_types[i])g_strdup_inline (mime_types[i]));
2239 }
2240
2241 g_strfreev (mime_types);
2242 }
2243
2244 supported_mime_types = g_list_sort (supported_mime_types,
2245 (GCompareFunc) compare_quarks);
2246
2247 g_slist_free (format_list);
2248 }
2249
2250 return supported_mime_types;
2251}
2252
2253gboolean
2254eoc_image_is_supported_mime_type (const char *mime_type)
2255{
2256 GList *supported_mime_types, *result;
2257 GQuark quark;
2258
2259 if (mime_type == NULL((void*)0)) {
2260 return FALSE(0);
2261 }
2262
2263 supported_mime_types = eoc_image_get_supported_mime_types ();
2264
2265 quark = g_quark_from_string (mime_type);
2266
2267 result = g_list_find_custom (supported_mime_types,
2268 GINT_TO_POINTER (quark)((gpointer) (glong) (quark)),
2269 (GCompareFunc) compare_quarks);
2270
2271 return (result != NULL((void*)0));
2272}
2273
2274static gboolean
2275eoc_image_iter_advance (EocImage *img)
2276{
2277 EocImagePrivate *priv;
2278 gboolean new_frame;
2279
2280 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
2281 g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (img->priv->anim_iter), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img->priv->anim_iter)); GType __t = ((gdk_pixbuf_animation_iter_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__)), "GDK_IS_PIXBUF_ANIMATION_ITER (img->priv->anim_iter)"
); return ((0)); } } while (0)
;
2282
2283 priv = img->priv;
2284
2285 if ((new_frame = gdk_pixbuf_animation_iter_advance (img->priv->anim_iter, NULL((void*)0))) == TRUE(!(0))) {
2286 g_mutex_lock (&priv->status_mutex);
2287 g_object_unref (priv->image);
2288 priv->image = gdk_pixbuf_animation_iter_get_pixbuf (priv->anim_iter);
2289 g_object_ref (priv->image)((__typeof__ (priv->image)) (g_object_ref) (priv->image
))
;
2290 /* keep the transformation over time */
2291 if (EOC_IS_TRANSFORM (priv->trans)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(priv->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; }
))))
) {
2292 GdkPixbuf* transformed = eoc_transform_apply (priv->trans, priv->image, NULL((void*)0));
2293 g_object_unref (priv->image);
2294 priv->image = transformed;
2295 priv->width = gdk_pixbuf_get_width (transformed);
2296 priv->height = gdk_pixbuf_get_height (transformed);
2297 }
2298 g_mutex_unlock (&priv->status_mutex);
2299 /* Emit next frame signal so we can update the display */
2300 g_signal_emit (img, signals[SIGNAL_NEXT_FRAME], 0,
2301 gdk_pixbuf_animation_iter_get_delay_time (priv->anim_iter));
2302 }
2303
2304 return new_frame;
2305}
2306
2307/**
2308 * eoc_image_is_animation:
2309 * @img: a #EocImage
2310 *
2311 * Checks whether a given image is animated.
2312 *
2313 * Returns: #TRUE if it is an animated image, #FALSE otherwise.
2314 *
2315 **/
2316gboolean
2317eoc_image_is_animation (EocImage *img)
2318{
2319 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
2320 return img->priv->anim != NULL((void*)0);
2321}
2322
2323static gboolean
2324private_timeout (gpointer data)
2325{
2326 EocImage *img = EOC_IMAGE (data)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((eoc_image_get_type ()))))))
;
2327 EocImagePrivate *priv = img->priv;
2328
2329 if (eoc_image_is_animation (img) &&
2330 !g_source_is_destroyed (g_main_current_source ()) &&
2331 priv->is_playing) {
2332 while (eoc_image_iter_advance (img) != TRUE(!(0))) {}; /* cpu-sucking ? */
2333 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (priv->anim_iter), private_timeout, img);
2334 return FALSE(0);
2335 }
2336 priv->is_playing = FALSE(0);
2337 return FALSE(0); /* stop playing */
2338}
2339
2340/**
2341 * eoc_image_start_animation:
2342 * @img: a #EocImage
2343 *
2344 * Starts playing an animated image.
2345 *
2346 * Returns: %TRUE on success, %FALSE if @img is already playing or isn't an animated image.
2347 **/
2348gboolean
2349eoc_image_start_animation (EocImage *img)
2350{
2351 EocImagePrivate *priv;
2352
2353 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
2354 priv = img->priv;
2355
2356 if (!eoc_image_is_animation (img) || priv->is_playing)
2357 return FALSE(0);
2358
2359 g_mutex_lock (&priv->status_mutex);
2360 g_object_ref (priv->anim_iter)((__typeof__ (priv->anim_iter)) (g_object_ref) (priv->anim_iter
))
;
2361 priv->is_playing = TRUE(!(0));
2362 g_mutex_unlock (&priv->status_mutex);
2363
2364 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (priv->anim_iter), private_timeout, img);
2365
2366 return TRUE(!(0));
2367}
2368
2369#ifdef HAVE_RSVG1
2370gboolean
2371eoc_image_is_svg (EocImage *img)
2372{
2373 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
2374
2375 return (img->priv->svg != NULL((void*)0));
2376}
2377
2378RsvgHandle *
2379eoc_image_get_svg (EocImage *img)
2380{
2381 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
2382
2383 return img->priv->svg;
2384}
2385
2386#endif
2387
2388/**
2389 * eoc_image_get_transform:
2390 * @img: a #EocImage
2391 *
2392 * Get @img transform.
2393 *
2394 * Returns: (transfer none): A #EocTransform.
2395 */
2396
2397EocTransform *
2398eoc_image_get_transform (EocImage *img)
2399{
2400 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
2401
2402 return img->priv->trans;
2403}
2404
2405/**
2406 * eoc_image_get_autorotate_transform:
2407 * @img: a #EocImage
2408 *
2409 * Get @img autorotate transform.
2410 *
2411 * Returns: (transfer none): A #EocTransform.
2412 */
2413
2414EocTransform*
2415eoc_image_get_autorotate_transform (EocImage *img)
2416{
2417 g_return_val_if_fail (EOC_IS_IMAGE (img), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return (((void*)0)); } } while (0)
;
2418
2419 return img->priv->trans_autorotate;
2420}
2421
2422/**
2423 * eoc_image_file_changed:
2424 * @img: a #EocImage
2425 *
2426 * Marks the image files contents as changed. Also, emits
2427 * EocImage::file-changed signal
2428 **/
2429void
2430eoc_image_file_changed (EocImage *img)
2431{
2432 g_return_if_fail (EOC_IS_IMAGE (img))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return; } } while (0)
;
2433
2434 img->priv->file_is_changed = TRUE(!(0));
2435 g_signal_emit (img, signals[SIGNAL_FILE_CHANGED], 0);
2436}
2437
2438gboolean
2439eoc_image_is_file_changed (EocImage *img)
2440{
2441 g_return_val_if_fail (EOC_IS_IMAGE (img), TRUE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((!(0))); } } while (0)
;
2442
2443 return img->priv->file_is_changed;
2444}
2445
2446gboolean
2447eoc_image_is_jpeg (EocImage *img)
2448{
2449 g_return_val_if_fail (EOC_IS_IMAGE (img), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((img)); GType __t = ((eoc_image_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_IMAGE (img)"); return ((0)); } } while (0)
;
2450
2451 return ((img->priv->file_type != NULL((void*)0)) && (g_ascii_strcasecmp (img->priv->file_type, EOC_FILE_FORMAT_JPEG"jpeg") == 0));
2452}
2453