/// <summary> /// Copies one slice of image data from given pi2 pointer to array in this picture storage object. /// </summary> /// <param name="data"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="depth"></param> /// <param name="dt"></param> public void CopyFromPointerToTemp(IntPtr data, long width, long height, long depth, ImageDataType dt, int slice, CancellationToken cancellationToken) { if (width > int.MaxValue) { throw new InvalidOperationException("Image width is too large to be shown. Maximum supported width is " + int.MaxValue); } if (height > int.MaxValue) { throw new InvalidOperationException("Image height is too large to be shown. Maximum supported height is " + int.MaxValue); } if (depth > int.MaxValue) { throw new InvalidOperationException("Image depth is too large to be shown. Maximum supported depth is " + int.MaxValue); } long capacity = width * height; if (capacity > int.MaxValue) { throw new InvalidOperationException("Size of single slice is too large to be shown. Maximum supported count of pixels is " + int.MaxValue); } OriginalBitmap.Clear(); OriginalBitmap.Capacity = (int)capacity; for (int n = 0; n < width * height; n++) { OriginalBitmap.Add(0); } OriginalWidth = (int)width; OriginalHeight = (int)height; OriginalDepth = (int)depth; OriginalDataType = dt; cancellationToken.ThrowIfCancellationRequested(); if (slice < 0) { slice = 0; } else if (slice >= depth) { slice = (int)(depth - 1); } if (data != IntPtr.Zero) { unsafe { // Construct pixel getter function that converts all pixel data types to float. byte * pi8 = (byte *)data.ToPointer(); UInt16 *pi16 = (UInt16 *)pi8; UInt32 *pi32 = (UInt32 *)pi8; UInt64 *pi64 = (UInt64 *)pi8; float * pif = (float *)pi8; Func <int, int, float> getPixel; switch (dt) { case ImageDataType.UInt8: getPixel = (int x, int y) => pi8[x + y * width + slice * width * height]; DynamicMin = uint.MinValue; DynamicMax = uint.MaxValue; break; case ImageDataType.UInt16: getPixel = (int x, int y) => pi16[x + y * width + slice * width * height]; DynamicMin = UInt16.MinValue; DynamicMax = UInt16.MaxValue; break; case ImageDataType.UInt32: getPixel = (int x, int y) => pi32[x + y * width + slice * width * height]; DynamicMin = UInt32.MinValue; DynamicMax = UInt32.MaxValue; break; case ImageDataType.UInt64: getPixel = (int x, int y) => pi64[x + y * width + slice * width * height]; DynamicMin = UInt64.MinValue; DynamicMax = UInt64.MaxValue; break; case ImageDataType.Float32: getPixel = (int x, int y) => pif[x + y * width + slice * width * height]; // These are updated later as MinValue and MaxValue are not practically very usable choices. //DynamicMin = float.MinValue; //DynamicMax = float.MaxValue; break; default: getPixel = (int x, int y) => 0; DynamicMin = 0; DynamicMax = 0; break; } // Copy pixel values to the array. int iw = (int)width; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float val = getPixel(x, y); OriginalBitmap[x + y * iw] = val; } cancellationToken.ThrowIfCancellationRequested(); } } } UpdateHistogram(); }
/// <summary> /// Copies image data from given pi2 pointer to array in this picture box. /// </summary> /// <param name="data"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="depth"></param> /// <param name="dt"></param> private void CopyFromPointerToTemp(IntPtr data, int width, int height, int depth, ImageDataType dt) { OriginalBitmap.Clear(); OriginalBitmap.Capacity = width * height; for (int n = 0; n < width * height; n++) { OriginalBitmap.Add(0); } OriginalWidth = width; OriginalHeight = height; OriginalDepth = depth; OriginalDataType = dt; if (Slice < 0) { Slice = 0; } else if (Slice >= depth) { Slice = depth - 1; } if (data != IntPtr.Zero) { unsafe { // Construct pixel getter function that converts all pixel data types to float. byte * pi8 = (byte *)data.ToPointer(); UInt16 *pi16 = (UInt16 *)pi8; UInt32 *pi32 = (UInt32 *)pi8; UInt64 *pi64 = (UInt64 *)pi8; float * pif = (float *)pi8; Func <int, int, float> getPixel; switch (dt) { case ImageDataType.UInt8: getPixel = (int x, int y) => pi8[x + y * width + Slice * width * height]; DynamicMin = uint.MinValue; DynamicMax = uint.MaxValue; break; case ImageDataType.UInt16: getPixel = (int x, int y) => pi16[x + y * width + Slice * width * height]; DynamicMin = UInt16.MinValue; DynamicMax = UInt16.MaxValue; break; case ImageDataType.UInt32: getPixel = (int x, int y) => pi32[x + y * width + Slice * width * height]; DynamicMin = UInt32.MinValue; DynamicMax = UInt32.MaxValue; break; case ImageDataType.UInt64: getPixel = (int x, int y) => pi64[x + y * width + Slice * width * height]; DynamicMin = UInt64.MinValue; DynamicMax = UInt64.MaxValue; break; case ImageDataType.Float32: getPixel = (int x, int y) => pif[x + y * width + Slice * width * height]; // These are updated later as MinValue and MaxValue are not practically very usable choices. //DynamicMin = float.MinValue; //DynamicMax = float.MaxValue; break; default: getPixel = (int x, int y) => 0; DynamicMin = 0; DynamicMax = 0; break; } // Copy pixel values to the array. for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float val = getPixel(x, y); OriginalBitmap[x + y * width] = val; } } } } UpdateHistogram(); if (dt == ImageDataType.Float32) { float headroom = 0.1f * (GlobalMax - GlobalMin); DynamicMin = GlobalMin - headroom; DynamicMax = GlobalMax + headroom; } }