@ -764,6 +764,7 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s,
int layno , uint8_t * expn , int numgbits )
int layno , uint8_t * expn , int numgbits )
{
{
int bandno , cblkno , ret , nb_code_blocks ;
int bandno , cblkno , ret , nb_code_blocks ;
int cwsno ;
if ( ! ( ret = get_bits ( s , 1 ) ) ) {
if ( ! ( ret = get_bits ( s , 1 ) ) ) {
jpeg2000_flush ( s ) ;
jpeg2000_flush ( s ) ;
@ -819,16 +820,32 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s,
}
}
cblk - > lblock + = llen ;
cblk - > lblock + = llen ;
if ( ( ret = get_bits ( s , av_log2 ( newpasses ) + cblk - > lblock ) ) < 0 )
return ret ;
cblk - > nb_lengthinc = 0 ;
if ( ret > sizeof ( cblk - > data ) ) {
cblk - > nb_terminationsinc = 0 ;
avpriv_request_sample ( s - > avctx ,
do {
" Block with lengthinc greater than % " SIZE_SPECIFIER " " ,
int newpasses1 = 0 ;
sizeof ( cblk - > data ) ) ;
return AVERROR_PATCHWELCOME ;
while ( newpasses1 < newpasses ) {
}
newpasses1 + + ;
cblk - > lengthinc = ret ;
if ( needs_termination ( codsty - > cblk_style , cblk - > npasses + newpasses1 - 1 ) ) {
cblk - > npasses + = newpasses ;
cblk - > nb_terminationsinc + + ;
break ;
}
}
if ( ( ret = get_bits ( s , av_log2 ( newpasses1 ) + cblk - > lblock ) ) < 0 )
return ret ;
if ( ret > sizeof ( cblk - > data ) ) {
avpriv_request_sample ( s - > avctx ,
" Block with lengthinc greater than % " SIZE_SPECIFIER " " ,
sizeof ( cblk - > data ) ) ;
return AVERROR_PATCHWELCOME ;
}
cblk - > lengthinc [ cblk - > nb_lengthinc + + ] = ret ;
cblk - > npasses + = newpasses1 ;
newpasses - = newpasses1 ;
} while ( newpasses ) ;
}
}
}
}
jpeg2000_flush ( s ) ;
jpeg2000_flush ( s ) ;
@ -847,18 +864,27 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s,
nb_code_blocks = prec - > nb_codeblocks_height * prec - > nb_codeblocks_width ;
nb_code_blocks = prec - > nb_codeblocks_height * prec - > nb_codeblocks_width ;
for ( cblkno = 0 ; cblkno < nb_code_blocks ; cblkno + + ) {
for ( cblkno = 0 ; cblkno < nb_code_blocks ; cblkno + + ) {
Jpeg2000Cblk * cblk = prec - > cblk + cblkno ;
Jpeg2000Cblk * cblk = prec - > cblk + cblkno ;
if ( bytestream2_get_bytes_left ( & s - > g ) < cblk - > lengthinc
for ( cwsno = 0 ; cwsno < cblk - > nb_lengthinc ; cwsno + + ) {
| | sizeof ( cblk - > data ) < cblk - > length + cblk - > lengthinc + 2
if ( bytestream2_get_bytes_left ( & s - > g ) < cblk - > lengthinc [ cwsno ]
) {
| | sizeof ( cblk - > data ) < cblk - > length + cblk - > lengthinc [ cwsno ] + 4
av_log ( s - > avctx , AV_LOG_ERROR ,
) {
" Block length % " PRIu16 " or lengthinc %d is too large \n " ,
av_log ( s - > avctx , AV_LOG_ERROR ,
cblk - > length , cblk - > lengthinc ) ;
" Block length % " PRIu16 " or lengthinc %d is too large \n " ,
return AVERROR_INVALIDDATA ;
cblk - > length , cblk - > lengthinc [ cwsno ] ) ;
}
return AVERROR_INVALIDDATA ;
}
bytestream2_get_bufferu ( & s - > g , cblk - > data + cblk - > length , cblk - > lengthinc ) ;
bytestream2_get_bufferu ( & s - > g , cblk - > data + cblk - > length , cblk - > lengthinc [ cwsno ] ) ;
cblk - > length + = cblk - > lengthinc ;
cblk - > length + = cblk - > lengthinc [ cwsno ] ;
cblk - > lengthinc = 0 ;
cblk - > lengthinc [ cwsno ] = 0 ;
if ( cblk - > nb_terminationsinc ) {
cblk - > nb_terminationsinc - - ;
cblk - > nb_terminations + + ;
cblk - > data [ cblk - > length + + ] = 0xFF ;
cblk - > data [ cblk - > length + + ] = 0xFF ;
cblk - > data_start [ cblk - > nb_terminations ] = cblk - > length ;
}
}
}
}
}
}
return 0 ;
return 0 ;
@ -1012,7 +1038,7 @@ static void decode_sigpass(Jpeg2000T1Context *t1, int width, int height,
flags_mask & = ~ ( JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE ) ;
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 ) ) ) {
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 ) ;
int xorbit , ctxno = ff_jpeg2000_getsgnctxno ( t1 - > flags [ y + 1 ] [ x + 1 ] , & xorbit ) ;
if ( bpass_csty_symbol )
if ( t1 - > mqc . raw )
t1 - > data [ y ] [ x ] = ff_mqc_decode ( & t1 - > mqc , t1 - > mqc . cx_states + ctxno ) ? - mask : mask ;
t1 - > data [ y ] [ x ] = ff_mqc_decode ( & t1 - > mqc , t1 - > mqc . cx_states + ctxno ) ? - mask : mask ;
else
else
t1 - > data [ y ] [ x ] = ( ff_mqc_decode ( & t1 - > mqc , t1 - > mqc . cx_states + ctxno ) ^ xorbit ) ?
t1 - > data [ y ] [ x ] = ( ff_mqc_decode ( & t1 - > mqc , t1 - > mqc . cx_states + ctxno ) ^ xorbit ) ?
@ -1116,9 +1142,11 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
int width , int height , int bandpos )
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 ;
int cln pass_cnt = 0 ;
int pass_cnt = 0 ;
int bpass_csty_symbol = codsty - > cblk_style & JPEG2000_CBLK_BYPASS ;
int bpass_csty_symbol = codsty - > cblk_style & JPEG2000_CBLK_BYPASS ;
int vert_causal_ctx_csty_symbol = codsty - > cblk_style & JPEG2000_CBLK_VSC ;
int vert_causal_ctx_csty_symbol = codsty - > cblk_style & JPEG2000_CBLK_VSC ;
int term_cnt = 0 ;
int coder_type ;
av_assert0 ( width < = JPEG2000_MAX_CBLKW ) ;
av_assert0 ( width < = JPEG2000_MAX_CBLKW ) ;
av_assert0 ( height < = JPEG2000_MAX_CBLKH ) ;
av_assert0 ( height < = JPEG2000_MAX_CBLKH ) ;
@ -1141,24 +1169,33 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
switch ( pass_t ) {
switch ( pass_t ) {
case 0 :
case 0 :
decode_sigpass ( t1 , width , height , bpno + 1 , bandpos ,
decode_sigpass ( t1 , width , height , bpno + 1 , bandpos ,
bpass_csty_symbol & & ( cln pass_cnt > = 4 ) ,
bpass_csty_symbol & & ( pass_cnt > = 3 * 3 ) ,
vert_causal_ctx_csty_symbol ) ;
vert_causal_ctx_csty_symbol ) ;
break ;
break ;
case 1 :
case 1 :
decode_refpass ( t1 , width , height , bpno + 1 ) ;
decode_refpass ( t1 , width , height , bpno + 1 ) ;
break ;
break ;
case 2 :
case 2 :
av_assert2 ( ! t1 - > mqc . raw ) ;
decode_clnpass ( s , t1 , width , height , bpno + 1 , bandpos ,
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 ) ;
vert_causal_ctx_csty_symbol ) ;
break ;
break ;
}
}
if ( ( coder_type = needs_termination ( codsty - > cblk_style , pass_cnt ) ) ) {
if ( term_cnt > = cblk - > nb_terminations ) {
av_log ( s - > avctx , AV_LOG_ERROR , " Missing needed termination \n " ) ;
return AVERROR_INVALIDDATA ;
}
ff_mqc_initdec ( & t1 - > mqc , cblk - > data + cblk - > data_start [ + + term_cnt ] , coder_type = = 2 , 0 ) ;
}
pass_t + + ;
pass_t + + ;
if ( pass_t = = 3 ) {
if ( pass_t = = 3 ) {
bpno - - ;
bpno - - ;
pass_t = 0 ;
pass_t = 0 ;
}
}
pass_cnt + + ;
}
}
return 0 ;
return 0 ;
}
}