- Main Page
- Data Structures
- Files

- File List

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

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Sources
    00004 // Copyright (C) 2000-2009 by Denton Woods
    00005 // Last modified: 01/04/2009
    00006 //
    00007 // Filename: src-IL/src/il_devil.c
    00008 //
    00009 // Description: Functions for working with the ILimage's and the current image
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013
    00014 #include "il_internal.h"
    00015 #include <string.h>
    00016 #include <limits.h>
    00017 #include "il_manip.h"
    00018
    00019
    00020 ILAPI ILboolean ILAPIENTRY ilInitImage(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, void *Data)
    00021 {
    00022         ILubyte BpcType = ilGetBpcType(Type);
    00023         if (BpcType == 0) {
    00024                 ilSetError(IL_INVALID_PARAM);
    00025                 return IL_FALSE;
    00026         }
    00027
    00028         memset(Image, 0, sizeof(ILimage));
    00029
    00031         if (Width  == 0) Width = 1;
    00032         if (Height == 0) Height = 1;
    00033         if (Depth  == 0) Depth = 1;
    00034         Image->Width       = Width;
    00035         Image->Height      = Height;
    00036         Image->Depth       = Depth;
    00037         Image->Bpp                 = Bpp;
    00038         Image->Bpc                 = BpcType;
    00039         Image->Bps                 = Width * Bpp * Image->Bpc;
    00040         Image->SizeOfPlane = Image->Bps * Height;
    00041         Image->SizeOfData  = Image->SizeOfPlane * Depth;
    00042         Image->Format      = Format;
    00043         Image->Type        = Type;
    00044         Image->Origin      = IL_ORIGIN_LOWER_LEFT;
    00045         Image->Pal.PalType = IL_PAL_NONE;
    00046         Image->DxtcFormat  = IL_DXT_NO_COMP;
    00047         Image->DxtcData    = NULL;
    00048
    00049         Image->Data = (ILubyte*)ialloc(Image->SizeOfData);
    00050         if (Image->Data == NULL) {
    00051                 return IL_FALSE;
    00052         }
    00053
    00054         if (Data != NULL) {
    00055                 memcpy(Image->Data, Data, Image->SizeOfData);
    00056         }
    00057
    00058         return IL_TRUE;
    00059 }
    00060
    00061
    00062
    00063 // Creates a new ILimage based on the specifications given
    00064 ILAPI ILimage* ILAPIENTRY ilNewImage(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte Bpc)
    00065 {
    00066         ILimage *Image;
    00067
    00068         if (Bpp == 0 || Bpp > 4) {
    00069                 return NULL;
    00070         }
    00071
    00072         Image = (ILimage*)ialloc(sizeof(ILimage));
    00073         if (Image == NULL) {
    00074                 return NULL;
    00075         }
    00076
    00077         if (!ilInitImage(Image, Width, Height, Depth, Bpp, ilGetFormatBpp(Bpp), ilGetTypeBpc(Bpc), NULL)) {
    00078                 if (Image->Data != NULL) {
    00079                         ifree(Image->Data);
    00080                 }
    00081                 ifree(Image);
    00082                 return NULL;
    00083         }
    00084
    00085         return Image;
    00086 }
    00087
    00088
    00089 // Same as above but allows specification of Format and Type
    00090 ILAPI ILimage* ILAPIENTRY ilNewImageFull(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, void *Data)
    00091 {
    00092         ILimage *Image;
    00093
    00094         if (Bpp == 0 || Bpp > 4) {
    00095                 return NULL;
    00096         }
    00097
    00098         Image = (ILimage*)ialloc(sizeof(ILimage));
    00099         if (Image == NULL) {
    00100                 return NULL;
    00101         }
    00102
    00103         if (!ilInitImage(Image, Width, Height, Depth, Bpp, Format, Type, Data)) {
    00104                 if (Image->Data != NULL) {
    00105                         ifree(Image->Data);
    00106                 }
    00107                 ifree(Image);
    00108                 return NULL;
    00109         }
    00110
    00111         return Image;
    00112 }
    00113
    00114
    00116 ILboolean ILAPIENTRY ilTexImage(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, void *Data)
    00117 {
    00118         return ilTexImage_(iCurImage, Width, Height, Depth, Bpp, Format, Type, Data);
    00119 }
    00120
    00121
    00122 // Internal version of ilTexImage.
    00123 ILAPI ILboolean ILAPIENTRY ilTexImage_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, void *Data)
    00124 {
    00125         if (Image == NULL) {
    00126                 ilSetError(IL_ILLEGAL_OPERATION);
    00127                 return IL_FALSE;
    00128         }
    00129
    00131
    00132         // Not sure if we should be getting rid of the palette...
    00133         if (Image->Pal.Palette && Image->Pal.PalSize && Image->Pal.PalType != IL_PAL_NONE) {
    00134                 ifree(Image->Pal.Palette);
    00135         }
    00136
    00137         ilCloseImage(Image->Mipmaps);
    00138         ilCloseImage(Image->Next);
    00139         ilCloseImage(Image->Faces);
    00140         ilCloseImage(Image->Layers);
    00141
    00142         if (Image->AnimList) ifree(Image->AnimList);
    00143         if (Image->Profile)  ifree(Image->Profile);
    00144         if (Image->DxtcData) ifree(Image->DxtcData);
    00145         if (Image->Data)         ifree(Image->Data);
    00146
    00148
    00149         //@TODO: Also check against format?
    00150         /*if (Width == 0 || Height == 0 || Depth == 0 || Bpp == 0) {
    00151                 ilSetError(IL_INVALID_PARAM);
    00152         return IL_FALSE;
    00153         }*/
    00154
    00155         return ilInitImage(Image, Width, Height, Depth, Bpp, Format, Type, Data);
    00156 }
    00157
    00158
    00160 ILboolean ILAPIENTRY ilSetData(void *Data)
    00161 {
    00162         if (iCurImage == NULL) {
    00163                 ilSetError(IL_ILLEGAL_OPERATION);
    00164                 return IL_FALSE;
    00165         }
    00166
    00167         return ilTexSubImage_(iCurImage, Data);
    00168 }
    00169
    00170
    00171 // Internal version of ilTexSubImage.
    00172 ILAPI ILboolean ILAPIENTRY ilTexSubImage_(ILimage *Image, void *Data)
    00173 {
    00174         if (Image == NULL || Data == NULL) {
    00175                 ilSetError(IL_INVALID_PARAM);
    00176                 return IL_FALSE;
    00177         }
    00178         if (!Image->Data) {
    00179                 Image->Data = (ILubyte*)ialloc(Image->SizeOfData);
    00180                 if (Image->Data == NULL)
    00181                         return IL_FALSE;
    00182         }
    00183         memcpy(Image->Data, Data, Image->SizeOfData);
    00184         return IL_TRUE;
    00185 }
    00186
    00187
    00188 ILubyte* ILAPIENTRY ilGetData()
    00189 {
    00190         if (iCurImage == NULL) {
    00191                 ilSetError(IL_ILLEGAL_OPERATION);
    00192                 return NULL;
    00193         }
    00194
    00195         return iCurImage->Data;
    00196 }
    00197
    00198
    00199 ILubyte* ILAPIENTRY ilGetPalette()
    00200 {
    00201         if (iCurImage == NULL) {
    00202                 ilSetError(IL_ILLEGAL_OPERATION);
    00203                 return NULL;
    00204         }
    00205
    00206         return iCurImage->Pal.Palette;
    00207 }
    00208
    00209
    00210 //ILfloat ClearRed = 0.0f, ClearGreen = 0.0f, ClearBlue = 0.0f, ClearAlpha = 0.0f;
    00211
    00212 // Changed to the colour of the Universe
    00213 //      (http://www.newscientist.com/news/news.jsp?id=ns99991775)
    00214 //      *(http://www.space.com/scienceastronomy/universe_color_020308.html)*
    00215 //ILfloat ClearRed = 0.269f, ClearGreen = 0.388f, ClearBlue = 0.342f, ClearAlpha = 0.0f;
    00216 static ILfloat ClearRed   = 1.0f;
    00217 static ILfloat ClearGreen = 0.972549f;
    00218 static ILfloat ClearBlue  = 0.90588f;
    00219 static ILfloat ClearAlpha = 0.0f;
    00220 static ILfloat ClearLum   = 1.0f;
    00221
    00222 void ILAPIENTRY ilClearColour(ILclampf Red, ILclampf Green, ILclampf Blue, ILclampf Alpha)
    00223 {
    00224         // Clamp to 0.0f - 1.0f.
    00225         ClearRed        = Red < 0.0f ? 0.0f : (Red > 1.0f ? 1.0f : Red);
    00226         ClearGreen      = Green < 0.0f ? 0.0f : (Green > 1.0f ? 1.0f : Green);
    00227         ClearBlue       = Blue < 0.0f ? 0.0f : (Blue > 1.0f ? 1.0f : Blue);
    00228         ClearAlpha      = Alpha < 0.0f ? 0.0f : (Alpha > 1.0f ? 1.0f : Alpha);
    00229
    00230         if ((Red == Green) && (Red == Blue) && (Green == Blue)) {
    00231                 ClearLum = Red < 0.0f ? 0.0f : (Red > 1.0f ? 1.0f : Red);
    00232         }
    00233         else {
    00234                 ClearLum = 0.212671f * ClearRed + 0.715160f * ClearGreen + 0.072169f * ClearBlue;
    00235                 ClearLum = ClearLum < 0.0f ? 0.0f : (ClearLum > 1.0f ? 1.0f : ClearLum);
    00236         }
    00237
    00238         return;
    00239 }
    00240
    00241
    00242 ILAPI void ILAPIENTRY ilGetClear(void *Colours, ILenum Format, ILenum Type)
    00243 {
    00244         ILubyte         *BytePtr;
    00245         ILushort        *ShortPtr;
    00246         ILuint          *IntPtr;
    00247         ILfloat         *FloatPtr;
    00248         ILdouble        *DblPtr;
    00249
    00250         switch (Type)
    00251         {
    00252                 case IL_BYTE:
    00253                 case IL_UNSIGNED_BYTE:
    00254                         BytePtr = (ILubyte*)Colours;
    00255                         switch (Format)
    00256                         {
    00257                                 case IL_RGB:
    00258                                         BytePtr[0] = (ILubyte)(ClearRed * UCHAR_MAX);
    00259                                         BytePtr[1] = (ILubyte)(ClearGreen * UCHAR_MAX);
    00260                                         BytePtr[2] = (ILubyte)(ClearBlue * UCHAR_MAX);
    00261                                         break;
    00262
    00263                                 case IL_RGBA:
    00264                                         BytePtr[0] = (ILubyte)(ClearRed * UCHAR_MAX);
    00265                                         BytePtr[1] = (ILubyte)(ClearGreen * UCHAR_MAX);
    00266                                         BytePtr[2] = (ILubyte)(ClearBlue * UCHAR_MAX);
    00267                                         BytePtr[3] = (ILubyte)(ClearAlpha * UCHAR_MAX);
    00268                                         break;
    00269
    00270                                 case IL_BGR:
    00271                                         BytePtr[2] = (ILubyte)(ClearRed * UCHAR_MAX);
    00272                                         BytePtr[1] = (ILubyte)(ClearGreen * UCHAR_MAX);
    00273                                         BytePtr[0] = (ILubyte)(ClearBlue * UCHAR_MAX);
    00274                                         BytePtr[3] = (ILubyte)(ClearAlpha * UCHAR_MAX);
    00275                                         break;
    00276
    00277                                 case IL_BGRA:
    00278                                         BytePtr[2] = (ILubyte)(ClearRed * UCHAR_MAX);
    00279                                         BytePtr[1] = (ILubyte)(ClearGreen * UCHAR_MAX);
    00280                                         BytePtr[0] = (ILubyte)(ClearBlue * UCHAR_MAX);
    00281                                         BytePtr[3] = (ILubyte)(ClearAlpha * UCHAR_MAX);
    00282                                         break;
    00283
    00284                                 case IL_LUMINANCE:
    00285                                         BytePtr[0] = (ILubyte)(ClearAlpha * UCHAR_MAX);
    00286                                         break;
    00287
    00288                                 case IL_LUMINANCE_ALPHA:
    00289                                         BytePtr[0] = (ILubyte)(ClearLum * UCHAR_MAX);
    00290                                         BytePtr[1] = (ILubyte)(ClearAlpha * UCHAR_MAX);
    00291
    00292                                 case IL_COLOUR_INDEX:
    00293                                         BytePtr[0] = (ILubyte)(ClearAlpha * UCHAR_MAX);
    00294                                         break;
    00295
    00296                                 default:
    00297                                         ilSetError(IL_INTERNAL_ERROR);
    00298                                         return;
    00299                         }
    00300                                 break;
    00301
    00302                 case IL_SHORT:
    00303                 case IL_UNSIGNED_SHORT:
    00304                         ShortPtr = (ILushort*)Colours;
    00305                         switch (Format)
    00306                         {
    00307                                 case IL_RGB:
    00308                                         ShortPtr[0] = (ILushort)(ClearRed * USHRT_MAX);
    00309                                         ShortPtr[1] = (ILushort)(ClearGreen * USHRT_MAX);
    00310                                         ShortPtr[2] = (ILushort)(ClearBlue * USHRT_MAX);
    00311                                         break;
    00312
    00313                                 case IL_RGBA:
    00314                                         ShortPtr[0] = (ILushort)(ClearRed * USHRT_MAX);
    00315                                         ShortPtr[1] = (ILushort)(ClearGreen * USHRT_MAX);
    00316                                         ShortPtr[2] = (ILushort)(ClearBlue * USHRT_MAX);
    00317                                         ShortPtr[3] = (ILushort)(ClearAlpha * USHRT_MAX);
    00318                                         break;
    00319
    00320                                 case IL_BGR:
    00321                                         ShortPtr[2] = (ILushort)(ClearRed * USHRT_MAX);
    00322                                         ShortPtr[1] = (ILushort)(ClearGreen * USHRT_MAX);
    00323                                         ShortPtr[0] = (ILushort)(ClearBlue * USHRT_MAX);
    00324                                         ShortPtr[3] = (ILushort)(ClearAlpha * USHRT_MAX);
    00325                                         break;
    00326
    00327                                 case IL_BGRA:
    00328                                         ShortPtr[2] = (ILushort)(ClearRed * USHRT_MAX);
    00329                                         ShortPtr[1] = (ILushort)(ClearGreen * USHRT_MAX);
    00330                                         ShortPtr[0] = (ILushort)(ClearBlue * USHRT_MAX);
    00331                                         ShortPtr[3] = (ILushort)(ClearAlpha * USHRT_MAX);
    00332                                         break;
    00333
    00334                                 case IL_LUMINANCE:
    00335                                         ShortPtr[0] = (ILushort)(ClearAlpha * USHRT_MAX);
    00336                                         break;
    00337
    00338                                 case IL_LUMINANCE_ALPHA:
    00339                                         ShortPtr[0] = (ILushort)(ClearLum * USHRT_MAX);
    00340                                         ShortPtr[1] = (ILushort)(ClearAlpha * USHRT_MAX);
    00341                                         break;
    00342
    00343                                 case IL_COLOUR_INDEX:
    00344                                         ShortPtr[0] = (ILushort)(ClearAlpha * USHRT_MAX);
    00345                                         break;
    00346
    00347                                 default:
    00348                                         ilSetError(IL_INTERNAL_ERROR);
    00349                                         return;
    00350                         }
    00351                                 break;
    00352
    00353                 case IL_INT:
    00354                 case IL_UNSIGNED_INT:
    00355                         IntPtr = (ILuint*)Colours;
    00356                         switch (Format)
    00357                         {
    00358                                 case IL_RGB:
    00359                                         IntPtr[0] = (ILuint)(ClearRed * UINT_MAX);
    00360                                         IntPtr[1] = (ILuint)(ClearGreen * UINT_MAX);
    00361                                         IntPtr[2] = (ILuint)(ClearBlue * UINT_MAX);
    00362                                         break;
    00363
    00364                                 case IL_RGBA:
    00365                                         IntPtr[0] = (ILuint)(ClearRed * UINT_MAX);
    00366                                         IntPtr[1] = (ILuint)(ClearGreen * UINT_MAX);
    00367                                         IntPtr[2] = (ILuint)(ClearBlue * UINT_MAX);
    00368                                         IntPtr[3] = (ILuint)(ClearAlpha * UINT_MAX);
    00369                                         break;
    00370
    00371                                 case IL_BGR:
    00372                                         IntPtr[2] = (ILuint)(ClearRed * UINT_MAX);
    00373                                         IntPtr[1] = (ILuint)(ClearGreen * UINT_MAX);
    00374                                         IntPtr[0] = (ILuint)(ClearBlue * UINT_MAX);
    00375                                         IntPtr[3] = (ILuint)(ClearAlpha * UINT_MAX);
    00376                                         break;
    00377
    00378                                 case IL_BGRA:
    00379                                         IntPtr[2] = (ILuint)(ClearRed * UINT_MAX);
    00380                                         IntPtr[1] = (ILuint)(ClearGreen * UINT_MAX);
    00381                                         IntPtr[0] = (ILuint)(ClearBlue * UINT_MAX);
    00382                                         IntPtr[3] = (ILuint)(ClearAlpha * UINT_MAX);
    00383                                         break;
    00384
    00385                                 case IL_LUMINANCE:
    00386                                         IntPtr[0] = (ILuint)(ClearAlpha * UINT_MAX);
    00387                                         break;
    00388
    00389                                 case IL_LUMINANCE_ALPHA:
    00390                                         IntPtr[0] = (ILuint)(ClearLum * UINT_MAX);
    00391                                         IntPtr[1] = (ILuint)(ClearAlpha * UINT_MAX);
    00392                                         break;
    00393
    00394                                 case IL_COLOUR_INDEX:
    00395                                         IntPtr[0] = (ILuint)(ClearAlpha * UINT_MAX);
    00396                                         break;
    00397
    00398                                 default:
    00399                                         ilSetError(IL_INTERNAL_ERROR);
    00400                                         return;
    00401                         }
    00402                                 break;
    00403
    00404                 case IL_FLOAT:
    00405                         FloatPtr = (ILfloat*)Colours;
    00406                         switch (Format)
    00407                         {
    00408                                 case IL_RGB:
    00409                                         FloatPtr[0] = ClearRed;
    00410                                         FloatPtr[1] = ClearGreen;
    00411                                         FloatPtr[2] = ClearBlue;
    00412                                         break;
    00413
    00414                                 case IL_RGBA:
    00415                                         FloatPtr[0] = ClearRed;
    00416                                         FloatPtr[1] = ClearGreen;
    00417                                         FloatPtr[2] = ClearBlue;
    00418                                         FloatPtr[3] = ClearAlpha;
    00419                                         break;
    00420
    00421                                 case IL_BGR:
    00422                                         FloatPtr[2] = ClearRed;
    00423                                         FloatPtr[1] = ClearGreen;
    00424                                         FloatPtr[0] = ClearBlue;
    00425                                         FloatPtr[3] = ClearAlpha;
    00426                                         break;
    00427
    00428                                 case IL_BGRA:
    00429                                         FloatPtr[2] = ClearRed;
    00430                                         FloatPtr[1] = ClearGreen;
    00431                                         FloatPtr[0] = ClearBlue;
    00432                                         FloatPtr[3] = ClearAlpha;
    00433                                         break;
    00434
    00435                                 case IL_LUMINANCE:
    00436                                         FloatPtr[0] = ClearAlpha;
    00437                                         break;
    00438
    00439                                 case IL_LUMINANCE_ALPHA:
    00440                                         FloatPtr[0] = ClearLum;
    00441                                         FloatPtr[0] = ClearAlpha;
    00442                                         break;
    00443
    00444                                 case IL_COLOUR_INDEX:
    00445                                         FloatPtr[0] = ClearAlpha;
    00446                                         break;
    00447
    00448                                 default:
    00449                                         ilSetError(IL_INTERNAL_ERROR);
    00450                                         return;
    00451                         }
    00452                                 break;
    00453
    00454                 case IL_DOUBLE:
    00455                         DblPtr = (ILdouble*)Colours;
    00456                         switch (Format)
    00457                         {
    00458                                 case IL_RGB:
    00459                                         DblPtr[0] = ClearRed;
    00460                                         DblPtr[1] = ClearGreen;
    00461                                         DblPtr[2] = ClearBlue;
    00462                                         break;
    00463
    00464                                 case IL_RGBA:
    00465                                         DblPtr[0] = ClearRed;
    00466                                         DblPtr[1] = ClearGreen;
    00467                                         DblPtr[2] = ClearBlue;
    00468                                         DblPtr[3] = ClearAlpha;
    00469                                         break;
    00470
    00471                                 case IL_BGR:
    00472                                         DblPtr[2] = ClearRed;
    00473                                         DblPtr[1] = ClearGreen;
    00474                                         DblPtr[0] = ClearBlue;
    00475                                         DblPtr[3] = ClearAlpha;
    00476                                         break;
    00477
    00478                                 case IL_BGRA:
    00479                                         DblPtr[2] = ClearRed;
    00480                                         DblPtr[1] = ClearGreen;
    00481                                         DblPtr[0] = ClearBlue;
    00482                                         DblPtr[3] = ClearAlpha;
    00483                                         break;
    00484
    00485                                 case IL_LUMINANCE:
    00486                                         DblPtr[0] = ClearAlpha;
    00487                                         break;
    00488
    00489                                 case IL_LUMINANCE_ALPHA:
    00490                                         DblPtr[0] = ClearLum;
    00491                                         DblPtr[1] = ClearAlpha;
    00492                                         break;
    00493
    00494                                 case IL_COLOUR_INDEX:
    00495                                         DblPtr[0] = ClearAlpha;
    00496                                         break;
    00497
    00498                                 default:
    00499                                         ilSetError(IL_INTERNAL_ERROR);
    00500                                         return;
    00501                         }
    00502                                 break;
    00503
    00504                 default:
    00505                         ilSetError(IL_INTERNAL_ERROR);
    00506                         return;
    00507         }
    00508
    00509         return;
    00510 }
    00511
    00512
    00514 ILboolean ILAPIENTRY ilClearImage()
    00515 {
    00516         if (iCurImage == NULL) {
    00517                 ilSetError(IL_ILLEGAL_OPERATION);
    00518                 return IL_FALSE;
    00519         }
    00520
    00521         return ilClearImage_(iCurImage);
    00522 }
    00523
    00524
    00525 ILAPI ILboolean ILAPIENTRY ilClearImage_(ILimage *Image)
    00526 {
    00527         ILuint          i, c, NumBytes;
    00528         ILubyte         Colours[32];  // Maximum is sizeof(double) * 4 = 32
    00529         ILubyte         *BytePtr;
    00530         ILushort        *ShortPtr;
    00531         ILuint          *IntPtr;
    00532         ILfloat         *FloatPtr;
    00533         ILdouble        *DblPtr;
    00534
    00535         NumBytes = Image->Bpp * Image->Bpc;
    00536         ilGetClear(Colours, Image->Format, Image->Type);
    00537
    00538         if (Image->Format != IL_COLOUR_INDEX) {
    00539                 switch (Image->Type)
    00540                 {
    00541                         case IL_BYTE:
    00542                         case IL_UNSIGNED_BYTE:
    00543                                 BytePtr = (ILubyte*)Colours;
    00544                                 for (c = 0; c < NumBytes; c += Image->Bpc) {
    00545                                         for (i = c; i < Image->SizeOfData; i += NumBytes) {
    00546                                                 Image->Data[i] = BytePtr[c];
    00547                                         }
    00548                                 }
    00549                                         break;
    00550
    00551                         case IL_SHORT:
    00552                         case IL_UNSIGNED_SHORT:
    00553                                 ShortPtr = (ILushort*)Colours;
    00554                                 for (c = 0; c < NumBytes; c += Image->Bpc) {
    00555                                         for (i = c; i < Image->SizeOfData; i += NumBytes) {
    00556                                                 *((ILushort*)(Image->Data + i)) = ShortPtr[c / Image->Bpc];
    00557                                         }
    00558                                 }
    00559                                         break;
    00560
    00561                         case IL_INT:
    00562                         case IL_UNSIGNED_INT:
    00563                                 IntPtr = (ILuint*)Colours;
    00564                                 for (c = 0; c < NumBytes; c += Image->Bpc) {
    00565                                         for (i = c; i < Image->SizeOfData; i += NumBytes) {
    00566                                                 *((ILuint*)(Image->Data + i)) = IntPtr[c / Image->Bpc];
    00567                                         }
    00568                                 }
    00569                                         break;
    00570
    00571                         case IL_FLOAT:
    00572                                 FloatPtr = (ILfloat*)Colours;
    00573                                 for (c = 0; c < NumBytes; c += Image->Bpc) {
    00574                                         for (i = c; i < Image->SizeOfData; i += NumBytes) {
    00575                                                 *((ILfloat*)(Image->Data + i)) = FloatPtr[c / Image->Bpc];
    00576                                         }
    00577                                 }
    00578                                         break;
    00579
    00580                         case IL_DOUBLE:
    00581                                 DblPtr = (ILdouble*)Colours;
    00582                                 for (c = 0; c < NumBytes; c += Image->Bpc) {
    00583                                         for (i = c; i < Image->SizeOfData; i += NumBytes) {
    00584                                                 *((ILdouble*)(Image->Data + i)) = DblPtr[c / Image->Bpc];
    00585                                         }
    00586                                 }
    00587                                         break;
    00588                 }
    00589         }
    00590         else {
    00591                 imemclear(Image->Data, Image->SizeOfData);
    00592
    00593                 if (Image->Pal.Palette)
    00594                         ifree(Image->Pal.Palette);
    00595                 Image->Pal.Palette = (ILubyte*)ialloc(4);
    00596                 if (Image->Pal.Palette == NULL) {
    00597                         return IL_FALSE;
    00598                 }
    00599
    00600                 Image->Pal.PalType = IL_PAL_RGBA32;
    00601                 Image->Pal.PalSize = 4;
    00602
    00603                 Image->Pal.Palette[0] = Colours[0] * UCHAR_MAX;
    00604                 Image->Pal.Palette[1] = Colours[1] * UCHAR_MAX;
    00605                 Image->Pal.Palette[2] = Colours[2] * UCHAR_MAX;
    00606                 Image->Pal.Palette[3] = Colours[3] * UCHAR_MAX;
    00607         }
    00608
    00609         return IL_TRUE;
    00610 }
    00611
    00612
    00614 ILboolean ILAPIENTRY ilOverlayImage(ILuint Source, ILint XCoord, ILint YCoord, ILint ZCoord)
    00615 {
    00616         ILuint  Width, Height, Depth;
    00617         ILuint  Dest;
    00618
    00619         Dest = ilGetCurName();
    00620         ilBindImage(Source);
    00621         Width = iCurImage->Width;  Height = iCurImage->Height;  Depth = iCurImage->Depth;
    00622         ilBindImage(Dest);
    00623
    00624         return ilBlit(Source, XCoord, YCoord, ZCoord, 0, 0, 0, Width, Height, Depth);
    00625 }
    00626
    00627 //@NEXT DestX,DestY,DestZ must be set to ILuint
    00628 ILboolean ILAPIENTRY ilBlit(ILuint Source, ILint DestX,  ILint DestY,   ILint DestZ,
    00629                                            ILuint SrcX,  ILuint SrcY,   ILuint SrcZ,
    00630                                            ILuint Width, ILuint Height, ILuint Depth)
    00631 {
    00632         ILuint          x, y, z, ConvBps, ConvSizePlane;
    00633         ILimage         *Dest,*Src;
    00634         ILubyte         *Converted;
    00635         ILuint          DestName = ilGetCurName();
    00636         ILuint          c;
    00637         ILuint          StartX, StartY, StartZ;
    00638         ILboolean       DestFlipped = IL_FALSE;
    00639         ILubyte         *SrcTemp;
    00640         ILfloat         Back;
    00641
    00642         // Check if the desiination image really exists
    00643         if( DestName == 0 || iCurImage == NULL ) {
    00644                 ilSetError(IL_ILLEGAL_OPERATION);
    00645                 return IL_FALSE;
    00646         }
    00647         Dest = iCurImage;
    00648
    00649         // set the destination image to upper left origin
    00650         if( Dest->Origin == IL_ORIGIN_LOWER_LEFT ) {  // Dest
    00651                 DestFlipped = IL_TRUE;
    00652                 ilFlipImage();
    00653         }
    00654         //DestOrigin = Dest->Origin;
    00655         ilBindImage(Source);
    00656
    00657         // Check if the source image really exists
    00658         if( iCurImage == NULL ) {
    00659                 ilSetError(IL_INVALID_PARAM);
    00660                 return IL_FALSE;
    00661         }
    00662
    00663         Src = iCurImage;
    00664
    00665         //@TODO test if coordinates are inside the images (hard limit for source)
    00666
    00667         // set the source image to upper left origin
    00668         if (Src->Origin == IL_ORIGIN_LOWER_LEFT)
    00669         {
    00670                 SrcTemp = iGetFlipped(iCurImage);
    00671                 if (SrcTemp == NULL)
    00672                 {
    00673                         ilBindImage(DestName);
    00674                         if (DestFlipped)
    00675                                 ilFlipImage();
    00676                         return IL_FALSE;
    00677                 }
    00678         }
    00679         else
    00680         {
    00681                 SrcTemp = iCurImage->Data;
    00682         }
    00683
    00684         // convert source image to match the destination image type and format
    00685         Converted = (ILubyte*)ilConvertBuffer(Src->SizeOfData, Src->Format, Dest->Format, Src->Type, Dest->Type, SrcTemp);
    00686         if (Converted == NULL)
    00687                 return IL_FALSE;
    00688
    00689         ConvBps           = Dest->Bpp * Src->Width;
    00690         ConvSizePlane = ConvBps   * Src->Height;
    00691
    00692         //@NEXT in next version this would have to be removed since Dest* will be unsigned
    00693         StartX = DestX >= 0 ? 0 : -DestX;
    00694         StartY = DestY >= 0 ? 0 : -DestY;
    00695         StartZ = DestZ >= 0 ? 0 : -DestZ;
    00696
    00697         // Limit the copy of data inside of the destination image
    00698         if (Width  + DestX > Dest->Width)  Width  = Dest->Width  - DestX;
    00699         if (Height + DestY > Dest->Height) Height = Dest->Height - DestY;
    00700         if (Depth  + DestZ > Dest->Depth)  Depth  = Dest->Depth  - DestZ;
    00701
    00702         //@TODO: non funziona con rgba
    00703         if (Src->Format == IL_RGBA || Src->Format == IL_BGRA || Src->Format == IL_LUMINANCE_ALPHA) {
    00704                 const ILuint bpp_without_alpha = Dest->Bpp - 1;
    00705                 for (z = 0; z < Depth; z++) {
    00706                         for (y = 0; y < Height; y++) {
    00707                                 for (x = 0; x < Width; x++) {
    00708                                         const ILuint  SrcIndex  = (z+SrcZ)*ConvSizePlane + (y+SrcY)*ConvBps + (x+SrcX)*Dest->Bpp;
    00709                                         const ILuint  DestIndex = (z+DestZ)*Dest->SizeOfPlane + (y+DestY)*Dest->Bps + (x+DestX)*Dest->Bpp;
    00710                                         const ILuint  AlphaIdx = SrcIndex + bpp_without_alpha;
    00711                                         ILfloat Front = 0;
    00712
    00713                                         switch (Dest->Type)
    00714                                         {
    00715                                                 case IL_BYTE:
    00716                                                 case IL_UNSIGNED_BYTE:
    00717                                                         Front = Converted[AlphaIdx]/((float)IL_MAX_UNSIGNED_BYTE);
    00718                                                         break;
    00719                                                 case IL_SHORT:
    00720                                                 case IL_UNSIGNED_SHORT:
    00721                                                         Front = ((ILshort*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_SHORT);
    00722                                                         break;
    00723                                                 case IL_INT:
    00724                                                 case IL_UNSIGNED_INT:
    00725                                                         Front = ((ILint*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_INT);
    00726                                                         break;
    00727                                                 case IL_FLOAT:
    00728                                                         Front = ((ILfloat*)Converted)[AlphaIdx];
    00729                                                         break;
    00730                                                 case IL_DOUBLE:
    00731                                                         Front = (ILfloat)(((ILdouble*)Converted)[AlphaIdx]);
    00732                                                         break;
    00733                                         }
    00734                                         Back = 1.0f - Front;
    00735                                         // In case of Alpha channel, the data is blended. Keeps the original alpha.
    00736                                         if (ilIsEnabled(IL_BLIT_BLEND)) {
    00737                                                 for (c = 0; c < bpp_without_alpha; c++)
    00738                                                 {
    00739                                                         Dest->Data[DestIndex + c] =
    00740                                                                 (ILubyte)(Converted[SrcIndex + c] * Front
    00741                                                                                         + Dest->Data[DestIndex + c] * Back);
    00742                                                 }
    00743                                         }
    00744                                         else {
    00745                                                 for (c = 0; c < Dest->Bpp; c++)
    00746                                                 {
    00747                                                         Dest->Data[DestIndex + c] = (ILubyte)(Converted[SrcIndex + c]);
    00748                                                 }
    00749                                         }
    00750                                 }
    00751                         }
    00752                 }
    00753         } else {
    00754                 for( z = 0; z < Depth; z++ ) {
    00755                         for( y = 0; y < Height; y++ ) {
    00756                                 for( x = 0; x < Width; x++ ) {
    00757                                         for( c = 0; c < Dest->Bpp; c++ ) {
    00758                                                 Dest->Data[(z+DestZ)*Dest->SizeOfPlane + (y+DestY)*Dest->Bps + (x+DestX)*Dest->Bpp + c] =
    00759                                                  Converted[(z+SrcZ)*ConvSizePlane + (y+SrcY)*ConvBps + (x+SrcX)*Dest->Bpp + c];
    00760                                         }
    00761                                 }
    00762                         }
    00763                 }
    00764         }
    00765
    00766         if (SrcTemp != iCurImage->Data)
    00767                 ifree(SrcTemp);
    00768
    00769         ilBindImage(DestName);
    00770         if (DestFlipped)
    00771                 ilFlipImage();
    00772
    00773         ifree(Converted);
    00774
    00775         return IL_TRUE;
    00776 }
    00777
    00778
    00779 ILboolean iCopySubImage(ILimage *Dest, ILimage *Src)
    00780 {
    00781         ILimage *DestTemp, *SrcTemp;
    00782
    00783         DestTemp = Dest;
    00784         SrcTemp = Src;
    00785
    00786         do {
    00787                 ilCopyImageAttr(DestTemp, SrcTemp);
    00788                 DestTemp->Data = (ILubyte*)ialloc(SrcTemp->SizeOfData);
    00789                 if (DestTemp->Data == NULL) {
    00790                         return IL_FALSE;
    00791                 }
    00792                 memcpy(DestTemp->Data, SrcTemp->Data, SrcTemp->SizeOfData);
    00793
    00794                 if (SrcTemp->Next) {
    00795                         DestTemp->Next = (ILimage*)icalloc(1, sizeof(ILimage));
    00796                         if (!DestTemp->Next) {
    00797                                 return IL_FALSE;
    00798                         }
    00799                 }
    00800                 else {
    00801                         DestTemp->Next = NULL;
    00802                 }
    00803
    00804                 DestTemp = DestTemp->Next;
    00805                 SrcTemp = SrcTemp->Next;
    00806         } while (SrcTemp);
    00807
    00808         return IL_TRUE;
    00809 }
    00810
    00811
    00812 ILboolean iCopySubImages(ILimage *Dest, ILimage *Src)
    00813 {
    00814         if (Src->Faces) {
    00815                 Dest->Faces = (ILimage*)icalloc(1, sizeof(ILimage));
    00816                 if (!Dest->Faces) {
    00817                         return IL_FALSE;
    00818                 }
    00819                 if (!iCopySubImage(Dest->Faces, Src->Faces))
    00820                         return IL_FALSE;
    00821         }
    00822
    00823         if (Src->Layers) {
    00824                 Dest->Layers = (ILimage*)icalloc(1, sizeof(ILimage));
    00825                 if (!Dest->Layers) {
    00826                         return IL_FALSE;
    00827                 }
    00828                 if (!iCopySubImage(Dest->Layers, Src->Layers))
    00829                         return IL_FALSE;
    00830         }
    00831
    00832         if (Src->Mipmaps) {
    00833                 Dest->Mipmaps = (ILimage*)icalloc(1, sizeof(ILimage));
    00834                 if (!Dest->Mipmaps) {
    00835                         return IL_FALSE;
    00836                 }
    00837                 if (!iCopySubImage(Dest->Mipmaps, Src->Mipmaps))
    00838                         return IL_FALSE;
    00839         }
    00840
    00841         if (Src->Next) {
    00842                 Dest->Next = (ILimage*)icalloc(1, sizeof(ILimage));
    00843                 if (!Dest->Next) {
    00844                         return IL_FALSE;
    00845                 }
    00846                 if (!iCopySubImage(Dest->Next, Src->Next))
    00847                         return IL_FALSE;
    00848         }
    00849
    00850         return IL_TRUE;
    00851 }
    00852
    00853
    00854 // Copies everything but the Data from Src to Dest.
    00855 ILAPI ILboolean ILAPIENTRY ilCopyImageAttr(ILimage *Dest, ILimage *Src)
    00856 {
    00857         if (Dest == NULL || Src == NULL) {
    00858                 ilSetError(IL_INVALID_PARAM);
    00859                 return IL_FALSE;
    00860         }
    00861
    00862         if (Dest->Pal.Palette && Dest->Pal.PalSize && Dest->Pal.PalType != IL_PAL_NONE) {
    00863                 ifree(Dest->Pal.Palette);
    00864                 Dest->Pal.Palette = NULL;
    00865         }
    00866         if (Dest->Faces) {
    00867                 ilCloseImage(Dest->Faces);
    00868                 Dest->Faces = NULL;
    00869         }
    00870         if (Dest->Layers) {
    00871                 ilCloseImage(Dest->Layers);
    00872                 Dest->Layers = NULL;
    00873         }
    00874         if (Dest->Mipmaps) {
    00875                 ilCloseImage(Dest->Mipmaps);
    00876                 Dest->Mipmaps = NULL;
    00877         }
    00878         if (Dest->Next) {
    00879                 ilCloseImage(Dest->Next);
    00880                 Dest->Next = NULL;
    00881         }
    00882         if (Dest->Profile) {
    00883                 ifree(Dest->Profile);
    00884                 Dest->Profile = NULL;
    00885                 Dest->ProfileSize = 0;
    00886         }
    00887         if (Dest->DxtcData) {
    00888                 ifree(Dest->DxtcData);
    00889                 Dest->DxtcData = NULL;
    00890                 Dest->DxtcFormat = IL_DXT_NO_COMP;
    00891                 Dest->DxtcSize = 0;
    00892         }
    00893
    00894         if (Src->AnimList && Src->AnimSize) {
    00895                 Dest->AnimList = (ILuint*)ialloc(Src->AnimSize * sizeof(ILuint));
    00896                 if (Dest->AnimList == NULL) {
    00897                         return IL_FALSE;
    00898                 }
    00899                 memcpy(Dest->AnimList, Src->AnimList, Src->AnimSize * sizeof(ILuint));
    00900         }
    00901         if (Src->Profile) {
    00902                 Dest->Profile = (ILubyte*)ialloc(Src->ProfileSize);
    00903                 if (Dest->Profile == NULL) {
    00904                         return IL_FALSE;
    00905                 }
    00906                 memcpy(Dest->Profile, Src->Profile, Src->ProfileSize);
    00907                 Dest->ProfileSize = Src->ProfileSize;
    00908         }
    00909         if (Src->Pal.Palette) {
    00910                 Dest->Pal.Palette = (ILubyte*)ialloc(Src->Pal.PalSize);
    00911                 if (Dest->Pal.Palette == NULL) {
    00912                         return IL_FALSE;
    00913                 }
    00914                 memcpy(Dest->Pal.Palette, Src->Pal.Palette, Src->Pal.PalSize);
    00915         }
    00916         else {
    00917                 Dest->Pal.Palette = NULL;
    00918         }
    00919
    00920         Dest->Pal.PalSize = Src->Pal.PalSize;
    00921         Dest->Pal.PalType = Src->Pal.PalType;
    00922         Dest->Width = Src->Width;
    00923         Dest->Height = Src->Height;
    00924         Dest->Depth = Src->Depth;
    00925         Dest->Bpp = Src->Bpp;
    00926         Dest->Bpc = Src->Bpc;
    00927         Dest->Bps = Src->Bps;
    00928         Dest->SizeOfPlane = Src->SizeOfPlane;
    00929         Dest->SizeOfData = Src->SizeOfData;
    00930         Dest->Format = Src->Format;
    00931         Dest->Type = Src->Type;
    00932         Dest->Origin = Src->Origin;
    00933         Dest->Duration = Src->Duration;
    00934         Dest->CubeFlags = Src->CubeFlags;
    00935         Dest->AnimSize = Src->AnimSize;
    00936         Dest->OffX = Src->OffX;
    00937         Dest->OffY = Src->OffY;
    00938
    00939         return IL_TRUE/*iCopySubImages(Dest, Src)*/;
    00940 }
    00941
    00942
    00944 ILboolean ILAPIENTRY ilCopyImage(ILuint Src)
    00945 {
    00946         ILuint DestName = ilGetCurName();
    00947         ILimage *DestImage = iCurImage, *SrcImage;
    00948
    00949         if (iCurImage == NULL || DestName == 0) {
    00950                 ilSetError(IL_ILLEGAL_OPERATION);
    00951                 return IL_FALSE;
    00952         }
    00953
    00954         ilBindImage(Src);
    00955         SrcImage = iCurImage;
    00956         ilBindImage(DestName);
    00957         ilTexImage(SrcImage->Width, SrcImage->Height, SrcImage->Depth, SrcImage->Bpp, SrcImage->Format, SrcImage->Type, SrcImage->Data);
    00958         ilCopyImageAttr(DestImage, SrcImage);
    00959
    00960         return IL_TRUE;
    00961 }
    00962
    00963
    00964 // Creates a copy of Src and returns it.
    00965 ILAPI ILimage* ILAPIENTRY ilCopyImage_(ILimage *Src)
    00966 {
    00967         ILimage *Dest;
    00968
    00969         if (Src == NULL) {
    00970                 ilSetError(IL_INVALID_PARAM);
    00971                 return NULL;
    00972         }
    00973
    00974         Dest = ilNewImage(Src->Width, Src->Height, Src->Depth, Src->Bpp, Src->Bpc);
    00975         if (Dest == NULL) {
    00976                 return NULL;
    00977         }
    00978
    00979         if (ilCopyImageAttr(Dest, Src) == IL_FALSE)
    00980                 return NULL;
    00981
    00982         memcpy(Dest->Data, Src->Data, Src->SizeOfData);
    00983
    00984         return Dest;
    00985 }
    00986
    00987
    00988 ILuint ILAPIENTRY ilCloneCurImage()
    00989 {
    00990         ILuint Id;
    00991         ILimage *CurImage;
    00992
    00993         if (iCurImage == NULL) {
    00994                 ilSetError(IL_ILLEGAL_OPERATION);
    00995                 return 0;
    00996         }
    00997
    00998         ilGenImages(1, &Id);
    00999         if (Id == 0)
    01000                 return 0;
    01001
    01002         CurImage = iCurImage;
    01003
    01004         ilBindImage(Id);
    01005         ilTexImage(CurImage->Width, CurImage->Height, CurImage->Depth, CurImage->Bpp, CurImage->Format, CurImage->Type, CurImage->Data);
    01006         ilCopyImageAttr(iCurImage, CurImage);
    01007
    01008         iCurImage = CurImage;
    01009
    01010         return Id;
    01011 }
    01012
    01013
    01014 // Like ilTexImage but doesn't destroy the palette.
    01015 ILAPI ILboolean ILAPIENTRY ilResizeImage(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte Bpc)
    01016 {
    01017         if (Image == NULL) {
    01018                 ilSetError(IL_INVALID_PARAM);
    01019                 return IL_FALSE;
    01020         }
    01021
    01022         if (Image->Data != NULL)
    01023                 ifree(Image->Data);
    01024
    01025         Image->Depth = Depth;
    01026         Image->Width = Width;
    01027         Image->Height = Height;
    01028         Image->Bpp = Bpp;
    01029         Image->Bpc = Bpc;
    01030         Image->Bps = Bpp * Bpc * Width;
    01031         Image->SizeOfPlane = Image->Bps * Height;
    01032         Image->SizeOfData = Image->SizeOfPlane * Depth;
    01033
    01034         Image->Data = (ILubyte*)ialloc(Image->SizeOfData);
    01035         if (Image->Data == NULL) {
    01036                 return IL_FALSE;
    01037         }
    01038
    01039         return IL_TRUE;
    01040 }