diff options
Diffstat (limited to 'mpeglib/lib/mpegplay/copyFunctions.cpp')
-rw-r--r-- | mpeglib/lib/mpegplay/copyFunctions.cpp | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/mpeglib/lib/mpegplay/copyFunctions.cpp b/mpeglib/lib/mpegplay/copyFunctions.cpp new file mode 100644 index 00000000..e290da50 --- /dev/null +++ b/mpeglib/lib/mpegplay/copyFunctions.cpp @@ -0,0 +1,330 @@ +/* + stores heavily used copy functions (makes mmx support easier) + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "copyFunctions.h" + + +/* + * We use a lookup table to make sure values stay in the 0..255 range. + * Since this is cropping (ie, x = (x < 0)?0:(x>255)?255:x; ), wee call this + * table the "crop table". + * MAX_NEG_CROP is the maximum neg/pos value we can handle. + */ +/* + * We use a lookup table to make sure values stay in the 0..255 range. + * Since this is cropping (ie, x = (x < 0)?0:(x>255)?255:x; ), wee call this + * table the "crop table". + * MAX_NEG_CROP is the maximum neg/pos value we can handle. + */ + +// Compiler cannot allocate too big arrays. + + + + +CopyFunctions::CopyFunctions() { + /* Initialize crop table. */ + cropTbl=new unsigned char[NUM_CROP_ENTRIES]; + + int i; + + for (i = (-MAX_NEG_CROP); i < NUM_CROP_ENTRIES - MAX_NEG_CROP; i++) { + if (i <= 0) { + cropTbl[i + MAX_NEG_CROP] = 0; + } else if (i >= 255) { + cropTbl[i + MAX_NEG_CROP] = 255; + } else { + cropTbl[i + MAX_NEG_CROP] = i; + } + } + cm=cropTbl + MAX_NEG_CROP; + + copyFunctions_asm = new CopyFunctions_MMX(); + lmmx=copyFunctions_asm->support(); + + + +} + + +CopyFunctions::~CopyFunctions() { + delete cropTbl; +} + +void CopyFunctions::startNOFloatSection() { + // nothing + copyFunctions_asm->startNOFloatSection(); +} + + +void CopyFunctions::endNOFloatSection() { + copyFunctions_asm->endNOFloatSection(); + +} + + +void CopyFunctions::copy8_byte(unsigned char* source1, + unsigned char* dest,int inc) { + if (lmmx == false) { + int rr; + + for (rr = 0; rr < 8; rr++) { + memcpy(dest,source1,sizeof(char)*8); + source1+=inc; + dest+=inc; + } + + } else { + copyFunctions_asm->copy8_byte(source1,dest,inc); + } + + +} + +void CopyFunctions::copy8_word(unsigned short* source1, + unsigned short* dest,int inc) { + int rr; + + // Optimisation is slower, leave it in C + for (rr = 0; rr < 8; rr++) { + memcpy(dest,source1,sizeof(short)*8); + source1+=inc; + dest+=inc; + } + +} + + + +void CopyFunctions::copy8_src1linear_crop(short* source1, + unsigned char* dest,int inc) { + + if (lmmx == false) { + int rr; + + for (rr = 0; rr < 8; rr++) { + + dest[0] = cm[source1[0]]; + dest[1] = cm[source1[1]]; + dest[2] = cm[source1[2]]; + dest[3] = cm[source1[3]]; + dest[4] = cm[source1[4]]; + dest[5] = cm[source1[5]]; + dest[6] = cm[source1[6]]; + dest[7] = cm[source1[7]]; + + + dest += inc; + source1 += 8; + + } + } else { + copyFunctions_asm->copy8_src1linear_crop(source1,dest,inc); + } + +} + +void CopyFunctions::copy8_div2_nocrop(unsigned char* source1, + unsigned char* source2, + unsigned char* dest,int inc) { + if (lmmx == false) { + int rr; + for (rr = 0; rr < 8; rr++) { + + dest[0] = (int) (source1[0] + source2[0]+1) >> 1; + dest[1] = (int) (source1[1] + source2[1]+1) >> 1; + dest[2] = (int) (source1[2] + source2[2]+1) >> 1; + dest[3] = (int) (source1[3] + source2[3]+1) >> 1; + dest[4] = (int) (source1[4] + source2[4]+1) >> 1; + dest[5] = (int) (source1[5] + source2[5]+1) >> 1; + dest[6] = (int) (source1[6] + source2[6]+1) >> 1; + dest[7] = (int) (source1[7] + source2[7]+1) >> 1; + dest += inc; + source1 += inc; + source2 += inc; + } + } else { + copyFunctions_asm->copy8_div2_nocrop(source1,source2, dest, inc); + } + +} + +void CopyFunctions::copy8_div2_destlinear_nocrop(unsigned char* source1, + unsigned char* source2, + unsigned char* dest,int inc) { + + if (lmmx == false) { + int rr; + for (rr = 0; rr < 8; rr++) { + dest[0] = (int) (source1[0] + source2[0]) >> 1; + dest[1] = (int) (source1[1] + source2[1]) >> 1; + dest[2] = (int) (source1[2] + source2[2]) >> 1; + dest[3] = (int) (source1[3] + source2[3]) >> 1; + dest[4] = (int) (source1[4] + source2[4]) >> 1; + dest[5] = (int) (source1[5] + source2[5]) >> 1; + dest[6] = (int) (source1[6] + source2[6]) >> 1; + dest[7] = (int) (source1[7] + source2[7]) >> 1; + dest += 8; + source1 += inc; + source2 += inc; + } + } else { + copyFunctions_asm->copy8_div2_destlinear_nocrop(source1,source2,dest,inc); + } +} + + +void CopyFunctions::copy16_div2_destlinear_nocrop(unsigned char* source1, + unsigned char* source2, + unsigned char* dest,int inc){ + + if (lmmx == false) { + int rr; + for (rr = 0; rr < 16; rr++) { + dest[0] = (int) (source1[0] + source2[0]) >> 1; + dest[1] = (int) (source1[1] + source2[1]) >> 1; + dest[2] = (int) (source1[2] + source2[2]) >> 1; + dest[3] = (int) (source1[3] + source2[3]) >> 1; + dest[4] = (int) (source1[4] + source2[4]) >> 1; + dest[5] = (int) (source1[5] + source2[5]) >> 1; + dest[6] = (int) (source1[6] + source2[6]) >> 1; + dest[7] = (int) (source1[7] + source2[7]) >> 1; + dest[8] = (int) (source1[8] + source2[8]) >> 1; + dest[9] = (int) (source1[9] + source2[9]) >> 1; + dest[10] = (int) (source1[10] + source2[10]) >> 1; + dest[11] = (int) (source1[11] + source2[11]) >> 1; + dest[12] = (int) (source1[12] + source2[12]) >> 1; + dest[13] = (int) (source1[13] + source2[13]) >> 1; + dest[14] = (int) (source1[14] + source2[14]) >> 1; + dest[15] = (int) (source1[15] + source2[15]) >> 1; + dest += 16; + source1 += inc; + source2 += inc; + } + } else { + copyFunctions_asm->copy16_div2_destlinear_nocrop(source1,source2,dest,inc); + } + +} + + + +void CopyFunctions::copy8_div4_nocrop(unsigned char* source1, + unsigned char* source2, + unsigned char* source3, + unsigned char* source4, + unsigned char* dest,int inc) { + int rr; + + for (rr = 0; rr < 8; rr++) { + dest[0]=(int) (source1[0]+source2[0]+source3[0]+source4[0] + 2) >> 2; + dest[1]=(int) (source1[1]+source2[1]+source3[1]+source4[1] + 2) >> 2; + dest[2]=(int) (source1[2]+source2[2]+source3[2]+source4[2] + 2) >> 2; + dest[3]=(int) (source1[3]+source2[3]+source3[3]+source4[3] + 2) >> 2; + dest[4]=(int) (source1[4]+source2[4]+source3[4]+source4[4] + 2) >> 2; + dest[5]=(int) (source1[5]+source2[5]+source3[5]+source4[5] + 2) >> 2; + dest[6]=(int) (source1[6]+source2[6]+source3[6]+source4[6] + 2) >> 2; + dest[7]=(int) (source1[7]+source2[7]+source3[7]+source4[7] + 2) >> 2; + dest += inc; + source1 += inc; + source2 += inc; + source3 += inc; + source4 += inc; + } +} + +// Optimize me! +// should be mmx perfomance analysis shows: 8 % overall time + +void CopyFunctions::copy8_src2linear_crop(unsigned char* source1, + short int* source2, + unsigned char* dest,int inc) { + int rr; + if (lmmx == false) { + for (rr = 0; rr < 8; rr++) { + dest[0] = cm[(int) source1[0] + (int) source2[0]]; + dest[1] = cm[(int) source1[1] + (int) source2[1]]; + dest[2] = cm[(int) source1[2] + (int) source2[2]]; + dest[3] = cm[(int) source1[3] + (int) source2[3]]; + dest[4] = cm[(int) source1[4] + (int) source2[4]]; + dest[5] = cm[(int) source1[5] + (int) source2[5]]; + dest[6] = cm[(int) source1[6] + (int) source2[6]]; + dest[7] = cm[(int) source1[7] + (int) source2[7]]; + dest += inc; + source1 += inc; + source2 += 8; + } + } else { + copyFunctions_asm->copy8_src2linear_crop(source1,source2,dest,inc); + } + +} + +// Optimize me! +// should be mmx perfomance analysis shows: 13 % overall time +void CopyFunctions::copy8_div2_src3linear_crop(unsigned char* source1, + unsigned char* source2, + short int* source3, + unsigned char* dest,int inc) { + int rr; + if (lmmx==false) { + for (rr = 0; rr < 8; rr++) { + dest[0] = cm[((int) (source1[0] + source2[0]+1) >> 1) + source3[0]]; + dest[1] = cm[((int) (source1[1] + source2[1]+1) >> 1) + source3[1]]; + dest[2] = cm[((int) (source1[2] + source2[2]+1) >> 1) + source3[2]]; + dest[3] = cm[((int) (source1[3] + source2[3]+1) >> 1) + source3[3]]; + dest[4] = cm[((int) (source1[4] + source2[4]+1) >> 1) + source3[4]]; + dest[5] = cm[((int) (source1[5] + source2[5]+1) >> 1) + source3[5]]; + dest[6] = cm[((int) (source1[6] + source2[6]+1) >> 1) + source3[6]]; + dest[7] = cm[((int) (source1[7] + source2[7]+1) >> 1) + source3[7]]; + dest += inc; + source1 += inc; + source2 += inc; + source3 += 8; + + } + } else { + copyFunctions_asm->copy8_div2_src3linear_crop(source1,source2,source3, + dest,inc); + } + + +} + + +void CopyFunctions::copy8_div4_src5linear_crop(unsigned char* source1, + unsigned char* source2, + unsigned char* source3, + unsigned char* source4, + short int* source5, + unsigned char* dest,int inc) { + + int rr; + + for (rr = 0; rr < 8; rr++) { + dest[0]=cm[((int) (source1[0]+source2[0]+source3[0]+source4[0]+2) >> 2) + source5[0]]; + dest[1]=cm[((int) (source1[1]+source2[1]+source3[1]+source4[1]+2) >> 2) + source5[1]]; + dest[2]=cm[((int) (source1[2]+source2[2]+source3[2]+source4[2]+2) >> 2) + source5[2]]; + dest[3]=cm[((int) (source1[3]+source2[3]+source3[3]+source4[3]+2) >> 2) + source5[3]]; + dest[4]=cm[((int) (source1[4]+source2[4]+source3[4]+source4[4]+2) >> 2) + source5[4]]; + dest[5]=cm[((int) (source1[5]+source2[5]+source3[5]+source4[5]+2) >> 2) + source5[5]]; + dest[6]=cm[((int) (source1[6]+source2[6]+source3[6]+source4[6]+2) >> 2) + source5[6]]; + dest[7]=cm[((int) (source1[7]+source2[7]+source3[7]+source4[7]+2) >> 2) + source5[7]]; + dest +=inc; + source1 += inc; + source2 += inc; + source3 += inc; + source4 += inc; + source5 += 8; + } +} |