image: add function to create from argb32 data

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-09-17 17:28:38 +02:00
parent 6ac0c4130c
commit c8f58d7868
3 changed files with 70 additions and 61 deletions

30
ewmh.c
View File

@ -510,40 +510,16 @@ ewmh_window_icon_get_unchecked(xcb_window_t w)
image_t * image_t *
ewmh_window_icon_from_reply(xcb_get_property_reply_t *r) ewmh_window_icon_from_reply(xcb_get_property_reply_t *r)
{ {
double alpha;
image_t *icon;
int size, i;
uint32_t *data; uint32_t *data;
unsigned char *imgdata;
if(!r || r->type != CARDINAL || r->format != 32 || r->length < 2 || if(!r || r->type != CARDINAL || r->format != 32 || r->length < 2 ||
!(data = (uint32_t *) xcb_get_property_value(r))) !(data = (uint32_t *) xcb_get_property_value(r)))
return NULL; return NULL;
icon = p_new(image_t, 1); if(data[0] && data[1])
return image_new_from_argb32(data[0], data[1], data + 2);
icon->width = data[0]; return NULL;
icon->height = data[1];
size = icon->width * icon->height;
if(!size)
{
p_delete(&icon);
p_delete(&r);
return NULL;
}
icon->data = p_new(unsigned char, size * 4);
for(imgdata = icon->data, i = 2; i < size + 2; i++, imgdata += 4)
{
imgdata[3] = (data[i] >> 24) & 0xff; /* A */
alpha = imgdata[3] / 255.0;
imgdata[2] = ((data[i] >> 16) & 0xff) * alpha; /* R */
imgdata[1] = ((data[i] >> 8) & 0xff) * alpha; /* G */
imgdata[0] = (data[i] & 0xff) * alpha; /* B */
}
return icon;
} }
/** Get NET_WM_ICON. /** Get NET_WM_ICON.

92
image.c
View File

@ -19,10 +19,7 @@
* *
*/ */
#include <Imlib2.h>
#include "structs.h" #include "structs.h"
#include "image.h"
extern awesome_t globalconf; extern awesome_t globalconf;
@ -70,6 +67,63 @@ image_imlib_load_strerror(Imlib_Load_Error e)
return "unknown error"; return "unknown error";
} }
/** Recompute the ARGB32 data from an image.
* \param image The image.
* \return Data.
*/
static void
image_compute(image_t *image)
{
int size, i;
uint32_t *data;
double alpha;
uint8_t *dataimg;
imlib_context_set_image(image->image);
data = imlib_image_get_data_for_reading_only();
image->width = imlib_image_get_width();
image->height = imlib_image_get_height();
size = image->width * image->height;
p_delete(&image->data);
image->data = dataimg = p_new(uint8_t, size * 4);
for(i = 0; i < size; i++, dataimg += 4)
{
dataimg[3] = (data[i] >> 24) & 0xff; /* A */
/* cairo wants pre-multiplied alpha */
alpha = dataimg[3] / 255.0;
dataimg[2] = ((data[i] >> 16) & 0xff) * alpha; /* R */
dataimg[1] = ((data[i] >> 8) & 0xff) * alpha; /* G */
dataimg[0] = (data[i] & 0xff) * alpha; /* B */
}
}
/** Create a new image from ARGB32 data.
* \param width The image width.
* \param height The image height.
* \param data The image data.
* \return A brand new image.
*/
image_t *
image_new_from_argb32(int width, int height, uint32_t *data)
{
Imlib_Image imimage;
image_t *image = NULL;
if((imimage = imlib_create_image_using_data(width, height, data)))
{
image = p_new(image_t, 1);
image->image = imimage;
image_compute(image);
}
return image;
}
/** Load an image from filename. /** Load an image from filename.
* \param filename The image file to load. * \param filename The image file to load.
* \return A new image. * \return A new image.
@ -77,10 +131,6 @@ image_imlib_load_strerror(Imlib_Load_Error e)
image_t * image_t *
image_new_from_file(const char *filename) image_new_from_file(const char *filename)
{ {
int w, h, size, i;
uint32_t *data;
double alpha;
unsigned char *dataimg, *rdataimg;
Imlib_Image imimage; Imlib_Image imimage;
Imlib_Load_Error e = IMLIB_LOAD_ERROR_NONE; Imlib_Load_Error e = IMLIB_LOAD_ERROR_NONE;
image_t *image; image_t *image;
@ -94,34 +144,10 @@ image_new_from_file(const char *filename)
return NULL; return NULL;
} }
imlib_context_set_image(imimage);
w = imlib_image_get_width();
h = imlib_image_get_height();
size = w * h;
data = imlib_image_get_data_for_reading_only();
rdataimg = dataimg = p_new(unsigned char, size * 4);
for(i = 0; i < size; i++, dataimg += 4)
{
dataimg[3] = (data[i] >> 24) & 0xff; /* A */
/* cairo wants pre-multiplied alpha */
alpha = dataimg[3] / 255.0;
dataimg[2] = ((data[i] >> 16) & 0xff) * alpha; /* R */
dataimg[1] = ((data[i] >> 8) & 0xff) * alpha; /* G */
dataimg[0] = (data[i] & 0xff) * alpha; /* B */
}
image = p_new(image_t, 1); image = p_new(image_t, 1);
image->image = imimage;
image->data = rdataimg; image_compute(image);
image->width = w;
image->height = h;
imlib_free_image();
return image; return image;
} }

View File

@ -23,6 +23,7 @@
#define AWESOME_IMAGE_H #define AWESOME_IMAGE_H
#include <lua.h> #include <lua.h>
#include <Imlib2.h>
#include "common/util.h" #include "common/util.h"
#include "common/refcount.h" #include "common/refcount.h"
@ -31,12 +32,14 @@ typedef struct
{ {
/** Reference counter */ /** Reference counter */
int refcount; int refcount;
/** Imlib2 image */
Imlib_Image image;
/** Image width */ /** Image width */
int width; int width;
/** Image height */ /** Image height */
int height; int height;
/** Image data */ /** Image data */
void *data; uint8_t *data;
} image_t; } image_t;
static inline void static inline void
@ -44,6 +47,8 @@ image_delete(image_t **i)
{ {
if(*i) if(*i)
{ {
imlib_context_set_image((*i)->image);
imlib_free_image();
p_delete(&(*i)->data); p_delete(&(*i)->data);
p_delete(i); p_delete(i);
} }
@ -52,6 +57,8 @@ image_delete(image_t **i)
DO_RCNT(image_t, image, image_delete) DO_RCNT(image_t, image, image_delete)
image_t * image_new_from_file(const char *); image_t * image_new_from_file(const char *);
image_t * image_new_from_argb32(int, int, uint32_t *);
uint8_t * image_data_argb32_get(image_t *);
int luaA_image_userdata_new(lua_State *, image_t *); int luaA_image_userdata_new(lua_State *, image_t *);