Logo Search packages:      
Sourcecode: xawtv version File versions  Download package

flt-gamma.c

/*
 * libng filter -- gamma correction
 *
 * (c) 2002 Gerd Knorr <kraxel@bytesex.org>
 *
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>

#include "grab-ng.h"

/* ------------------------------------------------------------------- */

static unsigned char lut[256];
static int g = 100;

static void inline
gamma_bytes(unsigned char *dst, unsigned char *src, int bytes)
{
    while (bytes--)
      *(dst++) = lut[ *(src++) ];
}

static void inline
gamma_native_rgb15(void *d, void *s, int pixels)
{
    unsigned short *dst = d;
    unsigned short *src = s;
    unsigned short r,g,b;

    while (pixels--) {
      r = lut[ ((*src >> 7)  &  0xf8) ] & 0xf8;
      g = lut[ ((*src >> 2)  &  0xf8) ] & 0xf8;
      b = lut[ ((*src << 3)  &  0xf8) ] & 0xf8;
      *dst = (r << 7) | (g << 2) | (b >> 3);
      src++; dst++;
    }
}

static void inline
gamma_native_rgb16(void *d, void *s, int pixels)
{
    unsigned short *dst = d;
    unsigned short *src = s;
    unsigned short r,g,b;

    while (pixels--) {
      r = lut[ ((*src >> 8)  &  0xf8) ] & 0xf8;
      g = lut[ ((*src >> 3)  &  0xfc) ] & 0xfc;
      b = lut[ ((*src << 3)  &  0xf8) ] & 0xf8;
      *dst = (r << 8) | (g << 3) | (b >> 3);
      src++; dst++;
    }
}

/* ------------------------------------------------------------------- */

static void *init(struct ng_video_fmt *out)
{
    /* don't have to carry around status info */
    static int dummy;
    return &dummy;
}

static struct ng_video_buf*
frame(void *handle, struct ng_video_buf *in)
{
    struct ng_video_buf *out;
    unsigned char *dst;
    unsigned char *src;
    unsigned int y,cnt;

    out = ng_malloc_video_buf(&in->fmt, in->fmt.height * in->fmt.bytesperline);
    out->info = in->info;

    dst = out->data;
    src = in->data;
    cnt = in->fmt.width * ng_vfmt_to_depth[in->fmt.fmtid] / 8;
    for (y = 0; y < in->fmt.height; y++) {
      switch (in->fmt.fmtid) {
      case VIDEO_GRAY:
      case VIDEO_BGR24:
      case VIDEO_RGB24:
      case VIDEO_BGR32:
      case VIDEO_RGB32:
          gamma_bytes(dst,src,cnt);
          break;
      case VIDEO_RGB15_NATIVE:
          gamma_native_rgb15(dst,src,in->fmt.width);
          break;
      case VIDEO_RGB16_NATIVE:
          gamma_native_rgb16(dst,src,in->fmt.width);
          break;
      }
      dst += out->fmt.bytesperline;
      src += in->fmt.bytesperline;
    }

    ng_release_video_buf(in);
    return out;
}

static void fini(void *handle)
{
    /* nothing to clean up */
}

/* ------------------------------------------------------------------- */

static void calc_lut(void)
{
    int i,val;
    
    for (i = 0; i < 256; i++) {
      val = 255 * pow((float)i/255, 100.0/g);
      if (val < 0)   val = 0;
      if (val > 255) val = 255;
      lut[i] = val;
    }
}

static int read_attr(struct ng_attribute *attr)
{
    return g;
}

static void write_attr(struct ng_attribute *attr, int value)
{
    g = value;
    calc_lut();
}

/* ------------------------------------------------------------------- */

static struct ng_attribute attrs[] = {
    {
      id:       0,
      name:     "gamma value",
      type:     ATTR_TYPE_INTEGER,
      defval:   100,
      min:      1,
      max:      500,
      points:   2,
      read:     read_attr,
      write:    write_attr,
    },{
      /* end of list */
    }
};

static struct ng_filter filter = {
    name:    "gamma",
    attrs:   attrs,
    fmts:
    (1 << VIDEO_GRAY)         |
    (1 << VIDEO_RGB15_NATIVE) |
    (1 << VIDEO_RGB16_NATIVE) |
    (1 << VIDEO_BGR24)        |
    (1 << VIDEO_RGB24)        |
    (1 << VIDEO_BGR32)        |
    (1 << VIDEO_RGB32),
    init:    init,
    frame:   frame,
    fini:    fini,
};

extern void ng_plugin_init(void);
void ng_plugin_init(void)
{
    calc_lut();
    ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter);
}

Generated by  Doxygen 1.6.0   Back to index