393 lines
8.3 KiB
C
393 lines
8.3 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*
|
||
|
* $Id: mcomp_c.c 329 2005-11-04 17:17:55Z picard $
|
||
|
*
|
||
|
* The Core Pocket Media Player
|
||
|
* Copyright (c) 2004-2005 Gabor Kovacs
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include "../common.h"
|
||
|
#include "softidct.h"
|
||
|
|
||
|
#if !defined(ARM) && !defined(MIPS64) && !defined(MIPS32) && !defined(MMX)
|
||
|
|
||
|
#define LoadRow(a,b,ofs) \
|
||
|
{ \
|
||
|
a=LOAD32(Src+ofs+0); \
|
||
|
b=LOAD32(Src+ofs+4); \
|
||
|
}
|
||
|
#define LoadMRow(a,b,c,d,ofs) \
|
||
|
{ \
|
||
|
a=LOAD32(Src+ofs+0); \
|
||
|
b=LOAD32(Src+ofs+4); \
|
||
|
c=LOAD32(Src+ofs+8); \
|
||
|
d=LOAD32(Src+ofs+12); \
|
||
|
}
|
||
|
#define SaveRow(a,b) \
|
||
|
{ \
|
||
|
((uint32_t*)Dst)[0]=a; \
|
||
|
((uint32_t*)Dst)[1]=b; \
|
||
|
}
|
||
|
#define SaveMRow(a,b,c,d) \
|
||
|
{ \
|
||
|
((uint32_t*)Dst)[0]=a; \
|
||
|
((uint32_t*)Dst)[1]=b; \
|
||
|
((uint32_t*)Dst)[2]=c; \
|
||
|
((uint32_t*)Dst)[3]=d; \
|
||
|
}
|
||
|
#define AddRow(a,b,t0,t1) \
|
||
|
{ \
|
||
|
t0=((uint32_t*)Dst)[0]; \
|
||
|
t1=((uint32_t*)Dst)[1]; \
|
||
|
AVG32R(a,b,t0,t1); \
|
||
|
((uint32_t*)Dst)[0]=a; \
|
||
|
((uint32_t*)Dst)[1]=b; \
|
||
|
}
|
||
|
#define PrepareAvg4(a,b,c,d) \
|
||
|
{ \
|
||
|
uint32_t q,w; \
|
||
|
q=(a & 0x03030303); \
|
||
|
w=(b & 0x03030303); \
|
||
|
q+=(c & 0x03030303); \
|
||
|
w+=(d & 0x03030303); \
|
||
|
a=(a>>2) & 0x3F3F3F3F; \
|
||
|
b=(b>>2) & 0x3F3F3F3F; \
|
||
|
a+=(c>>2) & 0x3F3F3F3F; \
|
||
|
b+=(d>>2) & 0x3F3F3F3F; \
|
||
|
c=q; \
|
||
|
d=w; \
|
||
|
}
|
||
|
#define Avg4(a,b,c,d,g,h,i,j) \
|
||
|
{ \
|
||
|
a+=g; \
|
||
|
b+=h; \
|
||
|
c+=i+0x02020202; \
|
||
|
d+=j+0x02020202; \
|
||
|
a+=(c>>2) & 0x03030303; \
|
||
|
b+=(d>>2) & 0x03030303; \
|
||
|
}
|
||
|
#define Avg4Round(a,b,c,d,g,h,i,j) \
|
||
|
{ \
|
||
|
a+=g; \
|
||
|
b+=h; \
|
||
|
c+=i+0x01010101; \
|
||
|
d+=j+0x01010101; \
|
||
|
a+=(c>>2) & 0x03030303; \
|
||
|
b+=(d>>2) & 0x03030303; \
|
||
|
}
|
||
|
|
||
|
// Dst[p] = Src[p]
|
||
|
void STDCALL CopyBlock(uint8_t *Src, uint8_t *Dst, int SrcPitch, int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b;
|
||
|
do
|
||
|
{
|
||
|
LoadRow(a,b,0)
|
||
|
SaveRow(a,b)
|
||
|
Dst += DstPitch;
|
||
|
Src += SrcPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (Src[p] + Src[p+1]+1) >> 1;
|
||
|
void STDCALL CopyBlockHor(uint8_t *Src, uint8_t *Dst, int SrcPitch, int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d;
|
||
|
do
|
||
|
{
|
||
|
LoadRow(a,b,0)
|
||
|
LoadRow(c,d,1)
|
||
|
AVG32R(a,b,c,d)
|
||
|
SaveRow(a,b)
|
||
|
Dst += DstPitch;
|
||
|
Src += SrcPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (Src[p] + Src[p+SrcPitch]+1) >> 1;
|
||
|
void STDCALL CopyBlockVer(uint8_t *Src, uint8_t *Dst, int SrcPitch, int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d,e,f;
|
||
|
LoadRow(a,b,0)
|
||
|
do
|
||
|
{
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(c,d,0)
|
||
|
e = c;
|
||
|
f = d;
|
||
|
AVG32R(a,b,e,f)
|
||
|
SaveRow(a,b)
|
||
|
Dst += DstPitch;
|
||
|
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(a,b,0)
|
||
|
e = c;
|
||
|
f = d;
|
||
|
AVG32R(c,d,e,f)
|
||
|
SaveRow(c,d)
|
||
|
Dst += DstPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (Src[p] + Src[p+1] + Src[p+SrcPitch] + Src[p+SrcPitch+1] + 2) >> 2;
|
||
|
void STDCALL CopyBlockHorVer(uint8_t *Src, uint8_t *Dst, int SrcPitch, int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d,g,h,i,j;
|
||
|
LoadRow(a,b,0)
|
||
|
LoadRow(c,d,1)
|
||
|
PrepareAvg4(a,b,c,d)
|
||
|
do
|
||
|
{
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(g,h,0)
|
||
|
LoadRow(i,j,1)
|
||
|
PrepareAvg4(g,h,i,j)
|
||
|
Avg4(a,b,c,d,g,h,i,j)
|
||
|
SaveRow(a,b)
|
||
|
Dst += DstPitch;
|
||
|
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(a,b,0)
|
||
|
LoadRow(c,d,1)
|
||
|
PrepareAvg4(a,b,c,d)
|
||
|
Avg4(g,h,i,j,a,b,c,d)
|
||
|
SaveRow(g,h)
|
||
|
Dst += DstPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (Src[p] + Src[p+1]) >> 1;
|
||
|
void STDCALL CopyBlockHorRound(uint8_t *Src, uint8_t *Dst, int SrcPitch, int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d;
|
||
|
do
|
||
|
{
|
||
|
LoadRow(a,b,0)
|
||
|
LoadRow(c,d,1)
|
||
|
AVG32NR(a,b,c,d)
|
||
|
SaveRow(a,b)
|
||
|
Dst += DstPitch;
|
||
|
Src += SrcPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (Src[p] + Src[p+SrcPitch]) >> 1;
|
||
|
void STDCALL CopyBlockVerRound(uint8_t *Src, uint8_t *Dst, int SrcPitch, int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d,e,f;
|
||
|
LoadRow(a,b,0)
|
||
|
do
|
||
|
{
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(c,d,0)
|
||
|
e = c;
|
||
|
f = d;
|
||
|
AVG32NR(a,b,e,f)
|
||
|
SaveRow(a,b)
|
||
|
Dst += DstPitch;
|
||
|
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(a,b,0)
|
||
|
e = a;
|
||
|
f = b;
|
||
|
AVG32NR(c,d,e,f)
|
||
|
SaveRow(c,d)
|
||
|
Dst += DstPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (Src[p] + Src[p+1] + Src[p+SrcPitch] + Src[p+SrcPitch+1] + 1) >> 2;
|
||
|
void STDCALL CopyBlockHorVerRound(uint8_t *Src, uint8_t *Dst, int SrcPitch, int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d,g,h,i,j;
|
||
|
LoadRow(a,b,0)
|
||
|
LoadRow(c,d,1)
|
||
|
PrepareAvg4(a,b,c,d)
|
||
|
do
|
||
|
{
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(g,h,0)
|
||
|
LoadRow(i,j,1)
|
||
|
PrepareAvg4(g,h,i,j)
|
||
|
Avg4Round(a,b,c,d,g,h,i,j)
|
||
|
SaveRow(a,b)
|
||
|
Dst += DstPitch;
|
||
|
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(a,b,0)
|
||
|
LoadRow(c,d,1)
|
||
|
PrepareAvg4(a,b,c,d)
|
||
|
Avg4Round(g,h,i,j,a,b,c,d)
|
||
|
SaveRow(g,h)
|
||
|
Dst += DstPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (Src[p] + Dst[p] + 1) >> 1
|
||
|
void STDCALL AddBlock(uint8_t *Src, uint8_t *Dst, int SrcPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d;
|
||
|
do
|
||
|
{
|
||
|
LoadRow(a,b,0)
|
||
|
AddRow(a,b,c,d)
|
||
|
Dst += 8;
|
||
|
Src += SrcPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (((Src[p] + Src[p+1]+1) >> 1) + Dst[p] + 1) >> 1
|
||
|
void STDCALL AddBlockHor(uint8_t *Src, uint8_t *Dst, int SrcPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d;
|
||
|
do
|
||
|
{
|
||
|
LoadRow(a,b,0)
|
||
|
LoadRow(c,d,1)
|
||
|
AVG32R(a,b,c,d)
|
||
|
AddRow(a,b,c,d)
|
||
|
Dst += 8;
|
||
|
Src += SrcPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (((Src[p] + Src[p+SrcPitch]+1) >> 1) + Dst[p] + 1) >> 1
|
||
|
void STDCALL AddBlockVer(uint8_t *Src, uint8_t *Dst, int SrcPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d,e,f;
|
||
|
LoadRow(a,b,0)
|
||
|
do
|
||
|
{
|
||
|
Src += SrcPitch;
|
||
|
c=a;
|
||
|
d=b;
|
||
|
LoadRow(a,b,0)
|
||
|
e=a;
|
||
|
f=b;
|
||
|
AVG32R(c,d,e,f)
|
||
|
AddRow(c,d,e,f)
|
||
|
Dst += 8;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = (((Src[p] + Src[p+1] + Src[p+SrcPitch] + Src[p+SrcPitch+1] + 2) >> 2) + Dst[p] + 1) >> 1
|
||
|
void STDCALL AddBlockHorVer(uint8_t *Src, uint8_t *Dst, int SrcPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d,g,h,i,j;
|
||
|
LoadRow(a,b,0)
|
||
|
LoadRow(c,d,1)
|
||
|
PrepareAvg4(a,b,c,d)
|
||
|
do
|
||
|
{
|
||
|
Src += SrcPitch;
|
||
|
LoadRow(g,h,0)
|
||
|
LoadRow(i,j,1)
|
||
|
PrepareAvg4(g,h,i,j)
|
||
|
Avg4(a,b,c,d,g,h,i,j)
|
||
|
AddRow(a,b,c,d)
|
||
|
a=g;
|
||
|
b=h;
|
||
|
c=i;
|
||
|
d=j;
|
||
|
Dst += 8;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = Src[p]
|
||
|
void STDCALL CopyBlock16x16(uint8_t *Src, uint8_t *Dst, int SrcPitch,int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 16*SrcPitch;
|
||
|
uint32_t a,b,c,d;
|
||
|
do
|
||
|
{
|
||
|
a=((uint32_t*)Src)[0];
|
||
|
b=((uint32_t*)Src)[1];
|
||
|
c=((uint32_t*)Src)[2];
|
||
|
d=((uint32_t*)Src)[3];
|
||
|
((uint32_t*)Dst)[0]=a;
|
||
|
((uint32_t*)Dst)[1]=b;
|
||
|
((uint32_t*)Dst)[2]=c;
|
||
|
((uint32_t*)Dst)[3]=d;
|
||
|
Dst += DstPitch;
|
||
|
Src += SrcPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = Src[p]
|
||
|
void STDCALL CopyBlock8x8(uint8_t *Src, uint8_t *Dst, int SrcPitch,int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 8*SrcPitch;
|
||
|
uint32_t a,b,c,d;
|
||
|
do
|
||
|
{
|
||
|
a=((uint32_t*)Src)[0];
|
||
|
b=((uint32_t*)Src)[1];
|
||
|
Src += SrcPitch;
|
||
|
c=((uint32_t*)Src)[0];
|
||
|
d=((uint32_t*)Src)[1];
|
||
|
Src += SrcPitch;
|
||
|
((uint32_t*)Dst)[0]=a;
|
||
|
((uint32_t*)Dst)[1]=b;
|
||
|
Dst += DstPitch;
|
||
|
((uint32_t*)Dst)[0]=c;
|
||
|
((uint32_t*)Dst)[1]=d;
|
||
|
Dst += DstPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
// Dst[p] = Src[p]
|
||
|
void STDCALL CopyBlockM(uint8_t *Src, uint8_t *Dst, int SrcPitch, int DstPitch)
|
||
|
{
|
||
|
uint8_t *SrcEnd = Src + 16*SrcPitch;
|
||
|
uint32_t a,b,c,d;
|
||
|
do
|
||
|
{
|
||
|
LoadMRow(a,b,c,d,0)
|
||
|
SaveMRow(a,b,c,d)
|
||
|
Dst += DstPitch;
|
||
|
Src += SrcPitch;
|
||
|
}
|
||
|
while (Src != SrcEnd);
|
||
|
}
|
||
|
|
||
|
#endif
|