From patchwork Fri Aug 9 16:29:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: velocityra@gmail.com X-Patchwork-Id: 14356 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 A71F144A01D for ; Fri, 9 Aug 2019 19:31:40 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9412E68ABA6; Fri, 9 Aug 2019 19:31:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 531DA68AB51 for ; Fri, 9 Aug 2019 19:31:36 +0300 (EEST) Received: by mail-wr1-f48.google.com with SMTP id g17so98796427wrr.5 for ; Fri, 09 Aug 2019 09:31:36 -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 :mime-version:content-transfer-encoding; bh=z+qFyOkM2E1xekhQoWab2a94LCo0Q679WGIyuCjK3qM=; b=AZ6YAiyuNnqH2GY0KGKvIHFeI0+5hBL5OBx6dGvue2g/6X5buRNf+yQmQx93SB7d49 4c9uemqWPHt/9G13W3mdRtAS0fBDRhzr2WohHpO/iBuN7ye7gH+w0X1n76zG+wRZGXGJ uBQe0FgPHqsaT78YuKOGMND0Wc+uIuh7Hj4EoBHPsksd2zWLwN5nFAqi+ql1l/6zdLrW YI1m7fFL5EcQmYEcKDPZyFdOF8b+UT0GRIaXZvee06urYStlN16a1Idrk2yRRSAIwVk5 CU5BFFiGhNnsRJ60eCBOQq17VZOy9yEFg8IdMOZ6ocyyIfNLwv3ZSD/0FdV7kC/wlCRF IoDg== 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:mime-version:content-transfer-encoding; bh=z+qFyOkM2E1xekhQoWab2a94LCo0Q679WGIyuCjK3qM=; b=SdYXxgKo10ZT0iVqSMJ6Jgvu5OUH62xvEHPD0sl1EVVn9KXeRD88ZsOuXyEahtB5Ga YnwI2oTATL+dkZ44vgkdXvRrAL0y4PlgMEO72vvyQMq7fObgMIIfH5h/LtPguX1Y+2LP v7HEtoGNjKrQFGyj0yOEl9bLn9MraS7zOV53bzoHe6eQ+WDwKuStEOUAmNCkcL+JyOPp LHjL8nvCk7qeMmXzmQPDYaC3ER91vPZpvAvarSfojTKSU2hNVHB6qnYR2YnmIrcyQjb6 RoNypjCyldO0y3VHVmtMTL+8a7rrUY7VcLoi+Y0vjofegDA9XsiFo7iDzc9l/9fugy9k DKJQ== X-Gm-Message-State: APjAAAW7VTcJN1KIh1XGT7+d4Qx4JHMRqh2qyc/FEd8LPx32f03P3bek U8dmDtPVpXEm/xp5ByfkTcVWhjKeb0s= X-Google-Smtp-Source: APXvYqwpNdnVKTMsDdVhJW0OAUMvQA+q6IBtEcFT9S6FmM+N4QrU6lUR5PT+DxiJoctPcJzKITE3Xw== X-Received: by 2002:a5d:51c1:: with SMTP id n1mr24803589wrv.254.1565368295677; Fri, 09 Aug 2019 09:31:35 -0700 (PDT) Received: from localhost.localdomain ([2a02:587:2409:5200:e9b3:b00d:2017:357c]) by smtp.gmail.com with ESMTPSA id u6sm6721745wml.9.2019.08.09.09.31.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Aug 2019 09:31:35 -0700 (PDT) From: Nick Renieris X-Google-Original-From: Nick Renieris To: ffmpeg-devel@ffmpeg.org Date: Fri, 9 Aug 2019 19:29:55 +0300 Message-Id: <20190809162959.17924-10-velocityra@gmail.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20190809162959.17924-1-velocityra@gmail.com> References: <20190808205233.16368-14-velocityra@gmail.com> <20190809162959.17924-1-velocityra@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v12 10/14] lavc/tiff: Support decoding of DNGs with single-component JPEGs 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: Nick Renieris Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Nick Renieris This enables decoding of DNG images generated by the 'DJI Zenmuse X7' digital camera Samples: https://www.dji.com/gr/zenmuse-x7/info#downloads Signed-off-by: Nick Renieris --- libavcodec/tiff.c | 61 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index cf8965453c..ecd87c0b2f 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -274,7 +274,8 @@ static int add_metadata(int count, int type, } static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int dst_stride, - const uint8_t *src, int src_stride, int width, int height, int is_u16); + const uint8_t *src, int src_stride, int width, int height, + int is_single_comp, int is_u16); static void av_always_inline horizontal_fill(TiffContext *s, unsigned int bpp, uint8_t* dst, @@ -698,6 +699,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid 0, // no stride, only 1 line width / pixel_size_bytes * pixel_size_bits / s->bpp, // need to account for [1, 16] bpp 1, + 0, // single-component variation is only preset in JPEG-encoded DNGs is_u16); } @@ -795,18 +797,32 @@ static uint16_t av_always_inline dng_process_color8(uint16_t value, static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, - int width, int height, int is_u16) + int width, int height, int is_single_comp, int is_u16) { int line, col; float scale_factor; scale_factor = 1.0f / (s->white_level - s->black_level); - if (is_u16) { - for (line = 0; line < height; line++) { + if (is_single_comp) { + if (!is_u16) + return; /* <= 8bpp unsupported */ + + /* Image is double the width and half the height we need, each row comprises 2 rows of the output + (split vertically in the middle). */ + for (line = 0; line < height / 2; line++) { uint16_t *dst_u16 = (uint16_t *)dst; uint16_t *src_u16 = (uint16_t *)src; + /* Blit first half of input row row to initial row of output */ + for (col = 0; col < width; col++) + *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); + + /* Advance the destination pointer by a row (source pointer remains in the same place) */ + dst += dst_stride * sizeof(uint16_t); + dst_u16 = (uint16_t *)dst; + + /* Blit second half of input row row to next row of output */ for (col = 0; col < width; col++) *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); @@ -814,12 +830,27 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride, src += src_stride * sizeof(uint16_t); } } else { - for (line = 0; line < height; line++) { - for (col = 0; col < width; col++) - *dst++ = dng_process_color8(*src++, s->dng_lut, s->black_level, scale_factor); + /* Input and output image are the same size and the MJpeg decoder has done per-component + deinterleaving, so blitting here is straightforward. */ + if (is_u16) { + for (line = 0; line < height; line++) { + uint16_t *dst_u16 = (uint16_t *)dst; + uint16_t *src_u16 = (uint16_t *)src; + + for (col = 0; col < width; col++) + *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); + + dst += dst_stride * sizeof(uint16_t); + src += src_stride * sizeof(uint16_t); + } + } else { + for (line = 0; line < height; line++) { + for (col = 0; col < width; col++) + *dst++ = dng_process_color8(*src++, s->dng_lut, s->black_level, scale_factor); - dst += dst_stride; - src += src_stride; + dst += dst_stride; + src += src_stride; + } } } } @@ -831,7 +862,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame, AVPacket jpkt; uint8_t *dst_data, *src_data; uint32_t dst_offset; /* offset from dst buffer in pixels */ - int is_u16, pixel_size; + int is_single_comp, is_u16, pixel_size; int ret; /* Prepare a packet and send to the MJPEG decoder */ @@ -865,9 +896,18 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame, /* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */ + /* See dng_blit for explanation */ + is_single_comp = (s->avctx_mjpeg->width == w * 2 && s->avctx_mjpeg->height == h / 2); + is_u16 = (s->bpp > 8); pixel_size = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t)); + if (is_single_comp && !is_u16) { + av_log(s->avctx, AV_LOG_ERROR, "DNGs with bpp <= 8 and 1 component are unsupported\n"); + av_frame_unref(s->jpgframe); + return AVERROR_PATCHWELCOME; + } + dst_offset = x + frame->linesize[0] * y / pixel_size; dst_data = frame->data[0] + dst_offset * pixel_size; src_data = s->jpgframe->data[0]; @@ -879,6 +919,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame, s->jpgframe->linesize[0] / pixel_size, w, h, + is_single_comp, is_u16); av_frame_unref(s->jpgframe);