1 #include "mrilib.h"
2
3 /*===========================================================================*/
4 #ifndef HAVE_ZLIB
5
zz_compress_dosave(int ii)6 void zz_compress_dosave( int ii ){return;}
zz_compress_dlev(int ii)7 void zz_compress_dlev( int ii ){return;}
zz_compress_some(int nsrc,void * ptr)8 int zz_compress_some( int nsrc, void *ptr ){return -1;}
zz_compress_all(int nsrc,char * src,char ** dest)9 int zz_compress_all( int nsrc , char *src , char **dest ){return -1;}
zz_uncompress_some(int nsrc,char * src,int ndest,char * dest)10 int zz_uncompress_some( int nsrc, char *src, int ndest, char *dest ){return -1;}
zz_uncompress_all(int nsrc,byte * src,char ** dest)11 int zz_uncompress_all( int nsrc , byte *src , char **dest ){return -1;}
zz_ncd_many(int nar,int * nsrc,char ** src)12 MRI_IMAGE * zz_ncd_many( int nar , int *nsrc , char **src ){return NULL;}
zz_ncd_pair(int n1,char * s1,int n2,char * s2)13 float zz_ncd_pair( int n1 , char *s1 , int n2 , char *s2 ){return -1.0f;}
THD_ncdfloat(int n,float * x,float * y)14 float THD_ncdfloat( int n , float *x , float *y ){return -1.0f;}
THD_ncdfloat_scl(int n,float xbot,float xtop,float * x,float ybot,float ytop,float * y)15 float THD_ncdfloat_scl( int n , float xbot,float xtop,float *x ,
16 float ybot,float ytop,float *y ){return -1.0f;}
17
array_to_zzb64(int nsrc,char * src,int linelen)18 char * array_to_zzb64( int nsrc , char *src , int linelen ){ return NULL; }
zzb64_to_array(char * zb,char ** dest)19 int zzb64_to_array( char *zb , char **dest ){ return -1; }
20
21 /*===========================================================================*/
22 #else /* HAVE_ZLIB */
23
24 #include "zlib.h"
25
26 #define CHUNK 262144 /* 256 K */
27
28 /*------------------------------------------------------------------------*/
29
30 static int dosave = 1 ;
zz_compress_dosave(int ii)31 void zz_compress_dosave( int ii ){ dosave = ii ; }
32
33 static int dlev = 6 ;
zz_compress_dlev(int ii)34 void zz_compress_dlev( int ii ){ dlev = (ii < 1 || ii > 9) ? 6 : ii ; }
35
36 /*------------------------------------------------------------------------*/
37 /*! Start, continue, or end compressing a byte stream.
38 - Startup: nsrc = 0, ptr == NULL
39 - Continue: nsrc > 0, ptr == (char *)source (mustn't be NULL)
40 - Finish: nsrc < 0, ptr == (char **)dest (might be NULL)
41 - Return value is total number of bytes in output thus far.
42 Will be 0 for Startup call, will be >= 0 for other calls.
43 - If a negative number is returned, that's bad news.
44 - On return from the Finish call, the compressed byte stream
45 will be available in *dest, if dest!=NULL, and dosave!=0;
46 the array should be free()-ed by the caller when done with it.
47 *//*----------------------------------------------------------------------*/
48
zz_compress_some(int nsrc,void * ptr)49 int zz_compress_some( int nsrc, void *ptr )
50 {
51 static int busy=0 ; static z_stream strm;
52 static char *saved=NULL ; static unsigned int nsaved=0 ;
53 int ret ; unsigned int have; char buf[CHUNK] ;
54
55 /**----- Startup case -----**/
56
57 if( nsrc == 0 || (nsrc > 0 && ptr == NULL) ){
58 int lev = (nsrc < 1 || nsrc > 9) ? dlev : nsrc ;
59
60 if( busy )
61 ERROR_message("zz_compress_some: busy during Startup!") ;
62 if( saved != NULL ){ free(saved); saved=NULL; }
63 nsaved = 0 ;
64
65 strm.zalloc = Z_NULL ;
66 strm.zfree = Z_NULL ;
67 strm.opaque = Z_NULL ;
68 ret = deflateInit( &strm , lev ) ;
69 if( ret != Z_OK ){
70 ERROR_message("zz_compress_none: Startup fails!") ;
71 busy = 0 ; return -1 ;
72 }
73 busy = 1 ; return 0 ;
74 }
75
76 /**----- Continue case -----**/
77
78 if( nsrc > 0 && ptr != NULL ){
79 if( !busy ){
80 ERROR_message("zz_compress_some: Continue from non-busy state!") ;
81 if( saved != NULL ){ free(saved); saved=NULL; nsaved=0; }
82 busy = 0 ; return -1 ;
83 }
84
85 strm.avail_in = nsrc ;
86 strm.next_in = ptr ;
87
88 /** compress input data until it is all consumed **/
89
90 /* INFO_message("zz_compress_some: nsrc=%d bytes",nsrc) ; */
91 do{
92 strm.avail_out = CHUNK ;
93 strm.next_out = buf ;
94 ret = deflate( &strm, Z_NO_FLUSH ) ;
95 if( ret == Z_STREAM_ERROR ){
96 ERROR_message("zz_compress_some: deflate failure!") ;
97 if( saved != NULL ){ free(saved); saved=NULL; nsaved=0; }
98 busy = 0 ; deflateEnd(&strm) ; return -1 ;
99 }
100 have = CHUNK - strm.avail_out;
101 if( dosave && have > 0 ){
102 saved = (char *)realloc( saved , sizeof(char)*(nsaved+have+1) ) ;
103 memcpy( saved+nsaved , buf , have ) ;
104 nsaved += have ;
105 }
106 /* INFO_message(" have=%u bytes",have) ; */
107 } while( strm.avail_out == 0 ) ;
108
109 if( strm.avail_in > 0 ){
110 strm.avail_out = CHUNK ;
111 strm.next_out = buf ;
112 ret = deflate( &strm, Z_SYNC_FLUSH ) ;
113 if( ret == Z_STREAM_ERROR ){
114 ERROR_message("zz_compress_some: deflate failure!") ;
115 if( saved != NULL ){ free(saved); saved=NULL; nsaved=0; }
116 busy = 0 ; deflateEnd(&strm) ; return -1 ;
117 }
118 have = CHUNK - strm.avail_out;
119 if( dosave && have > 0 ){
120 saved = (char *)realloc( saved , sizeof(char)*(nsaved+have+1) ) ;
121 memcpy( saved+nsaved , buf , have ) ;
122 nsaved += have ;
123 }
124 /* INFO_message(" last have=%u bytes",have) ; */
125 }
126
127 return (int)strm.total_out ;
128 }
129
130 /**----- Finish case -----**/
131
132 if( nsrc < 0 ){
133 if( !busy ){
134 ERROR_message("zz_compress_some: not busy during Finish!") ;
135 if( saved != NULL ){ free(saved); saved=NULL; nsaved=0; }
136 busy = 0 ; return -1 ;
137 }
138
139 do{
140 strm.avail_in = 0 ;
141 strm.avail_out = CHUNK ;
142 strm.next_out = buf ;
143 ret = deflate( &strm , Z_FINISH ) ;
144 if( ret == Z_STREAM_ERROR ){
145 ERROR_message("zz_compress_some: error during Finish!") ;
146 if( saved != NULL ){ free(saved); saved=NULL; nsaved=0; }
147 deflateEnd(&strm) ; busy = 0 ; return -1 ;
148 }
149 have = CHUNK - strm.avail_out ;
150 if( dosave && have > 0 ){
151 saved = (char *)realloc( saved , sizeof(char)*(nsaved+have+1) ) ;
152 memcpy( saved+nsaved , buf , have ) ;
153 nsaved += have ;
154 }
155 /* INFO_message(" finish have=%u bytes",have) ; */
156 } while( ret != Z_STREAM_END ) ;
157
158 (void)deflateEnd(&strm) ;
159
160 if( ptr != NULL && dosave ){
161 char **cpt = (char **)ptr ; *cpt = saved ; ret = (int)nsaved ;
162 } else {
163 free(saved) ; ret = (int)strm.total_out ;
164 }
165
166 saved = NULL ; nsaved = 0 ; busy = 0 ; return ret ;
167 }
168
169 /* should never be reached */
170
171 ERROR_message("zz_compress_some: runoff error!") ; return -1 ;
172 }
173
174 /*------------------------------------------------------------------------*/
175 /*! Compress all of src array into the *dest array (if not NULL).
176 Return value is size of dest array, as malloc()-ed.
177 *//*----------------------------------------------------------------------*/
178
zz_compress_all(int nsrc,char * src,char ** dest)179 int zz_compress_all( int nsrc , char *src , char **dest )
180 {
181 int ret ;
182 zz_compress_dosave( (dest != NULL) ) ;
183 ret = zz_compress_some( 0 , NULL ) ; if( ret < 0 ) return 0 ;
184 ret = zz_compress_some( nsrc , src ) ; if( ret < 0 ) return 0 ;
185 ret = zz_compress_some( -1 , dest ) ;
186 return ret ;
187 }
188
189 /*------------------------------------------------------------------------*/
190 /*! - Startup: nsrc > 0, src != NULL
191 - Continue: nsrc == 0, src == don't care
192 - Finish: nsrc < 0, src == don't care
193 - Return value = actual number of bytes stored into dest
194 - Finish calls should repeat until this value is 0, to make sure
195 that all the data has been extracted. If you wish to stop the
196 extraction before getting all the data, call with nsrc=-666.
197 - A negative return value indicates an error.
198 *//*----------------------------------------------------------------------*/
199
zz_uncompress_some(int nsrc,char * src,int ndest,char * dest)200 int zz_uncompress_some( int nsrc, char *src, int ndest, char *dest )
201 {
202 static int busy=0 ; static z_stream strm;
203 int ret , done ;
204
205 if( ndest <= 0 || dest == NULL ){
206 ERROR_message("zz_uncompress_some: bad dest inputs!") ;
207 if( busy ) inflateEnd(&strm) ;
208 busy = 0 ; return -1 ;
209 }
210 if( nsrc > 0 && src == NULL ){
211 ERROR_message("zz_uncompress_some: bad src inputs!") ;
212 if( busy ) inflateEnd(&strm) ;
213 busy = 0 ; return -1 ;
214 }
215
216 /**----- Start case -----**/
217
218 if( nsrc > 0 ){
219 if( busy )
220 ERROR_message("zz_uncompress_some: Start call in busy state!") ;
221 busy = 0 ;
222
223 strm.zalloc = Z_NULL ;
224 strm.zfree = Z_NULL ;
225 strm.opaque = Z_NULL ;
226 strm.avail_in = nsrc ;
227 strm.next_in = src ;
228 ret = inflateInit( &strm ) ;
229 if( ret != Z_OK ){
230 ERROR_message("zz_uncompress_some: can't initalize inflation!") ;
231 return -1 ;
232 }
233 busy = 1 ;
234 }
235
236 if( !busy ){
237 ERROR_message("zz_uncompress_some: non-Start call in non-busy state!") ;
238 return -1 ;
239 }
240
241 /**----- Quit right now -----**/
242
243 if( nsrc == -666 ){
244 inflateEnd(&strm) ; busy = 0 ; return 0 ;
245 }
246
247 /**----- Continuation -----**/
248
249 strm.avail_out = ndest ;
250 strm.next_out = dest ;
251 ret = inflate( &strm , (nsrc >= 0) ? Z_SYNC_FLUSH : Z_FINISH ) ;
252 /* INFO_message("inflate ret=%d",ret) ; */
253
254 if( ret != Z_OK && ret != Z_STREAM_END ){
255 ERROR_message("zz_uncompress_some: inflation fails: %d",ret) ;
256 inflateEnd(&strm) ; busy = 0 ; return -1 ;
257 }
258 done = (ret == Z_STREAM_END) ;
259
260 ret = ndest - strm.avail_out ; /* number of bytes output */
261 /* ININFO_message(" #bytes = %d",ret) ; */
262
263 if( ret == 0 ){ inflateEnd(&strm); busy = 0; } /* finished */
264
265 if( ret == 0 && done ) ret = -1 ;
266 return ret ;
267 }
268
269 /*------------------------------------------------------------------------*/
270 /*! Uncompress all nsrc bytes in src at once, malloc()-ing *dest;
271 the number of bytes in *dest is the return value of this function.
272 *//*----------------------------------------------------------------------*/
273
zz_uncompress_all(int nsrc,byte * src,char ** dest)274 int zz_uncompress_all( int nsrc , byte *src , char **dest )
275 {
276 char buf[CHUNK] , *ddd=NULL ; int nbuf , nddd ;
277
278 if( nsrc <= 0 || src == NULL || dest == NULL ) return -1 ;
279
280 /* INFO_message("zz_uncompress_all: nsrc=%d",nsrc) ; */
281
282 nbuf = zz_uncompress_some( nsrc , src , CHUNK , buf ) ;
283 /* ININFO_message("zz_uncompress_some returns %d",nbuf) ; */
284 if( nbuf <= 0 ) return -1 ;
285
286 nddd = nbuf ;
287 ddd = (char *)malloc(sizeof(char)*nddd) ;
288 memcpy( ddd , buf , nbuf ) ;
289
290 while(1){
291 nbuf = zz_uncompress_some( 0 , NULL , CHUNK , buf ) ;
292 /* ININFO_message("zz_uncompress_some returns %d",nbuf) ; */
293 if( nbuf <= 0 ) break ;
294 ddd = (char *)realloc(ddd,sizeof(char)*(nddd+nbuf)) ;
295 memcpy(ddd+nddd,buf,nbuf) ;
296 nddd += nbuf ;
297 }
298
299 if( nbuf == 0 ){
300 while(1){
301 nbuf = zz_uncompress_some( -1 , NULL , CHUNK , buf ) ;
302 /* ININFO_message("cleanup zz_uncompress_some returns %d",nbuf) ; */
303 if( nbuf <= 0 ) break ;
304 ddd = (char *)realloc(ddd,sizeof(char)*(nddd+nbuf)) ;
305 memcpy(ddd+nddd,buf,nbuf) ;
306 nddd += nbuf ;
307 }
308 }
309
310 /* ININFO_message("Finally: %d bytes",nddd) ; */
311 *dest = ddd ; return nddd ;
312 }
313
314 /*------------------------------------------------------------------------*/
315
zz_ncd_many(int nar,int * nsrc,char ** src)316 MRI_IMAGE * zz_ncd_many( int nar , int *nsrc , char **src )
317 {
318 int ii , jj , nstop ;
319 MRI_IMAGE *fim ;
320 float *far , *ncom , qcom,rcom , ncd ;
321 char *qbuf ;
322
323 if( nar < 2 || nsrc == NULL || src == NULL ) return NULL ;
324
325 for( ii=0 ; ii < nar ; ii++ )
326 if( nsrc[ii] <= 0 || src[ii] == NULL ) return NULL ;
327
328 qbuf = getenv("ZLIB_NCD_FACTOR") ; ii = 6 ;
329 if( qbuf != NULL ){
330 ii = (int)strtol(qbuf,NULL,10) ;
331 if( ii < 1 || ii > 9 ) ii = 6 ;
332 }
333 zz_compress_dlev(ii) ;
334
335 ncom = (float *)malloc(sizeof(float)*nar) ;
336 for( nstop=ii=0 ; ii < nar ; ii++ ){
337 nstop = MAX( nstop , nsrc[ii] ) ;
338 ncom[ii] = zz_compress_all( nsrc[ii] , src[ii] , NULL ) ;
339 if( ncom[ii] <= 0 ){ free(ncom); return NULL; }
340 }
341
342 qbuf = (char *)malloc(sizeof(char)*(2*nstop+16)) ;
343 fim = mri_new( nar , nar , MRI_float ) ;
344 far = MRI_FLOAT_PTR(fim) ;
345 for( ii=0 ; ii < nar ; ii++ ){
346 for( jj=ii+1 ; jj < nar ; jj++ ){
347 memcpy( qbuf , src[ii] , nsrc[ii] ) ;
348 memcpy( qbuf+nsrc[ii] , src[jj] , nsrc[jj] ) ;
349 qcom = zz_compress_all( nsrc[ii]+nsrc[jj] , qbuf , NULL ) ;
350
351 memcpy( qbuf , src[jj] , nsrc[jj] ) ;
352 memcpy( qbuf+nsrc[jj] , src[ii] , nsrc[ii] ) ;
353 rcom = zz_compress_all( nsrc[ii]+nsrc[jj] , qbuf , NULL ) ;
354
355 ncd = (MIN(rcom,qcom)-MIN(ncom[ii],ncom[jj])) / MAX(ncom[ii],ncom[jj]) ;
356 if( ncd > 1.0f ) ncd = 1.0f ;
357 far[ii+jj*nar] = far[jj+ii*nar] = ncd ;
358 }
359 far[ii+ii*nar] = 1.0f ;
360 }
361
362 free(qbuf) ; free(ncom) ; return fim ;
363 }
364
365 /*------------------------------------------------------------------------*/
366
zz_ncd_pair(int n1,char * s1,int n2,char * s2)367 float zz_ncd_pair( int n1 , char *s1 , int n2 , char *s2 )
368 {
369 int nsrc[2] ; char *src[2] ;
370 MRI_IMAGE *fim ; float ncd , *far ;
371
372 nsrc[0] = n1 ; src[0] = s1 ;
373 nsrc[1] = n2 ; src[1] = s2 ;
374 fim = zz_ncd_many( 2 , nsrc , src ) ;
375 if( fim == NULL ) return -1.0f ;
376 far = MRI_FLOAT_PTR(fim) ;
377 ncd = far[1] ;
378 mri_free(fim) ; return ncd ;
379 }
380
381 /*------------------------------------------------------------------------*/
382 /*! Compute NCD between two float vectors,
383 which will be scaled to bytes in build_byteized_vectors().
384 *//*----------------------------------------------------------------------*/
385
THD_ncdfloat_scl(int n,float xbot,float xtop,float * x,float ybot,float ytop,float * y)386 float THD_ncdfloat_scl( int n , float xbot,float xtop,float *x ,
387 float ybot,float ytop,float *y )
388 {
389 MRI_IMAGE *bim ; byte *xbar,*ybar,*qbuf ; int nbar,ii ;
390 float ncd , nx,ny,nxy,nxy2 ;
391
392 ENTRY("THD_ncdfloat_scl") ;
393
394 /* scale data vectors to bytes (cf. thd_correlate.c) */
395
396 bim = build_byteized_vectors( n , xbot,xtop,x , ybot,ytop,y ) ;
397 if( bim == NULL ) RETURN(1.0f) ;
398
399 nbar = bim->nx ;
400 xbar = MRI_BYTE_PTR(bim) ;
401 ybar = xbar + nbar ;
402
403 qbuf = (byte *)getenv("ZLIB_NCD_FACTOR") ; ii = 6 ;
404 if( qbuf != NULL ){
405 ii = (int)strtol((char *)qbuf,NULL,10) ;
406 if( ii < 1 || ii > 9 ) ii = 6 ;
407 }
408 zz_compress_dlev(ii) ;
409
410 nx = (float)zz_compress_all( nbar , xbar , NULL ) ;
411 ny = (float)zz_compress_all( nbar , ybar , NULL ) ;
412
413 qbuf = (byte *)malloc(2*nbar) ;
414 for( ii=0 ; ii < nbar ; ii++ ){ /* interleave */
415 qbuf[2*ii] = xbar[ii] ; qbuf[2*ii+1] = ybar[ii] ;
416 }
417 nxy = (float)zz_compress_all( 2*nbar , qbuf , NULL ) ;
418
419 memcpy(qbuf ,xbar,nbar) ; /* x then y */
420 memcpy(qbuf+nbar,ybar,nbar) ;
421 nxy2 = (float)zz_compress_all( 2*nbar , qbuf , NULL ) ;
422 nxy = MIN(nxy,nxy2) ;
423
424 memcpy(qbuf ,ybar,nbar) ; /* y then x */
425 memcpy(qbuf+nbar,xbar,nbar) ;
426 nxy2 = (float)zz_compress_all( 2*nbar , qbuf , NULL ) ;
427 nxy = MIN(nxy,nxy2) ;
428
429 ncd = (nxy-MIN(nx,ny)) / MAX(nx,ny) ;
430 if( ncd < 0.0f || ncd > 1.0f ) ncd = 1.0f ;
431
432 free(qbuf) ; mri_free(bim) ; RETURN(ncd) ;
433 }
434
435 /*------------------------------------------------------------------------*/
436 /*! Compute NCD between two float vectors, autoscaled to bytes. */
437
THD_ncdfloat(int n,float * x,float * y)438 float THD_ncdfloat( int n , float *x , float *y )
439 {
440 return THD_ncdfloat_scl( n, 1.0f,-1.0f, x, 1.0f,-1.0f, y ) ;
441 }
442
443 /*------------------------------------------------------------------------*/
444 /*! Compress and Base64 string-ify an input array. */
445
array_to_zzb64(int nsrc,char * src,int linelen)446 char * array_to_zzb64( int nsrc , char *src , int linelen )
447 {
448 int nzb ; char *zb ;
449 int nzdest ; char *zdest ;
450
451 if( nsrc <= 0 || src == NULL ) return NULL ;
452
453 zz_compress_dosave(1) ; zz_compress_dlev(9) ;
454
455 nzdest = zz_compress_all( nsrc , src , &zdest ) ;
456 if( nzdest <= 0 ) return NULL ;
457
458 if( linelen < 4 ) B64_set_crlf(0);
459 else { B64_set_crlf(1); B64_set_linelen(linelen); }
460
461 B64_to_base64( nzdest , (byte *)zdest , &nzb , (byte **)(&zb) ) ;
462 free(zdest) ;
463 if( nzb <= 0 ) return NULL ;
464 return zb ;
465 }
466
467 /*------------------------------------------------------------------------*/
468 /*! Inverse to array_to_zzb64(). */
469
zzb64_to_array(char * zb,char ** dest)470 int zzb64_to_array( char *zb , char **dest )
471 {
472 int nzdest=0 ; byte *zdest=NULL ;
473 int nout ; char *cout ;
474
475 if( zb == NULL ) return 0 ;
476
477 B64_to_binary( strlen(zb) , (byte *)zb , &nzdest , &zdest ) ;
478
479 if( nzdest <= 0 ) return 0 ;
480
481 nout = zz_uncompress_all( nzdest , zdest , dest ) ;
482 free(zdest) ;
483 return nout ;
484 }
485
486 #endif /* HAVE_ZLIB */
487 /*===========================================================================*/
488