/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */
package org.apache.poi.hdgf;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.poi.util.LZWDecompresser;

/**
 * A decoder for the crazy LZW implementation used
 *  in Visio.
 * According to VSDump, "it's a slightly perverted version of LZW
 *  compression, with inverted meaning of flag byte and 0xFEE as an
 *  'initial shift'". It uses 12 bit codes
 * (http://www.gnome.ru/projects/vsdump_en.html)
 *
 * Two good resources on LZW are:
 *  http://en.wikipedia.org/wiki/LZW
 *  http://marknelson.us/1989/10/01/lzw-data-compression/
 */
public class HDGFLZW extends LZWDecompresser {
   public HDGFLZW() {
      // Out flag is the wrong way round!
      // Length wise, we're 3 longer than we say, so the max len is 19
      // Endian wise, we're little endian, so 0x1234 is pos 0x312
      super(false, 3, false);
   }

   /**
    * Compress the given input stream, returning the array of bytes
    *  of the compressed input
    *
    * @param src the compression source byte
    * @return the compressed stream as bytes
    *
    * @throws IOException when the InputStream can't be read
    */
   public byte[] compress(InputStream src) throws IOException {
      ByteArrayOutputStream res = new ByteArrayOutputStream();
      compress(src,res);
      return res.toByteArray();
   }

   /**
    * We have a slight shift by 18 bytes
    */
   @Override
   protected int adjustDictionaryOffset(int pntr) {
      if(pntr > 4078) {
         pntr = pntr - 4078;
      } else {
         pntr = pntr + 18;
      }
      return pntr;
   }

   /**
    * We want an empty dictionary, so do nothing
    */
   @Override
   protected int populateDictionary(byte[] dict) {
      return 0;
   }

   /**
    * Performs the Visio compatible streaming LZW compression.
    *
    * @param src the input bytes for the compression
    * @param res the OutputStream which receives the compressed bytes
    *
    * @throws IOException when the InputStream can't be read
    *    or the OutputStream can't be written to
    */
   public void compress(InputStream src, OutputStream res) throws IOException {
      HDGFLZWCompressor c = new HDGFLZWCompressor(res);
      c.compress(src);
   }
}
