// "Invert all LUTs"
// Converts all LUTs in a multi-channel image between
// inverted and non inverted and switches the
// composite rendering mode accordingly.
// !!Only works with linear LUTs (one primary color). 
// Author: Kevin Terretaz

  requires("1.53o");
  getDimensions(width, height, channels, slices, frames);

  // Are the LUTs single color and linear?
  if (!is("Inverting LUT")) {
     for (c=1; c<=channels; c++) {
        Stack.setChannel(c);
        getLut(reds,greens,blues);
        linearR = true;
        linearG = true;
        linearB = true;
        zeroR = true;
        zeroG = true;
        zeroB = true;
        for (i=0; i<255; i++) {
           if ((reds[i+1]-reds[i])!=1) linearR=false;
           if ((greens[i+1]-greens[i])!=1) linearG=false;
           if ((blues[i+1]-blues[i])!=1) linearB=false;
           if (reds[i]!=0) zeroR=false;
           if (greens[i]!=0) zeroG=false;
           if (blues[i]!=0) zeroB=false;
        }
        if ((linearR+linearG+linearB+zeroR+zeroG+zeroB)!=3)
          exit;
     }
  }

  REDS = newArray(256);
  GREENS = newArray(256);
  BLUES = newArray(256);
  for (c=1; c<=channels; c++) {
      Stack.setChannel(c);
      getLut(reds,greens,blues);
      RED=reds[255]; GREEN=greens[255]; BLUE=blues[255];
      if (is("Inverting LUT")) {
          for (i=0; i<256; i++) { 
              REDS[i]   = (RED/256)*(i+1);
              GREENS[i] = (GREEN/256)*(i+1);
              BLUES[i]  = (BLUE/256)*(i+1);
          }
          setLut(REDS, GREENS, BLUES);
          if (RED+GREEN+BLUE == 0)
             run("Grays");
      } else {
         //make inverted LUT
         for (i=0; i<256; i++) {
              REDS[i]   = 255-(((255-RED)/256)*i);
              GREENS[i] = 255-(((255-GREEN)/256)*i);
              BLUES[i]  = 255-(((255-BLUE)/256)*i);
          }
          setLut(REDS, GREENS, BLUES);
          if (RED+GREEN+BLUE == 765) {
             run("Grays"); 
             run("Invert LUT");
         }
      }
  }

  Stack.setChannel(1);
  // CompositeProjection mode switch :
  mode = Property.get("CompositeProjection");
  if (is("Inverting LUT")&&(mode=="Min"||mode=="Invert"))
     ; // do nothing
  else if (!is("Inverting LUT")&&(mode=="Sum"||mode=="Max"))
     ; // do nothing
  else if (mode=="Invert")
     Property.set("CompositeProjection", "Sum");
  else if (mode=="Min")
     Property.set("CompositeProjection", "Max");
  else if (mode=="Max")
     Property.set("CompositeProjection", "Min");
  else // if Composite Sum
     Property.set("CompositeProjection", "Invert"); 
  updateDisplay();

