home *** CD-ROM | disk | FTP | other *** search
- // VirtualDub - Video processing and capture application
- // Graphics support library
- // Copyright (C) 1998-2007 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 "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;
- }
- }
- }
-