Skip to content

Commit

Permalink
OME Slides Fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
BiologyTools committed Apr 28, 2024
1 parent 75dc4c2 commit 83e49aa
Show file tree
Hide file tree
Showing 5 changed files with 477 additions and 105 deletions.
107 changes: 47 additions & 60 deletions BioCore/Source/Bio.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5969,20 +5969,20 @@ public async void UpdateBuffersPyramidal()
}
else
{
start:
int l = LevelFromResolution(resolution);
byte[] bts = await slideBase.GetSlice(new SliceInfo(PyramidalOrigin.X, PyramidalOrigin.Y, PyramidalSize.Width, PyramidalSize.Height, resolution, new ZCT()));
if (bts == null)
if (Resolutions[l].PixelFormat == PixelFormat.Format24bppRgb)
{
if (PyramidalOrigin.X == 0 && PyramidalOrigin.Y == 0)
{
Resolution = 1;
}
pyramidalOrigin = new PointD(0, 0);
goto start;
BufferInfo bf = new BufferInfo((int)Math.Round(SlideBase.destExtent.Width), (int)Math.Round(SlideBase.destExtent.Height), PixelFormat.Format24bppRgb, bts, new ZCT(), "");
bf.Stats = Statistics.FromBytes(bf);
Buffers.Add(bf);
}
else
{
BufferInfo bf = new BufferInfo((int)Math.Round(SlideBase.destExtent.Width), (int)Math.Round(SlideBase.destExtent.Height), PixelFormat.Format16bppGrayScale, bts, new ZCT(), "");
bf.Stats = Statistics.FromBytes(bf);
Buffers.Add(bf);
}
BufferInfo bf = new BufferInfo((int)Math.Round(SlideBase.destExtent.Width), (int)Math.Round(SlideBase.destExtent.Height), PixelFormat.Format24bppRgb, bts, new ZCT(), "");
bf.Stats = Statistics.FromBytes(bf);
Buffers.Add(bf);
}
}
BioImage.AutoThreshold(this, false);
Expand Down Expand Up @@ -10169,24 +10169,24 @@ public static BioImage OpenOME(string file, int serie, bool tab, bool addToImage

b.Buffers = new List<BufferInfo>();
if (b.Type == ImageType.pyramidal)
try
try
{
string st = OpenSlideImage.DetectVendor(file);
if (st != null && !file.EndsWith("ome.tif") && useOpenSlide)
{
string st = OpenSlideImage.DetectVendor(file);
if (st != null && !file.EndsWith("ome.tif") && useOpenSlide)
{
b.openSlideImage = OpenSlideImage.Open(file);
b.openSlideBase = (OpenSlideBase)OpenSlideGTK.SlideSourceBase.Create(file);
}
else
{
b.slideBase = new SlideBase(b,SlideImage.Open(b));
}
b.openSlideImage = OpenSlideImage.Open(file);
b.openSlideBase = (OpenSlideBase)OpenSlideGTK.SlideSourceBase.Create(file);
}
catch (Exception e)
else
{
Console.WriteLine(e.Message.ToString());
b.slideBase = new SlideBase(b,SlideImage.Open(b));
}
}
catch (Exception e)
{
Console.WriteLine(e.Message.ToString());
b.slideBase = new SlideBase(b,SlideImage.Open(b));
}

// read the image data bytes
int pages = reader.getImageCount();
Expand All @@ -10195,52 +10195,39 @@ public static BioImage OpenOME(string file, int serie, bool tab, bool addToImage
int c = 0;
int t = 0;
pr.Status = "Reading Image Data";
if (!tile)
try
{
try
for (int p = 0; p < pages; p++)
{
for (int p = 0; p < pages; p++)
{
BufferInfo bf;
pr.UpdateProgressF((float)p / (float)pages);
byte[] bytes = reader.openBytes(p);
bf = new BufferInfo(file, SizeX, SizeY, PixelFormat, bytes, new ZCT(z, c, t), p, null, b.littleEndian, inter);
b.Buffers.Add(bf);
}
BufferInfo bf;
pr.UpdateProgressF((float)p / (float)pages);
byte[] bytes = reader.openBytes(p);
bf = new BufferInfo(file, SizeX, SizeY, PixelFormat, bytes, new ZCT(z, c, t), p, null, b.littleEndian, inter);
b.Buffers.Add(bf);
}
catch (Exception)
}
catch (Exception ex)
{
//If we failed to read an entire plane it is likely too large so we open as pyramidal.
b.Type = ImageType.pyramidal;
try
{
//If we failed to read an entire plane it is likely too large so we open as pyramidal.
b.Type = ImageType.pyramidal;
try
string st = OpenSlideImage.DetectVendor(file);
if (st != null && !file.EndsWith("ome.tif") && useOpenSlide)
{
string st = OpenSlideImage.DetectVendor(file);
if (st != null && !file.EndsWith("ome.tif") && useOpenSlide)
{
b.openSlideImage = OpenSlideImage.Open(file);
b.openSlideBase = (OpenSlideBase)OpenSlideGTK.SlideSourceBase.Create(file);
}
else
{
b.slideBase = new SlideBase(b, SlideImage.Open(b));
}
b.openSlideImage = OpenSlideImage.Open(file);
b.openSlideBase = (OpenSlideBase)OpenSlideGTK.SlideSourceBase.Create(file);
}
catch (Exception e)
else
{
Console.WriteLine(e.Message.ToString());
b.slideBase = new SlideBase(b, SlideImage.Open(b));
}
b.imRead = reader;
for (int p = 0; p < pages; p++)
{
b.Buffers.Add(GetTile(b, p, serie, tilex, tiley, tileSizeX, tileSizeY));
Statistics.CalcStatistics(b.Buffers.Last());
}
}

}
else
{
catch (Exception e)
{
Console.WriteLine(e.Message.ToString());
b.slideBase = new SlideBase(b, SlideImage.Open(b));
}
b.imRead = reader;
for (int p = 0; p < pages; p++)
{
Expand Down
78 changes: 58 additions & 20 deletions BioCore/Source/Bio/ISlideSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using AForge;
using Image = SixLabors.ImageSharp.Image;
namespace BioCore
{
public class LruCache<TileInformation, TValue>
Expand Down Expand Up @@ -62,6 +63,13 @@ public void Add(Info key, TValue value)
lruList.AddLast(newNode);
cacheMap[key] = newNode;
}
public void Dispose()
{
foreach (LinkedListNode<(Info key, TValue value)> item in cacheMap.Values)
{
lruList.Remove(item);
}
}
}
public class TileCache
{
Expand Down Expand Up @@ -110,6 +118,10 @@ private async Task<byte[]> LoadTile(TileInformation tileId)
return null;
}
}
public void Dispose()
{
cache.Dispose();
}
}

public class TileInformation
Expand Down Expand Up @@ -160,7 +172,6 @@ public static ISlideSource Create(BioImage source, SlideImage im, bool enableCac
}
#endregion
public double MinUnitsPerPixel { get; protected set; }
public static byte[] LastSlice;
public static Extent destExtent;
public static Extent sourceExtent;
public static double curUnitsPerPixel = 1;
Expand Down Expand Up @@ -194,9 +205,12 @@ public async Task<byte[]> GetSlice(SliceInfo sliceInfo)
{
try
{
NetVips.Image im = OpenSlideGTK.ImageUtil.JoinVips(tiles, srcPixelExtent, new Extent(0, 0, dstPixelWidth, dstPixelHeight));
LastSlice = im.WriteToMemory();
return LastSlice;
NetVips.Image im = null;
if (this.Image.BioImage.Resolutions[curLevel].PixelFormat == System.Drawing.Imaging.PixelFormat.Format16bppGrayScale)
im = ImageUtil.JoinVips16(tiles, srcPixelExtent, new Extent(0, 0, dstPixelWidth, dstPixelHeight));
else if(this.Image.BioImage.Resolutions[curLevel].PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
im = ImageUtil.JoinVipsRGB24(tiles, srcPixelExtent, new Extent(0, 0, dstPixelWidth, dstPixelHeight));
return im.WriteToMemory();
}
catch (Exception e)
{
Expand All @@ -207,16 +221,28 @@ public async Task<byte[]> GetSlice(SliceInfo sliceInfo)
}
try
{
Image<Rgb24> im = OpenSlideGTK.ImageUtil.Join(tiles, srcPixelExtent, new Extent(0, 0, dstPixelWidth, dstPixelHeight));
LastSlice = GetRgb24Bytes(im);
im.Dispose();
Image im = null;
if (this.Image.BioImage.Resolutions[curLevel].PixelFormat == System.Drawing.Imaging.PixelFormat.Format16bppGrayScale)
{
im = ImageUtil.Join16(tiles, srcPixelExtent, new Extent(0, 0, dstPixelWidth, dstPixelHeight));
byte[] bts = Get16Bytes((Image<L16>)im);
im.Dispose();
return bts;
}
else if (this.Image.BioImage.Resolutions[curLevel].PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
{
im = ImageUtil.JoinRGB24(tiles, srcPixelExtent, new Extent(0, 0, dstPixelWidth, dstPixelHeight));
byte[] bts = GetRgb24Bytes((Image<Rgb24>)im);
im.Dispose();
return bts;
}
}
catch (Exception er)
{
Console.WriteLine(er.Message);
return null;
}
return LastSlice;
return null;
}
public byte[] GetRgb24Bytes(Image<Rgb24> image)
{
Expand All @@ -230,14 +256,34 @@ public byte[] GetRgb24Bytes(Image<Rgb24> image)
for (int x = 0; x < width; x++)
{
Rgb24 pixel = image[x, y];
rgbBytes[byteIndex++] = pixel.R;
rgbBytes[byteIndex++] = pixel.G;
rgbBytes[byteIndex++] = pixel.B;
rgbBytes[byteIndex++] = pixel.G;
rgbBytes[byteIndex++] = pixel.R;
}
}

return rgbBytes;
}
public byte[] Get16Bytes(Image<L16> image)
{
int width = image.Width;
int height = image.Height;
byte[] bytes = new byte[width * height * 2];

int byteIndex = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
L16 pixel = image[x, y];
byte[] bts = BitConverter.GetBytes(pixel.PackedValue);
bytes[byteIndex++] = bts[0];
bytes[byteIndex++] = bts[1];
}
}

return bytes;
}

public SlideImage Image { get; set; }

Expand Down Expand Up @@ -291,11 +337,7 @@ public async Task<byte[]> GetTileAsync(TileInformation tileInfo)
var curTileWidth = (int)(tileInfo.Extent.MaxX > Schema.Extent.Width ? tileWidth - (tileInfo.Extent.MaxX - Schema.Extent.Width) / r : tileWidth);
var curTileHeight = (int)(-tileInfo.Extent.MinY > Schema.Extent.Height ? tileHeight - (-tileInfo.Extent.MinY - Schema.Extent.Height) / r : tileHeight);
var bgraData = await Image.ReadRegionAsync(tileInfo.Index.Level, (long)curLevelOffsetXPixel, (long)curLevelOffsetYPixel, curTileWidth, curTileHeight,tileInfo.Coordinate);
//We check to see if the data is valid.
if (bgraData.Length != curTileWidth * curTileHeight * 4)
return null;
byte[] bm = ConvertRgbaToRgb(bgraData);
return bm;
return bgraData;
}
public async Task<byte[]> GetTileAsync(BruTile.TileInfo tileInfo)
{
Expand All @@ -309,11 +351,7 @@ public async Task<byte[]> GetTileAsync(BruTile.TileInfo tileInfo)
var curTileWidth = (int)(tileInfo.Extent.MaxX > Schema.Extent.Width ? tileWidth - (tileInfo.Extent.MaxX - Schema.Extent.Width) / r : tileWidth);
var curTileHeight = (int)(-tileInfo.Extent.MinY > Schema.Extent.Height ? tileHeight - (-tileInfo.Extent.MinY - Schema.Extent.Height) / r : tileHeight);
var bgraData = await Image.ReadRegionAsync(tileInfo.Index.Level, (long)curLevelOffsetXPixel, (long)curLevelOffsetYPixel, curTileWidth, curTileHeight, new ZCT());
//We check to see if the data is valid.
if (bgraData.Length != curTileWidth * curTileHeight * 4)
return null;
byte[] bm = ConvertRgbaToRgb(bgraData);
return bm;
return bgraData;
}
public static byte[] ConvertRgbaToRgb(byte[] rgbaArray)
{
Expand Down
4 changes: 2 additions & 2 deletions BioCore/Source/Bio/SlideImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public int GetBestLevelForDownsample(double downsample)
/// <exception cref="OpenSlideException"/>
public unsafe byte[] ReadRegion(int level, long x, long y, long width, long height)
{
return BioImage.GetTile(BioImage, App.viewer.GetCoordinate(), level, (int)x, (int)y, (int)width, (int)height).RGBBytes;
return BioImage.GetTile(BioImage, App.viewer.GetCoordinate(), level, (int)x, (int)y, (int)width, (int)height).Bytes;
}

/// <summary>
Expand All @@ -239,7 +239,7 @@ public unsafe byte[] ReadRegion(int level, long x, long y, long width, long heig
/// <returns></returns>
public unsafe bool TryReadRegion(int level, long x, long y, long width, long height, out byte[] data, ZCT zct)
{
data = BioImage.GetTile(BioImage, zct, level, (int)x, (int)y, (int)width, (int)height).RGBBytes;
data = BioImage.GetTile(BioImage, zct, level, (int)x, (int)y, (int)width, (int)height).Bytes;
if (data == null)
return false;
else
Expand Down
Loading

0 comments on commit 83e49aa

Please sign in to comment.