mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-16 12:24:52 +00:00
cleanup
pegasus "pseudo yuv" (=RCT) lossless decoding support bigendian fix? Originally committed as revision 1963 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
1433e6c499
commit
63efe9a7e6
@ -281,19 +281,16 @@ void mjpeg_close(MpegEncContext *s)
|
||||
av_free(s->mjpeg_ctx);
|
||||
}
|
||||
|
||||
static inline int predict(uint8_t *ptr, int stride, int predictor, int size){
|
||||
switch(predictor){
|
||||
case 0: return ptr[0];
|
||||
case 1: return ptr[-size];
|
||||
case 2: return ptr[-stride];
|
||||
case 3: return ptr[-stride-size];
|
||||
case 4: return ptr[-size] + ptr[-stride] - ptr[-stride-size];
|
||||
case 5: return ptr[-size] + ((ptr[-stride] - ptr[-stride-size])>>1);
|
||||
case 6: return ptr[-stride] + ((ptr[-size] - ptr[-stride-size])>>1);
|
||||
case 7: return (ptr[-size] + ptr[-stride])>>1;
|
||||
default: return 0xFFFF;
|
||||
#define PREDICT(ret, topleft, top, left, predictor)\
|
||||
switch(predictor){\
|
||||
case 1: ret= left; break;\
|
||||
case 2: ret= top; break;\
|
||||
case 3: ret= topleft; break;\
|
||||
case 4: ret= left + top - topleft; break;\
|
||||
case 5: ret= left + ((top - topleft)>>1); break;\
|
||||
case 6: ret= top + ((left - topleft)>>1); break;\
|
||||
case 7: ret= (left + top)>>1; break;\
|
||||
}
|
||||
}
|
||||
|
||||
static inline void put_marker(PutBitContext *p, int code)
|
||||
{
|
||||
@ -671,6 +668,8 @@ typedef struct MJpegDecodeContext {
|
||||
int bottom_field; /* true if bottom field */
|
||||
int lossless;
|
||||
int rgb;
|
||||
int rct; /* pegasus reversible colorspace transform */
|
||||
int bits; /* bits per component */
|
||||
|
||||
int width, height;
|
||||
int nb_components;
|
||||
@ -834,7 +833,10 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
|
||||
|
||||
/* XXX: verify len field validity */
|
||||
len = get_bits(&s->gb, 16);
|
||||
if (get_bits(&s->gb, 8) != 8){
|
||||
s->bits= get_bits(&s->gb, 8);
|
||||
if(s->rct) s->bits=9;
|
||||
|
||||
if (s->bits != 8 && !s->lossless){
|
||||
printf("only 8 bits/component accepted\n");
|
||||
return -1;
|
||||
}
|
||||
@ -865,6 +867,8 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
|
||||
dprintf("component %d %d:%d id: %d quant:%d\n", i, s->h_count[i],
|
||||
s->v_count[i], s->component_id[i], s->quant_index[i]);
|
||||
}
|
||||
|
||||
if(s->v_max==1 && s->h_max==1 && s->lossless==1) s->rgb=1;
|
||||
|
||||
/* if different size, realloc/alloc picture */
|
||||
/* XXX: also check h_count and v_count */
|
||||
@ -882,7 +886,6 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
|
||||
s->bottom_field = 0;
|
||||
}
|
||||
|
||||
assert(s->rgb==0 || (s->h_max==1 && s->v_max==1));
|
||||
if(s->rgb){
|
||||
int w, h;
|
||||
w = s->width;
|
||||
@ -1033,6 +1036,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
||||
}
|
||||
|
||||
comp_index[i] = index;
|
||||
|
||||
nb_blocks[i] = s->h_count[index] * s->v_count[index];
|
||||
h_count[i] = s->h_count[index];
|
||||
v_count[i] = s->v_count[index];
|
||||
@ -1060,6 +1064,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
predictor= get_bits(&s->gb, 8); /* lossless predictor or start of spectral (Ss) */
|
||||
skip_bits(&s->gb, 8); /* Se */
|
||||
skip_bits(&s->gb, 4); /* Ah */
|
||||
@ -1082,56 +1087,64 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
||||
v_count[0] = 1;
|
||||
}
|
||||
|
||||
if(s->avctx->debug & FF_DEBUG_PICT_INFO)
|
||||
printf("%s %s p:%d >>:%d\n", s->lossless ? "lossless" : "sequencial DCT", s->rgb ? "RGB" : "", predictor, point_transform);
|
||||
|
||||
if(s->lossless){
|
||||
if(s->rgb){ //FIXME cleanup
|
||||
if(s->rgb){
|
||||
uint16_t buffer[2048][4];
|
||||
int left[3], top[3], topleft[3];
|
||||
const int linesize= s->linesize[0];
|
||||
const int mask= (1<<s->bits)-1;
|
||||
|
||||
for(i=0; i<3; i++){
|
||||
buffer[0][i]= 1 << (s->bits + point_transform - 1);
|
||||
}
|
||||
for(mb_y = 0; mb_y < mb_height; mb_y++) {
|
||||
const int modified_predictor= mb_y ? 1 : predictor;
|
||||
uint8_t *ptr = s->current_picture[0] + (linesize * mb_y);
|
||||
|
||||
if (s->interlaced && s->bottom_field)
|
||||
ptr += linesize >> 1;
|
||||
|
||||
for(i=0; i<3; i++){
|
||||
top[i]= left[i]= topleft[i]= buffer[0][i];
|
||||
}
|
||||
for(mb_x = 0; mb_x < mb_width; mb_x++) {
|
||||
if (s->restart_interval && !s->restart_count)
|
||||
s->restart_count = s->restart_interval;
|
||||
|
||||
if(mb_x==0 || mb_y==0 || s->interlaced || 1){
|
||||
for(i=0;i<3;i++) {
|
||||
uint8_t *ptr;
|
||||
int c, pred;
|
||||
c = comp_index[i];
|
||||
for(i=0;i<3;i++) {
|
||||
int pred;
|
||||
|
||||
ptr = s->current_picture[0] + (linesize * mb_y) + 4*mb_x + c; //FIXME optimize this crap
|
||||
if(mb_y==0){
|
||||
if(mb_x==0){
|
||||
pred= 128 << point_transform;
|
||||
}else{
|
||||
pred= ptr[-4];
|
||||
}
|
||||
}else{
|
||||
if(mb_x==0){
|
||||
pred= ptr[-linesize];
|
||||
}else{
|
||||
pred= predict(ptr, linesize, predictor, 4);
|
||||
}
|
||||
}
|
||||
if (s->interlaced && s->bottom_field)
|
||||
ptr += linesize >> 1;
|
||||
*ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform);
|
||||
}
|
||||
}else{
|
||||
for(i=0;i<3;i++) {
|
||||
uint8_t *ptr;
|
||||
int c, pred;
|
||||
c = comp_index[i];
|
||||
|
||||
ptr = s->current_picture[0] + (linesize * mb_y) + 4*mb_x + c; //FIXME optimize this crap
|
||||
pred= predict(ptr, linesize, predictor, 4);
|
||||
*ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform);
|
||||
}
|
||||
PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
|
||||
|
||||
topleft[i]= top[i];
|
||||
top[i]= buffer[mb_x][i];
|
||||
|
||||
left[i]=
|
||||
buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform));
|
||||
}
|
||||
/* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */
|
||||
if (s->restart_interval && (s->restart_interval < 1350) &&
|
||||
!--s->restart_count) {
|
||||
|
||||
if (s->restart_interval && !--s->restart_count) {
|
||||
align_get_bits(&s->gb);
|
||||
skip_bits(&s->gb, 16); /* skip RSTn */
|
||||
}
|
||||
}
|
||||
|
||||
if(s->rct){
|
||||
for(mb_x = 0; mb_x < mb_width; mb_x++) {
|
||||
ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2])>>2);
|
||||
ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1];
|
||||
ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1];
|
||||
}
|
||||
}else{
|
||||
for(mb_x = 0; mb_x < mb_width; mb_x++) {
|
||||
ptr[4*mb_x+0] = buffer[mb_x][0];
|
||||
ptr[4*mb_x+1] = buffer[mb_x][1];
|
||||
ptr[4*mb_x+2] = buffer[mb_x][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for(mb_y = 0; mb_y < mb_height; mb_y++) {
|
||||
@ -1139,7 +1152,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
||||
if (s->restart_interval && !s->restart_count)
|
||||
s->restart_count = s->restart_interval;
|
||||
|
||||
if(mb_x==0 || mb_y==0 || s->interlaced || 1){
|
||||
if(mb_x==0 || mb_y==0 || s->interlaced){
|
||||
for(i=0;i<nb_components;i++) {
|
||||
uint8_t *ptr;
|
||||
int x, y, c, linesize;
|
||||
@ -1165,7 +1178,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
||||
if(x==0 && mb_x==0){
|
||||
pred= ptr[-linesize];
|
||||
}else{
|
||||
pred= predict(ptr, linesize, predictor, 1);
|
||||
PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1195,7 +1208,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
||||
int pred;
|
||||
|
||||
ptr = s->current_picture[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
|
||||
pred= predict(ptr, linesize, predictor, 1);
|
||||
PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
|
||||
*ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform);
|
||||
if (++x == h) {
|
||||
x = 0;
|
||||
@ -1204,9 +1217,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */
|
||||
if (s->restart_interval && (s->restart_interval < 1350) &&
|
||||
!--s->restart_count) {
|
||||
if (s->restart_interval && !--s->restart_count) {
|
||||
align_get_bits(&s->gb);
|
||||
skip_bits(&s->gb, 16); /* skip RSTn */
|
||||
}
|
||||
@ -1293,6 +1304,10 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
|
||||
id = be2me_32(id);
|
||||
len -= 6;
|
||||
|
||||
if(s->avctx->debug & FF_DEBUG_STARTCODE){
|
||||
printf("APPx %8X\n", id);
|
||||
}
|
||||
|
||||
/* buggy AVID, it puts EOI only at every 10th frame */
|
||||
/* also this fourcc is used by non-avid files too, it holds some
|
||||
informations, but it's always present in AVID creates files */
|
||||
@ -1374,6 +1389,29 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
|
||||
len -= 7;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (id == ff_get_fourcc("LJIF")){
|
||||
printf("Pegasus lossless jpeg header found\n");
|
||||
int i;
|
||||
skip_bits(&s->gb, 16); /* version ? */
|
||||
skip_bits(&s->gb, 16); /* unknwon always 0? */
|
||||
skip_bits(&s->gb, 16); /* unknwon always 0? */
|
||||
skip_bits(&s->gb, 16); /* unknwon always 0? */
|
||||
switch( get_bits(&s->gb, 8)){
|
||||
case 1:
|
||||
s->rgb= 1;
|
||||
s->rct=0;
|
||||
break;
|
||||
case 2:
|
||||
s->rgb= 1;
|
||||
s->rct=1;
|
||||
break;
|
||||
default:
|
||||
printf("unknown colorspace\n");
|
||||
}
|
||||
len -= 9;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Apple MJPEG-A */
|
||||
if ((s->start_code == APP1) && (len > (0x28 - 8)))
|
||||
@ -1563,6 +1601,9 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
|
||||
init_get_bits(&s->gb, buf_ptr, (buf_end - buf_ptr)*8);
|
||||
|
||||
s->start_code = start_code;
|
||||
if(s->avctx->debug & FF_DEBUG_STARTCODE){
|
||||
printf("startcode: %X\n", start_code);
|
||||
}
|
||||
|
||||
/* process markers */
|
||||
if (start_code >= 0xd0 && start_code <= 0xd7) {
|
||||
@ -1589,13 +1630,11 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
|
||||
break;
|
||||
case SOF0:
|
||||
s->lossless=0;
|
||||
s->rgb=0;
|
||||
if (mjpeg_decode_sof(s) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case SOF3:
|
||||
s->lossless=1;
|
||||
s->rgb=1; //FIXME
|
||||
if (mjpeg_decode_sof(s) < 0)
|
||||
return -1;
|
||||
break;
|
||||
@ -1622,7 +1661,11 @@ eoi_parser:
|
||||
switch((s->h_count[0] << 4) | s->v_count[0]) {
|
||||
case 0x11:
|
||||
if(s->rgb){
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
avctx->pix_fmt = PIX_FMT_ABGR32;
|
||||
#else
|
||||
avctx->pix_fmt = PIX_FMT_RGBA32;
|
||||
#endif
|
||||
}else
|
||||
avctx->pix_fmt = PIX_FMT_YUV444P;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user