2 static char *RCSid() { return RCSid("$Id: breaders.c,v 1.3.2.1 2009/01/28 10:39:37 mikulik Exp $"); }
5 /* GNUPLOT - breaders.c */
8 * Copyright 2004 Petr Mikulik
10 * As part of the program Gnuplot, which is
12 * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
14 * Permission to use, copy, and distribute this software and its
15 * documentation for any purpose with or without fee is hereby granted,
16 * provided that the above copyright notice appear in all copies and
17 * that both that copyright notice and this permission notice appear
18 * in supporting documentation.
20 * Permission to modify the software is granted, but not the right to
21 * distribute the complete modified source code. Modifications are to
22 * be distributed as patches to the released version. Permission to
23 * distribute binaries produced by compiling modified sources is granted,
25 * 1. distribute the corresponding source modifications from the
26 * released version in the form of a patch file along with the binaries,
27 * 2. add special version identification to distinguish your version
28 * in addition to the base release version number,
29 * 3. provide your name and address as the primary contact for the
30 * support of your modified version, and
31 * 4. retain our contact information in regard to use of the base
33 * Permission to distribute the released version of the source code along
34 * with corresponding source modifications in the form of a patch file is
35 * granted with same provisions 2 through 4 for binary distributions.
37 * This software is provided "as is" without express or implied warranty
38 * to the extent permitted by applicable law.
41 /* AUTHOR : Petr Mikulik */
44 * Readers to set up binary data file information for particular formats.
49 #ifdef BINARY_DATA_FILE
56 * Reader for the ESRF Header File format files (EDF / EHF).
59 /* Inside datafile.c, but kept hidden. */
60 extern char *df_filename; /* name of data file */
61 extern int df_no_bin_cols; /* cols to read */
62 extern df_endianess_type df_bin_file_endianess;
64 /* Reader for the ESRF Header File format files (EDF / EHF).
71 short signum; /* 0..unsigned, 1..signed, 2..float or double */
72 short sajzof; /* sizeof on 32bit architecture */
75 /* Exactly like lookup_table_nth from tables.c, but for gen_table4 instead
79 lookup_table4_nth(const struct gen_table4 *tbl, const char *search_str)
83 if (tbl[k].key && !strncmp(search_str, tbl[k].key, strlen(tbl[k].key)))
85 return -1; /* not found */
88 static const struct gen_table4 edf_datatype_table[] =
90 { "UnsignedByte", DF_UCHAR, 0, 1 },
91 { "SignedByte", DF_CHAR, 1, 1 },
92 { "UnsignedShort", DF_USHORT, 0, 2 },
93 { "SignedShort", DF_SHORT, 1, 2 },
94 { "UnsignedInteger",DF_UINT, 0, 4 },
95 { "SignedInteger", DF_INT, 1, 4 },
96 { "UnsignedLong", DF_ULONG, 0, 8 },
97 { "SignedLong", DF_LONG, 1, 8 },
98 { "FloatValue", DF_FLOAT, 2, 4 },
99 { "DoubleValue", DF_DOUBLE, 2, 8 },
100 { "Float", DF_FLOAT, 2, 4 }, /* Float and FloatValue are synonyms */
101 { "Double", DF_DOUBLE, 2, 8 }, /* Double and DoubleValue are synonyms */
105 static const struct gen_table edf_byteorder_table[] =
107 { "LowByteFirst", DF_LITTLE_ENDIAN }, /* little endian */
108 { "HighByteFirst", DF_BIG_ENDIAN }, /* big endian */
112 /* Orientation of axes of the raster, as the binary matrix is saved in
116 EDF_RASTER_AXES_XrightYdown, /* matricial format: rows, columns */
117 EDF_RASTER_AXES_XrightYup /* cartesian coordinate system */
118 /* other 6 combinations not available (not needed until now) */
121 static const struct gen_table edf_rasteraxes_table[] =
123 { "XrightYdown", EDF_RASTER_AXES_XrightYdown },
124 { "XrightYup", EDF_RASTER_AXES_XrightYup },
129 /* Find value_ptr as pointer to the parameter of the given key in the header.
130 * Returns NULL on success.
133 edf_findInHeader ( const char* header, const char* key )
135 char *value_ptr = strstr( header, key );
136 if (!value_ptr) return NULL;
137 /* an edf line is "key = value ;" */
138 value_ptr = 1 + strchr( value_ptr + strlen(key), '=' );
139 while (isspace(*value_ptr)) value_ptr++;
144 edf_filetype_function(void)
151 /* open (header) file */
152 fp = loadpath_fopen(df_filename, "rb");
154 os_error(NO_CARET, "Can't open data file \"%s\"", df_filename);
155 /* read header: it is a multiple of 512 B ending by "}\n" */
156 while (header_size == 0 || strncmp(&header[header_size-2],"}\n",2)) {
157 int header_size_prev = header_size;
160 header = gp_alloc(header_size+1, "EDF header");
162 header = gp_realloc(header, header_size+1, "EDF header");
163 header[header_size_prev] = 0; /* protection against empty file */
164 k = fread(header+header_size_prev, 512, 1, fp);
165 if (k == 0) { /* protection against indefinite loop */
167 os_error(NO_CARET, "Damaged EDF header of %s: not multiple of 512 B.\n", df_filename);
169 header[header_size] = 0; /* end of string: protection against strstr later on */
172 /* make sure there is a binary record structure for each image */
173 if (df_num_bin_records < 1)
174 df_add_binary_records(1-df_num_bin_records, DF_CURRENT_RECORDS); /* otherwise put here: number of images (records) from this file */
175 if ((p = edf_findInHeader(header, "EDF_BinaryFileName"))) {
176 int plen = strcspn(p, " ;\n");
177 df_filename = gp_realloc(df_filename, plen+1, "datafile name");
178 strncpy(df_filename, p, plen);
179 df_filename[plen] = '\0';
180 if ((p = edf_findInHeader(header, "EDF_BinaryFilePosition")))
181 df_bin_record[0].scan_skip[0] = atoi(p);
183 df_bin_record[0].scan_skip[0] = 0;
185 df_bin_record[0].scan_skip[0] = header_size; /* skip header */
186 /* set default values */
187 df_bin_record[0].scan_dir[0] = 1;
188 df_bin_record[0].scan_dir[1] = -1;
189 df_bin_record[0].scan_generate_coord = TRUE;
190 df_bin_record[0].cart_scan[0] = DF_SCAN_POINT;
191 df_bin_record[0].cart_scan[1] = DF_SCAN_LINE;
192 df_extend_binary_columns(1);
193 df_set_skip_before(1,0);
194 df_set_skip_after(1,0);
196 use_spec[0].column = 1;
197 /* now parse the header */
198 if ((p = edf_findInHeader(header, "Dim_1")))
199 df_bin_record[0].scan_dim[0] = atoi(p);
200 if ((p = edf_findInHeader(header, "Dim_2")))
201 df_bin_record[0].scan_dim[1] = atoi(p);
202 if ((p = edf_findInHeader(header, "DataType"))) {
203 k = lookup_table4_nth(edf_datatype_table, p);
204 if (k >= 0) { /* known EDF DataType */
205 int s = edf_datatype_table[k].sajzof;
206 switch (edf_datatype_table[k].signum) {
207 case 0: df_set_read_type(1,SIGNED_TEST(s)); break;
208 case 1: df_set_read_type(1,UNSIGNED_TEST(s)); break;
209 case 2: df_set_read_type(1,FLOAT_TEST(s)); break;
213 if ((p = edf_findInHeader(header, "ByteOrder"))) {
214 k = lookup_table_nth(edf_byteorder_table, p);
216 df_bin_file_endianess = edf_byteorder_table[k].value;
218 /* Origin vs center: EDF specs allows only Center, but it does not hurt if
219 Origin is supported as well; however, Center rules if both specified.
221 if ((p = edf_findInHeader(header, "Origin_1"))) {
222 df_bin_record[0].scan_cen_or_ori[0] = atof(p);
223 df_bin_record[0].scan_trans = DF_TRANSLATE_VIA_ORIGIN;
225 if ((p = edf_findInHeader(header, "Origin_2"))) {
226 df_bin_record[0].scan_cen_or_ori[1] = atof(p);
227 df_bin_record[0].scan_trans = DF_TRANSLATE_VIA_ORIGIN;
229 if ((p = edf_findInHeader(header, "Center_1"))) {
230 df_bin_record[0].scan_cen_or_ori[0] = atof(p);
231 df_bin_record[0].scan_trans = DF_TRANSLATE_VIA_CENTER;
233 if ((p = edf_findInHeader(header, "Center_2"))) {
234 df_bin_record[0].scan_cen_or_ori[1] = atof(p);
235 df_bin_record[0].scan_trans = DF_TRANSLATE_VIA_CENTER;
237 /* now pixel sizes and raster orientation */
238 if ((p = edf_findInHeader(header, "PSize_1")))
239 df_bin_record[0].scan_delta[0] = atof(p);
240 if ((p = edf_findInHeader(header, "PSize_2")))
241 df_bin_record[0].scan_delta[1] = atof(p);
242 if ((p = edf_findInHeader(header, "RasterAxes"))) {
243 k = lookup_table_nth(edf_rasteraxes_table, p);
245 case EDF_RASTER_AXES_XrightYup:
246 df_bin_record[0].scan_dir[0] = 1;
247 df_bin_record[0].scan_dir[1] = 1;
248 df_bin_record[0].cart_scan[0] = DF_SCAN_POINT;
249 df_bin_record[0].cart_scan[1] = DF_SCAN_LINE;
251 default: /* also EDF_RASTER_AXES_XrightYdown */
252 df_bin_record[0].scan_dir[0] = 1;
253 df_bin_record[0].scan_dir[1] = -1;
254 df_bin_record[0].cart_scan[0] = DF_SCAN_POINT;
255 df_bin_record[0].cart_scan[1] = DF_SCAN_LINE;
261 /* Print results. This routine will be completely removed later. */
262 fprintf(stderr,"EDF: dim=%ix%i skip=%i datatype=%i datasize=%i dx=%g dy=%g\n",
263 df_bin_record[0].scan_dim[0], df_bin_record[0].scan_dim[1],
264 df_bin_record[0].scan_skip[0],
265 df_get_read_type(1), df_get_read_size(1),
266 df_bin_record[0].scan_delta[0], df_bin_record[0].scan_delta[1]);
271 #endif /* BINARY_DATA_FILE */