📄 resize.cpp
字号:
tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
*tp = tmp;
tp += src_pitch;
pos += pos_inc;
pos_int = pos >> POS_SCALE_BITS;
line++;
}
}
}
if (dest_width == src_width)
{
// no horizontal resizing
for (line = 0; line < dest_height; line++)
{
tp = buff + line * src_pitch;
dp = dest + line * dest_pitch;
for (pel = 0; pel < dest_width - 3; pel += 4)
{
dp[0] = CLIP_PEL(tp[0]);
dp[1] = CLIP_PEL(tp[1]);
dp[2] = CLIP_PEL(tp[2]);
dp[3] = CLIP_PEL(tp[3]);
dp += 4;
tp += 4;
}
for (; pel < dest_width; pel++)
{
*dp = CLIP_PEL(*tp);
dp ++;
tp ++;
}
}
}
else if (dest_width == (src_width >> 1))
{
// decimate horizontally by 2
int src_skip = src_pitch - src_width + 2;
int dest_skip = dest_pitch - dest_width + 1;
int a, b, c, d;
tp = buff;
dp = dest;
for (line = 0; line < dest_height; line ++)
{
a = tp[0];
b = a;
c = tp[1];
d = tp[2];
b += c;
a += d;
b *= 9;
b -= a;
b += 7;
b >>= 4;
*dp = CLIP_PEL(b);
tp += 2;
dp ++;
for (pel = 1; pel < dest_width - 1; pel++)
{
a = c;
b = d;
c = tp[1];
d = tp[2];
b += c;
a += d;
b *= 9;
b -= a;
b += 7;
b >>= 4;
*dp = CLIP_PEL(b);
tp += 2;
dp ++;
}
a = c;
b = d;
c = tp[1];
d = c;
b += c;
a += d;
b *= 9;
b -= a;
b += 7;
b >>= 4;
*dp = CLIP_PEL(b);
tp += src_skip;
dp += dest_skip;
}
}
else
{
// horizonal filtering
pos_inc = ((src_width << POS_SCALE_BITS) + (dest_width >> 1)) / (dest_width);
pos_bgn = (pos_inc - (1 << POS_SCALE_BITS)) >> 1;
filt_tab_inc = (FULL_PEL_INC * dest_width + (src_width >> 1)) / (src_width);
if (filt_tab_inc > FULL_PEL_INC)
filt_tab_inc = FULL_PEL_INC;
filt_tap_num = (INT_FILT_SIZE - 1) / (filt_tab_inc << 1);
filt_scale = ((dest_width << FILT_SCALE_BITS) + (src_width >> 1)) / (src_width);
for (line = 0; line < dest_height; line++)
{
dp = dest + line * dest_pitch;
pel = 0;
pos = pos_bgn;
pos_int = pos >> POS_SCALE_BITS;
// Left edge pels
while (pos_int < filt_tap_num)
{
tp = buff + line * src_pitch + pos_int;
#if USE_SOURCE_LEVEL
source_level = *tp;
#endif
tp -= filt_tap_num;
filt_tab_ptr = int_filt_tab;
filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
if (filt_tab_ptr < int_filt_tab)
{
tp ++;
filt_tab_ptr += filt_tab_inc;
}
tmp = 0;
while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
{
if (tp < buff)
tmp += (*filt_tab_ptr) * (buff[line * src_pitch] - source_level);
else
tmp += (*filt_tab_ptr) * (*tp - source_level);
tp++;
filt_tab_ptr += filt_tab_inc;
}
tmp *= filt_scale;
tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
*dp = CLIP_PEL(tmp);
dp++;
pos += pos_inc;
pos_int = pos >> POS_SCALE_BITS;
pel++;
}
// Center pels
while (pos_int < src_width - filt_tap_num - 1)
{
tp = buff + line * src_pitch + pos_int;
#if USE_SOURCE_LEVEL
source_level = *tp;
#endif
tp -= filt_tap_num;
filt_tab_ptr = int_filt_tab;
filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
if (filt_tab_ptr < int_filt_tab)
{
tp ++;
filt_tab_ptr += filt_tab_inc;
}
// There are at least 4 taps...
tmp = (*filt_tab_ptr) * (tp[0] - source_level);
filt_tab_ptr += filt_tab_inc;
tmp += (*filt_tab_ptr) * (tp[1] - source_level);
filt_tab_ptr += filt_tab_inc;
tmp += (*filt_tab_ptr) * (tp[2] - source_level);
filt_tab_ptr += filt_tab_inc;
tmp += (*filt_tab_ptr) * (tp[3] - source_level);
filt_tab_ptr += filt_tab_inc;
tp += 4;
// Remaining taps...
while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
{
tmp += (*filt_tab_ptr) * (*tp - source_level);
tp++;
filt_tab_ptr += filt_tab_inc;
}
tmp *= filt_scale;
tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
*dp = CLIP_PEL(tmp);
dp++;
pos += pos_inc;
pos_int = pos >> POS_SCALE_BITS;
pel++;
}
// Right edge pels
while (pel < dest_width)
{
tp = buff + line * src_pitch + pos_int;
#if USE_SOURCE_LEVEL
source_level = *tp;
#endif
tp -= filt_tap_num;
filt_tab_ptr = int_filt_tab;
filt_tab_ptr -= (filt_tab_inc * (pos & ((1L << POS_SCALE_BITS) - 1))) >> POS_SCALE_BITS;
filt_tab_ptr += INT_FILT_CENTER - (filt_tap_num * filt_tab_inc);
if (filt_tab_ptr < int_filt_tab)
{
tp ++;
filt_tab_ptr += filt_tab_inc;
}
tmp = 0;
while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
{
if (tp >= buff + line * src_pitch + src_width)
tmp += (*filt_tab_ptr) * (buff[line * src_pitch + src_width - 1] - source_level);
else
tmp += (*filt_tab_ptr) * (*tp - source_level);
tp++;
filt_tab_ptr += filt_tab_inc;
}
tmp *= filt_scale;
tmp += (source_level << (FILT_COEFF_BITS + FILT_SCALE_BITS));
tmp += (1U << (FILT_COEFF_BITS + FILT_SCALE_BITS - 1));
tmp >>= (FILT_COEFF_BITS + FILT_SCALE_BITS);
*dp = CLIP_PEL(tmp);
dp++;
pos += pos_inc;
pos_int = pos >> POS_SCALE_BITS;
pel++;
}
}
}
}
/* 12-19-98 02:36am, written by Yuriy A. Reznik, yreznik@real.com */
#define TOTAL_SCALE_BITS 16 /* precision of inverse coordinate mapping */
#define COEF_SCALE_BITS 3 /* actual grid used to select scale coeffs */
/*
* Interpolate image.
* Use:
* void interpolate_x (
* unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
* unsigned char *src, int src_width, int src_height, int src_pitch);
*/
static void /** G2H263Codec:: NEVER make this function a class method!!!! */
interpolate_ii (
unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
unsigned char *src, int src_width, int src_height, int src_pitch)
{
/* scaled row/column counters, limits, & increment values: */
int src_x, src_y;
int src_x_inc = ((src_width << TOTAL_SCALE_BITS) + dest_width / 2) / dest_width;
int src_y_inc = ((src_height << TOTAL_SCALE_BITS) + dest_height / 2) / dest_height;
int src_x_max = (src_width - 1) << TOTAL_SCALE_BITS;
int src_y_max = (src_height - 1) << TOTAL_SCALE_BITS;
int src_x_end = src_x_inc * dest_width;
int src_y_end = src_y_inc * dest_height;
int src_x_bgn = (src_width < dest_width)?(0):((src_x_inc - (1 << TOTAL_SCALE_BITS)) >> 1);
int src_y_bgn = (src_height < dest_height)?(0):((src_y_inc - (1 << TOTAL_SCALE_BITS)) >> 1);
src_x_bgn = 0;
src_y_bgn = 0;
/* source/destination pointers: */
unsigned char *s1, *s2, *d1 = dest;
/* perform interpolation by inverse mapping from destination to source: */
for (src_y = src_y_bgn; src_y < src_y_max; src_y += src_y_inc) {
/* map row: */
int src_y_i = src_y >> TOTAL_SCALE_BITS;
int q = (src_y >> (TOTAL_SCALE_BITS - COEF_SCALE_BITS)) & ((1U << COEF_SCALE_BITS) - 1);
/* get source row pointers: */
s1 = src + src_y_i * src_pitch;
s2 = s1 + src_pitch;
src_x = src_x_bgn;
do {
register int src_x_i, p;
register unsigned int a, b, c;
/* get first pixel: */
src_x_i = src_x >> TOTAL_SCALE_BITS;
p = (src_x >> (TOTAL_SCALE_BITS - COEF_SCALE_BITS)) & ((1U << COEF_SCALE_BITS) - 1);
/* load 4 pixels in 2 registers: */
a = (s2 [src_x_i] << 16) + s1 [src_x_i];
c = (s2 [src_x_i + 1] << 16) + s1 [src_x_i + 1];
/* perform 1st horisontal projection: */
a = (a << COEF_SCALE_BITS) + p * (c - a);
src_x += src_x_inc; /* 1! */
/* get second pixel: */
src_x_i = src_x >> TOTAL_SCALE_BITS;
p = (src_x >> (TOTAL_SCALE_BITS - COEF_SCALE_BITS)) & ((1U << COEF_SCALE_BITS) - 1);
/* load 4 pixels in 2 registers: */
b = (s2 [src_x_i] << 16) + s1 [src_x_i];
c = (s2 [src_x_i + 1] << 16) + s1 [src_x_i + 1];
/* perform 2nd horisontal projection: */
b = (b << COEF_SCALE_BITS) + p * (c - b);
/* repack & perform vertical projection: */
c = a;
a = (a & 0xFFFF) + (b << 16);
b = (b & 0xFFFF0000) + ((unsigned int)c >> 16);
a = (a << COEF_SCALE_BITS) + q * (b - a);
/* store pixels: */
*d1++ = (unsigned int)a >> 2 * COEF_SCALE_BITS;
*d1++ = (unsigned int)a >> (16 + 2 * COEF_SCALE_BITS);
src_x += src_x_inc; /* 2! */
} while (src_x < src_x_max);
/* last pixels: */
{
int a = s1 [src_width - 1];
int c = s2 [src_width - 1];
a = (unsigned int)((a << COEF_SCALE_BITS) + q * (c - a)) >> COEF_SCALE_BITS;
for (; src_x < src_x_end; src_x += src_x_inc)
*d1++ = a;
}
d1 = (dest += dest_pitch);
}
/* last rows: */
for (; src_y < src_y_end; src_y += src_y_inc) {
s1 = src + (src_height-1) * src_pitch;
for (src_x = 0; src_x < src_x_max; src_x += src_x_inc) {
int src_x_i = src_x >> TOTAL_SCALE_BITS;
int p = (src_x >> (TOTAL_SCALE_BITS - COEF_SCALE_BITS)) & ((1U << COEF_SCALE_BITS) - 1);
/* get four pixels: */
int a = s1 [src_x_i];
int b = s1 [src_x_i + 1];
/* compute the interpolated pixel value: */
a = (a << COEF_SCALE_BITS) + p * (b - a);
*d1++ = (unsigned int)a >> COEF_SCALE_BITS;
}
/* last delta_x pixels: */
for (; src_x < src_x_end; src_x += src_x_inc)
*d1++ = s1 [src_width - 1];
d1 = (dest += dest_pitch);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -