Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
6d4f53cb
Commit
6d4f53cb
authored
Mar 03, 2009
by
Michael Niedermayer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove old scaler.
Originally committed as revision 17786 to
svn://svn.ffmpeg.org/ffmpeg/trunk
parent
1ad1eaad
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
2 additions
and
3400 deletions
+2
-3400
Makefile
Makefile
+1
-11
cmdutils.c
cmdutils.c
+0
-2
configure
configure
+0
-14
Makefile
libavcodec/Makefile
+0
-3
imgconvert.c
libavcodec/imgconvert.c
+0
-1492
imgconvert_template.c
libavcodec/imgconvert_template.c
+0
-875
imgresample.c
libavcodec/imgresample.c
+0
-833
imgresample_altivec.c
libavcodec/ppc/imgresample_altivec.c
+0
-142
imgresample_altivec.h
libavcodec/ppc/imgresample_altivec.h
+0
-26
Makefile
libavfilter/Makefile
+1
-2
No files found.
Makefile
View file @
6d4f53cb
...
...
@@ -20,9 +20,8 @@ ALLMANPAGES = $(addsuffix .1, $(BASENAMES))
FFLIBS-$(CONFIG_AVFILTER)
+=
avfilter
FFLIBS-$(CONFIG_POSTPROC)
+=
postproc
FFLIBS-$(CONFIG_SWSCALE)
+=
swscale
FFLIBS
:=
avdevice avformat avcodec avutil
FFLIBS
:=
avdevice avformat avcodec avutil
swscale
DATA_FILES
:=
$
(
wildcard
$(SRC_DIR)
/ffpresets/
*
.ffpreset
)
...
...
@@ -236,15 +235,6 @@ LAVF_REG = tests/data/lavf.regression
ROTOZOOM_REG
=
tests/data/rotozoom.regression
VSYNTH_REG
=
tests/data/vsynth.regression
ifneq
($(CONFIG_SWSCALE),yes)
servertest codectest $(CODEC_TESTS) libavtest
:
swscale-error
swscale-error
:
@
echo
@
echo
"This regression test requires --enable-swscale."
@
echo
@
exit
1
endif
ifneq
($(CONFIG_ZLIB),yes)
regtest-flashsv codectest
:
zlib-error
endif
...
...
cmdutils.c
View file @
6d4f53cb
...
...
@@ -280,9 +280,7 @@ static void print_all_lib_versions(FILE* outstream, int indent)
#if CONFIG_AVFILTER
PRINT_LIB_VERSION
(
outstream
,
avfilter
,
AVFILTER
,
indent
);
#endif
#if CONFIG_SWSCALE
PRINT_LIB_VERSION
(
outstream
,
swscale
,
SWSCALE
,
indent
);
#endif
#if CONFIG_POSTPROC
PRINT_LIB_VERSION
(
outstream
,
postproc
,
POSTPROC
,
indent
);
#endif
...
...
configure
View file @
6d4f53cb
...
...
@@ -81,7 +81,6 @@ show_help(){
echo
" --disable-ffplay disable ffplay build"
echo
" --disable-ffserver disable ffserver build"
echo
" --enable-postproc enable GPLed postprocessing support [no]"
echo
" --enable-swscale enable GPLed software scaler support [no]"
echo
" --enable-avfilter video filter support [no]"
echo
" --enable-avfilter-lavf video filters dependent on avformat [no]"
echo
" --enable-beosthreads use BeOS threads [no]"
...
...
@@ -796,7 +795,6 @@ CONFIG_LIST="
shared
small
static
swscale
vdpau
x11grab
zlib
...
...
@@ -912,7 +910,6 @@ HAVE_LIST="
# options emitted with CONFIG_ prefix but not available on command line
CONFIG_EXTRA
=
"
oldscaler
"
CMDLINE_SELECT
=
"
...
...
@@ -980,9 +977,6 @@ sse_deps="mmx"
ssse3_deps
=
"sse"
vis_deps
=
"sparc"
# common features
oldscaler_deps
=
"!swscale"
# decoders / encoders
aac_decoder_select
=
"fft mdct"
ac3_decoder_deps
=
"gpl"
...
...
@@ -1170,7 +1164,6 @@ enable ffserver
enable
ipv6
enable
mpegaudio_hp
enable
network
enable
oldscaler
enable
optimizations
enable
protocols
enable
static
...
...
@@ -1691,7 +1684,6 @@ if ! enabled gpl; then
die_gpl_disabled
"libxvidcore"
libxvid
die_gpl_disabled
"FAAD2"
libfaad2
die_gpl_disabled
"The X11 grabber"
x11grab
die_gpl_disabled
"The software scaler"
swscale
fi
if
!
enabled nonfree
&&
enabled_any libamr_nb libamr_wb
;
then
...
...
@@ -2265,7 +2257,6 @@ echo "optimizations ${optimizations-no}"
echo
"static
${
static
-no
}
"
echo
"shared
${
shared
-no
}
"
echo
"postprocessing support
${
postproc
-no
}
"
echo
"software scaler enabled
${
swscale
-no
}
"
echo
"new filter support
${
avfilter
-no
}
"
echo
"filters using lavformat
${
avfilter_lavf
-no
}
"
echo
"network support
${
network
-no
}
"
...
...
@@ -2549,9 +2540,4 @@ enabled avfilter &&
pkgconfig_generate libavfilter
"FFmpeg video filtering library"
"
$LIBAVFILTER_VERSION
"
"
$extralibs
"
"libavutil =
$LIBAVUTIL_VERSION
"
enabled postproc
&&
pkgconfig_generate libpostproc
"FFmpeg post processing library"
"
$LIBPOSTPROC_VERSION
"
if
enabled swscale
;
then
pkgconfig_generate libswscale
"FFmpeg image rescaling library"
"
$LIBSWSCALE_VERSION
"
""
"libavutil =
$LIBAVUTIL_VERSION
"
else
pkgconfig_generate libswscale
"FFmpeg image rescaling library"
"
$LIBSWSCALE_VERSION
"
""
"libavcodec =
$LIBAVCODEC_VERSION
"
apply libswscale/libswscale.pc
sed
s/^Libs:.
*
$/
Libs:/
fi
libavcodec/Makefile
View file @
6d4f53cb
...
...
@@ -29,7 +29,6 @@ OBJS-$(CONFIG_ENCODERS) += faandct.o jfdctfst.o jfdctint.o
OBJS-$(CONFIG_FFT)
+=
fft.o
OBJS-$(CONFIG_GOLOMB)
+=
golomb.o
OBJS-$(CONFIG_MDCT)
+=
mdct.o
OBJS-$(CONFIG_OLDSCALER)
+=
imgresample.o
OBJS-$(CONFIG_RDFT)
+=
rdft.o
# decoders/encoders
...
...
@@ -494,7 +493,6 @@ OBJS-$(ARCH_BFIN) += bfin/dsputil_bfin.o \
OBJS-$(ARCH_PPC)
+=
ppc/dsputil_ppc.o
\
ALTIVEC-OBJS-$(CONFIG_H264_DECODER)
+=
ppc/h264_altivec.o
ALTIVEC-OBJS-$(CONFIG_OLDSCALER)
+=
ppc/imgresample_altivec.o
ALTIVEC-OBJS-$(CONFIG_SNOW_DECODER)
+=
ppc/snow_altivec.o
ALTIVEC-OBJS-$(CONFIG_VC1_DECODER)
+=
ppc/vc1dsp_altivec.o
ALTIVEC-OBJS-$(CONFIG_WMV3_DECODER)
+=
ppc/vc1dsp_altivec.o
...
...
@@ -525,7 +523,6 @@ OBJS-$(HAVE_VIS) += sparc/dsputil_vis.o \
TESTS
=
$
(
addsuffix
-test
$(EXESUF)
, cabac dct
eval
fft h264 rangecoder snow
)
TESTS-$(CONFIG_OLDSCALER)
+=
imgresample-test$(EXESUF)
TESTS-$(ARCH_X86)
+=
x86/cpuid-test$(EXESUF)
motion-test$(EXESUF)
CLEANFILES
=
apiexample
$(EXESUF)
...
...
libavcodec/imgconvert.c
View file @
6d4f53cb
...
...
@@ -1033,357 +1033,6 @@ void av_picture_copy(AVPicture *dst, const AVPicture *src,
}
}
/* XXX: totally non optimized */
static
void
yuyv422_to_yuv420p
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
p
,
*
p1
;
uint8_t
*
lum
,
*
cr
,
*
cb
,
*
lum1
,
*
cr1
,
*
cb1
;
int
w
;
p1
=
src
->
data
[
0
];
lum1
=
dst
->
data
[
0
];
cb1
=
dst
->
data
[
1
];
cr1
=
dst
->
data
[
2
];
for
(;
height
>=
1
;
height
-=
2
)
{
p
=
p1
;
lum
=
lum1
;
cb
=
cb1
;
cr
=
cr1
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
lum
[
0
]
=
p
[
0
];
cb
[
0
]
=
p
[
1
];
lum
[
1
]
=
p
[
2
];
cr
[
0
]
=
p
[
3
];
p
+=
4
;
lum
+=
2
;
cb
++
;
cr
++
;
}
if
(
w
)
{
lum
[
0
]
=
p
[
0
];
cb
[
0
]
=
p
[
1
];
cr
[
0
]
=
p
[
3
];
cb
++
;
cr
++
;
}
p1
+=
src
->
linesize
[
0
];
lum1
+=
dst
->
linesize
[
0
];
if
(
height
>
1
)
{
p
=
p1
;
lum
=
lum1
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
lum
[
0
]
=
p
[
0
];
lum
[
1
]
=
p
[
2
];
p
+=
4
;
lum
+=
2
;
}
if
(
w
)
{
lum
[
0
]
=
p
[
0
];
}
p1
+=
src
->
linesize
[
0
];
lum1
+=
dst
->
linesize
[
0
];
}
cb1
+=
dst
->
linesize
[
1
];
cr1
+=
dst
->
linesize
[
2
];
}
}
static
void
uyvy422_to_yuv420p
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
p
,
*
p1
;
uint8_t
*
lum
,
*
cr
,
*
cb
,
*
lum1
,
*
cr1
,
*
cb1
;
int
w
;
p1
=
src
->
data
[
0
];
lum1
=
dst
->
data
[
0
];
cb1
=
dst
->
data
[
1
];
cr1
=
dst
->
data
[
2
];
for
(;
height
>=
1
;
height
-=
2
)
{
p
=
p1
;
lum
=
lum1
;
cb
=
cb1
;
cr
=
cr1
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
lum
[
0
]
=
p
[
1
];
cb
[
0
]
=
p
[
0
];
lum
[
1
]
=
p
[
3
];
cr
[
0
]
=
p
[
2
];
p
+=
4
;
lum
+=
2
;
cb
++
;
cr
++
;
}
if
(
w
)
{
lum
[
0
]
=
p
[
1
];
cb
[
0
]
=
p
[
0
];
cr
[
0
]
=
p
[
2
];
cb
++
;
cr
++
;
}
p1
+=
src
->
linesize
[
0
];
lum1
+=
dst
->
linesize
[
0
];
if
(
height
>
1
)
{
p
=
p1
;
lum
=
lum1
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
lum
[
0
]
=
p
[
1
];
lum
[
1
]
=
p
[
3
];
p
+=
4
;
lum
+=
2
;
}
if
(
w
)
{
lum
[
0
]
=
p
[
1
];
}
p1
+=
src
->
linesize
[
0
];
lum1
+=
dst
->
linesize
[
0
];
}
cb1
+=
dst
->
linesize
[
1
];
cr1
+=
dst
->
linesize
[
2
];
}
}
static
void
uyvy422_to_yuv422p
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
p
,
*
p1
;
uint8_t
*
lum
,
*
cr
,
*
cb
,
*
lum1
,
*
cr1
,
*
cb1
;
int
w
;
p1
=
src
->
data
[
0
];
lum1
=
dst
->
data
[
0
];
cb1
=
dst
->
data
[
1
];
cr1
=
dst
->
data
[
2
];
for
(;
height
>
0
;
height
--
)
{
p
=
p1
;
lum
=
lum1
;
cb
=
cb1
;
cr
=
cr1
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
lum
[
0
]
=
p
[
1
];
cb
[
0
]
=
p
[
0
];
lum
[
1
]
=
p
[
3
];
cr
[
0
]
=
p
[
2
];
p
+=
4
;
lum
+=
2
;
cb
++
;
cr
++
;
}
p1
+=
src
->
linesize
[
0
];
lum1
+=
dst
->
linesize
[
0
];
cb1
+=
dst
->
linesize
[
1
];
cr1
+=
dst
->
linesize
[
2
];
}
}
static
void
yuyv422_to_yuv422p
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
p
,
*
p1
;
uint8_t
*
lum
,
*
cr
,
*
cb
,
*
lum1
,
*
cr1
,
*
cb1
;
int
w
;
p1
=
src
->
data
[
0
];
lum1
=
dst
->
data
[
0
];
cb1
=
dst
->
data
[
1
];
cr1
=
dst
->
data
[
2
];
for
(;
height
>
0
;
height
--
)
{
p
=
p1
;
lum
=
lum1
;
cb
=
cb1
;
cr
=
cr1
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
lum
[
0
]
=
p
[
0
];
cb
[
0
]
=
p
[
1
];
lum
[
1
]
=
p
[
2
];
cr
[
0
]
=
p
[
3
];
p
+=
4
;
lum
+=
2
;
cb
++
;
cr
++
;
}
p1
+=
src
->
linesize
[
0
];
lum1
+=
dst
->
linesize
[
0
];
cb1
+=
dst
->
linesize
[
1
];
cr1
+=
dst
->
linesize
[
2
];
}
}
static
void
yuv422p_to_yuyv422
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
uint8_t
*
p
,
*
p1
;
const
uint8_t
*
lum
,
*
cr
,
*
cb
,
*
lum1
,
*
cr1
,
*
cb1
;
int
w
;
p1
=
dst
->
data
[
0
];
lum1
=
src
->
data
[
0
];
cb1
=
src
->
data
[
1
];
cr1
=
src
->
data
[
2
];
for
(;
height
>
0
;
height
--
)
{
p
=
p1
;
lum
=
lum1
;
cb
=
cb1
;
cr
=
cr1
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
p
[
0
]
=
lum
[
0
];
p
[
1
]
=
cb
[
0
];
p
[
2
]
=
lum
[
1
];
p
[
3
]
=
cr
[
0
];
p
+=
4
;
lum
+=
2
;
cb
++
;
cr
++
;
}
p1
+=
dst
->
linesize
[
0
];
lum1
+=
src
->
linesize
[
0
];
cb1
+=
src
->
linesize
[
1
];
cr1
+=
src
->
linesize
[
2
];
}
}
static
void
yuv422p_to_uyvy422
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
uint8_t
*
p
,
*
p1
;
const
uint8_t
*
lum
,
*
cr
,
*
cb
,
*
lum1
,
*
cr1
,
*
cb1
;
int
w
;
p1
=
dst
->
data
[
0
];
lum1
=
src
->
data
[
0
];
cb1
=
src
->
data
[
1
];
cr1
=
src
->
data
[
2
];
for
(;
height
>
0
;
height
--
)
{
p
=
p1
;
lum
=
lum1
;
cb
=
cb1
;
cr
=
cr1
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
p
[
1
]
=
lum
[
0
];
p
[
0
]
=
cb
[
0
];
p
[
3
]
=
lum
[
1
];
p
[
2
]
=
cr
[
0
];
p
+=
4
;
lum
+=
2
;
cb
++
;
cr
++
;
}
p1
+=
dst
->
linesize
[
0
];
lum1
+=
src
->
linesize
[
0
];
cb1
+=
src
->
linesize
[
1
];
cr1
+=
src
->
linesize
[
2
];
}
}
static
void
uyyvyy411_to_yuv411p
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
p
,
*
p1
;
uint8_t
*
lum
,
*
cr
,
*
cb
,
*
lum1
,
*
cr1
,
*
cb1
;
int
w
;
p1
=
src
->
data
[
0
];
lum1
=
dst
->
data
[
0
];
cb1
=
dst
->
data
[
1
];
cr1
=
dst
->
data
[
2
];
for
(;
height
>
0
;
height
--
)
{
p
=
p1
;
lum
=
lum1
;
cb
=
cb1
;
cr
=
cr1
;
for
(
w
=
width
;
w
>=
4
;
w
-=
4
)
{
cb
[
0
]
=
p
[
0
];
lum
[
0
]
=
p
[
1
];
lum
[
1
]
=
p
[
2
];
cr
[
0
]
=
p
[
3
];
lum
[
2
]
=
p
[
4
];
lum
[
3
]
=
p
[
5
];
p
+=
6
;
lum
+=
4
;
cb
++
;
cr
++
;
}
p1
+=
src
->
linesize
[
0
];
lum1
+=
dst
->
linesize
[
0
];
cb1
+=
dst
->
linesize
[
1
];
cr1
+=
dst
->
linesize
[
2
];
}
}
static
void
yuv420p_to_yuyv422
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
w
,
h
;
uint8_t
*
line1
,
*
line2
,
*
linesrc
=
dst
->
data
[
0
];
uint8_t
*
lum1
,
*
lum2
,
*
lumsrc
=
src
->
data
[
0
];
uint8_t
*
cb1
,
*
cb2
=
src
->
data
[
1
];
uint8_t
*
cr1
,
*
cr2
=
src
->
data
[
2
];
for
(
h
=
height
/
2
;
h
--
;)
{
line1
=
linesrc
;
line2
=
linesrc
+
dst
->
linesize
[
0
];
lum1
=
lumsrc
;
lum2
=
lumsrc
+
src
->
linesize
[
0
];
cb1
=
cb2
;
cr1
=
cr2
;
for
(
w
=
width
/
2
;
w
--
;)
{
*
line1
++
=
*
lum1
++
;
*
line2
++
=
*
lum2
++
;
*
line1
++
=
*
line2
++
=
*
cb1
++
;
*
line1
++
=
*
lum1
++
;
*
line2
++
=
*
lum2
++
;
*
line1
++
=
*
line2
++
=
*
cr1
++
;
}
linesrc
+=
dst
->
linesize
[
0
]
*
2
;
lumsrc
+=
src
->
linesize
[
0
]
*
2
;
cb2
+=
src
->
linesize
[
1
];
cr2
+=
src
->
linesize
[
2
];
}
}
static
void
yuv420p_to_uyvy422
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
w
,
h
;
uint8_t
*
line1
,
*
line2
,
*
linesrc
=
dst
->
data
[
0
];
uint8_t
*
lum1
,
*
lum2
,
*
lumsrc
=
src
->
data
[
0
];
uint8_t
*
cb1
,
*
cb2
=
src
->
data
[
1
];
uint8_t
*
cr1
,
*
cr2
=
src
->
data
[
2
];
for
(
h
=
height
/
2
;
h
--
;)
{
line1
=
linesrc
;
line2
=
linesrc
+
dst
->
linesize
[
0
];
lum1
=
lumsrc
;
lum2
=
lumsrc
+
src
->
linesize
[
0
];
cb1
=
cb2
;
cr1
=
cr2
;
for
(
w
=
width
/
2
;
w
--
;)
{
*
line1
++
=
*
line2
++
=
*
cb1
++
;
*
line1
++
=
*
lum1
++
;
*
line2
++
=
*
lum2
++
;
*
line1
++
=
*
line2
++
=
*
cr1
++
;
*
line1
++
=
*
lum1
++
;
*
line2
++
=
*
lum2
++
;
}
linesrc
+=
dst
->
linesize
[
0
]
*
2
;
lumsrc
+=
src
->
linesize
[
0
]
*
2
;
cb2
+=
src
->
linesize
[
1
];
cr2
+=
src
->
linesize
[
2
];
}
}
/* 2x2 -> 1x1 */
void
ff_shrink22
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
...
...
@@ -1470,622 +1119,6 @@ void ff_shrink88(uint8_t *dst, int dst_wrap,
}
}
/* XXX: add jpeg quantize code */
#define TRANSP_INDEX (6*6*6)
/* this is maybe slow, but allows for extensions */
static
inline
unsigned
char
gif_clut_index
(
uint8_t
r
,
uint8_t
g
,
uint8_t
b
)
{
return
(((
r
)
/
47
)
%
6
)
*
6
*
6
+
(((
g
)
/
47
)
%
6
)
*
6
+
(((
b
)
/
47
)
%
6
);
}
static
void
build_rgb_palette
(
uint8_t
*
palette
,
int
has_alpha
)
{
uint32_t
*
pal
;
static
const
uint8_t
pal_value
[
6
]
=
{
0x00
,
0x33
,
0x66
,
0x99
,
0xcc
,
0xff
};
int
i
,
r
,
g
,
b
;
pal
=
(
uint32_t
*
)
palette
;
i
=
0
;
for
(
r
=
0
;
r
<
6
;
r
++
)
{
for
(
g
=
0
;
g
<
6
;
g
++
)
{
for
(
b
=
0
;
b
<
6
;
b
++
)
{
pal
[
i
++
]
=
(
0xff
<<
24
)
|
(
pal_value
[
r
]
<<
16
)
|
(
pal_value
[
g
]
<<
8
)
|
pal_value
[
b
];
}
}
}
if
(
has_alpha
)
pal
[
i
++
]
=
0
;
while
(
i
<
256
)
pal
[
i
++
]
=
0xff000000
;
}
/* copy bit n to bits 0 ... n - 1 */
static
inline
unsigned
int
bitcopy_n
(
unsigned
int
a
,
int
n
)
{
int
mask
;
mask
=
(
1
<<
n
)
-
1
;
return
(
a
&
(
0xff
&
~
mask
))
|
((
-
((
a
>>
n
)
&
1
))
&
mask
);
}
/* rgb555 handling */
#define RGB_NAME rgb555
#define RGB_IN(r, g, b, s)\
{\
unsigned int v = ((const uint16_t *)(s))[0];\
r = bitcopy_n(v >> (10 - 3), 3);\
g = bitcopy_n(v >> (5 - 3), 3);\
b = bitcopy_n(v << 3, 3);\
}
#define RGB_OUT(d, r, g, b)\
{\
((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
}
#define BPP 2
#include "imgconvert_template.c"
/* rgb565 handling */
#define RGB_NAME rgb565
#define RGB_IN(r, g, b, s)\
{\
unsigned int v = ((const uint16_t *)(s))[0];\
r = bitcopy_n(v >> (11 - 3), 3);\
g = bitcopy_n(v >> (5 - 2), 2);\
b = bitcopy_n(v << 3, 3);\
}
#define RGB_OUT(d, r, g, b)\
{\
((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
}
#define BPP 2
#include "imgconvert_template.c"
/* bgr24 handling */
#define RGB_NAME bgr24
#define RGB_IN(r, g, b, s)\
{\
b = (s)[0];\
g = (s)[1];\
r = (s)[2];\
}
#define RGB_OUT(d, r, g, b)\
{\
(d)[0] = b;\
(d)[1] = g;\
(d)[2] = r;\
}
#define BPP 3
#include "imgconvert_template.c"
#undef RGB_IN
#undef RGB_OUT
#undef BPP
/* rgb24 handling */
#define RGB_NAME rgb24
#define FMT_RGB24
#define RGB_IN(r, g, b, s)\
{\
r = (s)[0];\
g = (s)[1];\
b = (s)[2];\
}
#define RGB_OUT(d, r, g, b)\
{\
(d)[0] = r;\
(d)[1] = g;\
(d)[2] = b;\
}
#define BPP 3
#include "imgconvert_template.c"
/* rgb32 handling */
#define RGB_NAME rgb32
#define FMT_RGB32
#define RGB_IN(r, g, b, s)\
{\
unsigned int v = ((const uint32_t *)(s))[0];\
r = (v >> 16) & 0xff;\
g = (v >> 8) & 0xff;\
b = v & 0xff;\
}
#define RGBA_IN(r, g, b, a, s)\
{\
unsigned int v = ((const uint32_t *)(s))[0];\
a = (v >> 24) & 0xff;\
r = (v >> 16) & 0xff;\
g = (v >> 8) & 0xff;\
b = v & 0xff;\
}
#define RGBA_OUT(d, r, g, b, a)\
{\
((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
}
#define BPP 4
#include "imgconvert_template.c"
static
void
mono_to_gray
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
,
int
xor_mask
)
{
const
unsigned
char
*
p
;
unsigned
char
*
q
;
int
v
,
dst_wrap
,
src_wrap
;
int
y
,
w
;
p
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
((
width
+
7
)
>>
3
);
q
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
w
=
width
;
while
(
w
>=
8
)
{
v
=
*
p
++
^
xor_mask
;
q
[
0
]
=
-
(
v
>>
7
);
q
[
1
]
=
-
((
v
>>
6
)
&
1
);
q
[
2
]
=
-
((
v
>>
5
)
&
1
);
q
[
3
]
=
-
((
v
>>
4
)
&
1
);
q
[
4
]
=
-
((
v
>>
3
)
&
1
);
q
[
5
]
=
-
((
v
>>
2
)
&
1
);
q
[
6
]
=
-
((
v
>>
1
)
&
1
);
q
[
7
]
=
-
((
v
>>
0
)
&
1
);
w
-=
8
;
q
+=
8
;
}
if
(
w
>
0
)
{
v
=
*
p
++
^
xor_mask
;
do
{
q
[
0
]
=
-
((
v
>>
7
)
&
1
);
q
++
;
v
<<=
1
;
}
while
(
--
w
);
}
p
+=
src_wrap
;
q
+=
dst_wrap
;
}
}
static
void
monowhite_to_gray
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
mono_to_gray
(
dst
,
src
,
width
,
height
,
0xff
);
}
static
void
monoblack_to_gray
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
mono_to_gray
(
dst
,
src
,
width
,
height
,
0x00
);
}
static
void
gray_to_mono
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
,
int
xor_mask
)
{
int
n
;
const
uint8_t
*
s
;
uint8_t
*
d
;
int
j
,
b
,
v
,
n1
,
src_wrap
,
dst_wrap
,
y
;
s
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
;
d
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
((
width
+
7
)
>>
3
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
n
=
width
;
while
(
n
>=
8
)
{
v
=
0
;
for
(
j
=
0
;
j
<
8
;
j
++
)
{
b
=
s
[
0
];
s
++
;
v
=
(
v
<<
1
)
|
(
b
>>
7
);
}
d
[
0
]
=
v
^
xor_mask
;
d
++
;
n
-=
8
;
}
if
(
n
>
0
)
{
n1
=
n
;
v
=
0
;
while
(
n
>
0
)
{
b
=
s
[
0
];
s
++
;
v
=
(
v
<<
1
)
|
(
b
>>
7
);
n
--
;
}
d
[
0
]
=
(
v
<<
(
8
-
(
n1
&
7
)))
^
xor_mask
;
d
++
;
}
s
+=
src_wrap
;
d
+=
dst_wrap
;
}
}
static
void
gray_to_monowhite
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
gray_to_mono
(
dst
,
src
,
width
,
height
,
0xff
);
}
static
void
gray_to_monoblack
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
gray_to_mono
(
dst
,
src
,
width
,
height
,
0x00
);
}
static
void
gray_to_gray16
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
x
,
y
,
src_wrap
,
dst_wrap
;
uint8_t
*
s
,
*
d
;
s
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
;
d
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
*
2
;
for
(
y
=
0
;
y
<
height
;
y
++
){
for
(
x
=
0
;
x
<
width
;
x
++
){
*
d
++
=
*
s
;
*
d
++
=
*
s
++
;
}
s
+=
src_wrap
;
d
+=
dst_wrap
;
}
}
static
void
gray16_to_gray
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
x
,
y
,
src_wrap
,
dst_wrap
;
uint8_t
*
s
,
*
d
;
s
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
*
2
;
d
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
;
for
(
y
=
0
;
y
<
height
;
y
++
){
for
(
x
=
0
;
x
<
width
;
x
++
){
*
d
++
=
*
s
;
s
+=
2
;
}
s
+=
src_wrap
;
d
+=
dst_wrap
;
}
}
static
void
gray16be_to_gray
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
gray16_to_gray
(
dst
,
src
,
width
,
height
);
}
static
void
gray16le_to_gray
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
AVPicture
tmpsrc
=
*
src
;
tmpsrc
.
data
[
0
]
++
;
gray16_to_gray
(
dst
,
&
tmpsrc
,
width
,
height
);
}
static
void
gray16_to_gray16
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
x
,
y
,
src_wrap
,
dst_wrap
;
uint16_t
*
s
,
*
d
;
s
=
(
uint16_t
*
)
src
->
data
[
0
];
src_wrap
=
(
src
->
linesize
[
0
]
-
width
*
2
)
/
2
;
d
=
(
uint16_t
*
)
dst
->
data
[
0
];
dst_wrap
=
(
dst
->
linesize
[
0
]
-
width
*
2
)
/
2
;
for
(
y
=
0
;
y
<
height
;
y
++
){
for
(
x
=
0
;
x
<
width
;
x
++
){
*
d
++
=
bswap_16
(
*
s
++
);
}
s
+=
src_wrap
;
d
+=
dst_wrap
;
}
}
typedef
struct
ConvertEntry
{
void
(
*
convert
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
);
}
ConvertEntry
;
/* Add each new conversion function in this table. In order to be able
to convert from any format to any format, the following constraints
must be satisfied:
- all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
- all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
- all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
- PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
PIX_FMT_RGB24.
- PIX_FMT_422 must convert to and from PIX_FMT_422P.
The other conversion functions are just optimizations for common cases.
*/
static
const
ConvertEntry
convert_table
[
PIX_FMT_NB
][
PIX_FMT_NB
]
=
{
[
PIX_FMT_YUV420P
]
=
{
[
PIX_FMT_YUYV422
]
=
{
.
convert
=
yuv420p_to_yuyv422
,
},
[
PIX_FMT_RGB555
]
=
{
.
convert
=
yuv420p_to_rgb555
},
[
PIX_FMT_RGB565
]
=
{
.
convert
=
yuv420p_to_rgb565
},
[
PIX_FMT_BGR24
]
=
{
.
convert
=
yuv420p_to_bgr24
},
[
PIX_FMT_RGB24
]
=
{
.
convert
=
yuv420p_to_rgb24
},
[
PIX_FMT_RGB32
]
=
{
.
convert
=
yuv420p_to_rgb32
},
[
PIX_FMT_UYVY422
]
=
{
.
convert
=
yuv420p_to_uyvy422
,
},
},
[
PIX_FMT_YUV422P
]
=
{
[
PIX_FMT_YUYV422
]
=
{
.
convert
=
yuv422p_to_yuyv422
,
},
[
PIX_FMT_UYVY422
]
=
{
.
convert
=
yuv422p_to_uyvy422
,
},
},
[
PIX_FMT_YUV444P
]
=
{
[
PIX_FMT_RGB24
]
=
{
.
convert
=
yuv444p_to_rgb24
},
},
[
PIX_FMT_YUVJ420P
]
=
{
[
PIX_FMT_RGB555
]
=
{
.
convert
=
yuvj420p_to_rgb555
},
[
PIX_FMT_RGB565
]
=
{
.
convert
=
yuvj420p_to_rgb565
},
[
PIX_FMT_BGR24
]
=
{
.
convert
=
yuvj420p_to_bgr24
},
[
PIX_FMT_RGB24
]
=
{
.
convert
=
yuvj420p_to_rgb24
},
[
PIX_FMT_RGB32
]
=
{
.
convert
=
yuvj420p_to_rgb32
},
},
[
PIX_FMT_YUVJ444P
]
=
{
[
PIX_FMT_RGB24
]
=
{
.
convert
=
yuvj444p_to_rgb24
},
},
[
PIX_FMT_YUYV422
]
=
{
[
PIX_FMT_YUV420P
]
=
{
.
convert
=
yuyv422_to_yuv420p
,
},
[
PIX_FMT_YUV422P
]
=
{
.
convert
=
yuyv422_to_yuv422p
,
},
},
[
PIX_FMT_UYVY422
]
=
{
[
PIX_FMT_YUV420P
]
=
{
.
convert
=
uyvy422_to_yuv420p
,
},
[
PIX_FMT_YUV422P
]
=
{
.
convert
=
uyvy422_to_yuv422p
,
},
},
[
PIX_FMT_RGB24
]
=
{
[
PIX_FMT_YUV420P
]
=
{
.
convert
=
rgb24_to_yuv420p
},
[
PIX_FMT_RGB565
]
=
{
.
convert
=
rgb24_to_rgb565
},
[
PIX_FMT_RGB555
]
=
{
.
convert
=
rgb24_to_rgb555
},
[
PIX_FMT_RGB32
]
=
{
.
convert
=
rgb24_to_rgb32
},
[
PIX_FMT_BGR24
]
=
{
.
convert
=
rgb24_to_bgr24
},
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
rgb24_to_gray
},
[
PIX_FMT_PAL8
]
=
{
.
convert
=
rgb24_to_pal8
},
[
PIX_FMT_YUV444P
]
=
{
.
convert
=
rgb24_to_yuv444p
},
[
PIX_FMT_YUVJ420P
]
=
{
.
convert
=
rgb24_to_yuvj420p
},
[
PIX_FMT_YUVJ444P
]
=
{
.
convert
=
rgb24_to_yuvj444p
},
},
[
PIX_FMT_RGB32
]
=
{
[
PIX_FMT_RGB24
]
=
{
.
convert
=
rgb32_to_rgb24
},
[
PIX_FMT_BGR24
]
=
{
.
convert
=
rgb32_to_bgr24
},
[
PIX_FMT_RGB565
]
=
{
.
convert
=
rgb32_to_rgb565
},
[
PIX_FMT_RGB555
]
=
{
.
convert
=
rgb32_to_rgb555
},
[
PIX_FMT_PAL8
]
=
{
.
convert
=
rgb32_to_pal8
},
[
PIX_FMT_YUV420P
]
=
{
.
convert
=
rgb32_to_yuv420p
},
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
rgb32_to_gray
},
},
[
PIX_FMT_BGR24
]
=
{
[
PIX_FMT_RGB32
]
=
{
.
convert
=
bgr24_to_rgb32
},
[
PIX_FMT_RGB24
]
=
{
.
convert
=
bgr24_to_rgb24
},
[
PIX_FMT_YUV420P
]
=
{
.
convert
=
bgr24_to_yuv420p
},
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
bgr24_to_gray
},
},
[
PIX_FMT_RGB555
]
=
{
[
PIX_FMT_RGB24
]
=
{
.
convert
=
rgb555_to_rgb24
},
[
PIX_FMT_RGB32
]
=
{
.
convert
=
rgb555_to_rgb32
},
[
PIX_FMT_YUV420P
]
=
{
.
convert
=
rgb555_to_yuv420p
},
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
rgb555_to_gray
},
},
[
PIX_FMT_RGB565
]
=
{
[
PIX_FMT_RGB32
]
=
{
.
convert
=
rgb565_to_rgb32
},
[
PIX_FMT_RGB24
]
=
{
.
convert
=
rgb565_to_rgb24
},
[
PIX_FMT_YUV420P
]
=
{
.
convert
=
rgb565_to_yuv420p
},
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
rgb565_to_gray
},
},
[
PIX_FMT_GRAY16BE
]
=
{
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
gray16be_to_gray
},
[
PIX_FMT_GRAY16LE
]
=
{
.
convert
=
gray16_to_gray16
},
},
[
PIX_FMT_GRAY16LE
]
=
{
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
gray16le_to_gray
},
[
PIX_FMT_GRAY16BE
]
=
{
.
convert
=
gray16_to_gray16
},
},
[
PIX_FMT_GRAY8
]
=
{
[
PIX_FMT_RGB555
]
=
{
.
convert
=
gray_to_rgb555
},
[
PIX_FMT_RGB565
]
=
{
.
convert
=
gray_to_rgb565
},
[
PIX_FMT_RGB24
]
=
{
.
convert
=
gray_to_rgb24
},
[
PIX_FMT_BGR24
]
=
{
.
convert
=
gray_to_bgr24
},
[
PIX_FMT_RGB32
]
=
{
.
convert
=
gray_to_rgb32
},
[
PIX_FMT_MONOWHITE
]
=
{
.
convert
=
gray_to_monowhite
},
[
PIX_FMT_MONOBLACK
]
=
{
.
convert
=
gray_to_monoblack
},
[
PIX_FMT_GRAY16LE
]
=
{
.
convert
=
gray_to_gray16
},
[
PIX_FMT_GRAY16BE
]
=
{
.
convert
=
gray_to_gray16
},
},
[
PIX_FMT_MONOWHITE
]
=
{
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
monowhite_to_gray
},
},
[
PIX_FMT_MONOBLACK
]
=
{
[
PIX_FMT_GRAY8
]
=
{
.
convert
=
monoblack_to_gray
},
},
[
PIX_FMT_PAL8
]
=
{
[
PIX_FMT_RGB555
]
=
{
.
convert
=
pal8_to_rgb555
},
[
PIX_FMT_RGB565
]
=
{
.
convert
=
pal8_to_rgb565
},
[
PIX_FMT_BGR24
]
=
{
.
convert
=
pal8_to_bgr24
},
[
PIX_FMT_RGB24
]
=
{
.
convert
=
pal8_to_rgb24
},
[
PIX_FMT_RGB32
]
=
{
.
convert
=
pal8_to_rgb32
},
},
[
PIX_FMT_UYYVYY411
]
=
{
[
PIX_FMT_YUV411P
]
=
{
.
convert
=
uyyvyy411_to_yuv411p
,
},
},
};
int
avpicture_alloc
(
AVPicture
*
picture
,
int
pix_fmt
,
int
width
,
int
height
)
...
...
@@ -2204,528 +1237,6 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
return
0
;
}
#if !CONFIG_SWSCALE
static
uint8_t
y_ccir_to_jpeg
[
256
];
static
uint8_t
y_jpeg_to_ccir
[
256
];
static
uint8_t
c_ccir_to_jpeg
[
256
];
static
uint8_t
c_jpeg_to_ccir
[
256
];
/* init various conversion tables */
static
av_cold
void
img_convert_init
(
void
)
{
int
i
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
y_ccir_to_jpeg
[
i
]
=
Y_CCIR_TO_JPEG
(
i
);
y_jpeg_to_ccir
[
i
]
=
Y_JPEG_TO_CCIR
(
i
);
c_ccir_to_jpeg
[
i
]
=
C_CCIR_TO_JPEG
(
i
);
c_jpeg_to_ccir
[
i
]
=
C_JPEG_TO_CCIR
(
i
);
}
}
/* apply to each pixel the given table */
static
void
img_apply_table
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
,
const
uint8_t
*
table1
)
{
int
n
;
const
uint8_t
*
s
;
uint8_t
*
d
;
const
uint8_t
*
table
;
table
=
table1
;
for
(;
height
>
0
;
height
--
)
{
s
=
src
;
d
=
dst
;
n
=
width
;
while
(
n
>=
4
)
{
d
[
0
]
=
table
[
s
[
0
]];
d
[
1
]
=
table
[
s
[
1
]];
d
[
2
]
=
table
[
s
[
2
]];
d
[
3
]
=
table
[
s
[
3
]];
d
+=
4
;
s
+=
4
;
n
-=
4
;
}
while
(
n
>
0
)
{
d
[
0
]
=
table
[
s
[
0
]];
d
++
;
s
++
;
n
--
;
}
dst
+=
dst_wrap
;
src
+=
src_wrap
;
}
}
/* XXX: use generic filter ? */
/* XXX: in most cases, the sampling position is incorrect */
/* 4x1 -> 1x1 */
static
void
shrink41
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
int
w
;
const
uint8_t
*
s
;
uint8_t
*
d
;
for
(;
height
>
0
;
height
--
)
{
s
=
src
;
d
=
dst
;
for
(
w
=
width
;
w
>
0
;
w
--
)
{
d
[
0
]
=
(
s
[
0
]
+
s
[
1
]
+
s
[
2
]
+
s
[
3
]
+
2
)
>>
2
;
s
+=
4
;
d
++
;
}
src
+=
src_wrap
;
dst
+=
dst_wrap
;
}
}
/* 2x1 -> 1x1 */
static
void
shrink21
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
int
w
;
const
uint8_t
*
s
;
uint8_t
*
d
;
for
(;
height
>
0
;
height
--
)
{
s
=
src
;
d
=
dst
;
for
(
w
=
width
;
w
>
0
;
w
--
)
{
d
[
0
]
=
(
s
[
0
]
+
s
[
1
])
>>
1
;
s
+=
2
;
d
++
;
}
src
+=
src_wrap
;
dst
+=
dst_wrap
;
}
}
/* 1x2 -> 1x1 */
static
void
shrink12
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
int
w
;
uint8_t
*
d
;
const
uint8_t
*
s1
,
*
s2
;
for
(;
height
>
0
;
height
--
)
{
s1
=
src
;
s2
=
s1
+
src_wrap
;
d
=
dst
;
for
(
w
=
width
;
w
>=
4
;
w
-=
4
)
{
d
[
0
]
=
(
s1
[
0
]
+
s2
[
0
])
>>
1
;
d
[
1
]
=
(
s1
[
1
]
+
s2
[
1
])
>>
1
;
d
[
2
]
=
(
s1
[
2
]
+
s2
[
2
])
>>
1
;
d
[
3
]
=
(
s1
[
3
]
+
s2
[
3
])
>>
1
;
s1
+=
4
;
s2
+=
4
;
d
+=
4
;
}
for
(;
w
>
0
;
w
--
)
{
d
[
0
]
=
(
s1
[
0
]
+
s2
[
0
])
>>
1
;
s1
++
;
s2
++
;
d
++
;
}
src
+=
2
*
src_wrap
;
dst
+=
dst_wrap
;
}
}
static
void
grow21_line
(
uint8_t
*
dst
,
const
uint8_t
*
src
,
int
width
)
{
int
w
;
const
uint8_t
*
s1
;
uint8_t
*
d
;
s1
=
src
;
d
=
dst
;
for
(
w
=
width
;
w
>=
4
;
w
-=
4
)
{
d
[
1
]
=
d
[
0
]
=
s1
[
0
];
d
[
3
]
=
d
[
2
]
=
s1
[
1
];
s1
+=
2
;
d
+=
4
;
}
for
(;
w
>=
2
;
w
-=
2
)
{
d
[
1
]
=
d
[
0
]
=
s1
[
0
];
s1
++
;
d
+=
2
;
}
/* only needed if width is not a multiple of two */
/* XXX: veryfy that */
if
(
w
)
{
d
[
0
]
=
s1
[
0
];
}
}
static
void
grow41_line
(
uint8_t
*
dst
,
const
uint8_t
*
src
,
int
width
)
{
int
w
,
v
;
const
uint8_t
*
s1
;
uint8_t
*
d
;
s1
=
src
;
d
=
dst
;
for
(
w
=
width
;
w
>=
4
;
w
-=
4
)
{
v
=
s1
[
0
];
d
[
0
]
=
v
;
d
[
1
]
=
v
;
d
[
2
]
=
v
;
d
[
3
]
=
v
;
s1
++
;
d
+=
4
;
}
}
/* 1x1 -> 2x1 */
static
void
grow21
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
for
(;
height
>
0
;
height
--
)
{
grow21_line
(
dst
,
src
,
width
);
src
+=
src_wrap
;
dst
+=
dst_wrap
;
}
}
/* 1x1 -> 1x2 */
static
void
grow12
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
for
(;
height
>
0
;
height
-=
2
)
{
memcpy
(
dst
,
src
,
width
);
dst
+=
dst_wrap
;
memcpy
(
dst
,
src
,
width
);
dst
+=
dst_wrap
;
src
+=
src_wrap
;
}
}
/* 1x1 -> 2x2 */
static
void
grow22
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
for
(;
height
>
0
;
height
--
)
{
grow21_line
(
dst
,
src
,
width
);
if
(
height
%
2
)
src
+=
src_wrap
;
dst
+=
dst_wrap
;
}
}
/* 1x1 -> 4x1 */
static
void
grow41
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
for
(;
height
>
0
;
height
--
)
{
grow41_line
(
dst
,
src
,
width
);
src
+=
src_wrap
;
dst
+=
dst_wrap
;
}
}
/* 1x1 -> 4x4 */
static
void
grow44
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
for
(;
height
>
0
;
height
--
)
{
grow41_line
(
dst
,
src
,
width
);
if
((
height
&
3
)
==
1
)
src
+=
src_wrap
;
dst
+=
dst_wrap
;
}
}
/* 1x2 -> 2x1 */
static
void
conv411
(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
)
{
int
w
,
c
;
const
uint8_t
*
s1
,
*
s2
;
uint8_t
*
d
;
width
>>=
1
;
for
(;
height
>
0
;
height
--
)
{
s1
=
src
;
s2
=
src
+
src_wrap
;
d
=
dst
;
for
(
w
=
width
;
w
>
0
;
w
--
)
{
c
=
(
s1
[
0
]
+
s2
[
0
])
>>
1
;
d
[
0
]
=
c
;
d
[
1
]
=
c
;
s1
++
;
s2
++
;
d
+=
2
;
}
src
+=
src_wrap
*
2
;
dst
+=
dst_wrap
;
}
}
/* XXX: always use linesize. Return -1 if not supported */
int
img_convert
(
AVPicture
*
dst
,
int
dst_pix_fmt
,
const
AVPicture
*
src
,
int
src_pix_fmt
,
int
src_width
,
int
src_height
)
{
static
int
initialized
;
int
i
,
ret
,
dst_width
,
dst_height
,
int_pix_fmt
;
const
PixFmtInfo
*
src_pix
,
*
dst_pix
;
const
ConvertEntry
*
ce
;
AVPicture
tmp1
,
*
tmp
=
&
tmp1
;
if
(
src_pix_fmt
<
0
||
src_pix_fmt
>=
PIX_FMT_NB
||
dst_pix_fmt
<
0
||
dst_pix_fmt
>=
PIX_FMT_NB
)
return
-
1
;
if
(
src_width
<=
0
||
src_height
<=
0
)
return
0
;
if
(
!
initialized
)
{
initialized
=
1
;
img_convert_init
();
}
dst_width
=
src_width
;
dst_height
=
src_height
;
dst_pix
=
&
pix_fmt_info
[
dst_pix_fmt
];
src_pix
=
&
pix_fmt_info
[
src_pix_fmt
];
if
(
src_pix_fmt
==
dst_pix_fmt
)
{
/* no conversion needed: just copy */
av_picture_copy
(
dst
,
src
,
dst_pix_fmt
,
dst_width
,
dst_height
);
return
0
;
}
ce
=
&
convert_table
[
src_pix_fmt
][
dst_pix_fmt
];
if
(
ce
->
convert
)
{
/* specific conversion routine */
ce
->
convert
(
dst
,
src
,
dst_width
,
dst_height
);
return
0
;
}
/* gray to YUV */
if
(
is_yuv_planar
(
dst_pix
)
&&
src_pix_fmt
==
PIX_FMT_GRAY8
)
{
int
w
,
h
,
y
;
uint8_t
*
d
;
if
(
dst_pix
->
color_type
==
FF_COLOR_YUV_JPEG
)
{
ff_img_copy_plane
(
dst
->
data
[
0
],
dst
->
linesize
[
0
],
src
->
data
[
0
],
src
->
linesize
[
0
],
dst_width
,
dst_height
);
}
else
{
img_apply_table
(
dst
->
data
[
0
],
dst
->
linesize
[
0
],
src
->
data
[
0
],
src
->
linesize
[
0
],
dst_width
,
dst_height
,
y_jpeg_to_ccir
);
}
/* fill U and V with 128 */
w
=
dst_width
;
h
=
dst_height
;
w
>>=
dst_pix
->
x_chroma_shift
;
h
>>=
dst_pix
->
y_chroma_shift
;
for
(
i
=
1
;
i
<=
2
;
i
++
)
{
d
=
dst
->
data
[
i
];
for
(
y
=
0
;
y
<
h
;
y
++
)
{
memset
(
d
,
128
,
w
);
d
+=
dst
->
linesize
[
i
];
}
}
return
0
;
}
/* YUV to gray */
if
(
is_yuv_planar
(
src_pix
)
&&
dst_pix_fmt
==
PIX_FMT_GRAY8
)
{
if
(
src_pix
->
color_type
==
FF_COLOR_YUV_JPEG
)
{
ff_img_copy_plane
(
dst
->
data
[
0
],
dst
->
linesize
[
0
],
src
->
data
[
0
],
src
->
linesize
[
0
],
dst_width
,
dst_height
);
}
else
{
img_apply_table
(
dst
->
data
[
0
],
dst
->
linesize
[
0
],
src
->
data
[
0
],
src
->
linesize
[
0
],
dst_width
,
dst_height
,
y_ccir_to_jpeg
);
}
return
0
;
}
/* YUV to YUV planar */
if
(
is_yuv_planar
(
dst_pix
)
&&
is_yuv_planar
(
src_pix
))
{
int
x_shift
,
y_shift
,
w
,
h
,
xy_shift
;
void
(
*
resize_func
)(
uint8_t
*
dst
,
int
dst_wrap
,
const
uint8_t
*
src
,
int
src_wrap
,
int
width
,
int
height
);
/* compute chroma size of the smallest dimensions */
w
=
dst_width
;
h
=
dst_height
;
if
(
dst_pix
->
x_chroma_shift
>=
src_pix
->
x_chroma_shift
)
w
>>=
dst_pix
->
x_chroma_shift
;
else
w
>>=
src_pix
->
x_chroma_shift
;
if
(
dst_pix
->
y_chroma_shift
>=
src_pix
->
y_chroma_shift
)
h
>>=
dst_pix
->
y_chroma_shift
;
else
h
>>=
src_pix
->
y_chroma_shift
;
x_shift
=
(
dst_pix
->
x_chroma_shift
-
src_pix
->
x_chroma_shift
);
y_shift
=
(
dst_pix
->
y_chroma_shift
-
src_pix
->
y_chroma_shift
);
xy_shift
=
((
x_shift
&
0xf
)
<<
4
)
|
(
y_shift
&
0xf
);
/* there must be filters for conversion at least from and to
YUV444 format */
switch
(
xy_shift
)
{
case
0x00
:
resize_func
=
ff_img_copy_plane
;
break
;
case
0x10
:
resize_func
=
shrink21
;
break
;
case
0x20
:
resize_func
=
shrink41
;
break
;
case
0x01
:
resize_func
=
shrink12
;
break
;
case
0x11
:
resize_func
=
ff_shrink22
;
break
;
case
0x22
:
resize_func
=
ff_shrink44
;
break
;
case
0xf0
:
resize_func
=
grow21
;
break
;
case
0x0f
:
resize_func
=
grow12
;
break
;
case
0xe0
:
resize_func
=
grow41
;
break
;
case
0xff
:
resize_func
=
grow22
;
break
;
case
0xee
:
resize_func
=
grow44
;
break
;
case
0xf1
:
resize_func
=
conv411
;
break
;
default:
/* currently not handled */
goto
no_chroma_filter
;
}
ff_img_copy_plane
(
dst
->
data
[
0
],
dst
->
linesize
[
0
],
src
->
data
[
0
],
src
->
linesize
[
0
],
dst_width
,
dst_height
);
for
(
i
=
1
;
i
<=
2
;
i
++
)
resize_func
(
dst
->
data
[
i
],
dst
->
linesize
[
i
],
src
->
data
[
i
],
src
->
linesize
[
i
],
dst_width
>>
dst_pix
->
x_chroma_shift
,
dst_height
>>
dst_pix
->
y_chroma_shift
);
/* if yuv color space conversion is needed, we do it here on
the destination image */
if
(
dst_pix
->
color_type
!=
src_pix
->
color_type
)
{
const
uint8_t
*
y_table
,
*
c_table
;
if
(
dst_pix
->
color_type
==
FF_COLOR_YUV
)
{
y_table
=
y_jpeg_to_ccir
;
c_table
=
c_jpeg_to_ccir
;
}
else
{
y_table
=
y_ccir_to_jpeg
;
c_table
=
c_ccir_to_jpeg
;
}
img_apply_table
(
dst
->
data
[
0
],
dst
->
linesize
[
0
],
dst
->
data
[
0
],
dst
->
linesize
[
0
],
dst_width
,
dst_height
,
y_table
);
for
(
i
=
1
;
i
<=
2
;
i
++
)
img_apply_table
(
dst
->
data
[
i
],
dst
->
linesize
[
i
],
dst
->
data
[
i
],
dst
->
linesize
[
i
],
dst_width
>>
dst_pix
->
x_chroma_shift
,
dst_height
>>
dst_pix
->
y_chroma_shift
,
c_table
);
}
return
0
;
}
no_chroma_filter:
/* try to use an intermediate format */
if
(
src_pix_fmt
==
PIX_FMT_YUYV422
||
dst_pix_fmt
==
PIX_FMT_YUYV422
)
{
/* specific case: convert to YUV422P first */
int_pix_fmt
=
PIX_FMT_YUV422P
;
}
else
if
(
src_pix_fmt
==
PIX_FMT_UYVY422
||
dst_pix_fmt
==
PIX_FMT_UYVY422
)
{
/* specific case: convert to YUV422P first */
int_pix_fmt
=
PIX_FMT_YUV422P
;
}
else
if
(
src_pix_fmt
==
PIX_FMT_UYYVYY411
||
dst_pix_fmt
==
PIX_FMT_UYYVYY411
)
{
/* specific case: convert to YUV411P first */
int_pix_fmt
=
PIX_FMT_YUV411P
;
}
else
if
((
src_pix
->
color_type
==
FF_COLOR_GRAY
&&
src_pix_fmt
!=
PIX_FMT_GRAY8
)
||
(
dst_pix
->
color_type
==
FF_COLOR_GRAY
&&
dst_pix_fmt
!=
PIX_FMT_GRAY8
))
{
/* gray8 is the normalized format */
int_pix_fmt
=
PIX_FMT_GRAY8
;
}
else
if
((
is_yuv_planar
(
src_pix
)
&&
src_pix_fmt
!=
PIX_FMT_YUV444P
&&
src_pix_fmt
!=
PIX_FMT_YUVJ444P
))
{
/* yuv444 is the normalized format */
if
(
src_pix
->
color_type
==
FF_COLOR_YUV_JPEG
)
int_pix_fmt
=
PIX_FMT_YUVJ444P
;
else
int_pix_fmt
=
PIX_FMT_YUV444P
;
}
else
if
((
is_yuv_planar
(
dst_pix
)
&&
dst_pix_fmt
!=
PIX_FMT_YUV444P
&&
dst_pix_fmt
!=
PIX_FMT_YUVJ444P
))
{
/* yuv444 is the normalized format */
if
(
dst_pix
->
color_type
==
FF_COLOR_YUV_JPEG
)
int_pix_fmt
=
PIX_FMT_YUVJ444P
;
else
int_pix_fmt
=
PIX_FMT_YUV444P
;
}
else
{
/* the two formats are rgb or gray8 or yuv[j]444p */
if
(
src_pix
->
is_alpha
&&
dst_pix
->
is_alpha
)
int_pix_fmt
=
PIX_FMT_RGB32
;
else
int_pix_fmt
=
PIX_FMT_RGB24
;
}
if
(
src_pix_fmt
==
int_pix_fmt
)
return
-
1
;
if
(
avpicture_alloc
(
tmp
,
int_pix_fmt
,
dst_width
,
dst_height
)
<
0
)
return
-
1
;
ret
=
-
1
;
if
(
img_convert
(
tmp
,
int_pix_fmt
,
src
,
src_pix_fmt
,
src_width
,
src_height
)
<
0
)
goto
fail1
;
if
(
img_convert
(
dst
,
dst_pix_fmt
,
tmp
,
int_pix_fmt
,
dst_width
,
dst_height
)
<
0
)
goto
fail1
;
ret
=
0
;
fail1:
avpicture_free
(
tmp
);
return
ret
;
}
#endif
/* NOTE: we scan all the pixels to have an exact information */
static
int
get_alpha_info_pal8
(
const
AVPicture
*
src
,
int
width
,
int
height
)
{
...
...
@@ -2763,9 +1274,6 @@ int img_get_alpha_info(const AVPicture *src,
if
(
!
pf
->
is_alpha
)
return
0
;
switch
(
pix_fmt
)
{
case
PIX_FMT_RGB32
:
ret
=
get_alpha_info_rgb32
(
src
,
width
,
height
);
break
;
case
PIX_FMT_PAL8
:
ret
=
get_alpha_info_pal8
(
src
,
width
,
height
);
break
;
...
...
libavcodec/imgconvert_template.c
deleted
100644 → 0
View file @
1ad1eaad
/*
* templates for image conversion routines
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef RGB_OUT
#define RGB_OUT(d, r, g, b) RGBA_OUT(d, r, g, b, 0xff)
#endif
static
void
glue
(
yuv420p_to_
,
RGB_NAME
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
y1_ptr
,
*
y2_ptr
,
*
cb_ptr
,
*
cr_ptr
;
uint8_t
*
d
,
*
d1
,
*
d2
;
int
w
,
y
,
cb
,
cr
,
r_add
,
g_add
,
b_add
,
width2
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
unsigned
int
r
,
g
,
b
;
d
=
dst
->
data
[
0
];
y1_ptr
=
src
->
data
[
0
];
cb_ptr
=
src
->
data
[
1
];
cr_ptr
=
src
->
data
[
2
];
width2
=
(
width
+
1
)
>>
1
;
for
(;
height
>=
2
;
height
-=
2
)
{
d1
=
d
;
d2
=
d
+
dst
->
linesize
[
0
];
y2_ptr
=
y1_ptr
+
src
->
linesize
[
0
];
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
YUV_TO_RGB1_CCIR
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
/* output 4 pixels */
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y1_ptr
[
1
]);
RGB_OUT
(
d1
+
BPP
,
r
,
g
,
b
);
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y2_ptr
[
0
]);
RGB_OUT
(
d2
,
r
,
g
,
b
);
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y2_ptr
[
1
]);
RGB_OUT
(
d2
+
BPP
,
r
,
g
,
b
);
d1
+=
2
*
BPP
;
d2
+=
2
*
BPP
;
y1_ptr
+=
2
;
y2_ptr
+=
2
;
cb_ptr
++
;
cr_ptr
++
;
}
/* handle odd width */
if
(
w
)
{
YUV_TO_RGB1_CCIR
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y2_ptr
[
0
]);
RGB_OUT
(
d2
,
r
,
g
,
b
);
d1
+=
BPP
;
d2
+=
BPP
;
y1_ptr
++
;
y2_ptr
++
;
cb_ptr
++
;
cr_ptr
++
;
}
d
+=
2
*
dst
->
linesize
[
0
];
y1_ptr
+=
2
*
src
->
linesize
[
0
]
-
width
;
cb_ptr
+=
src
->
linesize
[
1
]
-
width2
;
cr_ptr
+=
src
->
linesize
[
2
]
-
width2
;
}
/* handle odd height */
if
(
height
)
{
d1
=
d
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
YUV_TO_RGB1_CCIR
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
/* output 2 pixels */
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y1_ptr
[
1
]);
RGB_OUT
(
d1
+
BPP
,
r
,
g
,
b
);
d1
+=
2
*
BPP
;
y1_ptr
+=
2
;
cb_ptr
++
;
cr_ptr
++
;
}
/* handle width */
if
(
w
)
{
YUV_TO_RGB1_CCIR
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
/* output 2 pixels */
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
d1
+=
BPP
;
y1_ptr
++
;
cb_ptr
++
;
cr_ptr
++
;
}
}
}
static
void
glue
(
yuvj420p_to_
,
RGB_NAME
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
y1_ptr
,
*
y2_ptr
,
*
cb_ptr
,
*
cr_ptr
;
uint8_t
*
d
,
*
d1
,
*
d2
;
int
w
,
y
,
cb
,
cr
,
r_add
,
g_add
,
b_add
,
width2
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
unsigned
int
r
,
g
,
b
;
d
=
dst
->
data
[
0
];
y1_ptr
=
src
->
data
[
0
];
cb_ptr
=
src
->
data
[
1
];
cr_ptr
=
src
->
data
[
2
];
width2
=
(
width
+
1
)
>>
1
;
for
(;
height
>=
2
;
height
-=
2
)
{
d1
=
d
;
d2
=
d
+
dst
->
linesize
[
0
];
y2_ptr
=
y1_ptr
+
src
->
linesize
[
0
];
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
YUV_TO_RGB1
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
/* output 4 pixels */
YUV_TO_RGB2
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
YUV_TO_RGB2
(
r
,
g
,
b
,
y1_ptr
[
1
]);
RGB_OUT
(
d1
+
BPP
,
r
,
g
,
b
);
YUV_TO_RGB2
(
r
,
g
,
b
,
y2_ptr
[
0
]);
RGB_OUT
(
d2
,
r
,
g
,
b
);
YUV_TO_RGB2
(
r
,
g
,
b
,
y2_ptr
[
1
]);
RGB_OUT
(
d2
+
BPP
,
r
,
g
,
b
);
d1
+=
2
*
BPP
;
d2
+=
2
*
BPP
;
y1_ptr
+=
2
;
y2_ptr
+=
2
;
cb_ptr
++
;
cr_ptr
++
;
}
/* handle odd width */
if
(
w
)
{
YUV_TO_RGB1
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
YUV_TO_RGB2
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
YUV_TO_RGB2
(
r
,
g
,
b
,
y2_ptr
[
0
]);
RGB_OUT
(
d2
,
r
,
g
,
b
);
d1
+=
BPP
;
d2
+=
BPP
;
y1_ptr
++
;
y2_ptr
++
;
cb_ptr
++
;
cr_ptr
++
;
}
d
+=
2
*
dst
->
linesize
[
0
];
y1_ptr
+=
2
*
src
->
linesize
[
0
]
-
width
;
cb_ptr
+=
src
->
linesize
[
1
]
-
width2
;
cr_ptr
+=
src
->
linesize
[
2
]
-
width2
;
}
/* handle odd height */
if
(
height
)
{
d1
=
d
;
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
YUV_TO_RGB1
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
/* output 2 pixels */
YUV_TO_RGB2
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
YUV_TO_RGB2
(
r
,
g
,
b
,
y1_ptr
[
1
]);
RGB_OUT
(
d1
+
BPP
,
r
,
g
,
b
);
d1
+=
2
*
BPP
;
y1_ptr
+=
2
;
cb_ptr
++
;
cr_ptr
++
;
}
/* handle width */
if
(
w
)
{
YUV_TO_RGB1
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
/* output 2 pixels */
YUV_TO_RGB2
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
d1
+=
BPP
;
y1_ptr
++
;
cb_ptr
++
;
cr_ptr
++
;
}
}
}
static
void
glue
(
RGB_NAME
,
_to_yuv420p
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
wrap
,
wrap3
,
width2
;
int
r
,
g
,
b
,
r1
,
g1
,
b1
,
w
;
uint8_t
*
lum
,
*
cb
,
*
cr
;
const
uint8_t
*
p
;
lum
=
dst
->
data
[
0
];
cb
=
dst
->
data
[
1
];
cr
=
dst
->
data
[
2
];
width2
=
(
width
+
1
)
>>
1
;
wrap
=
dst
->
linesize
[
0
];
wrap3
=
src
->
linesize
[
0
];
p
=
src
->
data
[
0
];
for
(;
height
>=
2
;
height
-=
2
)
{
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
r1
=
r
;
g1
=
g
;
b1
=
b
;
lum
[
0
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
RGB_IN
(
r
,
g
,
b
,
p
+
BPP
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
1
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
p
+=
wrap3
;
lum
+=
wrap
;
RGB_IN
(
r
,
g
,
b
,
p
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
0
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
RGB_IN
(
r
,
g
,
b
,
p
+
BPP
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
1
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U_CCIR
(
r1
,
g1
,
b1
,
2
);
cr
[
0
]
=
RGB_TO_V_CCIR
(
r1
,
g1
,
b1
,
2
);
cb
++
;
cr
++
;
p
+=
-
wrap3
+
2
*
BPP
;
lum
+=
-
wrap
+
2
;
}
if
(
w
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
r1
=
r
;
g1
=
g
;
b1
=
b
;
lum
[
0
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
p
+=
wrap3
;
lum
+=
wrap
;
RGB_IN
(
r
,
g
,
b
,
p
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
0
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U_CCIR
(
r1
,
g1
,
b1
,
1
);
cr
[
0
]
=
RGB_TO_V_CCIR
(
r1
,
g1
,
b1
,
1
);
cb
++
;
cr
++
;
p
+=
-
wrap3
+
BPP
;
lum
+=
-
wrap
+
1
;
}
p
+=
wrap3
+
(
wrap3
-
width
*
BPP
);
lum
+=
wrap
+
(
wrap
-
width
);
cb
+=
dst
->
linesize
[
1
]
-
width2
;
cr
+=
dst
->
linesize
[
2
]
-
width2
;
}
/* handle odd height */
if
(
height
)
{
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
r1
=
r
;
g1
=
g
;
b1
=
b
;
lum
[
0
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
RGB_IN
(
r
,
g
,
b
,
p
+
BPP
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
1
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U_CCIR
(
r1
,
g1
,
b1
,
1
);
cr
[
0
]
=
RGB_TO_V_CCIR
(
r1
,
g1
,
b1
,
1
);
cb
++
;
cr
++
;
p
+=
2
*
BPP
;
lum
+=
2
;
}
if
(
w
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
lum
[
0
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U_CCIR
(
r
,
g
,
b
,
0
);
cr
[
0
]
=
RGB_TO_V_CCIR
(
r
,
g
,
b
,
0
);
}
}
}
static
void
glue
(
RGB_NAME
,
_to_gray
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
unsigned
char
*
p
;
unsigned
char
*
q
;
int
r
,
g
,
b
,
dst_wrap
,
src_wrap
;
int
x
,
y
;
p
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
BPP
*
width
;
q
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
q
[
0
]
=
RGB_TO_Y
(
r
,
g
,
b
);
q
++
;
p
+=
BPP
;
}
p
+=
src_wrap
;
q
+=
dst_wrap
;
}
}
static
void
glue
(
gray_to_
,
RGB_NAME
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
unsigned
char
*
p
;
unsigned
char
*
q
;
int
r
,
dst_wrap
,
src_wrap
;
int
x
,
y
;
p
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
;
q
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
BPP
*
width
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
r
=
p
[
0
];
RGB_OUT
(
q
,
r
,
r
,
r
);
q
+=
BPP
;
p
++
;
}
p
+=
src_wrap
;
q
+=
dst_wrap
;
}
}
static
void
glue
(
pal8_to_
,
RGB_NAME
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
unsigned
char
*
p
;
unsigned
char
*
q
;
int
r
,
g
,
b
,
dst_wrap
,
src_wrap
;
int
x
,
y
;
uint32_t
v
;
const
uint32_t
*
palette
;
p
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
;
palette
=
(
uint32_t
*
)
src
->
data
[
1
];
q
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
BPP
*
width
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
v
=
palette
[
p
[
0
]];
r
=
(
v
>>
16
)
&
0xff
;
g
=
(
v
>>
8
)
&
0xff
;
b
=
(
v
)
&
0xff
;
#ifdef RGBA_OUT
{
int
a
;
a
=
(
v
>>
24
)
&
0xff
;
RGBA_OUT
(
q
,
r
,
g
,
b
,
a
);
}
#else
RGB_OUT
(
q
,
r
,
g
,
b
);
#endif
q
+=
BPP
;
p
++
;
}
p
+=
src_wrap
;
q
+=
dst_wrap
;
}
}
// RGB24 has optimized routines
#if !defined(FMT_RGB32) && !defined(FMT_RGB24)
/* alpha support */
static
void
glue
(
rgb32_to_
,
RGB_NAME
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
s
;
uint8_t
*
d
;
int
src_wrap
,
dst_wrap
,
j
,
y
;
unsigned
int
v
,
r
,
g
,
b
;
#ifdef RGBA_OUT
unsigned
int
a
;
#endif
s
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
*
4
;
d
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
*
BPP
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
j
=
0
;
j
<
width
;
j
++
)
{
v
=
((
const
uint32_t
*
)(
s
))[
0
];
r
=
(
v
>>
16
)
&
0xff
;
g
=
(
v
>>
8
)
&
0xff
;
b
=
v
&
0xff
;
#ifdef RGBA_OUT
a
=
(
v
>>
24
)
&
0xff
;
RGBA_OUT
(
d
,
r
,
g
,
b
,
a
);
#else
RGB_OUT
(
d
,
r
,
g
,
b
);
#endif
s
+=
4
;
d
+=
BPP
;
}
s
+=
src_wrap
;
d
+=
dst_wrap
;
}
}
static
void
glue
(
RGB_NAME
,
_to_rgb32
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
s
;
uint8_t
*
d
;
int
src_wrap
,
dst_wrap
,
j
,
y
;
unsigned
int
r
,
g
,
b
;
#ifdef RGBA_IN
unsigned
int
a
;
#endif
s
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
*
BPP
;
d
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
*
4
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
j
=
0
;
j
<
width
;
j
++
)
{
#ifdef RGBA_IN
RGBA_IN
(
r
,
g
,
b
,
a
,
s
);
((
uint32_t
*
)(
d
))[
0
]
=
(
a
<<
24
)
|
(
r
<<
16
)
|
(
g
<<
8
)
|
b
;
#else
RGB_IN
(
r
,
g
,
b
,
s
);
((
uint32_t
*
)(
d
))[
0
]
=
(
0xff
<<
24
)
|
(
r
<<
16
)
|
(
g
<<
8
)
|
b
;
#endif
d
+=
4
;
s
+=
BPP
;
}
s
+=
src_wrap
;
d
+=
dst_wrap
;
}
}
#endif
/* !defined(FMT_RGB32) */
#ifndef FMT_RGB24
static
void
glue
(
rgb24_to_
,
RGB_NAME
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
s
;
uint8_t
*
d
;
int
src_wrap
,
dst_wrap
,
j
,
y
;
unsigned
int
r
,
g
,
b
;
s
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
*
3
;
d
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
*
BPP
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
j
=
0
;
j
<
width
;
j
++
)
{
r
=
s
[
0
];
g
=
s
[
1
];
b
=
s
[
2
];
RGB_OUT
(
d
,
r
,
g
,
b
);
s
+=
3
;
d
+=
BPP
;
}
s
+=
src_wrap
;
d
+=
dst_wrap
;
}
}
static
void
glue
(
RGB_NAME
,
_to_rgb24
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
s
;
uint8_t
*
d
;
int
src_wrap
,
dst_wrap
,
j
,
y
;
unsigned
int
r
,
g
,
b
;
s
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
width
*
BPP
;
d
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
*
3
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
j
=
0
;
j
<
width
;
j
++
)
{
RGB_IN
(
r
,
g
,
b
,
s
)
d
[
0
]
=
r
;
d
[
1
]
=
g
;
d
[
2
]
=
b
;
d
+=
3
;
s
+=
BPP
;
}
s
+=
src_wrap
;
d
+=
dst_wrap
;
}
}
#endif
/* !FMT_RGB24 */
#ifdef FMT_RGB24
static
void
yuv444p_to_rgb24
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
y1_ptr
,
*
cb_ptr
,
*
cr_ptr
;
uint8_t
*
d
,
*
d1
;
int
w
,
y
,
cb
,
cr
,
r_add
,
g_add
,
b_add
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
unsigned
int
r
,
g
,
b
;
d
=
dst
->
data
[
0
];
y1_ptr
=
src
->
data
[
0
];
cb_ptr
=
src
->
data
[
1
];
cr_ptr
=
src
->
data
[
2
];
for
(;
height
>
0
;
height
--
)
{
d1
=
d
;
for
(
w
=
width
;
w
>
0
;
w
--
)
{
YUV_TO_RGB1_CCIR
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
YUV_TO_RGB2_CCIR
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
d1
+=
BPP
;
y1_ptr
++
;
cb_ptr
++
;
cr_ptr
++
;
}
d
+=
dst
->
linesize
[
0
];
y1_ptr
+=
src
->
linesize
[
0
]
-
width
;
cb_ptr
+=
src
->
linesize
[
1
]
-
width
;
cr_ptr
+=
src
->
linesize
[
2
]
-
width
;
}
}
static
void
yuvj444p_to_rgb24
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
uint8_t
*
y1_ptr
,
*
cb_ptr
,
*
cr_ptr
;
uint8_t
*
d
,
*
d1
;
int
w
,
y
,
cb
,
cr
,
r_add
,
g_add
,
b_add
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
unsigned
int
r
,
g
,
b
;
d
=
dst
->
data
[
0
];
y1_ptr
=
src
->
data
[
0
];
cb_ptr
=
src
->
data
[
1
];
cr_ptr
=
src
->
data
[
2
];
for
(;
height
>
0
;
height
--
)
{
d1
=
d
;
for
(
w
=
width
;
w
>
0
;
w
--
)
{
YUV_TO_RGB1
(
cb_ptr
[
0
],
cr_ptr
[
0
]);
YUV_TO_RGB2
(
r
,
g
,
b
,
y1_ptr
[
0
]);
RGB_OUT
(
d1
,
r
,
g
,
b
);
d1
+=
BPP
;
y1_ptr
++
;
cb_ptr
++
;
cr_ptr
++
;
}
d
+=
dst
->
linesize
[
0
];
y1_ptr
+=
src
->
linesize
[
0
]
-
width
;
cb_ptr
+=
src
->
linesize
[
1
]
-
width
;
cr_ptr
+=
src
->
linesize
[
2
]
-
width
;
}
}
static
void
rgb24_to_yuv444p
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
src_wrap
,
x
,
y
;
int
r
,
g
,
b
;
uint8_t
*
lum
,
*
cb
,
*
cr
;
const
uint8_t
*
p
;
lum
=
dst
->
data
[
0
];
cb
=
dst
->
data
[
1
];
cr
=
dst
->
data
[
2
];
src_wrap
=
src
->
linesize
[
0
]
-
width
*
BPP
;
p
=
src
->
data
[
0
];
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
lum
[
0
]
=
RGB_TO_Y_CCIR
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U_CCIR
(
r
,
g
,
b
,
0
);
cr
[
0
]
=
RGB_TO_V_CCIR
(
r
,
g
,
b
,
0
);
p
+=
BPP
;
cb
++
;
cr
++
;
lum
++
;
}
p
+=
src_wrap
;
lum
+=
dst
->
linesize
[
0
]
-
width
;
cb
+=
dst
->
linesize
[
1
]
-
width
;
cr
+=
dst
->
linesize
[
2
]
-
width
;
}
}
static
void
rgb24_to_yuvj420p
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
wrap
,
wrap3
,
width2
;
int
r
,
g
,
b
,
r1
,
g1
,
b1
,
w
;
uint8_t
*
lum
,
*
cb
,
*
cr
;
const
uint8_t
*
p
;
lum
=
dst
->
data
[
0
];
cb
=
dst
->
data
[
1
];
cr
=
dst
->
data
[
2
];
width2
=
(
width
+
1
)
>>
1
;
wrap
=
dst
->
linesize
[
0
];
wrap3
=
src
->
linesize
[
0
];
p
=
src
->
data
[
0
];
for
(;
height
>=
2
;
height
-=
2
)
{
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
r1
=
r
;
g1
=
g
;
b1
=
b
;
lum
[
0
]
=
RGB_TO_Y
(
r
,
g
,
b
);
RGB_IN
(
r
,
g
,
b
,
p
+
BPP
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
1
]
=
RGB_TO_Y
(
r
,
g
,
b
);
p
+=
wrap3
;
lum
+=
wrap
;
RGB_IN
(
r
,
g
,
b
,
p
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
0
]
=
RGB_TO_Y
(
r
,
g
,
b
);
RGB_IN
(
r
,
g
,
b
,
p
+
BPP
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
1
]
=
RGB_TO_Y
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U
(
r1
,
g1
,
b1
,
2
);
cr
[
0
]
=
RGB_TO_V
(
r1
,
g1
,
b1
,
2
);
cb
++
;
cr
++
;
p
+=
-
wrap3
+
2
*
BPP
;
lum
+=
-
wrap
+
2
;
}
if
(
w
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
r1
=
r
;
g1
=
g
;
b1
=
b
;
lum
[
0
]
=
RGB_TO_Y
(
r
,
g
,
b
);
p
+=
wrap3
;
lum
+=
wrap
;
RGB_IN
(
r
,
g
,
b
,
p
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
0
]
=
RGB_TO_Y
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U
(
r1
,
g1
,
b1
,
1
);
cr
[
0
]
=
RGB_TO_V
(
r1
,
g1
,
b1
,
1
);
cb
++
;
cr
++
;
p
+=
-
wrap3
+
BPP
;
lum
+=
-
wrap
+
1
;
}
p
+=
wrap3
+
(
wrap3
-
width
*
BPP
);
lum
+=
wrap
+
(
wrap
-
width
);
cb
+=
dst
->
linesize
[
1
]
-
width2
;
cr
+=
dst
->
linesize
[
2
]
-
width2
;
}
/* handle odd height */
if
(
height
)
{
for
(
w
=
width
;
w
>=
2
;
w
-=
2
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
r1
=
r
;
g1
=
g
;
b1
=
b
;
lum
[
0
]
=
RGB_TO_Y
(
r
,
g
,
b
);
RGB_IN
(
r
,
g
,
b
,
p
+
BPP
);
r1
+=
r
;
g1
+=
g
;
b1
+=
b
;
lum
[
1
]
=
RGB_TO_Y
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U
(
r1
,
g1
,
b1
,
1
);
cr
[
0
]
=
RGB_TO_V
(
r1
,
g1
,
b1
,
1
);
cb
++
;
cr
++
;
p
+=
2
*
BPP
;
lum
+=
2
;
}
if
(
w
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
lum
[
0
]
=
RGB_TO_Y
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U
(
r
,
g
,
b
,
0
);
cr
[
0
]
=
RGB_TO_V
(
r
,
g
,
b
,
0
);
}
}
}
static
void
rgb24_to_yuvj444p
(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
int
src_wrap
,
x
,
y
;
int
r
,
g
,
b
;
uint8_t
*
lum
,
*
cb
,
*
cr
;
const
uint8_t
*
p
;
lum
=
dst
->
data
[
0
];
cb
=
dst
->
data
[
1
];
cr
=
dst
->
data
[
2
];
src_wrap
=
src
->
linesize
[
0
]
-
width
*
BPP
;
p
=
src
->
data
[
0
];
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
RGB_IN
(
r
,
g
,
b
,
p
);
lum
[
0
]
=
RGB_TO_Y
(
r
,
g
,
b
);
cb
[
0
]
=
RGB_TO_U
(
r
,
g
,
b
,
0
);
cr
[
0
]
=
RGB_TO_V
(
r
,
g
,
b
,
0
);
p
+=
BPP
;
cb
++
;
cr
++
;
lum
++
;
}
p
+=
src_wrap
;
lum
+=
dst
->
linesize
[
0
]
-
width
;
cb
+=
dst
->
linesize
[
1
]
-
width
;
cr
+=
dst
->
linesize
[
2
]
-
width
;
}
}
#endif
/* FMT_RGB24 */
#if defined(FMT_RGB24) || defined(FMT_RGB32)
static
void
glue
(
RGB_NAME
,
_to_pal8
)(
AVPicture
*
dst
,
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
unsigned
char
*
p
;
unsigned
char
*
q
;
int
dst_wrap
,
src_wrap
;
int
x
,
y
,
has_alpha
;
unsigned
int
r
,
g
,
b
;
p
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
BPP
*
width
;
q
=
dst
->
data
[
0
];
dst_wrap
=
dst
->
linesize
[
0
]
-
width
;
has_alpha
=
0
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
#ifdef RGBA_IN
{
unsigned
int
a
;
RGBA_IN
(
r
,
g
,
b
,
a
,
p
);
/* crude approximation for alpha ! */
if
(
a
<
0x80
)
{
has_alpha
=
1
;
q
[
0
]
=
TRANSP_INDEX
;
}
else
{
q
[
0
]
=
gif_clut_index
(
r
,
g
,
b
);
}
}
#else
RGB_IN
(
r
,
g
,
b
,
p
);
q
[
0
]
=
gif_clut_index
(
r
,
g
,
b
);
#endif
q
++
;
p
+=
BPP
;
}
p
+=
src_wrap
;
q
+=
dst_wrap
;
}
build_rgb_palette
(
dst
->
data
[
1
],
has_alpha
);
}
#endif
/* defined(FMT_RGB24) || defined(FMT_RGB32) */
#ifdef RGBA_IN
static
int
glue
(
get_alpha_info_
,
RGB_NAME
)(
const
AVPicture
*
src
,
int
width
,
int
height
)
{
const
unsigned
char
*
p
;
int
src_wrap
,
ret
,
x
,
y
;
unsigned
int
r
,
g
,
b
,
a
;
p
=
src
->
data
[
0
];
src_wrap
=
src
->
linesize
[
0
]
-
BPP
*
width
;
ret
=
0
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
RGBA_IN
(
r
,
g
,
b
,
a
,
p
);
if
(
a
==
0x00
)
{
ret
|=
FF_ALPHA_TRANSP
;
}
else
if
(
a
!=
0xff
)
{
ret
|=
FF_ALPHA_SEMI_TRANSP
;
}
p
+=
BPP
;
}
p
+=
src_wrap
;
}
return
ret
;
}
#endif
/* RGBA_IN */
#undef RGB_IN
#undef RGBA_IN
#undef RGB_OUT
#undef RGBA_OUT
#undef BPP
#undef RGB_NAME
#undef FMT_RGB24
#undef FMT_RGB32
libavcodec/imgresample.c
deleted
100644 → 0
View file @
1ad1eaad
/*
* High quality image resampling with polyphase filters
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavcodec/imgresample.c
* High quality image resampling with polyphase filters .
*
* WARNING: This file is deprecated and will be removed after FFmpeg 0.5
* release, do not lose your time improving it!
*/
#include "avcodec.h"
#include "dsputil.h"
#include "imgconvert.h"
#include "libswscale/swscale.h"
#if HAVE_ALTIVEC
#include "ppc/imgresample_altivec.h"
#endif
#define NB_COMPONENTS 3
#define PHASE_BITS 4
#define NB_PHASES (1 << PHASE_BITS)
#define NB_TAPS 4
#define FCENTER 1
/* index of the center of the filter */
//#define TEST 1 /* Test it */
#define POS_FRAC_BITS 16
#define POS_FRAC (1 << POS_FRAC_BITS)
/* 6 bits precision is needed for MMX */
#define FILTER_BITS 8
#define LINE_BUF_HEIGHT (NB_TAPS * 4)
struct
SwsContext
{
const
AVClass
*
av_class
;
struct
ImgReSampleContext
*
resampling_ctx
;
enum
PixelFormat
src_pix_fmt
,
dst_pix_fmt
;
};
typedef
struct
ImgReSampleContext
{
int
iwidth
,
iheight
,
owidth
,
oheight
;
int
topBand
,
bottomBand
,
leftBand
,
rightBand
;
int
padtop
,
padbottom
,
padleft
,
padright
;
int
pad_owidth
,
pad_oheight
;
int
h_incr
,
v_incr
;
DECLARE_ALIGNED_8
(
int16_t
,
h_filters
[
NB_PHASES
][
NB_TAPS
]);
/* horizontal filters */
DECLARE_ALIGNED_8
(
int16_t
,
v_filters
[
NB_PHASES
][
NB_TAPS
]);
/* vertical filters */
uint8_t
*
line_buf
;
}
ImgReSampleContext
;
void
av_build_filter
(
int16_t
*
filter
,
double
factor
,
int
tap_count
,
int
phase_count
,
int
scale
,
int
type
);
static
inline
int
get_phase
(
int
pos
)
{
return
((
pos
)
>>
(
POS_FRAC_BITS
-
PHASE_BITS
))
&
((
1
<<
PHASE_BITS
)
-
1
);
}
/* This function must be optimized */
static
void
h_resample_fast
(
uint8_t
*
dst
,
int
dst_width
,
const
uint8_t
*
src
,
int
src_width
,
int
src_start
,
int
src_incr
,
int16_t
*
filters
)
{
int
src_pos
,
phase
,
sum
,
i
;
const
uint8_t
*
s
;
int16_t
*
filter
;
src_pos
=
src_start
;
for
(
i
=
0
;
i
<
dst_width
;
i
++
)
{
#ifdef TEST
/* test */
if
((
src_pos
>>
POS_FRAC_BITS
)
<
0
||
(
src_pos
>>
POS_FRAC_BITS
)
>
(
src_width
-
NB_TAPS
))
av_abort
();
#endif
s
=
src
+
(
src_pos
>>
POS_FRAC_BITS
);
phase
=
get_phase
(
src_pos
);
filter
=
filters
+
phase
*
NB_TAPS
;
#if NB_TAPS == 4
sum
=
s
[
0
]
*
filter
[
0
]
+
s
[
1
]
*
filter
[
1
]
+
s
[
2
]
*
filter
[
2
]
+
s
[
3
]
*
filter
[
3
];
#else
{
int
j
;
sum
=
0
;
for
(
j
=
0
;
j
<
NB_TAPS
;
j
++
)
sum
+=
s
[
j
]
*
filter
[
j
];
}
#endif
sum
=
sum
>>
FILTER_BITS
;
if
(
sum
<
0
)
sum
=
0
;
else
if
(
sum
>
255
)
sum
=
255
;
dst
[
0
]
=
sum
;
src_pos
+=
src_incr
;
dst
++
;
}
}
/* This function must be optimized */
static
void
v_resample
(
uint8_t
*
dst
,
int
dst_width
,
const
uint8_t
*
src
,
int
wrap
,
int16_t
*
filter
)
{
int
sum
,
i
;
const
uint8_t
*
s
;
s
=
src
;
for
(
i
=
0
;
i
<
dst_width
;
i
++
)
{
#if NB_TAPS == 4
sum
=
s
[
0
*
wrap
]
*
filter
[
0
]
+
s
[
1
*
wrap
]
*
filter
[
1
]
+
s
[
2
*
wrap
]
*
filter
[
2
]
+
s
[
3
*
wrap
]
*
filter
[
3
];
#else
{
int
j
;
uint8_t
*
s1
=
s
;
sum
=
0
;
for
(
j
=
0
;
j
<
NB_TAPS
;
j
++
)
{
sum
+=
s1
[
0
]
*
filter
[
j
];
s1
+=
wrap
;
}
}
#endif
sum
=
sum
>>
FILTER_BITS
;
if
(
sum
<
0
)
sum
=
0
;
else
if
(
sum
>
255
)
sum
=
255
;
dst
[
0
]
=
sum
;
dst
++
;
s
++
;
}
}
#if HAVE_MMX
#include "x86/mmx.h"
#define FILTER4(reg) \
{\
s = src + (src_pos >> POS_FRAC_BITS);\
phase = get_phase(src_pos);\
filter = filters + phase * NB_TAPS;\
movq_m2r(*s, reg);\
punpcklbw_r2r(mm7, reg);\
movq_m2r(*filter, mm6);\
pmaddwd_r2r(reg, mm6);\
movq_r2r(mm6, reg);\
psrlq_i2r(32, reg);\
paddd_r2r(mm6, reg);\
psrad_i2r(FILTER_BITS, reg);\
src_pos += src_incr;\
}
#define DUMP(reg) movq_r2m(reg, tmp); printf(#reg "=%016"PRIx64"\n", tmp.uq);
/* XXX: do four pixels at a time */
static
void
h_resample_fast4_mmx
(
uint8_t
*
dst
,
int
dst_width
,
const
uint8_t
*
src
,
int
src_width
,
int
src_start
,
int
src_incr
,
int16_t
*
filters
)
{
int
src_pos
,
phase
;
const
uint8_t
*
s
;
int16_t
*
filter
;
uint64_t
tmp
;
src_pos
=
src_start
;
pxor_r2r
(
mm7
,
mm7
);
while
(
dst_width
>=
4
)
{
FILTER4
(
mm0
);
FILTER4
(
mm1
);
FILTER4
(
mm2
);
FILTER4
(
mm3
);
packuswb_r2r
(
mm7
,
mm0
);
packuswb_r2r
(
mm7
,
mm1
);
packuswb_r2r
(
mm7
,
mm3
);
packuswb_r2r
(
mm7
,
mm2
);
movq_r2m
(
mm0
,
tmp
);
dst
[
0
]
=
tmp
&
0xFF
;
movq_r2m
(
mm1
,
tmp
);
dst
[
1
]
=
tmp
&
0xFF
;
movq_r2m
(
mm2
,
tmp
);
dst
[
2
]
=
tmp
&
0xFF
;
movq_r2m
(
mm3
,
tmp
);
dst
[
3
]
=
tmp
&
0xFF
;
dst
+=
4
;
dst_width
-=
4
;
}
while
(
dst_width
>
0
)
{
FILTER4
(
mm0
);
packuswb_r2r
(
mm7
,
mm0
);
movq_r2m
(
mm0
,
tmp
);
dst
[
0
]
=
tmp
&
0xFF
;
dst
++
;
dst_width
--
;
}
emms
();
}
static
void
v_resample4_mmx
(
uint8_t
*
dst
,
int
dst_width
,
const
uint8_t
*
src
,
int
wrap
,
int16_t
*
filter
)
{
int
sum
,
i
;
const
uint8_t
*
s
;
uint64_t
tmp
;
uint64_t
coefs
[
4
];
for
(
i
=
0
;
i
<
4
;
i
++
)
{
tmp
=
filter
[
i
];
coefs
[
i
]
=
(
tmp
<<
48
)
+
(
tmp
<<
32
)
+
(
tmp
<<
16
)
+
tmp
;
}
pxor_r2r
(
mm7
,
mm7
);
s
=
src
;
while
(
dst_width
>=
4
)
{
movq_m2r
(
s
[
0
*
wrap
],
mm0
);
punpcklbw_r2r
(
mm7
,
mm0
);
movq_m2r
(
s
[
1
*
wrap
],
mm1
);
punpcklbw_r2r
(
mm7
,
mm1
);
movq_m2r
(
s
[
2
*
wrap
],
mm2
);
punpcklbw_r2r
(
mm7
,
mm2
);
movq_m2r
(
s
[
3
*
wrap
],
mm3
);
punpcklbw_r2r
(
mm7
,
mm3
);
pmullw_m2r
(
coefs
[
0
],
mm0
);
pmullw_m2r
(
coefs
[
1
],
mm1
);
pmullw_m2r
(
coefs
[
2
],
mm2
);
pmullw_m2r
(
coefs
[
3
],
mm3
);
paddw_r2r
(
mm1
,
mm0
);
paddw_r2r
(
mm3
,
mm2
);
paddw_r2r
(
mm2
,
mm0
);
psraw_i2r
(
FILTER_BITS
,
mm0
);
packuswb_r2r
(
mm7
,
mm0
);
movq_r2m
(
mm0
,
tmp
);
*
(
uint32_t
*
)
dst
=
tmp
&
0xFFFFFFFF
;
dst
+=
4
;
s
+=
4
;
dst_width
-=
4
;
}
while
(
dst_width
>
0
)
{
sum
=
s
[
0
*
wrap
]
*
filter
[
0
]
+
s
[
1
*
wrap
]
*
filter
[
1
]
+
s
[
2
*
wrap
]
*
filter
[
2
]
+
s
[
3
*
wrap
]
*
filter
[
3
];
sum
=
sum
>>
FILTER_BITS
;
if
(
sum
<
0
)
sum
=
0
;
else
if
(
sum
>
255
)
sum
=
255
;
dst
[
0
]
=
sum
;
dst
++
;
s
++
;
dst_width
--
;
}
emms
();
}
#endif
/* HAVE_MMX */
/* slow version to handle limit cases. Does not need optimization */
static
void
h_resample_slow
(
uint8_t
*
dst
,
int
dst_width
,
const
uint8_t
*
src
,
int
src_width
,
int
src_start
,
int
src_incr
,
int16_t
*
filters
)
{
int
src_pos
,
phase
,
sum
,
j
,
v
,
i
;
const
uint8_t
*
s
,
*
src_end
;
int16_t
*
filter
;
src_end
=
src
+
src_width
;
src_pos
=
src_start
;
for
(
i
=
0
;
i
<
dst_width
;
i
++
)
{
s
=
src
+
(
src_pos
>>
POS_FRAC_BITS
);
phase
=
get_phase
(
src_pos
);
filter
=
filters
+
phase
*
NB_TAPS
;
sum
=
0
;
for
(
j
=
0
;
j
<
NB_TAPS
;
j
++
)
{
if
(
s
<
src
)
v
=
src
[
0
];
else
if
(
s
>=
src_end
)
v
=
src_end
[
-
1
];
else
v
=
s
[
0
];
sum
+=
v
*
filter
[
j
];
s
++
;
}
sum
=
sum
>>
FILTER_BITS
;
if
(
sum
<
0
)
sum
=
0
;
else
if
(
sum
>
255
)
sum
=
255
;
dst
[
0
]
=
sum
;
src_pos
+=
src_incr
;
dst
++
;
}
}
static
void
h_resample
(
uint8_t
*
dst
,
int
dst_width
,
const
uint8_t
*
src
,
int
src_width
,
int
src_start
,
int
src_incr
,
int16_t
*
filters
)
{
int
n
,
src_end
;
if
(
src_start
<
0
)
{
n
=
(
0
-
src_start
+
src_incr
-
1
)
/
src_incr
;
h_resample_slow
(
dst
,
n
,
src
,
src_width
,
src_start
,
src_incr
,
filters
);
dst
+=
n
;
dst_width
-=
n
;
src_start
+=
n
*
src_incr
;
}
src_end
=
src_start
+
dst_width
*
src_incr
;
if
(
src_end
>
((
src_width
-
NB_TAPS
)
<<
POS_FRAC_BITS
))
{
n
=
(((
src_width
-
NB_TAPS
+
1
)
<<
POS_FRAC_BITS
)
-
1
-
src_start
)
/
src_incr
;
}
else
{
n
=
dst_width
;
}
#if HAVE_MMX
if
((
mm_flags
&
FF_MM_MMX
)
&&
NB_TAPS
==
4
)
h_resample_fast4_mmx
(
dst
,
n
,
src
,
src_width
,
src_start
,
src_incr
,
filters
);
else
#endif
h_resample_fast
(
dst
,
n
,
src
,
src_width
,
src_start
,
src_incr
,
filters
);
if
(
n
<
dst_width
)
{
dst
+=
n
;
dst_width
-=
n
;
src_start
+=
n
*
src_incr
;
h_resample_slow
(
dst
,
dst_width
,
src
,
src_width
,
src_start
,
src_incr
,
filters
);
}
}
static
void
component_resample
(
ImgReSampleContext
*
s
,
uint8_t
*
output
,
int
owrap
,
int
owidth
,
int
oheight
,
uint8_t
*
input
,
int
iwrap
,
int
iwidth
,
int
iheight
)
{
int
src_y
,
src_y1
,
last_src_y
,
ring_y
,
phase_y
,
y1
,
y
;
uint8_t
*
new_line
,
*
src_line
;
last_src_y
=
-
FCENTER
-
1
;
/* position of the bottom of the filter in the source image */
src_y
=
(
last_src_y
+
NB_TAPS
)
*
POS_FRAC
;
ring_y
=
NB_TAPS
;
/* position in ring buffer */
for
(
y
=
0
;
y
<
oheight
;
y
++
)
{
/* apply horizontal filter on new lines from input if needed */
src_y1
=
src_y
>>
POS_FRAC_BITS
;
while
(
last_src_y
<
src_y1
)
{
if
(
++
ring_y
>=
LINE_BUF_HEIGHT
+
NB_TAPS
)
ring_y
=
NB_TAPS
;
last_src_y
++
;
/* handle limit conditions : replicate line (slightly
inefficient because we filter multiple times) */
y1
=
last_src_y
;
if
(
y1
<
0
)
{
y1
=
0
;
}
else
if
(
y1
>=
iheight
)
{
y1
=
iheight
-
1
;
}
src_line
=
input
+
y1
*
iwrap
;
new_line
=
s
->
line_buf
+
ring_y
*
owidth
;
/* apply filter and handle limit cases correctly */
h_resample
(
new_line
,
owidth
,
src_line
,
iwidth
,
-
FCENTER
*
POS_FRAC
,
s
->
h_incr
,
&
s
->
h_filters
[
0
][
0
]);
/* handle ring buffer wrapping */
if
(
ring_y
>=
LINE_BUF_HEIGHT
)
{
memcpy
(
s
->
line_buf
+
(
ring_y
-
LINE_BUF_HEIGHT
)
*
owidth
,
new_line
,
owidth
);
}
}
/* apply vertical filter */
phase_y
=
get_phase
(
src_y
);
#if HAVE_MMX
/* desactivated MMX because loss of precision */
if
((
mm_flags
&
FF_MM_MMX
)
&&
NB_TAPS
==
4
&&
0
)
v_resample4_mmx
(
output
,
owidth
,
s
->
line_buf
+
(
ring_y
-
NB_TAPS
+
1
)
*
owidth
,
owidth
,
&
s
->
v_filters
[
phase_y
][
0
]);
else
#endif
#if HAVE_ALTIVEC
if
((
mm_flags
&
FF_MM_ALTIVEC
)
&&
NB_TAPS
==
4
&&
FILTER_BITS
<=
6
)
v_resample16_altivec
(
output
,
owidth
,
s
->
line_buf
+
(
ring_y
-
NB_TAPS
+
1
)
*
owidth
,
owidth
,
&
s
->
v_filters
[
phase_y
][
0
]);
else
#endif
v_resample
(
output
,
owidth
,
s
->
line_buf
+
(
ring_y
-
NB_TAPS
+
1
)
*
owidth
,
owidth
,
&
s
->
v_filters
[
phase_y
][
0
]);
src_y
+=
s
->
v_incr
;
output
+=
owrap
;
}
}
ImgReSampleContext
*
img_resample_full_init
(
int
owidth
,
int
oheight
,
int
iwidth
,
int
iheight
,
int
topBand
,
int
bottomBand
,
int
leftBand
,
int
rightBand
,
int
padtop
,
int
padbottom
,
int
padleft
,
int
padright
)
{
ImgReSampleContext
*
s
;
if
(
!
owidth
||
!
oheight
||
!
iwidth
||
!
iheight
)
return
NULL
;
s
=
av_mallocz
(
sizeof
(
ImgReSampleContext
));
if
(
!
s
)
return
NULL
;
if
((
unsigned
)
owidth
>=
UINT_MAX
/
(
LINE_BUF_HEIGHT
+
NB_TAPS
))
goto
fail
;
s
->
line_buf
=
av_mallocz
(
owidth
*
(
LINE_BUF_HEIGHT
+
NB_TAPS
));
if
(
!
s
->
line_buf
)
goto
fail
;
s
->
owidth
=
owidth
;
s
->
oheight
=
oheight
;
s
->
iwidth
=
iwidth
;
s
->
iheight
=
iheight
;
s
->
topBand
=
topBand
;
s
->
bottomBand
=
bottomBand
;
s
->
leftBand
=
leftBand
;
s
->
rightBand
=
rightBand
;
s
->
padtop
=
padtop
;
s
->
padbottom
=
padbottom
;
s
->
padleft
=
padleft
;
s
->
padright
=
padright
;
s
->
pad_owidth
=
owidth
-
(
padleft
+
padright
);
s
->
pad_oheight
=
oheight
-
(
padtop
+
padbottom
);
s
->
h_incr
=
((
iwidth
-
leftBand
-
rightBand
)
*
POS_FRAC
)
/
s
->
pad_owidth
;
s
->
v_incr
=
((
iheight
-
topBand
-
bottomBand
)
*
POS_FRAC
)
/
s
->
pad_oheight
;
av_build_filter
(
&
s
->
h_filters
[
0
][
0
],
(
float
)
s
->
pad_owidth
/
(
float
)
(
iwidth
-
leftBand
-
rightBand
),
NB_TAPS
,
NB_PHASES
,
1
<<
FILTER_BITS
,
0
);
av_build_filter
(
&
s
->
v_filters
[
0
][
0
],
(
float
)
s
->
pad_oheight
/
(
float
)
(
iheight
-
topBand
-
bottomBand
),
NB_TAPS
,
NB_PHASES
,
1
<<
FILTER_BITS
,
0
);
return
s
;
fail:
av_free
(
s
);
return
NULL
;
}
ImgReSampleContext
*
img_resample_init
(
int
owidth
,
int
oheight
,
int
iwidth
,
int
iheight
)
{
return
img_resample_full_init
(
owidth
,
oheight
,
iwidth
,
iheight
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
}
void
img_resample
(
ImgReSampleContext
*
s
,
AVPicture
*
output
,
const
AVPicture
*
input
)
{
int
i
,
shift
;
uint8_t
*
optr
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
shift
=
(
i
==
0
)
?
0
:
1
;
optr
=
output
->
data
[
i
]
+
(((
output
->
linesize
[
i
]
*
s
->
padtop
)
+
s
->
padleft
)
>>
shift
);
component_resample
(
s
,
optr
,
output
->
linesize
[
i
],
s
->
pad_owidth
>>
shift
,
s
->
pad_oheight
>>
shift
,
input
->
data
[
i
]
+
(
input
->
linesize
[
i
]
*
(
s
->
topBand
>>
shift
))
+
(
s
->
leftBand
>>
shift
),
input
->
linesize
[
i
],
((
s
->
iwidth
-
s
->
leftBand
-
s
->
rightBand
)
>>
shift
),
(
s
->
iheight
-
s
->
topBand
-
s
->
bottomBand
)
>>
shift
);
}
}
void
img_resample_close
(
ImgReSampleContext
*
s
)
{
av_free
(
s
->
line_buf
);
av_free
(
s
);
}
static
const
char
*
context_to_name
(
void
*
ptr
)
{
return
"imgconvert"
;
}
static
const
AVClass
context_class
=
{
"imgresample"
,
context_to_name
,
NULL
};
struct
SwsContext
*
sws_getContext
(
int
srcW
,
int
srcH
,
int
srcFormat
,
int
dstW
,
int
dstH
,
int
dstFormat
,
int
flags
,
SwsFilter
*
srcFilter
,
SwsFilter
*
dstFilter
,
double
*
param
)
{
struct
SwsContext
*
ctx
;
ctx
=
av_malloc
(
sizeof
(
struct
SwsContext
));
if
(
!
ctx
)
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"Cannot allocate a resampling context!
\n
"
);
return
NULL
;
}
ctx
->
av_class
=
&
context_class
;
if
((
srcH
!=
dstH
)
||
(
srcW
!=
dstW
))
{
if
((
srcFormat
!=
PIX_FMT_YUV420P
)
||
(
dstFormat
!=
PIX_FMT_YUV420P
))
{
av_log
(
ctx
,
AV_LOG_INFO
,
"PIX_FMT_YUV420P will be used as an intermediate format for rescaling
\n
"
);
}
ctx
->
resampling_ctx
=
img_resample_init
(
dstW
,
dstH
,
srcW
,
srcH
);
}
else
{
ctx
->
resampling_ctx
=
av_malloc
(
sizeof
(
ImgReSampleContext
));
ctx
->
resampling_ctx
->
iheight
=
srcH
;
ctx
->
resampling_ctx
->
iwidth
=
srcW
;
ctx
->
resampling_ctx
->
oheight
=
dstH
;
ctx
->
resampling_ctx
->
owidth
=
dstW
;
}
ctx
->
src_pix_fmt
=
srcFormat
;
ctx
->
dst_pix_fmt
=
dstFormat
;
return
ctx
;
}
void
sws_freeContext
(
struct
SwsContext
*
ctx
)
{
if
(
!
ctx
)
return
;
if
((
ctx
->
resampling_ctx
->
iwidth
!=
ctx
->
resampling_ctx
->
owidth
)
||
(
ctx
->
resampling_ctx
->
iheight
!=
ctx
->
resampling_ctx
->
oheight
))
{
img_resample_close
(
ctx
->
resampling_ctx
);
}
else
{
av_free
(
ctx
->
resampling_ctx
);
}
av_free
(
ctx
);
}
/**
* Checks if context is valid or reallocs a new one instead.
* If context is NULL, just calls sws_getContext() to get a new one.
* Otherwise, checks if the parameters are the same already saved in context.
* If that is the case, returns the current context.
* Otherwise, frees context and gets a new one.
*
* Be warned that srcFilter, dstFilter are not checked, they are
* assumed to remain valid.
*/
struct
SwsContext
*
sws_getCachedContext
(
struct
SwsContext
*
ctx
,
int
srcW
,
int
srcH
,
int
srcFormat
,
int
dstW
,
int
dstH
,
int
dstFormat
,
int
flags
,
SwsFilter
*
srcFilter
,
SwsFilter
*
dstFilter
,
double
*
param
)
{
if
(
ctx
!=
NULL
)
{
if
((
ctx
->
resampling_ctx
->
iwidth
!=
srcW
)
||
(
ctx
->
resampling_ctx
->
iheight
!=
srcH
)
||
(
ctx
->
src_pix_fmt
!=
srcFormat
)
||
(
ctx
->
resampling_ctx
->
owidth
!=
dstW
)
||
(
ctx
->
resampling_ctx
->
oheight
!=
dstH
)
||
(
ctx
->
dst_pix_fmt
!=
dstFormat
))
{
sws_freeContext
(
ctx
);
ctx
=
NULL
;
}
}
if
(
ctx
==
NULL
)
{
return
sws_getContext
(
srcW
,
srcH
,
srcFormat
,
dstW
,
dstH
,
dstFormat
,
flags
,
srcFilter
,
dstFilter
,
param
);
}
return
ctx
;
}
int
sws_scale
(
struct
SwsContext
*
ctx
,
uint8_t
*
src
[],
int
srcStride
[],
int
srcSliceY
,
int
srcSliceH
,
uint8_t
*
dst
[],
int
dstStride
[])
{
AVPicture
src_pict
,
dst_pict
;
int
i
,
res
=
0
;
AVPicture
picture_format_temp
;
AVPicture
picture_resample_temp
,
*
formatted_picture
,
*
resampled_picture
;
uint8_t
*
buf1
=
NULL
,
*
buf2
=
NULL
;
enum
PixelFormat
current_pix_fmt
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
src_pict
.
data
[
i
]
=
src
[
i
];
src_pict
.
linesize
[
i
]
=
srcStride
[
i
];
dst_pict
.
data
[
i
]
=
dst
[
i
];
dst_pict
.
linesize
[
i
]
=
dstStride
[
i
];
}
if
((
ctx
->
resampling_ctx
->
iwidth
!=
ctx
->
resampling_ctx
->
owidth
)
||
(
ctx
->
resampling_ctx
->
iheight
!=
ctx
->
resampling_ctx
->
oheight
))
{
/* We have to rescale the picture, but only YUV420P rescaling is supported... */
if
(
ctx
->
src_pix_fmt
!=
PIX_FMT_YUV420P
)
{
int
size
;
/* create temporary picture for rescaling input*/
size
=
avpicture_get_size
(
PIX_FMT_YUV420P
,
ctx
->
resampling_ctx
->
iwidth
,
ctx
->
resampling_ctx
->
iheight
);
buf1
=
av_malloc
(
size
);
if
(
!
buf1
)
{
res
=
-
1
;
goto
the_end
;
}
formatted_picture
=
&
picture_format_temp
;
avpicture_fill
((
AVPicture
*
)
formatted_picture
,
buf1
,
PIX_FMT_YUV420P
,
ctx
->
resampling_ctx
->
iwidth
,
ctx
->
resampling_ctx
->
iheight
);
if
(
img_convert
((
AVPicture
*
)
formatted_picture
,
PIX_FMT_YUV420P
,
&
src_pict
,
ctx
->
src_pix_fmt
,
ctx
->
resampling_ctx
->
iwidth
,
ctx
->
resampling_ctx
->
iheight
)
<
0
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"pixel format conversion not handled
\n
"
);
res
=
-
1
;
goto
the_end
;
}
}
else
{
formatted_picture
=
&
src_pict
;
}
if
(
ctx
->
dst_pix_fmt
!=
PIX_FMT_YUV420P
)
{
int
size
;
/* create temporary picture for rescaling output*/
size
=
avpicture_get_size
(
PIX_FMT_YUV420P
,
ctx
->
resampling_ctx
->
owidth
,
ctx
->
resampling_ctx
->
oheight
);
buf2
=
av_malloc
(
size
);
if
(
!
buf2
)
{
res
=
-
1
;
goto
the_end
;
}
resampled_picture
=
&
picture_resample_temp
;
avpicture_fill
((
AVPicture
*
)
resampled_picture
,
buf2
,
PIX_FMT_YUV420P
,
ctx
->
resampling_ctx
->
owidth
,
ctx
->
resampling_ctx
->
oheight
);
}
else
{
resampled_picture
=
&
dst_pict
;
}
/* ...and finally rescale!!! */
img_resample
(
ctx
->
resampling_ctx
,
resampled_picture
,
formatted_picture
);
current_pix_fmt
=
PIX_FMT_YUV420P
;
}
else
{
resampled_picture
=
&
src_pict
;
current_pix_fmt
=
ctx
->
src_pix_fmt
;
}
if
(
current_pix_fmt
!=
ctx
->
dst_pix_fmt
)
{
if
(
img_convert
(
&
dst_pict
,
ctx
->
dst_pix_fmt
,
resampled_picture
,
current_pix_fmt
,
ctx
->
resampling_ctx
->
owidth
,
ctx
->
resampling_ctx
->
oheight
)
<
0
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"pixel format conversion not handled
\n
"
);
res
=
-
1
;
goto
the_end
;
}
}
else
if
(
resampled_picture
!=
&
dst_pict
)
{
av_picture_copy
(
&
dst_pict
,
resampled_picture
,
current_pix_fmt
,
ctx
->
resampling_ctx
->
owidth
,
ctx
->
resampling_ctx
->
oheight
);
}
the_end:
av_free
(
buf1
);
av_free
(
buf2
);
return
res
;
}
#ifdef TEST
#include <stdio.h>
#undef exit
/* input */
#define XSIZE 256
#define YSIZE 256
uint8_t
img
[
XSIZE
*
YSIZE
];
/* output */
#define XSIZE1 512
#define YSIZE1 512
uint8_t
img1
[
XSIZE1
*
YSIZE1
];
uint8_t
img2
[
XSIZE1
*
YSIZE1
];
void
save_pgm
(
const
char
*
filename
,
uint8_t
*
img
,
int
xsize
,
int
ysize
)
{
#undef fprintf
FILE
*
f
;
f
=
fopen
(
filename
,
"w"
);
fprintf
(
f
,
"P5
\n
%d %d
\n
%d
\n
"
,
xsize
,
ysize
,
255
);
fwrite
(
img
,
1
,
xsize
*
ysize
,
f
);
fclose
(
f
);
#define fprintf please_use_av_log
}
static
void
dump_filter
(
int16_t
*
filter
)
{
int
i
,
ph
;
for
(
ph
=
0
;
ph
<
NB_PHASES
;
ph
++
)
{
av_log
(
NULL
,
AV_LOG_INFO
,
"%2d: "
,
ph
);
for
(
i
=
0
;
i
<
NB_TAPS
;
i
++
)
{
av_log
(
NULL
,
AV_LOG_INFO
,
" %5.2f"
,
filter
[
ph
*
NB_TAPS
+
i
]
/
256
.
0
);
}
av_log
(
NULL
,
AV_LOG_INFO
,
"
\n
"
);
}
}
#if HAVE_MMX
int
mm_flags
;
#endif
int
main
(
int
argc
,
char
**
argv
)
{
int
x
,
y
,
v
,
i
,
xsize
,
ysize
;
ImgReSampleContext
*
s
;
float
fact
,
factors
[]
=
{
1
/
2
.
0
,
3
.
0
/
4
.
0
,
1
.
0
,
4
.
0
/
3
.
0
,
16
.
0
/
9
.
0
,
2
.
0
};
char
buf
[
256
];
/* build test image */
for
(
y
=
0
;
y
<
YSIZE
;
y
++
)
{
for
(
x
=
0
;
x
<
XSIZE
;
x
++
)
{
if
(
x
<
XSIZE
/
2
&&
y
<
YSIZE
/
2
)
{
if
(
x
<
XSIZE
/
4
&&
y
<
YSIZE
/
4
)
{
if
((
x
%
10
)
<=
6
&&
(
y
%
10
)
<=
6
)
v
=
0xff
;
else
v
=
0x00
;
}
else
if
(
x
<
XSIZE
/
4
)
{
if
(
x
&
1
)
v
=
0xff
;
else
v
=
0
;
}
else
if
(
y
<
XSIZE
/
4
)
{
if
(
y
&
1
)
v
=
0xff
;
else
v
=
0
;
}
else
{
if
(
y
<
YSIZE
*
3
/
8
)
{
if
((
y
+
x
)
&
1
)
v
=
0xff
;
else
v
=
0
;
}
else
{
if
(((
x
+
3
)
%
4
)
<=
1
&&
((
y
+
3
)
%
4
)
<=
1
)
v
=
0xff
;
else
v
=
0x00
;
}
}
}
else
if
(
x
<
XSIZE
/
2
)
{
v
=
((
x
-
(
XSIZE
/
2
))
*
255
)
/
(
XSIZE
/
2
);
}
else
if
(
y
<
XSIZE
/
2
)
{
v
=
((
y
-
(
XSIZE
/
2
))
*
255
)
/
(
XSIZE
/
2
);
}
else
{
v
=
((
x
+
y
-
XSIZE
)
*
255
)
/
XSIZE
;
}
img
[(
YSIZE
-
y
)
*
XSIZE
+
(
XSIZE
-
x
)]
=
v
;
}
}
save_pgm
(
"/tmp/in.pgm"
,
img
,
XSIZE
,
YSIZE
);
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
factors
);
i
++
)
{
fact
=
factors
[
i
];
xsize
=
(
int
)(
XSIZE
*
fact
);
ysize
=
(
int
)((
YSIZE
-
100
)
*
fact
);
s
=
img_resample_full_init
(
xsize
,
ysize
,
XSIZE
,
YSIZE
,
50
,
50
,
0
,
0
,
0
,
0
,
0
,
0
);
av_log
(
NULL
,
AV_LOG_INFO
,
"Factor=%0.2f
\n
"
,
fact
);
dump_filter
(
&
s
->
h_filters
[
0
][
0
]);
component_resample
(
s
,
img1
,
xsize
,
xsize
,
ysize
,
img
+
50
*
XSIZE
,
XSIZE
,
XSIZE
,
YSIZE
-
100
);
img_resample_close
(
s
);
snprintf
(
buf
,
sizeof
(
buf
),
"/tmp/out%d.pgm"
,
i
);
save_pgm
(
buf
,
img1
,
xsize
,
ysize
);
}
/* mmx test */
#if HAVE_MMX
av_log
(
NULL
,
AV_LOG_INFO
,
"MMX test
\n
"
);
fact
=
0
.
72
;
xsize
=
(
int
)(
XSIZE
*
fact
);
ysize
=
(
int
)(
YSIZE
*
fact
);
mm_flags
=
FF_MM_MMX
;
s
=
img_resample_init
(
xsize
,
ysize
,
XSIZE
,
YSIZE
);
component_resample
(
s
,
img1
,
xsize
,
xsize
,
ysize
,
img
,
XSIZE
,
XSIZE
,
YSIZE
);
mm_flags
=
0
;
s
=
img_resample_init
(
xsize
,
ysize
,
XSIZE
,
YSIZE
);
component_resample
(
s
,
img2
,
xsize
,
xsize
,
ysize
,
img
,
XSIZE
,
XSIZE
,
YSIZE
);
if
(
memcmp
(
img1
,
img2
,
xsize
*
ysize
)
!=
0
)
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"mmx error
\n
"
);
exit
(
1
);
}
av_log
(
NULL
,
AV_LOG_INFO
,
"MMX OK
\n
"
);
#endif
/* HAVE_MMX */
return
0
;
}
#endif
/* TEST */
libavcodec/ppc/imgresample_altivec.c
deleted
100644 → 0
View file @
1ad1eaad
/*
* High quality image resampling with polyphase filters
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavcodec/ppc/imgresample_altivec.c
* High quality image resampling with polyphase filters - AltiVec bits
*/
#include "util_altivec.h"
#define FILTER_BITS 8
typedef
union
{
vector
signed
short
v
;
signed
short
s
[
8
];
}
vec_ss
;
void
v_resample16_altivec
(
uint8_t
*
dst
,
int
dst_width
,
const
uint8_t
*
src
,
int
wrap
,
int16_t
*
filter
)
{
int
sum
,
i
;
const
uint8_t
*
s
;
vector
unsigned
char
*
tv
,
tmp
,
dstv
,
zero
;
vec_ss
srchv
[
4
],
srclv
[
4
],
fv
[
4
];
vector
signed
short
zeros
,
sumhv
,
sumlv
;
s
=
src
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/*
The vec_madds later on does an implicit >>15 on the result.
Since FILTER_BITS is 8, and we have 15 bits of magnitude in
a signed short, we have just enough bits to pre-shift our
filter constants <<7 to compensate for vec_madds.
*/
fv
[
i
].
s
[
0
]
=
filter
[
i
]
<<
(
15
-
FILTER_BITS
);
fv
[
i
].
v
=
vec_splat
(
fv
[
i
].
v
,
0
);
}
zero
=
vec_splat_u8
(
0
);
zeros
=
vec_splat_s16
(
0
);
/*
When we're resampling, we'd ideally like both our input buffers,
and output buffers to be 16-byte aligned, so we can do both aligned
reads and writes. Sadly we can't always have this at the moment, so
we opt for aligned writes, as unaligned writes have a huge overhead.
To do this, do enough scalar resamples to get dst 16-byte aligned.
*/
i
=
(
-
(
int
)
dst
)
&
0xf
;
while
(
i
>
0
)
{
sum
=
s
[
0
*
wrap
]
*
filter
[
0
]
+
s
[
1
*
wrap
]
*
filter
[
1
]
+
s
[
2
*
wrap
]
*
filter
[
2
]
+
s
[
3
*
wrap
]
*
filter
[
3
];
sum
=
sum
>>
FILTER_BITS
;
if
(
sum
<
0
)
sum
=
0
;
else
if
(
sum
>
255
)
sum
=
255
;
dst
[
0
]
=
sum
;
dst
++
;
s
++
;
dst_width
--
;
i
--
;
}
/* Do our altivec resampling on 16 pixels at once. */
while
(
dst_width
>=
16
)
{
/* Read 16 (potentially unaligned) bytes from each of
4 lines into 4 vectors, and split them into shorts.
Interleave the multipy/accumulate for the resample
filter with the loads to hide the 3 cycle latency
the vec_madds have. */
tv
=
(
vector
unsigned
char
*
)
&
s
[
0
*
wrap
];
tmp
=
vec_perm
(
tv
[
0
],
tv
[
1
],
vec_lvsl
(
0
,
&
s
[
i
*
wrap
]));
srchv
[
0
].
v
=
(
vector
signed
short
)
vec_mergeh
(
zero
,
tmp
);
srclv
[
0
].
v
=
(
vector
signed
short
)
vec_mergel
(
zero
,
tmp
);
sumhv
=
vec_madds
(
srchv
[
0
].
v
,
fv
[
0
].
v
,
zeros
);
sumlv
=
vec_madds
(
srclv
[
0
].
v
,
fv
[
0
].
v
,
zeros
);
tv
=
(
vector
unsigned
char
*
)
&
s
[
1
*
wrap
];
tmp
=
vec_perm
(
tv
[
0
],
tv
[
1
],
vec_lvsl
(
0
,
&
s
[
1
*
wrap
]));
srchv
[
1
].
v
=
(
vector
signed
short
)
vec_mergeh
(
zero
,
tmp
);
srclv
[
1
].
v
=
(
vector
signed
short
)
vec_mergel
(
zero
,
tmp
);
sumhv
=
vec_madds
(
srchv
[
1
].
v
,
fv
[
1
].
v
,
sumhv
);
sumlv
=
vec_madds
(
srclv
[
1
].
v
,
fv
[
1
].
v
,
sumlv
);
tv
=
(
vector
unsigned
char
*
)
&
s
[
2
*
wrap
];
tmp
=
vec_perm
(
tv
[
0
],
tv
[
1
],
vec_lvsl
(
0
,
&
s
[
2
*
wrap
]));
srchv
[
2
].
v
=
(
vector
signed
short
)
vec_mergeh
(
zero
,
tmp
);
srclv
[
2
].
v
=
(
vector
signed
short
)
vec_mergel
(
zero
,
tmp
);
sumhv
=
vec_madds
(
srchv
[
2
].
v
,
fv
[
2
].
v
,
sumhv
);
sumlv
=
vec_madds
(
srclv
[
2
].
v
,
fv
[
2
].
v
,
sumlv
);
tv
=
(
vector
unsigned
char
*
)
&
s
[
3
*
wrap
];
tmp
=
vec_perm
(
tv
[
0
],
tv
[
1
],
vec_lvsl
(
0
,
&
s
[
3
*
wrap
]));
srchv
[
3
].
v
=
(
vector
signed
short
)
vec_mergeh
(
zero
,
tmp
);
srclv
[
3
].
v
=
(
vector
signed
short
)
vec_mergel
(
zero
,
tmp
);
sumhv
=
vec_madds
(
srchv
[
3
].
v
,
fv
[
3
].
v
,
sumhv
);
sumlv
=
vec_madds
(
srclv
[
3
].
v
,
fv
[
3
].
v
,
sumlv
);
/* Pack the results into our destination vector,
and do an aligned write of that back to memory. */
dstv
=
vec_packsu
(
sumhv
,
sumlv
)
;
vec_st
(
dstv
,
0
,
(
vector
unsigned
char
*
)
dst
);
dst
+=
16
;
s
+=
16
;
dst_width
-=
16
;
}
/* If there are any leftover pixels, resample them
with the slow scalar method. */
while
(
dst_width
>
0
)
{
sum
=
s
[
0
*
wrap
]
*
filter
[
0
]
+
s
[
1
*
wrap
]
*
filter
[
1
]
+
s
[
2
*
wrap
]
*
filter
[
2
]
+
s
[
3
*
wrap
]
*
filter
[
3
];
sum
=
sum
>>
FILTER_BITS
;
if
(
sum
<
0
)
sum
=
0
;
else
if
(
sum
>
255
)
sum
=
255
;
dst
[
0
]
=
sum
;
dst
++
;
s
++
;
dst_width
--
;
}
}
libavcodec/ppc/imgresample_altivec.h
deleted
100644 → 0
View file @
1ad1eaad
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_PPC_IMGRESAMPLE_ALTIVEC_H
#define AVCODEC_PPC_IMGRESAMPLE_ALTIVEC_H
#include <stdint.h>
void
v_resample16_altivec
(
uint8_t
*
dst
,
int
dst_width
,
const
uint8_t
*
src
,
int
wrap
,
int16_t
*
filter
);
#endif
/* AVCODEC_PPC_IMGRESAMPLE_ALTIVEC_H */
libavfilter/Makefile
View file @
6d4f53cb
include
$(SUBDIR)../config.mak
NAME
=
avfilter
FFLIBS
=
avcodec avutil
FFLIBS-$(CONFIG_SWSCALE)
+=
swscale
FFLIBS
=
avcodec avutil swscale
FFLIBS-$(CONFIG_AVFILTER_LAVF)
+=
avformat
HEADERS
=
avfilter.h
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment