- Main Page
- Data Structures
- Files

- File List

# E:/DevIL/src-IL/src/il_psp.c

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Sources
    00004 // Copyright (C) 2000-2002 by Denton Woods
    00005 // Last modified: 05/04/2002 <--Y2K Compliant! =]
    00006 //
    00007 // Filename: src-IL/src/il_psp.c
    00008 //
    00009 // Description: Reads a Paint Shop Pro file.
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013
    00014 #include "il_internal.h"
    00015 #include "il_psp.h"
    00016 #ifndef IL_NO_PSP
    00017
    00018
    00019 ILubyte PSPSignature[32] = {
    00020         0x50, 0x61, 0x69, 0x6E, 0x74, 0x20, 0x53, 0x68, 0x6F, 0x70, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x49,
    00021         0x6D, 0x61, 0x67, 0x65, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x0A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00
    00022 };
    00023
    00024 ILubyte GenAttHead[4] = {
    00025         0x7E, 0x42, 0x4B, 0x00
    00026 };
    00027
    00028
    00029 // Make these global, since they contain most of the image information.
    00030 GENATT_CHUNK    AttChunk;
    00031 PSPHEAD                 Header;
    00032 ILuint                  NumChannels;
    00033 ILubyte                 **Channels = NULL;
    00034 ILubyte                 *Alpha = NULL;
    00035 ILpal                   Pal;
    00036
    00037
    00038
    00040 ILboolean ilIsValidPsp(ILconst_string FileName)
    00041 {
    00042         ILHANDLE        PspFile;
    00043         ILboolean       bPsp = IL_FALSE;
    00044
    00045         if (!iCheckExtension(FileName, IL_TEXT("psp"))) {
    00046                 ilSetError(IL_INVALID_EXTENSION);
    00047                 return bPsp;
    00048         }
    00049
    00050         PspFile = iopenr(FileName);
    00051         if (PspFile == NULL) {
    00052                 ilSetError(IL_COULD_NOT_OPEN_FILE);
    00053                 return bPsp;
    00054         }
    00055
    00056         bPsp = ilIsValidPspF(PspFile);
    00057         icloser(PspFile);
    00058
    00059         return bPsp;
    00060 }
    00061
    00062
    00064 ILboolean ilIsValidPspF(ILHANDLE File)
    00065 {
    00066         ILuint          FirstPos;
    00067         ILboolean       bRet;
    00068
    00069         iSetInputFile(File);
    00070         FirstPos = itell();
    00071         bRet = iIsValidPsp();
    00072         iseek(FirstPos, IL_SEEK_SET);
    00073
    00074         return bRet;
    00075 }
    00076
    00077
    00079 ILboolean ilIsValidPspL(const void *Lump, ILuint Size)
    00080 {
    00081         iSetInputLump(Lump, Size);
    00082         return iIsValidPsp();
    00083 }
    00084
    00085
    00086 // Internal function used to get the Psp header from the current file.
    00087 ILboolean iGetPspHead()
    00088 {
    00089         if (iread(Header.FileSig, 1, 32) != 32)
    00090                 return IL_FALSE;
    00091         Header.MajorVersion = GetLittleUShort();
    00092         Header.MinorVersion = GetLittleUShort();
    00093
    00094         return IL_TRUE;
    00095 }
    00096
    00097
    00098 // Internal function to get the header and check it.
    00099 ILboolean iIsValidPsp()
    00100 {
    00101         if (!iGetPspHead())
    00102                 return IL_FALSE;
    00103         iseek(-(ILint)sizeof(PSPHEAD), IL_SEEK_CUR);
    00104
    00105         return iCheckPsp();
    00106 }
    00107
    00108
    00109 // Internal function used to check if the HEADER is a valid Psp header.
    00110 ILboolean iCheckPsp()
    00111 {
    00112         if (stricmp(Header.FileSig, "Paint Shop Pro Image File\n\x1a"))
    00113                 return IL_FALSE;
    00114         if (Header.MajorVersion < 3 || Header.MajorVersion > 5)
    00115                 return IL_FALSE;
    00116         if (Header.MinorVersion != 0)
    00117                 return IL_FALSE;
    00118
    00119
    00120         return IL_TRUE;
    00121 }
    00122
    00123
    00125 ILboolean ilLoadPsp(ILconst_string FileName)
    00126 {
    00127         ILHANDLE        PSPFile;
    00128         ILboolean       bPsp = IL_FALSE;
    00129
    00130         PSPFile = iopenr(FileName);
    00131         if (PSPFile == NULL) {
    00132                 ilSetError(IL_COULD_NOT_OPEN_FILE);
    00133                 return bPsp;
    00134         }
    00135
    00136         bPsp = ilLoadPspF(PSPFile);
    00137         icloser(PSPFile);
    00138
    00139         return bPsp;
    00140 }
    00141
    00142
    00144 ILboolean ilLoadPspF(ILHANDLE File)
    00145 {
    00146         ILuint          FirstPos;
    00147         ILboolean       bRet;
    00148
    00149         iSetInputFile(File);
    00150         FirstPos = itell();
    00151         bRet = iLoadPspInternal();
    00152         iseek(FirstPos, IL_SEEK_SET);
    00153
    00154         return bRet;
    00155 }
    00156
    00157
    00159 ILboolean ilLoadPspL(const void *Lump, ILuint Size)
    00160 {
    00161         iSetInputLump(Lump, Size);
    00162         return iLoadPspInternal();
    00163 }
    00164
    00165
    00166 // Internal function used to load the PSP.
    00167 ILboolean iLoadPspInternal()
    00168 {
    00169         if (iCurImage == NULL) {
    00170                 ilSetError(IL_ILLEGAL_OPERATION);
    00171                 return IL_FALSE;
    00172         }
    00173
    00174         Channels = NULL;
    00175         Alpha = NULL;
    00176         Pal.Palette = NULL;
    00177
    00178         if (!iGetPspHead())
    00179                 return IL_FALSE;
    00180         if (!iCheckPsp()) {
    00181                 ilSetError(IL_INVALID_FILE_HEADER);
    00182                 return IL_FALSE;
    00183         }
    00184
    00185         if (!ReadGenAttributes())
    00186                 return IL_FALSE;
    00187         if (!ParseChunks())
    00188                 return IL_FALSE;
    00189         if (!AssembleImage())
    00190                 return IL_FALSE;
    00191
    00192         Cleanup();
    00193         ilFixImage();
    00194
    00195         return IL_TRUE;
    00196 }
    00197
    00198
    00199 ILboolean ReadGenAttributes()
    00200 {
    00201         BLOCKHEAD               AttHead;
    00202         ILint                   Padding;
    00203         ILuint                  ChunkLen;
    00204
    00205         if (iread(&AttHead, sizeof(AttHead), 1) != 1)
    00206                 return IL_FALSE;
    00207         UShort(&AttHead.BlockID);
    00208         UInt(&AttHead.BlockLen);
    00209
    00210         if (AttHead.HeadID[0] != 0x7E || AttHead.HeadID[1] != 0x42 ||
    00211                 AttHead.HeadID[2] != 0x4B || AttHead.HeadID[3] != 0x00) {
    00212                 ilSetError(IL_INVALID_FILE_HEADER);
    00213                 return IL_FALSE;
    00214         }
    00215         if (AttHead.BlockID != PSP_IMAGE_BLOCK) {
    00216                 ilSetError(IL_INVALID_FILE_HEADER);
    00217                 return IL_FALSE;
    00218         }
    00219
    00220         ChunkLen = GetLittleUInt();
    00221         if (Header.MajorVersion != 3)
    00222                 ChunkLen -= 4;
    00223         if (iread(&AttChunk, IL_MIN(sizeof(AttChunk), ChunkLen), 1) != 1)
    00224                 return IL_FALSE;
    00225
    00226         // Can have new entries in newer versions of the spec (4.0).
    00227         Padding = (ChunkLen) - sizeof(AttChunk);
    00228         if (Padding > 0)
    00229                 iseek(Padding, IL_SEEK_CUR);
    00230
    00231         // @TODO:  Anything but 24 not supported yet...
    00232         if (AttChunk.BitDepth != 24 && AttChunk.BitDepth != 8) {
    00233                 ilSetError(IL_INVALID_FILE_HEADER);
    00234                 return IL_FALSE;
    00235         }
    00236
    00237         // @TODO;  Add support for compression...
    00238         if (AttChunk.Compression != PSP_COMP_NONE && AttChunk.Compression != PSP_COMP_RLE) {
    00239                 ilSetError(IL_INVALID_FILE_HEADER);
    00240                 return IL_FALSE;
    00241         }
    00242
    00243         // @TODO: Check more things in the general attributes chunk here.
    00244
    00245         return IL_TRUE;
    00246 }
    00247
    00248
    00249 ILboolean ParseChunks()
    00250 {
    00251         BLOCKHEAD       Block;
    00252         ILuint          Pos;
    00253
    00254         do {
    00255                 if (iread(&Block, 1, sizeof(Block)) != sizeof(Block)) {
    00256                         ilGetError();  // Get rid of the erroneous IL_FILE_READ_ERROR.
    00257                         return IL_TRUE;
    00258                 }
    00259                 if (Header.MajorVersion == 3)
    00260                         Block.BlockLen = GetLittleUInt();
    00261                 else
    00262                         UInt(&Block.BlockLen);
    00263
    00264                 if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
    00265                         Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
    00266                                 return IL_TRUE;
    00267                 }
    00268                 UShort(&Block.BlockID);
    00269                 UInt(&Block.BlockLen);
    00270
    00271                 Pos = itell();
    00272
    00273                 switch (Block.BlockID)
    00274                 {
    00275                         case PSP_LAYER_START_BLOCK:
    00276                                 if (!ReadLayerBlock(Block.BlockLen))
    00277                                         return IL_FALSE;
    00278                                 break;
    00279
    00280                         case PSP_ALPHA_BANK_BLOCK:
    00281                                 if (!ReadAlphaBlock(Block.BlockLen))
    00282                                         return IL_FALSE;
    00283                                 break;
    00284
    00285                         case PSP_COLOR_BLOCK:
    00286                                 if (!ReadPalette(Block.BlockLen))
    00287                                         return IL_FALSE;
    00288                                 break;
    00289
    00290                         // Gets done in the next iseek, so this is now commented out.
    00291                         //default:
    00292                                 //iseek(Block.BlockLen, IL_SEEK_CUR);
    00293                 }
    00294
    00295                 // Skip to next block just in case we didn't read the entire block.
    00296                 iseek(Pos + Block.BlockLen, IL_SEEK_SET);
    00297
    00298                 // @TODO: Do stuff here.
    00299
    00300         } while (1);
    00301
    00302         return IL_TRUE;
    00303 }
    00304
    00305
    00306 ILboolean ReadLayerBlock(ILuint BlockLen)
    00307 {
    00308         BLOCKHEAD                       Block;
    00309         LAYERINFO_CHUNK         LayerInfo;
    00310         LAYERBITMAP_CHUNK       Bitmap;
    00311         ILuint                          ChunkSize, Padding, i, j;
    00312         ILushort                        NumChars;
    00313
    00314         BlockLen;
    00315
    00316         // Layer sub-block header
    00317         if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
    00318                 return IL_FALSE;
    00319         if (Header.MajorVersion == 3)
    00320                 Block.BlockLen = GetLittleUInt();
    00321         else
    00322                 UInt(&Block.BlockLen);
    00323
    00324         if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
    00325                 Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
    00326                         return IL_FALSE;
    00327         }
    00328         if (Block.BlockID != PSP_LAYER_BLOCK)
    00329                 return IL_FALSE;
    00330
    00331
    00332         if (Header.MajorVersion == 3) {
    00333                 iseek(256, IL_SEEK_CUR);  // We don't care about the name of the layer.
    00334                 iread(&LayerInfo, sizeof(LayerInfo), 1);
    00335                 if (iread(&Bitmap, sizeof(Bitmap), 1) != 1)
    00336                         return IL_FALSE;
    00337         }
    00338         else {  // Header.MajorVersion >= 4
    00339                 ChunkSize = GetLittleUInt();
    00340                 NumChars = GetLittleUShort();
    00341                 iseek(NumChars, IL_SEEK_CUR);  // We don't care about the layer's name.
    00342
    00343                 ChunkSize -= (2 + 4 + NumChars);
    00344
    00345                 if (iread(&LayerInfo, IL_MIN(sizeof(LayerInfo), ChunkSize), 1) != 1)
    00346                         return IL_FALSE;
    00347
    00348                 // Can have new entries in newer versions of the spec (5.0).
    00349                 Padding = (ChunkSize) - sizeof(LayerInfo);
    00350                 if (Padding > 0)
    00351                         iseek(Padding, IL_SEEK_CUR);
    00352
    00353                 ChunkSize = GetLittleUInt();
    00354                 if (iread(&Bitmap, sizeof(Bitmap), 1) != 1)
    00355                         return IL_FALSE;
    00356                 Padding = (ChunkSize - 4) - sizeof(Bitmap);
    00357                 if (Padding > 0)
    00358                         iseek(Padding, IL_SEEK_CUR);
    00359         }
    00360
    00361
    00362         Channels = (ILubyte**)ialloc(sizeof(ILubyte*) * Bitmap.NumChannels);
    00363         if (Channels == NULL) {
    00364                 return IL_FALSE;
    00365         }
    00366
    00367         NumChannels = Bitmap.NumChannels;
    00368
    00369         for (i = 0; i < NumChannels; i++) {
    00370                 Channels[i] = GetChannel();
    00371                 if (Channels[i] == NULL) {
    00372                         for (j = 0; j < i; j++)
    00373                                 ifree(Channels[j]);
    00374                         return IL_FALSE;
    00375                 }
    00376         }
    00377
    00378         return IL_TRUE;
    00379 }
    00380
    00381
    00382 ILboolean ReadAlphaBlock(ILuint BlockLen)
    00383 {
    00384         BLOCKHEAD               Block;
    00385         ALPHAINFO_CHUNK AlphaInfo;
    00386         ALPHA_CHUNK             AlphaChunk;
    00387         ILushort                NumAlpha, StringSize;
    00388         ILuint                  ChunkSize, Padding;
    00389
    00390         if (Header.MajorVersion == 3) {
    00391                 NumAlpha = GetLittleUShort();
    00392         }
    00393         else {
    00394                 ChunkSize = GetLittleUInt();
    00395                 NumAlpha = GetLittleUShort();
    00396                 Padding = (ChunkSize - 4 - 2);
    00397                 if (Padding > 0)
    00398                         iseek(Padding, IL_SEEK_CUR);
    00399         }
    00400
    00401         // Alpha channel header
    00402         if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
    00403                 return IL_FALSE;
    00404         if (Header.MajorVersion == 3)
    00405                 Block.BlockLen = GetLittleUInt();
    00406         else
    00407                 UInt(&Block.BlockLen);
    00408
    00409         if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
    00410                 Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
    00411                         return IL_FALSE;
    00412         }
    00413         if (Block.BlockID != PSP_ALPHA_CHANNEL_BLOCK)
    00414                 return IL_FALSE;
    00415
    00416
    00417         if (Header.MajorVersion >= 4) {
    00418                 ChunkSize = GetLittleUInt();
    00419                 StringSize = GetLittleUShort();
    00420                 iseek(StringSize, IL_SEEK_CUR);
    00421                 if (iread(&AlphaInfo, sizeof(AlphaInfo), 1) != 1)
    00422                         return IL_FALSE;
    00423                 Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo));
    00424                 if (Padding > 0)
    00425                         iseek(Padding, IL_SEEK_CUR);
    00426
    00427                 ChunkSize = GetLittleUInt();
    00428                 if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1)
    00429                         return IL_FALSE;
    00430                 Padding = (ChunkSize - 4 - sizeof(AlphaChunk));
    00431                 if (Padding > 0)
    00432                         iseek(Padding, IL_SEEK_CUR);
    00433         }
    00434         else {
    00435                 iseek(256, IL_SEEK_CUR);
    00436                 iread(&AlphaInfo, sizeof(AlphaInfo), 1);
    00437                 if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1)
    00438                         return IL_FALSE;
    00439         }
    00440
    00441
    00442         /*Alpha = (ILubyte*)ialloc(AlphaInfo.AlphaRect.x2 * AlphaInfo.AlphaRect.y2);
    00443         if (Alpha == NULL) {
    00444                 return IL_FALSE;
    00445         }*/
    00446
    00447
    00448         Alpha = GetChannel();
    00449         if (Alpha == NULL)
    00450                 return IL_FALSE;
    00451
    00452         return IL_TRUE;
    00453 }
    00454
    00455
    00456 ILubyte *GetChannel()
    00457 {
    00458         BLOCKHEAD               Block;
    00459         CHANNEL_CHUNK   Channel;
    00460         ILubyte                 *CompData, *Data;
    00461         ILuint                  ChunkSize, Padding;
    00462
    00463         if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
    00464                 return NULL;
    00465         if (Header.MajorVersion == 3)
    00466                 Block.BlockLen = GetLittleUInt();
    00467         else
    00468                 UInt(&Block.BlockLen);
    00469
    00470         if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
    00471                 Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
    00472                         ilSetError(IL_ILLEGAL_FILE_VALUE);
    00473                         return NULL;
    00474         }
    00475         if (Block.BlockID != PSP_CHANNEL_BLOCK) {
    00476                 ilSetError(IL_ILLEGAL_FILE_VALUE);
    00477                 return NULL;
    00478         }
    00479
    00480
    00481         if (Header.MajorVersion >= 4) {
    00482                 ChunkSize = GetLittleUInt();
    00483                 if (iread(&Channel, sizeof(Channel), 1) != 1)
    00484                         return NULL;
    00485
    00486                 Padding = (ChunkSize - 4) - sizeof(Channel);
    00487                 if (Padding > 0)
    00488                         iseek(Padding, IL_SEEK_CUR);
    00489         }
    00490         else {
    00491                 if (iread(&Channel, sizeof(Channel), 1) != 1)
    00492                         return NULL;
    00493         }
    00494
    00495
    00496         CompData = (ILubyte*)ialloc(Channel.CompLen);
    00497         Data = (ILubyte*)ialloc(AttChunk.Width * AttChunk.Height);
    00498         if (CompData == NULL || Data == NULL) {
    00499                 ifree(Data);
    00500                 ifree(CompData);
    00501                 return NULL;
    00502         }
    00503
    00504         if (iread(CompData, 1, Channel.CompLen) != Channel.CompLen) {
    00505                 ifree(CompData);
    00506                 ifree(Data);
    00507                 return NULL;
    00508         }
    00509
    00510         switch (AttChunk.Compression)
    00511         {
    00512                 case PSP_COMP_NONE:
    00513                         ifree(Data);
    00514                         return CompData;
    00515                         break;
    00516
    00517                 case PSP_COMP_RLE:
    00518                         if (!UncompRLE(CompData, Data, Channel.CompLen)) {
    00519                                 ifree(CompData);
    00520                                 ifree(Data);
    00521                                 return IL_FALSE;
    00522                         }
    00523                         break;
    00524
    00525                 default:
    00526                         ifree(CompData);
    00527                         ifree(Data);
    00528                         ilSetError(IL_INVALID_FILE_HEADER);
    00529                         return NULL;
    00530         }
    00531
    00532         ifree(CompData);
    00533
    00534         return Data;
    00535 }
    00536
    00537
    00538 ILboolean UncompRLE(ILubyte *CompData, ILubyte *Data, ILuint CompLen)
    00539 {
    00540         ILubyte Run, Colour;
    00541         ILint   i, /*x, y,*/ Count/*, Total = 0*/;
    00542
    00543         /*for (y = 0; y < AttChunk.Height; y++) {
    00544                 for (x = 0, Count = 0; x < AttChunk.Width; ) {
    00545                         Run = *CompData++;
    00546                         if (Run > 128) {
    00547                                 Run -= 128;
    00548                                 Colour = *CompData++;
    00549                                 memset(Data, Colour, Run);
    00550                                 Data += Run;
    00551                                 Count += 2;
    00552                         }
    00553                         else {
    00554                                 memcpy(Data, CompData, Run);
    00555                                 CompData += Run;
    00556                                 Data += Run;
    00557                                 Count += Run;
    00558                         }
    00559                         x += Run;
    00560                 }
    00561
    00562                 Total += Count;
    00563
    00564                 if (Count % 4) {  // Has to be on a 4-byte boundary.
    00565                         CompData += (4 - (Count % 4)) % 4;
    00566                         Total += (4 - (Count % 4)) % 4;
    00567                 }
    00568
    00569                 if (Total >= CompLen)
    00570                         return IL_FALSE;
    00571         }*/
    00572
    00573         for (i = 0, Count = 0; i < (ILint)CompLen; ) {
    00574                 Run = *CompData++;
    00575                 i++;
    00576                 if (Run > 128) {
    00577                         Run -= 128;
    00578                         Colour = *CompData++;
    00579                         i++;
    00580                         memset(Data, Colour, Run);
    00581                 }
    00582                 else {
    00583                         memcpy(Data, CompData, Run);
    00584                         CompData += Run;
    00585                         i += Run;
    00586                 }
    00587                 Data += Run;
    00588                 Count += Run;
    00589         }
    00590
    00591         return IL_TRUE;
    00592 }
    00593
    00594
    00595 ILboolean ReadPalette(ILuint BlockLen)
    00596 {
    00597         ILuint ChunkSize, PalCount, Padding;
    00598
    00599         if (Header.MajorVersion >= 4) {
    00600                 ChunkSize = GetLittleUInt();
    00601                 PalCount = GetLittleUInt();
    00602                 Padding = (ChunkSize - 4 - 4);
    00603                 if (Padding > 0)
    00604                         iseek(Padding, IL_SEEK_CUR);
    00605         }
    00606         else {
    00607                 PalCount = GetLittleUInt();
    00608         }
    00609
    00610         Pal.PalSize = PalCount * 4;
    00611         Pal.PalType = IL_PAL_BGRA32;
    00612         Pal.Palette = (ILubyte*)ialloc(Pal.PalSize);
    00613         if (Pal.Palette == NULL)
    00614                 return IL_FALSE;
    00615
    00616         if (iread(Pal.Palette, Pal.PalSize, 1) != 1) {
    00617                 ifree(Pal.Palette);
    00618                 return IL_FALSE;
    00619         }
    00620
    00621         return IL_TRUE;
    00622 }
    00623
    00624
    00625 ILboolean AssembleImage()
    00626 {
    00627         ILuint Size, i, j;
    00628
    00629         Size = AttChunk.Width * AttChunk.Height;
    00630
    00631         if (NumChannels == 1) {
    00632                 ilTexImage(AttChunk.Width, AttChunk.Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL);
    00633                 for (i = 0; i < Size; i++) {
    00634                         iCurImage->Data[i] = Channels[0][i];
    00635                 }
    00636
    00637                 if (Pal.Palette) {
    00638                         iCurImage->Format = IL_COLOUR_INDEX;
    00639                         iCurImage->Pal.PalSize = Pal.PalSize;
    00640                         iCurImage->Pal.PalType = Pal.PalType;
    00641                         iCurImage->Pal.Palette = Pal.Palette;
    00642                 }
    00643         }
    00644         else {
    00645                 if (Alpha) {
    00646                         ilTexImage(AttChunk.Width, AttChunk.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
    00647                         for (i = 0, j = 0; i < Size; i++, j += 4) {
    00648                                 iCurImage->Data[j  ] = Channels[0][i];
    00649                                 iCurImage->Data[j+1] = Channels[1][i];
    00650                                 iCurImage->Data[j+2] = Channels[2][i];
    00651                                 iCurImage->Data[j+3] = Alpha[i];
    00652                         }
    00653                 }
    00654
    00655                 else if (NumChannels == 4) {
    00656
    00657                         ilTexImage(AttChunk.Width, AttChunk.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
    00658
    00659                         for (i = 0, j = 0; i < Size; i++, j += 4) {
    00660
    00661                                 iCurImage->Data[j  ] = Channels[0][i];
    00662
    00663                                 iCurImage->Data[j+1] = Channels[1][i];
    00664
    00665                                 iCurImage->Data[j+2] = Channels[2][i];
    00666
    00667                                 iCurImage->Data[j+3] = Channels[3][i];
    00668
    00669                         }
    00670
    00671                 }
    00672                 else if (NumChannels == 3) {
    00673                         ilTexImage(AttChunk.Width, AttChunk.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
    00674                         for (i = 0, j = 0; i < Size; i++, j += 3) {
    00675                                 iCurImage->Data[j  ] = Channels[0][i];
    00676                                 iCurImage->Data[j+1] = Channels[1][i];
    00677                                 iCurImage->Data[j+2] = Channels[2][i];
    00678                         }
    00679                 }
    00680                 else
    00681                         return IL_FALSE;
    00682         }
    00683
    00684         iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
    00685
    00686         return IL_TRUE;
    00687 }
    00688
    00689
    00690 ILboolean Cleanup()
    00691 {
    00692         ILuint  i;
    00693
    00694         if (Channels) {
    00695                 for (i = 0; i < NumChannels; i++) {
    00696                         ifree(Channels[i]);
    00697                 }
    00698                 ifree(Channels);
    00699         }
    00700
    00701         if (Alpha) {
    00702                 ifree(Alpha);
    00703         }
    00704
    00705         Channels = NULL;
    00706         Alpha = NULL;
    00707         Pal.Palette = NULL;
    00708
    00709         return IL_TRUE;
    00710 }
    00711
    00712
    00713
    00714 #endif//IL_NO_PSP