Commit 5dce32d9 authored by Robert Butora's avatar Robert Butora
Browse files

adds alternative path to libtango and adds (missing?) linker reference to libcfitsio

parent b48ae61d
Loading
Loading
Loading
Loading

src/dataunitsum.cpp

0 → 100644
+166 −0
Original line number Diff line number Diff line
#include <stdio.h>
#include <string>
#include <boost/filesystem.hpp>
#include <openssl/md5.h>

#include "fitsio.h"


// computes datasum over DataUnits of all HDU's of a FITS-file


int hdu_count(const char * filename)
{
  int lasthdu = 0;/* hdu count: 1..lasthdu */
  int status = 0;
  fitsfile *fptr;

  if( fits_open_file(&fptr, filename, READONLY, &status) ) goto f_end;
  if( fits_get_num_hdus(fptr, &lasthdu, &status) ) goto f_end; 
f_end:
  fits_close_file(fptr, &status);// no err check, we read only 

  return lasthdu;
}

struct du_offs
{
	long int datastart;
	long int dataend;
};

void init_du_offsets(int nhdu, struct du_offs * duoffs)
{
  for (int ix = 0; ix < nhdu; ix++)
  {
	duoffs[ix].datastart = (long int)0; 
	duoffs[ix].dataend   = (long int)0;
  } 
}

int du_offsets(const char * filename, int nhdu, struct du_offs * duoffs)
{
  int status = 0;
  fitsfile *fptr;
  int hdunum, hdutype;

  if( fits_open_file(&fptr, filename, READONLY, &status) ) goto f_end;

  for (hdunum = 1; hdunum <= nhdu; hdunum++)
  {
            if ( fits_movabs_hdu(fptr, hdunum, &hdutype, &status) ) goto f_end;

    	    LONGLONG headstart, datastart, dataend;

            if( fits_get_hduaddrll (fptr, &headstart, &datastart, &dataend, &status) ) goto f_end;
	    
	    int ix = hdunum - 1;

 	    // FIXME cast LONGLONG -> long int (here both 64 bit)
	    duoffs[ix].datastart = (long int)datastart;	    
	    duoffs[ix].dataend   = (long int)dataend;
  }

f_end:
  fits_close_file(fptr, &status);// no err check, we read only 
  return status;
}


std::string calcDigest(const char * filename, int nhdu, struct du_offs * duoffs)
{
  char mdString[33] = "";
  unsigned char digest[MD5_DIGEST_LENGTH];
  int nbytes, hdunum;
  unsigned char block[2880];
 
  FILE *inFile = fopen(filename,"rb");
  if(inFile == NULL) goto f_end;

  MD5_CTX mdContext;
  MD5_Init (&mdContext);

  for (hdunum = 1; hdunum <= nhdu; hdunum++)
  {
	    int ix = hdunum - 1;
           
	    long int datastart = duoffs[ix].datastart;
	    long int dataend   = duoffs[ix].dataend;

            long int nrec = (dataend - datastart) / 2880;

	    if(nrec > 0)
            {

                    // backup
                    long int offbup = ftell(inFile);
		    if(offbup <0) goto f_end;

                    // accumulate over DUs
                    if(0 != fseek(inFile,datastart,SEEK_SET)) goto f_end;
		    
                    for(long int r=0; r<nrec; r++)
                    {
                        nbytes = fread (block, 1, 2880, inFile);
                        if(nbytes != 2880)
			{
				MD5_Final(digest,&mdContext);
				goto f_end;
			}
                        MD5_Update (&mdContext, block, nbytes);
                    }

                    // restore
                    if(0 != fseek(inFile,offbup,SEEK_SET)) goto f_end;
           }
  }

  MD5_Final (digest,&mdContext);

  /* convert digest to string */
  int i;
  for(i = 0; i < MD5_DIGEST_LENGTH; i++)
       sprintf(&mdString[i*2], "%02x", (unsigned int)digest[i]);

f_end:
  fclose (inFile);

  return mdString;
}




std::string compute_dataunitsum(const std::string& fileName)
{
  const char *filename = fileName.c_str();

  const int hducnt = hdu_count(filename);

  struct du_offs * duoffs = new struct du_offs[hducnt];
  init_du_offsets(hducnt,duoffs);

  int rc = du_offsets(filename, hducnt, duoffs);

  if(rc == 0)
  {
  	std::string dusum = calcDigest(filename, hducnt, duoffs);
  	delete[] duoffs;
	return dusum;
  }
  else
  {
  	delete[] duoffs;
	return "";
  }
}









src/dataunitsum.h

0 → 100644
+22 −0
Original line number Diff line number Diff line
#ifndef FILEDATASUM_H
#define FILEDATASUM_H

#ifdef __cplusplus
// extern "C" {
#endif



// computes datasum over all DataUnits of a FITS-file
// should any error occur, returns empty string
std::string compute_dataunitsum(const std::string& fileName);


#ifdef __cplusplus
//}
#endif



#endif