banner_info3.jpg

MAT5 DATA FORMAT

TRADITIONAL MAT5 FORMAT: (5 files that end with *C.bmp, *I.bmp, *X.byt, *Y.byt, *Z.byt) This is a format we use to represent our data. We made it up but we know other 3-D folk have used almost the same thing. The reason we use it is that we haven’t really found a better one that is an accepted standard. We have the capability to convert it to STL, IGES, ASCII, Wavefront, VRML and GPD + UV formats.

Mat5 consists of 5 matrices, hence the name. The first matrix is the color image, sometimes called the texture map in BMP format. So for a mat5 set named lgh, the first matrix is lghC.bmp (suffix is C.bmp) which is viewable by any image viewer. Also note that since it is a BMP file, the number of columns must be an integer multiple of 4. The row, column size of the “color” image sets the size of the remaining 4 image matrices. The second matrix is the “Indicator” or “quality” matrix. The most common format we use for this is also BMP and so we would have lghI.bmp (suffix is I.bmp). This Indicator matrix is black and white in value and can also be stored as a headerless file with each pixel being one unsigned char but will have the suffix “I.byt” or lghI.byt. Since we use the I.bmp so much there is a chance that some of our software does not recognize the I.byt but if you find that is the case, let us know and we will fix it. This would save you some memory. The indicator matrix can be edited to exclude pixels. If a pixel in the indicator matrix is 0 then that pixel is considered nonvalid. You can also threshold the indicator to exclude pixels that are dark in color. Never the less, everything to do with pixel selection revolves around the indictor matrix. The remaining three matrices are X, Y, and Z. They contain no header information and use one float value for each element. The X, Y and Z matrices contain the X, Y and Z coordinates, respectively. Their suffixes are X.byt, Y.byt and Z.byt, respectively. In this example they would be lghX.byt, lghY.byt and lghZ.byt. The reason mat5 is so advantageous is that the indice position of the elements corresponds to the relative spatial position of the 3-D points. So if you rotate, scale and/or translate the coordinates X,Y,Z you will still know the relative positions of the points with respect to each other. This cannot be over stressed and it make triangulation and merging of data much easier. The format GPD + UV has this feature but by separating the coordinates from the indices, it uses up more space for storage.

 

// MAT5 BSD LICENSE

//Copyright (c) 2009, University of Kentucky, Lexington
//All rights reserved.

//Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

//1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

//2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer

//   in the documentation and/or other materials provided with the distribution.

//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,

//BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

//IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,

//OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

//DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,

//OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 

AnnabelleFilteredC.bmpAnnabelleFilteredI.bmp

(Left) Annabell_C.bmp and (right) Annabell_I.bmp. The X.byt, Y.byt and Z.byt are not shown.

 

We have a PreMat5 format consisting of a A.byt, G.byt and either, or both XP.byt and YP.byt. A.byt is a 4x4 transformation matrix in floating point, the G.byt is the calibration grid data with the first two bytes being a short integer number representing the number of calibration points, and the point format being floating point values for  Xw, Yw, Zw, Xc, Yc, Xp and Yp. The XP.byt and/or YP.byt matrices are the “phase” of the projected patterns. From these, the X.byt, Y.byt and Z.byt can be generated for multiple scanners. Other mat5 matrices that we sometimes use but generally don’t support are P.byt and O.byt. The P.byt matrix is the “phase” of the surface which has not yet been converted to X,Y,Z and is context dependent on the set up of the scanner. The O.byt with stands for original texture image. We use this to store the raw texture image prior to Bayer filtering or other color mapping algorithms.

 

Samples of mat5 formatted data: weisu_mat5.zip, fingerprint0.jpg, finger0_crop.ZIP

 

NEW F FORMAT MAT5: We imbedded our 5 matrices into a single 32 bit BMP formatted file that ends with *F.bmp. Try downloading the bitmap below and view in our new GL3Dview.exe program.

Annabelle1_clipF.bmp

 

APPENDIX SOURCE CODE FOR MAT5 I/O

BSD LICENSE

Copyright (c)  2009, University of Kentucky, Lexington
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

STRUCTURES

// BITMAP STRUCTURES

typedef struct

{

      unsigned short ImageFileType; // Image file type always 4d42h ("BMP")

      unsigned long FileSize;             // Physical file size in bytes

      unsigned short reserved1;           // always 0

      unsigned short reserved2;           // always 0

      unsigned long ImageDataOffset;      // Start of image data offset in bytes

} BMPHEADER;

 

struct BMPINFOHEADER

{

      unsigned short HeaderSize;                // size of this header

      unsigned short Spacer;

      unsigned long ImageWidth;                 // image width in pixels

      unsigned long ImageHeight;                // image height in pixels

      unsigned short NumberOfImagePlanes; // always 1

      unsigned short BitsPerPixel;              // 1 4 8 or 24

      unsigned long CompressionMethod;    // 0(uncompressed) 1(8 bit RLE) or 2(4bit RLE)

      unsigned long SizeOfBitmap;               // in bytes

      unsigned long HorzResolution;       // pixels per meter

      unsigned long VertResolution;       // pixels per meter

      unsigned long NumColorsUsed;        // 0 implies max posible size

      unsigned long NumSignificantColors; // 0 implies all colors significant

};

/*. BMP pixel structure .*/

typedef struct

      {

      unsigned char b;   /*. 1 byte .*/

      unsigned char g;   /*. 1 byte .*/

      unsigned char r;   /*. 1 byte .*/

      }  BMPPIXEL;

/*. 32 bit BMP pixel structure .*/

typedef struct

      {

      unsigned char b;   /*. 1 byte .*/

      unsigned char g;   /*. 1 byte .*/

      unsigned char r;   /*. 1 byte .*/

      unsigned char blank;   /*. 1 byte .*/

      }  BMPPIXEL32;

/*. MAT5 pixel structure .*/

typedef struct

      {

            BMPPIXEL C;             /*. 3 byte .*/

            unsigned char I;  /*. 1 byte .*/

        float X;              /*. 4 bytes .*/

        float Y;              /*. 4 bytes .*/

        float Z;              /*. 4 bytes .*/

      }  MAT5PIXEL;

TRADITIONAL FORMAT

/*****************************************************/

// Hassebrook copyright 2009, University of Kentucky copyright 2009

// initialized 8-19-09

// returns mat5 knowing that CIXYZ exists

short fileCIXYZ2mat5(char *mat5prefix,BMPPIXEL *bmpimageC,BMPPIXEL *bmpimageI,float *fltimageX,float *fltimageY,float *fltimageZ,unsigned long Nx,unsigned long My)

{

      char filename[512];

      short iresult;

      // input C

      strcpy_ansi(filename,mat5prefix);

      strcat_ansi(filename,"C.bmp");

      iresult=mat5bmpin(bmpimageC,filename,Nx,My);

      // input I

      strcpy_ansi(filename,mat5prefix);

      strcat_ansi(filename,"I.bmp");

      iresult=mat5bmpin(bmpimageI,filename,Nx,My);

      // input X,Y,Z

      strcpy_ansi(filename,mat5prefix);

      strcat_ansi(filename,"X.byt");

      iresult=mat5fltfileio(0,filename,fltimageX,Nx,My);

      strcpy_ansi(filename,mat5prefix);

      strcat_ansi(filename,"Y.byt");

      iresult=mat5fltfileio(0,filename,fltimageY,Nx,My);

      strcpy_ansi(filename,mat5prefix);

      strcat_ansi(filename,"Z.byt");

      iresult=mat5fltfileio(0,filename,fltimageZ,Nx,My);

      return(iresult);

}

 

/*******************************************************/

/*******************************************************/

short mat5bmpin(BMPPIXEL *bmpimage,char *bmpfilein,unsigned long Nx,unsigned long My)

{

BMPPIXEL bmppixel,bmpblack,bmpwhite,bmptable[256];

BMPHEADER bmphead;

BMPINFOHEADER bmpinfohead;

FILE *fp;

short dtype;

unsigned long index,indexbit;

unsigned long j,m,n,m1,n1,Ntable;

unsigned long mirror,ipad,pad2,n1bit,n4bit;

unsigned char btemp,bitvalues[8],highnibble,lownibble;

 

bmpblack.r=bmpblack.g=bmpblack.b=0;

bmpwhite.r=bmpwhite.g=bmpwhite.b=255;

// input BMP header

errno_t err;

err=fopen_s(&fp,bmpfilein,"rb");

if(err!=0) return(0);

fseek(fp,0,SEEK_SET);

/* read the header */

fread(&bmphead.ImageFileType,sizeof(bmphead.ImageFileType),1,fp);

fread(&bmphead.FileSize,sizeof(bmphead.FileSize),1,fp);

fread(&bmphead.reserved1,sizeof(bmphead.reserved1),1,fp);

fread(&bmphead.reserved2,sizeof(bmphead.reserved2),1,fp);

fread(&bmphead.ImageDataOffset,sizeof(bmphead.ImageDataOffset),1,fp);

/* read the info header */

fread(&bmpinfohead,sizeof(bmpinfohead),1,fp);

// verify BMP

if(bmphead.ImageFileType!=19778)

      {

      MessageBeep((WORD)-1);

      //MessageBox("INPUT BMP file is not 19778","Sorry.",MB_OK+MB_ICONSTOP);

      return(-1);

      }

/* input header*/

Nx=n1=bmpinfohead.ImageWidth;

My=m1=bmpinfohead.ImageHeight;

if((n1<1)||(m1<1)) {fclose(fp);return(0);}

if((bmpinfohead.BitsPerPixel!=24)&&(bmpinfohead.BitsPerPixel!=8)&&(bmpinfohead.BitsPerPixel!=4)&&(bmpinfohead.BitsPerPixel!=1))

      {

      fclose(fp);

      MessageBeep((WORD)-1);

      //sprintf(stemp,"INPUT BMP file has %d bits per pixel",bmpinfohead.BitsPerPixel);

      //MessageBox(stemp,"Sorry, this version only does 24 bits only.",MB_OK+MB_ICONSTOP);

      return(-2);

      }

if(bmpinfohead.CompressionMethod!=0)

      {

      fclose(fp);

      MessageBeep((WORD)-1);

      //MessageBox("INPUT BMP file is compressed","Sorry,maybe next version.",MB_OK+MB_ICONSTOP);

      return(-3);

      }

// input color table

fseek(fp,54,SEEK_SET);

Ntable=0;

Ntable=(bmphead.ImageDataOffset-54)/4;

if(Ntable>256) Ntable=256;

for(n=0;n<Ntable;n++)

{

      fread((BMPPIXEL *)&bmptable[n],sizeof(BMPPIXEL),1,fp);

      fread((char *)&btemp,sizeof(char),1,fp);

}

fseek(fp,bmphead.ImageDataOffset,SEEK_SET);

// end of color table input

if(bmpinfohead.BitsPerPixel==24)

{

      dtype=30;

      pad2=4-(n1*bmpinfohead.BitsPerPixel/8)%4; // bytes to pad each scan line so that it is a multiple of 4

      if(pad2==4) pad2=0;

}

if(bmpinfohead.BitsPerPixel==8)

{

      dtype=20;

      pad2=4-(n1*bmpinfohead.BitsPerPixel/8)%4; // bytes to pad each scan line so that it is a multiple of 4

      if(pad2==4) pad2=0;

}

if(bmpinfohead.BitsPerPixel==1)

{

      dtype=21;

      n1bit=n1/8;n1bit*=8;

      if(n1bit==n1) n1bit=n1/8; //full byte fill

      else n1bit=(n1/8) + 1; // partial byte fill

      pad2=4-(n1bit)%4; // bytes to pad each scan line so that it is a multiple of 4

      if(pad2==4) pad2=0;

}

if(bmpinfohead.BitsPerPixel==4)

{

      dtype=24;

      n4bit=n1/2;n4bit*=2;

      if(n4bit==n1) n4bit=n1/2; //full byte fill

      else n4bit=(n1/2) + 1; // partial byte fill

      pad2=4-(n4bit)%4; // bytes to pad each scan line so that it is a multiple of 4

      if(pad2==4) pad2=0;

}

// load the file into the array

if(dtype==21) // 1 bit

{

      for(m=0;m<m1;m++)

      {

            indexbit=0;

            for(n=0;n<n1bit;n++)

            {

                  mirror=(m1-1)-m;

                  fread((char *)&btemp,sizeof(char),1,fp);

                  // decompose bits

                  mat5byte2bit(&bitvalues[0],btemp);

                  for(j=0;j<8;j++)

                  {

                        if(indexbit<n1)

                        {

                              // store in output array

                              bmppixel=bmptable[(short)bitvalues[7-j]];

                              index=n1 * mirror + indexbit;

                              bmpimage[index]=bmppixel;

                              ++indexbit;

                        }

                        else goto SKIPBITS;

                  }

                  SKIPBITS:;

                  if(n==(n1bit-1))

                  {

                        for(ipad=0;ipad<pad2;ipad++)

                              fread((char *)&btemp,sizeof(char),1,fp);

                  }

            } // n

      } // m

}

if(dtype==24) // 4 bit

{

      for(m=0;m<m1;m++)

      {

            indexbit=0;

            for(n=0;n<n4bit;n++)

            {

                  mirror=(m1-1)-m;

                  fread((char *)&btemp,sizeof(char),1,fp);

                  // decompose nibbles

                  mat5byte2nibble(&highnibble,&lownibble,btemp);

                  // store highbyte

                  if(indexbit<n1)

                  {

                        // convert to rgb

                        bmppixel=bmptable[(short)highnibble];

                        index=n1 * mirror + indexbit;

                        bmpimage[index]=bmppixel;

                        ++indexbit;

                  }

                  // store lowbyte

                  if(indexbit<n1)

                  {

                        // convert to rgb

                        bmppixel=bmptable[(short)lownibble];

                        index=n1 * mirror + indexbit;

                        bmpimage[index]=bmppixel;

                        ++indexbit;

                  }

                  // store in output array

                  if(n==(n4bit-1))

                  {

                        for(ipad=0;ipad<pad2;ipad++)

                              fread((char *)&btemp,sizeof(char),1,fp);

                  }

            } // n

      } // m

}

if(dtype==20) // 8 bit

{

      for(m=0;m<m1;m++)

      for(n=0;n<n1;n++)

            {

            mirror=(m1-1)-m;

            index=n1 * mirror + n;

            fread((char *)&btemp,sizeof(char),1,fp);

            // store in output array

            bmppixel=bmptable[(short)btemp];

            bmpimage[index]=bmppixel;

            if(n==(n1-1))

                  {

                  for(ipad=0;ipad<pad2;ipad++)

                        fread((char *)&btemp,sizeof(char),1,fp);

                  }

            } // m,n

}

if(dtype==30) // 24 bit

{

      for(m=0;m<m1;m++)

      for(n=0;n<n1;n++)

            {

            mirror=(m1-1)-m;

            index=n1 * mirror +n;

            fread((BMPPIXEL *)&bmppixel,sizeof(BMPPIXEL),1,fp);

            // store in output array, swap r ang b

            bmpimage[index]=bmppixel;

            if(n==(n1-1))

                  {

                  for(ipad=0;ipad<pad2;ipad++)

                        fread((char *)&btemp,sizeof(char),1,fp);

                  }

            } // m,n

}

fclose(fp);

return(1);

}

short mat5fltfileio(short iotype,char *filename,float *fltimage,unsigned long Nx,unsigned long My)

{

      FILE *fpflt;

      unsigned long Nindex;

      errno_t err;

      Nindex=Nx*My;

      if(iotype==0) //read in file

      {

            // open file

            err=fopen_s(&fpflt,filename,"rb");

            if(err!=0) return(0);

            fread((float *)fltimage,1,Nindex*sizeof(float),fpflt);

            fclose(fpflt);

            return(1);

      }

      if(iotype==1)

      {

            // open file

            err=fopen_s(&fpflt,filename,"wb");

            if(err!=0) return(0);

            fwrite((float *)fltimage,Nindex*sizeof(float),1,fpflt);

            fclose(fpflt);

            return(1);

      }

            return(-1);

}

 

F FORMAT, MAT5 IMBEDDED INTO BMP FORMAT

 

/*****************************************************/

//Copyright (c) 2009, University of Kentucky, Lexington
//All rights reserved.

//Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

//1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

//2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer

//   in the documentation and/or other materials provided with the distribution.

//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,

//BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

//IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,

//OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

//DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,

//OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Hassebrook copyright 2009, University of Kentucky copyright 2009

// initialized 8-19-09

// returns mat5 knowing that F exists

short fileF2mat5(char *mat5prefix,BMPPIXEL *bmpimageC,BMPPIXEL *bmpimageI,float *fltimageX,float *fltimageY,float *fltimageZ,unsigned long Nx,unsigned long My)

{

      char filename[512],btemp;

      BMPPIXEL black;

      BMPPIXEL32 bmppixel32;

      BMPHEADER bmphead;

      BMPINFOHEADER bmpinfohead;

      FILE *fp;

      unsigned long M1,N1,ipad,pad2,m,n,m1,index;

      float fltvalue;

      black.r=0;black.g=0;black.b=0;

      strcpy_ansi(filename,mat5prefix);

      strcat_ansi(filename,"F.bmp");

      // input BMP header

      errno_t err;

      err=fopen_s(&fp,filename,"rb");

      if(err!=0) return(0);

      fseek(fp,0,SEEK_SET);

      /* read the header */

      fread(&bmphead.ImageFileType,sizeof(bmphead.ImageFileType),1,fp);

      fread(&bmphead.FileSize,sizeof(bmphead.FileSize),1,fp);

      fread(&bmphead.reserved1,sizeof(bmphead.reserved1),1,fp);

      fread(&bmphead.reserved2,sizeof(bmphead.reserved2),1,fp);

      fread(&bmphead.ImageDataOffset,sizeof(bmphead.ImageDataOffset),1,fp);

      /* read the info header */

      fread(&bmpinfohead,sizeof(bmpinfohead),1,fp);

      // verify BMP

      if(bmphead.ImageFileType!=19778)

      {

            MessageBeep((WORD)-1);

            //MessageBox("INPUT BMP file is not 19778","Sorry.",MB_OK+MB_ICONSTOP);

            return(-1);

      }

      /* input header*/

      N1=bmpinfohead.ImageWidth;

      M1=bmpinfohead.ImageHeight;

      if((N1<1)||(M1<1)||(M1/4!=My)||(N1!=Nx)) {fclose(fp);return(0);}

      if(bmpinfohead.BitsPerPixel!=32)

      {

            fclose(fp);

            MessageBeep((WORD)-1);

            //sprintf(stemp,"INPUT BMP file has %d bits per pixel",bmpinfohead.BitsPerPixel);

            //MessageBox(stemp,"Sorry, this version only does 24 bits only.",MB_OK+MB_ICONSTOP);

            return(-2);

      }

      if(bmpinfohead.CompressionMethod!=0)

      {

            fclose(fp);

            MessageBeep((WORD)-1);

            //MessageBox("INPUT BMP file is compressed","Sorry,maybe next version.",MB_OK+MB_ICONSTOP);

            return(-3);

      }

      // goto data

      fseek(fp,bmphead.ImageDataOffset,SEEK_SET);

      // end of color table input

      if(bmpinfohead.BitsPerPixel==32)

      {

            pad2=4-(Nx*bmpinfohead.BitsPerPixel/8)%4; // bytes to pad each scan line so that it is a multiple of 4

            if(pad2==4) pad2=0;

      }

      // input Z matrix

      for(m=0;m<My;m++)

      for(n=0;n<Nx;n++)

      {

            m1=My-1-m;

            index=m1*Nx+n;

            fread((float *)&fltvalue,sizeof(float),1,fp);

            fltimageZ[index]=fltvalue;

            if(n==(Nx-1))

            {

                  for(ipad=0;ipad<pad2;ipad++) fread((char *)&btemp,sizeof(char),1,fp);

            }

      }

      // input Y matrix

      for(m=0;m<My;m++)

      for(n=0;n<Nx;n++)

      {

            m1=My-1-m;

            index=m1*Nx+n;

            fread((float *)&fltvalue,sizeof(float),1,fp);

            fltimageY[index]=fltvalue;

            if(n==(Nx-1))

            {

                  for(ipad=0;ipad<pad2;ipad++) fread((char *)&btemp,sizeof(char),1,fp);

            }

      }

      // input X matrix

      for(m=0;m<My;m++)

      for(n=0;n<Nx;n++)

      {

            m1=My-1-m;

            index=m1*Nx+n;

            fread((float *)&fltvalue,sizeof(float),1,fp);

            fltimageX[index]=fltvalue;

            if(n==(Nx-1))

            {

                  for(ipad=0;ipad<pad2;ipad++) fread((char *)&btemp,sizeof(char),1,fp);

            }

      }

      // store C and I image pixels

      for(m=0;m<My;m++)

      for(n=0;n<Nx;n++)

      {

            m1=My-1-m;

            index=m1*Nx+n;

            fread((BMPPIXEL32 *)&bmppixel32,sizeof(BMPPIXEL32),1,fp);

            bmpimageC[index].r=bmppixel32.r;

            bmpimageC[index].g=bmppixel32.g;

            bmpimageC[index].b=bmppixel32.b;

            bmpimageI[index].r=bmppixel32.blank;

            bmpimageI[index].g=bmppixel32.blank;

            bmpimageI[index].b=bmppixel32.blank;

            if(n==(Nx-1))

            {

                  btemp=0;

                  for(ipad=0;ipad<pad2;ipad++) fread((char *)&btemp,sizeof(char),1,fp);

            }

      }

      fclose(fp);

      return(0);

}