예제 #1
0
파일: ps_reader.c 프로젝트: ms-iot/userland
static VC_CONTAINER_STATUS_T ps_read_system_header( VC_CONTAINER_T *ctx )
{
   uint8_t header[8];
   uint32_t length;
   VC_CONTAINER_BITS_T bits;

   if(_READ_U32(ctx) != 0x1BB) return VC_CONTAINER_ERROR_CORRUPTED;
   LOG_FORMAT(ctx, "system_header");
   ctx->priv->module->level++;

   length = READ_U16(ctx, "header_length");
   if(length < 6) return VC_CONTAINER_ERROR_CORRUPTED;
   if(READ_BYTES(ctx, header, 6) != 6) return VC_CONTAINER_ERROR_EOS;

   BITS_INIT(ctx, &bits, header, 6);

   if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
   BITS_SKIP(ctx, &bits, 22, "rate_bound");
   if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
   BITS_SKIP(ctx, &bits, 6, "audio_bound");
   BITS_SKIP(ctx, &bits, 1, "fixed_flag");
   BITS_SKIP(ctx, &bits, 1, "CSPS_flag");
   BITS_SKIP(ctx, &bits, 1, "system_audio_lock_flag");
   BITS_SKIP(ctx, &bits, 1, "system_video_lock_flag");
   if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
   BITS_SKIP(ctx, &bits, 5, "video_bound");
   BITS_SKIP(ctx, &bits, 1, "packet_rate_restriction_flag");
   BITS_SKIP(ctx, &bits, 7, "reserved_bits");
   length -= 6;

   while(length >= 3 && (PEEK_U8(ctx) & 0x80))
   {
      SKIP_U8(ctx, "stream_id");
      SKIP_BYTES(ctx, 2);
      length -= 3;
   }
   SKIP_BYTES(ctx, length);

   ctx->priv->module->level--;
   return STREAM_STATUS(ctx);
}
예제 #2
0
/*****************************************************************************
 * FUNCTION
 *  image_gif_get_frame_count
 * DESCRIPTION
 *  get frame count of a gif from file
 * PARAMETERS
 *  filename    [IN]
 *  framecount  [OUT]
 * RETURNS
 *  MMI_BOOL	MMI_TRUE or MMI_FALSE
 *****************************************************************************/
static MMI_BOOL image_gif_get_frame_count(S8 *filename, U32 *framecount)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    FILE *fp;
    U8 *buf, *src;
    U32 header;
    U32 file_size;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* open file and read header to buffer */
    fp = fopen((char *)filename, "rb");
    if (fp == NULL)
    {
        fprintf(stderr, "Open file error:\t%s\n", filename);
        fprintf(stderr, "\t%s\n", strerror(errno));
        return MMI_FALSE;
    }

    fseek(fp, 0, SEEK_END);
    file_size = (U32)ftell(fp);
    fseek(fp, 0, SEEK_SET);

    buf = (U8*)malloc(file_size*sizeof(U8));
    if (buf == NULL)
    {
        fprintf(stderr, "Memory allocation failed:\t%s\n", filename);
        MYFCLOSE(fp);
        return MMI_FALSE;
    }
    if (fread(buf, sizeof(char), file_size, fp) != file_size)
    {
        fprintf(stderr, "Read file error:\t%s\n", filename);
        MYFCLOSE(fp);
        return MMI_FALSE;
    }
    src = buf;
    MYFCLOSE(fp);

    /* init the return frame_count value */
    *framecount = 0;

    /* read the GIF file signature */
    {
        U8 sig[3];

        GET_U8(src, sig[0]);
        GET_U8(src, sig[1]);
        GET_U8(src, sig[2]);

        if (sig[0] != 'G' || sig[1] != 'I' || sig[2] != 'F')
        {
            return MMI_FALSE;
        }
    }

    /* skip dimension value */
    {
        S16 img_w, img_h;

        FLUSH(src, 3);
        GET_U16(src, img_w);
        GET_U16(src, img_h);
        if(img_w < 0 || img_h < 0 || img_w >= 10240 || img_h >= 10240)
        {
            return MMI_FALSE;
        }
    }

    /* read the global color palette */
    {
        S32 palette_count;

        GET_U8(src, palette_count);
        FLUSH(src, 2);


        if (palette_count & 0x80)
        {
            palette_count = 1 << ((palette_count & 0x7) + 1);
            FLUSH(src, (palette_count * 3));
        }
    }

    /* start decoding */
    do
    {
        U8 symbol;

        GET_U8(src, symbol);
        switch(symbol)
        {
        /* Process the GIF extension block */
        case '!':
        {
            U8 ext;

            GET_U8(src, ext);

            if (ext == 0xf9)
            {
                FLUSH(src, 6);
            }
            else
            {
                U8 boffset;
                S32 offset;

                while (1)
                {
                    GET_U8(src, boffset);
                    offset = (S32)boffset;
                    if (offset == 0)
                    {
                        break;
                    }
                    FLUSH(src, offset);
                }
            }
        }
        break;

        case ',':
            /* gdi_image_gif_dummy_decoder(); */
        {
            S32 want_pixels;
            S32 bitstream_available_bits, bytestream_available;
            S32 GDI_TREE_BUFFER[GDI_GIF_TREE_SIZE / sizeof(S32)];
            U32 bitstream;
            S16 GIF_current_code_size, GIF_clear_code, GIF_end_code, GIF_new_codes, GIF_top_slot, GIF_slot;
            S16 size, c, oc, fc, code;
            S16 *stack_pointer;
            S16 GIF_mtk_stack[GDI_GIF_STACK_SIZE / sizeof(S16)];
            S16 *GIF_mtk_suffix = (S16 *) GDI_TREE_BUFFER;
            S16 *GIF_mtk_prefix = (S16 *) (((U8 *) GDI_TREE_BUFFER) + sizeof(GDI_TREE_BUFFER) / 2);
            U16 temp;
            U8 finished_decoding = 0;

            {
                S32 x, y, xsize, ysize;

                GET_U16(src, temp);
                x = (S32)temp;
                GET_U16(src, temp);
                y = (S32)temp;
                GET_U16(src, temp);
                xsize = (S32)temp;
                GET_U16(src, temp);
                ysize = (S32)temp;

                want_pixels = xsize * ysize;
            }

            {
                S32 n;

                GET_U8(src, n);

                if (src >= buf + file_size)
                {
                    return MMI_FALSE;
                }

                if (n & 0x80)
                {
                    n = 1 << ((n & 0x7) + 1);

                    /* skip reading palette */
                    FLUSH(src, n * 3);
                }
            }

            GET_U8(src, temp);
            size = (S16)temp;

            /* GIF_INITIALIZE_DECODER(size);*/
            GIF_current_code_size = (S16)(size + 1);
            GIF_top_slot = (S16)(1 << GIF_current_code_size);
            GIF_clear_code = (S16)(1 << size);
            GIF_end_code = (S16)(GIF_clear_code + 1);
            GIF_slot = (GIF_new_codes) = (S16)(GIF_end_code + 1);
            bitstream_available_bits = 0;
            bytestream_available = 0;
            bitstream = 0;

            oc = fc = 0;
            stack_pointer = GIF_mtk_stack;

            /* begin decoding */
            while (!finished_decoding)
            {
                /* GIF_GET_NEXT_CODE(c); */
                while(GIF_current_code_size > bitstream_available_bits)
                {
                    if(bytestream_available == 0)
                    {
                        GET_U8(src, temp);
                        bytestream_available = (S32)temp;
                    }
                    GET_U8(src, temp);
                    bitstream |= temp << bitstream_available_bits;
                    bitstream_available_bits +=8;
                    bytestream_available--;
                }
                bitstream_available_bits -= GIF_current_code_size;
                c = (S16) bitstream & ((1 << GIF_current_code_size) - 1);
                bitstream >>= GIF_current_code_size;

                if (c == GIF_end_code)
                {
                    break;
                }

                if (src >= buf + file_size)
                {
                    return MMI_FALSE;
                }

                if (c == GIF_clear_code)
                {
                    GIF_current_code_size = (S16) (size + 1);
                    GIF_slot = GIF_new_codes;
                    GIF_top_slot = (S16) (1 << GIF_current_code_size);

                    /* GIF_GET_NEXT_CODE(c); */
                    while(GIF_current_code_size > bitstream_available_bits)
                    {
                        if(bytestream_available == 0)
                        {
                            GET_U8(src, temp);
                            bytestream_available = (S32)temp;
                        }
                        GET_U8(src, temp);
                        bitstream |= temp << bitstream_available_bits;
                        bitstream_available_bits +=8;
                        bytestream_available--;
                    }
                    bitstream_available_bits -= GIF_current_code_size;
                    c = (S16) bitstream & ((1 << GIF_current_code_size) - 1);
                    bitstream >>= GIF_current_code_size;

                    if (c == GIF_end_code)
                    {
                        break;
                    }

                    if (src >= buf + file_size)
                    {
                        return MMI_FALSE;
                    }

                    if (c >= GIF_slot)
                    {
                        c = 0;
                    }

                    oc = fc = c;
                    if ((--want_pixels) < 0)
                    {
                        finished_decoding = 1;
                    }
                }
                else
                {
                    code = c;
                    if (code >= GIF_slot)
                    {
                        code = oc;
                        *stack_pointer++ = fc;
                    }

                    while (code >= GIF_new_codes)
                    {
                        if(stack_pointer >= (S16*)(((U8*)GIF_mtk_stack) + sizeof(GIF_mtk_stack)))
                        {
                            return MMI_FALSE;
                        }

                        *stack_pointer++ = GIF_mtk_suffix[code];
                        code = GIF_mtk_prefix[code];
                    }

                    *stack_pointer++ = code;
                    if (GIF_slot < GIF_top_slot)
                    {
                        GIF_mtk_suffix[GIF_slot] = fc = code;
                        GIF_mtk_prefix[GIF_slot++] = oc;
                        oc = c;
                    }

                    if (GIF_slot >= GIF_top_slot)
                    {
                        if (GIF_current_code_size < 12)
                        {
                            GIF_top_slot <<= 1;
                            GIF_current_code_size++;
                        }
                    }

                    while (stack_pointer > GIF_mtk_stack)
                    {
                        if ((--want_pixels) < 0)
                        {
                            finished_decoding = 1;
                            break;
                        }
                        --stack_pointer;
                    }
                }
            }
        }

        (*framecount) += 1;

            /* peek if is last frame */
        {
            U8 test1, test2;

            PEEK_U8(src, test1);
            PEEK_U8_N(src, test2, 1);
            if ((test1 == '\0') && (test2 == ';'))
            {
                /* GDI_GIF_LAST_FRAME;; */
                return MMI_TRUE;
            }
        }
        break;

        case '\0':
            if (src >= buf + file_size)
            {
                /* GDI_GIF_LAST_FRAME */
                return MMI_TRUE;
            }
            break;

        case ';':
            /* GDI_GIF_LAST_FRAME;; */
            return MMI_TRUE;
            break;
        }
예제 #3
0
파일: ps_reader.c 프로젝트: ms-iot/userland
static VC_CONTAINER_STATUS_T ps_read_pack_header( VC_CONTAINER_T *ctx )
{
   VC_CONTAINER_MODULE_T *module = ctx->priv->module;
   uint8_t header[10];
   int64_t scr, scr_base, scr_ext = INT64_C(0);
   uint64_t pack_offset = STREAM_POSITION(ctx);
   uint32_t mux_rate, stuffing;
   VC_CONTAINER_BITS_T bits;
   VC_CONTAINER_STATUS_T status;

   if(_READ_U32(ctx) != 0x1BA) return VC_CONTAINER_ERROR_CORRUPTED;
   LOG_FORMAT(ctx, "pack_header");
   
   module->level++;

   if (PEEK_U8(ctx) & 0x40)  /* program stream */
   {
      if(READ_BYTES(ctx, header, 10) != 10) return VC_CONTAINER_ERROR_EOS;
      BITS_INIT(ctx, &bits, header, 10);
      if(BITS_READ_U32(ctx, &bits, 2, "'01' marker bits") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      scr_base = BITS_READ_U32(ctx, &bits, 3, "system_clock_reference_base [32..30]") << 30;
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      scr_base |= BITS_READ_U32(ctx, &bits, 15, "system_clock_reference_base [29..15]") << 15;
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      scr_base |= BITS_READ_U32(ctx, &bits, 15, "system_clock_reference_base [14..0]");
      LOG_FORMAT(ctx, "system_clock_reference_base %"PRId64, scr_base);
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      scr_ext = BITS_READ_U32(ctx, &bits, 9, "system_clock_reference_extension");
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      mux_rate = BITS_READ_U32(ctx, &bits, 22, "program_mux_rate");
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      BITS_SKIP(ctx, &bits, 5, "reserved");
      stuffing = BITS_READ_U32(ctx, &bits, 3, "pack_stuffing_length");
      SKIP_BYTES(ctx, stuffing);
   }
   else /* system stream */
   {
      if(READ_BYTES(ctx, header, 8) != 8) return VC_CONTAINER_ERROR_EOS;
      BITS_INIT(ctx, &bits, header, 8);
      if(BITS_READ_U32(ctx, &bits, 4, "'0010' marker bits") != 0x2) return VC_CONTAINER_ERROR_CORRUPTED;
      scr_base = BITS_READ_U32(ctx, &bits, 3, "system_clock_reference_base [32..30]") << 30;
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      scr_base |= BITS_READ_U32(ctx, &bits, 15, "system_clock_reference_base [29..15]") << 15;
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      scr_base |= BITS_READ_U32(ctx, &bits, 15, "system_clock_reference_base [14..0]");
      LOG_FORMAT(ctx, "system_clock_reference_base %"PRId64, scr_base);
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
      mux_rate = BITS_READ_U32(ctx, &bits, 22, "program_mux_rate");
      if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
   }

   if ((status = STREAM_STATUS(ctx)) != VC_CONTAINER_SUCCESS) return status;
   
   module->level--;

   /* Set or update system_clock_reference, adjust bias if necessary */
   scr = scr_base * INT64_C(300) + scr_ext;

   if (module->scr_offset == VC_CONTAINER_TIME_UNKNOWN)
      module->scr_offset = scr;

   if (module->scr == VC_CONTAINER_TIME_UNKNOWN)
      module->scr_bias = -scr;
   else if (scr < module->scr)
      module->scr_bias = module->scr - scr;

   if (module->scr != VC_CONTAINER_TIME_UNKNOWN)
   {
      /* system_clock_reference is not necessarily continuous across the entire stream */
      if (scr > module->scr)
      {
         int64_t data_rate;
         data_rate = INT64_C(27000000) * (pack_offset - module->pack_offset) / (scr - module->scr);

         if (module->data_rate)
         {
            /* Simple moving average over data rate seen so far */
            module->data_rate = (module->data_rate * 31 + data_rate) >> 5;
         }
         else
         {