.NET version

Demo code to show the usage of the DicomImage property (ExplicitVOILUT) by generating and applying a LookupTable that has been calculated based on the standard DICOM windowing formula for calculating a Lookup table.

This example code assumes min and max as the range of values you need to handle in input data (anything beyond that is mapped to the first/last value) and for screen display it defaults to 8 bit output.

This sample code here uses the official DICOM windowing formula and reproduces the existing window via an explicit LUT.

void createExplicitVOILUT(DicomImage image)
{
	if (image.ExplicitVOILUT != null)
	{
		image.ExplicitVOILUT = null;
		image.VoiLUT = 1;
		return;
	}
	// 8 is enough unless going to a 12 bit printer etc
	int bits = image[Keyword.BitsStored].ExistsWithValue ? (int)image[Keyword.BitsStored].Value : 8;
	int min = -1024;
	int max = (int)(Math.Pow(2, bits) - 1);
	float w = image.Width;
	float l = image.Level;
	int maxoutput = (1 << bits) - 1;
	ushort[] LUTdata = new ushort[max - min];
	for (int i = min; i < max; i++)
	{
		// copy current windowing
		float v = ((i - l) / w + 0.5F); // standard DICOM windowing formula - gives 0 to 1
		v \*= maxoutput; // to go full range
		LUTdata[i - min] = (ushort)Math.Min(Math.Max(v, 0), maxoutput);
	}
	
	image.ExplicitVOILUT = new LookupTable(min, bits, true, LUTdata);
	image.VoiLUT = 1;
}