summaryrefslogtreecommitdiff
path: root/silx/io/specfile/src/sfwrite.c
diff options
context:
space:
mode:
Diffstat (limited to 'silx/io/specfile/src/sfwrite.c')
-rw-r--r--silx/io/specfile/src/sfwrite.c587
1 files changed, 587 insertions, 0 deletions
diff --git a/silx/io/specfile/src/sfwrite.c b/silx/io/specfile/src/sfwrite.c
new file mode 100644
index 0000000..4422ae0
--- /dev/null
+++ b/silx/io/specfile/src/sfwrite.c
@@ -0,0 +1,587 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfwrite.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions for scan output
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2003/09/12 13:20:35 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfwrite.c,v $
+ * Log: Revision 1.1 2003/09/12 13:20:35 rey
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:14 19:05:14 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+/*
+ * Declarations
+ */
+DllExport SpecFileOut *SfoInit ( SpecFile *sf, int *error );
+DllExport void SfoClose ( SpecFileOut *sfo );
+DllExport long SfoSelectAll ( SpecFileOut *sfo, int *error );
+DllExport long SfoSelectOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport long SfoSelect ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport long SfoSelectRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport long SfoRemoveOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport long SfoRemove ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport long SfoRemoveRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport long SfoRemoveAll ( SpecFileOut *sfo, int *error );
+DllExport long SfoWrite ( SpecFileOut *sfo, char *name,
+ int *error );
+DllExport long SfoGetList ( SpecFileOut *sfo, long **list,
+ int *error );
+
+/*
+ * Internal functions
+ */
+static int sfoWriteOne(SpecFileOut *sfo,int output, long index,int *error);
+
+
+/*********************************************************************
+ * Function: SpecFileOut *SfoInit( sf, error )
+ *
+ * Description: Initializes a SpecFileOut structure:
+ * - pointer to SpecFile
+ * - list of scans to be copied
+ * - size of this list
+ * - last written file header
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ *
+ * Output:
+ * (2) error number
+ * Returns:
+ * Pointer to the initialized SpecFileOut structure.
+ * NULL in case of an error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMOREY_ALLOC
+ *
+ * Remark: This function MUST be the FIRST called before
+ * any other WRITE function is called !
+ *
+ *********************************************************************/
+DllExport SpecFileOut *
+SfoInit( SpecFile *sf, int *error )
+{
+ SpecFileOut *sfo;
+
+ /*
+ * Alloc memory
+ */
+ sfo = (SpecFileOut *) malloc ( sizeof(SpecFileOut) );
+
+ if ( sfo == (SpecFileOut *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( (SpecFileOut *)NULL );
+ }
+
+ /*
+ * Initialize
+ */
+ sfo->sf = sf;
+ sfo->list = (long *)NULL;
+ sfo->list_size = 0;
+ sfo->file_header = -1;
+
+ return( sfo );
+}
+
+
+/*********************************************************************
+ * Function: long SfoGetList( sfo, list, error )
+ *
+ * Description: Makes a copy of the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ *
+ * Output: (2) Copy of the output list of spec scan indices.
+ * (3) error code
+ * Returns:
+ * Number of scan indices in the output list ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) in case of an error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMOREY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfoGetList( SpecFileOut *sfo, long **list, int *error )
+{
+ long i;
+
+ *list = (long *)NULL;
+
+ if ( sfo->list_size > 0 ) {
+ *list = (long *)malloc( sfo->list_size * sizeof(long) );
+ if ( *list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ for ( i=0 ; i < sfo->list_size ; i++ ) {
+ (*list)[i] = sfo->list[i];
+ }
+ } else *list = (long *)NULL;
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectOne( sfo, index, error )
+ *
+ * Description: Adds one scan index to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Scan index
+ * Output:
+ * (3) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectOne( SpecFileOut *sfo, long index, int *error )
+{
+ long i;
+
+ /*
+ * Check if index exists or if it's out of range.
+ */
+ if ( index > sfo->sf->no_scans || index < 1 ) {
+ return( sfo->list_size );
+ }
+
+ /*
+ * Alloc memory for the new index and add it to the list.
+ */
+ if ( sfo->list == (long *)NULL ) {
+ sfo->list = (long *)malloc( sizeof(long) );
+ if ( sfo->list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ sfo->list_size = 1;
+ } else {
+ /*
+ * Is the new index already in list ?
+ */
+ for ( i=0 ; i<sfo->list_size ; i++ )
+ if ( index == sfo->list[i] ) return( sfo->list_size );
+ sfo->list = realloc( sfo->list, ++(sfo->list_size) * sizeof(long) );
+ if ( sfo->list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ sfo->list_size = 0;
+ return( -1 );
+ }
+ }
+ sfo->list[sfo->list_size-1] = index;
+ printf("Adding scan %ld\n",index);
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelect( sfo, list, error )
+ *
+ * Description: Adds several scan indices to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) List scan indices (!The last element
+ * MUST be a '0' !)
+ * Output:
+ * (3) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoSelectOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoSelect( SpecFileOut *sfo, long *list, int *error )
+{
+ for ( ; *list != 0 ; list++ ) {
+ if ( SfoSelectOne( sfo, *list , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectRange( sfo, begin, end, error )
+ *
+ * Description: Adds scan indices between 'begin' and 'end'
+ * to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) First ...
+ * (3) Last index to be added
+ * Output:
+ * (4) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoSelectOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectRange( SpecFileOut *sfo, long begin, long end, int *error )
+{
+ long i;
+
+ if ( begin > end ) {
+ i=begin;
+ begin = end;
+ end = i;
+ }
+ if ( begin < 1 || end > sfo->sf->no_scans ) {
+ return( sfo->list_size );
+ }
+ for ( i=begin ; i<=end ; i++ ) {
+ if ( SfoSelectOne( sfo, i , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectAll( sfo, error )
+ *
+ * Description: Writes all scan indices in the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOutput pointer
+ * Output: (2) error number
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectAll( SpecFileOut *sfo, int *error )
+{
+ long i;
+
+ if ( sfo->sf->no_scans > 0 ) {
+ for ( i=1 ; i<=sfo->sf->no_scans ; i++ ) {
+ if ( SfoSelectOne( sfo, i , error ) < 0 ) return( -1 );
+ }
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveOne( sfo, index, error )
+ *
+ * Description: Removes one scan index from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Scan index to be removed
+ * Output:
+ * (3) error code
+ * Returns:
+ * Number of scans left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveOne( SpecFileOut *sfo, long index, int *error )
+{
+ long i;
+ int found = 0;
+
+ /*
+ * Look for scan index and delete.
+ */
+ for ( i=0 ; i < (sfo->list_size - found) ; i++ ) {
+ if ( sfo->list[i] == index ) found = 1;
+ if ( found ) sfo->list[i]=sfo->list[i+1];
+ }
+
+ /*
+ * Free unused memory
+ */
+ if ( found ) {
+ (sfo->list_size)--;
+ sfo->list = realloc( sfo->list, sfo->list_size * sizeof(long) );
+ if ( sfo->list == (long *)NULL && sfo->list_size != 0 ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemove( sfo, list, error )
+ *
+ * Description: Removes several scans indices from the
+ * SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) List of scan indices to be removed
+ * ( !!! The last element MUST be a '0' !!! )
+ * Output:
+ * (3) error code
+ * Returns:
+ * Number of scan indices left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoRemoveOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoRemove( SpecFileOut *sfo, long *list, int *error )
+{
+ for ( ; *list != 0 ; list++ ) {
+ if ( SfoRemoveOne( sfo, *list , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveRange( sfo, begin, end, error )
+ *
+ * Description: Removes scans indices from 'begin' to 'end'
+ * from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input :
+ * (1) SpecFileOut pointer
+ * (2) First ...
+ * (3) Last index to be removed
+ * Output:
+ * (4) error code
+ * Returns:
+ * Number of scan indices left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoRemoveOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveRange( SpecFileOut *sfo, long begin, long end, int *error )
+{
+ long i;
+
+ if ( begin > end ) {
+ i=begin;
+ begin = end;
+ end = i;
+ }
+ if ( begin < 1 || end > sfo->sf->no_scans ) {
+ return( sfo->list_size );
+ }
+ for ( i=begin ; i <= end ; i++ ) {
+ if ( SfoRemoveOne( sfo, i, error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveAll( sfo, error )
+ *
+ * Description: Removes all scans indices
+ * from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input :
+ * (1) SpecFileOut pointer
+ * Output:
+ * (2) error code
+ * Returns:
+ * ( 0 ) => OK
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveAll( SpecFileOut *sfo, int *error )
+{
+ free( sfo->list );
+ sfo->list = (long *)NULL;
+ sfo->list_size = 0;
+ sfo->file_header = -1;
+ return( 0 );
+}
+
+
+/*********************************************************************
+ * Function: int SfoWrite( sfo, name, error )
+ *
+ * Description: Writes (appends) SpecScans specified in the sfo->list
+ * in the file 'name'. Related file headers are copied
+ * too.
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Output file name
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of written scans,
+ * (-1 ) => Errors occured
+ * Possible errors:
+ * SF_ERR_FILE_WRITE | => cpyBlock()
+ * SF_ERR_FILE_READ
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_FILE_CLOSE
+ *
+ *********************************************************************/
+DllExport long
+SfoWrite( SpecFileOut *sfo, char *name, int *error )
+{
+ int output;
+ long i;
+
+ if ( sfo == (SpecFileOut *)NULL || sfo->list_size<1 ) return( 0 );
+
+ /*
+ * Open file
+ */
+ if ( (output = open(name, O_CREAT | O_RDWR | O_APPEND, SF_UMASK )) == (int)NULL ) {
+ *error = SF_ERR_FILE_OPEN;
+ return( -1 );
+ }
+
+ for ( i=0 ; i < sfo->list_size ; i++ )
+ sfoWriteOne(sfo,output,sfo->list[i],error);
+
+ if ( close( output ) ) {
+ *error = SF_ERR_FILE_CLOSE;
+ return( -1 );
+ }
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: int SfoClose( sfo )
+ *
+ * Description: Frees all memory used by
+ * SpecFileOut structure.
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ *
+ * Remark: This function should be called after all
+ * writing operations.
+ *
+ *********************************************************************/
+DllExport void
+SfoClose( SpecFileOut *sfo )
+{
+ /*
+ * Free memory.
+ */
+ free( sfo->list );
+ free( sfo );
+}
+
+
+static int
+sfoWriteOne(SpecFileOut *sfo,int output,long index,int *error)
+{
+ long file_header,size;
+ SpecFile *sf;
+
+ if ( sfSetCurrent(sfo->sf,index,error) == -1 ) {
+ *error = SF_ERR_SCAN_NOT_FOUND;
+ return(-1);
+ }
+
+ /*
+ * File header
+ */
+ sf = sfo->sf;
+
+ file_header = ((SpecScan *)sf->current->contents)->size;
+
+ if (file_header != -1 && file_header != sfo->file_header ) {
+ printf("Writing %ld bytes\n",sf->filebuffersize);
+ write(output, (void *) sf->filebuffer, sf->filebuffersize);
+ sfo->file_header = file_header;
+ }
+
+ /*
+ * write scan
+ */
+ size = ((SpecScan *)sf->current->contents)->size;
+
+ if ( write(output,(void *) sf->scanbuffer,size) == -1 ) {
+ *error = SF_ERR_FILE_WRITE;
+ return(-1);
+ }
+ return(0);
+}