Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
0e1ad2f5
Commit
0e1ad2f5
authored
Jan 21, 2014
by
Kostya Shishkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dxtory: add more compressed and uncompressed modes
parent
50866c8d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
418 additions
and
11 deletions
+418
-11
dxtory.c
libavcodec/dxtory.c
+418
-11
No files found.
libavcodec/dxtory.c
View file @
0e1ad2f5
...
...
@@ -29,8 +29,78 @@
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
static
int
dxtory_decode_v1
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
static
int
dxtory_decode_v1_rgb
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
,
int
id
,
int
bpp
)
{
int
h
;
uint8_t
*
dst
;
int
ret
;
if
(
src_size
<
avctx
->
width
*
avctx
->
height
*
bpp
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"packet too small
\n
"
);
return
AVERROR_INVALIDDATA
;
}
avctx
->
pix_fmt
=
id
;
if
((
ret
=
ff_get_buffer
(
avctx
,
pic
,
0
))
<
0
)
return
ret
;
dst
=
pic
->
data
[
0
];
for
(
h
=
0
;
h
<
avctx
->
height
;
h
++
)
{
memcpy
(
dst
,
src
,
avctx
->
width
*
bpp
);
src
+=
avctx
->
width
*
bpp
;
dst
+=
pic
->
linesize
[
0
];
}
return
0
;
}
static
int
dxtory_decode_v1_410
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
{
int
h
,
w
;
uint8_t
*
Y1
,
*
Y2
,
*
Y3
,
*
Y4
,
*
U
,
*
V
;
int
ret
;
if
(
src_size
<
avctx
->
width
*
avctx
->
height
*
18
/
16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"packet too small
\n
"
);
return
AVERROR_INVALIDDATA
;
}
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV410P
;
if
((
ret
=
ff_get_buffer
(
avctx
,
pic
,
0
))
<
0
)
return
ret
;
Y1
=
pic
->
data
[
0
];
Y2
=
pic
->
data
[
0
]
+
pic
->
linesize
[
0
];
Y3
=
pic
->
data
[
0
]
+
pic
->
linesize
[
0
]
*
2
;
Y4
=
pic
->
data
[
0
]
+
pic
->
linesize
[
0
]
*
3
;
U
=
pic
->
data
[
1
];
V
=
pic
->
data
[
2
];
for
(
h
=
0
;
h
<
avctx
->
height
;
h
+=
4
)
{
for
(
w
=
0
;
w
<
avctx
->
width
;
w
+=
4
)
{
AV_COPY32
(
Y1
+
w
,
src
);
AV_COPY32
(
Y2
+
w
,
src
+
4
);
AV_COPY32
(
Y3
+
w
,
src
+
8
);
AV_COPY32
(
Y4
+
w
,
src
+
12
);
U
[
w
>>
2
]
=
src
[
16
]
+
0x80
;
V
[
w
>>
2
]
=
src
[
17
]
+
0x80
;
src
+=
18
;
}
Y1
+=
pic
->
linesize
[
0
]
<<
2
;
Y2
+=
pic
->
linesize
[
0
]
<<
2
;
Y3
+=
pic
->
linesize
[
0
]
<<
2
;
Y4
+=
pic
->
linesize
[
0
]
<<
2
;
U
+=
pic
->
linesize
[
1
];
V
+=
pic
->
linesize
[
2
];
}
return
0
;
}
static
int
dxtory_decode_v1_420
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
{
int
h
,
w
;
uint8_t
*
Y1
,
*
Y2
,
*
U
,
*
V
;
...
...
@@ -66,6 +136,39 @@ static int dxtory_decode_v1(AVCodecContext *avctx, AVFrame *pic,
return
0
;
}
static
int
dxtory_decode_v1_444
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
{
int
h
,
w
;
uint8_t
*
Y
,
*
U
,
*
V
;
int
ret
;
if
(
src_size
<
avctx
->
width
*
avctx
->
height
*
3
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"packet too small
\n
"
);
return
AVERROR_INVALIDDATA
;
}
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV444P
;
if
((
ret
=
ff_get_buffer
(
avctx
,
pic
,
0
))
<
0
)
return
ret
;
Y
=
pic
->
data
[
0
];
U
=
pic
->
data
[
1
];
V
=
pic
->
data
[
2
];
for
(
h
=
0
;
h
<
avctx
->
height
;
h
++
)
{
for
(
w
=
0
;
w
<
avctx
->
width
;
w
++
)
{
Y
[
w
]
=
*
src
++
;
U
[
w
]
=
*
src
++
^
0x80
;
V
[
w
]
=
*
src
++
^
0x80
;
}
Y
+=
pic
->
linesize
[
0
];
U
+=
pic
->
linesize
[
1
];
V
+=
pic
->
linesize
[
2
];
}
return
0
;
}
const
uint8_t
def_lru
[
8
]
=
{
0x00
,
0x20
,
0x40
,
0x60
,
0x80
,
0xA0
,
0xC0
,
0xFF
};
static
inline
uint8_t
decode_sym
(
GetBitContext
*
gb
,
uint8_t
lru
[
8
])
...
...
@@ -85,9 +188,193 @@ static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
return
val
;
}
static
int
dx2_decode_slice
(
GetBitContext
*
gb
,
int
width
,
int
height
,
uint8_t
*
Y
,
uint8_t
*
U
,
uint8_t
*
V
,
int
ystride
,
int
ustride
,
int
vstride
)
static
int
dx2_decode_slice_rgb
(
GetBitContext
*
gb
,
int
width
,
int
height
,
uint8_t
*
dst
,
int
stride
)
{
int
x
,
y
,
i
;
uint8_t
lru
[
3
][
8
];
for
(
i
=
0
;
i
<
3
;
i
++
)
memcpy
(
lru
[
i
],
def_lru
,
8
*
sizeof
(
*
def_lru
));
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
dst
[
x
*
3
+
0
]
=
decode_sym
(
gb
,
lru
[
0
]);
dst
[
x
*
3
+
1
]
=
decode_sym
(
gb
,
lru
[
1
]);
dst
[
x
*
3
+
2
]
=
decode_sym
(
gb
,
lru
[
2
]);
}
dst
+=
stride
;
}
return
0
;
}
static
int
dxtory_decode_v2_rgb
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
{
GetByteContext
gb
;
GetBitContext
gb2
;
int
nslices
,
slice
,
slice_height
;
uint32_t
off
,
slice_size
;
uint8_t
*
dst
;
int
ret
;
bytestream2_init
(
&
gb
,
src
,
src_size
);
nslices
=
bytestream2_get_le16
(
&
gb
);
off
=
FFALIGN
(
nslices
*
4
+
2
,
16
);
if
(
src_size
<
off
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"no slice data
\n
"
);
return
AVERROR_INVALIDDATA
;
}
if
(
!
nslices
||
avctx
->
height
%
nslices
)
{
avpriv_request_sample
(
avctx
,
"%d slices for %dx%d"
,
nslices
,
avctx
->
width
,
avctx
->
height
);
return
AVERROR_PATCHWELCOME
;
}
slice_height
=
avctx
->
height
/
nslices
;
avctx
->
pix_fmt
=
AV_PIX_FMT_BGR24
;
if
((
ret
=
ff_get_buffer
(
avctx
,
pic
,
0
))
<
0
)
return
ret
;
dst
=
pic
->
data
[
0
];
for
(
slice
=
0
;
slice
<
nslices
;
slice
++
)
{
slice_size
=
bytestream2_get_le32
(
&
gb
);
if
(
slice_size
>
src_size
-
off
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"invalid slice size %d (only %d bytes left)
\n
"
,
slice_size
,
src_size
-
off
);
return
AVERROR_INVALIDDATA
;
}
if
(
slice_size
<=
16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"invalid slice size %d
\n
"
,
slice_size
);
return
AVERROR_INVALIDDATA
;
}
if
(
AV_RL32
(
src
+
off
)
!=
slice_size
-
16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Slice sizes mismatch: got %d instead of %d
\n
"
,
AV_RL32
(
src
+
off
),
slice_size
-
16
);
}
init_get_bits
(
&
gb2
,
src
+
off
+
16
,
(
slice_size
-
16
)
*
8
);
dx2_decode_slice_rgb
(
&
gb2
,
avctx
->
width
,
slice_height
,
dst
,
pic
->
linesize
[
0
]);
dst
+=
pic
->
linesize
[
0
]
*
slice_height
;
off
+=
slice_size
;
}
return
0
;
}
static
int
dx2_decode_slice_410
(
GetBitContext
*
gb
,
int
width
,
int
height
,
uint8_t
*
Y
,
uint8_t
*
U
,
uint8_t
*
V
,
int
ystride
,
int
ustride
,
int
vstride
)
{
int
x
,
y
,
i
,
j
;
uint8_t
lru
[
3
][
8
];
for
(
i
=
0
;
i
<
3
;
i
++
)
memcpy
(
lru
[
i
],
def_lru
,
8
*
sizeof
(
*
def_lru
));
for
(
y
=
0
;
y
<
height
;
y
+=
4
)
{
for
(
x
=
0
;
x
<
width
;
x
+=
4
)
{
for
(
j
=
0
;
j
<
4
;
j
++
)
for
(
i
=
0
;
i
<
4
;
i
++
)
Y
[
x
+
i
+
j
*
ystride
]
=
decode_sym
(
gb
,
lru
[
0
]);
U
[
x
>>
2
]
=
decode_sym
(
gb
,
lru
[
1
])
^
0x80
;
V
[
x
>>
2
]
=
decode_sym
(
gb
,
lru
[
2
])
^
0x80
;
}
Y
+=
ystride
<<
2
;
U
+=
ustride
;
V
+=
vstride
;
}
return
0
;
}
static
int
dxtory_decode_v2_410
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
{
GetByteContext
gb
;
GetBitContext
gb2
;
int
nslices
,
slice
,
slice_height
,
ref_slice_height
;
int
cur_y
,
next_y
;
uint32_t
off
,
slice_size
;
uint8_t
*
Y
,
*
U
,
*
V
;
int
ret
;
bytestream2_init
(
&
gb
,
src
,
src_size
);
nslices
=
bytestream2_get_le16
(
&
gb
);
off
=
FFALIGN
(
nslices
*
4
+
2
,
16
);
if
(
src_size
<
off
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"no slice data
\n
"
);
return
AVERROR_INVALIDDATA
;
}
if
(
!
nslices
||
avctx
->
height
%
nslices
)
{
avpriv_request_sample
(
avctx
,
"%d slices for %dx%d"
,
nslices
,
avctx
->
width
,
avctx
->
height
);
return
AVERROR_PATCHWELCOME
;
}
ref_slice_height
=
avctx
->
height
/
nslices
;
if
((
avctx
->
width
&
3
)
||
(
avctx
->
height
&
3
))
{
avpriv_request_sample
(
avctx
,
"Frame dimensions %dx%d"
,
avctx
->
width
,
avctx
->
height
);
}
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV410P
;
if
((
ret
=
ff_get_buffer
(
avctx
,
pic
,
0
))
<
0
)
return
ret
;
Y
=
pic
->
data
[
0
];
U
=
pic
->
data
[
1
];
V
=
pic
->
data
[
2
];
cur_y
=
0
;
next_y
=
ref_slice_height
;
for
(
slice
=
0
;
slice
<
nslices
;
slice
++
)
{
slice_size
=
bytestream2_get_le32
(
&
gb
);
slice_height
=
(
next_y
&
~
3
)
-
(
cur_y
&
~
3
);
if
(
slice_size
>
src_size
-
off
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"invalid slice size %d (only %d bytes left)
\n
"
,
slice_size
,
src_size
-
off
);
return
AVERROR_INVALIDDATA
;
}
if
(
slice_size
<=
16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"invalid slice size %d
\n
"
,
slice_size
);
return
AVERROR_INVALIDDATA
;
}
if
(
AV_RL32
(
src
+
off
)
!=
slice_size
-
16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Slice sizes mismatch: got %d instead of %d
\n
"
,
AV_RL32
(
src
+
off
),
slice_size
-
16
);
}
init_get_bits
(
&
gb2
,
src
+
off
+
16
,
(
slice_size
-
16
)
*
8
);
dx2_decode_slice_410
(
&
gb2
,
avctx
->
width
,
slice_height
,
Y
,
U
,
V
,
pic
->
linesize
[
0
],
pic
->
linesize
[
1
],
pic
->
linesize
[
2
]);
Y
+=
pic
->
linesize
[
0
]
*
slice_height
;
U
+=
pic
->
linesize
[
1
]
*
(
slice_height
>>
2
);
V
+=
pic
->
linesize
[
2
]
*
(
slice_height
>>
2
);
off
+=
slice_size
;
cur_y
=
next_y
;
next_y
+=
ref_slice_height
;
}
return
0
;
}
static
int
dx2_decode_slice_420
(
GetBitContext
*
gb
,
int
width
,
int
height
,
uint8_t
*
Y
,
uint8_t
*
U
,
uint8_t
*
V
,
int
ystride
,
int
ustride
,
int
vstride
)
{
int
x
,
y
,
i
;
uint8_t
lru
[
3
][
8
];
...
...
@@ -113,8 +400,8 @@ static int dx2_decode_slice(GetBitContext *gb, int width, int height,
return
0
;
}
static
int
dxtory_decode_v2
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
static
int
dxtory_decode_v2
_420
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
{
GetByteContext
gb
;
GetBitContext
gb2
;
...
...
@@ -174,8 +461,9 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
AV_RL32
(
src
+
off
),
slice_size
-
16
);
}
init_get_bits
(
&
gb2
,
src
+
off
+
16
,
(
slice_size
-
16
)
*
8
);
dx2_decode_slice
(
&
gb2
,
avctx
->
width
,
slice_height
,
Y
,
U
,
V
,
pic
->
linesize
[
0
],
pic
->
linesize
[
1
],
pic
->
linesize
[
2
]);
dx2_decode_slice_420
(
&
gb2
,
avctx
->
width
,
slice_height
,
Y
,
U
,
V
,
pic
->
linesize
[
0
],
pic
->
linesize
[
1
],
pic
->
linesize
[
2
]);
Y
+=
pic
->
linesize
[
0
]
*
slice_height
;
U
+=
pic
->
linesize
[
1
]
*
(
slice_height
>>
1
);
...
...
@@ -188,6 +476,97 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
return
0
;
}
static
int
dx2_decode_slice_444
(
GetBitContext
*
gb
,
int
width
,
int
height
,
uint8_t
*
Y
,
uint8_t
*
U
,
uint8_t
*
V
,
int
ystride
,
int
ustride
,
int
vstride
)
{
int
x
,
y
,
i
;
uint8_t
lru
[
3
][
8
];
for
(
i
=
0
;
i
<
3
;
i
++
)
memcpy
(
lru
[
i
],
def_lru
,
8
*
sizeof
(
*
def_lru
));
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
Y
[
x
]
=
decode_sym
(
gb
,
lru
[
0
]);
U
[
x
]
=
decode_sym
(
gb
,
lru
[
1
])
^
0x80
;
V
[
x
]
=
decode_sym
(
gb
,
lru
[
2
])
^
0x80
;
}
Y
+=
ystride
;
U
+=
ustride
;
V
+=
vstride
;
}
return
0
;
}
static
int
dxtory_decode_v2_444
(
AVCodecContext
*
avctx
,
AVFrame
*
pic
,
const
uint8_t
*
src
,
int
src_size
)
{
GetByteContext
gb
;
GetBitContext
gb2
;
int
nslices
,
slice
,
slice_height
;
uint32_t
off
,
slice_size
;
uint8_t
*
Y
,
*
U
,
*
V
;
int
ret
;
bytestream2_init
(
&
gb
,
src
,
src_size
);
nslices
=
bytestream2_get_le16
(
&
gb
);
off
=
FFALIGN
(
nslices
*
4
+
2
,
16
);
if
(
src_size
<
off
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"no slice data
\n
"
);
return
AVERROR_INVALIDDATA
;
}
if
(
!
nslices
||
avctx
->
height
%
nslices
)
{
avpriv_request_sample
(
avctx
,
"%d slices for %dx%d"
,
nslices
,
avctx
->
width
,
avctx
->
height
);
return
AVERROR_PATCHWELCOME
;
}
slice_height
=
avctx
->
height
/
nslices
;
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV444P
;
if
((
ret
=
ff_get_buffer
(
avctx
,
pic
,
0
))
<
0
)
return
ret
;
Y
=
pic
->
data
[
0
];
U
=
pic
->
data
[
1
];
V
=
pic
->
data
[
2
];
for
(
slice
=
0
;
slice
<
nslices
;
slice
++
)
{
slice_size
=
bytestream2_get_le32
(
&
gb
);
if
(
slice_size
>
src_size
-
off
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"invalid slice size %d (only %d bytes left)
\n
"
,
slice_size
,
src_size
-
off
);
return
AVERROR_INVALIDDATA
;
}
if
(
slice_size
<=
16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"invalid slice size %d
\n
"
,
slice_size
);
return
AVERROR_INVALIDDATA
;
}
if
(
AV_RL32
(
src
+
off
)
!=
slice_size
-
16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Slice sizes mismatch: got %d instead of %d
\n
"
,
AV_RL32
(
src
+
off
),
slice_size
-
16
);
}
init_get_bits
(
&
gb2
,
src
+
off
+
16
,
(
slice_size
-
16
)
*
8
);
dx2_decode_slice_444
(
&
gb2
,
avctx
->
width
,
slice_height
,
Y
,
U
,
V
,
pic
->
linesize
[
0
],
pic
->
linesize
[
1
],
pic
->
linesize
[
2
]);
Y
+=
pic
->
linesize
[
0
]
*
slice_height
;
U
+=
pic
->
linesize
[
1
]
*
slice_height
;
V
+=
pic
->
linesize
[
2
]
*
slice_height
;
off
+=
slice_size
;
}
return
0
;
}
static
int
decode_frame
(
AVCodecContext
*
avctx
,
void
*
data
,
int
*
got_frame
,
AVPacket
*
avpkt
)
{
...
...
@@ -201,11 +580,39 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
}
switch
(
AV_RB32
(
src
))
{
case
0x01000001
:
ret
=
dxtory_decode_v1_rgb
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
,
AV_PIX_FMT_BGR24
,
3
);
break
;
case
0x01000009
:
ret
=
dxtory_decode_v2_rgb
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
break
;
case
0x02000001
:
ret
=
dxtory_decode_v1
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
ret
=
dxtory_decode_v1
_420
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
break
;
case
0x02000009
:
ret
=
dxtory_decode_v2
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
ret
=
dxtory_decode_v2_420
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
break
;
case
0x03000001
:
ret
=
dxtory_decode_v1_410
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
break
;
case
0x03000009
:
ret
=
dxtory_decode_v2_410
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
break
;
case
0x04000001
:
ret
=
dxtory_decode_v1_444
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
break
;
case
0x04000009
:
ret
=
dxtory_decode_v2_444
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
);
break
;
case
0x17000001
:
ret
=
dxtory_decode_v1_rgb
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
,
AV_PIX_FMT_RGB565LE
,
2
);
break
;
case
0x18000001
:
case
0x19000001
:
ret
=
dxtory_decode_v1_rgb
(
avctx
,
pic
,
src
+
16
,
avpkt
->
size
-
16
,
AV_PIX_FMT_RGB555LE
,
2
);
break
;
default:
avpriv_request_sample
(
avctx
,
"Frame header %X"
,
AV_RB32
(
src
));
...
...
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