Exemplo n.º 1
0
int main (int argc, const char **argv) {
  Param_t *param = NULL;
  Input_t *input = NULL;
  Lut_t *lut = NULL;
  Output_t *output = NULL;
  Output_t *output_th = NULL;
  int iline, isamp,oline, ib, jb, iz, val;
  unsigned char *line_in = NULL;
  unsigned char *line_in_thz = NULL;
  unsigned char *line_out_qa = NULL;
  int16 *line_out = NULL;
  int16 *line_out_th = NULL;
  int16 *line_out_thz = NULL;
  Cal_stats_t cal_stats;
  Cal_stats6_t cal_stats6;
  int nps,nls, nps6, nls6;
  int zoomx, zoomy;
  int i,odometer_flag=0;
  char msgbuf[1024];
  char envi_file[STR_SIZE]; /* name of the output ENVI header file */
  char *cptr=NULL;          /* pointer to the file extension */
  size_t input_psize;
  int qa_band = QA_BAND_NUM;
  int nband_refl = NBAND_REFL_MAX;
  int ifill, num_zero;
  int maxth=0;
  int mss_flag=0;
  Espa_internal_meta_t xml_metadata;  /* XML metadata structure */
  Envi_header_t envi_hdr;   /* output ENVI header information */

  printf ("\nRunning lndcal ...\n");
  for (i=1; i<argc; i++)if ( !strcmp(argv[i],"-o") )odometer_flag=1;

  /* Read the parameters from the input parameter file */
  param = GetParam(argc, argv);
  if (param == (Param_t *)NULL) EXIT_ERROR("getting runtime parameters",
    "main");

  /* Validate the input metadata file */
  if (validate_xml_file (param->input_xml_file_name) != SUCCESS)
  {  /* Error messages already written */
      EXIT_ERROR("Failure validating XML file", "main");
  }

  /* Initialize the metadata structure */
  init_metadata_struct (&xml_metadata);

  /* Parse the metadata file into our internal metadata structure; also
     allocates space as needed for various pointers in the global and band
     metadata */
  if (parse_metadata (param->input_xml_file_name, &xml_metadata) != SUCCESS)
  {  /* Error messages already written */
    EXIT_ERROR("parsing XML file", "main");
  }

  /* Check to see if the gain and bias values were specified */
  if (!existRadGB (&xml_metadata))
    EXIT_ERROR("Gains and biases don't exist in XML file (TOA radiance gain "
      "and bias fields) for each band.  Make sure to utilize the latest LPGS "
      "MTL file for conversion to the ESPA internal raw binary format as the "
      "gains and biases should be in that file.", "main");
  
  /* Open input file */
  input = OpenInput (&xml_metadata);
  if (input == (Input_t *)NULL)
    EXIT_ERROR("setting up input from XML structure", "main");

  /* Get Lookup table */
  lut = GetLut(param, input->nband, input);
  if (lut == (Lut_t *)NULL) EXIT_ERROR("bad lut file", "main");

  nps6=  input->size_th.s;
  nls6=  input->size_th.l;
  nps =  input->size.s;
  nls =  input->size.l;
  zoomx= nint( (float)nps / (float)nps6 );
  zoomy= nint( (float)nls / (float)nls6 );

  for (ib = 0; ib < input->nband; ib++) 
    cal_stats.first[ib] = true;
  cal_stats6.first = true;
  if (input->meta.inst == INST_MSS)mss_flag=1; 

  /* Open the output files.  Raw binary band files will be be opened. */
  output = OpenOutput(&xml_metadata, input, param, lut, false /*not thermal*/,
    mss_flag);
  if (output == NULL) EXIT_ERROR("opening output file", "main");

  /* Allocate memory for the input buffer, enough for all reflectance bands */
  input_psize = sizeof(unsigned char);
  line_in = calloc (input->size.s * nband_refl, input_psize);
   if (line_in == NULL) 
     EXIT_ERROR("allocating input line buffer", "main");

  /* Create and open output thermal band, if one exists */
  if ( input->nband_th > 0 ) {
    output_th = OpenOutput (&xml_metadata, input, param, lut, true /*thermal*/,
      mss_flag);
    if (output_th == NULL)
      EXIT_ERROR("opening output therm file", "main");

    /* Allocate memory for the thermal input and output buffer, only holds
       one band */
    line_out_th = calloc(input->size_th.s, sizeof(int16));
    if (line_out_th == NULL) 
      EXIT_ERROR("allocating thermal output line buffer", "main");

    if (zoomx == 1) {
      line_out_thz = line_out_th;
      line_in_thz = line_in;
    }
    else {
      line_out_thz = calloc (input->size.s, sizeof(int16));
      if (line_out_thz == NULL) 
        EXIT_ERROR("allocating thermal zoom output line buffer", "main");
      line_in_thz = calloc (input->size.s, input_psize);
      if (line_in_thz == NULL) 
        EXIT_ERROR("allocating thermal zoom input line buffer", "main");
    }
  } else {
    printf("*** no output thermal file ***\n"); 
  }

  /* Allocate memory for output lines for both the image and QA data */
  line_out = calloc (input->size.s, sizeof (int16));
  if (line_out == NULL) 
    EXIT_ERROR("allocating output line buffer", "main");

  line_out_qa = calloc (input->size.s, sizeof(unsigned char));
  if (line_out_qa == NULL) 
    EXIT_ERROR("allocating qa output line buffer", "main");
  memset (line_out_qa, 0, input->size.s * sizeof(unsigned char));    

  /* Do for each THERMAL line */
  oline= 0;
  if (input->nband_th > 0) {
    ifill= (int)lut->in_fill;
    for (iline = 0; iline < input->size_th.l; iline++) {
      ib=0;
      if (!GetInputLineTh(input, iline, line_in))
        EXIT_ERROR("reading input data for a line", "main");

      if ( odometer_flag && ( iline==0 || iline ==(nls-1) || iline%100==0  ) ){ 
        if ( zoomy == 1 )
          printf("--- main loop BAND6 Line %d --- \r",iline); 
        else
          printf("--- main loop BAND6 Line in=%d out=%d --- \r",iline,oline); 
        fflush(stdout); 
      }

      memset(line_out_qa, 0, input->size.s*sizeof(unsigned char));    
      if (!Cal6(lut, input, line_in, line_out_th, line_out_qa, &cal_stats6,
        iline))
        EXIT_ERROR("doing calibration for a line", "main");

      if ( zoomx>1 ) {
        zoomIt(line_out_thz, line_out_th, nps/zoomx, zoomx );
        zoomIt8(line_in_thz, line_in, nps/zoomx, zoomx );
      }

      for ( iz=0; iz<zoomy; iz++ ) {
        for (isamp = 0; isamp < input->size.s; isamp++) {
          val= getValue(line_in_thz, isamp);
          if ( val> maxth) maxth=val;
          if ( val==ifill) line_out_qa[isamp] = lut->qa_fill; 
          else if ( val>=SATU_VAL6 ) line_out_qa[isamp] = ( 0x000001 << 6 ); 
        }

        if ( oline<nls ) {
          if (!PutOutputLine(output_th, ib, oline, line_out_thz)) {
            sprintf(msgbuf,"write thermal error ib=%d oline=%d iline=%d",ib,
              oline,iline);
            EXIT_ERROR(msgbuf, "main");
          }

          if (input->meta.inst != INST_MSS) 
            if (!PutOutputLine(output_th, ib+1, oline, line_out_qa)) {
	          sprintf(msgbuf,"write thermal QA error ib=%d oline=%d iline=%d",
                ib+1,oline,iline);
              EXIT_ERROR(msgbuf, "main");
            }
        }
        oline++;
      }
    } /* end loop for each thermal line */
  }
  if (odometer_flag) printf("\n");

  if (input->nband_th > 0)
    if (!CloseOutput(output_th))
      EXIT_ERROR("closing output thermal file", "main");

  /* Do for each REFLECTIVE line */
  ifill= (int)lut->in_fill;
  for (iline = 0; iline < input->size.l; iline++){
    /* Do for each band */

    if ( odometer_flag && ( iline==0 || iline ==(nls-1) || iline%100==0  ) )
     {printf("--- main reflective loop Line %d ---\r",iline); fflush(stdout);}

    memset(line_out_qa, 0, input->size.s*sizeof(unsigned char));
    
    for (ib = 0; ib < input->nband; ib++) {
      if (!GetInputLine(input, ib, iline, &line_in[ib*nps]))
        EXIT_ERROR("reading input data for a line", "main");
    }
    
    for (isamp = 0; isamp < input->size.s; isamp++){
      num_zero=0;
      for (ib = 0; ib < input->nband; ib++) {
        jb= (ib != 5 ) ? ib+1 : ib+2;
        val= getValue((unsigned char *)&line_in[ib*nps], isamp);
	    if ( val==ifill   )num_zero++;
        if ( val==SATU_VAL[ib] ) line_out_qa[isamp]|= ( 0x000001 <<jb ); 
      }
      /* Feng fixed bug by changing "|=" to "=" below (4/17/09) */
      if ( num_zero >  0 )line_out_qa[isamp] = lut->qa_fill; 
    }

    for (ib = 0; ib < input->nband; ib++) {
      if (!Cal(lut, ib, input, &line_in[ib*nps], line_out, line_out_qa,
        &cal_stats,iline))
        EXIT_ERROR("doing calibraton for a line", "main");

      if (!PutOutputLine(output, ib, iline, line_out))
        EXIT_ERROR("reading input data for a line", "main");
    } /* End loop for each band */
        
    if (input->meta.inst != INST_MSS) 
      if (!PutOutputLine(output, qa_band, iline, line_out_qa))
        EXIT_ERROR("writing qa data for a line", "main");
  } /* End loop for each line */

  if ( odometer_flag )printf("\n");

  for (ib = 0; ib < input->nband; ib++) {
    printf(
      " band %d rad min %8.5g max %8.4f  |  ref min  %8.5f max  %8.4f\n", 
      input->meta.iband[ib], cal_stats.rad_min[ib], cal_stats.rad_max[ib],
      cal_stats.ref_min[ib], cal_stats.ref_max[ib]);
  }

  if ( input->nband_th > 0 )
    printf(
      " band %d rad min %8.5g max %8.4f  |  tmp min  %8.5f max  %8.4f\n", 6,
      cal_stats6.rad_min,  cal_stats6.rad_max,
      cal_stats6.temp_min, cal_stats6.temp_max);

  /* Close input and output files */
  if (!CloseInput(input)) EXIT_ERROR("closing input file", "main");
  if (!CloseOutput(output)) EXIT_ERROR("closing input file", "main");

  /* Write the ENVI header for reflectance files */
  for (ib = 0; ib < output->nband; ib++) {
    /* Create the ENVI header file this band */
    if (create_envi_struct (&output->metadata.band[ib], &xml_metadata.global,
      &envi_hdr) != SUCCESS)
        EXIT_ERROR("Creating the ENVI header structure for this file.", "main");

    /* Write the ENVI header */
    strcpy (envi_file, output->metadata.band[ib].file_name);
    cptr = strchr (envi_file, '.');
    strcpy (cptr, ".hdr");
    if (write_envi_hdr (envi_file, &envi_hdr) != SUCCESS)
        EXIT_ERROR("Writing the ENVI header file.", "main");
  }

  /* Write the ENVI header for thermal files */
  for (ib = 0; ib < output_th->nband; ib++) {
    /* Create the ENVI header file this band */
    if (create_envi_struct (&output_th->metadata.band[ib], &xml_metadata.global,
      &envi_hdr) != SUCCESS)
        EXIT_ERROR("Creating the ENVI header structure for this file.", "main");

    /* Write the ENVI header */
    strcpy (envi_file, output_th->metadata.band[ib].file_name);
    cptr = strchr (envi_file, '.');
    strcpy (cptr, ".hdr");
    if (write_envi_hdr (envi_file, &envi_hdr) != SUCCESS)
        EXIT_ERROR("Writing the ENVI header file.", "main");
  }

  /* Append the reflective and thermal bands to the XML file */
  if (append_metadata (output->nband, output->metadata.band,
    param->input_xml_file_name) != SUCCESS)
    EXIT_ERROR("appending reflectance and QA bands", "main");
  if (input->nband_th > 0) {
    if (append_metadata (output_th->nband, output_th->metadata.band,
      param->input_xml_file_name) != SUCCESS)
      EXIT_ERROR("appending thermal and QA bands", "main");
  }

  /* Free the metadata structure */
  free_metadata (&xml_metadata);

  /* Free memory */
  if (!FreeParam(param)) 
    EXIT_ERROR("freeing parameter stucture", "main");

  if (!FreeInput(input)) 
    EXIT_ERROR("freeing input file stucture", "main");

  if (!FreeLut(lut)) 
    EXIT_ERROR("freeing lut file stucture", "main");

  if (!FreeOutput(output)) 
    EXIT_ERROR("freeing output file stucture", "main");

  free(line_out);
  line_out = NULL;
  free(line_in);
  line_in = NULL;
  free(line_out_qa);
  line_out_qa = NULL;
  free(line_out_th);
  line_out_th = NULL;
  if (zoomx != 1) {
    free(line_in_thz);
    free(line_out_thz);
  }
  line_in_thz = NULL;
  line_out_thz = NULL;

  /* All done */
  printf ("lndcal complete.\n");
  return (EXIT_SUCCESS);
}
Exemplo n.º 2
0
static void
parse_named_action(enum ofputil_action_code code, const struct flow *flow,
                   char *arg, struct ofpbuf *ofpacts)
{
    struct ofpact_tunnel *tunnel;
    uint16_t vid;
    uint16_t ethertype;
    ovs_be32 ip;
    uint8_t pcp;
    uint8_t tos;

    switch (code) {
    case OFPUTIL_ACTION_INVALID:
        NOT_REACHED();

    case OFPUTIL_OFPAT10_OUTPUT:
    case OFPUTIL_OFPAT11_OUTPUT:
        parse_output(arg, ofpacts);
        break;

    case OFPUTIL_OFPAT10_SET_VLAN_VID:
    case OFPUTIL_OFPAT11_SET_VLAN_VID:
        vid = str_to_u32(arg);
        if (vid & ~VLAN_VID_MASK) {
            ovs_fatal(0, "%s: not a valid VLAN VID", arg);
        }
        ofpact_put_SET_VLAN_VID(ofpacts)->vlan_vid = vid;
        break;

    case OFPUTIL_OFPAT10_SET_VLAN_PCP:
    case OFPUTIL_OFPAT11_SET_VLAN_PCP:
        pcp = str_to_u32(arg);
        if (pcp & ~7) {
            ovs_fatal(0, "%s: not a valid VLAN PCP", arg);
        }
        ofpact_put_SET_VLAN_PCP(ofpacts)->vlan_pcp = pcp;
        break;

    case OFPUTIL_OFPAT12_SET_FIELD:
        set_field_parse(arg, ofpacts);
        break;

    case OFPUTIL_OFPAT10_STRIP_VLAN:
    case OFPUTIL_OFPAT11_POP_VLAN:
        ofpact_put_STRIP_VLAN(ofpacts);
        break;

    case OFPUTIL_OFPAT11_PUSH_VLAN:
        ethertype = str_to_u16(arg, "ethertype");
        if (ethertype != ETH_TYPE_VLAN_8021Q) {
            /* XXX ETH_TYPE_VLAN_8021AD case isn't supported */
            ovs_fatal(0, "%s: not a valid VLAN ethertype", arg);
        }
        ofpact_put_PUSH_VLAN(ofpacts);
        break;

    case OFPUTIL_OFPAT11_SET_QUEUE:
        ofpact_put_SET_QUEUE(ofpacts)->queue_id = str_to_u32(arg);
        break;


    case OFPUTIL_OFPAT10_SET_DL_SRC:
    case OFPUTIL_OFPAT11_SET_DL_SRC:
        str_to_mac(arg, ofpact_put_SET_ETH_SRC(ofpacts)->mac);
        break;

    case OFPUTIL_OFPAT10_SET_DL_DST:
    case OFPUTIL_OFPAT11_SET_DL_DST:
        str_to_mac(arg, ofpact_put_SET_ETH_DST(ofpacts)->mac);
        break;

    case OFPUTIL_OFPAT10_SET_NW_SRC:
    case OFPUTIL_OFPAT11_SET_NW_SRC:
        str_to_ip(arg, &ip);
        ofpact_put_SET_IPV4_SRC(ofpacts)->ipv4 = ip;
        break;

    case OFPUTIL_OFPAT10_SET_NW_DST:
    case OFPUTIL_OFPAT11_SET_NW_DST:
        str_to_ip(arg, &ip);
        ofpact_put_SET_IPV4_DST(ofpacts)->ipv4 = ip;
        break;

    case OFPUTIL_OFPAT10_SET_NW_TOS:
    case OFPUTIL_OFPAT11_SET_NW_TOS:
        tos = str_to_u32(arg);
        if (tos & ~IP_DSCP_MASK) {
            ovs_fatal(0, "%s: not a valid TOS", arg);
        }
        ofpact_put_SET_IPV4_DSCP(ofpacts)->dscp = tos;
        break;

    case OFPUTIL_OFPAT11_DEC_NW_TTL:
        NOT_REACHED();

    case OFPUTIL_OFPAT10_SET_TP_SRC:
    case OFPUTIL_OFPAT11_SET_TP_SRC:
        ofpact_put_SET_L4_SRC_PORT(ofpacts)->port = str_to_u32(arg);
        break;

    case OFPUTIL_OFPAT10_SET_TP_DST:
    case OFPUTIL_OFPAT11_SET_TP_DST:
        ofpact_put_SET_L4_DST_PORT(ofpacts)->port = str_to_u32(arg);
        break;

    case OFPUTIL_OFPAT10_ENQUEUE:
        parse_enqueue(arg, ofpacts);
        break;

    case OFPUTIL_NXAST_RESUBMIT:
        parse_resubmit(arg, ofpacts);
        break;

    case OFPUTIL_NXAST_SET_TUNNEL:
    case OFPUTIL_NXAST_SET_TUNNEL64:
        tunnel = ofpact_put_SET_TUNNEL(ofpacts);
        tunnel->ofpact.compat = code;
        tunnel->tun_id = str_to_u64(arg);
        break;

    case OFPUTIL_NXAST_WRITE_METADATA:
        parse_metadata(ofpacts, arg);
        break;

    case OFPUTIL_NXAST_SET_QUEUE:
        ofpact_put_SET_QUEUE(ofpacts)->queue_id = str_to_u32(arg);
        break;

    case OFPUTIL_NXAST_POP_QUEUE:
        ofpact_put_POP_QUEUE(ofpacts);
        break;

    case OFPUTIL_NXAST_REG_MOVE:
        nxm_parse_reg_move(ofpact_put_REG_MOVE(ofpacts), arg);
        break;

    case OFPUTIL_NXAST_REG_LOAD:
        nxm_parse_reg_load(ofpact_put_REG_LOAD(ofpacts), arg);
        break;

    case OFPUTIL_NXAST_NOTE:
        parse_note(arg, ofpacts);
        break;

    case OFPUTIL_NXAST_MULTIPATH:
        multipath_parse(ofpact_put_MULTIPATH(ofpacts), arg);
        break;

    case OFPUTIL_NXAST_AUTOPATH__DEPRECATED:
        autopath_parse(ofpact_put_AUTOPATH(ofpacts), arg);
        break;

    case OFPUTIL_NXAST_BUNDLE:
        bundle_parse(arg, ofpacts);
        break;

    case OFPUTIL_NXAST_BUNDLE_LOAD:
        bundle_parse_load(arg, ofpacts);
        break;

    case OFPUTIL_NXAST_RESUBMIT_TABLE:
    case OFPUTIL_NXAST_OUTPUT_REG:
    case OFPUTIL_NXAST_DEC_TTL_CNT_IDS:
        NOT_REACHED();

    case OFPUTIL_NXAST_LEARN:
        learn_parse(arg, flow, ofpacts);
        break;

    case OFPUTIL_NXAST_EXIT:
        ofpact_put_EXIT(ofpacts);
        break;

    case OFPUTIL_NXAST_DEC_TTL:
        parse_dec_ttl(ofpacts, arg);
        break;

    case OFPUTIL_NXAST_FIN_TIMEOUT:
        parse_fin_timeout(ofpacts, arg);
        break;

    case OFPUTIL_NXAST_CONTROLLER:
        parse_controller(ofpacts, arg);
        break;
    }
}
Exemplo n.º 3
0
int zmq::plain_server_t::receive_and_process_zap_reply ()
{
    int rc = 0;
    msg_t msg [7];  //  ZAP reply consists of 7 frames

    //  Initialize all reply frames
    for (int i = 0; i < 7; i++) {
        rc = msg [i].init ();
        errno_assert (rc == 0);
    }

    for (int i = 0; i < 7; i++) {
        rc = session->read_zap_msg (&msg [i]);
        if (rc == -1)
            break;
        if ((msg [i].flags () & msg_t::more) == (i < 6? 0: msg_t::more)) {
            //  Temporary support for security debugging
            puts ("PLAIN I: ZAP handler sent incomplete reply message");
            errno = EPROTO;
            rc = -1;
            break;
        }
    }

    if (rc != 0)
        goto error;

    //  Address delimiter frame
    if (msg [0].size () > 0) {
        //  Temporary support for security debugging
        puts ("PLAIN I: ZAP handler sent malformed reply message");
        errno = EPROTO;
        rc = -1;
        goto error;
    }

    //  Version frame
    if (msg [1].size () != 3 || memcmp (msg [1].data (), "1.0", 3)) {
        //  Temporary support for security debugging
        puts ("PLAIN I: ZAP handler sent bad version number");
        errno = EPROTO;
        rc = -1;
        goto error;
    }

    //  Request id frame
    if (msg [2].size () != 1 || memcmp (msg [2].data (), "1", 1)) {
        //  Temporary support for security debugging
        puts ("PLAIN I: ZAP handler sent bad request ID");
        rc = -1;
        errno = EPROTO;
        goto error;
    }

    //  Status code frame
    if (msg [3].size () != 3) {
        //  Temporary support for security debugging
        puts ("PLAIN I: ZAP handler rejected client authentication");
        errno = EACCES;
        rc = -1;
        goto error;
    }

    //  Save status code
    status_code.assign (static_cast <char *> (msg [3].data ()), 3);

    //  Save user id
    set_user_id (msg [5].data (), msg [5].size ());

    //  Process metadata frame
    rc = parse_metadata (static_cast <const unsigned char*> (msg [6].data ()),
                         msg [6].size (), true);

error:
    for (int i = 0; i < 7; i++) {
        const int rc2 = msg [i].close ();
        errno_assert (rc2 == 0);
    }

    return rc;
}
Exemplo n.º 4
0
int zmq::curve_server_t::process_initiate (msg_t *msg_)
{
    if (msg_->size () < 257) {
        //  Temporary support for security debugging
        puts ("CURVE I: client INITIATE is not correct size");
        errno = EPROTO;
        return -1;
    }

    const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
    if (memcmp (initiate, "\x08INITIATE", 9)) {
        //  Temporary support for security debugging
        puts ("CURVE I: client INITIATE has invalid command name");
        errno = EPROTO;
        return -1;
    }

    uint8_t cookie_nonce [crypto_secretbox_NONCEBYTES];
    uint8_t cookie_plaintext [crypto_secretbox_ZEROBYTES + 64];
    uint8_t cookie_box [crypto_secretbox_BOXZEROBYTES + 80];

    //  Open Box [C' + s'](t)
    memset (cookie_box, 0, crypto_secretbox_BOXZEROBYTES);
    memcpy (cookie_box + crypto_secretbox_BOXZEROBYTES, initiate + 25, 80);

    memcpy (cookie_nonce, "COOKIE--", 8);
    memcpy (cookie_nonce + 8, initiate + 9, 16);

    int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
                                    sizeof cookie_box,
                                    cookie_nonce, cookie_key);
    if (rc != 0) {
        //  Temporary support for security debugging
        puts ("CURVE I: cannot open client INITIATE cookie");
        errno = EPROTO;
        return -1;
    }

    //  Check cookie plain text is as expected [C' + s']
    if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES, cn_client, 32)
    ||  memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, cn_secret, 32)) {
        //  Temporary support for security debugging
        puts ("CURVE I: client INITIATE cookie is not valid");
        errno = EPROTO;
        return -1;
    }

    const size_t clen = (msg_->size () - 113) + crypto_box_BOXZEROBYTES;

    uint8_t initiate_nonce [crypto_box_NONCEBYTES];
    uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256];
    uint8_t initiate_box [crypto_box_BOXZEROBYTES + 144 + 256];

    //  Open Box [C + vouch + metadata](C'->S')
    memset (initiate_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (initiate_box + crypto_box_BOXZEROBYTES,
            initiate + 113, clen - crypto_box_BOXZEROBYTES);

    memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
    memcpy (initiate_nonce + 16, initiate + 105, 8);
    cn_peer_nonce = get_uint64(initiate + 105);

    rc = crypto_box_open (initiate_plaintext, initiate_box,
                          clen, initiate_nonce, cn_client, cn_secret);
    if (rc != 0) {
        //  Temporary support for security debugging
        puts ("CURVE I: cannot open client INITIATE");
        errno = EPROTO;
        return -1;
    }

    const uint8_t *client_key = initiate_plaintext + crypto_box_ZEROBYTES;

    uint8_t vouch_nonce [crypto_box_NONCEBYTES];
    uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t vouch_box [crypto_box_BOXZEROBYTES + 80];

    //  Open Box Box [C',S](C->S') and check contents
    memset (vouch_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (vouch_box + crypto_box_BOXZEROBYTES,
            initiate_plaintext + crypto_box_ZEROBYTES + 48, 80);

    memcpy (vouch_nonce, "VOUCH---", 8);
    memcpy (vouch_nonce + 8,
            initiate_plaintext + crypto_box_ZEROBYTES + 32, 16);

    rc = crypto_box_open (vouch_plaintext, vouch_box,
                          sizeof vouch_box,
                          vouch_nonce, client_key, cn_secret);
    if (rc != 0) {
        //  Temporary support for security debugging
        puts ("CURVE I: cannot open client INITIATE vouch");
        errno = EPROTO;
        return -1;
    }

    //  What we decrypted must be the client's short-term public key
    if (memcmp (vouch_plaintext + crypto_box_ZEROBYTES, cn_client, 32)) {
        //  Temporary support for security debugging
        puts ("CURVE I: invalid handshake from client (public key)");
        errno = EPROTO;
        return -1;
    }

    //  Precompute connection secret from client key
    rc = crypto_box_beforenm (cn_precom, cn_client, cn_secret);
    zmq_assert (rc == 0);

    //  Use ZAP protocol (RFC 27) to authenticate the user.
    rc = session->zap_connect ();
    if (rc == 0) {
        send_zap_request (client_key);
        rc = receive_and_process_zap_reply ();
        if (rc == 0)
            state = status_code == "200"
                ? send_ready
                : send_error;
        else
        if (errno == EAGAIN)
            state = expect_zap_reply;
        else
            return -1;
    }
    else
        state = send_ready;

    return parse_metadata (initiate_plaintext + crypto_box_ZEROBYTES + 128,
                           clen - crypto_box_ZEROBYTES - 128);
}
Exemplo n.º 5
0
Arquivo: fcserver.c Projeto: C3MA/fc_c
/** @fn fcserver_ret_t fcserver_process (fcserver_t* server, int clientSocket)
 * @brief Speak with the client
 *
 * @param[in]	server			structure, where the client should be put in
 * @param[in]	client			the connected client to talk to.
 * @return status 
 */
static fcserver_ret_t process_client(fcserver_t* server, fcclient_t* client)
{
	int n, offset = 0;
    int type=-1;
    int length = 0;
	int write_offset = 0;
	
	/* FIXME the server->tmpMem should probalby exists for each client
	 * (even if only one client, connected to the wall can generate the huge packets) */
	n = hwal_socket_tcp_read(client->clientsocket, 
							 (server->tmpMem + server->reading_offset), 
							 (server->tmpMemSize - server->reading_offset));
		
	/*FIXME try to check if client is still connected FCSERVER_RET_CLOSED */
		
	/* First check, if the Client has something to say */
	if (n == -1)
	{
		/* no new packet found on the network */
		return FCSERVER_RET_NOTHINGNEW;
	}
	else if (n == 0)
	{
		return FCSERVER_RET_CLOSED;
	}
	else if (n < HEADER_LENGTH)
	{
		DEBUG_PLINE("Error : Network read error");
		return FCSERVER_RET_IOERR;
	}
	offset = get_header(server->tmpMem, 0, &type, &length);
	if (offset == -1)
	{
		DEBUG_PLINE("Error : Could not analyze header");
		return FCSERVER_RET_IOERR;
	}
	
	/* Add the already extracted bytes to the new ones */
	n += server->reading_offset;
	
	DEBUG_PLINE("New Header typ: %d length of information: %d [fetched is %d byte from the network]",type,length, n);
	
	if (length > n)
	{
		server->reading_offset = n;
		DEBUG_PLINE("Update offset to %d", server->reading_offset);
	}
	else
	{
		/* reset the fragment detection for packets */
		server->reading_offset = 0;
		
		/* Decode the information */
		switch (type)
		{
			case SNIPTYPE_REQUEST:
			{
				char *color;
				int seqId;
				int meta_offset;
				int meta_length;
				int frames_per_second, width, heigth;
				char *generator_name;
				char *generator_version;
				
				offset = recv_request(server->tmpMem, offset, &color, &seqId, &meta_offset, &meta_length);
				if (offset == -1) {
					DEBUG_PLINE("recv_request Faild!");
				} else {
					DEBUG_PLINE("Parse Request, Color: %s, seqId: %d",color,seqId);
				}
				offset = parse_metadata(server->tmpMem,meta_offset,&frames_per_second, 
										&width, &heigth, &generator_name, &generator_version);
				if (offset == -1) {
					DEBUG_PLINE("parse Metadata Faild!");
					return -1;
				} else {
					DEBUG_PLINE("Metadata, fps: %d, width: %d, height: %d, gen._name: %s, gen._version: %s",
								frames_per_second,width,heigth,generator_name,generator_version);
				}
				
				/* allocate some memory for answering */
				uint8_t *output = hwal_malloc(BUFFERSIZE_OUTPUT); hwal_memset(output, 0, BUFFERSIZE_OUTPUT);
				uint8_t *buffer = hwal_malloc(BUFFERSIZE_SENDINGBUFFER); hwal_memset(output, 0, BUFFERSIZE_SENDINGBUFFER);
				
				/* Verify , if the client has the correct resolution */
				if (server->width == width && server->height == heigth)
				{
					client->clientstatus = FCCLIENT_STATUS_WAITING;
					/* Send the client an acknowledgement (ACK) */
					write_offset = send_ack(buffer, write_offset);
					DEBUG_PLINE("ACK Request send");
				}
				else
				{
					uint8_t buffer[BUFFERSIZE_SENDINGBUFFER];
					/* Inform the client with an error message */
					char descr[] = "Wrong Screen resolution";
					DEBUG_PLINE("Error while requesting: '%s'", descr);
					write_offset = send_error(buffer, write_offset, FCSERVER_ERR_RESOLUTION, descr);
				}
				
				/* send the corresponding message: Success or error */
				add_header(buffer, output, write_offset);
				hwal_socket_tcp_write(client->clientsocket, output, write_offset+HEADER_LENGTH);
				
				hwal_free(buffer);
				hwal_free(output);
				
				/* Free all resources needed for sending */
				hwal_free(color);
				hwal_free(generator_name);
				hwal_free(generator_version);
				break;
			}
			case SNIPTYPE_FRAME:
			{
				int x, y, red, green, blue;
				int frame_length;
				int frame_offset, frame_offset_start;
				int index;
				
				offset = recv_frame(server->tmpMem, offset, &frame_offset, &frame_length);
				if (offset == -1) {
					DEBUG_PLINE("recv_frame Faild!");
				} else {
					DEBUG_PLINE("Parse Frame, frame_length: %d",frame_length);
				}
				frame_offset_start = frame_offset;
				do {
					frame_offset = frame_parse_pixel(server->tmpMem,frame_offset, &red, &green, &blue, &x, &y);
					index = (((x * server->width) + y) * 3);
					server->imageBuffer[index + 0] = red;
					server->imageBuffer[index + 1] = green;
					server->imageBuffer[index + 2] = blue;				
				} while (frame_offset < (frame_offset_start+frame_length));
				
				if (server->onNewImage > 0)
				{
					server->onNewImage(server->imageBuffer, server->width, server->height);
				}
				break;
			}
			case SNIPTYPE_INFOREQUEST:
			{
				uint8_t *output = hwal_malloc(BUFFERSIZE_OUTPUT); hwal_memset(output, 0, BUFFERSIZE_OUTPUT);
				uint8_t *buffer = hwal_malloc(BUFFERSIZE_SENDINGBUFFER); hwal_memset(output, 0, BUFFERSIZE_SENDINGBUFFER);
				uint8_t *meta	= hwal_malloc(BUFFERSIZE_SENDINGBUFFER); hwal_memset(output, 0, BUFFERSIZE_SENDINGBUFFER);			
				int offset_meta = create_metadata(meta, 0, FCSERVER_DEFAULT_FPS, 
											  server->width, server->height, 
											  FCSERVER_DEFAULT_NAME,
											  FCSERVER_DEFAULT_VERSION);
				write_offset = send_infoanswer(buffer, write_offset, meta, offset_meta);
				add_header(buffer, output, write_offset);
				hwal_socket_tcp_write(client->clientsocket, output, write_offset+HEADER_LENGTH);
				DEBUG_PLINE("Answered %dx%d pixel (%d fps) for '%s' on version '%s'",server->width, server->height, FCSERVER_DEFAULT_FPS,
							FCSERVER_DEFAULT_NAME,
							FCSERVER_DEFAULT_VERSION);
				hwal_free(meta);
				hwal_free(buffer);
				hwal_free(output);
			}
				break;
			case SNIPTYPE_PING:
			case SNIPTYPE_PONG:
			case SNIPTYPE_ERROR:
			case SNIPTYPE_START:
			case SNIPTYPE_ACK:
			case SNIPTYPE_NACK:
			case SNIPTYPE_TIMEOUT:
			case SNIPTYPE_ABORT:
			case SNIPTYPE_EOS:
			case SNIPTYPE_INFOANSWER:
			default:
				DEBUG_PLINE("%d is not implemented",type);
				break;
		}
	}
	
	return FCSERVER_RET_OK;
}
Exemplo n.º 6
0
int zmq::null_mechanism_t::receive_and_process_zap_reply ()
{
    int rc = 0;
    msg_t msg [7];  //  ZAP reply consists of 7 frames

    //  Initialize all reply frames
    for (int i = 0; i < 7; i++) {
        rc = msg [i].init ();
        errno_assert (rc == 0);
    }

    for (int i = 0; i < 7; i++) {
        rc = session->read_zap_msg (&msg [i]);
        if (rc == -1)
            break;
        if ((msg [i].flags () & msg_t::more) == (i < 6? 0: msg_t::more)) {
            errno = EPROTO;
            rc = -1;
            break;
        }
    }

    if (rc != 0)
        goto error;

    //  Address delimiter frame
    if (msg [0].size () > 0) {
        rc = -1;
        errno = EPROTO;
        goto error;
    }

    //  Version frame
    if (msg [1].size () != 3 || memcmp (msg [1].data (), "1.0", 3)) {
        rc = -1;
        errno = EPROTO;
        goto error;
    }

    //  Request id frame
    if (msg [2].size () != 1 || memcmp (msg [2].data (), "1", 1)) {
        rc = -1;
        errno = EPROTO;
        goto error;
    }

    //  Status code frame
    if (msg [3].size () != 3 || memcmp (msg [3].data (), "200", 3)) {
        rc = -1;
        errno = EACCES;
        goto error;
    }

    //  Save user id
    set_user_id (msg [5].data (), msg [5].size ());

    //  Process metadata frame
    rc = parse_metadata (static_cast <const unsigned char*> (msg [6].data ()),
                         msg [6].size ());

error:
    for (int i = 0; i < 7; i++) {
        const int rc2 = msg [i].close ();
        errno_assert (rc2 == 0);
    }

    return rc;
}
Exemplo n.º 7
0
/*****************************************************************************
METHOD:  cfmask

PURPOSE:  The main routine for fmask written in C

RETURN VALUE: Type = int
    Value           Description
    -----           -----------
    ERROR           An error occurred during processing of cfmask
    SUCCESS         Processing was successful
*****************************************************************************/
int
main (int argc, char *argv[])
{
    char *FUNC_NAME = "main";
    char *ext = NULL;            /* pointer to the file extension */
    char *xml_name = NULL;       /* input XML filename */
    char envi_file[MAX_STR_LEN]; /* output ENVI file name */
    char temp_file[MAX_STR_LEN]; /* temp file name */

    int status;
    int band_index;

    bool verbose;            /* verbose flag for printing messages */
    bool use_cirrus;         /* should we use Cirrus during determination? */
    bool use_thermal;        /* should we use Thermal during determination? */

    Input_t *input = NULL;    /* input data and meta data */
    Output_t *output = NULL;  /* output structure and metadata */
    Espa_internal_meta_t xml_metadata; /* XML metadata structure */
    Envi_header_t envi_hdr;            /* output ENVI header information */

    unsigned char *pixel_mask = NULL; /* pixel mask */
    unsigned char *conf_mask = NULL;  /* confidence mask */

    float clear_ptm;          /* percent of clear-sky pixels */
    float t_templ = 0.0;      /* percentile of low background temperature */
    float t_temph = 0.0;      /* percentile of high background temperature */

    int cldpix = 2;           /* Default buffer for cloud pixel dilate */
    int sdpix = 2;            /* Default buffer for shadow pixel dilate */
    float cloud_prob;         /* Default cloud probability */
    float sun_azi_temp = 0.0; /* Keep the original sun azimuth angle */

    int pixel_count;
    int pixel_index;

    time_t now;
    time(&now);

    /* Read the command-line arguments, including the name of the input
       Landsat TOA reflectance product and the DEM */
    status = get_args(argc, argv, &xml_name, &cloud_prob, &cldpix,
                      &sdpix, &use_cirrus, &use_thermal, &verbose);
    if (status != SUCCESS)
    {
        RETURN_ERROR("calling get_args", FUNC_NAME, EXIT_FAILURE);
    }

    printf("CFmask start_time=%s\n", ctime(&now));

    /* Validate the input metadata file */
    if (validate_xml_file(xml_name) != SUCCESS)
    {
        RETURN_ERROR("XML validation error", FUNC_NAME, EXIT_FAILURE);
    }

    /* Initialize the metadata structure */
    init_metadata_struct(&xml_metadata);

    /* Parse the metadata file into our internal metadata structure; also
       allocates space as needed for various pointers in the global and band
       metadata */
    if (parse_metadata(xml_name, &xml_metadata) != SUCCESS)
    {
        RETURN_ERROR("XML parsing error", FUNC_NAME, EXIT_FAILURE);
    }

    /* Open input file, read metadata, and set up buffers */
    input = OpenInput(&xml_metadata, use_thermal);
    if (input == NULL)
    {
        RETURN_ERROR("opening input data specified in input XML",
                     FUNC_NAME, EXIT_FAILURE);
    }

    if (verbose)
    {
        /* Print some info to show how the input metadata works */
        printf("Number of input TOA bands: %d\n", input->num_toa_bands);
        printf("Number of input thermal bands: %d\n", 1);
        printf("Number of input TOA lines: %d\n", input->size.l);
        printf("Number of input TOA samples: %d\n", input->size.s);
        printf("Fill value is %d\n", input->meta.fill);
        for (band_index = 0; band_index < MAX_BAND_COUNT; band_index++)
        {
            printf("Band %d-->\n", band_index);
            if (input->satellite != IS_LANDSAT_8)
            {
                /* Landsat 8 doesn't have saturation issues */
                printf("  band satu_value_ref: %d\n",
                       input->meta.satu_value_ref[band_index]);
                printf("  band satu_value_max: %d\n",
                       input->meta.satu_value_max[band_index]);
            }
            printf("  band gain: %f, band bias: %f\n",
                   input->meta.gain[band_index], input->meta.bias[band_index]);
        }

        printf("SUN AZIMUTH is %f\n", input->meta.sun_az);
        printf("SUN ZENITH is %f\n", input->meta.sun_zen);
    }

    /* If the scene is an ascending polar scene (flipped upside down), then
       the solar azimuth needs to be adjusted by 180 degrees.  The scene in
       this case would be north down and the solar azimuth is based on north
       being up clock-wise direction. Flip the south to be up will not change
       the actual sun location, with the below relations, the solar azimuth
       angle will need add in 180.0 for correct sun location */
    if (input->meta.ul_corner.lat < input->meta.lr_corner.lat)
    {
        /* Keep the original solar azimuth angle */
        sun_azi_temp = input->meta.sun_az;
        input->meta.sun_az += 180.0;
        if (input->meta.sun_az > 360.0)
        {
            input->meta.sun_az -= 360.0;
        }
        if (verbose)
        {
            printf("Polar or ascending scene."
                    "  Readjusting solar azimuth by 180 degrees.\n"
                    "  New value: %f degrees\n", input->meta.sun_az);
        }
    }

    pixel_count = input->size.l * input->size.s;

    /* Dynamic allocate the 2d mask memory */
    pixel_mask = calloc(pixel_count, sizeof(unsigned char));
    if (pixel_mask == NULL)
    {
        RETURN_ERROR("Allocating pixel mask memory", FUNC_NAME, EXIT_FAILURE);
    }

    conf_mask = calloc(pixel_count, sizeof(unsigned char));
    if (conf_mask == NULL)
    {
        RETURN_ERROR("Allocating confidence mask memory",
                     FUNC_NAME, EXIT_FAILURE);
    }

    /* Initialize the mask to clear data */
    for (pixel_index = 0; pixel_index < pixel_count; pixel_index++)
    {
        pixel_mask[pixel_index] = CF_NO_BITS;
        conf_mask[pixel_index] = CLOUD_CONFIDENCE_NONE;
    }

    /* Build the potential cloud, shadow, snow, water mask */
    status = potential_cloud_shadow_snow_mask(input, cloud_prob, &clear_ptm,
                                              &t_templ, &t_temph, pixel_mask,
                                              conf_mask, use_cirrus,
                                              use_thermal, verbose);
    if (status != SUCCESS)
    {
        RETURN_ERROR("processing potential_cloud_shadow_snow_mask",
                     FUNC_NAME, EXIT_FAILURE);
    }
    printf("Potential Cloud Shadow: Done\n");

    /* Build the final cloud shadow based on geometry matching and
       combine the final cloud, shadow, snow, water masks into fmask
       the pixel_mask is a bit mask as input and a value mask as output */
    int data_count = 0;
    status = object_cloud_shadow_match(input, clear_ptm, t_templ, t_temph,
                                       cldpix, sdpix, pixel_mask, &data_count,
                                       use_thermal, verbose);
    if (status != SUCCESS)
    {
        RETURN_ERROR("processing object_cloud_and_shadow_match",
                     FUNC_NAME, EXIT_FAILURE);
    }
    printf("Object Cloud Shadow Matching: Done\n");

    /* Convert the pixel_mask to a value mask
       Also retrieve and report statistics */
    float clear_percent = 0; /* Percent of clear pixels in the image data */
    float cloud_percent = 0; /* Percent of cloud pixels in the image data */
    float cloud_shadow_percent = 0; /* Percent of cloud shadow pixels in the
                                       image data */
    float water_percent = 0; /* Percent of water pixels in the image data */
    float snow_percent = 0;  /* Percent of snow pixels in the image data */
    convert_and_generate_statistics(verbose, pixel_mask,
                                    input->size.l * input->size.s,
                                    data_count, &clear_percent,
                                    &cloud_percent, &cloud_shadow_percent,
                                    &water_percent, &snow_percent);
    printf("Statistics Generation: Done\n");

    /* Reassign solar azimuth angle for output purpose if south up north
       down scene is involved */
    if (input->meta.ul_corner.lat < input->meta.lr_corner.lat)
    {
        input->meta.sun_az = sun_azi_temp;
    }

    /* Open the output file */
    output = OpenOutputCFmask(&xml_metadata, input, clear_percent,
                              cloud_percent, cloud_shadow_percent,
                              water_percent, snow_percent);
    if (output == NULL)
    {
        RETURN_ERROR("Opening output file", FUNC_NAME, EXIT_FAILURE);
    }

    if (!PutOutput(output, pixel_mask))
    {
        RETURN_ERROR("Writing output fmask files", FUNC_NAME, EXIT_FAILURE);
    }

    /* Close the output file */
    if (!CloseOutput(output))
    {
        RETURN_ERROR("closing output file", FUNC_NAME, EXIT_FAILURE);
    }

    /* Create the ENVI header file this band */
    if (create_envi_struct(&output->metadata.band[0], &xml_metadata.global,
                           &envi_hdr) != SUCCESS)
    {
        RETURN_ERROR("Creating ENVI header structure.", FUNC_NAME,
                     EXIT_FAILURE);
    }

    /* Write the ENVI header */
    snprintf(temp_file, sizeof(temp_file), "%s",
             output->metadata.band[0].file_name);
    ext = strrchr(temp_file, '.');
    if (ext == NULL)
    {
        RETURN_ERROR("error in ENVI header filename", FUNC_NAME, EXIT_FAILURE);
    }

    ext[0] = '\0';
    snprintf(envi_file, sizeof(envi_file), "%s.hdr", temp_file);
    if (write_envi_hdr(envi_file, &envi_hdr) != SUCCESS)
    {
        RETURN_ERROR("Writing ENVI header file.", FUNC_NAME, EXIT_FAILURE);
    }

    /* Append the cfmask band to the XML file */
    if (append_metadata(output->nband, output->metadata.band, xml_name)
        != SUCCESS)
    {
        RETURN_ERROR("Appending spectral index bands to XML file.",
                     FUNC_NAME, EXIT_FAILURE);
    }

    /* Free the structure */
    if (!FreeOutput(output))
    {
        RETURN_ERROR("freeing output file structure", FUNC_NAME, EXIT_FAILURE);
    }

    output = OpenOutputConfidence(&xml_metadata, input);
    if (output == NULL)
    {
        RETURN_ERROR("Opening output file", FUNC_NAME, EXIT_FAILURE);
    }

    if (!PutOutput(output, conf_mask))
    {
        RETURN_ERROR("Writing output fmask files", FUNC_NAME, EXIT_FAILURE);
    }

    /* Close the output file */
    if (!CloseOutput(output))
    {
        RETURN_ERROR("closing output file", FUNC_NAME, EXIT_FAILURE);
    }

    /* Create the ENVI header file this band */
    if (create_envi_struct(&output->metadata.band[0], &xml_metadata.global,
                           &envi_hdr) != SUCCESS)
    {
        RETURN_ERROR("Creating ENVI header structure.", FUNC_NAME,
                     EXIT_FAILURE);
    }

    /* Write the ENVI header */
    snprintf(temp_file, sizeof(temp_file), "%s",
             output->metadata.band[0].file_name);
    ext = strrchr(temp_file, '.');
    if (ext == NULL)
    {
        RETURN_ERROR("error in ENVI header filename", FUNC_NAME, EXIT_FAILURE);
    }

    ext[0] = '\0';
    snprintf(envi_file, sizeof(envi_file), "%s.hdr", temp_file);
    if (write_envi_hdr(envi_file, &envi_hdr) != SUCCESS)
    {
        RETURN_ERROR("Writing ENVI header file.", FUNC_NAME, EXIT_FAILURE);
    }

    /* Append the cfmask band to the XML file */
    if (append_metadata(output->nband, output->metadata.band,
                        xml_name) != SUCCESS)
    {
        RETURN_ERROR("Appending spectral index bands to XML file.",
                     FUNC_NAME, EXIT_FAILURE);
    }

    /* Free the structure */
    if (!FreeOutput(output))
    {
        RETURN_ERROR("freeing output file structure", FUNC_NAME, EXIT_FAILURE);
    }

    /* Free the metadata structure */
    free_metadata(&xml_metadata);

    /* Free the pixel mask */
    free(pixel_mask);
    pixel_mask = NULL;
    free(conf_mask);
    conf_mask = NULL;

    /* Close the input file and free the structure */
    CloseInput(input);
    FreeInput(input);

    free(xml_name);
    xml_name = NULL;

    printf("Processing complete.\n");
    time(&now);
    printf("CFmask end_time=%s\n", ctime(&now));

    return SUCCESS;
}
/*****************************************************************************
  NAME:  get_args

  PURPOSE:  Gets the command line arguments and validates that the required
            arguments were specified.

  RETURN VALUE:  Type = int
      Value    Description
      -------  ---------------------------------------------------------------
      ERROR    Error getting the command line arguments or a command line
               argument and associated value were not specified.
      SUCCESS  No errors encountered.
*****************************************************************************/
int
get_args
(
    int argc,                    /* I: number of cmd-line args */
    char *argv[],                /* I: string of cmd-line args */
    char **xml_filename,         /* O: input XML filename */
    Espa_internal_meta_t *xml_metadata, /* O: input metadata */
    bool *use_zeven_thorne_flag, /* O: use zeven thorne */
    bool *use_toa_flag,          /* O: process using TOA */
    bool *include_tests_flag,    /* O: include raw DSWE with output */
    bool *include_ps_flag,       /* O: include percent slope with output */
    bool *include_hs_flag,       /* O: include hillshade with output */
    float *wigt,                 /* O: tolerance value */
    float *awgt,                 /* O: tolerance value */
    float *pswt_1_mndwi,         /* O: tolerance value */
    int *pswt_1_nir,             /* O: tolerance value */
    int *pswt_1_swir1,           /* O: tolerance value */
    float *pswt_1_ndvi,          /* O: tolerance value */
    float *pswt_2_mndwi,         /* O: tolerance value */
    int *pswt_2_blue,            /* O: tolerance value */
    int *pswt_2_nir,             /* O: tolerance value */
    int *pswt_2_swir1,           /* O: tolerance value */
    int *pswt_2_swir2,           /* O: tolerance value */
    float *percent_slope_high,   /* O: slope tolerance for high confidence 
                                       water */
    float *percent_slope_moderate, /* O: slope tolerance for moderate 
                                       confidence water */
    float *percent_slope_wetland, /* O: slope tolerance for potential wetland */
    float *percent_slope_low,    /* O: slope tolerance for low confidence 
                                       water or wetland */
    int *hillshade,              /* O: hillshade tolerance value */ 
    bool *verbose_flag           /* O: verbose messaging */
)
{
    int c;
    int option_index;
    char msg[256];
    int tmp_zeven_thorne_flag = false;
    int tmp_toa_flag = false;
    int tmp_verbose_flag = false;
    int tmp_include_tests_flag = false;
    int tmp_include_ps_flag = false;
    int tmp_include_hs_flag = false;

    struct option long_options[] = {
        /* These options set a flag */
        {"use_zeven_thorne", no_argument, &tmp_zeven_thorne_flag, true},
        {"use_toa", no_argument, &tmp_toa_flag, true},

        {"include_tests", no_argument, &tmp_include_tests_flag, true},
        {"include_ps", no_argument, &tmp_include_ps_flag, true},
        {"include_hs", no_argument, &tmp_include_hs_flag, true},

        /* These options provide values */
        {"xml", required_argument, 0, 'x'},

        {"wigt", required_argument, 0, 'w'},
        {"awgt", required_argument, 0, 'a'},

        {"pswt_1_mndwi", required_argument, 0, 'z'},
        {"pswt_1_nir", required_argument, 0, 'n'},
        {"pswt_1_swir1", required_argument, 0, 'r'},
        {"pswt_1_ndvi", required_argument, 0, 'y'},

        {"pswt_2_mndwi", required_argument, 0, 'q'},
        {"pswt_2_blue", required_argument, 0, 'b'},
        {"pswt_2_nir", required_argument, 0, 'i'},
        {"pswt_2_swir1", required_argument, 0, '1'},
        {"pswt_2_swir2", required_argument, 0, '2'},

        {"percent_slope_high", required_argument, 0, 'g'},
        {"percent_slope_moderate", required_argument, 0, 'm'},
        {"percent_slope_wetland", required_argument, 0, 'd'},
        {"percent_slope_low", required_argument, 0, 'l'},
        {"hillshade", required_argument, 0, 's'},

        /* Special options */
        {"verbose", no_argument, &tmp_verbose_flag, true},
        {"version", no_argument, 0, 'v'},

        /* The help option */
        {"help", no_argument, 0, 'h'},

        /* The option termination set */
        {0, 0, 0, 0}
    };

    if (argc == 1)
    {
        ERROR_MESSAGE ("Missing required command line arguments\n\n",
                       MODULE_NAME);

        usage ();
        return ERROR;
    }

    /* Initialize to the not set values */
    *wigt = NOT_SET;
    *awgt = NOT_SET;
    *pswt_1_mndwi = NOT_SET;
    *pswt_1_nir = NOT_SET;
    *pswt_1_swir1 = NOT_SET;
    *pswt_1_ndvi = NOT_SET;
    *pswt_2_mndwi = NOT_SET;
    *pswt_2_blue = NOT_SET;
    *pswt_2_nir = NOT_SET;
    *pswt_2_swir1 = NOT_SET;
    *pswt_2_swir2 = NOT_SET;
    *percent_slope_high = NOT_SET;
    *percent_slope_moderate = NOT_SET;
    *percent_slope_wetland = NOT_SET;
    *percent_slope_low = NOT_SET;
    *hillshade = NOT_SET;

    /* loop through all the cmd-line options */
    opterr = 0; /* turn off getopt_long error msgs as we'll print our own */
    while (1)
    {
        c = getopt_long (argc, argv, "", long_options, &option_index);
        if (c == -1)
        {
            /* out of cmd-line options */
            break;
        }

        switch (c)
        {
        case 0:
            /* If this option set a flag, do nothing else now. */
            if (long_options[option_index].flag != 0)
                break;

        case 'h':
            usage ();
            exit (SUCCESS);
            break;

        case 'v':
            version ();
            exit (SUCCESS);
            break;

        case 'x':
            *xml_filename = strdup (optarg);
            break;

        case 'w':
            *wigt = atof (optarg);
            break;
        case 'a':
            *awgt = atof (optarg);
            break;

        case 'z':
            *pswt_1_mndwi = atof (optarg);
            break;
        case 'n':
            *pswt_1_nir = atof (optarg);
            break;
        case 'r':
            *pswt_1_swir1 = atoi (optarg);
            break;
        case 'y':
            *pswt_1_ndvi = atof (optarg);
            break;

        case 'q':
            *pswt_2_mndwi = atof (optarg);
            break;
        case 'b':
            *pswt_2_blue = atoi (optarg);
            break;
        case 'i':
            *pswt_2_nir = atoi (optarg);
            break;
        case '1':
            *pswt_2_swir1 = atoi (optarg);
            break;
        case '2':
            *pswt_2_swir2 = atoi (optarg);
            break;

        case 'g':
            *percent_slope_high = atof (optarg);
            break;
        case 'm':
            *percent_slope_moderate = atof (optarg);
            break;
        case 'd':
            *percent_slope_wetland = atof (optarg);
            break;
        case 'l':
            *percent_slope_low = atof (optarg);
            break;

        case 's':
            *hillshade = atoi (optarg);
            break;

        case '?':
        default:
            snprintf (msg, sizeof (msg),
                      "Unknown option %s\n\n", argv[optind - 1]);
            ERROR_MESSAGE (msg, MODULE_NAME);
            usage ();
            return ERROR;
            break;
        }
    }

    /* Grab the boolean command line options */
    if (tmp_zeven_thorne_flag)
        *use_zeven_thorne_flag = true;
    else
        *use_zeven_thorne_flag = false;

    if (tmp_toa_flag)
        *use_toa_flag = true;
    else
        *use_toa_flag = false;

    if (tmp_include_tests_flag)
        *include_tests_flag = true;
    else
        *include_tests_flag = false;

    if (tmp_include_ps_flag)
        *include_ps_flag = true;
    else
        *include_ps_flag = false;

    if (tmp_include_hs_flag)
        *include_hs_flag = true;
    else
        *include_hs_flag = false;

    if (tmp_verbose_flag)
        *verbose_flag = true;
    else
        *verbose_flag = false;

    /* Make sure the XML was specified */
    if (*xml_filename == NULL)
    {
        ERROR_MESSAGE ("XML input file is a required command line"
                       " argument\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    /* Validate the input XML metadata file */
    if (validate_xml_file (*xml_filename) != SUCCESS)
    {
        /* Error messages already written */
        return ERROR;
    }

    /* Initialize the metadata structure */
    init_metadata_struct (xml_metadata);

    /* Parse the metadata file into our internal metadata structure; also
       allocates space as needed for various pointers in the global and band
       metadata */
    if (parse_metadata (*xml_filename, xml_metadata) != SUCCESS)
    {
        /* Error messages already written */
        return ERROR;
    }

    /* Assign the default values if not provided on the command line */
    if (strcmp(xml_metadata->global.satellite, "LANDSAT_8") == 0)
    {
        if (*wigt == NOT_SET)
            *wigt = wigt_l8_default;

        if (*awgt == NOT_SET)
            *awgt = awgt_l8_default;

        if (*pswt_1_mndwi == NOT_SET)
            *pswt_1_mndwi = pswt_1_mndwi_l8_default;

        if (*pswt_1_nir == NOT_SET)
            *pswt_1_nir = pswt_1_nir_l8_default;

        if (*pswt_1_swir1 == NOT_SET)
            *pswt_1_swir1 = pswt_1_swir1_l8_default;

        if (*pswt_1_ndvi == NOT_SET)
            *pswt_1_ndvi = pswt_1_ndvi_l8_default;

        if (*pswt_2_mndwi == NOT_SET)
            *pswt_2_mndwi = pswt_2_mndwi_l8_default;

        if (*pswt_2_blue == NOT_SET)
            *pswt_2_blue = pswt_2_blue_l8_default;

        if (*pswt_2_nir == NOT_SET)
            *pswt_2_nir = pswt_2_nir_l8_default;

        if (*pswt_2_swir1 == NOT_SET)
            *pswt_2_swir1 = pswt_2_swir1_l8_default;

        if (*pswt_2_swir2 == NOT_SET)
            *pswt_2_swir2 = pswt_2_swir2_l8_default;
    }
    else
    {
        if (*wigt == NOT_SET)
            *wigt = wigt_l47_default;

        if (*awgt == NOT_SET)
            *awgt = awgt_l47_default;

        if (*pswt_1_mndwi == NOT_SET)
            *pswt_1_mndwi = pswt_1_mndwi_l47_default;

        if (*pswt_1_nir == NOT_SET)
            *pswt_1_nir = pswt_1_nir_l47_default;

        if (*pswt_1_swir1 == NOT_SET)
            *pswt_1_swir1 = pswt_1_swir1_l47_default;

        if (*pswt_1_ndvi == NOT_SET)
            *pswt_1_ndvi = pswt_1_ndvi_l47_default;

        if (*pswt_2_mndwi == NOT_SET)
            *pswt_2_mndwi = pswt_2_mndwi_l47_default;

        if (*pswt_2_blue == NOT_SET)
            *pswt_2_blue = pswt_2_blue_l47_default;

        if (*pswt_2_nir == NOT_SET)
            *pswt_2_nir = pswt_2_nir_l47_default;

        if (*pswt_2_swir1 == NOT_SET)
            *pswt_2_swir1 = pswt_2_swir1_l47_default;

        if (*pswt_2_swir2 == NOT_SET)
            *pswt_2_swir2 = pswt_2_swir2_l47_default;
    }

    if (*percent_slope_high == NOT_SET)
        *percent_slope_high = percent_slope_high_default;
    if (*percent_slope_moderate == NOT_SET)
        *percent_slope_moderate = percent_slope_moderate_default;
    if (*percent_slope_wetland == NOT_SET)
        *percent_slope_wetland = percent_slope_wetland_default;
    if (*percent_slope_low == NOT_SET)
        *percent_slope_low = percent_slope_low_default;

    if (*hillshade == NOT_SET)
        *hillshade = hillshade_default;


    /* ---------- Validate the parameters ---------- */
    if ((*wigt < 0.0) || (*wigt > 2.0))
    {
        ERROR_MESSAGE ("WIGT is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if ((*awgt < -2.0) || (*awgt > 2.0))
    {
        ERROR_MESSAGE ("AWGT is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if ((*pswt_1_mndwi < -2.0) || (*pswt_1_mndwi > 2.0))
    {
        ERROR_MESSAGE ("PSWT_1_MNDWI is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if (*pswt_1_nir < 0)
    {
        ERROR_MESSAGE ("PSWT_1_NIR is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if (*pswt_1_swir1 < 0)
    {
        ERROR_MESSAGE ("PSWT_1_SWIR1 is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if ((*pswt_1_ndvi < 0.0) || (*pswt_1_ndvi > 2.0))
    {
        ERROR_MESSAGE ("PSWT_1_NDVI is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }


    if ((*pswt_2_mndwi < -2.0) || (*pswt_2_mndwi > 2.0))
    {
        ERROR_MESSAGE ("PSWT_2_MNDWI is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if (*pswt_2_blue < 0)
    {
        ERROR_MESSAGE ("PSWT_2_BLUE is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if (*pswt_2_nir < 0)
    {
        ERROR_MESSAGE ("PSWT_2_NIR is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if (*pswt_2_swir1 < 0)
    {
        ERROR_MESSAGE ("PSWT_2_SWIR1 is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if (*pswt_2_swir2 < 0)
    {
        ERROR_MESSAGE ("PSWT_2_SWIR2 is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if ((*percent_slope_high < 0.0) || (*percent_slope_high > 100.0))
    {
        ERROR_MESSAGE ("Percent Slope high is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if ((*percent_slope_moderate < 0.0) || (*percent_slope_moderate > 100.0))
    {
        ERROR_MESSAGE ("Percent Slope moderate is out of range\n\n", 
            MODULE_NAME);

        usage ();
        return ERROR;
    }

    if ((*percent_slope_wetland < 0.0) || (*percent_slope_wetland > 100.0))
    {
        ERROR_MESSAGE ("Percent Slope wetland is out of range\n\n", 
            MODULE_NAME);

        usage ();
        return ERROR;
    }

    if ((*percent_slope_low < 0.0) || (*percent_slope_low > 100.0))
    {
        ERROR_MESSAGE ("Percent Slope low is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    if ((*hillshade < 0) || (*hillshade > 255))
    {
        ERROR_MESSAGE ("Hillshade threshold is out of range\n\n", MODULE_NAME);

        usage ();
        return ERROR;
    }

    return SUCCESS;
}
Exemplo n.º 9
0
/******************************************************************************
METHOD:  lst

PURPOSE:  The main routine for scene based LST (Land Surface Temperature).

RETURN VALUE:
Type = int
Value           Description
-----           -----------
ERROR           An error occurred during processing of the scene_based_lst
SUCCESS         Processing was successful

PROJECT:  Land Satellites Data System Science Research and Development (LSRD)
          at the USGS EROS
******************************************************************************/
int
main (int argc, char *argv[])
{
    char FUNC_NAME[] = "main";

    Espa_internal_meta_t xml_metadata;  /* XML metadata structure */

    char msg_str[MAX_STR_LEN];
    char xml_filename[PATH_MAX];        /* input XML filename */
    char dem_filename[PATH_MAX];        /* input DEM filename */
    char emissivity_filename[PATH_MAX]; /* input Emissivity filename */
    char command[PATH_MAX];

    Input_t *input = NULL;          /* input data and meta data */
    //    Output_t *output = NULL; /* output structure and metadata */

    bool use_tape6;             /* Use the tape6 output */
    bool verbose;               /* verbose flag for printing messages */
    bool debug;                 /* debug flag for debug output */

    int modtran_run;

    double alb = 0.1;
    double **modtran_results = NULL;

    char *tmp_env = NULL;

    REANALYSIS_POINTS points;

    time_t now;

    /* Display the starting time of the application */
    time (&now);
    snprintf (msg_str, sizeof(msg_str),
              "LST start_time [%s]", ctime (&now));
    LOG_MESSAGE (msg_str, FUNC_NAME);

    /* Read the command-line arguments, including the name of the input
       Landsat TOA reflectance product and the DEM */
    if (get_args (argc, argv, xml_filename, dem_filename, emissivity_filename,
                  &use_tape6, &verbose, &debug) != SUCCESS)
    {
        RETURN_ERROR ("calling get_args", FUNC_NAME, EXIT_FAILURE);
    }

    /* Verify the existence of required environment variables */
    /* Grab the environment path to the LST_DATA_DIR */
    tmp_env = getenv ("LST_DATA_DIR");
    if (tmp_env == NULL)
    {
        RETURN_ERROR ("LST_DATA_DIR environment variable is not set",
                      FUNC_NAME, EXIT_FAILURE);
    }

    /* Validate the input metadata file */
    if (validate_xml_file (xml_filename) != SUCCESS)
    {
        /* Error messages already written */
        return EXIT_FAILURE;
    }

    /* Initialize the metadata structure */
    init_metadata_struct (&xml_metadata);

    /* Parse the metadata file into our internal metadata structure; also
       allocates space as needed for various pointers in the global and band
       metadata */
    if (parse_metadata (xml_filename, &xml_metadata) != SUCCESS)
    {
        /* Error messages already written */
        return EXIT_FAILURE;
    }

    /* Open input file, read metadata, and set up buffers */
    input = OpenInput (&xml_metadata);
    if (input == NULL)
    {
        RETURN_ERROR ("opening input files", FUNC_NAME, EXIT_FAILURE);
    }

    if (verbose)
    {
        /* Print some info to show how the input metadata works */
        printf ("Satellite: %d\n", input->meta.satellite);
        printf ("Instrument: %d\n", input->meta.instrument);

        printf ("Number of input lines: %d\n", input->thermal.size.l);
        printf ("Number of input samples: %d\n", input->thermal.size.s);

        printf ("Fill value is %d\n", input->thermal.fill_value);

        printf ("Thermal Band -->\n");
        printf ("  therm_gain: %f\n  therm_bias: %f\n",
                input->thermal.rad_gain, input->thermal.rad_bias);

        printf ("Year, Month, Day, Hour, Minute, Second:"
                " %d, %d, %d, %d, %d, %f\n",
                input->meta.acq_date.year, input->meta.acq_date.month,
                input->meta.acq_date.day, input->meta.acq_date.hour,
                input->meta.acq_date.minute, input->meta.acq_date.second);
        printf ("ACQUISITION_DATE.DOY is %d\n",
                input->meta.acq_date.doy);

        printf ("UL_MAP_CORNER: %f, %f\n", input->meta.ul_map_corner.x,
                input->meta.ul_map_corner.y);
        printf ("LR_MAP_CORNER: %f, %f\n", input->meta.lr_map_corner.x,
                input->meta.lr_map_corner.y);
        printf ("UL_GEO_CORNER: %f, %f\n",
                input->meta.ul_geo_corner.lat, input->meta.ul_geo_corner.lon);
        printf ("LR_GEO_CORNER: %f, %f\n",
                input->meta.lr_geo_corner.lat, input->meta.lr_geo_corner.lon);
    }

    /* Build the points that will be used */
    if (build_points (input, &points) != SUCCESS)
    {
        RETURN_ERROR ("Building POINTS input\n", FUNC_NAME, EXIT_FAILURE);
    }

    if (verbose)
    {
        printf ("Number of Points: %d\n", points.num_points);
    }

    /* Call build_modtran_input to generate the tape5 file input and
       the MODTRAN commands for each point and height */
    if (build_modtran_input (input, &points, verbose, debug)
        != SUCCESS)
    {
        RETURN_ERROR ("Building MODTRAN input\n", FUNC_NAME, EXIT_FAILURE);
    }

    /* Perform MODTRAN runs by calling each command */
    for (modtran_run = 0; modtran_run < points.num_modtran_runs; modtran_run++)
    {
        snprintf (msg_str, sizeof(msg_str),
                  "Executing MODTRAN [%s]",
                   points.modtran_runs[modtran_run].command);
        LOG_MESSAGE (msg_str, FUNC_NAME);

#if RUN_MODTRAN
        if (system (points.modtran_runs[modtran_run].command) != SUCCESS)
        {
            RETURN_ERROR ("Error executing MODTRAN", FUNC_NAME,
                          EXIT_FAILURE);
        }
#endif
    }

    /* PARSING MODTRAN RESULTS:
       for each case in caseList (for each modtran run),
       parse wavelength and total radiance from tape6 file into parsed */
    for (modtran_run = 0; modtran_run < points.num_modtran_runs; modtran_run++)
    {
        if (use_tape6)
        {
            /* Use modtran generated tape6 output */
            snprintf (command, sizeof (command),
                      "lst_extract_modtran_results.py"
                      " --tape6"
                      " --input-path %s"
                      " --output-path %s",
                      points.modtran_runs[modtran_run].path,
                      points.modtran_runs[modtran_run].path);
        }
        else
        {
            /* Use modtran generated pltout.asc output */
            snprintf (command, sizeof (command),
                      "lst_extract_modtran_results.py"
                      " --pltout"
                      " --input-path %s"
                      " --output-path %s",
                      points.modtran_runs[modtran_run].path,
                      points.modtran_runs[modtran_run].path);
        }

        snprintf (msg_str, sizeof(msg_str), "Executing [%s]", command);
        LOG_MESSAGE (msg_str, FUNC_NAME);

#if EXTRACT_TAPE6_RESULTS
        if (system (command) != SUCCESS)
        {
            RETURN_ERROR ("Failed executing lst_extract_tape6_results.py",
                          FUNC_NAME, EXIT_FAILURE);
        }
#endif
    }

    /* Allocate memory for MODTRAN results */
    modtran_results =
        (double **) allocate_2d_array (points.num_points * NUM_ELEVATIONS,
                                       MGPE_NUM_ELEMENTS, sizeof (double));
    if (modtran_results == NULL)
    {
        RETURN_ERROR ("Allocating MODTRAN results memory", FUNC_NAME,
                      EXIT_FAILURE);
    }

    /* Generate parameters for each height and NARR point */
    if (calculate_point_atmospheric_parameters (input, &points, alb,
                                                modtran_results, verbose)
        != SUCCESS)
    {
        RETURN_ERROR ("Calculating point atmospheric parameters\n",
                      FUNC_NAME, EXIT_FAILURE);
    }

    /* Generate parameters for each Landsat pixel */
    if (calculate_pixel_atmospheric_parameters (input, &points,
                                                xml_filename,
                                                dem_filename,
                                                emissivity_filename,
                                                modtran_results, verbose)
        != SUCCESS)
    {
        RETURN_ERROR ("Calculating per/pixel atmospheric parameters\n",
                      FUNC_NAME, EXIT_FAILURE);
    }

    /* Free memory allocation */
    free_points_memory (&points);

#if NOT_TESTED
    /* Open the output file */
    output = OpenOutput (&xml_metadata, input);
    if (output == NULL)
    {                           /* error message already printed */
        RETURN_ERROR ("Opening output file", FUNC_NAME, EXIT_FAILURE);
    }

    if (!PutOutput (output, pixel_mask))
    {
        RETURN_ERROR ("Writing output LST in HDF files\n", FUNC_NAME,
                      EXIT_FAILURE);
    }

    /* Close the output file */
    if (!CloseOutput (output))
    {
        RETURN_ERROR ("closing output file", FUNC_NAME, EXIT_FAILURE);
    }

    /* Create the ENVI header file this band */
    if (create_envi_struct (&output->metadata.band[0], &xml_metadata.global,
                            &envi_hdr) != SUCCESS)
    {
        RETURN_ERROR ("Creating ENVI header structure.", FUNC_NAME,
                      EXIT_FAILURE);
    }

    /* Write the ENVI header */
    strcpy (envi_file, output->metadata.band[0].file_name);
    cptr = strchr (envi_file, '.');
    if (cptr == NULL)
    {
        RETURN_ERROR ("error in ENVI header filename", FUNC_NAME,
                      EXIT_FAILURE);
    }

    strcpy (cptr, ".hdr");
    if (write_envi_hdr (envi_file, &envi_hdr) != SUCCESS)
    {
        RETURN_ERROR ("Writing ENVI header file.", FUNC_NAME, EXIT_FAILURE);
    }

    /* Append the LST band to the XML file */
    if (append_metadata (output->nband, output->metadata.band, xml_filename)
        != SUCCESS)
    {
        RETURN_ERROR ("Appending spectral index bands to XML file.",
                      FUNC_NAME, EXIT_FAILURE);
    }

    /* Free the structure */
    if (!FreeOutput (output))
    {
        RETURN_ERROR ("freeing output file structure", FUNC_NAME,
                      EXIT_FAILURE);
    }
#endif

    /* Free the metadata structure */
    free_metadata (&xml_metadata);

    /* Close the input file and free the structure */
    CloseInput (input);
    FreeInput (input);

    /* Free memory allocations */
    if (free_2d_array ((void **) modtran_results) != SUCCESS)
    {
        RETURN_ERROR ("Freeing memory: MODTRAN results\n", FUNC_NAME,
                      EXIT_FAILURE);
    }

    if (!debug)
    {
        /* Delete temporary file */
        if (unlink ("atmospheric_parameters.txt") != SUCCESS)
        {
            RETURN_ERROR ("Deleting atmospheric_parameters.txt files\n",
                          FUNC_NAME, EXIT_FAILURE);
        }

        if (unlink ("base_head.txt") != SUCCESS)
        {
            RETURN_ERROR ("Deleting baseHead.txt files\n", FUNC_NAME,
                          EXIT_FAILURE);
        }

        if (unlink ("new_tail.txt") != SUCCESS)
        {
            RETURN_ERROR ("Deleting newTail.txt files\n", FUNC_NAME,
                          EXIT_FAILURE);
        }

        if (unlink ("temp_layers.txt") != SUCCESS)
        {
            RETURN_ERROR ("Deleting tempLayers.txt file\n", FUNC_NAME,
                          EXIT_FAILURE);
        }

        if (unlink ("used_points.txt") != SUCCESS)
        {
            RETURN_ERROR ("Deleting used_points.txt file\n", FUNC_NAME,
                          EXIT_FAILURE);
        }
    }

    time (&now);
    snprintf (msg_str, sizeof(msg_str),
              "scene_based_lst end_time=%s\n", ctime (&now));
    LOG_MESSAGE (msg_str, FUNC_NAME);

    return EXIT_SUCCESS;
}
Exemplo n.º 10
0
//-----------------------------------------------------------------
void MP3Worker::run_implementation()
{
  auto file_name = m_source_info.absoluteFilePath().replace('/', QDir::separator());

  // QTemporaryFile and QThreads are not playing fine together, the temp names are being reused
  // and taglib fails upon reading the file. This approach seems to work.
  auto id = QUuid::createUuid();
  QTemporaryFile temp_file(id.toString());
  if(!temp_file.open())
  {
    emit error_message(QString("Couldn't open temporary file for file '%1'.").arg(file_name));
    return;
  }

  QFile original_file(file_name);
  if(!original_file.open(QFile::ReadOnly))
  {
    emit error_message(QString("Couldn't open file '%1'.").arg(file_name));
    return;
  }

  // taglib wouldn't open files with unicode names.
  temp_file.write(original_file.readAll());
  temp_file.waitForBytesWritten(-1);
  temp_file.flush();
  temp_file.close();

  auto temp_name = temp_file.fileName() + MP3_EXTENSION;
  temp_file.rename(temp_name); // taglib won't open a file if it doesn't have the correct extension. ¿¿??
  original_file.close();

  QString track_title;

  { // ensure TagLib File object is destroyed at the end of scope.
    TagLib::MPEG::File file_metadata(temp_name.toStdString().c_str());

    if(file_metadata.hasID3v1Tag() || file_metadata.hasID3v2Tag())
    {
      if(m_configuration.useMetadataToRenameOutput())
      {
        if(!file_metadata.hasID3v2Tag())
        {
          track_title = parse_metadata(file_metadata.tag());
        }
        else
        {
          track_title = parse_metadata_id3v2(file_metadata.ID3v2Tag());
        }
      }

      emit progress(25);

      if(m_configuration.extractMetadataCoverPicture() && file_metadata.hasID3v2Tag())
      {
        extract_cover(file_metadata.ID3v2Tag());
      }

      emit progress(50);

      if(m_configuration.stripTagsFromMp3())
      {
        file_metadata.strip();
        file_metadata.save();
      }
    }
  }

  emit progress(75);

  if(track_title.isEmpty())
  {
    track_title = m_source_info.absoluteFilePath().split('/').last().remove(MP3_EXTENSION);
  }
  track_title = Utils::formatString(track_title, m_configuration.formatConfiguration());

  auto source_name = m_source_info.absoluteFilePath().split('/').last();
  emit information_message(QString("Renaming '%1' from '%2'.").arg(track_title).arg(source_name));

  auto final_name = m_source_path + track_title;

  original_file.rename(original_file.fileName() + TEMP_EXTENSION);

  if(!QFile::copy(temp_file.fileName(), final_name))
  {
    emit error_message(QString("Couldn't copy file '%1' to '%2'.").arg(m_source_info.absoluteFilePath()).arg(final_name));
    original_file.rename(original_file.fileName().remove(TEMP_EXTENSION));
  }
  else
  {
    original_file.remove();
  }
}
/******************************************************************************
MODULE:  main

PURPOSE: Creates the Landsat solar and view/satellite per-pixel angles.  Both
the zenith and azimuth angles are created for each angle type for the
representative band.

RETURN VALUE:
Type = int
Value           Description
-----           -----------
ERROR           Error creating the angle bands
SUCCESS         No errors encountered

NOTES:
1. Angles are written in degrees and scaled by 100.
2. There are 4 bands written for the representative band: solar zenith, solar
   azimuth, sensor zenith, sensor azimuth.
3. The landsat_per_pixel_angles library expects an array of solar/satellite
   azimuth/zenith pointers for all the input bands, as that's the possible
   full list of output bands.  So, even though we are not processing all the
   bands in the output list, we still need to provide an array of that size.
   This requires us to keep track of the indices for each of the output bands
   into the array of input bands, for both ETM and TM arrays.
******************************************************************************/
int main (int argc, char** argv)
{
    char FUNC_NAME[] = "create_angle_bands";  /* function name */
    char errmsg[STR_SIZE];       /* error message */
    char tmpstr[STR_SIZE];       /* temporary string */
    char tmpfile[STR_SIZE];      /* temporary filename */
    char ang_infile[STR_SIZE];   /* input angle coefficient filename */
    char outfile[STR_SIZE];      /* output base filename for angle bands */
    char band_list[STR_SIZE];    /* char array of list of bands to process */
    char etm_list[] = "4";       /* list of ETM bands to process */
    char tm_list[] = "4";        /* list of TM bands to process */
    char production_date[MAX_DATE_LEN+1]; /* current date/year for production */
    char band_angle[NANGLE_BANDS][STR_SIZE] = {"solar zenith", "solar azimuth",
                                    "sensor zenith", "sensor azimuth"};
    char *cptr = NULL;           /* pointer to file extension */
    char *xml_infile = NULL;     /* input XML filename */
    bool process_l7 = false;     /* are we processing L7 vs. L4-5 */
    bool process_l45 = false;    /* are we processing L4-5 vs. L7 */
    int i;                       /* looping variable for bands */
    int curr_bnd;                /* current input band location */
    int curr_band;               /* current input band number */
    int curr_bndx;               /* index of current input band */
    int curr_index;              /* index of current output band in the input
                                    band array */
    int etm_nbands = 1;          /* number of ETM bands to process for PPA */
    int tm_nbands = 1;           /* number of TM bands to process for PPA */
    int landsat_nbands;          /* number of bands to process for PPA */
    int *landsat_bands = NULL;   /* array of output bands to be processed;
                                    set to point to either etm_bands or
                                    tm_bands */
    int etm_bands[] = {4};       /* output bands to be processed */
    int tm_bands[] = {4};        /* output bands to be processed */
    int *band_indx = NULL;       /* array of indices for the output bands within
                                    the full set of input bands; set to point
                                    to either etm_band_indx or tm_band_indx */
    int etm_band_indx[] = {3};   /* index in the overall input bands for
                                    the output bands [1,2,3,4,5,61,62,7,8] */
    int tm_band_indx[] = {3};    /* index in the overall input bands for
                                    the output bands [1,2,3,4,5,6,7,8] */
    int out_nbands;              /* number of output bands to be written */
    int nlines[L7_NBANDS];       /* number of lines for each band */
    int nsamps[L7_NBANDS];       /* number of samples for each band */
    Angle_band_t ang;            /* looping variable for solar/senor angle */
    short *solar_zenith[L7_NBANDS];  /* array of pointers for the solar zenith
                                        angle array, one per band */
    short *solar_azimuth[L7_NBANDS]; /* array of pointers for the solar azimuth
                                        angle array, one per band */
    short *sat_zenith[L7_NBANDS];    /* array of pointers for the satellite
                                        zenith angle array, one per band */
    short *sat_azimuth[L7_NBANDS];   /* array of pointers for the satellite
                                        azimuth angle array, one per band */
    short *curr_angle = NULL;      /* pointer to the current angle array */
    time_t tp;                     /* time structure */
    struct tm *tm = NULL;          /* time structure for UTC time */
    FILE *fptr=NULL;               /* file pointer */
    Envi_header_t envi_hdr;        /* output ENVI header information */
    Espa_internal_meta_t xml_metadata;
                                   /* XML metadata structure to be populated by
                                      reading the input XML metadata file */
    Espa_band_meta_t *bmeta=NULL;    /* pointer to array of bands metadata */
    Espa_global_meta_t *gmeta=NULL;  /* pointer to the global metadata struct */
    Espa_band_meta_t *out_bmeta = NULL; /* band metadata for angle bands */
    Espa_internal_meta_t out_meta;      /* output metadata for angle bands */

    /* Read the command-line arguments */
    if (get_args (argc, argv, &xml_infile) != SUCCESS)
    {   /* get_args already printed the error message */
        exit (ERROR);
    }
    printf ("Processing the per-pixel angle bands for L4-7 ...\n");

    /* Validate the input metadata file */
    if (validate_xml_file (xml_infile) != SUCCESS)
    {  /* Error messages already written */
        return (ERROR);
    }

    /* Initialize the metadata structure */
    init_metadata_struct (&xml_metadata);

    /* Parse the metadata file into our internal metadata structure; also
       allocates space as needed for various pointers in the global and band
       metadata */
    if (parse_metadata (xml_infile, &xml_metadata) != SUCCESS)
    {  /* Error messages already written */
        return (ERROR);
    }
    bmeta = xml_metadata.band;
    gmeta = &xml_metadata.global;

    /* Determine which instrument is being processed */
    if (!strncmp (gmeta->instrument, "ETM", 3))
        process_l7 = true;
    else
        process_l45 = true;

    /* Determine the angle coefficient filename and the output file basename */
    strcpy (ang_infile, xml_infile);
    cptr = strchr (ang_infile, '.');
    strcpy (cptr, "_ANG.txt");

    strcpy (outfile, xml_infile);
    cptr = strchr (outfile, '.');
    *cptr = '\0';

    /* Initialize the output metadata structure.  The global metadata will
       not be used and will not be valid. */
    init_metadata_struct (&out_meta);

    /* Determine the number of output bands */
    if (process_l7)
    {
        landsat_bands = etm_bands;
        landsat_nbands = etm_nbands;
        out_nbands = landsat_nbands * NANGLE_BANDS;
        band_indx = etm_band_indx;
        strcpy (band_list, etm_list);
    }
    else
    {
        landsat_bands = tm_bands;
        landsat_nbands = tm_nbands;
        out_nbands = landsat_nbands * NANGLE_BANDS;
        band_indx = tm_band_indx;
        strcpy (band_list, tm_list);
    }

    /* Allocate memory for the output bands */
    if (allocate_band_metadata (&out_meta, out_nbands) != SUCCESS)
    {
        sprintf (errmsg, "Cannot allocate memory for the %d angle bands",
            out_nbands);
        error_handler (true, FUNC_NAME, errmsg);
        exit (ERROR);
    }

    /* Get the current date/time (UTC) for the production date of each band */
    if (time (&tp) == -1)
    {
        sprintf (errmsg, "Unable to obtain the current time.");
        error_handler (true, FUNC_NAME, errmsg);
        exit (ERROR);
    }

    tm = gmtime (&tp);
    if (tm == NULL)
    {
        sprintf (errmsg, "Converting time to UTC.");
        error_handler (true, FUNC_NAME, errmsg);
        exit (ERROR);
    }

    if (strftime (production_date, MAX_DATE_LEN, "%Y-%m-%dT%H:%M:%SZ", tm) == 0)
    {
        sprintf (errmsg, "Formatting the production date/time.");
        error_handler (true, FUNC_NAME, errmsg);
        exit (ERROR);
    }

    /* Initialize the Landsat angle bands to NULL */
    init_per_pixel_angles (solar_zenith, solar_azimuth, sat_zenith,
        sat_azimuth);

    /* Create the Landsat angle bands for the specified bands.  Create a full
       resolution product. */
    if (landsat_per_pixel_angles (ang_infile, 1, band_list, solar_zenith,
        solar_azimuth, sat_zenith, sat_azimuth, nlines, nsamps) != SUCCESS)
    {  /* Error messages already written */
        free_per_pixel_angles (solar_zenith, solar_azimuth, sat_zenith,
            sat_azimuth);
        exit (ERROR);
    }

    /* Setup the XML file for these bands */
    for (i = 0; i < out_nbands; i++)
    {
        /* Set up the band metadata for the current band */
        out_bmeta = &out_meta.band[i];
        strcpy (out_bmeta->product, "angle_bands");
        strcpy (out_bmeta->source, "level1");
        strcpy (out_bmeta->category, "image");

        /* Setup filename-related items for all four bands: solar zenith,
           solar azimuth, sensor zenith, sensor azimuth.  L4-5 and L8 band
           numbers follow a normal numbering scheme.  L7 band numbering
           needs a little help to get it correct. */
        curr_bnd = i / NANGLE_BANDS + 1;  /* current input band number */
        curr_bndx = curr_bnd - 1;         /* index of current input band */
        curr_band = landsat_bands[curr_bndx]; /* actual band number */
        curr_index = band_indx[curr_bndx];    /* index in output array */

        switch (i % NANGLE_BANDS)
        {
            case (SOLAR_ZEN):  /* solar zenith */
                /* Determine the output file for the solar zenith band */
                snprintf (tmpfile, sizeof (tmpfile),
                    "%s_b%d_solar_zenith.img", outfile, curr_band);
                sprintf (out_bmeta->name, "solar_zenith_band%d", curr_band);
                strncpy (tmpstr, bmeta[curr_bndx].short_name, 4);
                tmpstr[4] = '\0';
                sprintf (out_bmeta->short_name, "%sSOLZEN", tmpstr);
                sprintf (out_bmeta->long_name,
                    "band %d solar zenith angles", curr_band);
                break;

            case (SOLAR_AZ):  /* solar azimuth */
                /* Determine the output file for the solar azimuth band */
                snprintf (tmpfile, sizeof (tmpfile),
                    "%s_b%d_solar_azimuth.img", outfile, curr_band);
                sprintf (out_bmeta->name, "solar_azimuth_band%d",
                    curr_band);
                strncpy (tmpstr, bmeta[curr_bndx].short_name, 4);
                tmpstr[4] = '\0';
                sprintf (out_bmeta->short_name, "%sSOLAZ", tmpstr);
                sprintf (out_bmeta->long_name,
                    "band %d solar azimuth angles", curr_band);
                break;

            case (SENSOR_ZEN):  /* sensor zenith */
                /* Determine the output file for the sensor zenith band */
                snprintf (tmpfile, sizeof (tmpfile),
                    "%s_b%d_sensor_zenith.img", outfile, curr_band);
                sprintf (out_bmeta->name, "sensor_zenith_band%d",
                    curr_band);
                strncpy (tmpstr, bmeta[curr_bndx].short_name, 4);
                tmpstr[4] = '\0';
                sprintf (out_bmeta->short_name, "%sSENZEN", tmpstr);
                sprintf (out_bmeta->long_name,
                    "band %d sensor zenith angles", curr_band);
                break;

            case (SENSOR_AZ):  /* sensor azimuth */
                /* Determine the output file for the sensor azimuth band */
                snprintf (tmpfile, sizeof (tmpfile),
                    "%s_b%d_sensor_azimuth.img", outfile, curr_band);
                sprintf (out_bmeta->name, "sensor_azimuth_band%d",
                    curr_band);
                strncpy (tmpstr, bmeta[curr_bndx].short_name, 4);
                tmpstr[4] = '\0';
                sprintf (out_bmeta->short_name, "%sSENAZ", tmpstr);
                sprintf (out_bmeta->long_name,
                    "band %d sensor azimuth angles", curr_band);
                break;
        }

        snprintf (out_bmeta->file_name, sizeof (out_bmeta->file_name), "%s",
            tmpfile);
        out_bmeta->data_type = ESPA_INT16;
        out_bmeta->fill_value = ANGLE_BAND_FILL;
        out_bmeta->scale_factor = ANGLE_BAND_SCALE_FACT;
        strcpy (out_bmeta->data_units, "degrees");
        out_bmeta->nlines = nlines[curr_index];
        out_bmeta->nsamps = nsamps[curr_index];
        out_bmeta->pixel_size[0] = bmeta[curr_bndx].pixel_size[0];
        out_bmeta->pixel_size[1] = bmeta[curr_bndx].pixel_size[1];
        strcpy (out_bmeta->pixel_units, bmeta[curr_bndx].pixel_units);
        sprintf (out_bmeta->app_version, "create_angle_bands_%s",
            ESPA_COMMON_VERSION);
        strcpy (out_bmeta->production_date, production_date);
    }

    /* Loop through the four different angle files and write them for each
       band */
    for (ang = 0; ang < NANGLE_BANDS; ang++)
    {
        /* Write the angle bands */
        for (i = 0; i < landsat_nbands; i++)
        {
            /* Determine the index of this band in the overall list of input
               bands */
            curr_index = band_indx[i];

            /* Grab the correct data array to be written for this angle
               band */
            switch (ang)
            {
                case (SOLAR_ZEN):
                    curr_angle = &solar_zenith[curr_index][0];
                    break;
                case (SOLAR_AZ):
                    curr_angle = &solar_azimuth[curr_index][0];
                    break;
                case (SENSOR_ZEN):
                    curr_angle = &sat_zenith[curr_index][0];
                    break;
                case (SENSOR_AZ):
                    curr_angle = &sat_azimuth[curr_index][0];
                    break;
                default:
                    free_per_pixel_angles (solar_zenith, solar_azimuth,
                        sat_zenith, sat_azimuth);
                    sprintf (errmsg, "Invalid angle type %d", ang);
                    error_handler (true, FUNC_NAME, errmsg);
                    exit (ERROR);
            }

            /* Open the output file for this band */
            out_bmeta = &out_meta.band[i*NANGLE_BANDS + ang];
            fptr = open_raw_binary (out_bmeta->file_name, "wb");
            if (!fptr)
            {
                free_per_pixel_angles (solar_zenith, solar_azimuth, sat_zenith,
                    sat_azimuth);
                sprintf (errmsg, "Unable to open the %s file",
                    band_angle[ang]);
                error_handler (true, FUNC_NAME, errmsg);
                exit (ERROR);
            }

            /* Write the data for this band */
            if (write_raw_binary (fptr, nlines[curr_index], nsamps[curr_index],
                sizeof (short), curr_angle) != SUCCESS)
            {
                free_per_pixel_angles (solar_zenith, solar_azimuth, sat_zenith,
                    sat_azimuth);
                sprintf (errmsg, "Unable to write to the %s file",
                    band_angle[ang]);
                error_handler (true, FUNC_NAME, errmsg);
                exit (ERROR);
            }

            /* Close the file for this band */
            close_raw_binary (fptr);

            /* Create the ENVI header */
            if (create_envi_struct (out_bmeta, gmeta, &envi_hdr) != SUCCESS)
            {
                free_per_pixel_angles (solar_zenith, solar_azimuth, sat_zenith,
                    sat_azimuth);
                sprintf (errmsg, "Error creating the ENVI header file.");
                error_handler (true, FUNC_NAME, errmsg);
                exit (ERROR);
            }

            /* Write the ENVI header */
            sprintf (tmpfile, "%s", out_bmeta->file_name);
            sprintf (&tmpfile[strlen(tmpfile)-3], "hdr");
            if (write_envi_hdr (tmpfile, &envi_hdr) != SUCCESS)
            {
                free_per_pixel_angles (solar_zenith, solar_azimuth, sat_zenith,
                    sat_azimuth);
                sprintf (errmsg, "Writing the ENVI header file: %s.",
                    tmpfile);
                error_handler (true, FUNC_NAME, errmsg);
                exit (ERROR);
            }
        }  /* for i < landsat_nbands */
    }  /* for ang < NANGLE_BANDS */

    /* Free the pointers */
    free_per_pixel_angles (solar_zenith, solar_azimuth, sat_zenith,
        sat_azimuth);

    /* Append the solar/sensor angle bands to the XML file */
    if (append_metadata (out_nbands, out_meta.band, xml_infile) != SUCCESS)
    {
        sprintf (errmsg, "Appending solar/sensor angle bands to the XML file.");
        error_handler (true, FUNC_NAME, errmsg);
        exit (ERROR);
    }

    /* Free the input and output XML metadata */
    free_metadata (&xml_metadata);
    free_metadata (&out_meta);

    /* Free the pointers */
    free (xml_infile);

    /* Successful completion */
    exit (SUCCESS);
}
Exemplo n.º 12
0
int cdmifs_getattr(
		const char *path,
		struct stat *stbuf )
{
	int ret, i;
	cdmi_request_t request;

	memset( &request, 0, sizeof( cdmi_request_t ) );
	request.type = GET;
	request.cdmi = 1;
	request.fields = (char*[]){ "objectID", "metadata", NULL };
	request.flags = CDMI_CHECK;

	ret = cdmi_get( &request, path );
	if( ret == -1 )
		return errno == 0 ? -EIO : -errno;

	if( strcmp( request.contenttype, mime[M_CONTAINER] ) == 0 )
		stbuf->st_mode = S_IFDIR;
	else if( strcmp( request.contenttype, mime[M_DATAOBJECT] ) == 0 )
		stbuf->st_mode = S_IFREG;
	else
	{
		cdmi_free( &request );
		return -EPROTO;
	}

	if( parse_metadata( json_object_get(request.root, "metadata"), stbuf ) < 0 )
	{
		DEBUG( "error: unable to parse metadata\n" );
		cdmi_free( &request );
		return -EPROTO;
	}

	cdmi_free( &request );

	if( S_ISDIR( stbuf->st_mode ) )
	{
		stbuf->st_mode |= 0755;

		memset( &request, 0, sizeof( cdmi_request_t ) );
		request.type = GET;
		request.cdmi = 1;
		request.fields = (char*[]){"children",NULL};
		request.flags = CDMI_SINGLE;
		ret = cdmi_get( &request, path );
		if( ret == -1 )
			return errno == 0 ? -EIO : -errno;

		stbuf->st_nlink = 2;
		for(i = 0; i < (int)json_array_size(request.root); i++)
		{
			if( json_is_string( json_array_get(request.root, i) ) )
			{
				const char *cp = json_string_value(json_array_get(request.root, i));
				if( cp[strlen(cp)-1] == '/' )
					(stbuf->st_nlink)++;
			}
		}

		cdmi_free( &request );

		return 0;
	}
	else
	{
		stbuf->st_mode |= 0644;
		stbuf->st_nlink = 1;

		return 0;
	}

	return -ENOENT;
}
Exemplo n.º 13
0
int zmq::null_mechanism_t::process_ready_command (
    const unsigned char *cmd_data, size_t data_size)
{
    ready_command_received = true;
    return parse_metadata (cmd_data + 6, data_size - 6);
}
Exemplo n.º 14
0
int zmq::curve_server_t::process_initiate (msg_t *msg_)
{
    if (msg_->size () < 257) {
        errno = EPROTO;
        return -1;
    }

    const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
    if (memcmp (initiate, "\x08INITIATE", 9)) {
        errno = EPROTO;
        return -1;
    }

    uint8_t cookie_nonce [crypto_secretbox_NONCEBYTES];
    uint8_t cookie_plaintext [crypto_secretbox_ZEROBYTES + 64];
    uint8_t cookie_box [crypto_secretbox_BOXZEROBYTES + 80];

    //  Open Box [C' + s'](t)
    memset (cookie_box, 0, crypto_secretbox_BOXZEROBYTES);
    memcpy (cookie_box + crypto_secretbox_BOXZEROBYTES, initiate + 25, 80);

    memcpy (cookie_nonce, "COOKIE--", 8);
    memcpy (cookie_nonce + 8, initiate + 9, 16);

    int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
                                    sizeof cookie_box,
                                    cookie_nonce, cookie_key);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    //  Check cookie plain text is as expected [C' + s']
    if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES, cn_client, 32)
    ||  memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, cn_secret, 32)) {
        errno = EPROTO;
        return -1;
    }

    const size_t clen = (msg_->size () - 113) + crypto_box_BOXZEROBYTES;

    uint8_t initiate_nonce [crypto_box_NONCEBYTES];
    uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256];
    uint8_t initiate_box [crypto_box_BOXZEROBYTES + 144 + 256];

    //  Open Box [C + vouch + metadata](C'->S')
    memset (initiate_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (initiate_box + crypto_box_BOXZEROBYTES,
            initiate + 113, clen - crypto_box_BOXZEROBYTES);

    memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
    memcpy (initiate_nonce + 16, initiate + 105, 8);

    rc = crypto_box_open (initiate_plaintext, initiate_box,
                          clen, initiate_nonce, cn_client, cn_secret);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    const uint8_t *client_key = initiate_plaintext + crypto_box_ZEROBYTES;

    uint8_t vouch_nonce [crypto_box_NONCEBYTES];
    uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t vouch_box [crypto_box_BOXZEROBYTES + 80];

    //  Open Box Box [C',S](C->S') and check contents
    memset (vouch_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (vouch_box + crypto_box_BOXZEROBYTES,
            initiate_plaintext + crypto_box_ZEROBYTES + 48, 80);

    memcpy (vouch_nonce, "VOUCH---", 8);
    memcpy (vouch_nonce + 8,
            initiate_plaintext + crypto_box_ZEROBYTES + 32, 16);

    rc = crypto_box_open (vouch_plaintext, vouch_box,
                          sizeof vouch_box,
                          vouch_nonce, client_key, cn_secret);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    //  What we decrypted must be the client's short-term public key
    if (memcmp (vouch_plaintext + crypto_box_ZEROBYTES, cn_client, 32)) {
        errno = EPROTO;
        return -1;
    }

    //  Precompute connection secret from client key
    rc = crypto_box_beforenm (cn_precom, cn_client, cn_secret);
    zmq_assert (rc == 0);

    //  Use ZAP protocol (RFC 27) to authenticate the user.
    rc = session->zap_connect ();
    if (rc == 0) {
        send_zap_request (client_key);
        rc = receive_and_process_zap_reply ();
        if (rc != 0) {
            if (errno != EAGAIN)
                return -1;
            expecting_zap_reply = true;
        }
    }

    return parse_metadata (initiate_plaintext + crypto_box_ZEROBYTES + 128,
                           clen - crypto_box_ZEROBYTES - 128);
}