1 /*
2  * Copyright © 2009-2018 Siyan Panayotov <contact@siyanpanayotov.com>
3  *
4  * This file is part of Viewnior.
5  *
6  * Viewnior is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Viewnior is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Viewnior.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __VNR_IMAGE_H__
21 #define __VNR_IMAGE_H__
22 
23 #include <glib.h>
24 #include <gio/gio.h>
25 #include <gtk/gtk.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include "vnr-tools.h"
29 
30 void
vnr_tools_fit_to_size(gint * width,gint * height,gint max_width,gint max_height)31 vnr_tools_fit_to_size (gint * width, gint * height, gint max_width, gint max_height)
32 {
33     gfloat ratio, max_ratio;
34 
35     /* if size fits well, then exit */
36     if (*width < max_width && *height < max_height)
37         return;
38     /* check if dividing by 0 */
39     if (*width == 0 || max_height == 0)
40         return;
41 
42     ratio = 1. * (*height) / (*width);
43     max_ratio = 1. * max_height / max_width;
44 
45     if (max_ratio > ratio)
46     {
47         *width = max_width;
48         *height = ratio * (*width);
49     }
50     else if (ratio > max_ratio)
51     {
52         *height = max_height;
53         *width = (*height) / ratio;
54     }
55     else
56     {
57         *width = max_width;
58         *height = max_height;
59     }
60 
61     return;
62 }
63 
64 void
vnr_tools_fit_to_size_double(gdouble * width,gdouble * height,gint max_width,gint max_height)65 vnr_tools_fit_to_size_double (gdouble * width, gdouble * height, gint max_width, gint max_height)
66 {
67     gdouble ratio, max_ratio;
68 
69     /* if size fits well, then exit */
70     if (*width < max_width && *height < max_height)
71         return;
72     /* check if dividing by 0 */
73     if (*width == 0 || max_height == 0)
74         return;
75 
76     ratio = 1. * (*height) / (*width);
77     max_ratio = 1. * max_height / max_width;
78 
79     if (max_ratio > ratio)
80     {
81         *width = max_width;
82         *height = ratio * (*width);
83     }
84     else if (ratio > max_ratio)
85     {
86         *height = max_height;
87         *width = (*height) / ratio;
88     }
89     else
90     {
91         *width = max_width;
92         *height = max_height;
93     }
94 
95     return;
96 }
97 
98 GSList*
vnr_tools_get_list_from_array(gchar ** files)99 vnr_tools_get_list_from_array (gchar **files)
100 {
101     GSList *uri_list = NULL;
102     gint i;
103 
104     if (files == NULL) return NULL;
105 
106     for (i = 0; files[i]; i++) {
107         char *uri_string;
108 
109         GFile *file;
110 
111         file = g_file_new_for_commandline_arg (files[i]);
112 
113         uri_string = g_file_get_path (file);
114 
115         g_object_unref (file);
116 
117         if (uri_string) {
118             uri_list = g_slist_prepend (uri_list, g_strdup (uri_string));
119             g_free (uri_string);
120         }
121     }
122 
123     return g_slist_reverse (uri_list);
124 }
125 
126 /* modified version of eog's
127  * eog_util_parse_uri_string_list_to_file_list */
128 GSList*
vnr_tools_parse_uri_string_list_to_file_list(const gchar * uri_list)129 vnr_tools_parse_uri_string_list_to_file_list (const gchar *uri_list)
130 {
131     GSList* file_list = NULL;
132     gsize i = 0;
133     gchar **uris;
134     gchar* current_path;
135 
136     uris = g_uri_list_extract_uris (uri_list);
137 
138     while (uris[i] != NULL) {
139         current_path = g_file_get_path (g_file_new_for_uri(uris[i]));
140         if(current_path != NULL)
141             file_list = g_slist_append (file_list, current_path);
142         i++;
143     }
144 
145     g_strfreev (uris);
146     return g_slist_reverse (file_list);
147 }
148 
149 gint
compare_quarks(gconstpointer a,gconstpointer b)150 compare_quarks (gconstpointer a, gconstpointer b)
151 {
152     GQuark quark;
153 
154     quark = g_quark_from_string ((const gchar *) a);
155 
156     return quark - GPOINTER_TO_INT (b);
157 }
158 
159 void
get_position_of_element_in_list(GList * list,gint * current,gint * total)160 get_position_of_element_in_list (GList *list, gint *current, gint *total)
161 {
162     GList *it;
163     gint after, before;
164 
165     after = before = 0;
166     it = list;
167 
168     for(it = list; it != NULL; it = it->next)
169     {
170         after ++;
171     }
172 
173     for(it = list; it != NULL; it = it->prev)
174     {
175         before ++;
176     }
177 
178     *current = before;
179     *total = before + after - 1;
180 }
181 
182 void
vnr_tools_apply_embedded_orientation(GdkPixbufAnimation ** anim)183 vnr_tools_apply_embedded_orientation (GdkPixbufAnimation **anim)
184 {
185     GdkPixbuf *pixbuf;
186     GdkPixbuf *original;
187 
188     if(!gdk_pixbuf_animation_is_static_image (*anim))
189         return;
190 
191     pixbuf = gdk_pixbuf_animation_get_static_image (*anim);
192     original = pixbuf;
193     pixbuf = gdk_pixbuf_apply_embedded_orientation(pixbuf);
194 
195     if(original == pixbuf)
196     {
197         g_object_unref(pixbuf);
198         return;
199     }
200 
201     GdkPixbufSimpleAnim *s_anim;
202 
203     s_anim = gdk_pixbuf_simple_anim_new (gdk_pixbuf_get_width(pixbuf),
204                                          gdk_pixbuf_get_height(pixbuf),
205                                          -1);
206     gdk_pixbuf_simple_anim_add_frame(s_anim, pixbuf);
207 
208     g_object_unref(pixbuf);
209     g_object_unref(*anim);
210 
211     *anim = GDK_PIXBUF_ANIMATION(s_anim);
212 }
213 #endif /* __VNR_IMAGE_H__ */
214