static ILubyte *GetChannel(PSP_CTX *ctx) { BLOCKHEAD Block; CHANNEL_CHUNK Channel; ILubyte *CompData, *Data; ILuint ChunkSize, Padding; if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block)) return NULL; if (ctx->Header.MajorVersion == 3) { Block.BlockLen = GetLittleUInt(ctx->io); } else { UInt(&Block.BlockLen); } if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { iSetError(IL_ILLEGAL_FILE_VALUE); return NULL; } if (Block.BlockID != PSP_CHANNEL_BLOCK) { iSetError(IL_ILLEGAL_FILE_VALUE); return NULL; } if (ctx->Header.MajorVersion >= 4) { ChunkSize = GetLittleUInt(ctx->io); if (SIOread(ctx->io, &Channel, sizeof(Channel), 1) != 1) return NULL; Padding = (ChunkSize - 4) - sizeof(Channel); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); } else { if (SIOread(ctx->io, &Channel, sizeof(Channel), 1) != 1) return NULL; } CompData = (ILubyte*)ialloc(Channel.CompLen); Data = (ILubyte*)ialloc(ctx->AttChunk.Width * ctx->AttChunk.Height); if (CompData == NULL || Data == NULL) { ifree(Data); ifree(CompData); return NULL; } if (SIOread(ctx->io, CompData, 1, Channel.CompLen) != Channel.CompLen) { ifree(CompData); ifree(Data); return NULL; } switch (ctx->AttChunk.Compression) { case PSP_COMP_NONE: ifree(Data); return CompData; case PSP_COMP_RLE: if (!UncompRLE(CompData, Data, Channel.CompLen)) { ifree(CompData); ifree(Data); return NULL; } break; default: ifree(CompData); ifree(Data); iSetError(IL_INVALID_FILE_HEADER); return NULL; } ifree(CompData); return Data; }
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; }
int add_dir(DIR *cur_dir, int cur_inode, int parent_inode) { int r; int child_inode; int cur_fd, child_fd; struct xv6_dirent de; struct dinode din; struct dirent dir_buf; struct dirent *entry; struct stat st; int bytes_read; char buf[BLOCK_SIZE]; int off; bzero(&de, sizeof(de)); de.inum = xshort(cur_inode); strcpy(de.name, "."); iappend(cur_inode, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(parent_inode); strcpy(de.name, ".."); iappend(cur_inode, &de, sizeof(de)); if (cur_dir == NULL) { return 0; } cur_fd = dirfd(cur_dir); if (cur_fd == -1){ perror("add_dir"); exit(EXIT_FAILURE); } if (fchdir(cur_fd) != 0){ perror("add_dir"); return -1; } while (true) { r = readdir_r(cur_dir, &dir_buf, &entry); if (r != 0) { perror("add_dir"); return -1; } if (entry == NULL) break; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; printf("%s\n", entry->d_name); child_fd = open(entry->d_name, O_RDONLY); if (child_fd == -1) { perror("open"); return -1; } r = fstat(child_fd, &st); if (r != 0) { perror("stat"); return -1; } if (S_ISDIR(st.st_mode)) { child_inode = ialloc(T_DIR); r = add_dir(fdopendir(child_fd), child_inode, cur_inode); if (r != 0) return r; if (fchdir(cur_fd) != 0) { perror("chdir"); return -1; } } else { bytes_read = 0; child_inode = ialloc(T_FILE); bzero(&de, sizeof(de)); while((bytes_read = read(child_fd, buf, sizeof(buf))) > 0) { iappend(child_inode, buf, bytes_read); } } close(child_fd); de.inum = xshort(child_inode); strncpy(de.name, entry->d_name, DIRSIZ); iappend(cur_inode, &de, sizeof(de)); } // fix size of inode cur_dir rinode(cur_inode, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(cur_inode, &din); return 0; }
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; }
// Converts the palette to the DestFormat format. ILAPI ILpal* ILAPIENTRY iConvertPal(ILpal *Pal, ILenum DestFormat) { ILpal *NewPal = NULL; ILuint i, j, NewPalSize; // Checks to see if the current image is valid and has a palette if (Pal == NULL || Pal->PalSize == 0 || Pal->Palette == NULL || Pal->PalType == IL_PAL_NONE) { ilSetError(IL_ILLEGAL_OPERATION); return NULL; } /*if (Pal->PalType == DestFormat) { return NULL; }*/ NewPal = (ILpal*)ialloc(sizeof(ILpal)); if (NewPal == NULL) { return NULL; } NewPal->PalSize = Pal->PalSize; NewPal->PalType = Pal->PalType; switch (DestFormat) { case IL_PAL_RGB24: case IL_PAL_BGR24: switch (Pal->PalType) { case IL_PAL_RGB24: NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); if (NewPal->Palette == NULL) goto alloc_error; if (DestFormat == IL_PAL_BGR24) { j = ilGetBppPal(Pal->PalType); for (i = 0; i < Pal->PalSize; i += j) { NewPal->Palette[i] = Pal->Palette[i+2]; NewPal->Palette[i+1] = Pal->Palette[i+1]; NewPal->Palette[i+2] = Pal->Palette[i]; } } else { memcpy(NewPal->Palette, Pal->Palette, Pal->PalSize); } NewPal->PalType = DestFormat; break; case IL_PAL_BGR24: NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); if (NewPal->Palette == NULL) goto alloc_error; if (DestFormat == IL_PAL_RGB24) { j = ilGetBppPal(Pal->PalType); for (i = 0; i < Pal->PalSize; i += j) { NewPal->Palette[i] = Pal->Palette[i+2]; NewPal->Palette[i+1] = Pal->Palette[i+1]; NewPal->Palette[i+2] = Pal->Palette[i]; } } else { memcpy(NewPal->Palette, Pal->Palette, Pal->PalSize); } NewPal->PalType = DestFormat; break; case IL_PAL_BGR32: case IL_PAL_BGRA32: NewPalSize = (ILuint)((ILfloat)Pal->PalSize * 3.0f / 4.0f); NewPal->Palette = (ILubyte*)ialloc(NewPalSize); if (NewPal->Palette == NULL) goto alloc_error; if (DestFormat == IL_PAL_RGB24) { for (i = 0, j = 0; i < Pal->PalSize; i += 4, j += 3) { NewPal->Palette[j] = Pal->Palette[i+2]; NewPal->Palette[j+1] = Pal->Palette[i+1]; NewPal->Palette[j+2] = Pal->Palette[i]; } } else { for (i = 0, j = 0; i < Pal->PalSize; i += 4, j += 3) { NewPal->Palette[j] = Pal->Palette[i]; NewPal->Palette[j+1] = Pal->Palette[i+1]; NewPal->Palette[j+2] = Pal->Palette[i+2]; } } NewPal->PalSize = NewPalSize; NewPal->PalType = DestFormat; break; case IL_PAL_RGB32: case IL_PAL_RGBA32: NewPalSize = (ILuint)((ILfloat)Pal->PalSize * 3.0f / 4.0f); NewPal->Palette = (ILubyte*)ialloc(NewPalSize); if (NewPal->Palette == NULL) goto alloc_error; if (DestFormat == IL_PAL_RGB24) { for (i = 0, j = 0; i < Pal->PalSize; i += 4, j += 3) { NewPal->Palette[j] = Pal->Palette[i]; NewPal->Palette[j+1] = Pal->Palette[i+1]; NewPal->Palette[j+2] = Pal->Palette[i+2]; } } else { for (i = 0, j = 0; i < Pal->PalSize; i += 4, j += 3) { NewPal->Palette[j] = Pal->Palette[i+2]; NewPal->Palette[j+1] = Pal->Palette[i+1]; NewPal->Palette[j+2] = Pal->Palette[i]; } } NewPal->PalSize = NewPalSize; NewPal->PalType = DestFormat; break; default: ilSetError(IL_INVALID_PARAM); return NULL; } break; case IL_PAL_RGB32: case IL_PAL_RGBA32: case IL_PAL_BGR32: case IL_PAL_BGRA32: switch (Pal->PalType) { case IL_PAL_RGB24: case IL_PAL_BGR24: NewPalSize = Pal->PalSize * 4 / 3; NewPal->Palette = (ILubyte*)ialloc(NewPalSize); if (NewPal->Palette == NULL) goto alloc_error; if ((Pal->PalType == IL_PAL_BGR24 && (DestFormat == IL_PAL_RGB32 || DestFormat == IL_PAL_RGBA32)) || (Pal->PalType == IL_PAL_RGB24 && (DestFormat == IL_PAL_BGR32 || DestFormat == IL_PAL_BGRA32))) { for (i = 0, j = 0; i < Pal->PalSize; i += 3, j += 4) { NewPal->Palette[j] = Pal->Palette[i+2]; NewPal->Palette[j+1] = Pal->Palette[i+1]; NewPal->Palette[j+2] = Pal->Palette[i]; NewPal->Palette[j+3] = 255; } } else { for (i = 0, j = 0; i < Pal->PalSize; i += 3, j += 4) { NewPal->Palette[j] = Pal->Palette[i]; NewPal->Palette[j+1] = Pal->Palette[i+1]; NewPal->Palette[j+2] = Pal->Palette[i+2]; NewPal->Palette[j+3] = 255; } } NewPal->PalSize = NewPalSize; NewPal->PalType = DestFormat; break; case IL_PAL_RGB32: NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); if (NewPal->Palette == NULL) goto alloc_error; if (DestFormat == IL_PAL_BGR32 || DestFormat == IL_PAL_BGRA32) { for (i = 0; i < Pal->PalSize; i += 4) { NewPal->Palette[i] = Pal->Palette[i+2]; NewPal->Palette[i+1] = Pal->Palette[i+1]; NewPal->Palette[i+2] = Pal->Palette[i]; NewPal->Palette[i+3] = 255; } } else { for (i = 0; i < Pal->PalSize; i += 4) { NewPal->Palette[i] = Pal->Palette[i]; NewPal->Palette[i+1] = Pal->Palette[i+1]; NewPal->Palette[i+2] = Pal->Palette[i+2]; NewPal->Palette[i+3] = 255; } } NewPal->PalType = DestFormat; break; case IL_PAL_RGBA32: NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); if (NewPal->Palette == NULL) goto alloc_error; if (DestFormat == IL_PAL_BGR32 || DestFormat == IL_PAL_BGRA32) { for (i = 0; i < Pal->PalSize; i += 4) { NewPal->Palette[i] = Pal->Palette[i+2]; NewPal->Palette[i+1] = Pal->Palette[i+1]; NewPal->Palette[i+2] = Pal->Palette[i]; NewPal->Palette[i+3] = Pal->Palette[i+3]; } } else { memcpy(NewPal->Palette, Pal->Palette, Pal->PalSize); } NewPal->PalType = DestFormat; break; case IL_PAL_BGR32: NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); if (NewPal->Palette == NULL) goto alloc_error; if (DestFormat == IL_PAL_RGB32 || DestFormat == IL_PAL_RGBA32) { for (i = 0; i < Pal->PalSize; i += 4) { NewPal->Palette[i] = Pal->Palette[i+2]; NewPal->Palette[i+1] = Pal->Palette[i+1]; NewPal->Palette[i+2] = Pal->Palette[i]; NewPal->Palette[i+3] = 255; } } else { for (i = 0; i < Pal->PalSize; i += 4) { NewPal->Palette[i] = Pal->Palette[i]; NewPal->Palette[i+1] = Pal->Palette[i+1]; NewPal->Palette[i+2] = Pal->Palette[i+2]; NewPal->Palette[i+3] = 255; } } NewPal->PalType = DestFormat; break; case IL_PAL_BGRA32: NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); if (NewPal->Palette == NULL) goto alloc_error; if (DestFormat == IL_PAL_RGB32 || DestFormat == IL_PAL_RGBA32) { for (i = 0; i < Pal->PalSize; i += 4) { NewPal->Palette[i] = Pal->Palette[i+2]; NewPal->Palette[i+1] = Pal->Palette[i+1]; NewPal->Palette[i+2] = Pal->Palette[i]; NewPal->Palette[i+3] = Pal->Palette[i+3]; } } else { memcpy(NewPal->Palette, Pal->Palette, Pal->PalSize); } NewPal->PalType = DestFormat; break; default: ilSetError(IL_INVALID_PARAM); return NULL; } break; default: ilSetError(IL_INVALID_PARAM); return NULL; } NewPal->PalType = DestFormat; return NewPal; alloc_error: ifree(NewPal); return NULL; }
ILboolean iLoadPcdInternal(ILimage* image) { ILubyte VertOrientation; ILuint Width, Height, i, Total, x, CurPos = 0; ILubyte *Y1=NULL, *Y2=NULL, *CbCr=NULL, r = 0, g = 0, b = 0; ILuint PicNum; if (image == NULL) { il2SetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } image->io.seek(&image->io, 72, IL_SEEK_CUR); if (image->io.read(&image->io, &VertOrientation, 1, 1) != 1) return IL_FALSE; image->io.seek(&image->io, -72, IL_SEEK_CUR); // Can't rewind PicNum = iGetInt(IL_PCD_PICNUM); switch (PicNum) { case 0: image->io.seek(&image->io, 0x02000, IL_SEEK_CUR); Width = 192; Height = 128; break; case 1: image->io.seek(&image->io, 0x0b800, IL_SEEK_CUR); Width = 384; Height = 256; break; case 2: image->io.seek(&image->io, 0x30000, IL_SEEK_CUR); Width = 768; Height = 512; break; default: il2SetError(IL_INVALID_PARAM); return IL_FALSE; } if (image->io.tell(&image->io) == IL_EOF) // Supposed to have data here. return IL_FALSE; Y1 = (ILubyte*)ialloc(Width); Y2 = (ILubyte*)ialloc(Width); CbCr = (ILubyte*)ialloc(Width); if (Y1 == NULL || Y2 == NULL || CbCr == NULL) { ifree(Y1); ifree(Y2); ifree(CbCr); return IL_FALSE; } if (!il2TexImage(image, Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } image->Origin = IL_ORIGIN_LOWER_LEFT; Total = Height >> 1; for (i = 0; i < Total; i++) { image->io.read(&image->io, Y1, 1, Width); image->io.read(&image->io, Y2, 1, Width); if (image->io.read(&image->io, CbCr, 1, Width) != Width) { // Only really need to check the last one. ifree(Y1); ifree(Y2); ifree(CbCr); return IL_FALSE; } for (x = 0; x < Width; x++) { YCbCr2RGB(Y1[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b); image->Data[CurPos++] = r; image->Data[CurPos++] = g; image->Data[CurPos++] = b; } for (x = 0; x < Width; x++) { YCbCr2RGB(Y2[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b); image->Data[CurPos++] = r; image->Data[CurPos++] = g; image->Data[CurPos++] = b; } } ifree(Y1); ifree(Y2); ifree(CbCr); // Not sure how it is...the documentation is hard to understand if ((VertOrientation & 0x3F) != 8) image->Origin = IL_ORIGIN_LOWER_LEFT; else image->Origin = IL_ORIGIN_UPPER_LEFT; return il2FixImage(image); }
ILvoid EndianSwapData(void *_Image) { ILuint i; ILubyte *temp, *s, *d; ILushort *ShortS, *ShortD; ILuint *IntS, *IntD; ILfloat *FltS, *FltD; ILdouble *DblS, *DblD; ILimage *Image = (ILimage*)_Image; switch (Image->Type) { case IL_BYTE: case IL_UNSIGNED_BYTE: switch (Image->Bpp) { case 3: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; s = Image->Data; d = temp; for( i = Image->Width * Image->Height; i > 0; i-- ) { *d++ = *(s+2); *d++ = *(s+1); *d++ = *s; s += 3; } ifree(Image->Data); Image->Data = temp; break; case 4: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; s = Image->Data; d = temp; for (i = Image->Width * Image->Height; i > 0; i--) { *d++ = *(s+3); *d++ = *(s+2); *d++ = *(s+1); *d++ = *s; s += 4; } ifree(Image->Data); Image->Data = temp; break; } break; case IL_SHORT: case IL_UNSIGNED_SHORT: switch (Image->Bpp) { case 3: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; ShortS = (ILushort*)Image->Data; ShortD = (ILushort*)temp; for (i = Image->Width * Image->Height; i > 0; i--) { *ShortD = *ShortS++; iSwapUShort(ShortD++); *ShortD = *ShortS++; iSwapUShort(ShortD++); *ShortD = *ShortS++; iSwapUShort(ShortD++); } ifree(Image->Data); Image->Data = temp; break; case 4: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; ShortS = (ILushort*)Image->Data; ShortD = (ILushort*)temp; for (i = Image->Width * Image->Height; i > 0; i--) { *ShortD = *ShortS++; iSwapUShort(ShortD++); *ShortD = *ShortS++; iSwapUShort(ShortD++); *ShortD = *ShortS++; iSwapUShort(ShortD++); *ShortD = *ShortS++; iSwapUShort(ShortD++); } ifree(Image->Data); Image->Data = temp; break; } break; case IL_INT: case IL_UNSIGNED_INT: switch (Image->Bpp) { case 3: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; IntS = (ILuint*)Image->Data; IntD = (ILuint*)temp; for (i = Image->Width * Image->Height; i > 0; i--) { *IntD = *IntS++; iSwapUInt(IntD++); *IntD = *IntS++; iSwapUInt(IntD++); *IntD = *IntS++; iSwapUInt(IntD++); } ifree(Image->Data); Image->Data = temp; break; case 4: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; IntS = (ILuint*)Image->Data; IntD = (ILuint*)temp; for (i = Image->Width * Image->Height; i > 0; i--) { *IntD = *IntS++; iSwapUInt(IntD++); *IntD = *IntS++; iSwapUInt(IntD++); *IntD = *IntS++; iSwapUInt(IntD++); *IntD = *IntS++; iSwapUInt(IntD++); } ifree(Image->Data); Image->Data = temp; break; } break; case IL_FLOAT: switch (Image->Bpp) { case 3: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; FltS = (ILfloat*)Image->Data; FltD = (ILfloat*)temp; for (i = Image->Width * Image->Height; i > 0; i--) { *FltD = *FltS++; iSwapFloat(FltD++); *FltD = *FltS++; iSwapFloat(FltD++); *FltD = *FltS++; iSwapFloat(FltD++); } ifree(Image->Data); Image->Data = temp; break; case 4: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; FltS = (ILfloat*)Image->Data; FltD = (ILfloat*)temp; for (i = Image->Width * Image->Height; i > 0; i--) { *FltD = *FltS++; iSwapFloat(FltD++); *FltD = *FltS++; iSwapFloat(FltD++); *FltD = *FltS++; iSwapFloat(FltD++); *FltD = *FltS++; iSwapFloat(FltD++); } ifree(Image->Data); Image->Data = temp; break; } break; case IL_DOUBLE: switch (Image->Bpp) { case 3: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; DblS = (ILdouble*)Image->Data; DblD = (ILdouble*)temp; for (i = Image->Width * Image->Height; i > 0; i--) { *DblD = *DblS++; iSwapDouble(DblD++); *DblD = *DblS++; iSwapDouble(DblD++); *DblD = *DblS++; iSwapDouble(DblD++); } ifree(Image->Data); Image->Data = temp; break; case 4: temp = ialloc(Image->SizeOfData); if (temp == NULL) return; DblS = (ILdouble*)Image->Data; DblD = (ILdouble*)temp; for (i = Image->Width * Image->Height; i > 0; i--) { *DblD = *DblS++; iSwapDouble(DblD++); *DblD = *DblS++; iSwapDouble(DblD++); *DblD = *DblS++; iSwapDouble(DblD++); *DblD = *DblS++; iSwapDouble(DblD++); } ifree(Image->Data); Image->Data = temp; break; } break; } if( iCurImage->Format == IL_COLOUR_INDEX ) { switch (iCurImage->Pal.PalType) { case IL_PAL_RGB24: case IL_PAL_BGR24: temp = ialloc(Image->Pal.PalSize); if (temp == NULL) return; s = Image->Pal.Palette; d = temp; for (i = Image->Pal.PalSize / 3; i > 0; i--) { *d++ = *(s+2); *d++ = *(s+1); *d++ = *s; s += 3; } ifree(Image->Pal.Palette); Image->Pal.Palette = temp; break; case IL_PAL_RGBA32: case IL_PAL_RGB32: case IL_PAL_BGRA32: case IL_PAL_BGR32: temp = ialloc(Image->Pal.PalSize); if (temp == NULL) return; s = Image->Pal.Palette; d = temp; for (i = Image->Pal.PalSize / 4; i > 0; i--) { *d++ = *(s+3); *d++ = *(s+2); *d++ = *(s+1); *d++ = *s; s += 4; } ifree(Image->Pal.Palette); Image->Pal.Palette = temp; break; } } return; }
ILAPI ILubyte* ILAPIENTRY il2GetAlpha(ILimage* image, ILenum Type) { ILimage *TempImage; ILubyte *Alpha; ILushort *AlphaShort; ILuint *AlphaInt; ILdouble *AlphaDbl; ILuint i, j, Bpc, Size, AlphaOff; if (image == NULL) { il2SetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } Bpc = ilGetBpcType(Type); if (Bpc == 0) { il2SetError(IL_INVALID_PARAM); return NULL; } if (image->Type == Type) { TempImage = image; } else { TempImage = iConvertImage(image, image->Format, Type); if (TempImage == NULL) return NULL; } Size = image->Width * image->Height * image->Depth * TempImage->Bpp; Alpha = (ILubyte*)ialloc(Size / TempImage->Bpp * Bpc); if (Alpha == NULL) { if (TempImage != image) ilCloseImage(TempImage); return NULL; } switch (TempImage->Format) { case IL_RGB: case IL_BGR: case IL_LUMINANCE: case IL_COLOUR_INDEX: // @TODO: Make IL_COLOUR_INDEX separate. memset(Alpha, 0xFF, Size / TempImage->Bpp * Bpc); if (TempImage != image) ilCloseImage(TempImage); return Alpha; } // If our format is alpha, just return a copy. if (TempImage->Format == IL_ALPHA) { memcpy(Alpha, TempImage->Data, TempImage->SizeOfData); return Alpha; } if (TempImage->Format == IL_LUMINANCE_ALPHA) AlphaOff = 2; else AlphaOff = 4; switch (TempImage->Type) { case IL_BYTE: case IL_UNSIGNED_BYTE: for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) Alpha[j] = TempImage->Data[i]; break; case IL_SHORT: case IL_UNSIGNED_SHORT: AlphaShort = (ILushort*)Alpha; for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) AlphaShort[j] = ((ILushort*)TempImage->Data)[i]; break; case IL_INT: case IL_UNSIGNED_INT: case IL_FLOAT: // Can throw float in here, because it's the same size. AlphaInt = (ILuint*)Alpha; for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) AlphaInt[j] = ((ILuint*)TempImage->Data)[i]; break; case IL_DOUBLE: AlphaDbl = (ILdouble*)Alpha; for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) AlphaDbl[j] = ((ILdouble*)TempImage->Data)[i]; break; } if (TempImage != image) ilCloseImage(TempImage); return Alpha; }
//@JASON New routine created 28/03/2001 //! Mirrors an image over its y axis ILboolean ILAPIENTRY iMirror(ILimage* image) { ILubyte *Data, *DataPtr, *Temp; ILuint y, d, PixLine; ILint x, c; ILushort *ShortPtr, *TempShort; ILuint *IntPtr, *TempInt; ILdouble *DblPtr, *TempDbl; if (image == NULL) { il2SetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } Data = (ILubyte*)ialloc(image->SizeOfData); if (Data == NULL) return IL_FALSE; PixLine = image->Bps / image->Bpc; switch (image->Bpc) { case 1: Temp = image->Data; for (d = 0; d < image->Depth; d++) { DataPtr = Data + d * image->SizeOfPlane; for (y = 0; y < image->Height; y++) { for (x = image->Width - 1; x >= 0; x--) { for (c = 0; c < image->Bpp; c++, Temp++) { DataPtr[y * PixLine + x * image->Bpp + c] = *Temp; } } } } break; case 2: TempShort = (ILushort*)image->Data; for (d = 0; d < image->Depth; d++) { ShortPtr = (ILushort*)(Data + d * image->SizeOfPlane); for (y = 0; y < image->Height; y++) { for (x = image->Width - 1; x >= 0; x--) { for (c = 0; c < image->Bpp; c++, TempShort++) { ShortPtr[y * PixLine + x * image->Bpp + c] = *TempShort; } } } } break; case 4: TempInt = (ILuint*)image->Data; for (d = 0; d < image->Depth; d++) { IntPtr = (ILuint*)(Data + d * image->SizeOfPlane); for (y = 0; y < image->Height; y++) { for (x = image->Width - 1; x >= 0; x--) { for (c = 0; c < image->Bpp; c++, TempInt++) { IntPtr[y * PixLine + x * image->Bpp + c] = *TempInt; } } } } break; case 8: TempDbl = (ILdouble*)image->Data; for (d = 0; d < image->Depth; d++) { DblPtr = (ILdouble*)(Data + d * image->SizeOfPlane); for (y = 0; y < image->Height; y++) { for (x = image->Width - 1; x >= 0; x--) { for (c = 0; c < image->Bpp; c++, TempDbl++) { DblPtr[y * PixLine + x * image->Bpp + c] = *TempDbl; } } } } break; } ifree(image->Data); image->Data = Data; return IL_TRUE; }
ILboolean iLoadBlp1() { BLP1HEAD Header; ILubyte *DataAndAlpha, *Palette; ILuint i; ILimage *Image = iCurImage; ILboolean BaseCreated = IL_FALSE; #ifndef IL_NO_JPG ILubyte *JpegHeader, *JpegData; ILuint JpegHeaderSize; #endif//IL_NO_JPG if (!iGetBlp1Head(&Header)) return IL_FALSE; if (!iCheckBlp1(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } //@TODO: Remove this. i = 0; switch (Header.Compression) { case BLP_TYPE_JPG: #ifdef IL_NO_JPG // We can only do the Jpeg decoding if we do not have IL_NO_JPEG defined. return IL_FALSE; #else JpegHeaderSize = GetLittleUInt(); JpegHeader = (ILubyte*)ialloc(JpegHeaderSize); if (JpegHeader == NULL) return IL_FALSE; // Read the shared Jpeg header. if (iread(JpegHeader, 1, JpegHeaderSize) != JpegHeaderSize) { ifree(JpegHeader); return IL_FALSE; } //for (i = 0; i < 16; i++) { // Possible maximum of 16 mipmaps //@TODO: Check return value? iseek(Header.MipOffsets[i], IL_SEEK_SET); JpegData = (ILubyte*)ialloc(JpegHeaderSize + Header.MipLengths[i]); if (JpegData == NULL) { ifree(JpegHeader); return IL_FALSE; } memcpy(JpegData, JpegHeader, JpegHeaderSize); if (iread(JpegData + JpegHeaderSize, Header.MipLengths[i], 1) != 1) return IL_FALSE; // Just send the data straight to the Jpeg loader. if (!ilLoadJpegL(JpegData, JpegHeaderSize + Header.MipLengths[i])) return IL_FALSE; // The image data is in BGR(A) order, even though it is Jpeg-compressed. if (Image->Format == IL_RGBA) Image->Format = IL_BGRA; if (Image->Format == IL_RGB) Image->Format = IL_BGR; ifree(JpegData); //} ifree(JpegHeader); #endif//IL_NO_JPG break; case BLP_RAW: switch (Header.PictureType) { // There is no alpha list, so we just read like a normal indexed image. case BLP_RAW_NO_ALPHA: for (i = 0; i < 16; i++) { // Possible maximum of 16 mipmaps if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage. if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; Image = iCurImage; BaseCreated = IL_TRUE; // We have a BGRA palette. Image->Pal.Palette = (ILubyte*)ialloc(256 * 4); if (Image->Pal.Palette == NULL) return IL_FALSE; Image->Pal.PalSize = 1024; Image->Pal.PalType = IL_PAL_BGRA32; // Read in the palette ... if (iread(Image->Pal.Palette, 1, 1024) != 1024) return IL_FALSE; } else { if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done. break; if (Header.MipOffsets[i] == 0 || Header.MipLengths[i] == 0) // No more mipmaps in the file. break; Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOR_INDEX, IL_UNSIGNED_BYTE, NULL); if (Image->Mipmaps == NULL) return IL_FALSE; // Copy the palette from the first image before we change our Image pointer. Image->Mipmaps->Pal.Palette = (ILubyte*)ialloc(256 * 4); if (Image->Mipmaps->Pal.Palette == NULL) return IL_FALSE; Image->Mipmaps->Pal.PalSize = 1024; Image->Mipmaps->Pal.PalType = IL_PAL_BGRA32; memcpy(Image->Mipmaps->Pal.Palette, Image->Pal.Palette, 1024); // Move to the next mipmap in the linked list. Image = Image->Mipmaps; } // The origin should be in the upper left. Image->Origin = IL_ORIGIN_UPPER_LEFT; // Seek to the data and read it. iseek(Header.MipOffsets[i], IL_SEEK_SET); if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData) return IL_FALSE; } break; // These cases are identical and have an alpha list following the image data. case BLP_RAW_PLUS_ALPHA1: case BLP_RAW_PLUS_ALPHA2: // Create the image. if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; DataAndAlpha = (ILubyte*)ialloc(Header.Width * Header.Height); Palette = (ILubyte*)ialloc(256 * 4); if (DataAndAlpha == NULL || Palette == NULL) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } // Read in the data and the palette. if (iread(Palette, 1, 1024) != 1024) { ifree(Palette); return IL_FALSE; } // Seek to the data and read it. iseek(Header.MipOffsets[i], IL_SEEK_SET); if (iread(DataAndAlpha, Header.Width * Header.Height, 1) != 1) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } // Convert the color-indexed data to BGRX. for (i = 0; i < Header.Width * Header.Height; i++) { Image->Data[i*4] = Palette[DataAndAlpha[i]*4]; Image->Data[i*4+1] = Palette[DataAndAlpha[i]*4+1]; Image->Data[i*4+2] = Palette[DataAndAlpha[i]*4+2]; } // Read in the alpha list. if (iread(DataAndAlpha, Header.Width * Header.Height, 1) != 1) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } // Finally put the alpha data into the image data. for (i = 0; i < Header.Width * Header.Height; i++) { Image->Data[i*4+3] = DataAndAlpha[i]; } ifree(DataAndAlpha); ifree(Palette); break; } break; //default: // Should already be checked by iCheckBlp1. } // Set the origin (always upper left). Image->Origin = IL_ORIGIN_UPPER_LEFT; return ilFixImage(); }
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; }
// Internal function used to load the BLP. ILboolean iLoadBlpInternal(void) { BLP2HEAD Header; ILubyte *CompData; ILimage *Image; ILuint Mip, j, x, CompSize, AlphaSize, AlphaOff; ILint y; ILboolean BaseCreated = IL_FALSE; ILubyte *DataAndAlpha = NULL, *Palette = NULL, AlphaMask; //, *JpegHeader, *JpegData; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iGetBlp2Head(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!iCheckBlp2(&Header)) { goto check_blp1; } //@TODO: Remove this! if (Header.Type != BLP_TYPE_DXTC_RAW) return IL_FALSE; switch (Header.Compression) { case BLP_RAW: for (Mip = 0; Mip < 16; Mip++) { // Possible maximum of 16 mipmaps if (BaseCreated) { if (Header.HasMips == 0) // Does not have mipmaps, so we are done. break; if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done. break; if (Header.MipOffsets[Mip] == 0 || Header.MipLengths == 0) // No more mipmaps in the file. break; } switch (Header.AlphaBits) { case 0: if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage. if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; Image = iCurImage; BaseCreated = IL_TRUE; Image->Pal.Palette = (ILubyte*)ialloc(256 * 4); // 256 entries of ARGB8888 values (1024). if (Image->Pal.Palette == NULL) return IL_FALSE; Image->Pal.PalSize = 1024; Image->Pal.PalType = IL_PAL_BGRA32; //@TODO: Find out if this is really BGRA data. if (iread(Image->Pal.Palette, 1, 1024) != 1024) // Read in the palette. return IL_FALSE; } else { Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL); if (Image->Mipmaps == NULL) return IL_FALSE; // Copy the palette from the first image before we change our Image pointer. iCopyPalette(&Image->Mipmaps->Pal, &Image->Pal); // Move to the next mipmap in the linked list. Image = Image->Mipmaps; } // The origin should be in the upper left. Image->Origin = IL_ORIGIN_UPPER_LEFT; // These two should be the same (tells us how much data is in the file for this mipmap level). if (Header.MipLengths[Mip] != Image->SizeOfData) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Finally read in the image data. iseek(Header.MipOffsets[Mip], IL_SEEK_SET); if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData) return IL_FALSE; break; case 1: if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage. if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; Image = iCurImage; BaseCreated = IL_TRUE; Palette = (ILubyte*)ialloc(256 * 4); if (Palette == NULL) return IL_FALSE; // Read in the palette. if (iread(Palette, 1, 1024) != 1024) { ifree(Palette); return IL_FALSE; } // We only allocate this once and reuse this buffer with every mipmap (since successive ones are smaller). DataAndAlpha = (ILubyte*)ialloc(Image->Width * Image->Height); if (DataAndAlpha == NULL) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } } else { Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL); if (Image->Mipmaps == NULL) return IL_FALSE; // Move to the next mipmap in the linked list. Image = Image->Mipmaps; } // The origin should be in the upper left. Image->Origin = IL_ORIGIN_UPPER_LEFT; // Determine the size of the alpha data following the color indices. AlphaSize = Image->Width * Image->Height / 8; if (AlphaSize == 0) AlphaSize = 1; // Should never be 0. // These two should be the same (tells us how much data is in the file for this mipmap level). if (Header.MipLengths[Mip] != Image->SizeOfData / 4 + AlphaSize) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Seek to the data and read it. iseek(Header.MipOffsets[Mip], IL_SEEK_SET); if (iread(DataAndAlpha, Image->Width * Image->Height, 1) != 1) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } // Convert the color-indexed data to BGRX. for (j = 0; j < Image->Width * Image->Height; j++) { Image->Data[j*4] = Palette[DataAndAlpha[j]*4]; Image->Data[j*4+1] = Palette[DataAndAlpha[j]*4+1]; Image->Data[j*4+2] = Palette[DataAndAlpha[j]*4+2]; } // Read in the alpha list. if (iread(DataAndAlpha, AlphaSize, 1) != 1) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } AlphaMask = 0x01; // Lowest bit AlphaOff = 0; // The really strange thing about this alpha data is that it is upside-down when compared to the // regular color-indexed data, so we have to flip it. for (y = Image->Height - 1; y >= 0; y--) { for (x = 0; x < Image->Width; x++) { if (AlphaMask == 0) { // Shifting it past the highest bit makes it 0, since we only have 1 byte. AlphaOff++; // Move along the alpha buffer. AlphaMask = 0x01; // Reset the alpha mask. } // This is just 1-bit alpha, so it is either on or off. Image->Data[Image->Bps * y + x * 4 + 3] = DataAndAlpha[AlphaOff] & AlphaMask ? 0xFF : 0x00; AlphaMask <<= 1; } } break; default: //@TODO: Accept any other alpha values? ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } } // Done, so we can finally free these two. ifree(DataAndAlpha); ifree(Palette); break; case BLP_DXTC: for (Mip = 0; Mip < 16; Mip++) { // Possible maximum of 16 mipmaps //@TODO: Other formats //if (Header.AlphaBits == 0) // if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) // return IL_FALSE; if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage. if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; Image = iCurImage; BaseCreated = IL_TRUE; } else { if (Header.HasMips == 0) // Does not have mipmaps, so we are done. break; if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done. break; if (Header.MipOffsets[Mip] == 0 || Header.MipLengths[Mip] == 0) // No more mipmaps in the file. break; //@TODO: Other formats // ilNewImageFull automatically changes widths and heights of 0 to 1, so we do not have to worry about it. Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); if (Image->Mipmaps == NULL) return IL_FALSE; Image = Image->Mipmaps; } // The origin should be in the upper left. Image->Origin = IL_ORIGIN_UPPER_LEFT; //@TODO: Only do the allocation once. CompData = (ILubyte*)ialloc(Header.MipLengths[Mip]); if (CompData == NULL) return IL_FALSE; // Read in the compressed mipmap data. iseek(Header.MipOffsets[Mip], IL_SEEK_SET); if (iread(CompData, 1, Header.MipLengths[Mip]) != Header.MipLengths[Mip]) { ifree(CompData); return IL_FALSE; } switch (Header.AlphaBits) { case 0: // DXT1 without alpha case 1: // DXT1 with alpha // Check to make sure that the MipLength reported is the size needed, so that // DecompressDXT1 does not crash. CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 8; if (CompSize != Header.MipLengths[Mip]) { ilSetError(IL_INVALID_FILE_HEADER); ifree(CompData); return IL_FALSE; } if (!DecompressDXT1(Image, CompData)) { ifree(CompData); return IL_FALSE; } break; case 8: // Check to make sure that the MipLength reported is the size needed, so that // DecompressDXT3/5 do not crash. CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 16; if (CompSize != Header.MipLengths[Mip]) { ifree(CompData); ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } switch (Header.AlphaType) { case 0: // All three of case 1: // these refer to case 8: // DXT3... if (!DecompressDXT3(Image, CompData)) { ifree(CompData); return IL_FALSE; } break; case 7: // DXT5 compression if (!DecompressDXT5(Image, CompData)) { ifree(CompData); return IL_FALSE; } break; //default: // Should already be checked by iCheckBlp2. } break; //default: // Should already be checked by iCheckBlp2. } //@TODO: Save DXTC data. ifree(CompData); } break; //default: } return ilFixImage(); check_blp1: iseek(-148, IL_SEEK_CUR); // Go back the size of the BLP2 header, since we tried reading it. return iLoadBlp1(); }
ILboolean iIcnsReadData(ILboolean *BaseCreated, ILboolean IsAlpha, ILint Width, ICNSDATA *Entry, ILimage **Image) { ILint Position = 0, RLEPos = 0, Channel, i; ILubyte RLERead, *Data = NULL; ILimage *TempImage = NULL; ILboolean ImageAlreadyExists = IL_FALSE; // The .icns format stores the alpha and RGB as two separate images, so this // checks to see if one exists for that particular size. Unfortunately, // there is no guarantee that they are in any particular order. if (*BaseCreated && iCurImage != NULL) { TempImage = iCurImage; while (TempImage != NULL) { if ((ILuint)Width == TempImage->Width) { ImageAlreadyExists = IL_TRUE; break; } TempImage = TempImage->Next; } } Data = ialloc(Entry->Size - 8); if (Data == NULL) return IL_FALSE; if (!ImageAlreadyExists) { if (!*BaseCreated) // Create base image { ilTexImage(Width, Width, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; *Image = iCurImage; *BaseCreated = IL_TRUE; } else // Create next image in list { (*Image)->Next = ilNewImage(Width, Width, 1, 4, 1); *Image = (*Image)->Next; (*Image)->Format = IL_RGBA; (*Image)->Origin = IL_ORIGIN_UPPER_LEFT; } TempImage = *Image; } if (IsAlpha) // Alpha is never compressed. { iread(Data, Entry->Size - 8, 1); // Size includes the header if (Entry->Size - 8 != Width * Width) { ifree(Data); return IL_FALSE; } for (i = 0; i < Width * Width; i++) { TempImage->Data[(i * 4) + 3] = Data[i]; } } else if (Width == 256 || Width == 512) // JPEG2000 encoded - uses JasPer { #ifndef IL_NO_JP2 iread(Data, Entry->Size - 8, 1); // Size includes the header if (ilLoadJp2LInternal(Data, Entry->Size - 8, TempImage) == IL_FALSE) { ifree(Data); ilSetError(IL_LIB_JP2_ERROR); return IL_TRUE; } #else // Cannot handle this size. ilSetError(IL_LIB_JP2_ERROR); //@TODO: Handle this better...just skip the data. return IL_FALSE; #endif//IL_NO_JP2 } else // RGB data { iread(Data, Entry->Size - 8, 1); // Size includes the header if (Width == 128) RLEPos += 4; // There are an extra 4 bytes here of zeros. //@TODO: Should we check to make sure they are all 0? if (Entry->Size - 8 == Width * Width * 4) // Uncompressed { //memcpy(TempImage->Data, Data, Entry->Size); for (i = 0; i < Width * Width; i++, Position += 4) { TempImage->Data[i * 4 + 0] = Data[Position+1]; TempImage->Data[i * 4 + 1] = Data[Position+2]; TempImage->Data[i * 4 + 2] = Data[Position+3]; } } else // RLE decoding { for (Channel = 0; Channel < 3; Channel++) { Position = 0; while (Position < Width * Width) { RLERead = Data[RLEPos]; RLEPos++; if (RLERead >= 128) { for (i = 0; i < RLERead - 125 && (Position + i) < Width * Width; i++) { TempImage->Data[Channel + (Position + i) * 4] = Data[RLEPos]; } RLEPos++; Position += RLERead - 125; } else { for (i = 0; i < RLERead + 1 && (Position + i) < Width * Width; i++) { TempImage->Data[Channel + (Position + i) * 4] = Data[RLEPos + i]; } RLEPos += RLERead + 1; Position += RLERead + 1; } } } } } ifree(Data); return IL_TRUE; }
ILAPI ILboolean ILAPIENTRY ilClearImage_(ILimage *Image) { ILuint i, c, NumBytes; ILubyte Colours[32]; // Maximum is sizeof(double) * 4 = 32 ILubyte *BytePtr; ILushort *ShortPtr; ILuint *IntPtr; ILfloat *FloatPtr; ILdouble *DblPtr; NumBytes = Image->Bpp * Image->Bpc; ilGetClear(Colours, Image->Format, Image->Type); if (Image->Format != IL_COLOUR_INDEX) { switch (Image->Type) { case IL_BYTE: case IL_UNSIGNED_BYTE: BytePtr = (ILubyte*)Colours; for (c = 0; c < NumBytes; c += Image->Bpc) { for (i = c; i < Image->SizeOfData; i += NumBytes) { Image->Data[i] = BytePtr[c]; } } break; case IL_SHORT: case IL_UNSIGNED_SHORT: ShortPtr = (ILushort*)Colours; for (c = 0; c < NumBytes; c += Image->Bpc) { for (i = c; i < Image->SizeOfData; i += NumBytes) { *((ILushort*)(Image->Data + i)) = ShortPtr[c]; } } break; case IL_INT: case IL_UNSIGNED_INT: IntPtr = (ILuint*)Colours; for (c = 0; c < NumBytes; c += Image->Bpc) { for (i = c; i < Image->SizeOfData; i += NumBytes) { *((ILuint*)(Image->Data + i)) = IntPtr[c]; } } break; case IL_FLOAT: FloatPtr = (ILfloat*)Colours; for (c = 0; c < NumBytes; c += Image->Bpc) { for (i = c; i < Image->SizeOfData; i += NumBytes) { *((ILfloat*)(Image->Data + i)) = FloatPtr[c]; } } break; case IL_DOUBLE: DblPtr = (ILdouble*)Colours; for (c = 0; c < NumBytes; c += Image->Bpc) { for (i = c; i < Image->SizeOfData; i += NumBytes) { *((ILdouble*)(Image->Data + i)) = DblPtr[c]; } } break; } } else { imemclear(Image->Data, Image->SizeOfData); if (Image->Pal.Palette) ifree(Image->Pal.Palette); Image->Pal.Palette = (ILubyte*)ialloc(4); if (Image->Pal.Palette == NULL) { return IL_FALSE; } Image->Pal.PalType = IL_PAL_RGBA32; Image->Pal.PalSize = 4; Image->Pal.Palette[0] = Colours[0] * UCHAR_MAX; Image->Pal.Palette[1] = Colours[1] * UCHAR_MAX; Image->Pal.Palette[2] = Colours[2] * UCHAR_MAX; Image->Pal.Palette[3] = Colours[3] * UCHAR_MAX; } return IL_TRUE; }
/*! \param Image Specifies the image. The function fails if this is zero. \param Width Specifies the new image width. This cannot be 0. \param Height Specifies the new image height. This cannot be 0. \param Depth Specifies the new image depth. This cannot be 0. \param Bpp Number of channels (ex. 3 for RGB) \param Format Enum of the desired format. Any format values are accepted. \param Type Enum of the desired type. Any type values are accepted. \param Data Specifies data that should be copied to the new image. If this parameter is NULL, no data is copied, and the new image data consists of undefined values. \exception IL_ILLEGAL_OPERATION No currently bound image. \exception IL_INVALID_PARAM One of the parameters is incorrect, such as one of the dimensions being 0. \exception IL_OUT_OF_MEMORY Could not allocate enough memory. \return Boolean value of failure or success*/ ILAPI ILboolean ILAPIENTRY il2TexImage(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, void *Data) { if (Image == NULL) { il2SetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } ILubyte BpcType = ilGetBpcType(Type); if (BpcType == 0) { il2SetError(IL_INVALID_PARAM); return IL_FALSE; } // Reset palette Image->Pal.clear(); ilCloseImage(Image->Mipmaps); Image->Mipmaps = NULL; ilCloseImage(Image->Next); Image->Next = NULL; ilCloseImage(Image->Faces); Image->Faces = NULL; ilCloseImage(Image->Layers); Image->Layers = NULL; if (Image->AnimList) ifree(Image->AnimList); if (Image->Profile) ifree(Image->Profile); if (Image->DxtcData) ifree(Image->DxtcData); if (Image->Data) ifree(Image->Data); //// //@TODO: Also check against format? /*if (Width == 0 || Height == 0 || Depth == 0 || Bpp == 0) { il2SetError(IL_INVALID_PARAM); return IL_FALSE; }*/ //// if (Width == 0) Width = 1; if (Height == 0) Height = 1; if (Depth == 0) Depth = 1; Image->Width = Width; Image->Height = Height; Image->Depth = Depth; Image->Bpp = Bpp; Image->Bpc = BpcType; Image->Bps = Width * Bpp * Image->Bpc; Image->SizeOfPlane = Image->Bps * Height; Image->SizeOfData = Image->SizeOfPlane * Depth; Image->Format = Format; Image->Type = Type; Image->Data = (ILubyte*)ialloc(Image->SizeOfData); if (Image->Data != NULL) { if (Data != NULL) { memcpy(Image->Data, Data, Image->SizeOfData); } return IL_TRUE; } else { return IL_FALSE; } }
/* * NAME: jfs_create(dip, dentry, mode) * * FUNCTION: create a regular file in the parent directory <dip> * with name = <from dentry> and mode = <mode> * * PARAMETER: dip - parent directory vnode * dentry - dentry of new file * mode - create mode (rwxrwxrwx). * nd- nd struct * * RETURN: Errors from subroutines * */ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, bool excl) { int rc = 0; tid_t tid; /* transaction id */ struct inode *ip = NULL; /* child directory inode */ ino_t ino; struct component_name dname; /* child directory name */ struct btstack btstack; struct inode *iplist[2]; struct tblock *tblk; jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name); dquot_initialize(dip); /* * search parent directory for entry/freespace * (dtSearch() returns parent directory page pinned) */ if ((rc = get_UCSname(&dname, dentry))) goto out1; /* * Either iAlloc() or txBegin() may block. Deadlock can occur if we * block there while holding dtree page, so we allocate the inode & * begin the transaction before we search the directory. */ ip = ialloc(dip, mode); if (IS_ERR(ip)) { rc = PTR_ERR(ip); goto out2; } tid = txBegin(dip->i_sb, 0); mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); rc = jfs_init_acl(tid, ip, dip); if (rc) goto out3; rc = jfs_init_security(tid, ip, dip, &dentry->d_name); if (rc) { txAbort(tid, 0); goto out3; } if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { jfs_err("jfs_create: dtSearch returned %d", rc); txAbort(tid, 0); goto out3; } tblk = tid_to_tblock(tid); tblk->xflag |= COMMIT_CREATE; tblk->ino = ip->i_ino; tblk->u.ixpxd = JFS_IP(ip)->ixpxd; iplist[0] = dip; iplist[1] = ip; /* * initialize the child XAD tree root in-line in inode */ xtInitRoot(tid, ip); /* * create entry in parent directory for child directory * (dtInsert() releases parent directory page) */ ino = ip->i_ino; if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { if (rc == -EIO) { jfs_err("jfs_create: dtInsert returned -EIO"); txAbort(tid, 1); /* Marks Filesystem dirty */ } else txAbort(tid, 0); /* Filesystem full */ goto out3; } ip->i_op = &jfs_file_inode_operations; ip->i_fop = &jfs_file_operations; ip->i_mapping->a_ops = &jfs_aops; mark_inode_dirty(ip); dip->i_ctime = dip->i_mtime = CURRENT_TIME; mark_inode_dirty(dip); rc = txCommit(tid, 2, &iplist[0], 0); out3: txEnd(tid); mutex_unlock(&JFS_IP(ip)->commit_mutex); mutex_unlock(&JFS_IP(dip)->commit_mutex); if (rc) { free_ea_wmap(ip); clear_nlink(ip); unlock_new_inode(ip); iput(ip); } else { unlock_new_inode(ip); d_instantiate(dentry, ip); } out2: free_UCSname(&dname); out1: jfs_info("jfs_create: rc:%d", rc); return rc; }
// Copies everything but the Data from Src to Dest. ILAPI ILboolean ILAPIENTRY il2CopyImageAttr(ILimage *Dest, ILimage *Src) { if (Dest == NULL || Src == NULL) { il2SetError(IL_INVALID_PARAM); return IL_FALSE; } if (Dest->Data != NULL) { ifree(Dest->Data); Dest->Data = NULL; } Dest->Pal.clear(); if (Dest->Faces) { ilCloseImage(Dest->Faces); Dest->Faces = NULL; } if (Dest->Layers) { ilCloseImage(Dest->Layers); Dest->Layers = NULL; } if (Dest->Mipmaps) { ilCloseImage(Dest->Mipmaps); Dest->Mipmaps = NULL; } if (Dest->Next) { ilCloseImage(Dest->Next); Dest->Next = NULL; } if (Dest->Profile) { ifree(Dest->Profile); Dest->Profile = NULL; Dest->ProfileSize = 0; } if (Dest->DxtcData) { ifree(Dest->DxtcData); Dest->DxtcData = NULL; Dest->DxtcFormat = IL_DXT_NO_COMP; Dest->DxtcSize = 0; } if (Src->AnimList && Src->AnimSize) { Dest->AnimList = (ILuint*)ialloc(Src->AnimSize * sizeof(ILuint)); if (Dest->AnimList == NULL) { return IL_FALSE; } memcpy(Dest->AnimList, Src->AnimList, Src->AnimSize * sizeof(ILuint)); } if (Src->Profile) { Dest->Profile = (ILubyte*)ialloc(Src->ProfileSize); if (Dest->Profile == NULL) { return IL_FALSE; } memcpy(Dest->Profile, Src->Profile, Src->ProfileSize); Dest->ProfileSize = Src->ProfileSize; } Dest->Pal.use(Src->Pal.getNumCols(), Src->Pal.getPalette(), Src->Pal.getPalType()); Dest->Width = Src->Width; Dest->Height = Src->Height; Dest->Depth = Src->Depth; Dest->Bpp = Src->Bpp; Dest->Bpc = Src->Bpc; Dest->Bps = Src->Bps; Dest->SizeOfPlane = Src->SizeOfPlane; Dest->SizeOfData = Src->SizeOfData; Dest->Format = Src->Format; Dest->Type = Src->Type; Dest->Origin = Src->Origin; Dest->Duration = Src->Duration; Dest->CubeFlags = Src->CubeFlags; Dest->AnimSize = Src->AnimSize; Dest->OffX = Src->OffX; Dest->OffY = Src->OffY; return IL_TRUE/*iCopySubImages(Dest, Src)*/; }
// Internal function used to load the .hdr. ILboolean iLoadHdrInternal() { HDRHEADER Header; ILfloat *data; ILubyte *scanline; ILuint i, j, e, r, g, b; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iGetHdrHead(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!iCheckHdr(&Header)) { //iseek(-(ILint)sizeof(HDRHEAD), IL_SEEK_CUR); ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Update the current image with the new dimensions if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_FLOAT, NULL)) { return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; //read image data if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) iPreCache(iCurImage->Width / 8 * iCurImage->Height); data = (ILfloat*)iCurImage->Data; scanline = (ILubyte*)ialloc(Header.Width*4); for (i = 0; i < Header.Height; ++i) { ReadScanline(scanline, Header.Width); //convert hdrs internal format to floats for (j = 0; j < 4*Header.Width; j += 4) { ILuint *ee; ILfloat t, *ff; e = scanline[j + 3]; r = scanline[j + 0]; g = scanline[j + 1]; b = scanline[j + 2]; //t = (float)pow(2.f, ((ILint)e) - 128); if (e != 0) e = (e - 1) << 23; // All this just to avoid stric-aliasing warnings... // was: t = *(ILfloat*)&e ee = &e; ff = (ILfloat*)ee; t = *ff; data[0] = (r/255.0f)*t; data[1] = (g/255.0f)*t; data[2] = (b/255.0f)*t; data += 3; } } iUnCache(); ifree(scanline); return ilFixImage(); }
void main(int argc, char *argv[]) { Filsys *fs; int ream, fsok; int newbufsize, nocheck; char buf[NAMELEN]; int pid, ctl; progname = "kfs"; procname = "init"; /* * insulate from invoker's environment and keep it from swapping */ rfork(RFNAMEG|RFNOTEG|RFREND); confinit(); sfd = -1; ream = 0; newbufsize = 0; nocheck = 0; wrenfile = "/dev/sdC0/fs"; pid = getpid(); snprint(buf, sizeof buf, "/proc/%d/ctl", pid); ctl = open(buf, OWRITE); fprint(ctl, "noswap\n"); close(ctl); buf[0] = '\0'; ARGBEGIN{ case 'b': newbufsize = atol(ARGF()); break; case 'c': nocheck = 1; break; case 'f': wrenfile = ARGF(); break; case 'm': nwren = atol(ARGF()); break; case 'n': strncpy(buf, ARGF(), NAMELEN-1); buf[NAMELEN-1] = '\0'; break; case 'p': cmdmode = atol(ARGF()); break; case 'r': ream = 1; break; case 's': sfd = 0; rfd = dup(1, -1); close(1); if(open("/dev/cons", OWRITE) < 0) open("#c/cons", OWRITE); break; case 'B': conf.niobuf = strtoul(ARGF(), 0, 0); break; case 'C': chat = 1; break; default: usage(); }ARGEND if(argc != 0) usage(); cmdfd = 2; if (access(wrenfile, AREAD|AWRITE) == -1) sysfatal("%s cannot access device", wrenfile); formatinit(); sublockinit(); if(buf[0]) sprint(service, "kfs.%s", buf); else strcpy(service, "kfs"); chan = chaninit(service); consinit(); tlocks = ialloc(NTLOCK * sizeof *tlocks); uid = ialloc(conf.nuid * sizeof(*uid)); uidspace = ialloc(conf.uidspace * sizeof(*uidspace)); gidspace = ialloc(conf.gidspace * sizeof(*gidspace)); /* * init global locks */ wlock(&mainlock); wunlock(&mainlock); /* * init the file system, ream it if needed, and get the block sizes */ ream = fsinit(ream, newbufsize); iobufinit(); for(fs=filesys; fs->name; fs++) if(fs->flags & FREAM){ /* set by fsinit if reamed */ ream++; rootream(fs->dev, getraddr(fs->dev)); superream(fs->dev, superaddr(fs->dev)); } boottime = time(nil); consserve(); fsok = superok(filesys[0].dev, superaddr(filesys[0].dev), 0); if(!nocheck && !ream && !fsok) cmd_exec("check fq"); startproc(forkserve, "srv"); startproc(syncproc, "sync"); exits(0); }
// Internal function used to save the Hdr. ILboolean iSaveHdrInternal() { ILimage *TempImage; rgbe_header_info stHeader; unsigned char rgbe[4]; ILubyte *buffer; ILfloat *data; ILuint i; ILboolean bRet; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } stHeader.exposure = 0; stHeader.gamma = 0; stHeader.programtype[0] = 0; stHeader.valid = 0; if (iCurImage->Format != IL_UNSIGNED_BYTE) { TempImage = iConvertImage(iCurImage, IL_RGB, IL_FLOAT); if (TempImage == NULL) return IL_FALSE; } else TempImage = iCurImage; if (!RGBE_WriteHeader(TempImage->Width, TempImage->Height, &stHeader)) return IL_FALSE; if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) iFlipBuffer(TempImage->Data,TempImage->Depth,TempImage->Bps,TempImage->Height); data = (ILfloat*)TempImage->Data; if ((TempImage->Width < 8)||(TempImage->Width > 0x7fff)) { /* run length encoding is not allowed so write flat*/ bRet = RGBE_WritePixels(data,TempImage->Width*TempImage->Height); if (iCurImage != TempImage) ilCloseImage(TempImage); return bRet; } buffer = (ILubyte*)ialloc(sizeof(ILubyte)*4*TempImage->Width); if (buffer == NULL) { /* no buffer space so write flat */ bRet = RGBE_WritePixels(data,TempImage->Width*TempImage->Height); if (iCurImage != TempImage) ilCloseImage(TempImage); return bRet; } while(TempImage->Height-- > 0) { rgbe[0] = 2; rgbe[1] = 2; rgbe[2] = TempImage->Width >> 8; rgbe[3] = TempImage->Width & 0xFF; if (iwrite(rgbe, sizeof(rgbe), 1) < 1) { free(buffer); if (iCurImage != TempImage) ilCloseImage(TempImage); return IL_FALSE; } for(i=0;i<TempImage->Width;i++) { float2rgbe(rgbe,data[RGBE_DATA_RED],data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]); buffer[i] = rgbe[0]; buffer[i+TempImage->Width] = rgbe[1]; buffer[i+2*TempImage->Width] = rgbe[2]; buffer[i+3*TempImage->Width] = rgbe[3]; data += RGBE_DATA_SIZE; } /* write out each of the four channels separately run length encoded */ /* first red, then green, then blue, then exponent */ for(i=0;i<4;i++) { if (RGBE_WriteBytes_RLE(&buffer[i*TempImage->Width],TempImage->Width) != IL_TRUE) { ifree(buffer); if (iCurImage != TempImage) ilCloseImage(TempImage); return IL_FALSE; } } } ifree(buffer); if (iCurImage != TempImage) ilCloseImage(TempImage); return IL_TRUE; }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off; struct dirent de; char buf[512]; struct dinode din; if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((512 % sizeof(struct dinode)) == 0); assert((512 % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } sb.size = xint(size); sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.ninodes = xint(ninodes); bitblocks = size/(512*8) + 1; usedblocks = ninodes / IPB + 3 + bitblocks; freeblock = usedblocks; printf("used %d (bit %d ninode %lu) free %u total %d\n", usedblocks, bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks); assert(nblocks + usedblocks == size); for(i = 0; i < nblocks + usedblocks; i++) wsect(i, zeroes); // [vs] fix to avoid wsect() running over a page boundary char tmp_buf[512] = {}; memcpy(tmp_buf, &sb, sizeof(struct superblock)); wsect(1, &tmp_buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); for(i = 2; i < argc; i++){ assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') ++argv[i]; inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) iappend(inum, buf, cc); close(fd); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(usedblocks); exit(0); }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off, bin_inum, tests_inum, sbin_inum; //dir_inum struct dirent de; char buf[BSIZE]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2) { fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((BSIZE % sizeof(struct dinode)) == 0); assert((BSIZE % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666); if(fsfd < 0) { perror(argv[1]); exit(1); } // 1 fs block = 1 disk sector nmeta = 2 + nlog + ninodeblocks + nbitmap; nblocks = FSSIZE - nmeta; sb.size = xint(FSSIZE); sb.nblocks = xint(nblocks); sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); sb.logstart = xint(2); sb.inodestart = xint(2 + nlog); sb.bmapstart = xint(2 + nlog + ninodeblocks); printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); freeblock = nmeta; // the first free block that we can allocate for(i = 0; i < FSSIZE; i++) { wsect(i, zeroes); } memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); // create /bin folder bin_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(bin_inum); strcpy(de.name, "bin"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(bin_inum); strcpy(de.name, "."); iappend(bin_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(bin_inum, &de, sizeof(de)); // create /dev folder inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(inum); strcpy(de.name, "dev"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(inum); strcpy(de.name, "."); iappend(inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(inum, &de, sizeof(de)); // create /sbin folder sbin_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(sbin_inum); strcpy(de.name, "sbin"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(sbin_inum); strcpy(de.name, "."); iappend(sbin_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(sbin_inum, &de, sizeof(de)); // create /tests folder tests_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(tests_inum); strcpy(de.name, "tests"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(tests_inum); strcpy(de.name, "."); iappend(tests_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(tests_inum, &de, sizeof(de)); for(i = 2; i < argc; i++) { printf("argv[i]: %s and index: %s\n", argv[i], index(argv[i], '/')); //assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0) { perror(argv[i]); exit(1); } if(index(argv[i], '/') != 0) { char foldername[256]; char *progname = malloc(sizeof(char) * 256); strcpy(progname, skipelem(argv[i], foldername)); if(progname[0] == '_') { progname++; } if(strcmp(foldername, "bin") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(bin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "tests") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(tests_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "sbin") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(sbin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "docs") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "shell") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(bin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else { printf("\nERROR: Found folder other than bin and tests: %s\n", foldername); exit(1); } } else { // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') { ++argv[i]; } inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off / BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(freeblock); exit(0); }
//! Loads a .col palette file ILboolean ilLoadColPal(ILconst_string FileName) { ILuint RealFileSize, FileSize; ILushort Version; ILHANDLE ColFile; if (!iCheckExtension(FileName, IL_TEXT("col"))) { ilSetError(IL_INVALID_EXTENSION); return IL_FALSE; } if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } ColFile = iopenr(FileName); if (ColFile == NULL) { ilSetError(IL_COULD_NOT_OPEN_FILE); 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; } iseek(0, IL_SEEK_END); RealFileSize = ftell((FILE*)ColFile); iseek(0, IL_SEEK_SET); if (RealFileSize > 768) { // has a header fread(&FileSize, 4, 1, (FILE*)ColFile); if ((FileSize - 8) % 3 != 0) { // check to make sure an even multiple of 3! icloser(ColFile); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } if (iread(&Version, 2, 1) != 1) { icloser(ColFile); return IL_FALSE; } if (Version != 0xB123) { icloser(ColFile); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } if (iread(&Version, 2, 1) != 1) { icloser(ColFile); return IL_FALSE; } if (Version != 0) { icloser(ColFile); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } } iCurImage->Pal.Palette = (ILubyte*)ialloc(768); if (iCurImage->Pal.Palette == NULL) { icloser(ColFile); return IL_FALSE; } if (iread(iCurImage->Pal.Palette, 1, 768) != 768) { icloser(ColFile); ifree(iCurImage->Pal.Palette); iCurImage->Pal.Palette = NULL; return IL_FALSE; } iCurImage->Pal.PalSize = 768; iCurImage->Pal.PalType = IL_PAL_RGB24; icloser(ColFile); return IL_TRUE; }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off; struct dirent de; char buf[BSIZE]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((BSIZE % sizeof(struct dinode)) == 0); assert((BSIZE % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } // 1 fs block = 1 disk sector nmeta = 2 + nlog + ninodeblocks + nbitmap; nblocks = FSSIZE - nmeta; sb.size = xint(FSSIZE); sb.nblocks = xint(nblocks); sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); sb.logstart = xint(2); sb.inodestart = xint(2+nlog); sb.bmapstart = xint(2+nlog+ninodeblocks); printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); freeblock = nmeta; // the first free block that we can allocate for(i = 0; i < FSSIZE; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); for(i = 2; i < argc; i++){ assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') ++argv[i]; inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) iappend(inum, buf, cc); close(fd); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(freeblock); exit(0); }
//! Loads a Paint Shop Pro formatted palette (.pal) file. ILboolean ilLoadJascPal(ILconst_string FileName) { FILE *PalFile; ILuint NumColours, i, c; ILubyte Buff[BUFFLEN]; ILboolean Error = IL_FALSE; ILpal *Pal = &iCurImage->Pal; if (!iCheckExtension(FileName, IL_TEXT("pal"))) { ilSetError(IL_INVALID_EXTENSION); return IL_FALSE; } if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } #ifndef _UNICODE PalFile = fopen(FileName, "rt"); #else PalFile = _wfopen(FileName, L"rt"); #endif//_UNICODE if (PalFile == NULL) { ilSetError(IL_COULD_NOT_OPEN_FILE); 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; } iFgetw(Buff, BUFFLEN, PalFile); if (stricmp((const char*)Buff, "JASC-PAL")) { Error = IL_TRUE; } iFgetw(Buff, BUFFLEN, PalFile); if (stricmp((const char*)Buff, "0100")) { Error = IL_TRUE; } iFgetw(Buff, BUFFLEN, PalFile); NumColours = atoi((const char*)Buff); if (NumColours == 0 || Error) { ilSetError(IL_INVALID_FILE_HEADER); fclose(PalFile); return IL_FALSE; } Pal->PalSize = NumColours * PALBPP; Pal->PalType = IL_PAL_RGB24; Pal->Palette = (ILubyte*)ialloc(NumColours * PALBPP); if (Pal->Palette == NULL) { fclose(PalFile); return IL_FALSE; } for (i = 0; i < NumColours; i++) { for (c = 0; c < PALBPP; c++) { iFgetw(Buff, BUFFLEN, PalFile); Pal->Palette[i * PALBPP + c] = atoi((const char*)Buff); } } fclose(PalFile); return IL_TRUE; }
ILboolean iLoadXpmInternal() { #define BUFFER_SIZE 2000 ILubyte Buffer[BUFFER_SIZE], *Data; ILint Size, Pos, Width, Height, NumColours, i, x, y; ILint CharsPerPixel; #ifndef XPM_DONT_USE_HASHTABLE XPMHASHENTRY **HashTable; #else XpmPixel *Colours; ILint Offset; #endif Size = XpmGetsInternal(Buffer, BUFFER_SIZE); if (strncmp("/* XPM */", (char*)Buffer, strlen("/* XPM */"))) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } Size = XpmGets(Buffer, BUFFER_SIZE); // @TODO: Actually check the variable name here. Size = XpmGets(Buffer, BUFFER_SIZE); Pos = 0; Width = XpmGetInt(Buffer, Size, &Pos); Height = XpmGetInt(Buffer, Size, &Pos); NumColours = XpmGetInt(Buffer, Size, &Pos); CharsPerPixel = XpmGetInt(Buffer, Size, &Pos); #ifdef XPM_DONT_USE_HASHTABLE if (CharsPerPixel != 1) { ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } #endif if (CharsPerPixel > XPM_MAX_CHAR_PER_PIXEL || Width*CharsPerPixel > BUFFER_SIZE) { ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } #ifndef XPM_DONT_USE_HASHTABLE HashTable = XpmCreateHashTable(); if (HashTable == NULL) return IL_FALSE; #else Colours = ialloc(256 * sizeof(XpmPixel)); if (Colours == NULL) return IL_FALSE; #endif for (i = 0; i < NumColours; i++) { Size = XpmGets(Buffer, BUFFER_SIZE); #ifndef XPM_DONT_USE_HASHTABLE if (!XpmGetColour(Buffer, Size, CharsPerPixel, HashTable)) { XpmDestroyHashTable(HashTable); #else if (!XpmGetColour(Buffer, Size, CharsPerPixel, Colours)) { ifree(Colours); #endif return IL_FALSE; } } if (!ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) { #ifndef XPM_DONT_USE_HASHTABLE XpmDestroyHashTable(HashTable); #else ifree(Colours); #endif return IL_FALSE; } Data = iCurImage->Data; for (y = 0; y < Height; y++) { Size = XpmGets(Buffer, BUFFER_SIZE); for (x = 0; x < Width; x++) { #ifndef XPM_DONT_USE_HASHTABLE XpmGetEntry(HashTable, &Buffer[1 + x*CharsPerPixel], CharsPerPixel, &Data[(x << 2)]); #else Offset = (x << 2); Data[Offset + 0] = Colours[Buffer[x + 1]][0]; Data[Offset + 1] = Colours[Buffer[x + 1]][1]; Data[Offset + 2] = Colours[Buffer[x + 1]][2]; Data[Offset + 3] = Colours[Buffer[x + 1]][3]; #endif } Data += iCurImage->Bps; } //added 20040218 iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; #ifndef XPM_DONT_USE_HASHTABLE XpmDestroyHashTable(HashTable); #else ifree(Colours); #endif return IL_TRUE; #undef BUFFER_SIZE }
ILboolean ILAPIENTRY ilApplyProfile(ILstring InProfile, ILstring OutProfile) { #ifndef IL_NO_LCMS cmsHPROFILE hInProfile, hOutProfile; cmsHTRANSFORM hTransform; ILubyte *Temp; ILint Format=0; #ifdef _UNICODE char AnsiName[512]; #endif//_UNICODE if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } switch (iCurImage->Type) { case IL_BYTE: case IL_UNSIGNED_BYTE: switch (iCurImage->Format) { case IL_LUMINANCE: Format = TYPE_GRAY_8; break; case IL_RGB: Format = TYPE_RGB_8; break; case IL_BGR: Format = TYPE_BGR_8; break; case IL_RGBA: Format = TYPE_RGBA_8; break; case IL_BGRA: Format = TYPE_BGRA_8; break; default: ilSetError(IL_INTERNAL_ERROR); return IL_FALSE; } break; case IL_SHORT: case IL_UNSIGNED_SHORT: switch (iCurImage->Format) { case IL_LUMINANCE: Format = TYPE_GRAY_16; break; case IL_RGB: Format = TYPE_RGB_16; break; case IL_BGR: Format = TYPE_BGR_16; break; case IL_RGBA: Format = TYPE_RGBA_16; break; case IL_BGRA: Format = TYPE_BGRA_16; break; default: ilSetError(IL_INTERNAL_ERROR); return IL_FALSE; } break; // These aren't supported right now. case IL_INT: case IL_UNSIGNED_INT: case IL_FLOAT: case IL_DOUBLE: ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (InProfile == NULL) { if (!iCurImage->Profile || !iCurImage->ProfileSize) { ilSetError(IL_INVALID_PARAM); return IL_FALSE; } hInProfile = iCurImage->Profile; } else { #ifndef _UNICODE hInProfile = cmsOpenProfileFromFile(InProfile, "r"); #else wcstombs(AnsiName, InProfile, 512); hInProfile = cmsOpenProfileFromFile(AnsiName, "r"); #endif//_UNICODE } #ifndef _UNICODE hOutProfile = cmsOpenProfileFromFile(OutProfile, "r"); #else wcstombs(AnsiName, OutProfile, 512); hOutProfile = cmsOpenProfileFromFile(AnsiName, "r"); #endif//_UNICODE hTransform = cmsCreateTransform(hInProfile, Format, hOutProfile, Format, INTENT_PERCEPTUAL, 0); Temp = (ILubyte*)ialloc(iCurImage->SizeOfData); if (Temp == NULL) { return IL_FALSE; } cmsDoTransform(hTransform, iCurImage->Data, Temp, iCurImage->SizeOfData / 3); ifree(iCurImage->Data); iCurImage->Data = Temp; cmsDeleteTransform(hTransform); if (InProfile != NULL) cmsCloseProfile(hInProfile); cmsCloseProfile(hOutProfile); #endif//IL_NO_LCMS return IL_TRUE; }
ILboolean ILAPIENTRY ilRegisterLoad(const ILstring Ext, IL_LOADPROC Load) { iFormatL *TempNode, *NewNode; TempNode = LoadProcs; if (TempNode != NULL) { while (TempNode->Next != NULL) { TempNode = TempNode->Next; #ifndef _UNICODE if (!stricmp(TempNode->Ext, Ext)) { // already registered #else if (!wcsicmp(TempNode->Ext, Ext)) { #endif//_UNICODE return IL_TRUE; } } } NewNode = (iFormatL*)ialloc(sizeof(iFormatL)); if (NewNode == NULL) { return IL_FALSE; } if (LoadProcs == NULL) { LoadProcs = NewNode; } else { TempNode->Next = NewNode; } #ifndef _UNICODE NewNode->Ext = ilStrDup(Ext); #else NewNode->Ext = _wcsdup(Ext); #endif//_UNICODE NewNode->Load = Load; NewNode->Next = NULL; return IL_TRUE; } ILboolean ILAPIENTRY ilRegisterSave(const ILstring Ext, IL_SAVEPROC Save) { iFormatS *TempNode, *NewNode; TempNode = SaveProcs; if (TempNode != NULL) { while (TempNode->Next != NULL) { TempNode = TempNode->Next; #ifndef _UNICODE if (!stricmp(TempNode->Ext, Ext)) { // already registered #else if (!_wcsicmp(TempNode->Ext, Ext)) { #endif//_UNICODE return IL_TRUE; } } } NewNode = (iFormatS*)ialloc(sizeof(iFormatL)); if (NewNode == NULL) { return IL_FALSE; } if (SaveProcs == NULL) { SaveProcs = NewNode; } else { TempNode->Next = NewNode; } #ifndef _UNICODE NewNode->Ext = ilStrDup(Ext); #else NewNode->Ext = _wcsdup(Ext); #endif//_UNICODE NewNode->Save = Save; NewNode->Next = NULL; return IL_TRUE; } //! Unregisters a load extension - doesn't have to be called. ILboolean ILAPIENTRY ilRemoveLoad(const ILstring Ext) { iFormatL *TempNode = LoadProcs, *PrevNode = NULL; while (TempNode != NULL) { #ifndef _UNICODE if (!stricmp(Ext, TempNode->Ext)) { #else if (_wcsicmp(Ext, TempNode->Ext)) { #endif//_UNICODE if (PrevNode == NULL) { // first node in the list LoadProcs = TempNode->Next; ifree((void*)TempNode->Ext); ifree(TempNode); } else { PrevNode->Next = TempNode->Next; ifree((void*)TempNode->Ext); ifree(TempNode); } return IL_TRUE; } PrevNode = TempNode; TempNode = TempNode->Next; } return IL_FALSE; } //! Unregisters a save extension - doesn't have to be called. ILboolean ILAPIENTRY ilRemoveSave(const ILstring Ext) { iFormatS *TempNode = SaveProcs, *PrevNode = NULL; while (TempNode != NULL) { #ifndef _UNICODE if (!stricmp(Ext, TempNode->Ext)) { #else if (_wcsicmp(Ext, TempNode->Ext)) { #endif//_UNICODE if (PrevNode == NULL) { // first node in the list SaveProcs = TempNode->Next; ifree((void*)TempNode->Ext); ifree(TempNode); } else { PrevNode->Next = TempNode->Next; ifree((void*)TempNode->Ext); ifree(TempNode); } return IL_TRUE; } PrevNode = TempNode; TempNode = TempNode->Next; } return IL_FALSE; } // Automatically removes all registered formats. ILvoid ilRemoveRegistered() { iFormatL *TempNodeL = LoadProcs; iFormatS *TempNodeS = SaveProcs; while (LoadProcs != NULL) { TempNodeL = LoadProcs->Next; ifree((void*)LoadProcs->Ext); ifree(LoadProcs); LoadProcs = TempNodeL; } while (SaveProcs != NULL) { TempNodeS = SaveProcs->Next; ifree((void*)SaveProcs->Ext); ifree(SaveProcs); SaveProcs = TempNodeS; } return; } ILboolean iRegisterLoad(const ILstring FileName) { iFormatL *TempNode = LoadProcs; ILstring Ext = iGetExtension(FileName); ILenum Error; if (!Ext) return IL_FALSE; while (TempNode != NULL) { #ifndef _UNICODE if (!stricmp(Ext, TempNode->Ext)) { #else if (_wcsicmp(Ext, TempNode->Ext)) { #endif//_UNICODE Error = TempNode->Load(FileName); if (Error == IL_NO_ERROR || Error == 0) { // 0 and IL_NO_ERROR are both valid. return IL_TRUE; } else { ilSetError(Error); return IL_FALSE; } } TempNode = TempNode->Next; } return IL_FALSE; } ILboolean iRegisterSave(const ILstring FileName) { iFormatS *TempNode = SaveProcs; ILstring Ext = iGetExtension(FileName); ILenum Error; if (!Ext) return IL_FALSE; while (TempNode != NULL) { #ifndef _UNICODE if (!stricmp(Ext, TempNode->Ext)) { #else if (_wcsicmp(Ext, TempNode->Ext)) { #endif//_UNICODE Error = TempNode->Save(FileName); if (Error == IL_NO_ERROR || Error == 0) { // 0 and IL_NO_ERROR are both valid. return IL_TRUE; } else { ilSetError(Error); return IL_FALSE; } } TempNode = TempNode->Next; } return IL_FALSE; } // // "Reporting" functions // ILvoid ILAPIENTRY ilRegisterOrigin(ILenum Origin) { switch (Origin) { case IL_ORIGIN_LOWER_LEFT: case IL_ORIGIN_UPPER_LEFT: iCurImage->Origin = Origin; break; default: ilSetError(IL_INVALID_ENUM); } return; } ILvoid ILAPIENTRY ilRegisterFormat(ILenum Format) { switch (Format) { case IL_COLOUR_INDEX: case IL_RGB: case IL_RGBA: case IL_BGR: case IL_BGRA: case IL_LUMINANCE: case IL_LUMINANCE_ALPHA: iCurImage->Format = Format; break; default: ilSetError(IL_INVALID_ENUM); } return; } ILboolean ILAPIENTRY ilRegisterMipNum(ILuint Num) { ILimage *Next, *Prev; ilBindImage(ilGetCurName()); // Make sure the current image is actually bound. ilCloseImage(iCurImage->Mipmaps); // Close any current mipmaps. iCurImage->Mipmaps = NULL; if (Num == 0) // Just gets rid of all the mipmaps. return IL_TRUE; iCurImage->Mipmaps = ilNewImage(1, 1, 1, 1, 1); if (iCurImage->Mipmaps == NULL) return IL_FALSE; Next = iCurImage->Mipmaps; Num--; while (Num) { Next->Next = ilNewImage(1, 1, 1, 1, 1); if (Next->Next == NULL) { // Clean up before we error out. Prev = iCurImage->Mipmaps; while (Prev) { Next = Prev->Next; ilCloseImage(Prev); Prev = Next; } return IL_FALSE; } Next = Next->Next; Num--; } return IL_TRUE; }
/* zoom() Resizes bitmaps while resampling them. Returns -1 if error, 0 if success. */ int zoom( ILimage *dst, ILimage *src, double (*filterf)(double), double fwidth) { ILubyte* tmp; double xscale, yscale; /* zoom scale factors */ int xx; int i, j, k; /* loop variables */ int n; /* pixel number */ double center, left, right; /* filter calculation variables */ double width, fscale, weight; /* filter calculation variables */ ILubyte pel, pel2; int bPelDelta; CLIST *contribY; /* array of contribution lists */ CLIST contribX; int nRet = -1; /* create intermediate column to hold horizontal dst column zoom */ tmp = (ILubyte*)ialloc(src->Height * sizeof(ILubyte)); if (tmp == NULL) { return 0; } xscale = (double) dst->Width / (double) src->Width; /* Build y weights */ /* pre-calculate filter contributions for a column */ contribY = (CLIST*)icalloc(dst->Height, sizeof(CLIST)); if (contribY == NULL) { ifree(tmp); return -1; } yscale = (double) dst->Height / (double) src->Height; if(yscale < 1.0) { width = fwidth / yscale; fscale = 1.0 / yscale; for(i = 0; i < (ILint)dst->Height; ++i) { contribY[i].n = 0; contribY[i].p = (CONTRIB*)icalloc((int) (width * 2 + 1), sizeof(CONTRIB)); if(contribY[i].p == NULL) { ifree(tmp); ifree(contribY); return -1; } center = (double) i / yscale; left = ceil(center - width); right = floor(center + width); for(j = (int)left; j <= right; ++j) { weight = center - (double) j; weight = (*filterf)(weight / fscale) / fscale; n = wrap_filter_sample(j, src->Height); k = contribY[i].n++; contribY[i].p[k].pixel = n; contribY[i].p[k].weight = weight; } } } else { for(i = 0; i < (ILint)dst->Height; ++i) { contribY[i].n = 0; contribY[i].p = (CONTRIB*)icalloc((int) (fwidth * 2 + 1), sizeof(CONTRIB)); if (contribY[i].p == NULL) { ifree(tmp); ifree(contribY); return -1; } center = (double) i / yscale; left = ceil(center - fwidth); right = floor(center + fwidth); for(j = (int)left; j <= right; ++j) { weight = center - (double) j; weight = (*filterf)(weight); n = wrap_filter_sample(j, src->Height); k = contribY[i].n++; contribY[i].p[k].pixel = n; contribY[i].p[k].weight = weight; } } } for(xx = 0; xx < (ILint)dst->Width; xx++) { if(0 != calc_x_contrib(&contribX, xscale, fwidth, dst->Width, src->Width, filterf, xx)) { goto __zoom_cleanup; } /* Apply horz filter to make dst column in tmp. */ for(k = 0; k < (ILint)src->Height; ++k) { weight = 0.0; bPelDelta = IL_FALSE; // Denton: Put get_pixel source here //pel = get_pixel(src, contribX.p[0].pixel, k); pel = src->Data[k * src->Bps + contribX.p[0].pixel * src->Bpp + c]; for(j = 0; j < contribX.n; ++j) { // Denton: Put get_pixel source here //pel2 = get_pixel(src, contribX.p[j].pixel, k); pel2 = src->Data[k * src->Bps + contribX.p[j].pixel * src->Bpp + c]; if(pel2 != pel) bPelDelta = IL_TRUE; weight += pel2 * contribX.p[j].weight; } weight = bPelDelta ? roundcloser(weight) : pel; tmp[k] = (ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL); } /* next row in temp column */ ifree(contribX.p); /* The temp column has been built. Now stretch it vertically into dst column. */ for(i = 0; i < (ILint)dst->Height; ++i) { weight = 0.0; bPelDelta = IL_FALSE; pel = tmp[contribY[i].p[0].pixel]; for(j = 0; j < contribY[i].n; ++j) { pel2 = tmp[contribY[i].p[j].pixel]; if(pel2 != pel) bPelDelta = IL_TRUE; weight += pel2 * contribY[i].p[j].weight; } weight = bPelDelta ? roundcloser(weight) : pel; // Denton: Put set_pixel source here //put_pixel(dst, xx, i, (ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL)); dst->Data[i * dst->Bps + xx * dst->Bpp + c] = (ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL); } /* next dst row */ } /* next dst column */ nRet = 0; /* success */ __zoom_cleanup: ifree(tmp); // Free the memory allocated for vertical filter weights for (i = 0; i < (ILint)dst->Height; ++i) ifree(contribY[i].p); ifree(contribY); return nRet; } /* zoom */
static ILboolean ReadLayerBlock(PSP_CTX *ctx) { BLOCKHEAD Block; LAYERINFO_CHUNK LayerInfo; LAYERBITMAP_CHUNK Bitmap; ILuint ChunkSize, Padding, i, j; ILushort NumChars; // Layer sub-block header if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block)) return IL_FALSE; if (ctx->Header.MajorVersion == 3) { Block.BlockLen = GetLittleUInt(ctx->io); } else { UInt(&Block.BlockLen); } if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { return IL_FALSE; } if (Block.BlockID != PSP_LAYER_BLOCK) return IL_FALSE; if (ctx->Header.MajorVersion == 3) { SIOseek(ctx->io, 256, IL_SEEK_CUR); // We don't care about the name of the layer. SIOread(ctx->io, &LayerInfo, sizeof(LayerInfo), 1); if (SIOread(ctx->io, &Bitmap, sizeof(Bitmap), 1) != 1) return IL_FALSE; } else { // ctx->Header.MajorVersion >= 4 ChunkSize = GetLittleUInt(ctx->io); NumChars = GetLittleUShort(ctx->io); SIOseek(ctx->io, NumChars, IL_SEEK_CUR); // We don't care about the layer's name. ChunkSize -= (2 + 4 + NumChars); if (SIOread(ctx->io, &LayerInfo, IL_MIN(sizeof(LayerInfo), ChunkSize), 1) != 1) return IL_FALSE; // Can have new entries in newer versions of the spec (5.0). Padding = (ChunkSize) - sizeof(LayerInfo); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); ChunkSize = GetLittleUInt(ctx->io); if (SIOread(ctx->io, &Bitmap, sizeof(Bitmap), 1) != 1) return IL_FALSE; Padding = (ChunkSize - 4) - sizeof(Bitmap); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); } ctx->Channels = (ILubyte**)ialloc(sizeof(ILubyte*) * Bitmap.NumChannels); if (ctx->Channels == NULL) { return IL_FALSE; } ctx->NumChannels = Bitmap.NumChannels; for (i = 0; i < ctx->NumChannels; i++) { ctx->Channels[i] = GetChannel(ctx); if (ctx->Channels[i] == NULL) { for (j = 0; j < i; j++) ifree(ctx->Channels[j]); return IL_FALSE; } } return IL_TRUE; }