libcdio  2.1.0
About: GNU libcdio is a library for CD-ROM and CD image access.
  Fossies Dox: libcdio-2.1.0.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

bincue.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2006, 2008, 2011-2012, 2014, 2017
3  Rocky Bernstein <rocky@gnu.org>
4  Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
5  cue parsing routine adapted from cuetools
6  Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 /* This code implements low-level access functions for a CD images
23  residing inside a disk file (*.bin) and its associated cue sheet.
24  (*.cue).
25 */
26 #include "portable.h"
27 #include "image.h"
28 #include "cdio_assert.h"
29 #include "cdio_private.h"
30 #include "cdtext_private.h"
31 #include "_cdio_stdio.h"
32 
33 #include <cdio/logging.h>
34 #include <cdio/util.h>
35 #include <cdio/version.h>
36 
37 #ifdef HAVE_STDIO_H
38 #include <stdio.h>
39 #endif
40 #ifdef HAVE_STDLIB_H
41 #include <stdlib.h>
42 #endif
43 #ifdef HAVE_STRING_H
44 #include <string.h>
45 #endif
46 #ifdef HAVE_STRINGS_H
47 #include <strings.h>
48 #endif
49 #ifdef HAVE_ERRNO_H
50 #include <errno.h>
51 #endif
52 #ifdef HAVE_GLOB_H
53 #include <glob.h>
54 #endif
55 #ifdef HAVE_INTTYPES_H
56 #include <inttypes.h>
57 #else
58 #define PRId64 "lld"
59 #endif
60 #ifdef HAVE_WINDOWS_H
61 #include <windows.h>
62 #endif
63 
64 #include <ctype.h>
65 
66 #include <cdio/logging.h>
67 #include <cdio/util.h>
68 #include <cdio/utf8.h>
69 #include <cdio/version.h>
70 
71 #include "image.h"
72 #include "cdio_assert.h"
73 #include "cdio_private.h"
74 #include "_cdio_stdio.h"
75 
76 /* reader */
77 
78 #define DEFAULT_CDIO_DEVICE "videocd.bin"
79 #define DEFAULT_CDIO_CUE "videocd.cue"
80 
81 #ifdef _WIN32
82 #define CDIO_FOPEN fopen_utf8
83 #else
84 #define CDIO_FOPEN fopen
85 #endif
86 
87 static lsn_t get_disc_last_lsn_bincue(void *p_user_data);
88 #include "image_common.h"
89 static bool parse_cuefile(_img_private_t *cd, const char *toc_name);
90 
94 static bool
96 {
97  lsn_t lead_lsn;
98 
99  if (p_env->gen.init)
100  return false;
101 
102  if (!(p_env->gen.data_source = cdio_stdio_new (p_env->gen.source_name))) {
103  cdio_warn ("init failed");
104  return false;
105  }
106 
107  /* Have to set init before calling get_disc_last_lsn_bincue() or we will
108  get into infinite recursion calling passing right here.
109  */
110  p_env->gen.init = true;
111  p_env->gen.i_first_track = 1;
112  p_env->psz_mcn = NULL;
114 
115  lead_lsn = get_disc_last_lsn_bincue( (_img_private_t *) p_env);
116 
117  if (-1 == lead_lsn) return false;
118 
119  if (NULL == p_env->psz_cue_name) return false;
120 
121  /* Read in CUE sheet. */
122  if ( !parse_cuefile(p_env, p_env->psz_cue_name) ) return false;
123 
124  /* Fake out leadout track and sector count for last track*/
125  cdio_lsn_to_msf (lead_lsn, &p_env->tocent[p_env->gen.i_tracks].start_msf);
126  p_env->tocent[p_env->gen.i_tracks].start_lba = cdio_lsn_to_lba(lead_lsn);
127  p_env->tocent[p_env->gen.i_tracks - p_env->gen.i_first_track].sec_count =
128  cdio_lsn_to_lba(lead_lsn -
129  p_env->tocent[p_env->gen.i_tracks - p_env->gen.i_first_track].start_lba);
130 
131  return true;
132 }
133 
140 static off_t
141 _lseek_bincue (void *p_user_data, off_t offset, int whence)
142 {
143  _img_private_t *p_env = p_user_data;
144 
145  /* real_offset is the real byte offset inside the disk image
146  The number below was determined empirically. I'm guessing
147  the 1st 24 bytes of a bin file are used for something.
148  */
149  off_t real_offset=0;
150 
151  unsigned int i;
152 
153  p_env->pos.lba = 0;
154  for (i=0; i<p_env->gen.i_tracks; i++) {
155  track_info_t *this_track=&(p_env->tocent[i]);
156  p_env->pos.index = i;
157  if ( (this_track->sec_count*this_track->datasize) >= offset) {
158  int blocks = (int) (offset / this_track->datasize);
159  int rem = (int) (offset % this_track->datasize);
160  off_t block_offset = blocks * this_track->blocksize;
161  real_offset += block_offset + rem;
162  p_env->pos.buff_offset = rem;
163  p_env->pos.lba += (lba_t) blocks;
164  break;
165  }
166  real_offset += this_track->sec_count*this_track->blocksize;
167  offset -= this_track->sec_count*this_track->datasize;
168  p_env->pos.lba += this_track->sec_count;
169  }
170 
171  if (i==p_env->gen.i_tracks) {
172  cdio_warn ("seeking outside range of disk image");
173  return DRIVER_OP_ERROR;
174  } else {
175  real_offset += p_env->tocent[i].datastart;
176  return cdio_stream_seek(p_env->gen.data_source, real_offset, whence);
177  }
178 }
179 
187 static ssize_t
188 _read_bincue (void *p_user_data, void *data, size_t size)
189 {
190  _img_private_t *p_env = p_user_data;
191  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
192  char *p = data;
193  ssize_t final_size=0;
194  ssize_t this_size;
195  track_info_t *this_track=&(p_env->tocent[p_env->pos.index]);
196  ssize_t skip_size = this_track->datastart + this_track->endsize;
197 
198  while (size > 0) {
199  long int rem = (long int) (this_track->datasize - p_env->pos.buff_offset);
200  if ((long int) size <= rem) {
201  this_size = cdio_stream_read(p_env->gen.data_source, buf, size, 1);
202  final_size += this_size;
203  memcpy (p, buf, this_size);
204  break;
205  }
206 
207  /* Finish off reading this sector. */
208  cdio_warn ("Reading across block boundaries not finished");
209 
210  size -= rem;
211  this_size = cdio_stream_read(p_env->gen.data_source, buf, rem, 1);
212  final_size += this_size;
213  memcpy (p, buf, this_size);
214  p += this_size;
215  cdio_stream_read(p_env->gen.data_source, buf, rem, 1);
216 
217  /* Skip over stuff at end of this sector and the beginning of the next.
218  */
219  cdio_stream_read(p_env->gen.data_source, buf, skip_size, 1);
220 
221  /* Get ready to read another sector. */
222  p_env->pos.buff_offset=0;
223  p_env->pos.lba++;
224 
225  /* Have gone into next track. */
226  if (p_env->pos.lba >= p_env->tocent[p_env->pos.index+1].start_lba) {
227  p_env->pos.index++;
228  this_track=&(p_env->tocent[p_env->pos.index]);
229  skip_size = this_track->datastart + this_track->endsize;
230  }
231  }
232  return final_size;
233 }
234 
238 static lsn_t
239 get_disc_last_lsn_bincue (void *p_user_data)
240 {
241  _img_private_t *p_env = p_user_data;
242  off_t size;
243 
244  size = cdio_stream_stat (p_env->gen.data_source);
245 
246  if (size % CDIO_CD_FRAMESIZE_RAW)
247  {
248  cdio_warn ("image %s size (%" PRId64 ") not multiple of blocksize (%d)",
249  p_env->gen.source_name, (int64_t)size, CDIO_CD_FRAMESIZE_RAW);
250  if (size % M2RAW_SECTOR_SIZE == 0)
251  cdio_warn ("this may be a 2336-type disc image");
252  else if (size % CDIO_CD_FRAMESIZE_RAW == 0)
253  cdio_warn ("this may be a 2352-type disc image");
254  /* exit (EXIT_FAILURE); */
255  }
256 
257  size /= CDIO_CD_FRAMESIZE_RAW;
258 
259  return (lsn_t)size;
260 }
261 
262 #define MAXLINE 4096 /* maximum line length + 1 */
263 
264 static bool
265 parse_cuefile (_img_private_t *cd, const char *psz_cue_name)
266 {
267  /* The below declarations may be common in other image-parse routines. */
268  FILE *fp;
269  char psz_line[MAXLINE]; /* text of current line read in file fp. */
270  unsigned int i_line=0; /* line number in file of psz_line. */
271  int i = -1; /* Position in tocent. Same as
272  cd->gen.i_tracks - 1 */
273  char *psz_keyword, *psz_field, *psz_cue_name_dup;
274  cdio_log_level_t log_level = (NULL == cd) ? CDIO_LOG_INFO : CDIO_LOG_WARN;
275  cdtext_field_t cdtext_key;
276 
277  /* The below declarations may be unique to this image-parse routine. */
278  int start_index;
279  bool b_first_index_for_track=false;
280 
281  if (NULL == psz_cue_name)
282  return false;
283 
284  psz_cue_name_dup = _cdio_strdup_fixpath(psz_cue_name);
285  if (NULL == psz_cue_name_dup)
286  return false;
287 
288  fp = CDIO_FOPEN (psz_cue_name_dup, "r");
289  cdio_free(psz_cue_name_dup);
290  if (fp == NULL) {
291  cdio_log(log_level, "error opening %s for reading: %s",
292  psz_cue_name, strerror(errno));
293  return false;
294  }
295 
296  if (cd) {
297  cd->gen.i_tracks=0;
298  cd->gen.i_first_track=1;
299  cd->psz_mcn=NULL;
300  }
301 
302  while ((fgets(psz_line, MAXLINE, fp)) != NULL) {
303 
304  i_line++;
305 
306  if (NULL != (psz_keyword = strtok (psz_line, " \t\n\r"))) {
307  /* REM remarks ... */
308  if (0 == strcmp ("REM", psz_keyword)) {
309  ;
310 
311  /* global section */
312  /* CATALOG ddddddddddddd */
313  } else if (0 == strcmp ("CATALOG", psz_keyword)) {
314  if (-1 == i) {
315  if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
316  cdio_log(log_level,
317  "%s line %d after word CATALOG: ",
318  psz_cue_name, i_line);
319  cdio_log(log_level,
320  "expecting 13-digit media catalog number, got nothing.");
321  goto err_exit;
322  }
323  if (strlen(psz_field) != 13) {
324  cdio_log(log_level,
325  "%s line %d after word CATALOG: ",
326  psz_cue_name, i_line);
327  cdio_log(log_level,
328  "Token %s has length %ld. Should be 13 digits.",
329  psz_field, (long int) strlen(psz_field));
330  goto err_exit;
331  } else {
332  /* Check that we have all digits*/
333  unsigned int j;
334  for (j=0; j<13; j++) {
335  if (!isdigit((unsigned char) psz_field[j])) {
336  cdio_log(log_level,
337  "%s line %d after word CATALOG:",
338  psz_cue_name, i_line);
339  cdio_log(log_level,
340  "Character \"%c\" at postition %i of token \"%s\" "
341  "is not all digits.",
342  psz_field[j], j+1, psz_field);
343  goto err_exit;
344  }
345  }
346  }
347 
348  if (cd) cd->psz_mcn = strdup (psz_field);
349  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
350  goto format_error;
351  }
352  } else {
353  goto not_in_global_section;
354  }
355 
356  /* CDTEXTFILE "<filename>" */
357  } else if (0 == strcmp ("CDTEXTFILE", psz_keyword)) {
358  if(NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
359  if (cd) {
360  uint8_t cdt_data[CDTEXT_LEN_BINARY_MAX+4];
361  int size;
362  CdioDataSource_t *source;
363  char *dirname = cdio_dirname(psz_cue_name);
364  char *psz_filename = cdio_abspath(dirname, psz_field);
365 
366  if(NULL == (source = cdio_stdio_new(psz_filename))) {
367  cdio_log(log_level, "%s line %d: can't open file `%s' for reading",
368  psz_cue_name, i_line, psz_field);
369  free(psz_filename);
370  free(dirname);
371  goto err_exit;
372  }
373  size = cdio_stream_read(source, cdt_data, CDTEXT_LEN_BINARY_MAX, 1);
374 
375  if (size < 5) {
376  cdio_log(log_level,
377  "%s line %d: file `%s' is too small to contain CD-TEXT",
378  psz_cue_name, i_line, psz_filename);
379  free(psz_filename);
380  free(dirname);
381  free(source);
382  goto err_exit;
383  }
384 
385  /* Truncate header when it is too large. */
386  if (cdt_data[0] > 0x80) {
387  size -= 4;
388  }
389 
390  /* ignore trailing 0 */
391  if (1 == size % 18)
392  size -= 1;
393 
394  /* init cdtext */
395  if (NULL == cd->gen.cdtext) {
396  cd->gen.cdtext = cdtext_init ();
397  }
398 
399  if(0 != cdtext_data_init(cd->gen.cdtext, cdt_data, size))
400  cdio_log (log_level, "%s line %d: failed to parse CD-TEXT file `%s'", psz_cue_name, i_line, psz_filename);
401 
402  cdio_stdio_destroy (source);
403  free(psz_filename);
404  free(dirname);
405  }
406  } else {
407  goto format_error;
408  }
409 
410  /* FILE "<filename>" <BINARY|WAVE|other?> */
411  } else if (0 == strcmp ("FILE", psz_keyword)) {
412  if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
413  char *dirname = cdio_dirname(psz_cue_name);
414  char *filename = cdio_abspath(dirname, psz_field);
415  if (cd) cd->tocent[i + 1].filename = strdup(filename);
416  free(filename);
417  free(dirname);
418  } else {
419  goto format_error;
420  }
421 
422  /* TRACK N <mode> */
423  } else if (0 == strcmp("TRACK", psz_keyword)) {
424  int i_track;
425 
426  if (NULL != (psz_field = strtok(NULL, " \t\n\r"))) {
427  if (1!=sscanf(psz_field, "%d", &i_track)) {
428  cdio_log(log_level,
429  "%s line %d after word TRACK:",
430  psz_cue_name, i_line);
431  cdio_log(log_level,
432  "Expecting a track number, got %s", psz_field);
433  goto err_exit;
434  }
435  if (i_track < 1 || i_track > 99) {
436  cdio_log(log_level,
437  "Track number out of range 1 to 99, got %s", psz_field);
438  goto err_exit;
439  }
440  if(cd) {
441  if (-1 == i) {
442  cd->gen.i_first_track = i_track;
443  } else if(cd->gen.i_first_track + i + 1 != i_track) {
444  cdio_log(log_level,
445  "Track number out of sequence. Expected %d, got %d",
446  cd->gen.i_first_track + i + 1, i_track);
447  }
448  }
449  }
450  if (NULL != (psz_field = strtok(NULL, " \t\n\r"))) {
451  track_info_t *this_track=NULL;
452 
453  if (cd) {
454  this_track = &(cd->tocent[cd->gen.i_tracks]);
455  this_track->track_num = cd->gen.i_tracks;
456  this_track->num_indices = 0;
457  b_first_index_for_track = false;
458  cd->gen.i_tracks++;
459  }
460  i++;
461 
462  if (0 == strcmp("AUDIO", psz_field)) {
463  if (cd) {
464  this_track->mode = AUDIO;
465  this_track->blocksize = CDIO_CD_FRAMESIZE_RAW;
466  this_track->datasize = CDIO_CD_FRAMESIZE_RAW;
467  this_track->datastart = 0;
468  this_track->endsize = 0;
469  this_track->track_format = TRACK_FORMAT_AUDIO;
470  this_track->track_green = false;
471  switch(cd->disc_mode) {
474  break;
478  /* Disc type stays the same. */
479  break;
483  break;
484  default:
486  }
487  }
488  } else if (0 == strcmp("MODE1/2048", psz_field)) {
489  if (cd) {
490  this_track->mode = MODE1;
491  this_track->blocksize = 2048;
492  this_track->track_format= TRACK_FORMAT_DATA;
493  this_track->track_green = false;
494  /* Is the below correct? */
495  this_track->datastart = 0;
496  this_track->datasize = CDIO_CD_FRAMESIZE;
497  this_track->endsize = 0;
498  switch(cd->disc_mode) {
501  break;
505  /* Disc type stays the same. */
506  break;
510  break;
511  default:
513  }
514  }
515  } else if (0 == strcmp("MODE1/2352", psz_field)) {
516  if (cd) {
517  this_track->blocksize = 2352;
518  this_track->track_format= TRACK_FORMAT_DATA;
519  this_track->track_green = false;
520  this_track->datastart = CDIO_CD_SYNC_SIZE
522  this_track->datasize = CDIO_CD_FRAMESIZE;
523  this_track->endsize = CDIO_CD_EDC_SIZE
525  this_track->mode = MODE1_RAW;
526  switch(cd->disc_mode) {
529  break;
533  /* Disc type stays the same. */
534  break;
538  break;
539  default:
541  }
542  }
543  } else if (0 == strcmp("MODE2/2336", psz_field)) {
544  if (cd) {
545  this_track->blocksize = 2336;
546  this_track->track_format= TRACK_FORMAT_XA;
547  this_track->track_green = true;
548  this_track->mode = MODE2;
549  this_track->datastart = CDIO_CD_SYNC_SIZE
551  this_track->datasize = M2RAW_SECTOR_SIZE;
552  this_track->endsize = 0;
553  switch(cd->disc_mode) {
556  break;
560  /* Disc type stays the same. */
561  break;
565  break;
566  default:
568  }
569  }
570  } else if (0 == strcmp("MODE2/2048", psz_field)) {
571  if (cd) {
572  this_track->blocksize = 2048;
573  this_track->track_format= TRACK_FORMAT_XA;
574  this_track->track_green = true;
575  this_track->mode = MODE2_FORM1;
576  switch(cd->disc_mode) {
579  break;
583  /* Disc type stays the same. */
584  break;
588  break;
589  default:
591  }
592  }
593  } else if (0 == strcmp("MODE2/2324", psz_field)) {
594  if (cd) {
595  this_track->blocksize = 2324;
596  this_track->track_format= TRACK_FORMAT_XA;
597  this_track->track_green = true;
598  this_track->mode = MODE2_FORM2;
599  switch(cd->disc_mode) {
602  break;
606  /* Disc type stays the same. */
607  break;
611  break;
612  default:
614  }
615  }
616  } else if (0 == strcmp("MODE2/2336", psz_field)) {
617  if (cd) {
618  this_track->blocksize = 2336;
619  this_track->track_format= TRACK_FORMAT_XA;
620  this_track->track_green = true;
621  this_track->mode = MODE2_FORM_MIX;
622  this_track->datastart = CDIO_CD_SYNC_SIZE
624  this_track->datasize = M2RAW_SECTOR_SIZE;
625  this_track->endsize = 0;
626  switch(cd->disc_mode) {
629  break;
633  /* Disc type stays the same. */
634  break;
638  break;
639  default:
641  }
642  }
643  } else if (0 == strcmp("MODE2/2352", psz_field)) {
644  if (cd) {
645  this_track->blocksize = 2352;
646  this_track->track_format= TRACK_FORMAT_XA;
647  this_track->track_green = true;
648  this_track->mode = MODE2_RAW;
649  this_track->datastart = CDIO_CD_SYNC_SIZE
651  this_track->datasize = CDIO_CD_FRAMESIZE;
653  switch(cd->disc_mode) {
656  break;
660  /* Disc type stays the same. */
661  break;
665  break;
666  default:
668  }
669  }
670  } else {
671  cdio_log(log_level,
672  "%s line %d after word TRACK:",
673  psz_cue_name, i_line);
674  cdio_log(log_level,
675  "Unknown track mode %s", psz_field);
676  goto err_exit;
677  }
678  } else {
679  goto format_error;
680  }
681 
682  /* FLAGS flag1 flag2 ... */
683  } else if (0 == strcmp("FLAGS", psz_keyword)) {
684  if (0 <= i) {
685  while (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
686  if (0 == strcmp ("PRE", psz_field)) {
687  if (cd) cd->tocent[i].flags |= PRE_EMPHASIS;
688  } else if (0 == strcmp ("DCP", psz_field)) {
689  if (cd) cd->tocent[i].flags |= COPY_PERMITTED;
690  } else if (0 == strcmp ("4CH", psz_field)) {
691  if (cd) cd->tocent[i].flags |= FOUR_CHANNEL_AUDIO;
692  } else if (0 == strcmp ("SCMS", psz_field)) {
693  if (cd) cd->tocent[i].flags |= SCMS;
694  } else {
695  goto format_error;
696  }
697  }
698  } else {
699  goto format_error;
700  }
701 
702  /* ISRC CCOOOYYSSSSS */
703  } else if (0 == strcmp("ISRC", psz_keyword)) {
704  if (0 <= i) {
705  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
706  if (cd) cd->tocent[i].isrc = strdup (psz_field);
707  } else {
708  goto format_error;
709  }
710  } else {
711  goto in_global_section;
712  }
713 
714  /* PREGAP MM:SS:FF */
715  } else if (0 == strcmp("PREGAP", psz_keyword)) {
716  if (0 <= i) {
717  if (NULL != (psz_field = strtok(NULL, " \t\n\r"))) {
718  lba_t lba = cdio_lsn_to_lba(cdio_mmssff_to_lba (psz_field));
719  if (CDIO_INVALID_LBA == lba) {
720  cdio_log(log_level, "%s line %d: after word PREGAP:",
721  psz_cue_name, i_line);
722  cdio_log(log_level, "Invalid MSF string %s",
723  psz_field);
724  goto err_exit;
725  }
726  if (cd) {
727  cd->tocent[i].silence = lba;
728  }
729  } else {
730  goto format_error;
731  } if (NULL != strtok(NULL, " \t\n\r")) {
732  goto format_error;
733  }
734  } else {
735  goto in_global_section;
736  }
737 
738  /* INDEX [##] MM:SS:FF */
739  } else if (0 == strcmp ("INDEX", psz_keyword)) {
740  if (0 <= i) {
741  if (NULL != (psz_field = strtok(NULL, " \t\n\r")))
742  if (1!=sscanf(psz_field, "%d", &start_index)) {
743  cdio_log(log_level,
744  "%s line %d after word INDEX:",
745  psz_cue_name, i_line);
746  cdio_log(log_level,
747  "expecting an index number, got %s",
748  psz_field);
749  goto err_exit;
750  }
751  if (NULL != (psz_field = strtok(NULL, " \t\n\r"))) {
752  lba_t lba = cdio_mmssff_to_lba (psz_field);
753  if (CDIO_INVALID_LBA == lba) {
754  cdio_log(log_level, "%s line %d: after word INDEX:",
755  psz_cue_name, i_line);
756  cdio_log(log_level, "Invalid MSF string %s",
757  psz_field);
758  goto err_exit;
759  }
760  if (cd) {
761 #ifdef FIXME
762  cd->tocent[i].indexes[cd->tocent[i].nindex++] = lba;
763 #else
764  track_info_t *this_track=
765  &(cd->tocent[cd->gen.i_tracks - 1]);
766 
767  switch (start_index) {
768 
769  case 0:
770  lba += CDIO_PREGAP_SECTORS;
771  this_track->pregap = lba;
772  break;
773 
774  case 1:
775  if (!b_first_index_for_track) {
776  lba += CDIO_PREGAP_SECTORS;
777  cdio_lba_to_msf(lba, &(this_track->start_msf));
778  b_first_index_for_track = true;
779  this_track->start_lba = lba;
780  }
781 
782  if (cd->gen.i_tracks > 1) {
783  /* Figure out number of sectors for previous track */
784  track_info_t *prev_track=&(cd->tocent[cd->gen.i_tracks-2]);
785  if ( this_track->start_lba < prev_track->start_lba ) {
786  cdio_log (log_level,
787  "track %d at LBA %lu starts before track %d at LBA %lu",
788  cd->gen.i_tracks,
789  (unsigned long int) this_track->start_lba,
790  cd->gen.i_tracks,
791  (unsigned long int) prev_track->start_lba);
792  prev_track->sec_count = 0;
793  } else if ( this_track->start_lba >= prev_track->start_lba
794  + CDIO_PREGAP_SECTORS ) {
795  prev_track->sec_count = this_track->start_lba -
796  prev_track->start_lba - CDIO_PREGAP_SECTORS ;
797  } else {
798  cdio_log (log_level,
799  "%lu fewer than pregap (%d) sectors in track %d",
800  (long unsigned int)
801  this_track->start_lba - prev_track->start_lba,
803  cd->gen.i_tracks);
804  /* Include pregap portion in sec_count. Maybe the pregap
805  was omitted. */
806  prev_track->sec_count = this_track->start_lba -
807  prev_track->start_lba;
808  }
809  }
810  this_track->num_indices++;
811  break;
812 
813  default:
814  break;
815  }
816  }
817 #endif
818  } else {
819  goto format_error;
820  }
821  } else {
822  goto in_global_section;
823  }
824 
825  /* CD-Text */
826  } else if ( CDTEXT_FIELD_INVALID !=
827  (cdtext_key = cdtext_is_field (psz_keyword)) ) {
828  if (cd) {
829  if (NULL == cd->gen.cdtext) {
830  cd->gen.cdtext = cdtext_init ();
832  }
833  cdtext_set (cd->gen.cdtext, cdtext_key, (uint8_t*) strtok(NULL, "\"\t\n\r"),
834  (-1 == i ? 0 : cd->gen.i_first_track + i),
835  "ISO-8859-1");
836  }
837 
838  /* unrecognized line */
839  } else {
840  cdio_log(log_level, "%s line %d: warning: unrecognized keyword: %s",
841  psz_cue_name, i_line, psz_keyword);
842  goto err_exit;
843  }
844  }
845  }
846 
847  if (NULL != cd) {
848  cd->gen.toc_init = true;
849  }
850 
851  fclose (fp);
852  return true;
853 
854  format_error:
855  cdio_log(log_level, "%s line %d after word %s",
856  psz_cue_name, i_line, psz_keyword);
857  goto err_exit;
858 
859  in_global_section:
860  cdio_log(log_level, "%s line %d: word %s not allowed in global section",
861  psz_cue_name, i_line, psz_keyword);
862  goto err_exit;
863 
864  not_in_global_section:
865  cdio_log(log_level, "%s line %d: word %s only allowed in global section",
866  psz_cue_name, i_line, psz_keyword);
867 
868  err_exit:
869  fclose (fp);
870  return false;
871 
872 }
873 
879 _read_audio_sectors_bincue (void *p_user_data, void *data, lsn_t lsn,
880  unsigned int nblocks)
881 {
882  _img_private_t *p_env = p_user_data;
883  int ret;
884 
885  ret = cdio_stream_seek (p_env->gen.data_source,
887  if (ret!=0) return ret;
888 
889  ret = cdio_stream_read (p_env->gen.data_source, data,
890  CDIO_CD_FRAMESIZE_RAW, nblocks);
891 
892  /* ret is number of bytes if okay, but we need to return 0 okay. */
893  return ret == 0;
894 }
895 
901 _read_mode1_sector_bincue (void *p_user_data, void *data, lsn_t lsn,
902  bool b_form2)
903 {
904  _img_private_t *p_env = p_user_data;
905  int ret;
906  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
907  int blocksize = CDIO_CD_FRAMESIZE_RAW;
908 
909  ret = cdio_stream_seek (p_env->gen.data_source, lsn * blocksize, SEEK_SET);
910  if (ret!=0) return ret;
911 
912  /* FIXME: Not completely sure the below is correct. */
913  ret = cdio_stream_read (p_env->gen.data_source, buf, CDIO_CD_FRAMESIZE_RAW, 1);
914  if (ret==0) return ret;
915 
916  memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE,
918 
919  return DRIVER_OP_SUCCESS;
920 }
921 
928 _read_mode1_sectors_bincue (void *p_user_data, void *data, lsn_t lsn,
929  bool b_form2, unsigned int nblocks)
930 {
931  _img_private_t *p_env = p_user_data;
932  int i;
933  int retval;
934  unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
935 
936  for (i = 0; i < nblocks; i++) {
937  if ( (retval = _read_mode1_sector_bincue (p_env,
938  ((char *)data) + (blocksize * i),
939  lsn + i, b_form2)) )
940  return retval;
941  }
942  return DRIVER_OP_SUCCESS;
943 }
944 
950 _read_mode2_sector_bincue (void *p_user_data, void *data, lsn_t lsn,
951  bool b_form2)
952 {
953  _img_private_t *p_env = p_user_data;
954  int ret;
955  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
956 
957  /* NOTE: The logic below seems a bit wrong and convoluted
958  to me, but passes the regression tests. (Perhaps it is why we get
959  valgrind errors in vcdxrip). Leave it the way it was for now.
960  Review this sector 2336 stuff later.
961  */
962 
963  int blocksize = CDIO_CD_FRAMESIZE_RAW;
964 
965  ret = cdio_stream_seek (p_env->gen.data_source, lsn * blocksize, SEEK_SET);
966  if (ret!=0) return ret;
967 
968  ret = cdio_stream_read (p_env->gen.data_source, buf, CDIO_CD_FRAMESIZE_RAW, 1);
969  if (ret==0) return ret;
970 
971 
972  /* See NOTE above. */
973  if (b_form2)
974  memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE,
976  else
977  memcpy (data, buf + CDIO_CD_XA_SYNC_HEADER, CDIO_CD_FRAMESIZE);
978 
979  return DRIVER_OP_SUCCESS;
980 }
981 
988 _read_mode2_sectors_bincue (void *p_user_data, void *data, lsn_t lsn,
989  bool b_form2, unsigned int nblocks)
990 {
991  _img_private_t *p_env = p_user_data;
992  int i;
993  int retval;
994  unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
995 
996  for (i = 0; i < nblocks; i++) {
997  if ( (retval = _read_mode2_sector_bincue (p_env,
998  ((char *)data) + (blocksize * i),
999  lsn + i, b_form2)) )
1000  return retval;
1001  }
1002  return 0;
1003 }
1004 
1005 #if !defined(HAVE_GLOB_H) && defined(_WIN32)
1006 static void Win32Glob(const char* pattern, const char* szCurPath, char ***drives, unsigned int *num_files)
1007 {
1008  char szPath[MAX_PATH];
1009  WIN32_FIND_DATAA ffd;
1010  HANDLE hFind;
1011  BOOL bFound;
1012 
1013  SetCurrentDirectoryA(szCurPath);
1014 
1015  hFind = FindFirstFileA(pattern, &ffd);
1016  bFound = (hFind != INVALID_HANDLE_VALUE);
1017  while (bFound) {
1018  cdio_add_device_list(drives, ffd.cFileName, num_files);
1019  bFound = FindNextFileA(hFind, &ffd);
1020  }
1021  if (hFind != INVALID_HANDLE_VALUE)
1022  FindClose(hFind);
1023 
1024  hFind = FindFirstFileA("*", &ffd);
1025  bFound = (hFind != INVALID_HANDLE_VALUE);
1026  while (bFound) {
1027  if ( (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
1028  (strcmp(ffd.cFileName, ".") != 0) && (strcmp(ffd.cFileName, "..") != 0) ) {
1029  GetFullPathNameA(ffd.cFileName, sizeof(szPath), szPath, NULL);
1030  Win32Glob(pattern, szPath, drives, num_files);
1031  SetCurrentDirectoryA(szCurPath);
1032  }
1033  bFound = FindNextFileA(hFind, &ffd);
1034  }
1035  if (hFind != INVALID_HANDLE_VALUE)
1036  FindClose(hFind);
1037 }
1038 #endif
1039 
1043 char **
1045 {
1046  char **drives = NULL;
1047  unsigned int num_files=0;
1048 #ifdef HAVE_GLOB_H
1049  unsigned int i;
1050  glob_t globbuf;
1051  globbuf.gl_offs = 0;
1052  glob("*.cue", GLOB_DOOFFS, NULL, &globbuf);
1053  for (i=0; i<globbuf.gl_pathc; i++) {
1054  cdio_add_device_list(&drives, globbuf.gl_pathv[i], &num_files);
1055  }
1056  globfree(&globbuf);
1057 #elif defined(_WIN32)
1058  char szStartDir[MAX_PATH];
1059  GetCurrentDirectoryA(sizeof(szStartDir), szStartDir);
1060  Win32Glob("*.cue", szStartDir, &drives, &num_files);
1061 #else
1062  cdio_add_device_list(&drives, DEFAULT_CDIO_DEVICE, &num_files);
1063 #endif /*HAVE_GLOB_H*/
1064  cdio_add_device_list(&drives, NULL, &num_files);
1065  return drives;
1066 }
1067 
1071 char *
1073 {
1074  char **drives = cdio_get_devices_bincue();
1075  char *drive = (drives[0] == NULL) ? NULL : strdup(drives[0]);
1076  cdio_free_device_list(drives);
1077  return drive;
1078 }
1079 
1080 static bool
1081 get_hwinfo_bincue ( const CdIo_t *p_cdio, /*out*/ cdio_hwinfo_t *hw_info)
1082 {
1083  strncpy(hw_info->psz_vendor, "libcdio",
1084  sizeof(hw_info->psz_vendor)-1);
1085  hw_info->psz_vendor[sizeof(hw_info->psz_vendor)-1] = '\0';
1086  strncpy(hw_info->psz_model, "CDRWIN",
1087  sizeof(hw_info->psz_model)-1);
1088  hw_info->psz_model[sizeof(hw_info->psz_model)-1] = '\0';
1089  strncpy(hw_info->psz_revision, CDIO_VERSION,
1090  sizeof(hw_info->psz_revision)-1);
1091  hw_info->psz_revision[sizeof(hw_info->psz_revision)-1] = '\0';
1092  return true;
1093 
1094 }
1095 
1100 static track_format_t
1101 _get_track_format_bincue(void *p_user_data, track_t i_track)
1102 {
1103  const _img_private_t *p_env = p_user_data;
1104 
1105  if (!p_env->gen.init) return TRACK_FORMAT_ERROR;
1106 
1107  if (i_track > p_env->gen.i_first_track + p_env->gen.i_tracks - 1
1108  || i_track < p_env->gen.i_first_track)
1109  return TRACK_FORMAT_ERROR;
1110 
1111  return p_env->tocent[i_track-p_env->gen.i_first_track].track_format;
1112 }
1113 
1122 static bool
1123 _get_track_green_bincue(void *p_user_data, track_t i_track)
1124 {
1125  _img_private_t *p_env = p_user_data;
1126 
1127  if ( NULL == p_env ||
1128  ( i_track < p_env->gen.i_first_track
1129  || i_track >= p_env->gen.i_tracks + p_env->gen.i_first_track ) )
1130  return false;
1131 
1132  return p_env->tocent[i_track-p_env->gen.i_first_track].track_green;
1133 }
1134 
1142 static lba_t
1143 _get_lba_track_bincue(void *p_user_data, track_t i_track)
1144 {
1145  _img_private_t *p_env = p_user_data;
1146 
1147  if (i_track == CDIO_CDROM_LEADOUT_TRACK)
1148  i_track = p_env->gen.i_tracks + p_env->gen.i_first_track;
1149 
1150  if (i_track <= p_env->gen.i_tracks + p_env->gen.i_first_track
1151  && i_track >= p_env->gen.i_first_track) {
1152  return p_env->tocent[i_track-p_env->gen.i_first_track].start_lba;
1153  } else
1154  return CDIO_INVALID_LBA;
1155 }
1156 
1161 char *
1162 cdio_is_cuefile(const char *psz_cue_name)
1163 {
1164  int i;
1165  char *psz_bin_name;
1166 
1167  if (psz_cue_name == NULL) return NULL;
1168 
1169  /* FIXME? Now that we have cue parsing, should we really force
1170  the filename extension requirement or is it enough just to
1171  parse the cuefile?
1172  */
1173 
1174  psz_bin_name=strdup(psz_cue_name);
1175  i=strlen(psz_bin_name)-strlen("cue");
1176 
1177  if (i>0) {
1178  if (psz_cue_name[i]=='c' && psz_cue_name[i+1]=='u' && psz_cue_name[i+2]=='e') {
1179  psz_bin_name[i++]='b'; psz_bin_name[i++]='i'; psz_bin_name[i++]='n';
1180  if (parse_cuefile(NULL, psz_cue_name))
1181  return psz_bin_name;
1182  else
1183  goto error;
1184  }
1185  else if (psz_cue_name[i]=='C' && psz_cue_name[i+1]=='U' && psz_cue_name[i+2]=='E') {
1186  psz_bin_name[i++]='B'; psz_bin_name[i++]='I'; psz_bin_name[i++]='N';
1187  if (parse_cuefile(NULL, psz_cue_name))
1188  return psz_bin_name;
1189  else
1190  goto error;
1191  }
1192  }
1193  error:
1194  free(psz_bin_name);
1195  return NULL;
1196 }
1197 
1202 char *
1203 cdio_is_binfile(const char *psz_bin_name)
1204 {
1205  int i;
1206  char *psz_cue_name;
1207 
1208  if (psz_bin_name == NULL) return NULL;
1209 
1210  psz_cue_name=strdup(psz_bin_name);
1211  i=strlen(psz_bin_name)-strlen("bin");
1212 
1213  if (i>0) {
1214  if (psz_bin_name[i]=='b' && psz_bin_name[i+1]=='i' && psz_bin_name[i+2]=='n') {
1215  psz_cue_name[i++]='c'; psz_cue_name[i++]='u'; psz_cue_name[i++]='e';
1216  return psz_cue_name;
1217  }
1218  else if (psz_bin_name[i]=='B' && psz_bin_name[i+1]=='I' && psz_bin_name[i+2]=='N') {
1219  psz_cue_name[i++]='C'; psz_cue_name[i++]='U'; psz_cue_name[i++]='E';
1220  return psz_cue_name;
1221  }
1222  }
1223  free(psz_cue_name);
1224  return NULL;
1225 }
1226 
1232 CdIo_t *
1233 cdio_open_am_bincue (const char *psz_source_name, const char *psz_access_mode)
1234 {
1235  if (psz_access_mode != NULL)
1236  cdio_warn ("there is only one access mode for bincue. Arg %s ignored",
1237  psz_access_mode);
1238  return cdio_open_bincue(psz_source_name);
1239 }
1240 
1246 CdIo_t *
1247 cdio_open_bincue (const char *psz_source)
1248 {
1249  char *psz_bin_name = cdio_is_cuefile(psz_source);
1250 
1251  if (NULL != psz_bin_name) {
1252  free(psz_bin_name);
1253  return cdio_open_cue(psz_source);
1254  } else {
1255  char *psz_cue_name = cdio_is_binfile(psz_source);
1256  CdIo_t *cdio = cdio_open_cue(psz_cue_name);
1257  free(psz_cue_name);
1258  return cdio;
1259  }
1260 }
1261 
1262 CdIo_t *
1263 cdio_open_cue (const char *psz_cue_name)
1264 {
1265  CdIo_t *ret;
1266  _img_private_t *p_data;
1267  char *psz_bin_name;
1268 
1269  cdio_funcs_t _funcs;
1270 
1271  memset( &_funcs, 0, sizeof(_funcs) );
1272 
1274  _funcs.free = _free_image;
1275  _funcs.get_arg = _get_arg_image;
1276  _funcs.get_cdtext = _get_cdtext_image;
1277  _funcs.get_cdtext_raw = NULL;
1284  _funcs.get_hwinfo = get_hwinfo_bincue;
1286  _funcs.get_mcn = _get_mcn_image;
1297  _funcs.lseek = _lseek_bincue;
1298  _funcs.read = _read_bincue;
1305  _funcs.run_mmc_cmd = NULL;
1306  _funcs.set_arg = _set_arg_image;
1309 
1310  if (NULL == psz_cue_name) return NULL;
1311 
1312  p_data = calloc(1, sizeof (_img_private_t));
1313  p_data->gen.init = false;
1314  p_data->psz_cue_name = NULL;
1315 
1316  ret = cdio_new ((void *)p_data, &_funcs);
1317 
1318  if (ret == NULL) {
1319  free(p_data);
1320  return NULL;
1321  }
1322 
1323  ret->driver_id = DRIVER_BINCUE;
1324  psz_bin_name = cdio_is_cuefile(psz_cue_name);
1325 
1326  if (NULL == psz_bin_name) {
1327  cdio_error ("source name %s is not recognized as a CUE file",
1328  psz_cue_name);
1329  }
1330 
1331  _set_arg_image (p_data, "cue", psz_cue_name);
1332  _set_arg_image (p_data, "source", psz_bin_name);
1333  _set_arg_image (p_data, "access-mode", "bincue");
1334  free(psz_bin_name);
1335 
1336  if (_init_bincue(p_data)) {
1337  return ret;
1338  } else {
1339  _free_image(p_data);
1340  free(ret);
1341  return NULL;
1342  }
1343 }
1344 
1345 bool
1347 {
1348  return true;
1349 }
cdio_free_device_list
void cdio_free_device_list(char *device_list[])
Definition: device.c:477
SEEK_SET
#define SEEK_SET
Definition: read.c:171
cdio_get_default_device_bincue
char * cdio_get_default_device_bincue(void)
Definition: bincue.c:1072
_set_arg_image
driver_return_code_t _set_arg_image(void *p_user_data, const char key[], const char value[])
Definition: image_common.c:366
_read_mode1_sector_bincue
static driver_return_code_t _read_mode1_sector_bincue(void *p_user_data, void *data, lsn_t lsn, bool b_form2)
Definition: bincue.c:901
lba_t
int32_t lba_t
Definition: types.h:259
track_info_t::blocksize
uint16_t blocksize
Definition: image.h:80
_img_private_t::gen
generic_img_private_t gen
Definition: image_common.h:33
_CdioDataSource
Definition: _cdio_stream.c:48
generic_img_private_t::i_first_track
track_t i_first_track
Definition: generic.h:61
cdio_funcs_t::lseek
off_t(* lseek)(void *p_env, off_t offset, int whence)
Definition: cdio_private.h:360
cdio_generic_unimplemented_set_speed
int cdio_generic_unimplemented_set_speed(void *p_user_data, int i_speed)
Definition: _cdio_generic.c:92
cdtext_block_s::language_code
cdtext_lang_t language_code
Definition: cdtext_private.h:117
_get_track_msf_image
bool _get_track_msf_image(void *p_user_data, track_t i_track, msf_t *msf)
Definition: image_common.c:215
track_info_t::flags
flag_t flags
Definition: image.h:59
TRACK_FORMAT_XA
Definition: track.h:34
PRE_EMPHASIS
Definition: sector.h:84
track_info_t::pregap
lba_t pregap
Definition: image.h:54
SCMS
Definition: sector.h:88
cdio_open_cue
CdIo_t * cdio_open_cue(const char *psz_cue_name)
Definition: bincue.c:1263
cdio_lsn_to_lba
lba_t cdio_lsn_to_lba(lsn_t i_lsn)
Definition: sector.c:114
cdio_add_device_list
void cdio_add_device_list(char **device_list[], const char *drive, unsigned int *num_drives)
Definition: _cdio_generic.c:238
CDIO_DISC_MODE_CD_MIXED
Definition: disc.h:41
cdio_funcs_t::read_mode2_sectors
int(* read_mode2_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2, unsigned int i_blocks)
Definition: cdio_private.h:410
generic_img_private_t::source_name
char * source_name
Definition: generic.h:48
cdio_warn
void void void void cdio_warn(const char format[],...) GNUC_PRINTF(1
cdio_funcs_t::get_media_changed
int(* get_media_changed)(const void *p_env)
Definition: cdio_private.h:273
lsn_t
int32_t lsn_t
Definition: types.h:266
driver_return_code_t
driver_return_code_t
Definition: device.h:205
cdio_is_binfile
char * cdio_is_binfile(const char *psz_bin_name)
Definition: bincue.c:1203
cdio_funcs_t::get_default_device
char *(* get_default_device)(void)
Definition: cdio_private.h:223
cdio_is_cuefile
char * cdio_is_cuefile(const char *psz_cue_name)
Definition: bincue.c:1162
_img_private_t::psz_mcn
char * psz_mcn
Definition: image_common.h:41
track_info_t::num_indices
int num_indices
Definition: image.h:58
cdio_new
CdIo_t * cdio_new(generic_img_private_t *p_env, cdio_funcs_t *p_funcs)
Definition: cdio.c:58
CDTEXT_FIELD_INVALID
Definition: cdtext.h:55
cdio_lba_to_msf
void cdio_lba_to_msf(lba_t i_lba, msf_t *p_msf)
Definition: sector.c:124
cdio_hwinfo::psz_model
char psz_model[CDIO_MMC_HW_MODEL_LEN+1]
Definition: device.h:125
cdio_funcs_t::get_track_preemphasis
track_flag_t(* get_track_preemphasis)(const void *p_env, track_t i_track)
Definition: cdio_private.h:353
cdio_funcs_t::run_mmc_cmd
mmc_run_cmd_fn_t run_mmc_cmd
Definition: cdio_private.h:447
_read_bincue
static ssize_t _read_bincue(void *p_user_data, void *data, size_t size)
Definition: bincue.c:188
_img_private_t::psz_cue_name
char * psz_cue_name
Definition: image_common.h:36
generic_img_private_t::toc_init
bool toc_init
Definition: generic.h:50
cdio_funcs_t::get_devices
char **(* get_devices)(void)
Definition: cdio_private.h:211
track_info_t::filename
char * filename
Definition: image.h:61
get_disc_last_lsn_bincue
static lsn_t get_disc_last_lsn_bincue(void *p_user_data)
Definition: bincue.c:239
cdio_funcs_t::get_track_copy_permit
track_flag_t(* get_track_copy_permit)(void *p_env, track_t i_track)
Definition: cdio_private.h:297
cdio_generic_unimplemented_set_blocksize
int cdio_generic_unimplemented_set_blocksize(void *p_user_data, uint16_t i_blocksize)
Definition: _cdio_generic.c:82
cdtext_s::block
struct cdtext_block_s block[CDTEXT_NUM_BLOCKS_MAX]
Definition: cdtext_private.h:128
cdio_hwinfo::psz_revision
char psz_revision[CDIO_MMC_HW_REVISION_LEN+1]
Definition: device.h:126
CDTEXT_LANGUAGE_ENGLISH
Definition: cdtext.h:111
get_hwinfo_bincue
static bool get_hwinfo_bincue(const CdIo_t *p_cdio, cdio_hwinfo_t *hw_info)
Definition: bincue.c:1081
cdio_funcs_t::set_speed
int(* set_speed)(void *p_env, int i_speed)
Definition: cdio_private.h:466
_read_mode2_sectors_bincue
static driver_return_code_t _read_mode2_sectors_bincue(void *p_user_data, void *data, lsn_t lsn, bool b_form2, unsigned int nblocks)
Definition: bincue.c:988
cdio_funcs_t::get_track_lba
lba_t(* get_track_lba)(void *p_env, track_t i_track)
Definition: cdio_private.h:306
track_info_t::track_num
track_t track_num
Definition: image.h:50
_img_private_t::pos
internal_position_t pos
Definition: image_common.h:34
track_info_t::sec_count
int sec_count
Definition: image.h:56
CDIO_CD_FRAMESIZE_RAW
Definition: sector.h:118
read_data_sectors_image
driver_return_code_t read_data_sectors_image(void *p_user_data, void *p_buf, lsn_t i_lsn, uint16_t i_blocksize, uint32_t i_blocks)
Definition: image_common.c:330
track_t
uint8_t track_t
Definition: types.h:276
_get_arg_image
const char * _get_arg_image(void *user_data, const char key[])
Definition: image_common.c:83
cdtext_is_field
cdtext_field_t cdtext_is_field(const char *key)
Definition: cdtext.c:520
_get_first_track_num_image
track_t _get_first_track_num_image(void *p_user_data)
Definition: image_common.c:156
generic_img_private_t::init
bool init
Definition: generic.h:49
CDIO_DISC_MODE_ERROR
Definition: disc.h:55
cdio_funcs_t::get_track_format
track_format_t(* get_track_format)(void *p_env, track_t i_track)
Definition: cdio_private.h:327
version.h
A file containing the libcdio package version number (20100) and OS build name.
_img_private_t
Definition: image_common.h:30
_CdIo
Definition: cdio_private.h:472
CDIO_LOG_INFO
Definition: logging.h:38
cdio_funcs_t::get_track_green
bool(* get_track_green)(void *p_env, track_t i_track)
Definition: cdio_private.h:337
cdio_private.h
track_info_t::track_green
bool track_green
Definition: image.h:70
_get_discmode_image
discmode_t _get_discmode_image(void *p_user_data)
Definition: image_common.c:117
_img_private_t::disc_mode
discmode_t disc_mode
Definition: image_common.h:45
cdio_log_level_t
cdio_log_level_t
Definition: logging.h:36
i
int i
Definition: cdinfo-linux.c:194
_get_num_tracks_image
track_t _get_num_tracks_image(void *p_user_data)
Definition: image_common.c:200
_get_track_green_bincue
static bool _get_track_green_bincue(void *p_user_data, track_t i_track)
Definition: bincue.c:1123
cdio_funcs_t::read_mode1_sector
int(* read_mode1_sector)(void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2)
Definition: cdio_private.h:418
cdio_have_bincue
bool cdio_have_bincue(void)
Definition: bincue.c:1346
_cdio_strdup_fixpath
char * _cdio_strdup_fixpath(const char path[])
Definition: util.c:147
cdio_funcs_t::get_cdtext
cdtext_t *(* get_cdtext)(void *p_env)
Definition: cdio_private.h:191
cdio_open_am_bincue
CdIo_t * cdio_open_am_bincue(const char *psz_source_name, const char *psz_access_mode)
Definition: bincue.c:1233
cdio_hwinfo::psz_vendor
char psz_vendor[CDIO_MMC_HW_VENDOR_LEN+1]
Definition: device.h:124
cdio_error
void void void void void cdio_error(const char format[],...) GNUC_PRINTF(1
CDIO_CD_ECC_SIZE
Definition: sector.h:114
cdio_funcs_t::read_mode2_sector
int(* read_mode2_sector)(void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2)
Definition: cdio_private.h:402
cdio_funcs_t::eject_media
driver_return_code_t(* eject_media)(void *p_env)
Definition: cdio_private.h:166
cdtext_init
cdtext_t * cdtext_init(void)
Definition: cdtext.c:486
NULL
#define NULL
Definition: types.h:184
_cdio_stdio.h
cdtext_s::block_i
uint8_t block_i
Definition: cdtext_private.h:130
PRId64
#define PRId64
Definition: bincue.c:58
CDIO_DISC_MODE_CD_DA
Definition: disc.h:38
cdio_funcs_t::get_hwinfo
bool(* get_hwinfo)(const CdIo_t *p_cdio, cdio_hwinfo_t *p_hw_info)
Definition: cdio_private.h:256
_get_mcn_image
char * _get_mcn_image(const void *p_user_data)
Definition: image_common.c:188
_get_cdtext_image
cdtext_t * _get_cdtext_image(void *user_data)
Definition: image_common.c:103
MAXLINE
#define MAXLINE
Definition: bincue.c:262
generic_img_private_t::i_tracks
track_t i_tracks
Definition: generic.h:62
track_info_t::mode
trackmode_t mode
Definition: image.h:72
CDIO_CD_EDC_SIZE
#define CDIO_CD_EDC_SIZE
Definition: sector.h:149
cdio_dirname
char * cdio_dirname(const char *fname)
Definition: abs_path.c:84
cdtext_set
void cdtext_set(cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, track_t track, const char *charset)
Definition: cdtext.c:568
_lseek_bincue
static off_t _lseek_bincue(void *p_user_data, off_t offset, int whence)
Definition: bincue.c:141
cdio_funcs_t::read_audio_sectors
int(* read_audio_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, unsigned int i_blocks)
Definition: cdio_private.h:373
DEFAULT_CDIO_DEVICE
#define DEFAULT_CDIO_DEVICE
Definition: bincue.c:78
util.h
Miscellaneous utility functions.
cdio_lsn_to_msf
void cdio_lsn_to_msf(lsn_t i_lsn, msf_t *p_msf)
Definition: sector.c:62
cdio_stream_seek
int cdio_stream_seek(CdioDataSource_t *p_obj, off_t offset, int whence)
Definition: _cdio_stream.c:179
get_track_preemphasis_image
track_flag_t get_track_preemphasis_image(const void *p_user_data, track_t i_track)
Definition: image_common.c:261
MODE2_FORM_MIX
Definition: track.h:95
j
int j
Definition: cdinfo-linux.c:194
get_track_isrc_image
char * get_track_isrc_image(const void *p_user_data, track_t i_track)
Definition: image_common.c:300
track_info_t::datastart
uint16_t datastart
Definition: image.h:75
cdio_funcs_t::get_arg
const char *(* get_arg)(void *p_env, const char key[])
Definition: cdio_private.h:176
cdio_funcs_t::get_discmode
discmode_t(* get_discmode)(void *p_env)
Definition: cdio_private.h:234
track_format_t
track_format_t
Definition: track.h:31
FOUR_CHANNEL_AUDIO
Definition: sector.h:87
cdio_funcs_t::get_disc_last_lsn
lsn_t(* get_disc_last_lsn)(void *p_env)
Definition: cdio_private.h:229
cdio_abspath
char * cdio_abspath(const char *cwd, const char *fname)
Definition: abs_path.c:94
cdio_mmssff_to_lba
lba_t cdio_mmssff_to_lba(const char *psz_mmssff)
Definition: sector.c:192
TRACK_FORMAT_DATA
Definition: track.h:35
track_info_t::endsize
uint16_t endsize
Definition: image.h:77
generic_img_private_t::cdtext
cdtext_t * cdtext
Definition: generic.h:69
image.h
CDIO_DISC_MODE_CD_DATA
Definition: disc.h:39
get_track_pregap_lba_image
lba_t get_track_pregap_lba_image(const void *p_user_data, track_t i_track)
Definition: image_common.c:273
cdtext_private.h
CDIO_DISC_MODE_NO_INFO
Definition: disc.h:54
err_exit
#define err_exit(fmt, args...)
Definition: cdinfo-linux.c:97
MODE1_RAW
Definition: track.h:91
get_track_channels_image
int get_track_channels_image(const void *p_user_data, track_t i_track)
Definition: image_common.c:237
cdio_free
void cdio_free(void *p_memory)
Definition: memory.c:37
track_info_t::datasize
uint16_t datasize
Definition: image.h:73
cdio_stream_read
ssize_t cdio_stream_read(CdioDataSource_t *p_obj, void *ptr, size_t size, size_t nmemb)
Definition: _cdio_stream.c:150
cdio_funcs_t::get_track_msf
bool(* get_track_msf)(void *p_env, track_t i_track, msf_t *p_msf)
Definition: cdio_private.h:346
cdio_funcs_t::get_track_isrc
char *(* get_track_isrc)(const void *p_env, track_t i_track)
Definition: cdio_private.h:322
cdio_funcs_t::read_data_sectors
driver_return_code_t(* read_data_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, uint16_t i_blocksize, uint32_t i_blocks)
Definition: cdio_private.h:394
cdio_funcs_t::get_cdtext_raw
uint8_t *(* get_cdtext_raw)(void *p_env)
Definition: cdio_private.h:202
_get_lba_track_bincue
static lba_t _get_lba_track_bincue(void *p_user_data, track_t i_track)
Definition: bincue.c:1143
cdio_funcs_t::get_mcn
char *(* get_mcn)(const void *p_env)
Definition: cdio_private.h:279
M2RAW_SECTOR_SIZE
Definition: sector.h:190
cdio_hwinfo
Structure to return CD vendor, model, and revision-level strings obtained via the INQUIRY command
Definition: device.h:122
utf8.h
UTF-8 support.
DRIVER_OP_ERROR
Definition: device.h:211
_read_mode2_sector_bincue
static driver_return_code_t _read_mode2_sector_bincue(void *p_user_data, void *data, lsn_t lsn, bool b_form2)
Definition: bincue.c:950
CDIO_CD_SUBHEADER_SIZE
Definition: sector.h:112
MODE1
Definition: track.h:90
cdio_funcs_t::get_num_tracks
track_t(* get_num_tracks)(void *p_env)
Definition: cdio_private.h:285
_get_track_format_bincue
static track_format_t _get_track_format_bincue(void *p_user_data, track_t i_track)
Definition: bincue.c:1101
track_info_t::start_lba
lba_t start_lba
Definition: image.h:52
CDIO_DISC_MODE_CD_XA
Definition: disc.h:40
cdio_funcs_t::free
void(* free)(void *p_env)
Definition: cdio_private.h:171
CDIO_CD_HEADER_SIZE
Definition: sector.h:110
internal_position_t::buff_offset
off_t buff_offset
Definition: cdio_private.h:485
cdio_log
void cdio_log(cdio_log_level_t level, const char format[],...) GNUC_PRINTF(2
cdio_funcs_t::set_blocksize
driver_return_code_t(* set_blocksize)(void *p_env, uint16_t i_blocksize)
Definition: cdio_private.h:457
get_track_copy_permit_image
track_flag_t get_track_copy_permit_image(void *p_user_data, track_t i_track)
Definition: image_common.c:248
logging.h
Header to control logging and level of detail of output.
MODE2_FORM2
Definition: track.h:94
get_media_changed_image
int get_media_changed_image(const void *p_user_data)
Definition: image_common.c:175
CDIO_VERSION
#define CDIO_VERSION
Definition: version.h:10
image_common.h
CDIO_CD_XA_SYNC_HEADER
#define CDIO_CD_XA_SYNC_HEADER
Definition: sector.h:173
generic_img_private_t::data_source
CdioDataSource_t * data_source
Definition: generic.h:59
cdio_funcs_t::get_first_track_num
track_t(* get_first_track_num)(void *p_env)
Definition: cdio_private.h:249
CDIO_CD_M1F1_ZERO_SIZE
#define CDIO_CD_M1F1_ZERO_SIZE
Definition: sector.h:152
_init_bincue
static bool _init_bincue(_img_private_t *p_env)
Definition: bincue.c:95
track_info_t::track_format
track_format_t track_format
Definition: image.h:69
cdio_funcs_t::get_drive_cap
void(* get_drive_cap)(const void *p_env, cdio_drive_read_cap_t *p_read_cap, cdio_drive_write_cap_t *p_write_cap, cdio_drive_misc_cap_t *p_misc_cap)
Definition: cdio_private.h:241
CDIO_CDROM_LEADOUT_TRACK
Definition: track.h:78
cdtext_data_init
int cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data)
Definition: cdtext.c:601
_CdIo::driver_id
driver_id_t driver_id
Definition: cdio_private.h:473
parse_cuefile
static bool parse_cuefile(_img_private_t *cd, const char *toc_name)
Definition: bincue.c:265
DRIVER_OP_SUCCESS
Definition: device.h:206
_read_mode1_sectors_bincue
static driver_return_code_t _read_mode1_sectors_bincue(void *p_user_data, void *data, lsn_t lsn, bool b_form2, unsigned int nblocks)
Definition: bincue.c:928
CDIO_CD_FRAMESIZE
Definition: sector.h:116
_free_image
void _free_image(void *p_user_data)
Definition: image_common.c:57
cdio_stdio_new
CdioDataSource_t * cdio_stdio_new(const char pathname[])
Definition: _cdio_stdio.c:244
TRACK_FORMAT_AUDIO
Definition: track.h:32
_get_drive_cap_image
void _get_drive_cap_image(const void *user_data, cdio_drive_read_cap_t *p_read_cap, cdio_drive_write_cap_t *p_write_cap, cdio_drive_misc_cap_t *p_misc_cap)
Definition: image_common.c:128
cdio_funcs_t::set_arg
int(* set_arg)(void *p_env, const char key[], const char value[])
Definition: cdio_private.h:452
track_info_t
Definition: image.h:49
portable.h
track_info_t::isrc
char * isrc
Definition: image.h:60
AUDIO
Definition: track.h:89
CDIO_PREGAP_SECTORS
#define CDIO_PREGAP_SECTORS
Definition: sector.h:91
CDIO_INVALID_LBA
#define CDIO_INVALID_LBA
Definition: types.h:291
cdio_open_bincue
CdIo_t * cdio_open_bincue(const char *psz_source)
Definition: bincue.c:1247
_eject_media_image
driver_return_code_t _eject_media_image(void *p_user_data)
Definition: image_common.c:46
track_info_t::silence
lba_t silence
Definition: image.h:55
cdio_stream_stat
off_t cdio_stream_stat(CdioDataSource_t *p_obj)
Definition: _cdio_stream.c:206
internal_position_t::index
track_t index
Definition: cdio_private.h:486
cdio_stdio_destroy
void cdio_stdio_destroy(CdioDataSource_t *p_obj)
Definition: _cdio_stdio.c:238
cdtext_field_t
cdtext_field_t
Enumeration of CD-TEXT text fields.
Definition: cdtext.h:44
_read_audio_sectors_bincue
static driver_return_code_t _read_audio_sectors_bincue(void *p_user_data, void *data, lsn_t lsn, unsigned int nblocks)
Definition: bincue.c:879
CDIO_CD_SYNC_SIZE
Definition: sector.h:104
DRIVER_BINCUE
Definition: device.h:165
CDIO_FOPEN
#define CDIO_FOPEN
Definition: bincue.c:84
TRACK_FORMAT_ERROR
Definition: track.h:39
CDIO_LOG_WARN
Definition: logging.h:40
internal_position_t::lba
lba_t lba
Definition: cdio_private.h:487
cdio_assert.h
cdio_funcs_t::read_mode1_sectors
int(* read_mode1_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2, unsigned int i_blocks)
Definition: cdio_private.h:426
track_info_t::start_msf
msf_t start_msf
Definition: image.h:51
MODE2_FORM1
Definition: track.h:93
_img_private_t::tocent
track_info_t tocent[CDIO_CD_MAX_TRACKS+1]
Definition: image_common.h:43
cdio_funcs_t
Definition: cdio_private.h:91
MODE2
Definition: track.h:92
cdio_funcs_t::get_track_channels
int(* get_track_channels)(const void *p_env, track_t i_track)
Definition: cdio_private.h:291
cdio_get_devices_bincue
char ** cdio_get_devices_bincue(void)
Definition: bincue.c:1044
CDTEXT_LEN_BINARY_MAX
Definition: cdtext_private.h:32
cdio_funcs_t::get_track_pregap_lba
lba_t(* get_track_pregap_lba)(const void *p_env, track_t i_track)
Definition: cdio_private.h:313
COPY_PERMITTED
Definition: sector.h:85
cdio_funcs_t::read
ssize_t(* read)(void *p_env, void *p_buf, size_t i_size)
Definition: cdio_private.h:367
MODE2_RAW
Definition: track.h:96