Skip to content

Commit

Permalink
Added comments and improved naming in some image functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Doom032 committed Jan 18, 2015
1 parent fbb85b7 commit a75260f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
32 changes: 22 additions & 10 deletions win32/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,20 +136,32 @@ void drawalpha(int bm, int x, int y, int width, int height, uint32_t color)
}
};

uint8_t *p = bitmap[bm], *end = p + width * height;
// create pointer to begining and end of the alpha-channel-only bitmap
uint8_t *alpha_pixel = bitmap[bm], *end = alpha_pixel + width * height;


uint32_t *np;
HBITMAP temp = CreateDIBSection(hdcMem, &bmi, DIB_RGB_COLORS, (void**)&np, NULL, 0);
// create temporary bitmap we'll combine the alpha and colors on
uint32_t *out_pixel;
HBITMAP temp = CreateDIBSection(hdcMem, &bmi, DIB_RGB_COLORS, (void**)&out_pixel, NULL, 0);
SelectObject(hdcMem, temp);

while(p != end) {
uint8_t v = *p++;
*np++ = (((color & 0xFF) * v / 255) << 16) | ((((color >> 8) & 0xFF) * v / 255) << 8) | ((((color >> 16) & 0xFF) * v / 255) << 0) | (v << 24);
// create pixels for the drawable bitmap based on the alpha value of
// each pixel in the alpha bitmap and the color given by 'color',
// the Win32 API requires we pre-apply our alpha channel as well by
// doing (color * alpha / 255) for each color channel
// NOTE: Input color is in the format 0BGR, output pixel is in the format ARGB
while(alpha_pixel != end) {
uint8_t alpha = *alpha_pixel++;
*out_pixel++ = (((color & 0xFF) * alpha / 255) << 16) // red
| ((((color >> 8) & 0xFF) * alpha / 255) << 8) // green
| ((((color >> 16) & 0xFF) * alpha / 255) << 0) // blue
| (alpha << 24); // alpha
}

// draw temporary bitmap on screen
AlphaBlend(hdc, x, y, width, height, hdcMem, 0, 0, width, height, blend_function);

// clean up
DeleteObject(temp);
}

Expand Down Expand Up @@ -845,14 +857,14 @@ UTOX_NATIVE_IMAGE *png_to_image(const UTOX_PNG_IMAGE data, size_t size, uint16_t
uint8_t *out;
HBITMAP bitmap = CreateDIBSection(hdcMem, &bmi, DIB_RGB_COLORS, (void**)&out, NULL, 0);

// convert RGBA data to internal format, switching the first and
// third bytes, and pre-applying the alpha if we're keeping the
// alpha channel
// convert RGBA data to internal format
// pre-applying the alpha if we're keeping the alpha channel,
// put the result in out
// NOTE: input pixels are in format RGBA, output is BGRA
uint8_t *p, *end = rgba_data + width * height * 4;
uint8_t alpha;
p = rgba_data;
if (keep_alpha) {
uint8_t alpha;
do {
alpha = p[3];
out[0] = p[2] * (alpha / 255.0); // pre-apply alpha
Expand Down
8 changes: 8 additions & 0 deletions xlib/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ static void pastedata(void *data, Atom type, int len, _Bool select)
}
}

// converts an XImage to a Picture usable by XRender, uses XRenderPictFormat given by
// 'format', uses the default format if it is NULL
static Picture ximage_to_picture(XImage *img, const XRenderPictFormat *format)
{
Pixmap pixmap = XCreatePixmap(display, window, img->width, img->height, img->depth);
Expand All @@ -620,6 +622,9 @@ void loadalpha(int bm, void *data, int width, int height)
{
XImage *img = XCreateImage(display, CopyFromParent, 8, ZPixmap, 0, data, width, height, 8, 0);

// create picture that only holds alpha values
// NOTE: the XImage made earlier should really be freed, but calling XDestroyImage on it will also
// automatically free the data it's pointing to(which we don't want), so there's no easy way to destroy them currently
bitmap[bm] = ximage_to_picture(img, XRenderFindStandardFormat(display, PictStandardA8));
}

Expand All @@ -629,12 +634,14 @@ void loadalpha(int bm, void *data, int width, int height)
*/
static Picture generate_alpha_bitmask(const uint8_t *rgba_data, uint16_t width, uint16_t height, uint32_t rgba_size)
{
// we don't need to free this, that's done by XDestroyImage()
uint8_t *out = malloc(rgba_size / 4);
uint32_t i, j;
for (i = j = 0; i < rgba_size; i += 4, j++) {
out[j] = (rgba_data+i)[3] & 0xFF; // take only alpha values
}

// create 1-byte-per-pixel image and convert it to a Alpha-format Picture
XImage *img = XCreateImage(display, CopyFromParent, 8, ZPixmap, 0, (char*)out, width, height, 8, width);
Picture picture = ximage_to_picture(img, XRenderFindStandardFormat(display, PictStandardA8));

Expand All @@ -658,6 +665,7 @@ UTOX_NATIVE_IMAGE *png_to_image(const UTOX_PNG_IMAGE data, size_t size, uint16_t
// we don't need to free this, that's done by XDestroyImage()
uint8_t *out = malloc(rgba_size);

// colors are read into red, blue and green and written into the target pointer
uint8_t red, blue, green;
uint32_t *target;

Expand Down

0 comments on commit a75260f

Please sign in to comment.