- Main Page
- Data Structures
- Files

- File List

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

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Utility Sources
    00004 // Copyright (C) 2000-2008 by Denton Woods
    00005 // Last modified: 12/27/2008
    00006 //
    00007 // Filename: src-ILU/src/ilu_scale.c
    00008 //
    00009 // Description: Scales an image.
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013
    00014 #include "ilu_internal.h"
    00015 #include "ilu_states.h"
    00016
    00017
    00018 ILboolean ILAPIENTRY iluEnlargeImage(ILfloat XDim, ILfloat YDim, ILfloat ZDim)
    00019 {
    00020         if (XDim <= 0.0f || YDim <= 0.0f || ZDim <= 0.0f) {
    00021                 ilSetError(ILU_INVALID_PARAM);
    00022                 return IL_FALSE;
    00023         }
    00024
    00025         iluCurImage = ilGetCurImage();
    00026         return iluScale((ILuint)(iluCurImage->Width * XDim), (ILuint)(iluCurImage->Height * YDim),
    00027                                         (ILuint)(iluCurImage->Depth * ZDim));
    00028 }
    00029
    00030
    00031 ILimage *iluScale1D_(ILimage *Image, ILimage *Scaled, ILuint Width);
    00032 ILimage *iluScale2D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
    00033 ILimage *iluScale3D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth);
    00034
    00035
    00036 ILboolean ILAPIENTRY iluScale(ILuint Width, ILuint Height, ILuint Depth)
    00037 {
    00038         ILimage         *Temp;
    00039         ILboolean       UsePal;
    00040         ILenum          PalType;
    00041         ILenum          Origin;
    00042
    00043         iluCurImage = ilGetCurImage();
    00044         if (iluCurImage == NULL) {
    00045                 ilSetError(ILU_ILLEGAL_OPERATION);
    00046                 return IL_FALSE;
    00047         }
    00048
    00049         if (iluCurImage->Width == Width && iluCurImage->Height == Height && iluCurImage->Depth == Depth)
    00050                 return IL_TRUE;
    00051
    00052         // A parameter of 0 is not valid.  Let's just assume that the user wanted a value of 1 instead.
    00053         if (Width == 0)  Width = 1;
    00054         if (Height == 0) Height = 1;
    00055         if (Depth == 0)  Depth = 1;
    00056
    00057         if ((iluCurImage->Width<Width) || (iluCurImage->Height<Height)) // only do special scale if there is some zoom?
    00058         {
    00059                 switch (iluFilter)
    00060                 {
    00061                         case ILU_SCALE_BOX:
    00062                         case ILU_SCALE_TRIANGLE:
    00063                         case ILU_SCALE_BELL:
    00064                         case ILU_SCALE_BSPLINE:
    00065                         case ILU_SCALE_LANCZOS3:
    00066                         case ILU_SCALE_MITCHELL:
    00067
    00068                                 iluCurImage = ilGetCurImage();
    00069                                 if (iluCurImage == NULL) {
    00070                                         ilSetError(ILU_ILLEGAL_OPERATION);
    00071                                         return IL_FALSE;
    00072                                 }
    00073
    00074                                 // Not supported yet.
    00075                                 if (iluCurImage->Type != IL_UNSIGNED_BYTE ||
    00076                                         iluCurImage->Format == IL_COLOUR_INDEX ||
    00077                                         iluCurImage->Depth > 1) {
    00078                                                 ilSetError(ILU_ILLEGAL_OPERATION);
    00079                                                 return IL_FALSE;
    00080                                 }
    00081
    00082                                 if (iluCurImage->Width > Width) // shrink width first
    00083                                 {
    00084                                         Origin = iluCurImage->Origin;
    00085                                         Temp = iluScale_(iluCurImage, Width, iluCurImage->Height, iluCurImage->Depth);
    00086                                         if (Temp != NULL) {
    00087                                                 if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
    00088                                                         ilCloseImage(Temp);
    00089                                                         return IL_FALSE;
    00090                                                 }
    00091                                                 iluCurImage->Origin = Origin;
    00092                                                 ilCloseImage(Temp);
    00093                                         }
    00094                                 }
    00095                                 else if (iluCurImage->Height > Height) // shrink height first
    00096                                 {
    00097                                         Origin = iluCurImage->Origin;
    00098                                         Temp = iluScale_(iluCurImage, iluCurImage->Width, Height, iluCurImage->Depth);
    00099                                         if (Temp != NULL) {
    00100                                                 if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
    00101                                                         ilCloseImage(Temp);
    00102                                                         return IL_FALSE;
    00103                                                 }
    00104                                                 iluCurImage->Origin = Origin;
    00105                                                 ilCloseImage(Temp);
    00106                                         }
    00107                                 }
    00108
    00109                                 return (ILboolean)iluScaleAdvanced(Width, Height, iluFilter);
    00110                 }
    00111         }
    00112
    00113
    00114         Origin = iluCurImage->Origin;
    00115         UsePal = (iluCurImage->Format == IL_COLOUR_INDEX);
    00116         PalType = iluCurImage->Pal.PalType;
    00117         Temp = iluScale_(iluCurImage, Width, Height, Depth);
    00118         if (Temp != NULL) {
    00119                 if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
    00120                         ilCloseImage(Temp);
    00121                         return IL_FALSE;
    00122                 }
    00123                 iluCurImage->Origin = Origin;
    00124                 ilCloseImage(Temp);
    00125                 if (UsePal) {
    00126                         if (!ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE))
    00127                                 return IL_FALSE;
    00128                         ilConvertPal(PalType);
    00129                 }
    00130                 return IL_TRUE;
    00131         }
    00132
    00133         return IL_FALSE;
    00134 }
    00135
    00136
    00137 ILAPI ILimage* ILAPIENTRY iluScale_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth)
    00138 {
    00139         ILimage *Scaled, *CurImage, *ToScale;
    00140         ILenum  Format, PalType;
    00141
    00142         CurImage = ilGetCurImage();
    00143         Format = Image->Format;
    00144         if (Format == IL_COLOUR_INDEX) {
    00145                 ilSetCurImage(Image);
    00146                 PalType = Image->Pal.PalType;
    00147                 ToScale = iConvertImage(iluCurImage, ilGetPalBaseType(Image->Pal.PalType), iluCurImage->Type);
    00148         }
    00149         else {
    00150                 ToScale = Image;
    00151         }
    00152
    00153         // So we don't replicate this 3 times (one in each iluScalexD_() function.
    00154         Scaled = (ILimage*)icalloc(1, sizeof(ILimage));
    00155         if (ilCopyImageAttr(Scaled, ToScale) == IL_FALSE) {
    00156                 ilCloseImage(Scaled);
    00157                 if (ToScale != Image)
    00158                         ilCloseImage(ToScale);
    00159                 ilSetCurImage(CurImage);
    00160                 return NULL;
    00161         }
    00162         if (ilResizeImage(Scaled, Width, Height, Depth, ToScale->Bpp, ToScale->Bpc) == IL_FALSE) {
    00163                 ilCloseImage(Scaled);
    00164                 if (ToScale != Image)
    00165                         ilCloseImage(ToScale);
    00166                 ilSetCurImage(CurImage);
    00167                 return NULL;
    00168         }
    00169
    00170         if (Height <= 1 && Image->Height <= 1) {
    00171                 iluScale1D_(ToScale, Scaled, Width);
    00172         }
    00173         if (Depth <= 1 && Image->Depth <= 1) {
    00174                 iluScale2D_(ToScale, Scaled, Width, Height);
    00175         }
    00176         else {
    00177                 iluScale3D_(ToScale, Scaled, Width, Height, Depth);
    00178         }
    00179
    00180         if (Format == IL_COLOUR_INDEX) {
    00181                 //ilSetCurImage(Scaled);
    00182                 //ilConvertImage(IL_COLOUR_INDEX);
    00183                 ilSetCurImage(CurImage);
    00184                 ilCloseImage(ToScale);
    00185         }
    00186
    00187         return Scaled;
    00188 }
    00189
    00190
    00191 ILimage *iluScale1D_(ILimage *Image, ILimage *Scaled, ILuint Width)
    00192 {
    00193         ILuint          x1, x2;
    00194         ILuint          NewX1, NewX2, NewX3, x, c;
    00195         ILdouble        ScaleX, t1, t2, f;
    00196         ILushort        *ShortPtr, *SShortPtr;
    00197         ILuint          *IntPtr, *SIntPtr;
    00198
    00199         if (Image == NULL) {
    00200                 ilSetError(ILU_ILLEGAL_OPERATION);
    00201                 return IL_FALSE;
    00202         }
    00203
    00204         ScaleX = (ILdouble)Width / Image->Width;
    00205
    00206         ShortPtr = (ILushort*)Image->Data;
    00207         SShortPtr = (ILushort*)Scaled->Data;
    00208         IntPtr = (ILuint*)Image->Data;
    00209         SIntPtr = (ILuint*)Scaled->Data;
    00210
    00211         if (iluFilter == ILU_NEAREST) {
    00212                 switch (Image->Bpc)
    00213                 {
    00214                         case 1:
    00215                                 for (x = 0; x < Width; x++) {
    00216                                         NewX1 = x * Scaled->Bpp;
    00217                                         NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
    00218                                         for (c = 0; c < Scaled->Bpp; c++) {
    00219                                                 Scaled->Data[NewX1 + c] = Image->Data[NewX2 + c];
    00220                                         }
    00221                                 }
    00222                                 break;
    00223                         case 2:
    00224                                 for (x = 0; x < Width; x++) {
    00225                                         NewX1 = x * Scaled->Bpp;
    00226                                         NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
    00227                                         for (c = 0; c < Scaled->Bpp; c++) {
    00228                                                 SShortPtr[NewX1 + c] = ShortPtr[NewX2 + c];
    00229                                         }
    00230                                 }
    00231                                 break;
    00232                         case 4:
    00233                                 for (x = 0; x < Width; x++) {
    00234                                         NewX1 = x * Scaled->Bpp;
    00235                                         NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
    00236                                         for (c = 0; c < Scaled->Bpp; c++) {
    00237                                                 SIntPtr[NewX1 + c] = IntPtr[NewX2 + c];
    00238                                         }
    00239                                 }
    00240                                 break;
    00241                 }
    00242         }
    00243         else {  // IL_LINEAR or IL_BILINEAR
    00244                 switch (Image->Bpc)
    00245                 {
    00246                         case 1:
    00247                                 NewX3 = 0;
    00248                                 for (x = 0; x < Width; x++) {
    00249                                         t1 = x / (ILdouble)Width;
    00250                                         t2 = t1 * Width - (ILuint)(t1 * Width);
    00251                                         f = (1.0 - cos(t2 * IL_PI)) * .5;
    00252                                         NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
    00253                                         NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
    00254
    00255                                         for (c = 0; c < Scaled->Bpp; c++) {
    00256                                                 x1 = Image->Data[NewX1 + c];
    00257                                                 x2 = Image->Data[NewX2 + c];
    00258
    00259                                                 Scaled->Data[NewX3 + c] = (ILubyte)(x1 * (1.0 - f) + x2 * f);
    00260                                         }
    00261
    00262                                         NewX3 += Scaled->Bpp;
    00263                                 }
    00264                                 break;
    00265                         case 2:
    00266                                 NewX3 = 0;
    00267                                 for (x = 0; x < Width; x++) {
    00268                                         t1 = x / (ILdouble)Width;
    00269                                         t2 = t1 * Width - (ILuint)(t1 * Width);
    00270                                         f = (1.0 - cos(t2 * IL_PI)) * .5;
    00271                                         NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
    00272                                         NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
    00273
    00274                                         for (c = 0; c < Scaled->Bpp; c++) {
    00275                                                 x1 = ShortPtr[NewX1 + c];
    00276                                                 x2 = ShortPtr[NewX2 + c];
    00277
    00278                                                 SShortPtr[NewX3 + c] = (ILushort)(x1 * (1.0 - f) + x2 * f);
    00279                                         }
    00280
    00281                                         NewX3 += Scaled->Bpp;
    00282                                 }
    00283                                 break;
    00284                         case 4:
    00285                                 NewX3 = 0;
    00286                                 for (x = 0; x < Width; x++) {
    00287                                         t1 = x / (ILdouble)Width;
    00288                                         t2 = t1 * Width - (ILuint)(t1 * Width);
    00289                                         f = (1.0 - cos(t2 * IL_PI)) * .5;
    00290                                         NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
    00291                                         NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
    00292
    00293                                         for (c = 0; c < Scaled->Bpp; c++) {
    00294                                                 x1 = IntPtr[NewX1 + c];
    00295                                                 x2 = IntPtr[NewX2 + c];
    00296
    00297                                                 SIntPtr[NewX3 + c] = (ILuint)(x1 * (1.0 - f) + x2 * f);
    00298                                         }
    00299
    00300                                         NewX3 += Scaled->Bpp;
    00301                                 }
    00302                                 break;
    00303                 }
    00304         }
    00305
    00306         return Scaled;
    00307 }