Newer
Older
nb_components > MAX_COMPONENTS)
return -1;
s->nb_components = nb_components;
s->h_max = 1;
s->v_max = 1;
for(i=0;i<nb_components;i++) {
/* component id */
s->component_id[i] = get_bits(&s->gb, 8) - 1;
s->h_count[i] = get_bits(&s->gb, 4);
s->v_count[i] = get_bits(&s->gb, 4);
/* compute hmax and vmax (only used in interleaved case) */
if (s->h_count[i] > s->h_max)
s->h_max = s->h_count[i];
if (s->v_count[i] > s->v_max)
s->v_max = s->v_count[i];
s->quant_index[i] = get_bits(&s->gb, 8);
if (s->quant_index[i] >= 4)
return -1;
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 */
if (width != s->width || height != s->height) {
for(i=0;i<MAX_COMPONENTS;i++)
av_freep(&s->current_picture[i]);
s->width = width;
s->height = height;
/* test interlaced mode */
if (s->first_picture &&
s->org_height != 0 &&
s->height < ((s->org_height * 3) / 4)) {
s->interlaced = 1;
Alex Beregszaszi
committed
// s->bottom_field = (s->interlace_polarity) ? 1 : 0;
s->bottom_field = 0;
if(s->rgb){
int w, h;
w = s->width;
h = s->height;
if (s->interlaced)
w *= 2;
s->linesize[0] = 4*w;
s->current_picture[0] = av_mallocz(4*w * h);
s->current_picture[1] = s->current_picture[2] = NULL;
}else{
for(i=0;i<nb_components;i++) {
int w, h;
w = (s->width + 8 * s->h_max - 1) / (8 * s->h_max);
h = (s->height + 8 * s->v_max - 1) / (8 * s->v_max);
w = w * 8 * s->h_count[i];
h = h * 8 * s->v_count[i];
s->linesize[i] = w;
s->current_picture[i] = av_mallocz(w * h);
if (!s->current_picture[i])
{
dprintf("error: no picture buffers allocated\n");
return -1;
}
Arpi
committed
if (len != (8+(3*nb_components)))
{
Arpi
committed
dprintf("decode_sof0: error, len(%d) mismatch\n", len);
return 0;
}
static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index)
code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2);
Arpi
committed
{
dprintf("mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index,
Arpi
committed
}
if(code)
return get_xbits(&s->gb, code);
else
return 0;
}
/* decode block and dequantize */
static int decode_block(MJpegDecodeContext *s, DCTELEM *block,
int component, int dc_index, int ac_index, int quant_index)
{
/* DC coef */
val = mjpeg_decode_dc(s, dc_index);
if (val == 0xffff) {
dprintf("error dc\n");
return -1;
}
Arpi
committed
quant_matrix = s->quant_matrixes[quant_index];
val = val * quant_matrix[0] + s->last_dc[component];
s->last_dc[component] = val;
block[0] = val;
/* AC coefs */
ac_vlc = &s->vlcs[1][ac_index];
i = 1;
for(;;) {
code = get_vlc2(&s->gb, s->vlcs[1][ac_index].table, 9, 2);
if (code < 0) {
dprintf("error ac\n");
return -1;
}
/* EOB */
if (code == 0)
break;
if (code == 0xf0) {
i += 16;
} else {
level = get_xbits(&s->gb, code & 0xf);
i += code >> 4;
if (i >= 64) {
dprintf("error count: %d\n", i);
return -1;
}
j = s->scantable.permutated[i];
block[j] = level * quant_matrix[j];
i++;
if (i >= 64)
break;
}
}
return 0;
}
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)
Arpi
committed
{
dprintf("decode_sos: components(%d) mismatch\n", nb_components);
Arpi
committed
}
vmax = 0;
hmax = 0;
for(i=0;i<nb_components;i++) {
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)
Arpi
committed
{
dprintf("decode_sos: index(%d) out of components\n", index);
Arpi
committed
}
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);
Arpi
committed
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->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->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;
PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
left[i]=
buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform));
align_get_bits(&s->gb);
skip_bits(&s->gb, 16); /* skip RSTn */
}
}
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] - 0x200)>>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 if(s->pegasus_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++) {
for(mb_x = 0; mb_x < mb_width; mb_x++) {
if (s->restart_interval && !s->restart_count)
s->restart_count = s->restart_interval;
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
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{
PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
}
}
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
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;
y++;
}
}
}
}
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++) {
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);
Fabrice Bellard
committed
ret = -1;
goto the_end;
Arpi
committed
// 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) {
Leon van Stuivenberg
committed
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;
}
Fabrice Bellard
committed
ret = 0;
the_end:
emms_c();
Fabrice Bellard
committed
return ret;
Arpi
committed
out_of_range:
dprintf("decode_sos: ac/dc index out of range\n");
return -1;
static int mjpeg_decode_dri(MJpegDecodeContext *s)
{
if (get_bits(&s->gb, 16) != 4)
return -1;
s->restart_interval = get_bits(&s->gb, 16);
dprintf("restart interval: %d\n", s->restart_interval);
return 0;
}
Alex Beregszaszi
committed
static int mjpeg_decode_app(MJpegDecodeContext *s)
{
int len, id;
/* XXX: verify len field validity */
len = get_bits(&s->gb, 16);
if (len < 5)
return -1;
id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16);
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 */
Alex Beregszaszi
committed
if (id == ff_get_fourcc("AVI1"))
/* structure:
4bytes AVI1
1bytes polarity
1bytes always zero
4bytes field_size
4bytes field_size_less_padding
*/
s->buggy_avid = 1;
Alex Beregszaszi
committed
// if (s->first_picture)
// printf("mjpeg: workarounding buggy AVID\n");
s->interlace_polarity = get_bits(&s->gb, 8);
#if 0
skip_bits(&s->gb, 8);
skip_bits(&s->gb, 32);
skip_bits(&s->gb, 32);
len -= 10;
#endif
Alex Beregszaszi
committed
// if (s->interlace_polarity)
// printf("mjpeg: interlace polarity: %d\n", s->interlace_polarity);
goto out;
// len -= 2;
Alex Beregszaszi
committed
if (id == ff_get_fourcc("JFIF"))
int t_w, t_h;
skip_bits(&s->gb, 8); /* the trailing zero-byte */
printf("mjpeg: JFIF header found (version: %x.%x)\n",
get_bits(&s->gb, 8), get_bits(&s->gb, 8));
int x_density, y_density;
x_density = get_bits(&s->gb, 16);
y_density = get_bits(&s->gb, 16);
dprintf("x/y density: %d (%f), %d (%f)\n", x_density,
(float)x_density, y_density, (float)y_density);
#if 0
if(x_density)
// s->avctx->aspect_ratio= s->width*y_density/((float)s->height*x_density);
s->avctx->aspect_ratio = (float)x_density/y_density;
/* it's better, but every JFIF I have seen stores 1:1 */
else
s->avctx->aspect_ratio= 0.0;
}
else
{
skip_bits(&s->gb, 16);
skip_bits(&s->gb, 16);
}
t_w = get_bits(&s->gb, 8);
t_h = get_bits(&s->gb, 8);
if (t_w && t_h)
{
/* skip thumbnail */
if (len-10-(t_w*t_h*3) > 0)
len -= t_w*t_h*3;
}
len -= 10;
goto out;
}
if (id == ff_get_fourcc("Adob") && (get_bits(&s->gb, 8) == 'e'))
{
printf("mjpeg: Adobe header found\n");
skip_bits(&s->gb, 16); /* version */
skip_bits(&s->gb, 16); /* flags0 */
skip_bits(&s->gb, 16); /* flags1 */
skip_bits(&s->gb, 8); /* transform */
len -= 7;
goto out;
}
if (id == ff_get_fourcc("LJIF")){
printf("Pegasus lossless jpeg header found\n");
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->pegasus_rct=0;
s->pegasus_rct=1;
break;
default:
printf("unknown colorspace\n");
}
len -= 9;
goto out;
}
/* Apple MJPEG-A */
Alex Beregszaszi
committed
if ((s->start_code == APP1) && (len > (0x28 - 8)))
id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16);
id = be2me_32(id);
len -= 4;
Alex Beregszaszi
committed
if (id == ff_get_fourcc("mjpg")) /* Apple MJPEG-A */
{
#if 0
skip_bits(&s->gb, 32); /* field size */
skip_bits(&s->gb, 32); /* pad field size */
skip_bits(&s->gb, 32); /* next off */
skip_bits(&s->gb, 32); /* quant off */
skip_bits(&s->gb, 32); /* huff off */
skip_bits(&s->gb, 32); /* image off */
skip_bits(&s->gb, 32); /* scan off */
skip_bits(&s->gb, 32); /* data off */
#endif
if (s->first_picture)
printf("mjpeg: Apple MJPEG-A header found\n");
}
}
out:
/* slow but needed for extreme adobe jpegs */
if (len < 0)
printf("mjpeg: error, decode_app parser read over the end\n");
while(--len > 0)
skip_bits(&s->gb, 8);
static int mjpeg_decode_com(MJpegDecodeContext *s)
{
/* XXX: verify len field validity */
if (len >= 2 && len < 32768) {
/* XXX: any better upper bound */
if (cbuf) {
int i;
for (i = 0; i < len - 2; i++)
cbuf[i] = get_bits(&s->gb, 8);
if (i > 0 && cbuf[i-1] == '\n')
cbuf[i-1] = 0;
else
cbuf[i] = 0;
printf("mjpeg comment: '%s'\n", cbuf);
/* buggy avid, it puts EOI only at every 10th frame */
if (!strcmp(cbuf, "AVID"))
{
s->buggy_avid = 1;
// if (s->first_picture)
// printf("mjpeg: workarounding buggy AVID\n");
}
}
return 0;
}
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
#if 0
static int valid_marker_list[] =
{
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */
/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* c */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
}
#endif
/* return the 8 bit start code value and update the search
state. Return -1 if no start code found */
static int find_marker(uint8_t **pbuf_ptr, uint8_t *buf_end)
unsigned int v, v2;
#ifdef DEBUG
int skipped=0;
#endif
buf_ptr = *pbuf_ptr;
while (buf_ptr < buf_end) {
v = *buf_ptr++;
v2 = *buf_ptr;
if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe)) {
val = *buf_ptr++;
goto found;
#ifdef DEBUG
skipped++;
#endif
val = -1;
found:
#ifdef DEBUG
dprintf("find_marker skipped %d bytes\n", skipped);
#endif
*pbuf_ptr = buf_ptr;
return val;
}
static int mjpeg_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
{
MJpegDecodeContext *s = avctx->priv_data;
int i, start_code;
AVPicture *picture = data;
/* no supplementary picture */
return 0;
buf_ptr = buf;
buf_end = buf + buf_size;
while (buf_ptr < buf_end) {
/* find start next marker */
start_code = find_marker(&buf_ptr, buf_end);
{
/* EOF */
if (start_code < 0) {
goto the_end;
dprintf("marker=%x avail_size_in_buf=%d\n", start_code, buf_end - buf_ptr);
if ((buf_end - buf_ptr) > s->buffer_size)
{
av_free(s->buffer);
s->buffer_size = buf_end-buf_ptr;
s->buffer = av_malloc(s->buffer_size);
Alex Beregszaszi
committed
dprintf("buffer too small, expanding to %d bytes\n",
s->buffer_size);
}
/* unescape buffer of SOS */
if (start_code == SOS)
{
uint8_t *src = buf_ptr;
uint8_t *dst = s->buffer;
while (src<buf_end)
{
*(dst++) = x;
if (x == 0xff)
{
x = *(src++);
if (x >= 0xd0 && x <= 0xd7)
*(dst++) = x;
else if (x)
break;
}
}
Michael Niedermayer
committed
init_get_bits(&s->gb, s->buffer, (dst - s->buffer)*8);
dprintf("escaping removed %d bytes\n",
(buf_end - buf_ptr) - (dst - s->buffer));
}
else
Michael Niedermayer
committed
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) {
dprintf("restart marker: %d\n", start_code&0x0f);
} else if (s->first_picture) {
/* APP fields */
if (start_code >= 0xe0 && start_code <= 0xef)
Alex Beregszaszi
committed
mjpeg_decode_app(s);
/* Comment */
else if (start_code == COM)
mjpeg_decode_com(s);
}
switch(start_code) {
case SOI:
s->restart_interval = 0;
/* nothing to do on SOI */
break;
case DQT:
mjpeg_decode_dqt(s);
break;
case DHT:
if(mjpeg_decode_dht(s) < 0){
fprintf(stderr, "huffman table decode error\n");
return -1;
}
break;
case SOF0:
s->lossless=0;
if (mjpeg_decode_sof(s) < 0)
return -1;
break;
case SOF3:
s->lossless=1;
if (mjpeg_decode_sof(s) < 0)
case EOI:
eoi_parser:
{
if (s->interlaced) {
s->bottom_field ^= 1;
/* if not bottom field, do not output image yet */
if (s->bottom_field)
goto not_the_end;
for(i=0;i<3;i++) {
picture->data[i] = s->current_picture[i];
picture->linesize[i] = (s->interlaced) ?
s->linesize[i] >> 1 : s->linesize[i];
}
*data_size = sizeof(AVPicture);
avctx->height = s->height;
if (s->interlaced)
avctx->height *= 2;
avctx->width = s->width;
/* XXX: not complete test ! */
switch((s->h_count[0] << 4) | s->v_count[0]) {
case 0x11:
if(s->rgb){
avctx->pix_fmt = PIX_FMT_RGBA32;
}else
avctx->pix_fmt = PIX_FMT_YUV444P;
break;
case 0x21:
avctx->pix_fmt = PIX_FMT_YUV422P;
break;
default:
case 0x22:
avctx->pix_fmt = PIX_FMT_YUV420P;
break;
}
Fabrice Bellard
committed
/* dummy quality */
/* XXX: infer it with matrix */
goto the_end;
}
break;
case SOS:
mjpeg_decode_sos(s);
/* buggy avid puts EOI every 10-20th frame */
/* if restart period is over process EOI */
if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
goto eoi_parser;
case DRI:
mjpeg_decode_dri(s);
break;
case SOF1:
case SOF2:
case SOF5:
case SOF6:
case SOF7:
case SOF9:
case SOF10:
case SOF11:
case SOF13:
case SOF14:
case SOF15:
case JPG:
printf("mjpeg: unsupported coding type (%x)\n", start_code);
break;
// default:
// printf("mjpeg: unsupported marker (%x)\n", start_code);
// break;
not_the_end:
/* eof process start code */
buf_ptr += (get_bits_count(&s->gb)+7)/8;
dprintf("marker parser used %d bytes (%d bits)\n",
(get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb));
the_end:
dprintf("mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);
// return buf_end - buf_ptr;
return buf_ptr - buf;
}
static int mjpegb_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
{
MJpegDecodeContext *s = avctx->priv_data;
int i;
AVPicture *picture = data;
GetBitContext hgb; /* for the header */
uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;
uint32_t field_size;
*data_size = 0;
/* no supplementary picture */
if (buf_size == 0)
return 0;
buf_ptr = buf;
buf_end = buf + buf_size;
read_header:
/* reset on every SOI */
s->restart_interval = 0;
Michael Niedermayer
committed
init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8);
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
skip_bits(&hgb, 32); /* reserved zeros */
if (get_bits(&hgb, 32) != be2me_32(ff_get_fourcc("mjpg")))
{
dprintf("not mjpeg-b (bad fourcc)\n");
return 0;
}
field_size = get_bits(&hgb, 32); /* field size */
dprintf("field size: 0x%x\n", field_size);
skip_bits(&hgb, 32); /* padded field size */
second_field_offs = get_bits(&hgb, 32);
dprintf("second field offs: 0x%x\n", second_field_offs);
if (second_field_offs)
s->interlaced = 1;
dqt_offs = get_bits(&hgb, 32);
dprintf("dqt offs: 0x%x\n", dqt_offs);
if (dqt_offs)
{
Michael Niedermayer
committed
init_get_bits(&s->gb, buf+dqt_offs, (buf_end - (buf+dqt_offs))*8);
s->start_code = DQT;
mjpeg_decode_dqt(s);
}
dht_offs = get_bits(&hgb, 32);
dprintf("dht offs: 0x%x\n", dht_offs);
if (dht_offs)
{
Michael Niedermayer
committed
init_get_bits(&s->gb, buf+dht_offs, (buf_end - (buf+dht_offs))*8);
s->start_code = DHT;
mjpeg_decode_dht(s);
}
sof_offs = get_bits(&hgb, 32);
dprintf("sof offs: 0x%x\n", sof_offs);
if (sof_offs)
{
Michael Niedermayer
committed
init_get_bits(&s->gb, buf+sof_offs, (buf_end - (buf+sof_offs))*8);
}
sos_offs = get_bits(&hgb, 32);
dprintf("sos offs: 0x%x\n", sos_offs);
if (sos_offs)
{
Michael Niedermayer
committed
// init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8);
init_get_bits(&s->gb, buf+sos_offs, field_size*8);
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
s->start_code = SOS;
mjpeg_decode_sos(s);
}
skip_bits(&hgb, 32); /* start of data offset */
if (s->interlaced) {
s->bottom_field ^= 1;
/* if not bottom field, do not output image yet */
if (s->bottom_field && second_field_offs)
{
buf_ptr = buf + second_field_offs;
second_field_offs = 0;
goto read_header;
}
}
for(i=0;i<3;i++) {
picture->data[i] = s->current_picture[i];
picture->linesize[i] = (s->interlaced) ?
s->linesize[i] >> 1 : s->linesize[i];
}
*data_size = sizeof(AVPicture);
avctx->height = s->height;
if (s->interlaced)
avctx->height *= 2;
avctx->width = s->width;
/* XXX: not complete test ! */
switch((s->h_count[0] << 4) | s->v_count[0]) {
case 0x11:
avctx->pix_fmt = PIX_FMT_YUV444P;
break;
case 0x21:
avctx->pix_fmt = PIX_FMT_YUV422P;
break;
default:
case 0x22:
avctx->pix_fmt = PIX_FMT_YUV420P;
break;
}
/* dummy quality */
/* XXX: infer it with matrix */