/*
C source file to access the IDE SIMS data files.
A file named c_code.c is avaiable in case of
download difficulties.
Author: Klaus G. Paul
kpaul@qm.aif.ncsu.edu AND kpaul@asterix.lrt.mw.tu-muenchen.de
(the second address has forwarding to my actual current address)
Purpose: Access and dump IDE SIMS data file from IDE SIMS database
Language: Plain C (more ANSI than K&R)
Runs on: Tested on the following platforms:
- DOS-PC 486 [cl]
- SUN IPX/ELC, SunOS [used gcc, cc had a problem]
- DECstation 3100,Ultrix 4.3 (MIPS) [cc and gcc]
- DEC Alpha AXP,OSF/1.3 [cc]
- HP 730 HP-UX [c89, cc -a]
... and it worked *WITHOUT* *ANY* changes on all of them.
Notes: * All data is in Intel data format. Nevertheless, machine-in-
dependent conversion routines are supplied.
* The compiler used for creation of the database inserted some
filler bytes into the structures I used. See the header file
for reading (and skipping) these bytes.
* This program dumps all stored parameters to the screen and
creates data files for the mass data containing x, y and z
triplet lines ready to plot e.g. with GNU plot.
* Excuse the lack of comments. I feel that the program is quite
straightforward. The only two things that are of concern are
data type conversion from Intel to machine type, which is
documented in ALMOST EVERY book on Intel processors; the RLE-
type conversion is documented in the subroutine (yes, my back-
ground is FORTRAN) void UncompressImage.
*/
/*
USE POSIX/ANSI compliant C-compiler
compiler tested
DECstation 3100 MIPS Ultrix 4.3 cc, gcc 4/9/94
HP 730 HP-UX c89, cc -a 4/9/94
DEC Alpha OSF/1.3 cc 4/9/94
Sun IPX/ELC SunOS gcc 4/9/94
*/
#include <memory.h>
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#ifndef max
#define max(a,b) (((a)>(b))?(a):(b))
#endif
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#define I80x86WORD_SIZE (2)
#define I80x86INT_SIZE (2)
#define I80x86DWORD_SIZE (4)
#define I80x86FLOAT_SIZE (4)
typedef unsigned char CHAR;
typedef unsigned int WORD;
typedef int INT;
typedef unsigned long int DWORD;
typedef float FLOAT;
typedef unsigned char i80x86CHAR;
typedef unsigned short int i80x86WORD;
typedef short int i80x86INT;
typedef unsigned long int i80x86DWORD;
typedef DWORD i80x86FLOAT;
int iINTSize, iWORDSize, iDWORDSize, iFLOATSize;
CHAR i80x86CHAR_to_CHAR ( i80x86CHAR c )
{
return ((CHAR) c );
}
INT i80x86INT_to_INT ( i80x86INT w )
{
INT integer;
unsigned char *p;
p = (unsigned char *) &w;
integer = ((WORD) *p) + ((WORD) (*(p+1) << 8));
return (integer);
}
WORD i80x86WORD_to_WORD ( i80x86WORD w )
{
WORD word;
unsigned char *p;
p = (unsigned char *) &w;
word = ((WORD) *p) + ((WORD)(*(p+1) << 8));
return (word);
}
DWORD i80x86DWORD_to_DWORD ( i80x86DWORD dw )
{
DWORD dword;
unsigned char *p;
p = (unsigned char *) &dw;
dword = ((DWORD) *p) +
((DWORD)(*(p+1) << 8L)) +
((DWORD)(*(p+2) << 16L)) +
((DWORD)(*(p+3) << 24L));
return (dword);
}
FLOAT i80x86FLOAT_to_FLOAT ( i80x86FLOAT f )
{
int sign = 0;
FLOAT mantissa = 0;
int exponent = 0;
int i;
DWORD j;
if ( f == 0 )
return ( 0.0 );
f = i80x86DWORD_to_DWORD ( f );
sign = (f & 0x80000000)? -1 : 1;
for ( i = 23, j = 1 ; i <= 30 ; i++, j <<= 1 )
if (f & (1L << i))
exponent += j;
exponent = exponent-127;
for ( i = 22, j = 2 ; i >= 0 ; i--, j <<= 1 )
if (f & (1L << i))
mantissa += 1.0 / j;
mantissa += 1;
return ( sign * mantissa * ( 1L << exponent ) );
}
int DumpHeader ( FILE *IDEFile )
{
i80x86INT iPrimaryIonsUsed;
i80x86INT iPrimaryIonPolarity;
i80x86INT iSecondaryIonPolarity;
i80x86INT iPrimaryBeamCurrent;
i80x86INT iAccelerationVoltage;
i80x86INT iPrimaryAccelVoltage;
i80x86INT iRasterSize;
i80x86INT iTransferOpticsSetting;
i80x86INT iEnergySlitSetting;
i80x86INT iEnergySlitTranslation;
i80x86FLOAT fEntranceSlitSetting;
i80x86FLOAT fExitSlitSetting;
i80x86INT iFieldAperture;
i80x86INT iContrastAperture;
i80x86INT iRasterPotSetting;
i80x86INT iXDimension;
i80x86INT iYDimension;
i80x86INT iNImages;
i80x86INT iDate;
CHAR szInstrument[50];
CHAR szFeatureName[40];
i80x86FLOAT fXCoordinate;
i80x86FLOAT fXCoordinateError;
i80x86FLOAT fYCoordinate;
i80x86FLOAT fYCoordinateError;
CHAR cBay;
i80x86INT iRow;
CHAR szAnnotations[3*80];
i80x86WORD wDetectorID;
i80x86WORD wFeatureNum;
CHAR szFeatureTypeCode[5];
CHAR szDetectorTypeDesc[50];
CHAR szFeatureTypeDesc[50];
CHAR szFeatureOriginCode[5];
CHAR szFeatureOriginDesc[50];
CHAR szJSCCode[15];
i80x86WORD wCentralCraterDiameterX;
i80x86WORD wCentralCraterDiameterY;
i80x86WORD wDisChargeDiameterX;
i80x86WORD wDisChargeDiameterY;
i80x86WORD wCentralCraterFusedX;
i80x86WORD wCentralCraterFusedY;
i80x86WORD wInnerSpall;
i80x86WORD wOuterSpall;
i80x86WORD wPhotoCode;
i80x86WORD wAnalysesCode;
i80x86DWORD dwMosaicXRefCode;
CHAR szEDSFileName[100];
CHAR szAESFileName[100];
CHAR szPROFileName[100];
CHAR szBRGFileName[100];
CHAR szRATFileName[100];
CHAR szExperimentName[10];
CHAR bReserved[1000-715];
char cFill;
fread ( &iPrimaryIonsUsed, I80x86INT_SIZE, 1, IDEFile );
printf ( "iPrimaryIonsUsed %i\n", i80x86INT_to_INT ( iPrimaryIonsUsed ) );
fread ( &iPrimaryIonPolarity, I80x86INT_SIZE, 1, IDEFile );
printf ( "iPrimaryIonPolarity %i\n", i80x86INT_to_INT ( iPrimaryIonPolarity ) );
fread ( &iSecondaryIonPolarity, I80x86INT_SIZE, 1, IDEFile );
printf ( "iSecondaryIonPolarity %i\n", i80x86INT_to_INT ( iSecondaryIonPolarity ) );
fread ( &iPrimaryBeamCurrent, I80x86INT_SIZE, 1, IDEFile );
printf ( "iPrimaryBeamCurrent %i\n", i80x86INT_to_INT ( iPrimaryBeamCurrent ) );
fread ( &iAccelerationVoltage, I80x86INT_SIZE, 1, IDEFile );
printf ( "iAccelerationVoltage %i\n", i80x86INT_to_INT ( iAccelerationVoltage ) );
fread ( &iPrimaryAccelVoltage, I80x86INT_SIZE, 1, IDEFile );
printf ( "iPrimaryAccelVoltage %i\n", i80x86INT_to_INT ( iPrimaryAccelVoltage ) );
fread ( &iRasterSize, I80x86INT_SIZE, 1, IDEFile );
printf ( "iRasterSize %i\n", i80x86INT_to_INT ( iRasterSize ) );
fread ( &iTransferOpticsSetting, I80x86INT_SIZE, 1, IDEFile );
printf ( "iTransferOpticsSetting %i\n", i80x86INT_to_INT ( iTransferOpticsSetting ) );
fread ( &iEnergySlitSetting, I80x86INT_SIZE, 1, IDEFile );
printf ( "iEnergySlitSetting %i\n", i80x86INT_to_INT ( iEnergySlitSetting ) );
fread ( &iEnergySlitTranslation, I80x86INT_SIZE, 1, IDEFile );
printf ( "iEnergySlitTranslation %i\n", i80x86INT_to_INT ( iEnergySlitTranslation ) );
fread ( &fEntranceSlitSetting, I80x86FLOAT_SIZE, 1, IDEFile );
printf ( "fEntranceSlitSetting %f\n", i80x86FLOAT_to_FLOAT ( fEntranceSlitSetting ) );
fread ( &fExitSlitSetting, I80x86FLOAT_SIZE, 1, IDEFile );
printf ( "fExitSlitSetting %f\n", i80x86FLOAT_to_FLOAT ( fExitSlitSetting ) );
fread ( &iFieldAperture, I80x86INT_SIZE, 1, IDEFile );
printf ( "iFieldAperture %i\n", i80x86INT_to_INT ( iFieldAperture ) );
fread ( &iContrastAperture, I80x86INT_SIZE, 1, IDEFile );
printf ( "iContrastAperture %i\n", i80x86INT_to_INT ( iContrastAperture ) );
fread ( &iRasterPotSetting, I80x86INT_SIZE, 1, IDEFile );
printf ( "iRasterPotSetting %i\n", i80x86INT_to_INT ( iRasterPotSetting ) );
fread ( &iXDimension, I80x86INT_SIZE, 1, IDEFile );
printf ( "iXDimension %i\n", i80x86INT_to_INT ( iXDimension ) );
fread ( &iYDimension, I80x86INT_SIZE, 1, IDEFile );
printf ( "iYDimension %i\n", i80x86INT_to_INT ( iYDimension ) );
fread ( &iNImages, I80x86INT_SIZE, 1, IDEFile );
iNImages = i80x86INT_to_INT ( iNImages );
printf ( "iNImages %i\n", iNImages );
fread ( &iDate, I80x86INT_SIZE, 1, IDEFile );
printf ( "iDate %i\n", i80x86INT_to_INT ( iDate ) );
fread ( szInstrument, sizeof (szInstrument ), 1, IDEFile );
printf ( "szInstrument %s\n", szInstrument );
fread ( szFeatureName, sizeof (szFeatureName ), 1, IDEFile );
printf ( "szFeatureName %s\n", szFeatureName );
fread ( &fXCoordinate, I80x86FLOAT_SIZE, 1, IDEFile );
printf ( "fXCoordinate %f\n", i80x86FLOAT_to_FLOAT ( fXCoordinate ) );
fread ( &fXCoordinateError, I80x86FLOAT_SIZE, 1, IDEFile );
printf ( "fXCoordinateError %f\n", i80x86FLOAT_to_FLOAT ( fXCoordinateError ) );
fread ( &fYCoordinate, I80x86FLOAT_SIZE, 1, IDEFile );
printf ( "fYCoordinate %f\n", i80x86FLOAT_to_FLOAT ( fYCoordinate ) );
fread ( &fYCoordinateError, I80x86FLOAT_SIZE, 1, IDEFile );
printf ( "fYCoordinateError %f\n", i80x86FLOAT_to_FLOAT ( fYCoordinateError ) );
fread ( &cBay, 1, 1, IDEFile );
printf ( "cBay %c\n", cBay );
/* !!!!!!!!!!!!! */
fread ( &cFill, 1, 1, IDEFile );
fread ( &iRow, I80x86INT_SIZE, 1, IDEFile );
printf ( "iRow %i\n", i80x86INT_to_INT ( iRow ) );
fread ( szAnnotations, sizeof (szAnnotations ), 1, IDEFile );
printf ( "szAnnotations %s\n", szAnnotations );
fread ( &wDetectorID, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wDetectorID %u\n", i80x86WORD_to_WORD ( wDetectorID ) );
fread ( &wFeatureNum, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wFeatureNum %u\n", i80x86WORD_to_WORD ( wFeatureNum ) );
fread ( szFeatureTypeCode, sizeof (szFeatureTypeCode ), 1, IDEFile );
printf ( "szFeatureTypeCode %s\n", szFeatureTypeCode );
fread ( szDetectorTypeDesc, sizeof (szDetectorTypeDesc ), 1, IDEFile );
printf ( "szDetectorTypeDesc %s\n", szDetectorTypeDesc );
fread ( szFeatureTypeDesc, sizeof (szFeatureTypeDesc ), 1, IDEFile );
printf ( "szFeatureTypeDesc %s\n", szFeatureTypeDesc );
fread ( szFeatureOriginCode, sizeof (szFeatureOriginCode ), 1, IDEFile );
printf ( "szFeatureOriginCode %s\n", szFeatureOriginCode );
fread ( szFeatureOriginDesc, sizeof (szFeatureOriginDesc ), 1, IDEFile );
printf ( "szFeatureOriginDesc \n", szFeatureOriginDesc );
fread ( szJSCCode, sizeof (szJSCCode ), 1, IDEFile );
printf ( "szJSCCode %s\n", szJSCCode );
/* !!!!!!!!!!!!! */
fread ( &cFill, 1, 1, IDEFile );
fread ( &wCentralCraterDiameterX, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wCentralCraterDiameterX %u\n", i80x86WORD_to_WORD ( wCentralCraterDiameterX ) );
fread ( &wCentralCraterDiameterY, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wCentralCraterDiameterY %u\n", i80x86WORD_to_WORD ( wCentralCraterDiameterY ) );
fread ( &wDisChargeDiameterX, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wDisChargeDiameterX %u\n", i80x86WORD_to_WORD ( wDisChargeDiameterX ) );
fread ( &wDisChargeDiameterY, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wDisChargeDiameterY %u\n", i80x86WORD_to_WORD ( wDisChargeDiameterY ) );
fread ( &wCentralCraterFusedX, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wCentralCraterFusedX %u\n", i80x86WORD_to_WORD ( wCentralCraterFusedX ) );
fread ( &wCentralCraterFusedY, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wCentralCraterFusedY %u\n", i80x86WORD_to_WORD ( wCentralCraterFusedY ) );
fread ( &wInnerSpall, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wInnerSpall %u\n", i80x86WORD_to_WORD ( wInnerSpall ) );
fread ( &wOuterSpall, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wOuterSpall %u\n", i80x86WORD_to_WORD ( wOuterSpall ) );
fread ( &wPhotoCode, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wPhotoCode %u\n", i80x86WORD_to_WORD ( wPhotoCode ) );
fread ( &wAnalysesCode, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wAnalysesCode %u\n", i80x86WORD_to_WORD ( wAnalysesCode ) );
fread ( &dwMosaicXRefCode, I80x86DWORD_SIZE, 1, IDEFile );
printf ( "dwMosaicXRefCode %lu\n", i80x86DWORD_to_DWORD ( dwMosaicXRefCode ) );
fread ( szEDSFileName, sizeof (szEDSFileName ), 1, IDEFile );
printf ( "szEDSFileName %s\n", szEDSFileName );
fread ( szAESFileName, sizeof (szAESFileName ), 1, IDEFile );
printf ( "szAESFileName %s\n", szAESFileName );
fread ( szPROFileName, sizeof (szPROFileName ), 1, IDEFile );
printf ( "szPROFileName %s\n", szPROFileName );
fread ( szBRGFileName, sizeof (szBRGFileName ), 1, IDEFile );
printf ( "szBRGFileName %s\n", szBRGFileName );
fread ( szRATFileName, sizeof (szRATFileName ), 1, IDEFile );
printf ( "szRATFileName %s\n", szRATFileName );
fread ( szExperimentName, sizeof (szExperimentName ), 1, IDEFile );
printf ( "szExperimentName %s\n", szExperimentName );
fread ( bReserved, sizeof (bReserved), 1, IDEFile );
/* !!!!!!!!!!!!! */
fread ( &cFill, 1, 1, IDEFile );
return ( iNImages );
}
/*
The image data occupies 256*256 16-bit values. Since most of the
pixels, i.e. data values, are black, i.e. 0, a primitive run-length
encoder saved tens of megabytes in the IDE database. Instead of storing a
black pixel as a 0 word, all black values are combined and stored as
a word containing a 0 and a word containing a repeat factor.
Example:
IDE RLE-compressed image data:
12 0 5 42 554 0 7 2 55 4455 12 0 312 3 ....
would decompress as
12 0 0 0 0 0 42 554 0 0 0 0 0 0 0 2 55 4455 12 0 0 0 0 0 0 0 0 0 0 0 0.....
(5 zeroes) (7 zeroes)
All data values are 16-bit words, unsigned
*/
void UncompressImage ( FILE *IDEFile, int iNum, INT iMass,
DWORD dwCompressedImageSize,
INT iXShift, INT iYShift )
{
unsigned long m = 0, n = 0;
WORD data = 0, count = 0, k = 0;
int x = 0, y = 0;
char szBuffer[255];
FILE *f;
sprintf ( szBuffer, "im%02u-%03u", iNum , iMass );
f = fopen ( szBuffer, "w+t" );
for ( n = 0, m = 0 ; n < dwCompressedImageSize ; n++ )
{
fread ( &data, I80x86WORD_SIZE, 1, IDEFile );
data = i80x86DWORD_to_DWORD ( data );
if ( data == 0 )
{
fread ( &count, I80x86WORD_SIZE, 1, IDEFile );
count = i80x86DWORD_to_DWORD ( count );
n++;
for ( k = 0 ; k < count ; k++, m++ )
{
x = m % 256 + iXShift;
x = max ( x , 0 );
x = min ( x , 255 );
y = m / 256 + iYShift;
y = max ( y , 0 );
y = min ( y , 255 );
fprintf ( f, "%i %i 0\n", x, y, data );
}
}
else
{
x = m % 256 + iXShift;
y = m / 256 + iYShift;
fprintf ( f, "%i %i %u\n", x, y, data );
m++;
}
}
fclose ( f );
}
void DumpImage ( FILE *IDEFile, int iNum )
{
i80x86FLOAT fCpGain;
i80x86INT iNFrames;
i80x86INT iMass;
i80x86INT iImageNumber;
i80x86DWORD dwCompressedImageSize;
i80x86DWORD dwTotalCount;
i80x86WORD wMaxCount;
i80x86INT iXShift;
i80x86INT iYShift;
CHAR szElementName[20];
i80x86INT iElementID;
i80x86FLOAT fRSF;
i80x86INT iQualityElementClassification;
i80x86INT iObsolete1;
i80x86INT iObsolete2;
i80x86INT iObsolete3;
i80x86INT iObsolete4;
printf ( "\n" );
fread ( &fCpGain, I80x86FLOAT_SIZE, 1, IDEFile );
printf ( "fCpGain %f\n", i80x86FLOAT_to_FLOAT ( fCpGain ) );
fread ( &iNFrames, I80x86INT_SIZE, 1, IDEFile );
printf ( "iNFrames %i\n", i80x86INT_to_INT ( iNFrames ) );
fread ( &iMass, I80x86INT_SIZE, 1, IDEFile );
iMass = i80x86INT_to_INT ( iMass );
printf ( "iMass %i\n", iMass );
fread ( &iImageNumber, I80x86INT_SIZE, 1, IDEFile );
printf ( "iImageNumber %i\n", i80x86INT_to_INT ( iImageNumber ) );
fread ( &dwCompressedImageSize, I80x86DWORD_SIZE, 1, IDEFile );
dwCompressedImageSize = i80x86DWORD_to_DWORD ( dwCompressedImageSize );
printf ( "dwCompressedImageSize %lu\n", dwCompressedImageSize );
fread ( &dwTotalCount, I80x86DWORD_SIZE, 1, IDEFile );
printf ( "dwTotalCount %lu\n", i80x86DWORD_to_DWORD ( dwTotalCount ) );
fread ( &wMaxCount, I80x86WORD_SIZE, 1, IDEFile );
printf ( "wMaxCount %u\n", i80x86WORD_to_WORD ( wMaxCount ) );
fread ( &iXShift, I80x86INT_SIZE, 1, IDEFile );
iXShift = i80x86INT_to_INT ( iXShift );
printf ( "iXShift %i\n", iXShift );
fread ( &iYShift, I80x86INT_SIZE, 1, IDEFile );
iYShift = i80x86INT_to_INT ( iYShift );
printf ( "iYShift %i\n", i80x86INT_to_INT ( iYShift ) );
fread ( szElementName, sizeof (szElementName), 1, IDEFile );
printf ( "szElementName %s\n", szElementName );
fread ( &iElementID, I80x86INT_SIZE, 1, IDEFile );
printf ( "iElementID %i\n", i80x86INT_to_INT ( iElementID ) );
fread ( &fRSF, I80x86FLOAT_SIZE, 1, IDEFile );
printf ( "fRSF %f\n", i80x86FLOAT_to_FLOAT ( fRSF ) );
fread ( &iQualityElementClassification, I80x86INT_SIZE, 1, IDEFile );
printf ( "iQualityElementClassification %i\n", i80x86INT_to_INT ( iQualityElementClassification ) );
fread ( &iObsolete1, I80x86INT_SIZE, 1, IDEFile );
fread ( &iObsolete2, I80x86INT_SIZE, 1, IDEFile );
fread ( &iObsolete3, I80x86INT_SIZE, 1, IDEFile );
fread ( &iObsolete4, I80x86INT_SIZE, 1, IDEFile );
UncompressImage ( IDEFile, iNum, iMass, dwCompressedImageSize,
iXShift, iYShift );
}
main ( int argc, char **argv )
{
FILE *IDEFile;
int i, iNumImages;
if ( argc != 2 )
{
fprintf ( stderr, "Usage: dumpdata.c <IDE-FILENAME>\n" );
exit ( 1 );
}
if ( ( IDEFile = fopen ( argv[1], "rb" ) ) == NULL )
{
fprintf ( stderr, "Unable to access IDE file %s\n", argv[1] );
exit ( 1 );
}
iNumImages = DumpHeader ( IDEFile );
for ( i = 0 ; i < iNumImages ; i++ )
DumpImage ( IDEFile, i );
exit ( 0 );
}