@ -53,7 +53,9 @@
# define GIF_CHUNKS 100
/* slows down the decoding (and some browsers don't like it) */
/* 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 */
/* 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 */
# define GIF_ADD_APP_HEADER // required to enable looping of animated gif
typedef struct {
@ -65,8 +67,15 @@ typedef struct {
/* we use the standard 216 color palette */
/* this script was used to create the palette:
* 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
* echo - n " { 0x$r, 0x$g, 0x$b }, " ; done ; echo " " ; done ; done
* 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
* echo - n " { 0x$r, 0x$g, 0x$b }, "
* done
* echo " "
* done
* done
*/
static const rgb_triplet gif_clut [ 216 ] = {
@ -109,9 +118,8 @@ static const rgb_triplet gif_clut[216] = {
} ;
/* GIF header */
static int gif_image_write_header ( AVIOContext * pb ,
int width , int height , int loop_count ,
uint32_t * palette )
static int gif_image_write_header ( AVIOContext * pb , int width , int height ,
int loop_count , uint32_t * palette )
{
int i ;
unsigned int v ;
@ -139,23 +147,23 @@ static int gif_image_write_header(AVIOContext *pb,
}
}
/* update: this is the 'NETSCAPE EXTENSION' that allows for looped animated gif
see http : //members.aol.com/royalef/gifabout.htm#net-extension
byte 1 : 33 ( hex 0x21 ) GIF Extension code
byte 2 : 255 ( hex 0xFF ) Application Extension Label
byte 3 : 11 ( hex ( 0x0B ) Length of Application Block
( eleven bytes of data to follow )
bytes 4 to 11 : " NETSCAPE "
bytes 12 to 14 : " 2.0 "
byte 15 : 3 ( hex 0x03 ) Length of Data Sub - Block
( three bytes of data to follow )
byte 16 : 1 ( hex 0x01 )
bytes 17 to 18 : 0 to 65535 , an unsigned integer in
lo - hi byte format . This indicate the
number of iterations the loop should
be executed .
bytes 19 : 0 ( hex 0x00 ) a Data Sub - block Terminator
/* update: this is the 'NETSCAPE EXTENSION' that allows for looped animated
* GIF , see http : //members.aol.com/royalef/gifabout.htm#net-extension
*
* byte 1 : 33 ( hex 0x21 ) GIF Extension code
* byte 2 : 255 ( hex 0xFF ) Application Extension Label
* byte 3 : 11 ( hex ( 0x0B ) Length of Application Block
* ( eleven bytes of data to follow )
* bytes 4 to 11 : " NETSCAPE "
* bytes 12 to 14 : " 2.0 "
* byte 15 : 3 ( hex 0x03 ) Length of Data Sub - Block
* ( three bytes of data to follow )
* byte 16 : 1 ( hex 0x01 )
* bytes 17 to 18 : 0 to 65535 , an unsigned integer in
* lo - hi byte format . This indicate the
* number of iterations the loop should
* be executed .
* bytes 19 : 0 ( hex 0x00 ) a Data Sub - block Terminator
*/
/* application extension header */
@ -164,7 +172,8 @@ static int gif_image_write_header(AVIOContext *pb,
avio_w8 ( pb , 0x21 ) ;
avio_w8 ( pb , 0xff ) ;
avio_w8 ( pb , 0x0b ) ;
avio_write ( pb , " NETSCAPE2.0 " , sizeof ( " NETSCAPE2.0 " ) - 1 ) ; // bytes 4 to 14
// bytes 4 to 14
avio_write ( pb , " NETSCAPE2.0 " , sizeof ( " NETSCAPE2.0 " ) - 1 ) ;
avio_w8 ( pb , 0x03 ) ; // byte 15
avio_w8 ( pb , 0x01 ) ; // byte 16
avio_wl16 ( pb , ( uint16_t ) loop_count ) ;
@ -180,7 +189,6 @@ static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
return ( ( ( r ) / 47 ) % 6 ) * 6 * 6 + ( ( ( g ) / 47 ) % 6 ) * 6 + ( ( ( b ) / 47 ) % 6 ) ;
}
static int gif_image_write_image ( AVIOContext * pb ,
int x1 , int y1 , int width , int height ,
const uint8_t * buf , int linesize , int pix_fmt )
@ -206,13 +214,12 @@ static int gif_image_write_image(AVIOContext *pb,
init_put_bits ( & p , buffer , 130 ) ;
/*
* the thing here is the bitstream is written as little packets , with a size byte before
* but it ' s still the same bitstream between packets ( no flush ! )
* the thing here is the bitstream is written as little packets , with a size
* byte before b ut it ' s still the same bitstream between packets ( no flush ! )
*/
ptr = buf ;
w = width ;
while ( left > 0 ) {
put_bits ( & p , 9 , 0x0100 ) ; /* clear code */
for ( i = ( left < GIF_CHUNKS ) ? left : GIF_CHUNKS ; i ; i - - ) {
@ -261,8 +268,8 @@ static int gif_write_header(AVFormatContext *s)
int i , width , height /*, rate*/ ;
/* XXX: do we reject audio streams or just ignore them ?
if ( s - > nb_streams > 1 )
return - 1 ;
* if ( s - > nb_streams > 1 )
* return - 1 ;
*/
gif - > time = 0 ;
gif - > file_time = 0 ;
@ -284,7 +291,8 @@ static int gif_write_header(AVFormatContext *s)
}
if ( video_enc - > pix_fmt ! = PIX_FMT_RGB24 ) {
av_log ( s , AV_LOG_ERROR , " ERROR: gif only handles the rgb24 pixel format. Use -pix_fmt rgb24. \n " ) ;
av_log ( s , AV_LOG_ERROR ,
" ERROR: gif only handles the rgb24 pixel format. Use -pix_fmt rgb24. \n " ) ;
return AVERROR ( EIO ) ;
}
@ -294,8 +302,8 @@ static int gif_write_header(AVFormatContext *s)
return 0 ;
}
static int gif_write_video ( AVFormatContext * s ,
AVCodecContext * enc , const uint8_t * buf , int size )
static int gif_write_video ( AVFormatContext * s , AVCodecContext * enc ,
const uint8_t * buf , int size )
{
AVIOContext * pb = s - > pb ;
int jiffies ;
@ -346,7 +354,8 @@ static int gif_write_trailer(AVFormatContext *s)
# define OFFSET(x) offsetof(GIFContext, x)
# define ENC AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options [ ] = {
{ " loop " , " Number of times to loop the output. " , OFFSET ( loop ) , AV_OPT_TYPE_INT , { 0 } , 0 , 65535 , ENC } ,
{ " loop " , " Number of times to loop the output. " , OFFSET ( loop ) ,
AV_OPT_TYPE_INT , { 0 } , 0 , 65535 , ENC } ,
{ NULL } ,
} ;