| Bsoft 2.0.5 Bernard's software package

rwDM.cpp
Go to the documentation of this file.
1
9 #include "rwDM.h"
10 #include "utilities.h"
11
12 // Declaration of global variables
13 extern int verbose; // Level of output to the screen
14
15 // Internal function prototypes
16 int readFixedDMHeader(ifstream* fimg, Bimage* p, int readdata);
17 int readTagGroupData(ifstream* fimg, int dim_flag, Bimage* p, int readdata);
18 int readTagGroupWithVersion(ifstream* fimg, Bimage* p, int readdata, int img_select);
19
20 int show(0), keep(0), version(0), sb(0), endianness(1);
21 size_t level(0);
22
41 int readDM(Bimage* p, int readdata, int img_select)
42 {
43 ifstream* fimg = new ifstream(p->file_name());
44 if ( fimg->fail() ) return -1;
45
46 // Read a small block at the beginning to see if it is the fixed or tagged format
47 char buf[1024];
48 fimg->read(buf, 4);
49 if ( fimg->fail() ) return -2;
50
51 // version = *((int *) buf);
52 version = buf[0];
53
54 if ( version < 1 || version > 4 ) version = buf[3];
55
56 if ( show == 1 )
57 cout << "Magic number = " << version << endl;
58
59 fimg->seekg(0, ios::beg);
60
61 switch ( version ) {
62 case 0: readFixedDMHeader(fimg, p, readdata); break;
63 case 3:
64 case 4: readTagGroupWithVersion(fimg, p, readdata, img_select); break;
65 default:
66 cout << "Digital Micrograph format version " << version << " not supported!" << endl;
67 }
68
69 fimg->close();
70 delete fimg;
71
72 return 0;
73 }
74
81 int writeDM(Bimage* p)
82 {
83 DMhead* header = new DMhead;
84 memset(header, 0, sizeof(DMhead));
85
86 long datatypesize = p->channels()*p->data_type_size();
87 long datasize = p->data_size();
88
89 // Map the parameters
90 header->endian = 65535;
91 header->xSize = p->sizeX();
92 header->ySize = p->sizeY();
93 header->zSize = p->sizeZ();
94 header->depth = datatypesize;
95 switch ( p->data_type() ) {
96 case UCharacter : header->type = BINARY_DATA; break;
97 case UShort : header->type = UNSIGNED_INT16_DATA; break;
98 case Short : header->type = SIGNED_INT16_DATA; break;
99 case Integer : header->type = SIGNED_INT32_DATA; break;
100 case Float : header->type = ( p->compound_type() == TComplex )? COMPLEX8_DATA: REAL4_DATA; break;
101 case Double : header->type = ( p->compound_type() == TComplex )? COMPLEX16_DATA: REAL8_DATA; break;
102 default : header->type = NULL_DATA;
103 }
104
105 p->data_offset(24);
106
107 ofstream fimg(p->file_name().c_str());
108 if ( fimg.fail() ) return -1;
109
110 fimg.write((char *)header, p->data_offset());
111 fimg.write((char *)p->data_pointer(), datasize);
112
113 fimg.close();
114
115 delete header;
116
117 return 0;
118 }
119
120
121 DataType datatype_from_dm3_type(DMDataType dm3_type, Bimage* p)
122 {
123 if ( show == 1 ) cout << "\tDMDataType=" << dm3_type << endl;
124
125 p->compound_type(TSimple);
126 p->channels(1);
127
128 DataType datatype = Unknown_Type;
129
130 switch( dm3_type ) {
131 case BINARY_DATA : datatype = UCharacter; break;
132 case UNSIGNED_INT8_DATA : datatype = UCharacter; break;
133 case SIGNED_INT8_DATA : datatype = SCharacter; break;
134 case RGB_DATA :
135 case RGB_UINT8_DATA :
136 datatype = UCharacter;
137 p->channels(3);
138 p->compound_type(TRGB);
139 break;
140 case OS_RGBA_UINT8_DATA :
141 datatype = UCharacter;
142 p->channels(4);
143 p->compound_type(TRGBA);
144 break;
145 case UNSIGNED_INT16_DATA : datatype = UShort; break;
146 case RGB_UINT16_DATA :
147 datatype = UShort;
148 p->channels(3);
149 p->compound_type(TRGB);
150 break;
151 case RGBA_UINT16_DATA :
152 datatype = UShort;
153 p->channels(4);
154 p->compound_type(TRGBA);
155 break;
156 case SIGNED_INT16_DATA : datatype = Short; break;
157 case UNSIGNED_INT32_DATA : datatype = UInteger; break;
158 case SIGNED_INT32_DATA : datatype = Integer; break;
159 case REAL4_DATA : datatype = Float; break;
160 case RGBA_FLOAT32_DATA :
161 datatype = Float;
162 p->channels(4);
163 p->compound_type(TRGBA);
164 break;
165 case REAL8_DATA : datatype = Double; break;
166 case RGB_FLOAT64_DATA :
167 datatype = Double;
168 p->channels(3);
169 p->compound_type(TRGB);
170 break;
171 case RGBA_FLOAT64_DATA :
172 datatype = Double;
173 p->channels(4);
174 p->compound_type(TRGBA);
175 break;
176 case COMPLEX8_DATA : datatype = Float; p->compound_type(TComplex); break;
177 case COMPLEX16_DATA : datatype = Double; p->compound_type(TComplex); break;
178 default : datatype = UCharacter;
179 }
180
181 p->data_type(datatype);
182 if ( p->compound_type() == TComplex ) p->channels(2);
183
184 return datatype;
185 }
186
187
188
189 int readFixedDMHeader(ifstream* fimg, Bimage* p, int readdata)
190 {
191 DMhead* header = new DMhead;
192 DMMachead* macheader = (DMMachead *) header;
193
194 // if ( fread( header, sizeof(DMhead), 1, fimg ) < 1 ) return -2;
195 fimg->read((char *)header, sizeof(DMhead));
196 if ( fimg->fail() ) return -2;
197
198 if ( verbose & VERB_DEBUG || show )
199 cout << "DEBUG readFixedDMHeader: macheader=" << macheader <<
200 " width=" << macheader->width << " height=" << macheader->height << endl;
201
202 p->data_offset(8);
203 if ( ( macheader->width < 1 ) || ( macheader->height < 1 ) ) {
204 macheader = (DMMachead *) ((char*)header + 6);
205 p->data_offset(p->data_offset() + 6);
206 }
207
208 if ( verbose & VERB_DEBUG )
209 cout << "DEBUG readFixedDMHeader: macheader=" << macheader <<
210 " width=" << macheader->width << " height=" << macheader->height << endl;
211
212 // Determine header type
213 int i, fixed(1), sb(0);
214 /* if ( macheader->width == 0 && macheader->height == -1 ) {
215 fixed = 1;
216 sb = 0;
217 } else if ( macheader->width == -1 && macheader->height == 0 ) {
218 fixed = 1;
219 sb = 1;
220 } else if ( systype(0) >= LittleIEEE ) sb = 1;
221 */
222 // Swap bytes if necessary
223 unsigned char* b = (unsigned char *) header;
224 if ( sb ) {
225 if ( fixed ) {
226 if ( verbose & VERB_PROCESS )
227 cerr << "Warning: Swapping header byte order for 4-byte types" << endl;
228 for ( i=0; i<24; i+=4 ) swapbytes(b+i, 4);
229 } else {
230 b = (unsigned char *) macheader;
231 if ( verbose & VERB_PROCESS )
232 cerr << "Warning: Swapping header byte order for 2-byte types" << endl;
233 for ( i=0; i<8; i+=2 ) swapbytes(b+i, 2);
234 }
235 }
236
237 // Map the parameters
238 p->images(1);
239 p->channels(1);
240 p->compound_type(TSimple);
241 if ( fixed ) {
242 p->size(header->xSize, header->ySize, header->zSize);
243 p->data_offset(24);
244 datatype_from_dm3_type(header->type, p);
245 } else {
246 p->size(macheader->width, macheader->height, 1);
247 switch( macheader->type ) {
248 case 6 : p->data_type(UCharacter); break;
249 case 14 : p->data_type(UCharacter); break;
250 case 9 : p->data_type(SCharacter); break;
251 case 10 : p->data_type(UShort); break;
252 case 1 : p->data_type(Short); break;
253 case 7 : p->data_type(Integer); break;
254 case 2 : p->data_type(Float); break;
255 case 3 : p->data_type(Float); p->compound_type(TComplex); p->channels(2); break;
256 case 13 : p->data_type(Double); p->compound_type(TComplex); p->channels(2); break;
257 default : p->data_type(UCharacter);
258 }
259 }
260
261
262 delete header;
263
264 if ( readdata ) {
265 fimg->read((char *)p->data_pointer(), p->alloc_size());
266 if ( fimg->fail() ) return -3;
267 if ( sb ) swapbytes(p->alloc_size(), p->data_pointer(), p->data_type_size());
268 }
269
270 fimg->close();
271
272 return sb;
273 }
274
275 int dm3_type_length(int dm3_type)
276 {
277 int dtlen = 0;
278
279 switch ( dm3_type ) {
280 case 2: dtlen = 2; break;
281 case 3: dtlen = 4; break;
282 case 4: dtlen = 2; break;
283 case 5: dtlen = 4; break;
284 case 6: dtlen = 4; break;
285 case 7: dtlen = 8; break;
286 case 8: dtlen = 1; break;
287 case 9: dtlen = 1; break;
288 case 10: dtlen = 1; break;
289 case 11: dtlen = 8; break;
290 case 12: dtlen = 8; break;
291 default:
292 cerr << "Error: Data type " << dm3_type << " length not defined!" << endl;
293 }
294
295 return dtlen;
296 }
297
298 double dm3_value(ifstream* fimg, int dm3_type)
299 {
300 int dtlen = dm3_type_length(dm3_type);
301 if ( dtlen < 1 ) return 0;
302
303 long i, ivalue(0);
304 double dvalue(0);
305 char buf[1024];
306
307 fimg->read(buf, dtlen);
308
309 if ( sb - endianness ) swapbytes((unsigned char *)buf, dtlen);
310
311 switch ( dm3_type ) {
312 case 2: ivalue = *((short *) buf); break;
313 case 3: ivalue = *((int *) buf); break;
314 case 4: ivalue = *((unsigned short *) buf); break;
315 case 5: ivalue = *((unsigned int *) buf); break;
316 case 6: dvalue = *((float *) buf); break;
317 case 7: dvalue = *((double *) buf); break;
318 case 8: ivalue = *buf; break;
319 case 9: ivalue = *buf; break;
320 case 10: ivalue = *buf; break;
321 case 11: ivalue = *((long *) buf); break;
322 case 12: ivalue = *((unsigned long *) buf); break;
323 default:
324 cerr << "Error: Data type " << dm3_type << " not defined!" << endl;
325 }
326
327 if ( !dvalue ) dvalue = ivalue;
328
329 if ( show == 1 ) cout << tab << dvalue;
330
331 if ( show == 2 ) {
332 for ( i=0; i<level; i++ ) cout << tab;
333 if ( dm3_type == 6 || dm3_type == 7 )
334 cout << "<real>" << dvalue << "</real>" << endl;
335 else
336 cout << "<integer>" << ivalue << "</integer>" << endl;
337 }
338
339 return dvalue;
340 }
341
342 unsigned long dm_read_integer(ifstream* fimg, long len)
343 {
344 unsigned short sval(0);
345 unsigned int ival(0);
346 unsigned long lval(0);
347 char buf[1024];
348
349 if ( version < 4 && len > 4 ) len = 4;
350
351 fimg->read(buf, len);
352
353 if ( sb ) swapbytes((unsigned char *)buf, len);
354
355 switch ( len ) {
356 case 2: sval = *((unsigned short *) buf); lval = sval; break;
357 case 4: ival = *((unsigned int *) buf); lval = ival; break;
358 case 8: lval = *((unsigned long *) buf); break;
359 default: lval = *buf;
360 }
361
362 return lval;
363 }
364
365 int tag_convert(unsigned char* tag)
366 {
367 for ( ; *tag; tag++ ) if ( *tag > 127 ) *tag -= 64;
368
369 return 0;
370 }
371
372 /*
373 Image data is assigned to the data pointer based on the keep flag
374 Associated properties are also kept
375 */
376 int readTag(ifstream* fimg, int dim_flag, Bimage* p, int readdata, int& notag)
377 {
378 unsigned char t, tag[128];
379 unsigned short len;
380 size_t i, k, data_size(0);
381 size_t nnum, size(0), narr, nel, dt, dtarr[128], dtlen; // Change in v4
382 double val(0), arr[256];
383 char buf[1024];
384
385 level++;
386
387 // Common part of TagSubGroup and TagEntry records
388 // Selector (1 byte): TagSubGroup=20, TagEntry=21
389 // Length of label (2 bytes)
390 // Label
391 *fimg >> t;
392 len = dm_read_integer(fimg, sizeof(unsigned short));
393 // cout << "\tlen=" << len << endl;
394
395 if ( len > 128 ) {
396 cout << "\tlen=" << len << endl;
397 cerr << "Error: tag length too long!" << endl;
398 bexit(-1);
399 }
400
401 if ( len ) {
402 fimg->read((char *)tag, len);
403 tag[len] = 0;
404 tag_convert(tag);
405 notag = 0;
406 } else {
407 snprintf((char *)tag, 128, "%d", notag);
408 notag++;
409 }
410
411 // Image list
412 if ( strcmp((char *)tag, "ImageList") == 0 ) keep = 1;
413
414 // Start of a new image specification
415 if ( keep == 1 && p->data_offset() > 0 ) {
416 if ( strcmp((char *)tag, "ImageTags") == 0 || strcmp((char *)tag, "ImageData") == 0 ) {
417 p->next = p->copy_header();
418 p = p->next;
419 p->images(1);
420 keep = 2;
421 }
422 }
423
424 if ( show == 1 ) {
425 cout << endl;
426 for ( i=0; i<level; i++ ) cout << tab;
427 cout << "Tag=" << (int)t << "\tlen=" << len << tab << tag;
428 }
429 if ( show == 2 ) {
430 for ( i=0; i<level; i++ ) cout << tab;
431 cout << "<key>" << tag << "</key>" << endl;
432 }
433
434 if ( version == 4 ) { // Changed in v4
435 size = dm_read_integer(fimg, sizeof(size_t)); // Size of data type & data
436 if ( show == 1 )
437 cout << "\tsize=" << size;
438 }
439
440 if ( t == 20 ) { // TagSubGroup record
441 if ( strcmp((char *)tag, "Dimensions") == 0 ) dim_flag = 1;
442 readTagGroupData(fimg, dim_flag, p, readdata);
443 } else if ( t == 21 ) { // TagEntry record
444 fimg->read((char *)buf, 4); // String = "%%%%"
445 buf[4] = 0;
446 nnum = dm_read_integer(fimg, sizeof(size_t)); // Number of integers in array
447 if ( show == 1 ) cout << tab << setw(4) << buf << "\tnnum=" << nnum;
448
449 for ( i=0; i<nnum; i++ ) {
450 dtarr[i] = dm_read_integer(fimg, sizeof(size_t)); // Data type array
451 if ( show == 1 ) cout << "\tdt[" << i << "]=" << dtarr[i];
452 }
453 if ( show == 1 ) cout << endl;
454
455 dt = dtarr[0];
456 if ( dt <= 12 ) {
457 val = dm3_value(fimg, dt);
458 } else if ( dt == 15 ) { // Struct
459 narr = dtarr[2];
460 nel = 1;
461 if ( show == 1 )
462 cout << "\tstruct=" << narr << "x" << nel;
463 if ( show == 2 ) {
464 for ( i=0; i<level; i++ ) cout << tab;
465 cout << "<array>" << endl;
466 }
467 level++;
468 for ( k=0; k<narr; k++ )
469 arr[k] = dm3_value(fimg, dtarr[4+2*k]);
470 level--;
471 if ( show == 2 ) {
472 for ( i=0; i<level; i++ ) cout << tab;
473 cout << "</array>" << endl;
474 }
475 } else if ( dt == 18 ) { // String
476 fimg->read((char *)buf, dtarr[1]);
477 if ( show == 1 ) cout << "\tstrlen=" << dtarr[1];
478 if ( show == 2 ) {
479 for ( i=0; i<level; i++ ) cout << tab;
480 cout << "<string>" << buf << "</string>" << endl;
481 }
482 } else if ( dt == 20 ) { // Data array
483 if ( dtarr[1] == 15 ) narr = dtarr[3];
484 else narr = 1;
485 nel = dtarr[nnum-1]; // Number of elements
486 if ( show == 1 )
487 cout << "\tarr=" << narr << "x" << nel;
488 if ( show == 2 ) {
489 for ( i=0; i<level; i++ ) cout << tab;
490 cout << "<array>" << endl;
491 }
492 level++;
493 if ( dtarr[1] == 15 ) { // Struct
494 if ( show == 1 )
495 cout << "\tstruct=" << narr << "x" << nel;
496 if ( show == 2 ) {
497 for ( i=0; i<level; i++ ) cout << tab;
498 cout << "<array>" << endl;
499 }
500 level++;
501 for ( i=0; i<nel; i++ )
502 for ( k=0; k<narr; k++ )
503 arr[k] = dm3_value(fimg, dtarr[5+2*k]);
504 level--;
505 if ( show == 2 ) {
506 for ( i=0; i<level; i++ ) cout << tab;
507 cout << "</array>" << endl;
508 }
509 } else {
510 narr = 1;
511 dtlen = dm3_type_length(dtarr[1]);
512 data_size = nel*dtlen;
513 // The big image data block is not printed for the plist format
514 if ( strcmp((char *)tag, "Data") == 0 ) {
515 // if ( nel > 1e6 ) {
516 // keep = 1;
517 // p->data_offset(fimg->tellg());
518 // }
519 // if ( show == 1 )
520 // cout << "\tdata_size=" << data_size;
521 // if ( readdata ) {
522 // p->data_alloc(data_size);
523 // fimg->read((char *)p->data_pointer(), data_size);
524 // } else {
525 // fimg->seekg(data_size, ios_base::cur);
526 // }
527 // fimg->seekg(data_size, ios_base::cur);
528 } else {
529 for ( i=0; i<nel; i++ ) {
530 if ( i < 10 ) val = dm3_value(fimg, dtarr[1]); // Element value
531 else fimg->read((char *)buf, dtlen); // Element value
532 }
533 }
534 }
535 level--;
536 if ( show == 2 ) {
537 for ( i=0; i<level; i++ ) cout << tab;
538 cout << "</array>" << endl;
539 }
540 } else {
541 cerr << "Error: Data type " << dt << " not defined!" << endl;
542 }
543
544 // if ( keep && strcmp((char *)tag, "ImageData") == 0 ) keep = 0;
545
546 if ( keep ) {
547 // show = 1;
548 // if ( show == 1 ) cout << "\tdim_flag=" << dim_flag;
549 if ( strcmp((char *)tag, "Data") == 0 ) {
550 p->data_offset(fimg->tellg());
551 if ( show == 1 )
552 cout << "\tdata_size=" << data_size;
553 fimg->seekg(data_size, ios_base::cur);
554 }
555 if ( strcmp((char *)tag, "DataType") == 0 ) {
556 datatype_from_dm3_type((DMDataType)val, p);
557 if ( show == 1 )
558 cout << "\tdatatype=" << p->data_type() << "\tcompoundtype=" <<
559 p->compound_type() << "\tc=" << p->channels() << "\tval=" << val;
560 }
561 if ( strcmp((char *)tag, "Minimum Value (counts)") == 0 ) {
562 p->minimum(val);
563 }
564 if ( strcmp((char *)tag, "Maximum Value (counts)") == 0 ) {
565 p->maximum(val);
566 }
567 if ( dim_flag == 1 ) {
568 p->sizeX((long) val);
569 dim_flag = 2;
570 } else if ( dim_flag == 2 ) {
571 p->sizeY((long) val);
572 dim_flag = 3;
573 } else if ( dim_flag == 3 ) {
574 p->images((long) val);
575 dim_flag = 0;
576 if ( show == 1 ) cout << "\tx=" << p->sizeX() << "\ty=" <<
577 p->sizeY() << "\tn=" << p->images();
578 }
579 if ( strcmp((char *)tag, "PixelDepth") == 0 ) {
580 if ( show == 1 ) cout << tab << tag << "=" << val << endl;
581 }
582 // if ( strcmp((char *)tag, "Scale") == 0 ) {
583 // p->sampling(val, val, 1);
584 // if ( show == 1 ) cout << tab << tag << "=" << p->sampling() << endl;
585 // cout << tab << tag << "=" << p->sampling() << endl;
586 // }
587 if ( strcmp((char *)tag, "Pixel Size (um)") == 0 ) {
588 p->sampling(arr[0], arr[1], 1);
589 if ( show == 1 ) cout << tab << tag << "=" << p->sampling() << endl;
590 // cout << tab << tag << "=" << p->sampling() << endl;
591 }
592 if ( strcmp((char *)tag, "Actual Magnification") == 0 ) {
593 if ( val ) {
594 p->show_scale(val/1e4);
595 if ( show == 1 ) cout << tab << tag << "=" << val << endl;
596 // cout << tab << tag << "=" << val << endl;
597 }
598 }
599 if ( strcmp((char *)tag, "Pixel Upsampling") == 0 ) {
600 if ( show == 1 ) cout << tab << tag << "=" << arr[0] << "x" << arr[1] << endl;
601 }
602 if ( strcmp((char *)tag, "SourceSize_Pixels") == 0 ) {
603 if ( show == 1 ) cout << tab << tag << "=" << arr[0] << "x" << arr[1] << endl;
604 }
605 // if ( strcmp(tag, "ImageIndex") == 0 ) {
606 // if ( show == 1 ) cout << tab << tag << "=" << val << endl;
607 // }
608 if ( strstr((char *)tag, "Emission") ) {
609 if ( show == 1 ) {
610 cout << tab << tag << "=" << val << endl;
611 // for ( i=0; i<len; i++ ) cout << (int)tag[i] << tab << tag[i] << endl;
612 }
613 }
614 // show = 0;
615 }
616 } else {
617 cerr << "Error: Undefined tag type! (" << t << ")" << endl;
618 }
619
620 level--;
621
622 return 0;
623 }
624
625 // TagGroupData contains 3 items
626 // Sorted flag: 0,1; v3-v4 (1 byte)
627 // Open flag: 0,1; v3-v4 (1 byte)
628 // Number of records (TagEntry/TagSubGroup): v3 (4 byte), v4 (8 byte)
629 // Content (TagGroupData)
630 int readTagGroupData(ifstream* fimg, int dim_flag, Bimage* p, int readdata)
631 {
632 unsigned char sorted, open;
633 size_t i, ntag(0);
634 int notag(0);
635
636 *fimg >> sorted;
637 *fimg >> open;
638
639 ntag = dm_read_integer(fimg, sizeof(size_t)); // Number of tags
640
641 if ( show == 1 ) cout << "\tntag=" << ntag;
642 if ( show == 2 ) {
643 for ( i=0; i<level; i++ ) cout << tab;
644 cout << "<dict>" << endl;
645 }
646
647 for ( i=0; i<ntag; i++ ) {
648 readTag(fimg, dim_flag, p, readdata, notag);
649 if ( dim_flag ) dim_flag++;
650 }
651
652 if ( show == 2 ) {
653 for ( i=0; i<level; i++ ) cout << tab;
654 cout << "</dict>" << endl;
655 }
656
657 return 0;
658 }
659
660 /*
661 Main DM3/4 file database:
662
663 Arrangement:
664 The file header (TagGroupWithVersion) contains 4 items:
665 Version: 1-4 (4 byte)
666 Size of contained data (TagGroupData): v1-v3 (4 byte), v4 (8 byte)
667 Endianness: 0,1 (4 byte)
668 Content (TagGroupData)
669
670 Important image information:
671 Main block: "ImageList"
672 May contain more than one image, usually a small display version
673 followed by the real data
674 Important elements:
675 Pixel size (nm): ImageData/Calibrations/Dimension/Scale
676 Data element type: ImageData/DataType
677 Image size: ImageData/Dimensions
678 Data element size: ImageData/PixelDepth
679 Camera pixel size (um): ImageTags/Acquisition/Device/CCD/Pixel Size (um)
680 Dose rate: ImageTags/Calibration/Dose rate/Calibration
681 Magnification: ImageTags/Microscope Info/Actual Magnification
682 Acceleration voltage: ImageTags/Microscope Info/Voltage
683 */
684 int readTagGroupWithVersion(ifstream* fimg, Bimage* p, int readdata, int img_select)
685 {
686 if ( verbose & VERB_DEBUG_DM ) show = 2;
687
688 keep = level = 0;
689
690 size_t file_length(0), val(0);
691 char buf[1024];
692
693 fimg->read(buf, 4);
694 if ( fimg->fail() ) return -2;
695
696 version = *((int *) buf);
697
698 if ( version > 100 ) {
699 sb = 1;
700 version = buf[3];
701 }
702
703 file_length = dm_read_integer(fimg, sizeof(size_t)); // File length
704 file_length += 16;
705
706 endianness = dm_read_integer(fimg, sizeof(unsigned int)); // Endianness
707
708 if ( show == 1 ) {
709 if ( sb ) cout << "Warning: Swapping header bytes" << endl;
710 cout << "Version: " << version << endl;
711 cout << "File length: " << file_length << endl;
712 cout << "Endianness: " << endianness << endl;
713 }
714
715 if ( file_length <= 16 ) {
716 cout << "Error: file length = " << file_length << endl;
717 return error_show("File length specifier incorrect!\n", __FILE__, __LINE__);
718 }
719
720 if ( show == 2 ) {
721 cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
722 cout << "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << endl;
723 cout << "<plist version=\"1.0\">" << endl;
724 }
725
726 // Set up default parameters
727 p->size(1, 1, 1);
728 p->channels(1);
729 p->images(1);
730
731 readTagGroupData(fimg, 0, p, readdata);
732
733 // End of file
734 val = dm_read_integer(fimg, sizeof(unsigned int)); // 500
735 val = dm_read_integer(fimg, sizeof(unsigned int)); // Label size
736 if ( val ) {
737 fimg->read(buf, val);
738 if ( show == 2 ) cout << "<" << buf << "/>" << endl;
739 }
740
741 if ( show == 1 ) cout << endl;
742 if ( show == 2 ) cout << "</plist>" << endl;
743
744 int i;
745 Bimage* p1 = NULL;
746 if ( verbose & VERB_FULL ) {
747 for ( p1 = p, i = 0; p1; p1 = p1->next, ++i )
748 cout << "Image " << i << " dimensions: " <<
749 p1->channels() << tab << p1->size() << tab << p1->images() << endl;
750 cout << endl;
751 }
752
753 if ( p->next ) {
754 if ( p->next->sizeX() > p->sizeX() ) *p = *(p->next);
755 delete p->next;
756 p->next = NULL;
757 }
758
759 if ( img_select >= 0 ) {
760 p->data_offset(p->data_offset()+img_select*p->sizeX()*p->sizeY()*p->sizeZ()*p->channels()*p->data_type_size());
761 p->images(1);
762 }
763
764 if ( p->show_scale() != 1 ) {
765 p->sampling(p->sampling()[0]/p->show_scale(), p->sampling()[1]/p->show_scale(), 1);
766 p->show_scale(1);
767 }
768
769 if ( readdata ) {
770 // fimg->seekg(p->data_offset(), ios_base::beg);
771 // p->data_alloc();
772 // fimg->read((char *)p->data_pointer(), p->alloc_size());
773 // if ( version == 4 ) sb = 0;
774 sb -= endianness;
775 // cout << "sb = " << sb << endl;
776 p->read_data(fimg, 0, sb, 0, 0);
777 }
778
779 return version;
780 }
781
782
verbose
int verbose
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:650
DMDataType
DMDataType
Definition: rwDM.h:13
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
DMMachead::height
short height
Definition: rwDM.h:33
UNSIGNED_INT8_DATA
Definition: rwDM.h:15
Bimage::data_type_size
long data_type_size() const
Returns the size of the datatype in bytes.
Definition: Bimage.cpp:1585
RGBA_FLOAT32_DATA
Definition: rwDM.h:17
dm3_type_length
int dm3_type_length(int dm3_type)
Definition: rwDM.cpp:275
utilities.h
Header file for general utilities.
Bimage::read_data
unsigned char * read_data(ifstream *fimg, int img_select, int sb, int vax, long pad)
Read image data in a generalized style.
Definition: Bimage.cpp:2188
RGBA_UINT16_DATA
Definition: rwDM.h:18
UNSIGNED_INT32_DATA
Definition: rwDM.h:16
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
datatype_from_dm3_type
DataType datatype_from_dm3_type(DMDataType dm3_type, Bimage *p)
Definition: rwDM.cpp:121
Integer
Definition: utilities.h:154
DMMachead::type
short type
Definition: rwDM.h:35
DMhead::ySize
int ySize
Definition: rwDM.h:25
NULL_DATA
Definition: rwDM.h:14
OS_RGBA_UINT8_DATA
Definition: rwDM.h:19
SCharacter
Definition: utilities.h:150
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bimage::show_scale
double show_scale()
Definition: Bimage.h:556
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
TComplex
Definition: Bimage.h:59
SIGNED_INT16_DATA
Definition: rwDM.h:14
RGB_FLOAT64_DATA
Definition: rwDM.h:18
REAL4_DATA
Definition: rwDM.h:14
RGB_UINT8_DATA
Definition: rwDM.h:19
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
UInteger
Definition: utilities.h:153
SIGNED_INT32_DATA
Definition: rwDM.h:15
Bimage::maximum
double maximum()
Definition: Bimage.h:535
Double
Definition: utilities.h:158
DMhead::depth
int depth
Definition: rwDM.h:27
DMhead::type
DMDataType type
Definition: rwDM.h:28
VERB_DEBUG_DM
#define VERB_DEBUG_DM
Definition: utilities.h:115
RGB_UINT16_DATA
Definition: rwDM.h:17
sb
int sb(0)
writeDM
int writeDM(Bimage *p)
Writing a Digital Micrograph map image file format.
Definition: rwDM.cpp:81
BINARY_DATA
Definition: rwDM.h:17
readFixedDMHeader
int readFixedDMHeader(ifstream *fimg, Bimage *p, int readdata)
Definition: rwDM.cpp:189
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::data_offset
long data_offset()
Definition: Bimage.h:265
level
size_t level(0)
Bimage::channels
long channels()
Definition: Bimage.h:371
endianness
int endianness(1)
swapbytes
void swapbytes(unsigned char *v, size_t n)
Swaps bytes.
Definition: utilities.cpp:504
TRGB
Definition: Bimage.h:62
Bimage::next
Bimage * next
Definition: Bimage.h:165
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
COMPLEX16_DATA
Definition: rwDM.h:17
readDM
int readDM(Bimage *p, int readdata, int img_select)
Reading a Digital Micrograph image file format.
Definition: rwDM.cpp:41
DMhead
Definition: rwDM.h:22
dm_read_integer
unsigned long dm_read_integer(ifstream *fimg, long len)
Definition: rwDM.cpp:342
UCharacter
Definition: utilities.h:149
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
readTagGroupWithVersion
int readTagGroupWithVersion(ifstream *fimg, Bimage *p, int readdata, int img_select)
Definition: rwDM.cpp:684
keep
int keep(0)
COMPLEX8_DATA
Definition: rwDM.h:14
Bimage::alloc_size
long alloc_size() const
Definition: Bimage.h:252
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
DMhead::zSize
int zSize
Definition: rwDM.h:26
REAL8_DATA
Definition: rwDM.h:16
RGBA_FLOAT64_DATA
Definition: rwDM.h:18
show
int show(0)
DMhead::xSize
int xSize
Definition: rwDM.h:24
version
int version(0)
readTag
int readTag(ifstream *fimg, int dim_flag, Bimage *p, int readdata, int &notag)
Definition: rwDM.cpp:376
Short
Definition: utilities.h:152
Unknown_Type
Definition: utilities.h:147
TRGBA
Definition: Bimage.h:63
DMhead::endian
unsigned int endian
Definition: rwDM.h:23
UShort
Definition: utilities.h:151
Bimage::images
long images()
Definition: Bimage.h:491
readTagGroupData
int readTagGroupData(ifstream *fimg, int dim_flag, Bimage *p, int readdata)
Definition: rwDM.cpp:630
dm3_value
double dm3_value(ifstream *fimg, int dm3_type)
Definition: rwDM.cpp:298
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
tag_convert
int tag_convert(unsigned char *tag)
Definition: rwDM.cpp:365
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
RGB_DATA
Definition: rwDM.h:15
Bimage::data_size
long data_size()
Definition: Bimage.h:255
SIGNED_INT8_DATA
Definition: rwDM.h:16
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
rwDM.h
Header file for reading and writing DM files.
DMMachead::width
short width
Definition: rwDM.h:32
DMMachead
Definition: rwDM.h:31
UNSIGNED_INT16_DATA
Definition: rwDM.h:16