Coverage Report - org.jaudiotagger.audio.asf.io.StreamChunkReader
 
Classes in this File Line Coverage Branch Coverage Complexity
StreamChunkReader
77%
47/61
30%
3/10
1.75
 
 1  
 /*
 2  
  * Entagged Audio Tag library
 3  
  * Copyright (c) 2004-2005 Christian Laireiter <liree@web.de>
 4  
  * 
 5  
  * This library is free software; you can redistribute it and/or
 6  
  * modify it under the terms of the GNU Lesser General Public
 7  
  * License as published by the Free Software Foundation; either
 8  
  * version 2.1 of the License, or (at your option) any later version.
 9  
  *  
 10  
  * This library is distributed in the hope that it will be useful,
 11  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
  * Lesser General Public License for more details.
 14  
  * 
 15  
  * You should have received a copy of the GNU Lesser General Public
 16  
  * License along with this library; if not, write to the Free Software
 17  
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 18  
  */
 19  
 package org.jaudiotagger.audio.asf.io;
 20  
 
 21  
 import org.jaudiotagger.audio.asf.data.*;
 22  
 import org.jaudiotagger.audio.asf.util.Utils;
 23  
 
 24  
 import java.io.IOException;
 25  
 import java.io.InputStream;
 26  
 import java.math.BigInteger;
 27  
 
 28  
 /**
 29  
  * Reads and interprets the data of the audio or video stream information chunk.
 30  
  * <br>
 31  
  *
 32  
  * @author Christian Laireiter
 33  
  */
 34  
 public class StreamChunkReader implements ChunkReader
 35  
 {
 36  
 
 37  
     /**
 38  
      * Shouldn't be used for now.
 39  
      */
 40  
     protected StreamChunkReader()
 41  126
     {
 42  
         // Nothing to do
 43  126
     }
 44  
 
 45  
     /**
 46  
      * {@inheritDoc}
 47  
      */
 48  
     public boolean canFail()
 49  
     {
 50  55
         return true;
 51  
     }
 52  
 
 53  
     /**
 54  
      * {@inheritDoc}
 55  
      */
 56  
     public GUID getApplyingId()
 57  
     {
 58  126
         return GUID.GUID_STREAM;
 59  
     }
 60  
 
 61  
     /**
 62  
      * {@inheritDoc}
 63  
      */
 64  
     public Chunk read(final GUID guid, final InputStream stream, final long chunkStart) throws IOException
 65  
     {
 66  55
         StreamChunk result = null;
 67  55
         BigInteger chunkLength = Utils.readBig64(stream);
 68  
         // Now comes GUID indicating whether stream content type is audio or
 69  
         // video
 70  55
         GUID streamTypeGUID = Utils.readGUID(stream);
 71  55
         if (GUID.GUID_AUDIOSTREAM.equals(streamTypeGUID) || GUID.GUID_VIDEOSTREAM.equals(streamTypeGUID))
 72  
         {
 73  
 
 74  
             // A GUID is indicating whether the stream is error
 75  
             // concealed
 76  55
             GUID errorConcealment = Utils.readGUID(stream);
 77  
             /*
 78  
              * Read the Time Offset
 79  
              */
 80  55
             long timeOffset = Utils.readUINT64(stream);
 81  
 
 82  55
             long typeSpecificDataSize = Utils.readUINT32(stream);
 83  55
             long streamSpecificDataSize = Utils.readUINT32(stream);
 84  
 
 85  
             /*
 86  
              * Read a bit field. (Contains stream number, and whether
 87  
              * the stream content is encrypted.)
 88  
              */
 89  55
             int mask = Utils.readUINT16(stream);
 90  55
             int streamNumber = mask & 127;
 91  55
             boolean contentEncrypted = (mask & (1 << 15)) == 1;
 92  
 
 93  
             /*
 94  
              * Skip a reserved field
 95  
              */
 96  55
             stream.skip(4);
 97  
 
 98  
             /*
 99  
              * very important to set for every stream type.
 100  
              * The size of bytes read by the specific stream type, in order to skip the remaining
 101  
              * unread bytes of the stream chunk. 
 102  
              */
 103  55
             long streamSpecificBytes = 0;
 104  
             
 105  55
             if (GUID.GUID_AUDIOSTREAM.equals(streamTypeGUID))
 106  
             {
 107  
                 /*
 108  
                       * Reading audio specific information
 109  
                       */
 110  55
                 AudioStreamChunk audioStreamChunk = new AudioStreamChunk(chunkLength);
 111  55
                 result = audioStreamChunk;
 112  
 
 113  
                 /*
 114  
                       * read WAVEFORMATEX and format extension.
 115  
                       */
 116  55
                 long compressionFormat = Utils.readUINT16(stream);
 117  55
                 long channelCount = Utils.readUINT16(stream);
 118  55
                 long samplingRate = Utils.readUINT32(stream);
 119  55
                 long avgBytesPerSec = Utils.readUINT32(stream);
 120  55
                 long blockAlignment = Utils.readUINT16(stream);
 121  55
                 int bitsPerSample = Utils.readUINT16(stream);
 122  55
                 int codecSpecificDataSize = Utils.readUINT16(stream);
 123  55
                 byte[] codecSpecificData = new byte[codecSpecificDataSize];
 124  55
                 stream.read(codecSpecificData);
 125  
 
 126  55
                 audioStreamChunk.setCompressionFormat(compressionFormat);
 127  55
                 audioStreamChunk.setChannelCount(channelCount);
 128  55
                 audioStreamChunk.setSamplingRate(samplingRate);
 129  55
                 audioStreamChunk.setAverageBytesPerSec(avgBytesPerSec);
 130  55
                 audioStreamChunk.setErrorConcealment(errorConcealment);
 131  55
                 audioStreamChunk.setBlockAlignment(blockAlignment);
 132  55
                 audioStreamChunk.setBitsPerSample(bitsPerSample);
 133  55
                 audioStreamChunk.setCodecData(codecSpecificData);
 134  
                 
 135  55
                 streamSpecificBytes = 18 + codecSpecificData.length;
 136  55
             }
 137  0
             else if (GUID.GUID_VIDEOSTREAM.equals(streamTypeGUID))
 138  
             {
 139  
                 /*
 140  
                       * Reading video specific information
 141  
                       */
 142  0
                 VideoStreamChunk videoStreamChunk = new VideoStreamChunk(chunkLength);
 143  0
                 result = videoStreamChunk;
 144  
 
 145  0
                 long pictureWidth = Utils.readUINT32(stream);
 146  0
                 long pictureHeight = Utils.readUINT32(stream);
 147  
 
 148  
                 // Skip unknown field
 149  0
                 stream.skip(1);
 150  
 
 151  
                 /*
 152  
                  * Now read the format specific data
 153  
                  */
 154  
                 // Size of the data section (formatDataSize)
 155  0
                 stream.skip(2);
 156  
 
 157  0
                 stream.skip(16);
 158  0
                 byte[] fourCC = new byte[4];
 159  0
                 stream.read(fourCC);
 160  
 
 161  0
                 videoStreamChunk.setPictureWidth(pictureWidth);
 162  0
                 videoStreamChunk.setPictureHeight(pictureHeight);
 163  0
                 videoStreamChunk.setCodecId(fourCC);
 164  
                 
 165  0
                 streamSpecificBytes = 31;
 166  
             }
 167  
 
 168  
             /*
 169  
              * Setting common values for audio and video
 170  
              */
 171  55
             result.setStreamNumber(streamNumber);
 172  55
             result.setStreamSpecificDataSize(streamSpecificDataSize);
 173  55
             result.setTypeSpecificDataSize(typeSpecificDataSize);
 174  55
             result.setTimeOffset(timeOffset);
 175  55
             result.setContentEncrypted(contentEncrypted);
 176  55
             result.setPosition(chunkStart);
 177  
             /*
 178  
              * Now skip remainder of chunks bytes.
 179  
              * chunk-length - 24 (size of GUID and chunklen) - streamSpecificBytes(stream type specific data) - 54 (common data)
 180  
              */
 181  55
             stream.skip(chunkLength.longValue() - 24 - streamSpecificBytes - 54);
 182  
         }
 183  55
         return result;
 184  
     }
 185  
 
 186  
 }