179 {
180 try
181 {
182 if (Schema == null)
183 {
184 Console.WriteLine("Schema is null.");
185 return null;
186 }
187 var r = Schema.Resolutions[tileInfo.Index.Level].UnitsPerPixel;
188 var tileWidth = Schema.Resolutions[tileInfo.Index.Level].TileWidth;
189 var tileHeight = Schema.Resolutions[tileInfo.Index.Level].TileHeight;
190
191
192
193
194
195 var schemaExtent = Schema.Extent;
196
197
198
199
200
201 var curLevelOffsetXPixel = tileInfo.Index.Col * tileWidth;
202 var curLevelOffsetYPixel = tileInfo.Index.Row * tileHeight;
203
204
205 int lev = tileInfo.Index.Level;
206 var levelPixelW = (long)(lev < SlideImage.BioImage.Resolutions.Count
207 ? SlideImage.BioImage.Resolutions[lev].SizeX
208 : Math.Round(Schema.Extent.Width / r));
209 var levelPixelH = (long)(lev < SlideImage.BioImage.Resolutions.Count
210 ? SlideImage.BioImage.Resolutions[lev].SizeY
211 : Math.Round(Schema.Extent.Height / r));
212
213 long readX = (long)curLevelOffsetXPixel;
214 long readY = (long)curLevelOffsetYPixel;
215
216 int curTileWidth = tileWidth;
217 int curTileHeight = tileHeight;
218
219
220
221 if (readX < 0)
222 {
223 curTileWidth += (int)readX;
224 readX = 0;
225 }
226 if (readY < 0)
227 {
228 curTileHeight += (int)readY;
229 readY = 0;
230 }
231
232
233 curTileWidth = (int)Math.Max(0, Math.Min(curTileWidth, levelPixelW - readX));
234 curTileHeight = (int)Math.Max(0, Math.Min(curTileHeight, levelPixelH - readY));
235
236
237 if (curTileWidth <= 0 || curTileHeight <= 0)
238 {
239 return new byte[tileWidth * tileHeight * 4];
240 }
241
242 if (SlideImage == null)
243 {
244 Console.WriteLine("SlideImage is null.");
245 return null;
246 }
247
249 tileInfo.Index.Level, coord,
250 readX, readY,
251 curTileWidth, curTileHeight);
252
253 if (bgraData == null || bgraData.Length == 0)
254 return null;
255
256 int expectedSize = tileWidth * tileHeight * 4;
257
258
259
260
261 if (bgraData.Length == expectedSize)
262 return bgraData;
263
264
265
266
267
268
269 int actualW = Math.Min(curTileWidth, tileWidth);
270 int actualH = Math.Min(curTileHeight, tileHeight);
271 int srcStride = actualW * 4;
272
273
274 if (bgraData.Length < actualW * actualH * 4)
275 {
276 int safePixels = bgraData.Length / 4;
277 actualH = safePixels / actualW;
278 if (actualH == 0) return null;
279 }
280
281 byte[] padded = new byte[expectedSize];
282 for (int row = 0; row < actualH; row++)
283 {
284 int srcOffset = row * srcStride;
285 int dstOffset = row * tileWidth * 4;
286 Buffer.BlockCopy(bgraData, srcOffset, padded, dstOffset, srcStride);
287 }
288 return padded;
289 }
290 catch (Exception e)
291 {
292 Console.WriteLine(e.Message + " " + e.StackTrace);
293 }
294 return null;
295 }
unsafe byte[] ReadRegion(int level, ZCT zct, long x, long y, long width, long height)
Copy pre-multiplied BGRA data from a whole slide image.
Definition SlideImage.cs:282