[FFmpeg-devel] [PATCH] life: add slow_death, life_color and death_color options.
Stefano Sabatini
stefasab at gmail.com
Fri Dec 9 15:24:59 CET 2011
On date Friday 2011-12-09 03:14:03 +0100, Clément Bœsch encoded:
> On Fri, Dec 09, 2011 at 02:47:36AM +0100, Clément Bœsch wrote:
> [...]
> > From 30bb08c858790c43a7af3794f48e14706c53e92f Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <ubitux at gmail.com>
> > Date: Fri, 9 Dec 2011 02:33:01 +0100
> > Subject: [PATCH] life: add mold, mold_color, life_color and death_color
> > options.
> >
>
> New version with minor changes attached. Sorry for the noise.
>
> --
> Clément B.
> From 6385a0a9188a195fb0be260759b81d49d1a84ae6 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <ubitux at gmail.com>
> Date: Fri, 9 Dec 2011 02:33:01 +0100
> Subject: [PATCH] life: add mold, mold_color, life_color and death_color
> options.
>
> ---
> doc/filters.texi | 20 ++++++++
> libavfilter/vsrc_life.c | 114 +++++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 115 insertions(+), 19 deletions(-)
[...]
> /* compute the number of live neighbor cells */
> - n = (pos[NW][0] == -1 || pos[NW][1] == -1 ? 0 : oldbuf[pos[NW][0]*life->w + pos[NW][1]]) +
> - (pos[N ][0] == -1 || pos[N ][1] == -1 ? 0 : oldbuf[pos[N ][0]*life->w + pos[N ][1]]) +
> - (pos[NE][0] == -1 || pos[NE][1] == -1 ? 0 : oldbuf[pos[NE][0]*life->w + pos[NE][1]]) +
> - (pos[W ][0] == -1 || pos[W ][1] == -1 ? 0 : oldbuf[pos[W ][0]*life->w + pos[W ][1]]) +
> - (pos[E ][0] == -1 || pos[E ][1] == -1 ? 0 : oldbuf[pos[E ][0]*life->w + pos[E ][1]]) +
> - (pos[SW][0] == -1 || pos[SW][1] == -1 ? 0 : oldbuf[pos[SW][0]*life->w + pos[SW][1]]) +
> - (pos[S ][0] == -1 || pos[S ][1] == -1 ? 0 : oldbuf[pos[S ][0]*life->w + pos[S ][1]]) +
> - (pos[SE][0] == -1 || pos[SE][1] == -1 ? 0 : oldbuf[pos[SE][0]*life->w + pos[SE][1]]);
> - v = !!(1<<n & (oldbuf[i*life->w + j] ? life->stay_rule : life->born_rule));
> - av_dlog(ctx, "i:%d j:%d live_neighbors:%d cell:%d -> cell:%d\n", i, j, n, oldbuf[i*life->w + j], v);
> - newbuf[i*life->w+j] = v;
> + n = (pos[NW][0] == -1 || pos[NW][1] == -1 ? 0 : oldbuf[pos[NW][0]*life->w + pos[NW][1]] == ALIVE_CELL) +
> + (pos[N ][0] == -1 || pos[N ][1] == -1 ? 0 : oldbuf[pos[N ][0]*life->w + pos[N ][1]] == ALIVE_CELL) +
> + (pos[NE][0] == -1 || pos[NE][1] == -1 ? 0 : oldbuf[pos[NE][0]*life->w + pos[NE][1]] == ALIVE_CELL) +
> + (pos[W ][0] == -1 || pos[W ][1] == -1 ? 0 : oldbuf[pos[W ][0]*life->w + pos[W ][1]] == ALIVE_CELL) +
> + (pos[E ][0] == -1 || pos[E ][1] == -1 ? 0 : oldbuf[pos[E ][0]*life->w + pos[E ][1]] == ALIVE_CELL) +
> + (pos[SW][0] == -1 || pos[SW][1] == -1 ? 0 : oldbuf[pos[SW][0]*life->w + pos[SW][1]] == ALIVE_CELL) +
> + (pos[S ][0] == -1 || pos[S ][1] == -1 ? 0 : oldbuf[pos[S ][0]*life->w + pos[S ][1]] == ALIVE_CELL) +
> + (pos[SE][0] == -1 || pos[SE][1] == -1 ? 0 : oldbuf[pos[SE][0]*life->w + pos[SE][1]] == ALIVE_CELL);
> + v = 1<<n & (oldbuf[i*life->w + j] == ALIVE_CELL ? life->stay_rule : life->born_rule);
> + *newbuf = v ? ALIVE_CELL : *newbuf - (*newbuf != 0);
Maybe a bit too convoluted, possible suggestion:
if (v == ALIVE_CELL) *newbuf = v;
else if (*newbuf) (*newbuf)--;
> + av_dlog(ctx, "i:%d j:%d live_neighbors:%d cell:%d -> cell:%d\n", i, j, n, oldbuf[i*life->w + j], *newbuf);
> + newbuf++;
> }
> }
>
> life->buf_idx = !life->buf_idx;
> }
>
> -static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
> +static void fill_picture_monoblack(AVFilterContext *ctx, AVFilterBufferRef *picref)
> {
> LifeContext *life = ctx->priv;
> uint8_t *buf = life->buf[life->buf_idx];
> @@ -350,7 +391,7 @@ static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
> uint8_t byte = 0;
> uint8_t *p = picref->data[0] + i * picref->linesize[0];
> for (k = 0, j = 0; j < life->w; j++) {
> - byte |= buf[i*life->w+j]<<(7-k++);
> + byte |= (buf[i*life->w+j] == ALIVE_CELL)<<(7-k++);
> if (k==8 || j == life->w-1) {
> k = 0;
> *p++ = byte;
> @@ -360,6 +401,32 @@ static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
> }
> }
>
> +static void fill_picture_rgb(AVFilterContext *ctx, AVFilterBufferRef *picref)
> +{
> + LifeContext *life = ctx->priv;
> + uint8_t *buf = life->buf[life->buf_idx];
> + int i, j;
> +
> + /* fill the output picture with the old grid buffer */
> + for (i = 0; i < life->h; i++) {
> + uint8_t *p = picref->data[0] + i * picref->linesize[0];
> + for (j = 0; j < life->w; j++) {
> + uint8_t v = buf[i*life->w + j];
> + uint8_t *c = v == ALIVE_CELL ? life->life_color : life->death_color;
> + if (life->mold) {
> + int death_age = (0xff - v) * life->mold;
> + *p++ = FFMAX((int)c[0] - death_age, life->mold_color[0]);
> + *p++ = FFMAX((int)c[1] - death_age, life->mold_color[1]);
> + *p++ = FFMAX((int)c[2] - death_age, life->mold_color[2]);
why not a proper interpolation? The above doesn't work if for example death_color < mold_color
double left_energy = (double)(0xff - v) / 256;
*p++ = mold_color[comp] + ((int)death_color[comp] - (int)mold_color[comp]) * left_energy;
For avoiding divisions (not tested):
int left_energy = 0xff - v;
*p++ = ((mold_color[comp]<<8) + ((int)death_color[comp] - (int)mold_color[comp]) * left_energy)>>8;
> + } else {
> + *p++ = c[0];
> + *p++ = c[1];
> + *p++ = c[2];
> + }
AV_WB24(p, c); p += 3;
also you can drop the obfuscating c temporary, and directly use
life/death_color.
[...]
--
FFmpeg = Faithless Faithful Muttering Prodigious Earthshaking Gadget
More information about the ffmpeg-devel
mailing list