Hello,

Mipmap and ripmap is two way to store several resolution of the picture
inside an exr file
The difference between these two mode, is the number of subres level (lot
more subres in ripmap, than mipmap).
These files are mainly design to store maps for 3D render.

After some tests on official samples, it seems that mipmap and ripmap exr
file, store the full res tiles before subres tiles.
So the actual way of decoding tile, works fine with mipmap and ripmap (only
calc the full res tile count), run decode_block for theses tile.

So i think the patch in attach works fine for mipmap and ripmap.

I also ignore now, the tile round mode, because this value, is only, for
detecting tile count in subres level

This patch decode fine all Multiresolution tile files of the official
libray :
http://download.savannah.nongnu.org/releases/openexr/openexr-images-1.7.0.tar.gz

except : WavyLinesSphere.exr
But this file, is in fact not a Multiresolution file (exrheader information
show that it's a scanline PIZ).
And i suppose the decoding error, is related, to ticket
https://trac.ffmpeg.org/ticket/3932


Comments welcome

Martin
Jokyo Images
From 0418ccbdae5a94867ac2e7805f1311f88c434d8f Mon Sep 17 00:00:00 2001
From: Martin Vignali <martin.vign...@gmail.com>
Date: Tue, 5 Apr 2016 21:17:51 +0200
Subject: [PATCH] libavcodec/exr : enable mipmap, ripmap decoding

---
 libavcodec/exr.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index b542831..2763126 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -73,11 +73,13 @@ enum ExrTileLevelMode {
     EXR_TILE_LEVEL_ONE,
     EXR_TILE_LEVEL_MIPMAP,
     EXR_TILE_LEVEL_RIPMAP,
+    EXR_TILE_LEVEL_UNKNOWN,
 };
 
 enum ExrTileLevelRound {
     EXR_TILE_ROUND_UP,
     EXR_TILE_ROUND_DOWN,
+    EXR_TILE_ROUND_UNKNOWN,
 };
 
 typedef struct EXRChannel {
@@ -1011,9 +1013,9 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
         if (data_size <= 0 || data_size > buf_size)
             return AVERROR_INVALIDDATA;
 
-        if (tileLevelX || tileLevelY) { /* tile of low resolution (Mipmap, rimmap) */
-            av_log(s->avctx, AV_LOG_ERROR, "Wrong Tile level %i / %i.\n", tileLevelX, tileLevelY);
-            return AVERROR_INVALIDDATA;
+        if (tileLevelX || tileLevelY) { /* tile level, is not the full res level */
+            avpriv_report_missing_feature(s->avctx, "Subres tile before full res tile");
+            return AVERROR_PATCHWELCOME;
         }
 
         line = s->tile_attr.ySize * tileY;
@@ -1490,13 +1492,13 @@ static int decode_header(EXRContext *s)
             s->tile_attr.level_mode = tileLevel & 0x0f;
             s->tile_attr.level_round = (tileLevel >> 4) & 0x0f;
 
-            if (s->tile_attr.level_mode != EXR_TILE_LEVEL_ONE) {
+            if (s->tile_attr.level_mode >= EXR_TILE_LEVEL_UNKNOWN){
                 avpriv_report_missing_feature(s->avctx, "Tile level mode %d",
                                               s->tile_attr.level_mode);
                 return AVERROR_PATCHWELCOME;
             }
 
-            if (s->tile_attr.level_round != EXR_TILE_ROUND_UP) {
+            if (s->tile_attr.level_round >= EXR_TILE_ROUND_UNKNOWN) {
                 avpriv_report_missing_feature(s->avctx, "Tile level round %d",
                                               s->tile_attr.level_round);
                 return AVERROR_PATCHWELCOME;
-- 
1.9.3 (Apple Git-50)

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to