OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
epr_bitmask.c
Go to the documentation of this file.
1 /*
2  * $Id: epr_bitmask.c,v 1.2 2004-10-28 20:10:57 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 <ctype.h>
19 
20 #include "epr_api.h"
21 #include "epr_core.h"
22 #include "epr_string.h"
23 #include "epr_ptrarray.h"
24 #include "epr_swap.h"
25 #include "epr_field.h"
26 #include "epr_record.h"
27 #include "epr_param.h"
28 #include "epr_dsd.h"
29 #include "epr_msph.h"
30 #include "epr_band.h"
31 #include "epr_bitmask.h"
32 
33 #include "epr_dddb.h"
34 
35 void epr_resolve_bm_ref(EPR_SBmEvalContext* context, EPR_SBmTerm* term);
36 
37 
38 
39 EPR_SBmEvalContext* epr_create_bm_eval_context(EPR_SProductId* product_id,
40  int offset_x,
41  int offset_y,
42  EPR_SRaster* bitmask_raster)
43 {
44  EPR_SBmEvalContext* context;
45 
46  context = (EPR_SBmEvalContext*) calloc(1, sizeof (EPR_SBmEvalContext));
47  if (context == NULL) {
49  "epr_create_bm_eval_context: out of memory");
50  return NULL;
51  }
52  context->product_id = product_id;
53  context->offset_x = offset_x;
54  context->offset_y = offset_y;
55  context->bitmask_raster = bitmask_raster;
56  context->flag_band_ids = epr_create_ptr_array(4);
57  context->flag_rasters = epr_create_ptr_array(4);
58  return context;
59 }
60 
61 
62 void epr_free_bm_eval_context(EPR_SBmEvalContext* context)
63 {
64  EPR_SRaster* flag_raster;
65  epr_uint flag_index;
66 
67  if (context == NULL) {
68  return;
69  }
70 
71  if (context->flag_band_ids != NULL) {
72  for (flag_index = 0; flag_index < context->flag_band_ids->length; flag_index++) {
73  /*
74  * Note that the release of band ID's is handled by the epr_close_product() function,
75  * The rasters need to be released, because they are internally used by this
76  * context.
77  */
78  flag_raster = (EPR_SRaster*)context->flag_rasters->elems[flag_index];
79  epr_free_raster(flag_raster);
80  }
81  epr_free_ptr_array(context->flag_band_ids);
82  epr_free_ptr_array(context->flag_rasters);
83  }
84  free(context);
85 }
86 
99 int epr_read_bitmask_raster(EPR_SProductId* product_id,
100  const char* bm_expr,
101  int offset_x,
102  int offset_y,
103  EPR_SRaster* bm_raster)
104 {
105  EPR_SBmEvalContext* context;
106  EPR_SBmTerm* term;
107  epr_uint x, y;
108  epr_uint pos;
109  epr_uchar* bm_buffer = NULL;
110  EPR_EErrCode errcode;
111 
112  epr_clear_err();
113 
114  if (bm_raster->data_type != e_tid_uchar && bm_raster->data_type != e_tid_char) {
116  "epr_read_bitmask_raster: illegal raster datatype; must be 'char' or 'uchar'");
118  }
119 
120  bm_buffer = (epr_uchar*) bm_raster->buffer;
121  if (bm_buffer == NULL) {
123  "epr_read_bitmask_raster: false memory allocation for a raster buffer");
124  return e_err_out_of_memory;
125  }
126 
127  context = epr_create_bm_eval_context(product_id, offset_x, offset_y, bm_raster);
128  if (context == NULL) {
130  "epr_read_bitmask_raster: the context cannot be created");
131  return e_err_illegal_arg;
132  }
133 
134  term = epr_parse_bm_expr_str(bm_expr);
135 
136  if (term == NULL) {
138  "epr_read_bitmask_raster: the term was not build");
139  return e_err_illegal_arg;
140  }
141 
142  pos = 0;
143 
144  epr_clear_err();
145 
146  errcode = epr_get_last_err_code();
147  for (y = 0; y < bm_raster->raster_height; y++) {
148  for (x = 0; x < bm_raster->raster_width; x++) {
149  bm_buffer[pos] = (epr_uchar) epr_eval_bm_term(context, term, x, y);
150  pos++;
151  errcode = epr_get_last_err_code();
152  if (errcode != 0) {
153  break;
154  }
155  }
156  if (errcode != 0) {
157  break;
158  }
159  }
160 
162  epr_free_bm_eval_context(context);
163 
164  return errcode;
165 }
166 
174 epr_boolean epr_eval_bm_term(EPR_SBmEvalContext* context, EPR_SBmTerm* term, int x, int y) {
175 
176  epr_uint temp;
177  epr_uint eval;
178  if (term == NULL) {
179  return EPR_FALSE;
180  }
181 
182  switch (term->op_code) {
183  case BMT_REF:
184  {
185  EPR_SRaster* flag_raster = term->op.ref.flag_raster;
186  epr_uint flag_mask = term->op.ref.flag_mask;
187 
188  if (flag_raster == NULL) {
189  epr_resolve_bm_ref(context, term);
190  flag_raster = term->op.ref.flag_raster;
191  flag_mask = term->op.ref.flag_mask;
192  if (flag_raster == NULL) {
193  return EPR_FALSE;
194  }
195  }
196 
197  assert(flag_raster != NULL);
198  assert(flag_mask != FLAG_MASK_NOT_COMPUTED);
199  temp = epr_get_pixel_as_uint(flag_raster, x, y);
200  eval = temp & flag_mask;
201  return (eval) == flag_mask;
202  }
203  case BMT_AND:
204  {
205  if (!epr_eval_bm_term(context, term->op.binary.arg1, x, y)) {
206  return EPR_FALSE;
207  }
208  return epr_eval_bm_term(context, term->op.binary.arg2, x, y);
209  }
210  case BMT_OR:
211  {
212  if (epr_eval_bm_term(context, term->op.binary.arg1, x, y)) {
213  return EPR_TRUE;
214  }
215  return epr_eval_bm_term(context, term->op.binary.arg2, x, y);
216  }
217  case BMT_NOT:
218  {
219  return !epr_eval_bm_term(context, term->op.unary.arg, x, y);
220  }
221  default:
222  assert(0);
223  return EPR_FALSE;
224  }
225 }
226 
227 
228 void epr_resolve_bm_ref(EPR_SBmEvalContext* context, EPR_SBmTerm* term) {
229  const char* band_name = term->op.ref.band_name;
230  const char* flag_name = term->op.ref.flag_name;
231  EPR_SBandId* flag_band_id = NULL;
232  epr_uint flag_band_index = (epr_uint) -1;
233  epr_uint band_index = 0;
234  epr_uint num_bands = context->flag_band_ids->length;
235  EPR_SRaster* flag_raster = NULL;
236  epr_uint flag_mask = 0;
237  epr_uint flag_computed = 0;
238 
239  /* Find the corresponding flag_band_id for band_name */
240  for (band_index = 0; band_index < num_bands; band_index++) {
241  flag_band_id = (EPR_SBandId*) context->flag_band_ids->elems[band_index];
242  if (epr_equal_names(band_name, flag_band_id->band_name)) {
243  flag_band_index = band_index;
244  break;
245  }
246  }
247  /* flag_band_id found? */
248  if (flag_band_index != (epr_uint) -1) {
249  /* Yes, found: get flag_band_id and the corresponding raster */
250  flag_band_id = (EPR_SBandId*)(context->flag_band_ids->elems[flag_band_index]);
251  flag_raster = (EPR_SRaster*)(context->flag_rasters->elems[flag_band_index]);
252  } else {
253  /* Not found: get flag_band_id from product and load the corresponding raster */
254  flag_band_id = epr_get_band_id(context->product_id, band_name);
255  if (flag_band_id != NULL) {
256  flag_raster = epr_create_compatible_raster(flag_band_id,
257  context->bitmask_raster->source_width,
258  context->bitmask_raster->source_height,
259  context->bitmask_raster->source_step_x,
260  context->bitmask_raster->source_step_y);
261  epr_read_band_raster(flag_band_id,
262  context->offset_x,
263  context->offset_y,
264  flag_raster);
265  /* register flag_band_id and flag_raster for later use */
266  epr_add_ptr_array_elem(context->flag_band_ids, flag_band_id);
267  epr_add_ptr_array_elem(context->flag_rasters, flag_raster);
268  } else {
269  epr_set_err(e_err_flag_not_found, "flags band not found");
270  return;
271  }
272  }
273 
274  /* Now, compute flag_mask */
275 
276  /* Does the band have a flag coding? */
277  if (flag_band_id->flag_coding != NULL) {
278  /* Yes, now find flag definition for flag_name */
279  EPR_SFlagDef* flag_def = NULL;
280  epr_uint flag_def_index;
281  for (flag_def_index = 0; flag_def_index < flag_band_id->flag_coding->length; flag_def_index++) {
282  flag_def = (EPR_SFlagDef*) flag_band_id->flag_coding->elems[flag_def_index];
283  if (epr_equal_names(flag_def->name, flag_name)) {
284  flag_computed = 1;
285  flag_mask |= flag_def->bit_mask;
286  /* TODO!!! */
287  break;
288  }
289  }
290  }
291  if (flag_computed == 0) {
292  flag_mask = FLAG_MASK_NOT_COMPUTED;
293  epr_set_err(e_err_flag_not_found, "flag not found");
294  }
295  term->op.ref.flag_mask = flag_mask;
296  term->op.ref.flag_raster = flag_raster;
297 }
298 
307 EPR_SBmTerm* epr_parse_bm_expr_str(const char* bm_expr) {
308 
309  EPR_SBmTerm* term;
310  EPR_SParseInfo parse_info;
311 
312  parse_info.bm_expr = bm_expr;
313  parse_info.bm_expr_pos = 0;
314  parse_info.pushed_back = EPR_FALSE;
315  parse_info.token = NULL;
316  parse_info.err_message = NULL;
317 
318  term = epr_parse_bm_expr(&parse_info, EPR_FALSE);
319 
320  epr_free_string(parse_info.token);
321  parse_info.token = NULL;
322 
323  if (epr_is_bm_expr_error(&parse_info)) {
324  char tmp[256] = {"bitmap-expression error: "};
325  strcat(tmp, parse_info.err_message);
327  }
328 
329  return term;
330 }
331 
332 
333 EPR_SPtrArray* epr_create_flag_coding(EPR_SProductId* product_id, const char* flag_coding_name)
334 {
335  int num_descr;
336  int i, j;
337  const struct FlagDescriptorTable* fc_tables;
338  int fct_index;
339  EPR_SPtrArray* flag_coding = NULL;
340 
341  if (product_id == NULL) {
343  "epr_create_flag_coding: product_id must not be NULL");
344  return NULL;
345  }
346 
347  /* @DDDB */
348 
349  fc_tables = dddb_flag_coding_tables;
350  fct_index = -1;
351  for (i = 0; i < EPR_NUM_FLAG_CODING_TABLES; i++) {
352  const char* id = fc_tables[i].name;
353  if (epr_equal_names(id, flag_coding_name)) {
354  fct_index = i;
355  break;
356  }
357  }
358  if (fct_index == -1) {
360  "epr_create_flag_coding: unknown flag coding");
361  return NULL;
362  }
363 
364  flag_coding = epr_create_ptr_array(16);
365  num_descr = fc_tables[fct_index].num_descriptors;
366  for (i = 0; i < num_descr; i++) {
367  EPR_SFlagDef* flag_def = (EPR_SFlagDef*) calloc(1, sizeof (EPR_SFlagDef));
368  if (flag_def == NULL) {
370  "epr_create_flag_coding: out of memory");
371  return NULL;
372  }
373  /* 1: flag_name */
374  epr_assign_string(&flag_def->name, fc_tables[fct_index].descriptors[i].id);
375  if (flag_def->name == NULL) {
376  epr_set_err(e_err_out_of_memory, "epr_get_flag_coding: out of memory");
377  epr_free_flag_def(flag_def);
378  return NULL;
379  }
380  /* 2: dataset_name */
381  /* flag_def->bit_index = (epr_uint)fc_tables[fct_index].descriptors[i].bit_index; */
382  flag_def->bit_mask = 0;
383  for (j = 0; j < fc_tables[fct_index].descriptors[i].num_indices; j++) {
384  flag_def->bit_mask |= (1 << fc_tables[fct_index].descriptors[i].bit_indices[j]);
385  }
386  /* 3: sample_offset */
387  epr_assign_string(&flag_def->description, fc_tables[fct_index].descriptors[i].description);
388 
389  epr_add_ptr_array_elem(flag_coding, flag_def);
390  }
391  return flag_coding;
392 }
393 
394 
395 void epr_free_flag_coding(EPR_SPtrArray* flag_coding)
396 {
397  EPR_SFlagDef* flag_def = NULL;
398  epr_uint flag_index;
399 
400  if (flag_coding == NULL) {
401  return;
402  }
403 
404  for (flag_index = 0; flag_index < flag_coding->length; flag_index++)
405  {
406  flag_def = (EPR_SFlagDef*) flag_coding->elems[flag_index];
407  epr_free_flag_def(flag_def);
408  flag_def = NULL;
409  }
410  epr_free_ptr_array(flag_coding);
411 }
412 
413 
414 EPR_SFlagDef* epr_create_flag_def()
415 {
416  EPR_SFlagDef* flag_def = NULL;
417 
418  flag_def = (EPR_SFlagDef*) calloc(1, sizeof (EPR_SFlagDef));
419  if (flag_def == NULL) {
421  "epr_create_flag_def: out of memory");
422  return NULL;
423  }
424  flag_def->magic = EPR_MAGIC_FLAG_DEF;
425 
426  return flag_def;
427 }
428 
429 
430 void epr_free_flag_def(EPR_SFlagDef* flag_def)
431 {
432  if (flag_def == NULL)
433  return;
434 
435  epr_free_string(flag_def->name);
436  flag_def->name = NULL;
437  flag_def->bit_mask = 0;
438  epr_free_string(flag_def->description);
439  flag_def->description = NULL;
440 
441  free(flag_def);
442 }
443 
444 
445 EPR_SBmTerm* epr_parse_bm_expr(EPR_SParseInfo* parse_info, epr_boolean term_required) {
446  return epr_parse_bm_OR_expr(parse_info, term_required);
447 }
448 
449 
450 
451 EPR_SBmTerm* epr_parse_bm_OR_expr(EPR_SParseInfo* parse_info, epr_boolean term_required) {
452  EPR_SBmTerm* term1 = epr_parse_bm_AND_expr(parse_info, term_required);
453  if (term1 == NULL) {
454  return NULL;
455  }
456 
457  while (!epr_is_bm_expr_error(parse_info)) {
458  epr_next_bm_expr_token(parse_info);
459  if (epr_is_bm_OR_keyword(parse_info) || epr_is_bm_OR_operator(parse_info)) {
460  EPR_SBmTerm* term2 = epr_parse_bm_OR_expr(parse_info, EPR_TRUE);
461  term1 = epr_create_bm_OR_term(term1, term2);
462  } else {
463  epr_push_back_bm_expr_token(parse_info);
464  break;
465  }
466  }
467 
468  return term1;
469 }
470 
471 EPR_SBmTerm* epr_parse_bm_AND_expr(EPR_SParseInfo* parse_info, epr_boolean term_required) {
472  EPR_SBmTerm* term1 = epr_parse_bm_unary_expr(parse_info, term_required);
473  if (term1 == NULL) {
474  return NULL;
475  }
476 
477  while (!epr_is_bm_expr_error(parse_info)) {
478  epr_next_bm_expr_token(parse_info);
479  if (epr_is_bm_AND_keyword(parse_info) || epr_is_bm_AND_operator(parse_info)) {
480  EPR_SBmTerm* term2 = epr_parse_bm_AND_expr(parse_info, EPR_TRUE);
481  term1 = epr_create_bm_AND_term(term1, term2);
482  } else {
483  epr_push_back_bm_expr_token(parse_info);
484  break;
485  }
486  }
487 
488  return term1;
489 }
490 
491 
492 EPR_SBmTerm* epr_parse_bm_unary_expr(EPR_SParseInfo* parse_info, epr_boolean term_required) {
493 
494  EPR_SBmTerm* term = NULL;
495 
496  epr_next_bm_expr_token(parse_info);
497  if (epr_is_bm_NOT_keyword(parse_info) || epr_is_bm_NOT_operator(parse_info)) {
498  term = epr_parse_bm_unary_expr(parse_info, EPR_TRUE);
500  } else {
501  epr_push_back_bm_expr_token(parse_info);
502  term = epr_parse_bm_primary_expr(parse_info, term_required);
503  }
504 
505  return term;
506 }
507 
508 EPR_SBmTerm* epr_parse_bm_primary_expr(EPR_SParseInfo* parse_info, epr_boolean term_required) {
509 
510  EPR_SBmTerm* term = NULL;
511 
512  epr_next_bm_expr_token(parse_info);
513  if (epr_get_token_char(parse_info) == '(') {
514  term = epr_parse_bm_expr(parse_info, EPR_TRUE);
515  epr_next_bm_expr_token(parse_info);
516  if (epr_get_token_char(parse_info) != ')') {
517  epr_set_bm_expr_error(parse_info, "')' expected");
518  }
519  } else if (epr_is_bm_name_token(parse_info)) {
520  char* ds_name = epr_consume_token(parse_info);
521  epr_next_bm_expr_token(parse_info);
522  if (epr_get_token_char(parse_info) == '.') {
523  epr_next_bm_expr_token(parse_info);
524  if (epr_is_bm_name_token(parse_info)) {
525  char* flag_name = epr_consume_token(parse_info);
526  term = epr_create_bm_REF_term(ds_name, flag_name);
527  } else {
528  epr_set_bm_expr_error(parse_info, "flag name expected");
529  }
530  } else {
531  epr_set_bm_expr_error(parse_info, "'.' expected");
532  }
533  } else if (epr_is_bm_EOS_token(parse_info)) {
534  if (term_required) {
535  epr_set_bm_expr_error(parse_info, "operator or flag name expected");
536  }
537  } else {
538  epr_set_bm_expr_error(parse_info, "operator or flag name expected");
539  }
540 
541  return term;
542 }
543 
544 epr_boolean epr_is_bm_OR_keyword(EPR_SParseInfo* parse_info) {
545  return epr_is_bm_name_token(parse_info) && stricmp("or", parse_info->token) == 0;
546 }
547 
548 epr_boolean epr_is_bm_AND_keyword(EPR_SParseInfo* parse_info) {
549  return epr_is_bm_name_token(parse_info) && stricmp("and", parse_info->token) == 0;
550 }
551 
552 epr_boolean epr_is_bm_NOT_keyword(EPR_SParseInfo* parse_info) {
553  return epr_is_bm_name_token(parse_info) && stricmp("not", parse_info->token) == 0;
554 }
555 
556 epr_boolean epr_is_bm_AND_operator(EPR_SParseInfo* parse_info) {
557  return epr_get_token_char(parse_info) == '&';
558 }
559 
560 epr_boolean epr_is_bm_OR_operator(EPR_SParseInfo* parse_info) {
561  return epr_get_token_char(parse_info) == '|';
562 }
563 
564 epr_boolean epr_is_bm_NOT_operator(EPR_SParseInfo* parse_info) {
565  return epr_get_token_char(parse_info) == '!';
566 }
567 
568 epr_boolean epr_is_bm_name_token(EPR_SParseInfo* parse_info) {
569  return parse_info->token_type == BME_NAME && parse_info->token != NULL;
570 }
571 
572 epr_boolean epr_is_bm_EOS_token(EPR_SParseInfo* parse_info) {
573  return parse_info->token_type == BME_EOS;
574 }
575 
576 epr_boolean epr_is_bm_expr_error(EPR_SParseInfo* parse_info) {
577  return parse_info->err_message != NULL;
578 }
579 
580 int epr_get_token_char(EPR_SParseInfo* parse_info) {
581  if (parse_info->token_type == BME_SPECIAL && parse_info->token != NULL) {
582  return parse_info->token[0];
583  }
584  return '\0';
585 }
586 
587 char* epr_consume_token(EPR_SParseInfo* parse_info) {
588  char* token = parse_info->token;
589  /* Prevent from being released by epr_free_string() */
590  parse_info->token = NULL;
591  parse_info->token_type = BME_UNKNOWN;
592  parse_info->pushed_back = EPR_FALSE;
593  return token;
594 
595 }
596 
597 void epr_next_bm_expr_token(EPR_SParseInfo* parse_info) {
598  if (parse_info->pushed_back) {
599  parse_info->pushed_back = EPR_FALSE;
600  return;
601  }
602  epr_free_string(parse_info->token);
603  parse_info->token_type = epr_tokenize_bm_expr(parse_info->bm_expr,
604  &(parse_info->bm_expr_pos),
605  &(parse_info->token));
606 }
607 
608 void epr_push_back_bm_expr_token(EPR_SParseInfo* parse_info) {
609  parse_info->pushed_back = EPR_TRUE;
610 }
611 
612 void epr_set_bm_expr_error(EPR_SParseInfo* parse_info, const char* message) {
613  static char msg_buf[2048];
614 
615  epr_push_back_bm_expr_token(parse_info);
616 
617  if (message != NULL) {
618  if (!epr_is_bm_EOS_token(parse_info)) {
619  sprintf(msg_buf, "%s, but found token '%s'", message, parse_info->token);
620  } else {
621  sprintf(msg_buf, "%s, but found 'end-of-string'", message);
622  }
623  } else {
624  if (!epr_is_bm_EOS_token(parse_info)) {
625  sprintf(msg_buf, "unexpected token '%s' found", parse_info->token);
626  } else {
627  sprintf(msg_buf, "unexpected 'end-of-string' found");
628  }
629  }
630 
631  parse_info->err_message = epr_clone_string(msg_buf);
632 }
633 
634 
635 int epr_tokenize_bm_expr(const char* bm_expr, int* bm_expr_pos, char** token)
636 {
637  int pos = *bm_expr_pos;
638 
639  while (isspace(bm_expr[pos])) {
640  pos++;
641  }
642 
643  if (bm_expr[pos] == '\0') {
644  *bm_expr_pos = pos;
645  *token = NULL;
646  return BME_EOS;
647  }
648 
649  if (isalpha(bm_expr[pos]) || bm_expr[pos] == '_') {
650  int pos0 = pos;
651  size_t len;
652  char* tok;
653 
654  pos++;
655  while (isalnum(bm_expr[pos]) || bm_expr[pos] == '_') {
656  pos++;
657  }
658 
659  len = pos - pos0;
660  tok = epr_create_string(len + 1);
661  strncpy(tok, bm_expr + pos0, len);
662  tok[len] = '\0';
663 
664  *token = tok;
665  *bm_expr_pos = pos;
666  return BME_NAME;
667  }
668 
669  if (bm_expr[pos] == '(' ||
670  bm_expr[pos] == ')' ||
671  bm_expr[pos] == '.' ||
672  bm_expr[pos] == '&' ||
673  bm_expr[pos] == '|' ||
674  bm_expr[pos] == '!') {
675  char* tok;
676 
677  tok = epr_create_string(2);
678  tok[0] = bm_expr[pos];
679  tok[1] = '\0';
680 
681  pos++;
682 
683  *token = tok;
684  *bm_expr_pos = pos;
685  return BME_SPECIAL;
686  }
687 
688  *token = NULL;
689  *bm_expr_pos = pos;
690  return BME_UNKNOWN;
691 }
692 
693 
694 EPR_SBmTerm* epr_create_bm_term(EPR_EBmOpCode op_code)
695 {
696  EPR_SBmTerm* term = (EPR_SBmTerm*) malloc(sizeof (EPR_SBmTerm));
697  term->op_code = op_code;
698  return term;
699 }
700 
701 EPR_SBmTerm* epr_create_bm_REF_term(char* band_name, char* flag_name)
702 {
703  EPR_SBmTerm* term = epr_create_bm_term(BMT_REF);
704  term->op.ref.band_name = band_name;
705  term->op.ref.flag_name = flag_name;
706  term->op.ref.flag_mask = FLAG_MASK_NOT_COMPUTED; /* not computed */
707  term->op.ref.flag_raster = NULL;
708  return term;
709 }
710 
711 EPR_SBmTerm* epr_create_bm_NOT_term(EPR_SBmTerm* arg)
712 {
713  EPR_SBmTerm* term = epr_create_bm_term(BMT_NOT);
714  term->op.unary.arg = arg;
715  return term;
716 }
717 
718 EPR_SBmTerm* epr_create_bm_OR_term(EPR_SBmTerm* arg1, EPR_SBmTerm* arg2)
719 {
720  EPR_SBmTerm* term = epr_create_bm_term(BMT_OR);
721  term->op.binary.arg1 = arg1;
722  term->op.binary.arg2 = arg2;
723  return term;
724 }
725 
726 EPR_SBmTerm* epr_create_bm_AND_term(EPR_SBmTerm* arg1, EPR_SBmTerm* arg2)
727 {
728  EPR_SBmTerm* term = epr_create_bm_term(BMT_AND);
729  term->op.binary.arg1 = arg1;
730  term->op.binary.arg2 = arg2;
731  return term;
732 }
733 
734 
735 
736 epr_uint epr_get_pixel_as_uint(const EPR_SRaster* raster, int x, int y)
737 {
738  epr_clear_err();
739 
740  switch (raster->data_type) {
741  case (e_tid_uchar) :
742  return (epr_uint) ((epr_uchar*)raster->buffer)[y * raster->raster_width + x];
743  case (e_tid_char) :
744  return (epr_uint) ((char*)raster->buffer)[y * raster->raster_width + x];
745  case (e_tid_ushort):
746  return (epr_uint) ((epr_ushort*)raster->buffer)[y * raster->raster_width + x];
747  case (e_tid_short) :
748  return (epr_uint) ((short*)raster->buffer)[y * raster->raster_width + x];
749  case (e_tid_uint):
750  return (epr_uint) ((epr_uint*)raster->buffer)[y * raster->raster_width + x];
751  case (e_tid_int) :
752  return (epr_uint) ((int*)raster->buffer)[y * raster->raster_width + x];
753  case (e_tid_float) :
754  return (epr_uint) ((float*)raster->buffer)[y * raster->raster_width + x];
755  case (e_tid_double) :
756  return (epr_uint) ((double*)raster->buffer)[y * raster->raster_width + x];
757  default:
758  return 0;
759  }
760 }
761 
762 int epr_get_pixel_as_int(const EPR_SRaster* raster, int x, int y)
763 {
764  epr_clear_err();
765 
766  switch (raster->data_type) {
767  case (e_tid_uchar) :
768  return (int) ((epr_uchar*)raster->buffer)[y * raster->raster_width + x];
769  case (e_tid_char) :
770  return (int) ((char*)raster->buffer)[y * raster->raster_width + x];
771  case (e_tid_ushort):
772  return (int) ((epr_ushort*)raster->buffer)[y * raster->raster_width + x];
773  case (e_tid_short) :
774  return (int) ((short*)raster->buffer)[y * raster->raster_width + x];
775  case (e_tid_uint):
776  return (int) ((epr_uint*)raster->buffer)[y * raster->raster_width + x];
777  case (e_tid_int) :
778  return (int) ((int*)raster->buffer)[y * raster->raster_width + x];
779  case (e_tid_float) :
780  return (int) ((float*)raster->buffer)[y * raster->raster_width + x];
781  case (e_tid_double) :
782  return (int) ((double*)raster->buffer)[y * raster->raster_width + x];
783  default:
784  return 0;
785  }
786 }
787 
788 
789 float epr_get_pixel_as_float(const EPR_SRaster* raster, int x, int y)
790 {
791  epr_clear_err();
792 
793  switch (raster->data_type) {
794  case (e_tid_uchar) :
795  return (float) ((epr_uchar*)raster->buffer)[y * raster->raster_width + x];
796  case (e_tid_char) :
797  return (float) ((char*)raster->buffer)[y * raster->raster_width + x];
798  case (e_tid_ushort):
799  return (float) ((epr_ushort*)raster->buffer)[y * raster->raster_width + x];
800  case (e_tid_short) :
801  return (float) ((short*)raster->buffer)[y * raster->raster_width + x];
802  case (e_tid_uint):
803  return (float) ((epr_uint*)raster->buffer)[y * raster->raster_width + x];
804  case (e_tid_int) :
805  return (float) ((int*)raster->buffer)[y * raster->raster_width + x];
806  case (e_tid_float) :
807  return (float) ((float*)raster->buffer)[y * raster->raster_width + x];
808  case (e_tid_double) :
809  return (float) ((double*)raster->buffer)[y * raster->raster_width + x];
810  default:
811  return 0;
812  }
813 }
814 
815 double epr_get_pixel_as_double(const EPR_SRaster* raster, int x, int y)
816 {
817  epr_clear_err();
818 
819  switch (raster->data_type) {
820  case (e_tid_uchar) :
821  return (double) ((epr_uchar*)raster->buffer)[y * raster->raster_width + x];
822  case (e_tid_char) :
823  return (double) ((char*)raster->buffer)[y * raster->raster_width + x];
824  case (e_tid_ushort):
825  return (double) ((epr_ushort*)raster->buffer)[y * raster->raster_width + x];
826  case (e_tid_short) :
827  return (double) ((short*)raster->buffer)[y * raster->raster_width + x];
828  case (e_tid_uint):
829  return (double) ((epr_uint*)raster->buffer)[y * raster->raster_width + x];
830  case (e_tid_int) :
831  return (double) ((int*)raster->buffer)[y * raster->raster_width + x];
832  case (e_tid_float) :
833  return (double) ((float*)raster->buffer)[y * raster->raster_width + x];
834  case (e_tid_double) :
835  return (double) ((double*)raster->buffer)[y * raster->raster_width + x];
836  default:
837  return 0;
838  }
839 }
840 
844 void epr_free_bm_term(EPR_SBmTerm* term) {
845  if (term == NULL)
846  return;
847 
848  switch (term->op_code) {
849  case BMT_REF:
850  epr_free_string(term->op.ref.band_name);
851  epr_free_string(term->op.ref.flag_name);
852  term->op.ref.band_name = NULL;
853  term->op.ref.flag_name = NULL;
854  break;
855  case BMT_AND: /* OR */ case BMT_OR:
856  epr_free_bm_term(term->op.binary.arg1);
857  epr_free_bm_term(term->op.binary.arg2);
858  term->op.binary.arg1 = NULL;
859  term->op.binary.arg2 = NULL;
860  break;
861  case BMT_NOT:
862  epr_free_bm_term(term->op.unary.arg);
863  term->op.unary.arg = NULL;
864  break;
865  default:
866  assert(0);
867  }
868 
869  free(term);
870 }
871 
872 
880 char* epr_create_bm_expr(EPR_SBmTerm* term)
881 {
882  if (term == NULL)
883  return NULL;
884 
885  switch (term->op_code) {
886  case BMT_REF: {
887  char* s0 = epr_create_string(strlen(term->op.ref.band_name) + strlen(term->op.ref.flag_name) + 16);
888  sprintf(s0, "%s.%s", term->op.ref.band_name, term->op.ref.flag_name);
889  return s0;
890  }
891  case BMT_AND: {
892  char* s1 = epr_create_bm_expr(term->op.binary.arg1);
893  char* s2 = epr_create_bm_expr(term->op.binary.arg2);
894  char* s0 = epr_create_string(strlen(s1) + strlen(s2) + 16);
895  sprintf(s0, "(%s) AND (%s)", s1, s2);
896  epr_free_string(s1);
897  epr_free_string(s2);
898  return s0;
899  }
900  case BMT_OR: {
901  char* s1 = epr_create_bm_expr(term->op.binary.arg1);
902  char* s2 = epr_create_bm_expr(term->op.binary.arg2);
903  char* s0 = epr_create_string(strlen(s1) + strlen(s2) + 16);
904  sprintf(s0, "(%s) OR (%s)", s1, s2);
905  epr_free_string(s1);
906  epr_free_string(s2);
907  return s0;
908  }
909  case BMT_NOT: {
910  char* s1 = epr_create_bm_expr(term->op.unary.arg);
911  char* s0 = epr_create_string(strlen(s1) + 16);
912  sprintf(s0, "NOT (%s)", s1);
913  epr_free_string(s1);
914  return s0;
915  }
916  default:
917  assert(EPR_FALSE);
918  return NULL;
919  }
920 }
921 
925 void epr_print_bm_term(EPR_SBmTerm* term)
926 {
928 }
929 
933 void epr_write_bm_term(EPR_SBmTerm* term, FILE* ostream)
934 {
935  char* bm_expr = epr_create_bm_expr(term);
936  fprintf(ostream, "%s", bm_expr);
937  epr_free_string(bm_expr);
938 }
EPR_SBmTerm * epr_create_bm_NOT_term(EPR_SBmTerm *arg)
Definition: epr_bitmask.c:711
const struct FlagDescriptorTable dddb_flag_coding_tables[6]
Definition: epr_dddb.c:4277
@ e_err_out_of_memory
Definition: epr_api.h:83
EPR_SBmTerm * epr_parse_bm_expr(EPR_SParseInfo *parse_info, epr_boolean term_required)
Definition: epr_bitmask.c:445
int j
Definition: decode_rs.h:73
@ e_err_illegal_arg
Definition: epr_api.h:81
EPR_SBmTerm * epr_create_bm_term(EPR_EBmOpCode op_code)
Definition: epr_bitmask.c:694
@ BMT_REF
Definition: epr_bitmask.h:38
void epr_free_bm_eval_context(EPR_SBmEvalContext *context)
Definition: epr_bitmask.c:62
EPR_SRaster * epr_create_compatible_raster(EPR_SBandId *band_id, epr_uint source_width, epr_uint source_height, epr_uint source_step_x, epr_uint source_step_y)
Definition: epr_band.c:549
epr_uint epr_get_pixel_as_uint(const EPR_SRaster *raster, int x, int y)
Definition: epr_bitmask.c:736
unsigned int epr_uint
Definition: epr_api.h:188
void epr_free_ptr_array(EPR_SPtrArray *ptr_array)
Definition: epr_ptrarray.c:51
void epr_free_raster(EPR_SRaster *raster)
Definition: epr_band.c:568
EPR_SBmTerm * epr_parse_bm_OR_expr(EPR_SParseInfo *parse_info, epr_boolean term_required)
Definition: epr_bitmask.c:451
epr_boolean epr_is_bm_AND_operator(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:556
enum EPR_ErrCode EPR_EErrCode
Definition: epr_api.h:162
unsigned short epr_ushort
Definition: epr_api.h:187
#define NULL
Definition: decode_rs.h:63
void epr_free_flag_coding(EPR_SPtrArray *flag_coding)
Definition: epr_bitmask.c:395
const char * name
Definition: epr_dddb.h:63
void epr_print_bm_term(EPR_SBmTerm *term)
Definition: epr_bitmask.c:925
@ BME_EOS
Definition: epr_bitmask.h:46
@ BMT_OR
Definition: epr_bitmask.h:40
EPR_SBmEvalContext * epr_create_bm_eval_context(EPR_SProductId *product_id, int offset_x, int offset_y, EPR_SRaster *bitmask_raster)
Definition: epr_bitmask.c:39
void epr_set_bm_expr_error(EPR_SParseInfo *parse_info, const char *message)
Definition: epr_bitmask.c:612
epr_boolean epr_is_bm_NOT_keyword(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:552
float32 * pos
Definition: l1_czcs_hdf.c:35
char * epr_assign_string(char **str_clone, const char *str)
Definition: epr_string.c:29
int epr_boolean
Definition: epr_api.h:185
float epr_get_pixel_as_float(const EPR_SRaster *raster, int x, int y)
Definition: epr_bitmask.c:789
@ e_tid_float
Definition: epr_api.h:60
void epr_write_bm_term(EPR_SBmTerm *term, FILE *ostream)
Definition: epr_bitmask.c:933
const char * description
Definition: epr_dddb.h:45
double epr_get_pixel_as_double(const EPR_SRaster *raster, int x, int y)
Definition: epr_bitmask.c:815
character(len=1000) if
Definition: names.f90:13
char * epr_create_string(unsigned int length)
Definition: epr_string.c:37
EPR_SBmTerm * epr_parse_bm_primary_expr(EPR_SParseInfo *parse_info, epr_boolean term_required)
Definition: epr_bitmask.c:508
epr_boolean epr_equal_names(const char *name1, const char *name2)
Definition: epr_string.c:91
@ e_tid_int
Definition: epr_api.h:58
@ e_tid_ushort
Definition: epr_api.h:52
#define EPR_NUM_FLAG_CODING_TABLES
Definition: epr_dddb.h:85
@ e_err_illegal_data_type
Definition: epr_api.h:86
enum EPR_BmOpCode EPR_EBmOpCode
Definition: epr_bitmask.h:31
@ e_err_null_pointer
Definition: epr_api.h:80
EPR_SPtrArray * epr_create_flag_coding(EPR_SProductId *product_id, const char *flag_coding_name)
Definition: epr_bitmask.c:333
#define EPR_MAGIC_FLAG_DEF
Definition: epr_api.h:200
data_t tmp
Definition: decode_rs.h:74
@ BME_SPECIAL
Definition: epr_bitmask.h:47
void epr_free_bm_term(EPR_SBmTerm *term)
Definition: epr_bitmask.c:844
char * epr_clone_string(const char *str)
Definition: epr_string.c:43
EPR_SFlagDef * epr_create_flag_def()
Definition: epr_bitmask.c:414
@ e_err_invalid_value
Definition: epr_api.h:108
EPR_SBmTerm * epr_parse_bm_expr_str(const char *bm_expr)
Definition: epr_bitmask.c:307
@ e_tid_uint
Definition: epr_api.h:56
char * epr_consume_token(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:587
EPR_SBmTerm * epr_parse_bm_unary_expr(EPR_SParseInfo *parse_info, epr_boolean term_required)
Definition: epr_bitmask.c:492
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to already in place for MODIS TERRA was implemented for MODIS AQUA A time dependent LUT was added which gives coefficients for a detector specific crosstalk correction based on the aggregated Band radiances The Band scaled integers are adjusted by the Band correction term
Definition: HISTORY.txt:439
What value is used by your function when the data value is bad Default is BAD_FLT l2prod product_id[0]
instead the metadata field ProcessingEnvinronment is filled in from the output of a call to the POSIX compliant function uname from within the L1B code A small bug in L1B_Tables an incorrect comparison of RVS coefficients for TEBs to RVS coefficients for RSBs was being made This was replaced with a comparison between TEB coefficients This error never resulted in an incorrect RVS correction but did lead to recalculating the coefficients for each detector in a thermal band even if the coefficients were the same for all detectors To reduce to overall size of the reflective LUT HDF fill values were eliminated from all LUTs previously dimensioned where and where NUM_TIMES is the number of time dependent table pieces In Preprocess a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed This counter is internal only and is not yet used for any chiefly to casting of were added to make it LINUX compatible Output of code run on LINUX machines displays differences of at most scaled sector incalculable values of the Emissive calibration factor and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal c since none of these quantities are frame dependent Initialization of b1 and XMS values in Preprocess c routine Process_OBCENG_Emiss was moved inside the detector loops The code was altered so that if up to five scans are dropped between the leading middle or middle trailing the leading or trailing granule will still be used in emissive calibration to form a cross granule average QA bits and are set for a gap between the leading middle and middle trailing granules respectively This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule A small bug in the Band correction algorithm was corrected an uncertainty value was being checked against an upper bound whereas the proper quantity to be checked was the corresponding which is the product of the Band radiance times the ratio of the Band to Band scaling factors times the LUT correction value for that detector In addition a new LUT which allows for a frame offset with regard to the Band radiance was added A LUT which switches the correction off or on was also added Changes which do not affect scientific output of the the pixel is flagged with the newly created flag and the number of pixels for which this occurs is counted in the QA_common table The array of b1s in Preprocess c was being initialized to outside the loop over which meant that if b1 could not be the value of b1 from the previous band for that scan detector combination was used The initialization was moved inside the band loop Minor code changes were made to eliminate compiler warnings when the code is compiled in bit mode Temperature equations were upgraded to be MODIS AQUA or MODIS TERRA specific and temperature conversion coefficients for AQUA were MOD_PR02 will not cease execution if the value of this parameter is not but will print a message
Definition: HISTORY.txt:644
EPR_SBmTerm * epr_parse_bm_AND_expr(EPR_SParseInfo *parse_info, epr_boolean term_required)
Definition: epr_bitmask.c:471
epr_boolean epr_is_bm_OR_operator(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:560
void epr_free_flag_def(EPR_SFlagDef *flag_def)
Definition: epr_bitmask.c:430
@ e_tid_char
Definition: epr_api.h:50
int epr_add_ptr_array_elem(EPR_SPtrArray *ptr_array, void *elem)
Definition: epr_ptrarray.c:75
void epr_clear_err()
Definition: epr_core.c:247
epr_boolean epr_is_bm_NOT_operator(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:564
EPR_SBmTerm * epr_create_bm_REF_term(char *band_name, char *flag_name)
Definition: epr_bitmask.c:701
void epr_set_err(EPR_EErrCode err_code, const char *err_message)
Definition: epr_core.c:221
@ e_tid_double
Definition: epr_api.h:62
epr_boolean epr_eval_bm_term(EPR_SBmEvalContext *context, EPR_SBmTerm *term, int x, int y)
Definition: epr_bitmask.c:174
EPR_SBmTerm * epr_create_bm_OR_term(EPR_SBmTerm *arg1, EPR_SBmTerm *arg2)
Definition: epr_bitmask.c:718
#define isspace(c)
int epr_get_pixel_as_int(const EPR_SRaster *raster, int x, int y)
Definition: epr_bitmask.c:762
#define FLAG_MASK_NOT_COMPUTED
Definition: epr_bitmask.h:26
epr_boolean epr_is_bm_expr_error(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:576
void epr_resolve_bm_ref(EPR_SBmEvalContext *context, EPR_SBmTerm *term)
Definition: epr_bitmask.c:228
char * epr_create_bm_expr(EPR_SBmTerm *term)
Definition: epr_bitmask.c:880
int epr_tokenize_bm_expr(const char *bm_expr, int *bm_expr_pos, char **token)
Definition: epr_bitmask.c:635
@ e_tid_short
Definition: epr_api.h:54
#define isalpha(c)
@ BME_NAME
Definition: epr_bitmask.h:48
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
@ BME_UNKNOWN
Definition: epr_bitmask.h:45
void epr_push_back_bm_expr_token(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:608
EPR_SBandId * epr_get_band_id(EPR_SProductId *product_id, const char *band_name)
Definition: epr_band.c:237
epr_boolean epr_is_bm_name_token(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:568
const struct FlagDescriptor * descriptors
Definition: epr_dddb.h:66
const int num_indices
Definition: epr_dddb.h:43
EPR_EErrCode epr_get_last_err_code()
Definition: epr_core.c:265
const char * id
Definition: epr_dddb.h:42
@ BMT_AND
Definition: epr_bitmask.h:39
epr_boolean epr_is_bm_OR_keyword(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:544
const int bit_indices[2]
Definition: epr_dddb.h:44
int stricmp(const char *s1, const char *s2)
Definition: epr_string.c:378
unsigned char epr_uchar
Definition: epr_api.h:186
@ e_tid_uchar
Definition: epr_api.h:48
int epr_get_token_char(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:580
int epr_read_band_raster(EPR_SBandId *band_id, int offset_x, int offset_y, EPR_SRaster *raster)
Definition: epr_band.c:593
@ BMT_NOT
Definition: epr_bitmask.h:41
#define EPR_FALSE
Definition: epr_api.h:203
int i
Definition: decode_rs.h:71
#define EPR_TRUE
Definition: epr_api.h:202
void epr_free_string(char *str)
Definition: epr_string.c:100
int epr_read_bitmask_raster(EPR_SProductId *product_id, const char *bm_expr, int offset_x, int offset_y, EPR_SRaster *bm_raster)
Definition: epr_bitmask.c:99
@ e_err_flag_not_found
Definition: epr_api.h:113
epr_boolean epr_is_bm_AND_keyword(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:548
EPR_SPtrArray * epr_create_ptr_array(unsigned int capacity)
Definition: epr_ptrarray.c:29
void epr_next_bm_expr_token(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:597
epr_boolean epr_is_bm_EOS_token(EPR_SParseInfo *parse_info)
Definition: epr_bitmask.c:572
EPR_SBmTerm * epr_create_bm_AND_term(EPR_SBmTerm *arg1, EPR_SBmTerm *arg2)
Definition: epr_bitmask.c:726