| Bsoft 2.0.5 Bernard's software package

rwTIFF.cpp
Go to the documentation of this file.
1
9 #include "rwTIFF.h"
10 #include "utilities.h"
11
12 #ifdef HAVE_TIFF
13
14 #include "tiff.h"
15 #include "tiffio.h"
16 #include "tiffiop.h"
17
18 // Declaration of global variables
19 extern int verbose; // Level of output to the screen
20
21 extern char* month[];
22
36 int readTIFF(Bimage* p, int readdata, int img_select)
37 {
38 if ( verbose & VERB_DEBUG )
39 cout << "DEBUG readTIFF: Reading image: " << p->file_name() << endl;
40
41 TIFF* fimg;
42 if ( ( fimg = TIFFOpen(p->file_name().c_str(), "r") ) == NULL ) return -1;
43
44 int flags(0);
45 if ( verbose & VERB_DEBUG ) {
46 // cout << "Magic number:" << fimg->tif_header.tiff_magic << endl;
47 flags = TIFFPRINT_STRIPS & TIFFPRINT_CURVES & TIFFPRINT_COLORMAP;
48 TIFFPrintDirectory(fimg, stdout, flags);
49 }
50
51 // Map the parameters
52 long i, n, iz, iy, j, jz, jy, k;
53 uint32 x(1), y(1), z(1), px, py, pz;
54 uint16 compression(COMPRESSION_NONE);
55 uint16 samplesperpixel(1), bitspersample(0), lutsize(0);
56 uint16 sampleformat(SAMPLEFORMAT_UINT), photometric(0);
57 uint16 planarconfig(PLANARCONFIG_CONTIG);
58 uint16 orientation(ORIENTATION_BOTLEFT);
59 float xresolution(1), yresolution(1);
60 uint16* red = NULL;
61 uint16* green = NULL;
62 uint16* blue = NULL;
63
64 // Get the number of images in the file
65 int notdone(1), nimg(0);
66
67 if ( img_select > -1 ) {
68 while ( TIFFReadDirectory(fimg) ) nimg++;
69 if ( img_select > nimg ) img_select = nimg;
70 p->images(1);
71 TIFFSetDirectory(fimg, img_select);
72 TIFFGetField(fimg, TIFFTAG_IMAGEWIDTH, &x);
73 TIFFGetField(fimg, TIFFTAG_IMAGELENGTH, &y);
74 TIFFGetField(fimg, TIFFTAG_IMAGEDEPTH, &z);
75 p->size(x, y, z);
76 } else {
77 do {
78 TIFFGetField(fimg, TIFFTAG_IMAGEWIDTH, &x); // Test if image is the same size as the first image
79 TIFFGetField(fimg, TIFFTAG_IMAGELENGTH, &y);
80 TIFFGetField(fimg, TIFFTAG_IMAGEDEPTH, &z);
81 if ( nimg == 0 ) {
82 p->size(x, y, z);
83 nimg++;
84 } else {
85 if ( x != p->sizeX() || y != p->sizeY() || z != p->sizeZ() ) {
86 cerr << "Warning: TIFF image " << nimg << " is of a different size: " << x << "," << y << "," << z << endl;
87 cerr << " ---> Only " << nimg << " images read!" << endl;
88 notdone = 0;
89 } else nimg++;
90 }
91 } while ( notdone && TIFFReadDirectory(fimg) );
92 p->images(nimg);
93 TIFFSetDirectory(fimg, 0);
94 }
95
96 tm* t = p->get_localtime();
97 char* timestring = NULL, mon[4];
98 TIFFGetField(fimg, TIFFTAG_DATETIME, &timestring);
99 if ( timestring ) {
100 if ( verbose & VERB_DEBUG )
101 cout << "TIFF timestring: " << timestring << endl;
102 if ( isdigit(timestring[0]) ) {
103 sscanf(timestring, "%4d:%2d:%2d %2d:%2d:%2d",
104 &t->tm_year, &t->tm_mon, &t->tm_mday,
105 &t->tm_hour, &t->tm_min, &t->tm_sec);
106 t->tm_mon -= 1;
107 } else {
108 sscanf(timestring, "%3s %3s %2d %2d:%2d:%2d %4d",
109 mon, mon, &t->tm_mday, &t->tm_hour, &t->tm_min, &t->tm_sec, &t->tm_year);
110 for ( i=0; strncmp(mon, month[i], 3) != 0; i++ ) ;
111 if ( i < 12 ) t->tm_mon = i;
112 }
113 t->tm_year -= 1900;
114 p->set_time(t);
115 }
116
117 TIFFGetField(fimg, TIFFTAG_COMPRESSION, &compression);
118 // if ( compression > COMPRESSION_NONE ) {
119 // cerr << "Error: Decompression of TIFF files is not supported in Bsoft!" << endl;
120 // fclose(fimg);
121 // return -3;
122 // }
123
124 TIFFGetField(fimg, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
125
126 // Allocate the sub-image array structure
127 // cout << "***** TIFF images read = " << p->n << endl;
128
129 p->channels(samplesperpixel);
130 if ( p->sizeX() < 1 ) p->sizeX(1);
131 if ( p->sizeY() < 1 ) p->sizeY(1);
132 if ( p->sizeZ() < 1 ) p->sizeZ(1);
133 if ( p->channels() < 1 ) p->channels(1);
134 p->page_size(p->size());
135 if ( TIFFIsTiled(fimg) ) {
136 TIFFGetField(fimg, TIFFTAG_TILEWIDTH, &x);
137 TIFFGetField(fimg, TIFFTAG_TILELENGTH, &y);
138 TIFFGetField(fimg, TIFFTAG_TILEDEPTH, &z);
139 p->page_size(x, y, z);
140 }
141
142 TIFFGetField(fimg, TIFFTAG_XRESOLUTION, &xresolution);
143 TIFFGetField(fimg, TIFFTAG_YRESOLUTION, &yresolution);
144 if ( verbose & VERB_DEBUG )
145 cout << "DEBUG readTIFF: xresolution=" << xresolution << " yresolution=" << yresolution << endl;
146 p->sampling(xresolution, yresolution, 1);
147 if ( p->sizeZ() > 1 && fabs(p->sampling()[0] - p->sampling()[1]) < 0.001 )
148 p->sampling(xresolution, yresolution, xresolution);
149
150 TIFFGetField(fimg, TIFFTAG_BITSPERSAMPLE, &bitspersample);
151 TIFFGetField(fimg, TIFFTAG_PHOTOMETRIC, &photometric);
152 TIFFGetField(fimg, TIFFTAG_SAMPLEFORMAT, &sampleformat);
153 TIFFGetField(fimg, TIFFTAG_ORIENTATION, &orientation);
154
155 if ( verbose & VERB_DEBUG )
156 cout << "DEBUG readTIFF: bitspersample=" << bitspersample << " tiff datatype=" << sampleformat << endl;
157
158 switch ( photometric ) {
159 case PHOTOMETRIC_MINISWHITE:
160 case PHOTOMETRIC_MINISBLACK:
161 p->compound_type(TSimple); break;
162 case PHOTOMETRIC_RGB:
163 case PHOTOMETRIC_YCBCR:
164 p->compound_type(TRGB);
165 if ( p->channels() == 4 ) p->compound_type(TRGBA);
166 break;
167 case PHOTOMETRIC_SEPARATED:
168 p->compound_type(TCMYK);
169 break;
170 case PHOTOMETRIC_PALETTE:
171 p->compound_type(TRGB);
172 lutsize = 1;
173 for ( i=0; i<bitspersample; i++ ) lutsize *= 2;
174 if ( verbose & VERB_DEBUG )
175 cout << "DEBUG readTIFF: lutsize=" << lutsize << endl;
176 break;
177 default:
178 p->compound_type(TSimple);
179 }
180
181 switch ( bitspersample ) {
182 case 1:
183 p->data_type(Bit);
184 break;
185 case 8:
186 p->data_type(UCharacter);
187 if ( sampleformat == SAMPLEFORMAT_INT )
188 p->data_type(SCharacter);
189 break;
190 case 16:
191 p->data_type(UShort);
192 if ( sampleformat == SAMPLEFORMAT_INT )
193 p->data_type(Short);
194 break;
195 case 32:
196 p->data_type(UInteger);
197 if ( sampleformat == SAMPLEFORMAT_INT )
198 p->data_type(Integer);
199 else if ( sampleformat == SAMPLEFORMAT_IEEEFP )
200 p->data_type(Float);
201 break;
202 case 64:
203 p->data_type(ULong);
204 if ( sampleformat == SAMPLEFORMAT_INT )
205 p->data_type(Long);
206 else if ( sampleformat == SAMPLEFORMAT_IEEEFP )
207 p->data_type(Double);
208 break;
209 default:
210 p->data_type(UCharacter);
211 }
212
213 if ( verbose & VERB_DEBUG )
214 cout << "DEBUG readTIFF: Datatype=" << p->data_type() << " Compoundtype=" << p->compound_type() << endl;
215
216 uint16 min(0), max(0);
217 double dmin(0), dmax(0);
218 if ( p->data_type() <= Short ) {
219 TIFFGetField(fimg, TIFFTAG_MINSAMPLEVALUE, &min);
220 TIFFGetField(fimg, TIFFTAG_MAXSAMPLEVALUE, &max);
221 p->minimum(min);
222 p->maximum(max);
223 } else {
224 TIFFGetField(fimg, TIFFTAG_SMINSAMPLEVALUE, &dmin);
225 TIFFGetField(fimg, TIFFTAG_SMAXSAMPLEVALUE, &dmax);
226 p->minimum(dmin);
227 p->maximum(dmax);
228 }
229
230 char* label = NULL;
231 TIFFGetField(fimg, TIFFTAG_IMAGEDESCRIPTION, &label);
232 if ( label ) p->label(label);
233
234 if ( verbose & VERB_DEBUG )
235 cout << "DEBUG readTIFF: Minimum and maximum: " << p->minimum() << " " << p->maximum() << endl;
236
237 int tilesize;
238 long datatypesize = p->data_type_size();
239 long elementsize = p->channels()*datatypesize;
240 long linesize = p->sizeX()*elementsize;
241 unsigned char* data = NULL;
242 char *page;
243
244 if ( p->data_type() == Bit ) linesize = p->page_size()[0]/8;
245
246 TIFFGetField(fimg, TIFFTAG_PLANARCONFIG, &planarconfig);
247 if ( samplesperpixel > 1 && planarconfig == PLANARCONFIG_SEPARATE ) {
248 cerr << "Error: Separate planes not supported!" << endl;
249 // bexit(-1);
250 }
251
252 if ( verbose & VERB_DEBUG )
253 cout << "DEBUG readTIFF: readdata=" << readdata << " datasize=" <<
254 p->data_size() << " linesize=" << linesize << endl;
255
256 if ( !readdata ) {
257 TIFFClose(fimg);
258 if ( lutsize ) {
259 p->data_type(UShort);
260 p->channels(3);
261 }
262 return 0;
263 }
264
265 data = p->data_alloc();
266
267 unsigned short* rgbdata = NULL;
268 unsigned short idx;
269 long datasize = p->images()*p->sizeX()*p->sizeY()*p->sizeZ();
270 if ( lutsize ) {
271 if ( verbose & VERB_DEBUG )
272 cout << "DEBUG readTIFF: lutsize=" << lutsize << endl;
273 rgbdata = new unsigned short[3*datasize];
274 }
275
276 n = nimg = 0;
277 do {
278 if ( lutsize ) {
279 TIFFGetField(fimg, TIFFTAG_COLORMAP, &red, &green, &blue);
280 if ( verbose & VERB_DEBUG ) {
281 cout << "DEBUG readTIFF: lut:" << endl;
282 for ( i=0; i<lutsize; i++ )
283 cout << i << tab << red[i] << tab << green[i] << tab << blue[i] << endl;
284 }
285 }
286 TIFFGetField(fimg, TIFFTAG_PLANARCONFIG, &planarconfig);
287 if ( samplesperpixel > 1 && planarconfig == PLANARCONFIG_SEPARATE ) {
288 cerr << "Error: Separate planes not supported!" << endl;
289 bexit(-1);
290 }
291 if ( TIFFIsTiled(fimg) ) {
292 TIFFGetField(fimg, TIFFTAG_TILEWIDTH, &x);
293 TIFFGetField(fimg, TIFFTAG_TILELENGTH, &y);
294 TIFFGetField(fimg, TIFFTAG_TILEDEPTH, &z);
295 p->page_size(x, y, z);
296 tilesize = TIFFTileSize(fimg);
297
298 if ( verbose & VERB_DEBUG )
299 cout << "DEBUG readTIFF: tile size: " << x << " x " << y
300 << " x " << z << " = " << tilesize << endl;
301
302 page = new char[tilesize];
303 for ( pz=0; pz<p->sizeZ(); pz+=p->page_size()[2] ) {
304 for ( py=0; py<p->sizeY(); py+=p->page_size()[1] ) {
305 for ( px=0; px<p->sizeX(); px+=p->page_size()[0] ) {
306 TIFFReadTile(fimg, (char *) page, px, py, pz, 0);
307 for ( z=0; z<p->page_size()[2] && z<p->sizeZ()-pz; z++ ) {
308 iz = (nimg*p->sizeZ() + z + pz)*p->sizeY();
309 jz = z*p->page_size()[1];
310 for ( y=0; y<p->page_size()[1] && y<p->sizeY()-py; y++ ) {
311 iy = (iz + y + py)*p->sizeX();
312 jy = (jz + y)*p->page_size()[0];
313 if ( p->data_type() == Bit ) {
314 iy /= 8;
315 jy /= 8;
316 memcpy(data+iy, page+jy, linesize);
317 } else {
318 for ( x=0; x<p->page_size()[0] && x<p->sizeX()-px; x++ ) {
319 i = (iy + x + px)*elementsize;
320 j = (jy + x)*elementsize;
321 memcpy(data+i, page+j, elementsize);
322 }
323 }
324 }
325 }
326 }
327 }
328 }
329 delete[] page;
330 } else {
331
332 linesize = TIFFScanlineSize(fimg);
333 if ( verbose & VERB_DEBUG )
334 cout << "DEBUG readTIFF: scanline size=" << linesize << endl;
335
336 i = nimg*p->sizeZ()*p->sizeY()*linesize;
337 for ( z=0; z<p->sizeZ(); z++ ) {
338 for ( y=0; y<p->sizeY(); y++, i+=linesize ) {
339 // Note: Scanline rows are ambiguous for 3D images
340 TIFFReadScanline(fimg, data+i, y, 0);
341 if ( lutsize ) {
342 if ( bitspersample == 8 ) {
343 for ( x=0, j=i, k=3*j; x<p->sizeX(); x++, j++ ) {
344 idx = data[j];
345 rgbdata[k++] = red[idx];
346 rgbdata[k++] = green[idx];
347 rgbdata[k++] = blue[idx];
348 }
349 } else {
350 unsigned short* usdata = (unsigned short *) data;
351 for ( x=0, j=i/2, k=3*j; x<p->sizeX(); x++, j++ ) {
352 idx = usdata[j];
353 rgbdata[k++] = red[idx];
354 rgbdata[k++] = green[idx];
355 rgbdata[k++] = blue[idx];
356 }
357 }
358 }
359 }
360 }
361 }
362 p->image[nimg].view(0,0,1,0);
363 nimg++;
364 if ( verbose & VERB_DEBUG )
365 cout << "DEBUG readTIFF: image " << n << " read" << endl;
366 // }
367 n++;
368 } while ( n < p->images() && TIFFReadDirectory(fimg) );
369
370 TIFFClose(fimg);
371
372 if ( verbose & VERB_DEBUG )
373 cout << "DEBUG readTIFF: images read: " << p->images() << endl << endl;
374
375 if ( lutsize ) {
376 p->data_type(UShort);
377 p->channels(3);
378 p->data_assign((unsigned char *) rgbdata);
379 }
380
381 // Adherance to conventions:
382 // Density is positive-valued displayed as white on black background
383 // Display orientation is with the origin at the bottom left
384 Bstring order("xyz");
385 if ( p->data_pointer() ) {
386 if ( verbose & VERB_DEBUG )
387 cout << "DEBUG readTIFF: Tiff photometric order: " << photometric << endl;
388 if ( photometric == PHOTOMETRIC_MINISWHITE ) p->invert();
389 switch ( orientation ) {
390 case ORIENTATION_TOPLEFT: order = "x-yz"; break;
391 case ORIENTATION_TOPRIGHT: order = "-x-yz"; break;
392 case ORIENTATION_BOTRIGHT: order = "-xyz"; break;
393 case ORIENTATION_LEFTTOP: order = "-yxz"; break;
394 case ORIENTATION_RIGHTTOP: order = "-y-xz"; break;
395 case ORIENTATION_RIGHTBOT: order = "y-xz"; break;
396 case ORIENTATION_LEFTBOT: order = "yxz"; break;
397 default: order = "xyz";
398 }
399 if ( verbose & VERB_DEBUG )
400 cout << "DEBUG readTIFF: Tiff image order: " << order << endl;
401 if ( orientation != ORIENTATION_BOTLEFT ) p->reslice(order);
402 }
403
404 return 0;
405 }
406
418 int writeTIFF(Bimage* p, int flags)
419 {
420 TIFF *fimg;
421 if ( ( fimg = TIFFOpen(p->file_name().c_str(), "w") ) == NULL ) return -1;
422
423 // Map the parameters
424 int istiled = flags & 1;
425 // uint16 compression = flags & 62;
426 // uint16 compression(COMPRESSION_LZW);
427 uint16 compression(flags & COMPRESSION_LZW);
428 long i, j, y, z, n;
429 uint16 min = (uint16) p->minimum();
430 uint16 max = (uint16) p->maximum();
431 uint16 resolution_unit(1);
432 float xresolution = p->sampling()[0];
433 float yresolution = p->sampling()[1];
434 uint32 rowsperstrip = (uint32) -1;
435
436 long datatypesize = p->data_type_size();
437 long datasize = p->sizeX()*p->sizeY()*p->sizeZ()*p->channels()*datatypesize;
438 long linesize = p->sizeX()*p->channels()*datatypesize;
439 long unitsize = 64;
440 long pagesize, tilerowsize(0);
441 char* page;
442 // unsigned char* scanline;
443
444 if ( p->data_type() == Bit ) {
445 linesize = p->page_size()[0]/8;
446 datasize = linesize*p->sizeY()*p->sizeZ();
447 }
448
449 p->page_size((int) (unitsize*floor(p->sizeX()*1.0/unitsize + 0.99999)),
450 (int) (unitsize*floor(p->sizeY()*1.0/unitsize + 0.99999)), 1);
451
452 long tilex = (int) (unitsize*floor(p->sizeX()*1.0/unitsize + 0.99999));
453 long tiley = (int) (unitsize*floor(p->sizeY()*1.0/unitsize + 0.99999));
454 long tilez(1);
455
456 tm* t = p->get_localtime();
457 char timestring[20];
458 snprintf(timestring, 20, "%4d:%02d:%02d %02d:%02d:%02d",
459 t->tm_year+1900, t->tm_mon+1, t->tm_mday,
460 t->tm_hour, t->tm_min, t->tm_sec);
461
462 for ( n=0; n<p->images(); n++ ) {
463 TIFFSetDirectory(fimg, n);
464 TIFFSetField(fimg, TIFFTAG_IMAGEWIDTH, p->sizeX());
465 TIFFSetField(fimg, TIFFTAG_IMAGELENGTH, p->sizeY());
466 TIFFSetField(fimg, TIFFTAG_IMAGEDEPTH, p->sizeZ());
467 TIFFSetField(fimg, TIFFTAG_SAMPLESPERPIXEL, p->channels());
468 if ( istiled ) {
469 TIFFSetField(fimg, TIFFTAG_TILEWIDTH, tilex);
470 TIFFSetField(fimg, TIFFTAG_TILELENGTH, tiley);
471 TIFFSetField(fimg, TIFFTAG_TILEDEPTH, tilez);
472 } else
473 TIFFSetField(fimg, TIFFTAG_ROWSPERSTRIP,
474 TIFFDefaultStripSize(fimg, rowsperstrip));
475 if ( compression )
476 TIFFSetField(fimg, TIFFTAG_COMPRESSION, compression);
477
478 if ( verbose & VERB_DEBUG ) {
479 cout << "DEBUG writeTIFF: Image " << n << ": size " << p->sizeX() << " "
480 << p->sizeY() << " " << p->sizeZ() << " " << p->channels() << endl;
481 cout << "DEBUG writeTIFF: page dimensions: " <<
482 p->page_size()[0] << " " << p->page_size()[1] << " " << p->page_size()[2] << endl;
483 }
484
485 TIFFSetField(fimg, TIFFTAG_RESOLUTIONUNIT, resolution_unit);
486 TIFFSetField(fimg, TIFFTAG_XRESOLUTION, xresolution);
487 TIFFSetField(fimg, TIFFTAG_YRESOLUTION, yresolution);
488
489 TIFFSetField(fimg, TIFFTAG_IMAGEDESCRIPTION, p->label().c_str());
490 TIFFSetField(fimg, TIFFTAG_DATETIME, timestring);
491
492 if ( p->data_type() <= Short ) {
493 TIFFSetField(fimg, TIFFTAG_MINSAMPLEVALUE, min);
494 TIFFSetField(fimg, TIFFTAG_MAXSAMPLEVALUE, max);
495 } else {
496 TIFFSetField(fimg, TIFFTAG_SMINSAMPLEVALUE, p->minimum());
497 TIFFSetField(fimg, TIFFTAG_SMAXSAMPLEVALUE, p->maximum());
498 }
499
500 if ( verbose & VERB_DEBUG )
501 cout << "DEBUG writeTIFF: min & max: " << min << " " << max << endl;
502
503 switch ( p->data_type() ) {
504 case Bit:
505 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
506 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 1);
507 break;
508 case UCharacter:
509 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
510 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 8);
511 break;
512 case SCharacter:
513 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
514 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 8);
515 break;
516 case UShort:
517 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
518 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 16);
519 break;
520 case Short:
521 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
522 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 16);
523 break;
524 case UInteger:
525 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
526 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 32);
527 break;
528 case Integer:
529 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
530 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 32);
531 break;
532 case ULong:
533 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
534 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 64);
535 break;
536 case Long:
537 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
538 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 64);
539 break;
540 case Float:
541 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
542 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 32);
543 break;
544 case Double:
545 TIFFSetField(fimg, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
546 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 64);
547 break;
548 default:
549 TIFFSetField(fimg, TIFFTAG_BITSPERSAMPLE, 8);
550 }
551
552 int extraTypes[1] = {EXTRASAMPLE_ASSOCALPHA};
553 switch ( p->compound_type() ) {
554 case TSimple:
555 TIFFSetField(fimg, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
556 break;
557 case TVector3:
558 case TRGB:
559 TIFFSetField(fimg, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
560 break;
561 case TRGBA:
562 TIFFSetField(fimg, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
563 TIFFSetField(fimg, TIFFTAG_EXTRASAMPLES, 1, extraTypes);
564 break;
565 case TCMYK:
566 TIFFSetField(fimg, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED);
567 TIFFSetField(fimg, TIFFTAG_INKSET, INKSET_CMYK);
568 break;
569 default:
570 TIFFSetField(fimg, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
571 }
572
573 TIFFSetField(fimg, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
574 TIFFSetField(fimg, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
575
576 if ( verbose & VERB_DEBUG ) {
577 cout << "DEBUG writeTIFF: configuration set to planar" << endl;
578 cout << "DEBUG writeTIFF: Typesize=" << datatypesize << " Datasize=" << datasize << endl;
579 if ( istiled )
580 cout << "DEBUG writeTIFF: Tilesize=" << TIFFTileSize(fimg) << endl;
581 else
582 cout << "DEBUG writeTIFF: Scanlinesize=" << TIFFScanlineSize(fimg) << endl;
583 cout << "DEBUG writeTIFF: Pages: ";
584 }
585
586 if ( istiled ) {
587 pagesize = TIFFTileSize(fimg);
588 page = new char[pagesize];
589 tilerowsize = TIFFTileRowSize(fimg);
590 for ( z=0; z<p->sizeZ(); z++ ) {
591 memset(page, 0, pagesize);
592 for ( y=0; y<p->sizeY(); y++ ) {
593 i = y*tilerowsize;
594 j = ((n*p->sizeZ() + z)*p->sizeY() + y)*linesize;
595 memcpy(page+i, p->data_pointer()+j, linesize);
596 }
597 if ( verbose & VERB_DEBUG ) cout << " " << z;
598 TIFFWriteTile(fimg, page, 0, 0, z, 0);
599 }
600 delete[] page;
601 } else {
602 if ( verbose & VERB_DEBUG )
603 cout << "DEBUG writeTIFF: linesize=" << linesize << endl;
604 for ( z=0; z<p->sizeZ(); z++ ) {
605 for ( y=0; y<p->sizeY(); y++ ) {
606 j = ((n*p->sizeZ() + z)*p->sizeY() + y)*linesize;
607 TIFFWriteScanline(fimg, p->data_pointer()+j, y, 0);
608 // Note: Scanline rows are ambiguous for 3D images
609 }
610 if ( verbose & VERB_DEBUG ) cout << " " << z;
611 }
612 }
613 if ( verbose & VERB_DEBUG ) cout << endl;
614
615 TIFFWriteDirectory(fimg);
616 } // End of multi-image loop
617
618 if ( verbose & VERB_DEBUG )
619 cout << "DEBUG writeTIFF: data written" << endl;
620
621 TIFFClose(fimg);
622
623 if ( verbose & VERB_DEBUG )
624 cout << "DEBUG writeTIFF: Memory freed" << endl;
625
626 return 0;
627 }
628
629 #else
630
631 int readTIFF(Bimage* p, int readdata, int img_select)
632 {
633 cerr << "Error: TIFF files are not supported!" << endl;
634
635 return -1;
636 }
637
638 int writeTIFF(Bimage* p, int istiled)
639 {
640 cerr << "Error: TIFF files are not supported!" << endl;
641
642 return -1;
643 }
644
645 #endif
rwTIFF.h
Header file for reading and writing TIFF files.
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:143
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Bimage::invert
void invert()
Inverts the data in the image.
Definition: Bimage.cpp:3108
Bimage::data_type_size
long data_type_size() const
Returns the size of the datatype in bytes.
Definition: Bimage.cpp:1585
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
Integer
Definition: utilities.h:154
SCharacter
Definition: utilities.h:150
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
Long
Definition: utilities.h:156
TCMYK
Definition: Bimage.h:64
TVector3
Definition: Bimage.h:60
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
UInteger
Definition: utilities.h:153
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
Bimage::maximum
double maximum()
Definition: Bimage.h:535
Double
Definition: utilities.h:158
Bimage::label
void label(string s)
Definition: Bimage.h:235
Bimage::data_assign
unsigned char * data_assign(unsigned char *nudata)
Assign image data.
Definition: Bimage.cpp:852
ULong
Definition: utilities.h:155
Bimage::set_time
void set_time(time_t t)
Definition: Bimage.h:249
verbose
int verbose
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::get_localtime
tm * get_localtime()
Definition: Bimage.h:245
Bimage::channels
long channels()
Definition: Bimage.h:371
Bimage::reslice
void reslice(const char *order)
Definition: Bimage.h:709
TRGB
Definition: Bimage.h:62
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
UCharacter
Definition: utilities.h:149
Bstring
Definition: Bstring.h:29
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
Bit
Definition: utilities.h:148
writeTIFF
int writeTIFF(Bimage *p, int istiled)
Definition: rwTIFF.cpp:638
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
readTIFF
int readTIFF(Bimage *p, int readdata, int img_select)
Definition: rwTIFF.cpp:631
month
const char * month[]
Definition: rwimg.cpp:55
Short
Definition: utilities.h:152
TRGBA
Definition: Bimage.h:63
UShort
Definition: utilities.h:151
Bimage::page_size
Vector3< long > page_size()
Definition: Bimage.h:480
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bimage::minimum
double minimum()
Definition: Bimage.h:534
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
Bimage::data_size
long data_size()
Definition: Bimage.h:255
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:188