Ejemplo n.º 1
0
		chunk_t read_chunk( psocksxx::iosockstream * socket ) throw() {

			chunk_t chunk;
			std::string line;
			std::vector<std::string> chunk_header;

			// initialise chunk
			chunk.size      = 0;
			chunk.extention = "";
			chunk.data      = "";

			// read chunk header
			read_chunk_header( socket, chunk );

			// read chunk data
			if ( chunk.size > 0 ) {
				chunk.data = read_data( socket, chunk.size );
			}

			// read \r\n ending for the chunk
			read_data( socket, 2 );

			return chunk;

		}
Ejemplo n.º 2
0
bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng, unsigned *ret)
{
   unsigned i;

   struct png_chunk chunk = {0};

   if (!read_chunk_header(buf, &chunk))
      return false;

#if 0
   for (i = 0; i < 4; i++)
   {
      fprintf(stderr, "chunktype: %c\n", chunk.type[i]);
   }
#endif

   switch (png_chunk_type(&chunk))
   {
      case PNG_CHUNK_NOOP:
      default:
         break;

      case PNG_CHUNK_ERROR:
         goto error;

      case PNG_CHUNK_IHDR:
         if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend)
            goto error;

         if (chunk.size != 13)
            goto error;

         if (!png_parse_ihdr(buf, &rpng->ihdr))
            goto error;

         if (!png_process_ihdr(&rpng->ihdr))
            goto error;

         rpng->has_ihdr = true;
         break;

      case PNG_CHUNK_PLTE:
         {
            unsigned entries = chunk.size / 3;

            if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat)
               goto error;

            if (chunk.size % 3)
               goto error;

            if (!png_read_plte_into_buf(buf, rpng->palette, entries))
               goto error;

            rpng->has_plte = true;
         }
         break;

      case PNG_CHUNK_IDAT:
         if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !(rpng->has_plte)))
            goto error;

         if (!png_realloc_idat(&chunk, &rpng->idat_buf))
            goto error;

         buf += 8;

         for (i = 0; i < chunk.size; i++)
            rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i];

         rpng->idat_buf.size += chunk.size;

         rpng->has_idat = true;
         break;

      case PNG_CHUNK_IEND:
         if (!(rpng->has_ihdr) || !(rpng->has_idat))
            goto error;

         rpng->has_iend = true;
         goto error;
   }

   *ret = 4 + 4 + chunk.size + 4;

   return true;

error:
   return false;
}
Ejemplo n.º 3
0
int Cvqa_file::post_open()
{
	int error = read(&m_header, sizeof(t_vqa_header)); // Read header
	return error ? error : read_chunk_header();
}
Ejemplo n.º 4
0
static int open_roq(bgav_demuxer_context_t * ctx)
  {
  int i;
  chunk_header_t h;
  bgav_stream_t * s;
  uint16_t width = 0, height = 0, framerate;
  int num_channels = 0;
  
  
  /* We can play RoQ files only from seekable sources */
  if(!ctx->input->input->seek_byte)
    {
    bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
             "Cannot play Roq files from nonseekable source");
    return 0;
    }

  /* Skip magic */
  bgav_input_skip(ctx->input, 6);

  if(!bgav_input_read_16_le(ctx->input, &framerate))
    return 0;
  
  for(i = 0; i < RoQ_CHUNKS_TO_SCAN; i++)
    {
    if(!read_chunk_header(ctx->input, &h))
      break;

    switch(h.id)
      {
      case RoQ_INFO:
        if(!bgav_input_read_16_le(ctx->input, &width) ||
           !bgav_input_read_16_le(ctx->input, &height))
          return 0;
        bgav_input_skip(ctx->input, 4);
        break;
      case RoQ_QUAD_CODEBOOK:
      case RoQ_QUAD_VQ:
        bgav_input_skip(ctx->input, h.size);
        break;
      case RoQ_SOUND_MONO:
        num_channels = 1;
        bgav_input_skip(ctx->input, h.size);
        break;
      case RoQ_SOUND_STEREO:
        num_channels = 2;
        bgav_input_skip(ctx->input, h.size);
        break;
      default:
        bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
                 "Unknown Roq chunk %04x", h.id);
        return 0;
        break;
      }
    if(width && height && num_channels)
      break;
    }
  /* Seek back */
  bgav_input_seek(ctx->input, 8, SEEK_SET);

  /* Set up track table */
  ctx->tt = bgav_track_table_create(1);

  /* Set up audio stream */

  if(num_channels)
    {
    s = bgav_track_add_audio_stream(ctx->tt->cur, ctx->opt);
    s->stream_id = AUDIO_ID;
    s->fourcc = BGAV_MK_FOURCC('R','O','Q','A');
    s->data.audio.format.num_channels = num_channels;
    s->data.audio.format.samplerate = RoQ_AUDIO_SAMPLE_RATE;
    s->data.audio.bits_per_sample = 16;
    s->data.audio.block_align = num_channels * s->data.audio.bits_per_sample;
    }

  if(width && height)
    {
    s = bgav_track_add_video_stream(ctx->tt->cur, ctx->opt);
    s->stream_id = VIDEO_ID;
    s->fourcc = BGAV_MK_FOURCC('R','O','Q','V');
    s->data.video.format.image_width = width;
    s->data.video.format.image_height = height;

    s->data.video.format.frame_width = width;
    s->data.video.format.frame_height = height;

    s->data.video.format.pixel_width = 1;
    s->data.video.format.pixel_height = 1;
    
    s->data.video.format.timescale = framerate;
    s->data.video.format.frame_duration = 1;
    }

  gavl_metadata_set(&ctx->tt->cur->metadata, 
                    GAVL_META_FORMAT, "ID Roq");

  ctx->data_start = ctx->input->position;
  ctx->flags |= BGAV_DEMUXER_HAS_DATA_START;
  
  return 1;
  }
Ejemplo n.º 5
0
IFusionSoundBuffer *
load_sample (IFusionSound *sound, const char *filename)
{
     DirectResult         ret;
     int                  fd;
     FSBufferDescription  desc;
     IFusionSoundBuffer  *buffer;
     void                *data;
     fmtChunk             fmt;
     int                  len;

     fd = open (filename, O_RDONLY);
     if (fd < 0) {
          perror (filename);
          return NULL;
     }

     if (read_file_header (fd)) {
          close (fd);
          return NULL;
     }

     while (1) {
          char magic[4];

          len = read_chunk_header (fd, magic);
          if (len <= 0) {
               fprintf (stderr, "Could not find format chunk!\n");
               close (fd);
               return NULL;
          }

          if (magic[0] == 'f' || magic[1] == 'm' || magic[2] == 't') {
               if (len < sizeof(fmtChunk)) {
                    fprintf (stderr, "Format chunk has invalid size (%d/%zu)!\n",
                             len, sizeof(fmtChunk));
                    close (fd);
                    return NULL;
               }

               if (read (fd, &fmt, sizeof(fmtChunk)) < sizeof(fmtChunk)) {
                    fprintf (stderr, "Could not read format chunk!\n");
                    close (fd);
                    return NULL;
               }

               if (lseek (fd, len - sizeof(fmtChunk), SEEK_CUR) == (off_t) -1) {
                    fprintf (stderr, "Could not seek past chunk!\n");
                    close (fd);
                    return NULL;
               }

               break;
          }
          else {
               if (lseek (fd, len, SEEK_CUR) == (off_t) -1) {
                    fprintf (stderr, "Could not seek past chunk!\n");
                    close (fd);
                    return NULL;
               }
          }
     }

#ifdef WORDS_BIGENDIAN
     fixup_fmtchunk( &fmt );
#endif

     if (fmt.encoding != 1) {
          fprintf (stderr, "Only PCM supported, yet!\n");
          close (fd);
          return NULL;
     }

     if (fmt.bitspersample != 16 && fmt.bitspersample != 8) {
          fprintf (stderr, "Only 16 or 8 bit supported, yet!\n");
          close (fd);
          return NULL;
     }


     desc.flags        = FSBDF_LENGTH | FSBDF_CHANNELS |
                         FSBDF_SAMPLEFORMAT | FSBDF_SAMPLERATE;
     desc.channels     = fmt.channels;
     desc.sampleformat = (fmt.bitspersample == 8) ? FSSF_U8 : FSSF_S16;
     desc.samplerate   = fmt.frequency;

     while (1) {
          char magic[4];

          len = read_chunk_header (fd, magic);
          if (len <= 0) {
               fprintf (stderr, "Could not find data chunk!\n");
               close (fd);
               return NULL;
          }

          if (magic[0] == 'd' && magic[1] == 'a' &&
              magic[2] == 't' && magic[3] == 'a')
          {
               desc.length = len / fmt.blockalign;
               break;
          }
          else {
               if (lseek (fd, len, SEEK_CUR) == (off_t) -1) {
                    fprintf (stderr, "Could not seek past chunk!\n");
                    close (fd);
                    return NULL;
               }
          }
     }

     ret = sound->CreateBuffer (sound, &desc, &buffer);
     if (ret) {
          FusionSoundError ("IFusionSound::CreateBuffer", ret);
          close (fd);
          return NULL;
     }

     buffer->Lock (buffer, &data, 0, 0);

     if (read (fd, data, len) < len)
          fprintf (stderr, "Warning: Could not read all data bytes!\n");

#ifdef WORDS_BIGENDIAN
     if (fmt.bitspersample == 16)
          fixup_sampledata (data, len);
#endif

     close (fd);

     buffer->Unlock (buffer);

     return buffer;
}
Ejemplo n.º 6
0
int unpack(void *input, size_t input_size, void** output)
{
  int chunk_id;
  int chunk_options;
  int pos = 0;
  unsigned long chunk_size;
  unsigned long chunk_checksum;
  unsigned long chunk_extra;
  unsigned char buffer[BLOCK_SIZE];
  unsigned long checksum;

  unsigned long decompressed_size;
  unsigned long total_extracted;

  unsigned char* compressed_buffer;
  unsigned char* decompressed_buffer;
  unsigned long compressed_bufsize;
  unsigned long decompressed_bufsize;

  unsigned char* b_input = (unsigned char*) input;
  size_t output_size = 0;

  /* sanity check */
  if (input_size < 8) {
    php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Data too short");
    return -1;
  }
  input_size = input_size + sizeof(sixpack_magic);
  /* not a 6pack archive? */
  if(!detect_magic(input, input_size))
  {
    php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Data not in 6pack format");
    return -1;
  }

  /* position of first chunk */
  pos = 8;

  /* initialize */
  total_extracted = 0;
  decompressed_size = 0;
  compressed_buffer = 0;
  decompressed_buffer = 0;
  compressed_bufsize = 0;
  decompressed_bufsize = 0;

  /* main loop */
  for(;;)
  {
    /* end of file? */
    if(pos > input_size)
      break;

    read_chunk_header(input, input_size, &pos, &chunk_id, &chunk_options,
        &chunk_size, &chunk_checksum, &chunk_extra);

    if((chunk_id == 1) && (chunk_size > 10) && (chunk_size < BLOCK_SIZE))
    {
      /* file entry */
      int c;
      for (c=0;c<chunk_size;c++)
      {
        if (pos < input_size) {
          buffer[c] = b_input[pos];
          pos++;
        } else {
          break;
        }
      }
      checksum = update_adler32(1L, buffer, chunk_size);
      if(checksum != chunk_checksum)
      {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Checksum mismatch. Got %08lX, expected %08lX", checksum, chunk_checksum);
        return (-1);
      }

      decompressed_size = readU32(buffer);
      total_extracted = 0;
    }

    if((chunk_id == 17) && decompressed_size)
    {
      unsigned long remaining;

      /* uncompressed */
      switch(chunk_options)
      {
        /* stored, simply copy to output */
        case 0:
          /* read one block at at time, write and update checksum */
          total_extracted += chunk_size;
          remaining = chunk_size;
          checksum = 1L;
          for(;;)
          {
            unsigned long r = (BLOCK_SIZE < remaining) ? BLOCK_SIZE: remaining;
            int c;

           for (c=0;c<r;c++)
           {
            if (pos<input_size) {
              buffer[c] = b_input[pos];
              pos++;
            } else{
              break;
            }
           }
           size_t bytes_read = c;
            if(bytes_read == 0)
              break;
            output_size = mem_append(output, output_size, buffer, bytes_read);
            checksum = update_adler32(checksum, buffer, bytes_read);
            remaining -= bytes_read;
          }

          /* verify everything is written correctly */
          if(checksum != chunk_checksum)
          {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Checksum mismatch. Got %08lX, expected %08lX", checksum, chunk_checksum);
            return (-1);
          }
          break;

        /* compressed using FastLZ */
        case 1:
          /* enlarge input buffer if necessary */
          if(chunk_size > compressed_bufsize)
          {
            compressed_bufsize = chunk_size;
            efree(compressed_buffer);
            compressed_buffer = (unsigned char*)emalloc(compressed_bufsize);
          }

          /* enlarge output buffer if necessary */
          if(chunk_extra > decompressed_bufsize)
          {
            decompressed_bufsize = chunk_extra;
            efree(decompressed_buffer);
            decompressed_buffer = (unsigned char*)emalloc(decompressed_bufsize);
          }

          /* read and check checksum */
           int c;
           for (c=0;c<chunk_size;c++)
           {
            if (pos<input_size) {
              compressed_buffer[c] = b_input[pos];
              pos++;
            } else{
              break;
            }
           }
          checksum = update_adler32(1L, compressed_buffer, chunk_size);
          total_extracted += chunk_extra;

          /* verify that the chunk data is correct */
          if(checksum != chunk_checksum)
          {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Checksum mismatch. Got %08lX, expected %08lX", checksum, chunk_checksum);
            return (-1);
          }
          else
          {
            /* decompress and verify */
            remaining = fastlz_decompress(compressed_buffer, chunk_size, decompressed_buffer, chunk_extra);
            if(remaining != chunk_extra)
            {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Decompression failed. Skipped");
            }
            else
              output_size = mem_append(output, output_size, decompressed_buffer, chunk_extra);
          }
          break;

        default:
          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown compression method (%d)\n", chunk_options);
          break;
      }
    }

    /* position of next chunk */
    //pos = pos + 16 + chunk_size;
    //fseek(in, pos + 16 + chunk_size, SEEK_SET);
  }

  /* free allocated stuff */
  efree(compressed_buffer);
  efree(decompressed_buffer);

  /* so far so good */
  return total_extracted;
}
Ejemplo n.º 7
0
static int open_smaf(bgav_demuxer_context_t * ctx)
  {
  int done = 0;
  uint8_t params;
  chunk_header_t ch;
  bgav_stream_t * s;

  smaf_priv_t * priv;
  priv = calloc(1, sizeof(*priv));
  ctx->priv = priv;

  /* Skip MMMD chunk */
  bgav_input_skip(ctx->input, 8);

  while(!done)
    {
    if(!read_chunk_header(ctx->input, &ch))
      return 0;

    //    dump_chunk_header(&ch);

    if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('M','T','R',0))
      {
      bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
               "MIDI like files not supported");
      return 0;
      }

    else if((ch.fourcc == BGAV_MK_FOURCC('C','N','T','I')) ||
            (ch.fourcc == BGAV_MK_FOURCC('O','P','D','A')))
      bgav_input_skip(ctx->input, ch.size);

    else if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('A','T','R',0))
      done = 1;

    else
      {
      bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
               "Unsupported SMAF chunk (%c%c%c%c)",
               (ch.fourcc & 0xFF000000) >> 24,
               (ch.fourcc & 0x00FF0000) >> 16,
               (ch.fourcc & 0x0000FF00) >> 8,
               (ch.fourcc & 0x000000FF));
      return 0;
      }
    
    }

  /* Initialize generic things */

  ctx->tt = bgav_track_table_create(1);
  s = bgav_track_add_audio_stream(ctx->tt->cur, ctx->opt);
  
  /* Now, get the format */
   
  bgav_input_skip(ctx->input, 1); /* format type */
  bgav_input_skip(ctx->input, 1); /* sequence type */

  /* (channel << 7) | (format << 4) | rate */
  if(!bgav_input_read_data(ctx->input, &params, 1)) 
    return 0;
  
  s->data.audio.format.samplerate = mmf_rate(params & 0x0f);
  s->fourcc = BGAV_MK_FOURCC('S','M','A','F');
  s->data.audio.bits_per_sample = 4;
  s->data.audio.format.num_channels = 1;
  s->data.audio.bits_per_sample = 4;
  s->container_bitrate = s->data.audio.bits_per_sample *
    s->data.audio.format.samplerate;
    
  if(s->data.audio.format.samplerate < 0)
    {
    bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
             "Invalid samplerate");
    return 0;
    }
  bgav_input_skip(ctx->input, 1); /* wave base bit */
  bgav_input_skip(ctx->input, 1); /* time base d   */
  bgav_input_skip(ctx->input, 1); /* time base g   */

  done = 0;
  while(!done)
    {
    if(!read_chunk_header(ctx->input, &ch))
      return 0;

    //    dump_chunk_header(&ch);

    if((ch.fourcc == BGAV_MK_FOURCC('A','t','s','q')) ||
       (ch.fourcc == BGAV_MK_FOURCC('A','s','p','I')))
      bgav_input_skip(ctx->input, ch.size);

    else if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('A','w','a', 0))
      done = 1;

    else
      {
      bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
               "Unsupported SMAF chunk (%c%c%c%c)",
               (ch.fourcc & 0xFF000000) >> 24,
               (ch.fourcc & 0x00FF0000) >> 16,
               (ch.fourcc & 0x0000FF00) >> 8,
               (ch.fourcc & 0x000000FF));
      return 0;
      }
    }
  priv->bytes_left = ch.size;

  gavl_metadata_set(&ctx->tt->cur->metadata, 
                    GAVL_META_FORMAT, "SMAF Ringtone");

  return 1;
  }
Ejemplo n.º 8
0
bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height)
{
   long pos;
   *data   = NULL;
   *width  = 0;
   *height = 0;

   bool ret = true;
   FILE *file = fopen(path, "rb");
   if (!file)
      return false;

   fseek(file, 0, SEEK_END);
   long file_len = ftell(file);
   rewind(file);

   bool has_ihdr = false;
   bool has_idat = false;
   bool has_iend = false;
   bool has_plte = false;
   uint8_t *inflate_buf = NULL;
   size_t inflate_buf_size = 0;
   z_stream stream = {0};

   struct idat_buffer idat_buf = {0};
   struct png_ihdr ihdr = {0};
   uint32_t palette[256] = {0};

   char header[8];
   if (fread(header, 1, sizeof(header), file) != sizeof(header))
      GOTO_END_ERROR();

   if (memcmp(header, png_magic, sizeof(png_magic)) != 0)
      GOTO_END_ERROR();

   // feof() apparently isn't triggered after a seek (IEND).
   for (pos = ftell(file); pos < file_len && pos >= 0; pos = ftell(file))
   {
      struct png_chunk chunk = {0};
      if (!read_chunk_header(file, &chunk))
         GOTO_END_ERROR();

      switch (png_chunk_type(&chunk))
      {
         case PNG_CHUNK_NOOP:
         default:
            if (fseek(file, chunk.size + sizeof(uint32_t), SEEK_CUR) < 0)
               GOTO_END_ERROR();
            break;

         case PNG_CHUNK_ERROR:
            GOTO_END_ERROR();

         case PNG_CHUNK_IHDR:
            if (has_ihdr || has_idat || has_iend)
               GOTO_END_ERROR();

            if (!png_parse_ihdr(file, &chunk, &ihdr))
               GOTO_END_ERROR();

            has_ihdr = true;
            break;

         case PNG_CHUNK_PLTE:
            if (!has_ihdr || has_plte || has_iend || has_idat)
               GOTO_END_ERROR();

            if (chunk.size % 3)
               GOTO_END_ERROR();

            if (!png_read_plte(file, palette, chunk.size / 3))
               GOTO_END_ERROR();

            has_plte = true;
            break;

         case PNG_CHUNK_IDAT:
            if (!has_ihdr || has_iend || (ihdr.color_type == 3 && !has_plte))
               GOTO_END_ERROR();

            if (!png_append_idat(file, &chunk, &idat_buf))
               GOTO_END_ERROR();

            has_idat = true;
            break;

         case PNG_CHUNK_IEND:
            if (!has_ihdr || !has_idat)
               GOTO_END_ERROR();

            if (fseek(file, sizeof(uint32_t), SEEK_CUR) < 0)
               GOTO_END_ERROR();

            has_iend = true;
            break;
      }
   }

   if (!has_ihdr || !has_idat || !has_iend)
      GOTO_END_ERROR();

   if (inflateInit(&stream) != Z_OK)
      GOTO_END_ERROR();

   png_pass_geom(&ihdr, ihdr.width, ihdr.height, NULL, NULL, &inflate_buf_size);
   if (ihdr.interlace == 1) // To be sure.
      inflate_buf_size *= 2;

   inflate_buf = (uint8_t*)malloc(inflate_buf_size);
   if (!inflate_buf)
      GOTO_END_ERROR();

   stream.next_in   = idat_buf.data;
   stream.avail_in  = idat_buf.size;
   stream.avail_out = inflate_buf_size;
   stream.next_out  = inflate_buf;

   if (inflate(&stream, Z_FINISH) != Z_STREAM_END)
   {
      inflateEnd(&stream);
      GOTO_END_ERROR();
   }
   inflateEnd(&stream);

   *width  = ihdr.width;
   *height = ihdr.height;
   *data = (uint32_t*)malloc(ihdr.width * ihdr.height * sizeof(uint32_t));
   if (!*data)
      GOTO_END_ERROR();

   if (ihdr.interlace == 1)
   {
      if (!png_reverse_filter_adam7(*data, &ihdr, inflate_buf, stream.total_out, palette))
         GOTO_END_ERROR();
   }
   else if (!png_reverse_filter(*data, &ihdr, inflate_buf, stream.total_out, palette))
      GOTO_END_ERROR();

end:
   if (file)
      fclose(file);
   if (!ret)
      free(*data);
   free(idat_buf.data);
   free(inflate_buf);
   return ret;
}
Ejemplo n.º 9
0
bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng)
{
   unsigned i;

   rpng->chunk.size = 0;
   rpng->chunk.type[0] = '\0';

   if (!read_chunk_header(buf, &rpng->chunk))
      return false;

#if 0
   for (i = 0; i < 4; i++)
   {
      fprintf(stderr, "chunktype: %c\n", chunk.type[i]);
   }
#endif

   switch (png_chunk_type(&rpng->chunk))
   {
      case PNG_CHUNK_NOOP:
      default:
         break;

      case PNG_CHUNK_ERROR:
         return false;

      case PNG_CHUNK_IHDR:
         if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend)
            return false;

         if (rpng->chunk.size != 13)
            return false;

         if (!png_parse_ihdr(buf, &rpng->ihdr))
            return false;

         rpng->has_ihdr = true;
         break;

      case PNG_CHUNK_PLTE:
         {
            unsigned entries = rpng->chunk.size / 3;

            if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat)
               return false;

            if (rpng->chunk.size % 3)
               return false;

            if (!png_read_plte_into_buf(buf, rpng->palette, entries))
               return false;

            rpng->has_plte = true;
         }
         break;

      case PNG_CHUNK_IDAT:
         if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == 3 && !(rpng->has_plte)))
            return false;

         if (!png_realloc_idat(&rpng->chunk, &rpng->idat_buf))
            return false;

         buf += 8;

         for (i = 0; i < rpng->chunk.size; i++)
            rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i];

         rpng->idat_buf.size += rpng->chunk.size;

         rpng->has_idat = true;
         break;

      case PNG_CHUNK_IEND:
         if (!(rpng->has_ihdr) || !(rpng->has_idat))
            return false;

         rpng->has_iend = true;
         return false;
   }

   return true;
}
Ejemplo n.º 10
0
static int open_aiff(bgav_demuxer_context_t * ctx)
  {
  chunk_header_t ch;
  comm_chunk_t comm;

  uint32_t fourcc;
  bgav_stream_t * s = NULL;
  aiff_priv_t * priv;
  int keep_going = 1;
  bgav_track_t * track;
  char * tmp_string;
  
  /* Create track */
  ctx->tt = bgav_track_table_create(1);
  track = ctx->tt->cur;
  
  /* Check file magic */
  
  if(!read_chunk_header(ctx->input, &ch) ||
     (ch.fourcc != BGAV_MK_FOURCC('F','O','R','M')))
    return 0;

  if(!bgav_input_read_fourcc(ctx->input, &fourcc))
    return 0;

  /* Allocate private struct */

  priv = calloc(1, sizeof(*priv));
  ctx->priv = priv;
  
  if(fourcc == BGAV_MK_FOURCC('A','I','F','C'))
    {
    priv->is_aifc = 1;
    }
  else if(fourcc != BGAV_MK_FOURCC('A','I','F','F'))
    {
    return 0;
    }
  

  /* Read chunks until we are done */

  while(keep_going)
    {
    if(!read_chunk_header(ctx->input, &ch))
      return 0;
    switch(ch.fourcc)
      {
      case BGAV_MK_FOURCC('C','O','M','M'):
        s = bgav_track_add_audio_stream(track, ctx->opt);
        
        memset(&comm, 0, sizeof(comm));
        
        if(!comm_chunk_read(&ch,
                            ctx->input,
                            &comm, priv->is_aifc))
          {
          return 0;
          }
        
        s->data.audio.format.samplerate =   comm.samplerate;
        s->data.audio.format.num_channels = comm.num_channels;
        s->data.audio.bits_per_sample =     comm.num_bits;

        /*
         *  Multichannel support according to
         *  http://music.calarts.edu/~tre/AIFFC/
         */

        switch(s->data.audio.format.num_channels)
          {
          case 1:
            s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_CENTER;
            break;
          case 2:
            s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT;
            s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_RIGHT;
            break;
          case 3:
            s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT;
            s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_CENTER;
            s->data.audio.format.channel_locations[2] = GAVL_CHID_FRONT_RIGHT;
            break;
          case 4: /* Note: 4 channels can also be "left center right surround" but we
                     believe, that quad is more common */
            s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT;
            s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_RIGHT;
            s->data.audio.format.channel_locations[2] = GAVL_CHID_REAR_LEFT;
            s->data.audio.format.channel_locations[3] = GAVL_CHID_REAR_RIGHT;
            break;
          case 6:
            s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT;
            s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_CENTER_LEFT;
            s->data.audio.format.channel_locations[2] = GAVL_CHID_FRONT_CENTER;
            s->data.audio.format.channel_locations[3] = GAVL_CHID_FRONT_RIGHT;
            s->data.audio.format.channel_locations[4] = GAVL_CHID_FRONT_CENTER_RIGHT;
            s->data.audio.format.channel_locations[5] = GAVL_CHID_REAR_CENTER;
            break;
          }
        
        if(!priv->is_aifc)
          s->fourcc = BGAV_MK_FOURCC('a','i','f','f');
        else if(comm.compression_type == BGAV_MK_FOURCC('N','O','N','E'))
          s->fourcc = BGAV_MK_FOURCC('a','i','f','f');
        else
          s->fourcc = comm.compression_type;
        
        switch(s->fourcc)
          {
          case BGAV_MK_FOURCC('a','i','f','f'):
            if(s->data.audio.bits_per_sample <= 8)
              {
              s->data.audio.block_align = comm.num_channels;
              }
            else if(s->data.audio.bits_per_sample <= 16)
              {
              s->data.audio.block_align = 2 * comm.num_channels;
              }
            else if(s->data.audio.bits_per_sample <= 24)
              {
              s->data.audio.block_align = 3 * comm.num_channels;
              }
            else if(s->data.audio.bits_per_sample <= 32)
              {
              s->data.audio.block_align = 4 * comm.num_channels;
              }
            else
              {
              bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
                       "%d bit aiff not supported", 
                      s->data.audio.bits_per_sample);
              return 0;
              }
            s->data.audio.format.samples_per_frame = 1024;
            priv->samples_per_block = 1;
            break;
          case BGAV_MK_FOURCC('f','l','3','2'):
            s->data.audio.block_align = 4 * comm.num_channels;
            priv->samples_per_block = 1;
            break;
          case BGAV_MK_FOURCC('f','l','6','4'):
            s->data.audio.block_align = 8 * comm.num_channels;
            priv->samples_per_block = 1;
            s->data.audio.format.samples_per_frame = 1024;
            break;
          case BGAV_MK_FOURCC('a','l','a','w'):
          case BGAV_MK_FOURCC('A','L','A','W'):
          case BGAV_MK_FOURCC('u','l','a','w'):
          case BGAV_MK_FOURCC('U','L','A','W'):
            s->data.audio.block_align = comm.num_channels;
            priv->samples_per_block = 1;
            s->data.audio.format.samples_per_frame = 1024;
            break;
#if 0
          case BGAV_MK_FOURCC('G','S','M',' '):
            s->data.audio.block_align = 33;
            priv->samples_per_block = 160;
            s->data.audio.format.samples_per_frame = 160;
            break;
#endif
          case BGAV_MK_FOURCC('M','A','C','3'):
            s->data.audio.block_align = comm.num_channels * 2;
            priv->samples_per_block = 6;
            s->data.audio.format.samples_per_frame = 6*128;
            break;
          case BGAV_MK_FOURCC('M','A','C','6'):
            s->data.audio.block_align = comm.num_channels;
            priv->samples_per_block = 6;
            s->data.audio.format.samples_per_frame = 6*128;
            break;
          default:
            bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Compression %c%c%c%c not supported",
                    comm.compression_type >> 24,
                    (comm.compression_type >> 16) & 0xff,
                    (comm.compression_type >> 8) & 0xff,
                    (comm.compression_type) & 0xff);
            return 0;
          }
        break;
      case BGAV_MK_FOURCC('N','A','M','E'):
        tmp_string = read_meta_string(ctx->input, &ch);
        gavl_metadata_set_nocpy(&ctx->tt->cur->metadata,
                                GAVL_META_TITLE, tmp_string);
        break;
      case BGAV_MK_FOURCC('A','U','T','H'):
        tmp_string = read_meta_string(ctx->input, &ch);
        gavl_metadata_set_nocpy(&ctx->tt->cur->metadata,
                                GAVL_META_AUTHOR, tmp_string);
        break;
      case BGAV_MK_FOURCC('(','c',')',' '):
        tmp_string = read_meta_string(ctx->input, &ch);
        gavl_metadata_set_nocpy(&ctx->tt->cur->metadata,
                                GAVL_META_COPYRIGHT, tmp_string);
        break;
      case BGAV_MK_FOURCC('A','N','N','O'):
        tmp_string = read_meta_string(ctx->input, &ch);
        gavl_metadata_set_nocpy(&ctx->tt->cur->metadata,
                                GAVL_META_COMMENT, tmp_string);
        break;
      case BGAV_MK_FOURCC('S','S','N','D'):
        bgav_input_skip(ctx->input, 4); /* Offset */
        bgav_input_skip(ctx->input, 4); /* Blocksize */
        ctx->data_start = ctx->input->position;
        ctx->flags |= BGAV_DEMUXER_HAS_DATA_START;
        priv->data_size = ch.size - 8;

        ctx->tt->cur->audio_streams->duration = pos_2_time(ctx, priv->data_size + ctx->data_start);
        track->duration =
          gavl_time_unscale(s->data.audio.format.samplerate,
                            ctx->tt->cur->audio_streams->duration);
        
        keep_going = 0;
        break;
      default:
        bgav_input_skip(ctx->input, PADD(ch.size));
        break;
      }
    }
  if(ctx->input->input->seek_byte)
    ctx->flags |= BGAV_DEMUXER_CAN_SEEK;

  if(priv->is_aifc)
    gavl_metadata_set(&ctx->tt->cur->metadata, 
                      GAVL_META_FORMAT, "AIFF-C");
  else
    gavl_metadata_set(&ctx->tt->cur->metadata, 
                      GAVL_META_FORMAT, "AIFF");
  ctx->index_mode = INDEX_MODE_PCM;
  return 1;
  }
Ejemplo n.º 11
0
bool rpng_iterate_image(rpng_t *rpng)
{
   unsigned i;
   struct png_chunk chunk = {0};
   uint8_t *buf           = (uint8_t*)rpng->buff_data;

   if (!read_chunk_header(buf, &chunk))
      return false;

   *buf += 8;

#if 0
   for (i = 0; i < 4; i++)
   {
      fprintf(stderr, "chunktype: %c\n", chunk.type[i]);
   }
#endif

   switch (png_chunk_type(&chunk))
   {
      case PNG_CHUNK_NOOP:
      default:
         break;

      case PNG_CHUNK_ERROR:
         goto error;

      case PNG_CHUNK_IHDR:
         if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend)
            goto error;

         if (chunk.size != 13)
            goto error;

         if (!png_parse_ihdr(buf, &rpng->ihdr))
            goto error;

         if (!png_process_ihdr(&rpng->ihdr))
            goto error;

         rpng->has_ihdr = true;
         break;

      case PNG_CHUNK_PLTE:
         {
            unsigned entries = chunk.size / 3;

            if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat || rpng->has_trns)
               goto error;

            if (chunk.size % 3)
               goto error;

            if (entries > 256)
               goto error;

            buf += 8;

            if (!png_read_plte(buf, rpng->palette, entries))
               goto error;

            rpng->has_plte = true;
         }
         break;

      case PNG_CHUNK_tRNS:
         {
            unsigned entries = chunk.size / 3;

            if (rpng->has_idat)
               goto error;
            
            if (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT)
            {
               /* we should compare with the number of palette entries */
               if (chunk.size > 256)
                  goto error;
               
               if (!png_read_trns(buf, rpng->palette, chunk.size))
                  goto error;
            }
            /* TODO: support colorkey in grayscale and truecolor images */

            rpng->has_trns = true;
         }
         break;

      case PNG_CHUNK_IDAT:
         if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !(rpng->has_plte)))
            goto error;

         if (!png_realloc_idat(&chunk, &rpng->idat_buf))
            goto error;

         buf += 8;

         for (i = 0; i < chunk.size; i++)
            rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i];

         rpng->idat_buf.size += chunk.size;

         rpng->has_idat = true;
         break;

      case PNG_CHUNK_IEND:
         if (!(rpng->has_ihdr) || !(rpng->has_idat))
            goto error;

         rpng->has_iend = true;
         goto error;
   }

   rpng->buff_data += chunk.size + 12; 

   return true;

error:
   return false;
}