Blame src/liboggz/dirac.c

Packit a38265
/*
Packit a38265
  dirac.c
Packit a38265
*/
Packit a38265

Packit a38265
#include "config.h"
Packit a38265

Packit a38265
#ifdef HAVE_STDINT_H
Packit a38265
#include <stdint.h>
Packit a38265
#endif
Packit a38265
Packit a38265
#include "dirac.h"
Packit a38265
Packit a38265

Packit a38265
typedef struct
Packit a38265
dirac_bs_s
Packit a38265
{
Packit a38265
  uint8_t *p_start;
Packit a38265
  uint8_t *p;
Packit a38265
  uint8_t *p_end;
Packit a38265
Packit a38265
  int     i_left;    /* i_count number of available bits */
Packit a38265
} dirac_bs_t;
Packit a38265
Packit a38265
static inline void
Packit a38265
dirac_bs_init( dirac_bs_t *s, void *p_data, int i_data )
Packit a38265
{
Packit a38265
  s->p_start = p_data;
Packit a38265
  s->p       = p_data;
Packit a38265
  s->p_end   = s->p + i_data;
Packit a38265
  s->i_left  = 8;
Packit a38265
}
Packit a38265
Packit a38265
static inline ogg_uint32_t
Packit a38265
dirac_bs_read( dirac_bs_t *s, int i_count )
Packit a38265
{
Packit a38265
   static ogg_uint32_t i_mask[33] =
Packit a38265
   {  0x00,
Packit a38265
      0x01,      0x03,      0x07,      0x0f,
Packit a38265
      0x1f,      0x3f,      0x7f,      0xff,
Packit a38265
      0x1ff,     0x3ff,     0x7ff,     0xfff,
Packit a38265
      0x1fff,    0x3fff,    0x7fff,    0xffff,
Packit a38265
      0x1ffff,   0x3ffff,   0x7ffff,   0xfffff,
Packit a38265
      0x1fffff,  0x3fffff,  0x7fffff,  0xffffff,
Packit a38265
      0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
Packit a38265
      0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
Packit a38265
  int      i_shr;
Packit a38265
  ogg_uint32_t i_result = 0;
Packit a38265
Packit a38265
  while( i_count > 0 )
Packit a38265
  {
Packit a38265
    if( s->p >= s->p_end )
Packit a38265
    {
Packit a38265
      break;
Packit a38265
    }
Packit a38265
Packit a38265
    if( ( i_shr = s->i_left - i_count ) >= 0 )
Packit a38265
    {
Packit a38265
      /* more in the buffer than requested */
Packit a38265
      i_result |= ( *s->p >> i_shr )&i_mask[i_count];
Packit a38265
      s->i_left -= i_count;
Packit a38265
      if( s->i_left == 0 )
Packit a38265
      {
Packit a38265
        s->p++;
Packit a38265
        s->i_left = 8;
Packit a38265
      }
Packit a38265
      return( i_result );
Packit a38265
    }
Packit a38265
    else
Packit a38265
    {
Packit a38265
        /* less in the buffer than requested */
Packit a38265
       i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
Packit a38265
       i_count  -= s->i_left;
Packit a38265
       s->p++;
Packit a38265
       s->i_left = 8;
Packit a38265
    }
Packit a38265
  }
Packit a38265
Packit a38265
  return( i_result );
Packit a38265
}
Packit a38265
Packit a38265
static inline void
Packit a38265
dirac_bs_skip( dirac_bs_t *s, int i_count )
Packit a38265
{
Packit a38265
  s->i_left -= i_count;
Packit a38265
Packit a38265
  while( s->i_left <= 0 )
Packit a38265
  {
Packit a38265
    s->p++;
Packit a38265
    s->i_left += 8;
Packit a38265
  }
Packit a38265
}
Packit a38265
Packit a38265
static ogg_uint32_t
Packit a38265
dirac_uint ( dirac_bs_t *p_bs )
Packit a38265
{
Packit a38265
  ogg_uint32_t count = 0, value = 0;
Packit a38265
  while( !dirac_bs_read ( p_bs, 1 ) ) {
Packit a38265
    count++;
Packit a38265
    value <<= 1;
Packit a38265
    value |= dirac_bs_read ( p_bs, 1 );
Packit a38265
  }
Packit a38265
Packit a38265
  return (1<
Packit a38265
}
Packit a38265
Packit a38265
static int
Packit a38265
dirac_bool ( dirac_bs_t *p_bs )
Packit a38265
{
Packit a38265
  return dirac_bs_read ( p_bs, 1 );
Packit a38265
}
Packit a38265
Packit a38265
int
Packit a38265
dirac_parse_info (dirac_info *info, unsigned char * data, long len)
Packit a38265
{
Packit a38265
  dirac_bs_t bs;
Packit a38265
  ogg_uint32_t video_format;
Packit a38265
Packit a38265
  static const struct {
Packit a38265
    ogg_uint32_t fps_numerator, fps_denominator;
Packit a38265
  } dirac_frate_tbl[] = { /* table 10.3 */
Packit a38265
    {1,1}, /* this first value is never used */
Packit a38265
    {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
Packit a38265
    {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2}
Packit a38265
  };
Packit a38265
Packit a38265
  static const ogg_uint32_t dirac_vidfmt_frate[] = { /* table C.1 */
Packit a38265
    1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6
Packit a38265
  };
Packit a38265
Packit a38265
  static const int dirac_source_sampling[] = { /* extracted from table C.1 */
Packit a38265
    0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
Packit a38265
  };
Packit a38265
  static const int dirac_top_field_first[] = { /* from table C.1 */
Packit a38265
    0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Packit a38265
  };
Packit a38265
Packit a38265
  static const struct {
Packit a38265
    ogg_uint32_t width, height;
Packit a38265
  } dirac_fsize_tbl[] = { /* table 10.3 framesize */
Packit a38265
    {640,460}, {24,1}, {176,120}, {352,240}, {352,288},
Packit a38265
    {704,480}, {704,576}, {720,480}, {720,576},
Packit a38265
    {1280, 720}, {1280, 720}, {1920, 1080}, {1920, 1080},
Packit a38265
    {1920, 1080}, {1920, 1080}, {2048, 1080}, {4096, 2160}
Packit a38265
  };
Packit a38265
Packit a38265
  /* read in useful bits from sequence header */
Packit a38265
  dirac_bs_init( &bs, data, len);
Packit a38265
  dirac_bs_skip( &bs, 13*8); /* parse_info_header */
Packit a38265
  info->major_version = dirac_uint( &bs ); /* major_version */
Packit a38265
  info->minor_version = dirac_uint( &bs ); /* minor_version */
Packit a38265
  info->profile = dirac_uint( &bs ); /* profile */
Packit a38265
  info->level = dirac_uint( &bs ); /* level */
Packit a38265
  info->video_format = video_format = dirac_uint( &bs ); /* index */
Packit a38265
Packit a38265
  if (video_format >= (sizeof(dirac_fsize_tbl) / sizeof(dirac_fsize_tbl[0]))) {
Packit a38265
    return -1; 
Packit a38265
  }
Packit a38265
Packit a38265
  info->width = dirac_fsize_tbl[video_format].width;
Packit a38265
  info->height = dirac_fsize_tbl[video_format].height;
Packit a38265
  if (dirac_bool( &bs )) {
Packit a38265
    info->width = dirac_uint( &bs ); /* frame_width */
Packit a38265
    info->height = dirac_uint( &bs ); /* frame_height */
Packit a38265
  }
Packit a38265
Packit a38265
  if (dirac_bool( &bs )) {
Packit a38265
    info->chroma_format = dirac_uint( &bs ); /* chroma_format */
Packit a38265
  }
Packit a38265
Packit a38265
  if (dirac_bool( &bs )) { /* custom_scan_format_flag */
Packit a38265
    int scan_format = dirac_uint( &bs ); /* scan_format */
Packit a38265
    if (scan_format < 2) {
Packit a38265
      info->interlaced = scan_format;
Packit a38265
    } else { /* other scan_format values are reserved */
Packit a38265
      info->interlaced = 0;
Packit a38265
    }
Packit a38265
  } else { /* no custom scan_format, use the preset value */
Packit a38265
    info->interlaced = dirac_source_sampling[video_format];
Packit a38265
  }
Packit a38265
  /* field order is set by video_format and cannot be custom */
Packit a38265
  info->top_field_first = dirac_top_field_first[video_format];
Packit a38265
Packit a38265
  info->fps_numerator = dirac_frate_tbl[dirac_vidfmt_frate[video_format]].fps_numerator;
Packit a38265
  info->fps_denominator = dirac_frate_tbl[dirac_vidfmt_frate[video_format]].fps_denominator;
Packit a38265
  if (dirac_bool( &bs )) {
Packit a38265
    ogg_uint32_t frame_rate_index = dirac_uint( &bs );
Packit a38265
    info->fps_numerator = dirac_frate_tbl[frame_rate_index].fps_numerator;
Packit a38265
    info->fps_denominator = dirac_frate_tbl[frame_rate_index].fps_denominator;
Packit a38265
    if (frame_rate_index == 0) {
Packit a38265
      info->fps_numerator = dirac_uint( &bs );
Packit a38265
      info->fps_denominator = dirac_uint( &bs );
Packit a38265
    }
Packit a38265
  }
Packit a38265
Packit a38265
  return 0;
Packit a38265
}