Exemple #1
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : acr_peek_at_next_element_id
@INPUT      : afp - Acr_File pointer from which to read
@OUTPUT     : group_id
              element_id 
@RETURNS    : VIO_Status
@DESCRIPTION: Peeks ahead to get the group and element ids of the next 
              element. The file position is restored. If a read error occurs,
              then group_id and element_id are set to INT_MIN and the status
              is returned.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : February 5, 1997 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
Acr_Status acr_peek_at_next_element_id(Acr_File *afp,
                                       int *group_id, int *element_id)
{
   long buflen;
   unsigned char buffer[2*ACR_SIZEOF_SHORT];
   Acr_Short svalue;
   Acr_Status status, status2;
   Acr_byte_order byte_order;

   /* Set default values */
   status = ACR_OK;
   *group_id = INT_MIN;
   *element_id = INT_MIN;

   /* Read in the values */
   status = acr_read_buffer(afp, buffer, SIZEOF_ARRAY(buffer), &buflen);

   /* Put them back */
   status2 = acr_unget_buffer(afp, buffer, buflen);
   if (status == ACR_OK) status = status2;

   /* Check for input error */
   if (status != ACR_OK) return status;

   /* Get the id's */
   byte_order = acr_get_byte_order(afp);
   acr_get_short(byte_order, 1, &buffer[0], &svalue);
   *group_id = (int)svalue;
   acr_get_short(byte_order, 1, &buffer[ACR_SIZEOF_SHORT], &svalue);
   *element_id = (int)svalue;

   return status;

}
Exemple #2
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : acr_read_one_element
@INPUT      : afp - Acr_File pointer from which to read
@OUTPUT     : group_id - ACR-NEMA group id
              element_id - ACR-NEMA element id
              data_length - length of data to follow
              data_pointer - pointer to data. Space is allocated by this
                 routine. One additional byte is allocated and set to
                 zero so that the data can be treated as a string.
@RETURNS    : Status.
@DESCRIPTION: Routine to read in one ACR-NEMA element.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : November 10, 1993 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
Acr_Status acr_read_one_element(Acr_File *afp,
                                       int *group_id, int *element_id,
                                       long *data_length, char **data_pointer)
{
   int ch, i, buflen;
   unsigned char buffer[2*ACR_SIZEOF_SHORT+ACR_SIZEOF_LONG];
   unsigned short grpid, elid;
   size_t size_allocated;

   buflen = sizeof(buffer)/sizeof(buffer[0]);

   /* Read in group id, element id and length of data */
   for (i=0; i < buflen; i++) {
      ch = acr_getc(afp);
      if (ch == EOF) {
         if (i == 0)
            return ACR_END_OF_INPUT;
         else
            return ACR_PROTOCOL_ERROR;
      }
      buffer[i] = ch;
   }
   acr_get_short(1, &buffer[0], &grpid);
   *group_id = grpid;
   acr_get_short(1, &buffer[2], &elid);
   *element_id = elid;
   acr_get_long(1, &buffer[4], data_length);

   /* Allocate space for the data and null-terminate it */
   size_allocated = *data_length + 1;
   *data_pointer = MALLOC(size_allocated);
   if (*data_pointer == NULL) {
      *data_length = 0;
      size_allocated = *data_length + 1;
      *data_pointer = MALLOC(size_allocated);
   }
   (*data_pointer)[*data_length] = '\0';

   /* Read in the data */
   for (i=0; i < *data_length; i++) {
      ch = acr_getc(afp);
      if (ch == EOF) {
         FREE(*data_pointer);
         return ACR_PROTOCOL_ERROR;
      }
      (*data_pointer)[i] = ch;
   }

   return ACR_OK;
}
Exemple #3
0
/* ARGSUSED */
static double get_short(Acr_VR_Entry *vr_entry, 
                        Acr_byte_order byte_order,
                        char *data, long data_length)
{
   Acr_Short value;

   if (data_length == ACR_SIZEOF_SHORT) {
      acr_get_short(byte_order, 1, data, &value);
      return (double) value;
   }
   else {
      return 0.0;
   }
}
Exemple #4
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : acr_test_byte_order
@INPUT      : afp
@OUTPUT     : (none)
@RETURNS    : status.
@DESCRIPTION: Tests input for byte ordering to use. The test is done by 
              looking at the length of the first element. First a test is
              done for implicit VR, assuming that the length of the first 
              element is less than 64K and greater than zero, and we try 
              the two possible byte orders. If the VR encoding is explicit, 
              then we have two shortwords (2-bytes), both of which are 
              non-zero and the longword (4 bytes) will be greater than 64K. 
              In this case, we test the 2-byte length looking for a length
              that is less than 256 bytes. If that fails, than we revert
              to the original byte order.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : November 10, 1993 (Peter Neelin)
@MODIFIED   : January 29, 1997 (P.N.)
---------------------------------------------------------------------------- */
Acr_Status acr_test_byte_order(Acr_File *afp)
{
   long buflen;
   unsigned char buffer[2*ACR_SIZEOF_SHORT+ACR_SIZEOF_LONG];
   Acr_Long data_length;
   Acr_Short data_length2;
   Acr_Status status;
   Acr_byte_order byte_order, old_byte_order;

#define ACR_TEST_MAX USHRT_MAX
#define ACR_TEST_MAX2 UCHAR_MAX

   /* Save old byte ordering */
   old_byte_order = acr_get_byte_order(afp);

   /* Read in group id, element id and length of data */
   status = acr_read_buffer(afp, buffer, SIZEOF_ARRAY(buffer), &buflen);
   if (status != ACR_OK) return status;

   /* Put the characters back */
   status = acr_unget_buffer(afp, buffer, buflen);
   if (status != ACR_OK) return status;

   /* Test data length (the first element should be a group length).
      Try big-endian ordering first. */
   byte_order = ACR_BIG_ENDIAN;
   acr_set_byte_order(afp, byte_order);
   acr_get_long(byte_order, 1, &buffer[2*ACR_SIZEOF_SHORT], 
                &data_length);

   /* If that doesn't work, set it to little-endian ordering. */
   if (data_length >= ACR_TEST_MAX) {
      byte_order = ACR_LITTLE_ENDIAN;
      acr_set_byte_order(afp, byte_order);
      acr_get_long(byte_order, 1, &buffer[2*ACR_SIZEOF_SHORT], 
                   &data_length);
   }

   /* If one of them worked, then it means that we have implicit VR 
      encoding since we didn't look for a VR field */
   if (data_length < ACR_TEST_MAX) {
      acr_set_vr_encoding(afp, ACR_IMPLICIT_VR);
   }

   /* Otherwise we probably have explicit vr encoding. */
   else {
      acr_set_vr_encoding(afp, ACR_EXPLICIT_VR);

      /* Check the length in this case to see if it small. The default
         will be little endian. */
      byte_order = ACR_BIG_ENDIAN;
      acr_set_byte_order(afp, byte_order);
      acr_get_short(byte_order, 1, &buffer[3*ACR_SIZEOF_SHORT], 
                   &data_length2);
      if (data_length2 >= ACR_TEST_MAX2) {
         byte_order = ACR_LITTLE_ENDIAN;
         acr_set_byte_order(afp, byte_order);
         acr_get_short(byte_order, 1, &buffer[3*ACR_SIZEOF_SHORT], 
                       &data_length2);
      }
      if (data_length2 >= ACR_TEST_MAX2) {
         /* If we get here, we have completely failed to make sense of 
          * the byte ordering.
          */
         acr_set_byte_order(afp, old_byte_order);
      }
   }

   return ACR_OK;

}
Exemple #5
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : acr_read_one_element
@INPUT      : afp - Acr_File pointer from which to read
@OUTPUT     : group_id - ACR-NEMA group id
              element_id - ACR-NEMA element id
              vr_name - 2 character string giving value representation.
                 Two NULs are returned if VR is unknown.
              data_length - length of data to follow. Value 
                 ACR_VARIABLE_LENGTH is returned for undefined length elements
                 in which case the data portion is not read in.
              data_pointer - pointer to data. Space is allocated by this
                 routine. One additional byte is allocated and set to
                 zero so that the data can be treated as a string. If a
                 sequence is encountered, then NULL is returned.
@RETURNS    : VIO_Status.
@DESCRIPTION: Routine to read in one ACR-NEMA element.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : November 10, 1993 (Peter Neelin)
@MODIFIED   : January 29, 1997 (P.N.)
---------------------------------------------------------------------------- */
Acr_Status acr_read_one_element(Acr_File *afp,
                                int *group_id, int *element_id,
                                char vr_name[],
                                long *data_length, char **data_pointer)
{
   long buflen;
   unsigned char buffer[2*ACR_SIZEOF_SHORT+ACR_SIZEOF_LONG];
   Acr_Short grpid, elid, sval;
   Acr_Long datalen;
   size_t size_allocated;
   int offset;
   Acr_byte_order byte_order;
   Acr_Status status;

   /* Get byte ordering */
   byte_order = acr_get_byte_order(afp);

   /* Read in group id, element id and length of data */
   status = acr_read_buffer(afp, buffer, SIZEOF_ARRAY(buffer), &buflen);
   if (status != ACR_OK) return status;
   offset = 0;
   acr_get_short(byte_order, 1, &buffer[offset], &grpid);
   offset += ACR_SIZEOF_SHORT;
   *group_id = (int)grpid;
   acr_get_short(byte_order, 1, &buffer[offset], &elid);
   offset += ACR_SIZEOF_SHORT;
   *element_id = (int)elid;

   /* Look for VR and length of data */
   if (grpid == ACR_ITEM_GROUP || acr_get_vr_encoding(afp) == ACR_IMPLICIT_VR) {
      vr_name[0] = '\0';
      vr_name[1] = '\0';
      acr_get_long(byte_order, 1, &buffer[offset], &datalen);
      offset += ACR_SIZEOF_LONG;
   }
   else {
      vr_name[0] = buffer[offset++];
      vr_name[1] = buffer[offset++];
      acr_get_short(byte_order, 1, &buffer[offset], &sval);
      offset += ACR_SIZEOF_SHORT;
      datalen = (Acr_Long)sval;
   }

   /* Read in length for special VR's */
   if (is_special_vr(vr_name)) {
      status = acr_read_buffer(afp, buffer, (long) ACR_SIZEOF_LONG, NULL);
      if (status != ACR_OK) return ACR_ABNORMAL_END_OF_INPUT;
      acr_get_long(byte_order, 1, &buffer[0], &datalen);
   }

   /* Check for undefined length */
   if (datalen == ACR_UNDEFINED_ELEMENT_LENGTH) {
      *data_length = ACR_VARIABLE_LENGTH;
      *data_pointer = NULL;
      return ACR_OK;
   }
   *data_length = (long)datalen;

   /* Check for sequence VR */
   if (is_sequence_vr(vr_name)) {
      *data_pointer = NULL;
      return ACR_OK;
   }
   
   /* Allocate space for the data and null-terminate it */
   size_allocated = *data_length + 1;
   *data_pointer = MALLOC(size_allocated);
   if (*data_pointer == NULL) {
      *data_length = 0;
      size_allocated = *data_length + 1;
      *data_pointer = MALLOC(size_allocated);
   }
   (*data_pointer)[*data_length] = '\0';

   /* Read in the data */
   status = acr_read_buffer(afp, (unsigned char *) *data_pointer, 
                            *data_length, NULL);
   if (status != ACR_OK) {
      FREE(*data_pointer);
      return ACR_ABNORMAL_END_OF_INPUT;
   }

   return ACR_OK;
}