Bug Summary

File:src/eoc-image.c
Warning:line 964, 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 -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-16/lib/clang/16 -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-1.0 -I /usr/include/gobject-introspection-1.0 -I /usr/include/exempi-2.0 -I /usr/include/librsvg-2.0 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/src -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-08-05-200213-32259-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 anicafed 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,
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, guchar *buffer, guint bytes_read)
505{
506 EocMetadataReader *md_reader = NULL((void*)0);
507
508 eoc_debug_message (DEBUG_IMAGE_DATAEOC_DEBUG_IMAGE_DATA, "eoc-image.c", 508, ((const char*) (__func__
))
, "Check image format for jpeg: %x%x - length: %i",
509 buffer[0], buffer[1], bytes_read);
510
511 if (bytes_read >= 2) {
512 /* SOI (start of image) marker for JPEGs is 0xFFD8 */
513 if ((buffer[0] == 0xFF) && (buffer[1] == 0xD8)) {
514 md_reader = eoc_metadata_reader_new (EOC_METADATA_JPEG);
515 }
516 if (bytes_read >= 8 &&
517 memcmp (buffer, "\x89PNG\x0D\x0A\x1a\x0A", 8) == 0) {
518 md_reader = eoc_metadata_reader_new (EOC_METADATA_PNG);
519 }
520 }
521
522 return md_reader;
523}
524
525static gboolean
526eoc_image_needs_transformation (EocImage *img)
527{
528 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)
;
529
530 return (img->priv->trans != NULL((void*)0) || img->priv->trans_autorotate != NULL((void*)0));
531}
532
533static gboolean
534eoc_image_apply_transformations (EocImage *img, GError **error)
535{
536 GdkPixbuf *transformed = NULL((void*)0);
537 EocTransform *composition = NULL((void*)0);
538 EocImagePrivate *priv;
539
540 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)
;
541
542 priv = img->priv;
543
544 if (priv->trans == NULL((void*)0) && priv->trans_autorotate == NULL((void*)0)) {
545 return TRUE(!(0));
546 }
547
548 if (priv->image == NULL((void*)0)) {
549 g_set_error (error,
550 EOC_IMAGE_ERROReoc_image_error_quark (),
551 EOC_IMAGE_ERROR_NOT_LOADED,
552 _("Transformation on unloaded image.")gettext ("Transformation on unloaded image."));
553
554 return FALSE(0);
555 }
556
557 if (priv->trans != NULL((void*)0) && priv->trans_autorotate != NULL((void*)0)) {
558 composition = eoc_transform_compose (priv->trans,
559 priv->trans_autorotate);
560 } else if (priv->trans != NULL((void*)0)) {
561 composition = g_object_ref (priv->trans)((__typeof__ (priv->trans)) (g_object_ref) (priv->trans
))
;
562 } else if (priv->trans_autorotate != NULL((void*)0)) {
563 composition = g_object_ref (priv->trans_autorotate)((__typeof__ (priv->trans_autorotate)) (g_object_ref) (priv
->trans_autorotate))
;
564 }
565
566 if (composition != NULL((void*)0)) {
567 transformed = eoc_transform_apply (composition, priv->image, NULL((void*)0));
568 }
569
570 g_object_unref (priv->image);
571 priv->image = transformed;
572
573 if (transformed != NULL((void*)0)) {
574 priv->width = gdk_pixbuf_get_width (priv->image);
575 priv->height = gdk_pixbuf_get_height (priv->image);
576 } else {
577 g_set_error (error,
578 EOC_IMAGE_ERROReoc_image_error_quark (),
579 EOC_IMAGE_ERROR_GENERIC,
580 _("Transformation failed.")gettext ("Transformation failed."));
581 }
582
583 g_object_unref (composition);
584
585 return (transformed != NULL((void*)0));
586}
587
588static void
589eoc_image_get_file_info (EocImage *img,
590 goffset *bytes,
591 gchar **mime_type,
592 GError **error)
593{
594 GFileInfo *file_info;
595
596 file_info = g_file_query_info (img->priv->file,
597 G_FILE_ATTRIBUTE_STANDARD_SIZE"standard::size" ","
598 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE"standard::content-type",
599 0, NULL((void*)0), error);
600
601 if (file_info == NULL((void*)0)) {
9
Assuming 'file_info' is equal to NULL
10
Taking true branch
602 if (bytes
10.1
'bytes' is non-null
)
11
Taking true branch
603 *bytes = 0;
604
605 if (mime_type
11.1
'mime_type' is non-null
)
12
Taking true branch
606 *mime_type = NULL((void*)0);
13
Null pointer value stored to 'mime_type'
607
608 g_set_error (error,
609 EOC_IMAGE_ERROReoc_image_error_quark (),
610 EOC_IMAGE_ERROR_VFS,
611 "Error in getting image file info");
612 } else {
613 if (bytes)
614 *bytes = g_file_info_get_size (file_info);
615
616 if (mime_type)
617 *mime_type = g_strdup (g_file_info_get_content_type (file_info))g_strdup_inline (g_file_info_get_content_type (file_info));
618 g_object_unref (file_info);
619 }
620}
621
622#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
623void
624eoc_image_apply_display_profile (EocImage *img, cmsHPROFILE screen)
625{
626 EocImagePrivate *priv;
627 cmsHTRANSFORM transform;
628 gint row, width, rows, stride;
629 guchar *p;
630
631 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)
;
632
633 priv = img->priv;
634
635 if (screen == NULL((void*)0)) return;
636 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; }))))
) {
637 return;
638 }
639
640 if (priv->profile == NULL((void*)0)) {
641 /* Check whether GdkPixbuf was able to extract a profile */
642 const char* data = gdk_pixbuf_get_option (priv->image,
643 "icc-profile");
644
645 if(data) {
646 gsize profile_size = 0;
647 guchar *profile_data = g_base64_decode(data,
648 &profile_size);
649
650 if (profile_data && profile_size > 0) {
651 eoc_debug_message (DEBUG_LCMSEOC_DEBUG_LCMS, "eoc-image.c", 651, ((const char*) (__func__)
)
,
652 "Using ICC profile "
653 "extracted by GdkPixbuf");
654 priv->profile =
655 cmsOpenProfileFromMem(profile_data,
656 profile_size);
657 g_free(profile_data);
658 }
659 }
660
661 if(priv->profile == NULL((void*)0)) {
662 /* Assume sRGB color space for images without ICC profile */
663 eoc_debug_message (DEBUG_LCMSEOC_DEBUG_LCMS, "eoc-image.c", 663, ((const char*) (__func__)
)
, "Image has no ICC profile. "
664 "Assuming sRGB.");
665 priv->profile = cmsCreate_sRGBProfile ();
666 }
667 }
668
669 /* TODO: support other colorspaces than RGB */
670 if (cmsGetColorSpace (priv->profile) != cmsSigRgbData ||
671 cmsGetColorSpace (screen) != cmsSigRgbData) {
672 eoc_debug_message (DEBUG_LCMSEOC_DEBUG_LCMS, "eoc-image.c", 672, ((const char*) (__func__)
)
, "One or both ICC profiles not in RGB colorspace; not correcting");
673 return;
674 }
675
676 cmsUInt32Number color_type = TYPE_RGB_8(((4) << 16)|((3) << 3)|(1));
677
678 if (gdk_pixbuf_get_has_alpha (priv->image))
679 color_type = TYPE_RGBA_8(((4) << 16)|((1) << 7)|((3) << 3)|(1));
680
681 transform = cmsCreateTransform (priv->profile,
682 color_type,
683 screen,
684 color_type,
685 INTENT_PERCEPTUAL0,
686 0);
687
688 if (G_LIKELY (transform != NULL)(transform != ((void*)0))) {
689 rows = gdk_pixbuf_get_height (priv->image);
690 width = gdk_pixbuf_get_width (priv->image);
691 stride = gdk_pixbuf_get_rowstride (priv->image);
692 p = gdk_pixbuf_get_pixels (priv->image);
693
694 for (row = 0; row < rows; ++row) {
695 cmsDoTransform (transform, p, p, width);
696 p += stride;
697 }
698 cmsDeleteTransform (transform);
699 }
700}
701
702static void
703eoc_image_set_icc_data (EocImage *img, EocMetadataReader *md_reader)
704{
705 EocImagePrivate *priv = img->priv;
706
707 priv->profile = eoc_metadata_reader_get_icc_profile (md_reader);
708
709
710}
711#endif
712
713static void
714eoc_image_set_orientation (EocImage *img)
715{
716 EocImagePrivate *priv;
717#ifdef HAVE_EXIF1
718 ExifData* exif;
719#endif
720
721 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)
;
722
723 priv = img->priv;
724
725#ifdef HAVE_EXIF1
726 exif = (ExifData*) eoc_image_get_exif_info (img);
727
728 if (exif != NULL((void*)0)) {
729 ExifByteOrder o = exif_data_get_byte_order (exif);
730
731 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
))
732 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
))
;
733
734 if (entry && entry->data != NULL((void*)0)) {
735 priv->orientation = exif_get_short (entry->data, o);
736 }
737 exif_data_unref (exif);
738 } else
739#endif
740 {
741 GdkPixbuf *pbuf;
742
743 pbuf = eoc_image_get_pixbuf (img);
744
745 if (pbuf) {
746 const gchar *o_str;
747
748 o_str = gdk_pixbuf_get_option (pbuf, "orientation");
749 if (o_str) {
750 short t = (short) g_ascii_strtoll (o_str,
751 NULL((void*)0), 10);
752 if (t >= 0 && t < 9)
753 priv->orientation = t;
754 }
755 g_object_unref (pbuf);
756 }
757 }
758
759 if (priv->orientation > 4 &&
760 priv->orientation < 9) {
761 gint tmp;
762
763 tmp = priv->width;
764 priv->width = priv->height;
765 priv->height = tmp;
766 }
767}
768
769static void
770eoc_image_real_autorotate (EocImage *img)
771{
772 static const EocTransformType lookup[8] = {EOC_TRANSFORM_NONE,
773 EOC_TRANSFORM_FLIP_HORIZONTAL,
774 EOC_TRANSFORM_ROT_180,
775 EOC_TRANSFORM_FLIP_VERTICAL,
776 EOC_TRANSFORM_TRANSPOSE,
777 EOC_TRANSFORM_ROT_90,
778 EOC_TRANSFORM_TRANSVERSE,
779 EOC_TRANSFORM_ROT_270};
780 EocImagePrivate *priv;
781 EocTransformType type;
782
783 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)
;
784
785 priv = img->priv;
786
787 type = (priv->orientation >= 1 && priv->orientation <= 8 ?
788 lookup[priv->orientation - 1] : EOC_TRANSFORM_NONE);
789
790 if (type != EOC_TRANSFORM_NONE) {
791 img->priv->trans_autorotate = eoc_transform_new (type);
792 }
793
794 /* Disable auto orientation for next loads */
795 priv->autorotate = FALSE(0);
796}
797
798void
799eoc_image_autorotate (EocImage *img)
800{
801 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)
;
802
803 /* Schedule auto orientation */
804 img->priv->autorotate = TRUE(!(0));
805}
806
807#ifdef HAVE_EXEMPI1
808static void
809eoc_image_set_xmp_data (EocImage *img, EocMetadataReader *md_reader)
810{
811 EocImagePrivate *priv;
812
813 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)
;
814
815 priv = img->priv;
816
817 if (priv->xmp) {
818 xmp_free (priv->xmp);
819 }
820 priv->xmp = eoc_metadata_reader_get_xmp_data (md_reader);
821}
822#endif
823
824static void
825eoc_image_set_exif_data (EocImage *img, EocMetadataReader *md_reader)
826{
827 EocImagePrivate *priv;
828
829 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)
;
830
831 priv = img->priv;
832
833#ifdef HAVE_EXIF1
834 g_mutex_lock (&priv->status_mutex);
835 if (priv->exif) {
836 exif_data_unref (priv->exif);
837 }
838 priv->exif = eoc_metadata_reader_get_exif_data (md_reader);
839 g_mutex_unlock (&priv->status_mutex);
840
841 priv->exif_chunk = NULL((void*)0);
842 priv->exif_chunk_len = 0;
843
844 /* EXIF data is already available, set the image orientation */
845 if (priv->autorotate) {
846 eoc_image_set_orientation (img);
847
848 /* Emit size prepared signal if we have the size */
849 if (priv->width > 0 &&
850 priv->height > 0) {
851 eoc_image_emit_size_prepared (img);
852 }
853 }
854#else
855 if (priv->exif_chunk) {
856 g_free (priv->exif_chunk);
857 }
858 eoc_metadata_reader_get_exif_chunk (md_reader,
859 &priv->exif_chunk,
860 &priv->exif_chunk_len);
861#endif
862}
863
864/*
865 * Attempts to get the image dimensions from the thumbnail.
866 * Returns FALSE if this information is not found.
867 **/
868static gboolean
869eoc_image_get_dimension_from_thumbnail (EocImage *image,
870 gint *width,
871 gint *height)
872{
873 if (image->priv->thumbnail == NULL((void*)0))
874 return FALSE(0);
875
876 *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")))
877 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")))
;
878 *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")))
879 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")))
;
880
881 return (*width || *height);
882}
883
884static gboolean
885eoc_image_real_load (EocImage *img,
886 guint data2read,
887 EocJob *job,
888 GError **error)
889{
890 EocImagePrivate *priv;
891 GFileInputStream *input_stream;
892 EocMetadataReader *md_reader = NULL((void*)0);
893 GdkPixbufFormat *format;
894 gchar *mime_type;
895 GdkPixbufLoader *loader = NULL((void*)0);
896 guchar *buffer;
897 goffset bytes_read, bytes_read_total = 0;
898 gboolean failed = FALSE(0);
899 gboolean first_run = TRUE(!(0));
900 gboolean set_metadata = TRUE(!(0));
901 gboolean use_rsvg = FALSE(0);
902 gboolean read_image_data = (data2read & EOC_IMAGE_DATA_IMAGE);
903 gboolean read_only_dimension = (data2read & EOC_IMAGE_DATA_DIMENSION) &&
1
Assuming the condition is false
904 ((data2read ^ EOC_IMAGE_DATA_DIMENSION) == 0);
905
906
907 priv = img->priv;
908
909 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", 909, ((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
910
911 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
912 g_free (priv->file_type);
913 priv->file_type = NULL((void*)0);
914 }
915
916 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'
917
918 if (error && *error) {
15
Assuming 'error' is null
919 g_free (mime_type);
920 return FALSE(0);
921 }
922
923 if (read_only_dimension
15.1
'read_only_dimension' is 0
) {
16
Taking false branch
924 gint width, height;
925 gboolean done;
926
927 done = eoc_image_get_dimension_from_thumbnail (img,
928 &width,
929 &height);
930
931 if (done) {
932 priv->width = width;
933 priv->height = height;
934
935 g_free (mime_type);
936 return TRUE(!(0));
937 }
938 }
939
940 input_stream = g_file_read (priv->file, NULL((void*)0), error);
941
942 if (input_stream == NULL((void*)0)) {
17
Assuming 'input_stream' is not equal to NULL
18
Taking false branch
943 g_free (mime_type);
944
945 if (error != NULL((void*)0)) {
946 g_clear_error (error);
947 g_set_error (error,
948 EOC_IMAGE_ERROReoc_image_error_quark (),
949 EOC_IMAGE_ERROR_VFS,
950 "Failed to open input stream for file");
951 }
952 return FALSE(0);
953 }
954
955 buffer = g_new0 (guchar, EOC_IMAGE_READ_BUFFER_SIZE)((guchar *) g_malloc0_n ((65535), sizeof (guchar)));
956
957 if (read_image_data
18.1
'read_image_data' is not equal to 0
|| read_only_dimension) {
958#ifdef HAVE_RSVG1
959 if (priv->svg != NULL((void*)0)) {
19
Assuming field 'svg' is equal to NULL
960 g_object_unref (priv->svg);
961 priv->svg = NULL((void*)0);
962 }
963
964 if (!strcmp (mime_type, "image/svg+xml")
20
Null pointer passed to 1st parameter expecting 'nonnull'
965#if LIBRSVG_CHECK_FEATURE(SVGZ)(defined(((!(0)))) && ((!(0))))
966 || !strcmp (mime_type, "image/svg+xml-compressed")
967#endif
968 ) {
969 gchar *file_path;
970 /* Keep the object for rendering */
971 priv->svg = rsvg_handle_new ();
972 use_rsvg = (priv->svg != NULL((void*)0));
973 file_path = g_file_get_path (priv->file);
974 rsvg_handle_set_base_uri (priv->svg, file_path);
975 g_free (file_path);
976 }
977#endif
978
979 if (!use_rsvg) {
980 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error);
981
982 if (error && *error) {
983 g_error_free (*error);
984 *error = NULL((void*)0);
985
986 loader = gdk_pixbuf_loader_new ();
987 }
988
989 g_signal_connect_object (G_OBJECT (loader)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((loader)), (((GType) ((20) << (2))))))))
,
990 "size-prepared",
991 G_CALLBACK (eoc_image_size_prepared)((GCallback) (eoc_image_size_prepared)),
992 img,
993 0);
994 }
995 }
996 g_free (mime_type);
997
998 while (!priv->cancel_loading) {
999 /* FIXME: make this async */
1000 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 ()))))))
,
1001 buffer,
1002 EOC_IMAGE_READ_BUFFER_SIZE65535,
1003 NULL((void*)0), error);
1004
1005 if (bytes_read == 0) {
1006 /* End of the file */
1007 break;
1008 } else if (bytes_read == -1) {
1009 failed = TRUE(!(0));
1010
1011 g_set_error (error,
1012 EOC_IMAGE_ERROReoc_image_error_quark (),
1013 EOC_IMAGE_ERROR_VFS,
1014 "Failed to read from input stream");
1015
1016 break;
1017 }
1018
1019 if ((read_image_data || read_only_dimension)) {
1020#ifdef HAVE_RSVG1
1021 if (use_rsvg) {
1022 gboolean res;
1023
1024 res = rsvg_handle_write (priv->svg, buffer,
1025 bytes_read, error);
1026
1027 if (G_UNLIKELY (!res)(!res)) {
1028 failed = TRUE(!(0));
1029 break;
1030 }
1031 } else
1032#endif
1033 if (!gdk_pixbuf_loader_write (loader, buffer, bytes_read, error)) {
1034 failed = TRUE(!(0));
1035 break;
1036 }
1037 }
1038
1039 bytes_read_total += bytes_read;
1040
1041 if (job != NULL((void*)0)) {
1042 float progress = (float) bytes_read_total / (float) priv->bytes;
1043 eoc_job_set_progress (job, progress);
1044 }
1045
1046 if (first_run) {
1047 md_reader = check_for_metadata_img_format (img, buffer, bytes_read);
1048
1049 if (md_reader == NULL((void*)0)) {
1050 if (data2read == EOC_IMAGE_DATA_EXIF) {
1051 g_set_error (error,
1052 EOC_IMAGE_ERROReoc_image_error_quark (),
1053 EOC_IMAGE_ERROR_GENERIC,
1054 _("EXIF not supported for this file format.")gettext ("EXIF not supported for this file format."));
1055 break;
1056 }
1057
1058 priv->metadata_status = EOC_IMAGE_METADATA_NOT_AVAILABLE;
1059 }
1060
1061 first_run = FALSE(0);
1062 }
1063
1064 if (md_reader != NULL((void*)0)) {
1065 eoc_metadata_reader_consume (md_reader, buffer, bytes_read);
1066
1067 if (eoc_metadata_reader_finished (md_reader)) {
1068 if (set_metadata) {
1069 eoc_image_set_exif_data (img, md_reader);
1070
1071#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
1072 eoc_image_set_icc_data (img, md_reader);
1073#endif
1074
1075#ifdef HAVE_EXEMPI1
1076 eoc_image_set_xmp_data (img, md_reader);
1077#endif
1078 set_metadata = FALSE(0);
1079 priv->metadata_status = EOC_IMAGE_METADATA_READY;
1080 }
1081
1082 if (data2read == EOC_IMAGE_DATA_EXIF)
1083 break;
1084 }
1085 }
1086
1087 if (read_only_dimension &&
1088 eoc_image_has_data (img, EOC_IMAGE_DATA_DIMENSION)) {
1089 break;
1090 }
1091 }
1092
1093 if (read_image_data || read_only_dimension) {
1094#ifdef HAVE_RSVG1
1095 if (use_rsvg) {
1096 /* Ignore the error if loading failed earlier
1097 * as the error will already be set in that case */
1098 rsvg_handle_close (priv->svg,
1099 (failed ? NULL((void*)0) : error));
1100 } else
1101#endif
1102 if (failed) {
1103 gdk_pixbuf_loader_close (loader, NULL((void*)0));
1104 } else if (!gdk_pixbuf_loader_close (loader, error)) {
1105 if (gdk_pixbuf_loader_get_pixbuf (loader) != NULL((void*)0)) {
1106 /* Clear error in order to support partial
1107 * images as well. */
1108 g_clear_error (error);
1109 }
1110 }
1111 }
1112
1113 g_free (buffer);
1114
1115 g_object_unref (G_OBJECT (input_stream)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((input_stream)), (((GType) ((20) << (2))))))))
);
1116
1117 failed = (failed ||
1118 priv->cancel_loading ||
1119 bytes_read_total == 0 ||
1120 (error && *error != NULL((void*)0)));
1121
1122 if (failed) {
1123 if (priv->cancel_loading) {
1124 priv->cancel_loading = FALSE(0);
1125 priv->status = EOC_IMAGE_STATUS_UNKNOWN;
1126 } else {
1127 priv->status = EOC_IMAGE_STATUS_FAILED;
1128 }
1129 } else if (read_image_data) {
1130 if (priv->image != NULL((void*)0)) {
1131 g_object_unref (priv->image);
1132 }
1133
1134#ifdef HAVE_RSVG1
1135 if (use_rsvg) {
1136 priv->image = rsvg_handle_get_pixbuf (priv->svg);
1137 } else
1138#endif
1139
1140 {
1141
1142 priv->anim = gdk_pixbuf_loader_get_animation (loader);
1143
1144 if (gdk_pixbuf_animation_is_static_image (priv->anim)) {
1145 priv->image = gdk_pixbuf_animation_get_static_image (priv->anim);
1146 priv->anim = NULL((void*)0);
1147 } else {
1148 priv->anim_iter = gdk_pixbuf_animation_get_iter (priv->anim,NULL((void*)0));
1149 priv->image = gdk_pixbuf_animation_iter_get_pixbuf (priv->anim_iter);
1150 }
1151
1152 }
1153
1154 if (G_LIKELY (priv->image != NULL)(priv->image != ((void*)0))) {
1155 if (!use_rsvg)
1156 g_object_ref (priv->image)((__typeof__ (priv->image)) (g_object_ref) (priv->image
))
;
1157
1158 priv->width = gdk_pixbuf_get_width (priv->image);
1159 priv->height = gdk_pixbuf_get_height (priv->image);
1160
1161 if (use_rsvg) {
1162 format = NULL((void*)0);
1163 priv->file_type = g_strdup ("svg")g_strdup_inline ("svg");
1164 } else {
1165 format = gdk_pixbuf_loader_get_format (loader);
1166 }
1167
1168 if (format != NULL((void*)0)) {
1169 priv->file_type = gdk_pixbuf_format_get_name (format);
1170 }
1171
1172 priv->file_is_changed = FALSE(0);
1173
1174 /* Set orientation again for safety, eg. if we don't
1175 * have Exif data or HAVE_EXIF is undefined. */
1176 if (priv->autorotate) {
1177 eoc_image_set_orientation (img);
1178 eoc_image_emit_size_prepared (img);
1179 }
1180
1181 } else {
1182 /* Some loaders don't report errors correctly.
1183 * Error will be set below. */
1184 failed = TRUE(!(0));
1185 priv->status = EOC_IMAGE_STATUS_FAILED;
1186 }
1187 }
1188
1189 if (loader != NULL((void*)0)) {
1190 g_object_unref (loader);
1191 }
1192
1193 if (md_reader != NULL((void*)0)) {
1194 g_object_unref (md_reader);
1195 md_reader = NULL((void*)0);
1196 }
1197
1198 /* Catch-all in case of poor-error reporting */
1199 if (failed && error && *error == NULL((void*)0)) {
1200 g_set_error (error,
1201 EOC_IMAGE_ERROReoc_image_error_quark (),
1202 EOC_IMAGE_ERROR_GENERIC,
1203 _("Image loading failed.")gettext ("Image loading failed."));
1204 }
1205
1206 return !failed;
1207}
1208
1209gboolean
1210eoc_image_has_data (EocImage *img, EocImageData req_data)
1211{
1212 EocImagePrivate *priv;
1213 gboolean has_data = TRUE(!(0));
1214
1215 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)
;
1216
1217 priv = img->priv;
1218
1219 if ((req_data & EOC_IMAGE_DATA_IMAGE) > 0) {
1220 req_data = (req_data & ~EOC_IMAGE_DATA_IMAGE);
1221 has_data = has_data && (priv->image != NULL((void*)0));
1222 }
1223
1224 if ((req_data & EOC_IMAGE_DATA_DIMENSION) > 0 ) {
1225 req_data = (req_data & ~EOC_IMAGE_DATA_DIMENSION);
1226 has_data = has_data && (priv->width >= 0) && (priv->height >= 0);
1227 }
1228
1229 if ((req_data & EOC_IMAGE_DATA_EXIF) > 0) {
1230 req_data = (req_data & ~EOC_IMAGE_DATA_EXIF);
1231#ifdef HAVE_EXIF1
1232 has_data = has_data && (priv->exif != NULL((void*)0));
1233#else
1234 has_data = has_data && (priv->exif_chunk != NULL((void*)0));
1235#endif
1236 }
1237
1238 if ((req_data & EOC_IMAGE_DATA_XMP) > 0) {
1239 req_data = (req_data & ~EOC_IMAGE_DATA_XMP);
1240#ifdef HAVE_EXEMPI1
1241 has_data = has_data && (priv->xmp != NULL((void*)0));
1242#endif
1243 }
1244
1245 if (req_data != 0) {
1246 g_warning ("Asking for unknown data, remaining: %i\n", req_data);
1247 has_data = FALSE(0);
1248 }
1249
1250 return has_data;
1251}
1252
1253gboolean
1254eoc_image_load (EocImage *img, EocImageData data2read, EocJob *job, GError **error)
1255{
1256 EocImagePrivate *priv;
1257 gboolean success = FALSE(0);
1258
1259 eoc_debug (DEBUG_IMAGE_LOADEOC_DEBUG_IMAGE_LOAD, "eoc-image.c", 1259, ((const char*) (__func__
))
);
1260
1261 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)
;
1262
1263 priv = EOC_IMAGE (img)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((img)), ((eoc_image_get_type ()))))))
->priv;
1264
1265 if (data2read == 0) {
1266 return TRUE(!(0));
1267 }
1268
1269 if (eoc_image_has_data (img, data2read)) {
1270 return TRUE(!(0));
1271 }
1272
1273 priv->status = EOC_IMAGE_STATUS_LOADING;
1274
1275 success = eoc_image_real_load (img, data2read, job, error);
1276
1277 /* Check that the metadata was loaded at least once before
1278 * trying to autorotate. Also only an imatge load job should try to
1279 * autorotate and image */
1280 if (priv->autorotate &&
1281#ifdef HAVE_EXIF1
1282 priv->metadata_status != EOC_IMAGE_METADATA_NOT_READ &&
1283#endif
1284 data2read & EOC_IMAGE_DATA_IMAGE) {
1285 eoc_image_real_autorotate (img);
1286 }
1287
1288 if (success && eoc_image_needs_transformation (img)) {
1289 success = eoc_image_apply_transformations (img, error);
1290 }
1291
1292 if (success) {
1293 priv->status = EOC_IMAGE_STATUS_LOADED;
1294 } else {
1295 priv->status = EOC_IMAGE_STATUS_FAILED;
1296 }
1297
1298 return success;
1299}
1300
1301void
1302eoc_image_set_thumbnail (EocImage *img, GdkPixbuf *thumbnail)
1303{
1304 EocImagePrivate *priv;
1305
1306 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)
;
1307 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)
;
1308
1309 priv = img->priv;
1310
1311 if (priv->thumbnail != NULL((void*)0)) {
1312 g_object_unref (priv->thumbnail);
1313 priv->thumbnail = NULL((void*)0);
1314 }
1315
1316 if (thumbnail != NULL((void*)0) && priv->trans != NULL((void*)0)) {
1317 priv->thumbnail = eoc_transform_apply (priv->trans, thumbnail, NULL((void*)0));
1318 } else {
1319 priv->thumbnail = thumbnail;
1320
1321 if (thumbnail != NULL((void*)0)) {
1322 g_object_ref (priv->thumbnail)((__typeof__ (priv->thumbnail)) (g_object_ref) (priv->thumbnail
))
;
1323 }
1324 }
1325
1326 if (priv->thumbnail != NULL((void*)0)) {
1327 g_signal_emit (img, signals[SIGNAL_THUMBNAIL_CHANGED], 0);
1328 }
1329}
1330
1331/**
1332 * eoc_image_get_pixbuf:
1333 * @img: a #EocImage
1334 *
1335 * Gets the #GdkPixbuf of the image
1336 *
1337 * Returns: (transfer full): a #GdkPixbuf
1338 **/
1339GdkPixbuf *
1340eoc_image_get_pixbuf (EocImage *img)
1341{
1342 GdkPixbuf *image = NULL((void*)0);
1343
1344 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)
;
1345
1346 g_mutex_lock (&img->priv->status_mutex);
1347 image = img->priv->image;
1348 g_mutex_unlock (&img->priv->status_mutex);
1349
1350 if (image != NULL((void*)0)) {
1351 g_object_ref (image)((__typeof__ (image)) (g_object_ref) (image));
1352 }
1353
1354 return image;
1355}
1356
1357#if defined(HAVE_LCMS1) && defined(CDK_WINDOWING_X11)
1358cmsHPROFILE
1359eoc_image_get_profile (EocImage *img)
1360{
1361 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)
;
1362
1363 return img->priv->profile;
1364}
1365#endif
1366
1367/**
1368 * eoc_image_get_thumbnail:
1369 * @img: a #EocImage
1370 *
1371 * Gets the thumbnail pixbuf for @img
1372 *
1373 * Returns: (transfer full): a #GdkPixbuf with a thumbnail
1374 **/
1375GdkPixbuf *
1376eoc_image_get_thumbnail (EocImage *img)
1377{
1378 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)
;
1379
1380 if (img->priv->thumbnail != NULL((void*)0)) {
1381 return g_object_ref (img->priv->thumbnail)((__typeof__ (img->priv->thumbnail)) (g_object_ref) (img
->priv->thumbnail))
;
1382 }
1383
1384 return NULL((void*)0);
1385}
1386
1387void
1388eoc_image_get_size (EocImage *img, int *width, int *height)
1389{
1390 EocImagePrivate *priv;
1391
1392 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)
;
1393
1394 priv = img->priv;
1395
1396 *width = priv->width;
1397 *height = priv->height;
1398}
1399
1400void
1401eoc_image_transform (EocImage *img, EocTransform *trans, EocJob *job)
1402{
1403 eoc_image_real_transform (img, trans, FALSE(0), job);
1404}
1405
1406void
1407eoc_image_undo (EocImage *img)
1408{
1409 EocImagePrivate *priv;
1410 EocTransform *trans;
1411 EocTransform *inverse;
1412
1413 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)
;
1414
1415 priv = img->priv;
1416
1417 if (priv->undo_stack != NULL((void*)0)) {
1418 trans = EOC_TRANSFORM (priv->undo_stack->data)((((EocTransform*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->undo_stack->data)), ((eoc_transform_get_type
()))))))
;
1419
1420 inverse = eoc_transform_reverse (trans);
1421
1422 eoc_image_real_transform (img, inverse, TRUE(!(0)), NULL((void*)0));
1423
1424 priv->undo_stack = g_slist_delete_link (priv->undo_stack, priv->undo_stack);
1425
1426 g_object_unref (trans);
1427 g_object_unref (inverse);
1428
1429 if (eoc_transform_is_identity (priv->trans)) {
1430 g_object_unref (priv->trans);
1431 priv->trans = NULL((void*)0);
1432 }
1433 }
1434
1435 priv->modified = (priv->undo_stack != NULL((void*)0));
1436}
1437
1438static GFile *
1439tmp_file_get (void)
1440{
1441 GFile *tmp_file;
1442 char *tmp_file_path;
1443 gint fd;
1444
1445 tmp_file_path = g_build_filename (g_get_tmp_dir (), "eoc-save-XXXXXX", NULL((void*)0));
1446 fd = g_mkstemp (tmp_file_path);
1447 if (fd == -1) {
1448 g_free (tmp_file_path);
1449 return NULL((void*)0);
1450 }
1451 else {
1452 tmp_file = g_file_new_for_path (tmp_file_path);
1453 g_free (tmp_file_path);
1454 return tmp_file;
1455 }
1456}
1457
1458static void
1459transfer_progress_cb (goffset cur_bytes,
1460 goffset total_bytes,
1461 gpointer user_data)
1462{
1463 EocImage *image = EOC_IMAGE (user_data)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_image_get_type ()))))))
;
1464
1465 if (cur_bytes > 0) {
1466 g_signal_emit (G_OBJECT(image)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((image)), (((GType) ((20) << (2))))))))
,
1467 signals[SIGNAL_SAVE_PROGRESS],
1468 0,
1469 (gfloat) cur_bytes / (gfloat) total_bytes);
1470 }
1471}
1472
1473static void
1474tmp_file_restore_unix_attributes (GFile *temp_file,
1475 GFile *target_file)
1476{
1477 GFileInfo *file_info;
1478 guint uid;
1479 guint gid;
1480 guint mode;
1481 guint mode_mask = 00600;
1482
1483 GError *error = NULL((void*)0);
1484
1485 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)
;
1486 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)
;
1487
1488 /* check if file exists */
1489 if (!g_file_query_exists (target_file, NULL((void*)0))) {
1490 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1490, ((const char*) (__func__
))
,
1491 "Target file doesn't exist. Setting default attributes.");
1492 return;
1493 }
1494
1495 /* retrieve UID, GID, and MODE of the original file info */
1496 file_info = g_file_query_info (target_file,
1497 "unix::uid,unix::gid,unix::mode",
1498 G_FILE_QUERY_INFO_NONE,
1499 NULL((void*)0),
1500 &error);
1501
1502 /* check that there aren't any error */
1503 if (error != NULL((void*)0)) {
1504 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1504, ((const char*) (__func__
))
,
1505 "File information not available. Setting default attributes.");
1506
1507 /* free objects */
1508 g_object_unref (file_info);
1509 g_clear_error (&error);
1510
1511 return;
1512 }
1513
1514 /* save UID, GID and MODE values */
1515 uid = g_file_info_get_attribute_uint32 (file_info,
1516 G_FILE_ATTRIBUTE_UNIX_UID"unix::uid");
1517
1518 gid = g_file_info_get_attribute_uint32 (file_info,
1519 G_FILE_ATTRIBUTE_UNIX_GID"unix::gid");
1520
1521 mode = g_file_info_get_attribute_uint32 (file_info,
1522 G_FILE_ATTRIBUTE_UNIX_MODE"unix::mode");
1523
1524 /* apply default mode mask to file mode */
1525 mode |= mode_mask;
1526
1527 /* restore original UID, GID, and MODE into the temporal file */
1528 g_file_set_attribute_uint32 (temp_file,
1529 G_FILE_ATTRIBUTE_UNIX_UID"unix::uid",
1530 uid,
1531 G_FILE_QUERY_INFO_NONE,
1532 NULL((void*)0),
1533 &error);
1534
1535 /* check that there aren't any error */
1536 if (error != NULL((void*)0)) {
1537 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1537, ((const char*) (__func__
))
,
1538 "You do not have the permissions necessary to change the file UID.");
1539
1540 g_clear_error (&error);
1541 }
1542
1543 g_file_set_attribute_uint32 (temp_file,
1544 G_FILE_ATTRIBUTE_UNIX_GID"unix::gid",
1545 gid,
1546 G_FILE_QUERY_INFO_NONE,
1547 NULL((void*)0),
1548 &error);
1549
1550 /* check that there aren't any error */
1551 if (error != NULL((void*)0)) {
1552 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1552, ((const char*) (__func__
))
,
1553 "You do not have the permissions necessary to change the file GID. Setting user default GID.");
1554
1555 g_clear_error (&error);
1556 }
1557
1558 g_file_set_attribute_uint32 (temp_file,
1559 G_FILE_ATTRIBUTE_UNIX_MODE"unix::mode",
1560 mode,
1561 G_FILE_QUERY_INFO_NONE,
1562 NULL((void*)0),
1563 &error);
1564
1565 /* check that there aren't any error */
1566 if (error != NULL((void*)0)) {
1567 eoc_debug_message (DEBUG_IMAGE_SAVEEOC_DEBUG_IMAGE_SAVE, "eoc-image.c", 1567, ((const char*) (__func__
))
,
1568 "You do not have the permissions necessary to change the file MODE.");
1569
1570 g_clear_error (&error);
1571 }
1572
1573 /* free objects */
1574 g_object_unref (file_info);
1575}
1576
1577static gboolean
1578tmp_file_move_to_uri (EocImage *image,
1579 GFile *tmpfile,
1580 GFile *file,
1581 gboolean overwrite,
1582 GError **error)
1583{
1584 gboolean result;
1585 GError *ioerror = NULL((void*)0);
1586
1587 /* try to restore target file unix attributes */
1588 tmp_file_restore_unix_attributes (tmpfile, file);
1589
1590 /* replace target file with temporal file */
1591 result = g_file_move (tmpfile,
1592 file,
1593 (overwrite ? G_FILE_COPY_OVERWRITE : 0) |
1594 G_FILE_COPY_ALL_METADATA,
1595 NULL((void*)0),
1596 (GFileProgressCallback) transfer_progress_cb,
1597 image,
1598 &ioerror);
1599
1600 if (result == FALSE(0)) {
1601 if (g_error_matches (ioerror, G_IO_ERRORg_io_error_quark(),
1602 G_IO_ERROR_EXISTS)) {
1603 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1604 EOC_IMAGE_ERROR_FILE_EXISTS,
1605 "File exists");
1606 } else {
1607 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1608 EOC_IMAGE_ERROR_VFS,
1609 "VFS error moving the temp file");
1610 }
1611 g_clear_error (&ioerror);
1612 }
1613
1614 return result;
1615}
1616
1617static gboolean
1618tmp_file_delete (GFile *tmpfile)
1619{
1620 gboolean result;
1621 GError *err = NULL((void*)0);
1622
1623 if (tmpfile == NULL((void*)0)) return FALSE(0);
1624
1625 result = g_file_delete (tmpfile, NULL((void*)0), &err);
1626 if (result == FALSE(0)) {
1627 char *tmpfile_path;
1628 if (err != NULL((void*)0)) {
1629 if (err->code == G_IO_ERROR_NOT_FOUND) {
1630 g_error_free (err);
1631 return TRUE(!(0));
1632 }
1633 g_error_free (err);
1634 }
1635 tmpfile_path = g_file_get_path (tmpfile);
1636 g_warning ("Couldn't delete temporary file: %s", tmpfile_path);
1637 g_free (tmpfile_path);
1638 }
1639
1640 return result;
1641}
1642
1643static void
1644eoc_image_reset_modifications (EocImage *image)
1645{
1646 EocImagePrivate *priv;
1647
1648 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)
;
1649
1650 priv = image->priv;
1651
1652 g_slist_foreach (priv->undo_stack, (GFunc) g_object_unref, NULL((void*)0));
1653 g_slist_free (priv->undo_stack);
1654 priv->undo_stack = NULL((void*)0);
1655
1656 if (priv->trans != NULL((void*)0)) {
1657 g_object_unref (priv->trans);
1658 priv->trans = NULL((void*)0);
1659 }
1660
1661 if (priv->trans_autorotate != NULL((void*)0)) {
1662 g_object_unref (priv->trans_autorotate);
1663 priv->trans_autorotate = NULL((void*)0);
1664 }
1665
1666 priv->modified = FALSE(0);
1667}
1668
1669static void
1670eoc_image_link_with_target (EocImage *image, EocImageSaveInfo *target)
1671{
1672 EocImagePrivate *priv;
1673
1674 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)
;
1675 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)
;
1676
1677 priv = image->priv;
1678
1679 /* update file location */
1680 if (priv->file != NULL((void*)0)) {
1681 g_object_unref (priv->file);
1682 }
1683 priv->file = g_object_ref (target->file)((__typeof__ (target->file)) (g_object_ref) (target->file
))
;
1684
1685 /* Clear caption and caption key, these will be
1686 * updated on next eoc_image_get_caption call.
1687 */
1688 if (priv->caption != NULL((void*)0)) {
1689 g_free (priv->caption);
1690 priv->caption = NULL((void*)0);
1691 }
1692 if (priv->collate_key != NULL((void*)0)) {
1693 g_free (priv->collate_key);
1694 priv->collate_key = NULL((void*)0);
1695 }
1696
1697 /* update file format */
1698 if (priv->file_type != NULL((void*)0)) {
1699 g_free (priv->file_type);
1700 }
1701 priv->file_type = g_strdup (target->format)g_strdup_inline (target->format);
1702}
1703
1704gboolean
1705eoc_image_save_by_info (EocImage *img, EocImageSaveInfo *source, GError **error)
1706{
1707 EocImagePrivate *priv;
1708 EocImageStatus prev_status;
1709 gboolean success = FALSE(0);
1710 GFile *tmp_file;
1711 char *tmp_file_path;
1712
1713 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)
;
1714 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)
;
1715
1716 priv = img->priv;
1717
1718 prev_status = priv->status;
1719
1720 /* Image is now being saved */
1721 priv->status = EOC_IMAGE_STATUS_SAVING;
1722
1723 /* see if we need any saving at all */
1724 if (source->exists && !source->modified) {
1725 return TRUE(!(0));
1726 }
1727
1728 /* fail if there is no image to save */
1729 if (priv->image == NULL((void*)0)) {
1730 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1731 EOC_IMAGE_ERROR_NOT_LOADED,
1732 _("No image loaded.")gettext ("No image loaded."));
1733 return FALSE(0);
1734 }
1735
1736 /* generate temporary file */
1737 tmp_file = tmp_file_get ();
1738
1739 if (tmp_file == NULL((void*)0)) {
1740 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1741 EOC_IMAGE_ERROR_TMP_FILE_FAILED,
1742 _("Temporary file creation failed.")gettext ("Temporary file creation failed."));
1743 return FALSE(0);
1744 }
1745
1746 tmp_file_path = g_file_get_path (tmp_file);
1747
1748#ifdef HAVE_JPEG1
1749 /* determine kind of saving */
1750 if ((g_ascii_strcasecmp (source->format, EOC_FILE_FORMAT_JPEG"jpeg") == 0) &&
1751 source->exists && source->modified)
1752 {
1753 success = eoc_image_jpeg_save_file (img, tmp_file_path, source, NULL((void*)0), error);
1754 }
1755#endif
1756
1757 if (!success && (*error == NULL((void*)0))) {
1758 success = gdk_pixbuf_save (priv->image, tmp_file_path, source->format, error, NULL((void*)0));
1759 }
1760
1761 if (success) {
1762 /* try to move result file to target uri */
1763 success = tmp_file_move_to_uri (img, tmp_file, priv->file, TRUE(!(0)) /*overwrite*/, error);
1764 }
1765
1766 if (success) {
1767 eoc_image_reset_modifications (img);
1768 }
1769
1770 tmp_file_delete (tmp_file);
1771
1772 g_free (tmp_file_path);
1773 g_object_unref (tmp_file);
1774
1775 priv->status = prev_status;
1776
1777 return success;
1778}
1779
1780static gboolean
1781eoc_image_copy_file (EocImage *image, EocImageSaveInfo *source, EocImageSaveInfo *target, GError **error)
1782{
1783 gboolean result;
1784 GError *ioerror = NULL((void*)0);
1785
1786 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)
;
1787 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)
;
1788
1789 result = g_file_copy (source->file,
1790 target->file,
1791 (target->overwrite ? G_FILE_COPY_OVERWRITE : 0) |
1792 G_FILE_COPY_ALL_METADATA,
1793 NULL((void*)0),
1794 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),
1795 image,
1796 &ioerror);
1797
1798 if (result == FALSE(0)) {
1799 if (ioerror->code == G_IO_ERROR_EXISTS) {
1800 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1801 EOC_IMAGE_ERROR_FILE_EXISTS,
1802 "%s", ioerror->message);
1803 } else {
1804 g_set_error (error, EOC_IMAGE_ERROReoc_image_error_quark (),
1805 EOC_IMAGE_ERROR_VFS,
1806 "%s", ioerror->message);
1807 }
1808 g_error_free (ioerror);
1809 }
1810
1811 return result;
1812}
1813
1814gboolean
1815eoc_image_save_as_by_info (EocImage *img, EocImageSaveInfo *source, EocImageSaveInfo *target, GError **error)
1816{
1817 EocImagePrivate *priv;
1818 gboolean success = FALSE(0);
1819 char *tmp_file_path;
1820 GFile *tmp_file;
1821 gboolean direct_copy = FALSE(0);
1822
1823 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)
;
1824 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)
;
1825 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)
;
1826
1827 priv = img->priv;
1828
1829 /* fail if there is no image to save */
1830 if (priv->image == NULL((void*)0)) {
1831 g_set_error (error,
1832 EOC_IMAGE_ERROReoc_image_error_quark (),
1833 EOC_IMAGE_ERROR_NOT_LOADED,
1834 _("No image loaded.")gettext ("No image loaded."));
1835
1836 return FALSE(0);
1837 }
1838
1839 /* generate temporary file name */
1840 tmp_file = tmp_file_get ();
1841
1842 if (tmp_file == NULL((void*)0)) {
1843 g_set_error (error,
1844 EOC_IMAGE_ERROReoc_image_error_quark (),
1845 EOC_IMAGE_ERROR_TMP_FILE_FAILED,
1846 _("Temporary file creation failed.")gettext ("Temporary file creation failed."));
1847
1848 return FALSE(0);
1849 }
1850 tmp_file_path = g_file_get_path (tmp_file);
1851
1852 /* determine kind of saving */
1853 if (g_ascii_strcasecmp (source->format, target->format) == 0 && !source->modified) {
1854 success = eoc_image_copy_file (img, source, target, error);
1855 direct_copy = success;
1856 }
1857
1858#ifdef HAVE_JPEG1
1859 else if ((g_ascii_strcasecmp (source->format, EOC_FILE_FORMAT_JPEG"jpeg") == 0 && source->exists) ||
1860 (g_ascii_strcasecmp (target->format, EOC_FILE_FORMAT_JPEG"jpeg") == 0))
1861 {
1862 success = eoc_image_jpeg_save_file (img, tmp_file_path, source, target, error);
1863 }
1864#endif
1865
1866 if (!success && (*error == NULL((void*)0))) {
1867 success = gdk_pixbuf_save (priv->image, tmp_file_path, target->format, error, NULL((void*)0));
1868 }
1869
1870 if (success && !direct_copy) { /* not required if we alredy copied the file directly */
1871 /* try to move result file to target uri */
1872 success = tmp_file_move_to_uri (img, tmp_file, target->file, target->overwrite, error);
1873 }
1874
1875 if (success) {
1876 /* update image information to new uri */
1877 eoc_image_reset_modifications (img);
1878 eoc_image_link_with_target (img, target);
1879 }
1880
1881 tmp_file_delete (tmp_file);
1882 g_object_unref (tmp_file);
1883 g_free (tmp_file_path);
1884
1885 priv->status = EOC_IMAGE_STATUS_UNKNOWN;
1886
1887 return success;
1888}
1889
1890
1891/*
1892 * This function is extracted from
1893 * File: baul/libbaul-private/baul-file.c
1894 * Revision: 1.309
1895 * Author: Darin Adler <darin@bentspoon.com>
1896 */
1897static gboolean
1898have_broken_filenames (void)
1899{
1900 static gboolean initialized = FALSE(0);
1901 static gboolean broken;
1902
1903 if (initialized) {
1904 return broken;
1905 }
1906
1907 broken = g_getenv ("G_BROKEN_FILENAMES") != NULL((void*)0);
1908
1909 initialized = TRUE(!(0));
1910
1911 return broken;
1912}
1913
1914/*
1915 * This function is inspired by
1916 * baul/libbaul-private/baul-file.c:baul_file_get_display_name_nocopy
1917 * Revision: 1.309
1918 * Author: Darin Adler <darin@bentspoon.com>
1919 */
1920const gchar*
1921eoc_image_get_caption (EocImage *img)
1922{
1923 EocImagePrivate *priv;
1924 char *name;
1925 char *utf8_name;
1926 char *scheme;
1927 gboolean validated = FALSE(0);
1928 gboolean broken_filenames;
1929
1930 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)
;
1931
1932 priv = img->priv;
1933
1934 if (priv->file == NULL((void*)0)) return NULL((void*)0);
1935
1936 if (priv->caption != NULL((void*)0))
1937 /* Use cached caption string */
1938 return priv->caption;
1939
1940 name = g_file_get_basename (priv->file);
1941 scheme = g_file_get_uri_scheme (priv->file);
1942
1943 if (name != NULL((void*)0) && g_ascii_strcasecmp (scheme, "file") == 0) {
1944 /* Support the G_BROKEN_FILENAMES feature of
1945 * glib by using g_filename_to_utf8 to convert
1946 * local filenames to UTF-8. Also do the same
1947 * thing with any local filename that does not
1948 * validate as good UTF-8.
1949 */
1950 broken_filenames = have_broken_filenames ();
1951
1952 if (broken_filenames || !g_utf8_validate (name, -1, NULL((void*)0))) {
1953 utf8_name = g_locale_to_utf8 (name, -1, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1954 if (utf8_name != NULL((void*)0)) {
1955 g_free (name);
1956 name = utf8_name;
1957 /* Guaranteed to be correct utf8 here */
1958 validated = TRUE(!(0));
1959 }
1960 } else if (!broken_filenames) {
1961 /* name was valid, no need to re-validate */
1962 validated = TRUE(!(0));
1963 }
1964 }
1965
1966 if (!validated && !g_utf8_validate (name, -1, NULL((void*)0))) {
1967 if (name == NULL((void*)0)) {
1968 name = g_strdup ("[Invalid Unicode]")g_strdup_inline ("[Invalid Unicode]");
1969 } else {
1970 utf8_name = eoc_util_make_valid_utf8 (name);
1971 g_free (name);
1972 name = utf8_name;
1973 }
1974 }
1975
1976 priv->caption = name;
1977
1978 if (priv->caption == NULL((void*)0)) {
1979 char *short_str;
1980
1981 short_str = g_file_get_basename (priv->file);
1982 if (g_utf8_validate (short_str, -1, NULL((void*)0))) {
1983 priv->caption = g_strdup (short_str)g_strdup_inline (short_str);
1984 } else {
1985 priv->caption = g_filename_to_utf8 (short_str, -1, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1986 }
1987 g_free (short_str);
1988 }
1989 g_free (scheme);
1990
1991 return priv->caption;
1992}
1993
1994const gchar*
1995eoc_image_get_collate_key (EocImage *img)
1996{
1997 EocImagePrivate *priv;
1998
1999 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)
;
2000
2001 priv = img->priv;
2002
2003 if (priv->collate_key == NULL((void*)0)) {
2004 const char *caption;
2005
2006 caption = eoc_image_get_caption (img);
2007
2008 priv->collate_key = g_utf8_collate_key_for_filename (caption, -1);
2009 }
2010
2011 return priv->collate_key;
2012}
2013
2014void
2015eoc_image_cancel_load (EocImage *img)
2016{
2017 EocImagePrivate *priv;
2018
2019 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)
;
2020
2021 priv = img->priv;
2022
2023 g_mutex_lock (&priv->status_mutex);
2024
2025 if (priv->status == EOC_IMAGE_STATUS_LOADING) {
2026 priv->cancel_loading = TRUE(!(0));
2027 }
2028
2029 g_mutex_unlock (&priv->status_mutex);
2030}
2031
2032#ifdef HAVE_EXIF1
2033ExifData *
2034eoc_image_get_exif_info (EocImage *img)
2035{
2036 EocImagePrivate *priv;
2037 ExifData *data = NULL((void*)0);
2038
2039 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)
;
2040
2041 priv = img->priv;
2042
2043 g_mutex_lock (&priv->status_mutex);
2044
2045 exif_data_ref (priv->exif);
2046 data = priv->exif;
2047
2048 g_mutex_unlock (&priv->status_mutex);
2049
2050 return data;
2051}
2052#endif
2053
2054/**
2055 * eoc_image_get_xmp_info:
2056 * @img: a #EocImage
2057 *
2058 * Gets the XMP info for @img or NULL if compiled without
2059 * libexempi support.
2060 *
2061 * Returns: (transfer full): the xmp data
2062 **/
2063gpointer
2064eoc_image_get_xmp_info (EocImage *img)
2065{
2066 gpointer data = NULL((void*)0);
2067
2068 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)
;
2069
2070#ifdef HAVE_EXEMPI1
2071 EocImagePrivate *priv;
2072 priv = img->priv;
2073
2074 g_mutex_lock (&priv->status_mutex);
2075 data = (gpointer) xmp_copy (priv->xmp);
2076 g_mutex_unlock (&priv->status_mutex);
2077#endif
2078
2079 return data;
2080}
2081
2082
2083/**
2084 * eoc_image_get_file:
2085 * @img: a #EocImage
2086 *
2087 * Gets the #GFile associated with @img
2088 *
2089 * Returns: (transfer full): a #GFile
2090 **/
2091GFile *
2092eoc_image_get_file (EocImage *img)
2093{
2094 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)
;
2095
2096 return g_object_ref (img->priv->file)((__typeof__ (img->priv->file)) (g_object_ref) (img->
priv->file))
;
2097}
2098
2099gboolean
2100eoc_image_is_modified (EocImage *img)
2101{
2102 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)
;
2103
2104 return img->priv->modified;
2105}
2106
2107goffset
2108eoc_image_get_bytes (EocImage *img)
2109{
2110 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)
;
2111
2112 return img->priv->bytes;
2113}
2114
2115void
2116eoc_image_modified (EocImage *img)
2117{
2118 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)
;
2119
2120 g_signal_emit (G_OBJECT (img)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((img)), (((GType) ((20) << (2))))))))
, signals[SIGNAL_CHANGED], 0);
2121}
2122
2123gchar*
2124eoc_image_get_uri_for_display (EocImage *img)
2125{
2126 EocImagePrivate *priv;
2127 gchar *uri_str = NULL((void*)0);
2128 gchar *str = NULL((void*)0);
2129
2130 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)
;
2131
2132 priv = img->priv;
2133
2134 if (priv->file != NULL((void*)0)) {
2135 uri_str = g_file_get_uri (priv->file);
2136
2137 if (uri_str != NULL((void*)0)) {
2138 str = g_uri_unescape_string (uri_str, NULL((void*)0));
2139 g_free (uri_str);
2140 }
2141 }
2142
2143 return str;
2144}
2145
2146EocImageStatus
2147eoc_image_get_status (EocImage *img)
2148{
2149 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)
;
2150
2151 return img->priv->status;
2152}
2153
2154/**
2155 * eoc_image_get_metadata_status:
2156 * @img: a #EocImage
2157 *
2158 * Returns the current status of the image metadata, that is,
2159 * whether the metadata has not been read yet, is ready, or not available at all.
2160 *
2161 * Returns: one of #EocImageMetadataStatus
2162 **/
2163EocImageMetadataStatus
2164eoc_image_get_metadata_status (EocImage *img)
2165{
2166 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)
;
2167
2168 return img->priv->metadata_status;
2169}
2170
2171void
2172eoc_image_data_ref (EocImage *img)
2173{
2174 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)
;
2175
2176 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))))))
))))
;
2177 img->priv->data_ref_count++;
2178
2179 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", 2179, ((const char*) (__func__)), "img->priv->data_ref_count <= G_OBJECT (img)->ref_count"
); } while (0)
;
2180}
2181
2182void
2183eoc_image_data_unref (EocImage *img)
2184{
2185 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)
;
2186
2187 if (img->priv->data_ref_count > 0) {
2188 img->priv->data_ref_count--;
2189 } else {
2190 g_warning ("More image data unrefs than refs.");
2191 }
2192
2193 if (img->priv->data_ref_count == 0) {
2194 eoc_image_free_mem_private (img);
2195 }
2196
2197 g_object_unref (G_OBJECT (img)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((img)), (((GType) ((20) << (2))))))))
);
2198
2199 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", 2199, ((const char*) (__func__)), "img->priv->data_ref_count <= G_OBJECT (img)->ref_count"
); } while (0)
;
2200}
2201
2202static gint
2203compare_quarks (gconstpointer a, gconstpointer b)
2204{
2205 GQuark quark;
2206
2207 quark = g_quark_from_string ((const gchar *) a);
2208
2209 return quark - GPOINTER_TO_INT (b)((gint) (glong) (b));
2210}
2211
2212/**
2213 * eoc_image_get_supported_mime_types:
2214 *
2215 * Gets the list of supported mimetypes
2216 *
2217 * Returns: (transfer none)(element-type utf8): a #GList of supported mimetypes
2218 **/
2219GList *
2220eoc_image_get_supported_mime_types (void)
2221{
2222 GSList *format_list, *it;
2223 gchar **mime_types;
2224 int i;
2225
2226 if (!supported_mime_types) {
2227 format_list = gdk_pixbuf_get_formats ();
2228
2229 for (it = format_list; it != NULL((void*)0); it = it->next) {
2230 mime_types =
2231 gdk_pixbuf_format_get_mime_types ((GdkPixbufFormat *) it->data);
2232
2233 for (i = 0; mime_types[i] != NULL((void*)0); i++) {
2234 supported_mime_types =
2235 g_list_prepend (supported_mime_types,
2236 g_strdup (mime_types[i])g_strdup_inline (mime_types[i]));
2237 }
2238
2239 g_strfreev (mime_types);
2240 }
2241
2242 supported_mime_types = g_list_sort (supported_mime_types,
2243 (GCompareFunc) compare_quarks);
2244
2245 g_slist_free (format_list);
2246 }
2247
2248 return supported_mime_types;
2249}
2250
2251gboolean
2252eoc_image_is_supported_mime_type (const char *mime_type)
2253{
2254 GList *supported_mime_types, *result;
2255 GQuark quark;
2256
2257 if (mime_type == NULL((void*)0)) {
2258 return FALSE(0);
2259 }
2260
2261 supported_mime_types = eoc_image_get_supported_mime_types ();
2262
2263 quark = g_quark_from_string (mime_type);
2264
2265 result = g_list_find_custom (supported_mime_types,
2266 GINT_TO_POINTER (quark)((gpointer) (glong) (quark)),
2267 (GCompareFunc) compare_quarks);
2268
2269 return (result != NULL((void*)0));
2270}
2271
2272static gboolean
2273eoc_image_iter_advance (EocImage *img)
2274{
2275 EocImagePrivate *priv;
2276 gboolean new_frame;
2277
2278 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)
;
2279 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)
;
2280
2281 priv = img->priv;
2282
2283 if ((new_frame = gdk_pixbuf_animation_iter_advance (img->priv->anim_iter, NULL((void*)0))) == TRUE(!(0))) {
2284 g_mutex_lock (&priv->status_mutex);
2285 g_object_unref (priv->image);
2286 priv->image = gdk_pixbuf_animation_iter_get_pixbuf (priv->anim_iter);
2287 g_object_ref (priv->image)((__typeof__ (priv->image)) (g_object_ref) (priv->image
))
;
2288 /* keep the transformation over time */
2289 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; }
))))
) {
2290 GdkPixbuf* transformed = eoc_transform_apply (priv->trans, priv->image, NULL((void*)0));
2291 g_object_unref (priv->image);
2292 priv->image = transformed;
2293 priv->width = gdk_pixbuf_get_width (transformed);
2294 priv->height = gdk_pixbuf_get_height (transformed);
2295 }
2296 g_mutex_unlock (&priv->status_mutex);
2297 /* Emit next frame signal so we can update the display */
2298 g_signal_emit (img, signals[SIGNAL_NEXT_FRAME], 0,
2299 gdk_pixbuf_animation_iter_get_delay_time (priv->anim_iter));
2300 }
2301
2302 return new_frame;
2303}
2304
2305/**
2306 * eoc_image_is_animation:
2307 * @img: a #EocImage
2308 *
2309 * Checks whether a given image is anicafed.
2310 *
2311 * Returns: #TRUE if it is an anicafed image, #FALSE otherwise.
2312 *
2313 **/
2314gboolean
2315eoc_image_is_animation (EocImage *img)
2316{
2317 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)
;
2318 return img->priv->anim != NULL((void*)0);
2319}
2320
2321static gboolean
2322private_timeout (gpointer data)
2323{
2324 EocImage *img = EOC_IMAGE (data)((((EocImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((eoc_image_get_type ()))))))
;
2325 EocImagePrivate *priv = img->priv;
2326
2327 if (eoc_image_is_animation (img) &&
2328 !g_source_is_destroyed (g_main_current_source ()) &&
2329 priv->is_playing) {
2330 while (eoc_image_iter_advance (img) != TRUE(!(0))) {}; /* cpu-sucking ? */
2331 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (priv->anim_iter), private_timeout, img);
2332 return FALSE(0);
2333 }
2334 priv->is_playing = FALSE(0);
2335 return FALSE(0); /* stop playing */
2336}
2337
2338/**
2339 * eoc_image_start_animation:
2340 * @img: a #EocImage
2341 *
2342 * Starts playing an anicafed image.
2343 *
2344 * Returns: %TRUE on success, %FALSE if @img is already playing or isn't an anicafed image.
2345 **/
2346gboolean
2347eoc_image_start_animation (EocImage *img)
2348{
2349 EocImagePrivate *priv;
2350
2351 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)
;
2352 priv = img->priv;
2353
2354 if (!eoc_image_is_animation (img) || priv->is_playing)
2355 return FALSE(0);
2356
2357 g_mutex_lock (&priv->status_mutex);
2358 g_object_ref (priv->anim_iter)((__typeof__ (priv->anim_iter)) (g_object_ref) (priv->anim_iter
))
;
2359 priv->is_playing = TRUE(!(0));
2360 g_mutex_unlock (&priv->status_mutex);
2361
2362 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (priv->anim_iter), private_timeout, img);
2363
2364 return TRUE(!(0));
2365}
2366
2367#ifdef HAVE_RSVG1
2368gboolean
2369eoc_image_is_svg (EocImage *img)
2370{
2371 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)
;
2372
2373 return (img->priv->svg != NULL((void*)0));
2374}
2375
2376RsvgHandle *
2377eoc_image_get_svg (EocImage *img)
2378{
2379 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)
;
2380
2381 return img->priv->svg;
2382}
2383
2384#endif
2385
2386/**
2387 * eoc_image_get_transform:
2388 * @img: a #EocImage
2389 *
2390 * Get @img transform.
2391 *
2392 * Returns: (transfer none): A #EocTransform.
2393 */
2394
2395EocTransform *
2396eoc_image_get_transform (EocImage *img)
2397{
2398 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)
;
2399
2400 return img->priv->trans;
2401}
2402
2403/**
2404 * eoc_image_get_autorotate_transform:
2405 * @img: a #EocImage
2406 *
2407 * Get @img autorotate transform.
2408 *
2409 * Returns: (transfer none): A #EocTransform.
2410 */
2411
2412EocTransform*
2413eoc_image_get_autorotate_transform (EocImage *img)
2414{
2415 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)
;
2416
2417 return img->priv->trans_autorotate;
2418}
2419
2420/**
2421 * eoc_image_file_changed:
2422 * @img: a #EocImage
2423 *
2424 * Marks the image files contents as changed. Also, emits
2425 * EocImage::file-changed signal
2426 **/
2427void
2428eoc_image_file_changed (EocImage *img)
2429{
2430 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)
;
2431
2432 img->priv->file_is_changed = TRUE(!(0));
2433 g_signal_emit (img, signals[SIGNAL_FILE_CHANGED], 0);
2434}
2435
2436gboolean
2437eoc_image_is_file_changed (EocImage *img)
2438{
2439 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)
;
2440
2441 return img->priv->file_is_changed;
2442}
2443
2444gboolean
2445eoc_image_is_jpeg (EocImage *img)
2446{
2447 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)
;
2448
2449 return ((img->priv->file_type != NULL((void*)0)) && (g_ascii_strcasecmp (img->priv->file_type, EOC_FILE_FORMAT_JPEG"jpeg") == 0));
2450}
2451