resize.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:40k
源码类别:

Symbian

开发平台:

Visual C++

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