@ -57,6 +57,67 @@ typedef struct LJpegEncContext {
uint16_t ( * scratch ) [ 4 ] ;
} LJpegEncContext ;
static int ljpeg_encode_bgr ( AVCodecContext * avctx , PutBitContext * pb ,
const AVFrame * frame )
{
LJpegEncContext * s = avctx - > priv_data ;
const int width = frame - > width ;
const int height = frame - > height ;
const int linesize = frame - > linesize [ 0 ] ;
uint16_t ( * buffer ) [ 4 ] = s - > scratch ;
const int predictor = avctx - > prediction_method + 1 ;
int left [ 3 ] , top [ 3 ] , topleft [ 3 ] ;
int x , y , i ;
for ( i = 0 ; i < 3 ; i + + )
buffer [ 0 ] [ i ] = 1 < < ( 9 - 1 ) ;
for ( y = 0 ; y < height ; y + + ) {
const int modified_predictor = y ? predictor : 1 ;
uint8_t * ptr = frame - > data [ 0 ] + ( linesize * y ) ;
if ( pb - > buf_end - pb - > buf - ( put_bits_count ( pb ) > > 3 ) < width * 3 * 4 ) {
av_log ( avctx , AV_LOG_ERROR , " encoded frame too large \n " ) ;
return - 1 ;
}
for ( i = 0 ; i < 3 ; i + + )
top [ i ] = left [ i ] = topleft [ i ] = buffer [ 0 ] [ i ] ;
for ( x = 0 ; x < width ; x + + ) {
if ( avctx - > pix_fmt = = AV_PIX_FMT_BGR24 ) {
buffer [ x ] [ 1 ] = ptr [ 3 * x + 0 ] - ptr [ 3 * x + 1 ] + 0x100 ;
buffer [ x ] [ 2 ] = ptr [ 3 * x + 2 ] - ptr [ 3 * x + 1 ] + 0x100 ;
buffer [ x ] [ 0 ] = ( ptr [ 3 * x + 0 ] + 2 * ptr [ 3 * x + 1 ] + ptr [ 3 * x + 2 ] ) > > 2 ;
} else {
buffer [ x ] [ 1 ] = ptr [ 4 * x + 0 ] - ptr [ 4 * x + 1 ] + 0x100 ;
buffer [ x ] [ 2 ] = ptr [ 4 * x + 2 ] - ptr [ 4 * x + 1 ] + 0x100 ;
buffer [ x ] [ 0 ] = ( ptr [ 4 * x + 0 ] + 2 * ptr [ 4 * x + 1 ] + ptr [ 4 * x + 2 ] ) > > 2 ;
}
for ( i = 0 ; i < 3 ; i + + ) {
int pred , diff ;
PREDICT ( pred , topleft [ i ] , top [ i ] , left [ i ] , modified_predictor ) ;
topleft [ i ] = top [ i ] ;
top [ i ] = buffer [ x + 1 ] [ i ] ;
left [ i ] = buffer [ x ] [ i ] ;
diff = ( ( left [ i ] - pred + 0x100 ) & 0x1FF ) - 0x100 ;
if ( i = = 0 )
ff_mjpeg_encode_dc ( pb , diff , s - > huff_size_dc_luminance , s - > huff_code_dc_luminance ) ; //FIXME ugly
else
ff_mjpeg_encode_dc ( pb , diff , s - > huff_size_dc_chrominance , s - > huff_code_dc_chrominance ) ;
}
}
}
return 0 ;
}
static int ljpeg_encode_frame ( AVCodecContext * avctx , AVPacket * pkt ,
const AVFrame * pict , int * got_packet )
{
@ -92,57 +153,9 @@ static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if ( avctx - > pix_fmt = = AV_PIX_FMT_BGR0
| | avctx - > pix_fmt = = AV_PIX_FMT_BGRA
| | avctx - > pix_fmt = = AV_PIX_FMT_BGR24 ) {
int x , y , i ;
const int linesize = pict - > linesize [ 0 ] ;
uint16_t ( * buffer ) [ 4 ] = s - > scratch ;
int left [ 3 ] , top [ 3 ] , topleft [ 3 ] ;
for ( i = 0 ; i < 3 ; i + + ) {
buffer [ 0 ] [ i ] = 1 < < ( 9 - 1 ) ;
}
for ( y = 0 ; y < height ; y + + ) {
const int modified_predictor = y ? predictor : 1 ;
uint8_t * ptr = pict - > data [ 0 ] + ( linesize * y ) ;
if ( pb . buf_end - pb . buf - ( put_bits_count ( & pb ) > > 3 ) < width * 3 * 4 ) {
av_log ( avctx , AV_LOG_ERROR , " encoded frame too large \n " ) ;
return - 1 ;
}
for ( i = 0 ; i < 3 ; i + + ) {
top [ i ] = left [ i ] = topleft [ i ] = buffer [ 0 ] [ i ] ;
}
for ( x = 0 ; x < width ; x + + ) {
if ( avctx - > pix_fmt = = AV_PIX_FMT_BGR24 ) {
buffer [ x ] [ 1 ] = ptr [ 3 * x + 0 ] - ptr [ 3 * x + 1 ] + 0x100 ;
buffer [ x ] [ 2 ] = ptr [ 3 * x + 2 ] - ptr [ 3 * x + 1 ] + 0x100 ;
buffer [ x ] [ 0 ] = ( ptr [ 3 * x + 0 ] + 2 * ptr [ 3 * x + 1 ] + ptr [ 3 * x + 2 ] ) > > 2 ;
} else {
buffer [ x ] [ 1 ] = ptr [ 4 * x + 0 ] - ptr [ 4 * x + 1 ] + 0x100 ;
buffer [ x ] [ 2 ] = ptr [ 4 * x + 2 ] - ptr [ 4 * x + 1 ] + 0x100 ;
buffer [ x ] [ 0 ] = ( ptr [ 4 * x + 0 ] + 2 * ptr [ 4 * x + 1 ] + ptr [ 4 * x + 2 ] ) > > 2 ;
}
for ( i = 0 ; i < 3 ; i + + ) {
int pred , diff ;
PREDICT ( pred , topleft [ i ] , top [ i ] , left [ i ] , modified_predictor ) ;
topleft [ i ] = top [ i ] ;
top [ i ] = buffer [ x + 1 ] [ i ] ;
left [ i ] = buffer [ x ] [ i ] ;
diff = ( ( left [ i ] - pred + 0x100 ) & 0x1FF ) - 0x100 ;
if ( i = = 0 )
ff_mjpeg_encode_dc ( & pb , diff , s - > huff_size_dc_luminance , s - > huff_code_dc_luminance ) ; //FIXME ugly
else
ff_mjpeg_encode_dc ( & pb , diff , s - > huff_size_dc_chrominance , s - > huff_code_dc_chrominance ) ;
}
}
}
ret = ljpeg_encode_bgr ( avctx , & pb , pict ) ;
if ( ret < 0 )
return ret ;
} else {
int mb_x , mb_y , i ;