📄 resize.cpp
字号:
psrlw mm0, 1 lea esi, [esi+8] movq mm1, [esi] movq mm2, mm1 psrlw mm2, 8 pand mm1, mm7 paddw mm1, mm2 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 voiddecimate ( 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -