#ifdef VMS
#include <file.h>
#else
#include <fcntl.h>
#endif
#include <math.h>
#include <stdio.h>
/*
********************************
**     Program: reorder       **
********************************

Purpose: Reorder a film or image plate data file and swap bytes if
         required.

Author:  John Campbell, November 1991

Use: 

         reorder [-film] [-ip] [-order string] [-rast xrasts yrasts] 
                 [-swab] [-noswab] [-header hbytes] [-log] [-echo] 
                 [file_in] [file_out] 

              The user will be prompted for parameters not supplied
*/
main (argc, argv)
int argc;
char ** argv;
{
   static char *ordstr[8]=
   {
     "+xf +yf",
     "+xf -yf",
     "-xf +yf",
     "-xf -yf",
     "+yf +xf",
     "+yf -xf",
     "-yf +xf",
     "-yf -xf"
   };
   char str[80],str2[80];
   char filin[80],filout[80];
   char *p;
   int i,j,k;
   int irast;
   int type;
   int order;
   int swaptyp;
   int ifil;
   int echo;
   int fin, fout;
   int iarg;
   int ihead;
   int xrasts;
   int yrasts;
   unsigned char *byte_img;
   unsigned short *i2_img;
   int nbytes;
   int hbytes;
/*+ skinner - variables associated with -l option */
   int logflag;
   FILE *infp;
   char inf_file[100];
   int f_len;
   int pix_size;
   int pix_in_raster_cnt;
   int raster_cnt;
   int sensitivity;
   float latitude, temp_f;
/*- skinner */

   /* Initialisations */

/*+ skinner - added defaults */
   pix_size = 100;
   sensitivity = 4000;
   latitude = 4.0;
   logflag = 0;
/*- skinner */
   filin[0] = 0;
   filout[0] = 0;
   irast = 0;
   type = 0;
   order = 0;
   swaptyp = 0;
   ifil = 0;
   echo = 0;
   ihead = 0;
   hbytes = 0;


   /* Examine parameters passed to the program */

   iarg = 1;
   while (iarg<argc)
   {
       p = argv[iarg];
       if (p[0]=='-')
       {
          switch (p[1])
          {
             case 'f':  /*film*/
             case 'F':
                if (type==2)
                {
                  printf("\n**Error** Cannot be both film and image plate\n");
                  exit(1);
                }
                type = 1;
                break;
             case 'i': /*image plate*/
             case 'I':
                if (type==1)
                {
                  printf("\n**Error** Cannot be both film and image plate\n");
                  exit(1);
                }
                type = 2;
                break;
             case 's': /*Byte swap*/
             case 'S':
                if (swaptyp==1)
                {
                   printf("\n**Error** Cannot have swap bytes and noswap\n");
                   exit(1);
                }
                swaptyp = 2;
                break;
             case 'l': /* skinner - data in log format*/
             case 'L':
                if (type==1)
                {
                  printf("\n**Error** Cannot be both film and in log format\n");
                  exit(1);
                }
                logflag=1;
                break;
             case 'n': /*No byte swapping*/
             case 'N':
                if (swaptyp==2)
                {
                   printf("\n**Error** Cannot have swap bytes and noswap\n");
                   exit(1);
                }
                swaptyp = 1;
                break;
             case 'o': /*Axis order*/
             case 'O':
                iarg ++;
                if (iarg>=argc)
                {
                   printf("\n**Error** No string given after -o flag\n");
                   exit(1);
                }
                i = axord(argv[iarg],0,&order,&k);
                if (i>0)
                {
                   printf("\n**Error** Invalid axis order string");
                   switch (i)
                   {
                      case 1:
                         printf("\nOnly one axis defined\n");
                         break;
                      case 2:
                         printf("\nSame axis defined twice\n");
                         break;
                      case 3:
                         printf("\nMore than two axes defined\n");
                         break;
                      case 4:
                         printf("\nCannot have swap bytes and noswap\n");
                         break;
                   }
                   exit(1);
                }
                if (k>0)
                {
                   if (swaptyp==0)
                   {
                      swaptyp = k;
                   }
                   else
                   {
                      if (k!=swaptyp)
                      {
                         printf(
                          "\n**Error** Cannot have swap bytes and noswap\n");
                         exit(1);
                      }
                   }
                }
                break;
             case 'r': /*Raster sizes*/
             case 'R':
                if (irast==1)
                {
                   printf("\n**Error** Option -r occurs more than once\n");
                   exit(1);
                }
                if (iarg+2>=argc)
                {
                   printf(
                   "\n**Error** Two raster numbers must follow -r option\n");
                   exit(1);
                }
                iarg++;
                i = sscanf(argv[iarg],"%d",&xrasts);
                if (i==0)
                {
                   printf("**Error** Invalid number follows -r option\n");
                   exit(1);
                }
                iarg++;
                i = sscanf(argv[iarg],"%d",&yrasts);
                if (i==0)
                {
                   printf("**Error** Invalid number follows -r option\n");
                   exit(1);
                }
                irast = 1;
                break;
             case 'h': /*Header bytes*/
             case 'H':
                if (ihead==1)
                {
                   printf("\n**Error** Option -h occurs more than once\n");
                   exit(1);
                }
                if (iarg+1>=argc)
                {
                   printf(
                   "\n**Error** One byte count must follow -h option\n");
                   exit(1);
                }
                iarg++;
                i = sscanf(argv[iarg],"%d",&hbytes);
                if (i==0)
                {
                   printf("**Error** Invalid number follows -h option\n");
                   exit(1);
                }
                ihead = 1;
                break;
             case 'e': /*Echo details of translation*/
             case 'E':
                echo = 1;
                break;
          }
      }
      else
      {
         ifil = ifil + 1;
         if (ifil>2)
         {
            printf("\n**Error** More than two file names given\n");
            exit(1);
         }
         if (ifil==1)
         {
            strcpy(filin,p);
            fin = open (filin, O_RDONLY, 0);
            if (fin<0)
            {
               printf("\n**Error** Unable to open input file %s\n",filin);
               exit(1);
            }
         }
         else
         {
            strcpy(filout,p);
            fout = creat (filout, 0664);
            if (fout<0)
            {
               printf("\n**Error** Unable to open output file %s\n",filout);
               exit(1);
            }
         }
      }
      iarg++;
   }

   /* Input details not supplied via the parameters */
   /* --------------------------------------------- */


   /* Input file name */

   if (ifil==0)
   {
      echo = 1;
      labinf:
      printf("Name of input file: ");
      gets(str);
      i = sscanf(str,"%s",filin);
      if (filin[0]==0) goto labinf;
      fin = open (filin, O_RDONLY, 0);
      if (fin<0)
      {
         printf("**Error** Unable to open input file\n");
         goto labinf;
      }
   }

/*+ skinner - if -l option is used, try to read the 
settings from the *.inf file, else prompt for settings */

      if (logflag) {
        strcpy(inf_file,filin);
        f_len = strlen(inf_file);
        inf_file[f_len-2] = 'n';
        inf_file[f_len-1] = 'f';
        if ((infp = fopen(inf_file,"r")) == NULL) {
	labpix:
          printf("pixel size?: [%d]",pix_size);
          gets(str);
          i = sscanf(str,"%d",&j);
          if (i == 1) {
            pix_size = j;
          }
          else if (i != -1) {
            printf("**Error** Invalid reply\n");
            goto labpix;
          }
          else {    /* i == -1, take default */
            ;
          }
	labsens:
          printf("sensitivity?: [%d]",sensitivity);
          gets(str);
          i = sscanf(str,"%d",&j);
          if (i == 1) {
            sensitivity = j;
          }
          else if (i != -1) {
            printf("**Error** Invalid reply\n");
            goto labsens;
          }
          else {    /* i == -1, take default */
            ;
          }
	lablat:
          printf("latitude?: [%f]",latitude);
          gets(str);
          i = sscanf(str,"%f",&temp_f);
          if (i == 1) {
            latitude = temp_f;
          }
          else if (i != -1) {
            printf("**Error** Invalid reply\n");
            goto lablat;
          }
          else {    /* i == -1, take default */
            ;
          }
        }
        else {
          type = 2;
          irast = 1;  
          fscanf(infp,"%*s %*s %*s %d %*s %*s %d %d %d %f",
                 &pix_size,&yrasts,&xrasts,
                 &sensitivity,&latitude);
          fclose(infp);
          printf("Fuji scanner settings will be read from the info file.\n");
          printf("pixel size = %d microns; sensitivity = %d; latitude = %f\n",
                  pix_size,sensitivity,latitude); 
        }
      }
/*- skinner */


   /* Output file name */

   if (ifil<2)
   {
      echo = 1;
      laboutf:
      printf("Name of output file: ");
      gets(str);
      i = sscanf(str,"%s",filout);
      if (filout[0]==0) goto laboutf;
      fout = creat (filout, 0664);
      if (fout<0)
      {
         printf("**Error** Unable to open output file\n");
         goto laboutf;
      }
   }
 
   /* Film/image-plate */

   if (type==0)
   {
      echo = 1;
      labfip:
      printf("Film (f) or image-plate (i) file [i]: ");
      gets(str);
      str2[0] = 0;
      sscanf(str,"%s",str2);
      switch (str2[0])
      {
         case '\0':
            type = 2;
            break;
         case 'f':
         case 'F':
            type = 1;
            break;
         case 'i':
         case 'I':
            type = 2;
            break;
         default:
            printf("**Error** Invalid file type\n");
            goto labfip;
      }      
   }

   /* Raster sizes */

   if (irast==0)
   {
      echo = 1;
      if (type==1)
      {
         xrasts = 2400;
         yrasts = 2400;
      }
      else
      {
         xrasts = 1200;
         yrasts = 1200;
      }
      labrast:
      printf("No. of x rasters, no. of y rasters [%d %d]: ",xrasts,yrasts);
      gets(str);
      i = sscanf(str,"%d%d",&j,&k);
      if (i!=-1&&i!=2)
      {
         printf("**Error** Invalid reply\n");
         goto labrast;
      }
      if (i>0) xrasts = j;
      if (i>1) yrasts = k;
   }

   /* Axis order */

   if (order==0)
   {
      echo = 1;
      labord:
      printf("Order of axes in input data file [+x+y]: ");
      gets(str);
      i = axord (str,0,&order,&k);
      if (i>0)
      {
         printf("**Error** Invalid axis order string\n");
         switch (i)
         {
            case 1:
               printf("Only one axis defined\n");
               break;
            case 2:
               printf("Same axis defined twice\n");
               break;
            case 3:
               printf("More than two axes defined\n");
               break;
            case 4:
               printf("Cannot have swap bytes and noswap\n");
               break;
         }
         goto labord;
      }
      if (order==0) order = 1;
      if (k>0&&swaptyp>0&&k!=swaptyp)
      {
         printf("**Error** Byte swap requests not consistent\n");
         goto labord;
      }
      if (k>0) swaptyp = k;
   }

   /* Byte swap option */

   if (type==2)
   {
      if (swaptyp==0)
      {
         echo = 1;
         labswap:
         swaptyp = 1;
         printf("Byte swap data [n]: ");
         gets(str);
         str2[0] = 0;
         i = sscanf(str,"%s",str2);
         if (str2[0]!=0)
         {
            switch (str2[0])
            {
                case 'y':
                case 'Y':
                   swaptyp = 2;
                   break;
                case 'n':
                case 'N':
                   swaptyp = 1;
                   break;
                default:
                   printf("**Error** Invalid reply\n");
                   goto labswap;
                   break;
            }
         }
      }
   }

   /* Header bytes */
/*+ skinner - don't prompt for header bytes if -l and -i are used */
   if (logflag && type == 2) {   
     ihead = 1;
   }   
/*- skinner */
   if (ihead==0)
   {
      echo = 1;
      hbytes = 0;
      labhead:
      printf("No. of bytes of header information to skip [%d]: ",hbytes);
      gets(str);
      i = sscanf(str,"%d%d",&j);
      if (i!=-1&&i!=1)
      {
         printf("**Error** Invalid reply\n");
         goto labhead;
      }
      if (i>0) hbytes = j;
   }


   /* Print details of translate */       

   if (echo)
   {
      if (type==1)
      {
         printf("\nTranslating film data\n");
      }
      else
      {
         if (swaptyp==1)
         {
            printf("\nTranslating image plate data\n");
         }
         else
         {
            printf("\nTranslating image plate data with byte swapping\n");
         }
      }
      printf("Name of input  file: %s\n",filin);
      printf("Name of output file: %s\n",filout);
      printf("No. x rasters = %d, no. y rasters = %d\n",xrasts,yrasts);
      printf("Input axis order: %s\n",ordstr[order-1]);
      if (hbytes>0)
      {
         printf("Number of header bytes to skip = %d\n",hbytes);
      }
   }

   /* Translate the data */

   if (hbytes>0)
   {
      if (echo) printf("*Skipping header data*\n");
      lseek (fin, (long) hbytes, 0);
   }

   if (type==1)
   {
      if (echo) printf("*Reading file*\n");
      nbytes = xrasts*yrasts;
      byte_img = (unsigned char *) malloc(nbytes);
      if (byte_img==0)
      {
         printf("\n**Error** Unable to allocate memory to hold film image\n");
         exit(1);
      }
      i = read_full_film (fin,order,xrasts,yrasts,byte_img);
      if (i<0)
      {
         printf("\n**Error** Unable to allocate temporary buffer\n");
         exit(1);
      }
      if (i>0)
      {
         printf("\n**Error** Error reading record %d\n",i);
         exit(1);
      }
      if (echo) printf("*Writing file*\n");
      i = write (fout,byte_img,nbytes);
      if (i!=nbytes)
      {
         printf("\n**Error** Error writing file\n");
         exit(1);
      }
      if (echo) printf("*Translation successfully completed*");
      close (fin);
      close (fout);
      free (byte_img);
      exit(0);
   }
   else
   {
      if (echo) printf("*Reading file*\n");
      nbytes = 2*xrasts*yrasts;
      i2_img = (unsigned short *) malloc(nbytes);
      if (i2_img==0)
      {
         printf("\n**Error** Unable to allocate memory to hold image\n");
         exit(1);
      }
      if (swaptyp==2) order = -order;
      i = read_full_i2 (fin,order,logflag,xrasts,yrasts,i2_img,
        pix_size,sensitivity,latitude);
      if (i<0)
      {
         printf("\n**Error** Unable to allocate temporary buffer\n");
         exit(1);
      }
      if (i>0)
      {
         printf("\n**Error** Error reading record %d\n",i);
         exit(1);
      }
      if (echo) printf("*Writing file*\n");
      i = write (fout,i2_img,nbytes);
      if (i!=nbytes)
      {
         printf("\n**Error** Error writing file\n");
         exit(1);
      }
      if (echo) printf("*Translation successfully completed*");
      close (fin);
      close (fout);
      free (i2_img);
      exit(0);
   }
}
/*
***************************
**         axord         **
***************************

Purpose: Interpret image axes order and byte swapping option string
         (as xdl_axord in xdl_view routines)

Return:  Error flag =0 no error; 
                    >0 syntax error   =1 Only one axis defined.
                                      =2 Both axes the same.
                                      =3 More than two axes defined.
                                      =4 Byte swapping and no byte
                                         swapping defined.

Author:  John W. Campbell, November 1991

*/

int axord (str,len,order,swaptyp)

char *str;       /* String containing the axes order and byte swap flags
                    (R)*/
int len;         /* Length of the string; if 0 then assume a null
                    terminated string was passed (R) */
int *order;      /* Returns the axis order given as a number from 1 to 8
                    (If none specified (or syntax error) return 0)
                     1   +xf slow   +yf fast
                     2   +xf slow   -yf fast
                     3   -xf slow   +yf fast
                     4   -xf slow   -yf fast
                     5   +yf slow   +xf fast
                     6   +yf slow   -xf fast
                     7   -yf slow   +xf fast
                     8   -yf slow   -xf fast
                     (W)*/
int *swaptyp;    /* Returns byte swap type   =1 do not swap bytes
                                             =2 swap bytes
                                             =0 not specified (or syntax
                                                error)
                    (W)*/

{
   int saxis, ssign;
   int faxis, fsign;
   int n;
   int l;
   int err;

   /* Initialisations */

   if (len<=0) len=strlen(str);
   saxis = 0;
   ssign = 1;
   faxis = 0;
   fsign = 1;
   err = 0;
   *swaptyp = 0;
   *order = 0;
   if (len==0) return 0;
   n = 1;

   /* Decode the string */

   for (l=0;l<len;++l)
   {
      switch (str[l])
      {
         case '-':
            if (n==1) { ssign = -1; }else{ fsign = -1; }
            break;
         case '+':
            if (n==1) { ssign = 1; }else{ fsign = 1; }
            break;
         case 'x':
         case 'X':
            if (n==1) 
            {
               saxis = 1;
               n = 2;
            }
            else
            {
               if (n==3) { err=3; goto synterr; }
               faxis = 1;
               n = 3;
            }
            break;
         case 'y':
         case 'Y':
            if (n==1) 
            {
               saxis = 2;
               n = 2;
            }
            else
            {
               if (n==3) { err=3; goto synterr; }
               faxis = 2;
               n = 3;
            }
            break;
         case 's':
         case 'S':
            if (*swaptyp>0) { err=4; goto synterr; }
            *swaptyp = 2;
            break;
         case 'n':
         case 'N':
            if (*swaptyp>0) goto synterr;
            *swaptyp = 1;
            break;
      }
   }
   if (saxis==0&&faxis==0) return 0;
   if (saxis==0||faxis==0) { err=1; goto synterr; }
   if (saxis==faxis) { err=2; goto synterr; }
   *order = 4*saxis - 3;
   if (ssign<0) *order += 2;
   if (fsign<0) *order += 1;
   return 0;
   synterr:
   *order = 0;
   *swaptyp = 0;
   return err;
}
/*
*****************************
**     read_full_film      **
*****************************

Purpose: Read a film image file and return the image data in an array. 
         The film_file may have its data in any of the eight possible
         orders (the default is assumed to  have yf moving fastest and xf 
         slowest) and is in unsigned byte format without any header. The 
         number of x rasters and number of y rasters must be supplied.

Return:  =0 OK; >0 Record number where a read error occurred; -1 unable
         to allocate temporary buffer space.

*/

int read_full_film (fd, order,nxrasts, nyrasts, img_full)

int fd;           /* The file descriptor of the opened film format 
                     file (R)*/
int order;        /* Order of the data in the input film image file
                     in terms of the xf, yf coordinate system as
                     a number from 1 to 8.
                     1   +xf slow   +yf fast
                     2   +xf slow   -yf fast
                     3   -xf slow   +yf fast
                     4   -xf slow   -yf fast
                     5   +yf slow   +xf fast
                     6   +yf slow   -xf fast
                     7   -yf slow   +xf fast
                     8   -yf slow   -xf fast
                     (R)*/
int nxrasts;      /* The number of x rasters (no. of records) (R)*/
int nyrasts;      /* The number of y rasters (pixels in a record) (R)*/
unsigned char img_full[];
                  /* Array returning the read image data; 
                     The slower moving index in
                     the returned data is x going from low x to
                     high x and the faster moving index is y going 
                     from low y to high y. (W)*/
{
   int i, j, k;
   int irec;
   int step;
   int nrecs, nrasts;
   unsigned char *buf;
   int ir, ix;

   /* Initialisations */

   if(order<1||order>8) order=1;
   nrecs = nxrasts;
   nrasts = nyrasts;
   if (order>4)
   {
      nrecs = nyrasts;
      nrasts = nxrasts;
   }

   /* Read data */

   buf = (unsigned char *) malloc(nrasts);
   if (buf==0) return -1;
   irec = 1;
   for (ir=0;ir<nrecs;++ir)
   {
      i = read (fd, buf, nrasts);
      if (i!=nrasts) goto tidy;
      switch (order)
      {
         case 1:
            j = ir*nrasts;
            step = 1;
            break;
         case 2:
            j = (ir+1)*nrasts - 1;
            step = -1;
            break;
         case 3:
            j = (nrecs-ir-1)*nrasts;
            step = 1;
            break;
         case 4:
            j = (nrecs-ir)*nrasts - 1;
            step = -1;
            break;
         case 5:
            j = ir;
            step = nrecs;
            break;
         case 6:
            j = (nrasts-1)*nrecs + ir;
            step = -nrecs;
            break;
         case 7:
            j = nrecs - 1 - ir;
            step = nrecs;
            break;
         case 8:
            j = nrasts*nrecs - 1 - ir;
            step = -nrecs;
            break;
      }
      for (k=0;k<nrasts;++k)
      {
          img_full[j] = buf[k];
          j += step;
      }
      irec++;
   }
   irec = 0;   
   
   /* Tidy up */

   tidy:
   free (buf);
   return irec;
}
/*
*****************************
**     read_full_i2        **
*****************************

Purpose: Read an image-plate 'i2' image file and return the image data in 
         an array. The file may have its data in any of the eight
         possible orders and may be byte swapped if needed (the default
         is assumed to  have yf moving fastest and xf 
         slowest) and is in unsigned two byte integer format without any 
         header. The number of x rasters and number of y rasters must be 
         supplied.

Return:  =0 OK; >0 Record number where a read error occurred.

*/
int read_full_i2 (fd, order, logflag, nxrasts, nyrasts, img_full,
                  pix_size,sensitivity,latitude)

int fd;           /* The file descriptor of the opened film format 
                     file (R)*/
int order;        /* Order of the data in the input film image file
                     in terms of the xf, yf coordinate system as
                     a number from 1 to 8. (-order can be given to
                     byte swap the data as well as change the order)
                     1   +xf slow   +yf fast
                     2   +xf slow   -yf fast
                     3   -xf slow   +yf fast
                     4   -xf slow   -yf fast
                     5   +yf slow   +xf fast
                     6   +yf slow   -xf fast
                     7   -yf slow   +xf fast
                     8   -yf slow   -xf fast
                     (R)*/
int logflag;       /* 1 ==> Do Log to Lin conversion */
int nxrasts;      /* The number of x rasters (no. of records) (R)*/
int nyrasts;      /* The number of y rasters (pixels in a record) (R)*/
unsigned short img_full[];
                  /* Array returning the read image data; 
                     The slower moving index in
                     the returned data is x going from low x to
                     high x and the faster moving index is y going 
                     from low y to high y i.e. the same order as in the
                     file. (W)*/
int pix_size,sensitivity;
float latitude;      /* last 5 parameters for fuji calculations */
{
   int i, j, k, l;
   int swap;
   int irec;
   int step;
   int nrecs, nrasts;
   unsigned short *buf;
   unsigned char *cbuf;
   unsigned char tempc;
   int ir, is, ix;
/*+ skinner */
   unsigned short oldvalue;
   unsigned short lut[1024];
   double temp, sens_log, temp1, dsens;
/*- skinner */   


   /* Initialisations */
/*+ skinner - the next set of calculations was based on the
following information sent from the Fuji Film Co.:

QL : A/D converter output value, which is a logarithmic value.
Not calibrated with parameters such as sensitivity, latitude (dynamic
range), gray level resolution (8 bit or 10 bit), spatial resolution
(100um or 200 um). The QL value in 256 steps is used in 'Gradiation
Bar' and 'Profile' expresssion.
XQL: Calibrated value with above mentioned parameters except for
spatial resolution. This is still a logarithmic value.
PSL: Arbitrary unit used in the BAS system. This is the antilogarithm
value converted from XQL. This is the only value which is visible to
the normal users.

XQL = 4096(L x (QL/G - 1/2) + 5/2 -log10(S/20000))
PSL = (PixelSize/100)**2 x 4000/2000 x 10((XQL/4096) - 5/2)

Where:
L: Latitude (dynamic range)
QL: Raw data value (0 to 255, or 0 to 1023)
G: Total gradation level (256 or 1024)
S: Sensitivity (400 to 10000)
PixelSize: Spatial resolution (100 or 200)
*/
/*+ skinner */
   pix_size = (pix_size/100) * (pix_size/100);
   dsens = (double)sensitivity/20000.0;
   sens_log = log10(dsens);
   for (ir=0;ir<1024;++ir)
      {
         temp1 = ((double)ir/1024.0);
         temp1 = temp1 * (double)latitude;
         temp = (double)pix_size * pow(10,temp1);
         lut[ir] = (unsigned short) temp;
      } 
/*- skinner */
   swap = 0;
   if (order<0)
   {
      swap = 1;
      order = -order;
   }
   if(order<1||order>8) order=1;
   nrecs = nxrasts;
   nrasts = nyrasts;
   if (order>4)
   {
      nrecs = nyrasts;
      nrasts = nxrasts;
   }

   /* Read data */

   buf = (unsigned short *) malloc(nrasts*sizeof(unsigned short));
   if (buf==0) return -1;
   cbuf = (unsigned char *) buf;
   irec = 1;
   for (ir=0;ir<nrecs;++ir)
   {
      i = read (fd, buf, 2*nrasts);
      if (i!=2*nrasts) goto tidy;
      switch (order)
      {
         case 1:
            j = ir*nrasts;
            step = 1;
            break;
         case 2:
            j = (ir+1)*nrasts - 1;
            step = -1;
            break;
         case 3:
            j = (nrecs-ir-1)*nrasts;
            step = 1;
            break;
         case 4:
            j = (nrecs-ir)*nrasts - 1;
            step = -1;
            break;
         case 5:
            j = ir;
            step = nrecs;
            break;
         case 6:
            j = (nrasts-1)*nrecs + ir;
            step = -nrecs;
            break;
         case 7:
            j = nrecs - 1 - ir;
            step = nrecs;
            break;
         case 8:
            j = nrasts*nrecs - 1 - ir;
            step = -nrecs;
            break;
      }

      if (swap)
      {
         l=0;
         for (k=0;k<nrasts;++k)
         {
             tempc = cbuf[l];
             cbuf[l] = cbuf[l+1];
             cbuf[l+1] = tempc;
             l += 2;
         }
      }
/*+ skinner */
       if (logflag)
      {
          for (k=0;k<nrasts;++k)
          {
              oldvalue = buf[k];
              is = (int)buf[k];
              buf[k] = lut[is];
          }
      } 
/*- skinner */
      for (k=0;k<nrasts;++k)
      {
          img_full[j] = buf[k];
          j += step;
      }
      irec++;
   }
   irec = 0;   
   
   /* Tidy up */

   tidy:
   free (buf);
   return irec;
}
