//========================================================================
//
// FlateStream.cc
//
// Copyright (C) 2005, Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2010, Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2016, William Bader <williambader@hotmail.com>
// Copyright (C) 2017, Adrian Johnson <ajohnson@redneon.com>
//
// This file is under the GPLv2 or later license
//
//========================================================================

#include <config.h>

#include "poppler-config.h"

#ifdef ENABLE_ZLIB_UNCOMPRESS

#include "FlateStream.h"

FlateStream::FlateStream(Stream *strA, int predictor, int columns, int colors, int bits) :
  FilterStream(strA)
{
  if (predictor != 1) {
    pred = new StreamPredictor(this, predictor, columns, colors, bits);
  } else {
    pred = NULL;
  }
  out_pos = 0;
  memset(&d_stream, 0, sizeof(d_stream));
  inflateInit(&d_stream);
}

FlateStream::~FlateStream() {
  inflateEnd(&d_stream);
  delete pred;
  delete str;
}

void FlateStream::reset() {
  //FIXME: what are the semantics of reset?
  //i.e. how much initialization has to happen in the constructor?

  /* reinitialize zlib */
  inflateEnd(&d_stream);
  memset(&d_stream, 0, sizeof(d_stream));
  inflateInit(&d_stream);

  str->reset();
  d_stream.avail_in = 0;
  status = Z_OK;
  out_pos = 0;
  out_buf_len = 0;
}

int FlateStream::getRawChar() {
  return doGetRawChar();
}

void FlateStream::getRawChars(int nChars, int *buffer) {
  for (int i = 0; i < nChars; ++i)
    buffer[i] = doGetRawChar();
}

int FlateStream::getChar() {
  if (pred)
    return pred->getChar();
  else
    return getRawChar();
}

int FlateStream::lookChar() {
  if (pred)
    return pred->lookChar();

  if (fill_buffer())
    return EOF;

  return out_buf[out_pos];
}

int FlateStream::fill_buffer() {
  /* only fill the buffer if it has all been used */
  if (out_pos >= out_buf_len) {
    /* check if the flatestream has been exhausted */
    if (status == Z_STREAM_END) {
      return -1;
    }

    /* set to the beginning of out_buf */
    d_stream.avail_out = sizeof(out_buf);
    d_stream.next_out = out_buf;
    out_pos = 0;

    while (1) {
      /* buffer is empty so we need to fill it */
      if (d_stream.avail_in == 0) {
	int c;
	/* read from the source stream */
	while (d_stream.avail_in < sizeof(in_buf) && (c = str->getChar()) != EOF) {
	  in_buf[d_stream.avail_in++] = c;
	}
	d_stream.next_in = in_buf;
      }

      /* keep decompressing until we can't anymore */
      if (d_stream.avail_out == 0 || d_stream.avail_in == 0 || (status != Z_OK && status != Z_BUF_ERROR))
	break;
      status = inflate(&d_stream, Z_SYNC_FLUSH);
    }

    out_buf_len = sizeof(out_buf) - d_stream.avail_out;
    if (status != Z_OK && status != Z_STREAM_END)
      return -1;
    if (!out_buf_len)
      return -1;
  }

  return 0;
}

GooString *FlateStream::getPSFilter(int psLevel, const char *indent) {
  GooString *s;

  if (psLevel < 3 || pred) {
    return NULL;
  }
  if (!(s = str->getPSFilter(psLevel, indent))) {
    return NULL;
  }
  s->append(indent)->append("<< >> /FlateDecode filter\n");
  return s;
}

bool FlateStream::isBinary(bool last) {
  return str->isBinary(true);
}

#endif
