Beispiel #1
0
/** As certs_cell_cert_parse(), but do not allocate the output object.
 */
static ssize_t
certs_cell_cert_parse_into(certs_cell_cert_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u8 cert_type */
  CHECK_REMAINING(1, truncated);
  obj->cert_type = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;

  /* Parse u16 cert_len */
  CHECK_REMAINING(2, truncated);
  obj->cert_len = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;

  /* Parse u8 body[cert_len] */
  CHECK_REMAINING(obj->cert_len, truncated);
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->body, obj->cert_len, {});
  obj->body.n_ = obj->cert_len;
  memcpy(obj->body.elts_, ptr, obj->cert_len);
  ptr += obj->cert_len; remaining -= obj->cert_len;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
}
Beispiel #2
0
/** As trn_cell_introduce1_parse(), but do not allocate the output
 * object.
 */
static ssize_t
trn_cell_introduce1_parse_into(trn_cell_introduce1_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u8 legacy_key_id[TRUNNEL_SHA1_LEN] */
  CHECK_REMAINING(TRUNNEL_SHA1_LEN, truncated);
  memcpy(obj->legacy_key_id, ptr, TRUNNEL_SHA1_LEN);
  remaining -= TRUNNEL_SHA1_LEN; ptr += TRUNNEL_SHA1_LEN;

  /* Parse u8 auth_key_type IN [0, 1, 2] */
  CHECK_REMAINING(1, truncated);
  obj->auth_key_type = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;
  if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2))
    goto fail;

  /* Parse u16 auth_key_len */
  CHECK_REMAINING(2, truncated);
  obj->auth_key_len = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;

  /* Parse u8 auth_key[auth_key_len] */
  CHECK_REMAINING(obj->auth_key_len, truncated);
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->auth_key, obj->auth_key_len, {});
  obj->auth_key.n_ = obj->auth_key_len;
  if (obj->auth_key_len)
    memcpy(obj->auth_key.elts_, ptr, obj->auth_key_len);
  ptr += obj->auth_key_len; remaining -= obj->auth_key_len;

  /* Parse struct trn_cell_extension extensions */
  result = trn_cell_extension_parse(&obj->extensions, ptr, remaining);
  if (result < 0)
    goto relay_fail;
  trunnel_assert((size_t)result <= remaining);
  remaining -= result; ptr += result;

  /* Parse u8 encrypted[] */
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->encrypted, remaining, {});
  obj->encrypted.n_ = remaining;
  if (remaining)
    memcpy(obj->encrypted.elts_, ptr, remaining);
  ptr += remaining; remaining -= remaining;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 relay_fail:
  trunnel_assert(result < 0);
  return result;
 trunnel_alloc_failed:
  return -1;
 fail:
  result = -1;
  return result;
}
Beispiel #3
0
/** As trn_cell_introduce_ack_parse(), but do not allocate the output
 * object.
 */
static ssize_t
trn_cell_introduce_ack_parse_into(trn_cell_introduce_ack_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u16 status IN [0, 1, 2] */
  CHECK_REMAINING(2, truncated);
  obj->status = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;
  if (! (obj->status == 0 || obj->status == 1 || obj->status == 2))
    goto fail;

  /* Parse struct trn_cell_extension extensions */
  result = trn_cell_extension_parse(&obj->extensions, ptr, remaining);
  if (result < 0)
    goto relay_fail;
  trunnel_assert((size_t)result <= remaining);
  remaining -= result; ptr += result;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 relay_fail:
  trunnel_assert(result < 0);
  return result;
 fail:
  result = -1;
  return result;
}
Beispiel #4
0
/** As trn_cell_rendezvous1_parse(), but do not allocate the output
 * object.
 */
static ssize_t
trn_cell_rendezvous1_parse_into(trn_cell_rendezvous1_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u8 rendezvous_cookie[TRUNNEL_REND_COOKIE_LEN] */
  CHECK_REMAINING(TRUNNEL_REND_COOKIE_LEN, truncated);
  memcpy(obj->rendezvous_cookie, ptr, TRUNNEL_REND_COOKIE_LEN);
  remaining -= TRUNNEL_REND_COOKIE_LEN; ptr += TRUNNEL_REND_COOKIE_LEN;

  /* Parse u8 handshake_info[] */
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->handshake_info, remaining, {});
  obj->handshake_info.n_ = remaining;
  if (remaining)
    memcpy(obj->handshake_info.elts_, ptr, remaining);
  ptr += remaining; remaining -= remaining;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
}
/**
 * gst_mpeg4_parse_group_of_vop:
 * @gov: The #GstMpeg4GroupOfVOP structure to fill
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses @data containing the group of video object plane packet, and fills
 * the @gov structure.
 *
 * Returns: a #GstMpeg4ParseResult
 */
GstMpeg4ParseResult
gst_mpeg4_parse_group_of_vop (GstMpeg4GroupOfVOP *
    gov, const guint8 * data, gsize size)
{
  guint8 gov_start_code;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (gov != NULL, GST_MPEG4_PARSER_ERROR);

  READ_UINT8 (&br, gov_start_code, 8);
  if (gov_start_code != GST_MPEG4_GROUP_OF_VOP)
    goto wrong_start_code;

  CHECK_REMAINING (&br, 65);

  gov->hours = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
  gov->minutes = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
  /* marker bit */
  MARKER_UNCHECKED (&br);
  gov->seconds = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);

  gov->closed = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  gov->broken_link = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

  return GST_MPEG4_PARSER_OK;

failed:
  GST_WARNING ("failed parsing \"Group of Video Object Plane\"");
  return GST_MPEG4_PARSER_ERROR;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto failed;
}
Beispiel #6
0
/** As rsa_ed_crosscert_parse(), but do not allocate the output
 * object.
 */
static ssize_t
rsa_ed_crosscert_parse_into(rsa_ed_crosscert_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u8 ed_key[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->ed_key, ptr, 32);
  remaining -= 32; ptr += 32;

  /* Parse u32 expiration */
  CHECK_REMAINING(4, truncated);
  obj->expiration = trunnel_ntohl(trunnel_get_uint32(ptr));
  remaining -= 4; ptr += 4;
  obj->end_of_signed = ptr;

  /* Parse u8 sig_len */
  CHECK_REMAINING(1, truncated);
  obj->sig_len = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;

  /* Parse u8 sig[sig_len] */
  CHECK_REMAINING(obj->sig_len, truncated);
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {});
  obj->sig.n_ = obj->sig_len;
  if (obj->sig_len)
    memcpy(obj->sig.elts_, ptr, obj->sig_len);
  ptr += obj->sig_len; remaining -= obj->sig_len;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
}
Beispiel #7
0
/** As auth_challenge_cell_parse(), but do not allocate the output
 * object.
 */
static ssize_t
auth_challenge_cell_parse_into(auth_challenge_cell_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u8 challenge[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->challenge, ptr, 32);
  remaining -= 32; ptr += 32;

  /* Parse u16 n_methods */
  CHECK_REMAINING(2, truncated);
  obj->n_methods = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;

  /* Parse u16 methods[n_methods] */
  TRUNNEL_DYNARRAY_EXPAND(uint16_t, &obj->methods, obj->n_methods, {});
  {
    uint16_t elt;
    unsigned idx;
    for (idx = 0; idx < obj->n_methods; ++idx) {
      CHECK_REMAINING(2, truncated);
      elt = trunnel_ntohs(trunnel_get_uint16(ptr));
      remaining -= 2; ptr += 2;
      TRUNNEL_DYNARRAY_ADD(uint16_t, &obj->methods, elt, {});
    }
  }
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
}
Beispiel #8
0
/** As trn_cell_rendezvous2_parse(), but do not allocate the output
 * object.
 */
static ssize_t
trn_cell_rendezvous2_parse_into(trn_cell_rendezvous2_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u8 handshake_info[TRUNNEL_HANDSHAKE_INFO_LEN] */
  CHECK_REMAINING(TRUNNEL_HANDSHAKE_INFO_LEN, truncated);
  memcpy(obj->handshake_info, ptr, TRUNNEL_HANDSHAKE_INFO_LEN);
  remaining -= TRUNNEL_HANDSHAKE_INFO_LEN; ptr += TRUNNEL_HANDSHAKE_INFO_LEN;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
}
Beispiel #9
0
/** As auth1_parse(), but do not allocate the output object.
 */
static ssize_t
auth1_parse_into(auth1_t *obj, const uint8_t *input, const size_t len_in, const auth_ctx_t *auth_ctx_ctx)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;
  if (auth_ctx_ctx == NULL)
    return -1;

  /* Parse u8 type[8] */
  CHECK_REMAINING(8, truncated);
  memcpy(obj->type, ptr, 8);
  remaining -= 8; ptr += 8;

  /* Parse u8 cid[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->cid, ptr, 32);
  remaining -= 32; ptr += 32;

  /* Parse u8 sid[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->sid, ptr, 32);
  remaining -= 32; ptr += 32;

  /* Parse union u1[auth_ctx.is_ed] */
  switch (auth_ctx_ctx->is_ed) {

    case 0:
      break;

    case 1:

      /* Parse u8 u1_cid_ed[32] */
      CHECK_REMAINING(32, truncated);
      memcpy(obj->u1_cid_ed, ptr, 32);
      remaining -= 32; ptr += 32;

      /* Parse u8 u1_sid_ed[32] */
      CHECK_REMAINING(32, truncated);
      memcpy(obj->u1_sid_ed, ptr, 32);
      remaining -= 32; ptr += 32;
      break;

    default:
      goto fail;
      break;
  }

  /* Parse u8 slog[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->slog, ptr, 32);
  remaining -= 32; ptr += 32;

  /* Parse u8 clog[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->clog, ptr, 32);
  remaining -= 32; ptr += 32;

  /* Parse u8 scert[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->scert, ptr, 32);
  remaining -= 32; ptr += 32;

  /* Parse u8 tlssecrets[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->tlssecrets, ptr, 32);
  remaining -= 32; ptr += 32;
  obj->end_of_fixed_part = ptr;

  /* Parse u8 rand[24] */
  CHECK_REMAINING(24, truncated);
  memcpy(obj->rand, ptr, 24);
  remaining -= 24; ptr += 24;
  obj->end_of_signed = ptr;

  /* Parse u8 sig[] */
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, remaining, {});
  obj->sig.n_ = remaining;
  memcpy(obj->sig.elts_, ptr, remaining);
  ptr += remaining; remaining -= remaining;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
 fail:
  result = -1;
  return result;
}
/**
 * gst_mpeg4_parse_video_object_layer:
 * @vol: The #GstMpeg4VideoObjectLayer structure to fill
 * @vo: The #GstMpeg4VisualObject currently being parsed or %NULL
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses @data containing the video object layer packet, and fills
 * the @vol structure.
 *
 * Returns: a #GstMpeg4ParseResult
 */
GstMpeg4ParseResult
gst_mpeg4_parse_video_object_layer (GstMpeg4VideoObjectLayer * vol,
    GstMpeg4VisualObject * vo, const guint8 * data, gsize size)
{
  guint8 video_object_layer_start_code;

  /* Used for enums types */
  guint8 tmp;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);

  GST_DEBUG ("Parsing video object layer");

  READ_UINT8 (&br, video_object_layer_start_code, 8);
  if (!(video_object_layer_start_code >= GST_MPEG4_VIDEO_LAYER_FIRST &&
          video_object_layer_start_code <= GST_MPEG4_VIDEO_LAYER_LAST))
    goto wrong_start_code;

  /* set default values */
  if (vo) {
    vol->verid = vo->verid;
    vol->priority = vo->priority;
  } else {
    vol->verid = 1;
    vol->priority = 0;
  }

  vol->low_delay = FALSE;
  vol->chroma_format = 1;
  vol->vbv_parameters = FALSE;
  vol->quant_precision = 5;
  vol->bits_per_pixel = 8;
  vol->quarter_sample = FALSE;
  vol->newpred_enable = FALSE;
  vol->interlaced = 0;
  vol->width = 0;
  vol->height = 0;

  READ_UINT8 (&br, vol->random_accessible_vol, 1);
  READ_UINT8 (&br, vol->video_object_type_indication, 8);

  READ_UINT8 (&br, vol->is_object_layer_identifier, 1);
  if (vol->is_object_layer_identifier) {
    READ_UINT8 (&br, vol->verid, 4);
    READ_UINT8 (&br, vol->priority, 3);
  }

  READ_UINT8 (&br, tmp, 4);
  vol->aspect_ratio_info = tmp;
  if (vol->aspect_ratio_info != GST_MPEG4_EXTENDED_PAR) {
    mpeg4_util_par_from_info (vol->aspect_ratio_info, &vol->par_width,
        &vol->par_height);

  } else {
    gint v;

    READ_UINT8 (&br, vol->par_width, 8);
    v = vol->par_width;
    CHECK_ALLOWED (v, 1, 255);

    READ_UINT8 (&br, vol->par_height, 8);
    v = vol->par_height;
    CHECK_ALLOWED (v, 1, 255);
  }
  GST_DEBUG ("Pixel aspect ratio %d/%d", vol->par_width, vol->par_width);

  READ_UINT8 (&br, vol->control_parameters, 1);
  if (vol->control_parameters) {
    guint8 chroma_format;

    READ_UINT8 (&br, chroma_format, 2);
    vol->chroma_format = chroma_format;
    READ_UINT8 (&br, vol->low_delay, 1);

    READ_UINT8 (&br, vol->vbv_parameters, 1);
    if (vol->vbv_parameters) {
      CHECK_REMAINING (&br, 79);

      vol->first_half_bitrate =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
      MARKER_UNCHECKED (&br);

      vol->latter_half_bitrate =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
      MARKER_UNCHECKED (&br);

      vol->bit_rate =
          (vol->first_half_bitrate << 15) | vol->latter_half_bitrate;

      vol->first_half_vbv_buffer_size =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
      MARKER_UNCHECKED (&br);

      vol->latter_half_vbv_buffer_size =
          gst_bit_reader_get_bits_uint8_unchecked (&br, 3);

      vol->vbv_buffer_size = (vol->first_half_vbv_buffer_size << 15) |
          vol->latter_half_vbv_buffer_size;

      vol->first_half_vbv_occupancy =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 11);
      MARKER_UNCHECKED (&br);

      vol->latter_half_vbv_occupancy =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
      MARKER_UNCHECKED (&br);
    }
  }

  READ_UINT8 (&br, tmp, 2);
  vol->shape = tmp;

  if (vol->shape == GST_MPEG4_GRAYSCALE) {
    /* TODO support grayscale shapes, for now we just pass */

    /* Something the standard starts to define... */
    GST_WARNING ("Grayscale shaped not supported");
    goto failed;
  }

  if (vol->shape == GST_MPEG4_GRAYSCALE && vol->verid != 0x01)
    READ_UINT8 (&br, vol->shape_extension, 4);

  CHECK_REMAINING (&br, 19);

  MARKER_UNCHECKED (&br);
  vol->vop_time_increment_resolution =
      gst_bit_reader_get_bits_uint16_unchecked (&br, 16);
  if (vol->vop_time_increment_resolution < 1) {
    GST_WARNING ("value not in allowed range. value: %d, range %d-%d",
        vol->vop_time_increment_resolution, 1, G_MAXUINT16);
    goto failed;
  }
  vol->vop_time_increment_bits =
      g_bit_storage (vol->vop_time_increment_resolution);

  MARKER_UNCHECKED (&br);
  vol->fixed_vop_rate = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  if (vol->fixed_vop_rate)
    READ_UINT16 (&br, vol->fixed_vop_time_increment,
        vol->vop_time_increment_bits);

  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
    if (vol->shape == GST_MPEG4_RECTANGULAR) {
      CHECK_REMAINING (&br, 29);

      MARKER_UNCHECKED (&br);
      vol->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);
      vol->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);
    }

    READ_UINT8 (&br, vol->interlaced, 1);
    READ_UINT8 (&br, vol->obmc_disable, 1);

    if (vol->verid == 0x1)
      READ_UINT8 (&br, tmp, 1);
    else
      READ_UINT8 (&br, tmp, 2);
    vol->sprite_enable = tmp;

    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
        vol->sprite_enable == GST_MPEG4_SPRITE_GMG) {

      if (vol->sprite_enable == GST_MPEG4_SPRITE_GMG)
        CHECK_REMAINING (&br, 9);
      else {
        CHECK_REMAINING (&br, 65);

        vol->sprite_width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
        MARKER_UNCHECKED (&br);

        vol->sprite_height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
        MARKER_UNCHECKED (&br);

        vol->sprite_left_coordinate =
            gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
        MARKER_UNCHECKED (&br);

        vol->sprite_top_coordinate =
            gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
        MARKER_UNCHECKED (&br);
      }
      vol->no_of_sprite_warping_points =
          gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
      vol->sprite_warping_accuracy =
          gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
      vol->sprite_brightness_change =
          gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

      if (vol->sprite_enable != GST_MPEG4_SPRITE_GMG)
        vol->low_latency_sprite_enable =
            gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
    }

    if (vol->verid != 0x1 && vol->shape != GST_MPEG4_RECTANGULAR)
      READ_UINT8 (&br, vol->sadct_disable, 1);

    READ_UINT8 (&br, vol->not_8_bit, 1);
    if (vol->not_8_bit) {
      READ_UINT8 (&br, vol->quant_precision, 4);
      CHECK_ALLOWED (vol->quant_precision, 3, 9);

      READ_UINT8 (&br, vol->bits_per_pixel, 4);
      CHECK_ALLOWED (vol->bits_per_pixel, 4, 12);
    }

    if (vol->shape == GST_MPEG4_GRAYSCALE) {
      /* We don't actually support it */
      READ_UINT8 (&br, vol->no_gray_quant_update, 1);
      READ_UINT8 (&br, vol->composition_method, 1);
      READ_UINT8 (&br, vol->linear_composition, 1);
    }

    READ_UINT8 (&br, vol->quant_type, 1);
    if (vol->quant_type) {
      if (!parse_quant (&br, vol->intra_quant_mat, default_intra_quant_mat,
              &vol->load_intra_quant_mat))
        goto failed;

      if (!parse_quant (&br, vol->non_intra_quant_mat,
              default_non_intra_quant_mat, &vol->load_non_intra_quant_mat))
        goto failed;

      if (vol->shape == GST_MPEG4_GRAYSCALE) {
        /* Something the standard starts to define... */
        GST_WARNING ("Grayscale shaped not supported");
        goto failed;
      }

    } else {
      memset (&vol->intra_quant_mat, 0, 64);
      memset (&vol->non_intra_quant_mat, 0, 64);
    }

    if (vol->verid != 0x1)
      READ_UINT8 (&br, vol->quarter_sample, 1);

    READ_UINT8 (&br, vol->complexity_estimation_disable, 1);
    if (!vol->complexity_estimation_disable) {
      guint8 estimation_method;
      guint8 estimation_disable;

      /* skip unneeded properties */
      READ_UINT8 (&br, estimation_method, 2);
      if (estimation_method < 2) {
        READ_UINT8 (&br, estimation_disable, 1);
        if (!estimation_disable)
          SKIP (&br, 6);
        READ_UINT8 (&br, estimation_disable, 1);
        if (!estimation_disable)
          SKIP (&br, 4);
        CHECK_MARKER (&br);
        READ_UINT8 (&br, estimation_disable, 1);
        if (!estimation_disable)
          SKIP (&br, 4);
        READ_UINT8 (&br, estimation_disable, 1);
        if (!estimation_disable)
          SKIP (&br, 6);
        CHECK_MARKER (&br);

        if (estimation_method == 1) {
          READ_UINT8 (&br, estimation_disable, 1);
          if (!estimation_disable)
            SKIP (&br, 2);
        }
      }
    }

    READ_UINT8 (&br, vol->resync_marker_disable, 1);
    READ_UINT8 (&br, vol->data_partitioned, 1);

    if (vol->data_partitioned)
      READ_UINT8 (&br, vol->reversible_vlc, 1);

    if (vol->verid != 0x01) {
      READ_UINT8 (&br, vol->newpred_enable, 1);
      if (vol->newpred_enable)
        /* requested_upstream_message_type and newpred_segment_type */
        SKIP (&br, 3);

      READ_UINT8 (&br, vol->reduced_resolution_vop_enable, 1);
    }

    READ_UINT8 (&br, vol->scalability, 1);
    if (vol->scalability) {
      SKIP (&br, 26);           /* Few not needed props */
      READ_UINT8 (&br, vol->enhancement_type, 1);
    }

    /* More unused infos */
  } else if (vol->verid != 0x01) {
    GST_WARNING ("Binary only shapes not fully supported");
    goto failed;
  }
  /* ... */

  return GST_MPEG4_PARSER_OK;

failed:
  GST_WARNING ("failed parsing \"Video Object Layer\"");
  return GST_MPEG4_PARSER_ERROR;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto failed;
}
/**
 * gst_mpeg4_parse_video_packet_header:
 * @videopackethdr: The #GstMpeg4VideoPacketHdr structure to fill
 * @vol: The last parsed #GstMpeg4VideoObjectLayer, will be updated
 * with the informations found during the parsing
 * @vop: The last parsed #GstMpeg4VideoObjectPlane, will be updated
 * with the informations found during the parsing
 * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
 * with the informations found during the parsing
 * @data: The data to parse, should be set after the resync marker.
 * @size: The size of the data to parse
 *
 * Parsers @data containing the video packet header
 * and fills the @videopackethdr structure
 */
GstMpeg4ParseResult
gst_mpeg4_parse_video_packet_header (GstMpeg4VideoPacketHdr * videopackethdr,
    GstMpeg4VideoObjectLayer * vol, GstMpeg4VideoObjectPlane * vop,
    GstMpeg4SpriteTrajectory * sprite_trajectory, const guint8 * data,
    gsize size)
{
  guint8 markersize;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (videopackethdr != NULL, GST_MPEG4_PARSER_ERROR);
  g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);

  markersize = compute_resync_marker_size (vop, NULL, NULL);

  CHECK_REMAINING (&br, markersize);

  if (gst_bit_reader_get_bits_uint32_unchecked (&br, markersize) != 0x01)
    goto failed;

  if (vol->shape != GST_MPEG4_RECTANGULAR) {
    READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
        vop->coding_type == GST_MPEG4_I_VOP) {

      CHECK_REMAINING (&br, 56);

      U_READ_UINT16 (&br, vop->width, 13);
      CHECK_MARKER (&br);
      U_READ_UINT16 (&br, vop->height, 13);
      CHECK_MARKER (&br);
      U_READ_UINT16 (&br, vop->horizontal_mc_spatial_ref, 13);
      CHECK_MARKER (&br);
      U_READ_UINT16 (&br, vop->vertical_mc_spatial_ref, 13);
      CHECK_MARKER (&br);

      /* Update macroblock infirmations */
      vop->mb_height = (vop->height + 15) / 16;
      vop->mb_width = (vop->width + 15) / 16;
      vop->mb_num = vop->mb_height * vop->mb_width;
    }
  }

  READ_UINT16 (&br, videopackethdr->macroblock_number,
      g_bit_storage (vop->mb_num - 1));

  if (vol->shape != GST_MPEG4_BINARY_ONLY)
    READ_UINT16 (&br, videopackethdr->quant_scale, vol->quant_precision);

  if (vol->shape == GST_MPEG4_RECTANGULAR)
    READ_UINT8 (&br, videopackethdr->header_extension_code, 1);

  if (videopackethdr->header_extension_code) {
    guint timeincr = 0;
    guint8 bit = 0, coding_type;

    do {
      READ_UINT8 (&br, bit, 1);
      timeincr++;
    } while (bit);

    vol->vop_time_increment_bits = timeincr;

    CHECK_MARKER (&br);
    READ_UINT16 (&br, vop->time_increment, timeincr);
    CHECK_MARKER (&br);
    READ_UINT8 (&br, coding_type, 2);
    vop->coding_type = coding_type;

    if (vol->shape != GST_MPEG4_RECTANGULAR) {
      READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
      if (vop->coding_type != GST_MPEG4_I_VOP)
        READ_UINT8 (&br, vop->shape_coding_type, 1);
    }

    if (vol->shape != GST_MPEG4_BINARY_ONLY) {
      READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);

      if (sprite_trajectory && vol->sprite_enable == GST_MPEG4_SPRITE_GMG &&
          vop->coding_type == GST_MPEG4_S_VOP &&
          vol->no_of_sprite_warping_points > 0) {

        parse_sprite_trajectory (&br, sprite_trajectory,
            vol->no_of_sprite_warping_points);
      }

      if (vol->reduced_resolution_vop_enable &&
          vol->shape == GST_MPEG4_RECTANGULAR &&
          (vop->coding_type == GST_MPEG4_P_VOP ||
              vop->coding_type == GST_MPEG4_I_VOP))
        READ_UINT8 (&br, vop->reduced_resolution, 1);

      if (vop->coding_type != GST_MPEG4_I_VOP) {
        READ_UINT8 (&br, vop->fcode_forward, 3);
        CHECK_ALLOWED (vop->fcode_forward, 1, 7);
      }

      if (vop->coding_type == GST_MPEG4_B_VOP) {
        READ_UINT8 (&br, vop->fcode_backward, 3);
        CHECK_ALLOWED (vop->fcode_backward, 1, 7);
      }
    }
  }

  if (vol->newpred_enable) {
    guint16 nbbits =
        vol->vop_time_increment_bits + 3 < 15 ? vop->time_increment + 3 : 15;

    READ_UINT16 (&br, vop->id, nbbits);
    READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
    if (vop->id_for_prediction_indication) {
      /* Would be nice if the standard actually told us... */
      READ_UINT16 (&br, vop->id, nbbits);
      CHECK_MARKER (&br);
    }
  }

  videopackethdr->size = gst_bit_reader_get_pos (&br);

failed:
  GST_DEBUG ("Failed to parse video packet header");

  return GST_MPEG4_PARSER_NO_PACKET;
}
/**
 * gst_mpeg4_parse_video_object_plane:
 * @vop: The #GstMpeg4VideoObjectPlane currently being parsed
 * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
 * @vol: The #GstMpeg4VideoObjectLayer structure to fill
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses @data containing the video object plane packet, and fills the @vol
 * structure.
 *
 * Returns: a #GstMpeg4ParseResult
 */
GstMpeg4ParseResult
gst_mpeg4_parse_video_object_plane (GstMpeg4VideoObjectPlane * vop,
    GstMpeg4SpriteTrajectory * sprite_trajectory,
    GstMpeg4VideoObjectLayer * vol, const guint8 * data, gsize size)
{
  guint8 vop_start_code, coding_type, modulo_time_base;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);

  if (vol->shape == GST_MPEG4_BINARY_ONLY) {
    /* TODO: implement binary only shapes */
    GST_WARNING ("Binary only shapes not supported");
    goto failed;
  }

  READ_UINT8 (&br, vop_start_code, 8);
  if (vop_start_code != GST_MPEG4_VIDEO_OBJ_PLANE)
    goto wrong_start_code;


  /* set default values */
  vop->modulo_time_base = 0;
  vop->rounding_type = 0;
  vop->top_field_first = 1;
  vop->alternate_vertical_scan_flag = 0;
  vop->fcode_forward = 1;
  vop->fcode_backward = 1;

  /*  Compute macroblock informations */
  if (vol->interlaced)
    vop->mb_height = (2 * (vol->height + 31) / 32);
  else
    vop->mb_height = (vol->height + 15) / 16;

  vop->mb_width = (vol->width + 15) / 16;
  vop->mb_num = vop->mb_height * vop->mb_width;

  READ_UINT8 (&br, coding_type, 2);
  vop->coding_type = coding_type;

  READ_UINT8 (&br, modulo_time_base, 1);
  while (modulo_time_base) {
    vop->modulo_time_base++;

    READ_UINT8 (&br, modulo_time_base, 1);
  }

  CHECK_REMAINING (&br, vol->vop_time_increment_bits + 3);

  MARKER_UNCHECKED (&br);
  vop->time_increment =
      gst_bit_reader_get_bits_uint16_unchecked (&br,
      vol->vop_time_increment_bits);
  MARKER_UNCHECKED (&br);

  vop->coded = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  if (!vop->coded)
    return GST_MPEG4_PARSER_OK;

  if (vol->newpred_enable) {
    guint16 nbbits =
        vop->time_increment + 3 < 15 ? vop->time_increment + 3 : 15;

    READ_UINT16 (&br, vop->id, nbbits);
    READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
    if (vop->id_for_prediction_indication) {
      /* Would be nice if the standard actually told us... */
      READ_UINT16 (&br, vop->id, nbbits);
      CHECK_MARKER (&br);
    }
  }

  if (vol->shape != GST_MPEG4_BINARY_ONLY &&
      (vop->coding_type == GST_MPEG4_P_VOP ||
          (vop->coding_type == GST_MPEG4_S_VOP &&
              vol->sprite_enable == GST_MPEG4_SPRITE_GMG)))
    READ_UINT8 (&br, vop->rounding_type, 1);

  if ((vol->reduced_resolution_vop_enable) &&
      (vol->shape == GST_MPEG4_RECTANGULAR ||
          (vop->coding_type = GST_MPEG4_P_VOP ||
              vop->coding_type == GST_MPEG4_I_VOP)))
    READ_UINT8 (&br, vop->reduced_resolution, 1);

  if (vol->shape != GST_MPEG4_RECTANGULAR) {
    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
        vop->coding_type == GST_MPEG4_I_VOP) {
      CHECK_REMAINING (&br, 55);

      vop->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);

      vop->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);

      vop->horizontal_mc_spatial_ref =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);

      vop->vertical_mc_spatial_ref =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);

      /* Recompute the Macroblock informations
       * accordingly to the new values */
      if (vol->interlaced)
        vop->mb_height = (2 * (vol->height + 31) / 32);
      else
        vop->mb_height = (vol->height + 15) / 16;

      vop->mb_width = (vol->width + 15) / 16;
      vop->mb_num = vop->mb_height * vop->mb_width;
    }

    if ((vol->shape != GST_MPEG4_BINARY_ONLY) &&
        vol->scalability && vol->enhancement_type)
      READ_UINT8 (&br, vop->background_composition, 1);

    READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);

    READ_UINT8 (&br, vop->constant_alpha, 1);
    if (vop->constant_alpha)
      READ_UINT8 (&br, vop->constant_alpha_value, 1);
  }

  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
    if (!vol->complexity_estimation_disable) {
      GST_WARNING ("Complexity estimation not supported");
      goto failed;
    }

    READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);

    if (vol->interlaced) {
      READ_UINT8 (&br, vop->top_field_first, 1);
      READ_UINT8 (&br, vop->alternate_vertical_scan_flag, 1);
    }
  }

  if ((vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
          vol->sprite_enable == GST_MPEG4_SPRITE_GMG) &&
      vop->coding_type == GST_MPEG4_S_VOP) {

    /* only if @sprite_trajectory is not NULL we parse it */
    if (sprite_trajectory && vol->no_of_sprite_warping_points)
      parse_sprite_trajectory (&br, sprite_trajectory,
          vol->no_of_sprite_warping_points);

    if (vol->sprite_brightness_change) {
      GST_WARNING ("sprite_brightness_change not supported");
      goto failed;
    }

    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC) {
      GST_WARNING ("sprite enable static not supported");
      goto failed;
    }
  }

  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
    READ_UINT16 (&br, vop->quant, vol->quant_precision);

    if (vol->shape == GST_MPEG4_GRAYSCALE) {
      /* TODO implement grayscale support */
      GST_WARNING ("Grayscale shapes no supported");

      /* TODO implement me */
      goto failed;
    }

    if (vop->coding_type != GST_MPEG4_I_VOP) {
      READ_UINT8 (&br, vop->fcode_forward, 3);
      CHECK_ALLOWED (vop->fcode_forward, 1, 7);
    }

    if (vop->coding_type == GST_MPEG4_B_VOP) {
      READ_UINT8 (&br, vop->fcode_backward, 3);
      CHECK_ALLOWED (vop->fcode_backward, 1, 7);
    }
  }

  if (!vol->scalability) {
    if (vol->shape != GST_MPEG4_RECTANGULAR)
      READ_UINT8 (&br, vop->shape_coding_type, 1);

  } else {
    if (vol->enhancement_type) {
      READ_UINT8 (&br, vop->load_backward_shape, 1);

      if (vop->load_backward_shape) {
        GST_WARNING ("Load backward shape not supported");
        goto failed;
      }

      READ_UINT8 (&br, vop->ref_select_code, 2);
    }
  }

  vop->size = gst_bit_reader_get_pos (&br);
  /* More things to possibly parse ... */

  return GST_MPEG4_PARSER_OK;

failed:
  GST_WARNING ("failed parsing \"Video Object Plane\"");
  return GST_MPEG4_PARSER_ERROR;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto failed;
}
Beispiel #13
0
/** As pwbox_encoded_parse(), but do not allocate the output object.
 */
static ssize_t
pwbox_encoded_parse_into(pwbox_encoded_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u32 fixedbytes0 IN [PWBOX0_CONST0] */
  CHECK_REMAINING(4, truncated);
  obj->fixedbytes0 = trunnel_ntohl(trunnel_get_uint32(ptr));
  remaining -= 4; ptr += 4;
  if (! (obj->fixedbytes0 == PWBOX0_CONST0))
    goto fail;

  /* Parse u32 fixedbytes1 IN [PWBOX0_CONST1] */
  CHECK_REMAINING(4, truncated);
  obj->fixedbytes1 = trunnel_ntohl(trunnel_get_uint32(ptr));
  remaining -= 4; ptr += 4;
  if (! (obj->fixedbytes1 == PWBOX0_CONST1))
    goto fail;

  /* Parse u8 header_len */
  CHECK_REMAINING(1, truncated);
  obj->header_len = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;

  /* Parse u8 skey_header[header_len] */
  CHECK_REMAINING(obj->header_len, truncated);
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->skey_header, obj->header_len, {});
  obj->skey_header.n_ = obj->header_len;
  memcpy(obj->skey_header.elts_, ptr, obj->header_len);
  ptr += obj->header_len; remaining -= obj->header_len;

  /* Parse u8 iv[16] */
  CHECK_REMAINING(16, truncated);
  memcpy(obj->iv, ptr, 16);
  remaining -= 16; ptr += 16;
  {
    size_t remaining_after;
    CHECK_REMAINING(32, truncated);
    remaining_after = 32;
    remaining = remaining - 32;

    /* Parse u8 data[] */
    TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->data, remaining, {});
    obj->data.n_ = remaining;
    memcpy(obj->data.elts_, ptr, remaining);
    ptr += remaining; remaining -= remaining;
    if (remaining != 0)
      goto fail;
    remaining = remaining_after;
  }

  /* Parse u8 hmac[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->hmac, ptr, 32);
  remaining -= 32; ptr += 32;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
 fail:
  result = -1;
  return result;
}
Beispiel #14
0
/** As ed25519_cert_extension_parse(), but do not allocate the output
 * object.
 */
static ssize_t
ed25519_cert_extension_parse_into(ed25519_cert_extension_t *obj, const uint8_t *input, const size_t len_in)
{
  const uint8_t *ptr = input;
  size_t remaining = len_in;
  ssize_t result = 0;
  (void)result;

  /* Parse u16 ext_length */
  CHECK_REMAINING(2, truncated);
  obj->ext_length = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;

  /* Parse u8 ext_type */
  CHECK_REMAINING(1, truncated);
  obj->ext_type = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;

  /* Parse u8 ext_flags */
  CHECK_REMAINING(1, truncated);
  obj->ext_flags = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;
  {
    size_t remaining_after;
    CHECK_REMAINING(obj->ext_length, truncated);
    remaining_after = remaining - obj->ext_length;
    remaining = obj->ext_length;

    /* Parse union un[ext_type] */
    switch (obj->ext_type) {

      case CERTEXT_SIGNED_WITH_KEY:

        /* Parse u8 un_signing_key[32] */
        CHECK_REMAINING(32, fail);
        memcpy(obj->un_signing_key, ptr, 32);
        remaining -= 32; ptr += 32;
        break;

      default:

        /* Parse u8 un_unparsed[] */
        TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->un_unparsed, remaining, {});
        obj->un_unparsed.n_ = remaining;
        memcpy(obj->un_unparsed.elts_, ptr, remaining);
        ptr += remaining; remaining -= remaining;
        break;
    }
    if (remaining != 0)
      goto fail;
    remaining = remaining_after;
  }
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
 fail:
  result = -1;
  return result;
}