示例#1
0
文件: ilut_allegro.c 项目: jitrc/p3d
// Does not account for converting luminance...
BITMAP* ILAPIENTRY ilutConvertToAlleg(PALETTE Pal)
{
	BITMAP *Bitmap;
	ILimage *TempImage;
	ILuint i = 0, j = 0;

	ilutCurImage = ilGetCurImage();

	if (ilutCurImage == NULL) {
		ilSetError(ILUT_ILLEGAL_OPERATION);
		return NULL;
	}

	// Should be IL_BGR(A), but Djgpp screws up somewhere along the line.
	if (ilutCurImage->Format == IL_RGB || ilutCurImage->Format == IL_RGBA) {
		iluSwapColours();
	}

	if (ilutCurImage->Origin == IL_ORIGIN_LOWER_LEFT)
		iluFlipImage();
	if (ilutCurImage->Type > IL_UNSIGNED_BYTE) {}  // Can't do anything about this right now...
	if (ilutCurImage->Type == IL_BYTE) {}  // Can't do anything about this right now...

	Bitmap = create_bitmap_ex(ilutCurImage->Bpp * 8, ilutCurImage->Width, ilutCurImage->Height);
	if (Bitmap == NULL) {
		return IL_FALSE;
	}
	memcpy(Bitmap->dat, ilutCurImage->Data, ilutCurImage->SizeOfData);

	// Should we make this toggleable?
	if (ilutCurImage->Bpp == 8 && ilutCurImage->Pal.PalType != IL_PAL_NONE) {
		// Use the image's palette if there is one

		// ilConvertPal is destructive to the original image
		// @TODO:  Use new ilCopyPal!!!
		TempImage = ilNewImage(ilutCurImage->Width, ilutCurImage->Height, ilutCurImage->Depth, ilutCurImage->Bpp, 1);
		ilCopyImageAttr(TempImage, ilutCurImage);
		ilSetCurImage(TempImage);

		if (!ilConvertPal(IL_PAL_RGB24)) {
			destroy_bitmap(Bitmap);
			ilSetError(ILUT_ILLEGAL_OPERATION);
			return NULL;
		}

		for (; i < ilutCurImage->Pal.PalSize && i < 768; i += 3, j++) {
			Pal[j].r = TempImage->Pal.Palette[i+0];
			Pal[j].g = TempImage->Pal.Palette[i+1];
			Pal[j].b = TempImage->Pal.Palette[i+2];
			Pal[j].filler = 255;
		}

		ilCloseImage(TempImage);
		ilSetCurImage(ilutCurImage);
	}

	return Bitmap;
}
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;
}
示例#3
0
ILboolean ILAPIENTRY iluScale(ILuint Width, ILuint Height, ILuint Depth)
{
	ILimage		*Temp;
	ILboolean	UsePal;
	ILenum		PalType;
	ILenum		Origin;

	iluCurImage = ilGetCurImage();
	if (iluCurImage == NULL) {
		ilSetError(ILU_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	if (iluCurImage->Width == Width && iluCurImage->Height == Height && iluCurImage->Depth == Depth)
		return IL_TRUE;


	if( (iluCurImage->Width<Width) || (iluCurImage->Height<Height) ) // only do special scale if there is some zoom?
	{
		switch (iluFilter)
		{
			case ILU_SCALE_BOX:
			case ILU_SCALE_TRIANGLE:
			case ILU_SCALE_BELL:
			case ILU_SCALE_BSPLINE:
			case ILU_SCALE_LANCZOS3:
			case ILU_SCALE_MITCHELL:

				iluCurImage = ilGetCurImage();
				if (iluCurImage == NULL) {
					ilSetError(ILU_ILLEGAL_OPERATION);
					return IL_FALSE;
				}

				// Not supported yet.
				if (iluCurImage->Type != IL_UNSIGNED_BYTE ||
					iluCurImage->Format == IL_COLOUR_INDEX ||
					iluCurImage->Depth > 1) {
						ilSetError(ILU_ILLEGAL_OPERATION);
						return IL_FALSE;
				}

				if(iluCurImage->Width>Width) // shrink width first
				{
					Origin = iluCurImage->Origin;
					Temp = iluScale_(iluCurImage, Width, iluCurImage->Height, iluCurImage->Depth);
					if (Temp != NULL)
					{
						if( !ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data ) ) {
							ilCloseImage(Temp);
							return IL_FALSE;
						}
						iluCurImage->Origin = Origin;
						ilCloseImage(Temp);
					}
				}
				else
				if(iluCurImage->Height>Height) // shrink height first
				{
					Origin = iluCurImage->Origin;
					Temp = iluScale_(iluCurImage, iluCurImage->Width, Height, iluCurImage->Depth);
					if (Temp != NULL)
					{
						if( !ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data) ) {
							ilCloseImage(Temp);
							return IL_FALSE;
						}
						iluCurImage->Origin = Origin;
						ilCloseImage(Temp);
					}
				}

				return (ILboolean)iluScaleAdvanced(Width, Height, iluFilter);
		}
	}


	Origin = iluCurImage->Origin;
	UsePal = (iluCurImage->Format == IL_COLOUR_INDEX);
	PalType = iluCurImage->Pal.PalType;
	Temp = iluScale_(iluCurImage, Width, Height, Depth);
	if (Temp != NULL) {
		if( !ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data) ) {
			ilCloseImage(Temp);
			return IL_FALSE;
		}
		iluCurImage->Origin = Origin;
		ilCloseImage(Temp);
		if (UsePal) {
			if (!ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE))
				return IL_FALSE;
			ilConvertPal(PalType);
		}
		return IL_TRUE;
	}

	return IL_FALSE;
}
ILboolean ILAPIENTRY ilSavePal(ILconst_string FileName)
{
	ILstring Ext = iGetExtension(FileName);

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

#ifndef _UNICODE
	if (FileName == NULL || strlen(FileName) < 1 || Ext == NULL) {
#else
	if (FileName == NULL || wcslen(FileName) < 1 || Ext == NULL) {
#endif//_UNICODE
		ilSetError(IL_INVALID_PARAM);
		return IL_FALSE;
	}

	if (!iCurImage->Pal.Palette || !iCurImage->Pal.PalSize || iCurImage->Pal.PalType == IL_PAL_NONE) {
		ilSetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	if (!iStrCmp(Ext, IL_TEXT("pal"))) {
		return ilSaveJascPal(FileName);
	}

	ilSetError(IL_INVALID_EXTENSION);
	return IL_FALSE;
}


//! Saves a Paint Shop Pro formatted palette (.pal) file.
ILboolean ilSaveJascPal(ILconst_string FileName)
{
	FILE	*PalFile;
	ILuint	i, PalBpp, NumCols = ilGetInteger(IL_PALETTE_NUM_COLS);
	ILubyte	*CurPal;

	if (iCurImage == NULL || NumCols == 0 || NumCols > 256) {
		ilSetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}
	
#ifndef _UNICODE
	if (FileName == NULL || strlen(FileName) < 5) {
#else
	if (FileName == NULL || wcslen(FileName) < 5) {
#endif//_UNICODE
		ilSetError(IL_INVALID_VALUE);
		return IL_FALSE;
	}

	if (!iCheckExtension(FileName, IL_TEXT("pal"))) {
		ilSetError(IL_INVALID_EXTENSION);
		return IL_FALSE;
	}

	if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
		if (iFileExists(FileName)) {
			ilSetError(IL_FILE_ALREADY_EXISTS);
			return IL_FALSE;
		}
	}

	// Create a copy of the current palette and convert it to RGB24 format.
	CurPal = iCurImage->Pal.Palette;
	iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize);
	if (!iCurImage->Pal.Palette) {
		iCurImage->Pal.Palette = CurPal;
		return IL_FALSE;
	}

	memcpy(iCurImage->Pal.Palette, CurPal, iCurImage->Pal.PalSize);
	if (!ilConvertPal(IL_PAL_RGB24)) {
		ifree(iCurImage->Pal.Palette);
		iCurImage->Pal.Palette = CurPal;
		return IL_FALSE;
	}

#ifndef _UNICODE
	PalFile = fopen(FileName, "wt");
#else
	PalFile = _wfopen(FileName, L"wt");
#endif//_UNICODE
	if (!PalFile) {
		ilSetError(IL_COULD_NOT_OPEN_FILE);
		return IL_FALSE;
	}

	// Header needed on all .pal files
	fputs("JASC-PAL\n0100\n256\n", PalFile);

	PalBpp = ilGetBppPal(iCurImage->Pal.PalType);
	for (i = 0; i < iCurImage->Pal.PalSize; i += PalBpp) {
		fprintf(PalFile, "%d %d %d\n",
			iCurImage->Pal.Palette[i], iCurImage->Pal.Palette[i+1], iCurImage->Pal.Palette[i+2]);
	}

	NumCols = 256 - NumCols;
	for (i = 0; i < NumCols; i++) {
		fprintf(PalFile, "0 0 0\n");
	}

	ifree(iCurImage->Pal.Palette);
	iCurImage->Pal.Palette = CurPal;

	fclose(PalFile);

	return IL_TRUE;
}


//! Loads a Halo formatted palette (.pal) file.
ILboolean ilLoadHaloPal(ILconst_string FileName)
{
	ILHANDLE	HaloFile;
	HALOHEAD	HaloHead;
	ILushort	*TempPal;
	ILuint		i, Size;

	if (!iCheckExtension(FileName, IL_TEXT("pal"))) {
		ilSetError(IL_INVALID_EXTENSION);
		return IL_FALSE;
	}

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

	HaloFile = iopenr(FileName);
	if (HaloFile == NULL) {
		ilSetError(IL_COULD_NOT_OPEN_FILE);
		return IL_FALSE;
	}

	if (iread(&HaloHead, sizeof(HALOHEAD), 1) != 1)
		return IL_FALSE;

	if (HaloHead.Id != 'A' + ('H' << 8) || HaloHead.Version != 0xe3) {
		icloser(HaloFile);
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}

	Size = (HaloHead.MaxIndex + 1) * 3;
	TempPal = (ILushort*)ialloc(Size * sizeof(ILushort));
	if (TempPal == NULL) {
		icloser(HaloFile);
		return IL_FALSE;
	}

	if (iread(TempPal, sizeof(ILushort), Size) != Size) {
		icloser(HaloFile);
		ifree(TempPal);
		return IL_FALSE;
	}

	if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize > 0 && iCurImage->Pal.PalType != IL_PAL_NONE) {
		ifree(iCurImage->Pal.Palette);
		iCurImage->Pal.Palette = NULL;
	}
	iCurImage->Pal.PalType = IL_PAL_RGB24;
	iCurImage->Pal.PalSize = Size;
	iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize);
	if (iCurImage->Pal.Palette == NULL) {
		icloser(HaloFile);
		return IL_FALSE;
	}

	for (i = 0; i < iCurImage->Pal.PalSize; i++, TempPal++) {
		iCurImage->Pal.Palette[i] = (ILubyte)*TempPal;
	}
	TempPal -= iCurImage->Pal.PalSize;
	ifree(TempPal);

	icloser(HaloFile);

	return IL_TRUE;
}
示例#5
0
void ilFConvertPal_(int *RetVal, int *DestFormat)
{
	*RetVal = ilConvertPal(*DestFormat);
}