annotate gif.c @ 4765:85298e8c55c4 libavcodec

bfin dsputils, basic pixel operations sads, diffs, motion compensation and standard IEEE 8x8 block transforms patch by Marc Hoffman, mmh pleasantst com
author diego
date Sun, 01 Apr 2007 22:28:45 +0000
parents f6f67a8bdd09
children bff60ecc02f9
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
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
135 *s->buf_ptr = bit_buf & 0xff;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
136 s->buf_ptr[1] = (bit_buf >> 8) & 0xff;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
137 s->buf_ptr[2] = (bit_buf >> 16) & 0xff;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
138 s->buf_ptr[3] = (bit_buf >> 24) & 0xff;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
139
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
140 //printf("bitbuf = %08x\n", bit_buf);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
141 s->buf_ptr+=4;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
142 if (s->buf_ptr >= s->buf_end)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
143 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
144 // flush_buffer_rev(s);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
145 bit_cnt=bit_cnt + n - 32;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
146 if (bit_cnt == 0) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
147 bit_buf = 0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
148 } else {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
149 bit_buf = value >> (n - bit_cnt);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
150 }
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 s->bit_buf = bit_buf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
154 s->bit_left = 32 - bit_cnt;
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
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
157 /* pad the end of the output stream with zeros */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
158 static void gif_flush_put_bits_rev(PutBitContext *s)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
159 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
160 while (s->bit_left < 32) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
161 /* XXX: should test end of buffer */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
162 *s->buf_ptr++=s->bit_buf & 0xff;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
163 s->bit_buf>>=8;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
164 s->bit_left+=8;
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 // flush_buffer_rev(s);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
167 s->bit_left=32;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
168 s->bit_buf=0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
169 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
170
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
171 /* !RevPutBitContext */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
172
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
173 /* GIF header */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
174 static int gif_image_write_header(uint8_t **bytestream,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
175 int width, int height, int loop_count,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
176 uint32_t *palette)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
177 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
178 int i;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
179 unsigned int v;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
180
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
181 bytestream_put_buffer(bytestream, "GIF", 3);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
182 bytestream_put_buffer(bytestream, "89a", 3);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
183 bytestream_put_le16(bytestream, width);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
184 bytestream_put_le16(bytestream, height);
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 bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
187 bytestream_put_byte(bytestream, 0x1f); /* background color index */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
188 bytestream_put_byte(bytestream, 0); /* aspect ratio */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
189
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
190 /* the global palette */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
191 if (!palette) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
192 bytestream_put_buffer(bytestream, (const unsigned char *)gif_clut, 216*3);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
193 for(i=0;i<((256-216)*3);i++)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
194 bytestream_put_byte(bytestream, 0);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
195 } else {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
196 for(i=0;i<256;i++) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
197 v = palette[i];
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
198 bytestream_put_byte(bytestream, (v >> 16) & 0xff);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
199 bytestream_put_byte(bytestream, (v >> 8) & 0xff);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
200 bytestream_put_byte(bytestream, (v) & 0xff);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
201 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
202 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
203
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
204 /* update: this is the 'NETSCAPE EXTENSION' that allows for looped animated gif
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
205 see http://members.aol.com/royalef/gifabout.htm#net-extension
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
206
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
207 byte 1 : 33 (hex 0x21) GIF Extension code
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
208 byte 2 : 255 (hex 0xFF) Application Extension Label
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
209 byte 3 : 11 (hex (0x0B) Length of Application Block
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
210 (eleven bytes of data to follow)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
211 bytes 4 to 11 : "NETSCAPE"
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
212 bytes 12 to 14 : "2.0"
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
213 byte 15 : 3 (hex 0x03) Length of Data Sub-Block
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
214 (three bytes of data to follow)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
215 byte 16 : 1 (hex 0x01)
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
216 bytes 17 to 18 : 0 to 65535, an unsigned integer in
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
217 lo-hi byte format. This indicate the
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
218 number of iterations the loop should
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
219 be executed.
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
220 bytes 19 : 0 (hex 0x00) a Data Sub-block Terminator
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
221 */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
222
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
223 /* application extension header */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
224 #ifdef GIF_ADD_APP_HEADER
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
225 if (loop_count >= 0 && loop_count <= 65535) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
226 bytestream_put_byte(bytestream, 0x21);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
227 bytestream_put_byte(bytestream, 0xff);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
228 bytestream_put_byte(bytestream, 0x0b);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
229 bytestream_put_buffer(bytestream, "NETSCAPE2.0", 11); // bytes 4 to 14
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
230 bytestream_put_byte(bytestream, 0x03); // byte 15
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
231 bytestream_put_byte(bytestream, 0x01); // byte 16
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
232 bytestream_put_le16(bytestream, (uint16_t)loop_count);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
233 bytestream_put_byte(bytestream, 0x00); // byte 19
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
234 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
235 #endif
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
236 return 0;
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 /* this is maybe slow, but allows for extensions */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
240 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
241 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
242 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
243 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
244
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
245
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
246 static int gif_image_write_image(uint8_t **bytestream,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
247 int x1, int y1, int width, int height,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
248 const uint8_t *buf, int linesize, int pix_fmt)
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 PutBitContext p;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
251 uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
252 int i, left, w, v;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
253 const uint8_t *ptr;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
254 /* image block */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
255
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
256 bytestream_put_byte(bytestream, 0x2c);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
257 bytestream_put_le16(bytestream, x1);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
258 bytestream_put_le16(bytestream, y1);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
259 bytestream_put_le16(bytestream, width);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
260 bytestream_put_le16(bytestream, height);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
261 bytestream_put_byte(bytestream, 0x00); /* flags */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
262 /* no local clut */
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 bytestream_put_byte(bytestream, 0x08);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
265
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
266 left= width * height;
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 init_put_bits(&p, buffer, 130);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
269
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
270 /*
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
271 * 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
272 * but it's still the same bitstream between packets (no flush !)
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 ptr = buf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
275 w = width;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
276 while(left>0) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
277
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
278 gif_put_bits_rev(&p, 9, 0x0100); /* clear code */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
279
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
280 for(i=(left<GIF_CHUNKS)?left:GIF_CHUNKS;i;i--) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
281 if (pix_fmt == PIX_FMT_RGB24) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
282 v = gif_clut_index(ptr[0], ptr[1], ptr[2]);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
283 ptr+=3;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
284 } else {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
285 v = *ptr++;
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 gif_put_bits_rev(&p, 9, v);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
288 if (--w == 0) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
289 w = width;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
290 buf += linesize;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
291 ptr = buf;
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 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
294
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
295 if(left<=GIF_CHUNKS) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
296 gif_put_bits_rev(&p, 9, 0x101); /* end of stream */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
297 gif_flush_put_bits_rev(&p);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
298 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
299 if(pbBufPtr(&p) - p.buf > 0) {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
300 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
301 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
302 p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */
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 left-=GIF_CHUNKS;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
305 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
306 bytestream_put_byte(bytestream, 0x00); /* end of image block */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
307 bytestream_put_byte(bytestream, 0x3b);
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
308 return 0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
309 }
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 typedef struct {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
312 int64_t time, file_time;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
313 uint8_t buffer[100]; /* data chunks */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
314 AVFrame picture;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
315 } GIFContext;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
316
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
317 static int gif_encode_init(AVCodecContext *avctx)
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 GIFContext *s = avctx->priv_data;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
320
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
321 avctx->coded_frame = &s->picture;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
322 return 0;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
323 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
324
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
325 /* better than nothing gif encoder */
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
326 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
327 {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
328 GIFContext *s = avctx->priv_data;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
329 AVFrame *pict = data;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
330 AVFrame *const p = (AVFrame *)&s->picture;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
331 uint8_t *outbuf_ptr = outbuf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
332
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
333 *p = *pict;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
334 p->pict_type = FF_I_TYPE;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
335 p->key_frame = 1;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
336 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
337 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
338 return outbuf_ptr - outbuf;
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
339 }
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
340
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
341 AVCodec gif_encoder = {
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
342 "gif",
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
343 CODEC_TYPE_VIDEO,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
344 CODEC_ID_GIF,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
345 sizeof(GIFContext),
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
346 gif_encode_init,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
347 gif_encode_frame,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
348 NULL, //encode_end,
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
349 .pix_fmts= (enum PixelFormat[]){PIX_FMT_PAL8, -1},
f6f67a8bdd09 change gif muxer to simple gif encoder
bcoudurier
parents:
diff changeset
350 };