From patchwork Tue Jun 9 03:53:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 20237 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 1179B447ADD for ; Tue, 9 Jun 2020 07:23:19 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DE2B168B287; Tue, 9 Jun 2020 07:23:18 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oi1-f193.google.com (mail-oi1-f193.google.com [209.85.167.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8B0176804B3 for ; Tue, 9 Jun 2020 07:23:12 +0300 (EEST) Received: by mail-oi1-f193.google.com with SMTP id 25so16590732oiy.13 for ; Mon, 08 Jun 2020 21:23:12 -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=rC6rZ7jMwegO944chJtqnGOCCAJEomkb/NS/Hw2eujw=; b=O7NToz2Hka0zSGM8uQ5biaFoF10DsRlXOWmv1/dd5rqFQuswRkBJJeGRe0AgzJlnaN /4pUvsARcUK1HxRnrbemFU6fiUoG3EVxPOomK7mqPXptr7PD9AVqYRWfj0SuhfNd9cDP ThcSs8VcqAbH1VWEUEX2diLCB/p+WBwEmPPb4JkOMRYVPrjVjJZ9gpoYZyt2VU7v6HeK k/3zOWQyamn+WfungSss4Nv1JxxvAzx9p5tPuO6ZfuEiZwEtrYH4gJj91w+OJVvzKJ9S h0u/jKgvEpIbgGPgOywlys9+wxL0U0+dW9FMVVHmoXmuGV4Sfbu9uBQchKB4vu6w5JCi l1xg== 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=rC6rZ7jMwegO944chJtqnGOCCAJEomkb/NS/Hw2eujw=; b=TvREW9zHLEnpxhWnG0Fh9LuKfmQCcssTxdtt3LgokC1/D+0CYPrKtpO9B4W/qXdTd5 RlB8xf9m1aKCKxhCyYVbz1thxFdCIO5AcaZZF/69AXwi47YvsgB9N3gu4hQo3HAT2xDo bJgqh1QEpkeO/+SqirSTRX5fMnlnnyGvfWEVKsW6Cfwu9vw/UKkRxZwlLIyP9qqKVbMg 91jVBr2n5vA0VJ1wvdswxI43FfNIRKaXqh/d6li3AwCuBPNdGDREvFU9jJ8OVXDU4YYw J5UYK6XOyhqblDWXuXdl5CaPdgZVY8dA73gJD0SXrlAweNprmTmq8O81NIXuZf2UUR0K U+Tg== X-Gm-Message-State: AOAM530x4ZmAX/D0s1mBzcmpBlIGLSlETnVWws+DLoyR2bxWsoXHXdma 3zMgH98wqAygJDYav0F6sh7UhapO6Xo= X-Google-Smtp-Source: ABdhPJzLJCpUbzp/glWvcNH/BQUcOqDDvpc3GcsAyTRxBmtQpCJwaWczRyuLoaSdJDauR75UH2fThg== X-Received: by 2002:a17:90a:c797:: with SMTP id gn23mr2468142pjb.165.1591674816817; Mon, 08 Jun 2020 20:53:36 -0700 (PDT) Received: from localhost.localdomain ([122.172.136.215]) by smtp.gmail.com with ESMTPSA id x17sm874485pjr.29.2020.06.08.20.53.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jun 2020 20:53:36 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 9 Jun 2020 09:23:29 +0530 Message-Id: <20200609035329.23636-1-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH] 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 sample p1_03.j2k to be decoded. --- libavcodec/jpeg2000dec.c | 78 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index b7766459c4..4e66ebf7c6 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; @@ -901,6 +909,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; @@ -1012,6 +1045,17 @@ static int getlblockinc(Jpeg2000DecoderContext *s) return res; } +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) { @@ -1037,7 +1081,9 @@ 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); @@ -1151,7 +1197,10 @@ 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); + } else if (tile->has_ppt) { tile->packed_headers_stream = s->g; select_stream(s, tile, tp_index); } @@ -1201,7 +1250,9 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, return 0; skip_data: - if (tile->has_ppt) + if (s->has_ppm) + tile->tile_part[*tp_index].header_tpg = s->g; + else if (tile->has_ppt) tile->packed_headers_stream = s->g; else tile->tile_part[*tp_index].tpg = s->g; @@ -2068,6 +2119,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); } @@ -2119,6 +2175,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; @@ -2144,8 +2206,18 @@ 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 + 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: