ilu_scale.c
Upload User: wmy0603
Upload Date: 2022-05-02
Package Size: 1808k
Code Size: 8k
Development Platform:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. //
  3. // ImageLib Utility Sources
  4. // Copyright (C) 2000-2008 by Denton Woods
  5. // Last modified: 12/27/2008
  6. //
  7. // Filename: src-ILU/src/ilu_scale.c
  8. //
  9. // Description: Scales an image.
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include "ilu_internal.h"
  13. #include "ilu_states.h"
  14. ILboolean ILAPIENTRY iluEnlargeImage(ILfloat XDim, ILfloat YDim, ILfloat ZDim)
  15. {
  16. if (XDim <= 0.0f || YDim <= 0.0f || ZDim <= 0.0f) {
  17. ilSetError(ILU_INVALID_PARAM);
  18. return IL_FALSE;
  19. }
  20. iluCurImage = ilGetCurImage();
  21. return iluScale((ILuint)(iluCurImage->Width * XDim), (ILuint)(iluCurImage->Height * YDim),
  22. (ILuint)(iluCurImage->Depth * ZDim));
  23. }
  24. ILimage *iluScale1D_(ILimage *Image, ILimage *Scaled, ILuint Width);
  25. ILimage *iluScale2D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
  26. ILimage *iluScale3D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth);
  27. ILboolean ILAPIENTRY iluScale(ILuint Width, ILuint Height, ILuint Depth)
  28. {
  29. ILimage *Temp;
  30. ILboolean UsePal;
  31. ILenum PalType;
  32. ILenum Origin;
  33. iluCurImage = ilGetCurImage();
  34. if (iluCurImage == NULL) {
  35. ilSetError(ILU_ILLEGAL_OPERATION);
  36. return IL_FALSE;
  37. }
  38. if (iluCurImage->Width == Width && iluCurImage->Height == Height && iluCurImage->Depth == Depth)
  39. return IL_TRUE;
  40. // A parameter of 0 is not valid.  Let's just assume that the user wanted a value of 1 instead.
  41. if (Width == 0)  Width = 1;
  42. if (Height == 0) Height = 1;
  43. if (Depth == 0)  Depth = 1;
  44. if ((iluCurImage->Width<Width) || (iluCurImage->Height<Height)) // only do special scale if there is some zoom?
  45. {
  46. switch (iluFilter)
  47. {
  48. case ILU_SCALE_BOX:
  49. case ILU_SCALE_TRIANGLE:
  50. case ILU_SCALE_BELL:
  51. case ILU_SCALE_BSPLINE:
  52. case ILU_SCALE_LANCZOS3:
  53. case ILU_SCALE_MITCHELL:
  54. iluCurImage = ilGetCurImage();
  55. if (iluCurImage == NULL) {
  56. ilSetError(ILU_ILLEGAL_OPERATION);
  57. return IL_FALSE;
  58. }
  59. // Not supported yet.
  60. if (iluCurImage->Type != IL_UNSIGNED_BYTE ||
  61. iluCurImage->Format == IL_COLOUR_INDEX ||
  62. iluCurImage->Depth > 1) {
  63. ilSetError(ILU_ILLEGAL_OPERATION);
  64. return IL_FALSE;
  65. }
  66. if (iluCurImage->Width > Width) // shrink width first
  67. {
  68. Origin = iluCurImage->Origin;
  69. Temp = iluScale_(iluCurImage, Width, iluCurImage->Height, iluCurImage->Depth);
  70. if (Temp != NULL) {
  71. if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
  72. ilCloseImage(Temp);
  73. return IL_FALSE;
  74. }
  75. iluCurImage->Origin = Origin;
  76. ilCloseImage(Temp);
  77. }
  78. }
  79. else if (iluCurImage->Height > Height) // shrink height first
  80. {
  81. Origin = iluCurImage->Origin;
  82. Temp = iluScale_(iluCurImage, iluCurImage->Width, Height, iluCurImage->Depth);
  83. if (Temp != NULL) {
  84. if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
  85. ilCloseImage(Temp);
  86. return IL_FALSE;
  87. }
  88. iluCurImage->Origin = Origin;
  89. ilCloseImage(Temp);
  90. }
  91. }
  92. return (ILboolean)iluScaleAdvanced(Width, Height, iluFilter);
  93. }
  94. }
  95. Origin = iluCurImage->Origin;
  96. UsePal = (iluCurImage->Format == IL_COLOUR_INDEX);
  97. PalType = iluCurImage->Pal.PalType;
  98. Temp = iluScale_(iluCurImage, Width, Height, Depth);
  99. if (Temp != NULL) {
  100. if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
  101. ilCloseImage(Temp);
  102. return IL_FALSE;
  103. }
  104. iluCurImage->Origin = Origin;
  105. ilCloseImage(Temp);
  106. if (UsePal) {
  107. if (!ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE))
  108. return IL_FALSE;
  109. ilConvertPal(PalType);
  110. }
  111. return IL_TRUE;
  112. }
  113. return IL_FALSE;
  114. }
  115. ILAPI ILimage* ILAPIENTRY iluScale_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth)
  116. {
  117. ILimage *Scaled, *CurImage, *ToScale;
  118. ILenum Format, PalType;
  119. CurImage = ilGetCurImage();
  120. Format = Image->Format;
  121. if (Format == IL_COLOUR_INDEX) {
  122. ilSetCurImage(Image);
  123. PalType = Image->Pal.PalType;
  124. ToScale = iConvertImage(iluCurImage, ilGetPalBaseType(Image->Pal.PalType), iluCurImage->Type);
  125. }
  126. else {
  127. ToScale = Image;
  128. }
  129. // So we don't replicate this 3 times (one in each iluScalexD_() function.
  130. Scaled = (ILimage*)icalloc(1, sizeof(ILimage));
  131. if (ilCopyImageAttr(Scaled, ToScale) == IL_FALSE) {
  132. ilCloseImage(Scaled);
  133. if (ToScale != Image)
  134. ilCloseImage(ToScale);
  135. ilSetCurImage(CurImage);
  136. return NULL;
  137. }
  138. if (ilResizeImage(Scaled, Width, Height, Depth, ToScale->Bpp, ToScale->Bpc) == IL_FALSE) {
  139. ilCloseImage(Scaled);
  140. if (ToScale != Image)
  141. ilCloseImage(ToScale);
  142. ilSetCurImage(CurImage);
  143. return NULL;
  144. }
  145. if (Height <= 1 && Image->Height <= 1) {
  146. iluScale1D_(ToScale, Scaled, Width);
  147. }
  148. if (Depth <= 1 && Image->Depth <= 1) {
  149. iluScale2D_(ToScale, Scaled, Width, Height);
  150. }
  151. else {
  152. iluScale3D_(ToScale, Scaled, Width, Height, Depth);
  153. }
  154. if (Format == IL_COLOUR_INDEX) {
  155. //ilSetCurImage(Scaled);
  156. //ilConvertImage(IL_COLOUR_INDEX);
  157. ilSetCurImage(CurImage);
  158. ilCloseImage(ToScale);
  159. }
  160. return Scaled;
  161. }
  162. ILimage *iluScale1D_(ILimage *Image, ILimage *Scaled, ILuint Width)
  163. {
  164. ILuint x1, x2;
  165. ILuint NewX1, NewX2, NewX3, x, c;
  166. ILdouble ScaleX, t1, t2, f;
  167. ILushort *ShortPtr, *SShortPtr;
  168. ILuint *IntPtr, *SIntPtr;
  169. if (Image == NULL) {
  170. ilSetError(ILU_ILLEGAL_OPERATION);
  171. return IL_FALSE;
  172. }
  173. ScaleX = (ILdouble)Width / Image->Width;
  174. ShortPtr = (ILushort*)Image->Data;
  175. SShortPtr = (ILushort*)Scaled->Data;
  176. IntPtr = (ILuint*)Image->Data;
  177. SIntPtr = (ILuint*)Scaled->Data;
  178. if (iluFilter == ILU_NEAREST) {
  179. switch (Image->Bpc)
  180. {
  181. case 1:
  182. for (x = 0; x < Width; x++) {
  183. NewX1 = x * Scaled->Bpp;
  184. NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
  185. for (c = 0; c < Scaled->Bpp; c++) {
  186. Scaled->Data[NewX1 + c] = Image->Data[NewX2 + c];
  187. }
  188. }
  189. break;
  190. case 2:
  191. for (x = 0; x < Width; x++) {
  192. NewX1 = x * Scaled->Bpp;
  193. NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
  194. for (c = 0; c < Scaled->Bpp; c++) {
  195. SShortPtr[NewX1 + c] = ShortPtr[NewX2 + c];
  196. }
  197. }
  198. break;
  199. case 4:
  200. for (x = 0; x < Width; x++) {
  201. NewX1 = x * Scaled->Bpp;
  202. NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
  203. for (c = 0; c < Scaled->Bpp; c++) {
  204. SIntPtr[NewX1 + c] = IntPtr[NewX2 + c];
  205. }
  206. }
  207. break;
  208. }
  209. }
  210. else {  // IL_LINEAR or IL_BILINEAR
  211. switch (Image->Bpc)
  212. {
  213. case 1:
  214. NewX3 = 0;
  215. for (x = 0; x < Width; x++) {
  216. t1 = x / (ILdouble)Width;
  217. t2 = t1 * Width - (ILuint)(t1 * Width);
  218. f = (1.0 - cos(t2 * IL_PI)) * .5;
  219. NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
  220. NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
  221. for (c = 0; c < Scaled->Bpp; c++) {
  222. x1 = Image->Data[NewX1 + c];
  223. x2 = Image->Data[NewX2 + c];
  224. Scaled->Data[NewX3 + c] = (ILubyte)(x1 * (1.0 - f) + x2 * f);
  225. }
  226. NewX3 += Scaled->Bpp;
  227. }
  228. break;
  229. case 2:
  230. NewX3 = 0;
  231. for (x = 0; x < Width; x++) {
  232. t1 = x / (ILdouble)Width;
  233. t2 = t1 * Width - (ILuint)(t1 * Width);
  234. f = (1.0 - cos(t2 * IL_PI)) * .5;
  235. NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
  236. NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
  237. for (c = 0; c < Scaled->Bpp; c++) {
  238. x1 = ShortPtr[NewX1 + c];
  239. x2 = ShortPtr[NewX2 + c];
  240. SShortPtr[NewX3 + c] = (ILushort)(x1 * (1.0 - f) + x2 * f);
  241. }
  242. NewX3 += Scaled->Bpp;
  243. }
  244. break;
  245. case 4:
  246. NewX3 = 0;
  247. for (x = 0; x < Width; x++) {
  248. t1 = x / (ILdouble)Width;
  249. t2 = t1 * Width - (ILuint)(t1 * Width);
  250. f = (1.0 - cos(t2 * IL_PI)) * .5;
  251. NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
  252. NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
  253. for (c = 0; c < Scaled->Bpp; c++) {
  254. x1 = IntPtr[NewX1 + c];
  255. x2 = IntPtr[NewX2 + c];
  256. SIntPtr[NewX3 + c] = (ILuint)(x1 * (1.0 - f) + x2 * f);
  257. }
  258. NewX3 += Scaled->Bpp;
  259. }
  260. break;
  261. }
  262. }
  263. return Scaled;
  264. }