// VirtualDub - Video processing and capture application // Graphics support library // Copyright (C) 1998-2009 Avery Lee // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "blt_spanutils_x86.h" #ifdef _MSC_VER #pragma warning(disable: 4799) // warning C4799: function 'nsVDPixmapSpanUtils::vdasm_horiz_expand2x_coaligned_ISSE' has no EMMS instruction #endif extern "C" void __cdecl vdasm_horiz_expand2x_coaligned_ISSE(void *dst, const void *src, uint32 count); extern "C" void __cdecl vdasm_horiz_expand4x_coaligned_MMX(void *dst, const void *src, uint32 count); extern "C" void __cdecl vdasm_vert_average_13_ISSE(void *dst, const void *src1, const void *src3, uint32 count); extern "C" void __cdecl vdasm_vert_average_17_ISSE(void *dst, const void *src1, const void *src3, uint32 count); extern "C" void __cdecl vdasm_vert_average_35_ISSE(void *dst, const void *src1, const void *src3, uint32 count); namespace nsVDPixmapSpanUtils { void horiz_expand2x_coaligned_ISSE(uint8 *dst, const uint8 *src, sint32 w) { if (w >= 17) { uint32 fastcount = (w - 1) & ~15; vdasm_horiz_expand2x_coaligned_ISSE(dst, src, fastcount); dst += fastcount; src += fastcount >> 1; w -= fastcount; } w = -w; if ((w+=2) < 0) { do { dst[0] = src[0]; dst[1] = (uint8)((src[0] + src[1] + 1)>>1); dst += 2; ++src; } while((w+=2)<0); } w -= 2; while(w < 0) { ++w; *dst++ = src[0]; } } void horiz_expand4x_coaligned_MMX(uint8 *dst, const uint8 *src, sint32 w) { if (w >= 17) { uint32 fastcount = (w - 1) >> 4; vdasm_horiz_expand4x_coaligned_MMX(dst, src, fastcount); dst += fastcount << 4; src += fastcount << 2; w -= fastcount << 4; } w = -w; if ((w+=4) < 0) { do { dst[0] = src[0]; dst[1] = (uint8)((3*src[0] + src[1] + 2)>>2); dst[2] = (uint8)((src[0] + src[1] + 1)>>1); dst[3] = (uint8)((src[0] + 3*src[1] + 2)>>2); dst += 4; ++src; } while((w+=4)<0); } w -= 4; while(w < 0) { ++w; *dst++ = src[0]; } } void vert_expand2x_centered_ISSE(uint8 *dst, const uint8 *const *srcs, sint32 w, uint8 phase) { const uint8 *src3 = srcs[0]; const uint8 *src1 = srcs[1]; if (phase >= 128) std::swap(src1, src3); uint32 fastcount = w & ~15; if (fastcount) { vdasm_vert_average_13_ISSE(dst, src1, src3, fastcount); dst += fastcount; src1 += fastcount; src3 += fastcount; w -= fastcount; } if (w) { do { *dst++ = (uint8)((*src1++ + 3**src3++ + 2) >> 2); } while(--w); } } void vert_average_1_7_ISSE(uint8 *dst, const uint8 *src7, const uint8 *src1, sint32 w) { uint32 fastcount = w & ~7; if (fastcount) { vdasm_vert_average_17_ISSE(dst, src1, src7, fastcount); dst += fastcount; src1 += fastcount; src7 += fastcount; w -= fastcount; } if (w) { do { *dst++ = (uint8)((*src1++ + 7**src7++ + 4) >> 3); } while(--w); } } void vert_average_3_5_ISSE(uint8 *dst, const uint8 *src7, const uint8 *src1, sint32 w) { uint32 fastcount = w & ~7; if (fastcount) { vdasm_vert_average_35_ISSE(dst, src1, src7, fastcount); dst += fastcount; src1 += fastcount; src7 += fastcount; w -= fastcount; } if (w) { do { *dst++ = (uint8)((3**src1++ + 5**src7++ + 4) >> 3); } while(--w); } } void vert_expand4x_centered_ISSE(uint8 *dst, const uint8 *const *srcs, sint32 w, uint8 phase) { const uint8 *src1 = srcs[0]; const uint8 *src2 = srcs[1]; switch(phase & 0xc0) { case 0x00: vert_average_1_7_ISSE(dst, src2, src1, w); break; case 0x40: vert_average_3_5_ISSE(dst, src2, src1, w); break; case 0x80: vert_average_3_5_ISSE(dst, src1, src2, w); break; case 0xc0: vert_average_1_7_ISSE(dst, src1, src2, w); break; default: VDNEVERHERE; } } }