# PixelIop

> The PixelIop class provides a more specialized version of Iop that provides certain boilerplate code, given certain assumptions. PixelIop is intended for ops that are not spatial in any way - each pixel in the output depends upon the pixel at the same coordinates in the input, and no other pixels. Examples of Ops that might be implemented as PixelIops could include Gain or Desaturate.

> PixelIop varies from Iop by having two new pure virtual calls that the plugin must implement. These are:

>     virtual void in_channels(int input, ChannelSet& mask) const = 0;
>     virtual void pixel_engine(const Row &in, int y, int x, int r, ChannelMask, Row &);

> in_channels is called by the PixelIop’s definition of _request, for each input. It passes the input number as /input/ and a reference to a ChannelSet as /mask/. This ChannelSet is initialized with the channels that have been requested - in_channels should fill in any other channels that are needed (or remove those that are unnecessary) on the given input. For example, a simple Desaturate would implement in_channels like so:

>     virtual void in_channels(int input, ChannelSet& mask) const
>     {
>       if (mask.contains(Mask_RGB))
>         mask += Mask_RGB;
>     }

> That is, if any of the red, green, or blue channels have been requested, it needs to request all of them from its input.

> The pixel_engine function is called with the row from the input already fetched with the correct channels from in_channels. Generally, the output row and the input row are actually the same Row, but this should not be relied upon. A simple implementation of pixel_engine that merely multiples all the pixels by 0.5 is as follows:

>     virtual void pixel_engine(const Row &in, int y, int l, int r, ChannelMask channels, Row& out)
>     {
>       foreach(z, channels) {
>         const float* inptr = in[z];
>         float* outptr = out.writable(z);
>         for (int x = l; x < r; x++) {
>           outptr[x] = inptr[x] * 0.5;
>         }
>       }
>     }