Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

salio.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #include "salio.h"
00037 #include "util.h"
00038 #include "geometry.h"
00039 
00040 #ifndef WIN32
00041 #include <sys/param.h>
00042 #else
00043 #define  MAXPATHLEN (MAX_PATH * 4)
00044 #endif
00045 
00046 #include <cstdio>
00047 #include <climits>
00048 #include <cstring>
00049 
00050 using namespace EMAN;
00051 
00052 const char *SalIO::HDR_EXT = "hdr";
00053 const char *SalIO::IMG_EXT = "img";
00054 const char *SalIO::MAGIC = " IDENTIFICATION";
00055 
00056 
00057 SalIO::SalIO(const string & file, IOMode rw)
00058 :       filename(file), rw_mode(rw), sal_file(0), initialized(false)
00059 {
00060         nx = 0;
00061         ny = 0;
00062         record_length = 512;
00063         scan_mode = NON_RASTER_SCAN;
00064         pixel = 4.6667f;
00065 }
00066 
00067 SalIO::~SalIO()
00068 {
00069         if (sal_file) {
00070                 fclose(sal_file);
00071                 sal_file = 0;
00072         }
00073 }
00074 
00075 void SalIO::init()
00076 {
00077         ENTERFUNC;
00078 
00079         if (initialized) {
00080                 return;
00081         }
00082 
00083         initialized = true;
00084 
00085         string hdr_filename = Util::change_filename_ext(filename, HDR_EXT);
00086         string img_filename = Util::change_filename_ext(filename, IMG_EXT);
00087 
00088         bool is_new_file = false;
00089         sal_file = sfopen(hdr_filename, rw_mode, &is_new_file);
00090 
00091         char scan_type[MAXPATHLEN];
00092         ScanAxis axis = X_SCAN_AXIS;
00093 
00094         if (!is_new_file) {
00095                 char buf[MAXPATHLEN];
00096                 if (fgets(buf, MAXPATHLEN, sal_file)) {
00097                         if (!is_valid(buf)) {
00098                                 throw ImageReadException(filename, "ivalid SAL");
00099                         }
00100                 }
00101 
00102                 while (fgets(buf, MAXPATHLEN, sal_file)) {
00103                         const char *buf1 = buf + 1;
00104 
00105                         if (Util::sstrncmp(buf1, "NXP")) {
00106                                 sscanf(strchr(buf, '=') + 1, " %d", &nx);
00107                         }
00108                         else if (Util::sstrncmp(buf1, "NYP")) {
00109                                 sscanf(strchr(buf, '=') + 1, " %d", &ny);
00110                         }
00111                         else if (Util::sstrncmp(buf1, "AXSCAN")) {
00112                                 char *t = strrchr(buf, '\'');
00113                                 if (t && t[-1] == 'Y') {
00114                                         axis = Y_SCAN_AXIS;
00115                                 }
00116                         }
00117                         else if (Util::sstrncmp(buf1, "FILE REC LEN")) {
00118                                 sscanf(strchr(buf, '=') + 1, " %d", &record_length);
00119                         }
00120                         else if (Util::sstrncmp(buf1, "SCAN TYPE")) {
00121                                 sscanf(strchr(buf, '\'') + 1, " %s", scan_type);
00122                                 if (scan_type[0] == 'R') {
00123                                         scan_mode = RASTER_SCAN;
00124                                 }
00125                         }
00126                         else if (Util::sstrncmp(buf1, "DELTAX")) {
00127                                 sscanf(strchr(buf, '=') + 1, " %f", &pixel);
00128                                 pixel /= 3.0;
00129                         }
00130                 }
00131 
00132 
00133                 if (axis == Y_SCAN_AXIS) {
00134                         int t = nx;
00135                         nx = ny;
00136                         ny = t;
00137                 }
00138         }
00139         fclose(sal_file);
00140         sal_file = sfopen(img_filename, rw_mode);
00141 
00142         EXITFUNC;
00143 }
00144 
00145 bool SalIO::is_valid(const void *first_block)
00146 {
00147         ENTERFUNC;
00148         bool result = false;
00149 
00150         if (!first_block) {
00151                 result = false;
00152         }
00153         result = Util::check_file_by_magic(first_block, MAGIC);
00154         EXITFUNC;
00155         return result;
00156 }
00157 
00158 int SalIO::read_header(Dict & dict, int image_index, const Region * area, bool)
00159 {
00160         ENTERFUNC;
00161 
00162         //single image format, index can only be zero
00163         if(image_index == -1) {
00164                 image_index = 0;
00165         }
00166 
00167         if(image_index != 0) {
00168                 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().");
00169         }
00170 
00171         init();
00172         
00173         check_region(area, IntSize(nx, ny));
00174 
00175         int xlen = 0, ylen = 0;
00176         EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
00177 
00178         dict["nx"] = xlen;
00179         dict["ny"] = ylen;
00180         dict["nz"] = 1;
00181         dict["datatype"] = EMUtil::EM_SHORT;
00182         dict["SAL.pixel"] = pixel;
00183 
00184         EXITFUNC;
00185         return 0;
00186 }
00187 
00188 int SalIO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00189 {
00190         ENTERFUNC;
00191         LOGWARN("SAL write is not supported.");
00192         EXITFUNC;
00193         return 1;
00194 }
00195 
00196 int SalIO::read_data(float *data, int image_index, const Region * area, bool)
00197 {
00198         ENTERFUNC;
00199 
00200         //single image format, index can only be zero
00201         image_index = 0;
00202         check_read_access(image_index, data);
00203         check_region(area, IntSize(nx, ny));
00204 
00205         if (scan_mode != NON_RASTER_SCAN) {
00206                 LOGERR("only NON_RASTER_SCAN scan mode is supported in a SAL image");
00207                 return 1;
00208         }
00209 
00210         rewind(sal_file);
00211 
00212         int mode_size = (int)sizeof(short);
00213         unsigned char *cdata = (unsigned char *) data;
00214         short *sdata = (short *) data;
00215         size_t row_size = nx * mode_size;
00216         size_t block_size = (((row_size - 1) / record_length) + 1) * record_length;
00217         size_t post_row = block_size - row_size;
00218 
00219         EMUtil::process_region_io(cdata, sal_file, READ_ONLY, image_index,
00220                                                           mode_size, nx, ny, 1, area, false,
00221                                                           EMUtil::IMAGE_SAL, 0, post_row);
00222 
00223 #if 0
00224         int row_size = nx * mode_size;
00225         int block_size = (((row_size - 1) / record_length) + 1) * record_length;
00226 
00227         for (int j = 0; j < ny; j++) {
00228                 if (fread(&cdata[j * row_size], block_size, 1, sal_file) != 1) {
00229                         LOGERR("Incomplete SAL data read %d/%d blocks", j, ny);
00230                         return 1;
00231                 }
00232         }
00233 #endif
00234 
00235         int xlen = 0, ylen = 0;
00236         EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
00237 
00238         if (scan_mode == NON_RASTER_SCAN) {
00239                 become_host_endian(sdata, xlen * ylen);
00240 
00241                 for (int i = 0; i < ylen; i += 2) {
00242                         for (int j = 0; j < xlen / 2; j++) {
00243                                 short sw = sdata[i * xlen + j];
00244                                 sdata[i * xlen + j] = sdata[i * xlen + xlen - j - 1];
00245                                 sdata[i * xlen + xlen - j - 1] = sw;
00246                         }
00247                 }
00248         }
00249 
00250         for (int i = xlen * ylen - 1; i >= 0; i--) {
00251                 data[i] = static_cast < float >((cdata[i * 2 + 1] * UCHAR_MAX) + cdata[i * 2]);
00252         }
00253         EXITFUNC;
00254         return 0;
00255 }
00256 
00257 int SalIO::write_data(float *, int, const Region* , EMUtil::EMDataType, bool)
00258 {
00259         ENTERFUNC;
00260         LOGWARN("SAL write is not supported.");
00261         EXITFUNC;
00262         return 1;
00263 }
00264 
00265 void SalIO::flush()
00266 {
00267 }
00268 
00269 
00270 bool SalIO::is_complex_mode()
00271 {
00272         return false;
00273 }
00274 
00275 bool SalIO::is_image_big_endian()
00276 {
00277         return false;
00278 }
00279 

Generated on Tue Jun 11 13:40:43 2013 for EMAN2 by  doxygen 1.3.9.1