summaryrefslogtreecommitdiff
path: root/songdbj/javazoom/jl/converter/RiffFile.java
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/javazoom/jl/converter/RiffFile.java')
-rw-r--r--songdbj/javazoom/jl/converter/RiffFile.java495
1 files changed, 495 insertions, 0 deletions
diff --git a/songdbj/javazoom/jl/converter/RiffFile.java b/songdbj/javazoom/jl/converter/RiffFile.java
new file mode 100644
index 0000000000..fb5d9e53c6
--- /dev/null
+++ b/songdbj/javazoom/jl/converter/RiffFile.java
@@ -0,0 +1,495 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 02/23/99 JavaConversion by E.B
4 * Don Cross, April 1993.
5 * RIFF file format classes.
6 * See Chapter 8 of "Multimedia Programmer's Reference" in
7 * the Microsoft Windows SDK.
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.jl.converter;
27
28import java.io.IOException;
29import java.io.RandomAccessFile;
30
31
32/**
33 * Class to manage RIFF files
34 */
35public class RiffFile
36{
37 class RiffChunkHeader
38 {
39 public int ckID = 0; // Four-character chunk ID
40 public int ckSize = 0; // Length of data in chunk
41 public RiffChunkHeader()
42 {}
43 }
44
45
46 // DDCRET
47 public static final int DDC_SUCCESS = 0; // The operation succeded
48 public static final int DDC_FAILURE = 1; // The operation failed for unspecified reasons
49 public static final int DDC_OUT_OF_MEMORY = 2; // Operation failed due to running out of memory
50 public static final int DDC_FILE_ERROR = 3; // Operation encountered file I/O error
51 public static final int DDC_INVALID_CALL = 4; // Operation was called with invalid parameters
52 public static final int DDC_USER_ABORT = 5; // Operation was aborted by the user
53 public static final int DDC_INVALID_FILE = 6; // File format does not match
54
55 // RiffFileMode
56 public static final int RFM_UNKNOWN = 0; // undefined type (can use to mean "N/A" or "not open")
57 public static final int RFM_WRITE = 1; // open for write
58 public static final int RFM_READ = 2; // open for read
59
60 private RiffChunkHeader riff_header; // header for whole file
61 protected int fmode; // current file I/O mode
62 protected RandomAccessFile file; // I/O stream to use
63
64 /**
65 * Dummy Constructor
66 */
67 public RiffFile()
68 {
69 file = null;
70 fmode = RFM_UNKNOWN;
71 riff_header = new RiffChunkHeader();
72
73 riff_header.ckID = FourCC("RIFF");
74 riff_header.ckSize = 0;
75 }
76
77 /**
78 * Return File Mode.
79 */
80 public int CurrentFileMode()
81 {return fmode;}
82
83 /**
84 * Open a RIFF file.
85 */
86 public int Open(String Filename, int NewMode)
87 {
88 int retcode = DDC_SUCCESS;
89
90 if ( fmode != RFM_UNKNOWN )
91 {
92 retcode = Close();
93 }
94
95 if ( retcode == DDC_SUCCESS )
96 {
97 switch ( NewMode )
98 {
99 case RFM_WRITE:
100 try
101 {
102 file = new RandomAccessFile(Filename,"rw");
103
104 try
105 {
106 // Write the RIFF header...
107 // We will have to come back later and patch it!
108 byte[] br = new byte[8];
109 br[0] = (byte) ((riff_header.ckID >>> 24) & 0x000000FF);
110 br[1] = (byte) ((riff_header.ckID >>> 16) & 0x000000FF);
111 br[2] = (byte) ((riff_header.ckID >>> 8) & 0x000000FF);
112 br[3] = (byte) (riff_header.ckID & 0x000000FF);
113
114 byte br4 = (byte) ((riff_header.ckSize >>> 24)& 0x000000FF);
115 byte br5 = (byte) ((riff_header.ckSize >>> 16)& 0x000000FF);
116 byte br6 = (byte) ((riff_header.ckSize >>> 8)& 0x000000FF);
117 byte br7 = (byte) (riff_header.ckSize & 0x000000FF);
118
119 br[4] = br7;
120 br[5] = br6;
121 br[6] = br5;
122 br[7] = br4;
123
124 file.write(br,0,8);
125 fmode = RFM_WRITE;
126 } catch (IOException ioe)
127 {
128 file.close();
129 fmode = RFM_UNKNOWN;
130 }
131 } catch (IOException ioe)
132 {
133 fmode = RFM_UNKNOWN;
134 retcode = DDC_FILE_ERROR;
135 }
136 break;
137
138 case RFM_READ:
139 try
140 {
141 file = new RandomAccessFile(Filename,"r");
142 try
143 {
144 // Try to read the RIFF header...
145 byte[] br = new byte[8];
146 file.read(br,0,8);
147 fmode = RFM_READ;
148 riff_header.ckID = ((br[0]<<24)& 0xFF000000) | ((br[1]<<16)&0x00FF0000) | ((br[2]<<8)&0x0000FF00) | (br[3]&0x000000FF);
149 riff_header.ckSize = ((br[4]<<24)& 0xFF000000) | ((br[5]<<16)&0x00FF0000) | ((br[6]<<8)&0x0000FF00) | (br[7]&0x000000FF);
150 } catch (IOException ioe)
151 {
152 file.close();
153 fmode = RFM_UNKNOWN;
154 }
155 } catch (IOException ioe)
156 {
157 fmode = RFM_UNKNOWN;
158 retcode = DDC_FILE_ERROR;
159 }
160 break;
161 default:
162 retcode = DDC_INVALID_CALL;
163 }
164 }
165 return retcode;
166 }
167
168 /**
169 * Write NumBytes data.
170 */
171 public int Write(byte[] Data, int NumBytes )
172 {
173 if ( fmode != RFM_WRITE )
174 {
175 return DDC_INVALID_CALL;
176 }
177 try
178 {
179 file.write(Data,0,NumBytes);
180 fmode = RFM_WRITE;
181 }
182 catch (IOException ioe)
183 {
184 return DDC_FILE_ERROR;
185 }
186 riff_header.ckSize += NumBytes;
187 return DDC_SUCCESS;
188 }
189
190
191
192 /**
193 * Write NumBytes data.
194 */
195 public int Write(short[] Data, int NumBytes )
196 {
197 byte[] theData = new byte[NumBytes];
198 int yc = 0;
199 for (int y = 0;y<NumBytes;y=y+2)
200 {
201 theData[y] = (byte) (Data[yc] & 0x00FF);
202 theData[y+1] =(byte) ((Data[yc++] >>> 8) & 0x00FF);
203 }
204 if ( fmode != RFM_WRITE )
205 {
206 return DDC_INVALID_CALL;
207 }
208 try
209 {
210 file.write(theData,0,NumBytes);
211 fmode = RFM_WRITE;
212 }
213 catch (IOException ioe)
214 {
215 return DDC_FILE_ERROR;
216 }
217 riff_header.ckSize += NumBytes;
218 return DDC_SUCCESS;
219 }
220
221 /**
222 * Write NumBytes data.
223 */
224 public int Write(RiffChunkHeader Triff_header, int NumBytes )
225 {
226 byte[] br = new byte[8];
227 br[0] = (byte) ((Triff_header.ckID >>> 24) & 0x000000FF);
228 br[1] = (byte) ((Triff_header.ckID >>> 16) & 0x000000FF);
229 br[2] = (byte) ((Triff_header.ckID >>> 8) & 0x000000FF);
230 br[3] = (byte) (Triff_header.ckID & 0x000000FF);
231
232 byte br4 = (byte) ((Triff_header.ckSize >>> 24)& 0x000000FF);
233 byte br5 = (byte) ((Triff_header.ckSize >>> 16)& 0x000000FF);
234 byte br6 = (byte) ((Triff_header.ckSize >>> 8)& 0x000000FF);
235 byte br7 = (byte) (Triff_header.ckSize & 0x000000FF);
236
237 br[4] = br7;
238 br[5] = br6;
239 br[6] = br5;
240 br[7] = br4;
241
242 if ( fmode != RFM_WRITE )
243 {
244 return DDC_INVALID_CALL;
245 }
246 try
247 {
248 file.write(br,0,NumBytes);
249 fmode = RFM_WRITE;
250 } catch (IOException ioe)
251 {
252 return DDC_FILE_ERROR;
253 }
254 riff_header.ckSize += NumBytes;
255 return DDC_SUCCESS;
256 }
257
258 /**
259 * Write NumBytes data.
260 */
261 public int Write(short Data, int NumBytes )
262 {
263 short theData = (short) ( ((Data>>>8)&0x00FF) | ((Data<<8)&0xFF00) );
264 if ( fmode != RFM_WRITE )
265 {
266 return DDC_INVALID_CALL;
267 }
268 try
269 {
270 file.writeShort(theData);
271 fmode = RFM_WRITE;
272 } catch (IOException ioe)
273 {
274 return DDC_FILE_ERROR;
275 }
276 riff_header.ckSize += NumBytes;
277 return DDC_SUCCESS;
278 }
279 /**
280 * Write NumBytes data.
281 */
282 public int Write(int Data, int NumBytes )
283 {
284 short theDataL = (short) ((Data>>>16)&0x0000FFFF);
285 short theDataR = (short) (Data&0x0000FFFF);
286 short theDataLI = (short) ( ((theDataL>>>8)&0x00FF) | ((theDataL<<8)&0xFF00) );
287 short theDataRI = (short) ( ((theDataR>>>8)&0x00FF) | ((theDataR<<8)&0xFF00) );
288 int theData = ((theDataRI<<16)&0xFFFF0000) | (theDataLI&0x0000FFFF);
289 if ( fmode != RFM_WRITE )
290 {
291 return DDC_INVALID_CALL;
292 }
293 try
294 {
295 file.writeInt(theData);
296 fmode = RFM_WRITE;
297 } catch (IOException ioe)
298 {
299 return DDC_FILE_ERROR;
300 }
301 riff_header.ckSize += NumBytes;
302 return DDC_SUCCESS;
303 }
304
305
306
307 /**
308 * Read NumBytes data.
309 */
310 public int Read (byte[] Data, int NumBytes)
311 {
312 int retcode = DDC_SUCCESS;
313 try
314 {
315 file.read(Data,0,NumBytes);
316 } catch (IOException ioe)
317 {
318 retcode = DDC_FILE_ERROR;
319 }
320 return retcode;
321 }
322
323 /**
324 * Expect NumBytes data.
325 */
326 public int Expect(String Data, int NumBytes )
327 {
328 byte target = 0;
329 int cnt = 0;
330 try
331 {
332 while ((NumBytes--) != 0)
333 {
334 target = file.readByte();
335 if (target != Data.charAt(cnt++)) return DDC_FILE_ERROR;
336 }
337 } catch (IOException ioe)
338 {
339 return DDC_FILE_ERROR;
340 }
341 return DDC_SUCCESS;
342 }
343
344 /**
345 * Close Riff File.
346 * Length is written too.
347 */
348 public int Close()
349 {
350 int retcode = DDC_SUCCESS;
351
352 switch ( fmode )
353 {
354 case RFM_WRITE:
355 try
356 {
357 file.seek(0);
358 try
359 {
360 byte[] br = new byte[8];
361 br[0] = (byte) ((riff_header.ckID >>> 24) & 0x000000FF);
362 br[1] = (byte) ((riff_header.ckID >>> 16) & 0x000000FF);
363 br[2] = (byte) ((riff_header.ckID >>> 8) & 0x000000FF);
364 br[3] = (byte) (riff_header.ckID & 0x000000FF);
365
366 br[7] = (byte) ((riff_header.ckSize >>> 24)& 0x000000FF);
367 br[6] = (byte) ((riff_header.ckSize >>> 16)& 0x000000FF);
368 br[5] = (byte) ((riff_header.ckSize >>> 8)& 0x000000FF);
369 br[4] = (byte) (riff_header.ckSize & 0x000000FF);
370 file.write(br,0,8);
371 file.close();
372 } catch (IOException ioe)
373 {
374 retcode = DDC_FILE_ERROR;
375 }
376 } catch (IOException ioe)
377 {
378 retcode = DDC_FILE_ERROR;
379 }
380 break;
381
382 case RFM_READ:
383 try
384 {
385 file.close();
386 } catch (IOException ioe)
387 {
388 retcode = DDC_FILE_ERROR;
389 }
390 break;
391 }
392 file = null;
393 fmode = RFM_UNKNOWN;
394 return retcode;
395 }
396
397 /**
398 * Return File Position.
399 */
400 public long CurrentFilePosition()
401 {
402 long position;
403 try
404 {
405 position = file.getFilePointer();
406 } catch (IOException ioe)
407 {
408 position = -1;
409 }
410 return position;
411 }
412
413 /**
414 * Write Data to specified offset.
415 */
416 public int Backpatch (long FileOffset, RiffChunkHeader Data, int NumBytes )
417 {
418 if (file == null)
419 {
420 return DDC_INVALID_CALL;
421 }
422 try
423 {
424 file.seek(FileOffset);
425 } catch (IOException ioe)
426 {
427 return DDC_FILE_ERROR;
428 }
429 return Write ( Data, NumBytes );
430 }
431
432 public int Backpatch (long FileOffset, byte[] Data, int NumBytes )
433 {
434 if (file == null)
435 {
436 return DDC_INVALID_CALL;
437 }
438 try
439 {
440 file.seek(FileOffset);
441 } catch (IOException ioe)
442 {
443 return DDC_FILE_ERROR;
444 }
445 return Write ( Data, NumBytes );
446 }
447
448
449 /**
450 * Seek in the File.
451 */
452 protected int Seek(long offset)
453 {
454 int rc;
455 try
456 {
457 file.seek(offset);
458 rc = DDC_SUCCESS;
459 } catch (IOException ioe)
460 {
461 rc = DDC_FILE_ERROR;
462 }
463 return rc;
464 }
465
466 /**
467 * Error Messages.
468 */
469 private String DDCRET_String(int retcode)
470 {
471 switch ( retcode )
472 {
473 case DDC_SUCCESS: return "DDC_SUCCESS";
474 case DDC_FAILURE: return "DDC_FAILURE";
475 case DDC_OUT_OF_MEMORY: return "DDC_OUT_OF_MEMORY";
476 case DDC_FILE_ERROR: return "DDC_FILE_ERROR";
477 case DDC_INVALID_CALL: return "DDC_INVALID_CALL";
478 case DDC_USER_ABORT: return "DDC_USER_ABORT";
479 case DDC_INVALID_FILE: return "DDC_INVALID_FILE";
480 }
481 return "Unknown Error";
482 }
483
484 /**
485 * Fill the header.
486 */
487 public static int FourCC(String ChunkName)
488 {
489 byte[] p = {0x20,0x20,0x20,0x20};
490 ChunkName.getBytes(0,4,p,0);
491 int ret = (((p[0] << 24)& 0xFF000000) | ((p[1] << 16)&0x00FF0000) | ((p[2] << 8)&0x0000FF00) | (p[3]&0x000000FF));
492 return ret;
493 }
494
495}