1 /* thumb-gdk.c: load, scale, and save the image using a GDK Pixbuf
3 Copyright 2011 Lewis Gentry.
5 This program is free software: you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation, either version 3 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 #include <gdk-pixbuf/gdk-pixbuf.h>
21 /* As soon as we learn the dimensions of the existing cover, this
22 callback function snaps into play to set the dimensions of the
25 void scale(GdkPixbufLoader
*self
, gint width
, gint height
, gpointer reqsize
)
27 gint max
= GPOINTER_TO_INT(reqsize
);
30 gdk_pixbuf_loader_set_size(self
, max
, max
);
31 else if (width
< height
)
32 gdk_pixbuf_loader_set_size(self
, width
* max
/ height
, max
);
34 gdk_pixbuf_loader_set_size(self
, max
, height
* max
/ width
);
37 /* Feed a quantity of bytes to dest (an initialized PixbufLoader) from
38 source (a stream open for reading) and return status. */
40 int fill(GdkPixbufLoader
*dest
, FILE *source
, unsigned int bytes_remaining
)
42 unsigned int stride
= 4096;
43 guchar buffer
[stride
];
45 for (; bytes_remaining
; bytes_remaining
-= stride
) {
46 if (bytes_remaining
< stride
)
47 stride
= bytes_remaining
;
48 if (fread(buffer
, sizeof(guchar
), stride
, source
) != stride
49 || !gdk_pixbuf_loader_write(dest
, buffer
, stride
, NULL
)) {
50 gdk_pixbuf_loader_close(dest
, NULL
);
54 return gdk_pixbuf_loader_close(dest
, NULL
);
57 /* Read, scale, and save an image. Return true if no mishaps. */
59 int thumb(FILE *stream
, unsigned int n
, char *pathname
, int requested_size
)
61 GdkPixbufLoader
*loader
;
65 g_type_init(); /* Required before doing gAnything. */
66 loader
= gdk_pixbuf_loader_new();
67 g_signal_connect(loader
, "size_prepared", (GCallback
) scale
,
68 GINT_TO_POINTER(requested_size
));
70 if (fill(loader
, stream
, n
)) {
71 pixbuf
= gdk_pixbuf_loader_get_pixbuf(loader
);
73 status
= gdk_pixbuf_save(pixbuf
, pathname
, "png", NULL
, NULL
);
75 g_object_unref(loader
);