TPCCLIB
Loading...
Searching...
No Matches
imgtiff.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcimgp.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
17 IMG *img,
19 int plane,
21 int frame,
24 float *maxvalue,
26 int colorscale,
28 char *fname,
30 int matXdim,
32 int matYdim,
34 int verbose,
37 char *status
38) {
39 FILE *fp;
40 short int svar, svars[2048];
41 char buf[4096], *cdata, *cptr;
42 int ivar, ivars[1024];
43 /* Rainbow color scale */
44 struct { int n, r, g, b, dr, dg, db; }
45 bitty[] = { {32, 0, 0, 0, 2, 0, 4}, /* violet to indigo */
46 {32, 64, 0,128, -2, 0, 4}, /* indigo to blue */
47 {32, 0, 0,255, 0, 8, -8}, /* blue to green */
48 {64, 0,255, 0, 4, 0, 0}, /* green to yellow */
49 {32, 255,255, 0, 0, -2, 0}, /* yellow to orange */
50 {64, 255,192, 0, 0, -3, 0} }; /* orange to red */
51
52 if(verbose>0) printf("tiffWriteImg(*img, %d, %d, %g, %d, %s, status, %d)\n",
53 plane, frame, *maxvalue, colorscale, fname, verbose);
54
55 /* Check input data */
56 if(status!=NULL) strcpy(status, "fault in calling routine");
57 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
58 if(img->dimt<(frame+1) || img->dimz<(plane+1)) return(2);
59 int pxlNr=img->dimx*img->dimy; if(pxlNr<1) return(3);
60 if(status!=NULL) strcpy(status, "ok");
61
62 /* If color scale maximum was not specified, then determine it here */
63 if(*maxvalue<=0.0) {
64 *maxvalue=-1.0e-12;
65 for(int pi=0; pi<img->dimz; pi++) if(plane<0 || plane==pi)
66 for(int ri=0; ri<img->dimy; ri++) for(int ci=0; ci<img->dimx; ci++)
67 for(int fi=0; fi<img->dimt; fi++) if(frame<0 || frame==fi)
68 if(img->m[pi][ri][ci][fi]>*maxvalue)
69 *maxvalue=img->m[pi][ri][ci][fi];
70 if(*maxvalue<=0.0) {
71 if(status!=NULL) strcpy(status, "no positive pixel values");
72 return(6);
73 }
74 }
75
76 /* Calculate image dimensions */
77 /* image matrix number */
78 int matNr=0;
79 if(plane<0) matNr=img->dimz; else matNr=1;
80 if(frame<0) matNr*=img->dimt; else matNr*=1;
81 if(verbose>1) printf("matNr=%d\n", matNr);
82 /* image matrix x*y number */
83 if(matXdim<=0 && matYdim<=0) {
84 matXdim=(int)ceil(sqrt((double)matNr));
85 matYdim=matNr/matXdim; if(matNr%matXdim) matYdim++;
86 } else {
87 if(matXdim>matNr) {
88 matXdim=matNr; matYdim=1;
89 } else if(matYdim>matNr) {
90 matYdim=matNr; matXdim=1;
91 } else if(matXdim>0) {
92 matYdim=matNr/matXdim; if(matNr%matXdim) matYdim++;
93 } else {
94 matXdim=matNr/matYdim; if(matNr%matYdim) matXdim++;
95 }
96 }
97 if(verbose>1) printf("matXdim:=%d\nmatYdim:=%d\n", matXdim, matYdim);
98
99
100 /* Open TIFF file */
101 if((fp=fopen(fname, "wb")) == NULL) {
102 if(status!=NULL) strcpy(status, "cannot open file for write");
103 return(11);
104 }
105
106 /* Construct TIFF header */
107 memset(buf, 0, 4096);
108 /* set the byte format */
109 if(little_endian()) memcpy(buf, "II", 2); else memcpy(buf, "MM", 2);
110 /* set file identifier */
111 svar=42; memcpy(buf+2, &svar, 2);
112 /* set byte offset of first IFD */
113 ivar=8; memcpy(buf+4, &ivar, 4);
114 /* Construct the (first) Image File Directory (IFD) */
115 /* set nr of directory entries */
116 if(colorscale==PET_RAINBOW || colorscale==PET_RAINBOW_WB)
117 svar=12; else svar=11;
118 memcpy(buf+8, &svar, 2);
119 /* move into start of first entry */
120 cptr=buf+10;
121 /* tag: ImageWidth */
122 svars[0]=256; svars[1]=4; memcpy(cptr, svars, 4); cptr+=4;
123 ivars[0]=1; ivars[1]=matXdim*img->dimx; memcpy(cptr, ivars, 8); cptr+=8;
124 /* tag: ImageLength */
125 svars[0]=257; svars[1]=4; memcpy(cptr, svars, 4); cptr+=4;
126 ivars[0]=1; ivars[1]=matYdim*img->dimy; memcpy(cptr, ivars, 8); cptr+=8;
127 /* tag: BitsPerSample (xv3 on Sun/Solaris gives warning but works) */
128 svars[0]=258; svars[1]=3; memcpy(cptr, svars, 4); cptr+=4;
129 ivars[0]=1; memcpy(cptr, ivars, 4); cptr+=4;
130 svars[0]=(unsigned short int)8; memcpy(cptr, svars, 2); cptr+=4; /* 256 shades */
131 /* tag: Compression */
132 svars[0]=259; svars[1]=3; memcpy(cptr, svars, 4); cptr+=4;
133 ivars[0]=1; memcpy(cptr, ivars, 4); cptr+=4;
134 svars[0]=1; memcpy(cptr, svars, 2); cptr+=4; /* no compression */
135 /* tag: Photometric Interpretation */
136 svars[0]=262; svars[1]=3; memcpy(cptr, svars, 4); cptr+=4;
137 ivars[0]=1; memcpy(cptr, ivars, 4); cptr+=4;
138 if(colorscale==PET_RAINBOW || colorscale==PET_RAINBOW_WB)
139 svars[0]=3; /* palette */
140 else if(colorscale==PET_GRAYSCALE)
141 svars[0]=1; /* black is zero */
142 else
143 svars[0]=0; /* white is zero */
144 memcpy(cptr, svars, 2); cptr+=4;
145 /* tag: StripOffsets */
146 svars[0]=273; svars[1]=4; memcpy(cptr, svars, 4); cptr+=4;
147 /* byte offset of strip(s) of data */
148 ivars[0]=1; ivars[1]=4096; memcpy(cptr, ivars, 8); cptr+=8;
149 /* tag: RowsPerStrip */
150 svars[0]=278; svars[1]=4; memcpy(cptr, svars, 4); cptr+=4;
151 ivars[0]=1; ivars[1]=matYdim*img->dimy; memcpy(cptr, ivars, 8); cptr+=8;
152 /* tag: StripByteCounts */
153 svars[0]=279; svars[1]=4; memcpy(cptr, svars, 4); cptr+=4;
154 ivars[0]=1; ivars[1]=matXdim*matYdim*pxlNr; memcpy(cptr, ivars, 8); cptr+=8;
155 /* tag: XResolution */
156 ivars[0]=33; ivars[1]=1; ivars[2]=33; ivars[3]=1; memcpy(buf+1024, ivars, 16);
157 svars[0]=282; svars[1]=5; memcpy(cptr, svars, 4); cptr+=4;
158 ivars[0]=1; ivars[1]=1024; memcpy(cptr, ivars, 8); cptr+=8;
159 /* tag: YResolution */
160 svars[0]=283; svars[1]=5; memcpy(cptr, svars, 4); cptr+=4;
161 ivars[0]=1; ivars[1]=1032; memcpy(cptr, ivars, 8); cptr+=8;
162 /* tag: ResolutionUnit */
163 svars[0]=296; svars[1]=3; memcpy(cptr, svars, 4); cptr+=4;
164 ivars[0]=1; memcpy(cptr, ivars, 4); cptr+=4;
165 svars[0]=3; memcpy(cptr, svars, 2); cptr+=4; /* cm */
166 if(colorscale!=PET_RAINBOW && colorscale!=PET_RAINBOW_WB) {
167 /* offset of the next IFD, or 0000 */
168 for(int i=0; i<4; i++) *cptr++=(char)0;
169 } else {
170 int i, j;
171 /* tag: ColorMap */
172 svars[0]=320; svars[1]=3; memcpy(cptr, svars, 4); cptr+=4;
173 ivars[0]=3*256; memcpy(cptr, ivars, 4); cptr+=4;
174 //svars[0]=2048; memcpy(cptr, svars, 2); cptr+=4;
175 ivars[0]=2048; memcpy(cptr, ivars, 4); cptr+=4;
176 /* offset of the next IFD, or 0000 */
177 for(i=0; i<4; i++) *cptr++=(char)0;
178 /* Color table */
179 cptr=buf+2048;
180 /* red */
181 for(i=0, j=0; j<6; j++) {
182 svars[i++]=bitty[j].r;
183 for(int k=1; k<bitty[j].n; k++, i++) svars[i]=svars[i-1]+bitty[j].dr;
184 }
185 if(colorscale==PET_RAINBOW_WB) svars[0]=255;
186 memcpy(cptr, svars, 512); cptr+=512;
187 /* green */
188 for(i=0, j=0; j<6; j++) {
189 svars[i++]=bitty[j].g;
190 for(int k=1; k<bitty[j].n; k++, i++) svars[i]=svars[i-1]+bitty[j].dg;
191 }
192 if(colorscale==PET_RAINBOW_WB) svars[0]=255;
193 memcpy(cptr, svars, 512); cptr+=512;
194 /* blue */
195 for(i=0, j=0; j<6; j++) {
196 svars[i++]=bitty[j].b;
197 for(int k=1; k<bitty[j].n; k++, i++) svars[i]=svars[i-1]+bitty[j].db;
198 }
199 if(colorscale==PET_RAINBOW_WB) svars[0]=255;
200 memcpy(cptr, svars, 512); cptr+=512;
201 }
202
203 /* write the IFD */
204 if(fwrite(buf, 1, 4096, fp) != 4096) {
205 fclose(fp); remove(fname);
206 if(status!=NULL) strcpy(status, "cannot write file");
207 return(13);
208 }
209
210 /* Write pixel data */
211 cdata=(char*)calloc(matXdim*matYdim*pxlNr, sizeof(char));
212 if(cdata==NULL) {
213 fclose(fp); remove(fname);
214 if(status!=NULL) strcpy(status, "out of memory");
215 return(14);
216 }
217 cptr=cdata;
218 int mi=0; int mc=0; int mr=1;
219 for(int fi=0; fi<img->dimt; fi++) if(frame<0 || frame==fi) {
220 for(int pi=0; pi<img->dimz; pi++) if(plane<0 || plane==pi) {
221 mi++; mc++;
222 for(int ri=0; ri<img->dimy; ri++)
223 for(int ci=0; ci<img->dimx; ci++) {
224 cptr=cdata + (mr-1)*matXdim*pxlNr + ri*matXdim*img->dimx + (mc-1)*img->dimx + ci;
225 if(img->m[pi][ri][ci][fi]>0.0) {
226 if((img->m[pi][ri][ci][fi])<(*maxvalue))
227 *cptr=(unsigned char)(255.*(img->m[pi][ri][ci][fi])/(*maxvalue));
228 else *cptr=(unsigned char)255;
229 } else
230 *cptr=(unsigned char)0;
231 }
232 if(mc==matXdim) {mc=0; mr++;}
233 }
234 }
235 cptr=cdata;
236 if(fwrite(cptr, 1, matXdim*matYdim*pxlNr, fp) != (unsigned int)matXdim*matYdim*pxlNr) {
237 fclose(fp); remove(fname); free(cdata);
238 if(status!=NULL) strcpy(status, "cannot write file");
239 return(15);
240 }
241 free(cdata);
242
243 fclose(fp);
244 if(status!=NULL) strcpy(status, "ok");
245 return(0);
246}
247/*****************************************************************************/
248
249/*****************************************************************************/
250
int tiffWriteImg(IMG *img, int plane, int frame, float *maxvalue, int colorscale, char *fname, int matXdim, int matYdim, int verbose, char *status)
Definition imgtiff.c:15
#define IMG_STATUS_OCCUPIED
Header file for libtpcimgp.
#define PET_RAINBOW_WB
Definition libtpcimgp.h:38
#define PET_RAINBOW
Definition libtpcimgp.h:36
#define PET_GRAYSCALE
Definition libtpcimgp.h:32
int little_endian()
Definition swap.c:14
unsigned short int dimx
float **** m
char status
unsigned short int dimt
unsigned short int dimz
unsigned short int dimy