[FFmpeg-devel] [PATCH v12 13/14] lavc/tiff: Support DNGs with striped (non-tiled) JPEGs images
Nick Renieris
velocityra at gmail.com
Fri Aug 9 19:29:58 EEST 2019
From: Nick Renieris <velocityra at gmail.com>
DNG samples here can now be decoded:
- https://www.photographyblog.com/previews/pentax_k1_photos
Signed-off-by: Nick Renieris <velocityra at gmail.com>
---
libavcodec/tiff.c | 73 +++++++++++++++++++++++++++--------------------
1 file changed, 42 insertions(+), 31 deletions(-)
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 0d931641c2..b9aa4efd02 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -550,6 +550,8 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride,
return ret;
}
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame);
+
static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int stride,
const uint8_t *src, int size, int strip_start, int lines)
{
@@ -665,6 +667,17 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid
is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG);
+ /* Decode JPEG-encoded DNGs with strips */
+ if (s->compr == TIFF_NEWJPEG && is_dng) {
+ if (s->strips > 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "More than one DNG JPEG strips unsupported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ if ((ret = dng_decode_strip(s->avctx, p)) < 0)
+ return ret;
+ return 0;
+ }
+
for (line = 0; line < lines; line++) {
if (src - ssrc > size) {
av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -859,8 +872,8 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
}
}
-static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame,
- int tile_byte_count, int x, int y, int w, int h)
+static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame,
+ int tile_byte_count, int dst_x, int dst_y, int w, int h)
{
TiffContext *s = avctx->priv_data;
AVPacket jpkt;
@@ -912,7 +925,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame,
return AVERROR_PATCHWELCOME;
}
- dst_offset = x + frame->linesize[0] * y / pixel_size;
+ dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size;
dst_data = frame->data[0] + dst_offset * pixel_size;
src_data = s->jpgframe->data[0];
@@ -931,7 +944,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame,
return 0;
}
-static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
+static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt)
{
TiffContext *s = avctx->priv_data;
int tile_idx;
@@ -944,6 +957,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
int pos_x = 0, pos_y = 0;
int ret;
+ s->jpgframe->width = s->tile_width;
+ s->jpgframe->height = s->tile_length;
+
+ s->avctx_mjpeg->width = s->tile_width;
+ s->avctx_mjpeg->height = s->tile_length;
+
has_width_leftover = (s->width % s->tile_width != 0);
has_height_leftover = (s->height % s->tile_length != 0);
@@ -980,7 +999,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
bytestream2_seek(&s->gb, tile_offset, SEEK_SET);
/* Decode JPEG tile and copy it in the reference frame */
- ret = dng_decode_jpeg_tile(avctx, frame, tile_byte_count, pos_x, pos_y, tile_width, tile_length);
+ ret = dng_decode_jpeg(avctx, frame, tile_byte_count, pos_x, pos_y, tile_width, tile_length);
if (ret < 0)
return ret;
@@ -993,30 +1012,24 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
}
}
- return 0;
-}
+ /* Frame is ready to be output */
+ frame->pict_type = AV_PICTURE_TYPE_I;
+ frame->key_frame = 1;
-static int dng_decode(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt) {
- int ret;
+ return avpkt->size;
+}
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame)
+{
TiffContext *s = avctx->priv_data;
- s->jpgframe->width = s->tile_width;
- s->jpgframe->height = s->tile_length;
-
- s->avctx_mjpeg->width = s->tile_width;
- s->avctx_mjpeg->height = s->tile_length;
-
- /* Decode all tiles in a frame */
- ret = dng_decode_tiles(avctx, frame);
- if (ret < 0)
- return ret;
+ s->jpgframe->width = s->width;
+ s->jpgframe->height = s->height;
- /* Frame is ready to be output */
- frame->pict_type = AV_PICTURE_TYPE_I;
- frame->key_frame = 1;
+ s->avctx_mjpeg->width = s->width;
+ s->avctx_mjpeg->height = s->height;
- return avpkt->size;
+ return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, s->height);
}
static int init_image(TiffContext *s, ThreadFrame *frame)
@@ -1880,17 +1893,15 @@ again:
/* Handle DNG images with JPEG-compressed tiles */
- if (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG) {
- if (!s->is_jpeg && s->is_tiled) {
+ if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG) && s->is_tiled) {
+ if (!s->is_jpeg) {
avpriv_report_missing_feature(avctx, "DNG uncompressed tiled images");
return AVERROR_PATCHWELCOME;
- }
- if (s->is_jpeg && !s->is_bayer) {
- avpriv_report_missing_feature(avctx, "DNG JPG-compressed non-bayer-encoded images");
+ } else if (!s->is_bayer) {
+ avpriv_report_missing_feature(avctx, "DNG JPG-compressed tiled non-bayer-encoded images");
return AVERROR_PATCHWELCOME;
- }
- if (s->is_jpeg && s->is_bayer) {
- if ((ret = dng_decode(avctx, (AVFrame*)data, avpkt)) > 0)
+ } else {
+ if ((ret = dng_decode_tiles(avctx, (AVFrame*)data, avpkt)) > 0)
*got_frame = 1;
return ret;
}
--
2.21.0.windows.1
More information about the ffmpeg-devel
mailing list