]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/gdk-pixbuf-io.c
Loading framework done, start of PNG loader
[~andy/gtk] / gdk-pixbuf / gdk-pixbuf-io.c
1 /*
2  * gdk-pixbuf-io.c: Code to load images into GdkPixBufs
3  *
4  * Author:
5  *    Miguel de Icaza (miguel@gnu.org)
6  */
7 #include <config.h>
8 #include <stdio.h>
9 #include "gdk-pixbuf.h"
10
11 static gboolean
12 pixbuf_check_png (unsigned char *buffer, int size)
13 {
14         if (size < 28)
15                 return FALSE;
16
17         if (buffer [0] != 0x89 ||
18             buffer [1] != 'P' ||
19             buffer [2] != 'N' ||
20             buffer [3] != 'G' ||
21             buffer [4] != 0x0d ||
22             buffer [5] != 0x0a ||
23             buffer [6] != 0x1a ||
24             buffer [7] != 0x0a)
25                 return FALSE;
26
27         return TRUE;
28 }
29
30 static gboolean
31 pixbuf_check_jpeg (unsigned char *buffer, int size)
32 {
33         if (size < 10)
34                 return FALSE;
35
36         if (buffer [0] != 0xff || buffer [1] != 0xd8)
37                 return FALSE;
38         
39         return TRUE;
40 }
41
42 static gboolean
43 pixbuf_check_tiff (unsigned char *buffer, int size)
44 {
45         if (size < 10)
46                 return FALSE;
47
48         if (buffer [0] == 'M' && buffer [1] == 'M' && buffer [2] == 0 && buffer [3] == 0x2a)
49                 return TRUE;
50
51         if (buffer [0] == 'I' && buffer [1] == 'I' && buffer [2] == 0x2a && buffer [3] == 0)
52                 return TRUE;
53         
54         return FALSE;
55 }
56
57 static gboolean
58 pixbuf_check_gif (unsigned char *buffer, int size)
59 {
60         if (size < 20)
61                 return FALSE;
62                 
63         if (strncmp (buffer, "GIF8", 4) == 0)
64                 return TRUE;
65         
66         return FALSE;
67 }
68
69 static gboolean
70 pixbuf_check_xpm (unsigned char *buffer, int size)
71 {
72         if (size < 20)
73                 return FALSE;
74         
75         if (strncmp (buffer, "/* XPM */", 9) == 0)
76                 return TRUE;
77         
78         return FALSE;
79 }
80
81 static gboolean
82 pixbuf_check_bmp (unsigned char *buffer, int size)
83 {
84         if (size < 20)
85                 return FALSE;
86         
87         if (buffer [0] != 'B' || buffer [1] != 'M')
88                 return FALSE;
89         
90         return TRUE;
91 }
92
93 static gboolean
94 pixbuf_check_ppm (unsigned char *buffer, int size)
95 {
96         if (size < 20)
97                 return FALSE;
98
99         if (buffer [0] == 'P'){
100                 if (buffer [1] == '1' ||
101                     buffer [1] == '2' ||
102                     buffer [1] == '3' ||
103                     buffer [1] == '4' ||
104                     buffer [1] == '5' ||
105                     buffer [1] == '6')
106                         return TRUE;
107         }
108         return FALSE;
109 }
110
111 static struct {
112         char      *module_name;
113         gboolean   (*format_check)(unsigned char *buffer, int size);
114         GModule   *module;
115         GdkPixBuf *(*load)(FILE *f)
116         int        (*save)(char *filename, ...);
117 } file_formats [] = {
118         { "png",  pixbuf_check_png,  NULL, NULL, NULL },
119         { "jpeg", pixbuf_check_jpeg, NULL, NULL, NULL },
120         { "tiff", pixbuf_check_tiff, NULL, NULL, NULL },
121         { "gif",  pixbuf_check_gif,  NULL, NULL, NULL },
122         { "xpm",  pixbuf_check_xpm,  NULL, NULL, NULL }
123         { "bmp",  pixbuf_check_bmp,  NULL, NULL, NULL },
124         { "ppm",  pixbuf_check_ppm,  NULL, NULL, NULL },
125         { NULL, NULL, NULL, NULL, NULL },
126 };
127
128 static int
129 image_file_format (const char *file)
130 {
131         FILE *f = fopen (file);
132
133         if (!f)
134                 return -1;
135 }
136
137 static void
138 image_handler_load (int idx)
139 {
140         char *module_name = g_strconcat ("pixbuf-", file_formats [idx].module_name, NULL);
141         char *path;
142         GModule *module;
143         void *load_sym, *save_sym;
144         
145         path = g_module_build_path (PIXBUF_LIBDIR, module_name);
146         g_free (module_name);
147
148         module = g_module_open (path, G_MODULE_BIND_LAZY);
149         if (!module)
150                 return;
151         
152         file_formats [idx].module = module;
153
154         if (g_module_symbol (module, "image_load", &load_sym))
155                 file_formats [idx].load = load_sym;
156
157         if (g_module_symbol (module, "image_save", &save_sym))
158                 file_formats [idx].save = save_sym;
159 }
160
161 GdkPixBuf *
162 gdk_pixbuf_load_image (const char *file)
163 {
164         GdkPixBuf *pixbuf;
165         FormatLoader format_loader;
166         FILE *f;
167         char buffer [128];
168
169         f = fopen (file);
170         if (!f)
171                 return NULL;
172         n = fread (&buffer, 1, sizeof (buffer), f);
173
174         if (n == 0){
175                 fclose (f);             
176                 return NULL;
177         }
178
179         for (i = 0; file_formats [i].module_name; i++){
180                 if ((*file_formats [i].format_check)(buffer, n)){
181                         if (!file_formats [i].load)
182                                 image_handler_load (i);
183
184                         if (!file_formats [i].load){
185                                 fclose (f);
186                                 return NULL;
187                         }
188
189                         rewind (f);
190                         pixbuf = (*file_formats [i].load)(f);
191                         fclose (f);
192                         return pixbuf;
193                 }
194         }
195
196         fclose (f);
197         return NULL;
198 }
199