/* inflate.c -- zlib interface to inflate modules
 * Copyright (C) 1995 Mark Adler
 * For conditions of distribution and use, see copyright notice in zlib.h 
 */

#include "zutil.h"
#include "infblock.h"

struct inflate_blocks_state {int dummy;}; /* for buggy compilers */

/* inflate private state */
struct internal_state {

  /* mode */
  enum {
      METHOD,	/* waiting for method byte */
      FLAG,	/* waiting for flag byte */
      BLOCKS,	/* decompressing blocks */
      CHECK4,	/* four check bytes to go */
      CHECK3,	/* three check bytes to go */
      CHECK2,	/* two check bytes to go */
      CHECK1,	/* one check byte to go */
      DONE,	/* finished check, done */
      BAD}	/* got an error--stay here */
    mode;		/* current inflate mode */

  /* mode dependent information */
  union {
    uInt method;	/* if FLAGS, method byte */
    struct {
      uLong was;                /* computed check value */
      uLong need;               /* stream check value */
    } check;            /* if CHECK, check values to compare */
    uInt marker;	/* if BAD, inflateSync's marker bytes count */
  } sub;	/* submode */

  /* mode independent information */
  int  nowrap;		/* flag for no wrapper */
  uInt wbits;  		/* log2(window size)  (8..15, defaults to 15) */
  struct inflate_blocks_state
    *blocks;		/* current inflate_blocks state */

};


int inflateReset(z)
z_stream *z;
{
  uLong c;

  if (z == Z_NULL || z->state == Z_NULL)
    return Z_STREAM_ERROR;
  z->total_in = z->total_out = 0;
  z->msg = Z_NULL;
  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
  inflate_blocks_reset(z->state->blocks, z, &c);
  Trace((stderr, "inflate: reset\n"));
  return Z_OK;
}


int inflateEnd(z)
z_stream *z;
{
  uLong c;

  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
    return Z_STREAM_ERROR;
  if (z->state->blocks != Z_NULL)
    inflate_blocks_free(z->state->blocks, z, &c);
  ZFREE(z, z->state);
  z->state = Z_NULL;
  Trace((stderr, "inflate: end\n"));
  return Z_OK;
}


int inflateInit2(z, w)
z_stream *z;
int w;
{
  /* initialize state */
  if (z == Z_NULL)
    return Z_STREAM_ERROR;
  if (z->zalloc == Z_NULL) z->zalloc = zcalloc;
  if (z->zfree == Z_NULL) z->zfree = zcfree;
  if ((z->state = (struct internal_state *)
       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
    return Z_MEM_ERROR;
  z->state->blocks = Z_NULL;

  /* handle undocumented nowrap option (no zlib header or check) */
  z->state->nowrap = 0;
  if (w < 0)
  {
    w = - w;
    z->state->nowrap = 1;
  }

  /* set window size */
  if (w < 8 || w > 15)
  {
    inflateEnd(z);
    return Z_STREAM_ERROR;
  }
  z->state->wbits = (uInt)w;

  /* create inflate_blocks state */
  if ((z->state->blocks =
       inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
      == Z_NULL)
  {
    inflateEnd(z);
    return Z_MEM_ERROR;
  }
  Trace((stderr, "inflate: allocated\n"));

  /* reset state */
  inflateReset(z);
  return Z_OK;
}


int inflateInit(z)
z_stream *z;
{
  return inflateInit2(z, DEF_WBITS);
}


#define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;}
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)

int inflate(z, f)
z_stream *z;
int f;
{
  int r = f;	/* to avoid warning about unused f */
  uInt b;

  if (z == Z_NULL || z->next_in == Z_NULL)
    return Z_STREAM_ERROR;
  r = Z_BUF_ERROR;
  while (1) switch (z->state->mode)
  {
    case METHOD:
      NEEDBYTE
      if (((z->state->sub.method = NEXTBYTE) & 0xf != DEFLATED))
      {
        z->state->mode = BAD;
	z->msg = "unknown compression method";
	z->state->sub.marker = 5;	/* can't try inflateSync */
	break;
      }
      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
      {
        z->state->mode = BAD;
	z->msg = "invalid window size";
	z->state->sub.marker = 5;	/* can't try inflateSync */
	break;
      }
      z->state->mode = FLAG;
    case FLAG:
      NEEDBYTE
      if ((b = NEXTBYTE) & 0x20)
      {
        z->state->mode = BAD;
	z->msg = "invalid reserved bit";
	z->state->sub.marker = 5;	/* can't try inflateSync */
	break;
      }
      if (((z->state->sub.method << 8) + b) % 31)
      {
        z->state->mode = BAD;
	z->msg = "incorrect header check";
	z->state->sub.marker = 5;	/* can't try inflateSync */
	break;
      }
      Trace((stderr, "inflate: zlib header ok\n"));
      z->state->mode = BLOCKS;
    case BLOCKS:
      r = inflate_blocks(z->state->blocks, z, r);
      if (r == Z_DATA_ERROR)
      {
        z->state->mode = BAD;
	z->state->sub.marker = 0;	/* can try inflateSync */
	break;
      }
      if (r != Z_STREAM_END)
	return r;
      r = Z_OK;
      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
      if (z->state->nowrap)
      {
	z->state->mode = DONE;
	break;
      }
      z->state->mode = CHECK4;
    case CHECK4:
      NEEDBYTE
      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
      z->state->mode = CHECK3;
    case CHECK3:
      NEEDBYTE
      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
      z->state->mode = CHECK2;
    case CHECK2:
      NEEDBYTE
      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
      z->state->mode = CHECK1;
    case CHECK1:
      NEEDBYTE
      z->state->sub.check.need += (uLong)NEXTBYTE;

      if (z->state->sub.check.was != z->state->sub.check.need)
      {
        z->state->mode = BAD;
        z->msg = "incorrect data check";
	z->state->sub.marker = 5;	/* can't try inflateSync */
	break;
      }
      Trace((stderr, "inflate: zlib check ok\n"));
      z->state->mode = DONE;
    case DONE:
      return Z_STREAM_END;
    case BAD:
      return Z_DATA_ERROR;
    default:
      return Z_STREAM_ERROR;
  }
}


int inflateSync(z)
z_stream *z;
{
  uInt n;	/* number of bytes to look at */
  Byte *p;	/* pointer to bytes */
  uInt m;	/* number of marker bytes found in a row */
  uLong r, w;	/* temporaries to save total_in and total_out */

  /* set up */
  if (z == Z_NULL || z->state == Z_NULL)
    return Z_STREAM_ERROR;
  if (z->state->mode != BAD)
    z->state->sub.marker = 0;
  if ((n = z->avail_in) == 0)
    return Z_BUF_ERROR;
  p = z->next_in;
  m = z->state->sub.marker;

  /* search */
  while (n && m < 4)
  {
    if (*p == (m < 2 ? 0 : 0xff))
      m++;
    else if (*p || m > 2)
      m = 0;
    p++, n--;
  }

  /* restore */
  z->total_in += p - z->next_in;
  z->next_in = p;
  z->avail_in = n;
  z->state->sub.marker = m;

  /* return no joy or set up to restart on a new block */
  if (m != 4)
    return Z_DATA_ERROR;
  r = z->total_in;  w = z->total_out;
  inflateReset(z);
  z->total_in = r;  z->total_out = w;
  z->state->mode = BLOCKS;
  return Z_OK;
}
