
/*
**
**  TARGA File 'flip' program
**
**  Written by Brian Reed  Copyright 1989
**  This file is provided as a sample for reading TARGA 'type 2' images.
**
**  This program will flip the order of lines in the 24-bit file for
**  better compatability with other 24-bit software.  Specifically, most
**  TARGA files are stored bottom-top, while Opticks images are stored
**  top-bottom.  This is allowable under the TARGA specification,
**  as long as the respective bit in the file header is set.
**  Unfortunately, many TARGA file reading programs ignore this bit,
**  and read images bottom-top regardless of the 'origin' setting.
**
**  This program runs only from the CLI, and requires two parameters.
**  The parameters are the file names for the input and output files.
**  They MUST not be the same file.  This flips only 'uncompressed RGB
**  (type 2)' 24-bit TARGA files.
**
**  -  Error checking (file i/o) could stand to be improved.
**
*/
/*  For the Amiga, you must compile and link this in the 32 bit mode  */


/*  include files  */
#include <stdio.h>

FILE *fopen(), *infile=0, *outfile=0;
char output[82], input[82];
int  pixels_x, pixels_y, offset_x, offset_y, file_id_len, header_len, ppl;
unsigned char pixel_line[12400], header_buffer[20], file_id_buffer[256];

/*  This is it...  */
main(argc, argv)
int argc;
char *argv[];
{
int i, temp;
char choice[80];

  if (argc != 3 || (!strcmp(argv[1], "?")) ) {
    printf("Usage:  FLIP input output\n");
    exit(0);
  }
  if ( (!strcmp(argv[1], argv[2])) ) {
    printf("Filenames must be different.\n");
    exit(0);
  }

  read_targa_header(argv[1]);

  while (1) {
    printf("Start line offset is %d\n", offset_y);
    printf("Would you like to change it?  (Y/N/Q)   ");
    scanf("%s", &choice[0]);
    if (choice[0] == 'Q' || choice[0] == 'q')
      done(NULL);
    if (choice[0] == 'Y' || choice[0] == 'y') {
      printf("Enter a new y offset -->  ");
      scanf("%d", &temp);
      if (temp >= 0)
        offset_y = temp;
    }
    if (choice[0] == 'N' || choice[0] == 'n')
      break;
  }

  write_targa_header(argv[2]);

  for (i=pixels_y-1; i>= 0; i--) {
    read_targa_line(i);
    write_targa_line();
  }

  done("Done!");
}

read_targa_header(name)
char *name;
{
int size=1;

  /*  Open file  */
   if ((infile = fopen(name, "r")) == NULL)
     done("Couldn't open infile for reading.");

  /*************  Fields 1 thru 5:                *********/
    size = 18;
    fread(header_buffer, (int)size, (int)1, infile);

    if (header_buffer[2] != 2)
      done("Not a 24 bit/pixel file.");
    if (header_buffer[16] != 24)
      done("Not a 24 bit/pixel file.");

  /*************  Field 6:  Image ID field    *************/
    file_id_len = header_buffer[0];
    header_len = file_id_len + 18;
    fread(file_id_buffer, (int)file_id_len, (int)1, infile);
    file_id_buffer[file_id_len] = 0;

  /*************  Set image stats  ***************/
    offset_x = header_buffer[9] * 256 + header_buffer[8];
    offset_y = header_buffer[11] * 256 + header_buffer[10];
    pixels_x = header_buffer[13] * 256 + header_buffer[12];
    ppl = pixels_x * 3;   /*  PixelsPerLine  */
    pixels_y = header_buffer[15] * 256 + header_buffer[14];
    printf("Picture size is %d x %d\n", pixels_x, pixels_y);
}

read_targa_line(line)
int line;
{
unsigned long offset;

  offset = header_len + ppl * line;
  fseek(infile, offset, (int)0);
  if (fread(pixel_line, (int)ppl, (int)1, infile) != 1)
    return(0);
  return(1);
}

write_targa_header(name)
char *name;
{
int size = 18;
int lsb, msb;

  if ((outfile = fopen(name, "w")) == NULL)
    done("Couldn't open outfile for writing.");

    lsb = offset_y;
    msb = 0;
    while (lsb > 255) {
      lsb -= 256;
      msb++;
    }
    header_buffer[11] = msb;
    header_buffer[10] = lsb;

    /*  FLIP the ORIGIN bit  */
    if (header_buffer[17])
      header_buffer[17] = 0;   /*  ORIGIN in LowerLeft  */
    else
      header_buffer[17] = 32;  /*  ORIGIN in UpperLeft  */

    /*  Write header and ID.  */
    fwrite(header_buffer, (int)size, (int)1, outfile);
    fwrite(file_id_buffer, (int)file_id_len, (int)1, outfile);
}

write_targa_line()
{
  if (fwrite(pixel_line, (int)ppl, (int)1, outfile) != 1)
    done("Couldn't write 24-bit line");
}

done(s)
char *s;
{
  if (infile)  fclose(infile);
  if (outfile)  fclose(outfile);
  if (s)  printf("TFLIP: %s\n", s);
  exit(0);
}

