pred= predict(ptr, linesize, predictor, 1);
PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
static int mjpeg_decode_sos(MJpegDecodeContext *s){    int len, nb_components, i, j, n, h, v, ret, point_transform, predictor;    int mb_width, mb_height, mb_x, mb_y, vmax, hmax, index, id;    int comp_index[4];    int dc_index[4];    int ac_index[4];    int nb_blocks[4];    int h_count[4];    int v_count[4];    const int block_size= s->lossless ? 1 : 8;    /* XXX: verify len field validity */    len = get_bits(&s->gb, 16);    nb_components = get_bits(&s->gb, 8);    if (len != 6+2*nb_components)    {	dprintf("decode_sos: invalid len (%d)\n", len);	return -1;    }    /* XXX: only interleaved scan accepted */    if (nb_components != 3)    {	dprintf("decode_sos: components(%d) mismatch\n", nb_components);        return -1;    }    vmax = 0;    hmax = 0;    for(i=0;i<nb_components;i++) {        id = get_bits(&s->gb, 8) - 1;	dprintf("component: %d\n", id);        /* find component index */        for(index=0;index<s->nb_components;index++)            if (id == s->component_id[index])                break;        if (index == s->nb_components)	{	    dprintf("decode_sos: index(%d) out of components\n", index);            return -1;	}        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];        dc_index[i] = get_bits(&s->gb, 4);        ac_index[i] = get_bits(&s->gb, 4);	if (dc_index[i] < 0 || ac_index[i] < 0 ||	    dc_index[i] >= 4 || ac_index[i] >= 4)	    goto out_of_range;	switch(s->start_code)	{	    case SOF0:		if (dc_index[i] > 1 || ac_index[i] > 1)		    goto out_of_range;		break;	    case SOF1:	    case SOF2:		if (dc_index[i] > 3 || ac_index[i] > 3)		    goto out_of_range;		break;	    case SOF3:		if (dc_index[i] > 3 || ac_index[i] != 0)		    goto out_of_range;		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 */    point_transform= get_bits(&s->gb, 4); /* Al */    for(i=0;i<nb_components;i++)         s->last_dc[i] = 1024;    if (nb_components > 1) {        /* interleaved stream */        mb_width  = (s->width  + s->h_max * block_size - 1) / (s->h_max * block_size);        mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size);    } else {        h = s->h_max / s->h_count[comp_index[0]];        v = s->v_max / s->v_count[comp_index[0]];        mb_width  = (s->width  + h * block_size - 1) / (h * block_size);        mb_height = (s->height + v * block_size - 1) / (v * block_size);        nb_blocks[0] = 1;        h_count[0] = 1;        v_count[0] = 1;    }    if(s->lossless){        if(s->rgb){ //FIXME cleanup            const int linesize= s->linesize[0];            for(mb_y = 0; mb_y < mb_height; mb_y++) {                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];                            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);                        }                    }                    /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */                    if (s->restart_interval && (s->restart_interval < 1350) &&                        !--s->restart_count) {                        align_get_bits(&s->gb);                        skip_bits(&s->gb, 16); /* skip RSTn */                    }                }            }        }else{            for(mb_y = 0; mb_y < mb_height; mb_y++) {                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<nb_components;i++) {                            uint8_t *ptr;                            int x, y, c, linesize;                            n = nb_blocks[i];                            c = comp_index[i];                            h = h_count[i];                            v = v_count[i];                            x = 0;                            y = 0;                            linesize= s->linesize[c];                                                        for(j=0; j<n; j++) {                                int pred;                                ptr = s->current_picture[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap                                if(y==0 && mb_y==0){                                    if(x==0 && mb_x==0){                                        pred= 128 << point_transform;                                    }else{                                        pred= ptr[-1];                                    }                                }else{                                    if(x==0 && mb_x==0){                                        pred= ptr[-linesize];                                    }else{                                        pred= predict(ptr, linesize, predictor, 1);                                    }                                }                                                                if (s->interlaced && s->bottom_field)                                    ptr += linesize >> 1;                                *ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform);                                if (++x == h) {                                    x = 0;                                    y++;                                }                            }                        }                    }else{                        for(i=0;i<nb_components;i++) {                            uint8_t *ptr;                            int x, y, c, linesize;                            n = nb_blocks[i];                            c = comp_index[i];                            h = h_count[i];                            v = v_count[i];                            x = 0;                            y = 0;                            linesize= s->linesize[c];                                                        for(j=0; j<n; j++) {                                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);                                *ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform);                                if (++x == h) {                                    x = 0;                                    y++;                                }                            }                        }                    }                    /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */                    if (s->restart_interval && (s->restart_interval < 1350) &&                        !--s->restart_count) {                        align_get_bits(&s->gb);                        skip_bits(&s->gb, 16); /* skip RSTn */                    }                }            }        }    }else{      for(mb_y = 0; mb_y < mb_height; mb_y++) {        for(mb_x = 0; mb_x < mb_width; mb_x++) {            if (s->restart_interval && !s->restart_count)                s->restart_count = s->restart_interval;            for(i=0;i<nb_components;i++) {                uint8_t *ptr;                int x, y, c;                n = nb_blocks[i];                c = comp_index[i];                h = h_count[i];                v = v_count[i];                x = 0;                y = 0;                for(j=0;j<n;j++) {                    memset(s->block, 0, sizeof(s->block));                    if (decode_block(s, s->block, i,                                      dc_index[i], ac_index[i],                                      s->quant_index[c]) < 0) {                        dprintf("error y=%d x=%d\n", mb_y, mb_x);                        ret = -1;                        goto the_end;                    }//		    dprintf("mb: %d %d processed\n", mb_y, mb_x);                    ptr = s->current_picture[c] +                         (s->linesize[c] * (v * mb_y + y) * 8) +                         (h * mb_x + x) * 8;                    if (s->interlaced && s->bottom_field)                        ptr += s->linesize[c] >> 1;                    s->idct_put(ptr, s->linesize[c], s->block);                    if (++x == h) {                        x = 0;                        y++;                    }                }            }	    /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */            if (s->restart_interval && (s->restart_interval < 1350) &&		!--s->restart_count) {                align_get_bits(&s->gb);                skip_bits(&s->gb, 16); /* skip RSTn */                for (j=0; j<nb_components; j++) /* reset dc */                    s->last_dc[j] = 1024;            }        }    }  }    ret = 0; the_end:    emms_c();    return ret; out_of_range:    dprintf("decode_sos: ac/dc index out of range\n");    return -1;}