From patchwork Thu Jul 23 17:11:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21235 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id EBF244473C4 for ; Thu, 23 Jul 2020 20:18:15 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BD59D68B605; Thu, 23 Jul 2020 20:18:15 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f193.google.com (mail-pl1-f193.google.com [209.85.214.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 043D268B562 for ; Thu, 23 Jul 2020 20:18:09 +0300 (EEST) Received: by mail-pl1-f193.google.com with SMTP id w17so2828580ply.11 for ; Thu, 23 Jul 2020 10:18:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=W4CO9a214z3IZjttK8rGTdPyqEF1XuRguX+y1HWOv0w=; b=Mpcpe4efsdBFPH3sXdcbBG5oDUvd+y29IwSe4FR7rXWM2gY9BHY3Vd7Z+vodcxeSLV xjarLXf2DBLIopXAybFrzma5PmtsdRQGGZQ8f9rBcj07Ng99ea/9B2LaYqm4jYOU1Ktz VqHPPrJJnSqiHghco0+qfgg2LgQJ3rj50+2mrnH+KcfqmrLwNN2wt70J6dZcgEHbzjpj nGs2UMGdFKJxJBQkOcRxK92DI6rb4+CBKGvd2mNqP5udDRyjoDcBdQrxR5J0jBhSL0WA gCrAWpW+nSQ86xiIj4qBhlMx+28lq0oTw7L0kAUiIs25am+WklfFTa1vMt1ZGI2X9FNr Jgrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=W4CO9a214z3IZjttK8rGTdPyqEF1XuRguX+y1HWOv0w=; b=JQhKz9A55AwkvMKGfb6BldGyGVUHRzv9vrbI4szzdzDq5dZuzed6d2qGHEMkE5HVr6 M72oL94b/e7LP0AWhNo6/+3Nl69dFzGuRaoP/4Fe4gCm/k6XUdyuuYXvgyspFKc8+FNy XhRQK5z4bCbDvWQcYHSh4Z0kSMS3XrPZcDW+VhCLgkNGsomVfYw7YIl9+AVGSsdo4wZ7 x+b06xHhasbnzGqJB1CxaHvNtT6GUAneRuD8FUJdJckPHjRhIGExdMuLV9I1ghY8kbxm msoPYFw14cN8A/zkyOYAZ/JgkuzR1SkHCUNQh9XXd6cmyMj2HSLk5+CVIHHIoNH7XfL0 m7bA== X-Gm-Message-State: AOAM532VsHNljjIWLQxN1bxiFZKH08sEqP6CddBEBKO9dzOaj9dgzbMO Cooh6eux6HuAtQoFliibslbbUFP/z3M= X-Google-Smtp-Source: ABdhPJzbt5P2zm85LbrrA6G6U93MK8sOR+ZPMOGzk9bDUretvbA1PDm8amLDjI3uL5TQStUWu34szA== X-Received: by 2002:aa7:97a1:: with SMTP id d1mr5038214pfq.190.1595524277529; Thu, 23 Jul 2020 10:11:17 -0700 (PDT) Received: from localhost.localdomain ([122.167.212.213]) by smtp.gmail.com with ESMTPSA id p10sm3766829pgn.6.2020.07.23.10.11.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jul 2020 10:11:16 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 Jul 2020 22:41:10 +0530 Message-Id: <20200723171111.11312-1-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH v4 1/2] libavcodec/jpeg2000dec: Fix codeblock decode check X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Gautam Ramakrishnan MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Gautam Ramakrishnan The codeblock decoder checks whether the mqc decoder has decoded the right number of bytes. However, this check does not account for the fact that the mqc encoder's flush routine adds 2 bytes of data which does not have to be read by the decoder. The check is modified to account for this. This patch solves issue #4827 --- libavcodec/jpeg2000dec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index e941ebb5d0..a470cf47da 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -1754,9 +1754,13 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, pass_cnt ++; } - if (cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) != t1->mqc.bp) { + if (cblk->data + cblk->length - 2 > t1->mqc.bp) { av_log(s->avctx, AV_LOG_WARNING, "End mismatch %"PTRDIFF_SPECIFIER"\n", - cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) - t1->mqc.bp); + cblk->data + cblk->length - 2 - t1->mqc.bp); + } + + if (cblk->data + cblk->length < t1->mqc.bp) { + av_log(s->avctx, AV_LOG_WARNING, "Synthetic End of Stream Marker Read.\n"); } return 1; From patchwork Thu Jul 23 17:11:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21236 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id E45DE4477F2 for ; Thu, 23 Jul 2020 20:19:49 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CD92E68B5FF; Thu, 23 Jul 2020 20:19:49 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f195.google.com (mail-pl1-f195.google.com [209.85.214.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3121268B256 for ; Thu, 23 Jul 2020 20:19:43 +0300 (EEST) Received: by mail-pl1-f195.google.com with SMTP id b9so2838658plx.6 for ; Thu, 23 Jul 2020 10:19:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DJvvqpb3di9/CA4QKNAVipaNTK7aNMQhZKQUuLDelHw=; b=q/9ctBP/9Xm9IBDlfsEVmG9rVaOZQ98rz4wwZ8tENor9fH10JwC9N0q0MSyTaFf1/4 29TFnjIb6zBNQ+c6gCX6h6ZetJ9mjZcNLi8qLuk9R8K7jfW+9IsvU2DaVMooBey9o9wA POJzydYeE6bykXNiZ4Ifo+QaT2UsF3Gyx3EGigCIjAKVZUGTrSfUCGw39vsSiyw3cmjK zkoxeBsCv3uaTIaIElmHqhtEDxVKJxCkV4Pk+nDQ0W17j37toHhh+w4PJ7mn/y14mWF0 e9Wzgd3nf3NPXJBqYdYwksSRcehoO/a337BtemESvR40TYtwF46x1ADLN5GdDuqC/gO8 Mg3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DJvvqpb3di9/CA4QKNAVipaNTK7aNMQhZKQUuLDelHw=; b=Euj+Fjb1YP7ty8rOEd3VSkcH/xhRwd86V5Ku1YnqDhuo3Fa7w9PIIzlN1ABI1ghu+x kP68/j+5LgmTQirKOZteH3HFUqDcclNG4M/a8tNygQlleY0FBx6QcMgQ/7mQIEkykLxR Y5YHXBSFhB7Pp0t3okTL9kIelrbl8L91oRQJraB9pY/BSbriq2nrgN5g+5AND0efy9FP EPeed3bYNsumgNYQ6PU43F3p2im3GtzXJswITLkTR/gNHqK4HaBhVHyjZ58G6+GZMChj gB2E7SdFth2PoQ/gAavJuyWmSEt3+F6H1PCHPLix030t0fDMlsZ1NsOtq6VZXkMaOroD 32hw== X-Gm-Message-State: AOAM532oZ1LRwcnwJeTtRdFSviqFMM4/QcuCy5krjmpEjwt0IDGx2r6A 2tzSezLTO2N+WZXCVpeA6ZpKuof7jgU= X-Google-Smtp-Source: ABdhPJymrRhRXKp8u0cRwMGSaX1DpoR4fES5tvSJGkYI7impPfesEX1e8wsMYluUFhK+8rSvH4Va2Q== X-Received: by 2002:a62:31c7:: with SMTP id x190mr5218185pfx.100.1595524279958; Thu, 23 Jul 2020 10:11:19 -0700 (PDT) Received: from localhost.localdomain ([122.167.212.213]) by smtp.gmail.com with ESMTPSA id p10sm3766829pgn.6.2020.07.23.10.11.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jul 2020 10:11:19 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 Jul 2020 22:41:11 +0530 Message-Id: <20200723171111.11312-2-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200723171111.11312-1-gautamramk@gmail.com> References: <20200723171111.11312-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [PATCH v4 2/2] libavcodec/jpeg2000dec: Support for PPM marker X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Gautam Ramakrishnan MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Gautam Ramakrishnan This patch adds support for PPM marker for JPEG2000 decoder. It allows the samples p1_03.j2k and p1_05.j2k to be decoded. --- libavcodec/jpeg2000dec.c | 107 +++++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 10 deletions(-) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index a470cf47da..558cc6b4de 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -71,6 +71,7 @@ typedef struct 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; @@ -102,7 +103,13 @@ typedef struct Jpeg2000DecoderContext { 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; @@ -929,6 +936,31 @@ static int get_plt(Jpeg2000DecoderContext *s, int n) return 0; } +static int get_ppm(Jpeg2000DecoderContext *s, int n) +{ + void *new; + + if (n < 3) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid length for PPM data.\n"); + return AVERROR_INVALIDDATA; + } + bytestream2_get_byte(&s->g); //Zppm is skipped and not used + new = av_realloc(s->packed_headers, + s->packed_headers_size + n - 3); + if (new) { + s->packed_headers = new; + } else + return AVERROR(ENOMEM); + s->has_ppm = 1; + memset(&s->packed_headers_stream, 0, sizeof(s->packed_headers_stream)); + memcpy(s->packed_headers + s->packed_headers_size, + s->g.buffer, n - 3); + s->packed_headers_size += n - 3; + bytestream2_skip(&s->g, n - 3); + + return 0; +} + static int get_ppt(Jpeg2000DecoderContext *s, int n) { Jpeg2000Tile *tile; @@ -1040,8 +1072,19 @@ static int getlblockinc(Jpeg2000DecoderContext *s) return res; } -static inline void select_stream(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, +static inline void select_header(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index) +{ + s->g = tile->tile_part[*tp_index].header_tpg; + if (bytestream2_get_bytes_left(&s->g) == 0 && s->bit_index == 8) { + if (*tp_index < FF_ARRAY_ELEMS(tile->tile_part) - 1) { + s->g = tile->tile_part[++(*tp_index)].tpg; + } + } +} + +static inline void select_stream(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, + int *tp_index, Jpeg2000CodingStyle *codsty) { s->g = tile->tile_part[*tp_index].tpg; if (bytestream2_get_bytes_left(&s->g) == 0 && s->bit_index == 8) { @@ -1049,8 +1092,12 @@ static inline void select_stream(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, s->g = tile->tile_part[++(*tp_index)].tpg; } } - if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES) - bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH); + if (codsty->csty & JPEG2000_CSTY_SOP) { + if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES) + bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH); + else + av_log(s->avctx, AV_LOG_ERROR, "SOP marker not found. instead %X\n", bytestream2_peek_be32(&s->g)); + } } static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index, @@ -1065,10 +1112,12 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, return 0; rlevel->band[0].prec[precno].decoded_layers = layno + 1; // Select stream to read from - if (tile->has_ppt) + if (s->has_ppm) + select_header(s, tile, tp_index); + else if (tile->has_ppt) s->g = tile->packed_headers_stream; else - select_stream(s, tile, tp_index); + select_stream(s, tile, tp_index, codsty); if (!(ret = get_bits(s, 1))) { jpeg2000_flush(s); @@ -1179,9 +1228,12 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, } // Save state of stream - if (tile->has_ppt) { + if (s->has_ppm) { + tile->tile_part[*tp_index].header_tpg = s->g; + select_stream(s, tile, tp_index, codsty); + } else if (tile->has_ppt) { tile->packed_headers_stream = s->g; - select_stream(s, tile, tp_index); + select_stream(s, tile, tp_index, codsty); } for (bandno = 0; bandno < rlevel->nbands; bandno++) { Jpeg2000Band *band = rlevel->band + bandno; @@ -1229,10 +1281,20 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, return 0; skip_data: - if (tile->has_ppt) + 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. instead %X\n", bytestream2_peek_be32(&s->g)); + } + if (s->has_ppm) { + tile->tile_part[*tp_index].header_tpg = s->g; + select_stream(s, tile, tp_index, codsty); + } else if (tile->has_ppt) { tile->packed_headers_stream = s->g; - else - tile->tile_part[*tp_index].tpg = s->g; + select_stream(s, tile, tp_index, codsty); + } + tile->tile_part[*tp_index].tpg = s->g; return 0; } @@ -2069,6 +2131,9 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s) s->tile[tileno].packed_headers_size = 0; } } + av_freep(&s->packed_headers); + s->packed_headers_size = 0; + memset(&s->packed_headers_stream, 0, sizeof(s->packed_headers_stream)); av_freep(&s->tile); memset(s->codsty, 0, sizeof(s->codsty)); memset(s->qntsty, 0, sizeof(s->qntsty)); @@ -2119,6 +2184,11 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) return AVERROR_INVALIDDATA; } + if (s->has_ppm) { + uint32_t tp_header_size = bytestream2_get_be32u(&s->packed_headers_stream); + bytestream2_init(&tp->header_tpg, s->packed_headers_stream.buffer, tp_header_size); + bytestream2_skip(&s->packed_headers_stream, tp_header_size); + } if (tile->has_ppt && tile->tp_idx == 0) { bytestream2_init(&tile->packed_headers_stream, tile->packed_headers, tile->packed_headers_size); } @@ -2172,6 +2242,9 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) case JPEG2000_SOT: if (!s->in_tile_headers) { s->in_tile_headers = 1; + if (s->has_ppm) { + bytestream2_init(&s->packed_headers_stream, s->packed_headers, s->packed_headers_size); + } } if (!(ret = get_sot(s, len))) { av_assert1(s->curtileno >= 0); @@ -2198,8 +2271,22 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) // Packet length, tile-part header ret = get_plt(s, len); break; + case JPEG2000_PPM: + // Packed headers, main header + if (s->in_tile_headers) { + av_log(s->avctx, AV_LOG_ERROR, "PPM Marker can only be in Main header\n"); + return AVERROR_INVALIDDATA; + } + ret = get_ppm(s, len); + break; case JPEG2000_PPT: // Packed headers, tile-part header + if (s->has_ppm) { + av_log(s->avctx, AV_LOG_ERROR, + "Cannot have both PPT and PPM marker.\n"); + return AVERROR_INVALIDDATA; + } + ret = get_ppt(s, len); break; default: