From BlenderWiki

Jump to: navigation, search
Note: This is an archived version of the Blender Developer Wiki. The current and active wiki is available on wiki.blender.org.

How to tell how many strips are connected to a sequence plugin

  • No matter how many strips are connected to a plugin, blender will always have a valid pointer to *ibuf1, *ibuf2, & *use.  This is to keep blender from crashing if a plugin fails to properly detect the number of inputs and tries to access a non existing input  strip.
  • There is no need to test for ibuf1, there is always at least 1 ibuf connected to a plugin.  You will get an error if you try to add a plugin without at least 1 strip selected .
  • This means that if you want to see if there is a 3rd strip, if(use) will always be true even if there is actually only 1 strip connected to the plugin.  What actually happens is that if there is only 1 strip connected to the plugin, blender points *ibuf2 & *use to *ibuf1. and if there are 2 strips connected, *use points to *ibuf2.
  • The way to tell how many strips are actually connected to a plugin is to test if the pointers are equal:
if(ibuf1==ibuf2) strips =1;
else if(ibuf2==use) strips=2;
else strips =3;

How to tell if a plugin is dealing with char or float buffers

  • A sequence plugin needs to be able to deal with either char buffers (normal 32bit rgba, 8 bits per channel, range 0->255) or float buffers (128bits rgba, 32bits per channel, range 0.0->1.0 usually but values can be outside this range).  This means that you need to have code that deals with either case.  In most cases, the image buffer will be a char type (jpeg, png, avi, etc... ) but if any of the inputs are float ( scene, openexr, or any other float image types), any char buffers will be converted and the image buffers will all be float.
  • The best way to tell if your image buffers are char or float is just to test to see if *out has char (out->rect) or float (out->rect_float) buffers:
if(out->rect){ /*or if(!out->rect_float) */

      /* code to work with char buffers */

}

else {

     /* code to work with float buffers */

}

Working with char buffers

Actually, it is interesting to note that the char buffer is actually defined as an 32 bit unsigned int... This is handy if you are just going to copy a pixel from one of the input strips to *out because it copies all 4 char channels at once:

unsigned int *src1= ibuf1->rect; 

unsigned int *dest= out->rect; 

int ii, totpix= sx*sy; 

for(ii=0;ii<totpix;ii++) dest[ii] = src1[ii]; 

will copy *ibuf1 to *out

but in most cases, you are going to do something to one or more of the individual color channels... If you use an integer pointer, and it's a little endian machine, it can lead to code like this:

/* this will invert the red, green, and blue channels */

unsigned int *src1= ibuf1->rect;
unsigned int *dest= out->rect;
unsigned int red, green, blue, alpha;
int ii, totpix= sx*sy; 

for(ii=0;ii<totpix;ii++){
     red = src1[ii]& 0x000000FF;
     green = (src1[ii]& 0x0000FF00)>>8;
     blue = (src1[ii]& 0x00FF0000)>>16;
     alpha = (src1[ii]& 0xFF000000)>>24;
     red = 255 - red;
     green = 255 - green;
     blue = 255 - blue;
     dest[ii] = red | green<<8 | blue<<16 | alpha<<24;;
}

Note: in a little endian machine, RGBA bytes are stored in reverse order in memory...The alpha channel is the 1st 8 bits, the blue channel is the 2nd 8 bits, the green channel is the 3rd 8 bits, and the red channel is the 4th 8 bits.  I believe blender keeps track of the endianess of the processor you are using so it's coded the same way, but I'm not sure...

Pretty confusing heh?  In this case, it's much easier and gives you much more readable code if you just cast the buffer to a char pointer:

/* this will invert the red, green, and blue channels */

unsigned char *src1 = (unsigned char *) ibuf1->rect;
unsigned char *dest = (unsigned char *) out->rect;
int ii, totops= sx*sy*4;  /* 4 chars per pixel */

for(ii=0; ii<totops; ii+=4){
     dest[ii] = 255 - src1[ii];  /*red channel*/
     dest[ii+1] = 255 - src1[ii+1];  /*green channel*/
     dest[ii+2] = 255 - src1[ii+2];  /*blue channel*/
     dest[ii+3] = src1[ii+3];   /*alpha channel*/
}

note how much easier this is to code and understand