LUT#

#include <stdio.h>
#include <stdlib.h>
#include "ItalaApiC/ItalaC.h"

ItalaError ErrorManager(ItalaError e) {
  size_t sizeMessage = 255;
  char* message = (char*)malloc(sizeof(char) * sizeMessage);
  ERR_GetLastErrorMessage(message, &sizeMessage);
  printf("\nITALA ERROR (%d):\t%s, %zu char", ERR_GetLastErrorCode(), message, sizeMessage);
  free(message);
  return e;
}

int main(int argc, char** argv) {
  printf("***** LUT example started. *****\n");
  ItalaError error = ItalaErrorSuccess;

  error = SYS_Initialize();
  if (error) return ErrorManager(error);

  size_t devicesInfoSize = 0;
  error = SYS_EnumerateDevices(700);
  if (error) return ErrorManager(error);
  error = SYS_GetDeviceCount(&devicesInfoSize);
  if (error) return ErrorManager(error);
  if (devicesInfoSize == 0) {
    printf("No devices found. Example canceled.\n");
    return ItalaErrorError;
  }
  DeviceInfo deviceInfo;
  error = SYS_GetDeviceByIndex(0, &deviceInfo);
  if (error) return ErrorManager(error);
  if (deviceInfo.AccessStatus != AvailableReadWrite) {
    printf("Target device is unaccessible in RW mode. Example canceled.\n");
    return ItalaErrorError;
  }

  H_DEVICE hDevice = NULL;
  error = SYS_CreateDevice(deviceInfo, &hDevice);
  if (error) return ErrorManager(error);
  printf("First device found is initialized.\n\n");
  printf("Configuring the LUT...\n");

  H_NODEMAP hNodeMap = NULL;
  error = DEV_GetNodeMap(hDevice, &hNodeMap);
  if (error) return ErrorManager(error);

  // Sets the LUT mode. In this case, the LUT is applied to the image luminance.
  H_NODE hNodeLUTSelector = NULL;
  error = NODEMAP_GetNode(hNodeMap, "LUTSelector", &hNodeLUTSelector);
  if (error) return ErrorManager(error);
  bool isWritable = false;
  error = IsNodeWritable(hNodeLUTSelector, &isWritable);
  if (error) return ErrorManager(error);
  if (!isWritable) {
    printf("Unable to select the LUT mode. Aborting.\n");
    return ItalaErrorError;
  }
  error = NODE_FromString(hNodeLUTSelector, "Luminance");
  if (error) ErrorManager(error);

  // Every different luminance value of the image pixel is also an index of
  // the LUT. This way, it's possible to map every luminance value by iterating
  // through the indexes.
  H_NODE hNodeLUTIndex = NULL;
  error = NODEMAP_GetNode(hNodeMap, "LUTIndex", &hNodeLUTIndex);
  if (error) return ErrorManager(error);
  isWritable = false;
  error = IsNodeWritable(hNodeLUTIndex, &isWritable);
  if (error) return ErrorManager(error);
  if (!isWritable) {
    printf("Unable to configure the LUT index. Aborting.\n");
    return ItalaErrorError;
  }
  int64_t maxIndex = 0;
  error = NODE_IntegerGetMax(hNodeLUTIndex, &maxIndex);
  if (error) return ErrorManager(error);
  int64_t indexInc = 0;
  error = NODE_IntegerGetInc(hNodeLUTIndex, &indexInc);
  if (error) return ErrorManager(error);

  // Gets the maximum and minimum luminance value allowed.
  H_NODE hNodeLUTValue = NULL;
  error = NODEMAP_GetNode(hNodeMap, "LUTValue", &hNodeLUTValue);
  if (error) return ErrorManager(error);
  isWritable = false;
  error = IsNodeWritable(hNodeLUTValue, &isWritable);
  if (error) return ErrorManager(error);
  if (!isWritable) {
    printf("Unable to get the allowed LUT values. Aborting.\n");
    return ItalaErrorError;
  }
  int64_t maxValue = 0;
  error = NODE_IntegerGetMax(hNodeLUTValue, &maxValue);
  if (error) return ErrorManager(error);

  // Iterate through all indexes, i.e. through all possible luminance values and
  // set them their inverted counterpart (e.g. 242 becomes 255 - 242 = 13 in Mono8).
  // The increment is also defined by the LUTIndex node.
  for (int64_t i = 0; i <= maxIndex; i += indexInc) {
    error = NODE_IntegerSetValue(hNodeLUTIndex, i);
    if (error) return ErrorManager(error);
    error = NODE_IntegerSetValue(hNodeLUTIndex, maxValue - i);
    if (error) return ErrorManager(error);
    printf("\t%jd becomes %jd\n", i, maxValue - i);
  }

  printf("\n");
  printf("LUT values set.\n");

  // Once all values are mapped, enable the LUT.
  H_NODE hNodeLUTEnable = NULL;
  error = NODEMAP_GetNode(hNodeMap, "LUTEnable", &hNodeLUTEnable);
  if (error) return ErrorManager(error);
  isWritable = false;
  error = IsNodeWritable(hNodeLUTEnable, &isWritable);
  if (error) return ErrorManager(error);
  if (!isWritable) {
    printf("Unable to activate the LUT. Aborting.\n");
    return ItalaErrorError;
  }
  error = NODE_BooleanSetValue(hNodeLUTEnable, true);
  if (error) return ErrorManager(error);

  printf("LUT functionality enabled\n\n");

  error = DEV_Dispose(hDevice);
  hDevice = NULL;
  if (error) return ErrorManager(error);
  printf("Device instance disposed.\n");

  error = SYS_Dispose();
  if (error) return ErrorManager(error);
  printf("System instance disposed.\n");
  return 0;
}