internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { //Sometimes there's 0-length ATs... uint readCount = length; if (readCount >= 2) { encapgroup = br.ReadUInt16(); readCount -= 2; } else { encapgroup = 0; } if (readCount >= 2) { encapelem = br.ReadUInt16(); readCount -= 2; } else { encapelem = 0; } br.ReadBytes((int)readCount); return(length); }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { //Store it as LSB-ordered bytes for optimization //Maybe down the line add some optimized way to modify a word array if it looks like a user's gonna be doing that a lot for some reason Data = br.ReadWords((int)length); return(this.length); }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { //reuse the setter! byte[] data = br.ReadBytesUpToMax((int)length); Data = data; return((uint)data.Length); }
internal uint ParseStream(SwappableBinaryReader br, ILogger logger, TransferSyntax transferSyntax, uint length, bool encapImage) { IsEncapsulatedImage = encapImage; if (encapImage && length != 0xFFFFFFFF) { //Encapsulated Image with explicit length! EncapsulatedImageData = br.ReadBytes((int)length); //Any way to figure out if we need to MSB-swap this? (i.e. is it an OW or an OB? Does that come from the parent element?) return(length); } bool done = false; uint count = 0; while (!done) { //Check if we're past the end yet if (length != 0xFFFFFFFF && count >= length) { done = true; continue; } long readPosition = br.BaseStream.Position; //Read in group/element info ushort group = br.ReadUInt16(); ushort elem = br.ReadUInt16(); count += 4; //Make element uint outLen; DICOMElement nelem = DICOMElement.Parse(group, elem, logger, transferSyntax, br, this, false, out outLen); //Store reading position in case it's useful later nelem.ReadPosition = readPosition; count += outLen; //Was that the end-of-sequence item? if (group == 0xFFFE && elem == 0xE00D) { done = true; } else { ElementsLookup[nelem.Tag] = nelem; Elements.Add(nelem); } } return(count); }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { if (length < 8) { data = 0; br.ReadBytes((int)length); } else { data = br.ReadDouble(); if (length > 8) { br.ReadBytes((int)length - 8); } } return(length); }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { if (length < 2) { //busted... data = (ushort)0; br.ReadBytes((int)length); } else if (length == 2) { data = br.ReadUInt16(); } else if (length > 2) { uint readBytes = 0; DataDictionaryElement elemCheck = DataDictionary.LookupElement(this.Tag); if (elemCheck == null || elemCheck.VMMax > 1) { //Unknown VM or VM goes to > 1 data = new ushort[length / 2]; for (int i = 0; i < length / 2; i++) { ((ushort[])data)[i] = br.ReadUInt16(); } readBytes = (length / 2) * 2; } else { //VM of 1 -- force to single data point data = br.ReadUInt16(); readBytes = 2; } if (length - readBytes > 0) { br.ReadBytes((int)(length - readBytes)); } } return(length); }
internal void ParsePacket(SwappableBinaryReader dataSource, int itemLength) { long startOffset = dataSource.BaseStream.Position; ContextID = dataSource.ReadByte(); byte reserved = dataSource.ReadByte(); Result = (PresentationResult)dataSource.ReadByte(); reserved = dataSource.ReadByte(); while (dataSource.BaseStream.Position - startOffset < itemLength) { //read sub-item byte subItemType = dataSource.ReadByte(); byte subItemReserved = dataSource.ReadByte(); ushort subItemLength = dataSource.ReadUInt16(); if (subItemType == 0x30) { string rawSyntax = Uid.UidRawToString(dataSource.ReadBytes(subItemLength)); AbstractSyntaxSpecified = AbstractSyntaxes.Lookup(rawSyntax); } else if (subItemType == 0x40) { string rawSyntax = Uid.UidRawToString(dataSource.ReadBytes(subItemLength)); TransferSyntax syntax = TransferSyntaxes.Lookup(rawSyntax); if (syntax != null) { TransferSyntaxesProposed.Add(syntax); } } else { //no idea what it is, or we don't care dataSource.ReadBytes(itemLength); } } }
internal bool ParseStream(Stream stream, TransferSyntax transferSyntax, bool allowSyntaxChanges, bool loadImageData, ILogger logger) { SwappableBinaryReader sr = new SwappableBinaryReader(stream); long readPosition = stream.Position; bool inGroup2 = false; if (transferSyntax.MSBSwap) //this should be applicable... { sr.ToggleSwapped(); } TransferSyntax parsedSyntax = null; while (readPosition + 8 < stream.Length) { //Read in group/element info ushort group = sr.ReadUInt16(); ushort elem = sr.ReadUInt16(); //Leaving the header? if (inGroup2 != (group == 2)) { if (transferSyntax.MSBSwap) { sr.ToggleSwapped(); } inGroup2 = (group == 2); } //Stop loading if we're at image data and not supposed to read it var skipData = !loadImageData && group == 0x7FE0 && elem == 0x0010; //Make element uint outLen; DICOMElement nelem; try { nelem = DICOMElement.Parse(group, elem, logger, transferSyntax, sr, null, skipData, out outLen); } catch (Exception e) { logger.Log(LogLevel.Error, "Exception in DICOMElement.Parse: " + e.ToString()); return(false); } //Debugging: //Console.WriteLine(nelem.Dump()); //Store reading position in case it's useful later nelem.ReadPosition = readPosition; //Store element in lookup array Elements[nelem.Tag] = nelem; //Store transfer syntax change for after the header if (nelem.Tag == DICOMTags.TransferSyntaxUID) { parsedSyntax = TransferSyntaxes.Lookup((string)nelem.Data); if (allowSyntaxChanges) { transferSyntax = parsedSyntax; } } //update read position pointer readPosition = stream.Position; } //Store whatever TS we ended up with TransferSyntax = (parsedSyntax != null) ? parsedSyntax : transferSyntax; return(true); }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { //reuse setter Data = System.Text.Encoding.ASCII.GetString(br.ReadBytes((int)length)); return(length); }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { //Covered by PS 3.5, Chapter 7.5 (pg. 42-45) bool encapImage = (Tag == DICOMTags.PixelData); bool done = false; uint count = 0; while (!done) { //If explicit length, see if we're done if (length != 0xFFFFFFFF && count >= length) { done = true; continue; } ushort grp = br.ReadUInt16(); ushort elem = br.ReadUInt16(); uint len = br.ReadUInt32(); count += 8; //Sometimes there's retarded files that are msb swapped inside of sequences outside of the transfer syntax bool needMoreSwap = (grp == 0xFEFF); if (needMoreSwap) { //Swap the reader for now, then swap back after the sqitem br.ToggleSwapped(); //still have to swap the stuff we've already read by hand tho grp = MSBSwapper.SwapW(grp); elem = MSBSwapper.SwapW(elem); len = MSBSwapper.SwapDW(len); } if (grp == 0xFFFE && elem == 0xE000) { //Normal element, parse it out. SQItem item = new SQItem(this); count += item.ParseStream(br, logger, transferSyntax, len, encapImage); Items.Add(item); } else if (grp == 0xFFFE && elem == 0xE0DD) { //End element //In case there's garbage in there, read the length bytes br.ReadBytes((int)len); count += len; done = true; } else { throw new NotImplementedException(); } //toggle back in case it's just one SQItem that's hosed if (needMoreSwap) { br.ToggleSwapped(); } } return(count); }
abstract internal uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax);
//parseLen returns total bytes read internal static DICOMElement Parse(ushort group, ushort elem, ILogger logger, TransferSyntax transferSyntax, SwappableBinaryReader br, SQItem parentSQ, bool skipOverData, out uint parseLen) { ushort vr; uint len; uint headerBytes = 0; // Group 0 is always little-endian implicit vr, group 2 is always little-endian explicit vr if ((transferSyntax.ExplicitVR && group != 0) || group == 2) { vr = br.ReadUInt16MSB(); headerBytes += 2; if (vr == DICOMElementUT.vrshort || vr == DICOMElementUN.vrshort || vr == DICOMElementOB.vrshort || vr == DICOMElementOW.vrshort || vr == DICOMElementSQ.vrshort) { //next 2 bytes reserved br.ReadUInt16(); headerBytes += 2; //len is next 4 len = br.ReadUInt32(); headerBytes += 4; } else { //len is next 2 len = br.ReadUInt16(); headerBytes += 2; } } else { //Look up VR in the dictionary DataDictionaryElement dde = DataDictionary.LookupElement(group, elem); if (dde != null) { //Found it. vr = dde.vrshort; } else { //No idea... OB! vr = DICOMElementOB.vrshort; } //Length will always be 32-bit here len = br.ReadUInt32(); headerBytes += 4; } DICOMElement ret = null; //Is it a compressed weirdo image data sequence that's actually an SQ? if (len == 0xFFFFFFFF) { ret = new DICOMElementSQ(group, elem); } else { ret = CreateByVR(group, elem, vr); } ret.parentSQItem = parentSQ; //Parse internal Data parseLen = headerBytes; try { // Can't skip over the length if it's not explicit if (skipOverData && len != 0xFFFFFFFF) { parseLen += len; br.BaseStream.Seek(len, SeekOrigin.Current); } else { parseLen += ret.ParseData(br, logger, len, transferSyntax); } } catch (Exception e) { logger.Log(LogLevel.Error, "Exception in ParseData(grp=" + group + ", elem=" + elem + ", len=" + len + "): " + e.ToString()); } return(ret); }
internal PresentationContext(SwappableBinaryReader dataSource, int itemLength) : this() { ParsePacket(dataSource, itemLength); }