Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * @(#)MC68000OutputStream.java  1.1  2010-10-26
   *
   * Copyright (c) 2006-2010 Werner Randelshofer, Goldau, Switzerland.
   * All rights reserved.
   *
   * You may not use, copy or modify this file, except in compliance with the
   * license agreement you entered into with Werner Randelshofer.
   * For details see accompanying license terms.
  */
 package org.monte.media.iff;
 
 import java.io.*;
MC68000OutputStream.

Author(s):
Werner Randelshofer
Version:
1.1 2010-12-26 Added method writeType().
1.0.1 2008-08-03 The ByteRun1 encoder incorrectly added 1 to its index when flushing the literal run.
1.0 December 25, 2006 Created.
 
 public class MC68000OutputStream extends FilterOutputStream {
    
The number of bytes written to the data output stream so far. If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
 
     protected long written;

    
Creates a new instance.
 
     public MC68000OutputStream(OutputStream out) {
         super(out);
     }
 
     public void writeLONG(int vthrows IOException {
         .write((v >>> 24) & 0xFF);
         .write((v >>> 16) & 0xFF);
         .write((v >>> 8) & 0xFF);
         .write((v >>> 0) & 0xFF);
         incCount(4);
     }
 
     public void writeULONG(long vthrows IOException {
         .write((int) ((v >>> 24) & 0xFF));
         .write((int) ((v >>> 16) & 0xFF));
         .write((int) ((v >>> 8) & 0xFF));
         .write((int) ((v >>> 0) & 0xFF));
         incCount(4);
     }
 
     public void writeWORD(int vthrows IOException {
         .write((v >>> 8) & 0xFF);
         .write((v >>> 0) & 0xFF);
         incCount(2);
     }
 
     public void writeUWORD(int vthrows IOException {
         .write((v >>> 8) & 0xFF);
         .write((v >>> 0) & 0xFF);
         incCount(2);
     }
 
     public void writeUBYTE(int vthrows IOException {
         .write((v >>> 0) & 0xFF);
         incCount(1);
     }

    
ByteRun1 Run Encoding.

The run encoding scheme in byteRun1 is best described by pseudo code for the decoder Unpacker (called UnPackBits in the Macintosh toolbox):

 UnPacker:
    LOOP until produced the desired number of bytes
       Read the next source byte into n
       SELECT n FROM
          [ 0..127 ] => copy the next n+1 bytes literally
          [-1..-127] => replicate the next byte -n+1 timees
          -128       => no operation
       ENDCASE
    ENDLOOP
 
 
     public void writeByteRun1(byte[] datathrows IOException {
         writeByteRun1(data, 0, data.length);
     }
 
     public void writeByteRun1(byte[] dataint offsetint lengththrows IOException {
         int end = offset + length;
 
         // Start offset of the literal run
         int literalOffset = offset;
         int i;
         for (i = offseti < endi++) {
             // Read a byte
            byte b = data[i];
            // Count repeats of that byte
            int repeatCount = i + 1;
            for (; repeatCount < endrepeatCount++) {
                if (data[repeatCount] != b) {
                    break;
                }
            }
            repeatCount = repeatCount - i;
            if (repeatCount == 1) {
                // Flush the literal run, if it gets too large
                if (i - literalOffset > 127) {
                    write(i - literalOffset - 1);
                    write(dataliteralOffseti - literalOffset);
                    literalOffset = i;
                }
                // If the byte repeats just twice, and we have a literal
                // run with enough space, add it the literal run
            } else if (repeatCount == 2
                    && literalOffset < i && i - literalOffset < 127) {
                i++;
            } else {
                // Flush the literal run, if we have one
                if (literalOffset < i) {
                    write(i - literalOffset - 1);
                    write(dataliteralOffseti - literalOffset);
                }
                // Write the repeat run
                i += repeatCount - 1;
                literalOffset = i + 1;
                // We have to write multiple runs, if the byte repeats more
                // than 128 times.
                for (; repeatCount > 128; repeatCount -= 128) {
                    write(-127);
                    write(b);
                }
                write(-repeatCount + 1);
                write(b);
            }
        }
        // Flush the literal run, if we have one
        if (literalOffset < end) {
            write(i - literalOffset - 1);
            write(dataliteralOffseti - literalOffset);
        }
    }
    @Override
    public void write(int bthrows IOException {
        .write(b);
        incCount(1);
    }
    @Override
    public void write(byte b[], int offint lenthrows IOException {
        .write(bofflen);
        incCount(len);
    }

    
Writes an chunk type identifier (4 bytes).

Parameters:
s A string with a length of 4 characters.
    public void writeType(String sthrows IOException {
        if (s.length() != 4) {
            throw new IllegalArgumentException("type string must have 4 characters");
        }
        try {
            .write(s.getBytes("ASCII"), 0, 4);
            incCount(4);
        } catch (UnsupportedEncodingException e) {
            throw new InternalError(e.toString());
        }
    }

    
Returns the current value of the counter written, the number of bytes written to this data output stream so far. If the counter overflows, it will be wrapped to Integer.MAX_VALUE.

Returns:
the value of the written field.
See also:
java.io.DataOutputStream.written
    public final long size() {
        return ;
    }

    
Sets the value of the counter written to 0.
    public void clearCount() {
         = 0;
    }
    
Increases the written counter by the specified value until it reaches Long.MAX_VALUE.
    protected void incCount(int value) {
        long temp =  + value;
        if (temp < 0) {
            temp = .;
        }
         = temp;
    }
New to GrepCode? Check out our FAQ X