2
* Copyright (C) 2006-2009 Anders Brander <anders@brander.dk> and
3
* Anders Kvist <akv@lnxbx.dk>
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
#define _XOPEN_SOURCE /* strptime() */
23
#include <glib/gstdio.h>
25
#include "conf_interface.h"
28
#define DOTDIR ".rawstudio"
31
* A version of atof() that isn't locale specific
32
* @note This doesn't do any error checking!
33
* @param str A NULL terminated string representing a number
34
* @return The number represented by str or 0.0 if str is NULL
37
rs_atof(const gchar *str)
39
gdouble result = 0.0f;
41
gboolean point_passed = FALSE;
43
gchar *ptr = (gchar *) str;
47
if (g_ascii_isdigit(*ptr))
49
result = result * 10.0f + g_ascii_digit_value(*ptr);
55
else if (g_ascii_ispunct(*ptr))
64
* A convenience function to convert an EXIF timestamp to a unix timestamp.
65
* @note This will only work until 2038 unless glib fixes its GTime
66
* @param str A NULL terminated string containing a timestamp in the format "YYYY:MM:DD HH:MM:SS" (EXIF 2.2 section 4.6.4)
67
* @return A unix timestamp or -1 on error
70
rs_exiftime_to_unixtime(const gchar *str)
72
struct tm *tm = g_new0(struct tm, 1);
75
if (strptime(str, "%Y:%m:%d %H:%M:%S", tm))
76
timestamp = (GTime) mktime(tm);
84
* A convenience function to convert an unix timestamp to an EXIF timestamp.
85
* @note This will only work until 2038 unless glib fixes its GTime
86
* @param timestamp A unix timestamp
87
* @return A string formatted as specified in EXIF 2.2 section 4.6.4
90
rs_unixtime_to_exiftime(GTime timestamp)
92
struct tm *tm = g_new0(struct tm, 1);
93
time_t tt = (time_t) timestamp;
94
gchar *result = g_new0(gchar, 20);
98
if (strftime(result, 20, "%Y:%m:%d %H:%M:%S", tm) != 19)
110
* Constrains a box to fill a bounding box without changing aspect
111
* @param target_width The width of the bounding box
112
* @param target_height The height of the bounding box
113
* @param width The input and output width
114
* @param height The input and output height
117
rs_constrain_to_bounding_box(gint target_width, gint target_height, gint *width, gint *height)
119
gdouble target_aspect = ((gdouble)target_width) / ((gdouble)target_height);
120
gdouble input_aspect = ((gdouble)*width) / ((gdouble)*height);
123
if (target_aspect < input_aspect)
124
scale = ((gdouble) *width) / ((gdouble) target_width);
126
scale = ((gdouble) *height) / ((gdouble) target_height);
128
*width = (gint) ((gdouble)*width) / scale;
129
*height = (gint) ((gdouble)*height) / scale;
133
* Try to count the number of processor cores in a system.
134
* @note This currently only works for systems with /proc/cpuinfo
135
* @return The numver of cores or 1 if the system is unsupported
138
rs_get_number_of_processor_cores()
140
static GStaticMutex lock = G_STATIC_MUTEX_INIT;
142
/* We assume processors will not be added/removed during our lifetime */
145
g_static_mutex_lock (&lock);
151
io = g_io_channel_new_file("/proc/cpuinfo", "r", NULL);
154
/* Count the "processor"-lines, there should be one for each processor/core */
155
while (G_IO_STATUS_NORMAL == g_io_channel_read_line(io, &line, NULL, NULL, NULL))
158
if (g_str_has_prefix(line, "processor"))
162
g_io_channel_shutdown(io, FALSE, NULL);
163
g_io_channel_unref(io);
168
g_static_mutex_unlock (&lock);
174
* Return a path to the current config directory for Rawstudio - this is the
175
* .rawstudio direcotry in home
176
* @return A path to an existing directory
181
static gchar *dir = NULL;
182
static GStaticMutex lock = G_STATIC_MUTEX_INIT;
184
g_static_mutex_lock(&lock);
187
const gchar *home = g_get_home_dir();
188
dir = g_build_filename(home, ".rawstudio", NULL);
191
g_mkdir_with_parents(dir, 00755);
192
g_static_mutex_unlock(&lock);
198
* Return a cache directory for filename
199
* @param filename A complete path to a photo
200
* @return A directory to hold the cache. This is guarenteed to exist
203
rs_dotdir_get(const gchar *filename)
208
gboolean dotdir_is_local = FALSE;
209
rs_conf_get_boolean(CONF_CACHEDIR_IS_LOCAL, &dotdir_is_local);
211
directory = g_path_get_dirname(filename);
214
dotdir = g_string_new(g_get_home_dir());
215
dotdir = g_string_append(dotdir, G_DIR_SEPARATOR_S);
216
dotdir = g_string_append(dotdir, DOTDIR);
217
dotdir = g_string_append(dotdir, G_DIR_SEPARATOR_S);
218
dotdir = g_string_append(dotdir, directory);
222
dotdir = g_string_new(directory);
223
dotdir = g_string_append(dotdir, G_DIR_SEPARATOR_S);
224
dotdir = g_string_append(dotdir, DOTDIR);
227
if (!g_file_test(dotdir->str, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
229
if (g_mkdir_with_parents(dotdir->str, 0700) != 0)
237
g_string_free(dotdir, FALSE);
242
* Normalize a RS_RECT, ie makes sure that x1 < x2 and y1<y2
243
* @param in A RS_RECT to read values from
244
* @param out A RS_RECT to write the values to (can be the same as in)
247
rs_rect_normalize(RS_RECT *in, RS_RECT *out)
279
* @param in A RS_RECT to read values from
280
* @param out A RS_RECT to write the values to (can be the same as in)
281
* @param w The width of the data OUTSIDE the RS_RECT
282
* @param h The height of the data OUTSIDE the RS_RECT
285
rs_rect_flip(RS_RECT *in, RS_RECT *out, gint w, gint h)
299
rs_rect_normalize(out, out);
304
* @param in A RS_RECT to read values from
305
* @param out A RS_RECT to write the values to (can be the same as in)
306
* @param w The width of the data OUTSIDE the RS_RECT
307
* @param h The height of the data OUTSIDE the RS_RECT
310
rs_rect_mirror(RS_RECT *in, RS_RECT *out, gint w, gint h)
324
rs_rect_normalize(out, out);
328
* Rotate a RS_RECT in 90 degrees steps
329
* @param in A RS_RECT to read values from
330
* @param out A RS_RECT to write the values to (can be the same as in)
331
* @param w The width of the data OUTSIDE the RS_RECT
332
* @param h The height of the data OUTSIDE the RS_RECT
333
* @param quarterturns How many times to turn the rect clockwise
336
rs_rect_rotate(RS_RECT *in, RS_RECT *out, gint w, gint h, gint quarterturns)
372
rs_rect_normalize(out, out);
376
* Check (and complain if needed) the Rawstudio install
381
#define TEST_FILE_ACCESS(path) do { if (g_access(path, R_OK)!=0) g_debug("Cannot access %s\n", path);} while (0)
382
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/icons/" PACKAGE ".png");
383
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/overlay_priority1.png");
384
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/overlay_priority2.png");
385
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/overlay_priority3.png");
386
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/overlay_deleted.png");
387
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/overlay_exported.png");
388
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/transform_flip.png");
389
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/transform_mirror.png");
390
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/transform_90.png");
391
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/transform_180.png");
392
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/transform_270.png");
393
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/" PACKAGE "/ui.xml");
394
TEST_FILE_ACCESS(PACKAGE_DATA_DIR "/" PACKAGE "/rawstudio.gtkrc");
395
#undef TEST_FILE_ACCESS