Browse code

dpx: use aligned line starts

SMPTE 268M-2003 specifies that each line starts at a 4-bytes boundary.
Therefore, modify correspondingly the input buffer strides and size.

Partially fixes ticket #3692: DLAD_8b_3c_big.dpx still has inverted
colors, which might be related to endianness.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Christophe Gisquet authored on 2014/08/13 07:37:00
Showing 1 changed files
... ...
@@ -77,9 +77,9 @@ static int decode_frame(AVCodecContext *avctx,
77 77
 
78 78
     unsigned int offset;
79 79
     int magic_num, endian;
80
-    int x, y, i, ret;
81
-    int w, h, bits_per_color, descriptor, elements, packing, total_size;
82
-    int encoding;
80
+    int x, y, stride, i, ret;
81
+    int w, h, bits_per_color, descriptor, elements, packing;
82
+    int encoding, need_align = 0;
83 83
 
84 84
     unsigned int rgbBuffer = 0;
85 85
     int n_datum = 0;
... ...
@@ -185,24 +185,24 @@ static int decode_frame(AVCodecContext *avctx,
185 185
 
186 186
     switch (bits_per_color) {
187 187
     case 8:
188
-        total_size = avctx->width * avctx->height * elements;
188
+        stride = avctx->width * elements;
189 189
         break;
190 190
     case 10:
191 191
         if (!packing) {
192 192
             av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
193 193
             return -1;
194 194
         }
195
-        total_size = (avctx->width * elements + 2) / 3 * 4 * avctx->height;
195
+        stride = (avctx->width * elements + 2) / 3 * 4;
196 196
         break;
197 197
     case 12:
198 198
         if (!packing) {
199 199
             av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
200 200
             return -1;
201 201
         }
202
-        total_size = 2 * avctx->width * avctx->height * elements;
202
+        stride = 2 * avctx->width * elements;
203 203
         break;
204 204
     case 16:
205
-        total_size = 2 * avctx->width * avctx->height * elements;
205
+        stride = 2 * avctx->width * elements;
206 206
         break;
207 207
     case 1:
208 208
     case 32:
... ...
@@ -213,6 +213,26 @@ static int decode_frame(AVCodecContext *avctx,
213 213
         return AVERROR_INVALIDDATA;
214 214
     }
215 215
 
216
+    // Table 3c: Runs will always break at scan line boundaries. Packing
217
+    // will always break to the next 32-bit word at scan-line boundaries.
218
+    // Unfortunately, the encoder produced invalid files, so attempt
219
+    // to detect it
220
+    need_align = FFALIGN(stride, 4);
221
+    if (need_align*avctx->height + (int64_t)offset > avpkt->size) {
222
+        // Alignment seems unappliable, try without
223
+        if (stride*avctx->height + (int64_t)offset > avpkt->size) {
224
+            av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
225
+            return AVERROR_INVALIDDATA;
226
+        } else {
227
+            av_log(avctx, AV_LOG_INFO, "Decoding DPX without scanline "
228
+                   "alignment.\n");
229
+            need_align = 0;
230
+        }
231
+    } else {
232
+        need_align -= stride;
233
+        stride = FFALIGN(stride, 4);
234
+    }
235
+
216 236
     switch (1000 * descriptor + 10 * bits_per_color + endian) {
217 237
     case 6081:
218 238
     case 6080:
... ...
@@ -276,10 +296,6 @@ static int decode_frame(AVCodecContext *avctx,
276 276
     for (i=0; i<AV_NUM_DATA_POINTERS; i++)
277 277
         ptr[i] = p->data[i];
278 278
 
279
-    if (total_size + (int64_t)offset > avpkt->size) {
280
-        av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
281
-        return AVERROR_INVALIDDATA;
282
-    }
283 279
     switch (bits_per_color) {
284 280
     case 10:
285 281
         for (x = 0; x < avctx->height; x++) {
... ...
@@ -318,6 +334,8 @@ static int decode_frame(AVCodecContext *avctx,
318 318
                 // For 12 bit, ignore alpha
319 319
                 if (elements == 4)
320 320
                     buf += 2;
321
+                // Jump to next aligned position
322
+                buf += need_align;
321 323
             }
322 324
             for (i = 0; i < 3; i++)
323 325
                 ptr[i] += p->linesize[i];
... ...
@@ -327,7 +345,7 @@ static int decode_frame(AVCodecContext *avctx,
327 327
         elements *= 2;
328 328
     case 8:
329 329
         av_image_copy_plane(ptr[0], p->linesize[0],
330
-                            buf, elements * avctx->width,
330
+                            buf, stride,
331 331
                             elements * avctx->width, avctx->height);
332 332
         break;
333 333
     }