std::shared_ptr<Handler::Base> MRtrix_sparse::read (Header& H) const { if (!Path::has_suffix (H.name(), ".msh") && !Path::has_suffix (H.name(), ".msf")) return std::shared_ptr<Handler::Base>(); File::KeyValue kv (H.name(), "mrtrix sparse image"); read_mrtrix_header (H, kv); // Although the endianness of the image data itself (the sparse data offsets) actually doesn't matter // (the Image::Buffer<> class would deal with this conversion), the sparse data itself needs to have // the correct endianness for the system. Since MRtrix_sparse::create() forces the endianness of the // offset data to be native, this is the easiest way to verify that the sparse data also has the // correct endianness #ifdef MRTRIX_BYTE_ORDER_BIG_ENDIAN const DataType dt = DataType::UInt64BE; #else const DataType dt = DataType::UInt64LE; #endif if (H.datatype() != dt) throw Exception ("Cannot open sparse image file " + H.name() + " due to type mismatch; expect " + dt.description() + ", file is " + H.datatype().description()); Header::const_iterator name_it = H.find (Image::Sparse::name_key); if (name_it == H.end()) throw Exception ("sparse data class name not specified in sparse image header " + H.name()); Header::const_iterator size_it = H.find (Image::Sparse::size_key); if (size_it == H.end()) throw Exception ("sparse data class size not specified in sparse image header " + H.name()); std::string image_fname, sparse_fname; size_t image_offset, sparse_offset; get_mrtrix_file_path (H, "file", image_fname, image_offset); ParsedName::List image_list; std::vector<int> image_num = image_list.parse_scan_check (image_fname); get_mrtrix_file_path (H, "sparse_file", sparse_fname, sparse_offset); Handler::Default base_handler (H); for (size_t n = 0; n < image_list.size(); ++n) base_handler.files.push_back (File::Entry (image_list[n].name(), image_offset)); std::shared_ptr<Handler::Base> handler (new Handler::Sparse (base_handler, name_it->second, to<size_t>(size_it->second), File::Entry (sparse_fname, sparse_offset))); return handler; }
RefPtr<Handler::Base> MRtrix_GZ::read (Header& H) const { if (!Path::has_suffix (H.name(), ".mif.gz")) return RefPtr<Handler::Base>(); File::GZ zf (H.name(), "r"); std::string first_line = zf.getline(); if (first_line != "mrtrix image") { zf.close(); throw Exception ("invalid first line for compressed image \"" + H.name() + "\" (expected \"mrtrix image\", read \"" + first_line + "\")"); } read_mrtrix_header (H, zf); zf.close(); std::string fname; size_t offset; get_mrtrix_file_path (H, "file", fname, offset); if (fname != H.name()) throw Exception ("GZip-compressed MRtrix format images must have image data within the same file as the header"); std::stringstream header; header << "mrtrix image\n"; write_mrtrix_header (H, header); offset = header.str().size() + size_t(24); offset += ((4 - (offset % 4)) % 4); header << "file: . " << offset << "\nEND\n"; RefPtr<Handler::Base> handler (new Handler::GZ (H, offset)); memcpy (reinterpret_cast<Handler::GZ*>((Handler::Base*)handler)->header(), header.str().c_str(), header.str().size()); memset (reinterpret_cast<Handler::GZ*>((Handler::Base*)handler)->header() + header.str().size(), 0, offset - header.str().size()); handler->files.push_back (File::Entry (H.name(), offset)); return handler; }
RefPtr<Handler::Base> MRtrix::read (Header& H) const { if (!Path::has_suffix (H.name(), ".mih") && !Path::has_suffix (H.name(), ".mif")) return RefPtr<Handler::Base>(); File::KeyValue kv (H.name(), "mrtrix image"); read_mrtrix_header (H, kv); std::string fname; size_t offset; get_mrtrix_file_path (H, "file", fname, offset); ParsedName::List list; std::vector<int> num = list.parse_scan_check (fname); RefPtr<Handler::Base> handler (new Handler::Default (H)); for (size_t n = 0; n < list.size(); ++n) handler->files.push_back (File::Entry (list[n].name(), offset)); return handler; }