Skip to content

Instantly share code, notes, and snippets.

@astiob
Last active August 29, 2015 14:13
Show Gist options
  • Save astiob/7e0dc1fa94fb4c8cf633 to your computer and use it in GitHub Desktop.
Save astiob/7e0dc1fa94fb4c8cf633 to your computer and use it in GitHub Desktop.
Code fragment blending ASS_Images onto an RGB surface
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#define dither() (rand() / (RAND_MAX + 1.0L))
typedef struct
{
size_t w, h;
struct rgb24_pixel { uint8_t r, g, b; } samples[];
} rgb24;
void render_subtitles_rgb24(rgb24 *restrict buffer, ASS_Image *restrict img)
{
for (; img; img = img->next)
{
if (!img->w || !img->h) continue;
uint_fast8_t r = img->color >> 24,
g = img->color >> 16 & 255,
b = img->color >> 8 & 255,
a = 255 - (img->color & 255);
for (int y = img->dst_y; y < img->dst_y + img->h; ++y)
{
const unsigned char *restrict map =
img->bitmap + (y - img->dst_y) * img->stride;
for (int x = img->dst_x; x < img->dst_x + img->w; ++x)
{
uint_fast32_t alpha = (unsigned) a * *map++;
struct rgb24_pixel *restrict p =
&buffer->samples[y * buffer->w + x];
p->r = (p->r * (65025 - alpha) + r * alpha) / 65025.0L + dither();
p->g = (p->g * (65025 - alpha) + g * alpha) / 65025.0L + dither();
p->b = (p->b * (65025 - alpha) + b * alpha) / 65025.0L + dither();
}
}
}
}
#include <stddef.h>
#include <stdint.h>
typedef struct
{
size_t w, h;
struct rgbld_pixel { long double r, g, b; } samples[];
} rgbld;
void render_subtitles_rgbld(rgbld *restrict buffer, ASS_Image *restrict img)
{
for (; img; img = img->next)
{
if (!img->w || !img->h) continue;
long double r = (img->color >> 24) / 255.0L,
g = (img->color >> 16 & 255) / 255.0L,
b = (img->color >> 8 & 255) / 255.0L;
uint_fast8_t a = 255 - (img->color & 255);
for (int y = img->dst_y; y < img->dst_y + img->h; ++y)
{
const unsigned char *restrict map =
img->bitmap + (y - img->dst_y) * img->stride;
for (int x = img->dst_x; x < img->dst_x + img->w; ++x)
{
unsigned alpha = (unsigned) a * *map++;
struct rgbld_pixel *restrict p =
&buffer->samples[y * buffer->w + x];
p->r = (p->r * (65025 - alpha) + r * alpha) / 65025;
p->g = (p->g * (65025 - alpha) + g * alpha) / 65025;
p->b = (p->b * (65025 - alpha) + b * alpha) / 65025;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment