text: /*=========================================================================
   *
   *  Copyright NumFOCUS
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *         http://www.apache.org/licenses/LICENSE-2.0.txt
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   *=========================================================================*/
  
  //  Software Guide : BeginLatex
  //
  //  RGB images are commonly used for representing data acquired from cryogenic
  //  sections, optical microscopy and endoscopy. This example illustrates how
  //  to read RGB color images from a set of files containing individual 2D
  //  slices in order to compose a 3D color dataset. Then we will save it into a
  //  single 3D file, and finally save it again as a set of 2D slices with other
  //  names.
  //
  //  This requires the following headers as shown.
  //
  //  \index{itk::RGBPixel!Image}
  //  \index{RGB!writing Image}
  //  \index{RGB!reading Image}
  //
  //  Software Guide : EndLatex
  
  // Software Guide : BeginCodeSnippet
  #include "itkRGBPixel.h"
  #include "itkImage.h"
  #include "itkImageSeriesReader.h"
  #include "itkImageSeriesWriter.h"
  #include "itkNumericSeriesFileNames.h"
  #include "itkPNGImageIO.h"
  // Software Guide : EndCodeSnippet
  
  
  int
  main(int argc, char ** argv)
  {
    // Verify the number of parameters in the command line
    if (argc < 4)
    {
      std::cerr << "Usage: " << std::endl;
      std::cerr << argv[0] << "first last  outputRGBImageFile " << std::endl;
      return EXIT_FAILURE;
    }
  
  
    // Software Guide : BeginLatex
    //
    // The \doxygen{RGBPixel} class is templated over the type used to
    // represent each one of the Red, Green and Blue components. A typical
    // instantiation of the RGB image class might be as follows.
    //
    //  \index{itk::RGBPixel!Instantiation}
    //
    // Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    using PixelType = itk::RGBPixel<unsigned char>;
    constexpr unsigned int Dimension = 3;
  
    using ImageType = itk::Image<PixelType, Dimension>;
    // Software Guide : EndCodeSnippet
  
    // Software Guide : BeginLatex
    //
    // The image type is used as a template parameter to instantiate
    // the series reader and the volumetric writer.
    //
    // \index{itk::ImageSeriesReader!RGB Image}
    // \index{itk::ImageFileWriter!RGB Image}
    //
    // Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    using SeriesReaderType = itk::ImageSeriesReader<ImageType>;
    using WriterType = itk::ImageFileWriter<ImageType>;
  
    SeriesReaderType::Pointer seriesReader = SeriesReaderType::New();
    WriterType::Pointer       writer = WriterType::New();
    // Software Guide : EndCodeSnippet
  
  
    const unsigned int first = std::stoi(argv[1]);
    const unsigned int last = std::stoi(argv[2]);
  
    const char * outputFilename = argv[3];
  
    // Software Guide : BeginLatex
    //
    // We use a NumericSeriesFileNames class in order to generate the filenames
    // of the slices to be read. Later on in this example we will reuse this
    // object in order to generate the filenames of the slices to be written.
    //
    // Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    using NameGeneratorType = itk::NumericSeriesFileNames;
  
    NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();
  
    nameGenerator->SetStartIndex(first);
    nameGenerator->SetEndIndex(last);
    nameGenerator->SetIncrementIndex(1);
  
    nameGenerator->SetSeriesFormat("vwe%03d.png");
    // Software Guide : EndCodeSnippet
  
    //  Software Guide : BeginLatex
    //
    //  The ImageIO object that actually performs the read process
    //  is now connected to the ImageSeriesReader.
    //
    //  Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    seriesReader->SetImageIO(itk::PNGImageIO::New());
    // Software Guide : EndCodeSnippet
  
    //  Software Guide : BeginLatex
    //
    //  The filenames of the input slices are taken from the names generator and
    //  passed to the series reader.
    //
    //  Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    seriesReader->SetFileNames(nameGenerator->GetFileNames());
    // Software Guide : EndCodeSnippet
  
    // Software Guide : BeginLatex
    //
    // The name of the volumetric output image is passed to the image writer,
    // and we connect the output of the series reader to the input of the
    // volumetric writer.
    //
    // Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    writer->SetFileName(outputFilename);
  
    writer->SetInput(seriesReader->GetOutput());
    // Software Guide : EndCodeSnippet
  
    //  Software Guide : BeginLatex
    //
    //  Finally, execution of the pipeline can be triggered by invoking the
    //  \code{Update()} method in the volumetric writer. This, of course, is
    //  done from inside a try/catch block.
    //
    //  Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    try
    {
      writer->Update();
    }
    catch (const itk::ExceptionObject & excp)
    {
      std::cerr << "Error reading the series " << std::endl;
      std::cerr << excp << std::endl;
    }
    // Software Guide : EndCodeSnippet
  
    // Software Guide : BeginLatex
    //
    // We now proceed to save the same volumetric dataset as a set of slices.
    // This is done only to illustrate the process for saving a volume as a
    // series of 2D individual datasets. The type of the series writer must be
    // instantiated taking into account that the input file is a 3D volume and
    // the output files are 2D images.  Additionally, the output of the series
    // reader is connected as input to the series writer.
    //
    //  Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    using Image2DType = itk::Image<PixelType, 2>;
  
    using SeriesWriterType = itk::ImageSeriesWriter<ImageType, Image2DType>;
  
    SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
  
    seriesWriter->SetInput(seriesReader->GetOutput());
    // Software Guide : EndCodeSnippet
  
    // Software Guide : BeginLatex
    //
    // We now reuse the filename generator in order to produce the list of
    // filenames for the output series. In this case we just need to modify the
    // format of the filename generator. Then, we pass the list of output
    // filenames to the series writer.
    //
    // Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    nameGenerator->SetSeriesFormat("output%03d.png");
  
    seriesWriter->SetFileNames(nameGenerator->GetFileNames());
    // Software Guide : EndCodeSnippet
  
    // Software Guide : BeginLatex
    //
    // Finally we trigger the execution of the series writer from inside a
    // try/catch block.
    //
    // Software Guide : EndLatex
  
    // Software Guide : BeginCodeSnippet
    try
    {
      seriesWriter->Update();
    }
    catch (const itk::ExceptionObject & excp)
    {
      std::cerr << "Error reading the series " << std::endl;
      std::cerr << excp << std::endl;
    }
    // Software Guide : EndCodeSnippet
  
    //  Software Guide : BeginLatex
    //
    //  You may have noticed that apart from the declaration of the
    //  \code{PixelType} there is nothing in this code that is specific to RGB
    //  images. All the actions required to support color images are implemented
    //  internally in the \doxygen{ImageIO} objects.
    //
    // Software Guide : EndLatex
  
    return EXIT_SUCCESS;
  }
  