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
9d56ccf5
Commit
9d56ccf5
authored
May 31, 2013
by
Michael Niedermayer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
j2k/jpeg2000dec: merge
Signed-off-by:
Michael Niedermayer
<
michaelni@gmx.at
>
parent
fd7e1190
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
133 additions
and
1505 deletions
+133
-1505
Makefile
libavcodec/Makefile
+1
-2
allcodecs.c
libavcodec/allcodecs.c
+1
-2
j2kdec.c
libavcodec/j2kdec.c
+0
-1396
j2kenc.c
libavcodec/j2kenc.c
+2
-2
jpeg2000.c
libavcodec/jpeg2000.c
+1
-1
jpeg2000dec.c
libavcodec/jpeg2000dec.c
+107
-81
vcodec.mak
tests/fate/vcodec.mak
+5
-5
vsynth1-j2k
tests/ref/vsynth/vsynth1-j2k
+0
-4
vsynth1-j2k-97
tests/ref/vsynth/vsynth1-j2k-97
+0
-4
vsynth1-jpeg2000
tests/ref/vsynth/vsynth1-jpeg2000
+4
-0
vsynth1-jpeg2000-97
tests/ref/vsynth/vsynth1-jpeg2000-97
+4
-0
vsynth2-j2k
tests/ref/vsynth/vsynth2-j2k
+0
-4
vsynth2-j2k-97
tests/ref/vsynth/vsynth2-j2k-97
+0
-4
vsynth2-jpeg2000
tests/ref/vsynth/vsynth2-jpeg2000
+4
-0
vsynth2-jpeg2000-97
tests/ref/vsynth/vsynth2-jpeg2000-97
+4
-0
No files found.
libavcodec/Makefile
View file @
9d56ccf5
...
...
@@ -243,8 +243,7 @@ OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi_common.o ivi_dsp.o
OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER)
+=
dpcm.o
OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER)
+=
interplayvideo.o
OBJS-$(CONFIG_JACOSUB_DECODER)
+=
jacosubdec.o
ass.o
OBJS-$(CONFIG_J2K_DECODER)
+=
j2kdec.o
mqcdec.o
mqc.o
jpeg2000.o
OBJS-$(CONFIG_J2K_ENCODER)
+=
j2kenc.o
mqcenc.o
mqc.o
jpeg2000.o
OBJS-$(CONFIG_JPEG2000_ENCODER)
+=
j2kenc.o
mqcenc.o
mqc.o
jpeg2000.o
OBJS-$(CONFIG_JPEG2000_DECODER)
+=
jpeg2000dec.o
jpeg2000.o
\
jpeg2000dwt.o
mqcdec.o
mqc.o
OBJS-$(CONFIG_JPEGLS_DECODER)
+=
jpeglsdec.o
jpegls.o
\
...
...
libavcodec/allcodecs.c
View file @
9d56ccf5
...
...
@@ -172,8 +172,7 @@ void avcodec_register_all(void)
REGISTER_DECODER
(
INDEO4
,
indeo4
);
REGISTER_DECODER
(
INDEO5
,
indeo5
);
REGISTER_DECODER
(
INTERPLAY_VIDEO
,
interplay_video
);
REGISTER_ENCDEC
(
J2K
,
j2k
);
REGISTER_DECODER
(
JPEG2000
,
jpeg2000
);
REGISTER_ENCDEC
(
JPEG2000
,
jpeg2000
);
REGISTER_ENCDEC
(
JPEGLS
,
jpegls
);
REGISTER_DECODER
(
JV
,
jv
);
REGISTER_DECODER
(
KGV1
,
kgv1
);
...
...
libavcodec/j2kdec.c
deleted
100644 → 0
View file @
fd7e1190
/*
* JPEG 2000 image decoder
* Copyright (c) 2007 Kamil Nowosad
* Copyright (c) 2013 Nicolas Bertrand <nicoinattendu@gmail.com>
*
* 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
*/
/**
* JPEG2000 image decoder
* @file
* @author Kamil Nowosad
*/
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "bytestream.h"
#include "internal.h"
#include "thread.h"
#include "jpeg2000.h"
#define JP2_SIG_TYPE 0x6A502020
#define JP2_SIG_VALUE 0x0D0A870A
#define JP2_CODESTREAM 0x6A703263
#define HAD_COC 0x01
#define HAD_QCC 0x02
typedef
struct
Jpeg2000TilePart
{
uint8_t
tile_index
;
// Tile index who refers the tile-part
const
uint8_t
*
tp_end
;
GetByteContext
tpg
;
// bit stream in tile-part
}
Jpeg2000TilePart
;
/* RMK: For JPEG2000 DCINEMA 3 tile-parts in a tile
* one per component, so tile_part elements have a size of 3 */
typedef
struct
Jpeg2000Tile
{
Jpeg2000Component
*
comp
;
uint8_t
properties
[
4
];
Jpeg2000CodingStyle
codsty
[
4
];
Jpeg2000QuantStyle
qntsty
[
4
];
Jpeg2000TilePart
tile_part
[
3
];
uint16_t
tp_idx
;
// Tile-part index
}
Jpeg2000Tile
;
typedef
struct
Jpeg2000DecoderContext
{
AVClass
*
class
;
AVCodecContext
*
avctx
;
GetByteContext
g
;
int
width
,
height
;
int
image_offset_x
,
image_offset_y
;
int
tile_offset_x
,
tile_offset_y
;
uint8_t
cbps
[
4
];
// bits per sample in particular components
uint8_t
sgnd
[
4
];
// if a component is signed
uint8_t
properties
[
4
];
int
cdx
[
4
],
cdy
[
4
];
int
precision
;
int
ncomponents
;
int
tile_width
,
tile_height
;
int
numXtiles
,
numYtiles
;
int
maxtilelen
;
Jpeg2000CodingStyle
codsty
[
4
];
Jpeg2000QuantStyle
qntsty
[
4
];
int
bit_index
;
int
curtileno
;
Jpeg2000Tile
*
tile
;
/*options parameters*/
int
lowres
;
int
reduction_factor
;
}
Jpeg2000DecoderContext
;
/* get_bits functions for JPEG2000 packet bitstream
* It is a get_bit function with a bit-stuffing routine. If the value of the
* byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB.
* cf. ISO-15444-1:2002 / B.10.1 Bit-stuffing routine */
static
int
get_bits
(
Jpeg2000DecoderContext
*
s
,
int
n
)
{
int
res
=
0
;
while
(
--
n
>=
0
)
{
res
<<=
1
;
if
(
s
->
bit_index
==
0
)
{
s
->
bit_index
=
7
+
(
bytestream2_get_byte
(
&
s
->
g
)
!=
0xFFu
);
}
s
->
bit_index
--
;
res
|=
(
bytestream2_peek_byte
(
&
s
->
g
)
>>
s
->
bit_index
)
&
1
;
}
return
res
;
}
static
void
jpeg2000_flush
(
Jpeg2000DecoderContext
*
s
)
{
if
(
bytestream2_get_byte
(
&
s
->
g
)
==
0xff
)
bytestream2_skip
(
&
s
->
g
,
1
);
s
->
bit_index
=
8
;
}
/* decode the value stored in node */
static
int
tag_tree_decode
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000TgtNode
*
node
,
int
threshold
)
{
Jpeg2000TgtNode
*
stack
[
30
];
int
sp
=
-
1
,
curval
=
0
;
if
(
!
node
)
return
AVERROR
(
EINVAL
);
while
(
node
&&
!
node
->
vis
)
{
stack
[
++
sp
]
=
node
;
node
=
node
->
parent
;
}
if
(
node
)
curval
=
node
->
val
;
else
curval
=
stack
[
sp
]
->
val
;
while
(
curval
<
threshold
&&
sp
>=
0
)
{
if
(
curval
<
stack
[
sp
]
->
val
)
curval
=
stack
[
sp
]
->
val
;
while
(
curval
<
threshold
)
{
int
ret
;
if
((
ret
=
get_bits
(
s
,
1
))
>
0
)
{
stack
[
sp
]
->
vis
++
;
break
;
}
else
if
(
!
ret
)
curval
++
;
else
return
ret
;
}
stack
[
sp
]
->
val
=
curval
;
sp
--
;
}
return
curval
;
}
/* marker segments */
/* get sizes and offsets of image, tiles; number of components */
static
int
get_siz
(
Jpeg2000DecoderContext
*
s
)
{
int
i
,
ret
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
36
)
return
AVERROR
(
EINVAL
);
s
->
avctx
->
profile
=
bytestream2_get_be16u
(
&
s
->
g
);
// Rsiz
s
->
width
=
bytestream2_get_be32u
(
&
s
->
g
);
// Width
s
->
height
=
bytestream2_get_be32u
(
&
s
->
g
);
// Height
s
->
image_offset_x
=
bytestream2_get_be32u
(
&
s
->
g
);
// X0Siz
s
->
image_offset_y
=
bytestream2_get_be32u
(
&
s
->
g
);
// Y0Siz
s
->
tile_width
=
bytestream2_get_be32u
(
&
s
->
g
);
// XTSiz
s
->
tile_height
=
bytestream2_get_be32u
(
&
s
->
g
);
// YTSiz
s
->
tile_offset_x
=
bytestream2_get_be32u
(
&
s
->
g
);
// XT0Siz
s
->
tile_offset_y
=
bytestream2_get_be32u
(
&
s
->
g
);
// YT0Siz
s
->
ncomponents
=
bytestream2_get_be16u
(
&
s
->
g
);
// CSiz
if
(
s
->
ncomponents
<=
0
||
s
->
ncomponents
>
4
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"unsupported/invalid ncomponents: %d
\n
"
,
s
->
ncomponents
);
return
AVERROR
(
EINVAL
);
}
if
(
s
->
tile_width
<=
0
||
s
->
tile_height
<=
0
)
return
AVERROR
(
EINVAL
);
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
3
*
s
->
ncomponents
)
return
AVERROR
(
EINVAL
);
for
(
i
=
0
;
i
<
s
->
ncomponents
;
i
++
)
{
// Ssiz_i XRsiz_i, YRsiz_i
uint8_t
x
=
bytestream2_get_byteu
(
&
s
->
g
);
s
->
cbps
[
i
]
=
(
x
&
0x7f
)
+
1
;
s
->
precision
=
FFMAX
(
s
->
cbps
[
i
],
s
->
precision
);
s
->
sgnd
[
i
]
=
!!
(
x
&
0x80
);
s
->
cdx
[
i
]
=
bytestream2_get_byteu
(
&
s
->
g
);
s
->
cdy
[
i
]
=
bytestream2_get_byteu
(
&
s
->
g
);
if
(
s
->
cdx
[
i
]
!=
1
||
s
->
cdy
[
i
]
!=
1
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"unsupported/ CDxy values
\n
"
);
}
}
s
->
numXtiles
=
ff_jpeg2000_ceildiv
(
s
->
width
-
s
->
tile_offset_x
,
s
->
tile_width
);
s
->
numYtiles
=
ff_jpeg2000_ceildiv
(
s
->
height
-
s
->
tile_offset_y
,
s
->
tile_height
);
if
(
s
->
numXtiles
*
(
uint64_t
)
s
->
numYtiles
>
INT_MAX
/
sizeof
(
Jpeg2000Tile
))
return
AVERROR
(
EINVAL
);
s
->
tile
=
av_mallocz
(
s
->
numXtiles
*
s
->
numYtiles
*
sizeof
(
*
s
->
tile
));
if
(
!
s
->
tile
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
s
->
numXtiles
*
s
->
numYtiles
;
i
++
)
{
Jpeg2000Tile
*
tile
=
s
->
tile
+
i
;
tile
->
comp
=
av_mallocz
(
s
->
ncomponents
*
sizeof
(
*
tile
->
comp
));
if
(
!
tile
->
comp
)
return
AVERROR
(
ENOMEM
);
}
/* compute image size with reduction factor */
s
->
avctx
->
width
=
ff_jpeg2000_ceildivpow2
(
s
->
width
-
s
->
image_offset_x
,
s
->
reduction_factor
);
s
->
avctx
->
height
=
ff_jpeg2000_ceildivpow2
(
s
->
height
-
s
->
image_offset_y
,
s
->
reduction_factor
);
switch
(
s
->
ncomponents
)
{
case
1
:
if
(
s
->
precision
>
8
)
s
->
avctx
->
pix_fmt
=
AV_PIX_FMT_GRAY16
;
else
s
->
avctx
->
pix_fmt
=
AV_PIX_FMT_GRAY8
;
break
;
case
3
:
switch
(
s
->
avctx
->
profile
)
{
case
FF_PROFILE_JPEG2000_DCINEMA_2K
:
case
FF_PROFILE_JPEG2000_DCINEMA_4K
:
/* XYZ color-space for digital cinema profiles */
s
->
avctx
->
pix_fmt
=
AV_PIX_FMT_XYZ12
;
break
;
default:
if
(
s
->
precision
>
8
)
s
->
avctx
->
pix_fmt
=
AV_PIX_FMT_RGB48
;
else
s
->
avctx
->
pix_fmt
=
AV_PIX_FMT_RGB24
;
break
;
}
break
;
case
4
:
s
->
avctx
->
pix_fmt
=
AV_PIX_FMT_RGBA
;
break
;
default:
/* pixel format can not be identified */
s
->
avctx
->
pix_fmt
=
AV_PIX_FMT_NONE
;
break
;
}
return
0
;
}
/* get common part for COD and COC segments */
static
int
get_cox
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000CodingStyle
*
c
)
{
uint8_t
byte
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
5
)
return
AVERROR
(
EINVAL
);
c
->
nreslevels
=
bytestream2_get_byteu
(
&
s
->
g
)
+
1
;
// num of resolution levels - 1
if
(
c
->
nreslevels
>=
JPEG2000_MAX_RESLEVELS
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"nreslevels %d is invalid
\n
"
,
c
->
nreslevels
);
return
AVERROR_INVALIDDATA
;
}
/* compute number of resolution levels to decode */
if
(
c
->
nreslevels
<
s
->
reduction_factor
)
c
->
nreslevels2decode
=
1
;
else
c
->
nreslevels2decode
=
c
->
nreslevels
-
s
->
reduction_factor
;
c
->
log2_cblk_width
=
(
bytestream2_get_byteu
(
&
s
->
g
)
&
15
)
+
2
;
// cblk width
c
->
log2_cblk_height
=
(
bytestream2_get_byteu
(
&
s
->
g
)
&
15
)
+
2
;
// cblk height
if
(
c
->
log2_cblk_width
>
10
||
c
->
log2_cblk_height
>
10
||
c
->
log2_cblk_width
+
c
->
log2_cblk_height
>
14
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"cblk size invalid
\n
"
);
return
AVERROR_INVALIDDATA
;
}
c
->
cblk_style
=
bytestream2_get_byteu
(
&
s
->
g
);
if
(
c
->
cblk_style
!=
0
)
{
// cblk style
av_log
(
s
->
avctx
,
AV_LOG_WARNING
,
"extra cblk styles %X
\n
"
,
c
->
cblk_style
);
}
c
->
transform
=
bytestream2_get_byteu
(
&
s
->
g
);
// DWT transformation type
/* set integer 9/7 DWT in case of BITEXACT flag */
if
((
s
->
avctx
->
flags
&
CODEC_FLAG_BITEXACT
)
&&
(
c
->
transform
==
FF_DWT97
))
c
->
transform
=
FF_DWT97_INT
;
if
(
c
->
csty
&
JPEG2000_CSTY_PREC
)
{
int
i
;
for
(
i
=
0
;
i
<
c
->
nreslevels
;
i
++
)
{
byte
=
bytestream2_get_byte
(
&
s
->
g
);
c
->
log2_prec_widths
[
i
]
=
byte
&
0x0F
;
// precinct PPx
c
->
log2_prec_heights
[
i
]
=
(
byte
>>
4
)
&
0x0F
;
// precinct PPy
}
}
else
{
memset
(
c
->
log2_prec_widths
,
15
,
sizeof
(
c
->
log2_prec_widths
));
memset
(
c
->
log2_prec_heights
,
15
,
sizeof
(
c
->
log2_prec_heights
));
}
return
0
;
}
/* get coding parameters for a particular tile or whole image*/
static
int
get_cod
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000CodingStyle
*
c
,
uint8_t
*
properties
)
{
Jpeg2000CodingStyle
tmp
;
int
compno
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
5
)
return
AVERROR
(
EINVAL
);
tmp
.
csty
=
bytestream2_get_byteu
(
&
s
->
g
);
// get progression order
tmp
.
prog_order
=
bytestream2_get_byteu
(
&
s
->
g
);
tmp
.
nlayers
=
bytestream2_get_be16u
(
&
s
->
g
);
tmp
.
mct
=
bytestream2_get_byteu
(
&
s
->
g
);
// multiple component transformation
get_cox
(
s
,
&
tmp
);
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
if
(
!
(
properties
[
compno
]
&
HAD_COC
))
memcpy
(
c
+
compno
,
&
tmp
,
sizeof
(
tmp
));
return
0
;
}
/* Get coding parameters for a component in the whole image or a
* particular tile. */
static
int
get_coc
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000CodingStyle
*
c
,
uint8_t
*
properties
)
{
int
compno
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
2
)
return
AVERROR
(
EINVAL
);
compno
=
bytestream2_get_byteu
(
&
s
->
g
);
c
+=
compno
;
c
->
csty
=
bytestream2_get_byteu
(
&
s
->
g
);
get_cox
(
s
,
c
);
properties
[
compno
]
|=
HAD_COC
;
return
0
;
}
/* Get common part for QCD and QCC segments. */
static
int
get_qcx
(
Jpeg2000DecoderContext
*
s
,
int
n
,
Jpeg2000QuantStyle
*
q
)
{
int
i
,
x
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
1
)
return
AVERROR
(
EINVAL
);
x
=
bytestream2_get_byteu
(
&
s
->
g
);
// Sqcd
q
->
nguardbits
=
x
>>
5
;
q
->
quantsty
=
x
&
0x1f
;
if
(
q
->
quantsty
==
JPEG2000_QSTY_NONE
)
{
n
-=
3
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
n
||
32
*
3
<
n
)
return
AVERROR
(
EINVAL
);
for
(
i
=
0
;
i
<
n
;
i
++
)
q
->
expn
[
i
]
=
bytestream2_get_byteu
(
&
s
->
g
)
>>
3
;
}
else
if
(
q
->
quantsty
==
JPEG2000_QSTY_SI
)
{
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
2
)
return
AVERROR
(
EINVAL
);
x
=
bytestream2_get_be16u
(
&
s
->
g
);
q
->
expn
[
0
]
=
x
>>
11
;
q
->
mant
[
0
]
=
x
&
0x7ff
;
for
(
i
=
1
;
i
<
32
*
3
;
i
++
)
{
int
curexpn
=
FFMAX
(
0
,
q
->
expn
[
0
]
-
(
i
-
1
)
/
3
);
q
->
expn
[
i
]
=
curexpn
;
q
->
mant
[
i
]
=
q
->
mant
[
0
];
}
}
else
{
n
=
(
n
-
3
)
>>
1
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
2
*
n
||
32
*
3
<
n
)
return
AVERROR
(
EINVAL
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
x
=
bytestream2_get_be16u
(
&
s
->
g
);
q
->
expn
[
i
]
=
x
>>
11
;
q
->
mant
[
i
]
=
x
&
0x7ff
;
}
}
return
0
;
}
/* Get quantization parameters for a particular tile or a whole image. */
static
int
get_qcd
(
Jpeg2000DecoderContext
*
s
,
int
n
,
Jpeg2000QuantStyle
*
q
,
uint8_t
*
properties
)
{
Jpeg2000QuantStyle
tmp
;
int
compno
;
if
(
get_qcx
(
s
,
n
,
&
tmp
))
return
-
1
;
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
if
(
!
(
properties
[
compno
]
&
HAD_QCC
))
memcpy
(
q
+
compno
,
&
tmp
,
sizeof
(
tmp
));
return
0
;
}
/* Get quantization parameters for a component in the whole image
* on in a particular tile. */
static
int
get_qcc
(
Jpeg2000DecoderContext
*
s
,
int
n
,
Jpeg2000QuantStyle
*
q
,
uint8_t
*
properties
)
{
int
compno
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
1
)
return
AVERROR
(
EINVAL
);
compno
=
bytestream2_get_byteu
(
&
s
->
g
);
properties
[
compno
]
|=
HAD_QCC
;
return
get_qcx
(
s
,
n
-
1
,
q
+
compno
);
}
/* Get start of tile segment. */
static
int
get_sot
(
Jpeg2000DecoderContext
*
s
,
int
n
)
{
Jpeg2000TilePart
*
tp
;
uint16_t
Isot
;
uint32_t
Psot
;
uint8_t
TPsot
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
8
)
return
AVERROR
(
EINVAL
);
s
->
curtileno
=
Isot
=
bytestream2_get_be16u
(
&
s
->
g
);
// Isot
if
((
unsigned
)
s
->
curtileno
>=
s
->
numXtiles
*
s
->
numYtiles
)
{
s
->
curtileno
=
0
;
return
AVERROR
(
EINVAL
);
}
Psot
=
bytestream2_get_be32u
(
&
s
->
g
);
// Psot
TPsot
=
bytestream2_get_byteu
(
&
s
->
g
);
// TPsot
/* Read TNSot but not used */
bytestream2_get_byteu
(
&
s
->
g
);
// TNsot
if
(
TPsot
>=
FF_ARRAY_ELEMS
(
s
->
tile
[
s
->
curtileno
].
tile_part
))
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"TPsot %d too big
\n
"
,
TPsot
);
return
AVERROR_PATCHWELCOME
;
}
s
->
tile
[
s
->
curtileno
].
tp_idx
=
TPsot
;
tp
=
s
->
tile
[
s
->
curtileno
].
tile_part
+
TPsot
;
tp
->
tile_index
=
Isot
;
tp
->
tp_end
=
s
->
g
.
buffer
+
Psot
-
n
-
2
;
if
(
!
TPsot
)
{
Jpeg2000Tile
*
tile
=
s
->
tile
+
s
->
curtileno
;
/* copy defaults */
memcpy
(
tile
->
codsty
,
s
->
codsty
,
s
->
ncomponents
*
sizeof
(
Jpeg2000CodingStyle
));
memcpy
(
tile
->
qntsty
,
s
->
qntsty
,
s
->
ncomponents
*
sizeof
(
Jpeg2000QuantStyle
));
}
return
0
;
}
/* Tile-part lengths: see ISO 15444-1:2002, section A.7.1
* Used to know the number of tile parts and lengths.
* There may be multiple TLMs in the header.
* TODO: The function is not used for tile-parts management, nor anywhere else.
* It can be useful to allocate memory for tile parts, before managing the SOT
* markers. Parsing the TLM header is needed to increment the input header
* buffer.
* This marker is mandatory for DCI. */
static
uint8_t
get_tlm
(
Jpeg2000DecoderContext
*
s
,
int
n
)
{
uint8_t
Stlm
,
ST
,
SP
,
tile_tlm
,
i
;
bytestream2_get_byte
(
&
s
->
g
);
/* Ztlm: skipped */
Stlm
=
bytestream2_get_byte
(
&
s
->
g
);
// too complex ? ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
ST
=
(
Stlm
>>
4
)
&
0x03
;
// TODO: Manage case of ST = 0b11 --> raise error
SP
=
(
Stlm
>>
6
)
&
0x01
;
tile_tlm
=
(
n
-
4
)
/
((
SP
+
1
)
*
2
+
ST
);
for
(
i
=
0
;
i
<
tile_tlm
;
i
++
)
{
switch
(
ST
)
{
case
0
:
break
;
case
1
:
bytestream2_get_byte
(
&
s
->
g
);
break
;
case
2
:
bytestream2_get_be16
(
&
s
->
g
);
break
;
case
3
:
bytestream2_get_be32
(
&
s
->
g
);
break
;
}
if
(
SP
==
0
)
{
bytestream2_get_be16
(
&
s
->
g
);
}
else
{
bytestream2_get_be32
(
&
s
->
g
);
}
}
return
0
;
}
static
int
init_tile
(
Jpeg2000DecoderContext
*
s
,
int
tileno
)
{
int
compno
;
int
tilex
=
tileno
%
s
->
numXtiles
;
int
tiley
=
tileno
/
s
->
numXtiles
;
Jpeg2000Tile
*
tile
=
s
->
tile
+
tileno
;
if
(
!
tile
->
comp
)
return
AVERROR
(
ENOMEM
);
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
{
Jpeg2000Component
*
comp
=
tile
->
comp
+
compno
;
Jpeg2000CodingStyle
*
codsty
=
tile
->
codsty
+
compno
;
Jpeg2000QuantStyle
*
qntsty
=
tile
->
qntsty
+
compno
;
int
ret
;
// global bandno
comp
->
coord_o
[
0
][
0
]
=
FFMAX
(
tilex
*
s
->
tile_width
+
s
->
tile_offset_x
,
s
->
image_offset_x
);
comp
->
coord_o
[
0
][
1
]
=
FFMIN
((
tilex
+
1
)
*
s
->
tile_width
+
s
->
tile_offset_x
,
s
->
width
);
comp
->
coord_o
[
1
][
0
]
=
FFMAX
(
tiley
*
s
->
tile_height
+
s
->
tile_offset_y
,
s
->
image_offset_y
);
comp
->
coord_o
[
1
][
1
]
=
FFMIN
((
tiley
+
1
)
*
s
->
tile_height
+
s
->
tile_offset_y
,
s
->
height
);
comp
->
coord
[
0
][
0
]
=
ff_jpeg2000_ceildivpow2
(
comp
->
coord_o
[
0
][
0
],
s
->
reduction_factor
);
comp
->
coord
[
0
][
1
]
=
ff_jpeg2000_ceildivpow2
(
comp
->
coord_o
[
0
][
1
],
s
->
reduction_factor
);
comp
->
coord
[
1
][
0
]
=
ff_jpeg2000_ceildivpow2
(
comp
->
coord_o
[
1
][
0
],
s
->
reduction_factor
);
comp
->
coord
[
1
][
1
]
=
ff_jpeg2000_ceildivpow2
(
comp
->
coord_o
[
1
][
1
],
s
->
reduction_factor
);
if
(
ret
=
ff_jpeg2000_init_component
(
comp
,
codsty
,
qntsty
,
s
->
cbps
[
compno
],
s
->
cdx
[
compno
],
s
->
cdy
[
compno
],
s
->
avctx
))
return
ret
;
}
return
0
;
}
/* Read the number of coding passes. */
static
int
getnpasses
(
Jpeg2000DecoderContext
*
s
)
{
int
num
;
if
(
!
get_bits
(
s
,
1
))
return
1
;
if
(
!
get_bits
(
s
,
1
))
return
2
;
if
((
num
=
get_bits
(
s
,
2
))
!=
3
)
return
num
<
0
?
num
:
3
+
num
;
if
((
num
=
get_bits
(
s
,
5
))
!=
31
)
return
num
<
0
?
num
:
6
+
num
;
num
=
get_bits
(
s
,
7
);
return
num
<
0
?
num
:
37
+
num
;
}
static
int
getlblockinc
(
Jpeg2000DecoderContext
*
s
)
{
int
res
=
0
,
ret
;
while
(
ret
=
get_bits
(
s
,
1
))
{
if
(
ret
<
0
)
return
ret
;
res
++
;
}
return
res
;
}
static
int
jpeg2000_decode_packet
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000CodingStyle
*
codsty
,
Jpeg2000ResLevel
*
rlevel
,
int
precno
,
int
layno
,
uint8_t
*
expn
,
int
numgbits
)
{
int
bandno
,
cblkno
,
ret
,
nb_code_blocks
;
if
(
!
(
ret
=
get_bits
(
s
,
1
)))
{
jpeg2000_flush
(
s
);
return
0
;
}
else
if
(
ret
<
0
)
return
ret
;
for
(
bandno
=
0
;
bandno
<
rlevel
->
nbands
;
bandno
++
)
{
Jpeg2000Band
*
band
=
rlevel
->
band
+
bandno
;
Jpeg2000Prec
*
prec
=
band
->
prec
+
precno
;
if
(
band
->
coord
[
0
][
0
]
==
band
->
coord
[
0
][
1
]
||
band
->
coord
[
1
][
0
]
==
band
->
coord
[
1
][
1
])
continue
;
nb_code_blocks
=
prec
->
nb_codeblocks_height
*
prec
->
nb_codeblocks_width
;
for
(
cblkno
=
0
;
cblkno
<
nb_code_blocks
;
cblkno
++
)
{
Jpeg2000Cblk
*
cblk
=
prec
->
cblk
+
cblkno
;
int
incl
,
newpasses
,
llen
;
if
(
cblk
->
npasses
)
incl
=
get_bits
(
s
,
1
);
else
incl
=
tag_tree_decode
(
s
,
prec
->
cblkincl
+
cblkno
,
layno
+
1
)
==
layno
;
if
(
!
incl
)
continue
;
else
if
(
incl
<
0
)
return
incl
;
if
(
!
cblk
->
npasses
)
cblk
->
nonzerobits
=
expn
[
bandno
]
+
numgbits
-
1
-
tag_tree_decode
(
s
,
prec
->
zerobits
+
cblkno
,
100
);
if
((
newpasses
=
getnpasses
(
s
))
<
0
)
return
newpasses
;
if
((
llen
=
getlblockinc
(
s
))
<
0
)
return
llen
;
cblk
->
lblock
+=
llen
;
if
((
ret
=
get_bits
(
s
,
av_log2
(
newpasses
)
+
cblk
->
lblock
))
<
0
)
return
ret
;
cblk
->
lengthinc
=
ret
;
cblk
->
npasses
+=
newpasses
;
}
}
jpeg2000_flush
(
s
);
if
(
codsty
->
csty
&
JPEG2000_CSTY_EPH
)
{
if
(
bytestream2_peek_be16
(
&
s
->
g
)
==
JPEG2000_EPH
)
bytestream2_skip
(
&
s
->
g
,
2
);
else
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"EPH marker not found.
\n
"
);
}
for
(
bandno
=
0
;
bandno
<
rlevel
->
nbands
;
bandno
++
)
{
Jpeg2000Band
*
band
=
rlevel
->
band
+
bandno
;
Jpeg2000Prec
*
prec
=
band
->
prec
+
precno
;
nb_code_blocks
=
prec
->
nb_codeblocks_height
*
prec
->
nb_codeblocks_width
;
for
(
cblkno
=
0
;
cblkno
<
nb_code_blocks
;
cblkno
++
)
{
Jpeg2000Cblk
*
cblk
=
prec
->
cblk
+
cblkno
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
cblk
->
lengthinc
||
sizeof
(
cblk
->
data
)
<
cblk
->
lengthinc
)
return
AVERROR
(
EINVAL
);
/* Code-block data can be empty. In that case initialize data
* with 0xFFFF. */
if
(
cblk
->
lengthinc
>
0
)
{
bytestream2_get_bufferu
(
&
s
->
g
,
cblk
->
data
,
cblk
->
lengthinc
);
}
else
{
cblk
->
data
[
0
]
=
0xFF
;
cblk
->
data
[
1
]
=
0xFF
;
}
cblk
->
length
+=
cblk
->
lengthinc
;
cblk
->
lengthinc
=
0
;
}
}
return
0
;
}
static
int
jpeg2000_decode_packets
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000Tile
*
tile
)
{
int
layno
,
reslevelno
,
compno
,
precno
,
ok_reslevel
;
int
x
,
y
;
s
->
bit_index
=
8
;
switch
(
tile
->
codsty
[
0
].
prog_order
)
{
case
JPEG2000_PGOD_LRCP
:
case
JPEG2000_PGOD_RLCP
:
for
(
layno
=
0
;
layno
<
tile
->
codsty
[
0
].
nlayers
;
layno
++
)
{
ok_reslevel
=
1
;
for
(
reslevelno
=
0
;
ok_reslevel
;
reslevelno
++
)
{
ok_reslevel
=
0
;
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
{
Jpeg2000CodingStyle
*
codsty
=
tile
->
codsty
+
compno
;
Jpeg2000QuantStyle
*
qntsty
=
tile
->
qntsty
+
compno
;
if
(
reslevelno
<
codsty
->
nreslevels
)
{
Jpeg2000ResLevel
*
rlevel
=
tile
->
comp
[
compno
].
reslevel
+
reslevelno
;
ok_reslevel
=
1
;
for
(
precno
=
0
;
precno
<
rlevel
->
num_precincts_x
*
rlevel
->
num_precincts_y
;
precno
++
)
if
(
jpeg2000_decode_packet
(
s
,
codsty
,
rlevel
,
precno
,
layno
,
qntsty
->
expn
+
(
reslevelno
?
3
*
(
reslevelno
-
1
)
+
1
:
0
),
qntsty
->
nguardbits
))
return
-
1
;
}
}
}
}
break
;
case
JPEG2000_PGOD_CPRL
:
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
{
Jpeg2000CodingStyle
*
codsty
=
tile
->
codsty
+
compno
;
Jpeg2000QuantStyle
*
qntsty
=
tile
->
qntsty
+
compno
;
/* Set bit stream buffer address according to tile-part.
* For DCinema one tile-part per component, so can be
* indexed by component. */
s
->
g
=
tile
->
tile_part
[
compno
].
tpg
;
/* Position loop (y axis)
* TODO: Automate computing of step 256.
* Fixed here, but to be computed before entering here. */
for
(
y
=
0
;
y
<
s
->
height
;
y
+=
256
)
{
/* Position loop (y axis)
* TODO: automate computing of step 256.
* Fixed here, but to be computed before entering here. */
for
(
x
=
0
;
x
<
s
->
width
;
x
+=
256
)
{
for
(
reslevelno
=
0
;
reslevelno
<
codsty
->
nreslevels
;
reslevelno
++
)
{
uint16_t
prcx
,
prcy
;
uint8_t
reducedresno
=
codsty
->
nreslevels
-
1
-
reslevelno
;
// ==> N_L - r
Jpeg2000ResLevel
*
rlevel
=
tile
->
comp
[
compno
].
reslevel
+
reslevelno
;
if
(
!
((
y
%
(
1
<<
(
rlevel
->
log2_prec_height
+
reducedresno
))
==
0
)
||
(
y
==
0
)))
// TODO: 2nd condition simplified as try0 always =0 for dcinema
continue
;
if
(
!
((
x
%
(
1
<<
(
rlevel
->
log2_prec_width
+
reducedresno
))
==
0
)
||
(
x
==
0
)))
// TODO: 2nd condition simplified as try0 always =0 for dcinema
continue
;
// check if a precinct exists
prcx
=
ff_jpeg2000_ceildivpow2
(
x
,
reducedresno
)
>>
rlevel
->
log2_prec_width
;
prcy
=
ff_jpeg2000_ceildivpow2
(
y
,
reducedresno
)
>>
rlevel
->
log2_prec_height
;
precno
=
prcx
+
rlevel
->
num_precincts_x
*
prcy
;
for
(
layno
=
0
;
layno
<
tile
->
codsty
[
0
].
nlayers
;
layno
++
)
{
if
(
jpeg2000_decode_packet
(
s
,
codsty
,
rlevel
,
precno
,
layno
,
qntsty
->
expn
+
(
reslevelno
?
3
*
(
reslevelno
-
1
)
+
1
:
0
),
qntsty
->
nguardbits
))
return
-
1
;
}
}
}
}
}
break
;
default:
break
;
}
/* EOC marker reached */
bytestream2_skip
(
&
s
->
g
,
2
);
return
0
;
}
/* TIER-1 routines */
static
void
decode_sigpass
(
Jpeg2000T1Context
*
t1
,
int
width
,
int
height
,
int
bpno
,
int
bandno
,
int
bpass_csty_symbol
,
int
vert_causal_ctx_csty_symbol
)
{
int
mask
=
3
<<
(
bpno
-
1
),
y0
,
x
,
y
;
for
(
y0
=
0
;
y0
<
height
;
y0
+=
4
)
for
(
x
=
0
;
x
<
width
;
x
++
)
for
(
y
=
y0
;
y
<
height
&&
y
<
y0
+
4
;
y
++
)
{
if
((
t1
->
flags
[
y
+
1
][
x
+
1
]
&
JPEG2000_T1_SIG_NB
)
&&
!
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG
|
JPEG2000_T1_VIS
)))
{
int
flags_mask
=
-
1
;
if
(
vert_causal_ctx_csty_symbol
&&
y
==
y0
+
3
)
flags_mask
&=
~
(
JPEG2000_T1_SIG_S
|
JPEG2000_T1_SIG_SW
|
JPEG2000_T1_SIG_SE
);
if
(
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ff_jpeg2000_getsigctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
flags_mask
,
bandno
)))
{
int
xorbit
,
ctxno
=
ff_jpeg2000_getsgnctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
],
&
xorbit
);
if
(
bpass_csty_symbol
)
t1
->
data
[
y
][
x
]
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ctxno
)
?
-
mask
:
mask
;
else
t1
->
data
[
y
][
x
]
=
(
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ctxno
)
^
xorbit
)
?
-
mask
:
mask
;
ff_jpeg2000_set_significance
(
t1
,
x
,
y
,
t1
->
data
[
y
][
x
]
<
0
);
}
t1
->
flags
[
y
+
1
][
x
+
1
]
|=
JPEG2000_T1_VIS
;
}
}
}
static
void
decode_refpass
(
Jpeg2000T1Context
*
t1
,
int
width
,
int
height
,
int
bpno
)
{
int
phalf
,
nhalf
;
int
y0
,
x
,
y
;
phalf
=
1
<<
(
bpno
-
1
);
nhalf
=
-
phalf
;
for
(
y0
=
0
;
y0
<
height
;
y0
+=
4
)
for
(
x
=
0
;
x
<
width
;
x
++
)
for
(
y
=
y0
;
y
<
height
&&
y
<
y0
+
4
;
y
++
)
if
((
t1
->
flags
[
y
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG
|
JPEG2000_T1_VIS
))
==
JPEG2000_T1_SIG
)
{
int
ctxno
=
ff_jpeg2000_getrefctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
]);
int
r
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ctxno
)
?
phalf
:
nhalf
;
t1
->
data
[
y
][
x
]
+=
t1
->
data
[
y
][
x
]
<
0
?
-
r
:
r
;
t1
->
flags
[
y
+
1
][
x
+
1
]
|=
JPEG2000_T1_REF
;
}
}
static
void
decode_clnpass
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000T1Context
*
t1
,
int
width
,
int
height
,
int
bpno
,
int
bandno
,
int
seg_symbols
,
int
vert_causal_ctx_csty_symbol
)
{
int
mask
=
3
<<
(
bpno
-
1
),
y0
,
x
,
y
,
runlen
,
dec
;
for
(
y0
=
0
;
y0
<
height
;
y0
+=
4
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
if
(
y0
+
3
<
height
&&
!
((
t1
->
flags
[
y0
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG_NB
|
JPEG2000_T1_VIS
|
JPEG2000_T1_SIG
))
||
(
t1
->
flags
[
y0
+
2
][
x
+
1
]
&
(
JPEG2000_T1_SIG_NB
|
JPEG2000_T1_VIS
|
JPEG2000_T1_SIG
))
||
(
t1
->
flags
[
y0
+
3
][
x
+
1
]
&
(
JPEG2000_T1_SIG_NB
|
JPEG2000_T1_VIS
|
JPEG2000_T1_SIG
))
||
(
t1
->
flags
[
y0
+
4
][
x
+
1
]
&
(
JPEG2000_T1_SIG_NB
|
JPEG2000_T1_VIS
|
JPEG2000_T1_SIG
))))
{
if
(
!
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
MQC_CX_RL
))
continue
;
runlen
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
MQC_CX_UNI
);
runlen
=
(
runlen
<<
1
)
|
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
MQC_CX_UNI
);
dec
=
1
;
}
else
{
runlen
=
0
;
dec
=
0
;
}
for
(
y
=
y0
+
runlen
;
y
<
y0
+
4
&&
y
<
height
;
y
++
)
{
if
(
!
dec
)
{
if
(
!
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG
|
JPEG2000_T1_VIS
)))
{
int
flags_mask
=
-
1
;
if
(
vert_causal_ctx_csty_symbol
&&
y
==
y0
+
3
)
flags_mask
&=
~
(
JPEG2000_T1_SIG_S
|
JPEG2000_T1_SIG_SW
|
JPEG2000_T1_SIG_SE
);
dec
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ff_jpeg2000_getsigctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
flags_mask
,
bandno
));
}
}
if
(
dec
)
{
int
xorbit
;
int
ctxno
=
ff_jpeg2000_getsgnctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
],
&
xorbit
);
t1
->
data
[
y
][
x
]
=
(
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ctxno
)
^
xorbit
)
?
-
mask
:
mask
;
ff_jpeg2000_set_significance
(
t1
,
x
,
y
,
t1
->
data
[
y
][
x
]
<
0
);
}
dec
=
0
;
t1
->
flags
[
y
+
1
][
x
+
1
]
&=
~
JPEG2000_T1_VIS
;
}
}
}
if
(
seg_symbols
)
{
int
val
;
val
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
MQC_CX_UNI
);
val
=
(
val
<<
1
)
+
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
MQC_CX_UNI
);
val
=
(
val
<<
1
)
+
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
MQC_CX_UNI
);
val
=
(
val
<<
1
)
+
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
MQC_CX_UNI
);
if
(
val
!=
0xa
)
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Segmentation symbol value incorrect
\n
"
);
}
}
static
int
decode_cblk
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000CodingStyle
*
codsty
,
Jpeg2000T1Context
*
t1
,
Jpeg2000Cblk
*
cblk
,
int
width
,
int
height
,
int
bandpos
)
{
int
passno
=
cblk
->
npasses
,
pass_t
=
2
,
bpno
=
cblk
->
nonzerobits
-
1
,
y
,
clnpass_cnt
=
0
;
int
bpass_csty_symbol
=
JPEG2000_CBLK_BYPASS
&
codsty
->
cblk_style
;
int
vert_causal_ctx_csty_symbol
=
JPEG2000_CBLK_VSC
&
codsty
->
cblk_style
;
for
(
y
=
0
;
y
<
height
;
y
++
)
memset
(
t1
->
data
[
y
],
0
,
width
*
sizeof
(
**
t1
->
data
));
/* If code-block contains no compressed data: nothing to do. */
if
(
!
cblk
->
length
)
return
0
;
for
(
y
=
0
;
y
<
height
+
2
;
y
++
)
memset
(
t1
->
flags
[
y
],
0
,
(
width
+
2
)
*
sizeof
(
**
t1
->
flags
));
cblk
->
data
[
cblk
->
length
]
=
0xff
;
cblk
->
data
[
cblk
->
length
+
1
]
=
0xff
;
ff_mqc_initdec
(
&
t1
->
mqc
,
cblk
->
data
);
while
(
passno
--
)
{
switch
(
pass_t
)
{
case
0
:
decode_sigpass
(
t1
,
width
,
height
,
bpno
+
1
,
bandpos
,
bpass_csty_symbol
&&
(
clnpass_cnt
>=
4
),
vert_causal_ctx_csty_symbol
);
break
;
case
1
:
decode_refpass
(
t1
,
width
,
height
,
bpno
+
1
);
if
(
bpass_csty_symbol
&&
clnpass_cnt
>=
4
)
ff_mqc_initdec
(
&
t1
->
mqc
,
cblk
->
data
);
break
;
case
2
:
decode_clnpass
(
s
,
t1
,
width
,
height
,
bpno
+
1
,
bandpos
,
codsty
->
cblk_style
&
JPEG2000_CBLK_SEGSYM
,
vert_causal_ctx_csty_symbol
);
clnpass_cnt
=
clnpass_cnt
+
1
;
if
(
bpass_csty_symbol
&&
clnpass_cnt
>=
4
)
ff_mqc_initdec
(
&
t1
->
mqc
,
cblk
->
data
);
break
;
}
pass_t
++
;
if
(
pass_t
==
3
)
{
bpno
--
;
pass_t
=
0
;
}
}
return
0
;
}
/* TODO: Verify dequantization for lossless case
* comp->data can be float or int
* band->stepsize can be float or int
* depending on the type of DWT transformation.
* see ISO/IEC 15444-1:2002 A.6.1 */
/* Float dequantization of a codeblock.*/
static
void
dequantization_float
(
int
x
,
int
y
,
Jpeg2000Cblk
*
cblk
,
Jpeg2000Component
*
comp
,
Jpeg2000T1Context
*
t1
,
Jpeg2000Band
*
band
)
{
int
i
,
j
,
idx
;
float
*
datap
=
&
comp
->
f_data
[(
comp
->
coord
[
0
][
1
]
-
comp
->
coord
[
0
][
0
])
*
y
+
x
];
for
(
j
=
0
;
j
<
(
cblk
->
coord
[
1
][
1
]
-
cblk
->
coord
[
1
][
0
]);
++
j
)
for
(
i
=
0
;
i
<
(
cblk
->
coord
[
0
][
1
]
-
cblk
->
coord
[
0
][
0
]);
++
i
)
{
idx
=
(
comp
->
coord
[
0
][
1
]
-
comp
->
coord
[
0
][
0
])
*
j
+
i
;
datap
[
idx
]
=
(
float
)(
t1
->
data
[
j
][
i
])
*
band
->
f_stepsize
;
}
}
/* Integer dequantization of a codeblock.*/
static
void
dequantization_int
(
int
x
,
int
y
,
Jpeg2000Cblk
*
cblk
,
Jpeg2000Component
*
comp
,
Jpeg2000T1Context
*
t1
,
Jpeg2000Band
*
band
)
{
int
i
,
j
,
idx
;
int32_t
*
datap
=
&
comp
->
i_data
[(
comp
->
coord
[
0
][
1
]
-
comp
->
coord
[
0
][
0
])
*
y
+
x
];
for
(
j
=
0
;
j
<
(
cblk
->
coord
[
1
][
1
]
-
cblk
->
coord
[
1
][
0
]);
++
j
)
for
(
i
=
0
;
i
<
(
cblk
->
coord
[
0
][
1
]
-
cblk
->
coord
[
0
][
0
]);
++
i
)
{
idx
=
(
comp
->
coord
[
0
][
1
]
-
comp
->
coord
[
0
][
0
])
*
j
+
i
;
datap
[
idx
]
=
((
int32_t
)(
t1
->
data
[
j
][
i
])
*
band
->
i_stepsize
+
(
1
<<
15
))
>>
16
;
}
}
/* Inverse ICT parameters in float and integer.
* int value = (float value) * (1<<16) */
static
const
float
f_ict_params
[
4
]
=
{
1
.
402
f
,
0
.
34413
f
,
0
.
71414
f
,
1
.
772
f
};
static
const
int
i_ict_params
[
4
]
=
{
91881
,
22553
,
46802
,
116130
};
static
void
mct_decode
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000Tile
*
tile
)
{
int
i
,
csize
=
1
;
int32_t
*
src
[
3
],
i0
,
i1
,
i2
;
float
*
srcf
[
3
],
i0f
,
i1f
,
i2f
;
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
tile
->
codsty
[
0
].
transform
==
FF_DWT97
)
srcf
[
i
]
=
tile
->
comp
[
i
].
f_data
;
else
src
[
i
]
=
tile
->
comp
[
i
].
i_data
;
for
(
i
=
0
;
i
<
2
;
i
++
)
csize
*=
tile
->
comp
[
0
].
coord
[
i
][
1
]
-
tile
->
comp
[
0
].
coord
[
i
][
0
];
switch
(
tile
->
codsty
[
0
].
transform
)
{
case
FF_DWT97
:
for
(
i
=
0
;
i
<
csize
;
i
++
)
{
i0f
=
*
srcf
[
0
]
+
(
f_ict_params
[
0
]
*
*
srcf
[
2
]);
i1f
=
*
srcf
[
0
]
-
(
f_ict_params
[
1
]
*
*
srcf
[
1
])
-
(
f_ict_params
[
2
]
*
*
srcf
[
2
]);
i2f
=
*
srcf
[
0
]
+
(
f_ict_params
[
3
]
*
*
srcf
[
1
]);
*
srcf
[
0
]
++
=
i0f
;
*
srcf
[
1
]
++
=
i1f
;
*
srcf
[
2
]
++
=
i2f
;
}
break
;
case
FF_DWT97_INT
:
for
(
i
=
0
;
i
<
csize
;
i
++
)
{
i0
=
*
src
[
0
]
+
(((
i_ict_params
[
0
]
*
*
src
[
2
])
+
(
1
<<
15
))
>>
16
);
i1
=
*
src
[
0
]
-
(((
i_ict_params
[
1
]
*
*
src
[
1
])
+
(
1
<<
15
))
>>
16
)
-
(((
i_ict_params
[
2
]
*
*
src
[
2
])
+
(
1
<<
15
))
>>
16
);
i2
=
*
src
[
0
]
+
(((
i_ict_params
[
3
]
*
*
src
[
1
])
+
(
1
<<
15
))
>>
16
);
*
src
[
0
]
++
=
i0
;
*
src
[
1
]
++
=
i1
;
*
src
[
2
]
++
=
i2
;
}
break
;
case
FF_DWT53
:
for
(
i
=
0
;
i
<
csize
;
i
++
)
{
i1
=
*
src
[
0
]
-
(
*
src
[
2
]
+
*
src
[
1
]
>>
2
);
i0
=
i1
+
*
src
[
2
];
i2
=
i1
+
*
src
[
1
];
*
src
[
0
]
++
=
i0
;
*
src
[
1
]
++
=
i1
;
*
src
[
2
]
++
=
i2
;
}
break
;
}
}
static
int
jpeg2000_decode_tile
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000Tile
*
tile
,
AVFrame
*
picture
)
{
int
compno
,
reslevelno
,
bandno
;
int
x
,
y
;
uint8_t
*
line
;
Jpeg2000T1Context
t1
;
/* Loop on tile components */
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
{
Jpeg2000Component
*
comp
=
tile
->
comp
+
compno
;
Jpeg2000CodingStyle
*
codsty
=
tile
->
codsty
+
compno
;
/* Loop on resolution levels */
for
(
reslevelno
=
0
;
reslevelno
<
codsty
->
nreslevels2decode
;
reslevelno
++
)
{
Jpeg2000ResLevel
*
rlevel
=
comp
->
reslevel
+
reslevelno
;
/* Loop on bands */
for
(
bandno
=
0
;
bandno
<
rlevel
->
nbands
;
bandno
++
)
{
int
nb_precincts
,
precno
;
Jpeg2000Band
*
band
=
rlevel
->
band
+
bandno
;
int
cblkno
=
0
,
bandpos
;
bandpos
=
bandno
+
(
reslevelno
>
0
);
if
(
band
->
coord
[
0
][
0
]
==
band
->
coord
[
0
][
1
]
||
band
->
coord
[
1
][
0
]
==
band
->
coord
[
1
][
1
])
continue
;
nb_precincts
=
rlevel
->
num_precincts_x
*
rlevel
->
num_precincts_y
;
/* Loop on precincts */
for
(
precno
=
0
;
precno
<
nb_precincts
;
precno
++
)
{
Jpeg2000Prec
*
prec
=
band
->
prec
+
precno
;
/* Loop on codeblocks */
for
(
cblkno
=
0
;
cblkno
<
prec
->
nb_codeblocks_width
*
prec
->
nb_codeblocks_height
;
cblkno
++
)
{
int
x
,
y
;
Jpeg2000Cblk
*
cblk
=
prec
->
cblk
+
cblkno
;
decode_cblk
(
s
,
codsty
,
&
t1
,
cblk
,
cblk
->
coord
[
0
][
1
]
-
cblk
->
coord
[
0
][
0
],
cblk
->
coord
[
1
][
1
]
-
cblk
->
coord
[
1
][
0
],
bandpos
);
/* Manage band offsets */
x
=
cblk
->
coord
[
0
][
0
];
y
=
cblk
->
coord
[
1
][
0
];
if
(
codsty
->
transform
==
FF_DWT97
)
dequantization_float
(
x
,
y
,
cblk
,
comp
,
&
t1
,
band
);
else
dequantization_int
(
x
,
y
,
cblk
,
comp
,
&
t1
,
band
);
}
/* end cblk */
}
/*end prec */
}
/* end band */
}
/* end reslevel */
/* inverse DWT */
ff_dwt_decode
(
&
comp
->
dwt
,
codsty
->
transform
==
FF_DWT97
?
(
void
*
)
comp
->
f_data
:
(
void
*
)
comp
->
i_data
);
}
/*end comp */
/* inverse MCT transformation */
if
(
tile
->
codsty
[
0
].
mct
)
mct_decode
(
s
,
tile
);
if
(
s
->
precision
<=
8
)
{
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
{
Jpeg2000Component
*
comp
=
tile
->
comp
+
compno
;
float
*
datap
=
comp
->
f_data
;
int32_t
*
i_datap
=
comp
->
i_data
;
y
=
tile
->
comp
[
compno
].
coord
[
1
][
0
]
-
s
->
image_offset_y
;
line
=
picture
->
data
[
0
]
+
y
*
picture
->
linesize
[
0
];
for
(;
y
<
tile
->
comp
[
compno
].
coord
[
1
][
1
]
-
s
->
image_offset_y
;
y
+=
s
->
cdy
[
compno
])
{
uint8_t
*
dst
;
x
=
tile
->
comp
[
compno
].
coord
[
0
][
0
]
-
s
->
image_offset_x
;
dst
=
line
+
x
*
s
->
ncomponents
+
compno
;
for
(;
x
<
tile
->
comp
[
compno
].
coord
[
0
][
1
]
-
s
->
image_offset_x
;
x
+=
s
->
cdx
[
compno
])
{
int
val
;
/* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
if
(
tile
->
codsty
->
transform
==
FF_DWT97
)
val
=
lrintf
(
*
datap
)
+
(
1
<<
(
s
->
cbps
[
compno
]
-
1
));
else
val
=
*
i_datap
+
(
1
<<
(
s
->
cbps
[
compno
]
-
1
));
val
=
av_clip
(
val
,
0
,
(
1
<<
s
->
cbps
[
compno
])
-
1
);
*
dst
=
val
<<
(
8
-
s
->
cbps
[
compno
]);
datap
++
;
i_datap
++
;
dst
+=
s
->
ncomponents
;
}
line
+=
picture
->
linesize
[
0
];
}
}
}
else
{
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
{
Jpeg2000Component
*
comp
=
tile
->
comp
+
compno
;
float
*
datap
=
comp
->
f_data
;
int32_t
*
i_datap
=
comp
->
i_data
;
uint16_t
*
linel
;
y
=
tile
->
comp
[
compno
].
coord
[
1
][
0
]
-
s
->
image_offset_y
;
linel
=
(
uint16_t
*
)
picture
->
data
[
0
]
+
y
*
(
picture
->
linesize
[
0
]
>>
1
);
for
(;
y
<
tile
->
comp
[
compno
].
coord
[
1
][
1
]
-
s
->
image_offset_y
;
y
+=
s
->
cdy
[
compno
])
{
uint16_t
*
dst
;
x
=
tile
->
comp
[
compno
].
coord
[
0
][
0
]
-
s
->
image_offset_x
;
dst
=
linel
+
(
x
*
s
->
ncomponents
+
compno
);
for
(;
x
<
tile
->
comp
[
compno
].
coord
[
0
][
1
]
-
s
->
image_offset_x
;
x
+=
s
->
cdx
[
compno
])
{
int
val
;
/* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
if
(
tile
->
codsty
->
transform
==
FF_DWT97
)
val
=
lrintf
(
*
datap
)
+
(
1
<<
(
s
->
cbps
[
compno
]
-
1
));
else
val
=
*
i_datap
+
(
1
<<
(
s
->
cbps
[
compno
]
-
1
));
val
=
av_clip
(
val
,
0
,
(
1
<<
s
->
cbps
[
compno
])
-
1
);
/* align 12 bit values in little-endian mode */
*
dst
=
val
<<
(
16
-
s
->
cbps
[
compno
]);
datap
++
;
i_datap
++
;
dst
+=
s
->
ncomponents
;
}
linel
+=
picture
->
linesize
[
0
]
>>
1
;
}
}
}
return
0
;
}
static
void
jpeg2000_dec_cleanup
(
Jpeg2000DecoderContext
*
s
)
{
int
tileno
,
compno
;
for
(
tileno
=
0
;
tileno
<
s
->
numXtiles
*
s
->
numYtiles
;
tileno
++
)
{
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
{
Jpeg2000Component
*
comp
=
s
->
tile
[
tileno
].
comp
+
compno
;
Jpeg2000CodingStyle
*
codsty
=
s
->
tile
[
tileno
].
codsty
+
compno
;
ff_jpeg2000_cleanup
(
comp
,
codsty
);
}
av_freep
(
&
s
->
tile
[
tileno
].
comp
);
}
av_freep
(
&
s
->
tile
);
}
static
int
jpeg2000_read_main_headers
(
Jpeg2000DecoderContext
*
s
)
{
Jpeg2000CodingStyle
*
codsty
=
s
->
codsty
;
Jpeg2000QuantStyle
*
qntsty
=
s
->
qntsty
;
uint8_t
*
properties
=
s
->
properties
;
for
(;;)
{
int
len
,
ret
=
0
;
int
marker
;
int
oldpos
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
2
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Missing EOC
\n
"
);
break
;
}
marker
=
bytestream2_get_be16u
(
&
s
->
g
);
oldpos
=
bytestream2_tell
(
&
s
->
g
);
if
(
marker
==
JPEG2000_SOD
)
{
Jpeg2000Tile
*
tile
=
s
->
tile
+
s
->
curtileno
;
Jpeg2000TilePart
*
tp
=
tile
->
tile_part
+
tile
->
tp_idx
;
bytestream2_init
(
&
tp
->
tpg
,
s
->
g
.
buffer
,
tp
->
tp_end
-
s
->
g
.
buffer
);
bytestream2_skip
(
&
s
->
g
,
tp
->
tp_end
-
s
->
g
.
buffer
);
continue
;
}
if
(
marker
==
JPEG2000_EOC
)
break
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
2
)
return
AVERROR
(
EINVAL
);
len
=
bytestream2_get_be16u
(
&
s
->
g
);
switch
(
marker
)
{
case
JPEG2000_SIZ
:
ret
=
get_siz
(
s
);
if
(
!
s
->
tile
)
s
->
numXtiles
=
s
->
numYtiles
=
0
;
break
;
case
JPEG2000_COC
:
ret
=
get_coc
(
s
,
codsty
,
properties
);
break
;
case
JPEG2000_COD
:
ret
=
get_cod
(
s
,
codsty
,
properties
);
break
;
case
JPEG2000_QCC
:
ret
=
get_qcc
(
s
,
len
,
qntsty
,
properties
);
break
;
case
JPEG2000_QCD
:
ret
=
get_qcd
(
s
,
len
,
qntsty
,
properties
);
break
;
case
JPEG2000_SOT
:
if
(
!
(
ret
=
get_sot
(
s
,
len
)))
{
codsty
=
s
->
tile
[
s
->
curtileno
].
codsty
;
qntsty
=
s
->
tile
[
s
->
curtileno
].
qntsty
;
properties
=
s
->
tile
[
s
->
curtileno
].
properties
;
}
break
;
case
JPEG2000_COM
:
// the comment is ignored
bytestream2_skip
(
&
s
->
g
,
len
-
2
);
break
;
case
JPEG2000_TLM
:
// Tile-part lengths
ret
=
get_tlm
(
s
,
len
);
break
;
default:
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"unsupported marker 0x%.4X at pos 0x%X
\n
"
,
marker
,
bytestream2_tell
(
&
s
->
g
)
-
4
);
bytestream2_skip
(
&
s
->
g
,
len
-
2
);
break
;
}
if
(
bytestream2_tell
(
&
s
->
g
)
-
oldpos
!=
len
||
ret
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"error during processing marker segment %.4x
\n
"
,
marker
);
return
ret
?
ret
:
-
1
;
}
}
return
0
;
}
/* Read bit stream packets --> T2 operation. */
static
int
jpeg2000_read_bitstream_packets
(
Jpeg2000DecoderContext
*
s
)
{
int
ret
=
0
;
int
tileno
;
for
(
tileno
=
0
;
tileno
<
s
->
numXtiles
*
s
->
numYtiles
;
tileno
++
)
{
Jpeg2000Tile
*
tile
=
s
->
tile
+
tileno
;
if
(
ret
=
init_tile
(
s
,
tileno
))
return
ret
;
s
->
g
=
tile
->
tile_part
[
0
].
tpg
;
if
(
ret
=
jpeg2000_decode_packets
(
s
,
tile
))
return
ret
;
}
return
0
;
}
static
int
jp2_find_codestream
(
Jpeg2000DecoderContext
*
s
)
{
uint32_t
atom_size
,
atom
;
int
found_codestream
=
0
,
search_range
=
10
;
while
(
!
found_codestream
&&
search_range
&&
bytestream2_get_bytes_left
(
&
s
->
g
)
>=
8
)
{
atom_size
=
bytestream2_get_be32u
(
&
s
->
g
);
atom
=
bytestream2_get_be32u
(
&
s
->
g
);
if
(
atom
==
JP2_CODESTREAM
)
{
found_codestream
=
1
;
}
else
{
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
atom_size
-
8
)
return
0
;
bytestream2_skipu
(
&
s
->
g
,
atom_size
-
8
);
search_range
--
;
}
}
if
(
found_codestream
)
return
1
;
return
0
;
}
static
int
jpeg2000_decode_frame
(
AVCodecContext
*
avctx
,
void
*
data
,
int
*
got_frame
,
AVPacket
*
avpkt
)
{
Jpeg2000DecoderContext
*
s
=
avctx
->
priv_data
;
ThreadFrame
frame
=
{
.
f
=
data
};
AVFrame
*
picture
=
data
;
int
tileno
,
ret
;
s
->
avctx
=
avctx
;
bytestream2_init
(
&
s
->
g
,
avpkt
->
data
,
avpkt
->
size
);
s
->
curtileno
=
-
1
;
// reduction factor, i.e number of resolution levels to skip
s
->
reduction_factor
=
avctx
->
lowres
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
2
)
{
ret
=
AVERROR
(
EINVAL
);
goto
err_out
;
}
// check if the image is in jp2 format
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
>=
12
&&
(
bytestream2_get_be32u
(
&
s
->
g
)
==
12
)
&&
(
bytestream2_get_be32u
(
&
s
->
g
)
==
JP2_SIG_TYPE
)
&&
(
bytestream2_get_be32u
(
&
s
->
g
)
==
JP2_SIG_VALUE
))
{
if
(
!
jp2_find_codestream
(
s
))
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"couldn't find jpeg2k codestream atom
\n
"
);
ret
=
-
1
;
goto
err_out
;
}
}
else
{
bytestream2_seek
(
&
s
->
g
,
0
,
SEEK_SET
);
}
if
(
bytestream2_get_be16u
(
&
s
->
g
)
!=
JPEG2000_SOC
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"SOC marker not present
\n
"
);
ret
=
-
1
;
goto
err_out
;
}
if
(
ret
=
jpeg2000_read_main_headers
(
s
))
goto
err_out
;
/* get picture buffer */
if
((
ret
=
ff_thread_get_buffer
(
avctx
,
&
frame
,
0
))
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"ff_thread_get_buffer() failed.
\n
"
);
goto
err_out
;
}
picture
->
pict_type
=
AV_PICTURE_TYPE_I
;
picture
->
key_frame
=
1
;
if
(
ret
=
jpeg2000_read_bitstream_packets
(
s
))
goto
err_out
;
for
(
tileno
=
0
;
tileno
<
s
->
numXtiles
*
s
->
numYtiles
;
tileno
++
)
if
(
ret
=
jpeg2000_decode_tile
(
s
,
s
->
tile
+
tileno
,
picture
))
goto
err_out
;
jpeg2000_dec_cleanup
(
s
);
*
got_frame
=
1
;
return
bytestream2_tell
(
&
s
->
g
);
err_out:
jpeg2000_dec_cleanup
(
s
);
return
ret
;
}
static
void
jpeg2000_init_static_data
(
AVCodec
*
codec
)
{
ff_jpeg2000_init_tier1_luts
();
}
#define OFFSET(x) offsetof(Jpeg2000DecoderContext, x)
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static
const
AVOption
options
[]
=
{
{
"lowres"
,
"Lower the decoding resolution by a power of two"
,
OFFSET
(
lowres
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
JPEG2000_MAX_RESLEVELS
-
1
,
VD
},
{
NULL
},
};
static
const
AVProfile
profiles
[]
=
{
{
FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0
,
"JPEG 2000 codestream restriction 0"
},
{
FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1
,
"JPEG 2000 codestream restriction 1"
},
{
FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION
,
"JPEG 2000 no codestream restrictions"
},
{
FF_PROFILE_JPEG2000_DCINEMA_2K
,
"JPEG 2000 digital cinema 2K"
},
{
FF_PROFILE_JPEG2000_DCINEMA_4K
,
"JPEG 2000 digital cinema 4K"
},
{
FF_PROFILE_UNKNOWN
},
};
static
const
AVClass
class
=
{
.
class_name
=
"j2k"
,
.
item_name
=
av_default_item_name
,
.
option
=
options
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
AVCodec
ff_j2k_decoder
=
{
.
name
=
"j2k"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"JPEG 2000"
),
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
id
=
AV_CODEC_ID_JPEG2000
,
.
capabilities
=
CODEC_CAP_EXPERIMENTAL
|
CODEC_CAP_FRAME_THREADS
,
.
priv_data_size
=
sizeof
(
Jpeg2000DecoderContext
),
.
init_static_data
=
jpeg2000_init_static_data
,
.
decode
=
jpeg2000_decode_frame
,
.
priv_class
=
&
class
,
.
max_lowres
=
5
,
.
profiles
=
NULL_IF_CONFIG_SMALL
(
profiles
)
};
libavcodec/j2kenc.c
View file @
9d56ccf5
...
...
@@ -1036,8 +1036,8 @@ static int j2kenc_destroy(AVCodecContext *avctx)
return
0
;
}
AVCodec
ff_j
2k
_encoder
=
{
.
name
=
"j
2k
"
,
AVCodec
ff_j
peg2000
_encoder
=
{
.
name
=
"j
peg2000
"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
id
=
AV_CODEC_ID_JPEG2000
,
.
priv_data_size
=
sizeof
(
Jpeg2000EncoderContext
),
...
...
libavcodec/jpeg2000.c
View file @
9d56ccf5
...
...
@@ -492,7 +492,7 @@ void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty)
void
ff_jpeg2000_cleanup
(
Jpeg2000Component
*
comp
,
Jpeg2000CodingStyle
*
codsty
)
{
int
reslevelno
,
bandno
,
precno
;
for
(
reslevelno
=
0
;
reslevelno
<
codsty
->
nreslevels
;
reslevelno
++
)
{
for
(
reslevelno
=
0
;
comp
->
reslevel
&&
reslevelno
<
codsty
->
nreslevels
;
reslevelno
++
)
{
Jpeg2000ResLevel
*
reslevel
=
comp
->
reslevel
+
reslevelno
;
for
(
bandno
=
0
;
bandno
<
reslevel
->
nbands
;
bandno
++
)
{
...
...
libavcodec/jpeg2000dec.c
View file @
9d56ccf5
...
...
@@ -41,9 +41,8 @@
#define HAD_QCC 0x02
typedef
struct
Jpeg2000TilePart
{
uint16_t
tp_idx
;
// Tile-part index
uint8_t
tile_index
;
// Tile index who refers the tile-part
uint32_t
tp_len
;
// Length of tile-part
const
uint8_t
*
tp_end
;
GetByteContext
tpg
;
// bit stream in tile-part
}
Jpeg2000TilePart
;
...
...
@@ -55,6 +54,7 @@ typedef struct Jpeg2000Tile {
Jpeg2000CodingStyle
codsty
[
4
];
Jpeg2000QuantStyle
qntsty
[
4
];
Jpeg2000TilePart
tile_part
[
3
];
uint16_t
tp_idx
;
// Tile-part index
}
Jpeg2000Tile
;
typedef
struct
Jpeg2000DecoderContext
{
...
...
@@ -122,6 +122,9 @@ static int tag_tree_decode(Jpeg2000DecoderContext *s, Jpeg2000TgtNode *node,
Jpeg2000TgtNode
*
stack
[
30
];
int
sp
=
-
1
,
curval
=
0
;
if
(
!
node
)
return
AVERROR
(
EINVAL
);
while
(
node
&&
!
node
->
vis
)
{
stack
[
++
sp
]
=
node
;
node
=
node
->
parent
;
...
...
@@ -185,9 +188,12 @@ static int get_siz(Jpeg2000DecoderContext *s)
uint8_t
x
=
bytestream2_get_byteu
(
&
s
->
g
);
s
->
cbps
[
i
]
=
(
x
&
0x7f
)
+
1
;
s
->
precision
=
FFMAX
(
s
->
cbps
[
i
],
s
->
precision
);
s
->
sgnd
[
i
]
=
!!
(
x
&
0x80
);
s
->
sgnd
[
i
]
=
!!
(
x
&
0x80
);
s
->
cdx
[
i
]
=
bytestream2_get_byteu
(
&
s
->
g
);
s
->
cdy
[
i
]
=
bytestream2_get_byteu
(
&
s
->
g
);
if
(
s
->
cdx
[
i
]
!=
1
||
s
->
cdy
[
i
]
!=
1
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"unsupported/ CDxy values
\n
"
);
}
}
s
->
numXtiles
=
ff_jpeg2000_ceildiv
(
s
->
width
-
s
->
tile_offset_x
,
s
->
tile_width
);
...
...
@@ -277,8 +283,7 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
c
->
cblk_style
=
bytestream2_get_byteu
(
&
s
->
g
);
if
(
c
->
cblk_style
!=
0
)
{
// cblk style
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"no extra cblk styles supported
\n
"
);
return
-
1
;
av_log
(
s
->
avctx
,
AV_LOG_WARNING
,
"extra cblk styles %X
\n
"
,
c
->
cblk_style
);
}
c
->
transform
=
bytestream2_get_byteu
(
&
s
->
g
);
// DWT transformation type
/* set integer 9/7 DWT in case of BITEXACT flag */
...
...
@@ -433,11 +438,6 @@ static int get_sot(Jpeg2000DecoderContext *s, int n)
s
->
curtileno
=
0
;
return
AVERROR
(
EINVAL
);
}
if
(
Isot
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Not a DCINEMA JP2K file: more than one tile
\n
"
);
return
-
1
;
}
Psot
=
bytestream2_get_be32u
(
&
s
->
g
);
// Psot
TPsot
=
bytestream2_get_byteu
(
&
s
->
g
);
// TPsot
...
...
@@ -449,24 +449,18 @@ static int get_sot(Jpeg2000DecoderContext *s, int n)
return
AVERROR_PATCHWELCOME
;
}
s
->
tile
[
s
->
curtileno
].
tp_idx
=
TPsot
;
tp
=
s
->
tile
[
s
->
curtileno
].
tile_part
+
TPsot
;
tp
->
tile_index
=
Isot
;
tp
->
tp_len
=
Psot
;
tp
->
tp_idx
=
TPsot
;
/* Start of bit stream. Pointer to SOD marker
* Check SOD marker is present. */
if
(
JPEG2000_SOD
==
bytestream2_get_be16
(
&
s
->
g
))
{
bytestream2_init
(
&
tp
->
tpg
,
s
->
g
.
buffer
,
tp
->
tp_len
-
n
-
4
);
bytestream2_skip
(
&
s
->
g
,
tp
->
tp_len
-
n
-
4
);
}
else
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"SOD marker not found
\n
"
);
return
-
1
;
}
tp
->
tp_end
=
s
->
g
.
buffer
+
Psot
-
n
-
2
;
if
(
!
TPsot
)
{
Jpeg2000Tile
*
tile
=
s
->
tile
+
s
->
curtileno
;
/* End address of bit stream =
* start address + (Psot - size of SOT HEADER(n)
* - size of SOT MARKER(2) - size of SOD marker(2) */
/* copy defaults */
memcpy
(
tile
->
codsty
,
s
->
codsty
,
s
->
ncomponents
*
sizeof
(
Jpeg2000CodingStyle
));
memcpy
(
tile
->
qntsty
,
s
->
qntsty
,
s
->
ncomponents
*
sizeof
(
Jpeg2000QuantStyle
));
}
return
0
;
}
...
...
@@ -523,12 +517,6 @@ static int init_tile(Jpeg2000DecoderContext *s, int tileno)
if
(
!
tile
->
comp
)
return
AVERROR
(
ENOMEM
);
/* copy codsty, qnsty to tile. TODO: Is it the best way?
* codsty, qnsty is an array of 4 structs Jpeg2000CodingStyle
* and Jpeg2000QuantStyle */
memcpy
(
tile
->
codsty
,
s
->
codsty
,
s
->
ncomponents
*
sizeof
(
*
tile
->
codsty
));
memcpy
(
tile
->
qntsty
,
s
->
qntsty
,
s
->
ncomponents
*
sizeof
(
*
tile
->
qntsty
));
for
(
compno
=
0
;
compno
<
s
->
ncomponents
;
compno
++
)
{
Jpeg2000Component
*
comp
=
tile
->
comp
+
compno
;
Jpeg2000CodingStyle
*
codsty
=
tile
->
codsty
+
compno
;
...
...
@@ -674,6 +662,7 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile
s
->
bit_index
=
8
;
switch
(
tile
->
codsty
[
0
].
prog_order
)
{
case
JPEG2000_PGOD_LRCP
:
case
JPEG2000_PGOD_RLCP
:
for
(
layno
=
0
;
layno
<
tile
->
codsty
[
0
].
nlayers
;
layno
++
)
{
ok_reslevel
=
1
;
for
(
reslevelno
=
0
;
ok_reslevel
;
reslevelno
++
)
{
...
...
@@ -683,7 +672,7 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile
Jpeg2000QuantStyle
*
qntsty
=
tile
->
qntsty
+
compno
;
if
(
reslevelno
<
codsty
->
nreslevels
)
{
Jpeg2000ResLevel
*
rlevel
=
tile
->
comp
[
compno
].
reslevel
+
reslevelno
;
reslevelno
;
ok_reslevel
=
1
;
for
(
precno
=
0
;
precno
<
rlevel
->
num_precincts_x
*
rlevel
->
num_precincts_y
;
precno
++
)
if
(
jpeg2000_decode_packet
(
s
,
...
...
@@ -758,32 +747,33 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile
/* TIER-1 routines */
static
void
decode_sigpass
(
Jpeg2000T1Context
*
t1
,
int
width
,
int
height
,
int
bpno
,
int
bandno
)
int
bpno
,
int
bandno
,
int
bpass_csty_symbol
,
int
vert_causal_ctx_csty_symbol
)
{
int
mask
=
3
<<
(
bpno
-
1
),
y0
,
x
,
y
;
for
(
y0
=
0
;
y0
<
height
;
y0
+=
4
)
for
(
x
=
0
;
x
<
width
;
x
++
)
for
(
y
=
y0
;
y
<
height
&&
y
<
y0
+
4
;
y
++
)
if
((
t1
->
flags
[
y
+
1
][
x
+
1
]
&
JPEG2000_T1_SIG_NB
)
&&
!
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG
|
JPEG2000_T1_VIS
)))
{
if
(
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ff_jpeg2000_getsigctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
],
bandno
)))
{
int
xorbit
,
ctxno
=
ff_jpeg2000_getsgnctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
],
&
xorbit
);
t1
->
data
[
y
][
x
]
=
(
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ctxno
)
^
xorbit
)
?
-
mask
:
mask
;
for
(
y
=
y0
;
y
<
height
&&
y
<
y0
+
4
;
y
++
)
{
if
((
t1
->
flags
[
y
+
1
][
x
+
1
]
&
JPEG2000_T1_SIG_NB
)
&&
!
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG
|
JPEG2000_T1_VIS
)))
{
int
flags_mask
=
-
1
;
if
(
vert_causal_ctx_csty_symbol
&&
y
==
y0
+
3
)
flags_mask
&=
~
(
JPEG2000_T1_SIG_S
|
JPEG2000_T1_SIG_SW
|
JPEG2000_T1_SIG_SE
);
if
(
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ff_jpeg2000_getsigctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
flags_mask
,
bandno
)))
{
int
xorbit
,
ctxno
=
ff_jpeg2000_getsgnctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
],
&
xorbit
);
if
(
bpass_csty_symbol
)
t1
->
data
[
y
][
x
]
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ctxno
)
?
-
mask
:
mask
;
else
t1
->
data
[
y
][
x
]
=
(
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ctxno
)
^
xorbit
)
?
-
mask
:
mask
;
ff_jpeg2000_set_significance
(
t1
,
x
,
y
,
t1
->
data
[
y
][
x
]
<
0
);
}
t1
->
flags
[
y
+
1
][
x
+
1
]
|=
JPEG2000_T1_VIS
;
}
}
}
static
void
decode_refpass
(
Jpeg2000T1Context
*
t1
,
int
width
,
int
height
,
...
...
@@ -810,11 +800,11 @@ static void decode_refpass(Jpeg2000T1Context *t1, int width, int height,
static
void
decode_clnpass
(
Jpeg2000DecoderContext
*
s
,
Jpeg2000T1Context
*
t1
,
int
width
,
int
height
,
int
bpno
,
int
bandno
,
int
seg_symbols
)
int
seg_symbols
,
int
vert_causal_ctx_csty_symbol
)
{
int
mask
=
3
<<
(
bpno
-
1
),
y0
,
x
,
y
,
runlen
,
dec
;
for
(
y0
=
0
;
y0
<
height
;
y0
+=
4
)
for
(
y0
=
0
;
y0
<
height
;
y0
+=
4
)
{
for
(
x
=
0
;
x
<
width
;
x
++
)
{
if
(
y0
+
3
<
height
&&
!
((
t1
->
flags
[
y0
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG_NB
|
JPEG2000_T1_VIS
|
JPEG2000_T1_SIG
))
||
...
...
@@ -836,11 +826,13 @@ static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
for
(
y
=
y0
+
runlen
;
y
<
y0
+
4
&&
y
<
height
;
y
++
)
{
if
(
!
dec
)
{
if
(
!
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG
|
JPEG2000_T1_VIS
)))
dec
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ff_jpeg2000_getsigctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
],
bandno
));
if
(
!
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
(
JPEG2000_T1_SIG
|
JPEG2000_T1_VIS
)))
{
int
flags_mask
=
-
1
;
if
(
vert_causal_ctx_csty_symbol
&&
y
==
y0
+
3
)
flags_mask
&=
~
(
JPEG2000_T1_SIG_S
|
JPEG2000_T1_SIG_SW
|
JPEG2000_T1_SIG_SE
);
dec
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
ff_jpeg2000_getsigctxno
(
t1
->
flags
[
y
+
1
][
x
+
1
]
&
flags_mask
,
bandno
));
}
}
if
(
dec
)
{
int
xorbit
;
...
...
@@ -856,6 +848,7 @@ static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
t1
->
flags
[
y
+
1
][
x
+
1
]
&=
~
JPEG2000_T1_VIS
;
}
}
}
if
(
seg_symbols
)
{
int
val
;
val
=
ff_mqc_decode
(
&
t1
->
mqc
,
t1
->
mqc
.
cx_states
+
MQC_CX_UNI
);
...
...
@@ -872,7 +865,9 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
Jpeg2000T1Context
*
t1
,
Jpeg2000Cblk
*
cblk
,
int
width
,
int
height
,
int
bandpos
)
{
int
passno
=
cblk
->
npasses
,
pass_t
=
2
,
bpno
=
cblk
->
nonzerobits
-
1
,
y
;
int
passno
=
cblk
->
npasses
,
pass_t
=
2
,
bpno
=
cblk
->
nonzerobits
-
1
,
y
,
clnpass_cnt
=
0
;
int
bpass_csty_symbol
=
JPEG2000_CBLK_BYPASS
&
codsty
->
cblk_style
;
int
vert_causal_ctx_csty_symbol
=
JPEG2000_CBLK_VSC
&
codsty
->
cblk_style
;
for
(
y
=
0
;
y
<
height
;
y
++
)
memset
(
t1
->
data
[
y
],
0
,
width
*
sizeof
(
**
t1
->
data
));
...
...
@@ -880,24 +875,31 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
/* If code-block contains no compressed data: nothing to do. */
if
(
!
cblk
->
length
)
return
0
;
for
(
y
=
0
;
y
<
height
+
2
;
y
++
)
memset
(
t1
->
flags
[
y
],
0
,
(
width
+
2
)
*
sizeof
(
**
t1
->
flags
));
cblk
->
data
[
cblk
->
length
]
=
0xff
;
cblk
->
data
[
cblk
->
length
+
1
]
=
0xff
;
for
(
y
=
0
;
y
<
height
+
2
;
y
++
)
memset
(
t1
->
flags
[
y
],
0
,
(
width
+
2
)
*
sizeof
(
**
t1
->
flags
));
cblk
->
data
[
cblk
->
length
]
=
0xff
;
cblk
->
data
[
cblk
->
length
+
1
]
=
0xff
;
ff_mqc_initdec
(
&
t1
->
mqc
,
cblk
->
data
);
while
(
passno
--
)
{
switch
(
pass_t
)
{
switch
(
pass_t
)
{
case
0
:
decode_sigpass
(
t1
,
width
,
height
,
bpno
+
1
,
bandpos
);
decode_sigpass
(
t1
,
width
,
height
,
bpno
+
1
,
bandpos
,
bpass_csty_symbol
&&
(
clnpass_cnt
>=
4
),
vert_causal_ctx_csty_symbol
);
break
;
case
1
:
decode_refpass
(
t1
,
width
,
height
,
bpno
+
1
);
if
(
bpass_csty_symbol
&&
clnpass_cnt
>=
4
)
ff_mqc_initdec
(
&
t1
->
mqc
,
cblk
->
data
);
break
;
case
2
:
decode_clnpass
(
s
,
t1
,
width
,
height
,
bpno
+
1
,
bandpos
,
codsty
->
cblk_style
&
JPEG2000_CBLK_SEGSYM
);
codsty
->
cblk_style
&
JPEG2000_CBLK_SEGSYM
,
vert_causal_ctx_csty_symbol
);
clnpass_cnt
=
clnpass_cnt
+
1
;
if
(
bpass_csty_symbol
&&
clnpass_cnt
>=
4
)
ff_mqc_initdec
(
&
t1
->
mqc
,
cblk
->
data
);
break
;
}
...
...
@@ -1033,8 +1035,12 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
int
nb_precincts
,
precno
;
Jpeg2000Band
*
band
=
rlevel
->
band
+
bandno
;
int
cblkno
=
0
,
bandpos
;
bandpos
=
bandno
+
(
reslevelno
>
0
);
if
(
band
->
coord
[
0
][
0
]
==
band
->
coord
[
0
][
1
]
||
band
->
coord
[
1
][
0
]
==
band
->
coord
[
1
][
1
])
continue
;
nb_precincts
=
rlevel
->
num_precincts_x
*
rlevel
->
num_precincts_y
;
/* Loop on precincts */
for
(
precno
=
0
;
precno
<
nb_precincts
;
precno
++
)
{
...
...
@@ -1114,8 +1120,8 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
x
=
tile
->
comp
[
compno
].
coord
[
0
][
0
]
-
s
->
image_offset_x
;
dst
=
linel
+
(
x
*
s
->
ncomponents
+
compno
);
for
(;
x
<
s
->
avctx
->
width
;
x
+=
s
->
cdx
[
compno
])
{
int
val
;
for
(;
x
<
tile
->
comp
[
compno
].
coord
[
0
][
1
]
-
s
->
image_offset_x
;
x
+=
s
->
cdx
[
compno
])
{
int
val
;
/* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
if
(
tile
->
codsty
->
transform
==
FF_DWT97
)
val
=
lrintf
(
*
datap
)
+
(
1
<<
(
s
->
cbps
[
compno
]
-
1
));
...
...
@@ -1169,6 +1175,15 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
marker
=
bytestream2_get_be16u
(
&
s
->
g
);
oldpos
=
bytestream2_tell
(
&
s
->
g
);
if
(
marker
==
JPEG2000_SOD
)
{
Jpeg2000Tile
*
tile
=
s
->
tile
+
s
->
curtileno
;
Jpeg2000TilePart
*
tp
=
tile
->
tile_part
+
tile
->
tp_idx
;
bytestream2_init
(
&
tp
->
tpg
,
s
->
g
.
buffer
,
tp
->
tp_end
-
s
->
g
.
buffer
);
bytestream2_skip
(
&
s
->
g
,
tp
->
tp_end
-
s
->
g
.
buffer
);
continue
;
}
if
(
marker
==
JPEG2000_EOC
)
break
;
...
...
@@ -1194,7 +1209,11 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
ret
=
get_qcd
(
s
,
len
,
qntsty
,
properties
);
break
;
case
JPEG2000_SOT
:
ret
=
get_sot
(
s
,
len
);
if
(
!
(
ret
=
get_sot
(
s
,
len
)))
{
codsty
=
s
->
tile
[
s
->
curtileno
].
codsty
;
qntsty
=
s
->
tile
[
s
->
curtileno
].
qntsty
;
properties
=
s
->
tile
[
s
->
curtileno
].
properties
;
}
break
;
case
JPEG2000_COM
:
// the comment is ignored
...
...
@@ -1211,7 +1230,7 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
bytestream2_skip
(
&
s
->
g
,
len
-
2
);
break
;
}
if
(
((
bytestream2_tell
(
&
s
->
g
)
-
oldpos
!=
len
)
&&
(
marker
!=
JPEG2000_SOT
))
||
ret
)
{
if
(
bytestream2_tell
(
&
s
->
g
)
-
oldpos
!=
len
||
ret
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"error during processing marker segment %.4x
\n
"
,
marker
);
return
ret
?
ret
:
-
1
;
...
...
@@ -1224,12 +1243,18 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
static
int
jpeg2000_read_bitstream_packets
(
Jpeg2000DecoderContext
*
s
)
{
int
ret
=
0
;
Jpeg2000Tile
*
tile
=
s
->
tile
+
s
->
cur
tileno
;
int
tileno
;
if
(
ret
=
init_tile
(
s
,
s
->
curtileno
))
return
ret
;
if
(
ret
=
jpeg2000_decode_packets
(
s
,
tile
))
return
ret
;
for
(
tileno
=
0
;
tileno
<
s
->
numXtiles
*
s
->
numYtiles
;
tileno
++
)
{
Jpeg2000Tile
*
tile
=
s
->
tile
+
tileno
;
if
(
ret
=
init_tile
(
s
,
tileno
))
return
ret
;
s
->
g
=
tile
->
tile_part
[
0
].
tpg
;
if
(
ret
=
jpeg2000_decode_packets
(
s
,
tile
))
return
ret
;
}
return
0
;
}
...
...
@@ -1267,13 +1292,15 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
s
->
avctx
=
avctx
;
bytestream2_init
(
&
s
->
g
,
avpkt
->
data
,
avpkt
->
size
);
s
->
curtileno
=
0
;
// TODO: only one tile in DCI JP2K. to implement for more tiles
s
->
curtileno
=
-
1
;
// reduction factor, i.e number of resolution levels to skip
s
->
reduction_factor
=
s
->
lowres
;
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
2
)
return
AVERROR
(
EINVAL
);
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
<
2
)
{
ret
=
AVERROR
(
EINVAL
);
goto
end
;
}
// check if the image is in jp2 format
if
(
bytestream2_get_bytes_left
(
&
s
->
g
)
>=
12
&&
...
...
@@ -1283,17 +1310,17 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
if
(
!
jp2_find_codestream
(
s
))
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"couldn't find jpeg2k codestream atom
\n
"
);
return
-
1
;
ret
=
-
1
;
goto
end
;
}
}
else
{
bytestream2_seek
(
&
s
->
g
,
0
,
SEEK_SET
);
if
(
bytestream2_peek_be16
(
&
s
->
g
)
!=
JPEG2000_SOC
/*&& AV_RB32(s->buf + 4) == JP2_CODESTREAM*/
)
bytestream2_skip
(
&
s
->
g
,
8
);
}
if
(
bytestream2_get_be16u
(
&
s
->
g
)
!=
JPEG2000_SOC
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"SOC marker not present
\n
"
);
return
-
1
;
ret
=
-
1
;
goto
end
;
}
if
(
ret
=
jpeg2000_read_main_headers
(
s
))
goto
end
;
...
...
@@ -1308,9 +1335,11 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
if
(
ret
=
jpeg2000_read_bitstream_packets
(
s
))
goto
end
;
for
(
tileno
=
0
;
tileno
<
s
->
numXtiles
*
s
->
numYtiles
;
tileno
++
)
if
(
ret
=
jpeg2000_decode_tile
(
s
,
s
->
tile
+
tileno
,
picture
))
goto
end
;
jpeg2000_dec_cleanup
(
s
);
*
got_frame
=
1
;
...
...
@@ -1361,9 +1390,6 @@ AVCodec ff_jpeg2000_decoder = {
.
init_static_data
=
jpeg2000_init_static_data
,
.
decode
=
jpeg2000_decode_frame
,
.
priv_class
=
&
class
,
.
pix_fmts
=
(
enum
AVPixelFormat
[])
{
AV_PIX_FMT_XYZ12
,
AV_PIX_FMT_GRAY8
,
-
1
},
.
max_lowres
=
5
,
.
profiles
=
NULL_IF_CONFIG_SMALL
(
profiles
)
};
tests/fate/vcodec.mak
View file @
9d56ccf5
...
...
@@ -89,11 +89,11 @@ FATE_VCODEC-$(call ENCDEC, JPEGLS, AVI) += jpegls
fate-vsynth%-jpegls: ENCOPTS = -sws_flags neighbor+full_chroma_int
fate-vsynth%-jpegls: DECOPTS = -sws_flags area
FATE_VCODEC-$(call ENCDEC, J
2K, AVI) += j2k j2k
-97
fate-vsynth%-j
2k
: ENCOPTS = -qscale 7 -strict experimental -pred 1 -pix_fmt rgb24
fate-vsynth%-j
2k: DECINOPTS = -vcodec j2k -strict experimental
fate-vsynth%-j
2k
-97: ENCOPTS = -qscale 7 -strict experimental -pix_fmt rgb24
fate-vsynth%-j
2k-97: DECINOPTS = -vcodec j2k -strict experimental
FATE_VCODEC-$(call ENCDEC, J
PEG2000, AVI) += jpeg2000 jpeg2000
-97
fate-vsynth%-j
peg2000
: ENCOPTS = -qscale 7 -strict experimental -pred 1 -pix_fmt rgb24
fate-vsynth%-j
peg2000: DECINOPTS = -vcodec jpeg2000
fate-vsynth%-j
peg2000
-97: ENCOPTS = -qscale 7 -strict experimental -pix_fmt rgb24
fate-vsynth%-j
peg2000-97: DECINOPTS = -vcodec jpeg2000
FATE_VCODEC-$(call ENCDEC, LJPEG MJPEG, AVI) += ljpeg
fate-vsynth%-ljpeg: ENCOPTS = -strict -1
...
...
tests/ref/vsynth/vsynth1-j2k
deleted
100644 → 0
View file @
fd7e1190
e6e3d338eeb394d6fadc7bbb55fa9e6e *tests/data/fate/vsynth1-j2k.avi
2306902 tests/data/fate/vsynth1-j2k.avi
1774b621bd92a53a24712cb77e9f0b28 *tests/data/fate/vsynth1-j2k.out.rawvideo
stddev: 5.37 PSNR: 33.52 MAXDIFF: 63 bytes: 7603200/ 7603200
tests/ref/vsynth/vsynth1-j2k-97
deleted
100644 → 0
View file @
fd7e1190
c135eb14e9f219242180270c2a242634 *tests/data/fate/vsynth1-j2k-97.avi
2243132 tests/data/fate/vsynth1-j2k-97.avi
30a9c13e18fe4acaf28062b5003bb671 *tests/data/fate/vsynth1-j2k-97.out.rawvideo
stddev: 6.41 PSNR: 31.99 MAXDIFF: 75 bytes: 7603200/ 7603200
tests/ref/vsynth/vsynth1-jpeg2000
0 → 100644
View file @
9d56ccf5
e6e3d338eeb394d6fadc7bbb55fa9e6e *tests/data/fate/vsynth1-jpeg2000.avi
2306902 tests/data/fate/vsynth1-jpeg2000.avi
1774b621bd92a53a24712cb77e9f0b28 *tests/data/fate/vsynth1-jpeg2000.out.rawvideo
stddev: 5.37 PSNR: 33.52 MAXDIFF: 63 bytes: 7603200/ 7603200
tests/ref/vsynth/vsynth1-jpeg2000-97
0 → 100644
View file @
9d56ccf5
c135eb14e9f219242180270c2a242634 *tests/data/fate/vsynth1-jpeg2000-97.avi
2243132 tests/data/fate/vsynth1-jpeg2000-97.avi
30a9c13e18fe4acaf28062b5003bb671 *tests/data/fate/vsynth1-jpeg2000-97.out.rawvideo
stddev: 6.41 PSNR: 31.99 MAXDIFF: 75 bytes: 7603200/ 7603200
tests/ref/vsynth/vsynth2-j2k
deleted
100644 → 0
View file @
fd7e1190
fc49816ba28731689872f5c87ca91c10 *tests/data/fate/vsynth2-j2k.avi
1151144 tests/data/fate/vsynth2-j2k.avi
e7d79c9e11d0fe97f03e38be66c34e4f *tests/data/fate/vsynth2-j2k.out.rawvideo
stddev: 4.41 PSNR: 35.23 MAXDIFF: 63 bytes: 7603200/ 7603200
tests/ref/vsynth/vsynth2-j2k-97
deleted
100644 → 0
View file @
fd7e1190
3ac3e49a89136bddde9e44bac3e5b4ed *tests/data/fate/vsynth2-j2k-97.avi
1118952 tests/data/fate/vsynth2-j2k-97.avi
9d69ac6d46152ed2d6dd6a90d5793c80 *tests/data/fate/vsynth2-j2k-97.out.rawvideo
stddev: 5.32 PSNR: 33.61 MAXDIFF: 60 bytes: 7603200/ 7603200
tests/ref/vsynth/vsynth2-jpeg2000
0 → 100644
View file @
9d56ccf5
fc49816ba28731689872f5c87ca91c10 *tests/data/fate/vsynth2-jpeg2000.avi
1151144 tests/data/fate/vsynth2-jpeg2000.avi
e7d79c9e11d0fe97f03e38be66c34e4f *tests/data/fate/vsynth2-jpeg2000.out.rawvideo
stddev: 4.41 PSNR: 35.23 MAXDIFF: 63 bytes: 7603200/ 7603200
tests/ref/vsynth/vsynth2-jpeg2000-97
0 → 100644
View file @
9d56ccf5
3ac3e49a89136bddde9e44bac3e5b4ed *tests/data/fate/vsynth2-jpeg2000-97.avi
1118952 tests/data/fate/vsynth2-jpeg2000-97.avi
9d69ac6d46152ed2d6dd6a90d5793c80 *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo
stddev: 5.32 PSNR: 33.61 MAXDIFF: 60 bytes: 7603200/ 7603200
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