// example3.c - Demonstrates how to use miniz.c's deflate() and inflate() functions for simple file compression.
// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
// For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c.
#include "miniz.c"
#include <limits.h>

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint;

#define my_max(a,b) (((a) > (b)) ? (a) : (b))
#define my_min(a,b) (((a) < (b)) ? (a) : (b))

#define BUF_SIZE (1024 * 1024)
static uint8 s_inbuf[BUF_SIZE];
static uint8 s_outbuf[BUF_SIZE];

int main(int argc, char *argv[])
{
  const char *pMode;
  FILE *pInfile, *pOutfile;
  uint infile_size;
  int level = Z_BEST_COMPRESSION;
  z_stream stream;
  int p = 1;
  const char *pSrc_filename;
  const char *pDst_filename;
  long file_loc;

  printf("miniz.c version: %s\n", MZ_VERSION);

  if (argc < 4)
  {
    printf("Usage: example3 [options] [mode:c or d] infile outfile\n");
    printf("\nModes:\n");
    printf("c - Compresses file infile to a zlib stream in file outfile\n");
    printf("d - Decompress zlib stream in file infile to file outfile\n");
    printf("\nOptions:\n");
    printf("-l[0-10] - Compression level, higher values are slower.\n");
    return EXIT_FAILURE;
  }

  while ((p < argc) && (argv[p][0] == '-'))
  {
    switch (argv[p][1])
    {
      case 'l':
      {
        level = atoi(&argv[1][2]);
        if ((level < 0) || (level > 10))
        {
          printf("Invalid level!\n");
          return EXIT_FAILURE;
        }
        break;
      }
      default:
      {
        printf("Invalid option: %s\n", argv[p]);
        return EXIT_FAILURE;
      }
    }
    p++;
  }

  if ((argc - p) < 3)
  {
    printf("Must specify mode, input filename, and output filename after options!\n");
    return EXIT_FAILURE;
  }
  else if ((argc - p) > 3)
  {
    printf("Too many filenames!\n");
    return EXIT_FAILURE;
  }

  pMode = argv[p++];
  if (!strchr("cCdD", pMode[0]))
  {
    printf("Invalid mode!\n");
    return EXIT_FAILURE;
  }

  pSrc_filename = argv[p++];
  pDst_filename = argv[p++];

  printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename);

  // Open input file.
  pInfile = fopen(pSrc_filename, "rb");
  if (!pInfile)
  {
    printf("Failed opening input file!\n");
    return EXIT_FAILURE;
  }

  // Determine input file's size.
  fseek(pInfile, 0, SEEK_END);
  file_loc = ftell(pInfile);
  fseek(pInfile, 0, SEEK_SET);

  if ((file_loc < 0) || (file_loc > INT_MAX))
  {
     // This is not a limitation of miniz or tinfl, but this example.
     printf("File is too large to be processed by this example.\n");
     return EXIT_FAILURE;
  }

  infile_size = (uint)file_loc;

  // Open output file.
  pOutfile = fopen(pDst_filename, "wb");
  if (!pOutfile)
  {
    printf("Failed opening output file!\n");
    return EXIT_FAILURE;
  }

  printf("Input file size: %u\n", infile_size);

  // Init the z_stream
  memset(&stream, 0, sizeof(stream));
  stream.next_in = s_inbuf;
  stream.avail_in = 0;
  stream.next_out = s_outbuf;
  stream.avail_out = BUF_SIZE;

  if ((pMode[0] == 'c') || (pMode[0] == 'C'))
  {
    // Compression.
    uint infile_remaining = infile_size;

    if (deflateInit(&stream, level) != Z_OK)
    {
      printf("deflateInit() failed!\n");
      return EXIT_FAILURE;
    }

    for ( ; ; )
    {
      int status;
      if (!stream.avail_in)
      {
        // Input buffer is empty, so read more bytes from input file.
        uint n = my_min(BUF_SIZE, infile_remaining);

        if (fread(s_inbuf, 1, n, pInfile) != n)
        {
          printf("Failed reading from input file!\n");
          return EXIT_FAILURE;
        }

        stream.next_in = s_inbuf;
        stream.avail_in = n;

        infile_remaining -= n;
        //printf("Input bytes remaining: %u\n", infile_remaining);
      }

      status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH);

      if ((status == Z_STREAM_END) || (!stream.avail_out))
      {
        // Output buffer is full, or compression is done, so write buffer to output file.
        uint n = BUF_SIZE - stream.avail_out;
        if (fwrite(s_outbuf, 1, n, pOutfile) != n)
        {
          printf("Failed writing to output file!\n");
          return EXIT_FAILURE;
        }
        stream.next_out = s_outbuf;
        stream.avail_out = BUF_SIZE;
      }

      if (status == Z_STREAM_END)
        break;
      else if (status != Z_OK)
      {
        printf("deflate() failed with status %i!\n", status);
        return EXIT_FAILURE;
      }
    }

    if (deflateEnd(&stream) != Z_OK)
    {
      printf("deflateEnd() failed!\n");
      return EXIT_FAILURE;
    }
  }
  else if ((pMode[0] == 'd') || (pMode[0] == 'D'))
  {
    // Decompression.
    uint infile_remaining = infile_size;

    if (inflateInit(&stream))
    {
      printf("inflateInit() failed!\n");
      return EXIT_FAILURE;
    }

    for ( ; ; )
    {
      int status;
      if (!stream.avail_in)
      {
        // Input buffer is empty, so read more bytes from input file.
        uint n = my_min(BUF_SIZE, infile_remaining);

        if (fread(s_inbuf, 1, n, pInfile) != n)
        {
          printf("Failed reading from input file!\n");
          return EXIT_FAILURE;
        }

        stream.next_in = s_inbuf;
        stream.avail_in = n;

        infile_remaining -= n;
      }

      status = inflate(&stream, Z_SYNC_FLUSH);

      if ((status == Z_STREAM_END) || (!stream.avail_out))
      {
        // Output buffer is full, or decompression is done, so write buffer to output file.
        uint n = BUF_SIZE - stream.avail_out;
        if (fwrite(s_outbuf, 1, n, pOutfile) != n)
        {
          printf("Failed writing to output file!\n");
          return EXIT_FAILURE;
        }
        stream.next_out = s_outbuf;
        stream.avail_out = BUF_SIZE;
      }

      if (status == Z_STREAM_END)
        break;
      else if (status != Z_OK)
      {
        printf("inflate() failed with status %i!\n", status);
        return EXIT_FAILURE;
      }
    }

    if (inflateEnd(&stream) != Z_OK)
    {
      printf("inflateEnd() failed!\n");
      return EXIT_FAILURE;
    }
  }
  else
  {
    printf("Invalid mode!\n");
    return EXIT_FAILURE;
  }

  fclose(pInfile);
  if (EOF == fclose(pOutfile))
  {
    printf("Failed writing to output file!\n");
    return EXIT_FAILURE;
  }

  printf("Total input bytes: %u\n", (mz_uint32)stream.total_in);
  printf("Total output bytes: %u\n", (mz_uint32)stream.total_out);
  printf("Success.\n");
  return EXIT_SUCCESS;
}
