resize.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:40k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. ////////////////////////////////////////////////////////
  36. // include files
  37. ////////////////////////////////////////////////////////
  38. #include "hlxclib/stdlib.h"
  39. #include "hlxclib/string.h"
  40. #include "mmx_util.h"
  41. #include "resize.h"
  42. ////////////////////////////////////////////////////////
  43. // internal prototypes
  44. ////////////////////////////////////////////////////////
  45. static void
  46. interpolate_ii (
  47.     unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
  48.     unsigned char *src,  int src_width,  int src_height,  int src_pitch);
  49. static void
  50. decimate (
  51.     unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
  52.     unsigned char *src,  int src_width,  int src_height,  int src_pitch, 
  53. RESIZE_BUFF_TYPE *buff);
  54. #ifdef _M_IX86
  55. static void
  56. decimate_half_horiz_MMX (
  57.     unsigned char *dest, int dest_width, int dest_height,
  58.     unsigned char *src,  int src_width,  int src_height);
  59. #endif
  60. static void 
  61. decimate_half_horiz_accurate(
  62.     unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
  63.     unsigned char *src,  int src_width,  int src_height, int src_pitch);
  64. ////////////////////////////////////////////////////////
  65. // Select interpolation or decimation
  66. ////////////////////////////////////////////////////////
  67. void resize_plane(
  68.     unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
  69.     unsigned char *src,  int src_width,  int src_height,  int src_pitch,
  70. RESIZE_BUFF_TYPE *buff, int accuracy)
  71. {
  72. if ((dest_width > src_width) || (dest_height > src_height) || 
  73. (accuracy == 0) || (buff == NULL))
  74. {
  75. // interpolation
  76. interpolate_ii (dest,dest_width, dest_height, dest_pitch,
  77. src, src_width, src_height, src_pitch);
  78. }
  79. else
  80. {
  81. // decimation -- check for special case functions
  82. #ifdef _M_IX86
  83. if (((dest_width) == (src_width >> 1)) &&
  84. ((dest_height) == (src_height)) &&
  85. ((dest_pitch) == (dest_width)) &&
  86. ((src_pitch) == (src_width)) &&
  87.             (checkMmxAvailablity()&CPU_HAS_MMX) && (accuracy == 0))
  88. {
  89. decimate_half_horiz_MMX (
  90. dest,dest_width, dest_height,
  91. src, src_width, src_height);
  92. }
  93. else
  94. #endif
  95. if (((dest_width) == (src_width >> 1)) &&
  96. ((dest_height) == (src_height)))
  97. {
  98. decimate_half_horiz_accurate(
  99. dest,dest_width, dest_height, dest_pitch,
  100. src, src_width, src_height, src_pitch);
  101. }
  102. else
  103. {
  104. decimate (dest,dest_width, dest_height, dest_pitch,
  105. src, src_width, src_height, src_pitch, buff);
  106. }
  107. }
  108. }
  109. #if 1 // simpler filter
  110. #define FULL_PEL_INC 256
  111. #define INT_FILT_SIZE 1025
  112. #define INT_FILT_CENTER 512
  113. static const int int_filt_tab[INT_FILT_SIZE] = 
  114. {
  115. 0,
  116. -3, -5, -8, -11, -13, -16, -19, -21, -24, -27, -29, -32, -35, -37, -40, -43, -45, -48, -50, -53,
  117. -56, -58, -61, -63, -66, -69, -71, -74, -76, -79, -81, -84, -87, -89, -92, -94, -97, -99, -102, -104,
  118. -107, -109, -111, -114, -116, -119, -121, -124, -126, -128, -131, -133, -135, -138, -140, -142, -144, -147, -149, -151,
  119. -153, -156, -158, -160, -162, -164, -166, -169, -171, -173, -175, -177, -179, -181, -183, -185, -187, -189, -191, -193,
  120. -194, -196, -198, -200, -202, -203, -205, -207, -209, -210, -212, -214, -215, -217, -218, -220, -222, -223, -225, -226,
  121. -227, -229, -230, -232, -233, -234, -235, -237, -238, -239, -240, -242, -243, -244, -245, -246, -247, -248, -249, -250,
  122. -251, -251, -252, -253, -254, -255, -255, -256, -257, -257, -258, -258, -259, -259, -260, -260, -261, -261, -261, -262,
  123. -262, -262, -262, -263, -263, -263, -263, -263, -263, -263, -263, -262, -262, -262, -262, -262, -261, -261, -260, -260,
  124. -260, -259, -258, -258, -257, -257, -256, -255, -254, -253, -253, -252, -251, -250, -249, -248, -246, -245, -244, -243,
  125. -241, -240, -239, -237, -236, -234, -233, -231, -229, -228, -226, -224, -222, -220, -218, -216, -214, -212, -210, -208,
  126. -206, -203, -201, -199, -196, -194, -191, -189, -186, -183, -180, -178, -175, -172, -169, -166, -163, -160, -157, -153,
  127. -150, -147, -143, -140, -137, -133, -129, -126, -122, -118, -114, -111, -107, -103, -99, -94, -90, -86, -82, -78,
  128. -73, -69, -64, -60, -55, -50, -45, -41, -36, -31, -26, -21, -16, -11, -5, 0, 16, 32, 48, 64,
  129. 81, 97, 113, 130, 146, 163, 180, 196, 213, 230, 247, 264, 280, 297, 314, 332, 349, 366, 383, 400,
  130. 418, 435, 452, 470, 487, 505, 522, 540, 558, 575, 593, 611, 629, 646, 664, 682, 700, 718, 736, 754,
  131. 772, 790, 808, 827, 845, 863, 881, 899, 918, 936, 954, 973, 991, 1009, 1028, 1046, 1065, 1083, 1102, 1120,
  132. 1139, 1157, 1176, 1194, 1213, 1231, 1250, 1268, 1287, 1306, 1324, 1343, 1362, 1380, 1399, 1418, 1436, 1455, 1473, 1492,
  133. 1511, 1529, 1548, 1567, 1585, 1604, 1623, 1641, 1660, 1679, 1697, 1716, 1735, 1753, 1772, 1790, 1809, 1828, 1846, 1865,
  134. 1883, 1902, 1920, 1939, 1957, 1976, 1994, 2013, 2031, 2049, 2068, 2086, 2104, 2123, 2141, 2159, 2177, 2195, 2214, 2232,
  135. 2250, 2268, 2286, 2304, 2322, 2340, 2358, 2376, 2394, 2411, 2429, 2447, 2465, 2482, 2500, 2518, 2535, 2553, 2570, 2588,
  136. 2605, 2622, 2640, 2657, 2674, 2691, 2708, 2725, 2742, 2759, 2776, 2793, 2810, 2827, 2843, 2860, 2877, 2893, 2910, 2926,
  137. 2942, 2959, 2975, 2991, 3007, 3023, 3039, 3055, 3071, 3087, 3103, 3119, 3134, 3150, 3165, 3181, 3196, 3211, 3226, 3242,
  138. 3257, 3272, 3287, 3301, 3316, 3331, 3345, 3360, 3374, 3389, 3403, 3417, 3432, 3446, 3460, 3473, 3487, 3501, 3515, 3528,
  139. 3542, 3555, 3568, 3582, 3595, 3608, 3621, 3633, 3646, 3659, 3671, 3684, 3696, 3708, 3721, 3733, 3745, 3757, 3768, 3780,
  140. 3792, 3803, 3814, 3826, 3837, 3848, 3859, 3870, 3880, 3891, 3902, 3912, 3922, 3932, 3943, 3953, 3962, 3972, 3982, 3991,
  141. 4001, 4010, 4019, 4028, 4037, 4046, 4054, 4063, 4071, 4080, 4088, 4096, 4088, 4080, 4071, 4063, 4054, 4046, 4037, 4028,
  142. 4019, 4010, 4001, 3991, 3982, 3972, 3962, 3953, 3943, 3932, 3922, 3912, 3902, 3891, 3880, 3870, 3859, 3848, 3837, 3826,
  143. 3814, 3803, 3792, 3780, 3768, 3757, 3745, 3733, 3721, 3708, 3696, 3684, 3671, 3659, 3646, 3633, 3621, 3608, 3595, 3582,
  144. 3568, 3555, 3542, 3528, 3515, 3501, 3487, 3473, 3460, 3446, 3432, 3417, 3403, 3389, 3374, 3360, 3345, 3331, 3316, 3301,
  145. 3287, 3272, 3257, 3242, 3226, 3211, 3196, 3181, 3165, 3150, 3134, 3119, 3103, 3087, 3071, 3055, 3039, 3023, 3007, 2991,
  146. 2975, 2959, 2942, 2926, 2910, 2893, 2877, 2860, 2843, 2827, 2810, 2793, 2776, 2759, 2742, 2725, 2708, 2691, 2674, 2657,
  147. 2640, 2622, 2605, 2588, 2570, 2553, 2535, 2518, 2500, 2482, 2465, 2447, 2429, 2411, 2394, 2376, 2358, 2340, 2322, 2304,
  148. 2286, 2268, 2250, 2232, 2214, 2195, 2177, 2159, 2141, 2123, 2104, 2086, 2068, 2049, 2031, 2013, 1994, 1976, 1957, 1939,
  149. 1920, 1902, 1883, 1865, 1846, 1828, 1809, 1790, 1772, 1753, 1735, 1716, 1697, 1679, 1660, 1641, 1623, 1604, 1585, 1567,
  150. 1548, 1529, 1511, 1492, 1473, 1455, 1436, 1418, 1399, 1380, 1362, 1343, 1324, 1306, 1287, 1268, 1250, 1231, 1213, 1194,
  151. 1176, 1157, 1139, 1120, 1102, 1083, 1065, 1046, 1028, 1009, 991, 973, 954, 936, 918, 899, 881, 863, 845, 827,
  152. 808, 790, 772, 754, 736, 718, 700, 682, 664, 646, 629, 611, 593, 575, 558, 540, 522, 505, 487, 470,
  153. 452, 435, 418, 400, 383, 366, 349, 332, 314, 297, 280, 264, 247, 230, 213, 196, 180, 163, 146, 130,
  154. 113, 97, 81, 64, 48, 32, 16, 0, -5, -11, -16, -21, -26, -31, -36, -41, -45, -50, -55, -60,
  155. -64, -69, -73, -78, -82, -86, -90, -94, -99, -103, -107, -111, -114, -118, -122, -126, -129, -133, -137, -140,
  156. -143, -147, -150, -153, -157, -160, -163, -166, -169, -172, -175, -178, -180, -183, -186, -189, -191, -194, -196, -199,
  157. -201, -203, -206, -208, -210, -212, -214, -216, -218, -220, -222, -224, -226, -228, -229, -231, -233, -234, -236, -237,
  158. -239, -240, -241, -243, -244, -245, -246, -248, -249, -250, -251, -252, -253, -253, -254, -255, -256, -257, -257, -258,
  159. -258, -259, -260, -260, -260, -261, -261, -262, -262, -262, -262, -262, -263, -263, -263, -263, -263, -263, -263, -263,
  160. -262, -262, -262, -262, -261, -261, -261, -260, -260, -259, -259, -258, -258, -257, -257, -256, -255, -255, -254, -253,
  161. -252, -251, -251, -250, -249, -248, -247, -246, -245, -244, -243, -242, -240, -239, -238, -237, -235, -234, -233, -232,
  162. -230, -229, -227, -226, -225, -223, -222, -220, -218, -217, -215, -214, -212, -210, -209, -207, -205, -203, -202, -200,
  163. -198, -196, -194, -193, -191, -189, -187, -185, -183, -181, -179, -177, -175, -173, -171, -169, -166, -164, -162, -160,
  164. -158, -156, -153, -151, -149, -147, -144, -142, -140, -138, -135, -133, -131, -128, -126, -124, -121, -119, -116, -114,
  165. -111, -109, -107, -104, -102, -99, -97, -94, -92, -89, -87, -84, -81, -79, -76, -74, -71, -69, -66, -63,
  166. -61, -58, -56, -53, -50, -48, -45, -43, -40, -37, -35, -32, -29, -27, -24, -21, -19, -16, -13, -11,
  167. -8, -5, -3, 0
  168. };
  169. #else  // complex filter
  170. #define FULL_PEL_INC 128
  171. #define INT_FILT_SIZE 1025
  172. #define INT_FILT_CENTER 512
  173. static const int int_filt_tab[INT_FILT_SIZE] = 
  174. {
  175. 0,
  176. 0, 0, -1, -1, -1, -1, -2, -2, -2, -2, -2, -3, -3, -3, -3, -4, -4, -4, -4, -4,
  177. -5, -5, -5, -5, -5, -6, -6, -6, -6, -6, -7, -7, -7, -7, -7, -7, -8, -8, -8, -8,
  178. -8, -8, -8, -8, -9, -9, -9, -9, -9, -9, -9, -9, -9, -10, -10, -10, -10, -10, -10, -10,
  179. -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
  180. -10, -9, -9, -9, -9, -9, -9, -9, -9, -9, -8, -8, -8, -8, -8, -8, -8, -7, -7, -7,
  181. -7, -7, -6, -6, -6, -6, -6, -5, -5, -5, -5, -4, -4, -4, -4, -3, -3, -3, -3, -2,
  182. -2, -2, -1, -1, -1, -1, 0, 0, 2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 23, 25,
  183. 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 51, 53, 55, 57, 59, 61, 62, 64,
  184. 66, 67, 69, 70, 72, 74, 75, 76, 78, 79, 81, 82, 83, 84, 85, 87, 88, 89, 90, 91,
  185. 91, 92, 93, 94, 95, 95, 96, 96, 97, 97, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99,
  186. 99, 98, 98, 98, 97, 97, 96, 96, 95, 94, 94, 93, 92, 91, 90, 89, 88, 87, 85, 84,
  187. 83, 81, 80, 78, 77, 75, 73, 71, 70, 68, 66, 64, 62, 60, 57, 55, 53, 51, 48, 46,
  188. 43, 41, 38, 35, 33, 30, 27, 24, 21, 18, 16, 12, 9, 6, 3, 0, -10, -19, -29, -39,
  189. -48, -58, -68, -78, -87, -97, -107, -117, -126, -136, -146, -155, -165, -175, -184, -194, -203, -212, -222, -231,
  190. -240, -249, -258, -267, -276, -285, -293, -302, -310, -318, -326, -335, -342, -350, -358, -365, -373, -380, -387, -394,
  191. -400, -407, -413, -420, -425, -431, -437, -442, -447, -452, -457, -462, -466, -470, -474, -478, -481, -484, -487, -490,
  192. -492, -495, -496, -498, -500, -501, -501, -502, -502, -502, -502, -501, -500, -499, -498, -496, -494, -491, -488, -485,
  193. -482, -478, -474, -470, -465, -460, -455, -449, -443, -436, -429, -422, -415, -407, -399, -390, -381, -372, -362, -352,
  194. -342, -331, -320, -309, -297, -285, -272, -259, -246, -232, -218, -203, -188, -173, -158, -142, -125, -108, -91, -74,
  195. -56, -38, -19, 0, 32, 65, 98, 131, 165, 198, 233, 267, 302, 338, 373, 409, 445, 481, 518, 555,
  196. 592, 629, 667, 705, 743, 781, 820, 858, 897, 936, 975, 1015, 1054, 1094, 1133, 1173, 1213, 1253, 1293, 1333,
  197. 1374, 1414, 1454, 1495, 1535, 1575, 1616, 1656, 1697, 1737, 1778, 1818, 1858, 1898, 1939, 1979, 2019, 2059, 2098, 2138,
  198. 2178, 2217, 2256, 2295, 2334, 2373, 2412, 2450, 2488, 2526, 2564, 2601, 2639, 2676, 2712, 2749, 2785, 2821, 2857, 2892,
  199. 2927, 2961, 2996, 3030, 3063, 3097, 3129, 3162, 3194, 3226, 3257, 3288, 3318, 3348, 3378, 3407, 3436, 3464, 3492, 3519,
  200. 3546, 3572, 3598, 3623, 3648, 3672, 3696, 3719, 3742, 3764, 3785, 3806, 3826, 3846, 3865, 3884, 3902, 3919, 3936, 3952,
  201. 3968, 3983, 3997, 4011, 4024, 4036, 4048, 4059, 4069, 4079, 4088, 4096, 4088, 4079, 4069, 4059, 4048, 4036, 4024, 4011,
  202. 3997, 3983, 3968, 3952, 3936, 3919, 3902, 3884, 3865, 3846, 3826, 3806, 3785, 3764, 3742, 3719, 3696, 3672, 3648, 3623,
  203. 3598, 3572, 3546, 3519, 3492, 3464, 3436, 3407, 3378, 3348, 3318, 3288, 3257, 3226, 3194, 3162, 3129, 3097, 3063, 3030,
  204. 2996, 2961, 2927, 2892, 2857, 2821, 2785, 2749, 2712, 2676, 2639, 2601, 2564, 2526, 2488, 2450, 2412, 2373, 2334, 2295,
  205. 2256, 2217, 2178, 2138, 2098, 2059, 2019, 1979, 1939, 1898, 1858, 1818, 1778, 1737, 1697, 1656, 1616, 1575, 1535, 1495,
  206. 1454, 1414, 1374, 1333, 1293, 1253, 1213, 1173, 1133, 1094, 1054, 1015, 975, 936, 897, 858, 820, 781, 743, 705,
  207. 667, 629, 592, 555, 518, 481, 445, 409, 373, 338, 302, 267, 233, 198, 165, 131, 98, 65, 32, 0,
  208. -19, -38, -56, -74, -91, -108, -125, -142, -158, -173, -188, -203, -218, -232, -246, -259, -272, -285, -297, -309,
  209. -320, -331, -342, -352, -362, -372, -381, -390, -399, -407, -415, -422, -429, -436, -443, -449, -455, -460, -465, -470,
  210. -474, -478, -482, -485, -488, -491, -494, -496, -498, -499, -500, -501, -502, -502, -502, -502, -501, -501, -500, -498,
  211. -496, -495, -492, -490, -487, -484, -481, -478, -474, -470, -466, -462, -457, -452, -447, -442, -437, -431, -425, -420,
  212. -413, -407, -400, -394, -387, -380, -373, -365, -358, -350, -342, -335, -326, -318, -310, -302, -293, -285, -276, -267,
  213. -258, -249, -240, -231, -222, -212, -203, -194, -184, -175, -165, -155, -146, -136, -126, -117, -107, -97, -87, -78,
  214. -68, -58, -48, -39, -29, -19, -10, 0, 3, 6, 9, 12, 16, 18, 21, 24, 27, 30, 33, 35,
  215. 38, 41, 43, 46, 48, 51, 53, 55, 57, 60, 62, 64, 66, 68, 70, 71, 73, 75, 77, 78,
  216. 80, 81, 83, 84, 85, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 96, 97, 97, 98,
  217. 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 98, 98, 98, 97, 97, 96, 96, 95, 95, 94,
  218. 93, 92, 91, 91, 90, 89, 88, 87, 85, 84, 83, 82, 81, 79, 78, 76, 75, 74, 72, 70,
  219. 69, 67, 66, 64, 62, 61, 59, 57, 55, 53, 51, 50, 48, 46, 44, 42, 40, 38, 36, 34,
  220. 32, 30, 28, 25, 23, 21, 19, 17, 15, 13, 11, 9, 6, 4, 2, 0, 0, -1, -1, -1,
  221. -1, -2, -2, -2, -3, -3, -3, -3, -4, -4, -4, -4, -5, -5, -5, -5, -6, -6, -6, -6,
  222. -6, -7, -7, -7, -7, -7, -8, -8, -8, -8, -8, -8, -8, -9, -9, -9, -9, -9, -9, -9,
  223. -9, -9, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
  224. -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -9, -9, -9, -9, -9, -9, -9, -9, -9, -8,
  225. -8, -8, -8, -8, -8, -8, -8, -7, -7, -7, -7, -7, -7, -6, -6, -6, -6, -6, -5, -5,
  226. -5, -5, -5, -4, -4, -4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -2, -1, -1, -1,
  227. -1, 0, 0, 0
  228. };
  229. #endif
  230. // Clipping table
  231. #define CLAMP_BIAS  128 // Bias in clamping table 
  232. #define CLIP_RANGE (CLAMP_BIAS + 256 + CLAMP_BIAS)
  233. const unsigned char ClampTbl[CLIP_RANGE] = { /* Flawfinder: ignore */
  234.              0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  235.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  236.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  237.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  238.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  239.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  240.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  241.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  242.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  243.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  244.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  245.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  246.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  247.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  248.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  249.             ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
  250.             ,0x00 ,0x01 ,0x02 ,0x03 ,0x04 ,0x05 ,0x06 ,0x07 
  251.             ,0x08 ,0x09 ,0x0a ,0x0b ,0x0c ,0x0d ,0x0e ,0x0f 
  252.             ,0x10 ,0x11 ,0x12 ,0x13 ,0x14 ,0x15 ,0x16 ,0x17 
  253.             ,0x18 ,0x19 ,0x1a ,0x1b ,0x1c ,0x1d ,0x1e ,0x1f 
  254.             ,0x20 ,0x21 ,0x22 ,0x23 ,0x24 ,0x25 ,0x26 ,0x27 
  255.             ,0x28 ,0x29 ,0x2a ,0x2b ,0x2c ,0x2d ,0x2e ,0x2f 
  256.             ,0x30 ,0x31 ,0x32 ,0x33 ,0x34 ,0x35 ,0x36 ,0x37 
  257.             ,0x38 ,0x39 ,0x3a ,0x3b ,0x3c ,0x3d ,0x3e ,0x3f 
  258.             ,0x40 ,0x41 ,0x42 ,0x43 ,0x44 ,0x45 ,0x46 ,0x47 
  259.             ,0x48 ,0x49 ,0x4a ,0x4b ,0x4c ,0x4d ,0x4e ,0x4f 
  260.             ,0x50 ,0x51 ,0x52 ,0x53 ,0x54 ,0x55 ,0x56 ,0x57 
  261.             ,0x58 ,0x59 ,0x5a ,0x5b ,0x5c ,0x5d ,0x5e ,0x5f 
  262.             ,0x60 ,0x61 ,0x62 ,0x63 ,0x64 ,0x65 ,0x66 ,0x67 
  263.             ,0x68 ,0x69 ,0x6a ,0x6b ,0x6c ,0x6d ,0x6e ,0x6f 
  264.             ,0x70 ,0x71 ,0x72 ,0x73 ,0x74 ,0x75 ,0x76 ,0x77 
  265.             ,0x78 ,0x79 ,0x7a ,0x7b ,0x7c ,0x7d ,0x7e ,0x7f 
  266.             ,0x80 ,0x81 ,0x82 ,0x83 ,0x84 ,0x85 ,0x86 ,0x87 
  267.             ,0x88 ,0x89 ,0x8a ,0x8b ,0x8c ,0x8d ,0x8e ,0x8f 
  268.             ,0x90 ,0x91 ,0x92 ,0x93 ,0x94 ,0x95 ,0x96 ,0x97 
  269.             ,0x98 ,0x99 ,0x9a ,0x9b ,0x9c ,0x9d ,0x9e ,0x9f 
  270.             ,0xa0 ,0xa1 ,0xa2 ,0xa3 ,0xa4 ,0xa5 ,0xa6 ,0xa7 
  271.             ,0xa8 ,0xa9 ,0xaa ,0xab ,0xac ,0xad ,0xae ,0xaf 
  272.             ,0xb0 ,0xb1 ,0xb2 ,0xb3 ,0xb4 ,0xb5 ,0xb6 ,0xb7 
  273.             ,0xb8 ,0xb9 ,0xba ,0xbb ,0xbc ,0xbd ,0xbe ,0xbf 
  274.             ,0xc0 ,0xc1 ,0xc2 ,0xc3 ,0xc4 ,0xc5 ,0xc6 ,0xc7 
  275.             ,0xc8 ,0xc9 ,0xca ,0xcb ,0xcc ,0xcd ,0xce ,0xcf 
  276.             ,0xd0 ,0xd1 ,0xd2 ,0xd3 ,0xd4 ,0xd5 ,0xd6 ,0xd7 
  277.             ,0xd8 ,0xd9 ,0xda ,0xdb ,0xdc ,0xdd ,0xde ,0xdf 
  278.             ,0xe0 ,0xe1 ,0xe2 ,0xe3 ,0xe4 ,0xe5 ,0xe6 ,0xe7 
  279.             ,0xe8 ,0xe9 ,0xea ,0xeb ,0xec ,0xed ,0xee ,0xef 
  280.             ,0xf0 ,0xf1 ,0xf2 ,0xf3 ,0xf4 ,0xf5 ,0xf6 ,0xf7 
  281.             ,0xf8 ,0xf9 ,0xfa ,0xfb ,0xfc ,0xfd ,0xfe ,0xff 
  282.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  283.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  284.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  285.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  286.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  287.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  288.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  289.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  290.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  291.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  292.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  293.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  294.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  295.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  296.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  297.             ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff 
  298.    };
  299. #ifdef CLIP_PEL
  300. #undef CLIP_PEL
  301. #endif
  302. #define CLIP_PEL(p) (ClampTbl[ (p) + CLAMP_BIAS ])
  303. #define POS_SCALE_BITS 16
  304. #define FILT_COEFF_BITS 12
  305. #define FILT_SCALE_BITS 8
  306. #define USE_SOURCE_LEVEL 1
  307. ////////////////////////////////////////////////////////
  308. //
  309. // Performs fast half horizontal w/ MMX
  310. // Greg Conklin - 9/21/99
  311. //
  312. ////////////////////////////////////////////////////////
  313. #ifdef _M_IX86
  314. static void
  315. decimate_half_horiz_MMX (
  316.     unsigned char *dest, int dest_width, int dest_height,
  317.     unsigned char *src,  int src_width,  int src_height)
  318. {
  319. unsigned char word_mask[8] = {0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00}; /* Flawfinder: ignore */
  320. int num_itrs;
  321. // must be doing half horizontal resolution
  322. if (((dest_width) != (src_width >> 1)) ||
  323. ((dest_height) != (src_height)))
  324. return;
  325. num_itrs = ((dest_height*dest_width) >> 3);
  326. __asm {
  327. mov ecx, num_itrs
  328. mov esi, src // esi -> source frame
  329. mov edi, dest // edi -> destination frame
  330. movq mm7, [word_mask] // mm7 holds the bytes->words mask
  331. ALIGN 16
  332. pel_loop:
  333. movq mm0, [esi]
  334. movq mm1, mm0
  335. psrlw mm1, 8
  336. pand mm0, mm7
  337. paddw mm0, mm1
  338. psrlw mm0, 1
  339. lea esi, [esi+8]
  340. movq mm1, [esi]
  341. movq mm2, mm1
  342. psrlw mm2, 8
  343. pand mm1, mm7
  344. paddw mm1, mm2
  345. psrlw mm1, 1
  346. lea esi, [esi+8]
  347. packuswb mm0, mm1
  348. movq [edi], mm0
  349. lea edi, [edi+8]
  350. dec ecx
  351. jnz pel_loop
  352. emms
  353. }
  354. }
  355. #endif
  356. ////////////////////////////////////////////////////////
  357. //
  358. // Performs fast and accurate half horizontal
  359. // Greg Conklin - 9/05/00
  360. //
  361. ////////////////////////////////////////////////////////
  362. static void 
  363. decimate_half_horiz_accurate(
  364.     unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
  365.     unsigned char *src,  int src_width,  int src_height, int src_pitch)
  366. {
  367. unsigned char *dd;
  368. unsigned char *ss;
  369. unsigned char *src_end;
  370. unsigned char *line_end;
  371. int dest_skip;
  372. int src_skip;
  373. int a,b,c,d;
  374. dd = dest;
  375. ss = src;
  376. dest_skip = dest_pitch - dest_width + 1;
  377. src_skip = src_pitch - src_width + 2;
  378. src_end = src + src_width * src_height;
  379. while (ss < src_end)
  380. {
  381. line_end = ss + src_width - 2;
  382. a = ss[0];
  383. b = a;
  384. c = ss[1];
  385. d = ss[2];
  386. b += c;
  387. a += d;
  388. b *= 9;
  389. b -= a;
  390. b += 7;
  391. b >>= 4;
  392. dd[0] = CLIP_PEL(b);
  393. ss += 2;
  394. dd ++;
  395. while (ss < line_end)
  396. {
  397. a = c;
  398. b = d;
  399. c = ss[1];
  400. d = ss[2];
  401. b += c;
  402. a += d;
  403. b *= 9;
  404. b -= a;
  405. b += 7;
  406. b >>= 4;
  407. dd[0] = CLIP_PEL(b);
  408. ss += 2;
  409. dd ++;
  410. }
  411. a = c;
  412. b = d;
  413. c = ss[1];
  414. d = c;
  415. b += c;
  416. a += d;
  417. b *= 9;
  418. b -= a;
  419. b += 7;
  420. b >>= 4;
  421. dd[0] = CLIP_PEL(b);
  422. ss += src_skip;
  423. dd += dest_skip;
  424. }
  425. }
  426. ////////////////////////////////////////////////////////
  427. //
  428. // Performs accurate decimation
  429. // Greg Conklin - 9/21/99
  430. //
  431. ////////////////////////////////////////////////////////
  432. static void
  433. decimate (
  434.     unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
  435.     unsigned char *src,  int src_width,  int src_height,  int src_pitch, 
  436. RESIZE_BUFF_TYPE *buff)
  437. {
  438. unsigned char *sp, *dp;
  439. RESIZE_BUFF_TYPE *tp;
  440. int pel; // destination x position
  441. int line; // destination y position
  442. int tmp; // temp storage for result pel
  443. int pos; // fractional position of source (x or y) location
  444. int pos_int; // integer position of source
  445. int pos_bgn; // the starting location of pos
  446. int pos_inc; // the increment of 'pos' to the next pel
  447. const int *filt_tab_ptr; // pointer to the current filter tap
  448. int filt_tab_inc; // spacing between tabs in the filter table
  449. int filt_tap_num; // number of filter taps
  450. int filt_scale; // filter gain 
  451. #if USE_SOURCE_LEVEL
  452. int source_level;
  453. #else
  454. #define source_level 0
  455. #endif
  456. if (dest_height == src_height)
  457. {
  458. // no vertical resizing
  459. for (line = 0; line < src_height; line++)
  460. {
  461. tp = buff + line * src_pitch;
  462. sp = src + line * src_pitch;
  463. for (pel = 0; pel < src_width - 3; pel += 4)
  464. {
  465. tp[0] = sp[0];
  466. tp[1] = sp[1];
  467. tp[2] = sp[2];
  468. tp[3] = sp[3];
  469. tp += 4;
  470. sp += 4;
  471. }
  472. for (; pel < dest_width; pel++)
  473. {
  474. *tp = *sp;
  475. tp ++;
  476. sp ++;
  477. }
  478. }
  479. }
  480. else if (dest_height == (src_height >> 1))
  481. {
  482. // decimate vertical by 2
  483. int src_skip = src_pitch - src_width;
  484. int a, b, c, d;
  485. tp = buff;
  486. sp = src;
  487. // top line
  488. for (pel = 0; pel < src_width; pel ++)
  489. {
  490. b = *sp;
  491. c = *(sp + src_pitch);
  492. d = *(sp + 2 * src_pitch);
  493. c += b;
  494. b += d;
  495. c *= 9;
  496. c -= b;
  497. c += 7;
  498. c >>= 4;
  499. *tp = CLIP_PEL(c);
  500. sp++;
  501. tp++;
  502. }
  503. tp += src_skip;
  504. sp += src_skip + src_pitch;
  505. // middle lines
  506. for (line = 2; line < dest_height; line ++)
  507. {
  508. for (pel = 0; pel < src_width; pel++)
  509. {
  510. a = *(sp - src_pitch);
  511. b = *sp;
  512. c = *(sp + src_pitch);
  513. d = *(sp + 2 * src_pitch);
  514. b += c;
  515. a += d;
  516. b *= 9;
  517. b -= a;
  518. b += 7;
  519. b >>= 4;
  520. *tp = CLIP_PEL(b);
  521. sp++;
  522. tp++;
  523. }
  524. tp += src_skip;
  525. sp += src_skip + src_pitch;
  526. }
  527. // bottom line
  528. for (pel = 0; pel < src_width; pel++)
  529. {
  530. a = *(sp - src_pitch);
  531. b = *sp;
  532. c = *(sp + src_pitch);
  533. b += c;
  534. a += c;
  535. b *= 9;
  536. b -= a;
  537. b += 7;
  538. b >>= 4;
  539. *tp = CLIP_PEL(b);
  540. sp++;
  541. tp++;
  542. }
  543. }
  544. else
  545. {
  546. // arbitrary vertical resize
  547. pos_inc = ((src_height << POS_SCALE_BITS) + (dest_height >> 1)) / (dest_height);
  548. pos_bgn = (pos_inc - (1 << POS_SCALE_BITS)) >> 1;
  549. filt_tab_inc = (FULL_PEL_INC * dest_height + (src_height >> 1)) / (src_height);
  550. if (filt_tab_inc > FULL_PEL_INC)
  551. filt_tab_inc = FULL_PEL_INC;
  552. filt_tap_num = (INT_FILT_SIZE - 1) / (filt_tab_inc << 1);
  553. filt_scale = ((dest_height << FILT_SCALE_BITS) + (src_height >> 1)) / (src_height);
  554. for (pel = 0; pel < src_width; pel++)
  555. {
  556. tp = buff + pel;
  557. line = 0;
  558. pos = pos_bgn;
  559. pos_int = pos >> POS_SCALE_BITS;
  560. // Top edge pels
  561. while (pos_int < filt_tap_num)
  562. {
  563. sp = src + (pos_int) * src_pitch + pel;
  564. #if USE_SOURCE_LEVEL
  565. source_level = *sp;
  566. #endif
  567. sp -= filt_tap_num * src_pitch;
  568. filt_tab_ptr = int_filt_tab;
  569. filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
  570. filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
  571. if (filt_tab_ptr < int_filt_tab)
  572. {
  573. sp += src_pitch;
  574. filt_tab_ptr += filt_tab_inc;
  575. }
  576. tmp = 0;
  577. while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
  578. {
  579. if (sp < src)
  580. tmp += (*filt_tab_ptr) * (src[pel] - source_level);
  581. else
  582. tmp += (*filt_tab_ptr) * (*sp - source_level);
  583. sp += src_pitch;;
  584. filt_tab_ptr += filt_tab_inc;
  585. }
  586. tmp *= filt_scale;
  587. tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
  588. tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
  589. tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
  590. *tp = tmp;
  591. tp += src_pitch;
  592. pos += pos_inc;
  593. pos_int = pos >> POS_SCALE_BITS;
  594. line++;
  595. }
  596. // Center pels
  597. while (pos_int < src_height - filt_tap_num - 1)
  598. {
  599. sp = src + (pos_int) * src_pitch + pel;
  600. #if USE_SOURCE_LEVEL
  601. source_level = *sp;
  602. #endif
  603. sp -= filt_tap_num * src_pitch;
  604. filt_tab_ptr = int_filt_tab;
  605. filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
  606. filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
  607. if (filt_tab_ptr < int_filt_tab)
  608. {
  609. sp += src_pitch;
  610. filt_tab_ptr += filt_tab_inc;
  611. }
  612. // There are at least 4 taps...
  613. tmp = (*filt_tab_ptr) * (*sp - source_level);
  614. sp += src_pitch;
  615. filt_tab_ptr += filt_tab_inc;
  616. tmp += (*filt_tab_ptr) * (*sp - source_level);
  617. sp += src_pitch;
  618. filt_tab_ptr += filt_tab_inc;
  619. tmp += (*filt_tab_ptr) * (*sp - source_level);
  620. sp += src_pitch;
  621. filt_tab_ptr += filt_tab_inc;
  622. tmp += (*filt_tab_ptr) * (*sp - source_level);
  623. sp += src_pitch;
  624. filt_tab_ptr += filt_tab_inc;
  625. // Remaining taps...
  626. while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
  627. {
  628. tmp += (*filt_tab_ptr) * (*sp - source_level);
  629. sp += src_pitch;
  630. filt_tab_ptr += filt_tab_inc;
  631. }
  632. // scale and store result...
  633. tmp *= filt_scale;
  634. tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
  635. tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
  636. tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
  637. *tp = tmp;
  638. tp += src_pitch;
  639. pos += pos_inc;
  640. pos_int = pos >> POS_SCALE_BITS;
  641. line++;
  642. }
  643. // Bottom edge pels
  644. while (line < dest_height)
  645. {
  646. sp = src + (pos_int) * src_pitch + pel;
  647. #if USE_SOURCE_LEVEL
  648. source_level = *sp;
  649. #endif
  650. sp -= filt_tap_num * src_pitch;
  651. filt_tab_ptr = int_filt_tab;
  652. filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
  653. filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
  654. if (filt_tab_ptr < int_filt_tab)
  655. {
  656. sp += src_pitch;
  657. filt_tab_ptr += filt_tab_inc;
  658. }
  659. tmp = 0;
  660. while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
  661. {
  662. if (sp >= src + src_height*src_pitch)
  663. tmp += (*filt_tab_ptr) * (src[(src_height - 1) * src_pitch + pel] - source_level);
  664. else
  665. tmp += (*filt_tab_ptr) * (*sp - source_level);
  666. sp += src_pitch;
  667. filt_tab_ptr += filt_tab_inc;
  668. }
  669. tmp *= filt_scale;
  670. tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
  671. tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
  672. tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
  673. *tp = tmp;
  674. tp += src_pitch;
  675. pos += pos_inc;
  676. pos_int = pos >> POS_SCALE_BITS;
  677. line++;
  678. }
  679. }
  680. }
  681. if (dest_width == src_width)
  682. {
  683. // no horizontal resizing
  684. for (line = 0; line < dest_height; line++)
  685. {
  686. tp = buff + line * src_pitch;
  687. dp = dest + line * dest_pitch;
  688. for (pel = 0; pel < dest_width - 3; pel += 4)
  689. {
  690. dp[0] = CLIP_PEL(tp[0]);
  691. dp[1] = CLIP_PEL(tp[1]);
  692. dp[2] = CLIP_PEL(tp[2]);
  693. dp[3] = CLIP_PEL(tp[3]);
  694. dp += 4;
  695. tp += 4;
  696. }
  697. for (; pel < dest_width; pel++)
  698. {
  699. *dp = CLIP_PEL(*tp);
  700. dp ++;
  701. tp ++;
  702. }
  703. }
  704. }
  705. else if (dest_width == (src_width >> 1))
  706. {
  707. // decimate horizontally by 2
  708. int src_skip = src_pitch - src_width + 2;
  709. int dest_skip = dest_pitch - dest_width + 1;
  710. int a, b, c, d;
  711. tp = buff;
  712. dp = dest;
  713. for (line = 0; line < dest_height; line ++)
  714. {
  715. a = tp[0];
  716. b = a;
  717. c = tp[1];
  718. d = tp[2];
  719. b += c;
  720. a += d;
  721. b *= 9;
  722. b -= a;
  723. b += 7;
  724. b >>= 4;
  725. *dp = CLIP_PEL(b);
  726. tp += 2;
  727. dp ++;
  728. for (pel = 1; pel < dest_width - 1; pel++)
  729. {
  730. a = c;
  731. b = d;
  732. c = tp[1];
  733. d = tp[2];
  734. b += c;
  735. a += d;
  736. b *= 9;
  737. b -= a;
  738. b += 7;
  739. b >>= 4;
  740. *dp = CLIP_PEL(b);
  741. tp += 2;
  742. dp ++;
  743. }
  744. a = c;
  745. b = d;
  746. c = tp[1];
  747. d = c;
  748. b += c;
  749. a += d;
  750. b *= 9;
  751. b -= a;
  752. b += 7;
  753. b >>= 4;
  754. *dp = CLIP_PEL(b);
  755. tp += src_skip;
  756. dp += dest_skip;
  757. }
  758. }
  759. else
  760. {
  761. // horizonal filtering
  762. pos_inc = ((src_width << POS_SCALE_BITS) + (dest_width >> 1)) / (dest_width);
  763. pos_bgn = (pos_inc - (1 << POS_SCALE_BITS)) >> 1;
  764. filt_tab_inc = (FULL_PEL_INC * dest_width + (src_width >> 1)) / (src_width);
  765. if (filt_tab_inc > FULL_PEL_INC)
  766. filt_tab_inc = FULL_PEL_INC;
  767. filt_tap_num = (INT_FILT_SIZE - 1) / (filt_tab_inc << 1);
  768. filt_scale = ((dest_width << FILT_SCALE_BITS) + (src_width >> 1)) / (src_width);
  769. for (line = 0; line < dest_height; line++)
  770. {
  771. dp = dest + line * dest_pitch;
  772. pel = 0;
  773. pos = pos_bgn;
  774. pos_int = pos >> POS_SCALE_BITS;
  775. // Left edge pels
  776. while (pos_int < filt_tap_num)
  777. {
  778. tp = buff + line * src_pitch + pos_int;
  779. #if USE_SOURCE_LEVEL
  780. source_level = *tp;
  781. #endif
  782. tp -= filt_tap_num;
  783. filt_tab_ptr = int_filt_tab;
  784. filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
  785. filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
  786. if (filt_tab_ptr < int_filt_tab)
  787. {
  788. tp ++;
  789. filt_tab_ptr += filt_tab_inc;
  790. }
  791. tmp = 0;
  792. while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
  793. {
  794. if (tp < buff)
  795. tmp += (*filt_tab_ptr) * (buff[line * src_pitch] - source_level);
  796. else
  797. tmp += (*filt_tab_ptr) * (*tp - source_level);
  798. tp++;
  799. filt_tab_ptr += filt_tab_inc;
  800. }
  801. tmp *= filt_scale;
  802. tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
  803. tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
  804. tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
  805. *dp = CLIP_PEL(tmp);
  806. dp++;
  807. pos += pos_inc;
  808. pos_int = pos >> POS_SCALE_BITS;
  809. pel++;
  810. }
  811. // Center pels
  812. while (pos_int < src_width - filt_tap_num - 1)
  813. {
  814. tp = buff + line * src_pitch + pos_int;
  815. #if USE_SOURCE_LEVEL
  816. source_level = *tp;
  817. #endif
  818. tp -= filt_tap_num;
  819. filt_tab_ptr = int_filt_tab;
  820. filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
  821. filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
  822. if (filt_tab_ptr < int_filt_tab)
  823. {
  824. tp ++;
  825. filt_tab_ptr += filt_tab_inc;
  826. }
  827. // There are at least 4 taps...
  828. tmp = (*filt_tab_ptr) * (tp[0] - source_level);
  829. filt_tab_ptr += filt_tab_inc;
  830. tmp += (*filt_tab_ptr) * (tp[1] - source_level);
  831. filt_tab_ptr += filt_tab_inc;
  832. tmp += (*filt_tab_ptr) * (tp[2] - source_level);
  833. filt_tab_ptr += filt_tab_inc;
  834. tmp += (*filt_tab_ptr) * (tp[3] - source_level);
  835. filt_tab_ptr += filt_tab_inc;
  836. tp += 4;
  837. // Remaining taps...
  838. while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
  839. {
  840. tmp += (*filt_tab_ptr) * (*tp - source_level);
  841. tp++;
  842. filt_tab_ptr += filt_tab_inc;
  843. }
  844. tmp *= filt_scale;
  845. tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
  846. tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
  847. tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
  848. *dp = CLIP_PEL(tmp);
  849. dp++;
  850. pos += pos_inc;
  851. pos_int = pos >> POS_SCALE_BITS;
  852. pel++;
  853. }
  854. // Right edge pels
  855. while (pel < dest_width)
  856. {
  857. tp = buff + line * src_pitch + pos_int;
  858. #if USE_SOURCE_LEVEL
  859. source_level = *tp;
  860. #endif
  861. tp -= filt_tap_num;
  862. filt_tab_ptr = int_filt_tab;
  863. filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
  864. filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
  865. if (filt_tab_ptr < int_filt_tab)
  866. {
  867. tp ++;
  868. filt_tab_ptr += filt_tab_inc;
  869. }
  870. tmp = 0;
  871. while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
  872. {
  873. if (tp >= buff + line * src_pitch + src_width)
  874. tmp += (*filt_tab_ptr) * (buff[line * src_pitch + src_width - 1] - source_level);
  875. else
  876. tmp += (*filt_tab_ptr) * (*tp - source_level);
  877. tp++;
  878. filt_tab_ptr += filt_tab_inc;
  879. }
  880. tmp *= filt_scale;
  881. tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
  882. tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
  883. tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
  884. *dp = CLIP_PEL(tmp);
  885. dp++;
  886. pos += pos_inc;
  887. pos_int = pos >> POS_SCALE_BITS;
  888. pel++;
  889. }
  890. }
  891. }
  892. }
  893. /* 12-19-98 02:36am, written by Yuriy A. Reznik, yreznik@real.com */
  894. #define TOTAL_SCALE_BITS    16  /* precision of inverse coordinate mapping */
  895. #define COEF_SCALE_BITS     3   /* actual grid used to select scale coeffs */
  896. /*
  897.  * Interpolate image.
  898.  * Use:
  899.  *  void interpolate_x (
  900.  *       unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
  901.  *       unsigned char *src,  int src_width,  int src_height,  int src_pitch);
  902.  */
  903. static void  /** G2H263Codec:: NEVER make this function a class method!!!! */
  904. interpolate_ii (
  905.     unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
  906.     unsigned char *src,  int src_width,  int src_height,  int src_pitch)
  907. {
  908.     /* scaled row/column counters, limits, & increment values: */
  909.     int src_x, src_y;
  910.     int src_x_inc = ((src_width << TOTAL_SCALE_BITS) + dest_width / 2) / dest_width;
  911.     int src_y_inc = ((src_height << TOTAL_SCALE_BITS) + dest_height / 2) / dest_height;
  912.     int src_x_max = (src_width - 1) << TOTAL_SCALE_BITS;
  913.     int src_y_max = (src_height - 1) << TOTAL_SCALE_BITS;
  914.     int src_x_end = src_x_inc * dest_width;
  915.     int src_y_end = src_y_inc * dest_height;
  916. int src_x_bgn = (src_width < dest_width)?(0):((src_x_inc  - (1 << TOTAL_SCALE_BITS)) >> 1);
  917. int src_y_bgn = (src_height < dest_height)?(0):((src_y_inc - (1 << TOTAL_SCALE_BITS)) >> 1);
  918. src_x_bgn = 0;
  919. src_y_bgn = 0;
  920.     /* source/destination pointers: */
  921.     unsigned char *s1, *s2, *d1 = dest;
  922.     /* perform interpolation by inverse mapping from destination to source: */
  923.     for (src_y = src_y_bgn; src_y < src_y_max; src_y += src_y_inc) {
  924.         /* map row: */
  925.         int src_y_i = src_y >> TOTAL_SCALE_BITS;
  926.         int q       = (src_y >> (TOTAL_SCALE_BITS - COEF_SCALE_BITS)) & ((1U << COEF_SCALE_BITS) - 1);
  927.         /* get source row pointers: */
  928.         s1 = src + src_y_i * src_pitch;
  929.         s2 = s1 + src_pitch;
  930.         src_x = src_x_bgn;
  931.         do {
  932.             register int src_x_i, p;
  933.             register unsigned int a, b, c;
  934.             /* get first pixel: */
  935.             src_x_i = src_x >> TOTAL_SCALE_BITS;
  936.             p = (src_x >> (TOTAL_SCALE_BITS - COEF_SCALE_BITS)) & ((1U << COEF_SCALE_BITS) - 1);
  937.             /* load 4 pixels in 2 registers: */
  938.             a = (s2 [src_x_i] << 16) + s1 [src_x_i]; 
  939.             c = (s2 [src_x_i + 1] << 16) + s1 [src_x_i + 1]; 
  940.             /* perform 1st horisontal projection: */
  941.             a = (a << COEF_SCALE_BITS) + p * (c - a);
  942.             src_x  += src_x_inc; /* 1! */
  943.             /* get second pixel: */
  944.             src_x_i = src_x >> TOTAL_SCALE_BITS;
  945.             p = (src_x >> (TOTAL_SCALE_BITS - COEF_SCALE_BITS)) & ((1U << COEF_SCALE_BITS) - 1);
  946.             /* load 4 pixels in 2 registers: */
  947.             b = (s2 [src_x_i] << 16) + s1 [src_x_i]; 
  948.             c = (s2 [src_x_i + 1] << 16) + s1 [src_x_i + 1]; 
  949.             /* perform 2nd horisontal projection: */
  950.             b = (b << COEF_SCALE_BITS) + p * (c - b);
  951.             /* repack & perform vertical projection: */
  952.             c = a;
  953.             a = (a & 0xFFFF) + (b << 16);
  954.             b = (b & 0xFFFF0000) + ((unsigned int)c >> 16);
  955.             a = (a << COEF_SCALE_BITS) + q * (b - a);
  956.             
  957.             /* store pixels: */
  958.             *d1++ = (unsigned int)a >> 2 * COEF_SCALE_BITS;
  959.             *d1++ = (unsigned int)a >> (16 + 2 * COEF_SCALE_BITS);
  960.             src_x  += src_x_inc; /* 2! */
  961.         } while (src_x < src_x_max);
  962.         /* last pixels: */
  963.         {
  964.             int a = s1 [src_width - 1];
  965.             int c = s2 [src_width - 1];
  966.             a = (unsigned int)((a << COEF_SCALE_BITS) + q * (c - a)) >> COEF_SCALE_BITS;
  967.             for (; src_x < src_x_end; src_x += src_x_inc)
  968.                 *d1++ = a;
  969.         }
  970.         d1 = (dest += dest_pitch);
  971.     }
  972.     /* last rows: */
  973.     for (; src_y < src_y_end; src_y += src_y_inc) {
  974.         s1 = src + (src_height-1) * src_pitch;
  975.         for (src_x = 0; src_x < src_x_max; src_x += src_x_inc) {
  976.             int src_x_i = src_x >> TOTAL_SCALE_BITS;
  977.             int p       = (src_x >> (TOTAL_SCALE_BITS - COEF_SCALE_BITS)) & ((1U << COEF_SCALE_BITS) - 1);
  978.             /* get four pixels: */
  979.             int a = s1 [src_x_i];
  980.             int b = s1 [src_x_i + 1];
  981.             /* compute the interpolated pixel value: */
  982.             a = (a << COEF_SCALE_BITS) + p * (b - a);
  983.             *d1++ = (unsigned int)a >> COEF_SCALE_BITS;
  984.         }
  985.         /* last delta_x pixels: */
  986.         for (; src_x < src_x_end; src_x += src_x_inc)
  987.             *d1++ = s1 [src_width - 1];
  988.         d1 = (dest += dest_pitch);
  989.     }
  990. }