Пример #1
0
ssize_t multi_read(void *buf, size_t count) {
  ssize_t size;
  int i;
  struct mfile *file;
  struct cdrom_msf* cdbuf = buf;

  file = &files[curFile];

  if (curFile == numfiles) {
#ifdef __DVD_DEBUG
    print_info("last file read.\n");
#endif
    return 0;
  }

  if(file->lba >= 0) {
    int frame = current_lba;
    lba_to_msf(frame, &cdbuf->cdmsf_min0, &cdbuf->cdmsf_sec0, &cdbuf->cdmsf_frame0);
    frame = current_lba + count;
    lba_to_msf(frame, &cdbuf->cdmsf_min0, &cdbuf->cdmsf_sec0, &cdbuf->cdmsf_frame1);
    size = ioctl(file->fd, CDROMREADMODE2, &cdbuf);
    current_lba += size;
  }
  else
    size = read(file->fd, buf, count);

  if (size == -1) {
#ifdef __DVD_DEBUG
    print_info("invalid read.\n");
#endif
    return -1;
  }

  if (size < count) {
#ifdef __DVD_DEBUG
    print_info("finished file %s.\n", files[curFile].name);
#endif
    if( ++curFile >= numfiles)
      return size;

#ifdef __DVD_DEBUG
    print_info("continuing with file %s.\n", files[curFile].name);
#endif
    current_lba = files[curFile].lba;

    if(files[curFile].lba >= 0) {
      int frame = current_lba;
      lba_to_msf(frame, &cdbuf->cdmsf_min0, &cdbuf->cdmsf_sec0, &cdbuf->cdmsf_frame0);
      frame = current_lba + count-size;
      lba_to_msf(frame, &cdbuf->cdmsf_min0, &cdbuf->cdmsf_sec0, &cdbuf->cdmsf_frame1);
      size += ioctl(files[curFile].fd, CDROMREADMODE2, &cdbuf);
      current_lba += size;
    }
    else
      size += read(files[curFile].fd, buf + size, count - size);
  }

  return size;
}
Пример #2
0
static int iso_readtoc(unsigned char *buf, unsigned char start_track, int msf, int maxlen, int single)
{
        uint8_t *q;
        int len;

        if (start_track > 1 && start_track != 0xaa)
                return -1;
        q = buf + 2;
        *q++ = 1; /* first session */
        *q++ = 1; /* last session */
        if (start_track <= 1)
        {
                *q++ = 0; /* reserved */
                *q++ = 0x14; /* ADR, control */
                *q++ = 1;    /* track number */
                *q++ = 0; /* reserved */
                if (msf)
                {
                        *q++ = 0; /* reserved */
                        lba_to_msf(q, 0);
                        q += 3;
                }
                else
                {
                        /* sector 0 */
                        *q++ = 0;
                        *q++ = 0;
                        *q++ = 0;
                        *q++ = 0;
                }
        }
        /* lead out track */
        *q++ = 0; /* reserved */
        *q++ = 0x16; /* ADR, control */
        *q++ = 0xaa; /* track number */
        *q++ = 0; /* reserved */
        last_block = image_size >> 11;
        if (msf)
        {
                *q++ = 0; /* reserved */
                lba_to_msf(q, last_block);
                q += 3;
        }
        else
        {
                *q++ = last_block >> 24;
                *q++ = last_block >> 16;
                *q++ = last_block >> 8;
                *q++ = last_block;
        }
        len = q - buf;
        buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
        buf[1] = (uint8_t)((len-2) & 0xff);
        return len;
}
Пример #3
0
static void iso_readsector_raw(uint8_t *b, int sector)
{
        uint32_t temp;
        if (!cdrom_drive) return;
        fseek(iso_image, sector*2048, SEEK_SET);
        fread(b+16, 2048, 1, iso_image);

        /* sync bytes */
        b[0] = 0;
        memset(b + 1, 0xff, 10);
        b[11] = 0;
        b += 12;
        lba_to_msf(b, sector);
        b[3] = 1; /* mode 1 data */
        b += 4;
        b += 2048;
        memset(b, 0, 288);
}
Пример #4
0
static int iso_readtoc_raw(unsigned char *buf, int maxlen)
{
        uint8_t *q;
        int len;

        q = buf + 2;
        *q++ = 1; /* first session */
        *q++ = 1; /* last session */

        *q++ = 1; /* session number */
        *q++ = 0x14; /* data track */
        *q++ = 0; /* track number */
        *q++ = 0xa0; /* lead-in */
        *q++ = 0; /* min */
        *q++ = 0; /* sec */
        *q++ = 0; /* frame */
        *q++ = 0;
        *q++ = 1; /* first track */
        *q++ = 0x00; /* disk type */
        *q++ = 0x00;

        *q++ = 1; /* session number */
        *q++ = 0x14; /* data track */
        *q++ = 0; /* track number */
        *q++ = 0xa1;
        *q++ = 0; /* min */
        *q++ = 0; /* sec */
        *q++ = 0; /* frame */
        *q++ = 0;
        *q++ = 1; /* last track */
        *q++ = 0x00;
        *q++ = 0x00;

        *q++ = 1; /* session number */
        *q++ = 0x14; /* data track */
        *q++ = 0; /* track number */
        *q++ = 0xa2; /* lead-out */
        *q++ = 0; /* min */
        *q++ = 0; /* sec */
        *q++ = 0; /* frame */
        last_block = image_size >> 11;
        /* this is raw, must be msf */
	*q++ = 0; /* reserved */
        lba_to_msf(q, last_block);
        q += 3;

        *q++ = 1; /* session number */
        *q++ = 0x14; /* ADR, control */
        *q++ = 0;    /* track number */
        *q++ = 1;    /* point */
        *q++ = 0; /* min */
        *q++ = 0; /* sec */
        *q++ = 0; /* frame */
        /* same here */
        *q++ = 0;
        *q++ = 0;
        *q++ = 0;
        *q++ = 0;
    
        len = q - buf;
        buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
        buf[1] = (uint8_t)((len-2) & 0xff);
        return len;
}
Пример #5
0
UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype)
{
	UINT32 tracktype, tracknum, sectoroffs;
	chd_error err;
	static const UINT8 syncbytes[12] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};

	if (file == NULL)
		return 0;

	/* cache in the sector */
	err = read_sector_into_cache(file, lbasector, &sectoroffs, &tracknum);
	if (err != CHDERR_NONE)
		return 0;

	/* copy out the requested sector */
	tracktype = file->cdtoc.tracks[tracknum].trktype;
	if ((datatype == tracktype) || (datatype == CD_TRACK_RAW_DONTCARE))
	{
		memcpy(buffer, &file->cache[sectoroffs * CD_FRAME_SIZE], file->cdtoc.tracks[tracknum].datasize);
	}
	else
	{
		/* return 2048 bytes of mode 1 data from a 2352 byte mode 1 raw sector */
		if ((datatype == CD_TRACK_MODE1) && (tracktype == CD_TRACK_MODE1_RAW))
		{
			memcpy(buffer, &file->cache[(sectoroffs * CD_FRAME_SIZE) + 16], 2048);
			return 1;
		}

		/* return 2352 byte mode 1 raw sector from 2048 bytes of mode 1 data */
		if ((datatype == CD_TRACK_MODE1_RAW) && (tracktype == CD_TRACK_MODE1))
		{
			UINT8 *bufptr = (UINT8 *)buffer;
			UINT32 msf = lba_to_msf(lbasector);

			memcpy(bufptr, syncbytes, 12);
			bufptr[12] = msf>>16;
			bufptr[13] = msf>>8;
			bufptr[14] = msf&0xff;
			bufptr[15] = 1;	// mode 1
			memcpy(bufptr+16, &file->cache[(sectoroffs * CD_FRAME_SIZE)], 2048);
			LOG(("CDROM: promotion of mode1/form1 sector to mode1 raw is not complete!\n"));
			return 1;
		}

		/* return 2048 bytes of mode 1 data from a mode2 form1 or raw sector */
		if ((datatype == CD_TRACK_MODE1) && ((tracktype == CD_TRACK_MODE2_FORM1)||(tracktype == CD_TRACK_MODE2_RAW)))
		{
			memcpy(buffer, &file->cache[(sectoroffs * CD_FRAME_SIZE) + 24], 2048);
			return 1;
		}

		/* return mode 2 2336 byte data from a 2352 byte mode 1 or 2 raw sector (skip the header) */
		if ((datatype == CD_TRACK_MODE2) && ((tracktype == CD_TRACK_MODE1_RAW) || (tracktype == CD_TRACK_MODE2_RAW)))
		{
			memcpy(buffer, &file->cache[(sectoroffs * CD_FRAME_SIZE) + 16], 2336);
			return 1;
		}

		LOG(("CDROM: Conversion from type %d to type %d not supported!\n", tracktype, datatype));
		return 0;
	}
Пример #6
0
int cueify_device_read_track_indices(cueify_device *d, cueify_indices *i,
				     uint8_t track) {
    cueify_device_private *dev = (cueify_device_private *)d;
    cueify_indices_private *indices = (cueify_indices_private *)i;
    cueify_full_toc_private toc;

    if (cueify_device_read_full_toc_unportable(dev, &toc) != CUEIFY_OK) {
	return CUEIFY_ERR_INTERNAL;
    }

    if ((track >= toc.first_track_number &&
	 track <= toc.last_track_number) ||
	track == CUEIFY_LEAD_OUT_TRACK) {
	/* First, see if there appears to be more than one index. */
	cueify_msf_t msf;
	cueify_position_t pos;
	int lba, first_lba, left_lba, right_lba, last_lba;
	int index;

	first_lba = left_lba = msf_to_lba(toc.tracks[track].offset);
	if (track ==
	    toc.sessions[toc.tracks[track].session].last_track_number) {
	    last_lba = right_lba =
		msf_to_lba(toc.sessions[toc.tracks[track].session].leadout);
	} else {
	    last_lba = right_lba = msf_to_lba(toc.tracks[track + 1].offset);
	}

	/* Get the index of the penultimate second of the track. */
	lba = last_lba - 1;
	if (lba < left_lba) {
	    lba = (left_lba + last_lba) / 2;
	}

	/* And the MSF of the first. */
	lba_to_msf(first_lba, &msf);

	if (cueify_device_read_position_unportable(
		dev, track, lba, &pos) != CUEIFY_OK) {
	    return CUEIFY_ERR_INTERNAL;
	}

	if (pos.track == track &&
	    pos.index != 1) {
	    indices->num_indices = pos.index;
	    indices->has_pregap = 0;
	    indices->indices = calloc(indices->num_indices,
				      sizeof(cueify_msf_t));
	    if (indices->indices == NULL) {
		return CUEIFY_ERR_INTERNAL;
	    }
	    indices->indices[0] = msf;
	} else if (pos.track == track + 1) {
	    indices->num_indices = 2;
	    indices->has_pregap = 1;
	    indices->indices = calloc(indices->num_indices,
				      sizeof(cueify_msf_t));
	    if (indices->indices == NULL) {
		return CUEIFY_ERR_INTERNAL;
	    }
	    indices->indices[0] = msf;

	    /* Detect the pre-gap. */
	    while (left_lba != right_lba) {
		lba = (left_lba + right_lba) / 2;

		if (cueify_device_read_position_unportable(
			dev, track, lba, &pos) != CUEIFY_OK) {
		    free(indices->indices);
		    indices->indices = NULL;
		    return CUEIFY_ERR_INTERNAL;
		}

		if (pos.track == track) {
		    /* Choose the right half. */
		    left_lba = lba + 1;
		} else {
		    /* Choose the left half. */
		    right_lba = lba;
		}
	    }

	    /* Found the start address. */
	    lba_to_msf(left_lba, &msf);
	    indices->indices[1] = msf;

	    /* Reset the right and left sides. */
	    last_lba = right_lba = lba;
	    left_lba = first_lba;

	    /* And calculate the TRUE index count. */
	    lba = last_lba - 1;
	    if (lba < left_lba) {
		lba = (left_lba + last_lba) / 2;
	    }

	    if (cueify_device_read_position_unportable(
		    dev, track, lba, &pos) != CUEIFY_OK) {
		free(indices->indices);
		indices->indices = NULL;
		return CUEIFY_ERR_INTERNAL;
	    }

	    if (pos.track == track &&
		pos.index != 1) {
		indices->num_indices = pos.index + 1;
		indices->indices = realloc(indices->indices,
					   indices->num_indices *
					   sizeof(cueify_msf_t));
		if (indices->indices == NULL) {
		    return CUEIFY_ERR_INTERNAL;
		}

		/* TODO: Test me. */
		/* Copy the pre-gap indices over. */
		memcpy(&(indices->indices[indices->num_indices]),
		       &(indices->indices[1]),
		       sizeof(cueify_msf_t));
	    } else {
		/* That's it. */
		return CUEIFY_OK;
	    }
	} else {
	    indices->num_indices = 1;
	    indices->has_pregap = 0;
	    indices->indices = calloc(1, sizeof(cueify_msf_t));
	    if (indices->indices == NULL) {
		return 0;
	    }
	    indices->indices[0] = msf;
	    return CUEIFY_OK;
	}

	for (index = 1; index < indices->num_indices; index++) {
	    /* Detect the given index by binary search. */
	    while (left_lba != right_lba) {
		lba = (left_lba + right_lba) / 2;

		if (cueify_device_read_position_unportable(
			dev, track, lba, &pos) != CUEIFY_OK) {
		    free(indices->indices);
		    indices->indices = NULL;
		    return CUEIFY_ERR_INTERNAL;
		}

		if (pos.index >= index + 1) {
		    /* Choose the left half. */
		    right_lba = lba;
		} else {
		    /* Choose the right half. */
		    left_lba = lba + 1;
		}
	    }

	    /* Found the start address. */
	    lba_to_msf(left_lba, &msf);
	    indices->indices[index] = msf;

	    /* Reset the right side. */
	    right_lba = last_lba;
	}
	
	return CUEIFY_OK;
    } else {
	return CUEIFY_ERR_INTERNAL;
    }
}  /* cueify_device_read_track_indices */
Пример #7
0
int 
main (int argc, const char *argv[])
{
  VcdMpegSource *src;
  unsigned packets, packet_no;
  VcdMpegStreamCtx ctx;

  if (argc != 2)
    return 1;

  src = vcd_mpeg_source_new (vcd_data_source_new_stdio (argv[1]));

  vcd_mpeg_source_scan (src, true, true,  NULL, NULL);

  packets = vcd_mpeg_source_get_info (src)->packets;

  printf ("packets: %d\n", packets);

  memset (&ctx, 0, sizeof (ctx));

  ctx.stream.scan_data_warnings = VCD_MPEG_SCAN_DATA_WARNS + 1;

  printf ("cur_ofs  (lba) aps prev_ofs  next_ofs  back_ofs  forw_ofs\n");

  for (packet_no = 0; packet_no < packets; packet_no++)
    {
      /* struct vcd_mpeg_packet_flags pkt_flags; */
      char buf[2324];

      vcd_mpeg_source_get_packet (src, packet_no,
				  buf, /* &pkt_flags */ NULL, false);

      vcd_mpeg_parse_packet (&buf, 2324, true, &ctx);

      if (ctx.packet.scan_data_ptr)
	{
	  struct vcd_mpeg_scan_data_t *sd = ctx.packet.scan_data_ptr;
	  msf_t _msf;

	  lba_to_msf (packet_no, &_msf);

	  printf ("%.2x:%.2x.%.2x (%4d) %d ",
		  _msf.m, _msf.s, _msf.f,
		  packet_no, ctx.packet.aps);

	  _dump_msf (&sd->prev_ofs);
	  _dump_msf (&sd->next_ofs);

	  _dump_msf (&sd->back_ofs);
	  _dump_msf (&sd->forw_ofs);

	  printf ("\n");
	}
    }

  {
    const struct vcd_mpeg_stream_info *_info = vcd_mpeg_source_get_info (src);
    printf ("mpeg info\n");
  
    printf (" %d x %d (%f:1) @%f v%d\n", _info->shdr[0].hsize, _info->shdr[0].vsize,
	    _info->shdr[0].aratio, _info->shdr[0].frate, _info->version);
  }

  vcd_mpeg_source_destroy (src, true);

  return 0;
}