Exemplo n.º 1
0
int
ReadRST::DoubleRecord(double *buf, int len)
{
    int ret = len;
    if (mmap_flag_)
    {
        memcpy(buf, (char *)mmap_ini_ + actual_off_, len * sizeof(double));
    }
    else
    {
        ret = fread(buf, sizeof(double), len, rfp_);
        if (ret != len)
            return ret;
    }
    int item;
    for (item = 0; item < len; ++item)
    {
        buf[item] = SwitchEndian(buf[item]);
    }
    return ret;
}
Exemplo n.º 2
0
// -----------------------------------------------
// OpenFile
// -----------------------------------------------
// Oeffnet den Ergebnisfile, liest den header und setzt
// den Read-File-Pointer rfp;
// Rueckgabe:
// 0    : alles OK
// 1    : File not found
// 2    : could not read header
// 3    : Read Error Nodal equivalence
// 4    : Read Error Element equivalence
// 5    : Read Error Time table
int
ReadRST::OpenFile(const std::string &filename)
{
    if (rfp_ && nodeindex_ && rstheader_.numsets_ != 0)
        return 0;

    if ((rfp_ = fopen(filename.c_str(), "rb")) == NULL)
    {
        return (1);
    }

    file_des_ = fileno(rfp_);

    if (get_file_size() != 0)
    {
        Covise::sendError("Could not get file size");
        return (1);
    }

    // File offen und OK
    // erst mal zwei INTs lesen (lead-in):
    // int 1 ergibt die Laenge des folgenden Records in bytes
    // int 2 ergibt den Typ des Records (z.B. 0x64==Integer)

    /****************************************************************************/
    /* Notes:                                                                                                           */
    /*                                                                                                                      */
    /* ANSYS binary files are written in Fortran which means that data is written   */
    /* blockwise.  Each block or record is delimited by markers, namely a header  */
    /* and trailer, both of them being identical and usually 4 bytes long.  These     */
    /* markers indicate the size of the record.  ANSYS uses particularly variable-  */
    /* length records, however it has been observed that the format of the          */
    /* binary files varies depending on the ANSYS version.                                     */
    /*                                                                                                                      */
    /* In older versions of ANSYS (i.e. V5.6) the size of the records is denoted      */
    /* in BYTES while the second integer after the record header corresponds to  */
    /* the size of the Standard ANSYS File Header which is 100 or 0x64 integers  */
    /* long.  This value is followed by the actual 100 values (integers) or items      */
    /* contained in the ANSYS File Header.                                                             */
    /*                                                                                                                     */
    /* In newer versions (i.e. V11.0) it has been observed that the size of the      */
    /* records is expressed in INTs, that is 0x64 items.  The second integer has  */
    /* the value 2147483648 or 0x80000000 which may be a reference to the    */
    /* data type of the elements contained in the ANSYS File Header, namely        */
    /* integers (signed int ?).  Nevertheless it seems this integer is not counted   */
    /* in the record size.  For more information refer to "Programmer's                */
    /* Manual for Mechanical APDL" (ANSYS Release 12.1)                                     */
    /***************************************************************************/

    int *buf = new int[1024];
    char version[150];

    // Reading the first 4 bytes of the binary file
    size_t iret = fread(buf, sizeof(int), 1, rfp_);

    if (iret != 1)
    {
        Covise::sendInfo("Error reading rtp_");
    }

    int header_offset = 0;
    if (buf[0] == 100 || buf[0] == 1677721600) // 100 and 1677721600 to recognize offset in little endian and big endian
    {
        header_offset = 1;
    }

    // Reading the header
    if (fread(buf + 1 + header_offset, sizeof(int), 102, rfp_) != 102)
    {
        return (2);
    }

    int subversion;
    version[4] = 0;
    memcpy(version, &buf[11 + header_offset], 4);
    SwitchEndian(version, 4);

    int ret = sscanf(version, "%d.%d", &header_.version_, &subversion);

    if (ret != 2)
    {
        header_.version_ = 9;
    }
    Covise::sendInfo("File generated by ANSYS V%d.%d", header_.version_, subversion);

    // alle INT-Elemente umdrehen

    header_.filenum_ = SwitchEndian(buf[2]);
    header_.format_ = SwitchEndian(buf[3]);
    header_.time_ = SwitchEndian(buf[4]);
    header_.date_ = SwitchEndian(buf[5]);
    header_.unit_ = SwitchEndian(buf[10]);
    header_.ansysdate_ = SwitchEndian(buf[12]);
    memcpy(header_.machine_, &buf[13], 3 * sizeof(int));
    header_.machine_[12] = '\0';
    SwitchEndian(header_.machine_, 12);
    memcpy(header_.jobname_, &buf[16], 2 * sizeof(int));
    header_.jobname_[8] = '\0';
    SwitchEndian(header_.jobname_, 8);
    memcpy(header_.product_, &buf[18], 2 * sizeof(int));
    header_.product_[8] = '\0';
    SwitchEndian(header_.product_, 8);
    memcpy(header_.label_, &buf[20], 1 * sizeof(int));
    header_.label_[4] = '\0';
    SwitchEndian(header_.label_, 4);
    memcpy(header_.user_, &buf[21], 3 * sizeof(int));
    header_.user_[12] = '\0';
    SwitchEndian(header_.user_, 12);
    memcpy(header_.machine2_, &buf[24], 3 * sizeof(int));
    header_.machine2_[12] = '\0';
    SwitchEndian(header_.machine2_, 12);
    header_.recordsize_ = SwitchEndian(buf[27]);
    header_.maxfilelen_ = SwitchEndian(buf[28]);
    header_.maxrecnum_ = SwitchEndian(buf[29]);
    header_.cpus_ = SwitchEndian(buf[30]);
    memcpy(header_.title_, &buf[42], 20 * sizeof(int));
    header_.title_[80] = '\0';
    SwitchEndian(header_.title_, 80);
    memcpy(header_.subtitle_, &buf[62], 20 * sizeof(int));
    header_.subtitle_[80] = '\0';
    SwitchEndian(header_.subtitle_, 80);
    // File Pointer steht jetzt auf Position (100+3)*4=412 Bytes

    Covise::sendInfo("Machine: %s   Jobname: %s", header_.machine_, header_.jobname_);
    Covise::sendInfo("Product: %s   Label: %s", header_.product_, header_.label_);
    Covise::sendInfo("Title: %s   Subtitle: %s", header_.title_, header_.subtitle_);

    // jetzt den RST-File Header reinbasteln
    if (fread(buf, sizeof(int), 43, rfp_) != 43)
    {
        return (2);
    }

    if (SwitchEndian(buf[2]) != 12)
    {
        ChangeSwitch();
        if (SwitchEndian(buf[2]) == 12)
        {
            // file can be read using byteswap, prepare to try again
            delete[] buf;
            fclose(rfp_);
            // try again
            Covise::sendInfo("File is byteswapped, trying again ...");
            return OpenFile(filename);
        }
        else
        {
            // file cannot be read at all
            Covise::sendError("Cannot correctly read file header length");
            return 2;
        }
    }

    // Werte zuweisen
    rstheader_.fun12_ = SwitchEndian(buf[2]);
    rstheader_.maxnodes_ = SwitchEndian(buf[3]);
    rstheader_.usednodes_ = SwitchEndian(buf[4]);
    rstheader_.maxres_ = SwitchEndian(buf[5]);
    rstheader_.numdofs_ = SwitchEndian(buf[6]);
    rstheader_.maxelement_ = SwitchEndian(buf[7]);
    rstheader_.numelement_ = SwitchEndian(buf[8]);
    rstheader_.analysis_ = SwitchEndian(buf[9]);
    rstheader_.numsets_ = SwitchEndian(buf[10]);
    rstheader_.ptr_eof_ = SwitchEndian(buf[11]);
    rstheader_.ptr_dsi_ = SwitchEndian(buf[12]);
    rstheader_.ptr_time_ = SwitchEndian(buf[13]);
    rstheader_.ptr_load_ = SwitchEndian(buf[14]);
    rstheader_.ptr_elm_ = SwitchEndian(buf[15]);
    rstheader_.ptr_node_ = SwitchEndian(buf[16]);
    rstheader_.ptr_geo_ = SwitchEndian(buf[17]);
    rstheader_.units_ = SwitchEndian(buf[21]);
    rstheader_.numsectors_ = SwitchEndian(buf[22]);
    rstheader_.ptr_end_ = 0;

    if (SwitchEndian_ == DO_NOT_SWITCH)
    {
        rstheader_.ptr_end_ = (long long)(buf[23]) << 32 | buf[24];
    }
    else
    {
        rstheader_.ptr_end_ = (long long)(SwitchEndian(buf[24])) << 32 | SwitchEndian(buf[23]);
    }
    delete[] buf;
    // Header fertig gelesen

    // Jetzt noch die Indextabellen laden
    int true_used_nodes;
    if (header_.version_ < 10)
    {
        int offset = rstheader_.ptr_node_ * sizeof(int);
        int buf[2];
        fseek(rfp_, offset, SEEK_SET);
        IntRecord(buf, 2);
        true_used_nodes = buf[1];
        if (true_used_nodes > rstheader_.usednodes_)
        {
            true_used_nodes = rstheader_.usednodes_;
        }
    }
    else
    {
        true_used_nodes = rstheader_.usednodes_;
    }

    int offset = (rstheader_.ptr_node_ + 2) * sizeof(int);
    fseek(rfp_, offset, SEEK_SET);

    nodeindex_ = new int[true_used_nodes /* rstheader_.usednodes_ */];
    // NEW
    // if(IntRecord(nodeindex_,rstheader_.usednodes_) != rstheader_.usednodes_){
    if (IntRecord(nodeindex_, true_used_nodes) != true_used_nodes)
    {
        return (3);
    }

    // das selbe für die Elemente
    offset = (rstheader_.ptr_elm_ + 2) * sizeof(int);
    fseek(rfp_, offset, SEEK_SET);
    elemindex_ = new int[rstheader_.numelement_];
    if (IntRecord(elemindex_, rstheader_.numelement_) != rstheader_.numelement_)
    {
        return (3);
    }

    // Timetable lesen
    timetable_ = new double[rstheader_.maxres_];
    offset = (rstheader_.ptr_time_ + 2) * sizeof(int);
    fseek(rfp_, offset, SEEK_SET);
    if (DoubleRecord(timetable_, rstheader_.maxres_)
        != rstheader_.maxres_)
    {
        return (6);
    }

    // That's all folks
    return (0);
}
Exemplo n.º 3
0
static BOOL
OrgLoadImplicitLittleEndian(DICOMDataObject* pDDO, FILE* fp, unsigned int iVrSizeLimit)
{
	DICOMDataObject*	pNewDDO;
	VR*					pVR;
	char				Buf[2 + 2 + 4];

	while (fread(Buf, 1, sizeof(Buf), fp) == sizeof(Buf))
	{
		/* Group, Element and Size could be read */
		pVR = new VR;
		if (!pVR)
			return FALSE;
#if NATIVE_ENDIAN == LITTLE_ENDIAN //Little Endian
		pVR->Group   = *((unsigned short*) Buf);
		pVR->Element = *((unsigned short*)(Buf + 2));
		pVR->Length  = *((unsigned int*)  (Buf + 2 + 2));
#else //Big Endian like Apple power pc
		pVR->Group   = SwitchEndian( *((UINT16*) Buf));
		pVR->Element = SwitchEndian( *((UINT16*)(Buf + 2)));
		pVR->Length  = SwitchEndian( *((UINT32*)  (Buf + 2 + 2)));
#endif //Big Endian

		if (pVR->Group == 0xfffe)
		{
			/* A deliminator */
			if ((pVR->Element == 0xe0dd) || (pVR->Element == 0xe00d))
			{
				delete pVR;
				return TRUE;
			}
			if (pVR->Length == 0xffffffff)
			{
				/* Implicit length... Go until deliminator */
				pVR->Length = 0;
				delete pVR;
				pNewDDO = new DICOMDataObject;
				if (OrgLoadImplicitLittleEndian(pNewDDO, fp, iVrSizeLimit))
				{
					pDDO->Push(pNewDDO);
					continue;
				}
				else
				{
					delete pNewDDO;
					return FALSE;
				}
			}
			if (pVR->Element == 0xe000)
			{
				/* Sequence begin ? */
				pVR->Length = 0;
				delete pVR;
				pNewDDO = new DICOMDataObject;
				if (OrgLoadImplicitLittleEndian(pNewDDO, fp, iVrSizeLimit))
				{
					pDDO->Push(pNewDDO);
					continue;
				}
				else
				{
					delete pNewDDO;
					return FALSE;
				}
			}
		}
		if (pVR->Length == 0xffffffff)
		{
			pVR->Length = 0;
			pDDO->Push(pVR);
			if (!OrgLoadImplicitLittleEndian(pDDO, fp, iVrSizeLimit))
				return FALSE;
			continue;
		}
		/* Check whether the current VR has to be read.
		   NKI DicomNodes can restrict what has to be read
		   Following code assumes that reading is finished when pixeldata
		   are encountered. (Maybe a problem here!!!)
		*/
		if (pVR->Length > iVrSizeLimit)
		{
			if (((pVR->Group == 0x7fdf) || (pVR->Group == 0x7fe0)) &&
				(pVR->Element == 0x0010))
			{
				/* Ready !? */
				pVR->Length = 0;
				delete pVR;
				return TRUE;
			}
			else
			{	/* Read it, throw it away and continue */
//				pVR->Data = new char [pVR->Length];
				pVR->ReAlloc(pVR->Length);
				if (!pVR->Data)
					return FALSE;
				fread(pVR->Data, 1, pVR->Length, fp);
				delete pVR;
				continue;
			}
		}
		if (pVR->Length)
		{
//			pVR->Data = new char [pVR->Length];
			pVR->ReAlloc(pVR->Length);
			if (!pVR->Data)
				return FALSE;
			fread(pVR->Data, 1, pVR->Length, fp);
/*			if ((pVR->Group == 0x7fdf) && (pVR->Element == 0x0010))
			{ 
				VR* v;
				signed char *CompressedData = ((signed char *)(pVR->Data));
				int UncompressedLength = get_nki_private_decompressed_length(CompressedData);
				v = new VR(0x7fe0, 0x0010, UncompressedLength, TRUE);
     				nki_private_decompress((short *)(v->Data), CompressedData);
				delete pVR;
				pVR = v;
			}
*/		}
		else
			pVR->Data = NULL;
		pDDO->Push(pVR);
	}
	return TRUE;
}
Exemplo n.º 4
0
static BOOL
LoadImplicitLittleEndian(DICOMDataObject* pDDO, CBufferedIO* pBufferedIO,
	int handle, unsigned int iVrSizeLimit)
{
	DICOMDataObject*	pNewDDO;
	VR*					pVR;
	char				Buf[2 + 2 + 4];

	while (pBufferedIO->read(handle, Buf, sizeof(Buf)) == sizeof(Buf))
	{
		/* Group, Element and Size could be read */
		pVR = new VR;
		if (!pVR)
			return FALSE;
#if NATIVE_ENDIAN == LITTLE_ENDIAN //Little Endian
		pVR->Group   = *((unsigned short*) Buf);
		pVR->Element = *((unsigned short*)(Buf + 2));
		pVR->Length  = *((unsigned int*)  (Buf + 2 + 2));
#else //Big Endian like Apple power pc
		pVR->Group   = SwitchEndian( *((UINT16*) Buf));
		pVR->Element = SwitchEndian( *((UINT16*)(Buf + 2)));
		pVR->Length  = SwitchEndian( *((UINT32*)  (Buf + 2 + 2)));
#endif //Big Endian

		if (pVR->Group == 0xfffe)
		{
			/* A deliminator */
			if ((pVR->Element == 0xe0dd) || (pVR->Element == 0xe00d))
			{
				delete pVR;
				return TRUE;
			}
			if (pVR->Length == 0xffffffff)
			{
				/* Implicit length... Go until deliminator */
				pVR->Length = 0;
				delete pVR;
				pNewDDO = new DICOMDataObject;
				if (LoadImplicitLittleEndian(pNewDDO, pBufferedIO, handle, iVrSizeLimit))
				{
					pDDO->Push(pNewDDO);
					continue;
				}
				else
				{
					delete pNewDDO;
					return FALSE;
				}
			}
			if (pVR->Element == 0xe000)
			{
				/* Sequence begin ? */
				pVR->Length = 0;
				delete pVR;
				pNewDDO = new DICOMDataObject;
				if (LoadImplicitLittleEndian(pNewDDO, pBufferedIO, handle, iVrSizeLimit))
				{
					pDDO->Push(pNewDDO);
					continue;
				}
				else
				{
					delete pNewDDO;
					return FALSE;
				}
			}
		}
		if (pVR->Length == 0xffffffff)
		{
			pVR->Length = 0;
			pDDO->Push(pVR);
			if (!LoadImplicitLittleEndian(pDDO, pBufferedIO, handle, iVrSizeLimit))
				return FALSE;
			continue;
		}
		/* Check whether the current VR has to be read.
		   NKI DicomNodes can restrict what has to be read
		   Following code assumes that reading is finished when pixeldata
		   are encountered. (Maybe a problem here!!!)
		*/
		if (pVR->Length > iVrSizeLimit)
		{
			if (((pVR->Group == 0x7fdf) || (pVR->Group == 0x7fe0)) &&
				(pVR->Element == 0x0010))
			{
				/* Ready !? */
				pVR->Length = 0;
				delete pVR;
				return TRUE;
			}
			else
			{	/* Read it, throw it away and continue */
//				pVR->Data = new char [pVR->Length];
				pVR->ReAlloc(pVR->Length);
				if (!pVR->Data)
					return FALSE;
				pBufferedIO->read(handle, pVR->Data, pVR->Length);
				delete pVR;
				continue;
			}
		}
		if (pVR->Length)
		{
//			pVR->Data = new char [pVR->Length];
			pVR->ReAlloc(pVR->Length);
			if (!pVR->Data)
				return FALSE;
			pBufferedIO->read(handle, pVR->Data, pVR->Length);
		}
		else
			pVR->Data = NULL;
		pDDO->Push(pVR);
	}
	return TRUE;
}
Exemplo n.º 5
0
static BOOL
SaveDDO(DICOMDataObject* DDOPtr, FILE* fp, int FileCompressMode)
{
	VR	*TempVR;
#if NATIVE_ENDIAN == BIG_ENDIAN //Big Endian like Apple power pc
	UINT16	beGroup, beElement;
	UINT32	beLength;
#endif //Big Endian

	while(TempVR = DDOPtr->Pop())
	{
		if(TempVR->Group==0x7fe0 && TempVR->Element==0x0010 && FileCompressMode)
		{
			int DataLength;
			short CompressedGroup = 0x7fdf, CompressedElement = 0x0010;
			signed char *CompressedData;

			CompressedData = new signed char [(TempVR->Length/2) * 3 + 10];

			DataLength = nki_private_compress(CompressedData, (short int *)(TempVR->Data), TempVR->Length/2, FileCompressMode);
			if (!CompressedData)
			{
				OperatorConsole.printf("***Out of memory NKI-compress");
				return FALSE;
			}

			if (DataLength&1)
				CompressedData[DataLength++] = 0;

#if NATIVE_ENDIAN == LITTLE_ENDIAN //Little Endian
			fwrite(&CompressedGroup,   1, 2, fp);
			fwrite(&CompressedElement, 1, 2, fp);
			fwrite(&DataLength,        1, 4, fp);
#else //Big Endian like Apple power pc
			beGroup = SwitchEndian((UINT16) CompressedGroup);
			beElement = SwitchEndian((UINT16) CompressedElement);
			beLength = SwitchEndian((UINT32) DataLength);
			fwrite(&beGroup,   1, 2, fp);
			fwrite(&beElement, 1, 2, fp);
			fwrite(&beLength,  1, 4, fp);
#endif //Big Endian

			if (fwrite(CompressedData, 1, DataLength, fp) != (unsigned int)DataLength)
			{
				free(CompressedData);
				OperatorConsole.printf("***Failed to save compressed pixel data (disk full?)");
				return FALSE;
			}

			delete [] CompressedData;
		}
		else
		{
#if NATIVE_ENDIAN == LITTLE_ENDIAN //Little Endian
			fwrite(&TempVR->Group, 1, 2, fp);
			fwrite(&TempVR->Element, 1, 2, fp);
			fwrite(&TempVR->Length, 1, 4, fp);
#else //Big Endian like Apple power pc
			beGroup = SwitchEndian((UINT16) TempVR->Group);
			beElement = SwitchEndian((UINT16) TempVR->Element);
			beLength = SwitchEndian((UINT32) TempVR->Length);
			fwrite(&beGroup,   1, 2, fp);
			fwrite(&beElement, 1, 2, fp);
			fwrite(&beLength,  1, 4, fp);
#endif //Big Endian
			if(TempVR->Length)
			{
				if(!TempVR->Data)
				{
					OperatorConsole.printf("***Missing data in VR (0x%04x,0x%04x)",
						TempVR->Group, TempVR->Element);
					return FALSE;
				}
				fwrite(TempVR->Data, 1, TempVR->Length, fp);
			}
		}
		delete TempVR;
	}
	return TRUE;	
}