[FFmpeg-devel] [PATCH] avcodec/jpeg2000htdec: Check for invalid magref length.
From: caleb --- libavcodec/jpeg2000htdec.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/libavcodec/jpeg2000htdec.c b/libavcodec/jpeg2000htdec.c index 51cd96e0f1..4c4e54710d 100644 --- a/libavcodec/jpeg2000htdec.c +++ b/libavcodec/jpeg2000htdec.c @@ -1101,8 +1101,9 @@ static void jpeg2000_decode_sigprop_segment(Jpeg2000Cblk *cblk, uint16_t width, * See procedure decodeSigPropMag at Rec. ITU-T T.814, 7.5. */ static int -jpeg2000_decode_magref_segment(Jpeg2000Cblk *cblk, uint16_t width, uint16_t block_height, uint8_t *magref_segment, - uint32_t magref_length, uint8_t pLSB, int32_t *sample_buf, uint8_t *block_states) +jpeg2000_decode_magref_segment( uint16_t width, uint16_t block_height, +uint8_t *magref_segment,uint32_t magref_length, +uint8_t pLSB, int32_t *sample_buf, uint8_t *block_states) { StateVars mag_ref = { 0 }; @@ -1260,10 +1261,17 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c jpeg2000_decode_sigprop_segment(cblk, width, height, Dref, Lref, pLSB - 1, sample_buf, block_states); -if (cblk->npasses > 2) -if ((ret = jpeg2000_decode_magref_segment(cblk, width, height, Dref, Lref, - pLSB - 1, sample_buf, block_states)) < 0) +if (cblk->npasses > 2) { + +if (Lref < 2){ +av_log(s->avctx,AV_LOG_ERROR,"Invalid magnitude refinement length\n"); +ret = AVERROR_INVALIDDATA; +goto free; +} +if ((ret = jpeg2000_decode_magref_segment(width, height, Dref, Lref, + pLSB - 1, sample_buf, block_states)) < 0) goto free; +} pLSB = 31 - M_b; -- 2.40.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avcodec/jpeg2000htdec: Check for invalid magref length.
From: caleb --- libavcodec/jpeg2000htdec.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libavcodec/jpeg2000htdec.c b/libavcodec/jpeg2000htdec.c index 51cd96e0f1..474d671ee0 100644 --- a/libavcodec/jpeg2000htdec.c +++ b/libavcodec/jpeg2000htdec.c @@ -1101,8 +1101,8 @@ static void jpeg2000_decode_sigprop_segment(Jpeg2000Cblk *cblk, uint16_t width, * See procedure decodeSigPropMag at Rec. ITU-T T.814, 7.5. */ static int -jpeg2000_decode_magref_segment(Jpeg2000Cblk *cblk, uint16_t width, uint16_t block_height, uint8_t *magref_segment, - uint32_t magref_length, uint8_t pLSB, int32_t *sample_buf, uint8_t *block_states) +jpeg2000_decode_magref_segment(const Jpeg2000DecoderContext *s,Jpeg2000Cblk *cblk, uint16_t width, uint16_t block_height, uint8_t *magref_segment, + uint32_t magref_length, uint8_t pLSB, int32_t *sample_buf, uint8_t *block_states) { StateVars mag_ref = { 0 }; @@ -,6 +,10 @@ jpeg2000_decode_magref_segment(Jpeg2000Cblk *cblk, uint16_t width, uint16_t bloc uint16_t i_start= 0; int32_t *sp; +if (magref_length < 2){ +av_log(s->avctx,AV_LOG_ERROR,"Invalid magnitude refinement length\n"); +return AVERROR_INVALIDDATA; +} jpeg2000_init_mag_ref(_ref, magref_length); for (int n1 = 0; n1 < num_v_stripe; n1++) { @@ -1261,7 +1265,7 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c pLSB - 1, sample_buf, block_states); if (cblk->npasses > 2) -if ((ret = jpeg2000_decode_magref_segment(cblk, width, height, Dref, Lref, +if ((ret = jpeg2000_decode_magref_segment(s,cblk, width, height, Dref, Lref, pLSB - 1, sample_buf, block_states)) < 0) goto free; -- 2.40.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avcodec/jpeg2000dec: Ensure calculation of buf_size cannot overflow.
From: caleb --- libavcodec/jpeg2000htdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/jpeg2000htdec.c b/libavcodec/jpeg2000htdec.c index 51cd96e0f1..d77293ddd8 100644 --- a/libavcodec/jpeg2000htdec.c +++ b/libavcodec/jpeg2000htdec.c @@ -595,7 +595,7 @@ static int jpeg2000_decode_ht_cleanup_segment(const Jpeg2000DecoderContext *s, const uint16_t quad_width = ff_jpeg2000_ceildivpow2(width, 1); const uint16_t quad_height = ff_jpeg2000_ceildivpow2(height, 1); -size_t buf_size = 4 * quad_width * quad_height; +size_t buf_size = 4UL * quad_width * quad_height; uint8_t *sigma_n = av_calloc(buf_size, sizeof(uint8_t)); uint8_t *E = av_calloc(buf_size, sizeof(uint8_t)); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avcodec/jpeg2000dec: Explicitly cast quad_width and quad_height to size_t
From: caleb Prevents un-necessary casts when calculating buf_size --- libavcodec/jpeg2000htdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/jpeg2000htdec.c b/libavcodec/jpeg2000htdec.c index 51cd96e0f1..8907820806 100644 --- a/libavcodec/jpeg2000htdec.c +++ b/libavcodec/jpeg2000htdec.c @@ -592,8 +592,8 @@ static int jpeg2000_decode_ht_cleanup_segment(const Jpeg2000DecoderContext *s, const uint16_t is_border_x = width % 2; const uint16_t is_border_y = height % 2; -const uint16_t quad_width = ff_jpeg2000_ceildivpow2(width, 1); -const uint16_t quad_height = ff_jpeg2000_ceildivpow2(height, 1); +const size_t quad_width = ff_jpeg2000_ceildivpow2(width, 1); +const size_t quad_height = ff_jpeg2000_ceildivpow2(height, 1); size_t buf_size = 4 * quad_width * quad_height; -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] avcodec/jpeg2000dec: Add support for HTJ2K decoding
From: caleb --- libavcodec/Makefile|2 +- libavcodec/jpeg2000.h |3 + libavcodec/jpeg2000dec.c | 69 +- libavcodec/jpeg2000htdec.c | 1425 libavcodec/jpeg2000htdec.h | 28 + 5 files changed, 1511 insertions(+), 16 deletions(-) create mode 100644 libavcodec/jpeg2000htdec.c create mode 100644 libavcodec/jpeg2000htdec.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 98841ed07c..1ba9e09528 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -464,7 +464,7 @@ OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o OBJS-$(CONFIG_JPEG2000_ENCODER)+= j2kenc.o mqcenc.o mqc.o jpeg2000.o \ jpeg2000dwt.o OBJS-$(CONFIG_JPEG2000_DECODER)+= jpeg2000dec.o jpeg2000.o jpeg2000dsp.o \ - jpeg2000dwt.o mqcdec.o mqc.o + jpeg2000dwt.o mqcdec.o mqc.o jpeg2000htdec.o OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o OBJS-$(CONFIG_JV_DECODER) += jvdec.o diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index e5ecb4cbf9..b2a8e13244 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -189,6 +189,9 @@ typedef struct Jpeg2000Cblk { Jpeg2000Pass *passes; Jpeg2000Layer *layers; int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} +/*HTJ2K settings */ +int zbp; +int pass_lengths[2]; } Jpeg2000Cblk; // code block typedef struct Jpeg2000Prec { diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 5994e29ae3..0863727420 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -43,6 +43,7 @@ #include "jpeg2000dsp.h" #include "profiles.h" #include "jpeg2000dec.h" +#include "jpeg2000htdec.h" #define JP2_SIG_TYPE0x6A502020 #define JP2_SIG_VALUE 0x0D0A870A @@ -436,12 +437,13 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) c->cblk_style = bytestream2_get_byteu(>g); if (c->cblk_style != 0) { // cblk style if (c->cblk_style & JPEG2000_CTSY_HTJ2K_M || c->cblk_style & JPEG2000_CTSY_HTJ2K_F) { -av_log(s->avctx, AV_LOG_ERROR, "Support for High throughput JPEG 2000 is not yet available\n"); -return AVERROR_PATCHWELCOME; +av_log(s->avctx,AV_LOG_TRACE,"High Throughput jpeg 2000 codestream.\n"); +s->is_htj2k = 1; +} else { +av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); +if (c->cblk_style & JPEG2000_CBLK_BYPASS) +av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n"); } -av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); -if (c->cblk_style & JPEG2000_CBLK_BYPASS) -av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n"); } c->transform = bytestream2_get_byteu(>g); // DWT transformation type /* set integer 9/7 DWT in case of BITEXACT flag */ @@ -1066,13 +1068,15 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, return incl; if (!cblk->npasses) { -int v = expn[bandno] + numgbits - 1 - -tag_tree_decode(s, prec->zerobits + cblkno, 100); +int zbp = tag_tree_decode(s,prec->zerobits + cblkno, 100); +int v = expn[bandno] + numgbits - 1 - zbp; + if (v < 0 || v > 30) { av_log(s->avctx, AV_LOG_ERROR, "nonzerobits %d invalid or unsupported\n", v); return AVERROR_INVALIDDATA; } +cblk->zbp = zbp; cblk->nonzerobits = v; } if ((newpasses = getnpasses(s)) < 0) @@ -1113,8 +1117,29 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, } } -if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0) -return ret; +if (newpasses > 1 && s->is_htj2k) { +// Retrieve pass lengths for each pass +int href_passes = (cblk->npasses + newpasses - 1) % 3; +int segment_passes = newpasses - href_passes; +int pass_bound = 2; +int eb = 0; +int extra_bit = newpasses > 2 ? 1 : 0; +while (pass_bound <=segment_passes) { +eb++; +pass_bound +=pass_bound; +} +if ((ret = get_bits(s, llen + eb + 3)) < 0) +return ret; +cblk->pass_lengths[0] = ret; +if ((ret = get_bits(s, llen + 3
[FFmpeg-devel] [PATCH 1/2] avcodec/jpeg2000dec: Move decoder structs to header files.
From: caleb --- libavcodec/jpeg2000dec.c | 88 +--- libavcodec/jpeg2000dec.h | 121 +++ 2 files changed, 122 insertions(+), 87 deletions(-) create mode 100644 libavcodec/jpeg2000dec.h diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index c2b81ec103..5994e29ae3 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -42,6 +42,7 @@ #include "jpeg2000.h" #include "jpeg2000dsp.h" #include "profiles.h" +#include "jpeg2000dec.h" #define JP2_SIG_TYPE0x6A502020 #define JP2_SIG_VALUE 0x0D0A870A @@ -51,93 +52,6 @@ #define HAD_COC 0x01 #define HAD_QCC 0x02 -#define MAX_POCS 32 - -typedef struct Jpeg2000POCEntry { -uint16_t LYEpoc; -uint16_t CSpoc; -uint16_t CEpoc; -uint8_t RSpoc; -uint8_t REpoc; -uint8_t Ppoc; -} Jpeg2000POCEntry; - -typedef struct Jpeg2000POC { -Jpeg2000POCEntry poc[MAX_POCS]; -int nb_poc; -int is_default; -} Jpeg2000POC; - -typedef struct Jpeg2000TilePart { -uint8_t tile_index; // Tile index who refers the tile-part -const uint8_t *tp_end; -GetByteContext header_tpg; // bit stream of header if PPM header is used -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]; -Jpeg2000POC poc; -Jpeg2000TileParttile_part[32]; -uint8_t has_ppt;// whether this tile has a ppt marker -uint8_t *packed_headers;// contains packed headers. Used only along with PPT marker -int packed_headers_size;// size in bytes of the packed headers -GetByteContext packed_headers_stream; // byte context corresponding to packed headers -uint16_t tp_idx;// Tile-part index -int coord[2][2];// border coordinates {{x0, x1}, {y0, y1}} -} 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]; - -uint8_t has_ppm; -uint8_t *packed_headers; // contains packed headers. Used only along with PPM marker -int packed_headers_size; -GetByteContext packed_headers_stream; -uint8_t in_tile_headers; - -int cdx[4], cdy[4]; -int precision; -int ncomponents; -int colour_space; -uint32_tpalette[256]; -int8_t pal8; -int cdef[4]; -int tile_width, tile_height; -unsignednumXtiles, numYtiles; -int maxtilelen; -AVRational sar; - -Jpeg2000CodingStyle codsty[4]; -Jpeg2000QuantStyle qntsty[4]; -Jpeg2000POC poc; -uint8_t roi_shift[4]; - -int bit_index; - -int curtileno; - -Jpeg2000Tile*tile; -Jpeg2000DSPContext dsp; - -/*options parameters*/ -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. diff --git a/libavcodec/jpeg2000dec.h b/libavcodec/jpeg2000dec.h new file mode 100644 index 00..c148416889 --- /dev/null +++ b/libavcodec/jpeg2000dec.h @@ -0,0 +1,121 @@ +/* + * JPEG 2000 image decoder + * Copyright (c) 2007 Kamil Nowosad + * Copyright (c) 2013 Nicolas Bertrand + * Copyright (c) 2022 Caleb Etemesi + * + * 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 + */ +
[FFmpeg-devel] [PATCH 2/2] avcodec/jpeg2000dec: Add support for High Throughput HTJ2K decoding.
From: caleb This is a revised patch with suggested changes from earlier and satisfies the Google Summer of Code 2022 FFmpeg project to add a HTJ2K decoder to FFmpeg. --- libavcodec/Makefile|2 +- libavcodec/jpeg2000.h |3 + libavcodec/jpeg2000dec.c | 69 +- libavcodec/jpeg2000dec.h |2 + libavcodec/jpeg2000htdec.c | 1441 libavcodec/jpeg2000htdec.h | 28 + 6 files changed, 1529 insertions(+), 16 deletions(-) create mode 100644 libavcodec/jpeg2000htdec.c create mode 100644 libavcodec/jpeg2000htdec.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 98841ed07c..1ba9e09528 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -464,7 +464,7 @@ OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o OBJS-$(CONFIG_JPEG2000_ENCODER)+= j2kenc.o mqcenc.o mqc.o jpeg2000.o \ jpeg2000dwt.o OBJS-$(CONFIG_JPEG2000_DECODER)+= jpeg2000dec.o jpeg2000.o jpeg2000dsp.o \ - jpeg2000dwt.o mqcdec.o mqc.o + jpeg2000dwt.o mqcdec.o mqc.o jpeg2000htdec.o OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o OBJS-$(CONFIG_JV_DECODER) += jvdec.o diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index e5ecb4cbf9..b2a8e13244 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -189,6 +189,9 @@ typedef struct Jpeg2000Cblk { Jpeg2000Pass *passes; Jpeg2000Layer *layers; int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} +/*HTJ2K settings */ +int zbp; +int pass_lengths[2]; } Jpeg2000Cblk; // code block typedef struct Jpeg2000Prec { diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 7fc09cb558..5c92baa88e 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -43,6 +43,7 @@ #include "jpeg2000dsp.h" #include "profiles.h" #include "jpeg2000dec.h" +#include "jpeg2000htdec.h" /* get_bits functions for JPEG2000 packet bitstream * It is a get_bit function with a bit-stuffing routine. If the value of the @@ -428,12 +429,13 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) c->cblk_style = bytestream2_get_byteu(>g); if (c->cblk_style != 0) { // cblk style if (c->cblk_style & JPEG2000_CTSY_HTJ2K_M || c->cblk_style & JPEG2000_CTSY_HTJ2K_F) { -av_log(s->avctx, AV_LOG_ERROR, "Support for High throughput JPEG 2000 is not yet available\n"); -return AVERROR_PATCHWELCOME; +av_log(s->avctx,AV_LOG_TRACE,"High Throughput jpeg 2000 codestream.\n"); +s->is_htj2k = 1; +} else { +av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); +if (c->cblk_style & JPEG2000_CBLK_BYPASS) +av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n"); } -av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); -if (c->cblk_style & JPEG2000_CBLK_BYPASS) -av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n"); } c->transform = bytestream2_get_byteu(>g); // DWT transformation type /* set integer 9/7 DWT in case of BITEXACT flag */ @@ -1058,13 +1060,15 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, return incl; if (!cblk->npasses) { -int v = expn[bandno] + numgbits - 1 - -tag_tree_decode(s, prec->zerobits + cblkno, 100); +int zbp = tag_tree_decode(s,prec->zerobits + cblkno, 100); +int v = expn[bandno] + numgbits - 1 - zbp; + if (v < 0 || v > 30) { av_log(s->avctx, AV_LOG_ERROR, "nonzerobits %d invalid or unsupported\n", v); return AVERROR_INVALIDDATA; } +cblk->zbp = zbp; cblk->nonzerobits = v; } if ((newpasses = getnpasses(s)) < 0) @@ -1105,8 +1109,29 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, } } -if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0) -return ret; +if (newpasses > 1 && s->is_htj2k) { +// Retrieve pass lengths for each pass +int href_passes = (cblk->npasses + newpasses - 1) % 3; +int segment_passes = newpasses - href_passes; +int pass_bound = 2; +int eb = 0; +int extra_bit = newpasses > 2 ? 1 : 0; +while (pass_bound <=segment_passes) { +eb++; +
[FFmpeg-devel] [PATCH 1/2] avcodec/jpeg2000dec: Move decoder structs to header files
From: caleb This should pave way for HTJ2K decoding --- libavcodec/jpeg2000dec.c | 96 + libavcodec/jpeg2000dec.h | 126 +++ 2 files changed, 127 insertions(+), 95 deletions(-) create mode 100644 libavcodec/jpeg2000dec.h diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index c2b81ec103..7fc09cb558 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -42,101 +42,7 @@ #include "jpeg2000.h" #include "jpeg2000dsp.h" #include "profiles.h" - -#define JP2_SIG_TYPE0x6A502020 -#define JP2_SIG_VALUE 0x0D0A870A -#define JP2_CODESTREAM 0x6A703263 -#define JP2_HEADER 0x6A703268 - -#define HAD_COC 0x01 -#define HAD_QCC 0x02 - -#define MAX_POCS 32 - -typedef struct Jpeg2000POCEntry { -uint16_t LYEpoc; -uint16_t CSpoc; -uint16_t CEpoc; -uint8_t RSpoc; -uint8_t REpoc; -uint8_t Ppoc; -} Jpeg2000POCEntry; - -typedef struct Jpeg2000POC { -Jpeg2000POCEntry poc[MAX_POCS]; -int nb_poc; -int is_default; -} Jpeg2000POC; - -typedef struct Jpeg2000TilePart { -uint8_t tile_index; // Tile index who refers the tile-part -const uint8_t *tp_end; -GetByteContext header_tpg; // bit stream of header if PPM header is used -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]; -Jpeg2000POC poc; -Jpeg2000TileParttile_part[32]; -uint8_t has_ppt;// whether this tile has a ppt marker -uint8_t *packed_headers;// contains packed headers. Used only along with PPT marker -int packed_headers_size;// size in bytes of the packed headers -GetByteContext packed_headers_stream; // byte context corresponding to packed headers -uint16_t tp_idx;// Tile-part index -int coord[2][2];// border coordinates {{x0, x1}, {y0, y1}} -} 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]; - -uint8_t has_ppm; -uint8_t *packed_headers; // contains packed headers. Used only along with PPM marker -int packed_headers_size; -GetByteContext packed_headers_stream; -uint8_t in_tile_headers; - -int cdx[4], cdy[4]; -int precision; -int ncomponents; -int colour_space; -uint32_tpalette[256]; -int8_t pal8; -int cdef[4]; -int tile_width, tile_height; -unsignednumXtiles, numYtiles; -int maxtilelen; -AVRational sar; - -Jpeg2000CodingStyle codsty[4]; -Jpeg2000QuantStyle qntsty[4]; -Jpeg2000POC poc; -uint8_t roi_shift[4]; - -int bit_index; - -int curtileno; - -Jpeg2000Tile*tile; -Jpeg2000DSPContext dsp; - -/*options parameters*/ -int reduction_factor; -} Jpeg2000DecoderContext; +#include "jpeg2000dec.h" /* get_bits functions for JPEG2000 packet bitstream * It is a get_bit function with a bit-stuffing routine. If the value of the diff --git a/libavcodec/jpeg2000dec.h b/libavcodec/jpeg2000dec.h new file mode 100644 index 00..b6410c1432 --- /dev/null +++ b/libavcodec/jpeg2000dec.h @@ -0,0 +1,126 @@ +/* + * JPEG 2000 image decoder + * Copyright (c) 2007 Kamil Nowosad + * Copyright (c) 2013 Nicolas Bertrand + * Copyright (c) 2022 Caleb Etemesi + * + * 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
[FFmpeg-devel] [PATCH 2/2] avcodec/jpeg2000dec: Add support for HTJ2K decoding.
From: caleb This patch adds support for HTJ2K decoding in FFMPEG. This is a revised patch with suggested changes from earlier and fixes some bugs that were in the first version. The paper describing HTJ2K can be found at https://htj2k.com/wp-content/uploads/white-paper.pdf --- libavcodec/Makefile|2 +- libavcodec/jpeg2000.h |3 + libavcodec/jpeg2000dec.c | 69 +- libavcodec/jpeg2000dec.h |2 + libavcodec/jpeg2000htdec.c | 1434 libavcodec/jpeg2000htdec.h | 28 + 6 files changed, 1522 insertions(+), 16 deletions(-) create mode 100644 libavcodec/jpeg2000htdec.c create mode 100644 libavcodec/jpeg2000htdec.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 98841ed07c..1ba9e09528 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -464,7 +464,7 @@ OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o OBJS-$(CONFIG_JPEG2000_ENCODER)+= j2kenc.o mqcenc.o mqc.o jpeg2000.o \ jpeg2000dwt.o OBJS-$(CONFIG_JPEG2000_DECODER)+= jpeg2000dec.o jpeg2000.o jpeg2000dsp.o \ - jpeg2000dwt.o mqcdec.o mqc.o + jpeg2000dwt.o mqcdec.o mqc.o jpeg2000htdec.o OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o OBJS-$(CONFIG_JV_DECODER) += jvdec.o diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index e5ecb4cbf9..b2a8e13244 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -189,6 +189,9 @@ typedef struct Jpeg2000Cblk { Jpeg2000Pass *passes; Jpeg2000Layer *layers; int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} +/*HTJ2K settings */ +int zbp; +int pass_lengths[2]; } Jpeg2000Cblk; // code block typedef struct Jpeg2000Prec { diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 7fc09cb558..5c92baa88e 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -43,6 +43,7 @@ #include "jpeg2000dsp.h" #include "profiles.h" #include "jpeg2000dec.h" +#include "jpeg2000htdec.h" /* get_bits functions for JPEG2000 packet bitstream * It is a get_bit function with a bit-stuffing routine. If the value of the @@ -428,12 +429,13 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) c->cblk_style = bytestream2_get_byteu(>g); if (c->cblk_style != 0) { // cblk style if (c->cblk_style & JPEG2000_CTSY_HTJ2K_M || c->cblk_style & JPEG2000_CTSY_HTJ2K_F) { -av_log(s->avctx, AV_LOG_ERROR, "Support for High throughput JPEG 2000 is not yet available\n"); -return AVERROR_PATCHWELCOME; +av_log(s->avctx,AV_LOG_TRACE,"High Throughput jpeg 2000 codestream.\n"); +s->is_htj2k = 1; +} else { +av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); +if (c->cblk_style & JPEG2000_CBLK_BYPASS) +av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n"); } -av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); -if (c->cblk_style & JPEG2000_CBLK_BYPASS) -av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n"); } c->transform = bytestream2_get_byteu(>g); // DWT transformation type /* set integer 9/7 DWT in case of BITEXACT flag */ @@ -1058,13 +1060,15 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, return incl; if (!cblk->npasses) { -int v = expn[bandno] + numgbits - 1 - -tag_tree_decode(s, prec->zerobits + cblkno, 100); +int zbp = tag_tree_decode(s,prec->zerobits + cblkno, 100); +int v = expn[bandno] + numgbits - 1 - zbp; + if (v < 0 || v > 30) { av_log(s->avctx, AV_LOG_ERROR, "nonzerobits %d invalid or unsupported\n", v); return AVERROR_INVALIDDATA; } +cblk->zbp = zbp; cblk->nonzerobits = v; } if ((newpasses = getnpasses(s)) < 0) @@ -1105,8 +1109,29 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, } } -if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0) -return ret; +if (newpasses > 1 && s->is_htj2k) { +// Retrieve pass lengths for each pass +int href_passes = (cblk->npasses + newpasses - 1) % 3; +int segment_passes = newpasses - href_passes; +int pass_bound = 2; +int eb = 0; +int extra_bit = newpasses > 2 ? 1 : 0; +
[FFmpeg-devel] [PATCH 1/2] avcodec/jpeg2000dec: Move decoder structs to header files
From: caleb --- libavcodec/jpeg2000dec.c | 96 + libavcodec/jpeg2000dec.h | 126 +++ 2 files changed, 127 insertions(+), 95 deletions(-) create mode 100644 libavcodec/jpeg2000dec.h diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index c2b81ec103..7fc09cb558 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -42,101 +42,7 @@ #include "jpeg2000.h" #include "jpeg2000dsp.h" #include "profiles.h" - -#define JP2_SIG_TYPE0x6A502020 -#define JP2_SIG_VALUE 0x0D0A870A -#define JP2_CODESTREAM 0x6A703263 -#define JP2_HEADER 0x6A703268 - -#define HAD_COC 0x01 -#define HAD_QCC 0x02 - -#define MAX_POCS 32 - -typedef struct Jpeg2000POCEntry { -uint16_t LYEpoc; -uint16_t CSpoc; -uint16_t CEpoc; -uint8_t RSpoc; -uint8_t REpoc; -uint8_t Ppoc; -} Jpeg2000POCEntry; - -typedef struct Jpeg2000POC { -Jpeg2000POCEntry poc[MAX_POCS]; -int nb_poc; -int is_default; -} Jpeg2000POC; - -typedef struct Jpeg2000TilePart { -uint8_t tile_index; // Tile index who refers the tile-part -const uint8_t *tp_end; -GetByteContext header_tpg; // bit stream of header if PPM header is used -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]; -Jpeg2000POC poc; -Jpeg2000TileParttile_part[32]; -uint8_t has_ppt;// whether this tile has a ppt marker -uint8_t *packed_headers;// contains packed headers. Used only along with PPT marker -int packed_headers_size;// size in bytes of the packed headers -GetByteContext packed_headers_stream; // byte context corresponding to packed headers -uint16_t tp_idx;// Tile-part index -int coord[2][2];// border coordinates {{x0, x1}, {y0, y1}} -} 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]; - -uint8_t has_ppm; -uint8_t *packed_headers; // contains packed headers. Used only along with PPM marker -int packed_headers_size; -GetByteContext packed_headers_stream; -uint8_t in_tile_headers; - -int cdx[4], cdy[4]; -int precision; -int ncomponents; -int colour_space; -uint32_tpalette[256]; -int8_t pal8; -int cdef[4]; -int tile_width, tile_height; -unsignednumXtiles, numYtiles; -int maxtilelen; -AVRational sar; - -Jpeg2000CodingStyle codsty[4]; -Jpeg2000QuantStyle qntsty[4]; -Jpeg2000POC poc; -uint8_t roi_shift[4]; - -int bit_index; - -int curtileno; - -Jpeg2000Tile*tile; -Jpeg2000DSPContext dsp; - -/*options parameters*/ -int reduction_factor; -} Jpeg2000DecoderContext; +#include "jpeg2000dec.h" /* get_bits functions for JPEG2000 packet bitstream * It is a get_bit function with a bit-stuffing routine. If the value of the diff --git a/libavcodec/jpeg2000dec.h b/libavcodec/jpeg2000dec.h new file mode 100644 index 00..b6410c1432 --- /dev/null +++ b/libavcodec/jpeg2000dec.h @@ -0,0 +1,126 @@ +/* + * JPEG 2000 image decoder + * Copyright (c) 2007 Kamil Nowosad + * Copyright (c) 2013 Nicolas Bertrand + * Copyright (c) 2022 Caleb Etemesi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_JPEG2000DEC_H
[FFmpeg-devel] [PATCH v2] avcodec/jpeg2000: Add support for High-Throughput JPEG 2000 (HTJ2K) decoding.
From: caleb Rebased this patch on master branch --- libavcodec/Makefile|2 +- libavcodec/j2kenc.c| 26 +- libavcodec/jpeg2000.h | 103 ++- libavcodec/jpeg2000dec.c | 193 ++ libavcodec/jpeg2000htdec.c | 1212 libavcodec/jpeg2000htdec.h | 210 +++ 6 files changed, 1599 insertions(+), 147 deletions(-) create mode 100644 libavcodec/jpeg2000htdec.c create mode 100644 libavcodec/jpeg2000htdec.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 945908e3b8..ecf5c47cad 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -450,7 +450,7 @@ OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o OBJS-$(CONFIG_JPEG2000_ENCODER)+= j2kenc.o mqcenc.o mqc.o jpeg2000.o \ jpeg2000dwt.o OBJS-$(CONFIG_JPEG2000_DECODER)+= jpeg2000dec.o jpeg2000.o jpeg2000dsp.o \ - jpeg2000dwt.o mqcdec.o mqc.o + jpeg2000dwt.o mqcdec.o mqc.o jpeg2000htdec.o OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o OBJS-$(CONFIG_JV_DECODER) += jvdec.o diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index e883d5deb7..233d75e96d 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -106,7 +106,7 @@ static const int dwt_norms[2][4][10] = { // [dwt_type][band][rlevel] (multiplied typedef struct { Jpeg2000Component *comp; double *layer_rates; -} Jpeg2000Tile; +} Jpeg2000EncTile; typedef struct { AVClass *class; @@ -131,7 +131,7 @@ typedef struct { Jpeg2000CodingStyle codsty; Jpeg2000QuantStyle qntsty; -Jpeg2000Tile *tile; +Jpeg2000EncTile *tile; int layer_rates[100]; uint8_t compression_rate_enc; ///< Is compression done using compression ratio? @@ -427,7 +427,7 @@ static void compute_rates(Jpeg2000EncoderContext* s) int layno, compno; for (i = 0; i < s->numYtiles; i++) { for (j = 0; j < s->numXtiles; j++) { -Jpeg2000Tile *tile = >tile[s->numXtiles * i + j]; +Jpeg2000EncTile *tile = >tile[s->numXtiles * i + j]; for (compno = 0; compno < s->ncomponents; compno++) { int tilew = tile->comp[compno].coord[0][1] - tile->comp[compno].coord[0][0]; int tileh = tile->comp[compno].coord[1][1] - tile->comp[compno].coord[1][0]; @@ -460,12 +460,12 @@ static int init_tiles(Jpeg2000EncoderContext *s) s->numXtiles = ff_jpeg2000_ceildiv(s->width, s->tile_width); s->numYtiles = ff_jpeg2000_ceildiv(s->height, s->tile_height); -s->tile = av_calloc(s->numXtiles, s->numYtiles * sizeof(Jpeg2000Tile)); +s->tile = av_calloc(s->numXtiles, s->numYtiles * sizeof(Jpeg2000EncTile)); if (!s->tile) return AVERROR(ENOMEM); for (tileno = 0, tiley = 0; tiley < s->numYtiles; tiley++) for (tilex = 0; tilex < s->numXtiles; tilex++, tileno++){ -Jpeg2000Tile *tile = s->tile + tileno; +Jpeg2000EncTile *tile = s->tile + tileno; tile->comp = av_calloc(s->ncomponents, sizeof(*tile->comp)); if (!tile->comp) @@ -509,7 +509,7 @@ static int init_tiles(Jpeg2000EncoderContext *s) int tileno, compno, i, y, x; \ const PIXEL *line; \ for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ \ -Jpeg2000Tile *tile = s->tile + tileno; \ +Jpeg2000EncTile *tile = s->tile + tileno; \ if (s->planar){ \ for (compno = 0; compno < s->ncomponents; compno++){ \ Jpeg2000Component *comp = tile->comp + compno; \ @@ -701,7 +701,7 @@ static void encode_clnpass(Jpeg2000T1Context *t1, int width, int height, int ban } } -static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk, Jpeg2000Tile *tile, +static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk, Jpeg2000EncTile *tile, int width, int height, int bandpos, int lev) { int pass_t = 2, passno, x, y, max=0, nmsedec, bpno; @@ -935,7 +935,7 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in return 0; } -static int