/* * Copyright (C) 1998 by Southwest Research Institute (SwRI) * * All rights reserved under U.S. Copyright Law and International Conventions. * * The development of this Software was supported by contracts NAG5-3148, * NAG5-6855, NAS8-36840, NAG5-2323, and NAG5-7043 issued on behalf of * the United States Government by its National Aeronautics and Space * Administration. Southwest Research Institute grants to the Government, * and others acting on its behalf, a paid-up nonexclusive, irrevocable, * worldwide license to reproduce, prepare derivative works, and perform * publicly and display publicly, by or on behalf of the Government. * Other than those rights granted to the United States Government, no part * of this Software may be reproduced in any form or by any means, electronic * or mechanical, including photocopying, without permission in writing from * Southwest Research Institute. All inquiries should be addressed to: * * Director of Contracts * Southwest Research Institute * P. O. Drawer 28510 * San Antonio, Texas 78228-0510 * * * Use of this Software is governed by the terms of the end user license * agreement, if any, which accompanies or is included with the Software * (the "License Agreement"). An end user will be unable to install any * Software that is accompanied by or includes a License Agreement, unless * the end user first agrees to the terms of the License Agreement. Except * as set forth in the applicable License Agreement, any further copying, * reproduction or distribution of this Software is expressly prohibited. * Installation assistance, product support and maintenance, if any, of the * Software is available from SwRI and/or the Third Party Providers, as the * case may be. * * Disclaimer of Warranty * * SOFTWARE IS WARRANTED, IF AT ALL, IN ACCORDANCE WITH THESE TERMS OF THE * LICENSE AGREEMENT. UNLESS OTHERWISE EXPLICITLY STATED, THIS SOFTWARE IS * PROVIDED "AS IS", IS EXPERIMENTAL, AND IS FOR NON-COMMERCIAL USE ONLY, * AND ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT * SUCH DISCLAIMERS ARE HELD TO BE LEGALLY INVALID. * * Limitation of Liability * * SwRI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED AS A RESULT OF USING, * MODIFYING, CONTRIBUTING, COPYING, DISTRIBUTING, OR DOWNLOADING THIS * SOFTWARE. IN NO EVENT SHALL SwRI BE LIABLE FOR ANY INDIRECT, PUNITIVE, * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGE (INCLUDING LOSS OF BUSINESS, * REVENUE, PROFITS, USE, DATA OR OTHER ECONOMIC ADVANTAGE) HOWEVER IT ARISES, * WHETHER FOR BREACH OF IN TORT, EVEN IF SwRI HAS BEEN PREVIOUSLY ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. YOU HAVE SOLE RESPONSIBILITY FOR ADEQUATE * PROTECTION AND BACKUP OF DATA AND/OR EQUIPMENT USED IN CONNECTION WITH THE * SOFTWARE AND WILL NOT MAKE A CLAIM AGAINST SwRI FOR LOST DATA, RE-RUN TIME, * INACCURATE OUTPUT, WORK DELAYS OR LOST PROFITS RESULTING FROM THE USE OF * THIS SOFTWARE. YOU AGREE TO HOLD SwRI HARMLESS FROM, AND YOU COVENANT NOT * TO SUE SwRI FOR, ANY CLAIMS BASED ON USING THE SOFTWARE. * * Local Laws: Export Control * * You acknowledge and agree this Software is subject to the U.S. Export * Administration Laws and Regulations. Diversion of such Software contrary * to U.S. law is prohibited. You agree that none of the Software, nor any * direct product therefrom, is being or will be acquired for, shipped, * transferred, or reexported, directly or indirectly, to proscribed or * embargoed countries or their nationals, nor be used for nuclear activities, * chemical biological weapons, or missile projects unless authorized by U.S. * Government. Proscribed countries are set forth in the U.S. Export * Administration Regulations. Countries subject to U.S embargo are: Cuba, * Iran, Iraq, Libya, North Korea, Syria, and the Sudan. This list is subject * to change without further notice from SwRI, and you must comply with the * list as it exists in fact. You certify that you are not on the U.S. * Department of Commerce's Denied Persons List or affiliated lists or on the * U.S. Department of Treasury's Specially Designated Nationals List. You agree * to comply strictly with all U.S. export laws and assume sole responsibilities * for obtaining licenses to export or reexport as may be required. * * General * * These Terms represent the entire understanding relating to the use of the * Software and prevail over any prior or contemporaneous, conflicting or * additional, communications. SwRI can revise these Terms at any time * without notice by updating this posting. * * Trademarks * * The SwRI logo is a trademark of SwRI in the United States and other countries. * */ #ident "@(#) fix_ptrs.c 1.25 05/08/19 SwRI" #include #if defined (__MINGW32__) || defined (__MSVCRT__) #include #else #include #endif #include "ret_codes.h" #include "gen_defs.h" #include "libbase_idfs.h" #include "libVIDF.h" /* for header format comparison */ /****************************************************************************** * * * IR_FIX_POINTERS SUBROUTINE * * * * DESCRIPTION * * This routine is called to assign the pointers for those information * * elements whose size may vary from header to header. Everytime a new * * header record is read, this routine is called to assign the pointers to * * the correct memory locations dynamically allocated for the header * * information. * * * * INPUT VARIABLES * * void *data_ptr ptr to memory location for the structure * * that holds returned data values (either * * idf_data_ptr or tensor_data_ptr) * * * * USAGE * * x = ir_fix_pointers (data_ptr) * * * * NECESSARY SUBPROGRAMS * * sizeof () the size of the specified object in bytes * * ntohs () network to host short conversion * * ntohl () network to host long conversion * * ir_number_of_cal_elements () determines the no. of calibration elements * * associated with the sample sequence values * * and the sensor data * * * * EXTERNAL VARIABLES * * struct general_info ginfo structure that holds information concern- * * ing the experiment that is being processed * * * * INTERNAL VARIABLES * * struct experiment_info *ex a pointer to the structure that holds * * specific experiment information * * struct ptr_rec *ptr a pointer to the structure which holds * * all pointers to the header and data for * * the experiment of interest * * SDDAS_ULONG tdqual_size no. of data quality flags defined per * * sensor for tensor values * * SDDAS_LONG header_offset index into the memory allocated for the * * header information * * SDDAS_LONG data_offset index into the memory allocated for the * * data information * * SDDAS_ULONG all_swp_bytes the number of bytes to bypass in order to * * get past the sweep calibration data defined* * for usage by all sensors * * SDDAS_ULONG all_sen_bytes the number of bytes to bypass in order to * * get past the calibration data to be applied* * to the sensor data for all sensors * * SDDAS_ULONG swp_bytes the number of bytes to bypass in order to * * get past the sweep calibration data * * SDDAS_ULONG num_values number of values to process * * SDDAS_LONG tnb the number of bytes to bypass in order to * * get past the sensor data * * SDDAS_LONG bit_off the total number of bits that need to be * * bypassed in order to get to the cal. data * * SDDAS_LONG add_bytes number of bytes to add to the indexing * * offset * * bypassed in order to get to the cal. data * * SDDAS_USHORT num_sample the number of samples returned * * SDDAS_SHORT byte_size how many bits are used per data element * * within each byte (necessary due to padding)* * SDDAS_SHORT ret_val holds the value returned by called module * * SDDAS_SHORT n_sen the number of sensors defined * * SDDAS_CHAR all_swp_next_off the number of bits needed to bypass the * * sample sequence cal. data * * SDDAS_CHAR all_sen_next_off the number of bits needed to bypass the * * sensor cal. data * * SDDAS_CHAR swp_next_off the number of bits needed to bypass the * * sample sequence cal. data * * size_t num_bytes_slong the number of bytes needed for a SDDAS_LONG* * size_t num_bytes_sshort number of bytes needed for a SDDAS_SHORT * * size_t num_bytes_schar number of bytes needed for a SDDAS_CHAR * * size_t num_bytes_suchar number of bytes needed for a SDDAS_UCHAR * * * * SUBSYSTEM * * Display Level * * * ******************************************************************************/ SDDAS_SHORT ir_fix_pointers (void *data_ptr) { extern struct general_info ginfo; struct experiment_info *ex; struct ptr_rec *ptr; SDDAS_ULONG tdqual_size, all_swp_bytes, all_sen_bytes, swp_bytes; SDDAS_ULONG num_values; SDDAS_LONG header_offset, data_offset; SDDAS_LONG tnb, bit_off, add_bytes; SDDAS_USHORT num_sample; SDDAS_SHORT byte_size, ret_val, n_sen; SDDAS_CHAR all_swp_next_off, all_sen_next_off, swp_next_off; size_t num_bytes_slong, num_bytes_sshort, num_bytes_schar, num_bytes_suchar; /***************************************************************************/ /* Set a pointer to the structure which holds all pointers for header and */ /* data information for the experiment currently being processed. */ /***************************************************************************/ ex = ginfo.expt; ptr = ex->info_ptr; num_bytes_slong = sizeof (SDDAS_LONG); num_bytes_sshort = sizeof (SDDAS_SHORT); num_bytes_schar = sizeof (SDDAS_CHAR); num_bytes_suchar = sizeof (SDDAS_UCHAR); /***********************************************************************/ /* Determine offset value up to and including N_SEN element in header */ /* record (common to all header formats). */ /***********************************************************************/ header_offset = num_bytes_sshort + num_bytes_sshort + num_bytes_sshort + num_bytes_schar + num_bytes_suchar + num_bytes_slong + num_bytes_slong + num_bytes_slong + num_bytes_slong + num_bytes_sshort; if (ex->header_format == ORIGINAL_HEADER) { /****************************************************************************/ /* Determine offset value up to SAMP_INDEX element in header record. */ /* The header offset value must bypass the SAMP_INDEX array to get to the */ /* next header element. */ /****************************************************************************/ num_sample = *(ptr->hdr_fmt1_ptr->N_SAMPLE); num_sample = ntohs (num_sample); header_offset += sizeof (SDDAS_USHORT); /* N_SAMPLE */ header_offset += (ex->smp_id == 2) ? num_bytes_sshort : (num_bytes_sshort * num_sample); } else { header_offset += sizeof (SDDAS_SHORT); /* WORD_PAD */ header_offset += sizeof (SDDAS_ULONG); /* DQUAL_SIZE */ } ptr->SENSOR_INDEX = (SDDAS_SHORT *)(ex->HEADER_MEM + header_offset); /***************************************************************************/ /* The SENSOR_INDEX element is an array of dimension N_SEN. */ /***************************************************************************/ n_sen = ntohs (*ptr->N_SEN); header_offset += n_sen * num_bytes_sshort; ptr->DQUAL = (SDDAS_UCHAR *) (ex->HEADER_MEM + header_offset); /***************************************************************************/ /* For IDFS data sets that make use of the original header, the D_QUAL */ /* element is an array of dimension N_SEN. */ /***************************************************************************/ if (ex->header_format == ORIGINAL_HEADER) header_offset += n_sen * num_bytes_suchar; else { tdqual_size = *ptr->hdr_fmt2_ptr->DQUAL_SIZE; tdqual_size = ntohl (tdqual_size); header_offset += n_sen * num_bytes_suchar * tdqual_size; } ptr->MODE_INDEX = (SDDAS_UCHAR *)(ex->HEADER_MEM + header_offset); /***********************************************************************/ /* Byte_size indicates how many bits are used per data element within */ /* each byte. For 5, 6 and 7 bit data, there are pad bits so that */ /* there is only one sample per byte (takes 8 bits). For 3 bit data, */ /* use 4 since the data is laid down as a 4-bit value with the most */ /* significant bit set to zero. The rest of the cases divide evenly */ /* into the byte. */ /***********************************************************************/ if (ex->tdw_len <= 8) byte_size = (ex->tdw_len >= 5) ? 8 : (ex->tdw_len == 3) ? 4 : ex->tdw_len; else byte_size = (ex->tdw_len <= 16) ? 16 : 32; /****************************************************************************/ /* Determine the pointer locations for the calibration values within the */ /* data matrix. The code is placed here since the number of sensors can */ /* change from read to read. */ /****************************************************************************/ data_offset = num_bytes_slong + num_bytes_slong + num_bytes_slong + (num_bytes_slong * ex->max_nss) + num_bytes_slong; /****************************************************************************/ /* Don't forget to bypass the nanosecond correction value when setting the */ /* pointers to the calibration data. */ /****************************************************************************/ if (ex->nano_defined) data_offset += num_bytes_slong; if (ex->header_format == ORIGINAL_HEADER) num_values = num_sample; else num_values = ex->tensor_elements; ret_val = ir_number_of_cal_elements (&ptr->num_all_swp_cal, &ptr->num_all_sen_cal, &ptr->num_swp_cal, &ptr->num_sen_cal, num_values, n_sen, data_ptr); if (ret_val != ALL_OKAY) return (ret_val); /*************************************************************************/ /* Determine the total number of bytes that need to be bypassed in order */ /* to get to the calibration data. It is assumed that the calibration */ /* data will always start on a byte boundary (bit 0). */ /*************************************************************************/ bit_off = (num_values * n_sen * byte_size); tnb = bit_off / 8; if (bit_off % 8 != 0) ++tnb; /****************************************************************************/ /* The order of the possible calibration sets is as follows: */ /* 1) cal. sets for the sample sequence values applicable to all sensors */ /* 2) cal. sets for the sensor data applicable to all sensors */ /* 3) cal. sets for the sample sequence values defined per sensor */ /* 4) cal. sets for the sensor data defined per sensor */ /* For tensor data, num_all_swp_cal and num_swp_cal SHOULD be zero since */ /* CAL_TARGET was checked when read from the VIDF file. */ /****************************************************************************/ if (ptr->num_all_swp_cal == 0) { ptr->ALL_CAL_SWP = NO_MEMORY; ptr->all_swp_bit = 0; } else { ptr->ALL_CAL_SWP = (SDDAS_UCHAR *) (ex->DATA_MEM + data_offset + tnb); ptr->all_swp_bit = 0; } /*************************************************************************/ /* Determine the additional number of bytes to bypass in order to get */ /* past the cal. data for the sample sequence values. Each cal set is */ /* only written once but will be used for all sensors. Since the cal. */ /* data starts on a byte boundary, all_swp_next_off can only be between */ /* 0 and 7. */ /*************************************************************************/ all_swp_bytes = (ptr->num_all_swp_cal * byte_size) / 8; all_swp_next_off = (ptr->num_all_swp_cal * byte_size) % 8; if (ptr->num_all_sen_cal == 0) { ptr->ALL_CAL_SEN = NO_MEMORY; ptr->all_sen_bit = 0; } else { /***********************************************************************/ /* TNB is the number of bytes to bypass to get past the sensor data. */ /* ALL_SWP_BYTES is the number of bytes to bypass to get past the cal.*/ /* data for the sample sequence values to be used by all sensors. */ /***********************************************************************/ ptr->ALL_CAL_SEN = (SDDAS_UCHAR *)(ex->DATA_MEM + data_offset + tnb + all_swp_bytes); ptr->all_sen_bit = all_swp_next_off; } /**************************************************************************/ /* Determine the additional number of bytes to bypass in order to get */ /* past the cal. data for the sensor data. Each cal set is only */ /* written once but will be used for all sensors. Since the cal. data */ /* starts on a byte boundary, all_sen_next_off can only be between 0 & 7.*/ /**************************************************************************/ all_sen_bytes = (ptr->num_all_sen_cal * byte_size) / 8; all_sen_next_off = (ptr->num_all_sen_cal * byte_size) % 8; /****************************************************************************/ /* If there are no cal. sets for the sample sequence values, the cal. */ /* values for the data immediately follows the data for the sensors if it */ /* exists; else, the cal. values for the sample sequence values immediately*/ /* follow the data for the sensors, which is, in turn, followed by the cal.*/ /* values for the sensor data, if it exists. */ /****************************************************************************/ if (ptr->num_swp_cal == 0) { ptr->CAL_SWP_TBL = NO_MEMORY; ptr->swp_bit = 0; } else { add_bytes = (all_swp_next_off + all_sen_next_off) / 8; ptr->CAL_SWP_TBL = (SDDAS_UCHAR *) (ex->DATA_MEM + data_offset + tnb + all_swp_bytes + all_sen_bytes + add_bytes); ptr->swp_bit = (all_swp_next_off + all_sen_next_off) % 8; } /*************************************************************************/ /* Determine the additional number of bytes to bypass in order to get */ /* past the cal. data for the sample sequence values. Also, determine */ /* the bit offset to point to the cal. data for the sensors. There is */ /* no need to multiply NUM_SWP_CAL by N_SEN since NUMBER_OF_CAL_ELEMENTS*/ /* multiplies by N_SEN. For example, if 1 sample sequence cal set and */ /* there are 3 sensors, NUM_SWP_CAL will be returned as 3 (not 1). */ /* Since the cal. data starts on a byte boundary, swp_next_off can only */ /* be between 0 and 7. */ /*************************************************************************/ swp_bytes = (ptr->num_swp_cal * byte_size) / 8; swp_next_off = (ptr->num_swp_cal * byte_size) % 8; if (ptr->num_sen_cal == 0) { ptr->CAL_SENSOR = NO_MEMORY; ptr->sen_bit = 0; } else { /***********************************************************************/ /* TNB is the number of bytes to bypass to get past the sensor data. */ /* SWP_BYTES is the number of bytes to bypass to get past the cal. */ /* data for the sample sequence values. */ /***********************************************************************/ add_bytes = (all_swp_next_off + all_sen_next_off + swp_next_off) / 8; ptr->CAL_SENSOR = (SDDAS_UCHAR *)(ex->DATA_MEM + data_offset + tnb + all_swp_bytes + all_sen_bytes + swp_bytes + add_bytes); ptr->sen_bit = (all_swp_next_off + all_sen_next_off + swp_next_off) % 8; } return (ALL_OKAY); }