Document BMP saving support.

2005-02-23  Matthias Clasen  <mclasen@redhat.com>

	* gdk-pixbuf-io.c: Document BMP saving support.

	* io-bmp.c: Support saving as BMP. (168173, Ivan Wong)
This commit is contained in:
Matthias Clasen 2005-02-24 04:41:35 +00:00 committed by Matthias Clasen
parent c06df5a44c
commit 534d584ba6
3 changed files with 128 additions and 7 deletions

View File

@ -1,5 +1,9 @@
2005-02-23 Matthias Clasen <mclasen@redhat.com>
* gdk-pixbuf-io.c: Document BMP saving support.
* io-bmp.c: Support saving as BMP. (168173, Ivan Wong)
* io-ico.c: Fix a typo. (#168173, Ivan Wong)
2005-02-15 Matthias Clasen <mclasen@redhat.com>

View File

@ -1528,8 +1528,8 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf *pixbuf,
* @error: return location for error, or %NULL
* @Varargs: list of key-value save options
*
* Saves pixbuf to a file in format @type. By default, "jpeg", "png" and
* "ico" are possible file formats to save in, but more formats may be
* Saves pixbuf to a file in format @type. By default, "jpeg", "png", "ico"
* and "bmp" are possible file formats to save in, but more formats may be
* installed. The list of all writable formats can be determined in the
* following way:
*
@ -1608,7 +1608,7 @@ gdk_pixbuf_save (GdkPixbuf *pixbuf,
* @option_values: values for named options
* @error: return location for error, or %NULL
*
* Saves pixbuf to a file in @type, which is currently "jpeg", "png" or "ico".
* Saves pixbuf to a file in @type, which is currently "jpeg", "png", "ico" or "bmp".
* If @error is set, %FALSE will be returned.
* See gdk_pixbuf_save () for more details.
*
@ -1738,7 +1738,7 @@ gdk_pixbuf_save_to_callback (GdkPixbuf *pixbuf,
* @error: return location for error, or %NULL
*
* Saves pixbuf to a callback in format @type, which is currently "jpeg",
* "png" or "ico". If @error is set, %FALSE will be returned. See
* "png", "ico" or "bmp". If @error is set, %FALSE will be returned. See
* gdk_pixbuf_save_to_callback () for more details.
*
* Return value: whether an error was set
@ -1784,7 +1784,7 @@ gdk_pixbuf_save_to_callbackv (GdkPixbuf *pixbuf,
* @Varargs: list of key-value save options
*
* Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
* "png" or "ico". This is a convenience function that uses
* "png", "ico" or "bmp". This is a convenience function that uses
* gdk_pixbuf_save_to_callback() to do the real work. Note that the buffer
* is not nul-terminated and may contain embedded nuls.
* If @error is set, %FALSE will be returned and @string will be set to
@ -1872,7 +1872,7 @@ save_to_buffer_callback (const gchar *data,
* @error: return location for error, or %NULL
*
* Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
* "png" or "ico". See gdk_pixbuf_save_to_buffer() for more details.
* "png", "ico" or "bmp". See gdk_pixbuf_save_to_buffer() for more details.
*
* Return value: whether an error was set
*

View File

@ -1123,12 +1123,129 @@ gdk_pixbuf__bmp_image_load_increment(gpointer data,
return TRUE;
}
/* for our convenience when filling file header */
#define put16u(buf,data) { *(guint16*)(buf) = GUINT16_TO_LE (data); buf += 2; }
#define put32u(buf,data) { *(guint32*)(buf) = GUINT32_TO_LE (data); buf += 4; }
#define put16(buf,data) { *(gint16*)(buf) = GINT16_TO_LE (data); buf += 2; }
#define put32(buf,data) { *(gint32*)(buf) = GINT32_TO_LE (data); buf += 4; }
static gboolean
gdk_pixbuf__bmp_image_save_to_callback (GdkPixbufSaveFunc save_func,
gpointer user_data,
GdkPixbuf *pixbuf,
gchar **keys,
gchar **values,
GError **error)
{
guint width, height, channel, size, stride, src_stride, x, y;
guchar BFH_BIH[40], *pixels, *buf, *src, *dst, *dst_line;
gboolean ret;
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
channel = gdk_pixbuf_get_n_channels (pixbuf);
pixels = gdk_pixbuf_get_pixels (pixbuf);
src_stride = gdk_pixbuf_get_rowstride (pixbuf);
stride = (width * 3 + 3) & ~3;
size = stride * height;
/* filling BFH */
dst = BFH_BIH;
*dst++ = 'B'; /* bfType */
*dst++ = 'M';
put32u (dst, size + 14 + 40); /* bfSize */
put32u (dst, 0); /* bfReserved1 + bfReserved2 */
put32u (dst, 14 + 40); /* bfOffBits */
/* filling BIH */
put32u (dst, 40); /* biSize */
put32 (dst, width); /* biWidth */
put32 (dst, height); /* biHeight */
put16 (dst, 1); /* biPlanes */
put16 (dst, 24); /* biBitCount */
put32u (dst, BI_RGB); /* biCompression */
put32u (dst, size); /* biSizeImage */
put32 (dst, 0); /* biXPelsPerMeter */
put32 (dst, 0); /* biYPelsPerMeter */
put32u (dst, 0); /* biClrUsed */
put32u (dst, 0); /* biClrImportant */
if (!save_func (BFH_BIH, 14 + 40, error, user_data))
return FALSE;
dst_line = buf = g_try_malloc (size);
if (!buf) {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
_("Couldn't allocate memory for saving BMP file"));
return FALSE;
}
/* saving as a bottom-up bmp */
pixels += (height - 1) * src_stride;
for (y = 0; y < height; ++y, pixels -= src_stride, dst_line += stride) {
dst = dst_line;
src = pixels;
for (x = 0; x < width; ++x, dst += 3, src += channel) {
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
}
}
ret = save_func (buf, size, error, user_data);
g_free (buf);
return ret;
}
static gboolean
save_to_file_cb (const gchar *buf,
gsize count,
GError **error,
gpointer data)
{
gint bytes;
while (count > 0) {
bytes = fwrite (buf, sizeof (gchar), count, (FILE *) data);
if (bytes <= 0)
break;
count -= bytes;
buf += bytes;
}
if (count) {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_FAILED,
_("Couldn't write to BMP file"));
return FALSE;
}
return TRUE;
}
static gboolean
gdk_pixbuf__bmp_image_save (FILE *f,
GdkPixbuf *pixbuf,
gchar **keys,
gchar **values,
GError **error)
{
return gdk_pixbuf__bmp_image_save_to_callback (save_to_file_cb,
f, pixbuf, keys,
values, error);
}
void
MODULE_ENTRY (bmp, fill_vtable) (GdkPixbufModule *module)
{
module->begin_load = gdk_pixbuf__bmp_image_begin_load;
module->stop_load = gdk_pixbuf__bmp_image_stop_load;
module->load_increment = gdk_pixbuf__bmp_image_load_increment;
module->save = gdk_pixbuf__bmp_image_save;
module->save_to_callback = gdk_pixbuf__bmp_image_save_to_callback;
}
void
@ -1154,7 +1271,7 @@ MODULE_ENTRY (bmp, fill_info) (GdkPixbufFormat *info)
info->description = N_("The BMP image format");
info->mime_types = mime_types;
info->extensions = extensions;
info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}