36 #define MAXPATHLEN (MAX_PATH*4)
46const char *AmiraIO::MAGIC =
"# AmiraMesh";
48AmiraIO::AmiraIO(
const string & fname,
IOMode rw)
50 is_big_endian(true), dt(
EMUtil::EM_UNKNOWN),
52 pixel(0), xorigin(0), yorigin(0), zorigin(0)
73 bool is_new_file =
false;
79 if (!fgets(buf, MAXPATHLEN,
file)) {
87 if(strstr(buf,
"BINARY-LITTLE-ENDIAN")!=0) {
90 else if(strstr(buf,
"BINARY")!=0) {
93 else if(strstr(buf,
"2.0")!=0) {
119 if(image_index == -1) {
123 if(image_index != 0) {
124 throw ImageReadException(
filename,
"no stack allowed for MRC image. For take 2D slice out of 3D image, read the 3D image first, then use get_clip().");
129 char ll[MAXPATHLEN+10];
130 char datatype[16] =
"";
133 char * str = fgets(ll,MAXPATHLEN,
file); str = str;
135 if(
char* s=strstr(ll,
"define Lattice ")) {
136 if(sscanf(s+15,
"%d %d %d",&
nx, &
ny, &
nz) == 3) {
143 else if(
char* s=strstr(ll,
"BoundingBoxXY")) {
144 float bx0, bx1, by0, by1;
145 if (sscanf(s+13,
"%f %f %f %f",&bx0, &bx1, &by0, &by1) == 4 ) {
149 dict[
"apix_x"] =
pixel;
150 dict[
"apix_y"] =
pixel;
151 dict[
"apix_z"] =
pixel;
157 else if(
char* s=strstr(ll,
"BoundingBox")) {
158 float bx0, bx1, by0, by1, bz0, bz1;
159 if (sscanf(s+11,
"%f %f %f %f %f %f",&bx0, &bx1, &by0, &by1, &bz0, &bz1) == 6 ) {
164 dict[
"apix_x"] =
pixel;
165 dict[
"apix_y"] =
pixel;
166 dict[
"apix_z"] =
pixel;
173 else if(
char* s=strstr(ll,
"Lattice { ")) {
174 sscanf(s+10,
"%s ", datatype);
175 if(!strncmp(datatype,
"float", 5)) {
179 else if(!strncmp(datatype,
"short", 5)) {
183 else if(!strncmp(datatype,
"byte", 4)) {
188 fprintf(stderr,
"AmiraIO::read_header: data type \"%s\" is not supported yet\n", datatype);
192 }
while (! ( ll[0]==
'@' && ll[1]==
'1') );
205 if(image_index == -1) {
209 if(image_index != 0) {
231 line1=
"# AmiraMesh 3D BINARY 2.1\n\n";
234 line1=
"# AmiraMesh BINARY-LITTLE-ENDIAN 2.1\n\n";
237 string type =
"float";
239 if (fprintf(
file,
"%s", line1.c_str()) <= 0) {
244 fprintf(
file,
"define Lattice %d %d %d\n\n",
nx,
ny,
nz);
245 fprintf(
file,
"Parameters {\n");
246 fprintf(
file,
"\tContent \"%dx%dx%d %s, uniform coordinates\",\n",
nx,
ny,
nz,type.c_str());
247 fprintf(
file,
"\tCoordType \"uniform\",\n");
249 fprintf(
file,
"Lattice { float ScalarField } @1\n\n# Data section follows\n@1\n");
261 size_t size = (size_t)
nx*
ny*
nz;
270 char *cdata=(
char*)
rdata;
272 for(
size_t i=0;i<size;++i){
274 tmpdata=cdata[4*i+3];
275 cdata[4*i+3]=cdata[4*i];
276 cdata[4*i] = tmpdata;
278 tmpdata=cdata[4*i+2];
279 cdata[4*i+2]=cdata[4*i+1];
280 cdata[4*i+1] = tmpdata;
285 copydata=
new float[size];
287 for (
size_t i=0;i<size;i++){
288 copydata[i]=
rdata[i];
291 for (
int i=0;i<
ny;i++){
292 for (
int j=0;j<
nx;j++){
301 short *datashort = (
short*)malloc(
sizeof(
short)*
nx*
ny*
nz);
302 nr = fread(datashort,
nx*
nz,
ny*
sizeof(
short),
file); nr++;
306 char *cdata=(
char*)datashort;
307 for(
size_t i=0;i<size;++i){
309 tmpdata=cdata[2*i+1];
310 cdata[2*i+1]=cdata[2*i];
311 cdata[2*i] = tmpdata;
313 for(
size_t i=0; i<size; ++i)
rdata[i] =
float(datashort[i]);
318 copydata=
new float[size];
320 for (
size_t i=0;i<size;i++){
321 copydata[i]=
rdata[i];
324 for (
int i=0;i<
ny;i++){
325 for (
int j=0;j<
nx;j++){
335 char *databyte = (
char*)malloc(
sizeof(
char)*
nx*
ny*
nz);
336 nr = fread(databyte,
nx*
nz,
ny*
sizeof(
char),
file); nr++;
338 for(
size_t i=0; i<size; ++i)
rdata[i] =
float(databyte[i]);
342 copydata=
new float[size];
344 for (
size_t i=0;i<size;i++){
345 copydata[i]=
rdata[i];
348 for (
int i=0;i<
ny;i++){
349 for (
int j=0;j<
nx;j++){
358 fprintf(stderr,
"AmiraIO::read_data: data type is not supported yet\n");
372 size_t size = (size_t)
nx*
ny*
nz;
375 copydata=
new float[size];
377 for (
size_t i=0;i<size;i++){
381 for (
int i=0;i<
ny;i++){
382 for (
int j=0;j<
nx;j++){
383 data[i*
nx+j]=copydata[(
ny-1-i)*
nx+j];
388 if (fwrite(data,
nx *
nz,
ny *
sizeof(
float),
file) !=
ny *
sizeof(
float)) {
static const char * MAGIC
static bool is_valid(const void *first_block)
static bool is_host_big_endian()
Dict is a dictionary to store <string, EMObject> pair.
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
EMDataType
Image pixel data type used in EMAN.
ImageIO classes are designed for reading/writing various electron micrography image formats,...
virtual void flush()=0
Flush the IO buffer.
virtual int write_header(const Dict &dict, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0
Write a header to an image.
virtual int write_data(float *data, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0
Write data to an image.
virtual bool is_complex_mode()=0
Is this an complex image or not.
virtual int read_header(Dict &dict, int image_index=0, const Region *area=0, bool is_3d=false)=0
Read the header from an image.
FILE * sfopen(const string &filename, IOMode mode, bool *is_new=0, bool overwrite=false)
Run fopen safely.
virtual int read_data(float *data, int image_index=0, const Region *area=0, bool is_3d=false)=0
Read the data from an image.
virtual void init()=0
Do some initialization before doing the read/write.
void check_write_access(IOMode rw_mode, int image_index, int max_nimg=0)
Validate rw_mode and image_index in file writing.
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
static bool check_file_by_magic(const void *first_block, const char *magic)
check whether a file starts with certain magic string.
#define ImageReadException(filename, desc)
#define ImageWriteException(imagename, desc)