| File: | _build/../cdk-pixbuf/cdk-pixbuf-io.c |
| Warning: | line 2442, column 21 Value of 'errno' was not checked and may be overwritten by function 'fread' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* CdkPixbuf library - Main loading interface. | |||
| 2 | * | |||
| 3 | * Copyright (C) 1999 The Free Software Foundation | |||
| 4 | * | |||
| 5 | * Authors: Miguel de Icaza <miguel@gnu.org> | |||
| 6 | * Federico Mena-Quintero <federico@gimp.org> | |||
| 7 | * | |||
| 8 | * This library is free software; you can redistribute it and/or | |||
| 9 | * modify it under the terms of the GNU Lesser General Public | |||
| 10 | * License as published by the Free Software Foundation; either | |||
| 11 | * version 2 of the License, or (at your option) any later version. | |||
| 12 | * | |||
| 13 | * This library is distributed in the hope that it will be useful, | |||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 16 | * Lesser General Public License for more details. | |||
| 17 | * | |||
| 18 | * You should have received a copy of the GNU Lesser General Public | |||
| 19 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. | |||
| 20 | */ | |||
| 21 | ||||
| 22 | #include "config.h" | |||
| 23 | ||||
| 24 | #include <stdlib.h> | |||
| 25 | #include <stdio.h> | |||
| 26 | #include <string.h> | |||
| 27 | #include <errno(*__errno_location ()).h> | |||
| 28 | #ifdef HAVE_UNISTD_H1 | |||
| 29 | #include <unistd.h> | |||
| 30 | #endif | |||
| 31 | ||||
| 32 | #include <glib.h> | |||
| 33 | #include <gio/gio.h> | |||
| 34 | ||||
| 35 | #include "cdk-pixbuf-private.h" | |||
| 36 | #include "cdk-pixbuf-loader.h" | |||
| 37 | #include "cdk-pixdata.h" | |||
| 38 | ||||
| 39 | #include <glib/gstdio.h> | |||
| 40 | ||||
| 41 | #ifdef G_OS_WIN32 | |||
| 42 | #define STRICT | |||
| 43 | #include <windows.h> | |||
| 44 | #undef STRICT | |||
| 45 | #endif | |||
| 46 | #ifdef OS_DARWIN | |||
| 47 | #include <mach-o/dyld.h> | |||
| 48 | #endif | |||
| 49 | ||||
| 50 | G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push
clang diagnostic ignored "-Wdeprecated-declarations" | |||
| 51 | ||||
| 52 | /** | |||
| 53 | * CdkPixbufModule: | |||
| 54 | * @module_name: the name of the module, usually the same as the | |||
| 55 | * usual file extension for images of this type, eg. "xpm", "jpeg" or "png". | |||
| 56 | * @module_path: the path from which the module is loaded. | |||
| 57 | * @module: the loaded `GModule`. | |||
| 58 | * @info: a `CdkPixbufFormat` holding information about the module. | |||
| 59 | * @load: loads an image from a file. | |||
| 60 | * @load_xpm_data: loads an image from data in memory. | |||
| 61 | * @begin_load: begins an incremental load. | |||
| 62 | * @stop_load: stops an incremental load. | |||
| 63 | * @load_increment: continues an incremental load. | |||
| 64 | * @load_animation: loads an animation from a file. | |||
| 65 | * @save: saves a `CdkPixbuf` to a file. | |||
| 66 | * @save_to_callback: saves a `CdkPixbuf` by calling the given `CdkPixbufSaveFunc`. | |||
| 67 | * @is_save_option_supported: returns whether a save option key is supported by the module | |||
| 68 | * | |||
| 69 | * A `CdkPixbufModule` contains the necessary functions to load and save | |||
| 70 | * images in a certain file format. | |||
| 71 | * | |||
| 72 | * If `CdkPixbuf` has been compiled with `GModule` support, it can be extended | |||
| 73 | * by modules which can load (and perhaps also save) new image and animation | |||
| 74 | * formats. | |||
| 75 | * | |||
| 76 | * ## Implementing modules | |||
| 77 | * | |||
| 78 | * The `CdkPixbuf` interfaces needed for implementing modules are contained in | |||
| 79 | * `cdk-pixbuf-io.h` (and `cdk-pixbuf-animation.h` if the module supports | |||
| 80 | * animations). They are not covered by the same stability guarantees as the | |||
| 81 | * regular CdkPixbuf API. To underline this fact, they are protected by the | |||
| 82 | * `CDK_PIXBUF_ENABLE_BACKEND` pre-processor symbol. | |||
| 83 | * | |||
| 84 | * Each loadable module must contain a `CdkPixbufModuleFillVtableFunc` function | |||
| 85 | * named `fill_vtable`, which will get called when the module | |||
| 86 | * is loaded and must set the function pointers of the `CdkPixbufModule`. | |||
| 87 | * | |||
| 88 | * In order to make format-checking work before actually loading the modules | |||
| 89 | * (which may require calling `dlopen` to load image libraries), modules export | |||
| 90 | * their signatures (and other information) via the `fill_info` function. An | |||
| 91 | * external utility, `cdk-pixbuf-query-loaders`, uses this to create a text | |||
| 92 | * file containing a list of all available loaders and their signatures. | |||
| 93 | * This file is then read at runtime by `CdkPixbuf` to obtain the list of | |||
| 94 | * available loaders and their signatures. | |||
| 95 | * | |||
| 96 | * Modules may only implement a subset of the functionality available via | |||
| 97 | * `CdkPixbufModule`. If a particular functionality is not implemented, the | |||
| 98 | * `fill_vtable` function will simply not set the corresponding | |||
| 99 | * function pointers of the `CdkPixbufModule` structure. If a module supports | |||
| 100 | * incremental loading (i.e. provides `begin_load`, `stop_load` and | |||
| 101 | * `load_increment`), it doesn't have to implement `load`, since `CdkPixbuf` | |||
| 102 | * can supply a generic `load` implementation wrapping the incremental loading. | |||
| 103 | * | |||
| 104 | * ## Installing modules | |||
| 105 | * | |||
| 106 | * Installing a module is a two-step process: | |||
| 107 | * | |||
| 108 | * - copy the module file(s) to the loader directory (normally | |||
| 109 | * `$libdir/cdk-pixbuf-2.0/$version/loaders`, unless overridden by the | |||
| 110 | * environment variable `CDK_PIXBUF_MODULEDIR`) | |||
| 111 | * - call `cdk-pixbuf-query-loaders` to update the module file (normally | |||
| 112 | * `$libdir/cdk-pixbuf-2.0/$version/loaders.cache`, unless overridden | |||
| 113 | * by the environment variable `CDK_PIXBUF_MODULE_FILE`) | |||
| 114 | */ | |||
| 115 | ||||
| 116 | static gint | |||
| 117 | format_check (CdkPixbufModule *module, guchar *buffer, int size) | |||
| 118 | { | |||
| 119 | int i, j; | |||
| 120 | gchar m; | |||
| 121 | CdkPixbufModulePattern *pattern; | |||
| 122 | gboolean anchored; | |||
| 123 | guchar *prefix; | |||
| 124 | gchar *mask; | |||
| 125 | ||||
| 126 | for (pattern = module->info->signature; pattern->prefix; pattern++) { | |||
| 127 | if (pattern->mask && pattern->mask[0] == '*') { | |||
| 128 | prefix = (guchar *)pattern->prefix + 1; | |||
| 129 | mask = pattern->mask + 1; | |||
| 130 | anchored = FALSE(0); | |||
| 131 | } | |||
| 132 | else { | |||
| 133 | prefix = (guchar *)pattern->prefix; | |||
| 134 | mask = pattern->mask; | |||
| 135 | anchored = TRUE(!(0)); | |||
| 136 | } | |||
| 137 | for (i = 0; i < size; i++) { | |||
| 138 | for (j = 0; i + j < size && prefix[j] != 0; j++) { | |||
| 139 | m = mask ? mask[j] : ' '; | |||
| 140 | if (m == ' ') { | |||
| 141 | if (buffer[i + j] != prefix[j]) | |||
| 142 | break; | |||
| 143 | } | |||
| 144 | else if (m == '!') { | |||
| 145 | if (buffer[i + j] == prefix[j]) | |||
| 146 | break; | |||
| 147 | } | |||
| 148 | else if (m == 'z') { | |||
| 149 | if (buffer[i + j] != 0) | |||
| 150 | break; | |||
| 151 | } | |||
| 152 | else if (m == 'n') { | |||
| 153 | if (buffer[i + j] == 0) | |||
| 154 | break; | |||
| 155 | } | |||
| 156 | } | |||
| 157 | ||||
| 158 | if (prefix[j] == 0) | |||
| 159 | return pattern->relevance; | |||
| 160 | ||||
| 161 | if (anchored) | |||
| 162 | break; | |||
| 163 | } | |||
| 164 | } | |||
| 165 | return 0; | |||
| 166 | } | |||
| 167 | ||||
| 168 | G_LOCK_DEFINE_STATIC (init_lock)static GMutex g__init_lock_lock; | |||
| 169 | ||||
| 170 | static gboolean file_formats_inited; | |||
| 171 | static GSList *file_formats = NULL((void*)0); | |||
| 172 | ||||
| 173 | static gboolean cdk_pixbuf_io_init (void); | |||
| 174 | ||||
| 175 | static GSList * | |||
| 176 | get_file_formats (void) | |||
| 177 | { | |||
| 178 | G_LOCK (init_lock)g_mutex_lock (&g__init_lock_lock); | |||
| 179 | if (file_formats == NULL((void*)0) || | |||
| 180 | !file_formats_inited) | |||
| 181 | file_formats_inited = cdk_pixbuf_io_init (); | |||
| 182 | G_UNLOCK (init_lock)g_mutex_unlock (&g__init_lock_lock); | |||
| 183 | ||||
| 184 | return file_formats; | |||
| 185 | } | |||
| 186 | ||||
| 187 | #ifdef CDK_PIXBUF_RELOCATABLE // implies that cdk-pixbuf is built as a dll on windows | |||
| 188 | ||||
| 189 | #ifdef G_OS_WIN32 | |||
| 190 | ||||
| 191 | /* DllMain function needed to tuck away the cdk-pixbuf DLL handle */ | |||
| 192 | ||||
| 193 | static HMODULE cdk_pixbuf_dll; | |||
| 194 | ||||
| 195 | BOOL WINAPI | |||
| 196 | DllMain (HINSTANCE hinstDLL, | |||
| 197 | DWORD fdwReason, | |||
| 198 | LPVOID lpvReserved) | |||
| 199 | { | |||
| 200 | switch (fdwReason) { | |||
| 201 | case DLL_PROCESS_ATTACH: | |||
| 202 | cdk_pixbuf_dll = (HMODULE) hinstDLL; | |||
| 203 | break; | |||
| 204 | } | |||
| 205 | ||||
| 206 | return TRUE(!(0)); | |||
| 207 | } | |||
| 208 | #endif | |||
| 209 | ||||
| 210 | gchar * | |||
| 211 | cdk_pixbuf_get_toplevel (void) | |||
| 212 | { | |||
| 213 | static gchar *toplevel = NULL((void*)0); | |||
| 214 | ||||
| 215 | if (toplevel == NULL((void*)0)) { | |||
| 216 | #if defined(G_OS_WIN32) | |||
| 217 | toplevel = g_win32_get_package_installation_directory_of_module (cdk_pixbuf_dll); | |||
| 218 | #elif defined(OS_DARWIN) | |||
| 219 | char pathbuf[PATH_MAX4096 + 1]; | |||
| 220 | uint32_t bufsize = sizeof(pathbuf); | |||
| 221 | gchar *bin_dir; | |||
| 222 | ||||
| 223 | _NSGetExecutablePath(pathbuf, &bufsize); | |||
| 224 | bin_dir = g_dirnameg_path_get_dirname GCC warning "Deprecated pre-processor symbol: replace with \"g_path_get_dirname\"" (pathbuf); | |||
| 225 | toplevel = g_build_path (G_DIR_SEPARATOR_S"/", bin_dir, "..", NULL((void*)0)); | |||
| 226 | g_free (bin_dir); | |||
| 227 | #elif defined (OS_LINUX1) | |||
| 228 | gchar *exe_path, *bin_dir; | |||
| 229 | ||||
| 230 | exe_path = g_file_read_link ("/proc/self/exe", NULL((void*)0)); | |||
| 231 | bin_dir = g_dirnameg_path_get_dirname GCC warning "Deprecated pre-processor symbol: replace with \"g_path_get_dirname\"" (exe_path); | |||
| 232 | toplevel = g_build_path (G_DIR_SEPARATOR_S"/", bin_dir, "..", NULL((void*)0)); | |||
| 233 | g_free (exe_path); | |||
| 234 | g_free (bin_dir); | |||
| 235 | #else | |||
| 236 | #error "Relocations not supported for this platform" | |||
| 237 | #endif | |||
| 238 | } | |||
| 239 | return toplevel; | |||
| 240 | } | |||
| 241 | ||||
| 242 | #endif /* CDK_PIXBUF_RELOCATABLE */ | |||
| 243 | ||||
| 244 | ||||
| 245 | #ifdef USE_GMODULE | |||
| 246 | ||||
| 247 | static gboolean | |||
| 248 | scan_string (const char **pos, GString *out) | |||
| 249 | { | |||
| 250 | const char *p = *pos, *q = *pos; | |||
| 251 | char *tmp, *tmp2; | |||
| 252 | gboolean quoted; | |||
| 253 | ||||
| 254 | while (g_ascii_isspace (*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_SPACE) != 0)) | |||
| 255 | p++; | |||
| 256 | ||||
| 257 | if (!*p) | |||
| 258 | return FALSE(0); | |||
| 259 | else if (*p == '"') { | |||
| 260 | p++; | |||
| 261 | quoted = FALSE(0); | |||
| 262 | for (q = p; (*q != '"') || quoted; q++) { | |||
| 263 | if (!*q) | |||
| 264 | return FALSE(0); | |||
| 265 | quoted = (*q == '\\') && !quoted; | |||
| 266 | } | |||
| 267 | ||||
| 268 | tmp = g_strndup (p, q - p); | |||
| 269 | tmp2 = g_strcompress (tmp); | |||
| 270 | g_string_truncate (out, 0)g_string_truncate_inline (out, 0); | |||
| 271 | g_string_append (out, tmp2)(__builtin_constant_p (tmp2) ? __extension__ ({ const char * const __val = (tmp2); g_string_append_len_inline (out, __val, (__builtin_expect (__extension__ ({ int _g_boolean_var_88 = 0; if (__val != (( void*)0)) _g_boolean_var_88 = 1; _g_boolean_var_88; }), 1)) ? (gssize) strlen (((__val) + !(__val))) : (gssize) -1); }) : g_string_append_len_inline (out, tmp2, (gssize) -1)); | |||
| 272 | g_free (tmp); | |||
| 273 | g_free (tmp2); | |||
| 274 | } | |||
| 275 | ||||
| 276 | q++; | |||
| 277 | *pos = q; | |||
| 278 | ||||
| 279 | return TRUE(!(0)); | |||
| 280 | } | |||
| 281 | ||||
| 282 | static gboolean | |||
| 283 | scan_int (const char **pos, int *out) | |||
| 284 | { | |||
| 285 | int i = 0; | |||
| 286 | char buf[32]; | |||
| 287 | const char *p = *pos; | |||
| 288 | ||||
| 289 | while (g_ascii_isspace (*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_SPACE) != 0)) | |||
| 290 | p++; | |||
| 291 | ||||
| 292 | if (*p < '0' || *p > '9') | |||
| 293 | return FALSE(0); | |||
| 294 | ||||
| 295 | while ((*p >= '0') && (*p <= '9') && i < sizeof (buf)) { | |||
| 296 | buf[i] = *p; | |||
| 297 | i++; | |||
| 298 | p++; | |||
| 299 | } | |||
| 300 | ||||
| 301 | if (i == sizeof (buf)) | |||
| 302 | return FALSE(0); | |||
| 303 | else | |||
| 304 | buf[i] = '\0'; | |||
| 305 | ||||
| 306 | *out = atoi (buf); | |||
| 307 | ||||
| 308 | *pos = p; | |||
| 309 | ||||
| 310 | return TRUE(!(0)); | |||
| 311 | } | |||
| 312 | ||||
| 313 | static gboolean | |||
| 314 | skip_space (const char **pos) | |||
| 315 | { | |||
| 316 | const char *p = *pos; | |||
| 317 | ||||
| 318 | while (g_ascii_isspace (*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_SPACE) != 0)) | |||
| 319 | p++; | |||
| 320 | ||||
| 321 | *pos = p; | |||
| 322 | ||||
| 323 | return !(*p == '\0'); | |||
| 324 | } | |||
| 325 | ||||
| 326 | #ifdef CDK_PIXBUF_RELOCATABLE | |||
| 327 | ||||
| 328 | static char * | |||
| 329 | get_libdir (void) | |||
| 330 | { | |||
| 331 | static char *libdir = NULL((void*)0); | |||
| 332 | ||||
| 333 | if (libdir == NULL((void*)0)) | |||
| 334 | libdir = g_build_filename (cdk_pixbuf_get_toplevel (), "lib", NULL((void*)0)); | |||
| 335 | ||||
| 336 | return libdir; | |||
| 337 | } | |||
| 338 | ||||
| 339 | #undef CDK_PIXBUF_LIBDIR"/usr/local/lib/x86_64-linux-gnu" | |||
| 340 | #define CDK_PIXBUF_LIBDIR"/usr/local/lib/x86_64-linux-gnu" get_libdir() | |||
| 341 | ||||
| 342 | #endif /* CDK_PIXBUF_RELOCATABLE */ | |||
| 343 | ||||
| 344 | /* In case we have a relative module path in the loaders cache | |||
| 345 | * prepend the toplevel dir */ | |||
| 346 | static gchar * | |||
| 347 | build_module_path (const gchar *path) | |||
| 348 | { | |||
| 349 | #ifdef CDK_PIXBUF_RELOCATABLE | |||
| 350 | if (g_path_is_absolute (path)) { | |||
| 351 | return g_strdup (path)g_strdup_inline (path); | |||
| 352 | } else { | |||
| 353 | return g_build_filename (cdk_pixbuf_get_toplevel (), path, NULL((void*)0)); | |||
| 354 | } | |||
| 355 | #else | |||
| 356 | return g_strdup (path)g_strdup_inline (path); | |||
| 357 | #endif | |||
| 358 | } | |||
| 359 | ||||
| 360 | static gchar * | |||
| 361 | cdk_pixbuf_get_module_file (void) | |||
| 362 | { | |||
| 363 | gchar *result = g_strdup (g_getenv ("CDK_PIXBUF_MODULE_FILE"))g_strdup_inline (g_getenv ("CDK_PIXBUF_MODULE_FILE")); | |||
| 364 | ||||
| 365 | if (!result) | |||
| 366 | result = g_build_filename (CDK_PIXBUF_LIBDIR"/usr/local/lib/x86_64-linux-gnu", "cdk-pixbuf-2.0", CDK_PIXBUF_BINARY_VERSION"2.10.0", "loaders.cache", NULL((void*)0)); | |||
| 367 | ||||
| 368 | return result; | |||
| 369 | } | |||
| 370 | ||||
| 371 | #endif /* USE_GMODULE */ | |||
| 372 | ||||
| 373 | ||||
| 374 | static gboolean | |||
| 375 | cdk_pixbuf_load_module_unlocked (CdkPixbufModule *image_module, | |||
| 376 | GError **error); | |||
| 377 | ||||
| 378 | static gboolean | |||
| 379 | cdk_pixbuf_io_init_modules (const char *filename, | |||
| 380 | GError **error) | |||
| 381 | { | |||
| 382 | #ifdef USE_GMODULE | |||
| 383 | GIOChannel *channel; | |||
| 384 | gchar *line_buf; | |||
| 385 | gsize term; | |||
| 386 | GString *tmp_buf = g_string_new (NULL((void*)0)); | |||
| 387 | gboolean have_error = FALSE(0); | |||
| 388 | CdkPixbufModule *module = NULL((void*)0); | |||
| 389 | int flags = 0; | |||
| 390 | int n_patterns = 0; | |||
| 391 | CdkPixbufModulePattern *pattern; | |||
| 392 | GError *local_error = NULL((void*)0); | |||
| 393 | guint num_formats; | |||
| 394 | ||||
| 395 | channel = g_io_channel_new_file (filename, "r", &local_error); | |||
| 396 | if (!channel) { | |||
| 397 | char *filename_utf8 = g_filename_display_name (filename); | |||
| 398 | g_set_error (error, | |||
| 399 | G_IO_ERRORg_io_error_quark(), | |||
| 400 | G_IO_ERROR_INVALID_ARGUMENT, | |||
| 401 | "Cannot open pixbuf loader module file '%s': %s\n\n" | |||
| 402 | "This likely means that your installation is broken.\n" | |||
| 403 | "Try running the command\n" | |||
| 404 | " cdk-pixbuf-query-loaders > %s\n" | |||
| 405 | "to make things work again for the time being.", | |||
| 406 | filename_utf8, local_error->message, filename_utf8); | |||
| 407 | g_clear_error (&local_error); | |||
| 408 | g_string_free (tmp_buf, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (tmp_buf), ((!(0)))) : g_string_free_and_steal (tmp_buf)) : ( g_string_free) ((tmp_buf), ((!(0))))); | |||
| 409 | g_free (filename_utf8); | |||
| 410 | return FALSE(0); | |||
| 411 | } | |||
| 412 | ||||
| 413 | num_formats = g_slist_length (file_formats); | |||
| 414 | ||||
| 415 | while (!have_error && g_io_channel_read_line (channel, &line_buf, NULL((void*)0), &term, NULL((void*)0)) == G_IO_STATUS_NORMAL) { | |||
| 416 | const char *p; | |||
| 417 | ||||
| 418 | p = line_buf; | |||
| 419 | ||||
| 420 | line_buf[term] = 0; | |||
| 421 | ||||
| 422 | if (!skip_space (&p)) { | |||
| 423 | /* Blank line marking the end of a module */ | |||
| 424 | if (module && *p != '#') { | |||
| 425 | file_formats = g_slist_prepend (file_formats, module); | |||
| 426 | module = NULL((void*)0); | |||
| 427 | } | |||
| 428 | ||||
| 429 | goto next_line; | |||
| 430 | } | |||
| 431 | ||||
| 432 | if (*p == '#') | |||
| 433 | goto next_line; | |||
| 434 | ||||
| 435 | if (!module) { | |||
| 436 | /* Read a module location */ | |||
| 437 | module = g_new0 (CdkPixbufModule, 1)(CdkPixbufModule *) (__extension__ ({ gsize __n = (gsize) (1) ; gsize __s = sizeof (CdkPixbufModule); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p ( __n) && (__s == 0 || __n <= (9223372036854775807L * 2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p; })); | |||
| 438 | n_patterns = 0; | |||
| 439 | ||||
| 440 | if (!scan_string (&p, tmp_buf)) { | |||
| 441 | g_warning ("Error parsing loader info in '%s'\n %s", | |||
| 442 | filename, line_buf); | |||
| 443 | have_error = TRUE(!(0)); | |||
| 444 | } | |||
| 445 | module->module_path = build_module_path (tmp_buf->str); | |||
| 446 | } | |||
| 447 | else if (!module->module_name) { | |||
| 448 | module->info = g_new0 (CdkPixbufFormat, 1)(CdkPixbufFormat *) (__extension__ ({ gsize __n = (gsize) (1) ; gsize __s = sizeof (CdkPixbufFormat); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p ( __n) && (__s == 0 || __n <= (9223372036854775807L * 2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p; })); | |||
| 449 | if (!scan_string (&p, tmp_buf)) { | |||
| 450 | g_warning ("Error parsing loader info in '%s'\n %s", | |||
| 451 | filename, line_buf); | |||
| 452 | have_error = TRUE(!(0)); | |||
| 453 | } | |||
| 454 | module->info->name = g_strdup (tmp_buf->str)g_strdup_inline (tmp_buf->str); | |||
| 455 | module->module_name = module->info->name; | |||
| 456 | ||||
| 457 | flags = 0; | |||
| 458 | if (!scan_int (&p, &flags)) { | |||
| 459 | g_warning ("Error parsing loader info in '%s'\n %s", | |||
| 460 | filename, line_buf); | |||
| 461 | have_error = TRUE(!(0)); | |||
| 462 | } | |||
| 463 | module->info->flags = flags; | |||
| 464 | ||||
| 465 | if (!scan_string (&p, tmp_buf)) { | |||
| 466 | g_warning ("Error parsing loader info in '%s'\n %s", | |||
| 467 | filename, line_buf); | |||
| 468 | have_error = TRUE(!(0)); | |||
| 469 | } | |||
| 470 | if (tmp_buf->str[0] != 0) | |||
| 471 | module->info->domain = g_strdup (tmp_buf->str)g_strdup_inline (tmp_buf->str); | |||
| 472 | ||||
| 473 | if (!scan_string (&p, tmp_buf)) { | |||
| 474 | g_warning ("Error parsing loader info in '%s'\n %s", | |||
| 475 | filename, line_buf); | |||
| 476 | have_error = TRUE(!(0)); | |||
| 477 | } | |||
| 478 | module->info->description = g_strdup (tmp_buf->str)g_strdup_inline (tmp_buf->str); | |||
| 479 | ||||
| 480 | if (scan_string (&p, tmp_buf)) { | |||
| 481 | module->info->license = g_strdup (tmp_buf->str)g_strdup_inline (tmp_buf->str); | |||
| 482 | } | |||
| 483 | } | |||
| 484 | else if (!module->info->mime_types) { | |||
| 485 | int n = 1; | |||
| 486 | module->info->mime_types = g_new0 (gchar*, 1)(gchar* *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (gchar*); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); | |||
| 487 | while (scan_string (&p, tmp_buf)) { | |||
| 488 | if (tmp_buf->str[0] != 0) { | |||
| 489 | module->info->mime_types = | |||
| 490 | g_realloc (module->info->mime_types, (n + 1) * sizeof (gchar*)); | |||
| 491 | module->info->mime_types[n - 1] = g_strdup (tmp_buf->str)g_strdup_inline (tmp_buf->str); | |||
| 492 | module->info->mime_types[n] = NULL((void*)0); | |||
| 493 | n++; | |||
| 494 | } | |||
| 495 | } | |||
| 496 | } | |||
| 497 | else if (!module->info->extensions) { | |||
| 498 | int n = 1; | |||
| 499 | module->info->extensions = g_new0 (gchar*, 1)(gchar* *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (gchar*); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); | |||
| 500 | while (scan_string (&p, tmp_buf)) { | |||
| 501 | if (tmp_buf->str[0] != 0) { | |||
| 502 | module->info->extensions = | |||
| 503 | g_realloc (module->info->extensions, (n + 1) * sizeof (gchar*)); | |||
| 504 | module->info->extensions[n - 1] = g_strdup (tmp_buf->str)g_strdup_inline (tmp_buf->str); | |||
| 505 | module->info->extensions[n] = NULL((void*)0); | |||
| 506 | n++; | |||
| 507 | } | |||
| 508 | } | |||
| 509 | } | |||
| 510 | else { | |||
| 511 | n_patterns++; | |||
| 512 | module->info->signature = (CdkPixbufModulePattern *) | |||
| 513 | g_realloc (module->info->signature, (n_patterns + 1) * sizeof (CdkPixbufModulePattern)); | |||
| 514 | pattern = module->info->signature + n_patterns; | |||
| 515 | pattern->prefix = NULL((void*)0); | |||
| 516 | pattern->mask = NULL((void*)0); | |||
| 517 | pattern->relevance = 0; | |||
| 518 | pattern--; | |||
| 519 | if (!scan_string (&p, tmp_buf)) | |||
| 520 | goto context_error; | |||
| 521 | pattern->prefix = g_strdup (tmp_buf->str)g_strdup_inline (tmp_buf->str); | |||
| 522 | ||||
| 523 | if (!scan_string (&p, tmp_buf)) | |||
| 524 | goto context_error; | |||
| 525 | if (*tmp_buf->str) | |||
| 526 | pattern->mask = g_strdup (tmp_buf->str)g_strdup_inline (tmp_buf->str); | |||
| 527 | else | |||
| 528 | pattern->mask = NULL((void*)0); | |||
| 529 | ||||
| 530 | if (!scan_int (&p, &pattern->relevance)) | |||
| 531 | goto context_error; | |||
| 532 | ||||
| 533 | goto next_line; | |||
| 534 | ||||
| 535 | context_error: | |||
| 536 | g_free (pattern->prefix); | |||
| 537 | g_free (pattern->mask); | |||
| 538 | g_free (pattern); | |||
| 539 | g_warning ("Error parsing loader info in '%s'\n %s", | |||
| 540 | filename, line_buf); | |||
| 541 | have_error = TRUE(!(0)); | |||
| 542 | } | |||
| 543 | next_line: | |||
| 544 | g_free (line_buf); | |||
| 545 | } | |||
| 546 | g_string_free (tmp_buf, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (tmp_buf), ((!(0)))) : g_string_free_and_steal (tmp_buf)) : ( g_string_free) ((tmp_buf), ((!(0))))); | |||
| 547 | g_io_channel_unref (channel); | |||
| 548 | ||||
| 549 | if (g_slist_length (file_formats) <= num_formats) { | |||
| 550 | char *filename_utf8 = g_filename_display_name (filename); | |||
| 551 | g_set_error (error, | |||
| 552 | G_IO_ERRORg_io_error_quark(), | |||
| 553 | G_IO_ERROR_NOT_INITIALIZED, | |||
| 554 | "No new CdkPixbufModule loaded from '%s'", | |||
| 555 | filename_utf8); | |||
| 556 | g_free (filename_utf8); | |||
| 557 | return FALSE(0); | |||
| 558 | } | |||
| 559 | #endif | |||
| 560 | return TRUE(!(0)); | |||
| 561 | } | |||
| 562 | ||||
| 563 | /** | |||
| 564 | * cdk_pixbuf_init_modules: | |||
| 565 | * @path: Path to directory where the `loaders.cache` is installed | |||
| 566 | * @error: return location for a `GError` | |||
| 567 | * | |||
| 568 | * Initalizes the cdk-pixbuf loader modules referenced by the `loaders.cache` | |||
| 569 | * file present inside that directory. | |||
| 570 | * | |||
| 571 | * This is to be used by applications that want to ship certain loaders | |||
| 572 | * in a different location from the system ones. | |||
| 573 | * | |||
| 574 | * This is needed when the OS or runtime ships a minimal number of loaders | |||
| 575 | * so as to reduce the potential attack surface of carefully crafted image | |||
| 576 | * files, especially for uncommon file types. Applications that require | |||
| 577 | * broader image file types coverage, such as image viewers, would be | |||
| 578 | * expected to ship the cdk-pixbuf modules in a separate location, bundled | |||
| 579 | * with the application in a separate directory from the OS or runtime- | |||
| 580 | * provided modules. | |||
| 581 | * | |||
| 582 | * Since: 2.40 | |||
| 583 | */ | |||
| 584 | gboolean | |||
| 585 | cdk_pixbuf_init_modules (const char *path, | |||
| 586 | GError **error) | |||
| 587 | { | |||
| 588 | char *filename; | |||
| 589 | gboolean ret; | |||
| 590 | ||||
| 591 | g_return_val_if_fail (path != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_89 = 0; if (path != ((void*)0)) _g_boolean_var_89 = 1; _g_boolean_var_89 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "path != NULL"); return ((0)); } } while (0); | |||
| 592 | filename = g_build_filename (path, "loaders.cache", NULL((void*)0)); | |||
| 593 | ret = cdk_pixbuf_io_init_modules (filename, error); | |||
| 594 | g_free (filename); | |||
| 595 | return ret; | |||
| 596 | } | |||
| 597 | ||||
| 598 | static void | |||
| 599 | cdk_pixbuf_io_init_builtin (void) | |||
| 600 | { | |||
| 601 | #define load_one_builtin_module(format) G_STMT_STARTdo { \ | |||
| 602 | CdkPixbufModule *__builtin_module = g_new0 (CdkPixbufModule, 1)(CdkPixbufModule *) (__extension__ ({ gsize __n = (gsize) (1) ; gsize __s = sizeof (CdkPixbufModule); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p ( __n) && (__s == 0 || __n <= (9223372036854775807L * 2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p; })); \ | |||
| 603 | __builtin_module->module_name = #format; \ | |||
| 604 | if (cdk_pixbuf_load_module_unlocked (__builtin_module, NULL((void*)0))) \ | |||
| 605 | file_formats = g_slist_prepend (file_formats, __builtin_module); \ | |||
| 606 | else \ | |||
| 607 | g_free (__builtin_module); } G_STMT_ENDwhile (0) | |||
| 608 | ||||
| 609 | #ifdef INCLUDE_ani | |||
| 610 | load_one_builtin_module (ani); | |||
| 611 | #endif | |||
| 612 | #ifdef INCLUDE_png1 | |||
| 613 | load_one_builtin_module (png); | |||
| 614 | #endif | |||
| 615 | #ifdef INCLUDE_bmp | |||
| 616 | load_one_builtin_module (bmp); | |||
| 617 | #endif | |||
| 618 | #ifdef INCLUDE_gif | |||
| 619 | load_one_builtin_module (gif); | |||
| 620 | #endif | |||
| 621 | #ifdef INCLUDE_ico | |||
| 622 | load_one_builtin_module (ico); | |||
| 623 | #endif | |||
| 624 | #ifdef INCLUDE_jpeg1 | |||
| 625 | load_one_builtin_module (jpeg); | |||
| 626 | #endif | |||
| 627 | #ifdef INCLUDE_pnm | |||
| 628 | load_one_builtin_module (pnm); | |||
| 629 | #endif | |||
| 630 | #ifdef INCLUDE_tiff | |||
| 631 | load_one_builtin_module (tiff); | |||
| 632 | #endif | |||
| 633 | #ifdef INCLUDE_xpm | |||
| 634 | load_one_builtin_module (xpm); | |||
| 635 | #endif | |||
| 636 | #ifdef INCLUDE_xbm | |||
| 637 | load_one_builtin_module (xbm); | |||
| 638 | #endif | |||
| 639 | #ifdef INCLUDE_tga | |||
| 640 | load_one_builtin_module (tga); | |||
| 641 | #endif | |||
| 642 | #ifdef INCLUDE_icns | |||
| 643 | load_one_builtin_module (icns); | |||
| 644 | #endif | |||
| 645 | #ifdef INCLUDE_qtif | |||
| 646 | load_one_builtin_module (qtif); | |||
| 647 | #endif | |||
| 648 | #ifdef INCLUDE_gdiplus | |||
| 649 | /* We don't bother having the GDI+ loaders individually selectable | |||
| 650 | * for building in or not. | |||
| 651 | */ | |||
| 652 | load_one_builtin_module (ico); | |||
| 653 | load_one_builtin_module (wmf); | |||
| 654 | load_one_builtin_module (emf); | |||
| 655 | load_one_builtin_module (bmp); | |||
| 656 | load_one_builtin_module (gif); | |||
| 657 | load_one_builtin_module (jpeg); | |||
| 658 | load_one_builtin_module (tiff); | |||
| 659 | #endif | |||
| 660 | #ifdef INCLUDE_gdip_png | |||
| 661 | /* Except the gdip-png loader which normally isn't built at all even */ | |||
| 662 | load_one_builtin_module (png); | |||
| 663 | #endif | |||
| 664 | #ifdef INCLUDE_glycin | |||
| 665 | load_one_builtin_module (avif); | |||
| 666 | load_one_builtin_module (bmp); | |||
| 667 | load_one_builtin_module (dds); | |||
| 668 | load_one_builtin_module (gif); | |||
| 669 | load_one_builtin_module (heic); | |||
| 670 | load_one_builtin_module (ico); | |||
| 671 | load_one_builtin_module (jpeg); | |||
| 672 | load_one_builtin_module (jxl); | |||
| 673 | load_one_builtin_module (openexr); | |||
| 674 | load_one_builtin_module (png); | |||
| 675 | load_one_builtin_module (pnm); | |||
| 676 | load_one_builtin_module (qoi); | |||
| 677 | load_one_builtin_module (raw); | |||
| 678 | load_one_builtin_module (svg); | |||
| 679 | load_one_builtin_module (tga); | |||
| 680 | load_one_builtin_module (tiff); | |||
| 681 | load_one_builtin_module (webp); | |||
| 682 | load_one_builtin_module (xbm); | |||
| 683 | load_one_builtin_module (xpm); | |||
| 684 | #endif | |||
| 685 | #ifdef INCLUDE_android | |||
| 686 | load_one_builtin_module (jpeg); | |||
| 687 | load_one_builtin_module (png); | |||
| 688 | load_one_builtin_module (gif); | |||
| 689 | load_one_builtin_module (webp); | |||
| 690 | load_one_builtin_module (bmp); | |||
| 691 | load_one_builtin_module (ico); | |||
| 692 | load_one_builtin_module (wbmp); | |||
| 693 | load_one_builtin_module (heif); | |||
| 694 | #endif | |||
| 695 | ||||
| 696 | #undef load_one_builtin_module | |||
| 697 | } | |||
| 698 | ||||
| 699 | static gboolean | |||
| 700 | cdk_pixbuf_io_init (void) | |||
| 701 | { | |||
| 702 | #ifdef USE_GMODULE | |||
| 703 | char *module_file; | |||
| 704 | ||||
| 705 | module_file = cdk_pixbuf_get_module_file (); | |||
| 706 | cdk_pixbuf_io_init_modules (module_file, NULL((void*)0)); | |||
| 707 | g_free (module_file); | |||
| 708 | #endif | |||
| 709 | ||||
| 710 | cdk_pixbuf_io_init_builtin (); | |||
| 711 | ||||
| 712 | return file_formats != NULL((void*)0); | |||
| 713 | } | |||
| 714 | ||||
| 715 | #define module(type) \ | |||
| 716 | extern void _cdk_pixbuf__##type##_fill_info (CdkPixbufFormat *info); \ | |||
| 717 | extern void _cdk_pixbuf__##type##_fill_vtable (CdkPixbufModule *module) | |||
| 718 | ||||
| 719 | module (png); | |||
| 720 | module (jpeg); | |||
| 721 | module (gif); | |||
| 722 | module (ico); | |||
| 723 | module (ani); | |||
| 724 | module (xpm); | |||
| 725 | module (tiff); | |||
| 726 | module (pnm); | |||
| 727 | module (bmp); | |||
| 728 | module (xbm); | |||
| 729 | module (tga); | |||
| 730 | module (icns); | |||
| 731 | module (qtif); | |||
| 732 | module (gdip_ico); | |||
| 733 | module (gdip_wmf); | |||
| 734 | module (gdip_emf); | |||
| 735 | module (gdip_bmp); | |||
| 736 | module (gdip_gif); | |||
| 737 | module (gdip_jpeg); | |||
| 738 | module (gdip_png); | |||
| 739 | module (gdip_tiff); | |||
| 740 | ||||
| 741 | module (glycin_avif); | |||
| 742 | module (glycin_bmp); | |||
| 743 | module (glycin_dds); | |||
| 744 | module (glycin_gif); | |||
| 745 | module (glycin_heic); | |||
| 746 | module (glycin_ico); | |||
| 747 | module (glycin_jpeg); | |||
| 748 | module (glycin_jxl); | |||
| 749 | module (glycin_openexr); | |||
| 750 | module (glycin_png); | |||
| 751 | module (glycin_pnm); | |||
| 752 | module (glycin_qoi); | |||
| 753 | module (glycin_raw); | |||
| 754 | module (glycin_svg); | |||
| 755 | module (glycin_tga); | |||
| 756 | module (glycin_tiff); | |||
| 757 | module (glycin_webp); | |||
| 758 | module (glycin_xbm); | |||
| 759 | module (glycin_xpm); | |||
| 760 | ||||
| 761 | module (android_jpeg); | |||
| 762 | module (android_png); | |||
| 763 | module (android_gif); | |||
| 764 | module (android_webp); | |||
| 765 | module (android_bmp); | |||
| 766 | module (android_ico); | |||
| 767 | module (android_wbmp); | |||
| 768 | module (android_heif); | |||
| 769 | ||||
| 770 | #undef module | |||
| 771 | ||||
| 772 | /* actually load the image handler - cdk_pixbuf_get_module only get a */ | |||
| 773 | /* reference to the module to load, it doesn't actually load it */ | |||
| 774 | /* perhaps these actions should be combined in one function */ | |||
| 775 | static gboolean | |||
| 776 | cdk_pixbuf_load_module_unlocked (CdkPixbufModule *image_module, | |||
| 777 | GError **error) | |||
| 778 | { | |||
| 779 | CdkPixbufModuleFillInfoFunc fill_info = NULL((void*)0); | |||
| 780 | CdkPixbufModuleFillVtableFunc fill_vtable = NULL((void*)0); | |||
| 781 | ||||
| 782 | if (image_module->module != NULL((void*)0)) | |||
| 783 | return TRUE(!(0)); | |||
| 784 | ||||
| 785 | #define try_module(format,id) \ | |||
| 786 | if (fill_info == NULL((void*)0) && \ | |||
| 787 | strcmp (image_module->module_name, #format) == 0) { \ | |||
| 788 | fill_info = _cdk_pixbuf__##id##_fill_info; \ | |||
| 789 | fill_vtable = _cdk_pixbuf__##id##_fill_vtable; \ | |||
| 790 | } | |||
| 791 | ||||
| 792 | #ifdef INCLUDE_gdiplus | |||
| 793 | try_module (ico,gdip_ico); | |||
| 794 | try_module (wmf,gdip_wmf); | |||
| 795 | try_module (emf,gdip_emf); | |||
| 796 | try_module (bmp,gdip_bmp); | |||
| 797 | try_module (gif,gdip_gif); | |||
| 798 | try_module (jpeg,gdip_jpeg); | |||
| 799 | try_module (tiff,gdip_tiff); | |||
| 800 | #endif | |||
| 801 | #ifdef INCLUDE_gdip_png | |||
| 802 | try_module (png,gdip_png); | |||
| 803 | #endif | |||
| 804 | #ifdef INCLUDE_glycin | |||
| 805 | try_module (avif, glycin_avif); | |||
| 806 | try_module (bmp, glycin_bmp); | |||
| 807 | try_module (dds, glycin_dds); | |||
| 808 | try_module (gif, glycin_gif); | |||
| 809 | try_module (heic, glycin_heic); | |||
| 810 | try_module (ico, glycin_ico); | |||
| 811 | try_module (jpeg, glycin_jpeg); | |||
| 812 | try_module (jxl, glycin_jxl); | |||
| 813 | try_module (openexr, glycin_openexr); | |||
| 814 | try_module (png, glycin_png); | |||
| 815 | try_module (pnm, glycin_pnm); | |||
| 816 | try_module (qoi, glycin_qoi); | |||
| 817 | try_module (raw, glycin_raw); | |||
| 818 | try_module (svg, glycin_svg); | |||
| 819 | try_module (tga, glycin_tga); | |||
| 820 | try_module (tiff, glycin_tiff); | |||
| 821 | try_module (webp, glycin_webp); | |||
| 822 | try_module (xbm, glycin_xbm); | |||
| 823 | try_module (xpm, glycin_xpm); | |||
| 824 | #endif | |||
| 825 | #ifdef INCLUDE_android | |||
| 826 | try_module (jpeg,android_jpeg); | |||
| 827 | try_module (png,android_png); | |||
| 828 | try_module (gif,android_gif); | |||
| 829 | try_module (webp,android_webp); | |||
| 830 | try_module (bmp,android_bmp); | |||
| 831 | try_module (ico,android_ico); | |||
| 832 | try_module (wbmp,android_wbmp); | |||
| 833 | try_module (heif,android_heif); | |||
| 834 | #endif | |||
| 835 | #ifdef INCLUDE_png1 | |||
| 836 | try_module (png,png); | |||
| 837 | #endif | |||
| 838 | #ifdef INCLUDE_bmp | |||
| 839 | try_module (bmp,bmp); | |||
| 840 | #endif | |||
| 841 | #ifdef INCLUDE_gif | |||
| 842 | try_module (gif,gif); | |||
| 843 | #endif | |||
| 844 | #ifdef INCLUDE_ico | |||
| 845 | try_module (ico,ico); | |||
| 846 | #endif | |||
| 847 | #ifdef INCLUDE_ani | |||
| 848 | try_module (ani,ani); | |||
| 849 | #endif | |||
| 850 | #ifdef INCLUDE_jpeg1 | |||
| 851 | try_module (jpeg,jpeg); | |||
| 852 | #endif | |||
| 853 | #ifdef INCLUDE_pnm | |||
| 854 | try_module (pnm,pnm); | |||
| 855 | #endif | |||
| 856 | #ifdef INCLUDE_tiff | |||
| 857 | try_module (tiff,tiff); | |||
| 858 | #endif | |||
| 859 | #ifdef INCLUDE_xpm | |||
| 860 | try_module (xpm,xpm); | |||
| 861 | #endif | |||
| 862 | #ifdef INCLUDE_xbm | |||
| 863 | try_module (xbm,xbm); | |||
| 864 | #endif | |||
| 865 | #ifdef INCLUDE_tga | |||
| 866 | try_module (tga,tga); | |||
| 867 | #endif | |||
| 868 | #ifdef INCLUDE_icns | |||
| 869 | try_module (icns,icns); | |||
| 870 | #endif | |||
| 871 | #ifdef INCLUDE_qtif | |||
| 872 | try_module (qtif,qtif); | |||
| 873 | #endif | |||
| 874 | ||||
| 875 | #undef try_module | |||
| 876 | ||||
| 877 | if (fill_vtable) { | |||
| 878 | image_module->module = (void *) 1; | |||
| 879 | (* fill_vtable) (image_module); | |||
| 880 | if (image_module->info == NULL((void*)0)) { | |||
| 881 | image_module->info = g_new0 (CdkPixbufFormat, 1)(CdkPixbufFormat *) (__extension__ ({ gsize __n = (gsize) (1) ; gsize __s = sizeof (CdkPixbufFormat); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p ( __n) && (__s == 0 || __n <= (9223372036854775807L * 2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p; })); | |||
| 882 | (* fill_info) (image_module->info); | |||
| 883 | } | |||
| 884 | return TRUE(!(0)); | |||
| 885 | } | |||
| 886 | else | |||
| 887 | #ifdef USE_GMODULE | |||
| 888 | { | |||
| 889 | char *path; | |||
| 890 | GModule *module; | |||
| 891 | gpointer sym; | |||
| 892 | ||||
| 893 | path = image_module->module_path; | |||
| 894 | module = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); | |||
| 895 | ||||
| 896 | if (!module) { | |||
| 897 | char *path_utf8 = g_filename_display_name (path); | |||
| 898 | g_set_error (error, | |||
| 899 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 900 | CDK_PIXBUF_ERROR_FAILED, | |||
| 901 | _("Unable to load image-loading module: %s: %s")((char *) g_dgettext ("cdk-pixbuf", "Unable to load image-loading module: %s: %s" )), | |||
| 902 | path_utf8, g_module_error ()); | |||
| 903 | g_free (path_utf8); | |||
| 904 | return FALSE(0); | |||
| 905 | } | |||
| 906 | ||||
| 907 | image_module->module = module; | |||
| 908 | ||||
| 909 | ||||
| 910 | if (g_module_symbol (module, "fill_vtable", &sym)) { | |||
| 911 | fill_vtable = (CdkPixbufModuleFillVtableFunc) sym; | |||
| 912 | (* fill_vtable) (image_module); | |||
| 913 | return TRUE(!(0)); | |||
| 914 | } else { | |||
| 915 | char *path_utf8 = g_filename_display_name (path); | |||
| 916 | g_set_error (error, | |||
| 917 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 918 | CDK_PIXBUF_ERROR_FAILED, | |||
| 919 | _("Image-loading module %s does not export the proper interface; perhaps it’s from a different cdk-pixbuf version?")((char *) g_dgettext ("cdk-pixbuf", "Image-loading module %s does not export the proper interface; perhaps it’s from a different cdk-pixbuf version?" )), | |||
| 920 | path_utf8); | |||
| 921 | g_free (path_utf8); | |||
| 922 | return FALSE(0); | |||
| 923 | } | |||
| 924 | } | |||
| 925 | #else | |||
| 926 | g_set_error (error, | |||
| 927 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 928 | CDK_PIXBUF_ERROR_UNKNOWN_TYPE, | |||
| 929 | _("Image type “%s” is not supported")((char *) g_dgettext ("cdk-pixbuf", "Image type “%s” is not supported" )), | |||
| 930 | image_module->module_name); | |||
| 931 | return FALSE(0); | |||
| 932 | #endif /* !USE_GMODULE */ | |||
| 933 | } | |||
| 934 | ||||
| 935 | ||||
| 936 | gboolean | |||
| 937 | _cdk_pixbuf_load_module (CdkPixbufModule *image_module, | |||
| 938 | GError **error) | |||
| 939 | { | |||
| 940 | gboolean ret; | |||
| 941 | ||||
| 942 | G_LOCK (init_lock)g_mutex_lock (&g__init_lock_lock); | |||
| 943 | ||||
| 944 | ret = cdk_pixbuf_load_module_unlocked (image_module, error); | |||
| 945 | ||||
| 946 | G_UNLOCK (init_lock)g_mutex_unlock (&g__init_lock_lock); | |||
| 947 | ||||
| 948 | return ret; | |||
| 949 | } | |||
| 950 | ||||
| 951 | ||||
| 952 | ||||
| 953 | CdkPixbufModule * | |||
| 954 | _cdk_pixbuf_get_named_module (const char *name, | |||
| 955 | GError **error) | |||
| 956 | { | |||
| 957 | GSList *modules; | |||
| 958 | ||||
| 959 | for (modules = get_file_formats (); modules; modules = g_slist_next (modules)((modules) ? (((GSList *)(modules))->next) : ((void*)0))) { | |||
| 960 | CdkPixbufModule *module = (CdkPixbufModule *)modules->data; | |||
| 961 | ||||
| 962 | if (module->info->disabled) | |||
| 963 | continue; | |||
| 964 | ||||
| 965 | if (!strcmp (name, module->module_name)) | |||
| 966 | return module; | |||
| 967 | } | |||
| 968 | ||||
| 969 | g_set_error (error, | |||
| 970 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 971 | CDK_PIXBUF_ERROR_UNKNOWN_TYPE, | |||
| 972 | _("Image type “%s” is not supported")((char *) g_dgettext ("cdk-pixbuf", "Image type “%s” is not supported" )), | |||
| 973 | name); | |||
| 974 | ||||
| 975 | return NULL((void*)0); | |||
| 976 | } | |||
| 977 | ||||
| 978 | CdkPixbufModule * | |||
| 979 | _cdk_pixbuf_get_module (guchar *buffer, guint size, | |||
| 980 | const gchar *filename, | |||
| 981 | GError **error) | |||
| 982 | { | |||
| 983 | GSList *modules; | |||
| 984 | ||||
| 985 | CdkPixbufModule *selected = NULL((void*)0); | |||
| 986 | gchar *display_name = NULL((void*)0); | |||
| 987 | #ifdef CDK_PIXBUF_USE_GIO_MIME1 | |||
| 988 | gchar *mime_type; | |||
| 989 | gchar **mimes; | |||
| 990 | gchar *type; | |||
| 991 | gint j; | |||
| 992 | gboolean uncertain; | |||
| 993 | ||||
| 994 | mime_type = g_content_type_guess (NULL((void*)0), buffer, size, &uncertain); | |||
| 995 | if ((uncertain || g_str_equal (mime_type, "text/plain")(strcmp ((const char *) (mime_type), (const char *) ("text/plain" )) == 0) || g_str_equal (mime_type, "application/gzip")(strcmp ((const char *) (mime_type), (const char *) ("application/gzip" )) == 0)) && filename != NULL((void*)0)) { | |||
| 996 | g_free (mime_type); | |||
| 997 | mime_type = g_content_type_guess (filename, buffer, size, NULL((void*)0)); | |||
| 998 | } | |||
| 999 | ||||
| 1000 | for (modules = get_file_formats (); modules; modules = g_slist_next (modules)((modules) ? (((GSList *)(modules))->next) : ((void*)0))) { | |||
| 1001 | CdkPixbufModule *module = (CdkPixbufModule *)modules->data; | |||
| 1002 | CdkPixbufFormat *info = module->info; | |||
| 1003 | ||||
| 1004 | if (info->disabled) | |||
| 1005 | continue; | |||
| 1006 | ||||
| 1007 | mimes = info->mime_types; | |||
| 1008 | for (j = 0; mimes[j] != NULL((void*)0); j++) { | |||
| 1009 | type = g_content_type_from_mime_type (mimes[j]); | |||
| 1010 | if (g_content_type_equals (type, mime_type)) { | |||
| 1011 | g_free (type); | |||
| 1012 | selected = module; | |||
| 1013 | break; | |||
| 1014 | } | |||
| 1015 | g_free (type); | |||
| 1016 | } | |||
| 1017 | ||||
| 1018 | if (selected != NULL((void*)0)) | |||
| 1019 | break; | |||
| 1020 | ||||
| 1021 | /* Make sure the builtin CdkPixdata support works even without mime sniffing */ | |||
| 1022 | if (strcmp (info->name, "CdkPixdata") == 0 && | |||
| 1023 | format_check (module, buffer, size) == 100) { | |||
| 1024 | selected = module; | |||
| 1025 | break; | |||
| 1026 | } | |||
| 1027 | } | |||
| 1028 | g_free (mime_type); | |||
| 1029 | #else | |||
| 1030 | gint score, best = 0; | |||
| 1031 | ||||
| 1032 | for (modules = get_file_formats (); modules; modules = g_slist_next (modules)((modules) ? (((GSList *)(modules))->next) : ((void*)0))) { | |||
| 1033 | CdkPixbufModule *module = (CdkPixbufModule *)modules->data; | |||
| 1034 | ||||
| 1035 | if (module->info->disabled) | |||
| 1036 | continue; | |||
| 1037 | ||||
| 1038 | score = format_check (module, buffer, size); | |||
| 1039 | if (score > best) { | |||
| 1040 | best = score; | |||
| 1041 | selected = module; | |||
| 1042 | } | |||
| 1043 | if (score >= 100) | |||
| 1044 | break; | |||
| 1045 | } | |||
| 1046 | #endif | |||
| 1047 | ||||
| 1048 | if (selected != NULL((void*)0)) | |||
| 1049 | return selected; | |||
| 1050 | ||||
| 1051 | if (filename) | |||
| 1052 | { | |||
| 1053 | display_name = g_filename_display_name (filename); | |||
| 1054 | g_set_error (error, | |||
| 1055 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 1056 | CDK_PIXBUF_ERROR_UNKNOWN_TYPE, | |||
| 1057 | _("Couldn’t recognize the image file format for file “%s”")((char *) g_dgettext ("cdk-pixbuf", "Couldn’t recognize the image file format for file “%s”" )), | |||
| 1058 | display_name); | |||
| 1059 | g_free (display_name); | |||
| 1060 | } | |||
| 1061 | else | |||
| 1062 | g_set_error_literal (error, | |||
| 1063 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 1064 | CDK_PIXBUF_ERROR_UNKNOWN_TYPE, | |||
| 1065 | _("Unrecognized image file format")((char *) g_dgettext ("cdk-pixbuf", "Unrecognized image file format" ))); | |||
| 1066 | ||||
| 1067 | ||||
| 1068 | return NULL((void*)0); | |||
| 1069 | } | |||
| 1070 | ||||
| 1071 | static | |||
| 1072 | CdkPixbufModule * | |||
| 1073 | _cdk_pixbuf_get_module_for_file (FILE *f, const gchar *filename, GError **error) | |||
| 1074 | { | |||
| 1075 | guchar buffer[SNIFF_BUFFER_SIZE4096]; | |||
| 1076 | int size; | |||
| 1077 | ||||
| 1078 | size = fread (&buffer, 1, sizeof (buffer), f); | |||
| 1079 | if (size == 0) { | |||
| 1080 | gchar *display_name; | |||
| 1081 | display_name = g_filename_display_name (filename); | |||
| 1082 | g_set_error (error, | |||
| 1083 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 1084 | CDK_PIXBUF_ERROR_CORRUPT_IMAGE, | |||
| 1085 | _("Image file “%s” contains no data")((char *) g_dgettext ("cdk-pixbuf", "Image file “%s” contains no data" )), | |||
| 1086 | display_name); | |||
| 1087 | g_free (display_name); | |||
| 1088 | return NULL((void*)0); | |||
| 1089 | } | |||
| 1090 | ||||
| 1091 | return _cdk_pixbuf_get_module (buffer, size, filename, error); | |||
| 1092 | } | |||
| 1093 | ||||
| 1094 | static void | |||
| 1095 | noop_size_notify (gint *width, | |||
| 1096 | gint *height, | |||
| 1097 | gpointer data) | |||
| 1098 | { | |||
| 1099 | } | |||
| 1100 | ||||
| 1101 | static void | |||
| 1102 | prepared_notify (CdkPixbuf *pixbuf, | |||
| 1103 | CdkPixbufAnimation *anim, | |||
| 1104 | gpointer user_data) | |||
| 1105 | { | |||
| 1106 | if (pixbuf != NULL((void*)0)) | |||
| 1107 | g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf)); | |||
| 1108 | *((CdkPixbuf **)user_data) = pixbuf; | |||
| 1109 | } | |||
| 1110 | ||||
| 1111 | static void | |||
| 1112 | noop_updated_notify (CdkPixbuf *pixbuf, | |||
| 1113 | int x, | |||
| 1114 | int y, | |||
| 1115 | int width, | |||
| 1116 | int height, | |||
| 1117 | gpointer user_data) | |||
| 1118 | { | |||
| 1119 | } | |||
| 1120 | ||||
| 1121 | static CdkPixbuf * | |||
| 1122 | generic_load_incrementally (CdkPixbufModule *module, FILE *f, GError **error) | |||
| 1123 | { | |||
| 1124 | CdkPixbuf *pixbuf = NULL((void*)0); | |||
| 1125 | gpointer context; | |||
| 1126 | ||||
| 1127 | context = module->begin_load (noop_size_notify, prepared_notify, noop_updated_notify, &pixbuf, error); | |||
| 1128 | ||||
| 1129 | if (!context) | |||
| 1130 | goto out; | |||
| 1131 | ||||
| 1132 | while (!feof (f) && !ferror (f)) { | |||
| 1133 | guchar buffer[LOAD_BUFFER_SIZE65536]; | |||
| 1134 | size_t length; | |||
| 1135 | ||||
| 1136 | length = fread (buffer, 1, sizeof (buffer), f); | |||
| 1137 | if (length > 0) { | |||
| 1138 | if (!module->load_increment (context, buffer, length, error)) { | |||
| 1139 | module->stop_load (context, NULL((void*)0)); | |||
| 1140 | if (pixbuf != NULL((void*)0)) { | |||
| 1141 | g_object_unref (pixbuf); | |||
| 1142 | pixbuf = NULL((void*)0); | |||
| 1143 | } | |||
| 1144 | goto out; | |||
| 1145 | } | |||
| 1146 | } | |||
| 1147 | } | |||
| 1148 | ||||
| 1149 | if (!module->stop_load (context, error)) { | |||
| 1150 | if (pixbuf != NULL((void*)0)) { | |||
| 1151 | g_object_unref (pixbuf); | |||
| 1152 | pixbuf = NULL((void*)0); | |||
| 1153 | } | |||
| 1154 | } | |||
| 1155 | ||||
| 1156 | out: | |||
| 1157 | return pixbuf; | |||
| 1158 | } | |||
| 1159 | ||||
| 1160 | CdkPixbuf * | |||
| 1161 | _cdk_pixbuf_generic_image_load (CdkPixbufModule *module, FILE *f, GError **error) | |||
| 1162 | { | |||
| 1163 | CdkPixbuf *pixbuf = NULL((void*)0); | |||
| 1164 | ||||
| 1165 | if (module->load != NULL((void*)0)) { | |||
| 1166 | pixbuf = (* module->load) (f, error); | |||
| 1167 | } else if (module->begin_load != NULL((void*)0)) { | |||
| 1168 | pixbuf = generic_load_incrementally (module, f, error); | |||
| 1169 | } else if (module->load_animation != NULL((void*)0)) { | |||
| 1170 | CdkPixbufAnimation *animation; | |||
| 1171 | ||||
| 1172 | animation = (* module->load_animation) (f, error); | |||
| 1173 | if (animation != NULL((void*)0)) { | |||
| 1174 | pixbuf = cdk_pixbuf_animation_get_static_image (animation); | |||
| 1175 | ||||
| 1176 | g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf)); | |||
| 1177 | g_object_unref (animation); | |||
| 1178 | } | |||
| 1179 | } | |||
| 1180 | ||||
| 1181 | return pixbuf; | |||
| 1182 | } | |||
| 1183 | ||||
| 1184 | /** | |||
| 1185 | * cdk_pixbuf_new_from_file: (constructor) | |||
| 1186 | * @filename: (type filename): Name of file to load, in the GLib file | |||
| 1187 | * name encoding | |||
| 1188 | * @error: (out): Return location for an error | |||
| 1189 | * | |||
| 1190 | * Creates a new pixbuf by loading an image from a file. | |||
| 1191 | * | |||
| 1192 | * The file format is detected automatically. | |||
| 1193 | * | |||
| 1194 | * If `NULL` is returned, then @error will be set. Possible errors are: | |||
| 1195 | * | |||
| 1196 | * - the file could not be opened | |||
| 1197 | * - there is no loader for the file's format | |||
| 1198 | * - there is not enough memory to allocate the image buffer | |||
| 1199 | * - the image buffer contains invalid data | |||
| 1200 | * | |||
| 1201 | * The error domains are `CDK_PIXBUF_ERROR` and `G_FILE_ERROR`. | |||
| 1202 | * | |||
| 1203 | * Returns: (nullable): A newly-created pixbuf | |||
| 1204 | */ | |||
| 1205 | CdkPixbuf * | |||
| 1206 | cdk_pixbuf_new_from_file (const char *filename, | |||
| 1207 | GError **error) | |||
| 1208 | { | |||
| 1209 | CdkPixbuf *pixbuf; | |||
| 1210 | FILE *f; | |||
| 1211 | CdkPixbufModule *image_module; | |||
| 1212 | ||||
| 1213 | g_return_val_if_fail (filename != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_90 = 0; if (filename != ((void*)0)) _g_boolean_var_90 = 1; _g_boolean_var_90 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "filename != NULL"); return (((void *)0)); } } while (0); | |||
| 1214 | g_return_val_if_fail (error == NULL || *error == NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_91 = 0; if (error == ((void*)0) || *error == ((void*)0)) _g_boolean_var_91 = 1; _g_boolean_var_91; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "error == NULL || *error == NULL" ); return (((void*)0)); } } while (0); | |||
| 1215 | ||||
| 1216 | f = g_fopenfopen (filename, "rb"); | |||
| 1217 | if (!f) { | |||
| 1218 | gint save_errno = errno(*__errno_location ()); | |||
| 1219 | gchar *display_name; | |||
| 1220 | display_name = g_filename_display_name (filename); | |||
| 1221 | g_set_error (error, | |||
| 1222 | G_FILE_ERRORg_file_error_quark (), | |||
| 1223 | g_file_error_from_errno (save_errno), | |||
| 1224 | _("Failed to open file “%s”: %s")((char *) g_dgettext ("cdk-pixbuf", "Failed to open file “%s”: %s" )), | |||
| 1225 | display_name, | |||
| 1226 | g_strerror (save_errno)); | |||
| 1227 | g_free (display_name); | |||
| 1228 | return NULL((void*)0); | |||
| 1229 | } | |||
| 1230 | ||||
| 1231 | image_module = _cdk_pixbuf_get_module_for_file (f, filename, error); | |||
| 1232 | if (image_module == NULL((void*)0)) { | |||
| 1233 | fclose (f); | |||
| 1234 | return NULL((void*)0); | |||
| 1235 | } | |||
| 1236 | ||||
| 1237 | if (!_cdk_pixbuf_load_module (image_module, error)) { | |||
| 1238 | fclose (f); | |||
| 1239 | return NULL((void*)0); | |||
| 1240 | } | |||
| 1241 | ||||
| 1242 | fseek (f, 0, SEEK_SET0); | |||
| 1243 | pixbuf = _cdk_pixbuf_generic_image_load (image_module, f, error); | |||
| 1244 | fclose (f); | |||
| 1245 | ||||
| 1246 | if (pixbuf == NULL((void*)0) && error != NULL((void*)0) && *error == NULL((void*)0)) { | |||
| 1247 | ||||
| 1248 | /* I don't trust these crufty longjmp()'ing image libs | |||
| 1249 | * to maintain proper error invariants, and I don't | |||
| 1250 | * want user code to segfault as a result. We need to maintain | |||
| 1251 | * the invariant that error gets set if NULL is returned. | |||
| 1252 | */ | |||
| 1253 | ||||
| 1254 | gchar *display_name; | |||
| 1255 | display_name = g_filename_display_name (filename); | |||
| 1256 | g_warning ("Bug! cdk-pixbuf loader '%s' didn't set an error on failure.", image_module->module_name); | |||
| 1257 | g_set_error (error, | |||
| 1258 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 1259 | CDK_PIXBUF_ERROR_FAILED, | |||
| 1260 | _("Failed to load image “%s”: reason not known, probably a corrupt image file")((char *) g_dgettext ("cdk-pixbuf", "Failed to load image “%s”: reason not known, probably a corrupt image file" )), | |||
| 1261 | display_name); | |||
| 1262 | g_free (display_name); | |||
| 1263 | } else if (error != NULL((void*)0) && *error != NULL((void*)0)) { | |||
| 1264 | /* Add the filename to the error message */ | |||
| 1265 | GError *e = *error; | |||
| 1266 | gchar *old; | |||
| 1267 | gchar *display_name; | |||
| 1268 | ||||
| 1269 | display_name = g_filename_display_name (filename); | |||
| 1270 | old = e->message; | |||
| 1271 | e->message = g_strdup_printf (_("Failed to load image “%s”: %s")((char *) g_dgettext ("cdk-pixbuf", "Failed to load image “%s”: %s" )), | |||
| 1272 | display_name, | |||
| 1273 | old); | |||
| 1274 | g_free (old); | |||
| 1275 | g_free (display_name); | |||
| 1276 | } | |||
| 1277 | ||||
| 1278 | return pixbuf; | |||
| 1279 | } | |||
| 1280 | ||||
| 1281 | #ifdef G_OS_WIN32 | |||
| 1282 | ||||
| 1283 | /** | |||
| 1284 | * cdk_pixbuf_new_from_file_utf8: (constructor) | |||
| 1285 | * @filename: (type filename): Name of file to load, in the GLib file name encoding | |||
| 1286 | * @error: Return location for an error | |||
| 1287 | * | |||
| 1288 | * Same as cdk_pixbuf_new_from_file() | |||
| 1289 | * | |||
| 1290 | * Returns: (nullable): A newly-created pixbuf with a reference count of 1, | |||
| 1291 | * or `NULL` if any of several error conditions occurred: the file could not be opened, | |||
| 1292 | * there was no loader for the file's format, there was not enough memory to | |||
| 1293 | * allocate the image buffer, or the image file contained invalid data. | |||
| 1294 | **/ | |||
| 1295 | CdkPixbuf * | |||
| 1296 | cdk_pixbuf_new_from_file_utf8 (const char *filename, | |||
| 1297 | GError **error) | |||
| 1298 | { | |||
| 1299 | return cdk_pixbuf_new_from_file (filename, error); | |||
| 1300 | } | |||
| 1301 | ||||
| 1302 | #endif | |||
| 1303 | ||||
| 1304 | ||||
| 1305 | /** | |||
| 1306 | * cdk_pixbuf_new_from_file_at_size: (constructor) | |||
| 1307 | * @filename: (type filename): Name of file to load, in the GLib file | |||
| 1308 | * name encoding | |||
| 1309 | * @width: The width the image should have or -1 to not constrain the width | |||
| 1310 | * @height: The height the image should have or -1 to not constrain the height | |||
| 1311 | * @error: (out): Return location for an error | |||
| 1312 | * | |||
| 1313 | * Creates a new pixbuf by loading an image from a file. | |||
| 1314 | * | |||
| 1315 | * The file format is detected automatically. | |||
| 1316 | * | |||
| 1317 | * If `NULL` is returned, then @error will be set. Possible errors are: | |||
| 1318 | * | |||
| 1319 | * - the file could not be opened | |||
| 1320 | * - there is no loader for the file's format | |||
| 1321 | * - there is not enough memory to allocate the image buffer | |||
| 1322 | * - the image buffer contains invalid data | |||
| 1323 | * | |||
| 1324 | * The error domains are `CDK_PIXBUF_ERROR` and `G_FILE_ERROR`. | |||
| 1325 | * | |||
| 1326 | * The image will be scaled to fit in the requested size, preserving | |||
| 1327 | * the image's aspect ratio. Note that the returned pixbuf may be smaller | |||
| 1328 | * than `width` x `height`, if the aspect ratio requires it. To load | |||
| 1329 | * and image at the requested size, regardless of aspect ratio, use | |||
| 1330 | * [ctor@CdkPixbuf.Pixbuf.new_from_file_at_scale]. | |||
| 1331 | * | |||
| 1332 | * Returns: (nullable): A newly-created pixbuf | |||
| 1333 | * | |||
| 1334 | * Since: 2.4 | |||
| 1335 | **/ | |||
| 1336 | CdkPixbuf * | |||
| 1337 | cdk_pixbuf_new_from_file_at_size (const char *filename, | |||
| 1338 | int width, | |||
| 1339 | int height, | |||
| 1340 | GError **error) | |||
| 1341 | { | |||
| 1342 | return cdk_pixbuf_new_from_file_at_scale (filename, | |||
| 1343 | width, height, | |||
| 1344 | TRUE(!(0)), error); | |||
| 1345 | } | |||
| 1346 | ||||
| 1347 | #ifdef G_OS_WIN32 | |||
| 1348 | ||||
| 1349 | /** | |||
| 1350 | * cdk_pixbuf_new_from_file_at_size_utf8: (constructor) | |||
| 1351 | * @filename: (type filename): Name of file to load, in the GLib file name encoding | |||
| 1352 | * @width: The width the image should have or -1 to not constrain the width | |||
| 1353 | * @height: The height the image should have or -1 to not constrain the height | |||
| 1354 | * @error: Return location for an error | |||
| 1355 | * | |||
| 1356 | * Same as cdk_pixbuf_new_from_file_at_size() | |||
| 1357 | * | |||
| 1358 | * Returns: (nullable): A newly-created pixbuf with a reference count of 1, or | |||
| 1359 | * `NULL` if any of several error conditions occurred: the file could not | |||
| 1360 | * be opened, there was no loader for the file's format, there was not | |||
| 1361 | * enough memory to allocate the image buffer, or the image file contained | |||
| 1362 | * invalid data. | |||
| 1363 | * | |||
| 1364 | * Since: 2.4 | |||
| 1365 | **/ | |||
| 1366 | CdkPixbuf * | |||
| 1367 | cdk_pixbuf_new_from_file_at_size_utf8 (const char *filename, | |||
| 1368 | int width, | |||
| 1369 | int height, | |||
| 1370 | GError **error) | |||
| 1371 | { | |||
| 1372 | return cdk_pixbuf_new_from_file_at_size (filename, width, height, error); | |||
| 1373 | } | |||
| 1374 | ||||
| 1375 | #endif | |||
| 1376 | ||||
| 1377 | typedef struct { | |||
| 1378 | gint width; | |||
| 1379 | gint height; | |||
| 1380 | gboolean preserve_aspect_ratio; | |||
| 1381 | } AtScaleData; | |||
| 1382 | ||||
| 1383 | static void | |||
| 1384 | at_scale_data_async_data_free (AtScaleData *data) | |||
| 1385 | { | |||
| 1386 | g_slice_free (AtScaleData, data)do { if (1) g_slice_free1 (sizeof (AtScaleData), (data)); else (void) ((AtScaleData*) 0 == (data)); } while (0); | |||
| 1387 | } | |||
| 1388 | ||||
| 1389 | static void | |||
| 1390 | at_scale_size_prepared_cb (CdkPixbufLoader *loader, | |||
| 1391 | int width, | |||
| 1392 | int height, | |||
| 1393 | gpointer data) | |||
| 1394 | { | |||
| 1395 | AtScaleData *info = data; | |||
| 1396 | ||||
| 1397 | g_return_if_fail (width > 0 && height > 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_92 = 0; if (width > 0 && height > 0) _g_boolean_var_92 = 1; _g_boolean_var_92; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "width > 0 && height > 0" ); return; } } while (0); | |||
| 1398 | ||||
| 1399 | if (info->preserve_aspect_ratio && | |||
| 1400 | (info->width > 0 || info->height > 0)) { | |||
| 1401 | if (info->width < 0) | |||
| 1402 | { | |||
| 1403 | width = width * (double)info->height/(double)height; | |||
| 1404 | height = info->height; | |||
| 1405 | } | |||
| 1406 | else if (info->height < 0) | |||
| 1407 | { | |||
| 1408 | height = height * (double)info->width/(double)width; | |||
| 1409 | width = info->width; | |||
| 1410 | } | |||
| 1411 | else if ((double)height * (double)info->width > | |||
| 1412 | (double)width * (double)info->height) { | |||
| 1413 | width = 0.5 + (double)width * (double)info->height / (double)height; | |||
| 1414 | height = info->height; | |||
| 1415 | } else { | |||
| 1416 | height = 0.5 + (double)height * (double)info->width / (double)width; | |||
| 1417 | width = info->width; | |||
| 1418 | } | |||
| 1419 | } else { | |||
| 1420 | if (info->width > 0) | |||
| 1421 | width = info->width; | |||
| 1422 | if (info->height > 0) | |||
| 1423 | height = info->height; | |||
| 1424 | } | |||
| 1425 | ||||
| 1426 | width = MAX (width, 1)(((width) > (1)) ? (width) : (1)); | |||
| 1427 | height = MAX (height, 1)(((height) > (1)) ? (height) : (1)); | |||
| 1428 | ||||
| 1429 | cdk_pixbuf_loader_set_size (loader, width, height); | |||
| 1430 | } | |||
| 1431 | ||||
| 1432 | /** | |||
| 1433 | * cdk_pixbuf_new_from_file_at_scale: (constructor) | |||
| 1434 | * @filename: (type filename): Name of file to load, in the GLib file | |||
| 1435 | * name encoding | |||
| 1436 | * @width: The width the image should have or -1 to not constrain the width | |||
| 1437 | * @height: The height the image should have or -1 to not constrain the height | |||
| 1438 | * @preserve_aspect_ratio: `TRUE` to preserve the image's aspect ratio | |||
| 1439 | * @error: Return location for an error | |||
| 1440 | * | |||
| 1441 | * Creates a new pixbuf by loading an image from a file. | |||
| 1442 | * | |||
| 1443 | * The file format is detected automatically. | |||
| 1444 | * | |||
| 1445 | * If `NULL` is returned, then @error will be set. Possible errors are: | |||
| 1446 | * | |||
| 1447 | * - the file could not be opened | |||
| 1448 | * - there is no loader for the file's format | |||
| 1449 | * - there is not enough memory to allocate the image buffer | |||
| 1450 | * - the image buffer contains invalid data | |||
| 1451 | * | |||
| 1452 | * The error domains are `CDK_PIXBUF_ERROR` and `G_FILE_ERROR`. | |||
| 1453 | * | |||
| 1454 | * The image will be scaled to fit in the requested size, optionally preserving | |||
| 1455 | * the image's aspect ratio. | |||
| 1456 | * | |||
| 1457 | * When preserving the aspect ratio, a `width` of -1 will cause the image | |||
| 1458 | * to be scaled to the exact given height, and a `height` of -1 will cause | |||
| 1459 | * the image to be scaled to the exact given width. When not preserving | |||
| 1460 | * aspect ratio, a `width` or `height` of -1 means to not scale the image | |||
| 1461 | * at all in that dimension. Negative values for `width` and `height` are | |||
| 1462 | * allowed since 2.8. | |||
| 1463 | * | |||
| 1464 | * Returns: (nullable): A newly-created pixbuf | |||
| 1465 | * | |||
| 1466 | * Since: 2.6 | |||
| 1467 | **/ | |||
| 1468 | CdkPixbuf * | |||
| 1469 | cdk_pixbuf_new_from_file_at_scale (const char *filename, | |||
| 1470 | int width, | |||
| 1471 | int height, | |||
| 1472 | gboolean preserve_aspect_ratio, | |||
| 1473 | GError **error) | |||
| 1474 | { | |||
| 1475 | ||||
| 1476 | CdkPixbufLoader *loader; | |||
| 1477 | CdkPixbuf *pixbuf; | |||
| 1478 | guchar buffer[LOAD_BUFFER_SIZE65536]; | |||
| 1479 | int length; | |||
| 1480 | FILE *f; | |||
| 1481 | AtScaleData info; | |||
| 1482 | CdkPixbufAnimation *animation; | |||
| 1483 | CdkPixbufAnimationIter *iter; | |||
| 1484 | gboolean has_frame; | |||
| 1485 | ||||
| 1486 | g_return_val_if_fail (filename != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_93 = 0; if (filename != ((void*)0)) _g_boolean_var_93 = 1; _g_boolean_var_93 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "filename != NULL"); return (((void *)0)); } } while (0); | |||
| 1487 | g_return_val_if_fail (width > 0 || width == -1, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_94 = 0; if (width > 0 || width == -1) _g_boolean_var_94 = 1; _g_boolean_var_94; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "width > 0 || width == -1" ); return (((void*)0)); } } while (0); | |||
| 1488 | g_return_val_if_fail (height > 0 || height == -1, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_95 = 0; if (height > 0 || height == -1) _g_boolean_var_95 = 1 ; _g_boolean_var_95; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "height > 0 || height == -1" ); return (((void*)0)); } } while (0); | |||
| 1489 | ||||
| 1490 | f = g_fopenfopen (filename, "rb"); | |||
| 1491 | if (!f) { | |||
| 1492 | gint save_errno = errno(*__errno_location ()); | |||
| 1493 | gchar *display_name = g_filename_display_name (filename); | |||
| 1494 | g_set_error (error, | |||
| 1495 | G_FILE_ERRORg_file_error_quark (), | |||
| 1496 | g_file_error_from_errno (save_errno), | |||
| 1497 | _("Failed to open file “%s”: %s")((char *) g_dgettext ("cdk-pixbuf", "Failed to open file “%s”: %s" )), | |||
| 1498 | display_name, | |||
| 1499 | g_strerror (save_errno)); | |||
| 1500 | g_free (display_name); | |||
| 1501 | return NULL((void*)0); | |||
| 1502 | } | |||
| 1503 | ||||
| 1504 | loader = _cdk_pixbuf_loader_new_with_filename (filename); | |||
| 1505 | ||||
| 1506 | info.width = width; | |||
| 1507 | info.height = height; | |||
| 1508 | info.preserve_aspect_ratio = preserve_aspect_ratio; | |||
| 1509 | ||||
| 1510 | g_signal_connect (loader, "size-prepared",g_signal_connect_data ((loader), ("size-prepared"), (((GCallback ) (at_scale_size_prepared_cb))), (&info), ((void*)0), (GConnectFlags ) 0) | |||
| 1511 | G_CALLBACK (at_scale_size_prepared_cb), &info)g_signal_connect_data ((loader), ("size-prepared"), (((GCallback ) (at_scale_size_prepared_cb))), (&info), ((void*)0), (GConnectFlags ) 0); | |||
| 1512 | ||||
| 1513 | has_frame = FALSE(0); | |||
| 1514 | while (!has_frame && !feof (f) && !ferror (f)) { | |||
| 1515 | length = fread (buffer, 1, sizeof (buffer), f); | |||
| 1516 | if (length > 0) | |||
| 1517 | if (!cdk_pixbuf_loader_write (loader, buffer, length, error)) { | |||
| 1518 | cdk_pixbuf_loader_close (loader, NULL((void*)0)); | |||
| 1519 | fclose (f); | |||
| 1520 | g_object_unref (loader); | |||
| 1521 | return NULL((void*)0); | |||
| 1522 | } | |||
| 1523 | ||||
| 1524 | animation = cdk_pixbuf_loader_get_animation (loader); | |||
| 1525 | if (animation) { | |||
| 1526 | iter = cdk_pixbuf_animation_get_iter (animation, NULL((void*)0)); | |||
| 1527 | if (!cdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) { | |||
| 1528 | has_frame = TRUE(!(0)); | |||
| 1529 | } | |||
| 1530 | g_object_unref (iter); | |||
| 1531 | } | |||
| 1532 | } | |||
| 1533 | ||||
| 1534 | fclose (f); | |||
| 1535 | ||||
| 1536 | if (!cdk_pixbuf_loader_close (loader, error) && !has_frame) { | |||
| 1537 | g_object_unref (loader); | |||
| 1538 | return NULL((void*)0); | |||
| 1539 | } | |||
| 1540 | ||||
| 1541 | pixbuf = cdk_pixbuf_loader_get_pixbuf (loader); | |||
| 1542 | ||||
| 1543 | if (!pixbuf) { | |||
| 1544 | gchar *display_name = g_filename_display_name (filename); | |||
| 1545 | g_object_unref (loader); | |||
| 1546 | g_set_error (error, | |||
| 1547 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 1548 | CDK_PIXBUF_ERROR_FAILED, | |||
| 1549 | _("Failed to load image “%s”: reason not known, probably a corrupt image file")((char *) g_dgettext ("cdk-pixbuf", "Failed to load image “%s”: reason not known, probably a corrupt image file" )), | |||
| 1550 | display_name); | |||
| 1551 | g_free (display_name); | |||
| 1552 | return NULL((void*)0); | |||
| 1553 | } | |||
| 1554 | ||||
| 1555 | g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf)); | |||
| 1556 | ||||
| 1557 | g_object_unref (loader); | |||
| 1558 | ||||
| 1559 | return pixbuf; | |||
| 1560 | } | |||
| 1561 | ||||
| 1562 | #ifdef G_OS_WIN32 | |||
| 1563 | ||||
| 1564 | /** | |||
| 1565 | * cdk_pixbuf_new_from_file_at_scale_utf8: (constructor) | |||
| 1566 | * @filename: (type filename): Name of file to load, in the GLib file name encoding | |||
| 1567 | * @width: The width the image should have or -1 to not constrain the width | |||
| 1568 | * @height: The height the image should have or -1 to not constrain the height | |||
| 1569 | * @preserve_aspect_ratio: `TRUE` to preserve the image's aspect ratio | |||
| 1570 | * @error: Return location for an error | |||
| 1571 | * | |||
| 1572 | * Same as cdk_pixbuf_new_from_file_at_scale(). | |||
| 1573 | * | |||
| 1574 | * Returns: (nullable): A newly-created pixbuf with a reference count of 1, | |||
| 1575 | * or `NULL` if any of several error conditions occurred: the file could not be opened, | |||
| 1576 | * there was no loader for the file's format, there was not enough memory to | |||
| 1577 | * allocate the image buffer, or the image file contained invalid data. | |||
| 1578 | * | |||
| 1579 | * Since: 2.6 | |||
| 1580 | **/ | |||
| 1581 | CdkPixbuf * | |||
| 1582 | cdk_pixbuf_new_from_file_at_scale_utf8 (const char *filename, | |||
| 1583 | int width, | |||
| 1584 | int height, | |||
| 1585 | gboolean preserve_aspect_ratio, | |||
| 1586 | GError **error) | |||
| 1587 | { | |||
| 1588 | return cdk_pixbuf_new_from_file_at_scale (filename, width, height, | |||
| 1589 | preserve_aspect_ratio, error); | |||
| 1590 | } | |||
| 1591 | #endif | |||
| 1592 | ||||
| 1593 | ||||
| 1594 | static CdkPixbuf * | |||
| 1595 | load_from_stream (CdkPixbufLoader *loader, | |||
| 1596 | GInputStream *stream, | |||
| 1597 | GCancellable *cancellable, | |||
| 1598 | GError **error) | |||
| 1599 | { | |||
| 1600 | CdkPixbuf *pixbuf; | |||
| 1601 | gssize n_read; | |||
| 1602 | guchar buffer[LOAD_BUFFER_SIZE65536]; | |||
| 1603 | ||||
| 1604 | while (1) { | |||
| 1605 | n_read = g_input_stream_read (stream, | |||
| 1606 | buffer, | |||
| 1607 | sizeof (buffer), | |||
| 1608 | cancellable, | |||
| 1609 | error); | |||
| 1610 | if (n_read < 0) { | |||
| 1611 | cdk_pixbuf_loader_close (loader, NULL((void*)0)); | |||
| 1612 | return NULL((void*)0); | |||
| 1613 | } | |||
| 1614 | ||||
| 1615 | if (n_read == 0) | |||
| 1616 | break; | |||
| 1617 | ||||
| 1618 | if (!cdk_pixbuf_loader_write (loader, | |||
| 1619 | buffer, | |||
| 1620 | n_read, | |||
| 1621 | error)) { | |||
| 1622 | cdk_pixbuf_loader_close (loader, NULL((void*)0)); | |||
| 1623 | return NULL((void*)0); | |||
| 1624 | } | |||
| 1625 | } | |||
| 1626 | ||||
| 1627 | if (!cdk_pixbuf_loader_close (loader, error)) | |||
| 1628 | return NULL((void*)0); | |||
| 1629 | ||||
| 1630 | pixbuf = cdk_pixbuf_loader_get_pixbuf (loader); | |||
| 1631 | if (pixbuf == NULL((void*)0)) | |||
| 1632 | return NULL((void*)0); | |||
| 1633 | ||||
| 1634 | return g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf)); | |||
| 1635 | } | |||
| 1636 | ||||
| 1637 | ||||
| 1638 | /** | |||
| 1639 | * cdk_pixbuf_new_from_stream_at_scale: (constructor) | |||
| 1640 | * @stream: a `GInputStream` to load the pixbuf from | |||
| 1641 | * @width: The width the image should have or -1 to not constrain the width | |||
| 1642 | * @height: The height the image should have or -1 to not constrain the height | |||
| 1643 | * @preserve_aspect_ratio: `TRUE` to preserve the image's aspect ratio | |||
| 1644 | * @cancellable: (allow-none): optional `GCancellable` object, `NULL` to ignore | |||
| 1645 | * @error: Return location for an error | |||
| 1646 | * | |||
| 1647 | * Creates a new pixbuf by loading an image from an input stream. | |||
| 1648 | * | |||
| 1649 | * The file format is detected automatically. If `NULL` is returned, then | |||
| 1650 | * @error will be set. The @cancellable can be used to abort the operation | |||
| 1651 | * from another thread. If the operation was cancelled, the error | |||
| 1652 | * `G_IO_ERROR_CANCELLED` will be returned. Other possible errors are in | |||
| 1653 | * the `CDK_PIXBUF_ERROR` and `G_IO_ERROR` domains. | |||
| 1654 | * | |||
| 1655 | * The image will be scaled to fit in the requested size, optionally | |||
| 1656 | * preserving the image's aspect ratio. | |||
| 1657 | * | |||
| 1658 | * When preserving the aspect ratio, a `width` of -1 will cause the image to be | |||
| 1659 | * scaled to the exact given height, and a `height` of -1 will cause the image | |||
| 1660 | * to be scaled to the exact given width. If both `width` and `height` are | |||
| 1661 | * given, this function will behave as if the smaller of the two values | |||
| 1662 | * is passed as -1. | |||
| 1663 | * | |||
| 1664 | * When not preserving aspect ratio, a `width` or `height` of -1 means to not | |||
| 1665 | * scale the image at all in that dimension. | |||
| 1666 | * | |||
| 1667 | * The stream is not closed. | |||
| 1668 | * | |||
| 1669 | * Returns: (nullable): A newly-created pixbuf | |||
| 1670 | * | |||
| 1671 | * Since: 2.14 | |||
| 1672 | */ | |||
| 1673 | CdkPixbuf * | |||
| 1674 | cdk_pixbuf_new_from_stream_at_scale (GInputStream *stream, | |||
| 1675 | gint width, | |||
| 1676 | gint height, | |||
| 1677 | gboolean preserve_aspect_ratio, | |||
| 1678 | GCancellable *cancellable, | |||
| 1679 | GError **error) | |||
| 1680 | { | |||
| 1681 | CdkPixbufLoader *loader; | |||
| 1682 | CdkPixbuf *pixbuf; | |||
| 1683 | AtScaleData info; | |||
| 1684 | ||||
| 1685 | loader = cdk_pixbuf_loader_new (); | |||
| 1686 | info.width = width; | |||
| 1687 | info.height = height; | |||
| 1688 | info.preserve_aspect_ratio = preserve_aspect_ratio; | |||
| 1689 | ||||
| 1690 | g_signal_connect (loader, "size-prepared",g_signal_connect_data ((loader), ("size-prepared"), (((GCallback ) (at_scale_size_prepared_cb))), (&info), ((void*)0), (GConnectFlags ) 0) | |||
| 1691 | G_CALLBACK (at_scale_size_prepared_cb), &info)g_signal_connect_data ((loader), ("size-prepared"), (((GCallback ) (at_scale_size_prepared_cb))), (&info), ((void*)0), (GConnectFlags ) 0); | |||
| 1692 | ||||
| 1693 | pixbuf = load_from_stream (loader, stream, cancellable, error); | |||
| 1694 | g_object_unref (loader); | |||
| 1695 | ||||
| 1696 | return pixbuf; | |||
| 1697 | } | |||
| 1698 | ||||
| 1699 | ||||
| 1700 | static void | |||
| 1701 | load_from_stream_async_cb (GObject *stream, | |||
| 1702 | GAsyncResult *res, | |||
| 1703 | gpointer data) | |||
| 1704 | { | |||
| 1705 | GTask *task = data; | |||
| 1706 | CdkPixbufLoader *loader; | |||
| 1707 | CdkPixbuf *pixbuf; | |||
| 1708 | GError *error = NULL((void*)0); | |||
| 1709 | GBytes *bytes = NULL((void*)0); | |||
| 1710 | ||||
| 1711 | loader = g_task_get_task_data (task); | |||
| 1712 | ||||
| 1713 | bytes = g_input_stream_read_bytes_finish (G_INPUT_STREAM (stream)((((GInputStream*) (void *) ((stream))))), res, &error); | |||
| 1714 | ||||
| 1715 | if (bytes == NULL((void*)0)) { | |||
| 1716 | cdk_pixbuf_loader_close (loader, NULL((void*)0)); | |||
| 1717 | g_task_return_error (task, error); | |||
| 1718 | } else if (g_bytes_get_size (bytes) > 0) { | |||
| 1719 | if (!cdk_pixbuf_loader_write (loader, | |||
| 1720 | g_bytes_get_data (bytes, NULL((void*)0)), | |||
| 1721 | g_bytes_get_size (bytes), | |||
| 1722 | &error)) { | |||
| 1723 | cdk_pixbuf_loader_close (loader, NULL((void*)0)); | |||
| 1724 | g_task_return_error (task, error); | |||
| 1725 | goto out; | |||
| 1726 | } | |||
| 1727 | g_input_stream_read_bytes_async (G_INPUT_STREAM (stream)((((GInputStream*) (void *) ((stream))))), | |||
| 1728 | LOAD_BUFFER_SIZE65536, | |||
| 1729 | G_PRIORITY_DEFAULT0, | |||
| 1730 | g_task_get_cancellable (task), | |||
| 1731 | load_from_stream_async_cb, | |||
| 1732 | g_object_ref (task)((__typeof__ (task)) (g_object_ref) (task))); | |||
| 1733 | ||||
| 1734 | } else { | |||
| 1735 | if (!cdk_pixbuf_loader_close (loader, &error)) { | |||
| 1736 | g_task_return_error (task, error); | |||
| 1737 | goto out; | |||
| 1738 | } | |||
| 1739 | ||||
| 1740 | pixbuf = cdk_pixbuf_loader_get_pixbuf (loader); | |||
| 1741 | g_task_return_pointer (task, g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf)), g_object_unref); | |||
| 1742 | } | |||
| 1743 | ||||
| 1744 | out: | |||
| 1745 | g_bytes_unref (bytes); | |||
| 1746 | g_object_unref (task); | |||
| 1747 | } | |||
| 1748 | ||||
| 1749 | ||||
| 1750 | /** | |||
| 1751 | * cdk_pixbuf_new_from_stream_at_scale_async: (finish-func cdk_pixbuf_new_from_stream_finish) | |||
| 1752 | * @stream: a `GInputStream` from which to load the pixbuf | |||
| 1753 | * @width: the width the image should have or -1 to not constrain the width | |||
| 1754 | * @height: the height the image should have or -1 to not constrain the height | |||
| 1755 | * @preserve_aspect_ratio: `TRUE` to preserve the image's aspect ratio | |||
| 1756 | * @cancellable: (nullable): optional `GCancellable` object, `NULL` to ignore | |||
| 1757 | * @callback: (scope async) (closure user_data): a `GAsyncReadyCallback` to call when the pixbuf is loaded | |||
| 1758 | * @user_data: the data to pass to the callback function | |||
| 1759 | * | |||
| 1760 | * Creates a new pixbuf by asynchronously loading an image from an input stream. | |||
| 1761 | * | |||
| 1762 | * For more details see cdk_pixbuf_new_from_stream_at_scale(), which is the synchronous | |||
| 1763 | * version of this function. | |||
| 1764 | * | |||
| 1765 | * When the operation is finished, @callback will be called in the main thread. | |||
| 1766 | * You can then call cdk_pixbuf_new_from_stream_finish() to get the result of the operation. | |||
| 1767 | * | |||
| 1768 | * Since: 2.24 | |||
| 1769 | **/ | |||
| 1770 | void | |||
| 1771 | cdk_pixbuf_new_from_stream_at_scale_async (GInputStream *stream, | |||
| 1772 | gint width, | |||
| 1773 | gint height, | |||
| 1774 | gboolean preserve_aspect_ratio, | |||
| 1775 | GCancellable *cancellable, | |||
| 1776 | GAsyncReadyCallback callback, | |||
| 1777 | gpointer user_data) | |||
| 1778 | { | |||
| 1779 | GTask *task; | |||
| 1780 | AtScaleData *data; | |||
| 1781 | CdkPixbufLoader *loader; | |||
| 1782 | ||||
| 1783 | g_return_if_fail (G_IS_INPUT_STREAM (stream))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_96 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((stream)); GType __t = ((g_input_stream_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; }))))) _g_boolean_var_96 = 1; _g_boolean_var_96; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "G_IS_INPUT_STREAM (stream)" ); return; } } while (0); | |||
| 1784 | g_return_if_fail (callback != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_97 = 0; if (callback != ((void*)0)) _g_boolean_var_97 = 1; _g_boolean_var_97 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "callback != NULL"); return; } } while (0); | |||
| 1785 | g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_98 = 0; if (!cancellable || (((__extension__ ({ GTypeInstance * __inst = (GTypeInstance*) ((cancellable)); GType __t = ((g_cancellable_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; }))))) _g_boolean_var_98 = 1; _g_boolean_var_98; }), 1) )) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char *) (__func__)), "!cancellable || G_IS_CANCELLABLE (cancellable)" ); return; } } while (0); | |||
| 1786 | ||||
| 1787 | data = g_slice_new (AtScaleData)((AtScaleData*) g_slice_alloc ((sizeof (AtScaleData) > 0 ? sizeof (AtScaleData) : 1))); | |||
| 1788 | data->width = width; | |||
| 1789 | data->height = height; | |||
| 1790 | data->preserve_aspect_ratio = preserve_aspect_ratio; | |||
| 1791 | ||||
| 1792 | loader = cdk_pixbuf_loader_new (); | |||
| 1793 | g_signal_connect (loader, "size-prepared",g_signal_connect_data ((loader), ("size-prepared"), (((GCallback ) (at_scale_size_prepared_cb))), (data), ((void*)0), (GConnectFlags ) 0) | |||
| 1794 | G_CALLBACK (at_scale_size_prepared_cb), data)g_signal_connect_data ((loader), ("size-prepared"), (((GCallback ) (at_scale_size_prepared_cb))), (data), ((void*)0), (GConnectFlags ) 0); | |||
| 1795 | g_object_set_data_full (G_OBJECT (loader)((((GObject*) (void *) ((loader))))), | |||
| 1796 | "cdk-pixbuf-please-kill-me-later", | |||
| 1797 | data, | |||
| 1798 | (GDestroyNotify) at_scale_data_async_data_free); | |||
| 1799 | ||||
| 1800 | task = g_task_new (stream, cancellable, callback, user_data); | |||
| 1801 | g_task_set_source_tag (task, cdk_pixbuf_new_from_stream_at_scale_async)do { GTask *_task = (task); (g_task_set_source_tag) (_task, cdk_pixbuf_new_from_stream_at_scale_async ); if (g_task_get_name (_task) == ((void*)0)) g_task_set_static_name (_task, "cdk_pixbuf_new_from_stream_at_scale_async"); } while (0); | |||
| 1802 | g_task_set_task_data (task, loader, g_object_unref); | |||
| 1803 | ||||
| 1804 | g_input_stream_read_bytes_async (stream, | |||
| 1805 | LOAD_BUFFER_SIZE65536, | |||
| 1806 | G_PRIORITY_DEFAULT0, | |||
| 1807 | cancellable, | |||
| 1808 | load_from_stream_async_cb, | |||
| 1809 | task); | |||
| 1810 | } | |||
| 1811 | ||||
| 1812 | /** | |||
| 1813 | * cdk_pixbuf_new_from_stream: | |||
| 1814 | * @stream: a `GInputStream` to load the pixbuf from | |||
| 1815 | * @cancellable: (allow-none): optional `GCancellable` object, `NULL` to ignore | |||
| 1816 | * @error: Return location for an error | |||
| 1817 | * | |||
| 1818 | * Creates a new pixbuf by loading an image from an input stream. | |||
| 1819 | * | |||
| 1820 | * The file format is detected automatically. | |||
| 1821 | * | |||
| 1822 | * If `NULL` is returned, then `error` will be set. | |||
| 1823 | * | |||
| 1824 | * The `cancellable` can be used to abort the operation from another thread. | |||
| 1825 | * If the operation was cancelled, the error `G_IO_ERROR_CANCELLED` will be | |||
| 1826 | * returned. Other possible errors are in the `CDK_PIXBUF_ERROR` and | |||
| 1827 | * `G_IO_ERROR` domains. | |||
| 1828 | * | |||
| 1829 | * The stream is not closed. | |||
| 1830 | * | |||
| 1831 | * Returns: (nullable): A newly-created pixbuf | |||
| 1832 | * | |||
| 1833 | * Since: 2.14 | |||
| 1834 | **/ | |||
| 1835 | CdkPixbuf * | |||
| 1836 | cdk_pixbuf_new_from_stream (GInputStream *stream, | |||
| 1837 | GCancellable *cancellable, | |||
| 1838 | GError **error) | |||
| 1839 | { | |||
| 1840 | CdkPixbuf *pixbuf; | |||
| 1841 | CdkPixbufLoader *loader; | |||
| 1842 | ||||
| 1843 | loader = cdk_pixbuf_loader_new (); | |||
| 1844 | pixbuf = load_from_stream (loader, stream, cancellable, error); | |||
| 1845 | g_object_unref (loader); | |||
| 1846 | ||||
| 1847 | return pixbuf; | |||
| 1848 | } | |||
| 1849 | ||||
| 1850 | CdkPixbuf * | |||
| 1851 | _cdk_pixbuf_new_from_resource_try_pixdata (const char *resource_path) | |||
| 1852 | { | |||
| 1853 | gsize data_size; | |||
| 1854 | GBytes *bytes; | |||
| 1855 | ||||
| 1856 | G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push
clang diagnostic ignored "-Wdeprecated-declarations" | |||
| 1857 | /* We specialize CdkPixdata files, making these a reference to the | |||
| 1858 | * compiled-in resource data, whether uncompressed and mmap'ed, or | |||
| 1859 | * compressed, and uncompressed on-the-fly. | |||
| 1860 | */ | |||
| 1861 | if (g_resources_get_info (resource_path, 0, &data_size, NULL((void*)0), NULL((void*)0)) && | |||
| 1862 | data_size > sizeof (guint32) && | |||
| 1863 | (bytes = g_resources_lookup_data (resource_path, 0, NULL((void*)0))) != NULL((void*)0)) { | |||
| 1864 | CdkPixbuf *pixbuf = NULL((void*)0); | |||
| 1865 | const guint8 *stream = g_bytes_get_data (bytes, NULL((void*)0)); | |||
| 1866 | CdkPixdata pixdata; | |||
| 1867 | guint32 magic; | |||
| 1868 | ||||
| 1869 | magic = ((guint32) stream[0] << 24) | |||
| 1870 | + ((guint32) stream[1] << 16) | |||
| 1871 | + ((guint32) stream[2] << 8) | |||
| 1872 | + (guint32) stream[3]; | |||
| 1873 | if (magic == CDK_PIXBUF_MAGIC_NUMBER(0x47646b50) && | |||
| 1874 | cdk_pixdata_deserialize (&pixdata, data_size, stream, NULL((void*)0))) { | |||
| 1875 | pixbuf = cdk_pixbuf_from_pixdata (&pixdata, FALSE(0), NULL((void*)0)); | |||
| 1876 | } | |||
| 1877 | ||||
| 1878 | if (pixbuf) { | |||
| 1879 | /* Free the GBytes with the pixbuf */ | |||
| 1880 | g_object_set_data_full (G_OBJECT (pixbuf)((((GObject*) (void *) ((pixbuf))))), "cdk-pixbuf-resource-bytes", bytes, (GDestroyNotify) g_bytes_unref); | |||
| 1881 | return pixbuf; | |||
| 1882 | } else { | |||
| 1883 | g_bytes_unref (bytes); | |||
| 1884 | } | |||
| 1885 | } | |||
| 1886 | G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop | |||
| 1887 | ||||
| 1888 | return NULL((void*)0); | |||
| 1889 | } | |||
| 1890 | ||||
| 1891 | /** | |||
| 1892 | * cdk_pixbuf_new_from_resource: (constructor) | |||
| 1893 | * @resource_path: the path of the resource file | |||
| 1894 | * @error: Return location for an error | |||
| 1895 | * | |||
| 1896 | * Creates a new pixbuf by loading an image from an resource. | |||
| 1897 | * | |||
| 1898 | * The file format is detected automatically. If `NULL` is returned, then | |||
| 1899 | * @error will be set. | |||
| 1900 | * | |||
| 1901 | * Returns: (nullable): A newly-created pixbuf | |||
| 1902 | * | |||
| 1903 | * Since: 2.26 | |||
| 1904 | **/ | |||
| 1905 | CdkPixbuf * | |||
| 1906 | cdk_pixbuf_new_from_resource (const gchar *resource_path, | |||
| 1907 | GError **error) | |||
| 1908 | { | |||
| 1909 | GInputStream *stream; | |||
| 1910 | CdkPixbuf *pixbuf; | |||
| 1911 | ||||
| 1912 | pixbuf = _cdk_pixbuf_new_from_resource_try_pixdata (resource_path); | |||
| 1913 | if (pixbuf) | |||
| 1914 | return pixbuf; | |||
| 1915 | ||||
| 1916 | stream = g_resources_open_stream (resource_path, 0, error); | |||
| 1917 | if (stream == NULL((void*)0)) | |||
| 1918 | return NULL((void*)0); | |||
| 1919 | ||||
| 1920 | pixbuf = cdk_pixbuf_new_from_stream (stream, NULL((void*)0), error); | |||
| 1921 | g_object_unref (stream); | |||
| 1922 | return pixbuf; | |||
| 1923 | } | |||
| 1924 | ||||
| 1925 | /** | |||
| 1926 | * cdk_pixbuf_new_from_resource_at_scale: (constructor) | |||
| 1927 | * @resource_path: the path of the resource file | |||
| 1928 | * @width: The width the image should have or -1 to not constrain the width | |||
| 1929 | * @height: The height the image should have or -1 to not constrain the height | |||
| 1930 | * @preserve_aspect_ratio: `TRUE` to preserve the image's aspect ratio | |||
| 1931 | * @error: Return location for an error | |||
| 1932 | * | |||
| 1933 | * Creates a new pixbuf by loading an image from an resource. | |||
| 1934 | * | |||
| 1935 | * The file format is detected automatically. If `NULL` is returned, then | |||
| 1936 | * @error will be set. | |||
| 1937 | * | |||
| 1938 | * The image will be scaled to fit in the requested size, optionally | |||
| 1939 | * preserving the image's aspect ratio. When preserving the aspect ratio, | |||
| 1940 | * a @width of -1 will cause the image to be scaled to the exact given | |||
| 1941 | * height, and a @height of -1 will cause the image to be scaled to the | |||
| 1942 | * exact given width. When not preserving aspect ratio, a @width or | |||
| 1943 | * @height of -1 means to not scale the image at all in that dimension. | |||
| 1944 | * | |||
| 1945 | * The stream is not closed. | |||
| 1946 | * | |||
| 1947 | * Returns: (nullable): A newly-created pixbuf | |||
| 1948 | * | |||
| 1949 | * Since: 2.26 | |||
| 1950 | */ | |||
| 1951 | CdkPixbuf * | |||
| 1952 | cdk_pixbuf_new_from_resource_at_scale (const char *resource_path, | |||
| 1953 | int width, | |||
| 1954 | int height, | |||
| 1955 | gboolean preserve_aspect_ratio, | |||
| 1956 | GError **error) | |||
| 1957 | { | |||
| 1958 | GInputStream *stream; | |||
| 1959 | CdkPixbuf *pixbuf; | |||
| 1960 | ||||
| 1961 | stream = g_resources_open_stream (resource_path, 0, error); | |||
| 1962 | if (stream == NULL((void*)0)) | |||
| 1963 | return NULL((void*)0); | |||
| 1964 | ||||
| 1965 | pixbuf = cdk_pixbuf_new_from_stream_at_scale (stream, width, height, preserve_aspect_ratio, NULL((void*)0), error); | |||
| 1966 | g_object_unref (stream); | |||
| 1967 | return pixbuf; | |||
| 1968 | } | |||
| 1969 | ||||
| 1970 | /** | |||
| 1971 | * cdk_pixbuf_new_from_stream_async: (finish-func cdk_pixbuf_new_from_stream_finish) | |||
| 1972 | * @stream: a `GInputStream` from which to load the pixbuf | |||
| 1973 | * @cancellable: (nullable): optional `GCancellable` object, `NULL` to ignore | |||
| 1974 | * @callback: (scope async) (closure user_data): a `GAsyncReadyCallback` to call when the pixbuf is loaded | |||
| 1975 | * @user_data: the data to pass to the callback function | |||
| 1976 | * | |||
| 1977 | * Creates a new pixbuf by asynchronously loading an image from an input stream. | |||
| 1978 | * | |||
| 1979 | * For more details see cdk_pixbuf_new_from_stream(), which is the synchronous | |||
| 1980 | * version of this function. | |||
| 1981 | * | |||
| 1982 | * When the operation is finished, @callback will be called in the main thread. | |||
| 1983 | * You can then call cdk_pixbuf_new_from_stream_finish() to get the result of | |||
| 1984 | * the operation. | |||
| 1985 | * | |||
| 1986 | * Since: 2.24 | |||
| 1987 | **/ | |||
| 1988 | void | |||
| 1989 | cdk_pixbuf_new_from_stream_async (GInputStream *stream, | |||
| 1990 | GCancellable *cancellable, | |||
| 1991 | GAsyncReadyCallback callback, | |||
| 1992 | gpointer user_data) | |||
| 1993 | { | |||
| 1994 | GTask *task; | |||
| 1995 | ||||
| 1996 | g_return_if_fail (G_IS_INPUT_STREAM (stream))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_99 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((stream)); GType __t = ((g_input_stream_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; }))))) _g_boolean_var_99 = 1; _g_boolean_var_99; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "G_IS_INPUT_STREAM (stream)" ); return; } } while (0); | |||
| 1997 | g_return_if_fail (callback != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_100 = 0; if (callback != ((void*)0)) _g_boolean_var_100 = 1; _g_boolean_var_100 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "callback != NULL"); return; } } while (0); | |||
| 1998 | g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_101 = 0; if (!cancellable || (((__extension__ ({ GTypeInstance * __inst = (GTypeInstance*) ((cancellable)); GType __t = ((g_cancellable_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; }))))) _g_boolean_var_101 = 1; _g_boolean_var_101; }), 1 ))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "!cancellable || G_IS_CANCELLABLE (cancellable)" ); return; } } while (0); | |||
| 1999 | ||||
| 2000 | task = g_task_new (stream, cancellable, callback, user_data); | |||
| 2001 | g_task_set_source_tag (task, cdk_pixbuf_new_from_stream_async)do { GTask *_task = (task); (g_task_set_source_tag) (_task, cdk_pixbuf_new_from_stream_async ); if (g_task_get_name (_task) == ((void*)0)) g_task_set_static_name (_task, "cdk_pixbuf_new_from_stream_async"); } while (0); | |||
| 2002 | g_task_set_task_data (task, cdk_pixbuf_loader_new (), g_object_unref); | |||
| 2003 | ||||
| 2004 | g_input_stream_read_bytes_async (stream, | |||
| 2005 | LOAD_BUFFER_SIZE65536, | |||
| 2006 | G_PRIORITY_DEFAULT0, | |||
| 2007 | cancellable, | |||
| 2008 | load_from_stream_async_cb, | |||
| 2009 | task); | |||
| 2010 | } | |||
| 2011 | ||||
| 2012 | /** | |||
| 2013 | * cdk_pixbuf_new_from_stream_finish: (constructor) | |||
| 2014 | * @async_result: a `GAsyncResult` | |||
| 2015 | * @error: a `GError`, or `NULL` | |||
| 2016 | * | |||
| 2017 | * Finishes an asynchronous pixbuf creation operation started with | |||
| 2018 | * cdk_pixbuf_new_from_stream_async(). | |||
| 2019 | * | |||
| 2020 | * Returns: (nullable): the newly created pixbuf | |||
| 2021 | * | |||
| 2022 | * Since: 2.24 | |||
| 2023 | **/ | |||
| 2024 | CdkPixbuf * | |||
| 2025 | cdk_pixbuf_new_from_stream_finish (GAsyncResult *async_result, | |||
| 2026 | GError **error) | |||
| 2027 | { | |||
| 2028 | GTask *task; | |||
| 2029 | ||||
| 2030 | g_return_val_if_fail (G_IS_TASK (async_result), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_102 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((async_result)); GType __t = ((g_task_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; }))))) _g_boolean_var_102 = 1; _g_boolean_var_102; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "G_IS_TASK (async_result)" ); return (((void*)0)); } } while (0); | |||
| 2031 | g_return_val_if_fail (!error || (error && !*error), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_103 = 0; if (!error || (error && !*error)) _g_boolean_var_103 = 1; _g_boolean_var_103; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "!error || (error && !*error)" ); return (((void*)0)); } } while (0); | |||
| 2032 | ||||
| 2033 | task = G_TASK (async_result)((((GTask*) (void *) ((async_result))))); | |||
| 2034 | ||||
| 2035 | g_warn_if_fail (g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_async ||do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_104 = 0; if (g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_async || g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_at_scale_async ) _g_boolean_var_104 = 1; _g_boolean_var_104; }), 1)) ; else g_warn_message ("CdkPixbuf", "../cdk-pixbuf/cdk-pixbuf-io.c", 2036, ((const char*) (__func__)), "g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_async || g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_at_scale_async" ); } while (0) | |||
| 2036 | g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_at_scale_async)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_104 = 0; if (g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_async || g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_at_scale_async ) _g_boolean_var_104 = 1; _g_boolean_var_104; }), 1)) ; else g_warn_message ("CdkPixbuf", "../cdk-pixbuf/cdk-pixbuf-io.c", 2036, ((const char*) (__func__)), "g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_async || g_task_get_source_tag (task) == cdk_pixbuf_new_from_stream_at_scale_async" ); } while (0); | |||
| 2037 | ||||
| 2038 | return g_task_propagate_pointer (task, error); | |||
| 2039 | } | |||
| 2040 | ||||
| 2041 | static void | |||
| 2042 | info_cb (CdkPixbufLoader *loader, | |||
| 2043 | int width, | |||
| 2044 | int height, | |||
| 2045 | gpointer data) | |||
| 2046 | { | |||
| 2047 | struct { | |||
| 2048 | CdkPixbufFormat *format; | |||
| 2049 | int width; | |||
| 2050 | int height; | |||
| 2051 | } *info = data; | |||
| 2052 | ||||
| 2053 | g_return_if_fail (width > 0 && height > 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_105 = 0; if (width > 0 && height > 0) _g_boolean_var_105 = 1; _g_boolean_var_105; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "width > 0 && height > 0" ); return; } } while (0); | |||
| 2054 | ||||
| 2055 | info->format = cdk_pixbuf_loader_get_format (loader); | |||
| 2056 | info->width = width; | |||
| 2057 | info->height = height; | |||
| 2058 | ||||
| 2059 | cdk_pixbuf_loader_set_size (loader, 0, 0); | |||
| 2060 | } | |||
| 2061 | ||||
| 2062 | /** | |||
| 2063 | * cdk_pixbuf_get_file_info: | |||
| 2064 | * @filename: (type filename): The name of the file to identify. | |||
| 2065 | * @width: (optional) (out): Return location for the width of the image | |||
| 2066 | * @height: (optional) (out): Return location for the height of the image | |||
| 2067 | * | |||
| 2068 | * Parses an image file far enough to determine its format and size. | |||
| 2069 | * | |||
| 2070 | * Returns: (nullable) (transfer none): A `CdkPixbufFormat` describing | |||
| 2071 | * the image format of the file | |||
| 2072 | * | |||
| 2073 | * Since: 2.4 | |||
| 2074 | **/ | |||
| 2075 | CdkPixbufFormat * | |||
| 2076 | cdk_pixbuf_get_file_info (const gchar *filename, | |||
| 2077 | gint *width, | |||
| 2078 | gint *height) | |||
| 2079 | { | |||
| 2080 | CdkPixbufLoader *loader; | |||
| 2081 | guchar buffer[SNIFF_BUFFER_SIZE4096]; | |||
| 2082 | int length; | |||
| 2083 | FILE *f; | |||
| 2084 | struct { | |||
| 2085 | CdkPixbufFormat *format; | |||
| 2086 | gint width; | |||
| 2087 | gint height; | |||
| 2088 | } info; | |||
| 2089 | ||||
| 2090 | g_return_val_if_fail (filename != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_106 = 0; if (filename != ((void*)0)) _g_boolean_var_106 = 1; _g_boolean_var_106 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "filename != NULL"); return (((void *)0)); } } while (0); | |||
| 2091 | ||||
| 2092 | f = g_fopenfopen (filename, "rb"); | |||
| 2093 | if (!f) | |||
| 2094 | return NULL((void*)0); | |||
| 2095 | ||||
| 2096 | loader = _cdk_pixbuf_loader_new_with_filename (filename); | |||
| 2097 | ||||
| 2098 | info.format = NULL((void*)0); | |||
| 2099 | info.width = -1; | |||
| 2100 | info.height = -1; | |||
| 2101 | ||||
| 2102 | g_signal_connect (loader, "size-prepared", G_CALLBACK (info_cb), &info)g_signal_connect_data ((loader), ("size-prepared"), (((GCallback ) (info_cb))), (&info), ((void*)0), (GConnectFlags) 0); | |||
| 2103 | ||||
| 2104 | while (!feof (f) && !ferror (f)) { | |||
| 2105 | length = fread (buffer, 1, sizeof (buffer), f); | |||
| 2106 | if (length > 0) { | |||
| 2107 | if (!cdk_pixbuf_loader_write (loader, buffer, length, NULL((void*)0))) | |||
| 2108 | break; | |||
| 2109 | } | |||
| 2110 | if (info.format != NULL((void*)0)) | |||
| 2111 | break; | |||
| 2112 | } | |||
| 2113 | ||||
| 2114 | fclose (f); | |||
| 2115 | cdk_pixbuf_loader_close (loader, NULL((void*)0)); | |||
| 2116 | g_object_unref (loader); | |||
| 2117 | ||||
| 2118 | if (width) | |||
| 2119 | *width = info.width; | |||
| 2120 | if (height) | |||
| 2121 | *height = info.height; | |||
| 2122 | ||||
| 2123 | return info.format; | |||
| 2124 | } | |||
| 2125 | ||||
| 2126 | typedef struct { | |||
| 2127 | gchar *filename; | |||
| 2128 | gint width; | |||
| 2129 | gint height; | |||
| 2130 | } GetFileInfoAsyncData; | |||
| 2131 | ||||
| 2132 | static void | |||
| 2133 | get_file_info_async_data_free (GetFileInfoAsyncData *data) | |||
| 2134 | { | |||
| 2135 | g_free (data->filename); | |||
| 2136 | g_slice_free (GetFileInfoAsyncData, data)do { if (1) g_slice_free1 (sizeof (GetFileInfoAsyncData), (data )); else (void) ((GetFileInfoAsyncData*) 0 == (data)); } while (0); | |||
| 2137 | } | |||
| 2138 | ||||
| 2139 | static void | |||
| 2140 | get_file_info_thread (GTask *task, | |||
| 2141 | gpointer source_object, | |||
| 2142 | GetFileInfoAsyncData *data, | |||
| 2143 | GCancellable *cancellable) | |||
| 2144 | { | |||
| 2145 | CdkPixbufFormat *format; | |||
| 2146 | ||||
| 2147 | format = cdk_pixbuf_get_file_info (data->filename, &data->width, &data->height); | |||
| 2148 | if (format == NULL((void*)0)) { | |||
| 2149 | g_task_return_new_error (task, | |||
| 2150 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 2151 | CDK_PIXBUF_ERROR_UNKNOWN_TYPE, | |||
| 2152 | "Failed to recognize image format"); | |||
| 2153 | } else { | |||
| 2154 | g_task_return_pointer (task, | |||
| 2155 | cdk_pixbuf_format_copy (format), | |||
| 2156 | (GDestroyNotify) cdk_pixbuf_format_free); | |||
| 2157 | } | |||
| 2158 | } | |||
| 2159 | ||||
| 2160 | /** | |||
| 2161 | * cdk_pixbuf_get_file_info_async: | |||
| 2162 | * @filename: (type filename): The name of the file to identify | |||
| 2163 | * @cancellable: (allow-none): optional `GCancellable` object, `NULL` to ignore | |||
| 2164 | * @callback: a `GAsyncReadyCallback` to call when the file info is available | |||
| 2165 | * @user_data: the data to pass to the callback function | |||
| 2166 | * | |||
| 2167 | * Asynchronously parses an image file far enough to determine its | |||
| 2168 | * format and size. | |||
| 2169 | * | |||
| 2170 | * For more details see cdk_pixbuf_get_file_info(), which is the synchronous | |||
| 2171 | * version of this function. | |||
| 2172 | * | |||
| 2173 | * When the operation is finished, @callback will be called in the | |||
| 2174 | * main thread. You can then call cdk_pixbuf_get_file_info_finish() to | |||
| 2175 | * get the result of the operation. | |||
| 2176 | * | |||
| 2177 | * Since: 2.32 | |||
| 2178 | **/ | |||
| 2179 | void | |||
| 2180 | cdk_pixbuf_get_file_info_async (const gchar *filename, | |||
| 2181 | GCancellable *cancellable, | |||
| 2182 | GAsyncReadyCallback callback, | |||
| 2183 | gpointer user_data) | |||
| 2184 | { | |||
| 2185 | GetFileInfoAsyncData *data; | |||
| 2186 | GTask *task; | |||
| 2187 | ||||
| 2188 | g_return_if_fail (filename != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_107 = 0; if (filename != ((void*)0)) _g_boolean_var_107 = 1; _g_boolean_var_107 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "filename != NULL"); return; } } while (0); | |||
| 2189 | g_return_if_fail (callback != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_108 = 0; if (callback != ((void*)0)) _g_boolean_var_108 = 1; _g_boolean_var_108 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "callback != NULL"); return; } } while (0); | |||
| 2190 | g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_109 = 0; if (!cancellable || (((__extension__ ({ GTypeInstance * __inst = (GTypeInstance*) ((cancellable)); GType __t = ((g_cancellable_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; }))))) _g_boolean_var_109 = 1; _g_boolean_var_109; }), 1 ))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "!cancellable || G_IS_CANCELLABLE (cancellable)" ); return; } } while (0); | |||
| 2191 | ||||
| 2192 | data = g_slice_new0 (GetFileInfoAsyncData)(GetFileInfoAsyncData *) (__extension__ ({ gsize __s = (sizeof (GetFileInfoAsyncData) > 0 ? sizeof (GetFileInfoAsyncData ) : 1); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s); __p; })); | |||
| 2193 | data->filename = g_strdup (filename)g_strdup_inline (filename); | |||
| 2194 | ||||
| 2195 | task = g_task_new (NULL((void*)0), cancellable, callback, user_data); | |||
| 2196 | g_task_set_return_on_cancel (task, TRUE(!(0))); | |||
| 2197 | g_task_set_source_tag (task, cdk_pixbuf_get_file_info_async)do { GTask *_task = (task); (g_task_set_source_tag) (_task, cdk_pixbuf_get_file_info_async ); if (g_task_get_name (_task) == ((void*)0)) g_task_set_static_name (_task, "cdk_pixbuf_get_file_info_async"); } while (0); | |||
| 2198 | g_task_set_task_data (task, data, (GDestroyNotify) get_file_info_async_data_free); | |||
| 2199 | g_task_run_in_thread (task, (GTaskThreadFunc) get_file_info_thread); | |||
| 2200 | g_object_unref (task); | |||
| 2201 | } | |||
| 2202 | ||||
| 2203 | /** | |||
| 2204 | * cdk_pixbuf_get_file_info_finish: | |||
| 2205 | * @async_result: a `GAsyncResult` | |||
| 2206 | * @width: (out): Return location for the width of the image, or `NULL` | |||
| 2207 | * @height: (out): Return location for the height of the image, or `NULL` | |||
| 2208 | * @error: a `GError`, or `NULL` | |||
| 2209 | * | |||
| 2210 | * Finishes an asynchronous pixbuf parsing operation started with | |||
| 2211 | * cdk_pixbuf_get_file_info_async(). | |||
| 2212 | * | |||
| 2213 | * Returns: (transfer none) (nullable): A `CdkPixbufFormat` describing the | |||
| 2214 | * image format of the file | |||
| 2215 | * | |||
| 2216 | * Since: 2.32 | |||
| 2217 | **/ | |||
| 2218 | CdkPixbufFormat * | |||
| 2219 | cdk_pixbuf_get_file_info_finish (GAsyncResult *async_result, | |||
| 2220 | gint *width, | |||
| 2221 | gint *height, | |||
| 2222 | GError **error) | |||
| 2223 | { | |||
| 2224 | GetFileInfoAsyncData *data; | |||
| 2225 | GTask *task; | |||
| 2226 | ||||
| 2227 | g_return_val_if_fail (g_task_is_valid (async_result, NULL), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_110 = 0; if (g_task_is_valid (async_result, ((void*)0))) _g_boolean_var_110 = 1; _g_boolean_var_110; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "g_task_is_valid (async_result, NULL)" ); return (((void*)0)); } } while (0); | |||
| 2228 | ||||
| 2229 | task = G_TASK (async_result)((((GTask*) (void *) ((async_result))))); | |||
| 2230 | ||||
| 2231 | g_return_val_if_fail (!error || (error && !*error), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_111 = 0; if (!error || (error && !*error)) _g_boolean_var_111 = 1; _g_boolean_var_111; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "!error || (error && !*error)" ); return (((void*)0)); } } while (0); | |||
| 2232 | g_warn_if_fail (g_task_get_source_tag (task) == cdk_pixbuf_get_file_info_async)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_112 = 0; if (g_task_get_source_tag (task) == cdk_pixbuf_get_file_info_async ) _g_boolean_var_112 = 1; _g_boolean_var_112; }), 1)) ; else g_warn_message ("CdkPixbuf", "../cdk-pixbuf/cdk-pixbuf-io.c", 2232, ((const char*) (__func__)), "g_task_get_source_tag (task) == cdk_pixbuf_get_file_info_async" ); } while (0); | |||
| 2233 | ||||
| 2234 | data = g_task_get_task_data (task); | |||
| 2235 | ||||
| 2236 | if (!g_task_had_error (task)) { | |||
| 2237 | if (width) | |||
| 2238 | *width = data->width; | |||
| 2239 | if (height) | |||
| 2240 | *height = data->height; | |||
| 2241 | } | |||
| 2242 | ||||
| 2243 | return g_task_propagate_pointer (task, error); | |||
| 2244 | } | |||
| 2245 | ||||
| 2246 | /** | |||
| 2247 | * cdk_pixbuf_new_from_xpm_data: (constructor) | |||
| 2248 | * @data: (array zero-terminated=1): Pointer to inline XPM data. | |||
| 2249 | * | |||
| 2250 | * Creates a new pixbuf by parsing XPM data in memory. | |||
| 2251 | * | |||
| 2252 | * This data is commonly the result of including an XPM file into a | |||
| 2253 | * program's C source. | |||
| 2254 | * | |||
| 2255 | * Returns: (nullable): A newly-created pixbuf | |||
| 2256 | * | |||
| 2257 | * Deprecated: 2.44: Use [ctor@CdkPixbuf.Pixbuf.new_from_stream] with | |||
| 2258 | * a [class@Gio.MemoryInputStream], making sure to handle errors in | |||
| 2259 | * case the XPM format loader is not available | |||
| 2260 | **/ | |||
| 2261 | CdkPixbuf * | |||
| 2262 | cdk_pixbuf_new_from_xpm_data (const char **data) | |||
| 2263 | { | |||
| 2264 | CdkPixbuf *(* load_xpm_data) (const char **data); | |||
| 2265 | CdkPixbuf *pixbuf; | |||
| 2266 | GError *error = NULL((void*)0); | |||
| 2267 | CdkPixbufModule *xpm_module; | |||
| 2268 | ||||
| 2269 | g_return_val_if_fail (data != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_113 = 0; if (data != ((void*)0)) _g_boolean_var_113 = 1; _g_boolean_var_113 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "data != NULL"); return (((void*)0 )); } } while (0); | |||
| 2270 | ||||
| 2271 | xpm_module = _cdk_pixbuf_get_named_module ("xpm", &error); | |||
| 2272 | if (xpm_module == NULL((void*)0)) { | |||
| 2273 | g_warning ("Error loading XPM image loader: %s", error->message); | |||
| 2274 | g_error_free (error); | |||
| 2275 | return NULL((void*)0); | |||
| 2276 | } | |||
| 2277 | ||||
| 2278 | if (!_cdk_pixbuf_load_module (xpm_module, &error)) { | |||
| 2279 | g_warning ("Error loading XPM image loader: %s", error->message); | |||
| 2280 | g_error_free (error); | |||
| 2281 | return NULL((void*)0); | |||
| 2282 | } | |||
| 2283 | ||||
| 2284 | if (xpm_module->load_xpm_data == NULL((void*)0)) { | |||
| 2285 | g_warning ("cdk-pixbuf XPM module lacks XPM data capability"); | |||
| 2286 | pixbuf = NULL((void*)0); | |||
| 2287 | } else { | |||
| 2288 | load_xpm_data = xpm_module->load_xpm_data; | |||
| 2289 | pixbuf = (* load_xpm_data) (data); | |||
| 2290 | } | |||
| 2291 | ||||
| 2292 | return pixbuf; | |||
| 2293 | } | |||
| 2294 | ||||
| 2295 | static void | |||
| 2296 | collect_save_options (va_list opts, | |||
| 2297 | gchar ***keys, | |||
| 2298 | gchar ***vals) | |||
| 2299 | { | |||
| 2300 | gchar *key; | |||
| 2301 | gchar *val; | |||
| 2302 | gchar *next; | |||
| 2303 | gint count; | |||
| 2304 | ||||
| 2305 | count = 0; | |||
| 2306 | *keys = NULL((void*)0); | |||
| 2307 | *vals = NULL((void*)0); | |||
| 2308 | ||||
| 2309 | next = va_arg (opts, gchar*)__builtin_va_arg(opts, gchar*); | |||
| 2310 | while (next) | |||
| 2311 | { | |||
| 2312 | key = next; | |||
| 2313 | val = va_arg (opts, gchar*)__builtin_va_arg(opts, gchar*); | |||
| 2314 | ||||
| 2315 | ++count; | |||
| 2316 | ||||
| 2317 | /* woo, slow */ | |||
| 2318 | *keys = g_realloc (*keys, sizeof(gchar*) * (count + 1)); | |||
| 2319 | *vals = g_realloc (*vals, sizeof(gchar*) * (count + 1)); | |||
| 2320 | ||||
| 2321 | (*keys)[count-1] = g_strdup (key)g_strdup_inline (key); | |||
| 2322 | (*vals)[count-1] = g_strdup (val)g_strdup_inline (val); | |||
| 2323 | ||||
| 2324 | (*keys)[count] = NULL((void*)0); | |||
| 2325 | (*vals)[count] = NULL((void*)0); | |||
| 2326 | ||||
| 2327 | next = va_arg (opts, gchar*)__builtin_va_arg(opts, gchar*); | |||
| 2328 | } | |||
| 2329 | } | |||
| 2330 | ||||
| 2331 | static gboolean | |||
| 2332 | save_to_file_callback (const gchar *buf, | |||
| 2333 | gsize count, | |||
| 2334 | GError **error, | |||
| 2335 | gpointer data) | |||
| 2336 | { | |||
| 2337 | FILE *filehandle = data; | |||
| 2338 | gsize n; | |||
| 2339 | ||||
| 2340 | n = fwrite (buf, 1, count, filehandle); | |||
| 2341 | if (n != count) { | |||
| 2342 | gint save_errno = errno(*__errno_location ()); | |||
| 2343 | g_set_error (error, | |||
| 2344 | G_FILE_ERRORg_file_error_quark (), | |||
| 2345 | g_file_error_from_errno (save_errno), | |||
| 2346 | _("Error writing to image file: %s")((char *) g_dgettext ("cdk-pixbuf", "Error writing to image file: %s" )), | |||
| 2347 | g_strerror (save_errno)); | |||
| 2348 | return FALSE(0); | |||
| 2349 | } | |||
| 2350 | return TRUE(!(0)); | |||
| 2351 | } | |||
| 2352 | ||||
| 2353 | static gboolean | |||
| 2354 | cdk_pixbuf_real_save (CdkPixbuf *pixbuf, | |||
| 2355 | FILE *filehandle, | |||
| 2356 | const char *type, | |||
| 2357 | gchar **keys, | |||
| 2358 | gchar **values, | |||
| 2359 | GError **error) | |||
| 2360 | { | |||
| 2361 | gboolean ret; | |||
| 2362 | CdkPixbufModule *image_module = NULL((void*)0); | |||
| 2363 | ||||
| 2364 | image_module = _cdk_pixbuf_get_named_module (type, error); | |||
| 2365 | ||||
| 2366 | if (image_module == NULL((void*)0)) | |||
| 2367 | return FALSE(0); | |||
| 2368 | ||||
| 2369 | if (!_cdk_pixbuf_load_module (image_module, error)) | |||
| 2370 | return FALSE(0); | |||
| 2371 | ||||
| 2372 | if (image_module->save) { | |||
| 2373 | /* save normally */ | |||
| 2374 | ret = (* image_module->save) (filehandle, pixbuf, | |||
| 2375 | keys, values, | |||
| 2376 | error); | |||
| 2377 | } else if (image_module->save_to_callback) { | |||
| 2378 | /* save with simple callback */ | |||
| 2379 | ret = (* image_module->save_to_callback) (save_to_file_callback, | |||
| 2380 | filehandle, pixbuf, | |||
| 2381 | keys, values, | |||
| 2382 | error); | |||
| 2383 | } else { | |||
| 2384 | /* can't save */ | |||
| 2385 | g_set_error (error, | |||
| 2386 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 2387 | CDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, | |||
| 2388 | _("This build of cdk-pixbuf does not support saving the image format: %s")((char *) g_dgettext ("cdk-pixbuf", "This build of cdk-pixbuf does not support saving the image format: %s" )), | |||
| 2389 | type); | |||
| 2390 | ret = FALSE(0); | |||
| 2391 | } | |||
| 2392 | ||||
| 2393 | return ret; | |||
| 2394 | } | |||
| 2395 | ||||
| 2396 | #define TMP_FILE_BUF_SIZE4096 4096 | |||
| 2397 | ||||
| 2398 | static gboolean | |||
| 2399 | save_to_callback_with_tmp_file (CdkPixbufModule *image_module, | |||
| 2400 | CdkPixbuf *pixbuf, | |||
| 2401 | CdkPixbufSaveFunc save_func, | |||
| 2402 | gpointer user_data, | |||
| 2403 | gchar **keys, | |||
| 2404 | gchar **values, | |||
| 2405 | GError **error) | |||
| 2406 | { | |||
| 2407 | int fd; | |||
| 2408 | FILE *f = NULL((void*)0); | |||
| 2409 | gboolean retval = FALSE(0); | |||
| 2410 | gchar *buf = NULL((void*)0); | |||
| 2411 | gsize n; | |||
| 2412 | gchar *filename = NULL((void*)0); | |||
| 2413 | ||||
| 2414 | buf = g_try_malloc (TMP_FILE_BUF_SIZE4096); | |||
| 2415 | if (buf == NULL((void*)0)) { | |||
| 2416 | g_set_error_literal (error, | |||
| 2417 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 2418 | CDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, | |||
| 2419 | _("Insufficient memory to save image to callback")((char *) g_dgettext ("cdk-pixbuf", "Insufficient memory to save image to callback" ))); | |||
| 2420 | goto end; | |||
| 2421 | } | |||
| 2422 | ||||
| 2423 | fd = g_file_open_tmp ("cdkpixbuf-save-tmp.XXXXXX", &filename, error); | |||
| 2424 | if (fd == -1) | |||
| 2425 | goto end; | |||
| 2426 | f = fdopen (fd, "wb+"); | |||
| 2427 | if (f
| |||
| 2428 | gint save_errno = errno(*__errno_location ()); | |||
| 2429 | g_set_error_literal (error, | |||
| 2430 | G_FILE_ERRORg_file_error_quark (), | |||
| 2431 | g_file_error_from_errno (save_errno), | |||
| 2432 | _("Failed to open temporary file")((char *) g_dgettext ("cdk-pixbuf", "Failed to open temporary file" ))); | |||
| 2433 | goto end; | |||
| 2434 | } | |||
| 2435 | ||||
| 2436 | retval = (image_module->save) (f, pixbuf, keys, values, error); | |||
| 2437 | if (!retval) | |||
| 2438 | goto end; | |||
| 2439 | ||||
| 2440 | rewind (f); | |||
| 2441 | for (;;) { | |||
| 2442 | n = fread (buf, 1, TMP_FILE_BUF_SIZE4096, f); | |||
| ||||
| 2443 | if (n > 0) { | |||
| 2444 | if (!save_func (buf, n, error, user_data)) | |||
| 2445 | goto end; | |||
| 2446 | } | |||
| 2447 | if (n != TMP_FILE_BUF_SIZE4096) | |||
| 2448 | break; | |||
| 2449 | } | |||
| 2450 | if (ferror (f)) { | |||
| 2451 | gint save_errno = errno(*__errno_location ()); | |||
| 2452 | g_set_error_literal (error, | |||
| 2453 | G_FILE_ERRORg_file_error_quark (), | |||
| 2454 | g_file_error_from_errno (save_errno), | |||
| 2455 | _("Failed to read from temporary file")((char *) g_dgettext ("cdk-pixbuf", "Failed to read from temporary file" ))); | |||
| 2456 | goto end; | |||
| 2457 | } | |||
| 2458 | retval = TRUE(!(0)); | |||
| 2459 | ||||
| 2460 | end: | |||
| 2461 | /* cleanup and return retval */ | |||
| 2462 | if (f) | |||
| 2463 | fclose (f); | |||
| 2464 | if (filename) { | |||
| 2465 | g_unlink (filename); | |||
| 2466 | g_free (filename); | |||
| 2467 | } | |||
| 2468 | g_free (buf); | |||
| 2469 | ||||
| 2470 | return retval; | |||
| 2471 | } | |||
| 2472 | ||||
| 2473 | static gboolean | |||
| 2474 | cdk_pixbuf_real_save_to_callback (CdkPixbuf *pixbuf, | |||
| 2475 | CdkPixbufSaveFunc save_func, | |||
| 2476 | gpointer user_data, | |||
| 2477 | const char *type, | |||
| 2478 | gchar **keys, | |||
| 2479 | gchar **values, | |||
| 2480 | GError **error) | |||
| 2481 | { | |||
| 2482 | gboolean ret; | |||
| 2483 | CdkPixbufModule *image_module = NULL((void*)0); | |||
| 2484 | ||||
| 2485 | image_module = _cdk_pixbuf_get_named_module (type, error); | |||
| 2486 | ||||
| 2487 | if (image_module == NULL((void*)0)) | |||
| 2488 | return FALSE(0); | |||
| 2489 | ||||
| 2490 | if (!_cdk_pixbuf_load_module (image_module, error)) | |||
| 2491 | return FALSE(0); | |||
| 2492 | ||||
| 2493 | if (image_module->save_to_callback) { | |||
| 2494 | /* save normally */ | |||
| 2495 | ret = (* image_module->save_to_callback) (save_func, user_data, | |||
| 2496 | pixbuf, keys, values, | |||
| 2497 | error); | |||
| 2498 | } else if (image_module->save) { | |||
| 2499 | /* use a temporary file */ | |||
| 2500 | ret = save_to_callback_with_tmp_file (image_module, pixbuf, | |||
| 2501 | save_func, user_data, | |||
| 2502 | keys, values, | |||
| 2503 | error); | |||
| 2504 | } else { | |||
| 2505 | /* can't save */ | |||
| 2506 | g_set_error (error, | |||
| 2507 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 2508 | CDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, | |||
| 2509 | _("This build of cdk-pixbuf does not support saving the image format: %s")((char *) g_dgettext ("cdk-pixbuf", "This build of cdk-pixbuf does not support saving the image format: %s" )), | |||
| 2510 | type); | |||
| 2511 | ret = FALSE(0); | |||
| 2512 | } | |||
| 2513 | ||||
| 2514 | return ret; | |||
| 2515 | } | |||
| 2516 | ||||
| 2517 | ||||
| 2518 | /** | |||
| 2519 | * cdk_pixbuf_save: | |||
| 2520 | * @pixbuf: a `CdkPixbuf`. | |||
| 2521 | * @filename: (type filename): name of file to save. | |||
| 2522 | * @type: name of file format. | |||
| 2523 | * @error: (nullable): return location for error | |||
| 2524 | * @...: list of key-value save options, followed by `NULL` | |||
| 2525 | * | |||
| 2526 | * Saves pixbuf to a file in format @type. By default, "jpeg", "png", "ico" | |||
| 2527 | * and "bmp" are possible file formats to save in, but more formats may be | |||
| 2528 | * installed. The list of all writable formats can be determined in the | |||
| 2529 | * following way: | |||
| 2530 | * | |||
| 2531 | * ```c | |||
| 2532 | * void add_if_writable (CdkPixbufFormat *data, GSList **list) | |||
| 2533 | * { | |||
| 2534 | * if (cdk_pixbuf_format_is_writable (data)) | |||
| 2535 | * *list = g_slist_prepend (*list, data); | |||
| 2536 | * } | |||
| 2537 | * | |||
| 2538 | * GSList *formats = cdk_pixbuf_get_formats (); | |||
| 2539 | * GSList *writable_formats = NULL; | |||
| 2540 | * g_slist_foreach (formats, add_if_writable, &writable_formats); | |||
| 2541 | * g_slist_free (formats); | |||
| 2542 | * ``` | |||
| 2543 | * | |||
| 2544 | * If `error` is set, `FALSE` will be returned. Possible errors include | |||
| 2545 | * those in the `CDK_PIXBUF_ERROR` domain and those in the `G_FILE_ERROR` | |||
| 2546 | * domain. | |||
| 2547 | * | |||
| 2548 | * The variable argument list should be `NULL`-terminated; if not empty, | |||
| 2549 | * it should contain pairs of strings that modify the save | |||
| 2550 | * parameters. For example: | |||
| 2551 | * | |||
| 2552 | * ```c | |||
| 2553 | * cdk_pixbuf_save (pixbuf, handle, "jpeg", &error, "quality", "100", NULL); | |||
| 2554 | * ``` | |||
| 2555 | * | |||
| 2556 | * Currently only few parameters exist. | |||
| 2557 | * | |||
| 2558 | * JPEG images can be saved with a "quality" parameter; its value should be | |||
| 2559 | * in the range `[0, 100]`. JPEG and PNG density can be set by setting the | |||
| 2560 | * "x-dpi" and "y-dpi" parameters to the appropriate values in dots per inch. | |||
| 2561 | * | |||
| 2562 | * Text chunks can be attached to PNG images by specifying parameters of | |||
| 2563 | * the form "tEXt::key", where key is an ASCII string of length 1-79. | |||
| 2564 | * The values are UTF-8 encoded strings. The PNG compression level can | |||
| 2565 | * be specified using the "compression" parameter; it's value is in an | |||
| 2566 | * integer in the range of `[0, 9]`. | |||
| 2567 | * | |||
| 2568 | * ICC color profiles can also be embedded into PNG, JPEG and TIFF images. | |||
| 2569 | * The "icc-profile" value should be the complete ICC profile encoded | |||
| 2570 | * into base64. | |||
| 2571 | * | |||
| 2572 | * ```c | |||
| 2573 | * char *contents; | |||
| 2574 | * gsize length; | |||
| 2575 | * | |||
| 2576 | * // icm_path is set elsewhere | |||
| 2577 | * g_file_get_contents (icm_path, &contents, &length, NULL); | |||
| 2578 | * | |||
| 2579 | * char *contents_encode = g_base64_encode ((const guchar *) contents, length); | |||
| 2580 | * | |||
| 2581 | * cdk_pixbuf_save (pixbuf, handle, "png", &error, "icc-profile", contents_encode, NULL); | |||
| 2582 | * ``` | |||
| 2583 | * | |||
| 2584 | * TIFF images recognize: | |||
| 2585 | * | |||
| 2586 | * 1. a "bits-per-sample" option (integer) which can be either 1 for saving | |||
| 2587 | * bi-level CCITTFAX4 images, or 8 for saving 8-bits per sample | |||
| 2588 | * 2. a "compression" option (integer) which can be 1 for no compression, | |||
| 2589 | * 2 for Huffman, 5 for LZW, 7 for JPEG and 8 for DEFLATE (see the libtiff | |||
| 2590 | * documentation and tiff.h for all supported codec values) | |||
| 2591 | * 3. an "icc-profile" option (zero-terminated string) containing a base64 | |||
| 2592 | * encoded ICC color profile. | |||
| 2593 | * | |||
| 2594 | * ICO images can be saved in depth 16, 24, or 32, by using the "depth" | |||
| 2595 | * parameter. When the ICO saver is given "x_hot" and "y_hot" parameters, | |||
| 2596 | * it produces a CUR instead of an ICO. | |||
| 2597 | * | |||
| 2598 | * Returns: `TRUE` on success, and `FALSE` otherwise | |||
| 2599 | **/ | |||
| 2600 | gboolean | |||
| 2601 | cdk_pixbuf_save (CdkPixbuf *pixbuf, | |||
| 2602 | const char *filename, | |||
| 2603 | const char *type, | |||
| 2604 | GError **error, | |||
| 2605 | ...) | |||
| 2606 | { | |||
| 2607 | gchar **keys = NULL((void*)0); | |||
| 2608 | gchar **values = NULL((void*)0); | |||
| 2609 | va_list args; | |||
| 2610 | gboolean result; | |||
| 2611 | ||||
| 2612 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_114 = 0; if (error == ((void*)0) || *error == ((void*)0)) _g_boolean_var_114 = 1; _g_boolean_var_114; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "error == NULL || *error == NULL" ); return ((0)); } } while (0); | |||
| 2613 | ||||
| 2614 | va_start (args, error)__builtin_va_start(args, error); | |||
| 2615 | ||||
| 2616 | collect_save_options (args, &keys, &values); | |||
| 2617 | ||||
| 2618 | va_end (args)__builtin_va_end(args); | |||
| 2619 | ||||
| 2620 | result = cdk_pixbuf_savev (pixbuf, filename, type, | |||
| 2621 | keys, values, | |||
| 2622 | error); | |||
| 2623 | ||||
| 2624 | g_strfreev (keys); | |||
| 2625 | g_strfreev (values); | |||
| 2626 | ||||
| 2627 | return result; | |||
| 2628 | } | |||
| 2629 | ||||
| 2630 | /** | |||
| 2631 | * cdk_pixbuf_savev: | |||
| 2632 | * @pixbuf: a `CdkPixbuf`. | |||
| 2633 | * @filename: (type filename): name of file to save. | |||
| 2634 | * @type: name of file format. | |||
| 2635 | * @option_keys: (array zero-terminated=1) (element-type utf8) (nullable): name of options to set | |||
| 2636 | * @option_values: (array zero-terminated=1) (element-type utf8) (nullable): values for named options | |||
| 2637 | * @error: (allow-none): return location for error, or `NULL` | |||
| 2638 | * | |||
| 2639 | * Vector version of `cdk_pixbuf_save()`. | |||
| 2640 | * | |||
| 2641 | * Saves pixbuf to a file in `type`, which is currently "jpeg", "png", "tiff", "ico" or "bmp". | |||
| 2642 | * | |||
| 2643 | * If @error is set, `FALSE` will be returned. | |||
| 2644 | * | |||
| 2645 | * See [method@CdkPixbuf.Pixbuf.save] for more details. | |||
| 2646 | * | |||
| 2647 | * Returns: whether an error was set | |||
| 2648 | **/ | |||
| 2649 | ||||
| 2650 | gboolean | |||
| 2651 | cdk_pixbuf_savev (CdkPixbuf *pixbuf, | |||
| 2652 | const char *filename, | |||
| 2653 | const char *type, | |||
| 2654 | char **option_keys, | |||
| 2655 | char **option_values, | |||
| 2656 | GError **error) | |||
| 2657 | { | |||
| 2658 | FILE *f = NULL((void*)0); | |||
| 2659 | gboolean result; | |||
| 2660 | ||||
| 2661 | g_return_val_if_fail (CDK_IS_PIXBUF (pixbuf), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_115 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((pixbuf)); 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; }))))) _g_boolean_var_115 = 1; _g_boolean_var_115; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "CDK_IS_PIXBUF (pixbuf)" ); return ((0)); } } while (0); | |||
| 2662 | g_return_val_if_fail (cdk_pixbuf_get_width (pixbuf) >= 0, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_116 = 0; if (cdk_pixbuf_get_width (pixbuf) >= 0) _g_boolean_var_116 = 1; _g_boolean_var_116; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_width (pixbuf) >= 0" ); return ((0)); } } while (0); | |||
| 2663 | g_return_val_if_fail (cdk_pixbuf_get_height (pixbuf) >= 0, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_117 = 0; if (cdk_pixbuf_get_height (pixbuf) >= 0) _g_boolean_var_117 = 1; _g_boolean_var_117; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_height (pixbuf) >= 0" ); return ((0)); } } while (0); | |||
| 2664 | g_return_val_if_fail (cdk_pixbuf_get_n_channels (pixbuf) >= 0, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_118 = 0; if (cdk_pixbuf_get_n_channels (pixbuf) >= 0) _g_boolean_var_118 = 1; _g_boolean_var_118; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_n_channels (pixbuf) >= 0" ); return ((0)); } } while (0); | |||
| 2665 | g_return_val_if_fail (filename != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_119 = 0; if (filename != ((void*)0)) _g_boolean_var_119 = 1; _g_boolean_var_119 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "filename != NULL"); return ((0)); } } while (0); | |||
| 2666 | g_return_val_if_fail (type != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_120 = 0; if (type != ((void*)0)) _g_boolean_var_120 = 1; _g_boolean_var_120 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "type != NULL"); return ((0)); } } while (0); | |||
| 2667 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_121 = 0; if (error == ((void*)0) || *error == ((void*)0)) _g_boolean_var_121 = 1; _g_boolean_var_121; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "error == NULL || *error == NULL" ); return ((0)); } } while (0); | |||
| 2668 | ||||
| 2669 | f = g_fopenfopen (filename, "wb"); | |||
| 2670 | ||||
| 2671 | if (f == NULL((void*)0)) { | |||
| 2672 | gint save_errno = errno(*__errno_location ()); | |||
| 2673 | gchar *display_name = g_filename_display_name (filename); | |||
| 2674 | g_set_error (error, | |||
| 2675 | G_FILE_ERRORg_file_error_quark (), | |||
| 2676 | g_file_error_from_errno (save_errno), | |||
| 2677 | _("Failed to open “%s” for writing: %s")((char *) g_dgettext ("cdk-pixbuf", "Failed to open “%s” for writing: %s" )), | |||
| 2678 | display_name, | |||
| 2679 | g_strerror (save_errno)); | |||
| 2680 | g_free (display_name); | |||
| 2681 | return FALSE(0); | |||
| 2682 | } | |||
| 2683 | ||||
| 2684 | ||||
| 2685 | result = cdk_pixbuf_real_save (pixbuf, f, type, | |||
| 2686 | option_keys, option_values, | |||
| 2687 | error); | |||
| 2688 | ||||
| 2689 | ||||
| 2690 | if (!result) { | |||
| 2691 | g_return_val_if_fail (error == NULL || *error != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_122 = 0; if (error == ((void*)0) || *error != ((void*)0)) _g_boolean_var_122 = 1; _g_boolean_var_122; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "error == NULL || *error != NULL" ); return ((0)); } } while (0); | |||
| 2692 | fclose (f); | |||
| 2693 | g_unlink (filename); | |||
| 2694 | return FALSE(0); | |||
| 2695 | } | |||
| 2696 | ||||
| 2697 | if (fclose (f) < 0) { | |||
| 2698 | gint save_errno = errno(*__errno_location ()); | |||
| 2699 | gchar *display_name = g_filename_display_name (filename); | |||
| 2700 | g_set_error (error, | |||
| 2701 | G_FILE_ERRORg_file_error_quark (), | |||
| 2702 | g_file_error_from_errno (save_errno), | |||
| 2703 | _("Failed to close “%s” while writing image, all data may not have been saved: %s")((char *) g_dgettext ("cdk-pixbuf", "Failed to close “%s” while writing image, all data may not have been saved: %s" )), | |||
| 2704 | display_name, | |||
| 2705 | g_strerror (save_errno)); | |||
| 2706 | g_free (display_name); | |||
| 2707 | return FALSE(0); | |||
| 2708 | } | |||
| 2709 | ||||
| 2710 | return TRUE(!(0)); | |||
| 2711 | } | |||
| 2712 | ||||
| 2713 | #ifdef G_OS_WIN32 | |||
| 2714 | ||||
| 2715 | /** | |||
| 2716 | * cdk_pixbuf_savev_utf8: | |||
| 2717 | * @pixbuf: a `CdkPixbuf`. | |||
| 2718 | * @filename: name of file to save. | |||
| 2719 | * @type: name of file format. | |||
| 2720 | * @option_keys: (array zero-terminated=1) (element-type utf8) (nullable): name of options to set | |||
| 2721 | * @option_values: (array zero-terminated=1) (element-type utf8) (nullable): values for named options | |||
| 2722 | * @error: (allow-none): return location for error, or `NULL` | |||
| 2723 | * | |||
| 2724 | * Same as cdk_pixbuf_savev() | |||
| 2725 | * | |||
| 2726 | * Returns: whether an error was set | |||
| 2727 | **/ | |||
| 2728 | gboolean | |||
| 2729 | cdk_pixbuf_savev_utf8 (CdkPixbuf *pixbuf, | |||
| 2730 | const char *filename, | |||
| 2731 | const char *type, | |||
| 2732 | char **option_keys, | |||
| 2733 | char **option_values, | |||
| 2734 | GError **error) | |||
| 2735 | { | |||
| 2736 | return cdk_pixbuf_savev (pixbuf, filename, type, option_keys, | |||
| 2737 | option_values, error); | |||
| 2738 | } | |||
| 2739 | ||||
| 2740 | #endif | |||
| 2741 | ||||
| 2742 | /** | |||
| 2743 | * cdk_pixbuf_save_to_callback: | |||
| 2744 | * @pixbuf: a `CdkPixbuf`. | |||
| 2745 | * @save_func: (scope call): a function that is called to save each block of data that | |||
| 2746 | * the save routine generates. | |||
| 2747 | * @user_data: user data to pass to the save function. | |||
| 2748 | * @type: name of file format. | |||
| 2749 | * @error: (allow-none): return location for error, or `NULL` | |||
| 2750 | * @...: list of key-value save options | |||
| 2751 | * | |||
| 2752 | * Saves pixbuf in format `type` by feeding the produced data to a | |||
| 2753 | * callback. | |||
| 2754 | * | |||
| 2755 | * This function can be used when you want to store the image to something | |||
| 2756 | * other than a file, such as an in-memory buffer or a socket. | |||
| 2757 | * | |||
| 2758 | * If @error is set, `FALSE` will be returned. Possible errors | |||
| 2759 | * include those in the `CDK_PIXBUF_ERROR` domain and whatever the save | |||
| 2760 | * function generates. | |||
| 2761 | * | |||
| 2762 | * See [method@CdkPixbuf.Pixbuf.save] for more details. | |||
| 2763 | * | |||
| 2764 | * Returns: whether an error was set | |||
| 2765 | * | |||
| 2766 | * Since: 2.4 | |||
| 2767 | **/ | |||
| 2768 | gboolean | |||
| 2769 | cdk_pixbuf_save_to_callback (CdkPixbuf *pixbuf, | |||
| 2770 | CdkPixbufSaveFunc save_func, | |||
| 2771 | gpointer user_data, | |||
| 2772 | const char *type, | |||
| 2773 | GError **error, | |||
| 2774 | ...) | |||
| 2775 | { | |||
| 2776 | gchar **keys = NULL((void*)0); | |||
| 2777 | gchar **values = NULL((void*)0); | |||
| 2778 | va_list args; | |||
| 2779 | gboolean result; | |||
| 2780 | ||||
| 2781 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_123 = 0; if (error == ((void*)0) || *error == ((void*)0)) _g_boolean_var_123 = 1; _g_boolean_var_123; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "error == NULL || *error == NULL" ); return ((0)); } } while (0); | |||
| 2782 | ||||
| 2783 | va_start (args, error)__builtin_va_start(args, error); | |||
| 2784 | ||||
| 2785 | collect_save_options (args, &keys, &values); | |||
| 2786 | ||||
| 2787 | va_end (args)__builtin_va_end(args); | |||
| 2788 | ||||
| 2789 | result = cdk_pixbuf_save_to_callbackv (pixbuf, save_func, user_data, | |||
| 2790 | type, keys, values, | |||
| 2791 | error); | |||
| 2792 | ||||
| 2793 | g_strfreev (keys); | |||
| 2794 | g_strfreev (values); | |||
| 2795 | ||||
| 2796 | return result; | |||
| 2797 | } | |||
| 2798 | ||||
| 2799 | /** | |||
| 2800 | * cdk_pixbuf_save_to_callbackv: | |||
| 2801 | * @pixbuf: a `CdkPixbuf` | |||
| 2802 | * @save_func: (scope call) (closure user_data): a function that is called to | |||
| 2803 | * save each block of data that the save routine generates | |||
| 2804 | * @user_data: user data to pass to the save function | |||
| 2805 | * @type: name of file format | |||
| 2806 | * @option_keys: (array zero-terminated=1) (element-type utf8) (nullable): name of options to set | |||
| 2807 | * @option_values: (array zero-terminated=1) (element-type utf8) (nullable): values for named options | |||
| 2808 | * @error: return location for error, or `NULL` | |||
| 2809 | * | |||
| 2810 | * Vector version of `cdk_pixbuf_save_to_callback()`. | |||
| 2811 | * | |||
| 2812 | * Saves pixbuf to a callback in format @type, which is currently "jpeg", | |||
| 2813 | * "png", "tiff", "ico" or "bmp". | |||
| 2814 | * | |||
| 2815 | * If @error is set, `FALSE` will be returned. | |||
| 2816 | * | |||
| 2817 | * See [method@CdkPixbuf.Pixbuf.save_to_callback] for more details. | |||
| 2818 | * | |||
| 2819 | * Returns: whether an error was set | |||
| 2820 | * | |||
| 2821 | * Since: 2.4 | |||
| 2822 | **/ | |||
| 2823 | gboolean | |||
| 2824 | cdk_pixbuf_save_to_callbackv (CdkPixbuf *pixbuf, | |||
| 2825 | CdkPixbufSaveFunc save_func, | |||
| 2826 | gpointer user_data, | |||
| 2827 | const char *type, | |||
| 2828 | char **option_keys, | |||
| 2829 | char **option_values, | |||
| 2830 | GError **error) | |||
| 2831 | { | |||
| 2832 | gboolean result; | |||
| 2833 | ||||
| 2834 | g_return_val_if_fail (CDK_IS_PIXBUF (pixbuf), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_124 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((pixbuf)); 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; }))))) _g_boolean_var_124 = 1; _g_boolean_var_124; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "CDK_IS_PIXBUF (pixbuf)" ); return ((0)); } } while (0); | |||
| 2835 | g_return_val_if_fail (cdk_pixbuf_get_width (pixbuf) >= 0, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_125 = 0; if (cdk_pixbuf_get_width (pixbuf) >= 0) _g_boolean_var_125 = 1; _g_boolean_var_125; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_width (pixbuf) >= 0" ); return ((0)); } } while (0); | |||
| 2836 | g_return_val_if_fail (cdk_pixbuf_get_height (pixbuf) >= 0, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_126 = 0; if (cdk_pixbuf_get_height (pixbuf) >= 0) _g_boolean_var_126 = 1; _g_boolean_var_126; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_height (pixbuf) >= 0" ); return ((0)); } } while (0); | |||
| 2837 | g_return_val_if_fail (cdk_pixbuf_get_n_channels (pixbuf) >= 0, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_127 = 0; if (cdk_pixbuf_get_n_channels (pixbuf) >= 0) _g_boolean_var_127 = 1; _g_boolean_var_127; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_n_channels (pixbuf) >= 0" ); return ((0)); } } while (0); | |||
| 2838 | g_return_val_if_fail (save_func != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_128 = 0; if (save_func != ((void*)0)) _g_boolean_var_128 = 1; _g_boolean_var_128 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "save_func != NULL"); return ((0)) ; } } while (0); | |||
| 2839 | g_return_val_if_fail (type != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_129 = 0; if (type != ((void*)0)) _g_boolean_var_129 = 1; _g_boolean_var_129 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "type != NULL"); return ((0)); } } while (0); | |||
| 2840 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_130 = 0; if (error == ((void*)0) || *error == ((void*)0)) _g_boolean_var_130 = 1; _g_boolean_var_130; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "error == NULL || *error == NULL" ); return ((0)); } } while (0); | |||
| 2841 | ||||
| 2842 | result = cdk_pixbuf_real_save_to_callback (pixbuf, | |||
| 2843 | save_func, user_data, type, | |||
| 2844 | option_keys, option_values, | |||
| 2845 | error); | |||
| 2846 | ||||
| 2847 | if (!result) { | |||
| 2848 | g_return_val_if_fail (error == NULL || *error != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_131 = 0; if (error == ((void*)0) || *error != ((void*)0)) _g_boolean_var_131 = 1; _g_boolean_var_131; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "error == NULL || *error != NULL" ); return ((0)); } } while (0); | |||
| 2849 | return FALSE(0); | |||
| 2850 | } | |||
| 2851 | ||||
| 2852 | return TRUE(!(0)); | |||
| 2853 | } | |||
| 2854 | ||||
| 2855 | /** | |||
| 2856 | * cdk_pixbuf_save_to_buffer: | |||
| 2857 | * @pixbuf: a `CdkPixbuf`. | |||
| 2858 | * @buffer: (array length=buffer_size) (out) (element-type guint8): location to receive a pointer | |||
| 2859 | * to the new buffer. | |||
| 2860 | * @buffer_size: location to receive the size of the new buffer. | |||
| 2861 | * @type: name of file format. | |||
| 2862 | * @error: return location for error, or `NULL` | |||
| 2863 | * @...: list of key-value save options | |||
| 2864 | * | |||
| 2865 | * Saves pixbuf to a new buffer in format `type`, which is currently "jpeg", | |||
| 2866 | * "png", "tiff", "ico" or "bmp". | |||
| 2867 | * | |||
| 2868 | * This is a convenience function that uses `cdk_pixbuf_save_to_callback()` | |||
| 2869 | * to do the real work. | |||
| 2870 | * | |||
| 2871 | * Note that the buffer is not `NUL`-terminated and may contain embedded `NUL` | |||
| 2872 | * characters. | |||
| 2873 | * | |||
| 2874 | * If @error is set, `FALSE` will be returned and @buffer will be set to | |||
| 2875 | * `NULL`. Possible errors include those in the `CDK_PIXBUF_ERROR` | |||
| 2876 | * domain. | |||
| 2877 | * | |||
| 2878 | * See `cdk_pixbuf_save()` for more details. | |||
| 2879 | * | |||
| 2880 | * Returns: whether an error was set | |||
| 2881 | * | |||
| 2882 | * Since: 2.4 | |||
| 2883 | **/ | |||
| 2884 | gboolean | |||
| 2885 | cdk_pixbuf_save_to_buffer (CdkPixbuf *pixbuf, | |||
| 2886 | gchar **buffer, | |||
| 2887 | gsize *buffer_size, | |||
| 2888 | const char *type, | |||
| 2889 | GError **error, | |||
| 2890 | ...) | |||
| 2891 | { | |||
| 2892 | gchar **keys = NULL((void*)0); | |||
| 2893 | gchar **values = NULL((void*)0); | |||
| 2894 | va_list args; | |||
| 2895 | gboolean result; | |||
| 2896 | ||||
| 2897 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_132 = 0; if (error == ((void*)0) || *error == ((void*)0)) _g_boolean_var_132 = 1; _g_boolean_var_132; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "error == NULL || *error == NULL" ); return ((0)); } } while (0); | |||
| 2898 | ||||
| 2899 | va_start (args, error)__builtin_va_start(args, error); | |||
| 2900 | ||||
| 2901 | collect_save_options (args, &keys, &values); | |||
| 2902 | ||||
| 2903 | va_end (args)__builtin_va_end(args); | |||
| 2904 | ||||
| 2905 | result = cdk_pixbuf_save_to_bufferv (pixbuf, buffer, buffer_size, | |||
| 2906 | type, keys, values, | |||
| 2907 | error); | |||
| 2908 | ||||
| 2909 | g_strfreev (keys); | |||
| 2910 | g_strfreev (values); | |||
| 2911 | ||||
| 2912 | return result; | |||
| 2913 | } | |||
| 2914 | ||||
| 2915 | struct SaveToBufferData { | |||
| 2916 | gchar *buffer; | |||
| 2917 | gsize len, max; | |||
| 2918 | }; | |||
| 2919 | ||||
| 2920 | static gboolean | |||
| 2921 | save_to_buffer_callback (const gchar *data, | |||
| 2922 | gsize count, | |||
| 2923 | GError **error, | |||
| 2924 | gpointer user_data) | |||
| 2925 | { | |||
| 2926 | struct SaveToBufferData *sdata = user_data; | |||
| 2927 | gchar *new_buffer; | |||
| 2928 | gsize new_max; | |||
| 2929 | ||||
| 2930 | if (sdata->len + count > sdata->max) { | |||
| 2931 | new_max = MAX (sdata->max*2, sdata->len + count)(((sdata->max*2) > (sdata->len + count)) ? (sdata-> max*2) : (sdata->len + count)); | |||
| 2932 | new_buffer = g_try_realloc (sdata->buffer, new_max); | |||
| 2933 | if (!new_buffer) { | |||
| 2934 | g_set_error_literal (error, | |||
| 2935 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 2936 | CDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, | |||
| 2937 | _("Insufficient memory to save image into a buffer")((char *) g_dgettext ("cdk-pixbuf", "Insufficient memory to save image into a buffer" ))); | |||
| 2938 | return FALSE(0); | |||
| 2939 | } | |||
| 2940 | sdata->buffer = new_buffer; | |||
| 2941 | sdata->max = new_max; | |||
| 2942 | } | |||
| 2943 | memcpy (sdata->buffer + sdata->len, data, count); | |||
| 2944 | sdata->len += count; | |||
| 2945 | return TRUE(!(0)); | |||
| 2946 | } | |||
| 2947 | ||||
| 2948 | /** | |||
| 2949 | * cdk_pixbuf_save_to_bufferv: | |||
| 2950 | * @pixbuf: a `CdkPixbuf`. | |||
| 2951 | * @buffer: (array length=buffer_size) (out) (element-type guint8): | |||
| 2952 | * location to receive a pointer to the new buffer. | |||
| 2953 | * @buffer_size: location to receive the size of the new buffer. | |||
| 2954 | * @type: name of file format. | |||
| 2955 | * @option_keys: (array zero-terminated=1) (element-type utf8) (nullable): name of options to set | |||
| 2956 | * @option_values: (array zero-terminated=1) (element-type utf8) (nullable): values for named options | |||
| 2957 | * @error: (allow-none): return location for error, or `NULL` | |||
| 2958 | * | |||
| 2959 | * Vector version of `cdk_pixbuf_save_to_buffer()`. | |||
| 2960 | * | |||
| 2961 | * Saves pixbuf to a new buffer in format @type, which is currently "jpeg", | |||
| 2962 | * "tiff", "png", "ico" or "bmp". | |||
| 2963 | * | |||
| 2964 | * See [method@CdkPixbuf.Pixbuf.save_to_buffer] for more details. | |||
| 2965 | * | |||
| 2966 | * Returns: whether an error was set | |||
| 2967 | * | |||
| 2968 | * Since: 2.4 | |||
| 2969 | **/ | |||
| 2970 | gboolean | |||
| 2971 | cdk_pixbuf_save_to_bufferv (CdkPixbuf *pixbuf, | |||
| 2972 | gchar **buffer, | |||
| 2973 | gsize *buffer_size, | |||
| 2974 | const char *type, | |||
| 2975 | char **option_keys, | |||
| 2976 | char **option_values, | |||
| 2977 | GError **error) | |||
| 2978 | { | |||
| 2979 | static const gint initial_max = 1024; | |||
| 2980 | struct SaveToBufferData sdata; | |||
| 2981 | ||||
| 2982 | *buffer = NULL((void*)0); | |||
| 2983 | *buffer_size = 0; | |||
| 2984 | ||||
| 2985 | sdata.buffer = g_try_malloc (initial_max); | |||
| 2986 | sdata.max = initial_max; | |||
| 2987 | sdata.len = 0; | |||
| 2988 | if (!sdata.buffer) { | |||
| 2989 | g_set_error_literal (error, | |||
| 2990 | CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (), | |||
| 2991 | CDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, | |||
| 2992 | _("Insufficient memory to save image into a buffer")((char *) g_dgettext ("cdk-pixbuf", "Insufficient memory to save image into a buffer" ))); | |||
| 2993 | return FALSE(0); | |||
| 2994 | } | |||
| 2995 | ||||
| 2996 | if (!cdk_pixbuf_save_to_callbackv (pixbuf, | |||
| 2997 | save_to_buffer_callback, &sdata, | |||
| 2998 | type, option_keys, option_values, | |||
| 2999 | error)) { | |||
| 3000 | g_free (sdata.buffer); | |||
| 3001 | return FALSE(0); | |||
| 3002 | } | |||
| 3003 | ||||
| 3004 | *buffer = sdata.buffer; | |||
| 3005 | *buffer_size = sdata.len; | |||
| 3006 | return TRUE(!(0)); | |||
| 3007 | } | |||
| 3008 | ||||
| 3009 | typedef struct { | |||
| 3010 | GOutputStream *stream; | |||
| 3011 | GCancellable *cancellable; | |||
| 3012 | } SaveToStreamData; | |||
| 3013 | ||||
| 3014 | static gboolean | |||
| 3015 | save_to_stream (const gchar *buffer, | |||
| 3016 | gsize count, | |||
| 3017 | GError **error, | |||
| 3018 | gpointer data) | |||
| 3019 | { | |||
| 3020 | SaveToStreamData *sdata = (SaveToStreamData *)data; | |||
| 3021 | gsize remaining; | |||
| 3022 | gssize written; | |||
| 3023 | GError *my_error = NULL((void*)0); | |||
| 3024 | ||||
| 3025 | remaining = count; | |||
| 3026 | written = 0; | |||
| 3027 | while (remaining > 0) { | |||
| 3028 | buffer += written; | |||
| 3029 | remaining -= written; | |||
| 3030 | written = g_output_stream_write (sdata->stream, | |||
| 3031 | buffer, remaining, | |||
| 3032 | sdata->cancellable, | |||
| 3033 | &my_error); | |||
| 3034 | if (written < 0) { | |||
| 3035 | if (!my_error) { | |||
| 3036 | g_set_error_literal (error, | |||
| 3037 | G_IO_ERRORg_io_error_quark(), 0, | |||
| 3038 | _("Error writing to image stream")((char *) g_dgettext ("cdk-pixbuf", "Error writing to image stream" ))); | |||
| 3039 | } | |||
| 3040 | else { | |||
| 3041 | g_propagate_error (error, my_error); | |||
| 3042 | } | |||
| 3043 | return FALSE(0); | |||
| 3044 | } | |||
| 3045 | } | |||
| 3046 | ||||
| 3047 | return TRUE(!(0)); | |||
| 3048 | } | |||
| 3049 | ||||
| 3050 | /** | |||
| 3051 | * cdk_pixbuf_save_to_streamv: | |||
| 3052 | * @pixbuf: a `CdkPixbuf` | |||
| 3053 | * @stream: a `GOutputStream` to save the pixbuf to | |||
| 3054 | * @type: name of file format | |||
| 3055 | * @option_keys: (array zero-terminated=1) (element-type utf8) (nullable): name of options to set | |||
| 3056 | * @option_values: (array zero-terminated=1) (element-type utf8) (nullable): values for named options | |||
| 3057 | * @cancellable: (nullable): optional `GCancellable` object, `NULL` to ignore | |||
| 3058 | * @error: return location for error | |||
| 3059 | * | |||
| 3060 | * Saves `pixbuf` to an output stream. | |||
| 3061 | * | |||
| 3062 | * Supported file formats are currently "jpeg", "tiff", "png", "ico" or | |||
| 3063 | * "bmp". | |||
| 3064 | * | |||
| 3065 | * See [method@CdkPixbuf.Pixbuf.save_to_stream] for more details. | |||
| 3066 | * | |||
| 3067 | * Returns: `TRUE` if the pixbuf was saved successfully, `FALSE` if an | |||
| 3068 | * error was set. | |||
| 3069 | * | |||
| 3070 | * Since: 2.36 | |||
| 3071 | */ | |||
| 3072 | gboolean | |||
| 3073 | cdk_pixbuf_save_to_streamv (CdkPixbuf *pixbuf, | |||
| 3074 | GOutputStream *stream, | |||
| 3075 | const char *type, | |||
| 3076 | char **option_keys, | |||
| 3077 | char **option_values, | |||
| 3078 | GCancellable *cancellable, | |||
| 3079 | GError **error) | |||
| 3080 | { | |||
| 3081 | SaveToStreamData data; | |||
| 3082 | ||||
| 3083 | data.stream = stream; | |||
| 3084 | data.cancellable = cancellable; | |||
| 3085 | ||||
| 3086 | return cdk_pixbuf_save_to_callbackv (pixbuf, save_to_stream, | |||
| 3087 | &data, type, | |||
| 3088 | option_keys, option_values, | |||
| 3089 | error); | |||
| 3090 | } | |||
| 3091 | ||||
| 3092 | /** | |||
| 3093 | * cdk_pixbuf_save_to_stream: | |||
| 3094 | * @pixbuf: a `CdkPixbuf` | |||
| 3095 | * @stream: a `GOutputStream` to save the pixbuf to | |||
| 3096 | * @type: name of file format | |||
| 3097 | * @cancellable: (allow-none): optional `GCancellable` object, `NULL` to ignore | |||
| 3098 | * @error: (allow-none): return location for error, or `NULL` | |||
| 3099 | * @...: list of key-value save options | |||
| 3100 | * | |||
| 3101 | * Saves `pixbuf` to an output stream. | |||
| 3102 | * | |||
| 3103 | * Supported file formats are currently "jpeg", "tiff", "png", "ico" or | |||
| 3104 | * "bmp". See `cdk_pixbuf_save_to_buffer()` for more details. | |||
| 3105 | * | |||
| 3106 | * The `cancellable` can be used to abort the operation from another | |||
| 3107 | * thread. If the operation was cancelled, the error `G_IO_ERROR_CANCELLED` | |||
| 3108 | * will be returned. Other possible errors are in the `CDK_PIXBUF_ERROR` | |||
| 3109 | * and `G_IO_ERROR` domains. | |||
| 3110 | * | |||
| 3111 | * The stream is not closed at the end of this call. | |||
| 3112 | * | |||
| 3113 | * Returns: `TRUE` if the pixbuf was saved successfully, `FALSE` if an | |||
| 3114 | * error was set. | |||
| 3115 | * | |||
| 3116 | * Since: 2.14 | |||
| 3117 | */ | |||
| 3118 | gboolean | |||
| 3119 | cdk_pixbuf_save_to_stream (CdkPixbuf *pixbuf, | |||
| 3120 | GOutputStream *stream, | |||
| 3121 | const char *type, | |||
| 3122 | GCancellable *cancellable, | |||
| 3123 | GError **error, | |||
| 3124 | ...) | |||
| 3125 | { | |||
| 3126 | gboolean res; | |||
| 3127 | gchar **keys = NULL((void*)0); | |||
| 3128 | gchar **values = NULL((void*)0); | |||
| 3129 | va_list args; | |||
| 3130 | ||||
| 3131 | va_start (args, error)__builtin_va_start(args, error); | |||
| 3132 | collect_save_options (args, &keys, &values); | |||
| 3133 | va_end (args)__builtin_va_end(args); | |||
| 3134 | ||||
| 3135 | res = cdk_pixbuf_save_to_streamv (pixbuf, stream, type, | |||
| 3136 | keys, values, | |||
| 3137 | cancellable, error); | |||
| 3138 | ||||
| 3139 | g_strfreev (keys); | |||
| 3140 | g_strfreev (values); | |||
| 3141 | ||||
| 3142 | return res; | |||
| 3143 | } | |||
| 3144 | ||||
| 3145 | typedef struct { | |||
| 3146 | GOutputStream *stream; | |||
| 3147 | gchar *type; | |||
| 3148 | gchar **keys; | |||
| 3149 | gchar **values; | |||
| 3150 | } SaveToStreamAsyncData; | |||
| 3151 | ||||
| 3152 | static void | |||
| 3153 | save_to_stream_async_data_free (SaveToStreamAsyncData *data) | |||
| 3154 | { | |||
| 3155 | if (data->stream) | |||
| 3156 | g_object_unref (data->stream); | |||
| 3157 | g_strfreev (data->keys); | |||
| 3158 | g_strfreev (data->values); | |||
| 3159 | g_free (data->type); | |||
| 3160 | g_slice_free (SaveToStreamAsyncData, data)do { if (1) g_slice_free1 (sizeof (SaveToStreamAsyncData), (data )); else (void) ((SaveToStreamAsyncData*) 0 == (data)); } while (0); | |||
| 3161 | } | |||
| 3162 | ||||
| 3163 | static void | |||
| 3164 | save_to_stream_thread (GTask *task, | |||
| 3165 | CdkPixbuf *pixbuf, | |||
| 3166 | SaveToStreamAsyncData *data, | |||
| 3167 | GCancellable *cancellable) | |||
| 3168 | { | |||
| 3169 | SaveToStreamData sync_data; | |||
| 3170 | gboolean retval; | |||
| 3171 | GError *error = NULL((void*)0); | |||
| 3172 | ||||
| 3173 | sync_data.stream = data->stream; | |||
| 3174 | sync_data.cancellable = cancellable; | |||
| 3175 | ||||
| 3176 | retval = cdk_pixbuf_save_to_callbackv (pixbuf, save_to_stream, | |||
| ||||
| 3177 | &sync_data, data->type, | |||
| 3178 | data->keys, data->values, | |||
| 3179 | &error); | |||
| 3180 | ||||
| 3181 | if (retval == FALSE(0)) { | |||
| 3182 | g_task_return_error (task, error); | |||
| 3183 | } else { | |||
| 3184 | g_task_return_boolean (task, TRUE(!(0))); | |||
| 3185 | } | |||
| 3186 | } | |||
| 3187 | ||||
| 3188 | /** | |||
| 3189 | * cdk_pixbuf_save_to_streamv_async: (finish-func cdk_pixbuf_save_to_stream_finish) | |||
| 3190 | * @pixbuf: a `CdkPixbuf` | |||
| 3191 | * @stream: a `GOutputStream` to which to save the pixbuf | |||
| 3192 | * @type: name of file format | |||
| 3193 | * @option_keys: (array zero-terminated=1) (element-type utf8) (nullable): name of options to set | |||
| 3194 | * @option_values: (array zero-terminated=1) (element-type utf8) (nullable): values for named options | |||
| 3195 | * @cancellable: (allow-none): optional `GCancellable` object, `NULL` to ignore | |||
| 3196 | * @callback: a `GAsyncReadyCallback` to call when the pixbuf is saved | |||
| 3197 | * @user_data: the data to pass to the callback function | |||
| 3198 | * | |||
| 3199 | * Saves `pixbuf` to an output stream asynchronously. | |||
| 3200 | * | |||
| 3201 | * For more details see cdk_pixbuf_save_to_streamv(), which is the synchronous | |||
| 3202 | * version of this function. | |||
| 3203 | * | |||
| 3204 | * When the operation is finished, `callback` will be called in the main thread. | |||
| 3205 | * | |||
| 3206 | * You can then call cdk_pixbuf_save_to_stream_finish() to get the result of | |||
| 3207 | * the operation. | |||
| 3208 | * | |||
| 3209 | * Since: 2.36 | |||
| 3210 | **/ | |||
| 3211 | void | |||
| 3212 | cdk_pixbuf_save_to_streamv_async (CdkPixbuf *pixbuf, | |||
| 3213 | GOutputStream *stream, | |||
| 3214 | const gchar *type, | |||
| 3215 | gchar **option_keys, | |||
| 3216 | gchar **option_values, | |||
| 3217 | GCancellable *cancellable, | |||
| 3218 | GAsyncReadyCallback callback, | |||
| 3219 | gpointer user_data) | |||
| 3220 | { | |||
| 3221 | GTask *task; | |||
| 3222 | SaveToStreamAsyncData *data; | |||
| 3223 | ||||
| 3224 | g_return_if_fail (CDK_IS_PIXBUF (pixbuf))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_133 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((pixbuf)); 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; }))))) _g_boolean_var_133 = 1; _g_boolean_var_133; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "CDK_IS_PIXBUF (pixbuf)" ); return; } } while (0); | |||
| 3225 | g_return_if_fail (cdk_pixbuf_get_width (pixbuf) >= 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_134 = 0; if (cdk_pixbuf_get_width (pixbuf) >= 0) _g_boolean_var_134 = 1; _g_boolean_var_134; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_width (pixbuf) >= 0" ); return; } } while (0); | |||
| 3226 | g_return_if_fail (cdk_pixbuf_get_height (pixbuf) >= 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_135 = 0; if (cdk_pixbuf_get_height (pixbuf) >= 0) _g_boolean_var_135 = 1; _g_boolean_var_135; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_height (pixbuf) >= 0" ); return; } } while (0); | |||
| 3227 | g_return_if_fail (cdk_pixbuf_get_n_channels (pixbuf) >= 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_136 = 0; if (cdk_pixbuf_get_n_channels (pixbuf) >= 0) _g_boolean_var_136 = 1; _g_boolean_var_136; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_n_channels (pixbuf) >= 0" ); return; } } while (0); | |||
| 3228 | g_return_if_fail (G_IS_OUTPUT_STREAM (stream))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_137 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((stream)); GType __t = ((g_output_stream_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; }))))) _g_boolean_var_137 = 1; _g_boolean_var_137; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "G_IS_OUTPUT_STREAM (stream)" ); return; } } while (0); | |||
| 3229 | g_return_if_fail (type != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_138 = 0; if (type != ((void*)0)) _g_boolean_var_138 = 1; _g_boolean_var_138 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "type != NULL"); return; } } while (0); | |||
| 3230 | g_return_if_fail (callback != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_139 = 0; if (callback != ((void*)0)) _g_boolean_var_139 = 1; _g_boolean_var_139 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "callback != NULL"); return; } } while (0); | |||
| 3231 | g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_140 = 0; if (!cancellable || (((__extension__ ({ GTypeInstance * __inst = (GTypeInstance*) ((cancellable)); GType __t = ((g_cancellable_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; }))))) _g_boolean_var_140 = 1; _g_boolean_var_140; }), 1 ))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "!cancellable || G_IS_CANCELLABLE (cancellable)" ); return; } } while (0); | |||
| 3232 | ||||
| 3233 | data = g_slice_new (SaveToStreamAsyncData)((SaveToStreamAsyncData*) g_slice_alloc ((sizeof (SaveToStreamAsyncData ) > 0 ? sizeof (SaveToStreamAsyncData) : 1))); | |||
| 3234 | data->stream = g_object_ref (stream)((__typeof__ (stream)) (g_object_ref) (stream)); | |||
| 3235 | data->type = g_strdup (type)g_strdup_inline (type); | |||
| 3236 | data->keys = g_strdupv (option_keys); | |||
| 3237 | data->values = g_strdupv (option_values); | |||
| 3238 | ||||
| 3239 | task = g_task_new (pixbuf, cancellable, callback, user_data); | |||
| 3240 | g_task_set_source_tag (task, cdk_pixbuf_save_to_streamv_async)do { GTask *_task = (task); (g_task_set_source_tag) (_task, cdk_pixbuf_save_to_streamv_async ); if (g_task_get_name (_task) == ((void*)0)) g_task_set_static_name (_task, "cdk_pixbuf_save_to_streamv_async"); } while (0); | |||
| 3241 | g_task_set_task_data (task, data, (GDestroyNotify) save_to_stream_async_data_free); | |||
| 3242 | g_task_run_in_thread (task, (GTaskThreadFunc) save_to_stream_thread); | |||
| 3243 | g_object_unref (task); | |||
| 3244 | } | |||
| 3245 | ||||
| 3246 | /** | |||
| 3247 | * cdk_pixbuf_save_to_stream_async: (finish-func cdk_pixbuf_save_to_stream_finish) | |||
| 3248 | * @pixbuf: a `CdkPixbuf` | |||
| 3249 | * @stream: a `GOutputStream` to which to save the pixbuf | |||
| 3250 | * @type: name of file format | |||
| 3251 | * @cancellable: (allow-none): optional `GCancellable` object, `NULL` to ignore | |||
| 3252 | * @callback: a `GAsyncReadyCallback` to call when the pixbuf is saved | |||
| 3253 | * @user_data: the data to pass to the callback function | |||
| 3254 | * @...: list of key-value save options | |||
| 3255 | * | |||
| 3256 | * Saves `pixbuf` to an output stream asynchronously. | |||
| 3257 | * | |||
| 3258 | * For more details see cdk_pixbuf_save_to_stream(), which is the synchronous | |||
| 3259 | * version of this function. | |||
| 3260 | * | |||
| 3261 | * When the operation is finished, `callback` will be called in the main thread. | |||
| 3262 | * | |||
| 3263 | * You can then call cdk_pixbuf_save_to_stream_finish() to get the result of | |||
| 3264 | * the operation. | |||
| 3265 | * | |||
| 3266 | * Since: 2.24 | |||
| 3267 | **/ | |||
| 3268 | void | |||
| 3269 | cdk_pixbuf_save_to_stream_async (CdkPixbuf *pixbuf, | |||
| 3270 | GOutputStream *stream, | |||
| 3271 | const gchar *type, | |||
| 3272 | GCancellable *cancellable, | |||
| 3273 | GAsyncReadyCallback callback, | |||
| 3274 | gpointer user_data, | |||
| 3275 | ...) | |||
| 3276 | { | |||
| 3277 | gchar **keys = NULL((void*)0); | |||
| 3278 | gchar **values = NULL((void*)0); | |||
| 3279 | va_list args; | |||
| 3280 | ||||
| 3281 | g_return_if_fail (CDK_IS_PIXBUF (pixbuf))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_141 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((pixbuf)); 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; }))))) _g_boolean_var_141 = 1; _g_boolean_var_141; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "CDK_IS_PIXBUF (pixbuf)" ); return; } } while (0); | |||
| 3282 | g_return_if_fail (cdk_pixbuf_get_width (pixbuf) >= 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_142 = 0; if (cdk_pixbuf_get_width (pixbuf) >= 0) _g_boolean_var_142 = 1; _g_boolean_var_142; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_width (pixbuf) >= 0" ); return; } } while (0); | |||
| 3283 | g_return_if_fail (cdk_pixbuf_get_height (pixbuf) >= 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_143 = 0; if (cdk_pixbuf_get_height (pixbuf) >= 0) _g_boolean_var_143 = 1; _g_boolean_var_143; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_height (pixbuf) >= 0" ); return; } } while (0); | |||
| 3284 | g_return_if_fail (cdk_pixbuf_get_n_channels (pixbuf) >= 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_144 = 0; if (cdk_pixbuf_get_n_channels (pixbuf) >= 0) _g_boolean_var_144 = 1; _g_boolean_var_144; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "cdk_pixbuf_get_n_channels (pixbuf) >= 0" ); return; } } while (0); | |||
| 3285 | g_return_if_fail (G_IS_OUTPUT_STREAM (stream))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_145 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((stream)); GType __t = ((g_output_stream_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; }))))) _g_boolean_var_145 = 1; _g_boolean_var_145; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "G_IS_OUTPUT_STREAM (stream)" ); return; } } while (0); | |||
| 3286 | g_return_if_fail (type != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_146 = 0; if (type != ((void*)0)) _g_boolean_var_146 = 1; _g_boolean_var_146 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "type != NULL"); return; } } while (0); | |||
| 3287 | g_return_if_fail (callback != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_147 = 0; if (callback != ((void*)0)) _g_boolean_var_147 = 1; _g_boolean_var_147 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "callback != NULL"); return; } } while (0); | |||
| 3288 | g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_148 = 0; if (!cancellable || (((__extension__ ({ GTypeInstance * __inst = (GTypeInstance*) ((cancellable)); GType __t = ((g_cancellable_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; }))))) _g_boolean_var_148 = 1; _g_boolean_var_148; }), 1 ))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "!cancellable || G_IS_CANCELLABLE (cancellable)" ); return; } } while (0); | |||
| 3289 | ||||
| 3290 | va_start (args, user_data)__builtin_va_start(args, user_data); | |||
| 3291 | collect_save_options (args, &keys, &values); | |||
| 3292 | va_end (args)__builtin_va_end(args); | |||
| 3293 | ||||
| 3294 | cdk_pixbuf_save_to_streamv_async (pixbuf, stream, type, | |||
| 3295 | keys, values, | |||
| 3296 | cancellable, callback, user_data); | |||
| 3297 | g_strfreev (keys); | |||
| 3298 | g_strfreev (values); | |||
| 3299 | } | |||
| 3300 | ||||
| 3301 | /** | |||
| 3302 | * cdk_pixbuf_save_to_stream_finish: | |||
| 3303 | * @async_result: a `GAsyncResult` | |||
| 3304 | * @error: a `GError`, or `NULL` | |||
| 3305 | * | |||
| 3306 | * Finishes an asynchronous pixbuf save operation started with | |||
| 3307 | * cdk_pixbuf_save_to_stream_async(). | |||
| 3308 | * | |||
| 3309 | * Returns: `TRUE` if the pixbuf was saved successfully, `FALSE` if an error was set. | |||
| 3310 | * | |||
| 3311 | * Since: 2.24 | |||
| 3312 | **/ | |||
| 3313 | gboolean | |||
| 3314 | cdk_pixbuf_save_to_stream_finish (GAsyncResult *async_result, | |||
| 3315 | GError **error) | |||
| 3316 | { | |||
| 3317 | GTask *task; | |||
| 3318 | ||||
| 3319 | /* Can not use g_task_is_valid because our GTask has a | |||
| 3320 | * source_object which is not available to us anymore. | |||
| 3321 | */ | |||
| 3322 | g_return_val_if_fail (G_IS_TASK (async_result), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_149 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((async_result)); GType __t = ((g_task_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; }))))) _g_boolean_var_149 = 1; _g_boolean_var_149; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "G_IS_TASK (async_result)" ); return ((0)); } } while (0); | |||
| 3323 | ||||
| 3324 | task = G_TASK (async_result)((((GTask*) (void *) ((async_result))))); | |||
| 3325 | ||||
| 3326 | g_return_val_if_fail (!error || (error && !*error), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_150 = 0; if (!error || (error && !*error)) _g_boolean_var_150 = 1; _g_boolean_var_150; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ((const char*) (__func__)), "!error || (error && !*error)" ); return ((0)); } } while (0); | |||
| 3327 | g_warn_if_fail (g_task_get_source_tag (task) == cdk_pixbuf_save_to_stream_async ||do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_151 = 0; if (g_task_get_source_tag (task) == cdk_pixbuf_save_to_stream_async || g_task_get_source_tag (task) == cdk_pixbuf_save_to_streamv_async ) _g_boolean_var_151 = 1; _g_boolean_var_151; }), 1)) ; else g_warn_message ("CdkPixbuf", "../cdk-pixbuf/cdk-pixbuf-io.c", 3328, ((const char*) (__func__)), "g_task_get_source_tag (task) == cdk_pixbuf_save_to_stream_async || g_task_get_source_tag (task) == cdk_pixbuf_save_to_streamv_async" ); } while (0) | |||
| 3328 | g_task_get_source_tag (task) == cdk_pixbuf_save_to_streamv_async)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_151 = 0; if (g_task_get_source_tag (task) == cdk_pixbuf_save_to_stream_async || g_task_get_source_tag (task) == cdk_pixbuf_save_to_streamv_async ) _g_boolean_var_151 = 1; _g_boolean_var_151; }), 1)) ; else g_warn_message ("CdkPixbuf", "../cdk-pixbuf/cdk-pixbuf-io.c", 3328, ((const char*) (__func__)), "g_task_get_source_tag (task) == cdk_pixbuf_save_to_stream_async || g_task_get_source_tag (task) == cdk_pixbuf_save_to_streamv_async" ); } while (0); | |||
| 3329 | ||||
| 3330 | return g_task_propagate_boolean (task, error); | |||
| 3331 | } | |||
| 3332 | ||||
| 3333 | /** | |||
| 3334 | * cdk_pixbuf_format_get_name: | |||
| 3335 | * @format: a `CdkPixbufFormat` | |||
| 3336 | * | |||
| 3337 | * Returns the name of the format. | |||
| 3338 | * | |||
| 3339 | * Returns: (transfer full) (nullable): the name of the format. | |||
| 3340 | * | |||
| 3341 | * Since: 2.2 | |||
| 3342 | */ | |||
| 3343 | gchar * | |||
| 3344 | cdk_pixbuf_format_get_name (CdkPixbufFormat *format) | |||
| 3345 | { | |||
| 3346 | g_return_val_if_fail (format != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_152 = 0; if (format != ((void*)0)) _g_boolean_var_152 = 1; _g_boolean_var_152 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return (((void* )0)); } } while (0); | |||
| 3347 | ||||
| 3348 | return g_strdup (format->name)g_strdup_inline (format->name); | |||
| 3349 | } | |||
| 3350 | ||||
| 3351 | /** | |||
| 3352 | * cdk_pixbuf_format_get_description: | |||
| 3353 | * @format: a `CdkPixbufFormat` | |||
| 3354 | * | |||
| 3355 | * Returns a description of the format. | |||
| 3356 | * | |||
| 3357 | * Returns: (transfer full) (nullable): a description of the format. | |||
| 3358 | * | |||
| 3359 | * Since: 2.2 | |||
| 3360 | */ | |||
| 3361 | gchar * | |||
| 3362 | cdk_pixbuf_format_get_description (CdkPixbufFormat *format) | |||
| 3363 | { | |||
| 3364 | gchar *domain; | |||
| 3365 | const gchar *description; | |||
| 3366 | g_return_val_if_fail (format != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_153 = 0; if (format != ((void*)0)) _g_boolean_var_153 = 1; _g_boolean_var_153 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return (((void* )0)); } } while (0); | |||
| 3367 | ||||
| 3368 | if (format->domain != NULL((void*)0)) | |||
| 3369 | domain = format->domain; | |||
| 3370 | else | |||
| 3371 | domain = GETTEXT_PACKAGE"cdk-pixbuf"; | |||
| 3372 | description = g_dgettext (domain, format->description); | |||
| 3373 | ||||
| 3374 | return g_strdup (description)g_strdup_inline (description); | |||
| 3375 | } | |||
| 3376 | ||||
| 3377 | /** | |||
| 3378 | * cdk_pixbuf_format_get_mime_types: | |||
| 3379 | * @format: a `CdkPixbufFormat` | |||
| 3380 | * | |||
| 3381 | * Returns the mime types supported by the format. | |||
| 3382 | * | |||
| 3383 | * Returns: (transfer full) (array zero-terminated=1) (nullable): an array of mime types | |||
| 3384 | * | |||
| 3385 | * Since: 2.2 | |||
| 3386 | */ | |||
| 3387 | gchar ** | |||
| 3388 | cdk_pixbuf_format_get_mime_types (CdkPixbufFormat *format) | |||
| 3389 | { | |||
| 3390 | g_return_val_if_fail (format != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_154 = 0; if (format != ((void*)0)) _g_boolean_var_154 = 1; _g_boolean_var_154 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return (((void* )0)); } } while (0); | |||
| 3391 | ||||
| 3392 | return g_strdupv (format->mime_types); | |||
| 3393 | } | |||
| 3394 | ||||
| 3395 | /** | |||
| 3396 | * cdk_pixbuf_format_get_extensions: | |||
| 3397 | * @format: a `CdkPixbufFormat` | |||
| 3398 | * | |||
| 3399 | * Returns the filename extensions typically used for files in the | |||
| 3400 | * given format. | |||
| 3401 | * | |||
| 3402 | * Returns: (transfer full) (array zero-terminated=1) (nullable): an array of | |||
| 3403 | * filename extensions | |||
| 3404 | * | |||
| 3405 | * Since: 2.2 | |||
| 3406 | */ | |||
| 3407 | gchar ** | |||
| 3408 | cdk_pixbuf_format_get_extensions (CdkPixbufFormat *format) | |||
| 3409 | { | |||
| 3410 | g_return_val_if_fail (format != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_155 = 0; if (format != ((void*)0)) _g_boolean_var_155 = 1; _g_boolean_var_155 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return (((void* )0)); } } while (0); | |||
| 3411 | ||||
| 3412 | return g_strdupv (format->extensions); | |||
| 3413 | } | |||
| 3414 | ||||
| 3415 | /** | |||
| 3416 | * cdk_pixbuf_format_is_writable: | |||
| 3417 | * @format: a `CdkPixbufFormat` | |||
| 3418 | * | |||
| 3419 | * Returns whether pixbufs can be saved in the given format. | |||
| 3420 | * | |||
| 3421 | * Returns: whether pixbufs can be saved in the given format. | |||
| 3422 | * | |||
| 3423 | * Since: 2.2 | |||
| 3424 | */ | |||
| 3425 | gboolean | |||
| 3426 | cdk_pixbuf_format_is_writable (CdkPixbufFormat *format) | |||
| 3427 | { | |||
| 3428 | g_return_val_if_fail (format != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_156 = 0; if (format != ((void*)0)) _g_boolean_var_156 = 1; _g_boolean_var_156 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return ((0)); } } while (0); | |||
| 3429 | ||||
| 3430 | return (format->flags & CDK_PIXBUF_FORMAT_WRITABLE) != 0; | |||
| 3431 | } | |||
| 3432 | ||||
| 3433 | /** | |||
| 3434 | * cdk_pixbuf_format_is_scalable: | |||
| 3435 | * @format: a `CdkPixbufFormat` | |||
| 3436 | * | |||
| 3437 | * Returns whether this image format is scalable. | |||
| 3438 | * | |||
| 3439 | * If a file is in a scalable format, it is preferable to load it at | |||
| 3440 | * the desired size, rather than loading it at the default size and | |||
| 3441 | * scaling the resulting pixbuf to the desired size. | |||
| 3442 | * | |||
| 3443 | * Returns: whether this image format is scalable. | |||
| 3444 | * | |||
| 3445 | * Since: 2.6 | |||
| 3446 | */ | |||
| 3447 | gboolean | |||
| 3448 | cdk_pixbuf_format_is_scalable (CdkPixbufFormat *format) | |||
| 3449 | { | |||
| 3450 | g_return_val_if_fail (format != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_157 = 0; if (format != ((void*)0)) _g_boolean_var_157 = 1; _g_boolean_var_157 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return ((0)); } } while (0); | |||
| 3451 | ||||
| 3452 | return (format->flags & CDK_PIXBUF_FORMAT_SCALABLE) != 0; | |||
| 3453 | } | |||
| 3454 | ||||
| 3455 | /** | |||
| 3456 | * cdk_pixbuf_format_is_disabled: | |||
| 3457 | * @format: a `CdkPixbufFormat` | |||
| 3458 | * | |||
| 3459 | * Returns whether this image format is disabled. | |||
| 3460 | * | |||
| 3461 | * See cdk_pixbuf_format_set_disabled(). | |||
| 3462 | * | |||
| 3463 | * Returns: whether this image format is disabled. | |||
| 3464 | * | |||
| 3465 | * Since: 2.6 | |||
| 3466 | */ | |||
| 3467 | gboolean | |||
| 3468 | cdk_pixbuf_format_is_disabled (CdkPixbufFormat *format) | |||
| 3469 | { | |||
| 3470 | g_return_val_if_fail (format != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_158 = 0; if (format != ((void*)0)) _g_boolean_var_158 = 1; _g_boolean_var_158 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return ((0)); } } while (0); | |||
| 3471 | ||||
| 3472 | return format->disabled; | |||
| 3473 | } | |||
| 3474 | ||||
| 3475 | /** | |||
| 3476 | * cdk_pixbuf_format_set_disabled: | |||
| 3477 | * @format: a `CdkPixbufFormat` | |||
| 3478 | * @disabled: `TRUE` to disable the format @format | |||
| 3479 | * | |||
| 3480 | * Disables or enables an image format. | |||
| 3481 | * | |||
| 3482 | * If a format is disabled, CdkPixbuf won't use the image loader for | |||
| 3483 | * this format to load images. | |||
| 3484 | * | |||
| 3485 | * Applications can use this to avoid using image loaders with an | |||
| 3486 | * inappropriate license, see cdk_pixbuf_format_get_license(). | |||
| 3487 | * | |||
| 3488 | * Since: 2.6 | |||
| 3489 | */ | |||
| 3490 | void | |||
| 3491 | cdk_pixbuf_format_set_disabled (CdkPixbufFormat *format, | |||
| 3492 | gboolean disabled) | |||
| 3493 | { | |||
| 3494 | g_return_if_fail (format != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_159 = 0; if (format != ((void*)0)) _g_boolean_var_159 = 1; _g_boolean_var_159 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return; } } while (0); | |||
| 3495 | ||||
| 3496 | format->disabled = disabled != FALSE(0); | |||
| 3497 | } | |||
| 3498 | ||||
| 3499 | /** | |||
| 3500 | * cdk_pixbuf_format_get_license: | |||
| 3501 | * @format: a pixbuf format | |||
| 3502 | * | |||
| 3503 | * Returns information about the license of the image loader for the format. | |||
| 3504 | * | |||
| 3505 | * The returned string should be a shorthand for a well known license, e.g. | |||
| 3506 | * "LGPL", "GPL", "QPL", "GPL/QPL", or "other" to indicate some other license. | |||
| 3507 | * | |||
| 3508 | * Returns: (transfer full) (nullable): a string describing the license of the pixbuf format | |||
| 3509 | * | |||
| 3510 | * Since: 2.6 | |||
| 3511 | */ | |||
| 3512 | gchar* | |||
| 3513 | cdk_pixbuf_format_get_license (CdkPixbufFormat *format) | |||
| 3514 | { | |||
| 3515 | g_return_val_if_fail (format != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_160 = 0; if (format != ((void*)0)) _g_boolean_var_160 = 1; _g_boolean_var_160 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return (((void* )0)); } } while (0); | |||
| 3516 | ||||
| 3517 | return g_strdup (format->license)g_strdup_inline (format->license); | |||
| 3518 | } | |||
| 3519 | ||||
| 3520 | CdkPixbufFormat * | |||
| 3521 | _cdk_pixbuf_get_format (CdkPixbufModule *module) | |||
| 3522 | { | |||
| 3523 | g_return_val_if_fail (module != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_161 = 0; if (module != ((void*)0)) _g_boolean_var_161 = 1; _g_boolean_var_161 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "module != NULL"); return (((void* )0)); } } while (0); | |||
| 3524 | ||||
| 3525 | return module->info; | |||
| 3526 | } | |||
| 3527 | ||||
| 3528 | /** | |||
| 3529 | * cdk_pixbuf_get_formats: | |||
| 3530 | * | |||
| 3531 | * Obtains the available information about the image formats supported | |||
| 3532 | * by CdkPixbuf. | |||
| 3533 | * | |||
| 3534 | * Returns: (transfer container) (element-type CdkPixbufFormat): A list of | |||
| 3535 | * support image formats. | |||
| 3536 | * | |||
| 3537 | * Since: 2.2 | |||
| 3538 | */ | |||
| 3539 | GSList * | |||
| 3540 | cdk_pixbuf_get_formats (void) | |||
| 3541 | { | |||
| 3542 | GSList *result = NULL((void*)0); | |||
| 3543 | GSList *modules; | |||
| 3544 | ||||
| 3545 | for (modules = get_file_formats (); modules; modules = g_slist_next (modules)((modules) ? (((GSList *)(modules))->next) : ((void*)0))) { | |||
| 3546 | CdkPixbufModule *module = (CdkPixbufModule *)modules->data; | |||
| 3547 | CdkPixbufFormat *info = _cdk_pixbuf_get_format (module); | |||
| 3548 | result = g_slist_prepend (result, info); | |||
| 3549 | } | |||
| 3550 | ||||
| 3551 | return result; | |||
| 3552 | } | |||
| 3553 | ||||
| 3554 | /** | |||
| 3555 | * cdk_pixbuf_format_copy: | |||
| 3556 | * @format: a pixbuf format | |||
| 3557 | * | |||
| 3558 | * Creates a copy of `format`. | |||
| 3559 | * | |||
| 3560 | * Returns: (transfer full) (nullable): the newly allocated copy of a `CdkPixbufFormat`. Use | |||
| 3561 | * cdk_pixbuf_format_free() to free the resources when done | |||
| 3562 | * | |||
| 3563 | * Since: 2.22 | |||
| 3564 | */ | |||
| 3565 | CdkPixbufFormat * | |||
| 3566 | cdk_pixbuf_format_copy (const CdkPixbufFormat *format) | |||
| 3567 | { | |||
| 3568 | if (G_LIKELY (format != NULL)(__builtin_expect (__extension__ ({ int _g_boolean_var_162 = 0 ; if (format != ((void*)0)) _g_boolean_var_162 = 1; _g_boolean_var_162 ; }), 1))) | |||
| 3569 | return g_slice_dup (CdkPixbufFormat, format)(1 ? (CdkPixbufFormat*) g_slice_copy ((sizeof (CdkPixbufFormat ) > 0 ? sizeof (CdkPixbufFormat) : 1), (format)) : ((void) ((CdkPixbufFormat*) 0 == (format)), (CdkPixbufFormat*) 0)); | |||
| 3570 | ||||
| 3571 | return NULL((void*)0); | |||
| 3572 | } | |||
| 3573 | ||||
| 3574 | /** | |||
| 3575 | * cdk_pixbuf_format_free: | |||
| 3576 | * @format: a pixbuf format | |||
| 3577 | * | |||
| 3578 | * Frees the resources allocated when copying a `CdkPixbufFormat` | |||
| 3579 | * using cdk_pixbuf_format_copy() | |||
| 3580 | * | |||
| 3581 | * Since: 2.22 | |||
| 3582 | */ | |||
| 3583 | void | |||
| 3584 | cdk_pixbuf_format_free (CdkPixbufFormat *format) | |||
| 3585 | { | |||
| 3586 | if (G_LIKELY (format != NULL)(__builtin_expect (__extension__ ({ int _g_boolean_var_163 = 0 ; if (format != ((void*)0)) _g_boolean_var_163 = 1; _g_boolean_var_163 ; }), 1))) | |||
| 3587 | g_slice_free (CdkPixbufFormat, format)do { if (1) g_slice_free1 (sizeof (CdkPixbufFormat), (format) ); else (void) ((CdkPixbufFormat*) 0 == (format)); } while (0 ); | |||
| 3588 | } | |||
| 3589 | ||||
| 3590 | /** | |||
| 3591 | * cdk_pixbuf_format_is_save_option_supported: | |||
| 3592 | * @format: a pixbuf format | |||
| 3593 | * @option_key: the name of an option | |||
| 3594 | * | |||
| 3595 | * Returns `TRUE` if the save option specified by @option_key is supported when | |||
| 3596 | * saving a pixbuf using the module implementing @format. | |||
| 3597 | * | |||
| 3598 | * See cdk_pixbuf_save() for more information about option keys. | |||
| 3599 | * | |||
| 3600 | * Returns: `TRUE` if the specified option is supported | |||
| 3601 | * | |||
| 3602 | * Since: 2.36 | |||
| 3603 | */ | |||
| 3604 | gboolean | |||
| 3605 | cdk_pixbuf_format_is_save_option_supported (CdkPixbufFormat *format, | |||
| 3606 | const gchar *option_key) | |||
| 3607 | { | |||
| 3608 | CdkPixbufModule *module; | |||
| 3609 | ||||
| 3610 | g_return_val_if_fail (format != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_164 = 0; if (format != ((void*)0)) _g_boolean_var_164 = 1; _g_boolean_var_164 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "format != NULL"); return ((0)); } } while (0); | |||
| 3611 | g_return_val_if_fail (option_key != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_165 = 0; if (option_key != ((void*)0)) _g_boolean_var_165 = 1; _g_boolean_var_165 ; }), 1))) { } else { g_return_if_fail_warning ("CdkPixbuf", ( (const char*) (__func__)), "option_key != NULL"); return ((0) ); } } while (0); | |||
| 3612 | ||||
| 3613 | module = _cdk_pixbuf_get_named_module (format->name, NULL((void*)0)); | |||
| 3614 | if (!module) | |||
| 3615 | return FALSE(0); | |||
| 3616 | ||||
| 3617 | if (!_cdk_pixbuf_load_module (module, NULL((void*)0))) | |||
| 3618 | return FALSE(0); | |||
| 3619 | ||||
| 3620 | if (!module->is_save_option_supported) | |||
| 3621 | return FALSE(0); | |||
| 3622 | ||||
| 3623 | return (* module->is_save_option_supported) (option_key); | |||
| 3624 | } | |||
| 3625 | ||||
| 3626 | G_DEFINE_BOXED_TYPE (CdkPixbufFormat, cdk_pixbuf_format,static GType cdk_pixbuf_format_get_type_once (void); GType cdk_pixbuf_format_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 = cdk_pixbuf_format_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 cdk_pixbuf_format_get_type_once ( void) { GType (* _g_register_boxed) (const gchar *, union { CdkPixbufFormat * (*do_copy_type) (CdkPixbufFormat *); CdkPixbufFormat * (*do_const_copy_type ) (const CdkPixbufFormat *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CdkPixbufFormat *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CdkPixbufFormat" ), cdk_pixbuf_format_copy, cdk_pixbuf_format_free); { {{};} } return g_define_type_id; } | |||
| 3627 | cdk_pixbuf_format_copy,static GType cdk_pixbuf_format_get_type_once (void); GType cdk_pixbuf_format_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 = cdk_pixbuf_format_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 cdk_pixbuf_format_get_type_once ( void) { GType (* _g_register_boxed) (const gchar *, union { CdkPixbufFormat * (*do_copy_type) (CdkPixbufFormat *); CdkPixbufFormat * (*do_const_copy_type ) (const CdkPixbufFormat *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CdkPixbufFormat *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CdkPixbufFormat" ), cdk_pixbuf_format_copy, cdk_pixbuf_format_free); { {{};} } return g_define_type_id; } | |||
| 3628 | cdk_pixbuf_format_free)static GType cdk_pixbuf_format_get_type_once (void); GType cdk_pixbuf_format_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 = cdk_pixbuf_format_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 cdk_pixbuf_format_get_type_once ( void) { GType (* _g_register_boxed) (const gchar *, union { CdkPixbufFormat * (*do_copy_type) (CdkPixbufFormat *); CdkPixbufFormat * (*do_const_copy_type ) (const CdkPixbufFormat *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CdkPixbufFormat *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CdkPixbufFormat" ), cdk_pixbuf_format_copy, cdk_pixbuf_format_free); { {{};} } return g_define_type_id; } |