001    /*
002     * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003     *
004     * http://uio.imagero.com
005     *
006     * Redistribution and use in source and binary forms, with or without
007     * modification, are permitted provided that the following conditions are met:
008     *
009     *  o Redistributions of source code must retain the above copyright notice,
010     *    this list of conditions and the following disclaimer.
011     *
012     *  o Redistributions in binary form must reproduce the above copyright notice,
013     *    this list of conditions and the following disclaimer in the documentation
014     *    and/or other materials provided with the distribution.
015     *
016     *  o Neither the name of Andrey Kuznetsov nor the names of
017     *    its contributors may be used to endorse or promote products derived
018     *    from this software without specific prior written permission.
019     *
020     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
029     * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
030     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031     */
032    
033    package com.imagero.uio.io;
034    
035    import java.io.FilterOutputStream;
036    import java.io.IOException;
037    import java.io.OutputStream;
038    
039    /**
040     * Utility to write data into App13 block(s).
041     * If data is longer as given App13 size then multiple App13 blocks are written.
042     * @author Andrey Kuznetsov
043     */
044    public class App13OutputStream extends FilterOutputStream {
045    
046        int count;
047        byte[] buffer;
048        private byte[] header = {(byte) 0xFF, (byte) 0xED, 0, 0, 'P', 'h', 'o', 't', 'o', 's', 'h', 'o', 'p', ' ', '3', '.', '0', 0};
049    
050        /**
051         * create new App13OutputStream with default App13 size (32000)
052         * @param out OutputStream
053         */
054        public App13OutputStream(OutputStream out) {
055            this(out, 32000);
056        }
057    
058        /**
059         * create App13OutputStream with user defined App13 size
060         * @param out OutputStream
061         * @param length length of App13
062         */
063        public App13OutputStream(OutputStream out, int length) {
064            super(out);
065            buffer = new byte[length];
066            for (int i = 0; i < header.length; i++) {
067                buffer[i] = header[i];
068            }
069            count = header.length;
070        }
071    
072        public synchronized void write(int b) throws IOException {
073            if (count >= buffer.length) {
074                flushBuffer();
075            }
076            buffer[count++] = (byte) b;
077        }
078    
079        protected void flushBuffer() throws IOException {
080            if (count > header.length) {
081                int cnt = count - 2;
082                buffer[2] = (byte) ((cnt >> 8) & 0xFF);
083                buffer[3] = (byte) (cnt & 0xFF);
084                out.write(buffer, 0, count);
085                count = header.length;
086            }
087        }
088    
089        public void write(byte b[]) throws IOException {
090            write(b, 0, b.length);
091        }
092    
093        public void write(byte b[], int off, int len) throws IOException {
094            for (int i = off; i < len; i++) {
095                write(b[i]);
096            }
097        }
098    
099        public void flush() throws IOException {
100            flushBuffer();
101            out.flush();
102        }
103    }