Browse code

Merge commit '34efb8a169e4551326e069be47125c6c2cb7ab90'

* commit '34efb8a169e4551326e069be47125c6c2cb7ab90':
quickdraw: Support direct pixel blocks

Conflicts:
Changelog
libavcodec/version.h

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

Michael Niedermayer authored on 2015/05/07 03:40:26
Showing 3 changed files
... ...
@@ -19,6 +19,7 @@ version <next>:
19 19
 - chorus filter
20 20
 - Canopus HQ/HQA decoder
21 21
 - Automatically rotate videos based on metadata in ffmpeg
22
+- improved Quickdraw compatibility
22 23
 
23 24
 
24 25
 version 2.6:
... ...
@@ -35,6 +35,8 @@
35 35
 enum QuickdrawOpcodes {
36 36
     PACKBITSRECT = 0x0098,
37 37
     PACKBITSRGN,
38
+    DIRECTBITSRECT,
39
+    DIRECTBITSRGN,
38 40
 
39 41
     EOP = 0x00FF,
40 42
 };
... ...
@@ -64,14 +66,17 @@ static int parse_palette(AVCodecContext *avctx, GetByteContext *gbc,
64 64
     return 0;
65 65
 }
66 66
 
67
-static int decode_rle(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)
67
+static int decode_rle(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc,
68
+                      int step)
68 69
 {
69
-    int i;
70
+    int i, j;
71
+    int offset = avctx->width * step;
70 72
     uint8_t *outdata = p->data[0];
71 73
 
72 74
     for (i = 0; i < avctx->height; i++) {
73 75
         int size, left, code, pix;
74 76
         uint8_t *out = outdata;
77
+        int pos = 0;
75 78
 
76 79
         /* size of packed line */
77 80
         size = left = bytestream2_get_be16(gbc);
... ...
@@ -83,12 +88,24 @@ static int decode_rle(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)
83 83
             code = bytestream2_get_byte(gbc);
84 84
             if (code & 0x80 ) { /* run */
85 85
                 pix = bytestream2_get_byte(gbc);
86
-                memset(out, pix, 257 - code);
87
-                out   += 257 - code;
86
+                for (j = 0; j < 257 - code; j++) {
87
+                    out[pos] = pix;
88
+                    pos += step;
89
+                    if (pos >= offset) {
90
+                        pos -= offset;
91
+                        pos++;
92
+                    }
93
+                }
88 94
                 left  -= 2;
89 95
             } else { /* copy */
90
-                bytestream2_get_buffer(gbc, out, code + 1);
91
-                out   += code + 1;
96
+                for (j = 0; j < code + 1; j++) {
97
+                    out[pos] = bytestream2_get_byte(gbc);
98
+                    pos += step;
99
+                    if (pos >= offset) {
100
+                        pos -= offset;
101
+                        pos++;
102
+                    }
103
+                }
92 104
                 left  -= 2 + code;
93 105
             }
94 106
         }
... ...
@@ -134,6 +151,7 @@ static int decode_frame(AVCodecContext *avctx,
134 134
 
135 135
     while (bytestream2_get_bytes_left(&gbc) >= 4) {
136 136
         int bppcnt, bpp;
137
+        int rowbytes, pack_type;
137 138
         int opcode = bytestream2_get_be16(&gbc);
138 139
 
139 140
         switch(opcode) {
... ...
@@ -183,7 +201,63 @@ static int decode_frame(AVCodecContext *avctx,
183 183
                 avpriv_report_missing_feature(avctx, "Packbit mask region");
184 184
             }
185 185
 
186
-            ret = decode_rle(avctx, p, &gbc);
186
+            ret = decode_rle(avctx, p, &gbc, bppcnt);
187
+            if (ret < 0)
188
+                return ret;
189
+            *got_frame = 1;
190
+            break;
191
+        case DIRECTBITSRECT:
192
+        case DIRECTBITSRGN:
193
+            av_log(avctx, AV_LOG_DEBUG, "Parsing Directbit opcode\n");
194
+
195
+            bytestream2_skip(&gbc, 4);
196
+            rowbytes = bytestream2_get_be16(&gbc) & 0x3FFF;
197
+            if (rowbytes <= 250) {
198
+                avpriv_report_missing_feature(avctx, "Short rowbytes");
199
+                return AVERROR_PATCHWELCOME;
200
+            }
201
+
202
+            bytestream2_skip(&gbc, 10);
203
+            pack_type = bytestream2_get_be16(&gbc);
204
+
205
+            bytestream2_skip(&gbc, 16);
206
+            bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
207
+            bpp    = bytestream2_get_be16(&gbc); /* cmpSize */
208
+
209
+            av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp);
210
+            if (bppcnt == 3 && bpp == 8) {
211
+                avctx->pix_fmt = AV_PIX_FMT_RGB24;
212
+            } else if (bppcnt == 4 && bpp == 8) {
213
+                avctx->pix_fmt = AV_PIX_FMT_ARGB;
214
+            } else {
215
+                av_log(avctx, AV_LOG_ERROR,
216
+                       "Invalid pixel format (bppcnt %d bpp %d) in Directbit\n",
217
+                       bppcnt, bpp);
218
+                return AVERROR_INVALIDDATA;
219
+            }
220
+
221
+            /* set packing when default is selected */
222
+            if (pack_type == 0)
223
+                pack_type = bppcnt;
224
+
225
+            if (pack_type != 3 && pack_type != 4) {
226
+                avpriv_request_sample(avctx, "Pack type %d", pack_type);
227
+                return AVERROR_PATCHWELCOME;
228
+            }
229
+            if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
230
+                av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
231
+                return ret;
232
+            }
233
+
234
+            /* jump to data */
235
+            bytestream2_skip(&gbc, 30);
236
+
237
+            if (opcode == DIRECTBITSRGN) {
238
+                bytestream2_skip(&gbc, 2 + 8); /* size + rect */
239
+                avpriv_report_missing_feature(avctx, "DirectBit mask region");
240
+            }
241
+
242
+            ret = decode_rle(avctx, p, &gbc, bppcnt);
187 243
             if (ret < 0)
188 244
                 return ret;
189 245
             *got_frame = 1;
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 #define LIBAVCODEC_VERSION_MAJOR 56
32 32
 #define LIBAVCODEC_VERSION_MINOR  37
33
-#define LIBAVCODEC_VERSION_MICRO 100
33
+#define LIBAVCODEC_VERSION_MICRO 101
34 34
 
35 35
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
36 36
                                                LIBAVCODEC_VERSION_MINOR, \