Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

thd_base64.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #include "stdlib.h"
00008 
00009 typedef unsigned char byte ;
00010 
00011 static int  dtable_mode = -1 ;    /* 1=encode, 2=decode, -1=neither */
00012 static byte dtable[256] ;         /* encode/decode table */
00013 static int linelen = 72 ;         /* line length (max 76) */
00014 static int ncrlf   = 1 ;
00015 
00016 #define B64_goodchar(c) (dtable[c] != 0x80)  /* for decode only */
00017 
00018 #define B64_EOL1 '\r'   /* CR */
00019 #define B64_EOL2 '\n'   /* LF */
00020 
00021 /*----------------------------------------------------------------------*/
00022 
00023 void B64_set_crlf( int nn )
00024 {
00025    if( nn >= 1 && nn <= 2 ) ncrlf = nn ;
00026    return ;
00027 }
00028 
00029 /*----------------------------------------------------------------------*/
00030 
00031 void B64_set_linelen( int ll )
00032 {
00033    if( ll >= 16 && ll <= 76 ) linelen = 4*(ll/4) ; /* multiple of 4 */
00034    else                       linelen = 72 ;
00035    return ;
00036 }
00037 
00038 /*----------------------------------------------------------------------*/
00039 
00040 static void load_encode_table(void)
00041 {
00042     int i ;
00043     if( dtable_mode == 1 ) return ;
00044     for (i = 0; i < 26; i++) {
00045         dtable[i] = 'A' + i;
00046         dtable[26 + i] = 'a' + i;
00047     }
00048     for (i = 0; i < 10; i++) dtable[52 + i] = '0' + i;
00049     dtable[62] = '+'; dtable[63] = '/'; dtable_mode = 1 ;
00050     return ;
00051 }
00052 
00053 /*----------------------------------------------------------------------*/
00054 
00055 static void load_decode_table(void)
00056 {
00057     int i;
00058     if( dtable_mode == 2 ) return ;
00059     for (i = 0  ; i < 255 ; i++) dtable[i] = 0x80;             /* bad */
00060     for (i = 'A'; i <= 'Z'; i++) dtable[i] =  0 + (i - 'A');
00061     for (i = 'a'; i <= 'z'; i++) dtable[i] = 26 + (i - 'a');
00062     for (i = '0'; i <= '9'; i++) dtable[i] = 52 + (i - '0');
00063     dtable['+'] = 62; dtable['/'] = 63; dtable['='] = 0; dtable_mode = 2 ;
00064     return ;
00065 }
00066 
00067 #define B64_encode3(a,b,c,w,x,y,z)                 \
00068      ( w = dtable[(a)>>2]                      ,   \
00069        x = dtable[((a & 3) << 4) | (b >> 4)]   ,   \
00070        y = dtable[((b & 0xF) << 2) | (c >> 6)] ,   \
00071        z = dtable[c & 0x3F]                     )
00072 
00073 #define B64_encode2(a,b,w,x,y,z)                   \
00074      ( B64_encode3(a,b,0,w,x,y,z) , z = '=' )
00075 
00076 #define B64_encode1(a,w,x,y,z)                     \
00077      ( B64_encode3(a,0,0,w,x,y,z) , y=z = '=' )
00078 
00079 #define B64_decode4(w,x,y,z,a,b,c)                 \
00080      ( a = (dtable[w] << 2) | (dtable[x] >> 4) ,   \
00081        b = (dtable[x] << 4) | (dtable[y] >> 2) ,   \
00082        c = (dtable[y] << 6) | dtable[z]         )
00083 
00084 #define B64_decode_count(w,x,y,z)                  \
00085      ( ((w)=='='||(x)=='=') ? 0                    \
00086                             : ((y)=='=') ? 1       \
00087                             : ((z)=='=') ? 2 : 3 )
00088 
00089 /*----------------------------------------------------------------------
00090    Convert base64 encoding to a binary array
00091 
00092    Inputs: nb64 = number of bytes in b64
00093             b64 = array of base64 encoding bytes
00094                   values not in the base64 encoding set will be skipped
00095 
00096    Outputs: *nbin = number of binary bytes [*nbin==0 flags an error]
00097              *bin = pointer to newly malloc()-ed space with bytes
00098 ------------------------------------------------------------------------*/
00099 
00100 void B64_to_binary( int nb64 , byte * b64 , int * nbin , byte ** bin )
00101 {
00102    int ii,jj , nn ;
00103    byte a,b,c , w,x,y,z ;
00104 
00105    /*- sanity checks -*/
00106 
00107    if( nbin == NULL || bin == NULL ) return ;
00108 
00109    if( nb64 < 4 || b64 == NULL ){ *nbin = 0 ; *bin = NULL ; return ; }
00110 
00111    *bin = (byte *) malloc(sizeof(byte)*(2+3*nb64/4)) ;
00112    if( *bin == NULL ){ *nbin = 0 ; return ; }
00113 
00114    /*- some work -*/
00115 
00116    load_decode_table() ;
00117    for( ii=jj=0 ; ii < nb64 ; ){  /* scan inputs, skipping bad characters */
00118       w = b64[ii++] ;
00119       while( !B64_goodchar(w) && ii < nb64 ) w = b64[ii++] ;
00120       x = (ii < nb64) ? b64[ii++] : '=' ;
00121       while( !B64_goodchar(x) && ii < nb64 ) x = b64[ii++] ;
00122       y = (ii < nb64) ? b64[ii++] : '=' ;
00123       while( !B64_goodchar(y) && ii < nb64 ) y = b64[ii++] ;
00124       z = (ii < nb64) ? b64[ii++] : '=' ;
00125       while( !B64_goodchar(z) && ii < nb64 ) z = b64[ii++] ;
00126 
00127       B64_decode4(w,x,y,z,a,b,c) ;
00128 
00129       if( z == '=' ){                        /* got to the end? */
00130          nn = B64_decode_count(w,x,y,z) ;    /* see how many to save */
00131          if( nn > 0 ) (*bin)[jj++] = a ;
00132          if( nn > 1 ) (*bin)[jj++] = b ;
00133          break ;
00134       }
00135 
00136       /* not at the end => save all 3 outputs */
00137 
00138       (*bin)[jj++] = a ; (*bin)[jj++] = b ; (*bin)[jj++] = c ;
00139    }
00140 
00141    *bin  = (byte *) realloc( *bin , sizeof(byte)*jj ) ;
00142    *nbin = jj ;
00143    return ;
00144 }
00145 
00146 /*----------------------------------------------------------------------
00147    Convert binary array to base64 encoding
00148 
00149    Inputs: nbin = number of bytes in bin
00150             bin = array of binary bytes to encode
00151 
00152    Outputs: *nb64 = number of base64 bytes [*nb64==0 flags an error]
00153              *b64 = pointer to newly malloc()-ed space with bytes
00154 
00155    The output array (*b64) line length can be set by
00156       B64_set_linelen(n)
00157    where n is from 16 to 76.  The default is 72.  Note, however, that
00158    encoded bytes will always be written out in groups of 4.
00159    The output array line separator can be the LF character only (Unix)
00160    or the CR-LF combination (DOS, etc.).  This is controlled by
00161       B64_set_crlf(n)
00162    where n=1 for LF, n=2 for CR-LF.  The default is LF.  The output
00163    array will be terminated with a line separator.  There will be
00164    no ASCII NUL character at the end of *b64 -- that is, the output
00165    is not a C string.
00166 ------------------------------------------------------------------------*/
00167 
00168 void B64_to_base64( int nbin , byte * bin , int * nb64 , byte ** b64 )
00169 {
00170    int ii,jj , nn,n3 ;
00171    byte a,b,c , w,x,y,z ;
00172 
00173    /*- sanity checks -*/
00174 
00175    if( nb64 == NULL || b64 == NULL ) return ;
00176    if( nbin <= 0    || bin == NULL ){ *nb64 = 0 ; *b64 = NULL ; return ; }
00177 
00178    nn   = (4.0*(linelen+ncrlf+1.0)/(3.0*linelen))*nbin + 256 ;
00179    *b64 = (byte *) malloc(sizeof(byte)*nn) ;
00180    if( *b64 == NULL ){ *nb64 = 0 ; return ; }
00181 
00182    /*- do blocks of 3 -*/
00183 
00184    load_encode_table() ;
00185    n3 = (nbin/3)*3 ;
00186    for( nn=jj=ii=0 ; ii < n3 ; ){
00187       a = bin[ii++] ; b = bin[ii++] ; c = bin[ii++] ;
00188       B64_encode3(a,b,c,w,x,y,z) ;
00189       (*b64)[jj++] = w ;
00190       (*b64)[jj++] = x ;
00191       (*b64)[jj++] = y ;
00192       (*b64)[jj++] = z ;
00193       nn += 4 ; if( nn >= linelen ){
00194                    if( ncrlf == 2 ) (*b64)[jj++] = B64_EOL1 ;
00195                    (*b64)[jj++] = B64_EOL2 ;
00196                    nn = 0 ;
00197                 }
00198    }
00199 
00200    /*- do the leftovers, if any (1 or 2 bytes) -*/
00201 
00202    if( ii < nbin ){
00203       if( ii == nbin-2 )
00204          B64_encode2(bin[ii],bin[ii+1],w,x,y,z) ;
00205       else
00206          B64_encode1(bin[ii],w,x,y,z) ;
00207 
00208       (*b64)[jj++] = w ;
00209       (*b64)[jj++] = x ;
00210       (*b64)[jj++] = y ;
00211       (*b64)[jj++] = z ; nn += 4 ;
00212    }
00213 
00214    if( nn > 0 ){
00215       if( ncrlf == 2 ) (*b64)[jj++] = B64_EOL1 ;
00216       (*b64)[jj++] = B64_EOL2 ;
00217    }
00218 
00219    *b64  = (byte *) realloc( *b64 , sizeof(byte)*jj ) ;
00220    *nb64 = jj ;
00221    return ;
00222 }
 

Powered by Plone

This site conforms to the following standards: