- Main Page
- Data Structures
- Files

- File List

# E:/DevIL/src-ILU/src/ilu_scale2d.c

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Utility Sources
    00004 // Copyright (C) 2000-2002 by Denton Woods
    00005 // Last modified: 05/25/2001 <--Y2K Compliant! =]
    00006 //
    00007 // Filename: src-ILU/src/ilu_scale2d.c
    00008 //
    00009 // Description: Scales an image.
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013
    00014 // NOTE:  Don't look at this file if you wish to preserve your sanity!
    00015
    00016
    00017 #include "ilu_internal.h"
    00018 #include "ilu_states.h"
    00019
    00020
    00021 ILimage *iluScale2DNear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
    00022 ILimage *iluScale2DLinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
    00023 ILimage *iluScale2DBilinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
    00024
    00025 static ILuint           x1, x2;
    00026 static ILuint           NewY1, NewY2, NewX1, NewX2, Size, x, y, c;
    00027 static ILdouble ScaleX, ScaleY, t1, t2, t3, t4, f, ft, NewX;
    00028 static ILdouble Table[2][4];  // Assumes we don't have larger than 32-bit images.
    00029 static ILuint           ImgBps, SclBps;
    00030 static ILushort *ShortPtr, *SShortPtr;
    00031 static ILuint           *IntPtr, *SIntPtr;
    00032 static ILfloat          *FloatPtr, *SFloatPtr;
    00033
    00034
    00035
    00036 ILimage *iluScale2D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height)
    00037 {
    00038         if (Image == NULL) {
    00039                 ilSetError(ILU_ILLEGAL_OPERATION);
    00040                 return IL_FALSE;
    00041         }
    00042
    00043         ScaleX = (ILfloat)Width / Image->Width;
    00044         ScaleY = (ILfloat)Height / Image->Height;
    00045
    00046         if (iluFilter == ILU_NEAREST)
    00047                 return iluScale2DNear_(Image, Scaled, Width, Height);
    00048         else if (iluFilter == ILU_LINEAR)
    00049                 return iluScale2DLinear_(Image, Scaled, Width, Height);
    00050         // iluFilter == ILU_BILINEAR
    00051         return iluScale2DBilinear_(Image, Scaled, Width, Height);
    00052 }
    00053
    00054
    00055 ILimage *iluScale2DNear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height)
    00056 {
    00057         ImgBps = Image->Bps / Image->Bpc;
    00058         SclBps = Scaled->Bps / Scaled->Bpc;
    00059
    00060         switch (Image->Bpc)
    00061         {
    00062                 case 1:
    00063                         for (y = 0; y < Height; y++) {
    00064                                 NewY1 = y * SclBps;
    00065                                 NewY2 = (ILuint)(y / ScaleY) * ImgBps;
    00066                                 for (x = 0; x < Width; x++) {
    00067                                         NewX1 = x * Scaled->Bpp;
    00068                                         NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
    00069                                         for (c = 0; c < Scaled->Bpp; c++) {
    00070                                                 Scaled->Data[NewY1 + NewX1 + c] = Image->Data[NewY2 + NewX2 + c];
    00071                                                 x1 = 0;
    00072                                         }
    00073                                 }
    00074                         }
    00075                         break;
    00076
    00077                 case 2:
    00078                         ShortPtr = (ILushort*)Image->Data;
    00079                         SShortPtr = (ILushort*)Scaled->Data;
    00080                         for (y = 0; y < Height; y++) {
    00081                                 NewY1 = y * SclBps;
    00082                                 NewY2 = (ILuint)(y / ScaleY) * ImgBps;
    00083                                 for (x = 0; x < Width; x++) {
    00084                                         NewX1 = x * Scaled->Bpp;
    00085                                         NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
    00086                                         for (c = 0; c < Scaled->Bpp; c++) {
    00087                                                 SShortPtr[NewY1 + NewX1 + c] = ShortPtr[NewY2 + NewX2 + c];
    00088                                                 x1 = 0;
    00089                                         }
    00090                                 }
    00091                         }
    00092                         break;
    00093
    00094                 case 4:
    00095                         IntPtr = (ILuint*)Image->Data;
    00096                         SIntPtr = (ILuint*)Scaled->Data;
    00097                         for (y = 0; y < Height; y++) {
    00098                                 NewY1 = y * SclBps;
    00099                                 NewY2 = (ILuint)(y / ScaleY) * ImgBps;
    00100                                 for (x = 0; x < Width; x++) {
    00101                                         NewX1 = x * Scaled->Bpp;
    00102                                         NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
    00103                                         for (c = 0; c < Scaled->Bpp; c++) {
    00104                                                 SIntPtr[NewY1 + NewX1 + c] = IntPtr[NewY2 + NewX2 + c];
    00105                                                 x1 = 0;
    00106                                         }
    00107                                 }
    00108                         }
    00109                         break;
    00110         }
    00111
    00112         return Scaled;
    00113 }
    00114
    00115
    00116 ILimage *iluScale2DLinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height)
    00117 {
    00118         ImgBps = Image->Bps / Image->Bpc;
    00119         SclBps = Scaled->Bps / Scaled->Bpc;
    00120
    00121         switch (Image->Bpc)
    00122         {
    00123                 case 1:
    00124                         for (y = 0; y < Height; y++) {
    00125                                 NewY1 = (ILuint)(y / ScaleY) * ImgBps;
    00126                                 for (x = 0; x < Width; x++) {
    00127                                         t1 = x / (ILdouble)Width;
    00128                                         t4 = t1 * Width;
    00129                                         t2 = t4 - (ILuint)(t4);
    00130                                         ft = t2 * IL_PI;
    00131                                         f = (1.0 - cos(ft)) * .5;
    00132                                         NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
    00133                                         NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
    00134
    00135                                         Size = y * SclBps + x * Scaled->Bpp;
    00136                                         for (c = 0; c < Scaled->Bpp; c++) {
    00137                                                 x1 = Image->Data[NewY1 + NewX1 + c];
    00138                                                 x2 = Image->Data[NewY1 + NewX2 + c];
    00139                                                 Scaled->Data[Size + c] = (ILubyte)((1.0 - f) * x1 + f * x2);
    00140                                         }
    00141                                 }
    00142                         }
    00143                         break;
    00144
    00145                 case 2:
    00146                         ShortPtr = (ILushort*)Image->Data;
    00147                         SShortPtr = (ILushort*)Scaled->Data;
    00148                         for (y = 0; y < Height; y++) {
    00149                                 NewY1 = (ILuint)(y / ScaleY) * ImgBps;
    00150                                 for (x = 0; x < Width; x++) {
    00151                                         t1 = x / (ILdouble)Width;
    00152                                         t4 = t1 * Width;
    00153                                         t2 = t4 - (ILuint)(t4);
    00154                                         ft = t2 * IL_PI;
    00155                                         f = (1.0 - cos(ft)) * .5;
    00156                                         NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
    00157                                         NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
    00158
    00159                                         Size = y * SclBps + x * Scaled->Bpp;
    00160                                         for (c = 0; c < Scaled->Bpp; c++) {
    00161                                                 x1 = ShortPtr[NewY1 + NewX1 + c];
    00162                                                 x2 = ShortPtr[NewY1 + NewX2 + c];
    00163                                                 SShortPtr[Size + c] = (ILushort)((1.0 - f) * x1 + f * x2);
    00164                                         }
    00165                                 }
    00166                         }
    00167                         break;
    00168
    00169                 case 4:
    00170                         IntPtr = (ILuint*)Image->Data;
    00171                         SIntPtr = (ILuint*)Scaled->Data;
    00172                         for (y = 0; y < Height; y++) {
    00173                                 NewY1 = (ILuint)(y / ScaleY) * ImgBps;
    00174                                 for (x = 0; x < Width; x++) {
    00175                                         t1 = x / (ILdouble)Width;
    00176                                         t4 = t1 * Width;
    00177                                         t2 = t4 - (ILuint)(t4);
    00178                                         ft = t2 * IL_PI;
    00179                                         f = (1.0 - cos(ft)) * .5;
    00180                                         NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
    00181                                         NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
    00182
    00183                                         Size = y * SclBps + x * Scaled->Bpp;
    00184                                         for (c = 0; c < Scaled->Bpp; c++) {
    00185                                                 x1 = IntPtr[NewY1 + NewX1 + c];
    00186                                                 x2 = IntPtr[NewY1 + NewX2 + c];
    00187                                                 SIntPtr[Size + c] = (ILuint)((1.0 - f) * x1 + f * x2);
    00188                                         }
    00189                                 }
    00190                         }
    00191                         break;
    00192         }
    00193
    00194         return Scaled;
    00195 }
    00196
    00197
    00198 ILimage *iluScale2DBilinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height)
    00199 {
    00200         ImgBps = Image->Bps / Image->Bpc;
    00201         SclBps = Scaled->Bps / Scaled->Bpc;
    00202
    00203         switch (Image->Bpc)
    00204         {
    00205                 case 1:
    00206                         Height--;  // Only use regular Height once in the following loop.
    00207                         for (y = 0; y < Height; y++) {
    00208                                 NewY1 = (ILuint)(y / ScaleY) * ImgBps;
    00209                                 NewY2 = (ILuint)((y+1) / ScaleY) * ImgBps;
    00210                                 for (x = 0; x < Width; x++) {
    00211                                         NewX = Width / ScaleX;
    00212                                         t1 = x / (ILdouble)Width;
    00213                                         t4 = t1 * Width;
    00214                                         t2 = t4 - (ILuint)(t4);
    00215                                         t3 = (1.0 - t2);
    00216                                         t4 = t1 * NewX;
    00217                                         NewX1 = (ILuint)(t4) * Image->Bpp;
    00218                                         NewX2 = (ILuint)(t4 + 1) * Image->Bpp;
    00219
    00220                                         for (c = 0; c < Scaled->Bpp; c++) {
    00221                                                 Table[0][c] = t3 * Image->Data[NewY1 + NewX1 + c] +
    00222                                                         t2 * Image->Data[NewY1 + NewX2 + c];
    00223
    00224                                                 Table[1][c] = t3 * Image->Data[NewY2 + NewX1 + c] +
    00225                                                         t2 * Image->Data[NewY2 + NewX2 + c];
    00226                                         }
    00227
    00228                                         // Linearly interpolate between the table values.
    00229                                         t1 = y / (ILdouble)(Height + 1);  // Height+1 is the real height now.
    00230                                         t3 = (1.0 - t1);
    00231                                         Size = y * SclBps + x * Scaled->Bpp;
    00232                                         for (c = 0; c < Scaled->Bpp; c++) {
    00233                                                 Scaled->Data[Size + c] =
    00234                                                         (ILubyte)(t3 * Table[0][c] + t1 * Table[1][c]);
    00235                                         }
    00236                                 }
    00237                         }
    00238
    00239                         // Calculate the last row.
    00240                         NewY1 = (ILuint)(Height / ScaleY) * ImgBps;
    00241                         for (x = 0; x < Width; x++) {
    00242                                 NewX = Width / ScaleX;
    00243                                 t1 = x / (ILdouble)Width;
    00244                                 t4 = t1 * Width;
    00245                                 ft = (t4 - (ILuint)(t4)) * IL_PI;
    00246                                 f = (1.0 - cos(ft)) * .5;  // Cosine interpolation
    00247                                 NewX1 = (ILuint)(t1 * NewX) * Image->Bpp;
    00248                                 NewX2 = (ILuint)(t1 * NewX + 1) * Image->Bpp;
    00249
    00250                                 Size = Height * SclBps + x * Image->Bpp;
    00251                                 for (c = 0; c < Scaled->Bpp; c++) {
    00252                                         Scaled->Data[Size + c] = (ILubyte)((1.0 - f) * Image->Data[NewY1 + NewX1 + c] +
    00253                                                 f * Image->Data[NewY1 + NewX2 + c]);
    00254                                 }
    00255                         }
    00256                         break;
    00257
    00258                 case 2:
    00259                         ShortPtr = (ILushort*)Image->Data;
    00260                         SShortPtr = (ILushort*)Scaled->Data;
    00261                         Height--;  // Only use regular Height once in the following loop.
    00262                         for (y = 0; y < Height; y++) {
    00263                                 NewY1 = (ILuint)(y / ScaleY) * ImgBps;
    00264                                 NewY2 = (ILuint)((y+1) / ScaleY) * ImgBps;
    00265                                 for (x = 0; x < Width; x++) {
    00266                                         NewX = Width / ScaleX;
    00267                                         t1 = x / (ILdouble)Width;
    00268                                         t4 = t1 * Width;
    00269                                         t2 = t4 - (ILuint)(t4);
    00270                                         t3 = (1.0 - t2);
    00271                                         t4 = t1 * NewX;
    00272                                         NewX1 = (ILuint)(t4) * Image->Bpp;
    00273                                         NewX2 = (ILuint)(t4 + 1) * Image->Bpp;
    00274
    00275                                         for (c = 0; c < Scaled->Bpp; c++) {
    00276                                                 Table[0][c] = t3 * ShortPtr[NewY1 + NewX1 + c] +
    00277                                                         t2 * ShortPtr[NewY1 + NewX2 + c];
    00278
    00279                                                 Table[1][c] = t3 * ShortPtr[NewY2 + NewX1 + c] +
    00280                                                         t2 * ShortPtr[NewY2 + NewX2 + c];
    00281                                         }
    00282
    00283                                         // Linearly interpolate between the table values.
    00284                                         t1 = y / (ILdouble)(Height + 1);  // Height+1 is the real height now.
    00285                                         t3 = (1.0 - t1);
    00286                                         Size = y * SclBps + x * Scaled->Bpp;
    00287                                         for (c = 0; c < Scaled->Bpp; c++) {
    00288                                                 SShortPtr[Size + c] =
    00289                                                         (ILushort)(t3 * Table[0][c] + t1 * Table[1][c]);
    00290                                         }
    00291                                 }
    00292                         }
    00293
    00294                         // Calculate the last row.
    00295                         NewY1 = (ILuint)(Height / ScaleY) * ImgBps;
    00296                         for (x = 0; x < Width; x++) {
    00297                                 NewX = Width / ScaleX;
    00298                                 t1 = x / (ILdouble)Width;
    00299                                 t4 = t1 * Width;
    00300                                 ft = (t4 - (ILuint)(t4)) * IL_PI;
    00301                                 f = (1.0 - cos(ft)) * .5;  // Cosine interpolation
    00302                                 NewX1 = (ILuint)(t1 * NewX) * Image->Bpp;
    00303                                 NewX2 = (ILuint)(t1 * NewX + 1) * Image->Bpp;
    00304
    00305                                 Size = Height * SclBps + x * Image->Bpp;
    00306                                 for (c = 0; c < Scaled->Bpp; c++) {
    00307                                         SShortPtr[Size + c] = (ILushort)((1.0 - f) * ShortPtr[NewY1 + NewX1 + c] +
    00308                                                 f * ShortPtr[NewY1 + NewX2 + c]);
    00309                                 }
    00310                         }
    00311                         break;
    00312
    00313                 case 4:
    00314
    00315                         if (Image->Type != IL_FLOAT) {
    00316
    00317                                 IntPtr = (ILuint*)Image->Data;
    00318                                 SIntPtr = (ILuint*)Scaled->Data;
    00319                                 Height--;  // Only use regular Height once in the following loop.
    00320                                 for (y = 0; y < Height; y++) {
    00321                                         NewY1 = (ILuint)(y / ScaleY) * ImgBps;
    00322                                         NewY2 = (ILuint)((y+1) / ScaleY) * ImgBps;
    00323                                         for (x = 0; x < Width; x++) {
    00324                                                 NewX = Width / ScaleX;
    00325                                                 t1 = x / (ILdouble)Width;
    00326                                                 t4 = t1 * Width;
    00327                                                 t2 = t4 - (ILuint)(t4);
    00328                                                 t3 = (1.0 - t2);
    00329                                                 t4 = t1 * NewX;
    00330                                                 NewX1 = (ILuint)(t4) * Image->Bpp;
    00331                                                 NewX2 = (ILuint)(t4 + 1) * Image->Bpp;
    00332
    00333                                                 for (c = 0; c < Scaled->Bpp; c++) {
    00334                                                         Table[0][c] = t3 * IntPtr[NewY1 + NewX1 + c] +
    00335                                                                 t2 * IntPtr[NewY1 + NewX2 + c];
    00336
    00337                                                         Table[1][c] = t3 * IntPtr[NewY2 + NewX1 + c] +
    00338                                                                 t2 * IntPtr[NewY2 + NewX2 + c];
    00339                                                 }
    00340
    00341                                                 // Linearly interpolate between the table values.
    00342                                                 t1 = y / (ILdouble)(Height + 1);  // Height+1 is the real height now.
    00343                                                 t3 = (1.0 - t1);
    00344                                                 Size = y * SclBps + x * Scaled->Bpp;
    00345                                                 for (c = 0; c < Scaled->Bpp; c++) {
    00346                                                         SIntPtr[Size + c] =
    00347                                                                 (ILuint)(t3 * Table[0][c] + t1 * Table[1][c]);
    00348                                                 }
    00349                                         }
    00350                                 }
    00351
    00352                                 // Calculate the last row.
    00353                                 NewY1 = (ILuint)(Height / ScaleY) * ImgBps;
    00354                                 for (x = 0; x < Width; x++) {
    00355                                         NewX = Width / ScaleX;
    00356                                         t1 = x / (ILdouble)Width;
    00357                                         t4 = t1 * Width;
    00358                                         ft = (t4 - (ILuint)(t4)) * IL_PI;
    00359                                         f = (1.0 - cos(ft)) * .5;  // Cosine interpolation
    00360                                         NewX1 = (ILuint)(t1 * NewX) * Image->Bpp;
    00361                                         NewX2 = (ILuint)(t1 * NewX + 1) * Image->Bpp;
    00362
    00363                                         Size = Height * SclBps + x * Image->Bpp;
    00364                                         for (c = 0; c < Scaled->Bpp; c++) {
    00365                                                 SIntPtr[Size + c] = (ILuint)((1.0 - f) * IntPtr[NewY1 + NewX1 + c] +
    00366                                                         f * IntPtr[NewY1 + NewX2 + c]);
    00367                                         }
    00368                                 }
    00369
    00370                         }
    00371
    00372                         else {  // IL_FLOAT
    00373
    00374                                 FloatPtr = (ILfloat*)Image->Data;
    00375
    00376                                 SFloatPtr = (ILfloat*)Scaled->Data;
    00377
    00378                                 Height--;  // Only use regular Height once in the following loop.
    00379
    00380                                 for (y = 0; y < Height; y++) {
    00381
    00382                                         NewY1 = (ILuint)(y / ScaleY) * ImgBps;
    00383
    00384                                         NewY2 = (ILuint)((y+1) / ScaleY) * ImgBps;
    00385
    00386                                         for (x = 0; x < Width; x++) {
    00387
    00388                                                 NewX = Width / ScaleX;
    00389
    00390                                                 t1 = x / (ILdouble)Width;
    00391
    00392                                                 t4 = t1 * Width;
    00393
    00394                                                 t2 = t4 - (ILuint)(t4);
    00395
    00396                                                 t3 = (1.0 - t2);
    00397
    00398                                                 t4 = t1 * NewX;
    00399
    00400                                                 NewX1 = (ILuint)(t4) * Image->Bpp;
    00401
    00402                                                 NewX2 = (ILuint)(t4 + 1) * Image->Bpp;
    00403
    00404
    00405
    00406                                                 for (c = 0; c < Scaled->Bpp; c++) {
    00407
    00408                                                         Table[0][c] = t3 * FloatPtr[NewY1 + NewX1 + c] +
    00409
    00410                                                                 t2 * FloatPtr[NewY1 + NewX2 + c];
    00411
    00412
    00413
    00414                                                         Table[1][c] = t3 * FloatPtr[NewY2 + NewX1 + c] +
    00415
    00416                                                                 t2 * FloatPtr[NewY2 + NewX2 + c];
    00417
    00418                                                 }
    00419
    00420
    00421
    00422                                                 // Linearly interpolate between the table values.
    00423
    00424                                                 t1 = y / (ILdouble)(Height + 1);  // Height+1 is the real height now.
    00425
    00426                                                 t3 = (1.0 - t1);
    00427
    00428                                                 Size = y * SclBps + x * Scaled->Bpp;
    00429
    00430                                                 for (c = 0; c < Scaled->Bpp; c++) {
    00431
    00432                                                         SFloatPtr[Size + c] =
    00433
    00434                                                                 (ILfloat)(t3 * Table[0][c] + t1 * Table[1][c]);
    00435
    00436                                                 }
    00437
    00438                                         }
    00439
    00440                                 }
    00441
    00442
    00443
    00444                                 // Calculate the last row.
    00445
    00446                                 NewY1 = (ILuint)(Height / ScaleY) * ImgBps;
    00447
    00448                                 for (x = 0; x < Width; x++) {
    00449
    00450                                         NewX = Width / ScaleX;
    00451
    00452                                         t1 = x / (ILdouble)Width;
    00453
    00454                                         t4 = t1 * Width;
    00455
    00456                                         ft = (t4 - (ILuint)(t4)) * IL_PI;
    00457
    00458                                         f = (1.0 - cos(ft)) * .5;  // Cosine interpolation
    00459
    00460                                         NewX1 = (ILuint)(t1 * NewX) * Image->Bpp;
    00461
    00462                                         NewX2 = (ILuint)(t1 * NewX + 1) * Image->Bpp;
    00463
    00464
    00465
    00466                                         Size = Height * SclBps + x * Image->Bpp;
    00467
    00468                                         for (c = 0; c < Scaled->Bpp; c++) {
    00469
    00470                                                 SFloatPtr[Size + c] = (ILfloat)((1.0 - f) * FloatPtr[NewY1 + NewX1 + c] +
    00471
    00472                                                         f * FloatPtr[NewY1 + NewX2 + c]);
    00473
    00474                                         }
    00475
    00476                                 }
    00477
    00478                         }
    00479
    00480                         break;
    00481         }
    00482
    00483         return Scaled;
    00484 }