/*****************************************************************************
Major portions of this software are copyrighted by the Medical College
of Wisconsin, 1994-2000, and are released under the Gnu General Public
License, Version 2. See the file README.Copyright for details.
******************************************************************************/
#include "thd_compress.h"
#include "Amalloc.h"
/*** check if the file exists on disk
-- returns 1 if it does, 0 if it does not ***/
int COMPRESS_is_file( char * pathname )
{
static struct stat buf ;
int ii ;
if( pathname == NULL ) return 0 ;
ii = stat( pathname , &buf ) ; if( ii != 0 ) return 0 ;
ii = (buf.st_mode & S_IFREG) != 0 ; return ii ;
}
/*--------------------------------------------------------------*/
/*** check if the filename has the apposite
suffix for the compression mode given ***/
int COMPRESS_has_suffix( char * fname , int mode )
{
int ll ;
if( mode < 0 ) return 1 ;
if( mode > COMPRESS_LASTCODE ) return 0 ;
ll = strlen(fname) ;
return ( ll > COMPRESS_suffix_len[mode] &&
strcmp(COMPRESS_suffix[mode] ,
fname+(ll-COMPRESS_suffix_len[mode])) == 0 ) ;
}
/*--------------------------------------------------------------*/
/*** return the compression code for the given filename;
if the file doesn't exist, will return COMPRESS_NOFILE ***/
int COMPRESS_filecode( char * fname )
{
int ii ;
char * buf ;
if( fname == NULL || fname[0] == '\0' ) return COMPRESS_NOFILE ;
/** check the filename suffix **/
for( ii=0 ; ii <= COMPRESS_LASTCODE ; ii++ ){
if( COMPRESS_has_suffix(fname,ii) ){
if( COMPRESS_is_file(fname) ) return ii ;
else return COMPRESS_NOFILE ;
}
}
if( COMPRESS_is_file(fname) ) return COMPRESS_NONE ;
/** add the suffixes to the name, and check again **/
buf = AFMALL(char, sizeof(char) * (strlen(fname)+16) ) ;
for( ii=0 ; ii <= COMPRESS_LASTCODE ; ii++ ){
strcpy(buf,fname) ; strcat(buf,COMPRESS_suffix[ii]) ;
if( COMPRESS_is_file(buf) ){ free(buf) ; return ii ; }
}
free(buf) ; return COMPRESS_NOFILE ;
}
/*--------------------------------------------------------------*/
/*** keep a table of which open files used fopen and which
used popen -- because they must be closed differently ***/
#define NFOPMAX 16
static int fop_init = 0 ;
static int fop_fileno[NFOPMAX] ;
static int fop_popend[NFOPMAX] ;
static void putin_fop_table( FILE * fp , int ppp )
{
int ii ;
if( fp == NULL ) return ; /* can't do much with nothing */
if( ! fop_init ){ /* initialize the table */
for( ii=0 ; ii < NFOPMAX ; ii++ ){
fop_fileno[ii] = -1 ;
fop_popend[ii] = 0 ;
}
fop_init = 1 ;
}
for( ii=0 ; ii < NFOPMAX ; ii++ ) /* find an unused entry */
if( fop_fileno[ii] < 0 ) break ;
if( ii == NFOPMAX ){
fprintf(stderr,"\n*** AFNI compressor table overflow!\n") ;
return ;
}
fop_fileno[ii] = fileno(fp) ; /* save the file number */
fop_popend[ii] = ppp ; /* save the popen code */
return ;
}
/*** Use this to close a file,
so that pclose or fclose can be called correctly ***/
int COMPRESS_fclose( FILE * fp )
{
int fn , ii ;
if( fp == NULL || ! fop_init ) return fclose(fp) ;
fn = fileno(fp) ;
for( ii=0 ; ii < NFOPMAX ; ii++ ){ /* find the file number */
if( fop_fileno[ii] == fn ){ /* found it! */
fop_fileno[ii] = -1 ; /* empty this table entry */
if( fop_popend[ii] ) return pclose(fp) ;
else return fclose(fp) ;
}
}
return fclose(fp) ; /* couldn't find it, so use fclose */
}
/*--------------------------------------------------------------*/
/*** return a malloc-ed filename string that has the
correct compression suffix attached.
If NULL is returned, the file doesn't exist.
The return string should be free()-ed after it is used. ***/
char * COMPRESS_filename( char * fname )
{
char * buf ;
int ll , mm ;
if( fname == NULL || fname[0] == '\0' ) return NULL ;
mm = COMPRESS_filecode( fname ) ; /* find compression mode */
if( mm == COMPRESS_NOFILE ) return NULL ;
ll = strlen(fname) ;
buf = AFMALL(char, sizeof(char) * (ll+16) ) ; /* worst case */
if( mm == COMPRESS_NONE ){
strcpy(buf,fname) ;
} else {
if( ! COMPRESS_has_suffix(fname,mm) ){
strcpy(buf,fname) ; strcat(buf,COMPRESS_suffix[mm]) ;
} else {
strcpy(buf,fname) ;
}
}
return buf ;
}
/*--- May 1998: a simple routine ---*/
char * COMPRESS_add_suffix( char * fname , int mm )
{
char * buf ;
int ll ;
if( fname == NULL || fname[0] == '\0' ) return NULL ;
ll = strlen(fname) ;
buf = AFMALL(char, sizeof(char) * (ll+16) ) ;
strcpy(buf,fname) ;
if( mm >= 0 && mm <= COMPRESS_LASTCODE &&
! COMPRESS_has_suffix(fname,mm) ){
strcat(buf,COMPRESS_suffix[mm]) ;
}
return buf ;
}
/*--------------------------------------------------------------*/
/*** open a file for readin, possibly using compresson ***/
FILE * COMPRESS_fopen_read( char * fname )
{
FILE * fp ;
int mm ;
char * buf , * cmd ;
if( fname == NULL || fname[0] == '\0' ) return NULL ;
mm = COMPRESS_filecode( fname ) ; /* find compression mode */
if( mm == COMPRESS_NOFILE ) return NULL ; /* can't do nothin */
if( mm == COMPRESS_NONE ){
fp = fopen(fname,"r") ; /* open it normally */
putin_fop_table(fp,0) ; /* save its open method */
return fp ;
}
#if 1
if( ! COMPRESS_has_suffix(fname,mm) ){
buf = AFMALL(char, sizeof(char) * (strlen(fname)+16) ) ;
strcpy(buf,fname) ; strcat(buf,COMPRESS_suffix[mm]) ;
} else {
buf = fname ;
}
#else
buf = fname ;
#endif
cmd = AFMALL(char, sizeof(char) * (strlen(buf)+32) ) ;
sprintf(cmd,COMPRESS_unprogram[mm],buf) ;
fp = popen(cmd,"r") ; /* open a pipe to read the file */
putin_fop_table(fp,1) ; /* save its open method */
free(cmd) ; if( buf != fname ) free(buf) ;
return fp ;
}
/*-------------------------------------------------------------
open a file for writing, possibly using compresson;
mm should be one of the COMPRESS_ codes at the top
of file thd_compress.h
---------------------------------------------------------------*/
FILE * COMPRESS_fopen_write( char * fname , int mm )
{
FILE * fp ;
char * buf , * cmd ;
if( fname == NULL || fname[0] == '\0' ) return NULL ;
/* Don't compress if the compression program isn't marked as OK */
/* [For modes that can only be compressed offline, like BRIKCOMP] */
if( mm < 0 || ! COMPRESS_program_ok[mm] ){
fp = fopen(fname,"w") ; /* open it normally */
putin_fop_table(fp,0) ; /* save its open method */
return fp ;
}
#if 1
if( ! COMPRESS_has_suffix(fname,mm) ){
buf = AFMALL(char, sizeof(char) * (strlen(fname)+16) ) ;
strcpy(buf,fname) ; strcat(buf,COMPRESS_suffix[mm]) ;
} else {
buf = fname ;
}
#else
buf = fname ;
#endif
cmd = AFMALL(char, sizeof(char) * (strlen(buf)+32) ) ;
sprintf(cmd,COMPRESS_program[mm],buf) ;
fp = popen(cmd,"w") ; /* open a pipe to write the file */
putin_fop_table(fp,1) ; /* save its open method */
free(cmd) ; if( buf != fname ) free(buf) ;
return fp ;
}
/*----------------------------------------------------------*/
int COMPRESS_unlink( char * fname )
{
char * fff = COMPRESS_filename(fname) ;
int ii = -1 ;
if( fff != NULL ){ ii=unlink(fff); free(fff); }
return ii ;
}
syntax highlighted by Code2HTML, v. 0.9.1