il_manip.h
Upload User: wmy0603
Upload Date: 2022-05-02
Package Size: 1808k
Code Size: 5k
Development Platform:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. //
  3. // ImageLib Sources
  4. // Copyright (C) 2001-2002 by Denton Woods
  5. // Last modified: 05/25/2001 <--Y2K Compliant! =]
  6. //
  7. // Filename: src-IL/include/il_manip.h
  8. //
  9. // Description: Image manipulation
  10. //
  11. //-----------------------------------------------------------------------------
  12. #ifndef MANIP_H
  13. #define MANIP_H
  14. #ifdef _cplusplus
  15. extern "C" {
  16. #endif
  17. ILboolean ilFlipImage(void);
  18. ILboolean ilMirrorImage(void); //@JASON New routine created 03/28/2001
  19. //-----------------------------------------------
  20. // Overflow handler for float-to-half conversion;
  21. // generates a hardware floating-point overflow,
  22. // which may be trapped by the operating system.
  23. //-----------------------------------------------
  24. #ifndef NOINLINE
  25. #if defined(_MSC_VER)
  26. #pragma warning(push)
  27. #pragma warning(disable : 4756)  // Disables 'named type definition in parentheses' warning
  28. #endif
  29. INLINE ILfloat /*ILAPIENTRY*/ ilFloatToHalfOverflow() {
  30. ILfloat f = 1e10;
  31. ILint j;
  32. for (j = 0; j < 10; j++)
  33. f *= f; // this will overflow before
  34. // the for loop terminates
  35. return f;
  36. }
  37. #if defined(_MSC_VER)
  38. #pragma warning(pop)
  39. #endif
  40. //-----------------------------------------------------
  41. // Float-to-half conversion -- general case, including
  42. // zeroes, denormalized numbers and exponent overflows.
  43. //-----------------------------------------------------
  44. INLINE ILushort ILAPIENTRY ilFloatToHalf(ILuint i) {
  45. //
  46. // Our floating point number, f, is represented by the bit
  47. // pattern in integer i.  Disassemble that bit pattern into
  48. // the sign, s, the exponent, e, and the significand, m.
  49. // Shift s into the position where it will go in in the
  50. // resulting half number.
  51. // Adjust e, accounting for the different exponent bias
  52. // of float and half (127 versus 15).
  53. //
  54. register int s =  (i >> 16) & 0x00008000;
  55. register int e = ((i >> 23) & 0x000000ff) - (127 - 15);
  56. register int m =   i        & 0x007fffff;
  57. //
  58. // Now reassemble s, e and m into a half:
  59. //
  60. if (e <= 0)
  61. {
  62. if (e < -10)
  63. {
  64. //
  65. // E is less than -10.  The absolute value of f is
  66. // less than HALF_MIN (f may be a small normalized
  67. // float, a denormalized float or a zero).
  68. //
  69. // We convert f to a half zero.
  70. //
  71. return 0;
  72. }
  73. //
  74. // E is between -10 and 0.  F is a normalized float,
  75. // whose magnitude is less than HALF_NRM_MIN.
  76. //
  77. // We convert f to a denormalized half.
  78. // 
  79. m = (m | 0x00800000) >> (1 - e);
  80. //
  81. // Round to nearest, round "0.5" up.
  82. //
  83. // Rounding may cause the significand to overflow and make
  84. // our number normalized.  Because of the way a half's bits
  85. // are laid out, we don't have to treat this case separately;
  86. // the code below will handle it correctly.
  87. // 
  88. if (m &  0x00001000)
  89. m += 0x00002000;
  90. //
  91. // Assemble the half from s, e (zero) and m.
  92. //
  93. return s | (m >> 13);
  94. }
  95. else if (e == 0xff - (127 - 15))
  96. {
  97. if (m == 0)
  98. {
  99. //
  100. // F is an infinity; convert f to a half
  101. // infinity with the same sign as f.
  102. //
  103. return s | 0x7c00;
  104. }
  105. else
  106. {
  107. //
  108. // F is a NAN; we produce a half NAN that preserves
  109. // the sign bit and the 10 leftmost bits of the
  110. // significand of f, with one exception: If the 10
  111. // leftmost bits are all zero, the NAN would turn 
  112. // into an infinity, so we have to set at least one
  113. // bit in the significand.
  114. //
  115. m >>= 13;
  116. return s | 0x7c00 | m | (m == 0);
  117. }
  118. }
  119. else
  120. {
  121. //
  122. // E is greater than zero.  F is a normalized float.
  123. // We try to convert f to a normalized half.
  124. //
  125. //
  126. // Round to nearest, round "0.5" up
  127. //
  128. if (m &  0x00001000)
  129. {
  130. m += 0x00002000;
  131. if (m & 0x00800000)
  132. {
  133. m =  0; // overflow in significand,
  134. e += 1; // adjust exponent
  135. }
  136. }
  137. //
  138. // Handle exponent overflow
  139. //
  140. if (e > 30)
  141. {
  142. ilFloatToHalfOverflow(); // Cause a hardware floating point overflow;
  143. return s | 0x7c00; // if this returns, the half becomes an
  144. }    // infinity with the same sign as f.
  145. //
  146. // Assemble the half from s, e and m.
  147. //
  148. return s | (e << 10) | (m >> 13);
  149. }
  150. }
  151. // Taken from OpenEXR
  152. INLINE ILuint ILAPIENTRY ilHalfToFloat (ILushort y) {
  153. int s = (y >> 15) & 0x00000001;
  154. int e = (y >> 10) & 0x0000001f;
  155. int m =  y   & 0x000003ff;
  156. if (e == 0)
  157. {
  158. if (m == 0)
  159. {
  160. //
  161. // Plus or minus zero
  162. //
  163. return s << 31;
  164. }
  165. else
  166. {
  167. //
  168. // Denormalized number -- renormalize it
  169. //
  170. while (!(m & 0x00000400))
  171. {
  172. m <<= 1;
  173. e -=  1;
  174. }
  175. e += 1;
  176. m &= ~0x00000400;
  177. }
  178. }
  179. else if (e == 31)
  180. {
  181. if (m == 0)
  182. {
  183. //
  184. // Positive or negative infinity
  185. //
  186. return (s << 31) | 0x7f800000;
  187. }
  188. else
  189. {
  190. //
  191. // Nan -- preserve sign and significand bits
  192. //
  193. return (s << 31) | 0x7f800000 | (m << 13);
  194. }
  195. }
  196. //
  197. // Normalized number
  198. //
  199. e = e + (127 - 15);
  200. m = m << 13;
  201. //
  202. // Assemble s, e and m.
  203. //
  204. return (s << 31) | (e << 23) | m;
  205. }
  206. #endif //NOINLINE
  207. #ifdef _cplusplus
  208. }
  209. #endif
  210. #endif//MANIP_H