You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
avcodec/jpeg2000: Change coord to 32bit to support larger than 32k width or height
Fixes: 03e0abe721b1174856d41a1eb5d6a896/signal_sigabrt_7ffff6ae7cc9_3813_e71bf3541abed3ccba031cd5ba0269a4.avi Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
@@ -322,7 +322,7 @@ static int init_prec(Jpeg2000Band *band,
|
|||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
for (cblkno = 0; cblkno < nb_codeblocks; cblkno++) {
|
for (cblkno = 0; cblkno < nb_codeblocks; cblkno++) {
|
||||||
Jpeg2000Cblk *cblk = prec->cblk + cblkno;
|
Jpeg2000Cblk *cblk = prec->cblk + cblkno;
|
||||||
uint16_t Cx0, Cy0;
|
int Cx0, Cy0;
|
||||||
|
|
||||||
/* Compute coordinates of codeblocks */
|
/* Compute coordinates of codeblocks */
|
||||||
/* Compute Cx0*/
|
/* Compute Cx0*/
|
||||||
@@ -468,8 +468,8 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp,
|
|||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
csize = (comp->coord[0][1] - comp->coord[0][0]) *
|
csize = (comp->coord[0][1] - comp->coord[0][0]) *
|
||||||
(comp->coord[1][1] - comp->coord[1][0]);
|
(comp->coord[1][1] - comp->coord[1][0]);
|
||||||
if (comp->coord[0][1] > 32768 ||
|
if (comp->coord[0][1] - comp->coord[0][0] > 32768 ||
|
||||||
comp->coord[1][1] > 32768) {
|
comp->coord[1][1] - comp->coord[1][0] > 32768) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "component size too large\n");
|
av_log(avctx, AV_LOG_ERROR, "component size too large\n");
|
||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
}
|
}
|
||||||
|
@@ -174,21 +174,21 @@ typedef struct Jpeg2000Cblk {
|
|||||||
int nb_terminationsinc;
|
int nb_terminationsinc;
|
||||||
int data_start[JPEG2000_MAX_PASSES];
|
int data_start[JPEG2000_MAX_PASSES];
|
||||||
Jpeg2000Pass passes[JPEG2000_MAX_PASSES];
|
Jpeg2000Pass passes[JPEG2000_MAX_PASSES];
|
||||||
uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
||||||
} Jpeg2000Cblk; // code block
|
} Jpeg2000Cblk; // code block
|
||||||
|
|
||||||
typedef struct Jpeg2000Prec {
|
typedef struct Jpeg2000Prec {
|
||||||
uint16_t nb_codeblocks_width;
|
int nb_codeblocks_width;
|
||||||
uint16_t nb_codeblocks_height;
|
int nb_codeblocks_height;
|
||||||
Jpeg2000TgtNode *zerobits;
|
Jpeg2000TgtNode *zerobits;
|
||||||
Jpeg2000TgtNode *cblkincl;
|
Jpeg2000TgtNode *cblkincl;
|
||||||
Jpeg2000Cblk *cblk;
|
Jpeg2000Cblk *cblk;
|
||||||
int decoded_layers;
|
int decoded_layers;
|
||||||
uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
||||||
} Jpeg2000Prec; // precinct
|
} Jpeg2000Prec; // precinct
|
||||||
|
|
||||||
typedef struct Jpeg2000Band {
|
typedef struct Jpeg2000Band {
|
||||||
uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
||||||
uint16_t log2_cblk_width, log2_cblk_height;
|
uint16_t log2_cblk_width, log2_cblk_height;
|
||||||
int i_stepsize; // quantization stepsize
|
int i_stepsize; // quantization stepsize
|
||||||
float f_stepsize; // quantization stepsize
|
float f_stepsize; // quantization stepsize
|
||||||
@@ -197,8 +197,8 @@ typedef struct Jpeg2000Band {
|
|||||||
|
|
||||||
typedef struct Jpeg2000ResLevel {
|
typedef struct Jpeg2000ResLevel {
|
||||||
uint8_t nbands;
|
uint8_t nbands;
|
||||||
uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
||||||
uint16_t num_precincts_x, num_precincts_y; // number of precincts in x/y direction
|
int num_precincts_x, num_precincts_y; // number of precincts in x/y direction
|
||||||
uint8_t log2_prec_width, log2_prec_height; // exponent of precinct size
|
uint8_t log2_prec_width, log2_prec_height; // exponent of precinct size
|
||||||
Jpeg2000Band *band;
|
Jpeg2000Band *band;
|
||||||
} Jpeg2000ResLevel; // resolution level
|
} Jpeg2000ResLevel; // resolution level
|
||||||
@@ -208,8 +208,8 @@ typedef struct Jpeg2000Component {
|
|||||||
DWTContext dwt;
|
DWTContext dwt;
|
||||||
float *f_data;
|
float *f_data;
|
||||||
int *i_data;
|
int *i_data;
|
||||||
uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- can be reduced with lowres option
|
int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- can be reduced with lowres option
|
||||||
uint16_t coord_o[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- original values from jpeg2000 headers
|
int coord_o[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- original values from jpeg2000 headers
|
||||||
} Jpeg2000Component;
|
} Jpeg2000Component;
|
||||||
|
|
||||||
/* misc tools */
|
/* misc tools */
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "libavutil/attributes.h"
|
#include "libavutil/attributes.h"
|
||||||
#include "libavutil/avassert.h"
|
#include "libavutil/avassert.h"
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
|
#include "libavutil/imgutils.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
@@ -279,7 +280,7 @@ static int get_siz(Jpeg2000DecoderContext *s)
|
|||||||
avpriv_request_sample(s->avctx, "Support for image offsets");
|
avpriv_request_sample(s->avctx, "Support for image offsets");
|
||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
}
|
}
|
||||||
if (s->width > 32768U || s->height > 32768U) {
|
if (av_image_check_size(s->width, s->height, 0, s->avctx)) {
|
||||||
avpriv_request_sample(s->avctx, "Large Dimensions");
|
avpriv_request_sample(s->avctx, "Large Dimensions");
|
||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
}
|
}
|
||||||
|
@@ -534,7 +534,7 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t)
|
|||||||
data[i] = (data[i] + ((1<<I_PRESHIFT)>>1)) >> I_PRESHIFT;
|
data[i] = (data[i] + ((1<<I_PRESHIFT)>>1)) >> I_PRESHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_jpeg2000_dwt_init(DWTContext *s, uint16_t border[2][2],
|
int ff_jpeg2000_dwt_init(DWTContext *s, int border[2][2],
|
||||||
int decomp_levels, int type)
|
int decomp_levels, int type)
|
||||||
{
|
{
|
||||||
int i, j, lev = decomp_levels, maxlen,
|
int i, j, lev = decomp_levels, maxlen,
|
||||||
@@ -623,7 +623,7 @@ void ff_dwt_destroy(DWTContext *s)
|
|||||||
|
|
||||||
#define MAX_W 256
|
#define MAX_W 256
|
||||||
|
|
||||||
static int test_dwt(int *array, int *ref, uint16_t border[2][2], int decomp_levels, int type, int max_diff) {
|
static int test_dwt(int *array, int *ref, int border[2][2], int decomp_levels, int type, int max_diff) {
|
||||||
int ret, j;
|
int ret, j;
|
||||||
DWTContext s1={{{0}}}, *s= &s1;
|
DWTContext s1={{{0}}}, *s= &s1;
|
||||||
int64_t err2 = 0;
|
int64_t err2 = 0;
|
||||||
@@ -662,7 +662,7 @@ static int test_dwt(int *array, int *ref, uint16_t border[2][2], int decomp_leve
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int test_dwtf(float *array, float *ref, uint16_t border[2][2], int decomp_levels, float max_diff) {
|
static int test_dwtf(float *array, float *ref, int border[2][2], int decomp_levels, float max_diff) {
|
||||||
int ret, j;
|
int ret, j;
|
||||||
DWTContext s1={{{0}}}, *s= &s1;
|
DWTContext s1={{{0}}}, *s= &s1;
|
||||||
double err2 = 0;
|
double err2 = 0;
|
||||||
@@ -708,7 +708,7 @@ static float reff [MAX_W * MAX_W];
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
AVLFG prng;
|
AVLFG prng;
|
||||||
int i,j;
|
int i,j;
|
||||||
uint16_t border[2][2];
|
int border[2][2];
|
||||||
int ret, decomp_levels;
|
int ret, decomp_levels;
|
||||||
|
|
||||||
av_lfg_init(&prng, 1);
|
av_lfg_init(&prng, 1);
|
||||||
|
@@ -42,7 +42,7 @@ enum DWTType {
|
|||||||
|
|
||||||
typedef struct DWTContext {
|
typedef struct DWTContext {
|
||||||
/// line lengths { horizontal, vertical } in consecutive decomposition levels
|
/// line lengths { horizontal, vertical } in consecutive decomposition levels
|
||||||
uint16_t linelen[FF_DWT_MAX_DECLVLS][2];
|
int linelen[FF_DWT_MAX_DECLVLS][2];
|
||||||
uint8_t mod[FF_DWT_MAX_DECLVLS][2]; ///< coordinates (x0, y0) of decomp. levels mod 2
|
uint8_t mod[FF_DWT_MAX_DECLVLS][2]; ///< coordinates (x0, y0) of decomp. levels mod 2
|
||||||
uint8_t ndeclevels; ///< number of decomposition levels
|
uint8_t ndeclevels; ///< number of decomposition levels
|
||||||
uint8_t type; ///< 0 for 9/7; 1 for 5/3
|
uint8_t type; ///< 0 for 9/7; 1 for 5/3
|
||||||
@@ -57,7 +57,7 @@ typedef struct DWTContext {
|
|||||||
* @param decomp_levels number of decomposition levels
|
* @param decomp_levels number of decomposition levels
|
||||||
* @param type 0 for DWT 9/7; 1 for DWT 5/3
|
* @param type 0 for DWT 9/7; 1 for DWT 5/3
|
||||||
*/
|
*/
|
||||||
int ff_jpeg2000_dwt_init(DWTContext *s, uint16_t border[2][2],
|
int ff_jpeg2000_dwt_init(DWTContext *s, int border[2][2],
|
||||||
int decomp_levels, int type);
|
int decomp_levels, int type);
|
||||||
|
|
||||||
int ff_dwt_encode(DWTContext *s, void *t);
|
int ff_dwt_encode(DWTContext *s, void *t);
|
||||||
|
Reference in New Issue
Block a user