001: /*
002: * $RCSfile: BitFile.java,v $
003: *
004: *
005: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * - Redistribution of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * - Redistribution in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * Neither the name of Sun Microsystems, Inc. or the names of
020: * contributors may be used to endorse or promote products derived
021: * from this software without specific prior written permission.
022: *
023: * This software is provided "AS IS," without a warranty of any
024: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
025: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
026: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027: * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
028: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
029: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
031: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035: * POSSIBILITY OF SUCH DAMAGES.
036: *
037: * You acknowledge that this software is not designed or intended for
038: * use in the design, construction, operation or maintenance of any
039: * nuclear facility.
040: *
041: * $Revision: 1.1 $
042: * $Date: 2005/02/11 05:01:21 $
043: * $State: Exp $
044: */
045:
046: package com.sun.media.imageioimpl.common;
047:
048: import java.io.IOException;
049: import javax.imageio.stream.ImageOutputStream;
050:
051: /**
052: * Came from GIFEncoder initially.
053: * Modified - to allow for output compressed data without the block counts
054: * which breakup the compressed data stream for GIF.
055: **/
056: public class BitFile {
057: ImageOutputStream output_;
058: byte buffer_[];
059: int index_;
060: int bitsLeft_; // bits left at current index that are avail.
061:
062: /** note this also indicates gif format BITFile. **/
063: boolean blocks_ = false;
064:
065: /**
066: * @param output destination for output data
067: * @param blocks GIF LZW requires block counts for output data
068: **/
069: public BitFile(ImageOutputStream output, boolean blocks) {
070: output_ = output;
071: blocks_ = blocks;
072: buffer_ = new byte[256];
073: index_ = 0;
074: bitsLeft_ = 8;
075: }
076:
077: public void flush() throws IOException {
078: int numBytes = index_ + (bitsLeft_ == 8 ? 0 : 1);
079: if (numBytes > 0) {
080: if (blocks_)
081: output_.write(numBytes);
082: output_.write(buffer_, 0, numBytes);
083: buffer_[0] = 0;
084: index_ = 0;
085: bitsLeft_ = 8;
086: }
087: }
088:
089: public void writeBits(int bits, int numbits) throws IOException {
090: int bitsWritten = 0;
091: int numBytes = 255; // gif block count
092: do {
093: // This handles the GIF block count stuff
094: if ((index_ == 254 && bitsLeft_ == 0) || index_ > 254) {
095: if (blocks_)
096: output_.write(numBytes);
097:
098: output_.write(buffer_, 0, numBytes);
099:
100: buffer_[0] = 0;
101: index_ = 0;
102: bitsLeft_ = 8;
103: }
104:
105: if (numbits <= bitsLeft_) // bits contents fit in current index byte
106: {
107: if (blocks_) // GIF
108: {
109: buffer_[index_] |= (bits & ((1 << numbits) - 1)) << (8 - bitsLeft_);
110: bitsWritten += numbits;
111: bitsLeft_ -= numbits;
112: numbits = 0;
113: } else {
114: buffer_[index_] |= (bits & ((1 << numbits) - 1)) << (bitsLeft_ - numbits);
115: bitsWritten += numbits;
116: bitsLeft_ -= numbits;
117: numbits = 0;
118:
119: }
120: } else // bits overflow from current byte to next.
121: {
122: if (blocks_) // GIF
123: {
124: // if bits > space left in current byte then the lowest order bits
125: // of code are taken and put in current byte and rest put in next.
126: buffer_[index_] |= (bits & ((1 << bitsLeft_) - 1)) << (8 - bitsLeft_);
127: bitsWritten += bitsLeft_;
128: bits >>= bitsLeft_;
129: numbits -= bitsLeft_;
130: buffer_[++index_] = 0;
131: bitsLeft_ = 8;
132: } else {
133: // if bits > space left in current byte then the highest order bits
134: // of code are taken and put in current byte and rest put in next.
135: // at highest order bit location !!
136: int topbits = (bits >>> (numbits - bitsLeft_))
137: & ((1 << bitsLeft_) - 1);
138: buffer_[index_] |= topbits;
139: numbits -= bitsLeft_; // ok this many bits gone off the top
140: bitsWritten += bitsLeft_;
141: buffer_[++index_] = 0; // next index
142: bitsLeft_ = 8;
143: }
144: }
145:
146: } while (numbits != 0);
147: }
148: }
|