1
/* GdkPixbuf library - Main loading interface.
3
* Copyright (C) 1999 The Free Software Foundation
5
* Authors: Miguel de Icaza <miguel@gnu.org>
6
* Federico Mena-Quintero <federico@gimp.org>
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Library 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.
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
* Library General Public License for more details.
18
* You should have received a copy of the GNU Library General Public
19
* License along with this library; if not, write to the
20
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21
* Boston, MA 02111-1307, USA.
27
#include "gdk-pixbuf-private.h"
28
#include "gdk-pixbuf-io.h"
33
pixbuf_check_png (guchar *buffer, int size)
38
if (buffer [0] != 0x89 ||
52
pixbuf_check_jpeg (guchar *buffer, int size)
57
if (buffer [0] != 0xff || buffer [1] != 0xd8)
64
pixbuf_check_tiff (guchar *buffer, int size)
69
if (buffer [0] == 'M' &&
75
if (buffer [0] == 'I' &&
85
pixbuf_check_gif (guchar *buffer, int size)
90
if (strncmp (buffer, "GIF8", 4) == 0)
97
pixbuf_check_xpm (guchar *buffer, int size)
102
if (strncmp (buffer, "/* XPM */", 9) == 0)
109
pixbuf_check_pnm (guchar *buffer, int size)
114
if (buffer [0] == 'P') {
115
if (buffer [1] == '1' ||
126
pixbuf_check_sunras (guchar *buffer, int size)
131
if (buffer [0] != 0x59 ||
132
buffer [1] != 0xA6 ||
133
buffer [2] != 0x6A ||
141
pixbuf_check_ico (guchar *buffer, int size)
143
/* Note that this may cause false positives, but .ico's don't
144
have a magic number.*/
147
if (buffer [0] != 0x0 ||
149
((buffer [2] != 0x1)&&(buffer[2]!=0x2)) ||
159
pixbuf_check_bmp (guchar *buffer, int size)
164
if (buffer [0] != 'B' || buffer [1] != 'M')
172
pixbuf_check_xbm (guchar *buffer, int size)
177
if (buffer [0] == '#'
184
&& buffer [7] == ' ')
187
/* Note that this requires xpm to be checked before xbm. */
188
if (buffer [0] == '/'
189
&& buffer [1] != '*')
195
static GdkPixbufModule file_formats [] = {
196
{ "png", pixbuf_check_png, NULL, NULL, NULL, NULL, NULL, NULL },
197
{ "jpeg", pixbuf_check_jpeg, NULL, NULL, NULL, NULL, NULL, NULL },
198
{ "tiff", pixbuf_check_tiff, NULL, NULL, NULL, NULL, NULL, NULL },
199
{ "gif", pixbuf_check_gif, NULL, NULL, NULL, NULL, NULL, NULL },
200
#define XPM_FILE_FORMAT_INDEX 4
201
{ "xpm", pixbuf_check_xpm, NULL, NULL, NULL, NULL, NULL, NULL },
202
{ "pnm", pixbuf_check_pnm, NULL, NULL, NULL, NULL, NULL, NULL },
203
{ "ras", pixbuf_check_sunras, NULL, NULL, NULL, NULL, NULL, NULL },
204
{ "bmp", pixbuf_check_bmp, NULL, NULL, NULL, NULL, NULL, NULL },
205
{ "xbm", pixbuf_check_xbm, NULL, NULL, NULL, NULL, NULL, NULL },
206
{ "ico", pixbuf_check_ico, NULL, NULL, NULL, NULL, NULL, NULL },
207
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
212
pixbuf_module_symbol (GModule *module, const char *module_name, const char *symbol_name, gpointer *symbol)
214
char *full_symbol_name = g_strconcat ("gdk_pixbuf__", module_name, "_", symbol_name, NULL);
215
gboolean return_value;
217
return_value = g_module_symbol (module, full_symbol_name, symbol);
218
g_free (full_symbol_name);
223
/* actually load the image handler - gdk_pixbuf_get_module only get a */
224
/* reference to the module to load, it doesn't actually load it */
225
/* perhaps these actions should be combined in one function */
227
gdk_pixbuf_load_module (GdkPixbufModule *image_module)
235
g_return_if_fail (image_module->module == NULL);
237
name = image_module->module_name;
239
module_name = g_strconcat ("pixbufloader-", name, NULL);
240
path = g_module_build_path (PIXBUF_LIBDIR, module_name);
242
module = g_module_open (path, G_MODULE_BIND_LAZY);
244
/* Debug feature, check in present working directory */
246
path = g_module_build_path ("", module_name);
247
module = g_module_open (path, G_MODULE_BIND_LAZY);
250
g_warning ("Unable to load module: %s: %s", path, g_module_error ());
251
g_free (module_name);
260
g_free (module_name);
262
image_module->module = module;
264
if (pixbuf_module_symbol (module, name, "image_load", &load_sym))
265
image_module->load = load_sym;
267
if (pixbuf_module_symbol (module, name, "image_load_xpm_data", &load_sym))
268
image_module->load_xpm_data = load_sym;
270
if (pixbuf_module_symbol (module, name, "image_begin_load", &load_sym))
271
image_module->begin_load = load_sym;
273
if (pixbuf_module_symbol (module, name, "image_stop_load", &load_sym))
274
image_module->stop_load = load_sym;
276
if (pixbuf_module_symbol (module, name, "image_load_increment", &load_sym))
277
image_module->load_increment = load_sym;
279
if (pixbuf_module_symbol (module, name, "image_load_animation", &load_sym))
280
image_module->load_animation = load_sym;
284
#define mname(type,fn) gdk_pixbuf__ ## type ## _image_ ##fn
285
#define m_load(type) extern GdkPixbuf * mname(type,load) (FILE *f);
286
#define m_load_xpm_data(type) extern GdkPixbuf * mname(type,load_xpm_data) (const char **data);
287
#define m_begin_load(type) \
288
extern gpointer mname(type,begin_load) (ModulePreparedNotifyFunc prepare_func, \
289
ModuleUpdatedNotifyFunc update_func, \
290
ModuleFrameDoneNotifyFunc frame_done_func,\
291
ModuleAnimationDoneNotifyFunc anim_done_func,\
293
#define m_stop_load(type) extern void mname(type,stop_load) (gpointer context);
294
#define m_load_increment(type) extern gboolean mname(type,load_increment) (gpointer context, const guchar *buf, guint size);
295
#define m_load_animation(type) extern GdkPixbufAnimation * mname(type,load_animation) (FILE *f);
299
m_load_increment (png);
303
m_load_increment (bmp);
307
m_load_increment (gif);
309
m_load_animation (gif);
312
m_load_increment (ico);
316
m_load_increment (jpeg);
320
m_load_increment (pnm);
324
m_load_increment (ras);
328
m_load_increment (tiff);
331
m_load_xpm_data (xpm);
334
m_load_increment (xbm);
338
gdk_pixbuf_load_module (GdkPixbufModule *image_module)
340
image_module->module = (void *) 1;
342
if (strcmp (image_module->module_name, "png") == 0){
343
image_module->load = mname (png,load);
344
image_module->begin_load = mname (png,begin_load);
345
image_module->load_increment = mname (png,load_increment);
346
image_module->stop_load = mname (png,stop_load);
350
if (strcmp (image_module->module_name, "bmp") == 0){
351
image_module->load = mname (bmp,load);
352
image_module->begin_load = mname (bmp,begin_load);
353
image_module->load_increment = mname (bmp,load_increment);
354
image_module->stop_load = mname (bmp,stop_load);
358
if (strcmp (image_module->module_name, "gif") == 0){
359
image_module->load = mname (gif,load);
360
image_module->begin_load = mname (gif,begin_load);
361
image_module->load_increment = mname (gif,load_increment);
362
image_module->stop_load = mname (gif,stop_load);
363
image_module->load_animation = mname (gif,load_animation);
367
if (strcmp (image_module->module_name, "ico") == 0){
368
image_module->load = mname (ico,load);
369
image_module->begin_load = mname (ico,begin_load);
370
image_module->load_increment = mname (ico,load_increment);
371
image_module->stop_load = mname (ico,stop_load);
375
if (strcmp (image_module->module_name, "jpeg") == 0){
376
image_module->load = mname (jpeg,load);
377
image_module->begin_load = mname (jpeg,begin_load);
378
image_module->load_increment = mname (jpeg,load_increment);
379
image_module->stop_load = mname (jpeg,stop_load);
382
if (strcmp (image_module->module_name, "pnm") == 0){
383
image_module->load = mname (pnm,load);
384
image_module->begin_load = mname (pnm,begin_load);
385
image_module->load_increment = mname (pnm,load_increment);
386
image_module->stop_load = mname (pnm,stop_load);
389
if (strcmp (image_module->module_name, "ras") == 0){
390
image_module->load = mname (ras,load);
391
image_module->begin_load = mname (ras,begin_load);
392
image_module->load_increment = mname (ras,load_increment);
393
image_module->stop_load = mname (ras,stop_load);
396
if (strcmp (image_module->module_name, "tiff") == 0){
397
image_module->load = mname (tiff,load);
398
image_module->begin_load = mname (tiff,begin_load);
399
image_module->load_increment = mname (tiff,load_increment);
400
image_module->stop_load = mname (tiff,stop_load);
403
if (strcmp (image_module->module_name, "xpm") == 0){
404
image_module->load = mname (xpm,load);
405
image_module->load_xpm_data = mname (xpm,load_xpm_data);
408
if (strcmp (image_module->module_name, "xbm") == 0){
409
image_module->load = mname (xbm,load);
410
image_module->begin_load = mname (xbm,begin_load);
411
image_module->load_increment = mname (xbm,load_increment);
412
image_module->stop_load = mname (xbm,stop_load);
423
gdk_pixbuf_get_module (guchar *buffer, guint size)
427
for (i = 0; file_formats [i].module_name; i++) {
428
if ((* file_formats [i].format_check) (buffer, size))
429
return &(file_formats[i]);
436
* gdk_pixbuf_new_from_file:
437
* @filename: Name of file to load.
439
* Creates a new pixbuf by loading an image from a file. The file format is
440
* detected automatically.
442
* Return value: A newly-created pixbuf with a reference count of 1, or %NULL if
443
* any of several error conditions occurred: the file could not be opened,
444
* there was no loader for the file's format, there was not enough memory to
445
* allocate the image buffer, or the image file contained invalid data.
448
gdk_pixbuf_new_from_file (const char *filename)
454
GdkPixbufModule *image_module;
456
g_return_val_if_fail (filename != NULL, NULL);
458
f = fopen (filename, "r");
462
size = fread (&buffer, 1, sizeof (buffer), f);
468
image_module = gdk_pixbuf_get_module (buffer, size);
470
g_warning ("Unable to find handler for file: %s", filename);
475
if (image_module->module == NULL)
476
gdk_pixbuf_load_module (image_module);
478
if (image_module->load == NULL) {
483
fseek (f, 0, SEEK_SET);
484
pixbuf = (* image_module->load) (f);
488
g_assert (pixbuf->ref_count > 0);
494
* gdk_pixbuf_new_from_xpm_data:
495
* @data: Pointer to inline XPM data.
497
* Creates a new pixbuf by parsing XPM data in memory. This data is commonly
498
* the result of including an XPM file into a program's C source.
500
* Return value: A newly-created pixbuf with a reference count of 1.
503
gdk_pixbuf_new_from_xpm_data (const char **data)
505
GdkPixbuf *(* load_xpm_data) (const char **data);
508
if (file_formats[XPM_FILE_FORMAT_INDEX].module == NULL)
509
gdk_pixbuf_load_module (&file_formats[XPM_FILE_FORMAT_INDEX]);
511
if (file_formats[XPM_FILE_FORMAT_INDEX].module == NULL) {
512
g_warning ("Can't find gdk-pixbuf module for parsing inline XPM data");
514
} else if (file_formats[XPM_FILE_FORMAT_INDEX].load_xpm_data == NULL) {
515
g_warning ("gdk-pixbuf XPM module lacks XPM data capability");
518
load_xpm_data = file_formats[XPM_FILE_FORMAT_INDEX].load_xpm_data;
520
pixbuf = (* load_xpm_data) (data);