/// <summary> /// Extracts the palette color LUT from DICOM dataset, valid for PALETTE COLOR <seealso cref="PhotometricInterpretation"/> /// </summary> /// <returns>Palette color LUT</returns> /// <exception cref="DicomImagingException">Invalid photometric interpretation or plaette color lUT missing from database</exception> private Color32[] GetPaletteColorLUT() { if (PhotometricInterpretation != PhotometricInterpretation.PaletteColor) { throw new DicomImagingException( "Attempted to get Palette Color LUT from image with invalid photometric interpretation."); } if (!Dataset.Contains(DicomTag.RedPaletteColorLookupTableDescriptor)) { throw new DicomImagingException("Palette Color LUT missing from dataset."); } int size = Dataset.Get <int>(DicomTag.RedPaletteColorLookupTableDescriptor, 0); int first = Dataset.Get <int>(DicomTag.RedPaletteColorLookupTableDescriptor, 1); int bits = Dataset.Get <int>(DicomTag.RedPaletteColorLookupTableDescriptor, 2); var r = Dataset.Get <byte[]>(DicomTag.RedPaletteColorLookupTableData); var g = Dataset.Get <byte[]>(DicomTag.GreenPaletteColorLookupTableData); var b = Dataset.Get <byte[]>(DicomTag.BluePaletteColorLookupTableData); // If the LUT size is 0, that means it's 65536 in size. if (size == 0) { size = 65536; } var lut = new Color32[size]; if (r.Length == size) { // 8-bit LUT entries for (int i = 0; i < size; i++) { lut[i] = new Color32(0xff, r[i], g[i], b[i]); } } else { // 16-bit LUT entries... we only support 8-bit until someone can find a sample image with a 16-bit palette // 8-bit entries with 16-bits allocated int offset = 0; // 16-bit entries with 8-bits stored if (bits == 16) { offset = 1; } for (int i = 0; i < size; i++, offset += 2) { lut[i] = new Color32(0xff, r[offset], g[offset], b[offset]); } } return(lut); }
/// <summary> /// Create image rendering pipeline according to the Dataset <see cref="PhotometricInterpretation"/>. /// </summary> private void CreatePipeline() { if (_pipeline != null) { return; } var pi = Dataset.Get <PhotometricInterpretation>(DicomTag.PhotometricInterpretation); var samples = Dataset.Get <ushort>(DicomTag.SamplesPerPixel, 0, 0); // temporary fix for JPEG compressed YBR images if ((Dataset.InternalTransferSyntax == DicomTransferSyntax.JPEGProcess1 || Dataset.InternalTransferSyntax == DicomTransferSyntax.JPEGProcess2_4) && samples == 3) { pi = PhotometricInterpretation.Rgb; } // temporary fix for JPEG 2000 Lossy images if (pi == PhotometricInterpretation.YbrIct || pi == PhotometricInterpretation.YbrRct) { pi = PhotometricInterpretation.Rgb; } if (pi == null) { // generally ACR-NEMA if (samples == 0 || samples == 1) { if (Dataset.Contains(DicomTag.RedPaletteColorLookupTableData)) { pi = PhotometricInterpretation.PaletteColor; } else { pi = PhotometricInterpretation.Monochrome2; } } else { // assume, probably incorrectly, that the image is RGB pi = PhotometricInterpretation.Rgb; } } if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2) { //Monochrom1 or Monochrome2 for grayscale image if (_renderOptions == null) { _renderOptions = GrayscaleRenderOptions.FromDataset(Dataset); } _pipeline = new GenericGrayscalePipeline(_renderOptions); } else if (pi == PhotometricInterpretation.Rgb) { //RGB for color image _pipeline = new RgbColorPipeline(); } else if (pi == PhotometricInterpretation.PaletteColor) { //PALETTE COLOR for Palette image _pipeline = new PaletteColorPipeline(PixelData); } else { throw new DicomImagingException("Unsupported pipeline photometric interpretation: {0}", pi.Value); } }
private IByteBuffer Load() { var tag = OverlayTag(DicomTag.OverlayData); if (Dataset.Contains(tag)) { var elem = Dataset.FirstOrDefault(x => x.Tag == tag) as DicomElement; return(elem.Buffer); } else { // overlay embedded in high bits of pixel data if (Dataset.InternalTransferSyntax.IsEncapsulated) { throw new DicomImagingException("Attempted to extract embedded overlay from compressed pixel data. Decompress pixel data before attempting this operation."); } var pixels = DicomPixelData.Create(Dataset); // (1,1) indicates top left pixel of image int ox = Math.Max(0, OriginX - 1); int oy = Math.Max(0, OriginY - 1); int ow = Rows - (pixels.Width - Rows - ox); int oh = Columns - (pixels.Height - Columns - oy); var frame = pixels.GetFrame(0); var bits = new BitList(); bits.Capacity = Rows * Columns; int mask = 1 << BitPosition; if (pixels.BitsAllocated == 8) { var data = ByteBufferEnumerator <byte> .Create(frame).ToArray(); for (int y = oy; y < oh; y++) { int n = (y * pixels.Width) + ox; int i = (y - oy) * Columns; for (int x = ox; x < ow; x++) { if ((data[n] & mask) != 0) { bits[i] = true; } n++; i++; } } } else if (pixels.BitsAllocated == 16) { // we don't really care if the pixel data is signed or not var data = ByteBufferEnumerator <ushort> .Create(frame).ToArray(); for (int y = oy; y < oh; y++) { int n = (y * pixels.Width) + ox; int i = (y - oy) * Columns; for (int x = ox; x < ow; x++) { if ((data[n] & mask) != 0) { bits[i] = true; } n++; i++; } } } else { throw new DicomImagingException("Unable to extract embedded overlay from pixel data with bits stored greater than 16."); } return(new MemoryByteBuffer(bits.Array)); } }
private IByteBuffer Load() { var tag = OverlayTag(DicomTag.OverlayData); if (Dataset.Contains(tag)) { var elem = Dataset.FirstOrDefault(x => x.Tag == tag) as DicomElement; return(elem.Buffer); } else { // overlay embedded in high bits of pixel data if (Dataset.InternalTransferSyntax.IsEncapsulated) { throw new DicomImagingException( "Attempted to extract embedded overlay from compressed pixel data. Decompress pixel data before attempting this operation."); } var pixels = DicomPixelData.Create(Dataset); // (1,1) indicates top left pixel of image int ox = Math.Max(0, OriginX - 1); int oy = Math.Max(0, OriginY - 1); int ow = Columns; int oh = Rows; var frame = pixels.GetFrame(0); var bits = new BitList(); bits.Capacity = Rows * Columns; int mask = 1 << BitPosition; // Sanity check: do not collect overlay data if Overlay Bit Position is within the used pixel range. (#110) if (this.BitPosition <= pixels.HighBit && this.BitPosition > pixels.HighBit - pixels.BitsStored) { // Do nothing } else if (pixels.BitsAllocated == 8) { var data = IO.ByteConverter.ToArray <byte>(frame); for (int y = 0; y < oh; y++) { int n = (y + oy) * pixels.Width + ox; int i = y * Columns; for (int x = 0; x < ow; x++) { if ((data[n] & mask) != 0) { bits[i] = true; } n++; i++; } } } else if (pixels.BitsAllocated == 16) { // we don't really care if the pixel data is signed or not var data = IO.ByteConverter.ToArray <ushort>(frame); for (int y = 0; y < oh; y++) { int n = (y + oy) * pixels.Width + ox; int i = y * Columns; for (int x = 0; x < ow; x++) { if ((data[n] & mask) != 0) { bits[i] = true; } n++; i++; } } } else { throw new DicomImagingException( "Unable to extract embedded overlay from pixel data with bits stored greater than 16."); } return(new MemoryByteBuffer(bits.Array)); } }
async Task ExecuteLoadDataCommand() { if (IsBusy) { return; } IsBusy = true; try { Dataset.Clear(); //var dataset = await SQLDataStore.GetAllAsync_Creature(true); if (CharactersViewModel.Instance.Dataset.Count == 0) { CharactersViewModel.Instance.LoadDataCommand.Execute(null); } else if (CharactersViewModel.Instance.NeedsRefresh()) { CharactersViewModel.Instance.LoadDataCommand.Execute(null); } var dataset = CharactersViewModel.Instance.GetAllCreatures(); int teamCount = 0; foreach (var data in dataset) { if ((data.Type == 0) && (teamCount < 6) && data.OnTeam)//the creature is a character, the team is not full, and it is on the current team { teamCount++; Dataset.Add(data); } } if (teamCount < 6) { foreach (var data in dataset) //if the team is not full more characters must be added { if ((data.Type == 0) && (teamCount < 6) && !Dataset.Contains(data)) //the creature is a character, the team is not full, and the character is not in the team { teamCount++; data.OnTeam = true; Dataset.Add(data); } } } if (teamCount < 6)//if you didn't make enough characters you get some sucky ones { int numOfSuckyCharacters = 0; for (int i = teamCount; i < 6; i++) { numOfSuckyCharacters++; Creature character = new Creature(); character.Type = 0; character.OnTeam = true; character.Name = "Sucky Character " + numOfSuckyCharacters.ToString(); character.Attack = 1; character.Defense = 1; character.Speed = 1; character.MaxHealth = 1; character.CurrHealth = character.MaxHealth; Dataset.Add(character); await DataStore.AddAsync_Creature(character); } } // ***temp for demo*** foreach (var data in Dataset) { data.RHandItemID = "bow"; data.LHandItemID = "bow"; } } catch (Exception ex) { Debug.WriteLine(ex); } finally { IsBusy = false; } }