ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Convert-CD/lib/Convert/CD.pm
Revision: 1.6
Committed: Tue Jun 10 15:02:10 2003 UTC (23 years, 3 months ago) by root
Branch: MAIN
Changes since 1.5: +16 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.2 Convert::CD - import/export/represent various cd image file formats
4 root 1.1
5     =head1 SYNOPSIS
6    
7     use Convert::CD;
8    
9     # to be done
10    
11     =head1 DESCRIPTION
12    
13     Kidding?
14    
15 root 1.3 =head2 Convert:CD METHODS
16    
17 root 1.4 This class represents a full CD image, which can consist of one or more
18     files. While track layout and TOC data is stored in this class, to
19     read/write TOC files you need a Convert::CD::TOCFile.
20 root 1.1
21     =over 4
22    
23     =cut
24    
25     package Convert::CD;
26    
27     $VERSION = 0.01;
28    
29 root 1.4 use base Exporter;
30    
31 root 1.1 =item new param => value...
32    
33     Create a new Convert::CD object.
34    
35 root 1.3 my $cd = new path => "/tmp/mycd.bin";
36 root 1.1
37     =cut
38    
39     sub new {
40     my $class = shift;
41 root 1.4 my $self = bless {
42     track => [], # an array of tracks, track #1 is in index 0
43 root 1.2 @_,
44     }, $class;
45 root 1.4
46     $self;
47     }
48    
49     =item $cd->append_track(param => value...)
50    
51     Appends a new track to the image. Same parameters as Convert::CD::Track->new.
52    
53     =cut
54    
55     sub append_track {
56     my ($self, %arg) = @_;
57    
58     push @{$self->{track}}, Convert::CD::Track->new (%arg);
59 root 1.3 }
60    
61 root 1.4 =item $cd->as_string
62    
63     Returns a multi-line, textual description of the CD Image.
64    
65     =cut
66    
67     sub as_string {
68     my ($self) = @_;
69     my $r;
70    
71     $r .= "Image Path: $self->{path}\n";
72    
73     for my $idx (1 .. @{$self->{track}}) {
74     $r .= sprintf "Track %02d: %s\n", $idx, $self->{track}[$idx - 1]->as_string;
75     }
76    
77     $r;
78     }
79    
80 root 1.5 =item $cd->track ([$idx])
81    
82     Returns the track with the given index, or, if no index is given, all the
83     tracks of the CD (or the number of tracks in scalar context). The first
84     track is track #1.
85    
86     =cut
87    
88     sub track {
89     my ($self, $idx) = @_;
90    
91     @_ > 1 ? $self->{track}[$idx - 1] : @{$self->{track}};
92     }
93    
94 root 1.4 package Convert::CD::Track;
95    
96 root 1.5 use POSIX qw(ceil);
97     use Carp;
98    
99 root 1.3 =back
100    
101     =head2 Convert::CD::Track METHODS
102    
103     This class is used to repesent single track objects.
104    
105     =over 4
106    
107     =item new param => value...
108    
109     Create a new track object.
110    
111     Parameters:
112    
113 root 1.4 path the file that contains the track
114     offset the offste within the file that contains the first sector
115     (may be negative)
116 root 1.5 rawsize the raw size (in bytes) of the track. (guessed if missing)
117 root 1.4 mode a mode string (MODE1, MODE2, AUDIO, CDI, CDG....)
118     datasize size of the data part of the sector (e.g. 2048). (def. secsize)
119     secsize size of a sector in disk image
120     index an array of index times (0 is pregap start, 1 is track start)
121 root 1.3
122     =cut
123    
124     sub new {
125     my $class = shift;
126 root 1.4 my $self = bless {
127 root 1.3 @_,
128     }, $class;
129 root 1.4
130 root 1.5 $self->{rawsize} ||= (-s $self->{path}) - $self->{offset};
131 root 1.4 $self->{datasize} ||= $self->{secsize};
132    
133     $self;
134     }
135    
136 root 1.5 # create and cache a filehandle of the given mode
137     sub fh {
138     my ($self, $mode) = @_;
139    
140     $self->{fh}{$mode} ||= do {
141     open my $fh, $mode, $self->{path}
142     or croak "$self->{path}: $!";
143     binmode $fh; # *seufz*
144     $fh;
145     };
146     }
147    
148     =item $track->read ($offset, $length)
149    
150     Reads and returns a part of the track. C<$offset> should be a multiple of
151     the datasize.
152    
153     =cut
154    
155     sub read {
156     my ($self, $offset, $length) = @_;
157     my $buf;
158    
159     my $fh = $self->fh ("<");
160    
161     $offset = $offset / $self->{secsize} * $self->{secsize};
162    
163     while ($length > 0) {
164     sysseek $fh, $self->{offset} + $offset, 0
165     or croak "seek($self->{path}): $!";
166     sysread $fh, $buf, ($length < $self->{datasize} ? $length : $self->{datasize}), length $buf
167     or croak "read($self->{path}): $!";
168    
169     $length -= $self->{datasize};
170     $offset += $self->{secsize};
171     }
172    
173     $buf;
174     }
175    
176     =item $track->size
177    
178     Returns the (cooked) size of the track in bytes, i.e. logical size of the
179     track without any ECC etc. information.
180    
181     =cut
182    
183     sub size {
184     my ($self) = @_;
185    
186     ceil ($self->{rawsize} / $self->{secsize}) * $self->{datasize};
187     }
188    
189     =item $track->as_string
190 root 1.4
191     Returns a single-line, textual description of the track.
192    
193     =cut
194    
195     sub as_string {
196     my ($self) = @_;
197 root 1.5 my %data = %$self;
198    
199     $data{index} = "<" . (join "|", @{$data{index}}) .">";
200 root 1.4
201 root 1.5 sprintf "%s %08x+%08x %s/%d (%s)",
202     delete @data{qw(path offset rawsize mode secsize)},
203     join " ", %data;
204 root 1.1 }
205    
206 root 1.6 =item $track->to_msf ($offset)
207    
208     Converts the given byte offste into M:S:F format.
209    
210     =cut
211    
212     sub to_msf {
213     my ($self, $offset) = @_;
214    
215     my $frame = $offset / $self->{datasize};
216    
217     sprintf "%02d:%02d:%02d", $frame / (60 * 75),
218     $frame / 75 % 60,
219     $frame % 75;
220     }
221    
222 root 1.1 1;
223    
224     =back
225    
226     =head1 AUTHOR
227    
228     Marc Lehmann <pcg@goof.com>
229    
230     =cut
231