/* -*- C++ -*-
 * File: 4channels.cpp
 * Copyright 2008-2025 LibRaw LLC (info@libraw.org)
 * Created: Mon Feb 09, 2009
 *
 * LibRaw sample
 * Generates 4 TIFF file from RAW data, one file per channel
 *

LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:

1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).

2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).


 */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "third_party/libraw/libraw/libraw.h"

#ifndef LIBRAW_WIN32_CALLS
#include <netinet/in.h>
#else
#include <winsock2.h>
#endif

#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#endif

int main(int ac, char *av[])
{
  int i, ret;
  int autoscale = 0, black_subtraction = 1, use_gamma = 0;
  char outfn[1024];

  LibRaw RawProcessor;
  if (ac < 2)
  {
  usage:
    printf("4channels - LibRaw %s sample. %d cameras supported\n"
           "Usage: %s [-s N] [-g] [-A] [-B] raw-files....\n"
           "\t-s N - select Nth image in file (default=0)\n"
           "\t-g - use gamma correction with gamma 2.2 (not precise,use for "
           "visual inspection only)\n"
           "\t-A - autoscaling (by integer factor)\n"
           "\t-B - no black subtraction\n",
           LibRaw::version(), LibRaw::cameraCount(), av[0]);
    return 0;
  }

#define P1 RawProcessor.imgdata.idata
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define T RawProcessor.imgdata.thumbnail
#define P2 RawProcessor.imgdata.other
#define OUT RawProcessor.imgdata.params
#define OUTR RawProcessor.imgdata.rawparams

  OUT.output_bps = 16;
  OUT.output_tiff = 1;
  OUT.user_flip = 0;
  OUT.no_auto_bright = 1;
  OUT.half_size = 1;

  for (i = 1; i < ac; i++)
  {
    if (av[i][0] == '-')
    {
      if (av[i][1] == 's' && av[i][2] == 0)
      {
        i++;
        OUTR.shot_select = av[i] ? atoi(av[i]) : 0;
      }
      else if (av[i][1] == 'g' && av[i][2] == 0)
        use_gamma = 1;
      else if (av[i][1] == 'A' && av[i][2] == 0)
        autoscale = 1;
      else if (av[i][1] == 'B' && av[i][2] == 0)
      {
        black_subtraction = 0;
      }
      else
        goto usage;
      continue;
    }
    if (!use_gamma)
      OUT.gamm[0] = OUT.gamm[1] = 1;

    int c;
    printf("Processing file %s\n", av[i]);
    if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret));
      continue; // no recycle b/c open file will recycle itself
    }
    if (P1.is_foveon)
    {
      printf("Cannot process Foveon image %s\n", av[i]);
      continue;
    }
    if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
      continue;
    }
    RawProcessor.raw2image();
    if (black_subtraction)
    {
      RawProcessor.subtract_black();
    }

    if (autoscale)
    {
      unsigned max = 0, scale = 1;
      for (int j = 0; j < S.iheight * S.iwidth; j++)
        for (int c = 0; c < 4; c++)
          if (max < RawProcessor.imgdata.image[j][c])
            max = RawProcessor.imgdata.image[j][c];
      if (max > 0 && max < 1 << 15)
      {
        scale = (1 << 16) / max;
        printf("Scaling with multiplier=%d (max=%d)\n", scale, max);
        for (int j = 0; j < S.iheight * S.iwidth; j++)
          for (c = 0; c < 4; c++)
            RawProcessor.imgdata.image[j][c] *= scale;
      }
      printf("Black level (scaled)=%d\n", C.black * scale);
    }
    else
      printf("Black level (unscaled)=%d\n", C.black);

    // hack to make dcraw tiff writer happy
    int isrgb = (P1.colors == 4 ? 0 : 1);
    P1.colors = 1;
    S.width = S.iwidth;
    S.height = S.iheight;

    for (int layer = 0; layer < 4; layer++)
    {
      if (layer > 0)
      {
        for (int rc = 0; rc < S.iheight * S.iwidth; rc++)
          RawProcessor.imgdata.image[rc][0] =
              RawProcessor.imgdata.image[rc][layer];
      }
      char lname[8];
      if (isrgb)
      {
        snprintf(lname, 7, "%c", ((char *)("RGBG"))[layer]);
        if (layer == 3)
          strcat(lname, "2");
      }
      else
        snprintf(lname, 7, "%c", ((char *)("GCMY"))[layer]);

      if (OUTR.shot_select)
        snprintf(outfn, sizeof(outfn), "%s-%d.%s.tiff", av[i], OUTR.shot_select,
                 lname);
      else
        snprintf(outfn, sizeof(outfn), "%s.%s.tiff", av[i], lname);

      printf("Writing file %s\n", outfn);
      if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
        fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret));
    }
  }
  return 0;
}
