javazoom.jl.converter.RiffFile Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jlayer Show documentation
Show all versions of jlayer Show documentation
Maven artifact for JLayer library. http://www.javazoom.net/javalayer/sources.html
/*
* 11/19/04 1.0 moved to LGPL.
* 02/23/99 JavaConversion by E.B
* Don Cross, April 1993.
* RIFF file format classes.
* See Chapter 8 of "Multimedia Programmer's Reference" in
* the Microsoft Windows SDK.
*
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.converter;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* Class to manage RIFF files
*/
public class RiffFile
{
class RiffChunkHeader
{
public int ckID = 0; // Four-character chunk ID
public int ckSize = 0; // Length of data in chunk
public RiffChunkHeader()
{}
}
// DDCRET
public static final int DDC_SUCCESS = 0; // The operation succeded
public static final int DDC_FAILURE = 1; // The operation failed for unspecified reasons
public static final int DDC_OUT_OF_MEMORY = 2; // Operation failed due to running out of memory
public static final int DDC_FILE_ERROR = 3; // Operation encountered file I/O error
public static final int DDC_INVALID_CALL = 4; // Operation was called with invalid parameters
public static final int DDC_USER_ABORT = 5; // Operation was aborted by the user
public static final int DDC_INVALID_FILE = 6; // File format does not match
// RiffFileMode
public static final int RFM_UNKNOWN = 0; // undefined type (can use to mean "N/A" or "not open")
public static final int RFM_WRITE = 1; // open for write
public static final int RFM_READ = 2; // open for read
private RiffChunkHeader riff_header; // header for whole file
protected int fmode; // current file I/O mode
protected RandomAccessFile file; // I/O stream to use
/**
* Dummy Constructor
*/
public RiffFile()
{
file = null;
fmode = RFM_UNKNOWN;
riff_header = new RiffChunkHeader();
riff_header.ckID = FourCC("RIFF");
riff_header.ckSize = 0;
}
/**
* Return File Mode.
*/
public int CurrentFileMode()
{return fmode;}
/**
* Open a RIFF file.
*/
public int Open(String Filename, int NewMode)
{
int retcode = DDC_SUCCESS;
if ( fmode != RFM_UNKNOWN )
{
retcode = Close();
}
if ( retcode == DDC_SUCCESS )
{
switch ( NewMode )
{
case RFM_WRITE:
try
{
file = new RandomAccessFile(Filename,"rw");
try
{
// Write the RIFF header...
// We will have to come back later and patch it!
byte[] br = new byte[8];
br[0] = (byte) ((riff_header.ckID >>> 24) & 0x000000FF);
br[1] = (byte) ((riff_header.ckID >>> 16) & 0x000000FF);
br[2] = (byte) ((riff_header.ckID >>> 8) & 0x000000FF);
br[3] = (byte) (riff_header.ckID & 0x000000FF);
byte br4 = (byte) ((riff_header.ckSize >>> 24)& 0x000000FF);
byte br5 = (byte) ((riff_header.ckSize >>> 16)& 0x000000FF);
byte br6 = (byte) ((riff_header.ckSize >>> 8)& 0x000000FF);
byte br7 = (byte) (riff_header.ckSize & 0x000000FF);
br[4] = br7;
br[5] = br6;
br[6] = br5;
br[7] = br4;
file.write(br,0,8);
fmode = RFM_WRITE;
} catch (IOException ioe)
{
file.close();
fmode = RFM_UNKNOWN;
}
} catch (IOException ioe)
{
fmode = RFM_UNKNOWN;
retcode = DDC_FILE_ERROR;
}
break;
case RFM_READ:
try
{
file = new RandomAccessFile(Filename,"r");
try
{
// Try to read the RIFF header...
byte[] br = new byte[8];
file.read(br,0,8);
fmode = RFM_READ;
riff_header.ckID = ((br[0]<<24)& 0xFF000000) | ((br[1]<<16)&0x00FF0000) | ((br[2]<<8)&0x0000FF00) | (br[3]&0x000000FF);
riff_header.ckSize = ((br[4]<<24)& 0xFF000000) | ((br[5]<<16)&0x00FF0000) | ((br[6]<<8)&0x0000FF00) | (br[7]&0x000000FF);
} catch (IOException ioe)
{
file.close();
fmode = RFM_UNKNOWN;
}
} catch (IOException ioe)
{
fmode = RFM_UNKNOWN;
retcode = DDC_FILE_ERROR;
}
break;
default:
retcode = DDC_INVALID_CALL;
}
}
return retcode;
}
/**
* Write NumBytes data.
*/
public int Write(byte[] Data, int NumBytes )
{
if ( fmode != RFM_WRITE )
{
return DDC_INVALID_CALL;
}
try
{
file.write(Data,0,NumBytes);
fmode = RFM_WRITE;
}
catch (IOException ioe)
{
return DDC_FILE_ERROR;
}
riff_header.ckSize += NumBytes;
return DDC_SUCCESS;
}
/**
* Write NumBytes data.
*/
public int Write(short[] Data, int NumBytes )
{
byte[] theData = new byte[NumBytes];
int yc = 0;
for (int y = 0;y>> 8) & 0x00FF);
}
if ( fmode != RFM_WRITE )
{
return DDC_INVALID_CALL;
}
try
{
file.write(theData,0,NumBytes);
fmode = RFM_WRITE;
}
catch (IOException ioe)
{
return DDC_FILE_ERROR;
}
riff_header.ckSize += NumBytes;
return DDC_SUCCESS;
}
/**
* Write NumBytes data.
*/
public int Write(RiffChunkHeader Triff_header, int NumBytes )
{
byte[] br = new byte[8];
br[0] = (byte) ((Triff_header.ckID >>> 24) & 0x000000FF);
br[1] = (byte) ((Triff_header.ckID >>> 16) & 0x000000FF);
br[2] = (byte) ((Triff_header.ckID >>> 8) & 0x000000FF);
br[3] = (byte) (Triff_header.ckID & 0x000000FF);
byte br4 = (byte) ((Triff_header.ckSize >>> 24)& 0x000000FF);
byte br5 = (byte) ((Triff_header.ckSize >>> 16)& 0x000000FF);
byte br6 = (byte) ((Triff_header.ckSize >>> 8)& 0x000000FF);
byte br7 = (byte) (Triff_header.ckSize & 0x000000FF);
br[4] = br7;
br[5] = br6;
br[6] = br5;
br[7] = br4;
if ( fmode != RFM_WRITE )
{
return DDC_INVALID_CALL;
}
try
{
file.write(br,0,NumBytes);
fmode = RFM_WRITE;
} catch (IOException ioe)
{
return DDC_FILE_ERROR;
}
riff_header.ckSize += NumBytes;
return DDC_SUCCESS;
}
/**
* Write NumBytes data.
*/
public int Write(short Data, int NumBytes )
{
short theData = (short) ( ((Data>>>8)&0x00FF) | ((Data<<8)&0xFF00) );
if ( fmode != RFM_WRITE )
{
return DDC_INVALID_CALL;
}
try
{
file.writeShort(theData);
fmode = RFM_WRITE;
} catch (IOException ioe)
{
return DDC_FILE_ERROR;
}
riff_header.ckSize += NumBytes;
return DDC_SUCCESS;
}
/**
* Write NumBytes data.
*/
public int Write(int Data, int NumBytes )
{
short theDataL = (short) ((Data>>>16)&0x0000FFFF);
short theDataR = (short) (Data&0x0000FFFF);
short theDataLI = (short) ( ((theDataL>>>8)&0x00FF) | ((theDataL<<8)&0xFF00) );
short theDataRI = (short) ( ((theDataR>>>8)&0x00FF) | ((theDataR<<8)&0xFF00) );
int theData = ((theDataRI<<16)&0xFFFF0000) | (theDataLI&0x0000FFFF);
if ( fmode != RFM_WRITE )
{
return DDC_INVALID_CALL;
}
try
{
file.writeInt(theData);
fmode = RFM_WRITE;
} catch (IOException ioe)
{
return DDC_FILE_ERROR;
}
riff_header.ckSize += NumBytes;
return DDC_SUCCESS;
}
/**
* Read NumBytes data.
*/
public int Read (byte[] Data, int NumBytes)
{
int retcode = DDC_SUCCESS;
try
{
file.read(Data,0,NumBytes);
} catch (IOException ioe)
{
retcode = DDC_FILE_ERROR;
}
return retcode;
}
/**
* Expect NumBytes data.
*/
public int Expect(String Data, int NumBytes )
{
byte target = 0;
int cnt = 0;
try
{
while ((NumBytes--) != 0)
{
target = file.readByte();
if (target != Data.charAt(cnt++)) return DDC_FILE_ERROR;
}
} catch (IOException ioe)
{
return DDC_FILE_ERROR;
}
return DDC_SUCCESS;
}
/**
* Close Riff File.
* Length is written too.
*/
public int Close()
{
int retcode = DDC_SUCCESS;
switch ( fmode )
{
case RFM_WRITE:
try
{
file.seek(0);
try
{
byte[] br = new byte[8];
br[0] = (byte) ((riff_header.ckID >>> 24) & 0x000000FF);
br[1] = (byte) ((riff_header.ckID >>> 16) & 0x000000FF);
br[2] = (byte) ((riff_header.ckID >>> 8) & 0x000000FF);
br[3] = (byte) (riff_header.ckID & 0x000000FF);
br[7] = (byte) ((riff_header.ckSize >>> 24)& 0x000000FF);
br[6] = (byte) ((riff_header.ckSize >>> 16)& 0x000000FF);
br[5] = (byte) ((riff_header.ckSize >>> 8)& 0x000000FF);
br[4] = (byte) (riff_header.ckSize & 0x000000FF);
file.write(br,0,8);
file.close();
} catch (IOException ioe)
{
retcode = DDC_FILE_ERROR;
}
} catch (IOException ioe)
{
retcode = DDC_FILE_ERROR;
}
break;
case RFM_READ:
try
{
file.close();
} catch (IOException ioe)
{
retcode = DDC_FILE_ERROR;
}
break;
}
file = null;
fmode = RFM_UNKNOWN;
return retcode;
}
/**
* Return File Position.
*/
public long CurrentFilePosition()
{
long position;
try
{
position = file.getFilePointer();
} catch (IOException ioe)
{
position = -1;
}
return position;
}
/**
* Write Data to specified offset.
*/
public int Backpatch (long FileOffset, RiffChunkHeader Data, int NumBytes )
{
if (file == null)
{
return DDC_INVALID_CALL;
}
try
{
file.seek(FileOffset);
} catch (IOException ioe)
{
return DDC_FILE_ERROR;
}
return Write ( Data, NumBytes );
}
public int Backpatch (long FileOffset, byte[] Data, int NumBytes )
{
if (file == null)
{
return DDC_INVALID_CALL;
}
try
{
file.seek(FileOffset);
} catch (IOException ioe)
{
return DDC_FILE_ERROR;
}
return Write ( Data, NumBytes );
}
/**
* Seek in the File.
*/
protected int Seek(long offset)
{
int rc;
try
{
file.seek(offset);
rc = DDC_SUCCESS;
} catch (IOException ioe)
{
rc = DDC_FILE_ERROR;
}
return rc;
}
/**
* Error Messages.
*/
private String DDCRET_String(int retcode)
{
switch ( retcode )
{
case DDC_SUCCESS: return "DDC_SUCCESS";
case DDC_FAILURE: return "DDC_FAILURE";
case DDC_OUT_OF_MEMORY: return "DDC_OUT_OF_MEMORY";
case DDC_FILE_ERROR: return "DDC_FILE_ERROR";
case DDC_INVALID_CALL: return "DDC_INVALID_CALL";
case DDC_USER_ABORT: return "DDC_USER_ABORT";
case DDC_INVALID_FILE: return "DDC_INVALID_FILE";
}
return "Unknown Error";
}
/**
* Fill the header.
*/
public static int FourCC(String ChunkName)
{
byte[] p = {0x20,0x20,0x20,0x20};
ChunkName.getBytes(0,4,p,0);
int ret = (((p[0] << 24)& 0xFF000000) | ((p[1] << 16)&0x00FF0000) | ((p[2] << 8)&0x0000FF00) | (p[3]&0x000000FF));
return ret;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy