Example #1
0
static boolean buf_src_fill_input_buffer(j_decompress_ptr cinfo) {
  static JOCTET mybuffer[4];
  buf_src_mgr *src = (buf_src_mgr *)cinfo->src;

  // Consume the entire buffer, even if bytes are still in bytes_in_buffer
  buffer_consume(src->buf, buffer_len(src->buf));

  if (!buffer_check_load(src->buf, src->fp, 1, BUF_SIZE))
    goto eof;

  cinfo->src->next_input_byte = (JOCTET *)buffer_ptr(src->buf);
  cinfo->src->bytes_in_buffer = buffer_len(src->buf);

  goto ok;

eof:
  // Insert a fake EOI marker if we can't read enough data
  LOG_DEBUG("  EOF filling input buffer, returning EOI marker\n");

  mybuffer[0] = (JOCTET)0xFF;
  mybuffer[1] = (JOCTET)JPEG_EOI;

  cinfo->src->next_input_byte = mybuffer;
  cinfo->src->bytes_in_buffer = 2;

ok:
  return TRUE;
}
Example #2
0
static void image_png_read_buf(png_structp png_ptr, png_bytep data, png_size_t len) {
  PNGData *p = (PNGData *)png_get_io_ptr(png_ptr);

  //LOG_DEBUG("PNG read_buf wants %ld bytes, %d in buffer\n", len, buffer_len(p->buf));

  if (!buffer_check_load(p->buf, p->fp, len, BUF_SIZE))
    goto eof;

  memcpy(data, buffer_ptr(p->buf), len);
  buffer_consume(p->buf, len);
  goto ok;

eof:
  png_error(png_ptr, "Not enough PNG data");

ok:
  return;
}
Example #3
0
static void
_parse_wav(ScanData s, Buffer *buf)
{
  uint32_t offset = 12;
  
  s->type_name = "wav";
  mediascan_add_StreamData(s, 1);
  
  while ( offset < s->size - 8 ) {
    char chunk_id[5];
    uint32_t chunk_size;
    
    // Verify we have at least 8 bytes
    if ( !buffer_check_load(buf, s->fp, 8, BLOCK_SIZE) ) {
      return;
    }
    
    strncpy( chunk_id, (char *)buffer_ptr(buf), 4 );
    chunk_id[4] = '\0';
    buffer_consume(buf, 4);
    
    chunk_size = buffer_get_int_le(buf);
    
    // Adjust for padding
    if ( chunk_size % 2 ) {
      chunk_size++;
    }
    
    offset += 8;
    
    LOG_DEBUG("%s size %d\n", chunk_id, chunk_size);
    
    // Seek past data, everything else we parse
    // XXX: Are there other large chunks we should ignore?
    if ( !strcmp( chunk_id, "data" ) ) {      
      s->audio_offset = offset;
      s->audio_size   = chunk_size;
      
      // Calculate duration, unless we already know it (i.e. from 'fact')
      if ( !s->duration_ms ) {
        if (s->bitrate) {
          s->duration_ms = (chunk_size / (s->bitrate / 8.)) * 1000;
        }
      }
      
      // sanity check size, this is inside the data chunk code
      // to support setting audio_offset even when the data size is wrong
      if (chunk_size > s->size - offset) {
        LOG_DEBUG("data size > file_size, skipping\n");
        return;
      }
      
      // Seek past data if there are more chunks after it
      if ( s->size > offset + chunk_size ) {
        fseek(s->fp, offset + chunk_size, SEEK_SET);
      }
      
      buffer_clear(buf);
    }
    else if ( !strcmp( chunk_id, "id3 " ) || !strcmp( chunk_id, "ID3 " ) || !strcmp( chunk_id, "ID32" ) ) {
      // Read header to verify version
      unsigned char *bptr = buffer_ptr(buf);
      
      if (
        (bptr[0] == 'I' && bptr[1] == 'D' && bptr[2] == '3') &&
        bptr[3] < 0xff && bptr[4] < 0xff &&
        bptr[6] < 0x80 && bptr[7] < 0x80 && bptr[8] < 0x80 && bptr[9] < 0x80
      ) {        
        // Start parsing ID3 from offset
        //parse_id3(infile, file, info, tags, offset, file_size);
      }
      
      // Seek past ID3 and clear buffer
      fseek(s->fp, offset + chunk_size, SEEK_SET);
      buffer_clear(buf);
    }
    else {
      // sanity check size
      if (chunk_size > s->size - offset) {
        LOG_DEBUG("chunk_size > file_size, skipping\n");
        return;
      }
      
      // Make sure we have enough data
      if ( !buffer_check_load(buf, s->fp, chunk_size, BLOCK_SIZE) ) {
        return;
      }
      
      if ( !strcmp( chunk_id, "fmt " ) ) {
        _parse_wav_fmt(s, buf, chunk_size);
      }
      else if ( !strcmp( chunk_id, "LIST" ) ) {
        //_parse_wav_list(buf, chunk_size, tags);
      }
      else if ( !strcmp( chunk_id, "PEAK" ) ) {
        _parse_wav_peak(s, buf, chunk_size, 0);
      }
      else if ( !strcmp( chunk_id, "fact" ) ) {
        // A 4-byte fact chunk in a non-PCM wav is the number of samples
        // Use it to calculate duration
        if ( chunk_size == 4 ) {
          uint32_t num_samples = buffer_get_int_le(buf);
          if (s->streams[0].samplerate) {
            s->duration_ms = (num_samples * 1000) / s->streams[0].samplerate;
          }
        }
        else {
          // Unknown, skip it
          buffer_consume(buf, chunk_size);
        }
      }
      else {
        if ( 
             !strcmp(chunk_id, "SAUR") // Wavosour data chunk
          || !strcmp(chunk_id, "otom") // Wavosaur?
          || !strcmp(chunk_id, "PAD ") // Padding
        ) {
          // Known chunks to skip
        }
        else {
          // Warn about unknown chunks so we can investigate them
          LOG_DEBUG("Unhandled WAV chunk %s size %d (skipped)\n", chunk_id, chunk_size);
        }
        
        buffer_consume(buf, chunk_size);
      }
    }
    
    offset += chunk_size;
  }
}
Example #4
0
int
wav_scan(ScanData s)
{
  int ret = 1;
  Buffer buf;
  uint32_t chunk_size;
  
  buffer_init(&buf, BLOCK_SIZE);
  
  if ( !buffer_check_load(&buf, s->fp, 12, BLOCK_SIZE) ) {
    ret = 0;
    goto out;
  }
  
  if ( !strncmp( (char *)buffer_ptr(&buf), "RIFF", 4 ) ) {
    // We've got a RIFF file
    buffer_consume(&buf, 4);
  
    chunk_size = buffer_get_int_le(&buf);
    
    // Check format
    if ( strncmp( (char *)buffer_ptr(&buf), "WAVE", 4 ) ) {
      LOG_ERROR("Invalid WAV file: missing WAVE header: %s\n", s->path);
      ret = 0;
      goto out;
    }
    
    buffer_consume(&buf, 4);
    
    _parse_wav(s, &buf);
  }
  else if ( !strncmp( (char *)buffer_ptr(&buf), "FORM", 4 ) ) {
    // We've got an AIFF file
    char *bptr;
    
    buffer_consume(&buf, 4);
    
    chunk_size = buffer_get_int(&buf);
    
    // Check format
    bptr = buffer_ptr(&buf);
    if ( bptr[0] == 'A' && bptr[1] == 'I' && bptr[2] == 'F' && (bptr[3] == 'F' || bptr[3] == 'C') ) {
      buffer_consume(&buf, 4);

      //_parse_aiff(s, &buf);
    }
    else {
      LOG_ERROR("Invalid AIFF file: missing AIFF header: %s\n", s->path);
      ret = 0;
      goto out;
    }
  }
  else {
    LOG_ERROR("Invalid WAV file: missing RIFF header: %s\n", s->path);
    ret = 0;
    goto out;
  }
  
out:
  buffer_free(&buf);
  
  return ret;
}