1 /*
2 * LucasArts Smush video decoder
3 * Copyright (c) 2006 Cyril Zorin
4 * Copyright (c) 2011 Konstantin Shishkov
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 // #define DEBUG 1
24
33
35
39
42 int16_t delta_pal[768];
43
48
50 uint16_t *frm0, *frm1, *
frm2;
54
57
59
61
62 uint16_t codebook[256];
63 uint16_t small_codebook[4];
64
68
70 int seq_num, codec, rotate_code, rle_output_size;
71
75
82 };
83
90 };
91
92 /**
93 * Return enum GlyphEdge of box where point (x, y) lies.
94 *
95 * @param x x point coordinate
96 * @param y y point coordinate
97 * @param edge_size box width/height.
98 */
100 {
101 const int edge_max = edge_size - 1;
102
103 if (!y) {
105 } else if (y == edge_max) {
107 } else if (!x) {
109 } else if (x == edge_max) {
111 } else {
113 }
114 }
115
117 {
134 }
135
137 }
138
139 /**
140 * Interpolate two points.
141 */
142 static void interp_point(int8_t *points,
int x0,
int y0,
int x1,
int y1,
143 int pos, int npoints)
144 {
145 if (npoints) {
146 points[0] = (x0 * pos + x1 * (npoints - pos) + (npoints >> 1)) / npoints;
147 points[1] = (y0 * pos + y1 * (npoints - pos) + (npoints >> 1)) / npoints;
148 } else {
149 points[0] = x0;
150 points[1] = y0;
151 }
152 }
153
154 /**
155 * Construct glyphs by iterating through vectors coordinates.
156 *
157 * @param pglyphs pointer to table where glyphs are stored
158 * @param xvec pointer to x component of vectors coordinates
159 * @param yvec pointer to y component of vectors coordinates
160 * @param side_length glyph width/height.
161 */
162 static void make_glyphs(int8_t *pglyphs,
const int8_t *xvec,
const int8_t *yvec,
163 const int side_length)
164 {
165 const int glyph_size = side_length * side_length;
166 int8_t *pglyph = pglyphs;
167
168 int i, j;
170 int x0 = xvec[i];
171 int y0 = yvec[i];
173
175 int x1 = xvec[j];
176 int y1 = yvec[j];
180 int ipoint;
181
182 for (ipoint = 0; ipoint <= npoints; ipoint++) {
183 int8_t point[2];
184 int irow, icol;
185
187
188 switch (dir) {
190 for (irow = point[1]; irow >= 0; irow--)
191 pglyph[point[0] + irow * side_length] = 1;
192 break;
193
195 for (irow = point[1]; irow < side_length; irow++)
196 pglyph[point[0] + irow * side_length] = 1;
197 break;
198
200 for (icol = point[0]; icol >= 0; icol--)
201 pglyph[icol + point[1] * side_length] = 1;
202 break;
203
205 for (icol = point[0]; icol < side_length; icol++)
206 pglyph[icol + point[1] * side_length] = 1;
207 break;
208 }
209 }
210 }
211 }
212 }
213
215 {
219
222
225 }
226
228 {
237 }
238
240 {
246
250 }
251
252 return 0;
253 }
254
256 {
258 if (rotate_code == 2)
261 }
262
264 {
266
269
271
276 }
277
280
282 int i;
283
287 }
288
290 for (i = 0; i < 256; i++)
292 }
293
294 return 0;
295 }
296
298 {
300
302
303 return 0;
304 }
305
307 {
309
310 while (left > 0) {
311 opcode = bytestream2_get_byte(&ctx->
gb);
312 run_len = (opcode >> 1) + 1;
315
316 if (opcode & 1) {
317 color = bytestream2_get_byte(&ctx->
gb);
318 memset(dst, color, run_len);
319 } else {
323 }
324
327 }
328
329 return 0;
330 }
331
334 {
336 int i, j,
len, flag, code,
val, pos,
end;
337
338 for (i = 0; i <
height; i++) {
339 pos = 0;
340
343
344 len = bytestream2_get_le16u(&ctx->
gb);
346
350
351 code = bytestream2_get_byteu(&ctx->
gb);
352 flag = code & 1;
353 code = (code >> 1) + 1;
354 if (pos + code > width)
356 if (flag) {
357 val = bytestream2_get_byteu(&ctx->
gb);
358 if (val)
359 memset(dst + pos, val, code);
360 pos += code;
361 } else {
364 for (j = 0; j < code; j++) {
365 val = bytestream2_get_byteu(&ctx->
gb);
366 if (val)
368 pos++;
369 }
370 }
371 }
373 }
375
376 return 0;
377 }
378
381 {
382 int pos, i, j;
383
385 for (j = 0; j < 4; j++) {
386 for (i = 0; i < 4; i++) {
387 if ((pos + i) < 0 || (pos + i) >= height * stride)
388 dst[i] = 0;
389 else
390 dst[i] = src[i];
391 }
395 }
396 }
397
400 {
403 int skip_run = 0;
404 int compr, mvoff, seq,
flags;
405 uint32_t decoded_size;
407
408 compr = bytestream2_get_byte(&ctx->
gb);
409 mvoff = bytestream2_get_byte(&ctx->
gb);
410 seq = bytestream2_get_le16(&ctx->
gb);
411 decoded_size = bytestream2_get_le32(&ctx->
gb);
413 flags = bytestream2_get_byte(&ctx->
gb);
415
416 if (decoded_size > ctx->
height * stride - left - top * stride) {
417 decoded_size = ctx->
height * stride - left - top *
stride;
419 }
420
422
423 if (((seq & 1) || !(flags & 1)) && (compr && compr != 2))
425
428
429 if (mvoff > 2) {
432 }
434 switch (compr) {
435 case 0:
436 for (i = 0; i <
height; i++) {
439 }
442 break;
443 case 2:
448 break;
449 case 3:
450 case 4:
451 if (flags & 4) {
452 for (j = 0; j <
height; j += 4) {
453 for (i = 0; i <
width; i += 4) {
454 int code;
455 if (skip_run) {
456 skip_run--;
458 continue;
459 }
462 code = bytestream2_get_byteu(&ctx->
gb);
463 switch (code) {
464 case 0xFF:
467 for (k = 0; k < 4; k++)
469 break;
470 case 0xFE:
473 for (k = 0; k < 4; k++)
474 memset(dst + i + k * stride, bytestream2_get_byteu(&ctx->
gb), 4);
475 break;
476 case 0xFD:
479 t = bytestream2_get_byteu(&ctx->
gb);
480 for (k = 0; k < 4; k++)
481 memset(dst + i + k * stride, t, 4);
482 break;
483 default:
484 if (compr == 4 && !code) {
487 skip_run = bytestream2_get_byteu(&ctx->
gb) + 1;
488 i -= 4;
489 } else {
490 int mx, my;
491
492 mx =
c37_mv[(mvoff * 255 + code) * 2 ];
493 my =
c37_mv[(mvoff * 255 + code) * 2 + 1];
494 codec37_mv(dst + i, prev + i + mx + my * stride,
495 ctx->
height, stride, i + mx, j + my);
496 }
497 }
498 }
499 dst += stride * 4;
500 prev += stride * 4;
501 }
502 } else {
503 for (j = 0; j <
height; j += 4) {
504 for (i = 0; i <
width; i += 4) {
505 int code;
506 if (skip_run) {
507 skip_run--;
509 continue;
510 }
511 code = bytestream2_get_byte(&ctx->
gb);
512 if (code == 0xFF) {
515 for (k = 0; k < 4; k++)
517 } else if (compr == 4 && !code) {
520 skip_run = bytestream2_get_byteu(&ctx->
gb) + 1;
521 i -= 4;
522 } else {
523 int mx, my;
524
525 mx =
c37_mv[(mvoff * 255 + code) * 2];
526 my =
c37_mv[(mvoff * 255 + code) * 2 + 1];
527 codec37_mv(dst + i, prev + i + mx + my * stride,
528 ctx->
height, stride, i + mx, j + my);
529 }
530 }
531 dst += stride * 4;
532 prev += stride * 4;
533 }
534 }
535 break;
536 default:
538 "subcodec 37 compression %d not implemented\n", compr);
540 }
541
542 return 0;
543 }
544
547 {
550 int8_t *pglyph;
551
554
555 code = bytestream2_get_byteu(&ctx->
gb);
556 if (code >= 0xF8) {
557 switch (code) {
558 case 0xFF:
559 if (size == 2) {
562 dst[0] = bytestream2_get_byteu(&ctx->
gb);
563 dst[1] = bytestream2_get_byteu(&ctx->
gb);
564 dst[0+
stride] = bytestream2_get_byteu(&ctx->
gb);
565 dst[1+
stride] = bytestream2_get_byteu(&ctx->
gb);
566 } else {
567 size >>= 1;
568 if (
process_block(ctx, dst, prev1, prev2, stride, tbl, size))
570 if (
process_block(ctx, dst + size, prev1 + size, prev2 + size,
571 stride, tbl, size))
576 if (
process_block(ctx, dst, prev1, prev2, stride, tbl, size))
578 if (
process_block(ctx, dst + size, prev1 + size, prev2 + size,
579 stride, tbl, size))
581 }
582 break;
583 case 0xFE:
586
587 t = bytestream2_get_byteu(&ctx->
gb);
588 for (k = 0; k <
size; k++)
589 memset(dst + k * stride, t, size);
590 break;
591 case 0xFD:
594
595 code = bytestream2_get_byteu(&ctx->
gb);
598
599 for (k = 0; k <
size; k++)
600 for (t = 0; t <
size; t++)
601 dst[t + k * stride] = colors[!*pglyph++];
602 break;
603 case 0xFC:
604 for (k = 0; k <
size; k++)
605 memcpy(dst + k * stride, prev1 + k * stride, size);
606 break;
607 default:
610 t = bytestream2_get_byte(&ctx->
gb);
612 for (k = 0; k <
size; k++)
613 memset(dst + k * stride, t, size);
614 }
615 } else {
619
621
622 if (index < - mx - my*stride ||
623 (ctx->
buf_size>>1) - index < mx + size + (my + size - 1)*stride) {
626 }
627
628 for (k = 0; k <
size; k++)
629 memcpy(dst + k * stride, prev2 + mx + (my + k) * stride, size);
630 }
631
632 return 0;
633 }
634
637 {
638 int i, j, seq, compr, new_rot, tbl_pos, skip;
643 uint32_t decoded_size;
644
646 seq = bytestream2_get_le16(&ctx->
gb);
647 compr = bytestream2_get_byte(&ctx->
gb);
648 new_rot = bytestream2_get_byte(&ctx->
gb);
649 skip = bytestream2_get_byte(&ctx->
gb);
651 decoded_size = bytestream2_get_le32(&ctx->
gb);
653
654 if (decoded_size > ctx->
height * stride - left - top * stride) {
655 decoded_size = ctx->
height * stride - left - top *
stride;
657 }
658
659 if (skip & 1)
661 if (!seq) {
663 memset(prev1, 0, ctx->
height * stride);
664 memset(prev2, 0, ctx->
height * stride);
665 }
667 switch (compr) {
668 case 0:
671 for (j = 0; j <
height; j++) {
674 }
675 break;
676 case 1:
679 for (j = 0; j <
height; j += 2) {
680 for (i = 0; i <
width; i += 2) {
681 dst[i] = dst[i + 1] =
682 dst[stride + i] = dst[stride + i + 1] = bytestream2_get_byteu(&ctx->
gb);
683 }
684 dst += stride * 2;
685 }
686 break;
687 case 2:
689 for (j = 0; j <
height; j += 8) {
690 for (i = 0; i <
width; i += 8) {
691 if (
process_block(ctx, dst + i, prev1 + i, prev2 + i, stride,
692 tbl_pos + 8, 8))
694 }
695 dst += stride * 8;
696 prev1 += stride * 8;
697 prev2 += stride * 8;
698 }
699 }
700 break;
701 case 3:
703 break;
704 case 4:
706 break;
707 case 5:
710 break;
711 default:
713 "subcodec 47 compression %d not implemented\n", compr);
715 }
718 else
721
722 return 0;
723 }
724
726 {
727 uint16_t codec, top, left, w, h;
728
729 codec = bytestream2_get_le16u(&ctx->
gb);
730 left = bytestream2_get_le16u(&ctx->
gb);
731 top = bytestream2_get_le16u(&ctx->
gb);
732 w = bytestream2_get_le16u(&ctx->
gb);
733 h = bytestream2_get_le16u(&ctx->
gb);
734
735 if (!w || !h) {
738 }
739
740 if (ctx->
width < left + w || ctx->
height < top + h) {
751 }
752 }
754
756 switch (codec) {
757 case 1:
758 case 3:
760 break;
761 case 37:
763 break;
764 case 47:
766 break;
767 default:
770 }
771 }
772
774 {
775 uint16_t *frm = ctx->
frm0;
777
781 }
782 for (y = 0; y < ctx->
height; y++) {
783 for (x = 0; x < ctx->
width; x++)
784 frm[x] = bytestream2_get_le16u(&ctx->
gb);
786 }
787 return 0;
788 }
789
791 {
794 }
795
796 static void copy_block(uint16_t *pdest, uint16_t *psrc,
int block_size,
int pitch)
797 {
801
802 switch (block_size) {
803 case 2:
805 break;
806 case 4:
808 break;
809 case 8:
811 break;
812 }
813 }
814
816 {
818
819 pitch -= block_size;
820 for (y = 0; y < block_size; y++, pdest += pitch)
821 for (x = 0; x < block_size; x++)
822 *pdest++ = color;
823 }
824
826 uint16_t bg_color, int block_size, int pitch)
827 {
828 int8_t *pglyph;
829 uint16_t colors[2] = { fg_color, bg_color };
831
835 }
836
838 pitch -= block_size;
839
840 for (y = 0; y < block_size; y++, dst += pitch)
841 for (x = 0; x < block_size; x++)
842 *dst++ = colors[*pglyph++];
843 return 0;
844 }
845
847 {
848 uint16_t *dst = ctx->
frm0 + cx + cy * ctx->
pitch;
849
850 if (block_size == 2) {
851 uint32_t indices;
852
855
856 indices = bytestream2_get_le32u(&ctx->
gb);
857 dst[0] = ctx->
codebook[indices & 0xFF]; indices >>= 8;
858 dst[1] = ctx->
codebook[indices & 0xFF]; indices >>= 8;
859 dst[pitch] = ctx->
codebook[indices & 0xFF]; indices >>= 8;
860 dst[pitch + 1] = ctx->
codebook[indices & 0xFF];
861 } else {
862 uint16_t fgcolor, bgcolor;
863 int glyph;
864
867
868 glyph = bytestream2_get_byteu(&ctx->
gb);
869 bgcolor = ctx->
codebook[bytestream2_get_byteu(&ctx->
gb)];
870 fgcolor = ctx->
codebook[bytestream2_get_byteu(&ctx->
gb)];
871
872 draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
873 }
874 return 0;
875 }
876
878 {
879 uint16_t *dst = ctx->
frm0 + cx + cy * ctx->
pitch;
880
881 if (block_size == 2) {
884
885 dst[0] = bytestream2_get_le16u(&ctx->
gb);
886 dst[1] = bytestream2_get_le16u(&ctx->
gb);
887 dst[pitch] = bytestream2_get_le16u(&ctx->
gb);
888 dst[pitch + 1] = bytestream2_get_le16u(&ctx->
gb);
889 } else {
890 uint16_t fgcolor, bgcolor;
891 int glyph;
892
895
896 glyph = bytestream2_get_byteu(&ctx->
gb);
897 bgcolor = bytestream2_get_le16u(&ctx->
gb);
898 fgcolor = bytestream2_get_le16u(&ctx->
gb);
899
900 draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
901 }
902 return 0;
903 }
904
906 int block_size)
907 {
908 int start_pos = cx + mx + (cy + my) * ctx->
pitch;
909 int end_pos = start_pos + (block_size - 1) * (ctx->
pitch + 1);
910
911 int good = start_pos >= 0 && end_pos < (ctx->
buf_size >> 1);
912
913 if (!good) {
915 cx + mx, cy + my, cx, cy, block_size);
916 }
917
918 return good;
919 }
920
922 {
923 int16_t mx, my,
index;
924 int opcode;
925
928
929 opcode = bytestream2_get_byteu(&ctx->
gb);
930
931 av_dlog(ctx->
avctx,
"opcode 0x%0X cx %d cy %d blk %d\n", opcode, cx, cy, blk_size);
932 switch (opcode) {
933 default:
936
937 if (
good_mvec(ctx, cx, cy, mx, my, blk_size)) {
939 ctx->
frm2 + cx + mx + ctx->
pitch * (cy + my),
940 blk_size, ctx->
pitch);
941 }
942 break;
943 case 0xF5:
946 index = bytestream2_get_le16u(&ctx->
gb);
947
948 mx = index % ctx->
width;
949 my = index / ctx->
width;
950
951 if (
good_mvec(ctx, cx, cy, mx, my, blk_size)) {
953 ctx->
frm2 + cx + mx + ctx->
pitch * (cy + my),
954 blk_size, ctx->
pitch);
955 }
956 break;
957 case 0xF6:
960 blk_size, ctx->
pitch);
961 break;
962 case 0xF7:
964 break;
965
966 case 0xF8:
968 break;
969 case 0xF9:
970 case 0xFA:
971 case 0xFB:
972 case 0xFC:
975 break;
976 case 0xFD:
981 break;
982 case 0xFE:
986 bytestream2_get_le16u(&ctx->
gb), blk_size, ctx->
pitch);
987 break;
988 case 0xFF:
989 if (blk_size == 2) {
991 } else {
992 blk_size >>= 1;
1001 }
1002 break;
1003 }
1004 return 0;
1005 }
1006
1008 {
1010
1015 }
1016 }
1017
1018 return 0;
1019 }
1020
1022 {
1024 return 0;
1025 }
1026
1028 {
1030 return 0;
1031 }
1032
1034 {
1035 #if HAVE_BIGENDIAN
1036 uint16_t *frm;
1037 int npixels;
1038 #endif
1040
1043
1044 #if HAVE_BIGENDIAN
1047 while (npixels--) {
1049 frm++;
1050 }
1051 #endif
1052
1053 return 0;
1054 }
1055
1057 {
1059 uint16_t *frm = ctx->
frm0;
1060
1064 }
1065 while (npixels--)
1066 *frm++ = ctx->
codebook[bytestream2_get_byteu(&ctx->
gb)];
1067
1068 return 0;
1069 }
1070
1072 {
1073 uint16_t *pdest = ctx->
frm0;
1076
1081 }
1083
1086
1087 while (npixels--)
1089
1090 return 0;
1091 }
1092
1094
1098 };
1099
1101 {
1103
1106 ret);
1108 }
1110
1111 hdr->
width = bytestream2_get_le32u(&ctx->
gb);
1112 hdr->
height = bytestream2_get_le32u(&ctx->
gb);
1113
1117 }
1118
1119 hdr->
seq_num = bytestream2_get_le16u(&ctx->
gb);
1120 hdr->
codec = bytestream2_get_byteu(&ctx->
gb);
1122
1124
1125 for (i = 0; i < 4; i++)
1127 hdr->
bg_color = bytestream2_get_le16u(&ctx->
gb);
1128
1130
1132 for (i = 0; i < 256; i++)
1133 ctx->
codebook[i] = bytestream2_get_le16u(&ctx->
gb);
1134
1136
1138 return 0;
1139 }
1140
1142 {
1143 while (buf_size--)
1145 }
1146
1148 {
1152 int srcpitch = ctx->
pitch * (hdr ?
sizeof(ctx->
frm0[0]) : 1);
1153
1155 return ret;
1156
1159
1161 memcpy(dst, src, srcpitch);
1162 src += srcpitch;
1163 dst += dstpitch;
1164 }
1165
1166 return 0;
1167 }
1168
1171 {
1174
1177
1179 int to_store = 0;
1180
1183 int pos;
1184
1185 sig = bytestream2_get_be32u(&ctx->
gb);
1186 size = bytestream2_get_be32u(&ctx->
gb);
1188
1191 break;
1192 }
1193 switch (sig) {
1194 case MKBETAG(
'N',
'P',
'A',
'L'):
1195 if (size != 256 * 3) {
1197 size);
1199 }
1200 for (i = 0; i < 256; i++)
1201 ctx->
pal[i] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->
gb);
1202 break;
1203 case MKBETAG(
'F',
'O',
'B',
'J'):
1204 if (size < 16)
1208 break;
1209 case MKBETAG(
'X',
'P',
'A',
'L'):
1210 if (size == 6 || size == 4) {
1212 int j;
1213
1214 for (i = 0; i < 256; i++) {
1215 for (j = 0; j < 3; j++) {
1216 int t = (ctx->
pal[i] >> (16 - j * 8)) & 0xFF;
1217 tmp[j] = av_clip_uint8((t * 129 + ctx->
delta_pal[i * 3 + j]) >> 7);
1218 }
1220 }
1221 } else {
1222 if (size < 768 * 2 + 4) {
1224 size);
1226 }
1228 for (i = 0; i < 768; i++)
1229 ctx->
delta_pal[i] = bytestream2_get_le16u(&ctx->
gb);
1230 if (size >= 768 * 5 + 4) {
1231 for (i = 0; i < 256; i++)
1232 ctx->
pal[i] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->
gb);
1233 } else {
1234 memset(ctx->
pal, 0,
sizeof(ctx->
pal));
1235 }
1236 }
1237 break;
1238 case MKBETAG(
'S',
'T',
'O',
'R'):
1239 to_store = 1;
1240 break;
1241 case MKBETAG(
'F',
'T',
'C',
'H'):
1243 break;
1244 default:
1247 break;
1248 }
1249
1251 if (size & 1)
1253 }
1254 if (to_store)
1259 } else {
1261
1264
1270 } else {
1272 }
1273
1277 "subcodec %d: error decoding frame\n", header.
codec);
1279 }
1280 } else {
1284 }
1285
1288 }
1291
1292 *got_frame_ptr = 1;
1293
1295 }
1296
1307 };