1 /*****************************************************************************
2 Major portions of this software are copyrighted by the Medical College
3 of Wisconsin, 1994-2000, and are released under the Gnu General Public
4 License, Version 2. See the file README.Copyright for details.
5 ******************************************************************************/
6
7 #include <stdio.h>
8 #include <unistd.h>
9 #include "mrilib.h"
10
11 typedef struct { unsigned char a,b,c,d ; } fourbytes ;
12
13 #define TEMP_FILE "Frodo.Lives"
14 #define BUFSIZE 64000
15
16 static byte bbuf[BUFSIZE] ;
17
18 #define MAXPAT 256
19
main(int argc,char * argv[])20 int main( int argc , char * argv[] )
21 {
22 FILE * infil , * outfil ;
23 int narg , nbyte , nbyt , quiet = 0 , ndone ;
24 int npat,ipat,jpat,ii,typ,len,num , cpat_len ;
25 int pattype[MAXPAT] , patsize[MAXPAT] ;
26 char * cpat = NULL ;
27
28 if( argc < 2 || strncmp(argv[1],"-help",2) == 0 ){
29 printf("Usage: 24swap [options] file ...\n"
30 "Swaps bytes pairs and/or quadruples on the files listed.\n"
31 "Options:\n"
32 " -q Operate quietly\n"
33 " -pattern pat 'pat' determines the pattern of 2 and 4\n"
34 " byte swaps. Each element is of the form\n"
35 " 2xN or 4xN, where N is the number of\n"
36 " bytes to swap as pairs (for 2x) or\n"
37 " as quadruples (for 4x). For 2x, N must\n"
38 " be divisible by 2; for 4x, N must be\n"
39 " divisible by 4. The whole pattern is\n"
40 " made up of elements separated by colons,\n"
41 " as in '-pattern 4x39984:2x0'. If bytes\n"
42 " are left over after the pattern is used\n"
43 " up, the pattern starts over. However,\n"
44 " if a byte count N is zero, as in the\n"
45 " example below, then it means to continue\n"
46 " until the end of file.\n"
47 "\n"
48 " N.B.: You can also use 1xN as a pattern, indicating to\n"
49 " skip N bytes without any swapping.\n"
50 " N.B.: A default pattern can be stored in the Unix\n"
51 " environment variable AFNI_24SWAP_PATTERN.\n"
52 " If no -pattern option is given, the default\n"
53 " will be used. If there is no default, then\n"
54 " nothing will be done.\n"
55 " N.B.: If there are bytes 'left over' at the end of the file,\n"
56 " they are written out unswapped. This will happen\n"
57 " if the file is an odd number of bytes long.\n"
58 " N.B.: If you just want to swap pairs, see program 2swap.\n"
59 " For quadruples only, see program 4swap.\n"
60 " N.B.: This program will overwrite the input file!\n"
61 " You might want to test it first.\n"
62 "\n"
63 " Example: 24swap -pat 4x8:2x0 fred\n"
64 " If fred contains 'abcdabcdabcdabcdabcd' on input,\n"
65 " then fred has 'dcbadcbabadcbadcbadc' on output.\n"
66 ) ;
67 exit(0) ;
68 }
69
70 machdep() ;
71
72 /*-- scan arguments --*/
73
74 narg = 1 ;
75
76 while( narg < argc && argv[narg][0] == '-' ){
77
78 if( strncmp(argv[narg],"-q",2) == 0 ){
79 quiet = 1 ; narg++ ; continue ;
80 }
81
82 if( strncmp(argv[narg],"-pat",4) == 0 ){
83 cpat = argv[++narg] ; narg++ ; continue ;
84 }
85
86 fprintf(stderr,"** 24swap: Unknown option %s\n",argv[narg]) ;
87 exit(1) ;
88 }
89
90 if( narg == argc ){
91 fprintf(stderr,"** 24swap: No input files?\n") ; exit(1) ;
92 }
93
94 if( cpat == NULL ) cpat = getenv("AFNI_24SWAP_PATTERN") ;
95 if( cpat == NULL ){
96 fprintf(stderr,"** 24swap: No pattern? Exiting!\n") ; exit(1) ;
97 }
98 cpat_len = strlen(cpat) ;
99 if( cpat_len < 3 ){
100 fprintf(stderr,"** 24swap: Stupid pattern? Exiting!\n") ; exit(1) ;
101 }
102
103 /*-- parse cpat --*/
104
105 ipat = npat = 0 ; cpat_len = strlen(cpat) ;
106 while( ipat < cpat_len ){
107 ii = sscanf( cpat+ipat , "%dx%d%n" , &typ,&len,&num ) ;
108 if( ii <= 0 ) break ;
109 if( ii != 2 ){
110 fprintf(stderr,"** 24swap: illegal pattern %s\n",cpat); exit(1);
111 }
112 if( len < 0 || (typ!=2 && typ!=4 && typ!=1 ) ){
113 fprintf(stderr,"** 24swap: illegal pattern %s\n",cpat); exit(1);
114 }
115 if( typ == 2 && len%2 != 0 ){
116 fprintf(stderr,"** 24swap: illegal pattern %s\n",cpat); exit(1);
117 }
118 if( typ == 4 && len%4 != 0 ){
119 fprintf(stderr,"** 24swap: illegal pattern %s\n",cpat); exit(1);
120 }
121
122 pattype[npat] = typ ;
123 patsize[npat] = len ;
124 npat++ ; ipat += num+1 ;
125 }
126
127 if( npat < 1 ){
128 fprintf(stderr,"** 24swap: illegal pattern %s\n",cpat); exit(1);
129 }
130
131 /*-- loop over files --*/
132
133 for( ; narg < argc ; narg++ ){
134 infil = fopen( argv[narg] , "r" ) ;
135 if( infil == NULL ){
136 fprintf(stderr,"** 24swap: File %s not found - skipping it!\n",argv[narg]);
137 continue ;
138 }
139
140 if( !quiet){ printf("-- opened %s",argv[narg]) ; fflush(stdout) ; }
141
142 outfil = fopen( TEMP_FILE , "w" ) ;
143 if( outfil == NULL ){
144 printf("** 24swap: Cannot open temporary file - exiting!\n"); exit(1);
145 }
146
147 ndone = 0 ; ipat = 0 ; /* loop over patterns and execute them */
148 while(1){
149
150 if( patsize[ipat] == 0 ){ /* do rest of file this way */
151 while(1){
152 nbyt = fread( bbuf , sizeof(byte) , BUFSIZE , infil ) ;
153 if( nbyt <= 0 ) break ; /* end of file */
154 switch( pattype[ipat] ){
155 case 1: /* nothing to do */ ; break ;
156 case 2: swap_twobytes ( nbyt/2 , bbuf ) ; break ;
157 case 4: swap_fourbytes( nbyt/4 , bbuf ) ; break ;
158 }
159 fwrite( bbuf , sizeof(byte) , nbyt , outfil ) ;
160 ndone += nbyt ;
161 if( !quiet && ndone > 1000000 ){
162 ndone -= 1000000 ; printf(".") ; fflush(stdout) ;
163 }
164 }
165 break ; /* to end of outer loop */
166
167 } else { /* do patsize[ipat] bytes */
168 ii = 0 ;
169 while(1){
170 jpat = MIN( patsize[ipat] - ii , BUFSIZE ) ;
171 nbyt = fread( bbuf , sizeof(byte) , jpat , infil ) ;
172 if( nbyt <= 0 ) break ; /* end of file */
173 switch( pattype[ipat] ){
174 case 1: /* nothing to do */ ; break ;
175 case 2: swap_twobytes ( nbyt/2 , bbuf ) ; break ;
176 case 4: swap_fourbytes( nbyt/4 , bbuf ) ; break ;
177 }
178 fwrite( bbuf , sizeof(byte) , nbyt , outfil ) ;
179 ndone += nbyt ;
180 if( !quiet && ndone > 1000000 ){
181 ndone -= 1000000 ; printf(".") ; fflush(stdout) ;
182 }
183 ii += nbyt ; if( ii >= patsize[ipat] ) break ;
184 }
185 }
186
187 if( nbyt <= 0 ) break ; /* to end of outer loop */
188
189 ipat++ ; if( ipat >= npat ) ipat = 0 ; /* continue outer loop */
190
191 } /* end of outer loop */
192
193 fsync(fileno(outfil)) ; fclose(infil) ; fclose(outfil) ;
194
195 unlink( argv[narg] ) ;
196 rename( TEMP_FILE , argv[narg] ) ;
197
198 if( !quiet ){ printf(".\n") ; fflush(stdout) ; }
199 }
200 exit(0) ;
201 }
202