📄 resize.cpp
字号:
psrlw mm1, 1
lea esi, [esi+8]
packuswb mm0, mm1
movq [edi], mm0
lea edi, [edi+8]
dec ecx
jnz pel_loop
emms
}
}
#endif
////////////////////////////////////////////////////////
//
// Performs fast and accurate half horizontal
// Greg Conklin - 9/05/00
//
////////////////////////////////////////////////////////
static void
decimate_half_horiz_accurate(
unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
unsigned char *src, int src_width, int src_height, int src_pitch)
{
unsigned char *dd;
unsigned char *ss;
unsigned char *src_end;
unsigned char *line_end;
int dest_skip;
int src_skip;
int a,b,c,d;
dd = dest;
ss = src;
dest_skip = dest_pitch - dest_width + 1;
src_skip = src_pitch - src_width + 2;
src_end = src + src_width * src_height;
while (ss < src_end)
{
line_end = ss + src_width - 2;
a = ss[0];
b = a;
c = ss[1];
d = ss[2];
b += c;
a += d;
b *= 9;
b -= a;
b += 7;
b >>= 4;
dd[0] = CLIP_PEL(b);
ss += 2;
dd ++;
while (ss < line_end)
{
a = c;
b = d;
c = ss[1];
d = ss[2];
b += c;
a += d;
b *= 9;
b -= a;
b += 7;
b >>= 4;
dd[0] = CLIP_PEL(b);
ss += 2;
dd ++;
}
a = c;
b = d;
c = ss[1];
d = c;
b += c;
a += d;
b *= 9;
b -= a;
b += 7;
b >>= 4;
dd[0] = CLIP_PEL(b);
ss += src_skip;
dd += dest_skip;
}
}
////////////////////////////////////////////////////////
//
// Performs accurate decimation
// Greg Conklin - 9/21/99
//
////////////////////////////////////////////////////////
static void
decimate (
unsigned char *dest, int dest_width, int dest_height, int dest_pitch,
unsigned char *src, int src_width, int src_height, int src_pitch,
RESIZE_BUFF_TYPE *buff)
{
unsigned char *sp, *dp;
RESIZE_BUFF_TYPE *tp;
int pel; // destination x position
int line; // destination y position
int tmp; // temp storage for result pel
int pos; // fractional position of source (x or y) location
int pos_int; // integer position of source
int pos_bgn; // the starting location of pos
int pos_inc; // the increment of 'pos' to the next pel
const int *filt_tab_ptr; // pointer to the current filter tap
int filt_tab_inc; // spacing between tabs in the filter table
int filt_tap_num; // number of filter taps
int filt_scale; // filter gain
#if USE_SOURCE_LEVEL
int source_level;
#else
#define source_level 0
#endif
if (dest_height == src_height)
{
// no vertical resizing
for (line = 0; line < src_height; line++)
{
tp = buff + line * src_pitch;
sp = src + line * src_pitch;
for (pel = 0; pel < src_width - 3; pel += 4)
{
tp[0] = sp[0];
tp[1] = sp[1];
tp[2] = sp[2];
tp[3] = sp[3];
tp += 4;
sp += 4;
}
for (; pel < dest_width; pel++)
{
*tp = *sp;
tp ++;
sp ++;
}
}
}
else if (dest_height == (src_height >> 1))
{
// decimate vertical by 2
int src_skip = src_pitch - src_width;
int a, b, c, d;
tp = buff;
sp = src;
// top line
for (pel = 0; pel < src_width; pel ++)
{
b = *sp;
c = *(sp + src_pitch);
d = *(sp + 2 * src_pitch);
c += b;
b += d;
c *= 9;
c -= b;
c += 7;
c >>= 4;
*tp = CLIP_PEL(c);
sp++;
tp++;
}
tp += src_skip;
sp += src_skip + src_pitch;
// middle lines
for (line = 2; line < dest_height; line ++)
{
for (pel = 0; pel < src_width; pel++)
{
a = *(sp - src_pitch);
b = *sp;
c = *(sp + src_pitch);
d = *(sp + 2 * src_pitch);
b += c;
a += d;
b *= 9;
b -= a;
b += 7;
b >>= 4;
*tp = CLIP_PEL(b);
sp++;
tp++;
}
tp += src_skip;
sp += src_skip + src_pitch;
}
// bottom line
for (pel = 0; pel < src_width; pel++)
{
a = *(sp - src_pitch);
b = *sp;
c = *(sp + src_pitch);
b += c;
a += c;
b *= 9;
b -= a;
b += 7;
b >>= 4;
*tp = CLIP_PEL(b);
sp++;
tp++;
}
}
else
{
// arbitrary vertical resize
pos_inc = ((src_height << POS_SCALE_BITS) + (dest_height >> 1)) / (dest_height);
pos_bgn = (pos_inc - (1 << POS_SCALE_BITS)) >> 1;
filt_tab_inc = (FULL_PEL_INC * dest_height + (src_height >> 1)) / (src_height);
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_height << FILT_SCALE_BITS) + (src_height >> 1)) / (src_height);
for (pel = 0; pel < src_width; pel++)
{
tp = buff + pel;
line = 0;
pos = pos_bgn;
pos_int = pos >> POS_SCALE_BITS;
// Top edge pels
while (pos_int < filt_tap_num)
{
sp = src + (pos_int) * src_pitch + pel;
#if USE_SOURCE_LEVEL
source_level = *sp;
#endif
sp -= filt_tap_num * src_pitch;
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)
{
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
}
tmp = 0;
while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
{
if (sp < src)
tmp += (*filt_tab_ptr) * (src[pel] - source_level);
else
tmp += (*filt_tab_ptr) * (*sp - source_level);
sp += src_pitch;;
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);
*tp = tmp;
tp += src_pitch;
pos += pos_inc;
pos_int = pos >> POS_SCALE_BITS;
line++;
}
// Center pels
while (pos_int < src_height - filt_tap_num - 1)
{
sp = src + (pos_int) * src_pitch + pel;
#if USE_SOURCE_LEVEL
source_level = *sp;
#endif
sp -= filt_tap_num * src_pitch;
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)
{
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
}
// There are at least 4 taps...
tmp = (*filt_tab_ptr) * (*sp - source_level);
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
tmp += (*filt_tab_ptr) * (*sp - source_level);
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
tmp += (*filt_tab_ptr) * (*sp - source_level);
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
tmp += (*filt_tab_ptr) * (*sp - source_level);
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
// Remaining taps...
while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
{
tmp += (*filt_tab_ptr) * (*sp - source_level);
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
}
// scale and store result...
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);
*tp = tmp;
tp += src_pitch;
pos += pos_inc;
pos_int = pos >> POS_SCALE_BITS;
line++;
}
// Bottom edge pels
while (line < dest_height)
{
sp = src + (pos_int) * src_pitch + pel;
#if USE_SOURCE_LEVEL
source_level = *sp;
#endif
sp -= filt_tap_num * src_pitch;
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)
{
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
}
tmp = 0;
while (filt_tab_ptr < int_filt_tab + INT_FILT_SIZE)
{
if (sp >= src + src_height*src_pitch)
tmp += (*filt_tab_ptr) * (src[(src_height - 1) * src_pitch + pel] - source_level);
else
tmp += (*filt_tab_ptr) * (*sp - source_level);
sp += src_pitch;
filt_tab_ptr += filt_tab_inc;
}
tmp *= filt_scale;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -