diff src/ca/randelshofer/DataChunkOutputStream.java @ 10:4c5fc53778c1

moved randelshofer stuff to rightfull place, enabled XuggleVideoRecorder
author Robert McIntyre <rlm@mit.edu>
date Wed, 26 Oct 2011 09:38:27 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/ca/randelshofer/DataChunkOutputStream.java	Wed Oct 26 09:38:27 2011 -0700
     1.3 @@ -0,0 +1,217 @@
     1.4 +/**
     1.5 + * @(#)DataChunkOutputStream.java  1.1  2011-01-17
     1.6 + *
     1.7 + * Copyright (c) 2008-2011 Werner Randelshofer, Immensee, Switzerland.
     1.8 + * All rights reserved.
     1.9 + *
    1.10 + * You may not use, copy or modify this file, except in compliance with the
    1.11 + * license agreement you entered into with Werner Randelshofer.
    1.12 + * For details see accompanying license terms.
    1.13 + */
    1.14 +package ca.randelshofer;
    1.15 +
    1.16 +import java.io.*;
    1.17 +
    1.18 +/**
    1.19 + * This output stream filter supports common data types used inside
    1.20 + * of AVI RIFF Data Chunks.
    1.21 + *
    1.22 + * @author Werner Randelshofer
    1.23 + * @version 1.1 2011-01-17 Adds functionality for blocking flush and close.
    1.24 + * <br>1.0.1 2010-04-05 Removed unused constants.
    1.25 + * <br>1.0  2008-08-11 Created.
    1.26 + */
    1.27 +public class DataChunkOutputStream extends FilterOutputStream {
    1.28 +
    1.29 +    /**
    1.30 +     * The number of bytes written to the data output stream so far. 
    1.31 +     * If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
    1.32 +     */
    1.33 +    protected long written;
    1.34 +
    1.35 +    /** Whether flush and close request shall be forwarded to underlying stream.*/
    1.36 +    private boolean forwardFlushAndClose;
    1.37 +
    1.38 +    public DataChunkOutputStream(OutputStream out) {
    1.39 +        this(out,true);
    1.40 +    }
    1.41 +    public DataChunkOutputStream(OutputStream out, boolean forwardFlushAndClose) {
    1.42 +        super(out);
    1.43 +        this.forwardFlushAndClose=forwardFlushAndClose;
    1.44 +    }
    1.45 +
    1.46 +    /**
    1.47 +     * Writes an chunk type identifier (4 bytes).
    1.48 +     * @param s A string with a length of 4 characters.
    1.49 +     */
    1.50 +    public void writeType(String s) throws IOException {
    1.51 +        if (s.length() != 4) {
    1.52 +            throw new IllegalArgumentException("type string must have 4 characters");
    1.53 +        }
    1.54 +
    1.55 +        try {
    1.56 +            out.write(s.getBytes("ASCII"), 0, 4);
    1.57 +            incCount(4);
    1.58 +        } catch (UnsupportedEncodingException e) {
    1.59 +            throw new InternalError(e.toString());
    1.60 +        }
    1.61 +    }
    1.62 +
    1.63 +    /**
    1.64 +     * Writes out a <code>byte</code> to the underlying output stream as 
    1.65 +     * a 1-byte value. If no exception is thrown, the counter 
    1.66 +     * <code>written</code> is incremented by <code>1</code>.
    1.67 +     *
    1.68 +     * @param      v   a <code>byte</code> value to be written.
    1.69 +     * @exception  IOException  if an I/O error occurs.
    1.70 +     * @see        java.io.FilterOutputStream#out
    1.71 +     */
    1.72 +    public final void writeByte(int v) throws IOException {
    1.73 +        out.write(v);
    1.74 +        incCount(1);
    1.75 +    }
    1.76 +
    1.77 +    /**
    1.78 +     * Writes <code>len</code> bytes from the specified byte array 
    1.79 +     * starting at offset <code>off</code> to the underlying output stream. 
    1.80 +     * If no exception is thrown, the counter <code>written</code> is 
    1.81 +     * incremented by <code>len</code>.
    1.82 +     *
    1.83 +     * @param      b     the data.
    1.84 +     * @param      off   the start offset in the data.
    1.85 +     * @param      len   the number of bytes to write.
    1.86 +     * @exception  IOException  if an I/O error occurs.
    1.87 +     * @see        java.io.FilterOutputStream#out
    1.88 +     */
    1.89 +    @Override
    1.90 +    public synchronized void write(byte b[], int off, int len)
    1.91 +            throws IOException {
    1.92 +        out.write(b, off, len);
    1.93 +        incCount(len);
    1.94 +    }
    1.95 +
    1.96 +    /**
    1.97 +     * Writes the specified byte (the low eight bits of the argument 
    1.98 +     * <code>b</code>) to the underlying output stream. If no exception 
    1.99 +     * is thrown, the counter <code>written</code> is incremented by 
   1.100 +     * <code>1</code>.
   1.101 +     * <p>
   1.102 +     * Implements the <code>write</code> method of <code>OutputStream</code>.
   1.103 +     *
   1.104 +     * @param      b   the <code>byte</code> to be written.
   1.105 +     * @exception  IOException  if an I/O error occurs.
   1.106 +     * @see        java.io.FilterOutputStream#out
   1.107 +     */
   1.108 +    @Override
   1.109 +    public synchronized void write(int b) throws IOException {
   1.110 +        out.write(b);
   1.111 +        incCount(1);
   1.112 +    }
   1.113 +
   1.114 +    /**
   1.115 +     * Writes an <code>int</code> to the underlying output stream as four
   1.116 +     * bytes, high byte first. If no exception is thrown, the counter 
   1.117 +     * <code>written</code> is incremented by <code>4</code>.
   1.118 +     *
   1.119 +     * @param      v   an <code>int</code> to be written.
   1.120 +     * @exception  IOException  if an I/O error occurs.
   1.121 +     * @see        java.io.FilterOutputStream#out
   1.122 +     */
   1.123 +    public void writeInt(int v) throws IOException {
   1.124 +        out.write((v >>> 0) & 0xff);
   1.125 +        out.write((v >>> 8) & 0xff);
   1.126 +        out.write((v >>> 16) & 0xff);
   1.127 +        out.write((v >>> 24) & 0xff);
   1.128 +        incCount(4);
   1.129 +    }
   1.130 +
   1.131 +    /**
   1.132 +     * Writes an unsigned 32 bit integer value.
   1.133 +     * 
   1.134 +     * @param v The value
   1.135 +     * @throws java.io.IOException
   1.136 +     */
   1.137 +    public void writeUInt(long v) throws IOException {
   1.138 +        out.write((int) ((v >>> 0) & 0xff));
   1.139 +        out.write((int) ((v >>> 8) & 0xff));
   1.140 +        out.write((int) ((v >>> 16) & 0xff));
   1.141 +        out.write((int) ((v >>> 24) & 0xff));
   1.142 +        incCount(4);
   1.143 +    }
   1.144 +
   1.145 +    /**
   1.146 +     * Writes a signed 16 bit integer value.
   1.147 +     * 
   1.148 +     * @param v The value
   1.149 +     * @throws java.io.IOException
   1.150 +     */
   1.151 +    public void writeShort(int v) throws IOException {
   1.152 +        out.write((int) ((v >>> 0) & 0xff));
   1.153 +        out.write((int) ((v >> 8) & 0xff));
   1.154 +        incCount(2);
   1.155 +    }
   1.156 +
   1.157 +    public void writeLong(long v) throws IOException {
   1.158 +        out.write((int) (v >>> 0) & 0xff);
   1.159 +        out.write((int) (v >>> 8) & 0xff);
   1.160 +        out.write((int) (v >>> 16) & 0xff);
   1.161 +        out.write((int) (v >>> 24) & 0xff);
   1.162 +        out.write((int) (v >>> 32) & 0xff);
   1.163 +        out.write((int) (v >>> 40) & 0xff);
   1.164 +        out.write((int) (v >>> 48) & 0xff);
   1.165 +        out.write((int) (v >>> 56) & 0xff);
   1.166 +        incCount(8);
   1.167 +    }
   1.168 +
   1.169 +    public void writeUShort(int v) throws IOException {
   1.170 +        out.write((int) ((v >>> 0) & 0xff));
   1.171 +        out.write((int) ((v >> 8) & 0xff));
   1.172 +        incCount(2);
   1.173 +    }
   1.174 +
   1.175 +    /**
   1.176 +     * Increases the written counter by the specified value
   1.177 +     * until it reaches Long.MAX_VALUE.
   1.178 +     */
   1.179 +    protected void incCount(int value) {
   1.180 +        long temp = written + value;
   1.181 +        if (temp < 0) {
   1.182 +            temp = Long.MAX_VALUE;
   1.183 +        }
   1.184 +        written = temp;
   1.185 +    }
   1.186 +
   1.187 +    /**
   1.188 +     * Returns the current value of the counter <code>written</code>, 
   1.189 +     * the number of bytes written to this data output stream so far.
   1.190 +     * If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
   1.191 +     *
   1.192 +     * @return  the value of the <code>written</code> field.
   1.193 +     * @see     java.io.DataOutputStream#written
   1.194 +     */
   1.195 +    public final long size() {
   1.196 +        return written;
   1.197 +    }
   1.198 +    
   1.199 +    /**
   1.200 +     * Sets the value of the counter <code>written</code> to 0.
   1.201 +     */
   1.202 +    public void clearCount() {
   1.203 +        written = 0;
   1.204 +    }
   1.205 +
   1.206 +    @Override
   1.207 +    public void close() throws IOException {
   1.208 +        if (forwardFlushAndClose) {
   1.209 +        super.close();
   1.210 +        }
   1.211 +    }
   1.212 +    
   1.213 +    @Override
   1.214 +    public void flush() throws IOException {
   1.215 +        if (forwardFlushAndClose) {
   1.216 +        super.flush();
   1.217 +        }
   1.218 +    }
   1.219 +
   1.220 +}