static ILboolean ReadGenAttributes(PSP_CTX *ctx) { BLOCKHEAD AttHead; ILint Padding; ILuint ChunkLen; if (SIOread(ctx->io, &AttHead, sizeof(AttHead), 1) != 1) return IL_FALSE; UShort(&AttHead.BlockID); UInt(&AttHead.BlockLen); if (AttHead.HeadID[0] != 0x7E || AttHead.HeadID[1] != 0x42 || AttHead.HeadID[2] != 0x4B || AttHead.HeadID[3] != 0x00) { iSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (AttHead.BlockID != PSP_IMAGE_BLOCK) { iSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } ChunkLen = GetLittleUInt(ctx->io); if (ctx->Header.MajorVersion != 3) ChunkLen -= 4; if (SIOread(ctx->io, &ctx->AttChunk, IL_MIN(sizeof(ctx->AttChunk), ChunkLen), 1) != 1) return IL_FALSE; // Can have new entries in newer versions of the spec (4.0). Padding = (ILint)(ChunkLen - sizeof(ctx->AttChunk)); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); // @TODO: Anything but 24 not supported yet... if (ctx->AttChunk.BitDepth != 24 && ctx->AttChunk.BitDepth != 8) { iSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // @TODO; Add support for compression... if (ctx->AttChunk.Compression != PSP_COMP_NONE && ctx->AttChunk.Compression != PSP_COMP_RLE) { iSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // @TODO: Check more things in the general attributes chunk here. return IL_TRUE; }
ILint64 ILAPIENTRY iReadLump(SIO* io, void *Buffer, const ILuint Size, const ILuint Number) { ILint64 i, ByteSize = IL_MIN( Size*Number, io->lumpSize-io->rwPos); for (i = 0; i < ByteSize; i++) { *((ILubyte*)Buffer + i) = *((ILubyte*)io->lump + io->rwPos + i); if (io->lumpSize > 0) { // ReadLumpSize is too large to care about apparently if (io->rwPos + i > io->lumpSize) { io->rwPos += i; if (i != Number) il2SetError(IL_FILE_READ_ERROR); return i; } } } io->rwPos += i; if (Size != 0) i /= Size; if (i != Number) il2SetError(IL_FILE_READ_ERROR); return i; }
ILuint ILAPIENTRY iReadLump(ILHANDLE h, void *Buffer, const ILuint Size, const ILuint Number) { ILuint i, ByteSize = IL_MIN( Size*Number, iCurImage->io.lumpSize-iCurImage->io.lumpPos); for (i = 0; i < ByteSize; i++) { *((ILubyte*)Buffer + i) = *((ILubyte*)iCurImage->io.lump + iCurImage->io.lumpPos + i); if (iCurImage->io.lumpSize > 0) { // ReadLumpSize is too large to care about apparently if (iCurImage->io.lumpPos + i > iCurImage->io.lumpSize) { iCurImage->io.lumpPos += i; if (i != Number) ilSetError(IL_FILE_READ_ERROR); return i; } } } iCurImage->io.lumpPos += i; if (Size != 0) i /= Size; if (i != Number) ilSetError(IL_FILE_READ_ERROR); return i; }
ILuint ILAPIENTRY iReadLump(ILvoid *Buffer, const ILuint Size, const ILuint Number) { ILuint i, ByteSize = IL_MIN( Size*Number, ReadLumpSize-ReadLumpPos); for (i = 0; i < ByteSize; i++) { *((ILubyte*)Buffer + i) = *((ILubyte*)ReadLump + ReadLumpPos + i); if (ReadLumpSize > 0) { // ReadLumpSize is too large to care about apparently if (ReadLumpPos + i > ReadLumpSize) { ReadLumpPos += i; if (i != Number) ilSetError(IL_FILE_READ_ERROR); return i; } } } ReadLumpPos += i; if (Size != 0) i /= Size; if (i != Number) ilSetError(IL_FILE_READ_ERROR); return i; }
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; }