OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
epr_product.c
Go to the documentation of this file.
1 /*
2  * $Id: epr_product.c,v 1.1.1.1 2004-10-28 19:22:23 norman Exp $
3  *
4  * Copyright (C) 2002 by Brockmann Consult (info@brockmann-consult.de)
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation. This program is distributed in the hope it will
9  * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
10  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16  */
17 
18 #include <assert.h>
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <time.h>
24 
25 #include "epr_api.h"
26 #include "epr_core.h"
27 #include "epr_string.h"
28 #include "epr_ptrarray.h"
29 #include "epr_swap.h"
30 #include "epr_field.h"
31 #include "epr_record.h"
32 #include "epr_dataset.h"
33 #include "epr_param.h"
34 #include "epr_dsd.h"
35 #include "epr_msph.h"
36 #include "epr_band.h"
37 #include "epr_bitmask.h"
38 
39 #include "epr_dddb.h"
40 
41 epr_uint epr_compute_scene_width(const EPR_SProductId* product_id);
42 epr_uint epr_compute_scene_height(const EPR_SProductId* product_id);
43 
44 /*********************************** PRODUCT ***********************************/
45 
46 /*
47  Function: epr_open_product
48  Access: public API
49  Changelog: 2002/01/05 nf initial version
50  */
54 EPR_SProductId* epr_open_product(const char* product_file_path) {
55  EPR_SProductId* product_id = NULL;
56  char message_buffer[80];
57  //int s_par;
58  epr_uint compare_ok = 0;
59 
60  epr_clear_err();
61  if (!epr_check_api_init_flag()) {
62  return NULL;
63  }
64 
65  if (product_file_path == NULL) {
67  "epr_open_product: product file path must not be NULL");
68  return NULL;
69  }
70 
71  product_id = (EPR_SProductId*) calloc(1, sizeof (EPR_SProductId));
72  if (product_id == NULL) {
74  "epr_open_product: out of memory");
75  return NULL;
76  }
78 
79  epr_assign_string(&product_id->file_path, product_file_path);
80 
81  if (product_id->file_path == NULL) {
83  "epr_open_product: out of memory");
84  return NULL;
85  }
86 
87  /* Convert to OS compatible path */
89 
90  product_id->istream = fopen(epr_trim_string(product_id->file_path), "rb");
91  if (product_id->istream == NULL) {
92  if (errno == ENOENT) {
94  "epr_open_product: file not found");
95  } else {
97  "epr_open_product: file open failed");
98  }
99  return NULL;
100  }
101 
102  epr_log(e_log_debug, "product opened:");
104 
105  /* Set file pointer to start of product identifier */
106  if (fseek(product_id->istream, EPR_PRODUCT_ID_OFFSET, SEEK_SET) != 0) {
108  "epr_open_product: file seek failed");
110  return NULL;
111  }
112 
113  if (fread(product_id->id_string,
114  1,
116  product_id->istream) != (epr_uint) EPR_PRODUCT_ID_STRLEN) {
118  "epr_open_product: file read failed");
120  return NULL;
121  }
122 
123  /* Product identifier filter*/
124  if ((strncmp(EPR_ENVISAT_PRODUCT_MERIS, product_id->id_string, 3) != 0) &&
125  (strncmp(EPR_ENVISAT_PRODUCT_ASAR, product_id->id_string, 3) != 0) &&
126  (strncmp(EPR_ENVISAT_PRODUCT_SAR, product_id->id_string, 3) != 0) &&
127  (strncmp(EPR_ENVISAT_PRODUCT_AATSR, product_id->id_string, 3) != 0)) {
129  "epr_open_product: invalid product identifier");
131  return NULL;
132  }
133 
134  if (product_id->id_string[9] != 'P') {
135  char* ch = product_id->id_string + 9;
136  if (*ch == 'C') {
137  epr_log(e_log_info, "child product detected, mapping to 'P'");
138  } else {
139  sprintf(message_buffer, "unknown product sub-type '%c', mapping to 'P'", *ch);
140  epr_log(e_log_warning, message_buffer);
141  }
142  *ch = 'P';
143  }
144 
145  /* Set file to end of file in order to determine file size */
146  if (fseek(product_id->istream, 0, SEEK_END) != 0) {
148  "epr_open_product: file seek failed");
150  return NULL;
151  }
152 
153  /* Get file size */
154  product_id->tot_size = (epr_uint) ftell(product_id->istream);
155  if (product_id->tot_size == (epr_uint) -1) {
157  "epr_open_product: failed to determine file size");
159  return NULL;
160  }
161  sprintf(message_buffer, "product size: %u", product_id->tot_size);
162  epr_log(e_log_debug, message_buffer);
163 
164  /* Set file pointer back to start */
165  if (fseek(product_id->istream, 0, SEEK_SET) != 0) {
167  "epr_open_product: file seek failed");
169  return NULL;
170  }
171 
172  product_id->record_info_cache = epr_create_ptr_array(32);
173  product_id->param_table = epr_create_param_table();
174 
175  epr_log(e_log_info, "reading MPH");
176  product_id->mph_record = epr_read_mph(product_id);
177 
178  epr_log(e_log_info, "reading SPH");
179  product_id->sph_record = epr_read_sph(product_id);
181 
182  epr_log(e_log_info, "reading all DSDs");
184  compare_ok = epr_compare_param(product_id);
185  if (compare_ok == 0) {
187  "epr_open_product: MPH_SIZE+SPH_SIZE must be equal to DSD[0].DS_OFFSET");
189  return NULL;
190  }
191 
192  if (strncmp(EPR_ENVISAT_PRODUCT_MERIS, product_id->id_string, 3) == 0) {
193  product_id->meris_iodd_version = epr_detect_meris_iodd_version(product_id);
194  sprintf(message_buffer, "product type %s (MERIS IODD%d)", product_id->id_string, product_id->meris_iodd_version);
195  epr_log(e_log_info, message_buffer);
196  }
197 
198  epr_log(e_log_info, "creating dataset identifiers");
200  if (product_id->dataset_ids == NULL) {
202  return NULL;
203  }
204 
205  epr_log(e_log_info, "creating band identifiers");
207  if (product_id->band_ids == NULL) {
209  return NULL;
210  }
211 
212  /* Get scene size */
215  sprintf(message_buffer, "product scene raster size: %u x %u", product_id->scene_width, product_id->scene_height);
216  epr_log(e_log_debug, message_buffer);
217 
218  return product_id;
219 }
220 
221 
222 
223 /*
224  Function: epr_close_product
225  Access: public API
226  Changelog: 2002/01/05 nf initial version
227  */
231 int epr_close_product(EPR_SProductId* product_id) {
232  /* Nothing to close, return */
233  if (product_id == NULL) {
234  return e_err_none;
235  }
236 
237  epr_clear_err();
238  if (!epr_check_api_init_flag()) {
239  return epr_get_last_err_code();
240  }
241 
242  assert(product_id->istream != NULL);
243  if (fclose(product_id->istream) != 0) {
245  "epr_close_product: product file close failed");
246  return epr_get_last_err_code();
247  }
248  product_id->istream = NULL;
249 
250  epr_log(e_log_info, "product closed: file path: ");
251  epr_log(e_log_info, product_id->file_path);
252 
254 
255  return e_err_none;
256 }
257 
258 
259 /*
260  Function: epr_free_product_id
261  Access: private API implementation helper
262  Changelog: 2002/01/05 nf initial version
263  */
269 void epr_free_product_id(EPR_SProductId* product_id) {
270  if (product_id == NULL)
271  return;
272 
273  product_id->istream = NULL;
274 
275  epr_free_string(product_id->file_path);
276  product_id->file_path = NULL;
277 
278  product_id->id_string[0] = '\0';
279 
280  epr_free_param_table(product_id->param_table);
281  product_id->param_table = NULL;
282 
283  if (product_id->record_info_cache != NULL) {
284  EPR_SRecordInfo* record_info = NULL;
285  epr_uint record_info_index = 0;
286 
287  for (record_info_index = 0; record_info_index < product_id->record_info_cache->length; record_info_index++) {
288  record_info = (EPR_SRecordInfo*)epr_get_ptr_array_elem_at(product_id->record_info_cache, record_info_index);
289  epr_free_record_info(record_info);
290  }
291 
292  epr_free_ptr_array(product_id->record_info_cache);
293  product_id->record_info_cache = NULL;
294  }
295 
296  if (product_id->dsd_array != NULL) {
297  EPR_SDSD* dsd = NULL;
298  epr_uint dsd_index = 0;
299 
300  for (dsd_index = 0; dsd_index < product_id->dsd_array->length; dsd_index++) {
301  dsd = (EPR_SDSD*)epr_get_ptr_array_elem_at(product_id->dsd_array, dsd_index);
302  epr_free_dsd(dsd);
303  }
304 
305  epr_free_ptr_array(product_id->dsd_array);
306  product_id->dsd_array = NULL;
307  }
308 
309  if (product_id->mph_record != NULL) {
310  epr_free_record(product_id->mph_record);
311  product_id->mph_record = NULL;
312  }
313 
314  if (product_id->sph_record != NULL) {
315  epr_free_record(product_id->sph_record);
316  product_id->sph_record = NULL;
317  }
318 
319  if (product_id->dataset_ids != NULL) {
320  EPR_SDatasetId* dataset_id = NULL;
321  epr_uint d_index = 0;
322 
323  for (d_index = 0; d_index < product_id->dataset_ids->length; d_index++) {
324  dataset_id = (EPR_SDatasetId*)epr_get_ptr_array_elem_at(product_id->dataset_ids, d_index);
325  epr_free_dataset_id(dataset_id);
326  }
327 
328  epr_free_ptr_array(product_id->dataset_ids);
329  product_id->dataset_ids = NULL;
330  }
331 
332  if (product_id->band_ids != NULL) {
333  EPR_SBandId* band_id = NULL;
334  epr_uint b_index = 0;
335 
336  for (b_index = 0; b_index < product_id->band_ids->length; b_index++) {
337  band_id = (EPR_SBandId*)epr_get_ptr_array_elem_at(product_id->band_ids, b_index);
338  epr_free_band_id(band_id);
339  }
340 
341  epr_free_ptr_array(product_id->band_ids);
342  product_id->band_ids = NULL;
343  }
344 
345  product_id->tot_size = 0;
346 
347  free(product_id);
348 }
349 
350 
357 epr_uint epr_get_scene_width(const EPR_SProductId* product_id) {
358  epr_clear_err();
359 
360  if (product_id == NULL) {
362  "epr_get_scene_width: product_id must not be NULL");
363  return (epr_uint)0;
364  }
365  return product_id->scene_width;
366 }
367 
374 epr_uint epr_get_scene_height(const EPR_SProductId* product_id) {
375  epr_clear_err();
376 
377  if (product_id == NULL) {
379  "epr_get_scene_height: product_id must not be NULL");
380  return (epr_uint)0;
381  }
382  return product_id->scene_height;
383 }
384 
385 
386 /*********************************** RECORD ***********************************/
387 
388 EPR_SRecord* epr_get_sph(const EPR_SProductId* product_id) {
389  epr_clear_err();
390 
391  if (product_id == NULL) {
393  "epr_get_sph: product-identifier must not be NULL");
394  return NULL;
395  }
396  return product_id->sph_record;
397 }
398 
399 EPR_SRecord* epr_get_mph(const EPR_SProductId* product_id) {
400  epr_clear_err();
401 
402  if (product_id == NULL) {
404  "epr_get_mph: product-identifier must not be NULL");
405  return NULL;
406  }
407  return product_id->mph_record;
408 }
409 
410 
419  EPR_SRecord* sph_record = NULL;
420  epr_uint scan_line_length;
421 
422  if (product_id == NULL) {
424  "epr_compute_scene_width: product ID must not be NULL");
425  return (epr_uint)0;
426  }
427 
428  sph_record = product_id->sph_record;
429 
430  if (strncmp(EPR_ENVISAT_PRODUCT_MERIS, product_id->id_string, 3) == 0) {
431  const EPR_SField* field = field = epr_get_field(sph_record, "LINE_LENGTH");
432  scan_line_length = epr_get_field_elem_as_uint(field, 0);
433  } else if (strncmp(EPR_ENVISAT_PRODUCT_AATSR, product_id->id_string, 3) == 0) {
434  scan_line_length = EPR_ATS_LINE_LENGTH;
435  } else if (strncmp(EPR_ENVISAT_PRODUCT_ASAR, product_id->id_string, 3) == 0) {
436  const EPR_SField* field = field = epr_get_field(sph_record, "LINE_LENGTH");
437  scan_line_length = epr_get_field_elem_as_uint(field, 0);
438  } else if (strncmp(EPR_ENVISAT_PRODUCT_SAR, product_id->id_string, 3) == 0) {
439  const EPR_SField* field = field = epr_get_field(sph_record, "LINE_LENGTH");
440  scan_line_length = epr_get_field_elem_as_uint(field, 0);
441  } else {
443  "epr_compute_scene_width: unknown product type");
444  scan_line_length = (epr_uint)0;
445  }
446 
447  return scan_line_length;
448 }
449 
458  EPR_SDSD* dsd = NULL;
459  epr_uint min_num_mds_recs = 0;
460  epr_uint dsd_index;
461 
462  if (product_id == NULL) {
464  "epr_compute_scene_height: product ID must not be NULL");
465  return (epr_uint)0;
466  }
467 
468  for (dsd_index = 0; dsd_index < product_id->dsd_array->length; dsd_index++) {
469  dsd = (EPR_SDSD*)epr_get_ptr_array_elem_at(product_id->dsd_array, dsd_index);
470  if (epr_equal_names(dsd->ds_type, "M")) {
471  if (dsd->num_dsr > min_num_mds_recs) {
472  min_num_mds_recs = dsd->num_dsr;
473  }
474  }
475  }
476 
477  if (min_num_mds_recs == 0) {
479  "epr_compute_scene_height: product height was zero");
480  }
481 
482  return min_num_mds_recs;
483 }
484 
485 
486 
#define EPR_ENVISAT_PRODUCT_AATSR
Definition: epr_core.h:40
#define EPR_PRODUCT_ID_OFFSET
Definition: epr_core.h:52
@ e_err_out_of_memory
Definition: epr_api.h:83
char * epr_trim_string(char *str)
Definition: epr_string.c:247
@ e_log_debug
Definition: epr_api.h:125
@ e_err_illegal_arg
Definition: epr_api.h:81
void epr_free_dsd(EPR_SDSD *dsd)
Definition: epr_dsd.c:175
unsigned int epr_uint
Definition: epr_api.h:188
void epr_free_ptr_array(EPR_SPtrArray *ptr_array)
Definition: epr_ptrarray.c:51
@ e_log_warning
Definition: epr_api.h:127
void epr_free_record(EPR_SRecord *record)
Definition: epr_record.c:405
#define NULL
Definition: decode_rs.h:63
int epr_set_dyn_dddb_params(EPR_SProductId *product_id)
Definition: epr_param.c:126
@ e_err_none
Definition: epr_api.h:77
@ e_err_file_close_failed
Definition: epr_api.h:94
epr_uint epr_compare_param(EPR_SProductId *product_id)
Definition: epr_msph.c:532
char * epr_assign_string(char **str_clone, const char *str)
Definition: epr_string.c:29
@ e_err_file_access_denied
Definition: epr_api.h:90
void epr_free_dataset_id(EPR_SDatasetId *dataset_id)
Definition: epr_dataset.c:76
EPR_SPtrArray * epr_create_band_ids(EPR_SProductId *product_id)
Definition: epr_band.c:43
@ e_err_invalid_data_format
Definition: epr_api.h:107
void epr_free_band_id(EPR_SBandId *band_id)
Definition: epr_band.c:284
const EPR_SField * epr_get_field(const EPR_SRecord *record, const char *field_name)
Definition: epr_field.c:247
@ e_err_invalid_product_id
Definition: epr_api.h:98
EPR_SPtrArray * epr_create_dataset_ids(EPR_SProductId *product_id)
Definition: epr_dataset.c:102
epr_boolean epr_equal_names(const char *name1, const char *name2)
Definition: epr_string.c:91
EPR_SRecord * epr_read_mph(EPR_SProductId *product_id)
Definition: epr_msph.c:47
@ e_err_null_pointer
Definition: epr_api.h:80
#define EPR_ENVISAT_PRODUCT_SAR
Definition: epr_core.h:39
int epr_detect_meris_iodd_version(EPR_SProductId *product_id)
Definition: epr_dsd.c:125
epr_uint epr_get_scene_width(const EPR_SProductId *product_id)
Definition: epr_product.c:357
void epr_free_record_info(EPR_SRecordInfo *record_info)
Definition: epr_record.c:109
#define EPR_PRODUCT_ID_STRLEN
Definition: epr_api.h:205
void epr_free_product_id(EPR_SProductId *product_id)
Definition: epr_product.c:269
@ e_err_invalid_value
Definition: epr_api.h:108
void epr_free_param_table(EPR_SPtrArray *param_table)
Definition: epr_param.c:86
What value is used by your function when the data value is bad Default is BAD_FLT l2prod product_id[0]
epr_uint epr_get_field_elem_as_uint(const EPR_SField *field, epr_uint elem_index)
Definition: epr_typconv.c:363
EPR_SPtrArray * epr_read_all_dsds(EPR_SProductId *product_id)
Definition: epr_dsd.c:469
@ e_err_file_not_found
Definition: epr_api.h:89
EPR_SPtrArray * epr_create_param_table()
Definition: epr_param.c:70
void * epr_get_ptr_array_elem_at(const EPR_SPtrArray *ptr_array, unsigned int index)
Definition: epr_ptrarray.c:122
@ e_log_info
Definition: epr_api.h:126
int errno
void epr_make_os_compatible_path(char *path)
Definition: epr_core.c:449
#define EPR_ATS_LINE_LENGTH
Definition: epr_core.h:76
void epr_log(EPR_ELogLevel log_level, const char *log_message)
Definition: epr_core.c:199
void epr_clear_err()
Definition: epr_core.c:247
void epr_set_err(EPR_EErrCode err_code, const char *err_message)
Definition: epr_core.c:221
EPR_SRecord * epr_get_sph(const EPR_SProductId *product_id)
Definition: epr_product.c:388
#define EPR_MAGIC_PRODUCT_ID
Definition: epr_api.h:194
epr_uint epr_compute_scene_height(const EPR_SProductId *product_id)
Definition: epr_product.c:457
epr_uint epr_get_scene_height(const EPR_SProductId *product_id)
Definition: epr_product.c:374
#define EPR_ENVISAT_PRODUCT_MERIS
Definition: epr_core.h:37
#define EPR_ENVISAT_PRODUCT_ASAR
Definition: epr_core.h:38
EPR_EErrCode epr_get_last_err_code()
Definition: epr_core.c:265
epr_uint epr_compute_scene_width(const EPR_SProductId *product_id)
Definition: epr_product.c:418
EPR_SProductId * epr_open_product(const char *product_file_path)
Definition: epr_product.c:54
epr_boolean epr_check_api_init_flag()
Definition: epr_core.c:475
EPR_SRecord * epr_get_mph(const EPR_SProductId *product_id)
Definition: epr_product.c:399
void epr_free_string(char *str)
Definition: epr_string.c:100
int epr_close_product(EPR_SProductId *product_id)
Definition: epr_product.c:231
EPR_SRecord * epr_read_sph(EPR_SProductId *product_id)
Definition: epr_msph.c:92
EPR_SPtrArray * epr_create_ptr_array(unsigned int capacity)
Definition: epr_ptrarray.c:29