[FFmpeg-devel] [PATCH] colorlevels filter
Clément Bœsch
ubitux at gmail.com
Thu May 23 13:42:11 CEST 2013
On Tue, May 14, 2013 at 05:19:19PM +0000, Paul B Mahol wrote:
[...]
> +static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> +{
> + AVFilterContext *ctx = inlink->dst;
> + ColorLevelsContext *s = ctx->priv;
> + AVFilterLink *outlink = ctx->outputs[0];
> + const int step = s->step;
> + AVFrame *out;
> + int x, y, i;
> +
> + if (av_frame_is_writable(in)) {
> + out = in;
> + } else {
> + out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
> + if (!out) {
> + av_frame_free(&in);
> + return AVERROR(ENOMEM);
> + }
> + av_frame_copy_props(out, in);
> + }
> +
> + switch (s->bpp) {
> + case 1:
> + for (i = 0; i < s->nb_comp; i++) {
> + Range *r = &s->range[i];
> + const uint8_t offset = s->rgba_map[i];
> + const uint8_t *srcrow = in->data[0];
> + uint8_t *dstrow = out->data[0];
> + int imin = round(r->in_min * UINT8_MAX);
> + int imax = round(r->in_max * UINT8_MAX);
> + int omin = round(r->out_min * UINT8_MAX);
> + int omax = round(r->out_max * UINT8_MAX);
> + double coeff;
> +
> + if (imin < 0) {
> + imin = UINT8_MAX;
> + for (y = 0; y < inlink->h; y++) {
> + const uint8_t *src = srcrow;
> +
> + for (x = 0; x < s->linesize; x += step)
> + imin = FFMIN(imin, src[x + offset]);
> + srcrow += in->linesize[0];
> + }
> + }
> + if (imax < 0) {
> + srcrow = in->data[0];
> + imax = 0;
> + for (y = 0; y < inlink->h; y++) {
> + const uint8_t *src = srcrow;
> +
> + for (x = 0; x < s->linesize; x += step)
> + imax = FFMAX(imax, src[x + offset]);
> + srcrow += in->linesize[0];
> + }
> + }
> +
> + srcrow = in->data[0];
> + coeff = (omax - omin) / (double)(imax - imin);
> + for (y = 0; y < inlink->h; y++) {
> + const uint8_t *src = srcrow;
> + uint8_t *dst = dstrow;
> +
> + for (x = 0; x < s->linesize; x += step)
> + dst[x + offset] = av_clip_uint8((src[x + offset] - imin) * coeff + omin);
> + dstrow += out->linesize[0];
> + srcrow += in->linesize[0];
> + }
> + }
> + break;
> + case 2:
> + for (i = 0; i < s->nb_comp; i++) {
> + Range *r = &s->range[i];
> + const uint8_t offset = s->rgba_map[i];
> + const uint8_t *srcrow = in->data[0];
> + uint8_t *dstrow = out->data[0];
> + int imin = round(r->in_min * UINT16_MAX);
> + int imax = round(r->in_max * UINT16_MAX);
> + int omin = round(r->out_min * UINT16_MAX);
> + int omax = round(r->out_max * UINT16_MAX);
> + double coeff;
> +
> + if (imin < 0) {
> + imin = UINT16_MAX;
> + for (y = 0; y < inlink->h; y++) {
> + const uint16_t *src = (const uint16_t *)srcrow;
> +
> + for (x = 0; x < s->linesize; x += step)
> + imin = FFMIN(imin, src[x + offset]);
> + srcrow += in->linesize[0];
> + }
> + }
> + if (imax < 0) {
> + srcrow = in->data[0];
> + imax = 0;
> + for (y = 0; y < inlink->h; y++) {
> + const uint16_t *src = (const uint16_t *)srcrow;
> +
> + for (x = 0; x < s->linesize; x += step)
> + imax = FFMAX(imax, src[x + offset]);
> + srcrow += in->linesize[0];
> + }
> + }
> +
> + srcrow = in->data[0];
> + coeff = (omax - omin) / (double)(imax - imin);
> + for (y = 0; y < inlink->h; y++) {
> + const uint16_t *src = (const uint16_t*)srcrow;
> + uint16_t *dst = (uint16_t *)dstrow;
> +
> + for (x = 0; x < s->linesize; x += step)
> + dst[x + offset] = av_clip_uint16((src[x + offset] - imin) * coeff + omin);
> + dstrow += out->linesize[0];
> + srcrow += in->linesize[0];
> + }
> + }
> + }
Don't you need to do something with the alpha channel if in != out?
[...]
Rest should be OK, but I'm curious about the documentation.
--
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130523/483ed323/attachment.asc>
More information about the ffmpeg-devel
mailing list