Re: Quick question...
- From: Tristan Van Berkom <vantr touchtunes com>
- To: Ian Molton <spyro f2s com>
- Cc: gtk-app-devel-list gnome org
- Subject: Re: Quick question...
- Date: Thu, 09 Jan 2003 11:37:51 -0500
from what I've heard there is no
standard for that (i think there
is a gdk_?_get_pixel();/set_pixel();
but I think its time-consuming).
to create (see gdk-pixbuf/gdk-pixbuf*.[ch])
GdkPixbuf *
gdk_pixbuf_new_from_data (const guchar *data, GdkColorspace colorspace,
gboolean has_alpha,
int bits_per_sample, int width, int height, int rowstride,
GdkPixbufDestroyNotify destroy_fn, gpointer destroy_fn_data)
I also have some odds and ends here I could ship you
(I think I picked this up and modified it
for the purpose of saving raw images
at optimized speed without jpeg compression etc...)
damn; I know I picked this up somewhere in
"contrib/" but I cant find the originals
right now.
Anyhow; this might help... hope so,
-Tristan
=========================================================
gboolean
gdk_pixdata_from_pixbuf (GdkPixdata *pixdata,
const GdkPixbuf *pixbuf)
GdkPixbuf*
gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata,
gboolean copy_pixels)
/***************** extract from ".h" ************************/
typedef enum
{
/* colorspace + alpha */
GDK_PIXDATA_COLOR_TYPE_RGB = 0x01,
GDK_PIXDATA_COLOR_TYPE_RGBA = 0x02,
GDK_PIXDATA_COLOR_TYPE_MASK = 0xff,
/* width, support 8bits only currently */
GDK_PIXDATA_SAMPLE_WIDTH_8 = 0x01 << 16,
GDK_PIXDATA_SAMPLE_WIDTH_MASK = 0x0f << 16,
/* encoding */
GDK_PIXDATA_ENCODING_RAW = 0x01 << 24,
GDK_PIXDATA_ENCODING_RLE = 0x02 << 24,
GDK_PIXDATA_ENCODING_MASK = 0x0f << 24
} GdkPixdataType;
typedef struct _GdkPixdata GdkPixdata;
struct _GdkPixdata
{
guint32 magic; /* GDK_PIXBUF_MAGIC_NUMBER */
gint32 length; /* <1 to disable length checks, otherwise:
* GDK_PIXDATA_HEADER_LENGTH + pixel_data length
*/
guint32 pixdata_type; /* GdkPixdataType */
guint32 rowstride; /* maybe 0 to indicate non-padded data */
guint32 width;
guint32 height;
guint8 *pixel_data;
};
#define GDK_PIXDATA_HEADER_LENGTH (4 + 4 + 4 + 4 + 4 + 4)
typedef enum
{
/* type of source to save */
GDK_PIXDATA_DUMP_PIXDATA_STREAM = 0,
GDK_PIXDATA_DUMP_PIXDATA_STRUCT = 1,
GDK_PIXDATA_DUMP_MACROS = 2,
/* type of variables to use */
GDK_PIXDATA_DUMP_GTYPES = 0,
GDK_PIXDATA_DUMP_CTYPES = 1 << 8,
GDK_PIXDATA_DUMP_STATIC = 1 << 9,
GDK_PIXDATA_DUMP_CONST = 1 << 10,
/* save RLE decoder macro? */
GDK_PIXDATA_DUMP_RLE_DECODER = 1 << 16,
} GdkPixdataDumpType;
/********************** extract from ".c" **********************/
gboolean
gdk_pixdata_from_pixbuf (GdkPixdata *pixdata,
const GdkPixbuf *pixbuf)
{
guint height, rowstride, bpp, length;
guint8 *img_buffer;
g_return_val_if_fail (pixdata != NULL, FALSE);
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
g_return_val_if_fail (pixbuf->bits_per_sample == 8, FALSE);
g_return_val_if_fail ((pixbuf->n_channels == 3 && !pixbuf->has_alpha)
||
(pixbuf->n_channels == 4 && pixbuf->has_alpha), FALSE);
g_return_val_if_fail (pixbuf->rowstride >= pixbuf->width, FALSE);
height = pixbuf->height;
rowstride = pixbuf->rowstride;
bpp = pixbuf->has_alpha ? 4 : 3;
img_buffer = pixbuf->pixels;
length = rowstride * height;
pixdata->magic = 0; // <-- now thats hard core !!
pixdata->length = GDK_PIXDATA_HEADER_LENGTH + length;
pixdata->pixdata_type = pixbuf->has_alpha ?
GDK_PIXDATA_COLOR_TYPE_RGBA : GDK_PIXDATA_COLOR_TYPE_RGB;
pixdata->pixdata_type |= GDK_PIXDATA_SAMPLE_WIDTH_8;
pixdata->pixdata_type |= GDK_PIXDATA_ENCODING_RAW;
pixdata->rowstride = rowstride;
pixdata->width = pixbuf->width;
pixdata->height = height;
pixdata->pixel_data = img_buffer;
return TRUE;
}
GdkPixbuf*
gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata,
gboolean copy_pixels)
{
guint encoding, bpp;
guint8 *data = NULL;
g_return_val_if_fail (pixdata != NULL, NULL);
g_return_val_if_fail (pixdata->width > 0, NULL);
g_return_val_if_fail (pixdata->height > 0, NULL);
g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL);
g_return_val_if_fail ((pixdata->pixdata_type &
GDK_PIXDATA_COLOR_TYPE_MASK) ==
GDK_PIXDATA_COLOR_TYPE_RGB ||
(pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) ==
GDK_PIXDATA_COLOR_TYPE_RGBA, NULL);
g_return_val_if_fail ((pixdata->pixdata_type &
GDK_PIXDATA_SAMPLE_WIDTH_MASK) ==
GDK_PIXDATA_SAMPLE_WIDTH_8, NULL);
g_return_val_if_fail ((pixdata->pixdata_type &
GDK_PIXDATA_ENCODING_MASK) ==
GDK_PIXDATA_ENCODING_RAW ||
(pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) ==
GDK_PIXDATA_ENCODING_RLE, NULL);
g_return_val_if_fail (pixdata->pixel_data != NULL, NULL);
bpp = (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) ==
GDK_PIXDATA_COLOR_TYPE_RGB ? 3 : 4;
encoding = pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK;
if (encoding == GDK_PIXDATA_ENCODING_RLE)
copy_pixels = TRUE;
if (copy_pixels)
{
data = g_try_malloc (pixdata->rowstride * pixdata->height);
if (!data)
{
return NULL;
}
}
if (encoding == GDK_PIXDATA_ENCODING_RLE)
{
const guint8 *rle_buffer = pixdata->pixel_data;
guint8 *image_buffer = data;
guint8 *image_limit = data + pixdata->rowstride * pixdata->height;
gboolean check_overrun = FALSE;
while (image_buffer < image_limit)
{
guint length = *(rle_buffer++);
if (length & 128)
{
length = length - 128;
check_overrun = image_buffer + length * bpp > image_limit;
if (check_overrun)
length = (image_limit - image_buffer) / bpp;
if (bpp < 4) /* RGB */
do
{
memcpy (image_buffer, rle_buffer, 3);
image_buffer += 3;
}
while (--length);
else /* RGBA */
do
{
memcpy (image_buffer, rle_buffer, 4);
image_buffer += 4;
}
while (--length);
rle_buffer += bpp;
}
else
{
length *= bpp;
check_overrun = image_buffer + length > image_limit;
if (check_overrun)
length = image_limit - image_buffer;
memcpy (image_buffer, rle_buffer, length);
image_buffer += length;
rle_buffer += length;
}
}
if (check_overrun)
{
return NULL;
}
}
else if (copy_pixels)
memcpy (data, pixdata->pixel_data, pixdata->rowstride *
pixdata->height);
else
data = pixdata->pixel_data;
return gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB,
(pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) ==
GDK_PIXDATA_COLOR_TYPE_RGBA,
8, pixdata->width, pixdata->height, pixdata->rowstride,
copy_pixels ? (GdkPixbufDestroyNotify) g_free : NULL, data);
}
Ian Molton wrote:
How do I create a pixmap (or similar) of a specified colourdepth, AND
get an efficient way of /directly/ manipulating the pixels in it?
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]