Logo Search packages:      
Sourcecode: libjlayer-java version File versions  Download package

RiffFile.java

/*
 * 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
 */
00035 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
      */
00067    public RiffFile()
   {
      file = null;
      fmode = RFM_UNKNOWN;
      riff_header = new RiffChunkHeader();
   
      riff_header.ckID = FourCC("RIFF");
        riff_header.ckSize = 0;
   }
 
   /**
    * Return File Mode.
      */
00080    public int CurrentFileMode()
   {return fmode;}
   
   /**
    * Open a RIFF file.
      */
00086    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.
      */
00171    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.
      */     
00195    public int Write(short[] Data, int NumBytes )
   {
      byte[] theData = new byte[NumBytes];
      int yc = 0;
      for (int y = 0;y<NumBytes;y=y+2)
      {
        theData[y] = (byte) (Data[yc] & 0x00FF);
        theData[y+1] =(byte) ((Data[yc++] >>> 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.
      */
00224    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.
      */
00261    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.
      */
00282    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.
      */   
00310    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.
      */
00326    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.
      */
00348    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.
      */
00400    public long CurrentFilePosition()
   {
        long      position;
        try
        {
            position = file.getFilePointer();
        } catch (IOException ioe)
          {
            position = -1;
          }
      return position;
   }

   /**
    * Write Data to specified offset.
      */
00416    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.
      */
00452    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.
      */
00469    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.
      */
00487    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;
   }

}

Generated by  Doxygen 1.6.0   Back to index