2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <guichaz@yahoo.fr>
21 /************************************************
22 * Files decompression (images and collections) *
23 ************************************************/
25 #include <unistd.h> /* read(), pipe(), fork(), execlp() ... */
26 #include <sys/types.h> /* pid_t */
27 #include <signal.h> /* kill(), SIGTERM */
28 #include <stdio.h> /* perror() */
29 #include <sys/wait.h> /* waitpid() */
30 #include <errno.h> /* errno */
33 #include "decompression.h"
34 #include "collection.h"
42 /* Read from the child process. */
43 static GdkPixbuf
*read_image(gint fd
, GError
** error
)
47 GdkPixbufLoader
*loader
;
50 loader
= gdk_pixbuf_loader_new();
52 while ((size
= read(fd
, buf
, sizeof(buf
))) > 0 || (errno
== EINTR
)) {
54 gdk_pixbuf_loader_write(loader
, buf
, size
, error
) == FALSE
)
58 if (gdk_pixbuf_loader_close(loader
, error
) == FALSE
)
61 pixbuf
= gdk_pixbuf_loader_get_pixbuf(loader
);
63 gdk_pixbuf_ref(pixbuf
);
65 g_object_unref(loader
);
69 /* Exec: "%cmd -c %filename" to send the output to stdout, the parent. */
70 static void decomp_file(const gchar
* cmd
, const gchar
* filename
, gint fd
)
72 if (dup2(fd
, STDOUT_FILENO
) < 0) {
77 if (execlp(cmd
, cmd
, "-c", filename
, NULL
) < 0) {
83 static gboolean
init_decompression(const gchar
* filename
, gint
* fd
,
87 static decompressor all_decomp
[] = {
90 { "z", "uncompress" },
100 /* Find the appropriate decompressor. */
101 ext
= get_extension(filename
);
105 for (decomp
= all_decomp
; decomp
->ext
!= NULL
; decomp
++)
106 if (!g_ascii_strcasecmp(decomp
->ext
, ext
))
109 if (decomp
->ext
== NULL
)
110 /* Decompressor not found. */
113 if (pipe(filedes
) < 0) {
127 decomp_file(decomp
->cmd
, filename
, filedes
[1]);
138 GdkPixbuf
*load_compressed_pixbuf(const gchar
* filename
, GError
** error
)
144 if (init_decompression(filename
, &fd
, &pid
) == FALSE
)
147 pixbuf
= read_image(fd
, error
);
149 waitpid(pid
, NULL
, 0);
154 gint
load_compressed_collection(const gchar
* filename
, gboolean reverse
)
161 if (init_decompression(filename
, &fd
, &pid
) == FALSE
)
164 file
= fdopen(fd
, "r");
170 nb_inserted
= load_dot_gliv_from_file(file
, reverse
);
173 waitpid(pid
, NULL
, 0);