Skip to content

Commit

Permalink
Add a modicum of support for an alpha channel.
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip Rideout committed Nov 13, 2015
1 parent ddce2db commit 1bf868c
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 12 deletions.
6 changes: 6 additions & 0 deletions include/heman.h
Expand Up @@ -46,6 +46,12 @@ void heman_image_clear(heman_image*, HEMAN_FLOAT value);
// Free memory for a image.
void heman_image_destroy(heman_image*);

// Create a one-band image from a four-band image by extracting the 4th channel.
heman_image* heman_image_extract_alpha(heman_image*);

// Create a three-band image from a four-band image by extracting first 3 bands.
heman_image* heman_image_extract_rgb(heman_image*);

// Create a 1-pixel tall, 3-band image representing a color gradient that lerps
// the given control points, in a gamma correct way. Each control point is
// defined by an X location (one integer each) and an RGB value (one 32-bit
Expand Down
10 changes: 5 additions & 5 deletions src/color.c
Expand Up @@ -149,22 +149,22 @@ heman_image* heman_color_from_cpcf(heman_image* cfield, heman_image* texture)
return heman_internal_rg(cfield);
}
assert(cfield->nbands == 2);
assert(texture->nbands == 3);
assert(texture->nbands == 3 || texture->nbands == 4);
assert(cfield->width == texture->width);
assert(cfield->height == texture->height);
int w = cfield->width;
int h = cfield->height;
heman_image* target = heman_image_create(w, h, 3);
heman_image* target = heman_image_create(w, h, texture->nbands);
HEMAN_FLOAT* dst = target->data;
HEMAN_FLOAT* src = cfield->data;
int size = w * h;
for (int i = 0; i < size; i++) {
HEMAN_FLOAT u = *src++;
HEMAN_FLOAT v = *src++;
HEMAN_FLOAT* texel = heman_image_texel(texture, u, v);
*dst++ = *texel++;
*dst++ = *texel++;
*dst++ = *texel;
for (int c = 0; c < texture->nbands; c++) {
*dst++ = *texel++;
}
}
return target;
}
24 changes: 17 additions & 7 deletions src/draw.c
Expand Up @@ -23,7 +23,7 @@ void heman_draw_points(heman_image* target, heman_points* pts, HEMAN_FLOAT val)
void heman_draw_colored_points(
heman_image* target, heman_points* pts, const heman_color* colors)
{
assert(target->nbands == 3);
assert(target->nbands == 3 || target->nbands == 4);
HEMAN_FLOAT* src = pts->data;
HEMAN_FLOAT inv = 1.0f / 255.0f;
for (int k = 0; k < pts->width; k++) {
Expand All @@ -37,9 +37,12 @@ void heman_draw_colored_points(
}
HEMAN_FLOAT* texel = heman_image_texel(target, i, j);
heman_color rgb = colors[k];
*texel++ = (HEMAN_FLOAT)(rgb >> 16) * inv;
*texel++ = (HEMAN_FLOAT)((rgb >> 16) & 0xff) * inv;
*texel++ = (HEMAN_FLOAT)((rgb >> 8) & 0xff) * inv;
*texel = (HEMAN_FLOAT)(rgb & 0xff) * inv;
*texel++ = (HEMAN_FLOAT)(rgb & 0xff) * inv;
if (target->nbands == 4) {
*texel = (HEMAN_FLOAT)(rgb >> 24) * inv;
}
}
}

Expand Down Expand Up @@ -110,7 +113,7 @@ void heman_internal_draw_seeds(heman_image* target, heman_points* pts, int filte
void heman_draw_contour_from_points(heman_image* target, heman_points* coords,
heman_color rgb, float mind, float maxd, int filterd)
{
assert(target->nbands == 3);
assert(target->nbands == 3 || target->nbands == 4);
int width = target->width;
int height = target->height;
heman_image* seed = heman_image_create(width, height, 1);
Expand All @@ -119,21 +122,28 @@ void heman_draw_contour_from_points(heman_image* target, heman_points* coords,
heman_internal_draw_seeds(seed, coords, filterd);

HEMAN_FLOAT inv = 1.0f / 255.0f;
HEMAN_FLOAT r = (HEMAN_FLOAT)(rgb >> 16) * inv;
HEMAN_FLOAT r = (HEMAN_FLOAT)((rgb >> 16) & 0xff) * inv;
HEMAN_FLOAT g = (HEMAN_FLOAT)((rgb >> 8) & 0xff) * inv;
HEMAN_FLOAT b = (HEMAN_FLOAT)(rgb & 0xff) * inv;
HEMAN_FLOAT a = 1;
if (target->nbands == 4) {
a = (HEMAN_FLOAT)(rgb >> 24) * inv;
}

#pragma omp parallel for
for (int y = 0; y < height; y++) {
HEMAN_FLOAT* dst = target->data + y * width * 3;
HEMAN_FLOAT* dst = target->data + y * width * target->nbands;
for (int x = 0; x < width; x++) {
HEMAN_FLOAT dist = *heman_image_texel(seed, x, y);
if (dist > mind && dist < maxd) {
dst[0] = r;
dst[1] = g;
dst[2] = b;
if (target->nbands == 4) {
dst[3] = a;
}
}
dst += 3;
dst += target->nbands;
}
}

Expand Down
30 changes: 30 additions & 0 deletions src/image.c
Expand Up @@ -57,3 +57,33 @@ void heman_image_clear(heman_image* img, HEMAN_FLOAT value)
*dst++ = value;
}
}

heman_image* heman_image_extract_alpha(heman_image* img)
{
assert(img->nbands == 4);
heman_image* retval = heman_image_create(img->width, img->height, 1);
int size = img->width * img->height;
HEMAN_FLOAT* src = img->data;
HEMAN_FLOAT* dst = retval->data;
while (size--) {
src += 3;
*dst++ = *src++;
}
return retval;
}

heman_image* heman_image_extract_rgb(heman_image* img)
{
assert(img->nbands == 4);
heman_image* retval = heman_image_create(img->width, img->height, 3);
int size = img->width * img->height;
HEMAN_FLOAT* src = img->data;
HEMAN_FLOAT* dst = retval->data;
while (size--) {
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
++src;
}
return retval;
}

0 comments on commit 1bf868c

Please sign in to comment.