/*
 * 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


extern "C" 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 = 0, height = 0, jpegSubsamp, jpegColorspace, i, t;
  tjtransform transforms[NUMXFORMS];
#if defined(__has_feature) && __has_feature(memory_sanitizer)
  char env[18] = "JSIMD_FORCENONE=1";

  /* The libjpeg-turbo SIMD extensions produce false positives with
     MemorySanitizer. */
  putenv(env);
#endif

  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;

  if (jpegSubsamp < 0 || jpegSubsamp >= TJ_NUMSAMP)
    jpegSubsamp = TJSAMP_444;

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

  transforms[0].op = TJXOP_NONE;
  transforms[0].options = TJXOPT_PROGRESSIVE | TJXOPT_COPYNONE;
  dstBufs[0] = (unsigned char *)malloc(tjBufSize(width, height, jpegSubsamp));
  if (!dstBufs[0])
    goto bailout;

  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 | TJXOPT_COPYNONE;
  dstBufs[1] =
    (unsigned char *)malloc(tjBufSize((width + 1) / 2, (height + 1) / 2,
                                      TJSAMP_GRAY));
  if (!dstBufs[1])
    goto bailout;

  transforms[2].op = TJXOP_ROT90;
  transforms[2].options = TJXOPT_TRIM | TJXOPT_COPYNONE;
  dstBufs[2] = (unsigned char *)malloc(tjBufSize(height, width, jpegSubsamp));
  if (!dstBufs[2])
    goto bailout;

  tjTransform(handle, data, size, NUMXFORMS, dstBufs, dstSizes, transforms,
              TJFLAG_LIMITSCANS | TJFLAG_NOREALLOC);

  maxBufSize = tjBufSize(width, height, jpegSubsamp);

  /* 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;
  }

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