1 #include "mrilib.h"
2 #include <string.h>
3
4 #define MMAX 82 /* max # colors */
5 #define NOUT 61 /* max # chars per output line */
6
7 static byte rmap[MMAX], gmap[MMAX], bmap[MMAX] ; /* color map */
8
9 static char alpha[MMAX] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* color codes */
10 "abcdefghijklmnopqrstuvwxyz" /* do not use */
11 ",<.>/?;:'[{]}|=+-_)(*&^%$#@!`~" ; /* digits */
12
13 static char num[10] = "0123456789" ; /* number codes */
14
15 static MRI_IMAGE * SPLASH_decodexx( int , int , int , int ,
16 byte *, byte *, byte * , char ** ) ;
17
18 #include "splash_blank_new.h"
19
main(int argc,char * argv[])20 int main( int argc , char * argv[] )
21 {
22 MRI_IMAGE *im ;
23 byte *bp , rr,bb,gg ;
24 int ii,jj,nmap,kk , nn , qq , nlin=0 ;
25 char out[NOUT+1] , zout[NOUT+1] , cc,nc , *nam ;
26
27 if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
28 printf("Usage: toxx NAME input.ppm > output.xx\n"
29 "Converts a PPM image to an 'xx' (C header) image\n"
30 "for use in afni_splash.c -- NAME is the string to\n"
31 "use in the output file variables defining the data.\n"
32 "Probably get the input by\n"
33 " ppmquant xx image.ppm > input.ppm\n"
34 "where 'xx' is the number of colors to use.\n"
35 "Max value of 'xx' is %d.\n\n" , MMAX
36 ) ;
37 printf("Alternative usage:\n"
38 " toxx -splash > output.ppm\n"
39 "Outputs the blank AFNI splash screen to a PPM image.\n"
40 "The .xx data for this is stored in splash_blank_new.h\n"
41 ) ;
42 exit(0);
43 }
44
45 /*----- alternative usage -----*/
46
47 if( strcasecmp(argv[1],"-splash") == 0 ){ /* 30 Nov 2009 */
48 MRI_IMAGE *imspl ;
49 imspl = SPLASH_decodexx( NX_blank, NY_blank, NLINE_blank, NC_blank,
50 RMAP_blank,GMAP_blank,BMAP_blank, BAR_blank ) ;
51 if( imspl == NULL ) ERROR_exit("Can't create splash image?!") ;
52 mri_write_pnm( "-" , imspl ) ; /* to stdout */
53 exit(0) ;
54 }
55
56 /*----- normal usage -----*/
57
58 nam = argv[1] ;
59 im = mri_read( argv[2] ) ;
60 if( im == NULL ){
61 fprintf(stderr,"** Can't read file %s\n",argv[2]); exit(1);
62 }
63 switch( im->kind ){
64 case MRI_rgb:
65 INFO_message("Input is color %dx%d",im->nx,im->ny) ;
66 break ;
67 case MRI_byte:{
68 MRI_IMAGE *qim = mri_to_rgb(im) ;
69 mri_free(im) ; im = qim ;
70 INFO_message("Input is grayscale %dx%d",im->nx,im->ny) ;
71 }
72 break ;
73 default:
74 ERROR_exit("Input %s is wrong kind of image!",argv[2]) ;
75 }
76 bp = MRI_RGB_PTR(im) ;
77
78 /*--- build color map (MMAX or fewer entries allowed) ---*/
79
80 rmap[0] = bp[0] ; gmap[0] = bp[1] ; bmap[0] = bp[2] ;
81
82 for( ii=nmap=1 ; ii < im->nvox ; ii++ ){
83 rr = bp[3*ii] ; gg = bp[3*ii+1] ; bb = bp[3*ii+2] ;
84 for( kk=0 ; kk < nmap ; kk++ ){
85 if( rr==rmap[kk] && gg==gmap[kk] && bb==bmap[kk] ) break ;
86 }
87 if( kk == nmap ){ /* new color */
88 if( nmap == MMAX )
89 ERROR_exit("Too many colors (> %d) in input %s\n",MMAX,argv[2]) ;
90 rmap[nmap] = rr ; gmap[nmap] = gg ; bmap[nmap] = bb ;
91 nmap++ ;
92 }
93 }
94
95 INFO_message("Input has %d distinct colors",nmap) ;
96
97 /*--- print header ---*/
98
99 nn = 0 ; qq = 0 ;
100 printf( "#define NX_%s %d\n",nam,im->nx) ;
101 printf( "#define NY_%s %d\n",nam,im->ny) ;
102 printf( "#define NC_%s %d\n",nam,nmap ) ;
103
104 printf( "static byte RMAP_%s[] = {\n " , nam ) ;
105 for( kk=0 ; kk < nmap ; kk++ )
106 printf("%d%s",(int)rmap[kk] , (kk==nmap-1) ? "};\n" : "," ) ;
107
108 printf( "static byte GMAP_%s[] = {\n " , nam ) ;
109 for( kk=0 ; kk < nmap ; kk++ )
110 printf("%d%s",(int)gmap[kk] , (kk==nmap-1) ? "};\n" : "," ) ;
111
112 printf( "static byte BMAP_%s[] = {\n " , nam ) ;
113 for( kk=0 ; kk < nmap ; kk++ )
114 printf("%d%s",(int)bmap[kk] , (kk==nmap-1) ? "};\n" : "," ) ;
115
116 /*--- print image data (BAR = byte array) ---*/
117
118 printf( "static char *BAR_%s[] = {\n" , nam ) ;
119 for( ii=0 ; ii < im->nvox ; ii++ ){
120
121 /* find color index kk of ii-th pixel */
122
123 rr = bp[3*ii] ; gg = bp[3*ii+1] ; bb = bp[3*ii+2] ;
124 for( kk=0 ; kk < nmap ; kk++ ){
125 if( rr==rmap[kk] && gg==gmap[kk] && bb==bmap[kk] ) break ;
126 }
127
128 out[nn++] = alpha[kk] ; /* save character code for this color */
129
130 /* when output line buffer is filled, write it */
131
132 if( nn == NOUT && ii < im->nvox-1 ){ /* output line is full; RLE it */
133 out[nn] = '\0' ;
134 cc = out[0] ; /* first character in output line */
135 qq = 1 ; kk = 0 ; /* qq = repetition count; kk = pos in zout buffer */
136 for( jj=1 ; jj <= nn ; jj++ ){
137 nc = out[jj] ; /* next character (cc = last character) */
138 if( nc == cc ){ /* same character ==> store */
139 if( qq == 9 ){ zout[kk++] = num[qq] ; zout[kk++] = cc ; qq = 0 ; }
140 qq++ ;
141 } else { /* new character */
142 if( qq == 1 ){
143 zout[kk++] = cc ; qq = 1 ;
144 } else if( qq == 2 ){
145 zout[kk++] = cc ; zout[kk++] = cc ; qq = 1 ;
146 } else {
147 zout[kk++] = num[qq] ; zout[kk++] = cc ; qq = 1 ;
148 }
149 }
150 cc = nc ;
151 }
152 zout[kk] = '\0' ;
153 printf(" \"%s\",\n",zout) ; nlin++ ; nn = 0 ;
154 }
155 }
156
157 /* put the last line out (no RLE here, because I'm lazy scum) */
158
159 out[nn] = '\0' ;
160 printf(" \"%s\"\n};\n",out) ; nlin++ ;
161 printf("#define NLINE_%s %d\n",nam,nlin) ; /* number of lines */
162 exit(0) ;
163 }
164
165 /*--------------------------------------------------------------------------
166 Decode 'xx' data into an image.
167 ----------------------------------------------------------------------------*/
168
SPLASH_decodexx(int nx,int ny,int nl,int nmap,byte * rmap,byte * gmap,byte * bmap,char ** imxx)169 static MRI_IMAGE * SPLASH_decodexx( int nx, int ny, int nl, int nmap,
170 byte *rmap, byte *gmap, byte *bmap ,
171 char **imxx )
172 {
173 MRI_IMAGE *im ;
174 byte *bim ;
175 int ii,jj , cc,qq , dd,ee , kk ;
176 char bb ;
177 static int first=1 , ainv[256] ;
178
179 ENTRY("SPLASH_decodexx") ;
180
181 if( nmap == 0 ) RETURN(NULL) ;
182
183 if( nx < 3 || ny < 3 || nl < 3 ||
184 rmap == NULL || gmap == NULL ||
185 bmap == NULL || imxx == NULL ) RETURN(NULL) ;
186
187 if( first ){
188 for( ii=0 ; ii < 256 ; ii++ ) ainv[ii] = -1 ;
189 for( ii=0 ; ii < MMAX ; ii++ ){
190 bb = alpha[ii] ; ainv[bb] = ii ;
191 }
192 first = 0 ;
193 }
194
195 im = mri_new( nx , ny , MRI_rgb ) ;
196 bim = MRI_RGB_PTR(im) ;
197
198 /* decode the RLE image data into a real image array */
199
200 cc = qq = 0 ;
201 for( ii=0 ; ii < 3*im->nvox && qq < nl ; ){
202 bb = imxx[qq][cc++] ; if( bb == '\0' ) break ;
203 jj = ainv[bb] ;
204 if( jj >= 0 ){
205 bim[ii++] = rmap[jj]; bim[ii++] = gmap[jj]; bim[ii++] = bmap[jj];
206 } else {
207 dd = bb - '0' ;
208 bb = imxx[qq][cc++] ; if( bb == '\0' ) break ;
209 jj = ainv[bb] ;
210 for( ee=0 ; ee < dd && ii < 3*im->nvox ; ee++ ){
211 bim[ii++] = rmap[jj]; bim[ii++] = gmap[jj]; bim[ii++] = bmap[jj];
212 }
213 }
214 if( imxx[qq][cc] == '\0' ){ cc = 0 ; qq++ ; }
215 }
216
217 RETURN(im) ;
218 }
219