convert.c 6.49 KB

#include <unistd.h>
#include <stdio.h>
#include <string.h>

#include <PRimage.h>

#define LINELENGTH 4096

unsigned short **OutputRed, **OutputGreen, **OutputBlue;

char InputBuffer[LINELENGTH];
FILE *InputFile;

char *InputFileName=NULL, *OutputFilePrefix=NULL, *DefaultOutputFilePrefix="t";
char OutputFileName[512];

int SeenHeader       = 0;
int DoneReadingImage = 0;
int CurrentLine      = 0;
int ImageHeight, ImageWidth, ImageBitSize;

int TestNumber, FrameNumber;

char BoardNumber[16];

int NoImageHeadersSeen = 1;
int CurrentImage       = 0;
int FlushImage         = 0;
int AutoIncrement      = 0;

void usage(void)
{
  printf("\nUsage: convert [-i inputasciidump] [-o output.rgb] \n\n");
  exit(1);
}

int getline(char s[], int lim, FILE *source)
{
  int c,i;

  i = 0;
  while (--lim > 0 && (c=getc(source)) != EOF && c != '\n')
     s[i++] = c;
  s[i] = '\0';
  if (c == '\n') i++;
  return(i);
}

void ReadHeader(void)
{
  char foo[2048];

  SeenHeader = 0;

  while (!SeenHeader)
    {      
      getline(InputBuffer, LINELENGTH, InputFile);

      if (feof(InputFile))
	{
	  if (NoImageHeadersSeen)
	    {
	      printf("ERROR, no image header seen \n");
	    }
	  exit(1);
	}

      if (strncmp("START IMAGE", InputBuffer, 11) == 0)
	  {
	    SeenHeader = 1;
	    NoImageHeadersSeen = 0;
	    CurrentImage++;
	  }      

      if (strncmp("EXIT", InputBuffer, 11) == 0)
	  {
	    fprintf(stdout, "Got exit \n");
	    exit(1);
	  }      

    }

  getline(InputBuffer, LINELENGTH, InputFile);
  if (!strncmp("Dimensions", InputBuffer, 10) == 0)
    {
      fprintf(stderr, "ERROR, corrupt header \n");
      exit(1);
    }      

  sscanf(InputBuffer, "%s %d %d %d \n", foo, &ImageWidth, &ImageHeight, &ImageBitSize);

  getline(InputBuffer, LINELENGTH, InputFile);
  sscanf(InputBuffer, "%s %d %d \n", BoardNumber, &TestNumber, &FrameNumber);
}

void MallocArrays(void)
{
    int i;

    OutputRed   = (unsigned short **) malloc(ImageHeight * sizeof(unsigned short *));
    OutputGreen = (unsigned short **) malloc(ImageHeight * sizeof(unsigned short *));
    OutputBlue  = (unsigned short **) malloc(ImageHeight * sizeof(unsigned short *));

    for (i=0; i < ImageHeight; i++)
	{
	    OutputRed[i]   = (unsigned short *)malloc(ImageWidth * sizeof(unsigned short));
	    OutputGreen[i] = (unsigned short *)malloc(ImageWidth * sizeof(unsigned short));
	    OutputBlue[i]  = (unsigned short *)malloc(ImageWidth * sizeof(unsigned short));
	}
}

void Write16BitOutput(int PixelPair, int NumPixelsRead)
{
  OutputRed[CurrentLine][NumPixelsRead+1]   = ((PixelPair >>  0)  & (0x1f << 11)) >> 8;
  OutputGreen[CurrentLine][NumPixelsRead+1] = ((PixelPair >>  0)  & (0x1f <<  6)) >> 3;
  OutputBlue[CurrentLine][NumPixelsRead+1]  = ((PixelPair >>  0)  & (0x1f <<  1)) << 2;
	  
  OutputRed[CurrentLine][NumPixelsRead+0]   = ((PixelPair >> 16)  & (0x1f << 11)) >> 8;
  OutputGreen[CurrentLine][NumPixelsRead+0] = ((PixelPair >> 16)  & (0x1f <<  6)) >> 3;
  OutputBlue[CurrentLine][NumPixelsRead+0]  = ((PixelPair >> 16)  & (0x1f <<  1)) << 2;
}

void Write32BitOutput(int Pixel, int NumPixelsRead)
{
  OutputRed[CurrentLine][NumPixelsRead]   = (Pixel >> 24)  & 0xff;
  OutputGreen[CurrentLine][NumPixelsRead] = (Pixel >> 16)  & 0xff;
  OutputBlue[CurrentLine][NumPixelsRead]  = (Pixel >>  8)  & 0xff;
}

int ParseInputLine(void)
{
  char *TokenPointer;
  int NumPixelsRead = 0;
  int PixelData;
  
  TokenPointer = strtok(InputBuffer, " ");

  while(TokenPointer)
    {
      sscanf(TokenPointer, "0x%x", &PixelData);

      if (ImageBitSize == 16)
	{
	  Write16BitOutput(PixelData, NumPixelsRead);
	  NumPixelsRead += 2;
	}
      else if (ImageBitSize == 32)
	{
	  Write32BitOutput(PixelData, NumPixelsRead);
	  NumPixelsRead++;
	}
      else
	{
	  fprintf(stderr, "ERROR, bit size %d not supported \n", ImageBitSize);
	  return 1;
	}
       
     TokenPointer = strtok(NULL, " ");      
    }

  if (NumPixelsRead != ImageWidth)
    {
      fprintf(stderr, "ERROR, corrupted scan line %d \n", CurrentLine);
      fprintf(stderr, "%d Pixels read in line %d \n", NumPixelsRead, CurrentLine);
      return 1;
    }
  
  CurrentLine++;
}

void ReadImage(void)
{
  DoneReadingImage = 0;
  CurrentLine      = 0;
  FlushImage       = 0;
  
  while (!DoneReadingImage && !FlushImage)
    {      
      getline(InputBuffer, LINELENGTH, InputFile);

      if (feof(InputFile))
	{
	  printf("ERROR, image truncated \n");
	  exit(1);
	}

      if (strncmp("END IMAGE", InputBuffer, 11) == 0)
	  {
	    DoneReadingImage = 1;
	    return;
	  }

      FlushImage = ParseInputLine();
    }
}

void WriteRGBFile(void)
{
    IMAGE *image;
    int i;

    if (OutputFileName == NULL) return;

    if ((image = iopen(OutputFileName, "w", RLE(1), 3, ImageWidth, ImageHeight, 3)) == NULL)
	{
	    fprintf(stderr, "Error, could not open output file %s \n", OutputFileName);
	    exit(1);
	}

    fprintf(stdout, "Opening file %s \n", OutputFileName);
    
    for (i = 0; i < ImageHeight ; i++)
	{
	    putrow(image, OutputRed[i],   ImageHeight - 1 - i, 0);
	    putrow(image, OutputGreen[i], ImageHeight - 1 - i, 1);
	    putrow(image, OutputBlue[i],  ImageHeight - 1 - i, 2);
	}

    iclose(image);
}

void WriteOutputFileName(void)
{
  if (OutputFilePrefix == NULL)
    {
      fprintf(stderr, "WARNING, no file prefix specified, using `%s' \n",
	      DefaultOutputFilePrefix);
      
      OutputFilePrefix = strdup(DefaultOutputFilePrefix);
    }

  sprintf(OutputFileName , "%s_%s_%.2d_%.2d.rgb", 
			   OutputFilePrefix, BoardNumber, TestNumber, FrameNumber); 

  if (AutoIncrement) FrameNumber++;
}

void Cleanup(void)
{  
  fclose(InputFile);
  exit(0);
}

void OpenInputFile(void)
{
    if (InputFileName == NULL)
      {
	InputFile = stdin;
      }
    else
      {
	if ((InputFile = fopen(InputFileName, "r")) == NULL)
	  {
	    fprintf(stderr, "Error, could not open file %s \n", InputFileName);
	    exit(1);
	  }
      }       
}

void ParseArgs(int argc, char **argv)
{
    int c;
    extern char *optarg;
    extern int optind;
    char *ofile = NULL;

    while ((c = getopt(argc, argv, "i:o:a")) != EOF)
	switch (c)
	    {
	    case 'a':
	      AutoIncrement = 1;
	      break;
	    case 'i':
	      InputFileName = strdup(optarg);
	      break;
	    case 'o':
	      OutputFilePrefix = strdup(optarg);
	      break;
	    case '?':
	      usage();
	      break;		
	    }    
}

main(int argc, char **argv)
{
  ParseArgs(argc, argv);
  OpenInputFile();
  
  while (!feof(InputFile))
    {
      ReadHeader();
      WriteOutputFileName();
      MallocArrays();
      ReadImage();
      if (!FlushImage) WriteRGBFile();
    }
  
  Cleanup();
}