- Main Page
- Data Structures
- Files

- File List

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

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Sources
    00004 // Copyright (C) 2000-2009 by Denton Woods
    00005 // Last modified: 01/24/2009
    00006 //
    00007 // Filename: src-IL/src/il_manip.c
    00008 //
    00009 // Description: Image manipulation
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013 #include "il_internal.h"
    00014 #include "il_manip.h"
    00015
    00016
    00017 ILAPI void ILAPIENTRY iFlipBuffer(ILubyte *buff, ILuint depth, ILuint line_size, ILuint line_num)
    00018 {
    00019         ILubyte *StartPtr, *EndPtr;
    00020         ILuint y, d;
    00021         const ILuint size = line_num * line_size;
    00022
    00023         for (d = 0; d < depth; d++) {
    00024                 StartPtr = buff + d * size;
    00025                 EndPtr   = buff + d * size + size;
    00026
    00027                 for (y = 0; y < (line_num/2); y++) {
    00028                         EndPtr -= line_size;
    00029                         iMemSwap(StartPtr, EndPtr, line_size);
    00030                         StartPtr += line_size;
    00031                 }
    00032         }
    00033 }
    00034
    00035 // Just created for internal use.
    00036 ILubyte* iFlipNewBuffer(ILubyte *buff, ILuint depth, ILuint line_size, ILuint line_num)
    00037 {
    00038         ILubyte *data;
    00039         ILubyte *s1, *s2;
    00040         ILuint y, d;
    00041         const ILuint size = line_num * line_size;
    00042
    00043         if ((data = (ILubyte*)ialloc(depth*size)) == NULL)
    00044                 return IL_FALSE;
    00045
    00046         for (d = 0; d < depth; d++) {
    00047                 s1 = buff + d * size;
    00048                 s2 = data + d * size+size;
    00049
    00050                 for (y = 0; y < line_num; y++) {
    00051                         s2 -= line_size;
    00052                         memcpy(s2,s1,line_size);
    00053                         s1 += line_size;
    00054                 }
    00055         }
    00056         return data;
    00057 }
    00058
    00059
    00060 // Flips an image over its x axis
    00061 ILboolean ilFlipImage()
    00062 {
    00063         if (iCurImage == NULL) {
    00064                 ilSetError(IL_ILLEGAL_OPERATION);
    00065                 return IL_FALSE;
    00066         }
    00067
    00068         iCurImage->Origin = (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) ?
    00069                                                 IL_ORIGIN_UPPER_LEFT : IL_ORIGIN_LOWER_LEFT;
    00070
    00071         iFlipBuffer(iCurImage->Data,iCurImage->Depth,iCurImage->Bps,iCurImage->Height);
    00072
    00073         return IL_TRUE;
    00074 }
    00075
    00076 // Just created for internal use.
    00077 ILubyte* ILAPIENTRY iGetFlipped(ILimage *img)
    00078 {
    00079         if (img == NULL) {
    00080                 ilSetError(IL_ILLEGAL_OPERATION);
    00081                 return NULL;
    00082         }
    00083         return iFlipNewBuffer(img->Data,img->Depth,img->Bps,img->Height);
    00084 }
    00085
    00086
    00087 //@JASON New routine created 28/03/2001
    00089 ILboolean ILAPIENTRY iMirror() {
    00090         ILubyte         *Data, *DataPtr, *Temp;
    00091         ILuint          y, d, PixLine;
    00092         ILint           x, c;
    00093         ILushort        *ShortPtr, *TempShort;
    00094         ILuint          *IntPtr, *TempInt;
    00095         ILdouble        *DblPtr, *TempDbl;
    00096
    00097         if (iCurImage == NULL) {
    00098                 ilSetError(IL_ILLEGAL_OPERATION);
    00099                 return IL_FALSE;
    00100         }
    00101
    00102         Data = (ILubyte*)ialloc(iCurImage->SizeOfData);
    00103         if (Data == NULL)
    00104                 return IL_FALSE;
    00105
    00106         PixLine = iCurImage->Bps / iCurImage->Bpc;
    00107         switch (iCurImage->Bpc)
    00108         {
    00109                 case 1:
    00110                         Temp = iCurImage->Data;
    00111                         for (d = 0; d < iCurImage->Depth; d++) {
    00112                                 DataPtr = Data + d * iCurImage->SizeOfPlane;
    00113                                 for (y = 0; y < iCurImage->Height; y++) {
    00114                                         for (x = iCurImage->Width - 1; x >= 0; x--) {
    00115                                                 for (c = 0; c < iCurImage->Bpp; c++, Temp++) {
    00116                                                         DataPtr[y * PixLine + x * iCurImage->Bpp + c] = *Temp;
    00117                                                 }
    00118                                         }
    00119                                 }
    00120                         }
    00121                         break;
    00122
    00123                 case 2:
    00124                         TempShort = (ILushort*)iCurImage->Data;
    00125                         for (d = 0; d < iCurImage->Depth; d++) {
    00126                                 ShortPtr = (ILushort*)(Data + d * iCurImage->SizeOfPlane);
    00127                                 for (y = 0; y < iCurImage->Height; y++) {
    00128                                         for (x = iCurImage->Width - 1; x >= 0; x--) {
    00129                                                 for (c = 0; c < iCurImage->Bpp; c++, TempShort++) {
    00130                                                         ShortPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempShort;
    00131                                                 }
    00132                                         }
    00133                                 }
    00134                         }
    00135                         break;
    00136
    00137                 case 4:
    00138                         TempInt = (ILuint*)iCurImage->Data;
    00139                         for (d = 0; d < iCurImage->Depth; d++) {
    00140                                 IntPtr = (ILuint*)(Data + d * iCurImage->SizeOfPlane);
    00141                                 for (y = 0; y < iCurImage->Height; y++) {
    00142                                         for (x = iCurImage->Width - 1; x >= 0; x--) {
    00143                                                 for (c = 0; c < iCurImage->Bpp; c++, TempInt++) {
    00144                                                         IntPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempInt;
    00145                                                 }
    00146                                         }
    00147                                 }
    00148                         }
    00149                         break;
    00150
    00151                 case 8:
    00152                         TempDbl = (ILdouble*)iCurImage->Data;
    00153                         for (d = 0; d < iCurImage->Depth; d++) {
    00154                                 DblPtr = (ILdouble*)(Data + d * iCurImage->SizeOfPlane);
    00155                                 for (y = 0; y < iCurImage->Height; y++) {
    00156                                         for (x = iCurImage->Width - 1; x >= 0; x--) {
    00157                                                 for (c = 0; c < iCurImage->Bpp; c++, TempDbl++) {
    00158                                                         DblPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempDbl;
    00159                                                 }
    00160                                         }
    00161                                 }
    00162                         }
    00163                         break;
    00164         }
    00165
    00166         ifree(iCurImage->Data);
    00167         iCurImage->Data = Data;
    00168
    00169         return IL_TRUE;
    00170 }
    00171
    00172
    00173 // Should we add type to the parameter list?
    00174 // Copies a 1d block of pixels to the buffer pointed to by Data.
    00175 ILboolean ilCopyPixels1D(ILuint XOff, ILuint Width, void *Data)
    00176 {
    00177         ILuint  x, c, NewBps, NewOff, PixBpp;
    00178         ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
    00179
    00180         if (ilIsEnabled(IL_ORIGIN_SET)) {
    00181                 if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
    00182                         TempData = iGetFlipped(iCurImage);
    00183                         if (TempData == NULL)
    00184                                 return IL_FALSE;
    00185                 }
    00186         }
    00187
    00188         PixBpp = iCurImage->Bpp * iCurImage->Bpc;
    00189
    00190         if (iCurImage->Width < XOff + Width) {
    00191                 NewBps = (iCurImage->Width - XOff) * PixBpp;
    00192         }
    00193         else {
    00194                 NewBps = Width * PixBpp;
    00195         }
    00196         NewOff = XOff * PixBpp;
    00197
    00198         for (x = 0; x < NewBps; x += PixBpp) {
    00199                 for (c = 0; c < PixBpp; c++) {
    00200                         Temp[x + c] = TempData[(x + NewOff) + c];
    00201                 }
    00202         }
    00203
    00204         if (TempData != iCurImage->Data)
    00205                 ifree(TempData);
    00206
    00207         return IL_TRUE;
    00208 }
    00209
    00210
    00211 // Copies a 2d block of pixels to the buffer pointed to by Data.
    00212 ILboolean ilCopyPixels2D(ILuint XOff, ILuint YOff, ILuint Width, ILuint Height, void *Data)
    00213 {
    00214         ILuint  x, y, c, NewBps, DataBps, NewXOff, NewHeight, PixBpp;
    00215         ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
    00216
    00217         if (ilIsEnabled(IL_ORIGIN_SET)) {
    00218                 if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
    00219                         TempData = iGetFlipped(iCurImage);
    00220                         if (TempData == NULL)
    00221                                 return IL_FALSE;
    00222                 }
    00223         }
    00224
    00225         PixBpp = iCurImage->Bpp * iCurImage->Bpc;
    00226
    00227         if (iCurImage->Width < XOff + Width)
    00228                 NewBps = (iCurImage->Width - XOff) * PixBpp;
    00229         else
    00230                 NewBps = Width * PixBpp;
    00231
    00232         if (iCurImage->Height < YOff + Height)
    00233                 NewHeight = iCurImage->Height - YOff;
    00234         else
    00235                 NewHeight = Height;
    00236
    00237         DataBps = Width * PixBpp;
    00238         NewXOff = XOff * PixBpp;
    00239
    00240         for (y = 0; y < NewHeight; y++) {
    00241                 for (x = 0; x < NewBps; x += PixBpp) {
    00242                         for (c = 0; c < PixBpp; c++) {
    00243                                 Temp[y * DataBps + x + c] =
    00244                                         TempData[(y + YOff) * iCurImage->Bps + x + NewXOff + c];
    00245                         }
    00246                 }
    00247         }
    00248
    00249         if (TempData != iCurImage->Data)
    00250                 ifree(TempData);
    00251
    00252         return IL_TRUE;
    00253 }
    00254
    00255
    00256 // Copies a 3d block of pixels to the buffer pointed to by Data.
    00257 ILboolean ilCopyPixels3D(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, void *Data)
    00258 {
    00259         ILuint  x, y, z, c, NewBps, DataBps, NewSizePlane, NewH, NewD, NewXOff, PixBpp;
    00260         ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
    00261
    00262         if (ilIsEnabled(IL_ORIGIN_SET)) {
    00263                 if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
    00264                         TempData = iGetFlipped(iCurImage);
    00265                         if (TempData == NULL)
    00266                                 return IL_FALSE;
    00267                 }
    00268         }
    00269
    00270         PixBpp = iCurImage->Bpp * iCurImage->Bpc;
    00271
    00272         if (iCurImage->Width < XOff + Width)
    00273                 NewBps = (iCurImage->Width - XOff) * PixBpp;
    00274         else
    00275                 NewBps = Width * PixBpp;
    00276
    00277         if (iCurImage->Height < YOff + Height)
    00278                 NewH = iCurImage->Height - YOff;
    00279         else
    00280                 NewH = Height;
    00281
    00282         if (iCurImage->Depth < ZOff + Depth)
    00283                 NewD = iCurImage->Depth - ZOff;
    00284         else
    00285                 NewD = Depth;
    00286
    00287         DataBps = Width * PixBpp;
    00288         NewSizePlane = NewBps * NewH;
    00289
    00290         NewXOff = XOff * PixBpp;
    00291
    00292         for (z = 0; z < NewD; z++) {
    00293                 for (y = 0; y < NewH; y++) {
    00294                         for (x = 0; x < NewBps; x += PixBpp) {
    00295                                 for (c = 0; c < PixBpp; c++) {
    00296                                         Temp[z * NewSizePlane + y * DataBps + x + c] =
    00297                                                 TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + x + NewXOff + c];
    00298                                                 //TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + (x + XOff) * iCurImage->Bpp + c];
    00299                                 }
    00300                         }
    00301                 }
    00302         }
    00303
    00304         if (TempData != iCurImage->Data)
    00305                 ifree(TempData);
    00306
    00307         return IL_TRUE;
    00308 }
    00309
    00310
    00311 ILuint ILAPIENTRY ilCopyPixels(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, void *Data)
    00312 {
    00313         void    *Converted = NULL;
    00314         ILubyte *TempBuff = NULL;
    00315         ILuint  SrcSize, DestSize;
    00316
    00317         if (iCurImage == NULL) {
    00318                 ilSetError(IL_ILLEGAL_OPERATION);
    00319                 return 0;
    00320         }
    00321         DestSize = Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type);
    00322         if (DestSize == 0) {
    00323                 return DestSize;
    00324         }
    00325         if (Data == NULL) {
    00326                 ilSetError(IL_INVALID_PARAM);
    00327                 return 0;
    00328         }
    00329         SrcSize = Width * Height * Depth * iCurImage->Bpp * iCurImage->Bpc;
    00330
    00331         if (Format == iCurImage->Format && Type == iCurImage->Type) {
    00332                 TempBuff = (ILubyte*)Data;
    00333         }
    00334         else {
    00335                 TempBuff = (ILubyte*)ialloc(SrcSize);
    00336                 if (TempBuff == NULL) {
    00337                         return 0;
    00338                 }
    00339         }
    00340
    00341         if (YOff + Height <= 1) {
    00342                 if (!ilCopyPixels1D(XOff, Width, TempBuff)) {
    00343                         goto failed;
    00344                 }
    00345         }
    00346         else if (ZOff + Depth <= 1) {
    00347                 if (!ilCopyPixels2D(XOff, YOff, Width, Height, TempBuff)) {
    00348                         goto failed;
    00349                 }
    00350         }
    00351         else {
    00352                 if (!ilCopyPixels3D(XOff, YOff, ZOff, Width, Height, Depth, TempBuff)) {
    00353                         goto failed;
    00354                 }
    00355         }
    00356
    00357         if (Format == iCurImage->Format && Type == iCurImage->Type) {
    00358                 return DestSize;
    00359         }
    00360
    00361         Converted = ilConvertBuffer(SrcSize, iCurImage->Format, Format, iCurImage->Type, Type, TempBuff);
    00362         if (Converted == NULL)
    00363                 goto failed;
    00364
    00365         memcpy(Data, Converted, DestSize);
    00366
    00367         ifree(Converted);
    00368         if (TempBuff != Data)
    00369                 ifree(TempBuff);
    00370
    00371         return DestSize;
    00372
    00373 failed:
    00374         if (TempBuff != Data)
    00375                 ifree(TempBuff);
    00376         ifree(Converted);
    00377         return 0;
    00378 }
    00379
    00380
    00381 ILboolean ilSetPixels1D(ILint XOff, ILuint Width, void *Data)
    00382 {
    00383         ILuint  c, SkipX = 0, PixBpp;
    00384         ILint   x, NewWidth;
    00385         ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
    00386
    00387         if (ilIsEnabled(IL_ORIGIN_SET)) {
    00388                 if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
    00389                         TempData = iGetFlipped(iCurImage);
    00390                         if (TempData == NULL)
    00391                                 return IL_FALSE;
    00392                 }
    00393         }
    00394
    00395         PixBpp = iCurImage->Bpp * iCurImage->Bpc;
    00396
    00397         if (XOff < 0) {
    00398                 SkipX = abs(XOff);
    00399                 XOff = 0;
    00400         }
    00401
    00402         if (iCurImage->Width < XOff + Width) {
    00403                 NewWidth = iCurImage->Width - XOff;
    00404         }
    00405         else {
    00406                 NewWidth = Width;
    00407         }
    00408
    00409         NewWidth -= SkipX;
    00410
    00411         for (x = 0; x < NewWidth; x++) {
    00412                 for (c = 0; c < PixBpp; c++) {
    00413                         TempData[(x + XOff) * PixBpp + c] = Temp[(x + SkipX) * PixBpp + c];
    00414                 }
    00415         }
    00416
    00417         if (TempData != iCurImage->Data) {
    00418                 ifree(iCurImage->Data);
    00419                 iCurImage->Data = TempData;
    00420         }
    00421
    00422         return IL_TRUE;
    00423 }
    00424
    00425
    00426 ILboolean ilSetPixels2D(ILint XOff, ILint YOff, ILuint Width, ILuint Height, void *Data)
    00427 {
    00428         ILuint  c, SkipX = 0, SkipY = 0, NewBps, PixBpp;
    00429         ILint   x, y, NewWidth, NewHeight;
    00430         ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
    00431
    00432         if (ilIsEnabled(IL_ORIGIN_SET)) {
    00433                 if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
    00434                         TempData = iGetFlipped(iCurImage);
    00435                         if (TempData == NULL)
    00436                                 return IL_FALSE;
    00437                 }
    00438         }
    00439
    00440         PixBpp = iCurImage->Bpp * iCurImage->Bpc;
    00441
    00442         if (XOff < 0) {
    00443                 SkipX = abs(XOff);
    00444                 XOff = 0;
    00445         }
    00446         if (YOff < 0) {
    00447                 SkipY = abs(YOff);
    00448                 YOff = 0;
    00449         }
    00450
    00451         if (iCurImage->Width < XOff + Width)
    00452                 NewWidth = iCurImage->Width - XOff;
    00453         else
    00454                 NewWidth = Width;
    00455         NewBps = Width * PixBpp;
    00456
    00457         if (iCurImage->Height < YOff + Height)
    00458                 NewHeight = iCurImage->Height - YOff;
    00459         else
    00460                 NewHeight = Height;
    00461
    00462         NewWidth -= SkipX;
    00463         NewHeight -= SkipY;
    00464
    00465         for (y = 0; y < NewHeight; y++) {
    00466                 for (x = 0; x < NewWidth; x++) {
    00467                         for (c = 0; c < PixBpp; c++) {
    00468                                 TempData[(y + YOff) * iCurImage->Bps + (x + XOff) * PixBpp + c] =
    00469                                         Temp[(y + SkipY) * NewBps + (x + SkipX) * PixBpp + c];
    00470                         }
    00471                 }
    00472         }
    00473
    00474         if (TempData != iCurImage->Data) {
    00475                 ifree(iCurImage->Data);
    00476                 iCurImage->Data = TempData;
    00477         }
    00478
    00479         return IL_TRUE;
    00480 }
    00481
    00482
    00483 ILboolean ilSetPixels3D(ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, void *Data)
    00484 {
    00485         ILuint  SkipX = 0, SkipY = 0, SkipZ = 0, c, NewBps, NewSizePlane, PixBpp;
    00486         ILint   x, y, z, NewW, NewH, NewD;
    00487         ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
    00488
    00489         if (ilIsEnabled(IL_ORIGIN_SET)) {
    00490                 if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
    00491                         TempData = iGetFlipped(iCurImage);
    00492                         if (TempData == NULL)
    00493                                 return IL_FALSE;
    00494                 }
    00495         }
    00496
    00497         PixBpp = iCurImage->Bpp * iCurImage->Bpc;
    00498
    00499         if (XOff < 0) {
    00500                 SkipX = abs(XOff);
    00501                 XOff = 0;
    00502         }
    00503         if (YOff < 0) {
    00504                 SkipY = abs(YOff);
    00505                 YOff = 0;
    00506         }
    00507         if (ZOff < 0) {
    00508                 SkipZ = abs(ZOff);
    00509                 ZOff = 0;
    00510         }
    00511
    00512         if (iCurImage->Width < XOff + Width)
    00513                 NewW = iCurImage->Width - XOff;
    00514         else
    00515                 NewW = Width;
    00516         NewBps = Width * PixBpp;
    00517
    00518         if (iCurImage->Height < YOff + Height)
    00519                 NewH = iCurImage->Height - YOff;
    00520         else
    00521                 NewH = Height;
    00522
    00523         if (iCurImage->Depth < ZOff + Depth)
    00524                 NewD = iCurImage->Depth - ZOff;
    00525         else
    00526                 NewD = Depth;
    00527         NewSizePlane = NewBps * Height;
    00528
    00529         NewW -= SkipX;
    00530         NewH -= SkipY;
    00531         NewD -= SkipZ;
    00532
    00533         for (z = 0; z < NewD; z++) {
    00534                 for (y = 0; y < NewH; y++) {
    00535                         for (x = 0; x < NewW; x++) {
    00536                                 for (c = 0; c < PixBpp; c++) {
    00537                                         TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + (x + XOff) * PixBpp + c] =
    00538                                                 Temp[(z + SkipZ) * NewSizePlane + (y + SkipY) * NewBps + (x + SkipX) * PixBpp + c];
    00539                                 }
    00540                         }
    00541                 }
    00542         }
    00543
    00544         if (TempData != iCurImage->Data) {
    00545                 ifree(iCurImage->Data);
    00546                 iCurImage->Data = TempData;
    00547         }
    00548
    00549         return IL_TRUE;
    00550 }
    00551
    00552
    00553 void ILAPIENTRY ilSetPixels(ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, void *Data)
    00554 {
    00555         void *Converted;
    00556
    00557         if (iCurImage == NULL) {
    00558                 ilSetError(IL_ILLEGAL_OPERATION);
    00559                 return;
    00560         }
    00561         if (Data == NULL) {
    00562                 ilSetError(IL_INVALID_PARAM);
    00563                 return;
    00564         }
    00565
    00566         if (Format == iCurImage->Format && Type == iCurImage->Type) {
    00567                 Converted = (void*)Data;
    00568         }
    00569         else {
    00570                 Converted = ilConvertBuffer(Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type), Format, iCurImage->Format, Type, iCurImage->Type, Data);
    00571                 if (!Converted)
    00572                         return;
    00573         }
    00574
    00575         if (YOff + Height <= 1) {
    00576                 ilSetPixels1D(XOff, Width, Converted);
    00577         }
    00578         else if (ZOff + Depth <= 1) {
    00579                 ilSetPixels2D(XOff, YOff, Width, Height, Converted);
    00580         }
    00581         else {
    00582                 ilSetPixels3D(XOff, YOff, ZOff, Width, Height, Depth, Converted);
    00583         }
    00584
    00585         if (Format == iCurImage->Format && Type == iCurImage->Type) {
    00586                 return;
    00587         }
    00588
    00589         if (Converted != Data)
    00590                 ifree(Converted);
    00591
    00592         return;
    00593 }
    00594
    00595
    00596
    00597 //      Ripped from Platinum (Denton's sources)
    00598 //      This could very well easily be changed to a 128x128 image instead...needed?
    00599
    00601 ILboolean ILAPIENTRY ilDefaultImage()
    00602 {
    00603         ILubyte *TempData;
    00604         ILubyte Yellow[3] = { 18, 246, 243 };
    00605         ILubyte Black[3]  = { 0, 0, 0 };
    00606         ILubyte *ColorPtr = Yellow;  // The start color
    00607         ILboolean Color = IL_TRUE;
    00608
    00609         // Loop Variables
    00610         ILint v, w, x, y;
    00611
    00612         if (iCurImage == NULL) {
    00613                 ilSetError(IL_ILLEGAL_OPERATION);
    00614                 return IL_FALSE;
    00615         }
    00616
    00617         if (!ilTexImage(64, 64, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) {
    00618                 return IL_FALSE;
    00619         }
    00620         iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
    00621         TempData = iCurImage->Data;
    00622
    00623         for (v = 0; v < 8; v++) {
    00624                 // We do this because after a "block" line ends, the next row of blocks
    00625                 // above starts with the ending colour, but the very inner loop switches them.
    00626                 if (Color) {
    00627                         Color = IL_FALSE;
    00628                         ColorPtr = Black;
    00629                 }
    00630                 else {
    00631                         Color = IL_TRUE;
    00632                         ColorPtr = Yellow;
    00633                 }
    00634
    00635                 for (w = 0; w < 8; w++) {
    00636                         for (x = 0; x < 8; x++) {
    00637                                 for (y = 0; y < 8; y++, TempData += iCurImage->Bpp) {
    00638                                         TempData[0] = ColorPtr[0];
    00639                                         TempData[1] = ColorPtr[1];
    00640                                         TempData[2] = ColorPtr[2];
    00641                                 }
    00642
    00643                                 // Switch to alternate between black and yellow
    00644                                 if (Color) {
    00645                                         Color = IL_FALSE;
    00646                                         ColorPtr = Black;
    00647                                 }
    00648                                 else {
    00649                                         Color = IL_TRUE;
    00650                                         ColorPtr = Yellow;
    00651                                 }
    00652                         }
    00653                 }
    00654         }
    00655
    00656         return IL_TRUE;
    00657 }
    00658
    00659
    00660 ILubyte* ILAPIENTRY ilGetAlpha(ILenum Type)
    00661 {
    00662         ILimage         *TempImage;
    00663         ILubyte         *Alpha;
    00664         ILushort        *AlphaShort;
    00665         ILuint          *AlphaInt;
    00666         ILdouble        *AlphaDbl;
    00667         ILuint          i, j, Bpc, Size, AlphaOff;
    00668
    00669         if (iCurImage == NULL) {
    00670                 ilSetError(IL_ILLEGAL_OPERATION);
    00671                 return IL_FALSE;
    00672         }
    00673
    00674         Bpc = ilGetBpcType(Type);
    00675         if (Bpc == 0) {
    00676                 ilSetError(IL_INVALID_PARAM);
    00677                 return NULL;
    00678         }
    00679
    00680         if (iCurImage->Type == Type) {
    00681                 TempImage = iCurImage;
    00682         } else {
    00683                 TempImage = iConvertImage(iCurImage, iCurImage->Format, Type);
    00684                 if (TempImage == NULL)
    00685                         return NULL;
    00686         }
    00687
    00688         Size = iCurImage->Width * iCurImage->Height * iCurImage->Depth * TempImage->Bpp;
    00689         Alpha = (ILubyte*)ialloc(Size / TempImage->Bpp * Bpc);
    00690         if (Alpha == NULL) {
    00691                 if (TempImage != iCurImage)
    00692                         ilCloseImage(TempImage);
    00693                 return NULL;
    00694         }
    00695
    00696         switch (TempImage->Format)
    00697         {
    00698                 case IL_RGB:
    00699                 case IL_BGR:
    00700                 case IL_LUMINANCE:
    00701                 case IL_COLOUR_INDEX:  // @TODO: Make IL_COLOUR_INDEX separate.
    00702                         memset(Alpha, 0xFF, Size / TempImage->Bpp * Bpc);
    00703                         if (TempImage != iCurImage)
    00704                                 ilCloseImage(TempImage);
    00705                         return Alpha;
    00706         }
    00707
    00708         if (TempImage->Format == IL_LUMINANCE_ALPHA)
    00709                 AlphaOff = 2;
    00710         else
    00711                 AlphaOff = 4;
    00712
    00713         switch (TempImage->Type)
    00714         {
    00715                 case IL_BYTE:
    00716                 case IL_UNSIGNED_BYTE:
    00717                         for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00718                                 Alpha[j] = TempImage->Data[i];
    00719                         break;
    00720
    00721                 case IL_SHORT:
    00722                 case IL_UNSIGNED_SHORT:
    00723                         AlphaShort = (ILushort*)Alpha;
    00724                         for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00725                                 AlphaShort[j] = ((ILushort*)TempImage->Data)[i];
    00726                         break;
    00727
    00728                 case IL_INT:
    00729                 case IL_UNSIGNED_INT:
    00730                 case IL_FLOAT:  // Can throw float in here, because it's the same size.
    00731                         AlphaInt = (ILuint*)Alpha;
    00732                         for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00733                                 AlphaInt[j] = ((ILuint*)TempImage->Data)[i];
    00734                         break;
    00735
    00736                 case IL_DOUBLE:
    00737                         AlphaDbl = (ILdouble*)Alpha;
    00738                         for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00739                                 AlphaDbl[j] = ((ILdouble*)TempImage->Data)[i];
    00740                         break;
    00741         }
    00742
    00743         if (TempImage != iCurImage)
    00744                 ilCloseImage(TempImage);
    00745
    00746         return Alpha;
    00747 }
    00748
    00749 // sets the Alpha value to a specific value for each pixel in the image
    00750 ILboolean ILAPIENTRY ilSetAlpha( ILdouble AlphaValue ) {
    00751     ILboolean ret = IL_TRUE;
    00752     ILuint    i,Size;
    00753     ILimage  *image = iCurImage;
    00754         ILuint AlphaOff;
    00755
    00756     if (image == NULL) {
    00757         ilSetError(IL_ILLEGAL_OPERATION);
    00758         return IL_FALSE;
    00759     }
    00760
    00761     AlphaValue = IL_CLAMP(AlphaValue);
    00762
    00763     switch (image->Format)
    00764         {
    00765             case IL_RGB:
    00766                 ret = ilConvertImage(IL_RGBA,image->Type);
    00767             case IL_RGBA:
    00768                 AlphaOff = 4;
    00769                 break;
    00770             case IL_BGR:
    00771                 ret = ilConvertImage(IL_BGRA,image->Type);
    00772             case IL_BGRA:
    00773                 AlphaOff = 4;
    00774                 break;
    00775             case IL_LUMINANCE:
    00776                 ret = ilConvertImage(IL_LUMINANCE_ALPHA,image->Type);
    00777             case IL_LUMINANCE_ALPHA:
    00778                 AlphaOff = 2;
    00779                 break;
    00780             case IL_COLOUR_INDEX: //@TODO use palette with alpha
    00781                 ret = ilConvertImage(IL_RGBA,image->Type);
    00782                 AlphaOff = 4;
    00783                 break;
    00784     }
    00785     if (ret == IL_FALSE) {
    00786         return IL_FALSE;
    00787         // error has been set by ilConvertImage
    00788     }
    00789         Size = image->Width * image->Height * image->Depth * image->Bpp;
    00790
    00791     switch (iCurImage->Type)
    00792         {
    00793         case IL_BYTE:
    00794                 case IL_UNSIGNED_BYTE: {
    00795                 const ILbyte alpha = (ILubyte)(AlphaValue * IL_MAX_UNSIGNED_BYTE + .5);
    00796             for (i = AlphaOff-1; i < Size; i += AlphaOff)
    00797                 image->Data[i] = alpha;
    00798                         break; }
    00799         case IL_SHORT:
    00800                 case IL_UNSIGNED_SHORT: {
    00801             const ILushort alpha = (ILushort)(AlphaValue * IL_MAX_UNSIGNED_SHORT + .5);
    00802             for( i = AlphaOff-1; i < Size; i += AlphaOff)
    00803                 ((ILushort*)image->Data)[i] = alpha;
    00804                         break; }
    00805         case IL_INT:
    00806                 case IL_UNSIGNED_INT: {
    00807             const ILushort alpha = (ILushort)(AlphaValue * IL_MAX_UNSIGNED_INT + .5);
    00808             for (i = AlphaOff-1; i < Size; i += AlphaOff)
    00809                 ((ILushort*)image->Data)[i] = alpha;
    00810                         break; }
    00811                 case IL_FLOAT: {
    00812             const ILfloat alpha = (ILfloat)AlphaValue;
    00813             for (i = AlphaOff-1; i < Size; i += AlphaOff)
    00814                 ((ILfloat*)image->Data)[i] = alpha;
    00815                         break; }
    00816                 case IL_DOUBLE: {
    00817             const ILdouble alpha  = AlphaValue;
    00818             for (i = AlphaOff-1; i < Size; i += AlphaOff)
    00819                 ((ILdouble*)image->Data)[i] = alpha;
    00820                         break; }
    00821     }
    00822     return IL_TRUE;
    00823 }
    00824
    00825 void ILAPIENTRY ilModAlpha(ILdouble AlphaValue)
    00826 {
    00827     ILuint AlphaOff = 0;
    00828     ILboolean ret = IL_FALSE;
    00829     ILuint i,j,Size;
    00830
    00831     union {
    00832         ILubyte alpha_byte;
    00833         ILushort alpha_short;
    00834         ILuint alpha_int;
    00835         ILfloat alpha_float;
    00836         ILdouble alpha_double;
    00837     } Alpha;
    00838
    00839
    00840     if (iCurImage == NULL) {
    00841         ilSetError(IL_ILLEGAL_OPERATION);
    00842         return;
    00843     }
    00844
    00845     switch (iCurImage->Format)
    00846         {
    00847             case IL_RGB:
    00848                 ret = ilConvertImage(IL_RGBA,iCurImage->Type);
    00849                 AlphaOff = 4;
    00850                 break;
    00851             case IL_BGR:
    00852                 ret = ilConvertImage(IL_BGRA,iCurImage->Type);
    00853                 AlphaOff = 4;
    00854                 break;
    00855             case IL_LUMINANCE:
    00856                 ret = ilConvertImage(IL_LUMINANCE_ALPHA,iCurImage->Type);
    00857                 AlphaOff = 2;
    00858                 break;
    00859             case IL_COLOUR_INDEX:
    00860                 ret = ilConvertImage(IL_RGBA,iCurImage->Type);
    00861                 AlphaOff = 4;
    00862                 break;
    00863     }
    00864     Size = iCurImage->Width * iCurImage->Height * iCurImage->Depth * iCurImage->Bpp;
    00865
    00866     if (!ret)
    00867                 return;
    00868
    00869     switch (iCurImage->Type)
    00870         {
    00871         case IL_BYTE:
    00872         case IL_UNSIGNED_BYTE:
    00873             Alpha.alpha_byte = (ILubyte)(AlphaValue * 0x000000FF + .5);
    00874             for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00875                 iCurImage->Data[i] = Alpha.alpha_byte;
    00876             break;
    00877         case IL_SHORT:
    00878         case IL_UNSIGNED_SHORT:
    00879             Alpha.alpha_short = (ILushort)(AlphaValue * 0x0000FFFF + .5);
    00880             for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00881                 ((ILushort*)iCurImage->Data)[i] = Alpha.alpha_short;
    00882             break;
    00883         case IL_INT:
    00884         case IL_UNSIGNED_INT:
    00885             Alpha.alpha_int = (ILuint)(AlphaValue * 0xFFFFFFFF + .5);
    00886             for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00887                 ((ILuint*)iCurImage->Data)[i] = Alpha.alpha_int;
    00888             break;
    00889         case IL_FLOAT:
    00890             Alpha.alpha_float = (ILfloat)AlphaValue;
    00891             for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00892                 ((ILfloat*)iCurImage->Data)[i] = Alpha.alpha_float;
    00893             break;
    00894         case IL_DOUBLE:
    00895             Alpha.alpha_double = AlphaValue;
    00896             for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
    00897                 ((ILdouble*)iCurImage->Data)[i] = Alpha.alpha_double;
    00898             break;
    00899     }
    00900
    00901         return;
    00902 }
    00903
    00904
    00906 //   NTSC television.  Reasoning for this is given at
    00907 //   http://msdn.microsoft.com/en-us/library/bb174608.aspx.
    00908 ILboolean ILAPIENTRY ilClampNTSC(void)
    00909 {
    00910         ILuint x, y, z, c;
    00911         ILuint Offset = 0;
    00912
    00913     if (iCurImage == NULL) {
    00914         ilSetError(IL_ILLEGAL_OPERATION);
    00915         return IL_FALSE;
    00916     }
    00917
    00918         if (iCurImage->Type != IL_UNSIGNED_BYTE)  // Should we set an error here?
    00919                 return IL_FALSE;
    00920
    00921         for (z = 0; z < iCurImage->Depth; z++) {
    00922                 for (y = 0; y < iCurImage->Height; y++) {
    00923                         for (x = 0; x < iCurImage->Width; x++) {
    00924                                 for (c = 0; c < iCurImage->Bpp; c++) {
    00925                                         iCurImage->Data[Offset + c] = IL_LIMIT(iCurImage->Data[Offset + c], 16, 235);
    00926                                 }
    00927                         Offset += iCurImage->Bpp;
    00928                         }
    00929                 }
    00930         }
    00931
    00932         return IL_TRUE;
    00933 }