Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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