1. 程式人生 > >Dicom學習之一:大尾和小尾LittleEndian/BigEndian

Dicom學習之一:大尾和小尾LittleEndian/BigEndian

是否進行交換的條件:是本地的編碼方式是否和dicom檔案的編碼方式不同,如是,就需要進行交換。

交換的原則:

        按照格式化入dicom資料集流中的基本資料單元而定的,如是ss us,那麼,就需要按照兩個位元組進行交換,用swap2Bytes函式;如是ul sl,那麼就按照四個位元組進行交換,利用函式swap4Bytes來進行。

       首先是Tag,預設tag是分成兩步格式化進dicom檔案二進位制流中,是Group Tag和Element Tag的兩個部分進行。所以讀取的過程中,就是要分成兩步,分別把兩個位元組讀取出來後,最後在進行資料的交換。

      但是對於VR值,由於它是一個字串,寫入的時候,最基本單元是一個byte,所以不用進行大小尾的交換。

      同理,字元長度也需要進行交換。

      再同理,資料的值也是根據寫入的最基本資料單元進行的。

以下是dcmtk中的函式:

//其中,newByteOrder:EBO_LittleEndian
// oldByteOrder: EBO_BigEndian 
OFCondition swapIfNecessary(const E_ByteOrder newByteOrder,
			    const E_ByteOrder oldByteOrder,
			    void * value, const Uint32 byteLength,
			    const size_t valWidth)
    /*
     * This function swaps byteLength bytes in value if newByteOrder and oldByteOrder
     * differ from each other. In case bytes have to be swapped, these bytes are seperated
     * in valWidth elements which will be swapped seperately.
     *
     * Parameters:
     *   newByteOrder - [in] The new byte ordering (little or big endian).
     *   oldByteOrder - [in] The current old byte ordering (little or big endian).
     *   value        - [in] Array that contains the actual bytes which might have to be swapped.
     *   byteLength   - [in] Length of the above array.
     *   valWidth     - [in] Specifies how many bytes shall be treated together as one element.
     */
{
    /* if the two byte orderings are unknown this is an illegal call */
    if(oldByteOrder != EBO_unknown && newByteOrder != EBO_unknown )
    {
        /* and if they differ from each other and valWidth is not 1 */
	if (oldByteOrder != newByteOrder && valWidth != 1)
	{
            /* in case the array length equals valWidth and only 2 or 4 bytes have to be swapped */
            /* we can swiftly swap these bytes by calling the corresponding functions. If this is */
            /* not the case we have to call a more sophisticated function. */
	    if (byteLength == valWidth)
	    {
		if (valWidth == 2)
		    swap2Bytes(OFstatic_cast(Uint8 *, value));
		else if (valWidth == 4)
		    swap4Bytes(OFstatic_cast(Uint8 *, value));
		else
		    swapBytes(value, byteLength, valWidth);
	    }
	    else
		swapBytes(value, byteLength, valWidth);
	}
	return EC_Normal;
    }
    return EC_IllegalCall;
}

inline void swap2Bytes(Uint8 * toSwap)
// swaps [byte0][byte1] to [byte1][byte0]
{
    Uint8 tmp = toSwap[0];
    toSwap[0] = toSwap[1];
    toSwap[1] = tmp;
}
inline void swap4Bytes(Uint8 * toSwap)
// swaps [byte0][byte1][byte2][byte3] to [byte3][byte2][byte1][byte0]
{
    Uint8 tmp = toSwap[0];
    toSwap[0] = toSwap[3];
    toSwap[3] = tmp;
    tmp = toSwap[1];
    toSwap[1] = toSwap[2];
    toSwap[2] = tmp;
}