#define RENDER_MAGIC 0x765AE
-typedef void (*render_color_f)(i_render *, int, int, int, unsigned char const *src, i_color const *color);
+typedef void (*render_color_f)(i_render *, i_img_dim, i_img_dim, i_img_dim, unsigned char const *src, i_color const *color);
#define i_has_alpha(channels) ((channels) == 2 || (channels) == 4)
#code
-static void IM_SUFFIX(render_color_alpha)(i_render *r, int x, int y, int width, unsigned char const *src, i_color const *color);
-static void IM_SUFFIX(render_color_13)(i_render *r, int x, int y, int width, unsigned char const *src, i_color const *color);
+static void IM_SUFFIX(render_color_alpha)(i_render *r, i_img_dim x, i_img_dim y, i_img_dim width, unsigned char const *src, i_color const *color);
+static void IM_SUFFIX(render_color_13)(i_render *r, i_img_dim x, i_img_dim y, i_img_dim width, unsigned char const *src, i_color const *color);
static render_color_f IM_SUFFIX(render_color_tab)[] =
{
IM_SUFFIX(render_color_alpha),
};
-static void IM_SUFFIX(combine_line_noalpha)(IM_COLOR *out, IM_COLOR const *in, int channels, int count);
-static void IM_SUFFIX(combine_line_alpha)(IM_COLOR *out, IM_COLOR const *in, int channels, int count);
+static void IM_SUFFIX(combine_line_noalpha)(IM_COLOR *out, IM_COLOR const *in, int channels, i_img_dim count);
+static void IM_SUFFIX(combine_line_alpha)(IM_COLOR *out, IM_COLOR const *in, int channels, i_img_dim count);
/* the copy variant copies the source alpha to the the output alpha channel */
-static void IM_SUFFIX(combine_line_alpha_na)(IM_COLOR *out, IM_COLOR const *in, int channels, int count);
+static void IM_SUFFIX(combine_line_alpha_na)(IM_COLOR *out, IM_COLOR const *in, int channels, i_img_dim count);
-static void IM_SUFFIX(combine_line)(IM_COLOR *out, IM_COLOR const *in, int channels, int count);
-static void IM_SUFFIX(combine_line_na)(IM_COLOR *out, IM_COLOR const *in, int channels, int count);
+static void IM_SUFFIX(combine_line)(IM_COLOR *out, IM_COLOR const *in, int channels, i_img_dim count);
+static void IM_SUFFIX(combine_line_na)(IM_COLOR *out, IM_COLOR const *in, int channels, i_img_dim count);
#/code
+/*
+=item i_render_new(im, width)
+=category Blit tools
+
+Allocate a new C<i_render> object and initialize it.
+
+=cut
+*/
+
+i_render *
+i_render_new(i_img *im, i_img_dim width) {
+ i_render *r = mymalloc(sizeof(i_render));
+
+ i_render_init(r, im, width);
+
+ return r;
+}
+
+/*
+=item i_render_delete(r)
+=category Blit tools
+
+Release an C<i_render> object.
+
+=cut
+*/
+
void
-i_render_init(i_render *r, i_img *im, int width) {
+i_render_delete(i_render *r) {
+ i_render_done(r);
+ myfree(r);
+}
+
+void
+i_render_init(i_render *r, i_img *im, i_img_dim width) {
r->magic = RENDER_MAGIC;
r->im = im;
r->line_width = width;
}
static void
-alloc_line(i_render *r, int width, int eight_bit) {
+alloc_line(i_render *r, i_img_dim width, i_img_dim eight_bit) {
if (width > r->line_width) {
- int new_width = r->line_width * 2;
+ i_img_dim new_width = r->line_width * 2;
if (new_width < width)
new_width = width;
}
static void
-alloc_fill_line(i_render *r, int width, int eight_bit) {
+alloc_fill_line(i_render *r, i_img_dim width, int eight_bit) {
if (width > r->fill_width) {
- int new_width = r->fill_width * 2;
+ i_img_dim new_width = r->fill_width * 2;
if (new_width < width)
new_width = width;
}
}
+/*
+=item i_render_color(r, x, y, width, source, color)
+=category Blit tools
+
+Render the given color with the coverage specified by C<source[0]> to
+C<source[width-1]>.
+
+Renders in normal combine mode.
+
+=cut
+*/
+
void
-i_render_color(i_render *r, int x, int y, int width, unsigned char const *src,
- i_color const *color) {
+i_render_color(i_render *r, i_img_dim x, i_img_dim y, i_img_dim width,
+ unsigned char const *src, i_color const *color) {
i_img *im = r->im;
if (y < 0 || y >= im->ysize)
return;
#/code
}
+/*
+=item i_render_fill(r, x, y, width, source, fill)
+=category Blit tools
+
+Render the given fill with the coverage in C<source[0]> through
+C<source[width-1]>.
+
+=cut
+*/
+
void
-i_render_fill(i_render *r, int x, int y, int width, unsigned char const *src,
- i_fill_t *fill) {
+i_render_fill(i_render *r, i_img_dim x, i_img_dim y, i_img_dim width,
+ unsigned char const *src, i_fill_t *fill) {
i_img *im = r->im;
int fill_channels = im->channels;
if (src) {
unsigned char const *srcc = src;
IM_COLOR *fillc = r->IM_SUFFIX(fill_line);
- int work_width = width;
+ i_img_dim work_width = width;
while (work_width) {
if (*srcc == 0) {
fillc->channel[fill_channels-1] = 0;
}
else {
if (src) {
- int work_width = width;
+ i_img_dim work_width = width;
IM_COLOR *srcc = r->IM_SUFFIX(fill_line);
IM_COLOR *destc = r->IM_SUFFIX(line);
int ch;
}
else if (*src) {
for (ch = 0; ch < im->channels; ++ch) {
- IM_WORK_T work = (destc->channel[ch] * (IM_SAMPLE_MAX - *src)
- + srcc->channel[ch] * *src) / IM_SAMPLE_MAX;
+ IM_WORK_T work = (destc->channel[ch] * (255 - *src)
+ + srcc->channel[ch] * *src) / 255.0;
destc->channel[ch] = IM_LIMIT(work);
}
}
}
}
else { /* if (src) */
- IM_FILL_FILLER(fill)(fill, x, y, width, r->im->channels, r->IM_SUFFIX(line));
+ IM_FILL_FILLER(fill)(fill, x, y, width, fill_channels, r->IM_SUFFIX(line));
}
}
IM_PLIN(im, x, x+width, y, r->IM_SUFFIX(line));
#/code
}
+#if 0
+
+/* for debuggin */
+
static void
-dump_src(const char *note, unsigned char const *src, int width) {
- int i;
- printf("%s - %p/%d\n", note, src, width);
+dump_src(const char *note, unsigned char const *src, i_img_dim width) {
+ i_img_dim i;
+ printf("%s - %p/%" i_DF "\n", note, src, i_DFc(width));
for (i = 0; i < width; ++i) {
printf("%02x ", src[i]);
}
putchar('\n');
}
+#endif
+
#code
+/*
+=item i_render_line(r, x, y, width, source, fill)
+=category Blit tools
+
+Render the given fill with the coverage in C<source[0]> through
+C<source[width-1]>.
+
+=cut
+
+=item i_render_linef(r, x, y, width, source, fill)
+=category Blit tools
+
+Render the given fill with the coverage in C<source[0]> through
+C<source[width-1]>.
+
+=cut
+*/
+
void
-IM_RENDER_LINE(i_render *r, int x, int y, int width, const IM_SAMPLE_T *src,
- IM_COLOR *line, IM_FILL_COMBINE_F combine) {
+IM_RENDER_LINE(i_render *r, i_img_dim x, i_img_dim y, i_img_dim width,
+ const IM_SAMPLE_T *src, IM_COLOR *line,
+ IM_FILL_COMBINE_F combine) {
i_img *im = r->im;
int src_chans = im->channels;
if (combine) {
if (src) {
- int work_width = width;
+ i_img_dim work_width = width;
IM_COLOR *linep = line;
const IM_SAMPLE_T *srcp = src;
int alpha_chan = src_chans - 1;
}
else {
if (src) {
- int work_width = width;
+ i_img_dim work_width = width;
IM_COLOR *srcc = line;
IM_COLOR *destc = r->IM_SUFFIX(line);
static
void
-IM_SUFFIX(render_color_13)(i_render *r, int x, int y, int width,
- unsigned char const *src, i_color const *color) {
+IM_SUFFIX(render_color_13)(i_render *r, i_img_dim x, i_img_dim y,
+ i_img_dim width, unsigned char const *src,
+ i_color const *color) {
i_img *im = r->im;
IM_COLOR *linep = r->IM_SUFFIX(line);
int ch, channels = im->channels;
- int fetch_offset;
+ i_img_dim fetch_offset;
+ int color_alpha = color->channel[im->channels];
#undef STORE_COLOR
#ifdef IM_EIGHT_BIT
#define STORE_COLOR (*color)
#endif
fetch_offset = 0;
- while (fetch_offset < width && *src == 0xFF) {
- *linep++ = STORE_COLOR;
- ++src;
- ++fetch_offset;
+ if (color_alpha == 0xFF) {
+ while (fetch_offset < width && *src == 0xFF) {
+ *linep++ = STORE_COLOR;
+ ++src;
+ ++fetch_offset;
+ }
}
IM_GLIN(im, x+fetch_offset, x+width, y, linep);
while (fetch_offset < width) {
#ifdef IM_EIGHT_BIT
- IM_WORK_T alpha = *src++;
+ IM_WORK_T alpha = *src++ * color_alpha / 255;
#else
- IM_WORK_T alpha = *src++ / 255.0;
+ IM_WORK_T alpha = *src++ * color_alpha / (255.0 * 255.0);
#endif
if (alpha == IM_SAMPLE_MAX)
*linep = STORE_COLOR;
static
void
-IM_SUFFIX(render_color_alpha)(i_render *r, int x, int y, int width,
- unsigned char const *src, i_color const *color) {
+IM_SUFFIX(render_color_alpha)(i_render *r, i_img_dim x, i_img_dim y,
+ i_img_dim width, unsigned char const *src,
+ i_color const *color) {
IM_COLOR *linep = r->IM_SUFFIX(line);
int ch;
int alpha_channel = r->im->channels - 1;
- int fetch_offset;
+ i_img_dim fetch_offset;
+ int color_alpha = color->channel[alpha_channel];
#undef STORE_COLOR
#ifdef IM_EIGHT_BIT
#define STORE_COLOR (*color)
#endif
fetch_offset = 0;
- while (fetch_offset < width && *src == 0xFF) {
- *linep++ = STORE_COLOR;
- ++src;
- ++fetch_offset;
+ if (color->channel[alpha_channel] == 0xFF) {
+ while (fetch_offset < width && *src == 0xFF) {
+ *linep++ = STORE_COLOR;
+ ++src;
+ ++fetch_offset;
+ }
}
IM_GLIN(r->im, x+fetch_offset, x+width, y, linep);
while (fetch_offset < width) {
#ifdef IM_EIGHT_BIT
- IM_WORK_T src_alpha = *src++;
+ IM_WORK_T src_alpha = *src++ * color_alpha / 255;
#else
- IM_WORK_T src_alpha = *src++ / 255.0;
+ IM_WORK_T src_alpha = *src++ * color_alpha / (255.0 * 255.0);
#endif
if (src_alpha == IM_SAMPLE_MAX)
*linep = STORE_COLOR;
static void
IM_SUFFIX(combine_line_alpha)(IM_COLOR *out, IM_COLOR const *in,
- int channels, int count) {
+ int channels, i_img_dim count) {
int ch;
int alpha_channel = channels - 1;
static void
IM_SUFFIX(combine_line_noalpha)
- (IM_COLOR *out, IM_COLOR const *in, int channels, int count) {
+ (IM_COLOR *out, IM_COLOR const *in, int channels, i_img_dim count) {
int ch;
while (count) {
static void
IM_SUFFIX(combine_line_alpha_na)(IM_COLOR *out, IM_COLOR const *in,
- int channels, int count) {
+ int channels, i_img_dim count) {
int ch;
int alpha_channel = channels - 1;
}
static void
-IM_SUFFIX(combine_line)(IM_COLOR *out, IM_COLOR const *in, int channels, int count) {
+IM_SUFFIX(combine_line)(IM_COLOR *out, IM_COLOR const *in, int channels, i_img_dim count) {
if (channels == 2 || channels == 4)
IM_SUFFIX(combine_line_alpha)(out, in, channels, count);
else
}
static void
-IM_SUFFIX(combine_line_na)(IM_COLOR *out, IM_COLOR const *in, int channels, int count) {
+IM_SUFFIX(combine_line_na)(IM_COLOR *out, IM_COLOR const *in, int channels, i_img_dim count) {
if (channels == 2 || channels == 4)
IM_SUFFIX(combine_line_alpha_na)(out, in, channels, count);
else
IM_SUFFIX(combine_line_noalpha)(out, in, channels, count);
}
-static void IM_SUFFIX(combine_alphablend)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_mult)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_dissolve)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_add)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_subtract)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_diff)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_darken)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_lighten)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_hue)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_sat)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_value)(IM_COLOR *, IM_COLOR *, int, int);
-static void IM_SUFFIX(combine_color)(IM_COLOR *, IM_COLOR *, int, int);
+static void IM_SUFFIX(combine_alphablend)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_mult)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_dissolve)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_add)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_subtract)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_diff)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_darken)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_lighten)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_hue)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_sat)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_value)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
+static void IM_SUFFIX(combine_color)(IM_COLOR *, IM_COLOR *, int, i_img_dim);
static const IM_FILL_COMBINE_F IM_SUFFIX(combines)[] =
{
static void
-IM_SUFFIX(combine_alphablend)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_alphablend)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
IM_SUFFIX(combine_line)(out, in, channels, count);
}
Dc' = Sc.Sa.Dc + Dc.(1 - Sa)
*/
static void
-IM_SUFFIX(combine_mult)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_mult)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
int ch;
IM_COLOR *inp = in;
IM_COLOR *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
int color_channels = i_color_channels(channels);
if (i_has_alpha(channels)) {
}
static void
-IM_SUFFIX(combine_dissolve)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_dissolve)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
int color_channels = i_color_channels(channels);
int ch;
*/
static void
-IM_SUFFIX(combine_add)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_add)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
int ch;
int color_channels = i_color_channels(channels);
- int work_count = count;
+ i_img_dim work_count = count;
IM_COLOR *inp = in;
IM_COLOR *outp = out;
channel to apply that to the target.
*/
static void
-IM_SUFFIX(combine_subtract)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_subtract)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
int ch;
IM_COLOR const *inp = in;
IM_COLOR *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
int color_channels = i_color_channels(channels);
if (i_has_alpha(channels)) {
Da' = Sa + Da - Sa.Da
*/
static void
-IM_SUFFIX(combine_diff)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_diff)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
int ch;
IM_COLOR const *inp = in;
IM_COLOR *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
int color_channels = i_color_channels(channels);
if (i_has_alpha(channels)) {
*/
static void
IM_SUFFIX(combine_darken)(IM_COLOR *out, IM_COLOR *in, int channels,
- int count) {
+ i_img_dim count) {
int ch;
IM_COLOR const *inp = in;
IM_COLOR *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
int color_channels = i_color_channels(channels);
if (i_has_alpha(channels)) {
}
static void
-IM_SUFFIX(combine_lighten)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_lighten)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
int ch;
IM_COLOR const *inp = in;
IM_COLOR *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
int color_channels = i_color_channels(channels);
if (i_has_alpha(channels)) {
#endif
static void
-IM_SUFFIX(combine_hue)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_hue)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
if (channels > 2) {
IM_COLOR *inp = in;
IM_COLOR const *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
if (i_has_alpha(channels)) {
while (work_count--) {
}
static void
-IM_SUFFIX(combine_sat)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_sat)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
if (channels > 2) {
IM_COLOR *inp = in;
IM_COLOR const *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
while (work_count--) {
IM_COLOR c = *inp;
}
static void
-IM_SUFFIX(combine_value)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_value)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
if (channels > 2) {
IM_COLOR *inp = in;
IM_COLOR const *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
while (work_count--) {
IM_COLOR c = *inp;
}
static void
-IM_SUFFIX(combine_color)(IM_COLOR *out, IM_COLOR *in, int channels, int count) {
+IM_SUFFIX(combine_color)(IM_COLOR *out, IM_COLOR *in, int channels, i_img_dim count) {
if (channels > 2) {
IM_COLOR *inp = in;
IM_COLOR const *outp = out;
- int work_count = count;
+ i_img_dim work_count = count;
while (work_count--) {
IM_COLOR c = *inp;