Blame doc/libcdio.texi

Packit dd8086
\input texinfo @c -*-texinfo-*-
Packit dd8086
@c %**start of header
Packit dd8086
@setfilename libcdio.info
Packit dd8086
@include version.texi
Packit dd8086
@settitle GNU @code{libcdio}: Compact Disc Input, Output, and Control Library
Packit dd8086
@c %**end of header
Packit dd8086
Packit dd8086
@c Karl Berry informs me that this will add straight quotes in
Packit dd8086
@c typewriter text.
Packit dd8086
@c See the "Inserting Quote Characters" node in the Texinfo manual
Packit dd8086
@set txicodequoteundirected
Packit dd8086
@set txicodequotebacktick
Packit dd8086
Packit dd8086
@copying
Packit dd8086
This manual documents @code{libcdio}, the GNU CD Input, Output, and Control
Packit dd8086
Library.
Packit dd8086
Packit dd8086
Copyright @copyright{} 2003-2008, 2010, 2012-2014 Rocky
Packit dd8086
Bernstein and Herbert Valerio Riedel.
Packit dd8086
Packit dd8086
@quotation
Packit dd8086
Permission is granted to copy, distribute and/or modify this document
Packit dd8086
under the terms of the GNU Free Documentation License, Version 1.2 or
Packit dd8086
any later version published by the Free Software Foundation; with no
Packit dd8086
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Packit dd8086
Texts.  A copy of the license is included in the section entitled
Packit dd8086
``GNU Free Documentation License''.
Packit dd8086
@end quotation
Packit dd8086
@end copying
Packit dd8086
Packit dd8086
@paragraphindent 0
Packit dd8086
@exampleindent 0
Packit dd8086
Packit dd8086
@set libcdio @code{libcdio}
Packit dd8086
@set program @kbd{libcdio}
Packit dd8086
Packit dd8086
@c A macro for defining terms variables.
Packit dd8086
@macro term{varname}
Packit dd8086
@c @cindex{\varname\}
Packit dd8086
@emph{\varname\}
Packit dd8086
@end macro
Packit dd8086
Packit dd8086
@dircategory Software libraries
Packit dd8086
@direntry
Packit dd8086
* libcdio: (libcdio).           GNU Compact Disc Input, Output, and Control Library.
Packit dd8086
@end direntry
Packit dd8086
Packit dd8086
@titlepage
Packit dd8086
@title GNU @code{libcdio}
Packit dd8086
@subtitle GNU Compact Disc Input, Output, and Control Library
Packit dd8086
@subtitle for version @value{VERSION}, @value{UPDATED}
Packit dd8086
@author Rocky Bernstein et al. (@email{bug-libcdio@@gnu.org})
Packit dd8086
@page
Packit dd8086
@vskip 0pt plus 1filll
Packit dd8086
@insertcopying
Packit dd8086
@end titlepage
Packit dd8086
Packit dd8086
@contents
Packit dd8086
Packit dd8086
@ifnottex
Packit dd8086
@node Top
Packit dd8086
@top GNU @value{libcdio}
Packit dd8086
Packit dd8086
@insertcopying
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* History::           How this came about
Packit dd8086
* Previous Work::     The problem and previous work
Packit dd8086
* Purpose::           What is in this package (and what's not)
Packit dd8086
* CD Formats::        A tour through the CD-specification spectrum
Packit dd8086
* CD Image Formats::  A tour through various CD-image formats
Packit dd8086
* CD Units::          The units that make up a CD
Packit dd8086
* How to use::        Okay enough babble, lemme at the library!
Packit dd8086
* Utility Programs::  Diagnostic programs that come with this library
Packit dd8086
* CD-ROM Access and Drivers::     CD-ROM access and drivers
Packit dd8086
* Internal Program Organization:: Looking under the hood
Packit dd8086
Packit dd8086
Appendices
Packit dd8086
* ISO-9660 Character Sets::
Packit dd8086
* Glossary::
Packit dd8086
* GNU Free Documentation License::
Packit dd8086
Packit dd8086
Indices
Packit dd8086
* General Index::       Overall index
Packit dd8086
@end menu
Packit dd8086
@end ifnottex
Packit dd8086
Packit dd8086
@node History
Packit dd8086
@chapter History
Packit dd8086
Packit dd8086
As a result of the repressive Digital Millennium Copyright Act, DMCA,
Packit dd8086
I became aware of Video CD's (VCD's). Video CD's are not subject to
Packit dd8086
the DMCA and therefore enjoy the protection afforded by copyright but
Packit dd8086
no more. But in order for VCD's to be competitive with DVD's, good
Packit dd8086
tools -- including GPL tools -- are needed for authoring and playing
Packit dd8086
them. And so through VCD's I became aware of the excellent Video CD
Packit dd8086
tools by Herbert Valerio Riedel which form the @kbd{vcdimager}
Packit dd8086
package.
Packit dd8086
Packit dd8086
Although vcdimager is great for authoring, examining and extracting
Packit dd8086
parts of a Video CD, it is not a VCD player. And when I looked at the
Packit dd8086
state of Video CD handling in existing VCD players: @code{xine},
Packit dd8086
@code{MPlayer}, and @code{vlc}, I was a bit disappointed. None handled
Packit dd8086
playback control, menu selections, or playing still frames and
Packit dd8086
segments from track 1.
Packit dd8086
Packit dd8086
Version 0.7.12 of vcdimager was very impressive, however it lacked
Packit dd8086
exportable libraries that could be used in other projects. So with the
Packit dd8086
blessing and encouragement of Herbert Valerio Riedel, I took to
Packit dd8086
extract and create libraries from this code base. The result was two
Packit dd8086
libraries: one to extract information from a VCD which I called
Packit dd8086
libvcdinfo, and another to do the reading and control of a VCD. Well,
Packit dd8086
actually, at this point I should say that a Video CD is really just
Packit dd8086
Video put on a existing well-established Compact Disc or CD format. So
Packit dd8086
the library for this is called @value{libcdio} rather than
Packit dd8086
@kbd{libvcdio}.
Packit dd8086
Packit dd8086
While on the topic of the name @value{libcdio}, I should also explain that
Packit dd8086
the library really doesn't handle writing or output (the final "o" in
Packit dd8086
the name). However it was felt that if I put @code{libcdi} that might be
Packit dd8086
confused with a particular CD format called CD-I.
Packit dd8086
Packit dd8086
Later on, the ISO-9660 filesystem handling component from
Packit dd8086
@kbd{vcdimager} was extracted, expanded and made a separate
Packit dd8086
library. Next the ability to add MMC commands was added, and then
Packit dd8086
CD paranoia support. And from there, the rest is history.
Packit dd8086
Packit dd8086
@node Previous Work
Packit dd8086
@chapter The problem and previous work
Packit dd8086
Packit dd8086
If around the year 2002 you were to look at the code for a number of
Packit dd8086
free software CD or media players that work on several platforms such as
Packit dd8086
vlc, MPlayer, xine, or xmms to name but a few, you'd find the code to
Packit dd8086
read a CD sprinkled with conditional compilation for this or that
Packit dd8086
platform. That is there was @emph{no} OS-independent programmer
Packit dd8086
library for CD reading and control even though the technology was over
Packit dd8086
10 years old; yet there are media players which strive for OS
Packit dd8086
independence.
Packit dd8086
Packit dd8086
One early CD player, @kbd{xmcd} by Ti Kan, was I think a bit better
Packit dd8086
than most in that it tried to @emph{encapsulate} the kinds of CD
Packit dd8086
control mechanisms, e.g.\ SCSI, Linux ioctl, Toshiba, in a "CD Audio
Packit dd8086
Device Interface Library" called @code{libdi}.  However this library is for
Packit dd8086
Audio CD's only and I don't believe this library has been used outside
Packit dd8086
of xmcd.
Packit dd8086
Packit dd8086
Another project, Simple DirectMedia Layer also encapsulates CD
Packit dd8086
reading.
Packit dd8086
Packit dd8086
@quotation
Packit dd8086
SDL is a library that allows you portable low-level access to a video
Packit dd8086
framebuffer, audio output, mouse, and keyboard. With SDL, it is easy
Packit dd8086
to write portable games which run on ...
Packit dd8086
@end quotation
Packit dd8086
Packit dd8086
Many of the media players mentioned above do in fact can make use of
Packit dd8086
the SDL library but for @emph{video} output only. Because the encapsulation
Packit dd8086
is over @emph{many} kinds of I/O (video, joysticks, mice, as well as CD's),
Packit dd8086
I believe that the level of control provided for CD a little bit
Packit dd8086
limited. (However to be fair, it may have only been intended for games
Packit dd8086
and may be suitable for that).  Applications that just want the CD
Packit dd8086
reading and control portion I think will find quite a bit overhead.
Packit dd8086
Packit dd8086
Another related project is J@"org Schilling's SCSI library. You can
Packit dd8086
use that to make a non-SCSI CD-ROM act like one that understands SCSI
Packit dd8086
MMC commands which is a neat thing to do. However it is a little weird
Packit dd8086
to have to install drivers just so you can run a particular user-level
Packit dd8086
program. Installing drivers often requires special privileges and
Packit dd8086
permissions and it is pervasive on a system. It is a little sad that
Packit dd8086
along the way to creating such a SCSI library a library similar to
Packit dd8086
@value{libcdio} wasn't created which could be used. Were that the
Packit dd8086
case, this library certainly never would have been written.
Packit dd8086
Packit dd8086
At the OS level there is the ``A Linux CD-ROM Standard'' by David van
Packit dd8086
Leeuwen from around 1999. This defines a set of definitions and
Packit dd8086
ioctl's that mask hardware differences of various Compact Disc
Packit dd8086
hardware. It is a great idea, however this ``standard'' lacked
Packit dd8086
adoption on OS's other than GNU/Linux. Or maybe it's the case that the
Packit dd8086
standard on other OS's lacked adoption on GNU/Linux. For example on
Packit dd8086
FreeBSD there is a ``Common Access Method'' (CAM) used for all SCSI
Packit dd8086
access which seems not to be adopted in GNU/Linux.@footnote{And I'm
Packit dd8086
thankful for that since, at least for MMC commands, it is
Packit dd8086
inordinately complicated and in some places arcane.}
Packit dd8086
Packit dd8086
Finally at the hardware level where a similar chaos exists, there has
Packit dd8086
been an attempt to do something similar with the MMC (multimedia
Packit dd8086
commands). This attempts to provide a uniform command set for CD
Packit dd8086
devices like PostScript does for printer commands.@footnote{I wrote
Packit dd8086
``attempts'' because over time the command set has changed and now
Packit dd8086
there are several different commands to do a particular function like
Packit dd8086
read a CD table of contents and some hardware understands some of the
Packit dd8086
version of the commands set but might not others} In contrast to
Packit dd8086
PostScript where there one in theory can write a PostScript program in
Packit dd8086
a uniform ASCII representation and send that to a printer, for MMC
Packit dd8086
although there are common internal structures defined, there is no
Packit dd8086
common syntax for representing the structures or an OS-independent
Packit dd8086
library or API for issuing MMC-commands which a programmer would need
Packit dd8086
to use. Instead each Operating System has its own interface.  For
Packit dd8086
example Adaptec's ASPI or Microsoft's DeviceIoControl on Microsoft
Packit dd8086
Windows, or IOKit for Apple's OS/X, or FreeBSD's CAM. I've been
Packit dd8086
positively awed at how many different variations and differing levels
Packit dd8086
of complexity there are for doing basically the same thing. How easy
Packit dd8086
it is to issue an MMC command from a program varies from easy to very
Packit dd8086
difficult. And mastering the boilerplate code to issue an MMC command
Packit dd8086
on one OS really doesn't help much in figuring out how to do it on
Packit dd8086
another OS. So in @value{libcdio} we provide a common (and hopefully
Packit dd8086
simple) API to issue MMC commands.
Packit dd8086
Packit dd8086
@node Purpose
Packit dd8086
@chapter What is in this package (and what's not)
Packit dd8086
Packit dd8086
The library, @command{libcdio}, encapsulates CD-ROM reading and
Packit dd8086
control. Applications wishing to be oblivious of the OS- and
Packit dd8086
device-dependent properties of a CD-ROM can use this library.
Packit dd8086
Packit dd8086
Also included is a library, @command{libiso9660}, for working with
Packit dd8086
ISO-9660 filesystems.
Packit dd8086
Packit dd8086
Some support for disk-image types like cdrdao's TOC, CDRWIN's BIN/CUE
Packit dd8086
and Ahead Nero's NRG format is available, so applications that use this
Packit dd8086
library also have the ability to read disc images as though they were
Packit dd8086
CDs.
Packit dd8086
Packit dd8086
@command{libcdio} also provides a way to issue SCSI ``MultiMedia
Packit dd8086
Commands'', MMC.  MMC is supported by many hardware CD-ROM
Packit dd8086
manufacturers; and in some cases where a CD-ROM doesn't understand MMC
Packit dd8086
directly, some Operating Systems (such as GNU/Linux, Solaris, or
Packit dd8086
FreeBSD or Microsoft Windows ASPI to name a few) provide the MMC
Packit dd8086
emulation.@footnote{This concept of software emulation of a common
Packit dd8086
hardware command language is common for printers such as using
Packit dd8086
ghostscript to private postscript emulation for a non-postscript
Packit dd8086
printer.}
Packit dd8086
Packit dd8086
As a separate package under a separate GPL2 license are
Packit dd8086
@command{libcdio_paranoia}, and @command{libcdio_cdda} libraries for
Packit dd8086
applications which want to use cdparanoia's error-correction and
Packit dd8086
jitter detection.
Packit dd8086
Packit dd8086
The first use of the library in this package are the Video CD
Packit dd8086
authoring and ripping tools, VCDImager
Packit dd8086
(@url{http://vcdimager.org}). See
Packit dd8086
@url{http://www.gnu.org/software/libcdio/projects.html} for a list of
Packit dd8086
projects using @command{libcdio}.
Packit dd8086
Packit dd8086
A version of the CD-DA extraction tool cdparanoia,
Packit dd8086
@url{http://www.xiph.org/paranoia}, and its library which corrects
Packit dd8086
for CD-ROM jitter are part of the distribution.
Packit dd8086
Packit dd8086
Also included in the libcdio package is a utility program
Packit dd8086
@command{cd-info} which displays CD information: number of tracks,
Packit dd8086
CD-format and if possible basic information about the format.  If
Packit dd8086
libcddb (@url{http://libcddb.sourceforge.net}) is available, the
Packit dd8086
@command{cd-info} program will display CDDB matches on CD-DA
Packit dd8086
discs. And if a new enough version of libvcdinfo is available from
Packit dd8086
the vcdimager project, then @command{cd-info} shows basic VCD
Packit dd8086
information.
Packit dd8086
Packit dd8086
Other utility programs in the libcdio package are:
Packit dd8086
Packit dd8086
@table @code
Packit dd8086
Packit dd8086
@item @code{cdda-player}
Packit dd8086
Packit dd8086
shows off @value{libcdio} audio and CD-ROM control commands. It can
Packit dd8086
play a track, eject or load media and show the the status of a CD-DA
Packit dd8086
that is might be currently played via the audio control commands.  It
Packit dd8086
can be run in batch mode or has a simple curses-based interface.
Packit dd8086
Packit dd8086
If libcddb is available or a CD has CD-Text and your CD-ROM drive
Packit dd8086
supports CD-Text, track/album information about the CD can be shown.
Packit dd8086
Packit dd8086
@item @code{cd-drive}
Packit dd8086
Packit dd8086
shows what drivers are available and some basic properties of
Packit dd8086
cd-drives attached to the system. Media may have to be inserted
Packit dd8086
in order to get this info. The program also lists out drive capabilities
Packit dd8086
Packit dd8086
@item cd-read
Packit dd8086
performs low-level block reading of a CD or CD image
Packit dd8086
Packit dd8086
@item @code{iso-info}
Packit dd8086
Packit dd8086
displays ISO-9660 information from an ISO-9660 image. Below is some
Packit dd8086
sample output
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
iso-info version 0.82 x86_64-unknown-linux-gnu
Packit dd8086
Copyright (c) 2003, 2004, 2005, 2007, 2008 R. Bernstein
Packit dd8086
This is free software; see the source for copying conditions.
Packit dd8086
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
Packit dd8086
PARTICULAR PURPOSE.
Packit dd8086
__________________________________
Packit dd8086
ISO 9660 image: ../test/joliet.iso
Packit dd8086
Application: K3B THE CD KREATOR VERSION 0.11.12 (C) 2003 SEBASTIAN TRUEG AND...
Packit dd8086
Preparer   : K3b - Version 0.11.12
Packit dd8086
Publisher  : Rocky Bernstein
Packit dd8086
System     : LINUX
Packit dd8086
Volume     : K3b data project
Packit dd8086
Volume Set :
Packit dd8086
__________________________________
Packit dd8086
ISO-9660 Information
Packit dd8086
/:
Packit dd8086
 Oct 22 2004 19:44  .
Packit dd8086
 Oct 22 2004 19:44  ..
Packit dd8086
 Oct 22 2004 19:44  libcdio
Packit dd8086
Packit dd8086
/libcdio/:
Packit dd8086
 Oct 22 2004 19:44  .
Packit dd8086
 Oct 22 2004 19:44  ..
Packit dd8086
 Mar 12 2004 02:18  COPYING
Packit dd8086
 Jun 26 2004 07:01  README
Packit dd8086
 Aug 12 2004 06:22  README.libcdio
Packit dd8086
 Oct 22 2004 19:44  test
Packit dd8086
Packit dd8086
/libcdio/test/:
Packit dd8086
 Oct 22 2004 19:44  .
Packit dd8086
 Oct 22 2004 19:44  ..
Packit dd8086
 Jul 25 2004 06:52  isofs-m1.cue
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
@item @code{iso-read}
Packit dd8086
Packit dd8086
extracts files from an ISO-9660 image.
Packit dd8086
Packit dd8086
@item @code{mmc-tool}
Packit dd8086
Packit dd8086
a program for issuing some MMC commands
Packit dd8086
Packit dd8086
@end table
Packit dd8086
Packit dd8086
Historically, @code{libcdio} did not support write access to
Packit dd8086
drives. In conjunction with additional work in a separate project
Packit dd8086
@code{libburn}, Thomas Schmitt has modified @code{libcdio} to enable
Packit dd8086
sending SCSI write commands on some of the drivers. This enables other
Packit dd8086
programs like @code{libburn} to write to CD's, DVD's and Blu-Ray
Packit dd8086
discs.
Packit dd8086
Packit dd8086
For the OS drivers which are lacking write access, volunteers are
Packit dd8086
welcome.
Packit dd8086
Packit dd8086
@node CD Formats
Packit dd8086
@chapter CD Formats
Packit dd8086
Packit dd8086
Much of what I write in this section can be found elsewhere. See for
Packit dd8086
example @url{http://www.pctechguide.com/08cd-rom.htm} or
Packit dd8086
@url{http://www.pcguide.com/ref/cd/format.htm}
Packit dd8086
Packit dd8086
We give just enough background here to cover Compact Discs and Compact
Packit dd8086
Disc formats that are handled by this library.
Packit dd8086
Packit dd8086
The Sony and Philips Corporations invented and Compact Disc (CD) in
Packit dd8086
the early 1980s. The specifications for the layout is often referred
Packit dd8086
to by the color of the cover on the specification.
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* Red Book::        Red Book (CD-DA) CD Text, CDDB
Packit dd8086
* Yellow Book::     Yellow Book (CD-ROM Digital Data)
Packit dd8086
* Green Book::      Green Book (CD-i)
Packit dd8086
* White Book::      White Book (DV, Video CD)
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node Red Book
Packit dd8086
@section Red Book (CD-DA)
Packit dd8086
@cindex Red Book
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* CD Text::         CD Text and CD+G
Packit dd8086
* CDDB::            Internet CD Database (CDDB)
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
The first type of CD that was produced was the Compact Disc Digital
Packit dd8086
Audio (CD-DA) or just plain ``audio CD''. The specification, ICE 60908
Packit dd8086
(formerly IEC 908) is commonly called the ``Red Book'',
Packit dd8086
@cite{@url{http://en.wikipedia.org/wiki/Red_Book_(audio_CD_standard)}}. Music
Packit dd8086
CD's are recorded in this format which basically allows for around 74
Packit dd8086
minutes of audio per disc and for that information to be split up into
Packit dd8086
tracks. Tracks are broken up into "sectors" and each sector contains
Packit dd8086
up to 2,352 bytes. To play one 44.1 kHz CD-DA sampled audio second, 75
Packit dd8086
sectors are used.
Packit dd8086
Packit dd8086
The minute/second/frame numbering of sectors or MSF format is based on
Packit dd8086
the fact that 75 sectors are used in a second of playing of
Packit dd8086
sound. (And for almost every other CD format and application the MSF
Packit dd8086
format doesn't make that much sense).
Packit dd8086
Packit dd8086
In @value{libcdio} when you you want to read an audio sector, you call
Packit dd8086
@code{cdio_read_audio_sector()} or @code{cdio_read_audio_sectors()}.
Packit dd8086
Packit dd8086
@cindex subchannel
Packit dd8086
In addition the the audio data ``channel'' a provision for other
Packit dd8086
information or @term{subchannel} information) can be stored in a
Packit dd8086
sector. Other subchannels include a Media Catalog Number (also
Packit dd8086
abbreviated as MCN and sometimes a UPC), or album meta data (also
Packit dd8086
called CD-Text). Karioke graphics can also be stored in a format
Packit dd8086
called @term{CD+G}.
Packit dd8086
Packit dd8086
@node CD Text
Packit dd8086
@subsection CD Text, CD+G
Packit dd8086
@cindex CD Text
Packit dd8086
@cindex CD+G
Packit dd8086
Packit dd8086
CD Text is an extension to the CD-DA standard that adds the ability to
Packit dd8086
album and track meta data (titles, artist/performer names, song
Packit dd8086
titles) and graphical (e.g. Karaoke) information.  For an
Packit dd8086
alternative way to get album and track meta-data see @xref{CDDB}.
Packit dd8086
Packit dd8086
Information is stored in such a way that it doesn't interfere with the
Packit dd8086
normal operation of any CD players or CDROM drives. There are two
Packit dd8086
different parts of the CD where the data can be stored.
Packit dd8086
Packit dd8086
The first place the information can be recorded is in the R-W sub
Packit dd8086
codes in the lead in area of the CD.  This information is stored as a
Packit dd8086
single block of data and is the format. The method for reading this
Packit dd8086
data from a CDROM drive is covered under the Sony proposal to the MMC
Packit dd8086
specification. The format of the data is partially covered in the MMC
Packit dd8086
specification.
Packit dd8086
Packit dd8086
CD Text information is stored in this area. The format that follows
Packit dd8086
the Interactive Text Transmission System (ITTS) is the same data
Packit dd8086
transmission standard used by such things as Digital Audio
Packit dd8086
Broadcasting (DAB), and virtually the same as the data standard for
Packit dd8086
the MiniDisc.
Packit dd8086
Packit dd8086
The second place the information can be recorded is in the R-W sub
Packit dd8086
codes in the program area of the CD giving a data capacity of roughly
Packit dd8086
31MB. CD+G (CD w/graphics) uses this method.
Packit dd8086
Packit dd8086
The methods for reading this data from a CD-ROM drive were first
Packit dd8086
covered by the programming specs from the individual drive
Packit dd8086
manufacturers. In the case of ATAPI drives, the SFF8020 spec covers
Packit dd8086
the reading of the RW subcodes. Subsequently it has been encorporated
Packit dd8086
into the MMC specifications.
Packit dd8086
Packit dd8086
Not all drives support reading the RW subcodes from the program
Packit dd8086
area. However for those that do, @value{libcdio} provides a way to get
Packit dd8086
at this information via @code{cdtext_get()} and its friends.
Packit dd8086
Packit dd8086
There is a separate document in this distribution describing CD-Text
Packit dd8086
information and how it is encoded.
Packit dd8086
Packit dd8086
@node CDDB
Packit dd8086
@subsection Internet CD Database (CDDB)
Packit dd8086
@cindex CDDB
Packit dd8086
Packit dd8086
CDDB is an database on the Internet of of CD album/track, artist, and
Packit dd8086
genre information similar to CD Text information. Using track
Packit dd8086
information (number of tracks and length of the tracks), devices that
Packit dd8086
have access to the Internet can query for meta information and
Packit dd8086
contribute information for CD's where there is no existing
Packit dd8086
information.  When storage is available (such as you'd expect for any
Packit dd8086
program using @value{libcdio}, the information is often saved for
Packit dd8086
later use when the Internet is not available; people tend request the
Packit dd8086
same information since they via programs play the same music.
Packit dd8086
Packit dd8086
Obtaining CD meta information when none is encoded in an audio CD is
Packit dd8086
useful in media players or making ones own compilations from audio
Packit dd8086
CDs.
Packit dd8086
Packit dd8086
There are currently two popular CDDB services on the Internet. The
Packit dd8086
original database has been renamed Gracenote and is a profit making
Packit dd8086
entity. FreeDB (@url{http://freedb.org} is an open source CD
Packit dd8086
information resource that is free for developers and the public to
Packit dd8086
use.
Packit dd8086
Packit dd8086
As there already is an excellent library for handling CDDB libcddb
Packit dd8086
(@url{http://libcddb.sourceforge.net} we suggest using that. Our
Packit dd8086
utility program @command{cd-info} will make use it if it is available
Packit dd8086
and it's what we use in our applications that need it.
Packit dd8086
Packit dd8086
@node Yellow Book
Packit dd8086
@section Yellow Book (CD-ROM Digital Data)
Packit dd8086
The CD-ROM specification or the ``Yellow Book'' followed a few years
Packit dd8086
later (Standards ISO/IEC 10149), and describes the extension of CD's
Packit dd8086
to store computer data, i.e. CD-ROM (Compact Disk Read Only Memory).
Packit dd8086
Packit dd8086
The specification in the Yellow Book defines two modes: Mode 1 and
Packit dd8086
Mode 2.
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* ISO 9660::
Packit dd8086
* Mode 1::           Mode 1 Format
Packit dd8086
* Mode 2::           Mode 2 Format
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node ISO 9660
Packit dd8086
@subsection ISO 9660
Packit dd8086
@cindex ISO 9660
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* ISO 9660 Level 1::
Packit dd8086
* ISO 9660 Level 2::
Packit dd8086
* ISO 9660 Level 3::
Packit dd8086
* Joliet Extensions::
Packit dd8086
* Rock Ridge Extensions::
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
The Yellow Book doesn't specify how data is to be stored on a CD-ROM.
Packit dd8086
It was feared that different companies would implement proprietary
Packit dd8086
data storage formats using this specification, resulting in
Packit dd8086
incompatible data CDs. To prevent this, representatives of major
Packit dd8086
manufacturers met at the High Sierra Hotel and Casino in Lake Tahoe,
Packit dd8086
NV, in 1985, to define a standard for storing data on CDs. This format
Packit dd8086
was nicknamed High Sierra Format. In a slightly modified form it was
Packit dd8086
later adopted as ISO the ISO 9660 standard. This standard is further
Packit dd8086
broken down into 3 "levels", the higher the level, the more
Packit dd8086
permissive.
Packit dd8086
Packit dd8086
@node ISO 9660 Level 1
Packit dd8086
@subsubsection ISO 9660 Level 1
Packit dd8086
Level 1 ISO 9660 defines names in the 8+3 convention so familiar to
Packit dd8086
MS-DOS: eight characters for the filename, a period, and then three
Packit dd8086
characters for the file type, all in upper case. The allowed
Packit dd8086
characters are A-Z, 0-9, ".", and "_".Level 1 ISO 9660 requires that
Packit dd8086
files occupy a contiguous range of sectors. This allows a file to be
Packit dd8086
specified with a start block and a count. The maximum directory depth
Packit dd8086
is 8. For a table of the characters, see @xref{ISO-9660 Character
Packit dd8086
Sets}.
Packit dd8086
Packit dd8086
@node ISO 9660 Level 2
Packit dd8086
@subsubsection ISO 9660 Level 2
Packit dd8086
Level 2 ISO 9660 allows far more flexibility in filenames, but isn't
Packit dd8086
usable on some systems, notably MS-DOS.
Packit dd8086
Packit dd8086
@node ISO 9660 Level 3
Packit dd8086
@subsubsection ISO 9660 Level 3
Packit dd8086
Level 3 ISO-9660 allows non-contiguous files, useful if the file was
Packit dd8086
written in multiple packets with packet-writing software.
Packit dd8086
Packit dd8086
There have been a number of extensions to the ISO 9660 CD-ROM file
Packit dd8086
format. One extension is Microsoft's Joliet specification, designed to
Packit dd8086
resolve a number of deficiencies in the original ISO 9660 Level 1 file
Packit dd8086
system, and in particular to support the long file names used in
Packit dd8086
Windows 95 and subsequent versions of Windows.
Packit dd8086
Packit dd8086
Another extension is the Rock Ridge Interchange Protocol (RRIP), which
Packit dd8086
enables the recording of sufficient information to support POSIX File
Packit dd8086
System semantics.
Packit dd8086
Packit dd8086
@node Joliet Extensions
Packit dd8086
@subsubsection Joliet Extensions
Packit dd8086
@cindex Joliet extensions
Packit dd8086
Packit dd8086
Joliet extensions were an upward-compatible extension to the ISO 9660
Packit dd8086
specification that removes the limitation initially put in to deal
Packit dd8086
with the limited filename conventions found in Microsoft DOS OS. In
Packit dd8086
particular, the Joliet specification allows for long filenames and
Packit dd8086
allows for UCS-BE (BigEndian Unicode) encoding of filenames which
Packit dd8086
include mixed case letter, accented characters spaces and various
Packit dd8086
symbols.
Packit dd8086
Packit dd8086
The way all of this is encoded is by adding a second directory and
Packit dd8086
filesystem structure in addition to or in parallels to original ISO
Packit dd8086
9600 filesystem. The root node of the ISO 9660 filesystem is found via
Packit dd8086
the @term{Primary Volume Descriptor} or @term{PVD}. The root of the
Packit dd8086
Joliet-encode filesystem is found in a Supplementary Volume
Packit dd8086
Descriptor or @term{SVD} defined in the ISO 9660 specification. The
Packit dd8086
SVD structure is almost identical to a PVD with a couple of unused
Packit dd8086
fields getting used and with the filename encoding changed to UCS-BE.
Packit dd8086
Packit dd8086
@node Rock Ridge Extensions
Packit dd8086
@subsubsection Rock Ridge Extensions
Packit dd8086
@cindex Rock Ridge extensions
Packit dd8086
Packit dd8086
Using the Joliet Extension one overcome the limitedness of the
Packit dd8086
original ISO-9660 naming scheme. But another and probably better
Packit dd8086
method is to use the Rock Ridge Extension. Not only can one store a
Packit dd8086
filename as one does in a POSIX OS, but the other file attributes,
Packit dd8086
such as the various timestamps (creation, modification, access), file
Packit dd8086
attributes (user, group, file mode permissions, device type, symbolic
Packit dd8086
links) can be stored. This is much as one would do in XA attributes;
Packit dd8086
however the two are not completely interchangeable in the information
Packit dd8086
they store: XA does @emph{not} address filename limitations, and the
Packit dd8086
Rock Ridge extensions don't indicate if a sector is in Mode 1 or Mode
Packit dd8086
2 format.
Packit dd8086
Packit dd8086
The Rock Ridge extension makes use of a hook that was defined as part
Packit dd8086
of the ISO 9660 standard.
Packit dd8086
Packit dd8086
@node Mode 1
Packit dd8086
@subsection Mode 1 (2048 data bytes per sector)
Packit dd8086
@cindex Mode 1
Packit dd8086
Mode 1 is the data storage mode used by to store computer data. There
Packit dd8086
are 3 layers of error correction. A Compact Disc using only this format can
Packit dd8086
hold at most 650 MB. The data is laid out in basically the same way as
Packit dd8086
in and audio CD format, except that the 2,352 bytes of data in each
Packit dd8086
block are broken down further. 2,048 of these bytes are for ``real''
Packit dd8086
data. The other 304 bytes are used for an additional level of error
Packit dd8086
detecting and correcting code. This is necessary because data CDs
Packit dd8086
cannot tolerate the loss of a handful of bits now and then, the way
Packit dd8086
audio CDs can.
Packit dd8086
Packit dd8086
In @value{libcdio} when you you want to read a mode1
Packit dd8086
sector you call the @code{cdio_read_mode1_sector()} or
Packit dd8086
@code{cdio_read_mode1_sectors()}.
Packit dd8086
Packit dd8086
@node Mode 2
Packit dd8086
@subsection Mode 2 (2336 data bytes per sector)
Packit dd8086
@cindex Mode 2
Packit dd8086
Mode 2 data CDs are the same as mode 1 CDs except that the error
Packit dd8086
detecting and correcting codes are omitted. So still there are 2
Packit dd8086
layers of error correction. A Compact Disc using only this mode can
Packit dd8086
thus hold at most 742 MB. Similar to audio CDs, the mode 2 format
Packit dd8086
provides a more flexible vehicle for storing types of data that do not
Packit dd8086
require high data integrity: for example, graphics and video can use
Packit dd8086
this format. But in contrast to the Red Book standard, different modes
Packit dd8086
can be mixed together; this is the basis for the extensions to the
Packit dd8086
original data CD standards known as CD-ROM Extended Architecture, or
Packit dd8086
CD-ROM XA.  CD-ROM XA formats currently in use are CD-I Bridge
Packit dd8086
formats, Photo CD and Video CD plus Sony's Playstation.
Packit dd8086
Packit dd8086
In @value{libcdio} when you you want to read a mode1
Packit dd8086
sector you call the @code{cdio_read_mode2_sector()} or
Packit dd8086
@code{cdio_read_mode2_sectors()}.
Packit dd8086
Packit dd8086
@node Green Book
Packit dd8086
@section Green Book (CD-i)
Packit dd8086
@cindex Green Book
Packit dd8086
Packit dd8086
This was a CD-ROM format developed by Philips for CD-i (an obsolete
Packit dd8086
embedded CD-ROM application allowing limited user user interaction
Packit dd8086
with films, games and educational applications). The format is ISO
Packit dd8086
9660 compliant and introduced mode 2 form 2 addressing. It also
Packit dd8086
contains XA (Extended Architecture) attributes.
Packit dd8086
Packit dd8086
Although some Green Book discs contain CD-i applications which can
Packit dd8086
only be played on a CD-i player, others have films or music
Packit dd8086
videos. Video CDs in Green-Book format are labeled "Digital Video on
Packit dd8086
CD." The Green Book for video is largely superseded by White book
Packit dd8086
CD-ROM which draws on this specification.
Packit dd8086
Packit dd8086
Packit dd8086
@node White Book
Packit dd8086
@section White Book (DV, Video CD)
Packit dd8086
@cindex Green Book
Packit dd8086
Packit dd8086
The White Book was released by Sony, Philips, Matsushita, and JVC in
Packit dd8086
1993, defines the Video CD specification. The White Book is also known
Packit dd8086
as Digital Video (DV).
Packit dd8086
Packit dd8086
A Video CD contains one data track recorded in CD-ROM XA Mode 2 Form
Packit dd8086
2. It is always the first track on the disc (Track 1). The ISO-9660
Packit dd8086
file structure and a CD-i application program are recorded in this
Packit dd8086
track, as well as the Video CD Information Area which gives general
Packit dd8086
information about the Video Compact Disc. After the data track, video
Packit dd8086
is written in one or more subsequent tracks within the same
Packit dd8086
session. These tracks are also recorded in Mode 2 Form 2.
Packit dd8086
Packit dd8086
In @value{libcdio} when you you want to read a mode2 format 2 audio
Packit dd8086
sector you call the @code{cdio_read_mode2_sector()} or
Packit dd8086
@code{cdio_read_mode2_sectors()} setting @code{b_form2} to @code{true}.
Packit dd8086
Packit dd8086
@node CD Image Formats
Packit dd8086
@chapter CD Image Formats
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* CDRDAO TOC Format::
Packit dd8086
* CDRWIN BIN/CUE Format::
Packit dd8086
* NRG Format::
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
In both the @command{cdrdao} and bin/cue formats there is one meta-file with
Packit dd8086
extensions @code{.toc} or @code{.cue} respectively and one or more
Packit dd8086
files (often with the extension @code{.bin}) which contains the
Packit dd8086
content of tracks. The format of the track data is often
Packit dd8086
interchangeable between the two formats.  For example, in
Packit dd8086
@value{libcdio}'s regression tests we make use of this to reduce the
Packit dd8086
size of the test data and just provide alternate meta-data files
Packit dd8086
(@code{.toc} or @code{.cue}).
Packit dd8086
Packit dd8086
In contrast to the first two formats, the NRG format consists of a
Packit dd8086
single file. This has the advantage of being a self-contained
Packit dd8086
unit: in the other two formats it is possible for the meta file to
Packit dd8086
refer to a file that can't be found. A disadvantage of the NRG format
Packit dd8086
is that the meta data can't be easily viewed or modified say in a text
Packit dd8086
file as it can be with the first two formats. In conjunction with this
Packit dd8086
disadvantage is another disadvantage that the format is not
Packit dd8086
documented, so how @value{libcdio} interprets an NRG image is based on
Packit dd8086
inference. It is recommended that one of the other forms be used
Packit dd8086
instead of NRG where possible.
Packit dd8086
Packit dd8086
@node CDRDAO TOC Format
Packit dd8086
@section CDRDAO TOC Format
Packit dd8086
Packit dd8086
This is @command{cdrdao}'s CD-image description format. Since this
Packit dd8086
program is GPL and everything about it is in the open, it is the
Packit dd8086
preferred format to use. (Alas, at present it isn't as well supported
Packit dd8086
in @value{libcdio} as the BIN/CUE format.)
Packit dd8086
Packit dd8086
The @emph{toc}-file describes what data is written to the media in the
Packit dd8086
@acronym{CD-ROM}; it allows control over track/index positions,
Packit dd8086
pre-gaps and sub-channel information.  It is a text file, so a text
Packit dd8086
editor can be used to create, view or modify it.
Packit dd8086
Packit dd8086
The @cite{cdrdao(1) manual page}, contains more information about this
Packit dd8086
format.
Packit dd8086
Packit dd8086
@subsection CDRDAO Grammar
Packit dd8086
Packit dd8086
Below are the lexical tokens and grammar for a cdrdao TOC. It was
Packit dd8086
taken from the cdrdao's pacct grammar; the token and nonterminal names
Packit dd8086
are the same.
Packit dd8086
Packit dd8086
@example
Packit dd8086
#lexclass START
Packit dd8086
#token Eof		"@@"
Packit dd8086
#token                  "[\t\r\ ]+"
Packit dd8086
#token Comment          "//~[\n@@]*"
Packit dd8086
#token                  "\n"
Packit dd8086
#token BeginString      "\""
Packit dd8086
#token Integer          "[0-9]+"
Packit dd8086
#tokclass AudioFile     @{ "AUDIOFILE" "FILE" @}
Packit dd8086
Packit dd8086
#lexclass STRING
Packit dd8086
#token EndString        "\""
Packit dd8086
#token StringQuote      "\\\""
Packit dd8086
#token StringOctal      "\\[0-9][0-9][0-9]"
Packit dd8086
#token String           "\\"
Packit dd8086
#token String           "[ ]+"
Packit dd8086
#token String           "~[\\\n\"\t ]*"
Packit dd8086
@end example
Packit dd8086
Packit dd8086
@example
Packit dd8086
Packit dd8086
<toc>  ::= ( "CATALOG" <string> | <tocType> )* @{ <cdTextGlobal> @}
Packit dd8086
           ( <track> )+ Eof
Packit dd8086
Packit dd8086
<track> ::= "TRACK" <trackMode>
Packit dd8086
    @{ <subChannelMode> @}
Packit dd8086
    (  "ISRC" <string> | @{ "NO" @} "COPY" | @{ "NO" @} "PRE_EMPHASIS"
Packit dd8086
    | "TWO_CHANNEL_AUDIO"  | "FOUR_CHANNEL_AUDIO" )*
Packit dd8086
    @{ <cdTextTrack>  @}
Packit dd8086
    @{ "PREGAP" <msf> @}
Packit dd8086
    ( <subTrack> | "START" @{ msf @} | "END" @{ msf @} )+
Packit dd8086
    ( "INDEX" <msf> )*
Packit dd8086
Packit dd8086
<subTrack> ::=
Packit dd8086
     AudioFile <string> @{ "SWAP"  @} @{ "#" <sLong>  @}  <samples>
Packit dd8086
     | "DATAFILE" <string> @{ "#" <sLong> @{ <dataLength> @} @}
Packit dd8086
     | "FIFO" <string> <dataLength>
Packit dd8086
     | "SILENCE" <samples>
Packit dd8086
     | "ZERO" @{ dataMode  @} @{ <subChannelMode>  @} <dataLength>
Packit dd8086
Packit dd8086
Packit dd8086
<string> ::=  BeginString ( String | StringQuote | StringOctal )+
Packit dd8086
            EndString
Packit dd8086
Packit dd8086
<stringEmpty> ::= BeginString ( String | StringQuote | StringOctal )*
Packit dd8086
                EndString
Packit dd8086
Packit dd8086
<uLong> ::= Integer
Packit dd8086
Packit dd8086
<sLong> ::= Integer
Packit dd8086
Packit dd8086
<msf> ::= Integer ":" Integer ":" Integer
Packit dd8086
Packit dd8086
<samples> ::= <msf> | <uLong>
Packit dd8086
Packit dd8086
<dataLength> ::= <msf> | <uLong>
Packit dd8086
Packit dd8086
<dataMode> ::=  "AUDIO" | "MODE0" | "MODE1" | "MODE1_RAW" | "MODE2"
Packit dd8086
     | "MODE2_RAW" | "MODE2_FORM1" | "MODE2_FORM2" | "MODE2_FORM_MIX"
Packit dd8086
Packit dd8086
<trackMode> ::= "AUDIO" | "MODE1" | "MODE1_RAW" | "MODE2"
Packit dd8086
     | "MODE2_RAW"  | "MODE2_FORM1" | "MODE2_FORM2" | "MODE2_FORM_MIX"
Packit dd8086
Packit dd8086
<subChannelMode> ::= "RW" | "RW_RAW"
Packit dd8086
Packit dd8086
<tocType> ::= "CD_DA" | "CD_ROM" | "CD_ROM_XA" | "CD_I"
Packit dd8086
Packit dd8086
<packType> ::= "TITLE" | "PERFORMER" | "SONGWRITER" | "COMPOSER" | "ARRANGER"
Packit dd8086
     | "MESSAGE" | "DISC_ID" | "GENRE" | "TOC_INFO1" | "TOC_INFO2"
Packit dd8086
     | "RESERVED1" | "RESERVED2" | "RESERVED3" | "RESERVED4" | "UPC_EAN" |
Packit dd8086
     "ISRC" | "SIZE_INFO"
Packit dd8086
Packit dd8086
<binaryData> ::=  "@{"
Packit dd8086
    @{ Integer ( "," Integer  )* @}
Packit dd8086
    "@}"
Packit dd8086
Packit dd8086
<cdTextItem> ::= <packType>  ( <stringEmpty> | <binaryData> )
Packit dd8086
Packit dd8086
<cdTextBlock> ::=  "LANGUAGE" Integer "@{" ( <cdTextItem> )* "@}"
Packit dd8086
Packit dd8086
<cdTextLanguageMap> ::=
Packit dd8086
    "LANGUAGE_MAP" "@{"
Packit dd8086
    ( Integer  ":" (  Integer | "EN"  ) )+
Packit dd8086
    "@}"
Packit dd8086
Packit dd8086
<cdTextTrack> ::=  "CD_TEXT" "@{" ( <cdTextBlock> )*  "@}"
Packit dd8086
Packit dd8086
<cdTextGlobal> ::= "CD_TEXT" "@{" @{ <cdTextLanguageMap> @} ( <cdTextBlock> )* "@}"
Packit dd8086
@end example
Packit dd8086
Packit dd8086
Packit dd8086
Packit dd8086
@node  CDRWIN BIN/CUE Format
Packit dd8086
@section CDRWIN BIN/CUE Format
Packit dd8086
@cindex BIN/CUE, CD Image Format
Packit dd8086
Packit dd8086
The format referred to as @emph{CDRWIN BIN/CUE Format} in this manual
Packit dd8086
is a popular CD image format used in the @acronym{PC} world. Not
Packit dd8086
unlike @command{cdrdao}'s TOC file, the @emph{cue} file describes the
Packit dd8086
track layout, i.e. how the sectors are to be placed on the CD
Packit dd8086
media. The @emph{cue} file usually contains a reference to a file
Packit dd8086
traditionally having the @file{.bin} extension in its filename, the
Packit dd8086
@emph{bin} file. This @emph{bin} file contains the sector data payload
Packit dd8086
which is to be written to the CD medium according to the description
Packit dd8086
in the @emph{cue} file.
Packit dd8086
Packit dd8086
The following is an attempt to describe the subset of the @file{.cue}
Packit dd8086
file syntax used in @value{libcdio} and vcdimager in an EBNF-like
Packit dd8086
notation:
Packit dd8086
Packit dd8086
@subsection BIN/CUE Grammar
Packit dd8086
Packit dd8086
@example
Packit dd8086
@cartouche
Packit dd8086
<cue-document> ::= +( <file-line> +<track-expr> )
Packit dd8086
Packit dd8086
<digit> ::= "0" | "1" ... "8" | "9"
Packit dd8086
<number> ::= +<digit>
Packit dd8086
<msf> ::= <digit><digit> ":" <digit><digit> ":" <digit><digit>
Packit dd8086
Packit dd8086
<file-line> ::= "FILE" <pathname-expr> <file-type> <EOL>
Packit dd8086
Packit dd8086
<pathname-expr> ::= [ "\"" ] <pathname-str-without-spaces> [ "\"" ]
Packit dd8086
                  | "\"" <pathname-str> "\""
Packit dd8086
Packit dd8086
<file-type> ::= "BINARY"
Packit dd8086
Packit dd8086
<track-expr> ::= <track-line> [ <flag-line> ]
Packit dd8086
                 [ <pregap-line> ] *<index-line> [ <postgap-line> ]
Packit dd8086
Packit dd8086
<flag-line> ::= "FLAGS" *<flag-type> <EOL>
Packit dd8086
<flag-type> ::= "DCP"
Packit dd8086
Packit dd8086
<track-line> ::= "TRACK" <number> <track-type> <EOL>
Packit dd8086
Packit dd8086
<pregap-line> ::= "PREGAP" <msf> <EOL>
Packit dd8086
Packit dd8086
<index-line> ::= "INDEX" <number> <msf> <EOL>
Packit dd8086
Packit dd8086
<postgap-line> ::= "POSTGAP" <msf> <EOL>
Packit dd8086
Packit dd8086
<track-type> ::= "AUDIO" | "MODE1/2048" | "MODE1/2352"
Packit dd8086
               | "MODE2/2336" | "MODE2/2352"
Packit dd8086
Packit dd8086
<comment-line> ::= "REM" *<char> <EOL>
Packit dd8086
@end cartouche
Packit dd8086
@end example
Packit dd8086
Packit dd8086
@node  NRG Format
Packit dd8086
@section NRG Format
Packit dd8086
@cindex Nero NRG, CD-Image format
Packit dd8086
Packit dd8086
The format referred to as @emph{NRG Format} in this manual is another
Packit dd8086
popular CD image format. It is available only on Nero software
Packit dd8086
on a Microsoft Windows Operating System. It is proprietary and not
Packit dd8086
generally published, so the information we have comes from guessing
Packit dd8086
based on sample CD images. So support for this is incomplete and using
Packit dd8086
this format is not recommended.
Packit dd8086
Packit dd8086
Unlike @command{cdrdao}'s TOC file the BIN/CUE format everything is
Packit dd8086
contained in one file that one can edit. Meta information such as the
Packit dd8086
number of tracks and track format is contained at the end of the
Packit dd8086
file. This information is not intended to be edited through a text
Packit dd8086
editor.
Packit dd8086
Packit dd8086
@node CD Units
Packit dd8086
@chapter The units that make up a CD
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* Tracks::   Tracks
Packit dd8086
* Sectors::  Block addressing (MSF, LSN, LBA)
Packit dd8086
* Pre-gaps::  Track pre-gaps
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node Tracks
Packit dd8086
@section tracks --- disc subdivisions
Packit dd8086
@cindex track
Packit dd8086
@cindex gaps
Packit dd8086
Packit dd8086
In this section we describe CD properties and terms that we make use
Packit dd8086
of in @value{libcdio}.
Packit dd8086
Packit dd8086
A CD is formatted into a number of @term{tracks}, and a CD can hold at
Packit dd8086
most 99 such tracks. This is defined by @code{CDIO_CD_MAX_TRACKS} in
Packit dd8086
@file{cdio/sector.h}. Between some tracks CD specifications require a
Packit dd8086
``2 second'' in gap (called a @term{lead-in gap}. This is unused space
Packit dd8086
with no ``data'' similar to the space between tracks on an old
Packit dd8086
phonograph. The word ``second'' here really refers to a measure of
Packit dd8086
space and not really necessarily an amount of time. However in the
Packit dd8086
special case that the CD encodes an audio CD or CD-DA, the amount of
Packit dd8086
time to play a gap of this size will take 2 seconds.
Packit dd8086
Packit dd8086
@cindex lead out
Packit dd8086
The beginning (or inner edge) of the CD is supposed to have a ``2
Packit dd8086
second'' lead-in gap and there is supposed to be another ``2 second''
Packit dd8086
@term{lead-out} gap at the end (or outer edge) of the CD.
Packit dd8086
Packit dd8086
People have discovered that they can put useful data in the @term{lead-in}
Packit dd8086
and @term{lead-out} gaps, and their equipment can read this, violating
Packit dd8086
the standards but allowing a CD to store more data.
Packit dd8086
Packit dd8086
In order to determine the number of tracks on a CD and where they
Packit dd8086
start, commands are used to get this table-of-contents or @term{TOC}
Packit dd8086
information. Asking about the start of the @term{lead-out track}
Packit dd8086
gives the amount of data stored on the Compact Disk. To make it easy
Packit dd8086
to specify this leadout track, special constant 0xAA (decimal 170) is
Packit dd8086
used to indicate it. This is safe since this is higher than the
Packit dd8086
largest legal track position. In @value{libcdio},
Packit dd8086
@code{CDIO_CDROM_LEADOUT_TRACK} is defined to be this special value.
Packit dd8086
Packit dd8086
@node Sectors
Packit dd8086
@section block addressing (MSF, LSN, LBA)
Packit dd8086
@cindex MSF
Packit dd8086
@cindex LSN
Packit dd8086
@cindex LBA
Packit dd8086
@cindex sectors
Packit dd8086
@cindex frames
Packit dd8086
Packit dd8086
A track is broken up into a number of 2352-byte @emph{blocks} which we
Packit dd8086
sometimes call @emph{sectors} or @emph{frames}. Whereas tracks may
Packit dd8086
have a gap between them, a block or sector does not. (In
Packit dd8086
@value{libcdio} the block size constant is defined using
Packit dd8086
@code{CDIO_CD_FRAMESIZE_RAW}).
Packit dd8086
Packit dd8086
A Compact Disc has a limit on the number of blocks or sectors.  This
Packit dd8086
values is defined by constant @code{CDIO_CD_MAX_LSN} in
Packit dd8086
@file{cdio/sector.h}.
Packit dd8086
Packit dd8086
One can addressing a block in one of three formats. The oldest format
Packit dd8086
is by it's minute/second/frame number, also referred to as @term{MSF}
Packit dd8086
and written in time-like format MM:SS:FF (e.g. 30:01:40). It is best
Packit dd8086
suited in audio (Red Book) applications. In @value{libcdio}, the type
Packit dd8086
@code{msf_t} can be used to declare variables to hold such
Packit dd8086
values. Minute, second and frame values are one byte @emph{and stored
Packit dd8086
BCD notation}.@footnote{Perhaps this is a @value{libcdio} design
Packit dd8086
flaw. It was originally done I guess because it was convenient for
Packit dd8086
VCDs.} There are @value{libcdio} conversion routines
Packit dd8086
@code{cdio_from_bcd8()} and @code{cdio_to_bcd8()} to convert the
Packit dd8086
minute, second, and frame values into or out of integers. If you want
Packit dd8086
to print a field in a BCD-encoded MSF, one can use the format
Packit dd8086
specifier @code{%x} @emph{(not @code{%d})} and things will come out
Packit dd8086
right.
Packit dd8086
Packit dd8086
In the MSF notation, there are 75 ``frames'' in a ``second,'' and the
Packit dd8086
familiar (if awkward) 60 seconds in a minute. @emph{Frame} here is
Packit dd8086
what we called a @emph{block} above. The CD specification defines
Packit dd8086
``frame'' to be @emph{another} unit which makes up a block. Very
Packit dd8086
confusing. A frame is also sometimes called a sector, analogous to
Packit dd8086
hard-disk terminology.
Packit dd8086
Packit dd8086
Even more confusing is using this time-like notation for an address or
Packit dd8086
for a length. Too often people confuse the MSF notation this with an
Packit dd8086
amount of time. A ``second'' (or @code{CDIO_CD_FRAMES_PER_SEC} blocks)
Packit dd8086
in this notation is only a second of playing time for something
Packit dd8086
encoded as CD-DA. It does @emph{not} necessarily represent the amount
Packit dd8086
time that it will take to play a of Video CD---usually you need more
Packit dd8086
blocks than this. Nor does it represent the amount of data used to
Packit dd8086
play a second of an MP3---usually you need fewer blocks than this. It
Packit dd8086
is also not the amount of time your CD-ROM will take to read a
Packit dd8086
``second'' of data off a Compact Disc: for example a 12x CD player
Packit dd8086
will read 12x @code{CDIO_CD_FRAMES_PER_SEC}
Packit dd8086
@code{CDIO_CD_FRAMSIZE_RAW}-byte blocks in a one second of time.
Packit dd8086
Packit dd8086
When programming, unless one is working with a CD-DA (and even here,
Packit dd8086
only in a time-like fashion), is generally more cumbersome to use an
Packit dd8086
MSF rather than a LBA or LSN described below, since subtraction of two
Packit dd8086
MSF's has the awkwardness akin to subtraction using Roman Numerals.
Packit dd8086
Packit dd8086
A simpler way to address a block is to use a ``Logical Sector Number''
Packit dd8086
(@term{LSN}) or a ``Logical Block Address (@term{LBA}). In the MMC-5
Packit dd8086
glossary these are synonymous terms. However historically it has been
Packit dd8086
used differently. In libcdio, to convert a LBA into an LSN you just
Packit dd8086
subtract 150. Both LBA's and LSN's can be negative.
Packit dd8086
Packit dd8086
@node Pre-gaps
Packit dd8086
@section track pre-gaps -- @acronym{CD-DA} discs and gaps
Packit dd8086
@cindex CD-DA
Packit dd8086
@cindex gaps
Packit dd8086
@cindex lead in
Packit dd8086
@cindex lead out
Packit dd8086
@cindex pre-gap
Packit dd8086
@cindex Q sub-channel
Packit dd8086
Packit dd8086
Gaps are possibly one of the least understood topics in audio discs.
Packit dd8086
In the case of @acronym{CD-DA} discs, standards require a silent 2
Packit dd8086
second gap before the first audio track and after the last audio track
Packit dd8086
(in each session.)  These are respectively referred to as
Packit dd8086
@term{lead-in} and @term{lead-out} gaps.  No other gaps are required.
Packit dd8086
It is important not to confuse the required @term{lead-in} and
Packit dd8086
@term{lead-out} gaps with the optional track @term{pre-gap}s.  Track
Packit dd8086
@term{pre-gap}s are the gaps that may occur between audio tracks.
Packit dd8086
Typically, track @term{pre-gap}s are filled with silence so that the
Packit dd8086
listener knows that one song has ended, and the next will soon begin.
Packit dd8086
However, track @term{pre-gap}s do not have to contain silence.  One
Packit dd8086
exception is an audio disc of a live performance.  Because the
Packit dd8086
performer may seamlessly move from one piece of the performance to the
Packit dd8086
next, it would be unnatural for the disc to contain silence between
Packit dd8086
the two pieces.  Instead, the track number updates with no
Packit dd8086
interruption in the performance.  This allows the listener to either
Packit dd8086
hear the entire performance without unnatural interruptions, or to
Packit dd8086
conveniently skip to certain pieces of the performance.  Finally, some
Packit dd8086
@acronym{CD-DA} discs--whose behavior will be described below--lack
Packit dd8086
track @term{pre-gap}s altogether although they must still include the
Packit dd8086
@term{lead-in} and @term{lead-out} gaps.
Packit dd8086
Packit dd8086
In order to understand the track @term{pre-gap}s that occur between
Packit dd8086
audio tracks, it is necessary to understand how CD players display the
Packit dd8086
track number and time.  Embedded in each block of audio data is
Packit dd8086
non-audio information known as the @term{Q sub-channel}.  The
Packit dd8086
@term{Q sub-channel} data tells the CD player what track number and time
Packit dd8086
it should display while it is playing the block of audio data in which
Packit dd8086
the @term{Q sub-channel} data is embedded.  Near the end of some
Packit dd8086
tracks, the @term{Q sub-channel} may instruct the CD player to update
Packit dd8086
the track number to the next track, and display a count down to the
Packit dd8086
next track, often starting at -2 seconds and proceeding to zero.  This
Packit dd8086
is known as an audio track @term{pre-gap}.  It may either contain
Packit dd8086
silence, or as previously discussed--in the case of live
Packit dd8086
performances--it may contain audio.  Almost as often as not, there is
Packit dd8086
no @term{pre-gap} whatsoever.  Regardless, an audio track
Packit dd8086
@term{pre-gap} is purely determined by the contents of the
Packit dd8086
@term{Q sub-channel}, which is embedded in each audio sector.  This has
Packit dd8086
some interesting implications for the track forward button.
Packit dd8086
Packit dd8086
When the track forward button is pressed on a CD player, the CD player
Packit dd8086
advances to the next track, skipping that track's @term{pre-gap}.
Packit dd8086
This is because the CD player uses the starting address of the track
Packit dd8086
from the disc's table of contents (TOC) to determine where to start
Packit dd8086
playing a track when either the track forward or track backward
Packit dd8086
buttons are pressed.  So to hear a @term{pre-gap} for track 4, the
Packit dd8086
listener must either listen to track 3 first, or use the track forward
Packit dd8086
or backward buttons to go to track 4, then use the seek backward
Packit dd8086
button to back up into track 4's @term{pre-gap}, which is really part
Packit dd8086
of track 3, at least according to the TOC.  Track 1 @term{pre-gap}s
Packit dd8086
are especially interesting because some commercial discs have audio
Packit dd8086
hidden before the beginning of the first track!  The only way to hear
Packit dd8086
this hidden audio with a standard player is to use the seek backward
Packit dd8086
button as soon as track 1 begins playing!
Packit dd8086
Packit dd8086
Audio track @term{pre-gap}s may be specified in a couple of different
Packit dd8086
ways in the popular cue file format.  The first way of specifying a
Packit dd8086
@term{pre-gap} is to use the @command{PREGAP} command.  This will
Packit dd8086
place a @term{pre-gap} containing silence before a track.  The second
Packit dd8086
way of specifying a @term{pre-gap} is to give a track an
Packit dd8086
@command{INDEX 00} as well as the more normal @command{INDEX 01}.
Packit dd8086
@command{INDEX 01} will be used to specify the start of the track in
Packit dd8086
the disc's TOC, while @command{INDEX 00} will be used to specify the
Packit dd8086
start of the track's @term{pre-gap} as recorded in the @term{Q sub-channel}.
Packit dd8086
@command{INDEX 00} is ordinarily used for specifying
Packit dd8086
track @term{pre-gap}s that contain audio rather than silence.  Thus,
Packit dd8086
the cue file format may be used to specify track @term{pre-gap}s with
Packit dd8086
silence or audio, depending on whether the @command{PREGAP} or
Packit dd8086
@command{INDEX 00} commands are specified.  If neither type of
Packit dd8086
@term{pre-gap} is specified for a track, no @term{pre-gap} is created
Packit dd8086
for that track, which merely means the absence of @term{pre-gap}
Packit dd8086
information in the @term{Q sub-channel}, and the lack of a short count
Packit dd8086
down to the next track.
Packit dd8086
Packit dd8086
Various @acronym{CD-DA} ripping programs take various approaches to
Packit dd8086
track @term{pre-gap}s.  Some ripping programs ignore track
Packit dd8086
@term{pre-gap}s altogether, relying solely on the disc's TOC to
Packit dd8086
determine where tracks begin and end.  If a disc is ripped with such a
Packit dd8086
program, then re-burned later, the resulting disc will lack track
Packit dd8086
@term{pre-gap}s, and thereby lack the playback behavior of counting
Packit dd8086
down to the next track.  Other ripping programs detect track
Packit dd8086
@term{pre-gap}s and record them in the popular cue file format among
Packit dd8086
others.  Such ripping programs sometimes allow the user to determine
Packit dd8086
whether track @term{pre-gap}s will be appended to the prior track or
Packit dd8086
pre-pended to the track to which they "belong".  Note that if a
Packit dd8086
ripping program is ignorant of track @term{pre-gap}s, the track
Packit dd8086
@term{pre-gap}s will be appended to the prior track, because that is
Packit dd8086
where the disc's TOC puts them.  Thus, there are many different ways
Packit dd8086
an application may chose to deal with track @term{pre-gap}s.
Packit dd8086
Consequently, @kbd{libcdio} does not dictate the policy a ripping
Packit dd8086
program should use in dealing with track @term{pre-gap}s.  Hence,
Packit dd8086
@kbd{libcdio} provides the @code{cdio_get_track_pregap_[lba|lsn]()}
Packit dd8086
interfaces to allow the application to deal with track @term{pre-gap}s
Packit dd8086
as it sees fit.
Packit dd8086
Packit dd8086
Note that the @code{cdio_get_track_pregap_[lba|lsn]()} interfaces
Packit dd8086
currently only provide information for CDRDAO TOC, CDRWIN BIN/CUE, and
Packit dd8086
NRG images.  Getting the track @term{pre-gap}s from a CD drive is a
Packit dd8086
more complicated problem because not all CD drives support reading the
Packit dd8086
@term{Q sub-channel} @emph{directly} at @emph{high} speed, and there is no
Packit dd8086
interface to determine whether or not a drive supports this optional
Packit dd8086
feature, aside from trying to read the @term{Q sub-channel}, and
Packit dd8086
possibly incurring IO errors.  However, all drives @emph{do} support reading
Packit dd8086
the @term{Q sub-channel} @emph{indirectly} while playing an audio disc by
Packit dd8086
asking the drive for the current position.  Unfortunately, this occurs
Packit dd8086
at normal playback speed, and requires a certain settling time after
Packit dd8086
the disc starts playing.  Thus, using this @emph{slow} interface
Packit dd8086
requires a more sophisticated algorithm, such as binary search or some
Packit dd8086
heuristic, like backing up progressively from the end of the prior
Packit dd8086
track to look for the next track's @term{pre-gap}.  Note that CD
Packit dd8086
drives seek @emph{slow}ly, so it is better to simply use a drive that
Packit dd8086
can read the @term{Q sub-channel} directly at @emph{high} speed, and
Packit dd8086
avoid complicated software solutions.  (Not to mention that if the
Packit dd8086
user has an older system with an analog audio cable hooked up between
Packit dd8086
their soundboard and their drive, and a ripping program uses the
Packit dd8086
@emph{slow} interface, the user will hear bits of the audio on the
Packit dd8086
disc!)  Consequently, because there is no good universal solution to
Packit dd8086
the problem of reading the @term{Q sub-channel} from a drive,
Packit dd8086
@kbd{libcdio} currently leaves this problem up to the application, a
Packit dd8086
problem which is readily approachable through either @kbd{libcdio}'s
Packit dd8086
MMC interface or @kbd{libcdio}'s cdda interface.  For an example of
Packit dd8086
one such application, see @url{https://gna.org/projects/cued/}.
Packit dd8086
Packit dd8086
The preceding section on track @term{pre-gaps} and @acronym{CD-DA} was
Packit dd8086
contributed by Robert William Fuller (@email{hydrologiccycle@@gmail.com}).
Packit dd8086
Packit dd8086
@node How to use
Packit dd8086
@chapter How to use
Packit dd8086
Packit dd8086
The @value{libcdio} package comes with a number of small example
Packit dd8086
programs in the directory @file{example} which demonstrate different
Packit dd8086
aspects of the library and show how to use the library. The source
Packit dd8086
code to all of the examples here are contained on the package.
Packit dd8086
Packit dd8086
Other sources for examples would be the larger utility programs
Packit dd8086
@command{cd-drive}, @command{cd-info}, @command{cd-read},
Packit dd8086
@command{iso-info}, and @command{iso-read} which are all in the
Packit dd8086
@file{src} directory of the @value{libcdio} package.  See also
Packit dd8086
@xref{Utility Programs}.
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* Include problem::  A note about including <cdio/cdio.h>
Packit dd8086
* Example 1::        list out tracks and LSNs
Packit dd8086
* Example 2::        list drivers available and default CD device
Packit dd8086
* Example 3::        figure out what kind of CD (image) we've got
Packit dd8086
* Example 4::        use libiso9660 to extract a file from an ISO-9660 image
Packit dd8086
* Example 5::        list CD-Text and CD disc mode info
Packit dd8086
* Example 6::        run a MMC INQUIRY command
Packit dd8086
* Example 7::        using the CD Paranoia library for CD-DA reading
Packit dd8086
* Example 8::        Setting output verbosity
Packit dd8086
* All sample programs:: list of all programs in the example directory
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node Include problem
Packit dd8086
@section A note about including @code{<cdio/cdio.h>}
Packit dd8086
Packit dd8086
libcdio installs @code{<cdio/cdio_config.h>}. This file contains all of
Packit dd8086
the C Preprocessor values from @code{config.h} (created by configure).
Packit dd8086
Packit dd8086
This header can be used to consult exactly how libcdio was built. Initially
Packit dd8086
I had selected ``interesting'' values, but this became too hard to maintain.
Packit dd8086
Packit dd8086
One set of values that libdio needs internally is the whether the CPU
Packit dd8086
that was used to compile libcdio is BigEndian or not; it can get this
Packit dd8086
from libcdio's @code{config.h} which is not installed and preferred or
Packit dd8086
@code{cdio/cdio_config.h}.
Packit dd8086
Packit dd8086
Some of the libcdio programs like the demo programs include
Packit dd8086
@code{config.h} for the generic reasons that the configuration-created
Packit dd8086
@code{config.h} file is used: to figure out what headers are available.
Packit dd8086
For example, do we have @code{<unistd.h>}?
Packit dd8086
Packit dd8086
The file @code{config.h} is generated by an autotools-generated
Packit dd8086
@code{configure} script. It doesn't check to see if it has been included
Packit dd8086
previously.
Packit dd8086
Packit dd8086
Later, the demo programs include @code{<cdio.h>} to get libcdio headers.
Packit dd8086
But because libcdio needs some of the same information like the BigEndian
Packit dd8086
value, this creates a duplicate include.
Packit dd8086
Packit dd8086
The way I get around this in the demo programs is by defining @code{__CDIO_CONFIG_H__} after
Packit dd8086
including @code{config.h} as follows:
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
# define __CDIO_CONFIG_H__ 1
Packit dd8086
#endif
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
Applications using libcdio may find it handy to do something like this as well.
Packit dd8086
Packit dd8086
Defining @code{__CDIO_CONFIG_H__} will make sure @code{config_cdio.h}
Packit dd8086
which is internally used,  doesn't try to redefine preprocessor symbols.
Packit dd8086
Packit dd8086
Ok. But now what about the problem that there are common preprocessor
Packit dd8086
symbols in @code{config_cdio.h} that an application may want to define in a
Packit dd8086
different manner, like @code{PACKAGE_NAME}?
Packit dd8086
Packit dd8086
For this, there is yet another header, @code{<cdio/cdio_unconfig.h>}.
Packit dd8086
This file undefines any symbol that @code{config.h} defines. And now we
Packit dd8086
bounce to the problem that there may be symbols that are normally
Packit dd8086
defined (@code{HAVE_UNISTD_H}) and you want to keep that way, but others that
Packit dd8086
you don't.  So here is what I suggest:
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
  // for cdio:
Packit dd8086
  #include <cdio.h>
Packit dd8086
  #include <cdio_unconfig.h> # remove *all* symbols libcdio defines
Packit dd8086
Packit dd8086
  // Add back in the ones you want your program
Packit dd8086
  #include <config.h>
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
The solution isn't the most simple or natural, but programming sometimes can
Packit dd8086
be difficult. If someone has a better solution, let me know.
Packit dd8086
Packit dd8086
Between header files @code{cdio_config.h} and @code{cdio_unconfig.h} and
Packit dd8086
all the fact that almost all headers@footnote{@code{<cdio_unconfig.h>} is
Packit dd8086
one of the few headers that doesn't set a preprocessor symbol: it does
Packit dd8086
its thing every time it is @code{#included}} define a symbol to indicate they
Packit dd8086
have been included, I think there is enough mechanism to cover most
Packit dd8086
situations that may arise.
Packit dd8086
Packit dd8086
@node Example 1
Packit dd8086
@section Example 1: list out tracks and LSNs
Packit dd8086
Here we will give an annotated example which can be found in the
Packit dd8086
distribution as @file{example/tracks.c}.
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
 1: #include <stdio.h>
Packit dd8086
 2: #include <sys/types.h>
Packit dd8086
 3: #include <cdio/cdio.h>
Packit dd8086
 4: int
Packit dd8086
 5: main(int argc, const char *argv[])
Packit dd8086
 6: @{
Packit dd8086
 7:  CdIo_t *p_cdio = cdio_open ("/dev/cdrom", DRIVER_DEVICE);
Packit dd8086
 8:  track_t first_track_num = cdio_get_first_track_num(p_cdio);
Packit dd8086
 9:  track_t i_tracks        = cdio_get_num_tracks(p_cdio);
Packit dd8086
10:  int j, i=first_track_num;
Packit dd8086
11:
Packit dd8086
12:  printf("CD-ROM Track List (%i - %i)\n", first_track_num, i_tracks);
Packit dd8086
13
Packit dd8086
14:  printf("  #:  LSN\n");
Packit dd8086
15:
Packit dd8086
16:  for (j = 0; j < i_tracks; i++, j++) @{
Packit dd8086
17:    lsn_t lsn = cdio_get_track_lsn(p_cdio, i);
Packit dd8086
18:    if (CDIO_INVALID_LSN != lsn)
Packit dd8086
19:      printf("%3d: %06d\n", (int) i, lsn);
Packit dd8086
20:  @}
Packit dd8086
21:  printf("%3X: %06d  leadout\n", CDIO_CDROM_LEADOUT_TRACK,
Packit dd8086
22:         cdio_get_track_lsn(p_cdio, CDIO_CDROM_LEADOUT_TRACK));
Packit dd8086
23:  cdio_destroy(p_cdio);
Packit dd8086
24:  return 0;
Packit dd8086
25: @}
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
Already from the beginning on line 2 we see something odd. The
Packit dd8086
@code{#include <sys/types.h>} is needed because @value{libcdio}
Packit dd8086
assumes type definitions exist for @code{uint32_t}, @code{uint16_t}
Packit dd8086
and so on.  Alternatively you change line 2 to:
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
#define HAVE_SYS_TYPES_H
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
and @code{<cdio/cdio.h>} will insert line 2. If you use GNU autoconf
Packit dd8086
to configure your program, add @code{sys/types.h} to
Packit dd8086
@code{AC_HAVE_HEADERS} and @emph{it} will arrange for
Packit dd8086
@code{HAVE_SYS_TYPES_H} to get defined. If you don't have
Packit dd8086
@code{<sys/types.h>} but have some other include that defines these
Packit dd8086
types, put that instead of line 2. Or you could roll your own
Packit dd8086
typedefs. (Note: In the future, this will probably get ``fixed'' by
Packit dd8086
requiring glib.h.)
Packit dd8086
Packit dd8086
Okay after getting over the hurdle of line 2, the next line pretty
Packit dd8086
straightforward: you need to include this to get cdio definitions. One
Packit dd8086
of the types that is defined via line 3 is @code{CdIo_t} and a pointer
Packit dd8086
that is used pretty much in all operations. Line 6 initializes the
Packit dd8086
variable @code{cdio} which we will be using in all of the subsequent
Packit dd8086
libcdio calls. It does this via a call to @code{cdio_open()}.
Packit dd8086
Packit dd8086
The second parameter of @code{cdio_open} is DRIVER_UNKNOWN. For any
Packit dd8086
given installation a number of Compact Disc device drivers may be
Packit dd8086
available. In particular it's not uncommon to have several drivers
Packit dd8086
that can read CD disk-image formats as well as a driver that handles
Packit dd8086
some CD-ROM piece of hardware. Using DRIVER_UNKNOWN as that second
Packit dd8086
parameter we let the library select a driver amongst those that are
Packit dd8086
available; generally the first hardware driver that is available is
Packit dd8086
the one selected.
Packit dd8086
Packit dd8086
If there is no CD in any of the CD-ROM drives or one does not have
Packit dd8086
access to the CD-ROM, it is possible that @value{libcdio} will find a
Packit dd8086
CD image in the directory you run this program and will pick a
Packit dd8086
suitable CD-image driver. If this is not what you want, but always
Packit dd8086
want some sort of CD-ROM driver (or failure if none), then use
Packit dd8086
DRIVER_DEVICE instead of DRIVER_UNKNOWN.
Packit dd8086
Packit dd8086
Note that in contrast to what is typically done using ioctls to read a
Packit dd8086
CD, you don't issue any sort of CD-ROM read TOC command---that is all
Packit dd8086
done by the driver. Of course, the information that you get from
Packit dd8086
reading the TOC is often desired: many tracks are on the CD, or what
Packit dd8086
number the first one is called. This is done through calls on lines 8
Packit dd8086
and 9.
Packit dd8086
Packit dd8086
For each track, we call a cdio routine to get the logical sector
Packit dd8086
number, @code{cdio_get_track_lsn()} on line 17 and print the track
Packit dd8086
number and LSN value. Finally we print out the ``lead-out track''
Packit dd8086
information and we finally call @code{cdio_destroy()} in line 23 to
Packit dd8086
indicate we're done with the CD.
Packit dd8086
Packit dd8086
@node Example 2
Packit dd8086
@section Example 2: list drivers available and default CD device
Packit dd8086
Packit dd8086
One thing that's a bit hockey in Example 1 is hard-coding the name of
Packit dd8086
the device used: @code{/dev/cdrom}. Although often this is the name of
Packit dd8086
a CD-ROM device on GNU/Linux and possibly some other Unix derivatives,
Packit dd8086
there are many OSs for which use a different device name.
Packit dd8086
Packit dd8086
In the next example, we'll let the driver give us the name of the CD-ROM
Packit dd8086
device that is right for it.
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
 1: #include <stdio.h>
Packit dd8086
 2: #include <sys/types.h>
Packit dd8086
 3: #include <cdio/cdio.h>
Packit dd8086
 4: int
Packit dd8086
 5: main(int argc, const char *argv[])
Packit dd8086
 6: @{
Packit dd8086
 7:   CdIo_t *p_cdio = cdio_open (NULL, DRIVER_DEVICE);
Packit dd8086
 8:   const driver_id_t *driver_id_p;
Packit dd8086
 9:
Packit dd8086
10:  if (NULL != p_cdio) @{
Packit dd8086
11:    printf("The driver selected is %s\n", cdio_get_driver_name(p_cdio));
Packit dd8086
12:    printf("The default device for this driver is %s\n\n",
Packit dd8086
13:           cdio_get_default_device(p_cdio));
Packit dd8086
14:    cdio_destroy(p_cdio);
Packit dd8086
15:  @} else @{
Packit dd8086
16:    printf("Problem in trying to find a driver.\n\n");
Packit dd8086
17:  @}
Packit dd8086
18:
Packit dd8086
19:  for (driver_id_p=cdio_drivers; *driver_id_p!=DRIVER_UNKNOWN; driver_id_p++)
Packit dd8086
20:    if (cdio_have_driver(*driver_id_p))
Packit dd8086
21:      printf("We have: %s\n", cdio_driver_describe(*driver_id_p));
Packit dd8086
22:    else
Packit dd8086
23:      printf("We don't have: %s\n", cdio_driver_describe(*driver_id_p));
Packit dd8086
24:  return 0;
Packit dd8086
25: @}
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
Packit dd8086
@node Example 3
Packit dd8086
@section Example 3: figure out what kind of CD (image) we've got
Packit dd8086
Packit dd8086
In this example is a somewhat simplified program to show the use of
Packit dd8086
@command{cdio_guess_cd_type()} to  figure out the kind of CD image
Packit dd8086
we've got. This can be found in the distribution as @file{example/sample3.c}.
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
#endif
Packit dd8086
#include <stdio.h>
Packit dd8086
#include <string.h>
Packit dd8086
#include <sys/types.h>
Packit dd8086
#include <cdio/cdio.h>
Packit dd8086
#include <cdio/cd_types.h>
Packit dd8086
Packit dd8086
static void
Packit dd8086
print_analysis(cdio_iso_analysis_t cdio_iso_analysis,
Packit dd8086
	       cdio_fs_anal_t fs, int first_data, unsigned int num_audio,
Packit dd8086
	       track_t i_tracks, track_t first_track_num, CdIo_t *cdio)
Packit dd8086
@{
Packit dd8086
  switch(CDIO_FSTYPE(fs)) @{
Packit dd8086
  case CDIO_FS_AUDIO:
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_ISO_9660:
Packit dd8086
    printf("CD-ROM with ISO 9660 filesystem");
Packit dd8086
    if (fs & CDIO_FS_ANAL_JOLIET) @{
Packit dd8086
      printf(" and joliet extension level %d", cdio_iso_analysis.joliet_level);
Packit dd8086
    @}
Packit dd8086
    if (fs & CDIO_FS_ANAL_ROCKRIDGE)
Packit dd8086
      printf(" and rockridge extensions");
Packit dd8086
    printf("\n");
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_ISO_9660_INTERACTIVE:
Packit dd8086
    printf("CD-ROM with CD-RTOS and ISO 9660 filesystem\n");
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_HIGH_SIERRA:
Packit dd8086
    printf("CD-ROM with High Sierra filesystem\n");
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_INTERACTIVE:
Packit dd8086
    printf("CD-Interactive%s\n", num_audio > 0 ? "/Ready" : "");
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_HFS:
Packit dd8086
    printf("CD-ROM with Macintosh HFS\n");
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_ISO_HFS:
Packit dd8086
    printf("CD-ROM with both Macintosh HFS and ISO 9660 filesystem\n");
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_UFS:
Packit dd8086
    printf("CD-ROM with Unix UFS\n");
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_EXT2:
Packit dd8086
    printf("CD-ROM with Linux second extended filesystem\n");
Packit dd8086
	  break;
Packit dd8086
  case CDIO_FS_3DO:
Packit dd8086
    printf("CD-ROM with Panasonic 3DO filesystem\n");
Packit dd8086
    break;
Packit dd8086
  case CDIO_FS_UNKNOWN:
Packit dd8086
    printf("CD-ROM with unknown filesystem\n");
Packit dd8086
    break;
Packit dd8086
  @}
Packit dd8086
  switch(CDIO_FSTYPE(fs)) @{
Packit dd8086
  case CDIO_FS_ISO_9660:
Packit dd8086
  case CDIO_FS_ISO_9660_INTERACTIVE:
Packit dd8086
  case CDIO_FS_ISO_HFS:
Packit dd8086
    printf("ISO 9660: %i blocks, label `%.32s'\n",
Packit dd8086
	   cdio_iso_analysis.isofs_size, cdio_iso_analysis.iso_label);
Packit dd8086
    break;
Packit dd8086
  @}
Packit dd8086
  if (first_data == 1 && num_audio > 0)
Packit dd8086
    printf("mixed mode CD   ");
Packit dd8086
  if (fs & CDIO_FS_ANAL_XA)
Packit dd8086
    printf("XA sectors   ");
Packit dd8086
  if (fs & CDIO_FS_ANAL_MULTISESSION)
Packit dd8086
    printf("Multisession");
Packit dd8086
  if (fs & CDIO_FS_ANAL_HIDDEN_TRACK)
Packit dd8086
    printf("Hidden Track   ");
Packit dd8086
  if (fs & CDIO_FS_ANAL_PHOTO_CD)
Packit dd8086
    printf("%sPhoto CD   ",
Packit dd8086
		      num_audio > 0 ? " Portfolio " : "");
Packit dd8086
  if (fs & CDIO_FS_ANAL_CDTV)
Packit dd8086
    printf("Commodore CDTV   ");
Packit dd8086
  if (first_data > 1)
Packit dd8086
    printf("CD-Plus/Extra   ");
Packit dd8086
  if (fs & CDIO_FS_ANAL_BOOTABLE)
Packit dd8086
    printf("bootable CD   ");
Packit dd8086
  if (fs & CDIO_FS_ANAL_VIDEOCD && num_audio == 0) @{
Packit dd8086
    printf("Video CD   ");
Packit dd8086
  @}
Packit dd8086
  if (fs & CDIO_FS_ANAL_SVCD)
Packit dd8086
    printf("Super Video CD (SVCD) or Chaoji Video CD (CVD)");
Packit dd8086
  if (fs & CDIO_FS_ANAL_CVD)
Packit dd8086
    printf("Chaoji Video CD (CVD)");
Packit dd8086
  printf("\n");
Packit dd8086
@}
Packit dd8086
Packit dd8086
int
Packit dd8086
main(int argc, const char *argv[])
Packit dd8086
@{
Packit dd8086
  CdIo_t *p_cdio = cdio_open (NULL, DRIVER_UNKNOWN);
Packit dd8086
  cdio_fs_anal_t fs=0;
Packit dd8086
Packit dd8086
  track_t i_tracks;
Packit dd8086
  track_t first_track_num;
Packit dd8086
  lsn_t start_track;          /* first sector of track */
Packit dd8086
  lsn_t data_start =0;        /* start of data area */
Packit dd8086
Packit dd8086
  int first_data = -1;        /* # of first data track */
Packit dd8086
  int first_audio = -1;       /* # of first audio track */
Packit dd8086
  unsigned int num_data  = 0; /* # of data tracks */
Packit dd8086
  unsigned int num_audio = 0; /* # of audio tracks */
Packit dd8086
  unsigned int i;
Packit dd8086
Packit dd8086
  if (NULL == p_cdio) @{
Packit dd8086
    printf("Problem in trying to find a driver.\n\n");
Packit dd8086
    return 1;
Packit dd8086
  @}
Packit dd8086
Packit dd8086
  first_track_num = cdio_get_first_track_num(p_cdio);
Packit dd8086
  i_tracks      = cdio_get_num_tracks(p_cdio);
Packit dd8086
Packit dd8086
  /* Count the number of data and audio tracks. */
Packit dd8086
  for (i = first_track_num; i <= i_tracks; i++) @{
Packit dd8086
    if (TRACK_FORMAT_AUDIO == cdio_get_track_format(p_cdio, i)) @{
Packit dd8086
      num_audio++;
Packit dd8086
      if (-1 == first_audio) first_audio = i;
Packit dd8086
    @} else @{
Packit dd8086
      num_data++;
Packit dd8086
      if (-1 == first_data)  first_data = i;
Packit dd8086
    @}
Packit dd8086
  @}
Packit dd8086
Packit dd8086
  /* try to find out what sort of CD we have */
Packit dd8086
  if (0 == num_data) @{
Packit dd8086
    printf("Audio CD\n");
Packit dd8086
  @} else @{
Packit dd8086
    /* we have data track(s) */
Packit dd8086
    int j;
Packit dd8086
    cdio_iso_analysis_t cdio_iso_analysis;
Packit dd8086
Packit dd8086
    memset(&cdio_iso_analysis, 0, sizeof(cdio_iso_analysis));
Packit dd8086
Packit dd8086
    for (j = 2, i = first_data; i <= i_tracks; i++) @{
Packit dd8086
      lsn_t lsn;
Packit dd8086
      track_format_t track_format = cdio_get_track_format(p_cdio, i);
Packit dd8086
Packit dd8086
      lsn = cdio_get_track_lsn(p_cdio, i);
Packit dd8086
Packit dd8086
      switch ( track_format ) @{
Packit dd8086
      case TRACK_FORMAT_AUDIO:
Packit dd8086
      case TRACK_FORMAT_ERROR:
Packit dd8086
	break;
Packit dd8086
      case TRACK_FORMAT_CDI:
Packit dd8086
      case TRACK_FORMAT_XA:
Packit dd8086
      case TRACK_FORMAT_DATA:
Packit dd8086
      case TRACK_FORMAT_PSX:
Packit dd8086
	;
Packit dd8086
      @}
Packit dd8086
Packit dd8086
      start_track = (i == 1) ? 0 : lsn;
Packit dd8086
Packit dd8086
      /* save the start of the data area */
Packit dd8086
      if (i == first_data)
Packit dd8086
	data_start = start_track;
Packit dd8086
Packit dd8086
      /* skip tracks which belong to the current walked session */
Packit dd8086
      if (start_track < data_start + cdio_iso_analysis.isofs_size)
Packit dd8086
	continue;
Packit dd8086
Packit dd8086
      fs = cdio_guess_cd_type(p_cdio, start_track, i, &cdio_iso_analysis);
Packit dd8086
Packit dd8086
      print_analysis(cdio_iso_analysis, fs, first_data, num_audio,
Packit dd8086
		     i_tracks, first_track_num, p_cdio);
Packit dd8086
Packit dd8086
      if ( !(CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660 ||
Packit dd8086
	     CDIO_FSTYPE(fs) == CDIO_FS_ISO_HFS  ||
Packit dd8086
	     CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660_INTERACTIVE) )
Packit dd8086
	/* no method for non-ISO9660 multisessions */
Packit dd8086
	break;
Packit dd8086
    @}
Packit dd8086
  @}
Packit dd8086
  cdio_destroy(p_cdio);
Packit dd8086
  return 0;
Packit dd8086
@}
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
@node Example 4
Packit dd8086
@section Example 4: use libiso9660 to extract a file from an ISO-9660 image
Packit dd8086
Packit dd8086
Next a program to show using @command{libiso9660} to extract a file
Packit dd8086
from an ISO-9660 image.  This can be found in the distribution as
Packit dd8086
@file{example/isofile.c}. A more complete and expanded version of this
Packit dd8086
is @command{iso-read}, part of this distribution.
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
/* This is the ISO 9660 image. */
Packit dd8086
#define ISO9660_IMAGE_PATH "../"
Packit dd8086
#define ISO9660_IMAGE ISO9660_IMAGE_PATH "test/copying.iso"
Packit dd8086
Packit dd8086
#define LOCAL_FILENAME "copying"
Packit dd8086
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <sys/types.h>
Packit dd8086
#include <cdio/cdio.h>
Packit dd8086
#include <cdio/iso9660.h>
Packit dd8086
Packit dd8086
#include <stdio.h>
Packit dd8086
Packit dd8086
#ifdef HAVE_ERRNO_H
Packit dd8086
#include <errno.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_STRING_H
Packit dd8086
#include <string.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_UNISTD_H
Packit dd8086
#include <unistd.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_SYS_TYPES_H
Packit dd8086
#include <sys/types.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#define my_exit(rc)				\
Packit dd8086
  fclose (p_outfd);				\
Packit dd8086
  free(p_statbuf);				\
Packit dd8086
  iso9660_close(p_iso);				\
Packit dd8086
  return rc;					\
Packit dd8086
Packit dd8086
int
Packit dd8086
main(int argc, const char *argv[])
Packit dd8086
@{
Packit dd8086
  iso9660_stat_t *p_statbuf;
Packit dd8086
  FILE *p_outfd;
Packit dd8086
  int i;
Packit dd8086
Packit dd8086
  iso9660_t *p_iso = iso9660_open (ISO9660_IMAGE);
Packit dd8086
Packit dd8086
  if (NULL == p_iso) @{
Packit dd8086
    fprintf(stderr, "Sorry, couldn't open ISO 9660 image %s\n", ISO9660_IMAGE);
Packit dd8086
    return 1;
Packit dd8086
  @}
Packit dd8086
Packit dd8086
  p_statbuf = iso9660_ifs_stat_translate (p_iso, LOCAL_FILENAME);
Packit dd8086
Packit dd8086
  if (NULL == p_statbuf)
Packit dd8086
    @{
Packit dd8086
      fprintf(stderr,
Packit dd8086
	      "Could not get ISO-9660 file information for file %s\n",
Packit dd8086
	      LOCAL_FILENAME);
Packit dd8086
      iso9660_close(p_iso);
Packit dd8086
      return 2;
Packit dd8086
    @}
Packit dd8086
Packit dd8086
  if (!(p_outfd = fopen (LOCAL_FILENAME, "wb")))
Packit dd8086
    @{
Packit dd8086
      perror ("fopen()");
Packit dd8086
      free(p_statbuf);
Packit dd8086
      iso9660_close(p_iso);
Packit dd8086
      return 3;
Packit dd8086
    @}
Packit dd8086
Packit dd8086
  /* Copy the blocks from the ISO-9660 filesystem to the local filesystem. */
Packit dd8086
  for (i = 0; i < p_statbuf->size; i += ISO_BLOCKSIZE)
Packit dd8086
    @{
Packit dd8086
      char buf[ISO_BLOCKSIZE];
Packit dd8086
Packit dd8086
      memset (buf, 0, ISO_BLOCKSIZE);
Packit dd8086
Packit dd8086
      if ( ISO_BLOCKSIZE != iso9660_iso_seek_read (p_iso, buf, p_statbuf->lsn
Packit dd8086
						   + (i / ISO_BLOCKSIZE),
Packit dd8086
						   1) )
Packit dd8086
      @{
Packit dd8086
	fprintf(stderr, "Error reading ISO 9660 file at lsn %lu\n",
Packit dd8086
		(long unsigned int) p_statbuf->lsn + (i / ISO_BLOCKSIZE));
Packit dd8086
	my_exit(4);
Packit dd8086
      @}
Packit dd8086
Packit dd8086
Packit dd8086
     fwrite (buf, ISO_BLOCKSIZE, 1, p_outfd);
Packit dd8086
Packit dd8086
     if (ferror (p_outfd))
Packit dd8086
        @{
Packit dd8086
          perror ("fwrite()");
Packit dd8086
          my_exit(5);
Packit dd8086
        @}
Packit dd8086
    @}
Packit dd8086
Packit dd8086
  fflush (p_outfd);
Packit dd8086
Packit dd8086
  /* Make sure the file size has the exact same byte size. Without the
Packit dd8086
     truncate below, the file will a multiple of ISO_BLOCKSIZE.
Packit dd8086
   */
Packit dd8086
  if (ftruncate (fileno (p_outfd), p_statbuf->size))
Packit dd8086
    perror ("ftruncate()");
Packit dd8086
Packit dd8086
  my_exit(0);
Packit dd8086
@}
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
@node Example 5
Packit dd8086
@section Example 5: list CD-Text and disc mode info
Packit dd8086
Packit dd8086
Next a program to show using @command{libcdio} to list CD-TEXT data.
Packit dd8086
This can be found in the distribution as @file{example/cdtext.c}.
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
/* Simple program to list CD-Text info of a Compact Disc using libcdio. */
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
#endif
Packit dd8086
#include <stdio.h>
Packit dd8086
#include <sys/types.h>
Packit dd8086
#include <cdio/cdio.h>
Packit dd8086
#include <cdio/cdtext.h>
Packit dd8086
Packit dd8086
Packit dd8086
static void
Packit dd8086
print_cdtext_track_info(CdIo_t *p_cdio, track_t i_track, const char *message) @{
Packit dd8086
  const cdtext_t *cdtext    = cdio_get_cdtext(p_cdio, 0);
Packit dd8086
  if (NULL != cdtext) @{
Packit dd8086
    cdtext_field_t i;
Packit dd8086
Packit dd8086
    printf("%s\n", message);
Packit dd8086
Packit dd8086
    for (i=0; i < MAX_CDTEXT_FIELDS; i++) @{
Packit dd8086
      if (cdtext->field[i]) @{
Packit dd8086
        printf("\t%s: %s\n", cdtext_field2str(i), cdtext->field[i]);
Packit dd8086
      @}
Packit dd8086
    @}
Packit dd8086
  @}
Packit dd8086
Packit dd8086
@}
Packit dd8086
Packit dd8086
static void
Packit dd8086
print_disc_info(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track) @{
Packit dd8086
  track_t i_last_track = i_first_track+i_tracks;
Packit dd8086
  discmode_t cd_discmode = cdio_get_discmode(p_cdio);
Packit dd8086
Packit dd8086
  printf("%s\n", discmode2str[cd_discmode]);
Packit dd8086
Packit dd8086
  print_cdtext_track_info(p_cdio, 0, "\nCD-Text for Disc:");
Packit dd8086
  for ( ; i_first_track < i_last_track; i_first_track++ ) @{
Packit dd8086
    char psz_msg[50];
Packit dd8086
    sprintf(msg, "CD-Text for Track %d:", i_first_track);
Packit dd8086
    print_cdtext_track_info(p_cdio, i_first_track, psz_msg);
Packit dd8086
  @}
Packit dd8086
@}
Packit dd8086
Packit dd8086
int
Packit dd8086
main(int argc, const char *argv[])
Packit dd8086
@{
Packit dd8086
  track_t i_first_track;
Packit dd8086
  track_t i_tracks;
Packit dd8086
  CdIo_t *p_cdio;
Packit dd8086
  cdio = cdio_open (NULL, DRIVER_UNKNOWN);
Packit dd8086
  i_first_track = cdio_get_first_track_num(p_cdio);
Packit dd8086
  i_tracks      = cdio_get_num_tracks(p_cdio);
Packit dd8086
Packit dd8086
  if (NULL == p_cdio) @{
Packit dd8086
    printf("Couldn't find CD\n");
Packit dd8086
    return 1;
Packit dd8086
  @} else @{
Packit dd8086
    print_disc_info(p_cdio, i_tracks, i_first_track);
Packit dd8086
  @}
Packit dd8086
Packit dd8086
  cdio_destroy(p_cdio);
Packit dd8086
Packit dd8086
  return 0;
Packit dd8086
@}
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
@node Example 6
Packit dd8086
@section Example 6: Using MMC to run an @code{INQURY} command
Packit dd8086
Packit dd8086
Now a program to show issuing a simple MMC command
Packit dd8086
(@code{INQUIRY}). This MMC command retrieves the vendor, model and
Packit dd8086
firmware revision number of a CD drive. For this command to work,
Packit dd8086
usually a CD to be loaded into the drive; odd since the CD itself is
Packit dd8086
not used.
Packit dd8086
Packit dd8086
This can be found in the distribution as @file{example/mmc1.c}.
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
# define __CDIO_CONFIG_H__ 1 /* assumes config.h is libcdio's config.h /
Packit dd8086
#endif
Packit dd8086
#include <stdio.h>
Packit dd8086
#include <sys/types.h>
Packit dd8086
#include <cdio/cdio.h>
Packit dd8086
#include <cdio/scsi_mmc.h>
Packit dd8086
#include <string.h>
Packit dd8086
Packit dd8086
/* Set how long to wait for MMC commands to complete */
Packit dd8086
#define DEFAULT_TIMEOUT_MS 10000
Packit dd8086
Packit dd8086
int
Packit dd8086
main(int argc, const char *argv[])
Packit dd8086
@{
Packit dd8086
  CdIo_t *p_cdio;
Packit dd8086
Packit dd8086
  p_cdio = cdio_open (NULL, DRIVER_UNKNOWN);
Packit dd8086
Packit dd8086
  if (NULL == p_cdio) @{
Packit dd8086
    printf("Couldn't find CD\n");
Packit dd8086
    return 1;
Packit dd8086
  @} else @{
Packit dd8086
    int i_status;                  /* Result of MMC command */
Packit dd8086
    char buf[36] = @{ 0, @};         /* Place to hold returned data */
Packit dd8086
    scsi_mmc_cdb_t cdb = @{@{0, @}@};  /* Command Descriptor Buffer */
Packit dd8086
Packit dd8086
    CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_INQUIRY);
Packit dd8086
    cdb.field[4] = sizeof(buf);
Packit dd8086
Packit dd8086
    i_status = scsi_mmc_run_cmd(p_cdio, DEFAULT_TIMEOUT_MS,
Packit dd8086
				&cdb, SCSI_MMC_DATA_READ,
Packit dd8086
				sizeof(buf), &buf;;
Packit dd8086
    if (i_status == 0) @{
Packit dd8086
      char psz_vendor[CDIO_MMC_HW_VENDOR_LEN+1];
Packit dd8086
      char psz_model[CDIO_MMC_HW_MODEL_LEN+1];
Packit dd8086
      char psz_rev[CDIO_MMC_HW_REVISION_LEN+1];
Packit dd8086
Packit dd8086
      memcpy(psz_vendor, buf + 8, sizeof(psz_vendor)-1);
Packit dd8086
      psz_vendor[sizeof(psz_vendor)-1] = '\0';
Packit dd8086
      memcpy(psz_model,
Packit dd8086
	     buf + 8 + CDIO_MMC_HW_VENDOR_LEN,
Packit dd8086
	     sizeof(psz_model)-1);
Packit dd8086
      psz_model[sizeof(psz_model)-1] = '\0';
Packit dd8086
      memcpy(psz_rev,
Packit dd8086
	     buf + 8 + CDIO_MMC_HW_VENDOR_LEN +CDIO_MMC_HW_MODEL_LEN,
Packit dd8086
	     sizeof(psz_rev)-1);
Packit dd8086
      psz_rev[sizeof(psz_rev)-1] = '\0';
Packit dd8086
Packit dd8086
      printf("Vendor: %s\nModel: %s\nRevision: %s\n",
Packit dd8086
	     psz_vendor, psz_model, psz_rev);
Packit dd8086
    @} else @{
Packit dd8086
      printf("Couldn't get INQUIRY data (vendor, model, and revision\n");
Packit dd8086
    @}
Packit dd8086
  @}
Packit dd8086
Packit dd8086
  cdio_destroy(p_cdio);
Packit dd8086
Packit dd8086
  return 0;
Packit dd8086
@}
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
Note the include of @code{#define} of @code{__CDIO_CONFIG_H__} towards
Packit dd8086
the beginning.  This is useful if the prior @code{#include} of
Packit dd8086
@code{config.h} refers to libcdio's configuration header. It indicates
Packit dd8086
that libcdio's configuration settings have been used. Without it, you
Packit dd8086
may get messages about C Preprocessor symbols getting redefined in the
Packit dd8086
@code{#include} of @code{<cdio.cdio.h>}.
Packit dd8086
Packit dd8086
@node Example 7
Packit dd8086
@section Example 7: Using the CD Paranoia library for CD-DA reading
Packit dd8086
Packit dd8086
The below program reads CD-DA data. For a more complete program to add
Packit dd8086
a WAV header so that the CD can be played from a copy on a hard disk,
Packit dd8086
see the corresponding distribution program.
Packit dd8086
Packit dd8086
This can be found in the distribution as @file{example/paranoia.c}.
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
# define __CDIO_CONFIG_H__ 1 /* assumes config.h is libcdio's config.h /
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <cdio/cdda.h>
Packit dd8086
#include <cdio/cd_types.h>
Packit dd8086
#include <stdio.h>
Packit dd8086
Packit dd8086
#ifdef HAVE_STDLIB_H
Packit dd8086
#include <stdlib.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
int
Packit dd8086
main(int argc, const char *argv[])
Packit dd8086
@{
Packit dd8086
  cdrom_drive_t *d = NULL; /* Place to store handle given by cd-paranoia. */
Packit dd8086
  char **ppsz_cd_drives;   /* List of all drives with a loaded CDDA in it. */
Packit dd8086
Packit dd8086
  /* See if we can find a device with a loaded CD-DA in it. */
Packit dd8086
  ppsz_cd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false);
Packit dd8086
Packit dd8086
  if (ppsz_cd_drives) @{
Packit dd8086
    /* Found such a CD-ROM with a CD-DA loaded. Use the first drive in
Packit dd8086
       the list. */
Packit dd8086
    d=cdio_cddap_identify(*ppsz_cd_drives, 1, NULL);
Packit dd8086
  @} else @{
Packit dd8086
    printf("Unable find or access a CD-ROM drive with an audio CD in it.\n");
Packit dd8086
    exit(1);
Packit dd8086
  @}
Packit dd8086
Packit dd8086
  /* Don't need a list of CD's with CD-DA's any more. */
Packit dd8086
  cdio_free_device_list(ppsz_cd_drives);
Packit dd8086
Packit dd8086
  /* We'll set for verbose paranoia messages. */
Packit dd8086
  cdio_cddap_verbose_set(d, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_PRINTIT);
Packit dd8086
Packit dd8086
  if ( 0 != cdio_cddap_open(d) ) @{
Packit dd8086
    printf("Unable to open disc.\n");
Packit dd8086
    exit(1);
Packit dd8086
  @}
Packit dd8086
Packit dd8086
  /* Okay now set up to read up to the first 300 frames of the first
Packit dd8086
     audio track of the Audio CD. */
Packit dd8086
  @{
Packit dd8086
    cdrom_paranoia_t *p = cdio_paranoia_init(d);
Packit dd8086
    lsn_t i_first_lsn = cdio_cddap_disc_firstsector(d);
Packit dd8086
Packit dd8086
    if ( -1 == i_first_lsn ) @{
Packit dd8086
      printf("Trouble getting starting LSN\n");
Packit dd8086
    @} else @{
Packit dd8086
      lsn_t   i_cursor;
Packit dd8086
      track_t i_track    = cdio_cddap_sector_gettrack(d, i_first_lsn);
Packit dd8086
      lsn_t   i_last_lsn = cdio_cddap_track_lastsector(d, i_track);
Packit dd8086
Packit dd8086
      /* For demo purposes we'll read only 300 frames (about 4
Packit dd8086
	 seconds).  We don't want this to take too long. On the other
Packit dd8086
	 hand, I suppose it should be something close to a real test.
Packit dd8086
       */
Packit dd8086
      if ( i_last_lsn - i_first_lsn > 300) i_last_lsn = i_first_lsn + 299;
Packit dd8086
Packit dd8086
      printf("Reading track %d from LSN %ld to LSN %ld\n", i_track,
Packit dd8086
	     (long int) i_first_lsn, (long int) i_last_lsn);
Packit dd8086
Packit dd8086
      /* Set reading mode for full paranoia, but allow skipping sectors. */
Packit dd8086
      paranoia_modeset(p, PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP);
Packit dd8086
Packit dd8086
      paranoia_seek(p, i_first_lsn, SEEK_SET);
Packit dd8086
Packit dd8086
      for ( i_cursor = i_first_lsn; i_cursor <= i_last_lsn; i_cursor ++) @{
Packit dd8086
	/* read a sector */
Packit dd8086
	int16_t *p_readbuf=cdio_paranoia_read(p, NULL);
Packit dd8086
	char *psz_err=cdio_cddap_errors(d);
Packit dd8086
	char *psz_mes=cdio_cddap_messages(d);
Packit dd8086
Packit dd8086
	if (psz_mes || psz_err)
Packit dd8086
	  printf("%s%s\n", psz_mes ? psz_mes: "", psz_err ? psz_err: "");
Packit dd8086
Packit dd8086
	if (psz_err) cdio_cddap_free_messages(psz_err);
Packit dd8086
	if (psz_mes) cdio_cddap_free_messages(psz_mes);
Packit dd8086
	if( !p_readbuf ) @{
Packit dd8086
	  printf("paranoia read error. Stopping.\n");
Packit dd8086
	  break;
Packit dd8086
	@}
Packit dd8086
      @}
Packit dd8086
    @}
Packit dd8086
    cdio_paranoia_free(p);
Packit dd8086
  @}
Packit dd8086
Packit dd8086
  cdio_cdda_close(d);
Packit dd8086
  exit(0);
Packit dd8086
@}
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
Those who are die-hard cdparanoia programmers will notice that the
Packit dd8086
@value{libcdio} paranoia names are similar but a little bit
Packit dd8086
different. In particular instead of @code{paranoia_read} we have above
Packit dd8086
@code{cdio_paranoia_read} and instead of @code{cdda_open} we have
Packit dd8086
@code{cdio_cddap_open}.
Packit dd8086
Packit dd8086
This was done intentionally so that it is possible for the original
Packit dd8086
paranoia program can co-exist both in source code and linked libraries
Packit dd8086
and not conflict with @value{libcdio}'s paranoia source and libraries.
Packit dd8086
Packit dd8086
In general in place of any paranoia routine that begins
Packit dd8086
@code{paranoia_}, use @code{cdio_paranoia_} and in place of any
Packit dd8086
paranoia routine that begins @code{cdda_}, use @code{cdio_cddap_}. But
Packit dd8086
for a limited time @value{libcdio} will accept the old paranoia names
Packit dd8086
which may be useful for legacy paranoia code. The way this magic works
Packit dd8086
is by defining the old paranoia name to be the @value{libcdio} name.
Packit dd8086
Packit dd8086
In the unusual case where you do want to use both the original
Packit dd8086
paranoia and @value{libcdio} routines in a single source, the C
Packit dd8086
preprocessor symbol @code{DO_NOT_WANT_PARANOIA_COMPATIBILITY} can be
Packit dd8086
@code{define}'d and this disables the @code{#define} substitution done
Packit dd8086
automatically. The may still be a problem with conflicting structure
Packit dd8086
definitions like @code{cdrom_drive_t}.
Packit dd8086
Packit dd8086
@node Example 8
Packit dd8086
@section Example 8: Setting output verbosity
Packit dd8086
Packit dd8086
Sometimes in tracking down a problem in your code or libcdio's you may
Packit dd8086
want more information about what is going on inside the
Packit dd8086
@command{libcdio} library.
Packit dd8086
Packit dd8086
The setting global variable @code{cdio_loglevel_default} defined in
Packit dd8086
header file @code{<cdio/logging.h>} controls the verbosity level. By
Packit dd8086
default, only warnings, errors, and fatal errors are printed. However
Packit dd8086
by setting this variable you can get either debug or informational
Packit dd8086
messages, or cause the normal messages that appear to be suppressed.
Packit dd8086
Packit dd8086
The verbosity levels defined in the library are from lowest number to
Packit dd8086
highest are:
Packit dd8086
Packit dd8086
@table @code
Packit dd8086
Packit dd8086
@item @code{CDIO_LOG_DEBUG} (value 1)
Packit dd8086
Packit dd8086
These are of a debugging nature and are give the most verbose output.
Packit dd8086
Packit dd8086
@item @code{CDIO_LOG_INFO} (value 2)
Packit dd8086
Packit dd8086
These are informational message.
Packit dd8086
Packit dd8086
@item @code{CDIO_LOG_WARN} (value 3)
Packit dd8086
Packit dd8086
These are warning message. Not an error, per se, but something that
Packit dd8086
might be of concern.
Packit dd8086
Packit dd8086
@item @code{CDIO_LOG_ERROR} (value 4)
Packit dd8086
Packit dd8086
These are error messages that force program termination.
Packit dd8086
Packit dd8086
@item @code{CDIO_LOG_ASSERT} (value 5)
Packit dd8086
Packit dd8086
These are error messages that represent an internal inconsistency in
Packit dd8086
the @command{libcdio} library. In the absence of @command{libcdio}
Packit dd8086
bugs, these should never appear.
Packit dd8086
Packit dd8086
@end table
Packit dd8086
Packit dd8086
Setting a lower or more verbose log level will cause higher-level
Packit dd8086
messages to appear, but not those that are less than the set verbosity
Packit dd8086
level. The ``debug'' level is the lowest. So setting
Packit dd8086
@code{cdio_loglevel_default} to level causes all other levels of
Packit dd8086
messages to be displayed. However setting the verbosity level to
Packit dd8086
``warn'' will cause debug and informational messages (lower
Packit dd8086
level messages) to be ignored while still showing warning, error, and
Packit dd8086
fatal error messages.
Packit dd8086
Packit dd8086
Another thing that can be done is to write a custom log handler that
Packit dd8086
will be used instead of @command{libcdio}'s default handlers. Using
Packit dd8086
this, you have complete control of how you want logging to be handled.
Packit dd8086
Packit dd8086
Here is an example adapted from example program @command{logging.c}.
Packit dd8086
Packit dd8086
@smallexample
Packit dd8086
#include <stdio.h>
Packit dd8086
#include <stdlib.h>
Packit dd8086
#include <sys/types.h>
Packit dd8086
#include <errno.h>
Packit dd8086
#include <limits.h>
Packit dd8086
#include <string.h>
Packit dd8086
Packit dd8086
#include <cdio/cdio.h>
Packit dd8086
#include <cdio/cd_types.h>
Packit dd8086
#include <cdio/logging.h>
Packit dd8086
Packit dd8086
/* Here is an example of a custom log handler. */
Packit dd8086
static void
Packit dd8086
custom_log_handler (cdio_log_level_t level, const char *message)
Packit dd8086
@{
Packit dd8086
  switch(level) @{
Packit dd8086
  case CDIO_LOG_DEBUG:
Packit dd8086
    printf("-- custom debug message: %s\n", message);
Packit dd8086
    return;
Packit dd8086
  case CDIO_LOG_INFO:
Packit dd8086
    printf("-- custom info message: %s\n", message);
Packit dd8086
    return;
Packit dd8086
  case CDIO_LOG_WARN:
Packit dd8086
    printf("-- custom warning message: %s\n", message);
Packit dd8086
    return;
Packit dd8086
  case CDIO_LOG_ERROR:
Packit dd8086
    printf("-- custom error message: %s\n", message);
Packit dd8086
    return;
Packit dd8086
  case CDIO_LOG_ASSERT:
Packit dd8086
    printf("-- custom fatal error message: %s\n", message);
Packit dd8086
    return;
Packit dd8086
  default:
Packit dd8086
    printf("custom level %d message: %s\n", level, message);
Packit dd8086
  @}
Packit dd8086
@}
Packit dd8086
Packit dd8086
static void
Packit dd8086
print_drives()
Packit dd8086
@{
Packit dd8086
    char **ppsz_cd_drives=NULL, **c;
Packit dd8086
    /* Print out a list of CD-drives with the above set log level. */
Packit dd8086
    ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
Packit dd8086
    if (NULL != ppsz_cd_drives)
Packit dd8086
	for( c = ppsz_cd_drives; *c != NULL; c++ ) @{
Packit dd8086
	    printf("-- Drive %s\n", *c);
Packit dd8086
	@}
Packit dd8086
    cdio_free_device_list(ppsz_cd_drives);
Packit dd8086
@}
Packit dd8086
Packit dd8086
int
Packit dd8086
main(int argc, const char *argv[])
Packit dd8086
@{
Packit dd8086
    /* Set the log level to the warning verbosity. */
Packit dd8086
    cdio_loglevel_default = CDIO_LOG_WARN;
Packit dd8086
Packit dd8086
    print_drives();
Packit dd8086
Packit dd8086
    /* Do the same thing again but with a custom log handler. */
Packit dd8086
    cdio_log_set_handler (custom_log_handler);
Packit dd8086
Packit dd8086
    print_drives();
Packit dd8086
    return 0;
Packit dd8086
Packit dd8086
@}
Packit dd8086
@end smallexample
Packit dd8086
Packit dd8086
@node All sample programs
Packit dd8086
@section A list of all sample programs in the @code{example} directory
Packit dd8086
Packit dd8086
The @code{example} directory contains some simple examples of the use
Packit dd8086
of the @value{libcdio} library.
Packit dd8086
Packit dd8086
A larger more-complicated example are the @command{cd-drive},
Packit dd8086
@command{cd-info}, @command{cd-read}, @command{iso-info} and
Packit dd8086
@command{iso-info} programs in the @command{src} directory.
Packit dd8086
Packit dd8086
Descriptions of the sample are as follows...
Packit dd8086
Packit dd8086
@table @code
Packit dd8086
Packit dd8086
@item @code{audio.c}
Packit dd8086
Packit dd8086
A program to show audio controls.
Packit dd8086
Packit dd8086
@item @code{cdchange.c}
Packit dd8086
Packit dd8086
A program to test if a CD has been changed since the last change test.
Packit dd8086
Packit dd8086
@item @code{cd-eject.c}
Packit dd8086
Packit dd8086
A a stripped-down "eject" command to open or close a CD-ROM tray.
Packit dd8086
Packit dd8086
@item @code{cdtext.c}
Packit dd8086
Packit dd8086
A program to show CD-Text and CD disc mode info.
Packit dd8086
Packit dd8086
@item @code{drives.c}
Packit dd8086
Packit dd8086
A program to show drivers installed and what the default CD-ROM drive
Packit dd8086
is and what CD drives are available.
Packit dd8086
Packit dd8086
@item @code{eject.c}
Packit dd8086
Packit dd8086
A program eject a CD from a CD-ROM drive and then close the door again.
Packit dd8086
Packit dd8086
@item @code{isofile.c}
Packit dd8086
Packit dd8086
A program to show using libiso9660 to extract a file from an ISO-9660 image.
Packit dd8086
Packit dd8086
@item @code{isofile2.c}
Packit dd8086
Packit dd8086
A program to show using libiso9660 to extract a file from a CDRWIN cue/bin CD image.
Packit dd8086
Packit dd8086
@item @code{C++/isofile2.cpp}
Packit dd8086
Packit dd8086
The same program as @code{isofile2.c} written in C++.
Packit dd8086
Packit dd8086
@item @code{isofuzzy.c}
Packit dd8086
Packit dd8086
A program showing fuzzy ISO-9660 detection/reading.
Packit dd8086
Packit dd8086
@item @code{isolist.c}
Packit dd8086
Packit dd8086
A program to show using @code{libiso9660} to list files in a
Packit dd8086
	directory of an ISO-9660 image.
Packit dd8086
Packit dd8086
@item @code{C++/isolist.cpp}
Packit dd8086
Packit dd8086
The same program as @code{isolist.c} written in C++.
Packit dd8086
Packit dd8086
@item @code{isofuzzy.c}
Packit dd8086
Packit dd8086
A program showing fuzzy ISO-9660 detection/reading.
Packit dd8086
Packit dd8086
@item @code{logging.c}
Packit dd8086
Packit dd8086
A program to show to to set log verbosity levels and how to write a
Packit dd8086
custom log handler.
Packit dd8086
Packit dd8086
@item @code{mmc1.c}
Packit dd8086
Packit dd8086
A program to show issuing a simple MMC command (@code{INQUIRY}).
Packit dd8086
Packit dd8086
@item @code{C++/mmc1.cpp}
Packit dd8086
Packit dd8086
The same program as @code{mmc1.c} written in C++.
Packit dd8086
Packit dd8086
@item @code{mmc2.c}
Packit dd8086
Packit dd8086
A more involved MMC command to list CD and drive features from a
Packit dd8086
SCSI-MMC @code{GET_CONFIGURATION} command.
Packit dd8086
Packit dd8086
@item @code{mmc2a.c}
Packit dd8086
Packit dd8086
Prints MMC @command{MODE_SENSE} page 2A parameters.
Packit dd8086
Page 2a are the CD/DVD Capabilities and Mechanical Status.
Packit dd8086
Packit dd8086
@item @code{C++/mmc2.cpp}
Packit dd8086
Packit dd8086
The same program as @code{mmc2.c} written in C++.
Packit dd8086
Packit dd8086
@item @code{paranoia.c}
Packit dd8086
Packit dd8086
A program to show using libcdio's version of the CD-DA paranoia.
Packit dd8086
Packit dd8086
@item @code{paranoia2.c}
Packit dd8086
Packit dd8086
A program to show using libcdio's version of the CD-DA paranoia
Packit dd8086
library. But in this version, we'll open a cdio object before calling
Packit dd8086
paranoia's open. I imagine in many cases such as media players this
Packit dd8086
may be what will be done since, one may want to get CDDB/CD-Text info
Packit dd8086
beforehand.
Packit dd8086
Packit dd8086
@item @code{tracks.c}
Packit dd8086
Packit dd8086
A simple program to list track numbers and logical sector numbers of a
Packit dd8086
Compact Disc using @value{libcdio}.
Packit dd8086
Packit dd8086
@item @code{sample2.c}
Packit dd8086
Packit dd8086
A simple program to show drivers installed and what the default CD-ROM
Packit dd8086
drive is.
Packit dd8086
Packit dd8086
@item @code{sample3.c}
Packit dd8086
Packit dd8086
A simple program to show the use of @code{cdio_guess_cd_type()}.  Figures out
Packit dd8086
the kind of CD image we've got.
Packit dd8086
Packit dd8086
@item @code{sample4.c}
Packit dd8086
Packit dd8086
 A slightly improved sample3 program: we handle cdio logging and take
Packit dd8086
an optional CD-location.
Packit dd8086
Packit dd8086
@item @code{udf1.c}
Packit dd8086
Packit dd8086
A program to show using libudf to list files in a directory of an UDF
Packit dd8086
image.
Packit dd8086
Packit dd8086
@item @code{udf2.c}
Packit dd8086
Packit dd8086
A program to show using libudf to extract a file from an UDF image.
Packit dd8086
Packit dd8086
@end table
Packit dd8086
Packit dd8086
@node Utility Programs
Packit dd8086
@chapter Diagnostic programs: @command{cd-drive}, @command{cd-info}, @command{cd-read}, @command{iso-info}, @command{iso-read}
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* cd-drive::       list out CD-ROM drive information
Packit dd8086
* cd-info::        list out CD or CD-image information
Packit dd8086
* cd-read::        read blocks of a CD or CD image
Packit dd8086
* iso-info::       list out ISO-9600 image information
Packit dd8086
* iso-read::       extract a file from an ISO 9660 image
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node cd-drive
Packit dd8086
@section @samp{cd-drive}
Packit dd8086
Packit dd8086
@samp{cd-drive} lists out drive information, what features drive
Packit dd8086
supports, and information about what hardware drivers are available.
Packit dd8086
Packit dd8086
@node cd-info
Packit dd8086
@section @samp{cd-info}
Packit dd8086
Packit dd8086
@samp{cd-info} will print out the structure of a CD medium which could
Packit dd8086
either be a Compact Disc in a CD ROM or an CD image. It can try to
Packit dd8086
analyze the medium to give characteristics of the medium, such as how
Packit dd8086
many tracks are in the CD and the format of each track, whether a CD
Packit dd8086
contains a Video CD, CD-DA, PhotoCD, whether a track has an ISO-9660
Packit dd8086
filesystem.
Packit dd8086
Packit dd8086
@node cd-read
Packit dd8086
@section @samp{cd-read}
Packit dd8086
Packit dd8086
@samp{cd-info} can be used to read blocks a CD medium which could
Packit dd8086
either be a Compact Disc in a CD ROM or an CD image. You specify the
Packit dd8086
beginning and ending LSN and what mode format to use in the reading.
Packit dd8086
Packit dd8086
@node iso-info
Packit dd8086
@section @samp{iso-info}
Packit dd8086
Packit dd8086
@samp{iso-info} can be used to print out the structure of an ISO 9660
Packit dd8086
image.
Packit dd8086
Packit dd8086
@node iso-read
Packit dd8086
@section @samp{iso-read}
Packit dd8086
Packit dd8086
@samp{iso-read} can be used to extract a file in an ISO-9660 image.
Packit dd8086
Packit dd8086
@node CD-ROM Access and Drivers
Packit dd8086
@chapter CD-ROM Access and Drivers
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* SCSI mess::  SCSI, SCSI commands, and MMC commands
Packit dd8086
* Access Modes::  Access Modes
Packit dd8086
* Accessing Driver Parameters:: Accessing Driver Parameters
Packit dd8086
Packit dd8086
* GNU/Linux:: GNU/Linux ioctl
Packit dd8086
* Microsoft:: Microsoft Windows ioctl and ASPI
Packit dd8086
* Solaris:: Solaris ATAPI and SCSI
Packit dd8086
* FreeBSD:: FreeBSD ioctl and CAM
Packit dd8086
* OS X::  OSX (non-exclussive access)
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node SCSI mess
Packit dd8086
@section SCSI, SCSI commands, and MMC commands
Packit dd8086
Packit dd8086
Historically, SCSI referred to a class of hardware devices and device
Packit dd8086
controllers, bus technology and the data cables and protocols which
Packit dd8086
attached to such devices. This is now called ``Parallel SCSI''.
Packit dd8086
Packit dd8086
A specification standard grew out of the @emph{commands} that
Packit dd8086
controlled such SCSI devices, but now covers a wider variety of bus
Packit dd8086
technologies including Parallel SCSI, ATA/ATAPI, Serial ATA, Universal
Packit dd8086
Serial Bus (USB versions 1.1 and 2.0), and High Performance Serial Bus
Packit dd8086
(IEEE 1394, 1394A, and 1394B).
Packit dd8086
Packit dd8086
Another similar class of hardware devices and controllers is called ATA
Packit dd8086
and a command interface to that is called ATAPI (ATA Packetized
Packit dd8086
Interface). ATAPI provides a mechanism for transferring and executing
Packit dd8086
SCSI commands.
Packit dd8086
Packit dd8086
MMC (Multimedia commands) is a specification which adds special SCSI
Packit dd8086
commands for CD, DVD, Blu-Ray devices.
Packit dd8086
Packit dd8086
If your optical drive understands MMC commands as most do nowadays,
Packit dd8086
this probably gives the most flexibility in control. SCSI and ATAPI
Packit dd8086
CD-ROM devices generally support a fairly large set of MMC
Packit dd8086
commands. Unfortunately, on most Operating Systems one may need to do
Packit dd8086
some additional setup, such as install drivers or modules, to allow
Packit dd8086
access in this manner.
Packit dd8086
Packit dd8086
The name ``SCSI MMC'' is often found in the literature in
Packit dd8086
specifications and on the Internet. The ``SCSI'' part is probably a
Packit dd8086
little bit misleading because a drive can understand ``SCSI MMC''
Packit dd8086
commands but not use a SCSI bus protocol---ATAPI CD-ROMs are one such
Packit dd8086
broad class of examples. In fact there are drivers to ``encapsulate''
Packit dd8086
non-SCSI drives to make them act like more like SCSI drives, such as
Packit dd8086
by adding SCSI address naming.
Packit dd8086
Packit dd8086
For clarity and precision we will use the term ``MMC'' rather than
Packit dd8086
``SCSI MMC''.
Packit dd8086
Packit dd8086
One of the problems with MMC is that there are so many different
Packit dd8086
``standards''. In particular:
Packit dd8086
@itemize
Packit dd8086
@item MMC --- @url{ftp://ftp.t10.org/t10/drafts/mmc/},
Packit dd8086
@item MMC 2 --- @url{ftp://ftp.t10.org/t10/drafts/mmc2/}
Packit dd8086
@item MMC 3 --- @url{ftp://ftp.t10.org/t10/drafts/mmc3/}
Packit dd8086
@item MMC 4 --- @url{ftp://ftp.t10.org/t10/drafts/mmc4/}
Packit dd8086
@item MMC 5 --- @url{ftp://ftp.t10.org/t10/drafts/mmc5/}
Packit dd8086
@end itemize
Packit dd8086
along with the several ``drafts'' of these.
Packit dd8086
Packit dd8086
Another problem with the MMC commands related to the variations in
Packit dd8086
standards is the variation in the commands themselves and there are
Packit dd8086
perhaps two or three ways to do many of the basic commands like read a
Packit dd8086
CD frame.
Packit dd8086
Packit dd8086
There seems to be a fascination with the number of bytes a command
Packit dd8086
takes in the MMC-specification world. (Size matters?) So often the
Packit dd8086
name of an operation will have a suffix with the number of bytes of
Packit dd8086
the command (actually in MMC jargon this is called a ``CDB''
Packit dd8086
@cindex CDB (Command Descriptor Block)
Packit dd8086
or command descriptor block). So for example there is a 6-byte ``MODE
Packit dd8086
SELECT'' often called ``MODE SELECT 6'' and a 10-byte ``MODE SELECT''
Packit dd8086
often called ``MODE SELECT 10''. Presumably the 6-byte command came
Packit dd8086
first and it was discovered that there was some deficiency causing the
Packit dd8086
longer command. In @value{libcdio} where there are two formats we add
Packit dd8086
the suffix in the name, e.g. @code{CDIO_MMC_GPCMD_MODE_SELECT_6} or
Packit dd8086
@code{CDIO_MMC_GPCMD_MODE_SELECT_10}.
Packit dd8086
Packit dd8086
If the fascination and emphasis in the MMC specifications of CDB size
Packit dd8086
is a bit odd, equally so is the fact that this too often has bled
Packit dd8086
through at the OS programming API. However in @value{libcdio}, you
Packit dd8086
just give the opcode in @code{scsi_mmc_run_cmd()} and we'll do the
Packit dd8086
work to figure out how many bytes of the CDB are used.
Packit dd8086
Packit dd8086
Down the line it is hoped that @value{libcdio} will have a way to
Packit dd8086
remove a distinction between the various alternative and
Packit dd8086
alternative-size MMC commands. In @code{cdio/scsi-mmc.h} you will
Packit dd8086
find a little bit of this for example via the routine
Packit dd8086
@code{scsi_mmc_get_drive_cap()}. However much more work is needed.
Packit dd8086
Packit dd8086
Finally, in @code{libcdio} there is a driver access mode (not a
Packit dd8086
driver) called ``MMC''. It tells the specific drivers to use MMC
Packit dd8086
commands instead of other OS-specific mechanisms.
Packit dd8086
Packit dd8086
@node Access Modes
Packit dd8086
@section Access Modes
Packit dd8086
Packit dd8086
There are serveral ways that you can open a CD-ROM drive for
Packit dd8086
subsequent use.  Each way is called an @emph{access
Packit dd8086
mode}. Historically libcdio only supported a reading kind of
Packit dd8086
access.
Packit dd8086
Packit dd8086
Adding the abilty to writing to a drive for ``burning'' is being added
Packit dd8086
by Thomas Schmitt, and this is accomplished by opening the drive in a
Packit dd8086
read-write mode. Currently writing modes are only supported via the
Packit dd8086
MMC command interface. Under this, one can get exclusive read-write
Packit dd8086
access or non-exclusive read-write access. The names of these two
Packit dd8086
modes are @code{MMC_RDWR_EXCL} and @code{MMC_RDWR} respectively.
Packit dd8086
Packit dd8086
On various OS's often there are two kinds of read modes that are
Packit dd8086
supported, one which uses MMC commands and one which uses some sort of
Packit dd8086
OS-specific native command interface. For example on Unix, there is
Packit dd8086
often a access mode associated with issuing an device-specific
Packit dd8086
@code{ioctl}'s that the OS supports.
Packit dd8086
Packit dd8086
To specify a particular kind of access mode, use @code{cdio_open_am}
Packit dd8086
which is like @code{cdio_open} but it requires one to specify an
Packit dd8086
access mode.
Packit dd8086
Packit dd8086
@node Accessing Driver Parameters
Packit dd8086
@section Accessing Driver Parameters --- @code{cdio_get_arg}
Packit dd8086
Packit dd8086
Once a driver is opened, you can use call @code{cdio_get_arg} to get
Packit dd8086
information about the driver. Each driver can have specific features
Packit dd8086
that can be queried, but there are features that are common to all
Packit dd8086
drivers. These are listed below:
Packit dd8086
Packit dd8086
@table @code
Packit dd8086
Packit dd8086
@item @code{access-mode}
Packit dd8086
This returns a string which is the name of the access mode in use.
Packit dd8086
@item @code{mmc-supported?}
Packit dd8086
This returns a string ``true'' or ``false'' depending whether the
Packit dd8086
driver with this access mode support MMC commands.
Packit dd8086
@item @code{scsi-tuple}
Packit dd8086
On drivers that support MMC commands, this returns the SCSI name or a
Packit dd8086
faked-up SCSI name that ripping front ends typically use.
Packit dd8086
@end table
Packit dd8086
Packit dd8086
@node GNU/Linux
Packit dd8086
@section GNU/Linux
Packit dd8086
Packit dd8086
The GNU/Linux uses a hybrid of methods. Somethings are done via ioctl
Packit dd8086
and some things via MMC. GNU/Linux has a rather nice and complete
Packit dd8086
ioctl mechanism. On the other hand, the MMC mechanism is more
Packit dd8086
universal.  There are other ``access modes'' listed which are not
Packit dd8086
really access modes and should probably be redone/rethought.  They are
Packit dd8086
just different ways to run the read command. But for completeness
Packit dd8086
These are ``READ_CD'' and ``READ_10''.
Packit dd8086
Packit dd8086
Writing/burning to a drive is supported via access modes
Packit dd8086
@code{MMC_RDWR_EXCL} or @code{MMC_RDWR}.
Packit dd8086
Packit dd8086
@node Microsoft
Packit dd8086
@section Microsoft Windows ioctl and ASPI
Packit dd8086
Packit dd8086
There are two CD drive access methods on Microsoft Windows platforms:
Packit dd8086
ioctl and ASPI.
Packit dd8086
Packit dd8086
The ASPI interface specification was developed by Adaptec for sending
Packit dd8086
commands to a SCSI host adapter (such as those controlling CD and DVD
Packit dd8086
drives) and used on Window 9x/NT and later. Emulation for ATAPI drives
Packit dd8086
was added so that the same sets of commands worked those even though
Packit dd8086
the drives might not be SCSI nor might there even be a SCSI controller
Packit dd8086
attached. The DLL is not part of Microsoft Windows and has to be
Packit dd8086
downloaded and installed separately.
Packit dd8086
Packit dd8086
However in Windows NT/2K/XP, Microsoft provides their Win32 ioctl
Packit dd8086
interface, and has taken steps to make using ASPI more inaccessible
Packit dd8086
(e.g. requiring administrative access to use ASPI).
Packit dd8086
Packit dd8086
Packit dd8086
@node Solaris
Packit dd8086
@section Solaris ATAPI and SCSI
Packit dd8086
Packit dd8086
There is currently only one CD drive access methods in Solaris: SCSI
Packit dd8086
(called ``USCSI'' or ``user SCSI'' in Solaris). There used to be an
Packit dd8086
ATAPI method and it could be resurrected if needed. USCSI was
Packit dd8086
preferred since on newer releases of Solaris and Solaris environments
Packit dd8086
one need to have root access for ATAPI.
Packit dd8086
Packit dd8086
@node FreeBSD
Packit dd8086
@section FreeBSD ioctl and CAM
Packit dd8086
Packit dd8086
There are two classes of access methods on FreeBSD: ioctl and CAM
Packit dd8086
(common access method). CAM is preferred when possible, especially on
Packit dd8086
newer releases. However CAM is right now sort of a hybrid and includes
Packit dd8086
some ioctl code.
Packit dd8086
Packit dd8086
Writing/burning to a drive is supported via access modes
Packit dd8086
@code{MMC_RDWR_EXCL} or @code{MMC_RDWR} which underneath use CAM access.
Packit dd8086
Packit dd8086
@node OS X
Packit dd8086
@section OS X (non-exclusive access)
Packit dd8086
Packit dd8086
A problem with libcdio on OS/X is that if the OS thinks it understands
Packit dd8086
the drive, it will get exclusive access to the drive and thus prevents
Packit dd8086
a library like this from obtaining non-exclusive access.
Packit dd8086
Packit dd8086
Currently @value{libcdio} access the CD-ROM non-exclusively. However
Packit dd8086
in order to be able to issue MMC, the current belief is that
Packit dd8086
exclusive access is needed. Probably in a future @value{libcdio},
Packit dd8086
there will be some way to specify which kind of access is desired
Packit dd8086
(with the inherent consequences of each).
Packit dd8086
Packit dd8086
More work on this driver is needed. Volunteers?
Packit dd8086
Packit dd8086
@node Internal Program Organization
Packit dd8086
@chapter Internal Program Organization
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* File Organization::
Packit dd8086
* Library Organization::
Packit dd8086
* Programming Conventions::
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node File Organization
Packit dd8086
@section File Organization
Packit dd8086
Packit dd8086
Here is a list of @value{libcdio} directories.
Packit dd8086
Packit dd8086
@itemize
Packit dd8086
Packit dd8086
@item @code{include/cdio}
Packit dd8086
Packit dd8086
This contains the headers that are public. One that will probably be
Packit dd8086
used quite a bit is @code{<cdio/cdio.h>}.
Packit dd8086
Packit dd8086
@item @code{lib}
Packit dd8086
Packit dd8086
Code for installed libraries. See below for further breakout
Packit dd8086
Packit dd8086
@item @code{lib/driver}
Packit dd8086
Packit dd8086
Code for various OS-specific CD-ROM drivers, image drivers, and
Packit dd8086
common MMC routines.
Packit dd8086
Packit dd8086
This code comprises @code{libcdio.a} (or the shared version of it).
Packit dd8086
Packit dd8086
@item @code{lib/iso9660}
Packit dd8086
Packit dd8086
Code for to extract or query ISO-9660 images.
Packit dd8086
Packit dd8086
This code comprises @code{libiso9660.a} (or the shared version of it).
Packit dd8086
Packit dd8086
@item @code{lib/paranoia}
Packit dd8086
Packit dd8086
This is from cdparanoia. It is the OS- and hardware- dependent code to
Packit dd8086
detect and correct jitter for CD-DA CDs.
Packit dd8086
Packit dd8086
@item @code{lib/cdda_interface}
Packit dd8086
Packit dd8086
This is also from cdparanoia. It is the OS- and hardware- independent
Packit dd8086
code to detect and correct jitter for CD-DA CDs.
Packit dd8086
Packit dd8086
@item @code{doc}
Packit dd8086
Packit dd8086
A home for fine documentation such as this masterpiece.
Packit dd8086
Packit dd8086
@item @code{example}
Packit dd8086
Packit dd8086
Here you will find various small example programs using
Packit dd8086
@value{libcdio} which are largely for pedagogical purposes. You might
Packit dd8086
be able to find one that is similar to what you want to do that could
Packit dd8086
be extended. In fact some these are contain the kernel ideas behind of
Packit dd8086
some of the larger programs in @file{src}.
Packit dd8086
Packit dd8086
@item @code{src}
Packit dd8086
Packit dd8086
Various stand-alone utility programs. See below.
Packit dd8086
Packit dd8086
@item @code{src/paranoia}
Packit dd8086
Packit dd8086
@value{libcdio}'s version of @code{cdparanoia}. Except for the fact
Packit dd8086
that the back-end CD-reading code has been replaced by
Packit dd8086
@value{libcdio}'s routines the code is pretty much identical.
Packit dd8086
Packit dd8086
@item @code{test}
Packit dd8086
Packit dd8086
Regression tests
Packit dd8086
Packit dd8086
@item @code{test/data}
Packit dd8086
Packit dd8086
Disk images and image meta-data used in tests
Packit dd8086
Packit dd8086
Packit dd8086
@item @code{test/driver}
Packit dd8086
Packit dd8086
Unit tests centered around the libcdio library (@code{libcdio}, source
Packit dd8086
location @code{lib/driver}
Packit dd8086
Packit dd8086
@end itemize
Packit dd8086
Packit dd8086
@node Library Organization
Packit dd8086
@section Library Organization
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* libcdio::
Packit dd8086
* libcdio_cdda:: Access to CD-DA via the CD Paranoia library
Packit dd8086
* libcdio_paranoia:: Access to the CD Paranoia library
Packit dd8086
* libiso9660::  Access to ISO 9660 file systems and structures
Packit dd8086
* libudf:: Access to UDF file systems and structures
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node libcdio
Packit dd8086
@subsection @samp{libcdio}
Packit dd8086
Packit dd8086
@value{libcdio} exports one opaque type @code{CdIo_t}. Internally this
Packit dd8086
a structure containing an enumeration for the driver, a structure
Packit dd8086
containing function pointers and a generic ``environment'' pointer
Packit dd8086
which is passed as a parameter on a function call. See
Packit dd8086
@file{lib/driver/cdio_private.h}. The initialization routine for each
Packit dd8086
driver sets up the function pointers and allocates memory for the
Packit dd8086
environment. When a particular user-level cdio routine is called (e.g
Packit dd8086
@code{cdio_get_first_track_num} for lib/driver/track.c), the
Packit dd8086
environment pointer is passed to a device-specific routine which will
Packit dd8086
then cast this pointer into something of the appropriate type.
Packit dd8086
Packit dd8086
Because function pointers are used, there can be and is quite a bit
Packit dd8086
of sharing of common routines. Some of the common routines are found
Packit dd8086
in the file @file{lib/driver/_cdio_generic.c}.
Packit dd8086
Packit dd8086
Another set of routines that one is likely to find shared amongst
Packit dd8086
drivers are the MMC commands. These are located in
Packit dd8086
@file{lib/driver/scsi_mmc.c}.
Packit dd8086
Packit dd8086
There is not only an attempt to share functions but we've tried to create
Packit dd8086
a generic CD structure @code{generic_img_private_t} of file
Packit dd8086
@file{lib/driver/generic.h}. By putting information into a common
Packit dd8086
structure, we increase the likelihood of being able to have a common
Packit dd8086
routine to perform some sort of function.
Packit dd8086
Packit dd8086
The generic CD structure would also be useful in a utility to convert
Packit dd8086
one CD-image format to another. Basically the first image format is
Packit dd8086
``parsed'' into the common internal format and then from this
Packit dd8086
structure it is not parsed.
Packit dd8086
Packit dd8086
@node libcdio_cdda
Packit dd8086
@subsection @samp{libcdio_cdda}
Packit dd8086
Packit dd8086
This library is intended to give access CD-DA disks using Monty's
Packit dd8086
cd-paranoia library underneath.
Packit dd8086
Packit dd8086
To be completed....
Packit dd8086
Packit dd8086
@node libcdio_paranoia
Packit dd8086
@subsection @samp{libcdio_paranoia}
Packit dd8086
Packit dd8086
This library is intended to give access Monty's cd-paranoia
Packit dd8086
library. It is the gap detection and jitter correction part without
Packit dd8086
the part dealing with CD-DA reading.
Packit dd8086
Packit dd8086
To be completed....
Packit dd8086
Packit dd8086
@node libiso9660
Packit dd8086
@subsection @samp{libiso9660}
Packit dd8086
Packit dd8086
This library is intended to give access and manipulate a ISO-9600 file
Packit dd8086
image. One part of it is concerned with the the entire ISO-9660 file
Packit dd8086
system image, and the other part access routines for manipulating data
Packit dd8086
structures and fields that go into such an image.
Packit dd8086
Packit dd8086
Packit dd8086
To be completed....
Packit dd8086
Packit dd8086
@node libudf
Packit dd8086
@subsection @samp{libudf}
Packit dd8086
Packit dd8086
This library is intended to give access and manipulate a UDF file
Packit dd8086
image.
Packit dd8086
Packit dd8086
To be completed....
Packit dd8086
Packit dd8086
@node Programming Conventions
Packit dd8086
@section Programming Conventions
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* Coding Conventions::
Packit dd8086
* Namespace Conventions::
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node Coding Conventions
Packit dd8086
@subsection Coding Conventions
Packit dd8086
Packit dd8086
In @value{libcdio} there are a number of conventions used. If you
Packit dd8086
understand some of these conventions it may facilitate understanding
Packit dd8086
the code a little.
Packit dd8086
Packit dd8086
@node Namespace Conventions
Packit dd8086
@subsection Namespace Conventions
Packit dd8086
Packit dd8086
For the most part, the visible external @value{libcdio} names follow
Packit dd8086
conventions so as not to be confused with other applications or
Packit dd8086
libraries. If you understand these conventions, there will be little
Packit dd8086
or no chance that the names you use will conflict with @value{libcdio}
Packit dd8086
and @code{libiso9660} and vice versa.
Packit dd8086
Packit dd8086
All of the external @value{libcdio} C routines start out with
Packit dd8086
@code{cdio_}, e.g. @code{cdio_open}; as a corollary, the
Packit dd8086
@value{libcdio} CD-Paranoia routines start @code{cdio_cddap_},
Packit dd8086
e.g. @code{cdio_cddap_open}.  @code{libiso9660} routines start
Packit dd8086
@code{iso9660_}, e.g. @code{iso9660_open}.
Packit dd8086
Packit dd8086
@value{libcdio} C-Preprocessor names generally start @code{CDIO_}, for
Packit dd8086
example @code{CDIO_CD_FRAMESIZE_RAW}; @code{libiso9660}
Packit dd8086
C-preprocessor names start @code{ISO9660_},
Packit dd8086
e.g. @code{ISO9660_FRAMESIZE}.
Packit dd8086
Packit dd8086
@subsubsection suffixes (type and structure names)
Packit dd8086
Packit dd8086
A few suffixes are used in type and structure names:
Packit dd8086
Packit dd8086
@itemize
Packit dd8086
Packit dd8086
@item @code{_e}
Packit dd8086
Packit dd8086
An enumeration tag. Generally though the same name will appear with the
Packit dd8086
@code{_t} suffix and probably that should be used instead.
Packit dd8086
Packit dd8086
@item @code{_s}
Packit dd8086
Packit dd8086
A structure tag. Generally though the same name will appear with the
Packit dd8086
@code{_t} suffix and probably that should be used instead.
Packit dd8086
Packit dd8086
@item @code{_t}
Packit dd8086
Packit dd8086
A type suffix.
Packit dd8086
Packit dd8086
@end itemize
Packit dd8086
Packit dd8086
@subsubsection prefixes (variable names)
Packit dd8086
Packit dd8086
A number of prefixes are used in variable names here's what they mean
Packit dd8086
Packit dd8086
@itemize
Packit dd8086
@item @code{i_}
Packit dd8086
Packit dd8086
An integer type of some sort. A variable of this ilk one might find
Packit dd8086
being iterated over in @code{for} loops or used as the index of an
Packit dd8086
array for example.
Packit dd8086
Packit dd8086
@item @code{b_}
Packit dd8086
Packit dd8086
A Boolean type of some sort. A variable of this ilk one might find
Packit dd8086
being in an @code{if} condition for example.
Packit dd8086
Packit dd8086
@item @code{p_}
Packit dd8086
Packit dd8086
A pointer of some sort. A variable of this ilk, say
Packit dd8086
@code{p_foo} one is like likely to see @code{*p_foo} or
Packit dd8086
@code{p_foo->...}.
Packit dd8086
Packit dd8086
@item @code{pp_}
Packit dd8086
Packit dd8086
A pointer to a pointer of some sort. A variable of this ilk, say
Packit dd8086
@code{pp_foo} one is like likely to see @code{**p_foo} or
Packit dd8086
@code{p_foo[x][y]} for example
Packit dd8086
Packit dd8086
@item @code{psz_}
Packit dd8086
Packit dd8086
A @code{char *} pointer of some sort. A variable of this ilk, say
Packit dd8086
@code{psz_foo} may be used in a string operation. For example
Packit dd8086
@code{printf(%s\n", psz_foo)} or @code{strdup(psz_foo)}.
Packit dd8086
Packit dd8086
@item @code{ppsz_}
Packit dd8086
Packit dd8086
A pointer to a @code{char *} pointer of some sort. A variable of this
Packit dd8086
ilk, say @code{ppsz_foo} is used for example to return a list of
Packit dd8086
CD-ROM device names
Packit dd8086
Packit dd8086
@end itemize
Packit dd8086
Packit dd8086
There are a some other naming conventions. Generally if a routine
Packit dd8086
name starts @code{cdio_}, e.g. @code{cdio_open}, then it is an
Packit dd8086
externally visible routine in @code{libcdio}. If a name starts
Packit dd8086
@code{iso9660_}, e.g. @code{iso9660_is_dchar} then it is an externally
Packit dd8086
visible routine in @code{libiso9660}. If a name starts
Packit dd8086
@code{scsi_mmc_}, e.g. @code{scsi_mmc_get_discmode}, then it is an
Packit dd8086
externally visible MMC routine. (We don't have a separate library for
Packit dd8086
this yet.
Packit dd8086
Packit dd8086
Names using entirely capital letters and that start @code{CDIO_} are
Packit dd8086
externally visible @code{#defines}.
Packit dd8086
Packit dd8086
Packit dd8086
@node ISO-9660 Character Sets
Packit dd8086
@appendix ISO-9660 Character Sets
Packit dd8086
Packit dd8086
For a description of where are used see @xref{ISO 9660 Level 1}.
Packit dd8086
Packit dd8086
@menu
Packit dd8086
* ISO646 d-Characters::
Packit dd8086
* ISO646 a-Characters::
Packit dd8086
@end menu
Packit dd8086
Packit dd8086
@node ISO646 d-Characters
Packit dd8086
@appendixsec ISO646 d-Characters
Packit dd8086
Packit dd8086
@example
Packit dd8086
  | 0 1 2 3 4 5 6 7
Packit dd8086
--+-----------------
Packit dd8086
0 |       0   P
Packit dd8086
1 |       1 A Q
Packit dd8086
2 |       2 B R
Packit dd8086
3 |       3 C S
Packit dd8086
4 |       4 D T
Packit dd8086
5 |       5 E U
Packit dd8086
6 |       6 F V
Packit dd8086
7 |       7 G W
Packit dd8086
8 |       8 H X
Packit dd8086
9 |       9 I Y
Packit dd8086
a |         J Z
Packit dd8086
b |         K
Packit dd8086
c |         L
Packit dd8086
d |         M
Packit dd8086
e |         N
Packit dd8086
f |         O _
Packit dd8086
@end example
Packit dd8086
Packit dd8086
@node ISO646 a-Characters
Packit dd8086
@appendixsec ISO646 a-Characters
Packit dd8086
Packit dd8086
@example
Packit dd8086
  | 0 1 2 3 4 5 6 7
Packit dd8086
--+-----------------
Packit dd8086
0 |       0   P
Packit dd8086
1 |     ! 1 A Q
Packit dd8086
2 |     " 2 B R
Packit dd8086
3 |       3 C S
Packit dd8086
4 |       4 D T
Packit dd8086
5 |     % 5 E U
Packit dd8086
6 |     & 6 F V
Packit dd8086
7 |     ' 7 G W
Packit dd8086
8 |     ( 8 H X
Packit dd8086
9 |     ) 9 I Y
Packit dd8086
a |     * : J Z
Packit dd8086
b |     + ; K
Packit dd8086
c |     , < L
Packit dd8086
d |     - = M
Packit dd8086
e |     . > N
Packit dd8086
f |     / ? O _
Packit dd8086
@end example
Packit dd8086
Packit dd8086
@node Glossary
Packit dd8086
@appendix Glossary
Packit dd8086
Packit dd8086
@include glossary.texi
Packit dd8086
Packit dd8086
@node GNU Free Documentation License
Packit dd8086
@appendix GNU Free Documentation License
Packit dd8086
@cindex FDL, GNU Free Documentation License
Packit dd8086
Packit dd8086
@include fdl.texi
Packit dd8086
Packit dd8086
@node General Index
Packit dd8086
@unnumbered General Index
Packit dd8086
@printindex cp
Packit dd8086
Packit dd8086
@bye