35 #include <sys/param.h>
38 #define MAXPATHLEN (MAX_PATH * 4)
51# define INT8_MIN (-128)
52# define INT16_MIN (-32767-1)
53# define INT32_MIN (-2147483647-1)
56# define INT8_MAX (127)
57# define INT16_MAX (32767)
58# define INT32_MAX (2147483647)
61# define UINT8_MAX (255)
62# define UINT16_MAX (65535)
63# define UINT32_MAX (4294967295U)
68hid_t HdfIO::mapinfo_type = -1;
69const char *HdfIO::HDF5_SIGNATURE =
"\211HDF\r\n\032\n";
71herr_t attr_info(hid_t dataset,
const char *name,
void *opdata)
73 hid_t attr = H5Aopen_name(dataset, name);
74 float value_float = 0.0f;
76 string value_string =
"";
77 char * tmp_string =
new char[1024];
81 hid_t atype = H5Aget_type(attr);
82 if (H5Tget_class(atype) == H5T_FLOAT) {
83 H5Aread(attr, atype, &value_float);
84 (*dict)[name] = value_float;
86 else if(H5Tget_class(atype) == H5T_INTEGER) {
87 H5Aread(attr, atype, &value_int);
88 (*dict)[name] = value_int;
90 else if(H5Tget_class(atype) == H5T_STRING) {
91 H5Aread(attr, atype, tmp_string);
92 value_string = tmp_string;
93 (*dict)[name] = value_string;
95 else if(H5Tget_class(atype) == H5T_ENUM || H5Tget_class(atype) == H5T_ARRAY) {
100 LOGERR(
"can only handle float/int/string parameters in HDF attr_info()");
110HdfIO::HdfIO(
const string & fname, IOMode rw)
117 cur_image_index = -1;
130 H5Fflush(file,H5F_SCOPE_GLOBAL);
146 FILE *tmp_file = sfopen(filename, rw_mode, &is_new_file);
150 if (fread(buf,
sizeof(buf), 1, tmp_file) != 1) {
155 if (!is_valid(buf)) {
165 if (rw_mode == READ_ONLY) {
166 file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
170 file = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
173 file = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
175 file = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
183 string root_group_str = get_item_name(ROOT_GROUP);
184 group = H5Gopen(file, root_group_str.c_str());
187 H5Giterate(file, root_group_str.c_str(), NULL, file_info, &image_indices);
194bool HdfIO::is_valid(
const void *first_block)
199 char signature[8] = { char(137),char(72),char(68),char(70),char(13),char(10),char(26), char(10) };
200 if (strncmp((
const char *)first_block,signature,8)==0)
return true;
209int HdfIO::read_header(
Dict & dict,
int image_index,
const Region * area,
bool)
213 check_read_access(image_index);
215 int nx = 0, ny = 0, nz = 0;
216 if (get_hdf_dims(image_index, &nx, &ny, &nz) != 0) {
220 check_region(area,
IntSize(nx, ny, nz));
222 int xlen = 0, ylen = 0, zlen = 0;
223 EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen, nz, &zlen);
225 set_dataset(image_index);
227 if (cur_dataset < 0) {
231 err = H5Aiterate(cur_dataset, 0, attr_info, &dict);
250 read_euler_angles(euler_angles, image_index);
252 vector<string> euler_names = euler_angles.
keys();
253 for (
size_t i = 0; i < euler_names.size(); i++) {
254 dict[euler_names[i]] = euler_angles[euler_names[i]];
257 dict[
"datatype"] = EMUtil::EM_FLOAT;
267 check_read_access(image_index, data);
268 set_dataset(image_index);
270 if (cur_dataset < 0) {
271 char cur_dataset_name[32];
272 sprintf(cur_dataset_name,
"%d", image_index);
273 cur_dataset = H5Dopen(file, cur_dataset_name);
275 if (cur_dataset < 0) {
277 sprintf(desc,
"no image with id = %d", image_index);
282 hid_t datatype = H5Dget_type(cur_dataset);
283 H5T_class_t t_class = H5Tget_class(datatype);
286 if (t_class != H5T_FLOAT) {
288 sprintf(desc,
"unsupported HDF5 data type '%d'", (
int) t_class);
292 int nx = 0, ny = 0, nz = 0;
293 if (get_hdf_dims(image_index, &nx, &ny, &nz) != 0) {
297 check_region(area,
FloatSize(nx, ny, nz));
301 err = H5Dread(cur_dataset, H5T_NATIVE_FLOAT, H5S_ALL,
302 H5S_ALL, H5P_DEFAULT, data);
305 hid_t dataspace_id = 0;
306 hid_t memspace_id = 0;
308 err = create_region_space(&dataspace_id, &memspace_id, area,
309 nx, ny, nz, image_index);
311 err = H5Dread(cur_dataset, H5T_NATIVE_FLOAT, memspace_id,
312 dataspace_id, H5P_DEFAULT, data);
315 H5Sclose(dataspace_id);
316 H5Sclose(memspace_id);
319 "creating memory space or file space id failed");
325 sprintf(desc,
"reading %dth HDF5 image failed", image_index);
334int HdfIO::write_header(
const Dict & dict,
int image_index,
const Region* area,
338 check_write_access(rw_mode, image_index);
345 if (get_hdf_dims(image_index, &nx0, &ny0, &nz0) != 0) {
349 check_region(area,
FloatSize(nx0, ny0, nz0), is_new_file);
359 create_cur_dataset(image_index, nx, ny, nz);
362 vector<string> keys = dict.
keys();
363 vector<string>::const_iterator iter;
364 for (iter = keys.begin(); iter != keys.end(); iter++) {
366 if(*iter ==
"orientation_convention") {
367 string eulerstr = (
const char*) dict[
"orientation_convention"];
368 write_string_attr(image_index,
"orientation_convention", eulerstr);
370 vector<string> euler_names = EMUtil::get_euler_names(eulerstr);
372 for (
size_t i = 0; i < euler_names.size(); i++) {
373 euler_dict[euler_names[i]] = dict[euler_names[i]];
376 write_euler_angles(euler_dict, image_index);
379 else if(*iter ==
"micrograph_id") {
380 write_string_attr(image_index,
"micrograph_id", (
const char *) dict[
"micrograph_id"]);
390 write_int_attr(image_index, *iter, attr_val);
392 case EMObject::FLOAT:
393 case EMObject::DOUBLE:
394 write_float_attr(image_index, *iter, attr_val);
396 case EMObject::STRING:
397 write_string_attr(image_index, *iter, attr_val.
to_str());
400 case EMObject::XYDATA:
401 case EMObject::FLOATARRAY:
402 case EMObject::STRINGARRAY:
405 case EMObject::UNKNOWN:
427 check_write_access(rw_mode, image_index, 0, data);
429 int nx = read_int_attr(image_index,
"nx");
430 int ny = read_int_attr(image_index,
"ny");
431 int nz = read_int_attr(image_index,
"nz");
434 check_region(area,
FloatSize(nx, ny, nz), is_new_file);
435 create_cur_dataset(image_index, nx, ny, nz);
441 err = H5Dwrite(cur_dataset, H5T_NATIVE_FLOAT, H5S_ALL,
442 H5S_ALL, H5P_DEFAULT, data);
449 hid_t dataspace_id = 0;
450 hid_t memspace_id = 0;
452 err = create_region_space(&dataspace_id, &memspace_id, area,
453 nx, ny, nz, image_index);
455 err = H5Dwrite(cur_dataset, H5T_NATIVE_FLOAT, memspace_id,
456 dataspace_id, H5P_DEFAULT, data);
459 H5Sclose(dataspace_id);
460 H5Sclose(memspace_id);
463 "creating memory space or file space id failed");
480 if (cur_dataset > 0) {
481 H5Fflush(cur_dataset, H5F_SCOPE_LOCAL);
485int *HdfIO::read_dims(
int image_index,
int *p_ndim)
487 set_dataset(image_index);
489 if (cur_dataset < 0) {
490 char cur_dataset_name[32];
491 sprintf(cur_dataset_name,
"%d", image_index);
492 cur_dataset = H5Dopen(file, cur_dataset_name);
494 if (cur_dataset < 0) {
499 hid_t dataspace = H5Dget_space(cur_dataset);
500 int rank = H5Sget_simple_extent_ndims(dataspace);
501 hsize_t *dims =
new hsize_t[rank];
502 H5Sget_simple_extent_dims(dataspace, dims, NULL);
504 int *dims1 =
new int[rank];
505 for (
int i = 0; i < rank; i++) {
506 dims1[i] =
static_cast < int >(dims[i]);
520int HdfIO::read_global_int_attr(
const string & attr_name)
523 hid_t attr = H5Aopen_name(group, attr_name.c_str());
528 H5Aread(attr, H5T_NATIVE_INT, &value);
535float HdfIO::read_global_float_attr(
const string & attr_name)
538 hid_t attr = H5Aopen_name(group, attr_name.c_str());
540 H5Aread(attr, H5T_NATIVE_INT, &value);
550 int n = read_global_int_attr(get_item_name(NUMDATASET));
556void HdfIO::increase_num_dataset()
560 write_global_int_attr(get_item_name(NUMDATASET), n);
564void HdfIO::set_dataset(
int image_index)
568 if (cur_image_index >= 0) {
569 if (image_index != cur_image_index) {
574 cur_image_index = image_index;
578 if (need_update || cur_dataset < 0) {
579 char cur_dataset_name[32];
580 sprintf(cur_dataset_name,
"%d", image_index);
583 cur_dataset = H5Dopen(file, cur_dataset_name);
584 if (cur_dataset < 0) {
588 cur_image_index = image_index;
596int HdfIO::read_int_attr(
int image_index,
const string & attr_name)
598 set_dataset(image_index);
601 hid_t attr = H5Aopen_name(cur_dataset, attr_name.c_str());
603 H5Aread(attr, H5T_NATIVE_INT, &value);
614float HdfIO::read_float_attr(
int image_index,
const string & attr_name)
616 set_dataset(image_index);
617 return read_float_attr(attr_name);
621float HdfIO::read_float_attr(
const string & attr_name)
624 hid_t attr = H5Aopen_name(cur_dataset, attr_name.c_str());
626 H5Aread(attr, H5T_NATIVE_FLOAT, &value);
638string HdfIO::read_string_attr(
int image_index,
const string & attr_name)
640 set_dataset(image_index);
641 hid_t attr = H5Aopen_name(cur_dataset, attr_name.c_str());
648 char *tmp_value =
new char[MAXPATHLEN];
649 hid_t datatype = H5Tcopy(H5T_C_S1);
650 H5Tset_size(datatype, MAXPATHLEN);
651 H5Aread(attr, datatype, tmp_value);
668int HdfIO::read_array_attr(
int image_index,
const string & attr_name,
void *value)
670 set_dataset(image_index);
673 hid_t attr = H5Aopen_name(cur_dataset, attr_name.c_str());
675 LOGERR(
"no such hdf attribute '%s'", attr_name.c_str());
679 hid_t datatype = H5Aget_type(attr);
680 H5Aread(attr, datatype, value);
687float HdfIO::read_euler_attr(
int image_index,
const string &attr_name)
689 string full_attr_name = string(EULER_MAGIC) + attr_name;
690 return read_float_attr(image_index, full_attr_name);
694int HdfIO::read_mapinfo_attr(
int image_index,
const string & attr_name)
696 set_dataset(image_index);
699 hid_t attr = H5Aopen_name(cur_dataset, attr_name.c_str());
701 LOGERR(
"no such hdf attribute '%s'", attr_name.c_str());
704 H5Aread(attr, mapinfo_type, &val);
707 return static_cast < int >(val);
710int HdfIO::write_int_attr(
int image_index,
const string & attr_name,
int value)
712 set_dataset(image_index);
713 return write_int_attr(attr_name, value);
717int HdfIO::write_int_attr(
const string & attr_name,
int value)
720 delete_attr(attr_name);
722 hid_t dataspace = H5Screate(H5S_SCALAR);
723 hid_t attr = H5Acreate(cur_dataset, attr_name.c_str(), H5T_NATIVE_INT, dataspace, H5P_DEFAULT);
726 err = H5Awrite(attr, H5T_NATIVE_INT, &value);
739int HdfIO::write_float_attr_from_dict(
int image_index,
const string & attr_name,
743 return write_float_attr(image_index, attr_name, dict[attr_name]);
748int HdfIO::write_float_attr(
int image_index,
const string & attr_name,
float value)
750 set_dataset(image_index);
751 return write_float_attr(attr_name, value);
754int HdfIO::write_float_attr(
const string & attr_name,
float value)
757 delete_attr(attr_name);
758 hid_t dataspace = H5Screate(H5S_SCALAR);
760 H5Acreate(cur_dataset, attr_name.c_str(), H5T_NATIVE_FLOAT, dataspace, H5P_DEFAULT);
763 err = H5Awrite(attr, H5T_NATIVE_FLOAT, &value);
776int HdfIO::write_string_attr(
int image_index,
const string & attr_name,
777 const string & value)
779 set_dataset(image_index);
782 delete_attr(attr_name);
784 hid_t datatype = H5Tcopy(H5T_C_S1);
785 H5Tset_size(datatype, value.size() + 1);
786 hid_t dataspace = H5Screate(H5S_SCALAR);
788 hid_t attr = H5Acreate(cur_dataset, attr_name.c_str(), datatype, dataspace, H5P_DEFAULT);
790 err = H5Awrite(attr, datatype, (
void *) value.c_str());
804int HdfIO::write_array_attr(
int image_index,
const string & attr_name,
805 int nitems,
void *data, DataType type)
814 set_dataset(image_index);
815 delete_attr(attr_name);
817 if (type != INT && type != FLOAT) {
818 fprintf(stderr,
"can only write INTEGER and FLOAT array");
826 hsize_t sdim[] = { 1 };
831 datatype = H5Tarray_create(H5T_NATIVE_INT, 1, dim, perm);
833 else if (type == FLOAT) {
834 datatype = H5Tarray_create(H5T_NATIVE_FLOAT, 1, dim, perm);
837 hid_t dataspace = H5Screate_simple(1, sdim, NULL);
838 hid_t attr = H5Acreate(cur_dataset, attr_name.c_str(), datatype, dataspace, H5P_DEFAULT);
840 err = H5Awrite(attr, datatype, data);
855int HdfIO::write_global_int_attr(
const string & attr_name,
int value)
857 hid_t tmp_dataset = cur_dataset;
859 int err = write_int_attr(attr_name, value);
860 cur_dataset = tmp_dataset;
865int HdfIO::write_euler_attr(
int image_index,
const string & attr_name,
float value)
867 string full_attr_name = string(EULER_MAGIC) + attr_name;
868 return write_float_attr(image_index, full_attr_name, value);
872int HdfIO::write_mapinfo_attr(
int image_index,
const string & attr_name,
int value)
874 set_dataset(image_index);
875 delete_attr(attr_name);
877 hsize_t dim[] = { 1 };
878 hid_t dataspace = H5Screate_simple(1, dim, NULL);
879 hid_t attr = H5Acreate(cur_dataset, attr_name.c_str(), mapinfo_type, dataspace, H5P_DEFAULT);
880 H5Awrite(attr, mapinfo_type, &value);
887int HdfIO::delete_attr(
int image_index,
const string & attr_name)
889 set_dataset(image_index);
892 int err = H5Adelete(cur_dataset, attr_name.c_str());
903int HdfIO::delete_attr(
const string & attr_name)
906 int err = H5Adelete(cur_dataset, attr_name.c_str());
917string HdfIO::get_compound_name(
int id,
const string & name)
919 string magic = get_item_name(COMPOUND_DATA_MAGIC);
921 sprintf(id_str,
"%d",
id);
922 string compound_name = magic +
"." + id_str +
"." + name;
923 return compound_name;
927int HdfIO::create_compound_attr(
int image_index,
const string & attr_name)
929 string cur_dataset_name = get_compound_name(image_index, attr_name);
930 cur_image_index = -1;
934 hid_t datatype = H5Tcopy(H5T_NATIVE_INT);
935 hid_t dataspace = H5Screate_simple(1, dims, NULL);
938 cur_dataset = H5Dcreate(file, cur_dataset_name.c_str(), datatype, dataspace, H5P_DEFAULT);
945int HdfIO::read_ctf(
Ctf & ctf,
int image_index)
948 int err = read_compound_dict(CTFIT, ctf_dict, image_index);
956void HdfIO::write_ctf(
const Ctf & ctf,
int image_index)
959 write_compound_dict(CTFIT, ctf_dict, image_index);
962int HdfIO::read_euler_angles(
Dict & euler_angles,
int image_index)
964 int err = read_compound_dict(EULER, euler_angles, image_index);
969void HdfIO::write_euler_angles(
const Dict & euler_angles,
int image_index)
971 write_compound_dict(EULER, euler_angles, image_index);
974int HdfIO::read_compound_dict(Nametype compound_type,
975 Dict & values,
int image_index)
982 hid_t cur_dataset_orig = cur_dataset;
983 string cur_dataset_name = get_compound_name(image_index, get_item_name(compound_type));
986 cur_dataset = H5Dopen(file, cur_dataset_name.c_str());
989 if (cur_dataset < 0) {
993 err = H5Aiterate(cur_dataset, 0, attr_info, &values);
999 H5Dclose(cur_dataset);
1000 cur_dataset = cur_dataset_orig;
1002 cur_image_index = -1;
1008void HdfIO::write_compound_dict(Nametype compound_type,
1009 const Dict & values,
int image_index)
1015 hid_t cur_dataset_orig = cur_dataset;
1017 string attr_name = get_item_name(compound_type);
1018 string cur_dataset_name = get_compound_name(image_index, attr_name);
1021 cur_dataset = H5Dopen(file, cur_dataset_name.c_str());
1024 if (cur_dataset < 0) {
1025 create_compound_attr(image_index, attr_name);
1030 H5Aiterate(cur_dataset, 0, attr_info, &attr_dict);
1031 vector <string> attr_keys = attr_dict.
keys();
1032 for (
size_t i = 0; i < attr_keys.size(); i++) {
1033 H5Adelete(cur_dataset, attr_keys[i].c_str());
1039 vector < string > keys = values.
keys();
1040 for (
size_t i = 0; i < keys.size(); i++) {
1041 float v = values[keys[i]];
1042 write_float_attr(keys[i].c_str(), v);
1045 H5Dclose(cur_dataset);
1046 cur_dataset = cur_dataset_orig;
1048 cur_image_index = -1;
1053bool HdfIO::is_complex_mode()
1059bool HdfIO::is_image_big_endian()
1065string HdfIO::get_item_name(Nametype type)
1073 return "num_dataset";
1074 case COMPOUND_DATA_MAGIC:
1077 return "euler_angles";
1084void HdfIO::hdf_err_off()
1086 H5Eget_auto(&old_func, &old_client_data);
1090void HdfIO::hdf_err_on()
1092 H5Eset_auto(old_func, old_client_data);
1095void HdfIO::close_cur_dataset()
1098 if (cur_dataset >= 0) {
1099 H5Dclose(cur_dataset);
1101 cur_image_index = -1;
1106void HdfIO::create_enum_types()
1108 static int enum_types_created = 0;
1110 if (!enum_types_created) {
1135 enum_types_created = 1;
1139vector < int >HdfIO::get_image_indices()
1141 return image_indices;
1144int HdfIO::get_hdf_dims(
int image_index,
int *p_nx,
int *p_ny,
int *p_nz)
1146 *p_nx = read_int_attr(image_index,
"nx");
1147 *p_ny = read_int_attr(image_index,
"ny");
1148 *p_nz = read_int_attr(image_index,
"nz");
1150 if (*p_nx == 0 || *p_ny == 0 || *p_nz == 0) {
1152 int *dims = read_dims(image_index, &ndim);
1154 if (ndim != 2 && ndim != 3) {
1155 LOGERR(
"only handle 2D/3D HDF5. Your file is %dD.", ndim);
1182herr_t HdfIO::file_info(hid_t,
const char *name,
void *opdata)
1185 vector < int >*image_indices =
static_cast < vector < int >*
>(opdata);
1186 string magic = HdfIO::get_item_name(HdfIO::COMPOUND_DATA_MAGIC);
1187 const char *magic_str = magic.c_str();
1189 if (strncmp(name, magic_str, strlen(magic_str)) != 0) {
1190 int id = atoi(name);
1191 image_indices->push_back(
id);
1197void HdfIO::create_cur_dataset(
int image_index,
int nx,
int ny,
int nz)
1212 char tmp_dataset_name[32];
1213 sprintf(tmp_dataset_name,
"%d", image_index);
1214 cur_image_index = image_index;
1217 cur_dataset = H5Dopen(file, tmp_dataset_name);
1221 if (cur_dataset >= 0) {
1223 int *dims1 = read_dims(image_index, &ndim1);
1226 for (
int i = 0; i < ndim; i++) {
1227 Assert(dims[i] == dims1[i]);
1236 hsize_t *sdims =
new hsize_t[ndim];
1237 for (
int i = 0; i < ndim; i++) {
1241 hid_t datatype = H5Tcopy(H5T_NATIVE_FLOAT);
1242 hid_t dataspace = H5Screate_simple(ndim, sdims, NULL);
1244 cur_dataset = H5Dcreate(file, tmp_dataset_name, datatype, dataspace, H5P_DEFAULT);
1247 H5Sclose(dataspace);
1255 if (cur_dataset < 0) {
1259 increase_num_dataset();
1260 image_indices.push_back(image_index);
1265int HdfIO::create_region_space(hid_t * p_dataspace_id, hid_t * p_memspace_id,
1266 const Region * area,
int nx,
int ny,
int nz,
1273 if (!p_dataspace_id || !p_memspace_id || !area) {
1277#if H5_VERS_MINOR > 6 || (H5_VERS_MINOR == 6 && H5_VERS_RELEASE >= 4)
1285 int x0 = 0, y0 = 0, z0 = 0;
1286 int xlen = 0, ylen = 0, zlen = 0;
1288 EMUtil::get_region_origins(area, &x0, &y0, &z0, nz, image_index);
1289 EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen, nz, &zlen);
1291 offset[0] =
static_cast < hssize_t
> (x0);
1292 offset[1] =
static_cast < hssize_t
> (y0);
1293 offset[2] =
static_cast < hssize_t
> (z0);
1295 count[0] =
static_cast < hsize_t
> (xlen);
1296 count[1] =
static_cast < hsize_t
> (ylen);
1297 count[2] =
static_cast < hsize_t
> (zlen);
1299 *p_dataspace_id = H5Dget_space(cur_dataset);
1301 int err = H5Sselect_hyperslab(*p_dataspace_id, H5S_SELECT_SET,
1302 offset, NULL, count, NULL);
1304 *p_memspace_id = H5Screate_simple(3, count, NULL);
1306#if H5_VERS_MINOR > 6 || (H5_VERS_MINOR == 6 && H5_VERS_RELEASE >= 4)
1307 hsize_t offset_out[3];
1309 hssize_t offset_out[3];
1316 err = H5Sselect_hyperslab(*p_memspace_id, H5S_SELECT_SET,
1317 offset_out, NULL, count, NULL);
1326int HdfIO::get_num_dataset()
1329 int n = read_global_int_attr(get_item_name(NUMDATASET));
Ctf is the base class for all CTF model.
virtual void from_dict(const Dict &dict)=0
virtual int from_string(const string &ctf)=0
virtual Dict to_dict() const =0
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.
vector< string > keys() const
Get a vector containing all of the (string) keys in this dictionary.
EMAN1Ctf is the CTF model used in EMAN1.
EMObject is a wrapper class for types including int, float, double, etc as defined in ObjectType.
string to_str() const
Calls to_str( this->type)
ObjectType get_type() const
Get the ObjectType This is an enumerated type first declared in the class EMObjectTypes.
EMDataType
Image pixel data type used in EMAN.
FloatSize is used to describe a 1D, 2D or 3D rectangular size in floating numbers.
ImageIO classes are designed for reading/writing various electron micrography image formats,...
IntSize is used to describe a 1D, 2D or 3D rectangular size in integers.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
#define Assert(s)
Define Assert() function that is effective only when -DDEBUG is used.
#define ImageReadException(filename, desc)
#define NotExistingObjectException(objname, desc)
#define FileAccessException(filename)
#define ImageWriteException(imagename, desc)
#define NullPointerException(desc)