/*
 * Copyright (C)2021 D. R. Commander.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name of the libjpeg-turbo Project nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <turbojpeg.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>


#define NUMXFORMS  3


int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
  tjhandle handle = NULL;
  unsigned char *dstBufs[NUMXFORMS] = { NULL, NULL, NULL };
  unsigned long dstSizes[NUMXFORMS] = { 0, 0, 0 }, maxBufSize;
  int width, height, jpegSubsamp, jpegColorspace, i, t;
  tjtransform transforms[NUMXFORMS];

  if ((handle = tjInitTransform()) == NULL)
    goto bailout;

  /* We ignore the return value of tjDecompressHeader3(), because some JPEG
     images may have unusual subsampling configurations that the TurboJPEG API
     cannot identify but can still transform. */
  tjDecompressHeader3(handle, data, size, &width, &height, &jpegSubsamp,
                      &jpegColorspace);

  /* Ignore 0-pixel images and images larger than 1 Megapixel.  Casting width
     to (uint64_t) prevents integer overflow if width * height > INT_MAX. */
  if (width < 1 || height < 1 || (uint64_t)width * height > 1048576)
    goto bailout;

  for (t = 0; t < NUMXFORMS; t++)
    memset(&transforms[t], 0, sizeof(tjtransform));

  transforms[0].op = TJXOP_NONE;
  transforms[0].options = TJXOPT_PROGRESSIVE | TJXOPT_COPYNONE;

  transforms[1].r.w = (width + 1) / 2;
  transforms[1].r.h = (height + 1) / 2;
  transforms[1].op = TJXOP_TRANSPOSE;
  transforms[1].options = TJXOPT_GRAY | TJXOPT_CROP;

  transforms[2].op = TJXOP_ROT90;
  transforms[2].options = TJXOPT_TRIM;

  tjTransform(handle, data, size, NUMXFORMS, dstBufs, dstSizes, transforms, 0);

  maxBufSize = tjBufSize(width, height, TJSAMP_444);

  /* Touch all of the output pixels in order to catch uninitialized reads
     when using MemorySanitizer. */
  for (t = 0; t < NUMXFORMS; t++) {
    int sum = 0;

    for (i = 0; i < dstSizes[t]; i++)
      sum += dstBufs[t][i];

    /* Prevent the code above from being optimized out.  This test should never
       be true, but the compiler doesn't know that. */
    if (sum > 255 * maxBufSize)
      goto bailout;

    tjFree(dstBufs[t]);
    dstBufs[t] = NULL;
  }

bailout:
  for (t = 0; t < NUMXFORMS; t++) {
    if (dstBufs[t]) tjFree(dstBufs[t]);
  }
  if (handle) tjDestroy(handle);
  return 0;
}
