* commit '34efb8a169e4551326e069be47125c6c2cb7ab90':
quickdraw: Support direct pixel blocks
Conflicts:
Changelog
libavcodec/version.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -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, \ |