annotate gif.c @ 5594:384629ebcb93 libavcodec

avoid overflow in the 3rd lifting step, this now needs mmx2 at minimum (patch for plain mmx support is welcome ...)
author michael
date Sun, 26 Aug 2007 01:11:02 +0000
parents bff60ecc02f9
children 448466ff832a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4125
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
1 /*
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
2 * GIF encoder.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
3 * Copyright (c) 2000 Fabrice Bellard.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
4 * Copyright (c) 2002 Francois Revol.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
5 * Copyright (c) 2006 Baptiste Coudurier.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
6 *
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
7 * This file is part of FFmpeg.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
8 *
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
9 * FFmpeg is free software; you can redistribute it and/or
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
10 * modify it under the terms of the GNU Lesser General Public
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
11 * License as published by the Free Software Foundation; either
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
12 * version 2.1 of the License, or (at your option) any later version.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
13 *
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
14 * FFmpeg is distributed in the hope that it will be useful,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
17 * Lesser General Public License for more details.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
18 *
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
19 * You should have received a copy of the GNU Lesser General Public
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
20 * License along with FFmpeg; if not, write to the Free Software
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
22 */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
23
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
24 /*
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
25 * First version by Francois Revol revol@free.fr
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
26 *
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
27 * Features and limitations:
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
28 * - currently no compression is performed,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
29 * in fact the size of the data is 9/8 the size of the image in 8bpp
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
30 * - uses only a global standard palette
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
31 * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS).
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
32 *
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
33 * Reference documents:
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
34 * http://www.goice.co.jp/member/mo/formats/gif.html
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
35 * http://astronomy.swin.edu.au/pbourke/dataformats/gif/
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
36 * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
37 *
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
38 * this url claims to have an LZW algorithm not covered by Unisys patent:
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
39 * http://www.msg.net/utility/whirlgif/gifencod.html
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
40 * could help reduce the size of the files _a lot_...
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
41 * some sites mentions an RLE type compression also.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
42 */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
43
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
44 #include "avcodec.h"
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
45 #include "bytestream.h"
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
46 #include "bitstream.h"
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
47
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
48 /* bitstream minipacket size */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
49 #define GIF_CHUNKS 100
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
50
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
51 /* slows down the decoding (and some browsers don't like it) */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
52 /* update on the 'some browsers don't like it issue from above: this was probably due to missing 'Data Sub-block Terminator' (byte 19) in the app_header */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
53 #define GIF_ADD_APP_HEADER // required to enable looping of animated gif
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
54
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
55 typedef struct {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
56 unsigned char r;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
57 unsigned char g;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
58 unsigned char b;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
59 } rgb_triplet;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
60
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
61 /* we use the standard 216 color palette */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
62
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
63 /* this script was used to create the palette:
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
64 * for r in 00 33 66 99 cc ff; do for g in 00 33 66 99 cc ff; do echo -n " "; for b in 00 33 66 99 cc ff; do
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
65 * echo -n "{ 0x$r, 0x$g, 0x$b }, "; done; echo ""; done; done
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
66 */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
67
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
68 static const rgb_triplet gif_clut[216] = {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
69 { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x33 }, { 0x00, 0x00, 0x66 }, { 0x00, 0x00, 0x99 }, { 0x00, 0x00, 0xcc }, { 0x00, 0x00, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
70 { 0x00, 0x33, 0x00 }, { 0x00, 0x33, 0x33 }, { 0x00, 0x33, 0x66 }, { 0x00, 0x33, 0x99 }, { 0x00, 0x33, 0xcc }, { 0x00, 0x33, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
71 { 0x00, 0x66, 0x00 }, { 0x00, 0x66, 0x33 }, { 0x00, 0x66, 0x66 }, { 0x00, 0x66, 0x99 }, { 0x00, 0x66, 0xcc }, { 0x00, 0x66, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
72 { 0x00, 0x99, 0x00 }, { 0x00, 0x99, 0x33 }, { 0x00, 0x99, 0x66 }, { 0x00, 0x99, 0x99 }, { 0x00, 0x99, 0xcc }, { 0x00, 0x99, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
73 { 0x00, 0xcc, 0x00 }, { 0x00, 0xcc, 0x33 }, { 0x00, 0xcc, 0x66 }, { 0x00, 0xcc, 0x99 }, { 0x00, 0xcc, 0xcc }, { 0x00, 0xcc, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
74 { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0x33 }, { 0x00, 0xff, 0x66 }, { 0x00, 0xff, 0x99 }, { 0x00, 0xff, 0xcc }, { 0x00, 0xff, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
75 { 0x33, 0x00, 0x00 }, { 0x33, 0x00, 0x33 }, { 0x33, 0x00, 0x66 }, { 0x33, 0x00, 0x99 }, { 0x33, 0x00, 0xcc }, { 0x33, 0x00, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
76 { 0x33, 0x33, 0x00 }, { 0x33, 0x33, 0x33 }, { 0x33, 0x33, 0x66 }, { 0x33, 0x33, 0x99 }, { 0x33, 0x33, 0xcc }, { 0x33, 0x33, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
77 { 0x33, 0x66, 0x00 }, { 0x33, 0x66, 0x33 }, { 0x33, 0x66, 0x66 }, { 0x33, 0x66, 0x99 }, { 0x33, 0x66, 0xcc }, { 0x33, 0x66, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
78 { 0x33, 0x99, 0x00 }, { 0x33, 0x99, 0x33 }, { 0x33, 0x99, 0x66 }, { 0x33, 0x99, 0x99 }, { 0x33, 0x99, 0xcc }, { 0x33, 0x99, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
79 { 0x33, 0xcc, 0x00 }, { 0x33, 0xcc, 0x33 }, { 0x33, 0xcc, 0x66 }, { 0x33, 0xcc, 0x99 }, { 0x33, 0xcc, 0xcc }, { 0x33, 0xcc, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
80 { 0x33, 0xff, 0x00 }, { 0x33, 0xff, 0x33 }, { 0x33, 0xff, 0x66 }, { 0x33, 0xff, 0x99 }, { 0x33, 0xff, 0xcc }, { 0x33, 0xff, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
81 { 0x66, 0x00, 0x00 }, { 0x66, 0x00, 0x33 }, { 0x66, 0x00, 0x66 }, { 0x66, 0x00, 0x99 }, { 0x66, 0x00, 0xcc }, { 0x66, 0x00, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
82 { 0x66, 0x33, 0x00 }, { 0x66, 0x33, 0x33 }, { 0x66, 0x33, 0x66 }, { 0x66, 0x33, 0x99 }, { 0x66, 0x33, 0xcc }, { 0x66, 0x33, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
83 { 0x66, 0x66, 0x00 }, { 0x66, 0x66, 0x33 }, { 0x66, 0x66, 0x66 }, { 0x66, 0x66, 0x99 }, { 0x66, 0x66, 0xcc }, { 0x66, 0x66, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
84 { 0x66, 0x99, 0x00 }, { 0x66, 0x99, 0x33 }, { 0x66, 0x99, 0x66 }, { 0x66, 0x99, 0x99 }, { 0x66, 0x99, 0xcc }, { 0x66, 0x99, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
85 { 0x66, 0xcc, 0x00 }, { 0x66, 0xcc, 0x33 }, { 0x66, 0xcc, 0x66 }, { 0x66, 0xcc, 0x99 }, { 0x66, 0xcc, 0xcc }, { 0x66, 0xcc, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
86 { 0x66, 0xff, 0x00 }, { 0x66, 0xff, 0x33 }, { 0x66, 0xff, 0x66 }, { 0x66, 0xff, 0x99 }, { 0x66, 0xff, 0xcc }, { 0x66, 0xff, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
87 { 0x99, 0x00, 0x00 }, { 0x99, 0x00, 0x33 }, { 0x99, 0x00, 0x66 }, { 0x99, 0x00, 0x99 }, { 0x99, 0x00, 0xcc }, { 0x99, 0x00, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
88 { 0x99, 0x33, 0x00 }, { 0x99, 0x33, 0x33 }, { 0x99, 0x33, 0x66 }, { 0x99, 0x33, 0x99 }, { 0x99, 0x33, 0xcc }, { 0x99, 0x33, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
89 { 0x99, 0x66, 0x00 }, { 0x99, 0x66, 0x33 }, { 0x99, 0x66, 0x66 }, { 0x99, 0x66, 0x99 }, { 0x99, 0x66, 0xcc }, { 0x99, 0x66, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
90 { 0x99, 0x99, 0x00 }, { 0x99, 0x99, 0x33 }, { 0x99, 0x99, 0x66 }, { 0x99, 0x99, 0x99 }, { 0x99, 0x99, 0xcc }, { 0x99, 0x99, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
91 { 0x99, 0xcc, 0x00 }, { 0x99, 0xcc, 0x33 }, { 0x99, 0xcc, 0x66 }, { 0x99, 0xcc, 0x99 }, { 0x99, 0xcc, 0xcc }, { 0x99, 0xcc, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
92 { 0x99, 0xff, 0x00 }, { 0x99, 0xff, 0x33 }, { 0x99, 0xff, 0x66 }, { 0x99, 0xff, 0x99 }, { 0x99, 0xff, 0xcc }, { 0x99, 0xff, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
93 { 0xcc, 0x00, 0x00 }, { 0xcc, 0x00, 0x33 }, { 0xcc, 0x00, 0x66 }, { 0xcc, 0x00, 0x99 }, { 0xcc, 0x00, 0xcc }, { 0xcc, 0x00, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
94 { 0xcc, 0x33, 0x00 }, { 0xcc, 0x33, 0x33 }, { 0xcc, 0x33, 0x66 }, { 0xcc, 0x33, 0x99 }, { 0xcc, 0x33, 0xcc }, { 0xcc, 0x33, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
95 { 0xcc, 0x66, 0x00 }, { 0xcc, 0x66, 0x33 }, { 0xcc, 0x66, 0x66 }, { 0xcc, 0x66, 0x99 }, { 0xcc, 0x66, 0xcc }, { 0xcc, 0x66, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
96 { 0xcc, 0x99, 0x00 }, { 0xcc, 0x99, 0x33 }, { 0xcc, 0x99, 0x66 }, { 0xcc, 0x99, 0x99 }, { 0xcc, 0x99, 0xcc }, { 0xcc, 0x99, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
97 { 0xcc, 0xcc, 0x00 }, { 0xcc, 0xcc, 0x33 }, { 0xcc, 0xcc, 0x66 }, { 0xcc, 0xcc, 0x99 }, { 0xcc, 0xcc, 0xcc }, { 0xcc, 0xcc, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
98 { 0xcc, 0xff, 0x00 }, { 0xcc, 0xff, 0x33 }, { 0xcc, 0xff, 0x66 }, { 0xcc, 0xff, 0x99 }, { 0xcc, 0xff, 0xcc }, { 0xcc, 0xff, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
99 { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0x33 }, { 0xff, 0x00, 0x66 }, { 0xff, 0x00, 0x99 }, { 0xff, 0x00, 0xcc }, { 0xff, 0x00, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
100 { 0xff, 0x33, 0x00 }, { 0xff, 0x33, 0x33 }, { 0xff, 0x33, 0x66 }, { 0xff, 0x33, 0x99 }, { 0xff, 0x33, 0xcc }, { 0xff, 0x33, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
101 { 0xff, 0x66, 0x00 }, { 0xff, 0x66, 0x33 }, { 0xff, 0x66, 0x66 }, { 0xff, 0x66, 0x99 }, { 0xff, 0x66, 0xcc }, { 0xff, 0x66, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
102 { 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
103 { 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
104 { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff },
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
105 };
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
106
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
107 /* The GIF format uses reversed order for bitstreams... */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
108 /* at least they don't use PDP_ENDIAN :) */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
109 /* so we 'extend' PutBitContext. hmmm, OOP :) */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
110 /* seems this thing changed slightly since I wrote it... */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
111
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
112 #ifdef ALT_BITSTREAM_WRITER
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
113 # error no ALT_BITSTREAM_WRITER support for now
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
114 #endif
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
115
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
116 static void gif_put_bits_rev(PutBitContext *s, int n, unsigned int value)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
117 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
118 unsigned int bit_buf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
119 int bit_cnt;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
120
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
121 // printf("put_bits=%d %x\n", n, value);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
122 assert(n == 32 || value < (1U << n));
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
123
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
124 bit_buf = s->bit_buf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
125 bit_cnt = 32 - s->bit_left; /* XXX:lazyness... was = s->bit_cnt; */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
126
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
127 // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
128 /* XXX: optimize */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
129 if (n < (32-bit_cnt)) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
130 bit_buf |= value << (bit_cnt);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
131 bit_cnt+=n;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
132 } else {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
133 bit_buf |= value << (bit_cnt);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
134
5089
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 4125
diff changeset
135 bytestream_put_le32(&s->buf_ptr, bit_buf);
4125
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
136
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
137 //printf("bitbuf = %08x\n", bit_buf);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
138 if (s->buf_ptr >= s->buf_end)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
139 puts("bit buffer overflow !!"); // should never happen ! who got rid of the callback ???
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
140 // flush_buffer_rev(s);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
141 bit_cnt=bit_cnt + n - 32;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
142 if (bit_cnt == 0) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
143 bit_buf = 0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
144 } else {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
145 bit_buf = value >> (n - bit_cnt);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
146 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
147 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
148
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
149 s->bit_buf = bit_buf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
150 s->bit_left = 32 - bit_cnt;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
151 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
152
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
153 /* pad the end of the output stream with zeros */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
154 static void gif_flush_put_bits_rev(PutBitContext *s)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
155 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
156 while (s->bit_left < 32) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
157 /* XXX: should test end of buffer */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
158 *s->buf_ptr++=s->bit_buf & 0xff;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
159 s->bit_buf>>=8;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
160 s->bit_left+=8;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
161 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
162 // flush_buffer_rev(s);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
163 s->bit_left=32;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
164 s->bit_buf=0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
165 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
166
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
167 /* !RevPutBitContext */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
168
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
169 /* GIF header */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
170 static int gif_image_write_header(uint8_t **bytestream,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
171 int width, int height, int loop_count,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
172 uint32_t *palette)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
173 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
174 int i;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
175 unsigned int v;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
176
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
177 bytestream_put_buffer(bytestream, "GIF", 3);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
178 bytestream_put_buffer(bytestream, "89a", 3);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
179 bytestream_put_le16(bytestream, width);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
180 bytestream_put_le16(bytestream, height);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
181
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
182 bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
183 bytestream_put_byte(bytestream, 0x1f); /* background color index */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
184 bytestream_put_byte(bytestream, 0); /* aspect ratio */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
185
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
186 /* the global palette */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
187 if (!palette) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
188 bytestream_put_buffer(bytestream, (const unsigned char *)gif_clut, 216*3);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
189 for(i=0;i<((256-216)*3);i++)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
190 bytestream_put_byte(bytestream, 0);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
191 } else {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
192 for(i=0;i<256;i++) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
193 v = palette[i];
5089
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 4125
diff changeset
194 bytestream_put_be24(bytestream, v);
4125
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
195 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
196 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
197
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
198 /* update: this is the 'NETSCAPE EXTENSION' that allows for looped animated gif
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
199 see http://members.aol.com/royalef/gifabout.htm#net-extension
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
200
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
201 byte 1 : 33 (hex 0x21) GIF Extension code
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
202 byte 2 : 255 (hex 0xFF) Application Extension Label
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
203 byte 3 : 11 (hex (0x0B) Length of Application Block
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
204 (eleven bytes of data to follow)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
205 bytes 4 to 11 : "NETSCAPE"
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
206 bytes 12 to 14 : "2.0"
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
207 byte 15 : 3 (hex 0x03) Length of Data Sub-Block
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
208 (three bytes of data to follow)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
209 byte 16 : 1 (hex 0x01)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
210 bytes 17 to 18 : 0 to 65535, an unsigned integer in
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
211 lo-hi byte format. This indicate the
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
212 number of iterations the loop should
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
213 be executed.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
214 bytes 19 : 0 (hex 0x00) a Data Sub-block Terminator
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
215 */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
216
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
217 /* application extension header */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
218 #ifdef GIF_ADD_APP_HEADER
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
219 if (loop_count >= 0 && loop_count <= 65535) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
220 bytestream_put_byte(bytestream, 0x21);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
221 bytestream_put_byte(bytestream, 0xff);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
222 bytestream_put_byte(bytestream, 0x0b);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
223 bytestream_put_buffer(bytestream, "NETSCAPE2.0", 11); // bytes 4 to 14
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
224 bytestream_put_byte(bytestream, 0x03); // byte 15
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
225 bytestream_put_byte(bytestream, 0x01); // byte 16
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
226 bytestream_put_le16(bytestream, (uint16_t)loop_count);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
227 bytestream_put_byte(bytestream, 0x00); // byte 19
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
228 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
229 #endif
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
230 return 0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
231 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
232
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
233 /* this is maybe slow, but allows for extensions */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
234 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
235 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
236 return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
237 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
238
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
239
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
240 static int gif_image_write_image(uint8_t **bytestream,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
241 int x1, int y1, int width, int height,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
242 const uint8_t *buf, int linesize, int pix_fmt)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
243 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
244 PutBitContext p;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
245 uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
246 int i, left, w, v;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
247 const uint8_t *ptr;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
248 /* image block */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
249
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
250 bytestream_put_byte(bytestream, 0x2c);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
251 bytestream_put_le16(bytestream, x1);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
252 bytestream_put_le16(bytestream, y1);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
253 bytestream_put_le16(bytestream, width);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
254 bytestream_put_le16(bytestream, height);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
255 bytestream_put_byte(bytestream, 0x00); /* flags */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
256 /* no local clut */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
257
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
258 bytestream_put_byte(bytestream, 0x08);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
259
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
260 left= width * height;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
261
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
262 init_put_bits(&p, buffer, 130);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
263
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
264 /*
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
265 * the thing here is the bitstream is written as little packets, with a size byte before
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
266 * but it's still the same bitstream between packets (no flush !)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
267 */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
268 ptr = buf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
269 w = width;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
270 while(left>0) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
271
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
272 gif_put_bits_rev(&p, 9, 0x0100); /* clear code */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
273
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
274 for(i=(left<GIF_CHUNKS)?left:GIF_CHUNKS;i;i--) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
275 if (pix_fmt == PIX_FMT_RGB24) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
276 v = gif_clut_index(ptr[0], ptr[1], ptr[2]);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
277 ptr+=3;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
278 } else {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
279 v = *ptr++;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
280 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
281 gif_put_bits_rev(&p, 9, v);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
282 if (--w == 0) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
283 w = width;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
284 buf += linesize;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
285 ptr = buf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
286 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
287 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
288
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
289 if(left<=GIF_CHUNKS) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
290 gif_put_bits_rev(&p, 9, 0x101); /* end of stream */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
291 gif_flush_put_bits_rev(&p);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
292 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
293 if(pbBufPtr(&p) - p.buf > 0) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
294 bytestream_put_byte(bytestream, pbBufPtr(&p) - p.buf); /* byte count of the packet */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
295 bytestream_put_buffer(bytestream, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
296 p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
297 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
298 left-=GIF_CHUNKS;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
299 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
300 bytestream_put_byte(bytestream, 0x00); /* end of image block */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
301 bytestream_put_byte(bytestream, 0x3b);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
302 return 0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
303 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
304
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
305 typedef struct {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
306 int64_t time, file_time;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
307 uint8_t buffer[100]; /* data chunks */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
308 AVFrame picture;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
309 } GIFContext;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
310
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
311 static int gif_encode_init(AVCodecContext *avctx)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
312 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
313 GIFContext *s = avctx->priv_data;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
314
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
315 avctx->coded_frame = &s->picture;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
316 return 0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
317 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
318
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
319 /* better than nothing gif encoder */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
320 static int gif_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
321 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
322 GIFContext *s = avctx->priv_data;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
323 AVFrame *pict = data;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
324 AVFrame *const p = (AVFrame *)&s->picture;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
325 uint8_t *outbuf_ptr = outbuf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
326
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
327 *p = *pict;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
328 p->pict_type = FF_I_TYPE;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
329 p->key_frame = 1;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
330 gif_image_write_header(&outbuf_ptr, avctx->width, avctx->height, -1, (uint32_t *)pict->data[1]);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
331 gif_image_write_image(&outbuf_ptr, 0, 0, avctx->width, avctx->height, pict->data[0], pict->linesize[0], PIX_FMT_PAL8);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
332 return outbuf_ptr - outbuf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
333 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
334
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
335 AVCodec gif_encoder = {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
336 "gif",
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
337 CODEC_TYPE_VIDEO,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
338 CODEC_ID_GIF,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
339 sizeof(GIFContext),
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
340 gif_encode_init,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
341 gif_encode_frame,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
342 NULL, //encode_end,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
343 .pix_fmts= (enum PixelFormat[]){PIX_FMT_PAL8, -1},
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
344 };