Esempio n. 1
0
// Internal function used to check if the HEADER is a valid DICOM header.
ILboolean iCheckDicom(DICOMHEAD *Header)
{
	// Always has the signature "DICM" at position 0x80.
    if (strncmp((const char*)Header->Signature, "DICM", 4))
		return IL_FALSE;
	// Does not make sense to have any dimension = 0.
	if (Header->Width == 0 || Header->Height == 0 || Header->Depth == 0)
		return IL_FALSE;
	// We can only deal with images that have byte-aligned data.
	//@TODO: Take care of any others?
	if (Header->BitsAllocated % 8)
		return IL_FALSE;
	// Check for an invalid format being set (or not set at all).
	if (ilGetBppFormat(Header->Format) == 0)
		return IL_FALSE;
	// Check for an invalid type being set (or not set at all).
	if (ilGetBpcType(Header->Type) == 0)
		return IL_FALSE;
	return IL_TRUE;
}
Esempio n. 2
0
ILAPI void ILAPIENTRY il2SetPixels(ILimage* image, ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, void *Data)
{
	void *Converted;

	if (image == NULL) {
		il2SetError(IL_ILLEGAL_OPERATION);
		return;
	}
	if (Data == NULL) {
		il2SetError(IL_INVALID_PARAM);
		return;
	}

	if (Format == image->Format && Type == image->Type) {
		Converted = (void*)Data;
	}
	else {
		Converted = ilConvertBuffer(Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type), Format, image->Format, Type, image->Type, NULL, Data);
		if (!Converted)
			return;
	}

	if (YOff + Height <= 1) {
		ilSetPixels1D(image, XOff, Width, Converted);
	}
	else if (ZOff + Depth <= 1) {
		ilSetPixels2D(image, XOff, YOff, Width, Height, Converted);
	}
	else {
		ilSetPixels3D(image, XOff, YOff, ZOff, Width, Height, Depth, Converted);
	}

	if (Format == image->Format && Type == image->Type) {
		return;
	}

	if (Converted != Data)
		ifree(Converted);

	return;
}
Esempio n. 3
0
// Internal function used to load the DICOM.
ILboolean iLoadDicomInternal(void)
{
	DICOMHEAD	Header;
	ILuint		i;
	ILushort	TempS, *ShortPtr;
	ILfloat		TempF, *FloatPtr;
	ILboolean	Swizzle = IL_FALSE;

	if (iCurImage == NULL) {
		ilSetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	// Clear the header to all 0s to make checks later easier.
	memset(&Header, 0, sizeof(DICOMHEAD));
	if (!iGetDicomHead(&Header)) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}
	if (!iCheckDicom(&Header))
		return IL_FALSE;

	if (!ilTexImage(Header.Width, Header.Height, Header.Depth, ilGetBppFormat(Header.Format), Header.Format, Header.Type, NULL))
		return IL_FALSE;
	//@TODO: Find out if the origin is always in the upper left.
	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
	// Header.DataLen may be larger than SizeOfData, since it has to be padded with a NULL if it is not an even length,
	//   so we just test to make sure it is at least large enough.
	//@TODO: Do this check before ilTexImage call.
	if (Header.DataLen < iCurImage->SizeOfData) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	// We may have to swap the order of the data.
#ifdef __BIG_ENDIAN__
			if (!Header.BigEndian) {
				if (Header.Format == IL_RGB)
					Header.Format = IL_BGR;
				else if (Header.Format == IL_RGBA)
					Swizzle = IL_TRUE;
			}
#else  // Little endian
			if (Header.BigEndian) {
				if (Header.Format == IL_RGB)
					Header.Format = IL_BGR;
				if (Header.Format == IL_RGBA)
					Swizzle = IL_TRUE;
			}
#endif

	switch (Header.Type)
	{
		case IL_UNSIGNED_BYTE:
			if (iread(iCurImage->Data, iCurImage->SizeOfData, 1) != 1)
				return IL_FALSE;

			// Swizzle the data from ABGR to RGBA.
			if (Swizzle) {
				for (i = 0; i < iCurImage->SizeOfData; i += 4) {
					iSwapUInt((ILuint*)(iCurImage->Data + i));
				}
			}
			break;

		case IL_UNSIGNED_SHORT:
			for (i = 0; i < iCurImage->SizeOfData; i += 2) {
				*((ILushort*)(iCurImage->Data + i)) = GetShort(&Header, 0);//GetLittleUShort();
			}

			// Swizzle the data from ABGR to RGBA.
			if (Swizzle) {
				ShortPtr = (ILushort*)iCurImage->Data;
				for (i = 0; i < iCurImage->SizeOfData / 2; i += 4) {
					TempS = ShortPtr[i];
					ShortPtr[i] = ShortPtr[i+3];
					ShortPtr[i+3] = TempS;
				}
			}
			break;

		case IL_FLOAT:
			for (i = 0; i < iCurImage->SizeOfData; i += 4) {
				*((ILfloat*)(iCurImage->Data + i)) = GetFloat(&Header, 0);//GetLittleFloat();
			}

			// Swizzle the data from ABGR to RGBA.
			if (Swizzle) {
				FloatPtr = (ILfloat*)iCurImage->Data;
				for (i = 0; i < iCurImage->SizeOfData / 4; i += 4) {
					TempF = FloatPtr[i];
					FloatPtr[i] = FloatPtr[i+3];
					FloatPtr[i+3] = TempF;
				}
			}
			break;
	}

	return ilFixImage();
}
ILboolean ILAPIENTRY ilApplyPal(ILconst_string FileName)
{
	ILimage		Image, *CurImage = iCurImage;
	ILubyte		*NewData;
	ILuint		*PalInfo, NumColours, NumPix, MaxDist, DistEntry=0, i, j;
	ILint		Dist1, Dist2, Dist3;
	ILboolean	Same;
	ILenum		Origin;
//	COL_CUBE	*Cubes;

    if( iCurImage == NULL || (iCurImage->Format != IL_BYTE || iCurImage->Format != IL_UNSIGNED_BYTE) ) {
    	ilSetError(IL_ILLEGAL_OPERATION);
        return IL_FALSE;
    }

	NewData = (ILubyte*)ialloc(iCurImage->Width * iCurImage->Height * iCurImage->Depth);
	if (NewData == NULL) {
		return IL_FALSE;
	}

	iCurImage = &Image;
	imemclear(&Image, sizeof(ILimage));
	// IL_PAL_RGB24, because we don't want to make parts transparent that shouldn't be.
	if (!ilLoadPal(FileName) || !ilConvertPal(IL_PAL_RGB24)) {
		ifree(NewData);
		iCurImage = CurImage;
		return IL_FALSE;
	}

	NumColours = Image.Pal.PalSize / 3;  // RGB24 is 3 bytes per entry.
	PalInfo = (ILuint*)ialloc(NumColours * sizeof(ILuint));
	if (PalInfo == NULL) {
		ifree(NewData);
		iCurImage = CurImage;
		return IL_FALSE;
	}

	NumPix = CurImage->SizeOfData / ilGetBppFormat(CurImage->Format);
	switch (CurImage->Format)
	{
		case IL_COLOUR_INDEX:
			iCurImage = CurImage;
			if (!ilConvertPal(IL_PAL_RGB24)) {
				ifree(NewData);
				ifree(PalInfo);
				return IL_FALSE;
			}

			NumPix = iCurImage->Pal.PalSize / ilGetBppPal(iCurImage->Pal.PalType);
			for (i = 0; i < NumPix; i++) {
				for (j = 0; j < Image.Pal.PalSize; j += 3) {
					// No need to perform a sqrt.
					Dist1 = (ILint)iCurImage->Pal.Palette[i] - (ILint)Image.Pal.Palette[j];
					Dist2 = (ILint)iCurImage->Pal.Palette[i+1] - (ILint)Image.Pal.Palette[j+1];
					Dist3 = (ILint)iCurImage->Pal.Palette[i+2] - (ILint)Image.Pal.Palette[j+2];
					PalInfo[j / 3] = Dist1 * Dist1 + Dist2 * Dist2 + Dist3 * Dist3;
				}
				MaxDist = UINT_MAX;
				DistEntry = 0;
				for (j = 0; j < NumColours; j++) {
					if (PalInfo[j] < MaxDist) {
						DistEntry = j;
						MaxDist = PalInfo[j];
					}
				}
				iCurImage->Pal.Palette[i] = DistEntry;
			}

			for (i = 0; i < iCurImage->SizeOfData; i++) {
				NewData[i] = iCurImage->Pal.Palette[iCurImage->Data[i]];
			}
			break;
		case IL_RGB:
		case IL_RGBA:
			/*Cube = (COL_CUBE*)ialloc(NumColours * sizeof(COL_CUBE));
			// @TODO:  Check if ialloc failed here!
			for (i = 0; i < NumColours; i++)
				memcpy(&Cubes[i].Val, Image.Pal.Palette[i * 3], 3);
			for (j = 0; j < 3; j++) {
				qsort(Cubes, NumColours, sizeof(COL_CUBE), sort_func);
				Cubes[0].Min = 0;
				Cubes[NumColours-1] = UCHAR_MAX;
				NumColours--;
				for (i = 1; i < NumColours; i++) {
					Cubes[i].Min[CurSort] = Cubes[i-1].Val[CurSort] + 1;
					Cubes[i-1].Max[CurSort] = Cubes[i].Val[CurSort] - 1;
				}
				CurSort++;
				NumColours++;
			}*/
			for (i = 0; i < CurImage->SizeOfData; i += CurImage->Bpp) {
				Same = IL_TRUE;
				if (i != 0) {
					for (j = 0; j < CurImage->Bpp; j++) {
						if (CurImage->Data[i-CurImage->Bpp+j] != CurImage->Data[i+j]) {
							Same = IL_FALSE;
							break;
						}
					}
				}
				if (Same) {
					NewData[i / CurImage->Bpp] = DistEntry;
					continue;
				}
				for (j = 0; j < Image.Pal.PalSize; j += 3) {
					// No need to perform a sqrt.
					Dist1 = (ILint)CurImage->Data[i] - (ILint)Image.Pal.Palette[j];
					Dist2 = (ILint)CurImage->Data[i+1] - (ILint)Image.Pal.Palette[j+1];
					Dist3 = (ILint)CurImage->Data[i+2] - (ILint)Image.Pal.Palette[j+2];
					PalInfo[j / 3] = Dist1 * Dist1 + Dist2 * Dist2 + Dist3 * Dist3;
				}
				MaxDist = UINT_MAX;
				DistEntry = 0;
				for (j = 0; j < NumColours; j++) {
					if (PalInfo[j] < MaxDist) {
						DistEntry = j;
						MaxDist = PalInfo[j];
					}
				}
				NewData[i / CurImage->Bpp] = DistEntry;
			}

			break;

		case IL_BGR:
		case IL_BGRA:
			for (i = 0; i < CurImage->SizeOfData; i += CurImage->Bpp) {
				for (j = 0; j < NumColours; j++) {
					// No need to perform a sqrt.
					PalInfo[j] = ((ILint)CurImage->Data[i+2] - (ILint)Image.Pal.Palette[j * 3]) *
						((ILint)CurImage->Data[i+2] - (ILint)Image.Pal.Palette[j * 3]) + 
						((ILint)CurImage->Data[i+1] - (ILint)Image.Pal.Palette[j * 3 + 1]) *
						((ILint)CurImage->Data[i+1] - (ILint)Image.Pal.Palette[j * 3 + 1]) +
						((ILint)CurImage->Data[i] - (ILint)Image.Pal.Palette[j * 3 + 2]) *
						((ILint)CurImage->Data[i] - (ILint)Image.Pal.Palette[j * 3 + 2]);
				}
				MaxDist = UINT_MAX;
				DistEntry = 0;
				for (j = 0; j < NumColours; j++) {
					if (PalInfo[j] < MaxDist) {
						DistEntry = j;
						MaxDist = PalInfo[j];
					}
				}
				NewData[i / CurImage->Bpp] = DistEntry;
			}

			break;

		case IL_LUMINANCE:
		case IL_LUMINANCE_ALPHA:
			for (i = 0; i < CurImage->SizeOfData; i += CurImage->Bpp ) {
				for (j = 0; j < NumColours; j++) {
					// No need to perform a sqrt.
					PalInfo[j] = ((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3]) *
						((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3]) + 
						((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3 + 1]) *
						((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3 + 1]) +
						((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3 + 2]) *
						((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3 + 2]);
				}
				MaxDist = UINT_MAX;
				DistEntry = 0;
				for (j = 0; j < NumColours; j++) {
					if (PalInfo[j] < MaxDist) {
						DistEntry = j;
						MaxDist = PalInfo[j];
					}
				}
				NewData[i] = DistEntry;
			}

			break;

		default:  // Should be no other!
			ilSetError(IL_INTERNAL_ERROR);
			return IL_FALSE;
	}

	iCurImage = CurImage;
	Origin = iCurImage->Origin;
	if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, 1,
		IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NewData)) {
		ifree(Image.Pal.Palette);
		ifree(PalInfo);
		ifree(NewData);
		return IL_FALSE;
	}
	iCurImage->Origin = Origin;

	iCurImage->Pal.Palette = Image.Pal.Palette;
	iCurImage->Pal.PalSize = Image.Pal.PalSize;
	iCurImage->Pal.PalType = Image.Pal.PalType;
	ifree(PalInfo);
	ifree(NewData);

	return IL_TRUE;
}
Esempio n. 5
0
ILAPI ILuint ILAPIENTRY il2CopyPixels(ILimage* image, ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, void *Data)
{
	void	*Converted = NULL;
	ILubyte	*TempBuff = NULL;
	ILuint	SrcSize, DestSize;

	if (image == NULL) {
		il2SetError(IL_ILLEGAL_OPERATION);
		return 0;
	}
	DestSize = Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type);
	if (DestSize == 0) {
		return DestSize;
	}
	if (Data == NULL || Format == IL_COLOUR_INDEX) {
		il2SetError(IL_INVALID_PARAM);
		return 0;
	}
	SrcSize = Width * Height * Depth * image->Bpp * image->Bpc;

	if (Format == image->Format && Type == image->Type) {
		TempBuff = (ILubyte*)Data;
	}
	else {
		TempBuff = (ILubyte*)ialloc(SrcSize);
		if (TempBuff == NULL) {
			return 0;
		}
	}

	if (YOff + Height <= 1) {
		if (!ilCopyPixels1D(image, XOff, Width, TempBuff)) {
			goto failed;
		}
	}
	else if (ZOff + Depth <= 1) {
		if (!ilCopyPixels2D(image, XOff, YOff, Width, Height, TempBuff)) {
			goto failed;
		}
	}
	else {
		if (!ilCopyPixels3D(image, XOff, YOff, ZOff, Width, Height, Depth, TempBuff)) {
			goto failed;
		}
	}

	if (Format == image->Format && Type == image->Type) {
		return DestSize;
	}

	Converted = ilConvertBuffer(SrcSize, image->Format, Format, image->Type, Type, &image->Pal, TempBuff);
	if (Converted == NULL)
		goto failed;

	memcpy(Data, Converted, DestSize);

	ifree(Converted);
	if (TempBuff != Data)
		ifree(TempBuff);

	return DestSize;

failed:
	if (TempBuff != Data)
		ifree(TempBuff);
	ifree(Converted);
	return 0;
}