From patchwork Sat Jul 18 11:00:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21164 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 476BA447829 for ; Sat, 18 Jul 2020 14:56:28 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 20F9668B759; Sat, 18 Jul 2020 14:56:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 72BA268B751 for ; Sat, 18 Jul 2020 14:56:21 +0300 (EEST) Received: by mail-pg1-f194.google.com with SMTP id o13so8000597pgf.0 for ; Sat, 18 Jul 2020 04:56:21 -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=sR/Kkzf7rX02B3eF+4HfpSBa8Mtz6KUp8aH7EszJRy4=; b=L+s2P/2PJxSib6RJQIvv8q8XNCBs5yKa6W5bKBvDtvyTB2mGo9GrjVDHLszguqH3CX EIW+6JR/kyGcpDHfvTXBAX9S41zGRoA0Lg6TvUq2Z4/BHlqsrmjbDbQXXohnMlaQlNlR 0L/KzR9GrawOMkDyAeBC3pN6NlQwpX9hkrPtlMDTLNvXCbN8rH7VTwfKwP4KNBhPIEkf gfVESn3r5PW6u5RhIrfM2m50+CPh5VeJK2f0E1+ffwPtgYnX7I4w8aB94KRJvsRSSpHN N5pjtmevj39BfIdL4Q55EFSmCXHUc0x4cPc0EE2++I526L0yzSPVaWYYpKhoO3+ziuBm 6iYg== 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=sR/Kkzf7rX02B3eF+4HfpSBa8Mtz6KUp8aH7EszJRy4=; b=Koaw9NxHUzqBqcBzNtyXUmIsbu5Q5k3no4SdjoYK0EH+1g5AzqryOgzu+TFwdIwDcZ vp7pKyYJDZFq7zTy4+f3IZ/eVMV9Z0Z3ZBXrx7Slx8JQt5O7GdqAL7HxObE8hVkUJkKr EuufJIJJvwVzqB+7h+0918yDcZyuGRZjeRzjHrHQr/rQSX7Mjqs6B0wwwK/AJ0KonUja kg+zqsGTvRaCACYKnKwI68/BEru3BgvuVTYsQGBGg7uLMZLQvloN5FXP7buPdtgUXH5x 3SgA6e6Wdjj/e4NVe3GzR7THG95GAXUdWSKjCp6dOKNS5J203DSYDYkGf5ZondwAYrK+ L0QA== X-Gm-Message-State: AOAM533dxBAHl4etzSvKkDwNV5p2DmKtftojMJNhhEX3DFpgf1LGw6uA 6s/qfRXtY7jS5cXdJXhIeBQLhJHUetg= X-Google-Smtp-Source: ABdhPJxFdMiJW2JyRQSQ8MC1TlUiiNKcFYE3YSZ3dvmtM7bBZucsh7H5GgwYzJP5GV75hzKbaYKuCg== X-Received: by 2002:a63:f1a:: with SMTP id e26mr12376189pgl.80.1595070052238; Sat, 18 Jul 2020 04:00:52 -0700 (PDT) Received: from localhost.localdomain ([122.172.60.196]) by smtp.gmail.com with ESMTPSA id a30sm10543521pfr.87.2020.07.18.04.00.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Jul 2020 04:00:51 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Sat, 18 Jul 2020 16:30:45 +0530 Message-Id: <20200718110046.28805-1-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH 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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 5ea6fd0b9a..5043125fe3 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -1753,9 +1753,9 @@ 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); } return 1; From patchwork Sat Jul 18 11:00:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21163 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 7931D44ACA4 for ; Sat, 18 Jul 2020 14:24:05 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5A2A468B728; Sat, 18 Jul 2020 14:24:05 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oi1-f194.google.com (mail-oi1-f194.google.com [209.85.167.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9F41068B6C0 for ; Sat, 18 Jul 2020 14:23:59 +0300 (EEST) Received: by mail-oi1-f194.google.com with SMTP id k22so10308085oib.0 for ; Sat, 18 Jul 2020 04:23:59 -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=PNcf9ArrtJp2/982Edews+b/xYN810tyStxye3GyZdg=; b=sP9/W+ok2HoCLCcVYfFrhnUqso+0CEhL6xGA5nff6YGbWjpFkfyAhB0YX9Rmj1S/kB oyloF6slA8jjzhoxGnN/9IUFYDwBIu4k+Jm0zICIZzoJLMIb7I6NIkKBsFAedH9zKkLK UU7TjxzSUBfx+G8zqWisYJ62SWp1aqtZXmnJiSwUTH5jDQlrDze9s71fwAvKBKpUMOLg QiVgCzzaFUg5KqzT04Mv71xk+kfFilMYHxPgFP1JLECrEKWn6JNv8xMEeCZb1BB8ST6q CX4F0TPuJb8PloVJI5U1BWET/8IjcQDM+/xxGEfDhSViKjhWUZ6APICo/VbXSOrwNNKl pB9A== 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=PNcf9ArrtJp2/982Edews+b/xYN810tyStxye3GyZdg=; b=g2MuqKy+czr8GKr3aCfsffua+Pf+YArYXJt+C4qHnKmaBub/tjB6qvChHni9uEJK6y m7Xy9kPCmdfqlJEtFhdnjs1ZSPNHAoNLdS9fSez1z4XRerB3SE3dI59zgTTVuCHrB9oa ZmNClHu14EX7LHocOovoAQs9sHAMM++O0+uT2W9Ass6ORDcwYVozxa3WyHDsBgLht2gx icAnBn1Vg9QEM+QD/aeNnILltipu6yH8whRrPwSeEvjmRspWt0iNo2SfitjLfMQUT2fc q1q26J0s3ZcKSNCra8v9fsOYjXeZgT1GidTErmDudA/ww+lHm8QNO6kZ/IDtMqLVlI+Y 0dvA== X-Gm-Message-State: AOAM530ACAncp6x4vUiiALxeFa4wefuAjh4eet2364WJVqL7U/FjWCEx cyUOKM3jruExaxCrWrYgCBG91qIaYlE= X-Google-Smtp-Source: ABdhPJxYk4//fGg/6ygrmd76eBPg6+soT9HT9vaz3nM3gTlgWMlXntaiUT1bDfSr2EB7KgW55DPs0w== X-Received: by 2002:a17:90b:2350:: with SMTP id ms16mr4743870pjb.127.1595070054157; Sat, 18 Jul 2020 04:00:54 -0700 (PDT) Received: from localhost.localdomain ([122.172.60.196]) by smtp.gmail.com with ESMTPSA id a30sm10543521pfr.87.2020.07.18.04.00.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Jul 2020 04:00:53 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Sat, 18 Jul 2020 16:30:46 +0530 Message-Id: <20200718110046.28805-2-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200718110046.28805-1-gautamramk@gmail.com> References: <20200718110046.28805-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [PATCH 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 | 111 +++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 10 deletions(-) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 5043125fe3..4f380eebe8 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,6 +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; @@ -928,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; + } + s->has_ppm = 1; + 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); + 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; @@ -1039,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) { @@ -1048,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, @@ -1064,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); @@ -1178,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; @@ -1228,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; } @@ -2064,6 +2127,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)); @@ -2113,6 +2179,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); } @@ -2164,6 +2235,12 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) ret = get_poc(s, len, poc); break; 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); codsty = s->tile[s->curtileno].codsty; @@ -2189,8 +2266,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: