/*
 * Copyright (c) 1994-1997 Sam Leffler
 * Copyright (c) 1994-1997 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Sam Leffler and Silicon Graphics.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */

#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN

#include "tiffiop.h"
#include <stdlib.h>

#ifdef JPEG_SUPPORT

/*
 * TIFF Library
 *
 * JPEG Compression support per TIFF Technical Note #2
 * (*not* per the original TIFF 6.0 spec).
 *
 * This file is simply an interface to the libjpeg library written by
 * the Independent JPEG Group.  You need release 5 or later of the IJG
 * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
 *
 * Contributed by Tom Lane <tgl@sss.pgh.pa.us>.
 */
#include <setjmp.h>

/* Settings that are independent of libjpeg ABI. Used when reinitializing the */
/* JPEGState from libjpegs 8 bit to libjpeg 12 bits, which have potentially */
/* different ABI */
typedef struct
{
    TIFFVGetMethod vgetparent;  /* super-class method */
    TIFFVSetMethod vsetparent;  /* super-class method */
    TIFFPrintMethod printdir;   /* super-class method */
    TIFFStripMethod defsparent; /* super-class method */
    TIFFTileMethod deftparent;  /* super-class method */

    /* pseudo-tag fields */
    void *jpegtables;           /* JPEGTables tag value, or NULL */
    uint32_t jpegtables_length; /* number of bytes in same */
    int jpegquality;            /* Compression quality level */
    int jpegcolormode;          /* Auto RGB<=>YCbCr convert? */
    int jpegtablesmode;         /* What to put in JPEGTables */

    int ycbcrsampling_fetched;
    int max_allowed_scan_number;
    int has_warned_about_progressive_mode;
} JPEGOtherSettings;

int TIFFFillStrip(TIFF *tif, uint32_t strip);
int TIFFFillTile(TIFF *tif, uint32_t tile);
int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings,
                      int scheme, int is_encode);
int TIFFJPEGIsFullStripRequired_12(TIFF *tif);

#if defined(USE_SYSTEM_LIBJPEG)
#include <jerror.h>
#include <jpeglib.h>
#else
#include "jerror.h"
#include "jpeglib.h"
#endif

/* Do optional compile-time version check */
#if defined(EXPECTED_JPEG_LIB_VERSION) && !defined(LIBJPEG_12_PATH)
#if EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION
#error EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION
#endif
#endif

/*
 * Do we want to do special processing suitable for when JSAMPLE is a
 * 16bit value?
 */

/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 3.0 which
 * adds a dual-mode 8/12 bit API in the same library.
 * (note: libjpeg-turbo 2.2 was actually released as 3.0)
 */

#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
#define JPEG_DUAL_MODE_8_12
/* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo
 * >= 3.0 Cf
 * https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b
 */
#undef BITS_IN_JSAMPLE
/* libjpeg-turbo >= 3.0 adds J12xxxx datatypes for the 12-bit mode. */
#if defined(FROM_TIF_JPEG_12)
#define BITS_IN_JSAMPLE 12
#define TIFF_JSAMPLE J12SAMPLE
#define TIFF_JSAMPARRAY J12SAMPARRAY
#define TIFF_JSAMPIMAGE J12SAMPIMAGE
#define TIFF_JSAMPROW J12SAMPROW
#else
#define BITS_IN_JSAMPLE 8
#define TIFF_JSAMPLE JSAMPLE
#define TIFF_JSAMPARRAY JSAMPARRAY
#define TIFF_JSAMPIMAGE JSAMPIMAGE
#define TIFF_JSAMPROW JSAMPROW
#endif
#else
#define TIFF_JSAMPLE JSAMPLE
#define TIFF_JSAMPARRAY JSAMPARRAY
#define TIFF_JSAMPIMAGE JSAMPIMAGE
#define TIFF_JSAMPROW JSAMPROW
#endif

#if defined(JPEG_LIB_MK1)
#define JPEG_LIB_MK1_OR_12BIT 1
#elif BITS_IN_JSAMPLE == 12
#define JPEG_LIB_MK1_OR_12BIT 1
#endif

/*
 * We are using width_in_blocks which is supposed to be private to
 * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has
 * renamed this member to width_in_data_units.  Since the header has
 * also renamed a define, use that unique define name in order to
 * detect the problem header and adjust to suit.
 */
#if defined(D_MAX_DATA_UNITS_IN_MCU)
#define width_in_blocks width_in_data_units
#endif

/*
 * On some machines it may be worthwhile to use _setjmp or sigsetjmp
 * in place of plain setjmp.  These macros will make it easier.
 */
#define SETJMP(jbuf) setjmp(jbuf)
#define LONGJMP(jbuf, code) longjmp(jbuf, code)
#define JMP_BUF jmp_buf

#ifndef TIFF_jpeg_destination_mgr_defined
#define TIFF_jpeg_destination_mgr_defined
typedef struct jpeg_destination_mgr jpeg_destination_mgr;
#endif

#ifndef TIFF_jpeg_source_mgr_defined
#define TIFF_jpeg_source_mgr_defined
typedef struct jpeg_source_mgr jpeg_source_mgr;
#endif

#ifndef TIFF_jpeg_error_mgr_defined
#define TIFF_jpeg_error_mgr_defined
typedef struct jpeg_error_mgr jpeg_error_mgr;
#endif

/*
 * State block for each open TIFF file using
 * libjpeg to do JPEG compression/decompression.
 *
 * libjpeg's visible state is either a jpeg_compress_struct
 * or jpeg_decompress_struct depending on which way we
 * are going.  comm can be used to refer to the fields
 * which are common to both.
 *
 * NB: cinfo is required to be the first member of JPEGState,
 *     so we can safely cast JPEGState* -> jpeg_xxx_struct*
 *     and vice versa!
 */
typedef struct
{
    union
    {
        struct jpeg_compress_struct c;
        struct jpeg_decompress_struct d;
        struct jpeg_common_struct comm;
    } cinfo; /* NB: must be first */
    int cinfo_initialized;

    jpeg_error_mgr err;  /* libjpeg error manager */
    JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */

    struct jpeg_progress_mgr progress;
    /*
     * The following two members could be a union, but
     * they're small enough that it's not worth the effort.
     */
    jpeg_destination_mgr dest; /* data dest for compression */
    jpeg_source_mgr src;       /* data source for decompression */
                               /* private state */
    TIFF *tif;                 /* back link needed by some code */
    uint16_t photometric;      /* copy of PhotometricInterpretation */
    uint16_t h_sampling;       /* luminance sampling factors */
    uint16_t v_sampling;
    tmsize_t bytesperline; /* decompressed bytes per scanline */
    /* pointers to intermediate buffers when processing downsampled data */
    TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS];
    int scancount; /* number of "scanlines" accumulated */
    int samplesperclump;

    JPEGOtherSettings otherSettings;

    int encode_raw_error;
} JPEGState;

#define JState(tif) ((JPEGState *)(tif)->tif_data)

static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
static int JPEGInitializeLibJPEG(TIFF *tif, int decode);
static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);

#define FIELD_JPEGTABLES (FIELD_CODEC + 0)

static const TIFFField jpegFields[] = {
    {TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8,
     FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL},
    {TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
     TRUE, FALSE, "", NULL},
    {TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
     FALSE, FALSE, "", NULL},
    {TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
     FALSE, FALSE, "", NULL}};

/*
 * libjpeg interface layer.
 *
 * We use setjmp/longjmp to return control to libtiff
 * when a fatal error is encountered within the JPEG
 * library.  We also direct libjpeg error and warning
 * messages through the appropriate libtiff handlers.
 */

/*
 * Error handling routines (these replace corresponding
 * IJG routines from jerror.c).  These are used for both
 * compression and decompression.
 */
static void TIFFjpeg_error_exit(j_common_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */
    char buffer[JMSG_LENGTH_MAX];

    (*cinfo->err->format_message)(cinfo, buffer);
    TIFFErrorExtR(sp->tif, "JPEGLib", "%s",
                  buffer);       /* display the error message */
    jpeg_abort(cinfo);           /* clean up libjpeg state */
    LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */
}

/*
 * This routine is invoked only for warning messages,
 * since error_exit does its own thing and trace_level
 * is never set > 0.
 */
static void TIFFjpeg_output_message(j_common_ptr cinfo)
{
    char buffer[JMSG_LENGTH_MAX];

    (*cinfo->err->format_message)(cinfo, buffer);
    TIFFWarningExtR(((JPEGState *)cinfo)->tif, "JPEGLib", "%s", buffer);
}

/* Avoid the risk of denial-of-service on crafted JPEGs with an insane */
/* number of scans. */
/* See
 * http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
 */
static void TIFFjpeg_progress_monitor(j_common_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */
    if (cinfo->is_decompressor)
    {
        const int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number;
        if (scan_no >= sp->otherSettings.max_allowed_scan_number)
        {
            TIFFErrorExtR(
                ((JPEGState *)cinfo)->tif, "TIFFjpeg_progress_monitor",
                "Scan number %d exceeds maximum scans (%d). This limit "
                "can be raised through the "
                "LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER "
                "environment variable.",
                scan_no, sp->otherSettings.max_allowed_scan_number);

            jpeg_abort(cinfo);           /* clean up libjpeg state */
            LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */
        }
    }
}

/*
 * Interface routines.  This layer of routines exists
 * primarily to limit side-effects from using setjmp.
 * Also, normal/error returns are converted into return
 * values per libtiff practice.
 */
#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op))
#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op), 1))

static int TIFFjpeg_create_compress(JPEGState *sp)
{
    /* initialize JPEG error handling */
    sp->cinfo.c.err = jpeg_std_error(&sp->err);
    sp->err.error_exit = TIFFjpeg_error_exit;
    sp->err.output_message = TIFFjpeg_output_message;

    /* set client_data to avoid UMR warning from tools like Purify */
    sp->cinfo.c.client_data = NULL;

    return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));
}

static int TIFFjpeg_create_decompress(JPEGState *sp)
{
    /* initialize JPEG error handling */
    sp->cinfo.d.err = jpeg_std_error(&sp->err);
    sp->err.error_exit = TIFFjpeg_error_exit;
    sp->err.output_message = TIFFjpeg_output_message;

    /* set client_data to avoid UMR warning from tools like Purify */
    sp->cinfo.d.client_data = NULL;

    return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));
}

static int TIFFjpeg_set_defaults(JPEGState *sp)
{
    return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c));
}

static int TIFFjpeg_set_colorspace(JPEGState *sp, J_COLOR_SPACE colorspace)
{
    return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace));
}

static int TIFFjpeg_set_quality(JPEGState *sp, int quality,
                                boolean force_baseline)
{
    return CALLVJPEG(sp,
                     jpeg_set_quality(&sp->cinfo.c, quality, force_baseline));
}

static int TIFFjpeg_suppress_tables(JPEGState *sp, boolean suppress)
{
    return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress));
}

static int TIFFjpeg_start_compress(JPEGState *sp, boolean write_all_tables)
{
    return CALLVJPEG(sp, jpeg_start_compress(&sp->cinfo.c, write_all_tables));
}

static int TIFFjpeg_write_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines,
                                    int num_lines)
{
#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
    return CALLJPEG(sp, -1,
                    (int)jpeg12_write_scanlines(&sp->cinfo.c, scanlines,
                                                (JDIMENSION)num_lines));
#else
    return CALLJPEG(sp, -1,
                    (int)jpeg_write_scanlines(&sp->cinfo.c, scanlines,
                                              (JDIMENSION)num_lines));
#endif
}

static int TIFFjpeg_write_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data,
                                   int num_lines)
{
#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
    return CALLJPEG(
        sp, -1,
        (int)jpeg12_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines));
#else
    return CALLJPEG(
        sp, -1,
        (int)jpeg_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines));
#endif
}

static int TIFFjpeg_finish_compress(JPEGState *sp)
{
    return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c));
}

static int TIFFjpeg_write_tables(JPEGState *sp)
{
    return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c));
}

static int TIFFjpeg_read_header(JPEGState *sp, boolean require_image)
{
    return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
}

static int TIFFjpeg_has_multiple_scans(JPEGState *sp)
{
    return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d));
}

static int TIFFjpeg_start_decompress(JPEGState *sp)
{
    const char *sz_max_allowed_scan_number;
    /* progress monitor */
    sp->cinfo.d.progress = &sp->progress;
    sp->progress.progress_monitor = TIFFjpeg_progress_monitor;
    sp->otherSettings.max_allowed_scan_number = 100;
    sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER");
    if (sz_max_allowed_scan_number)
        sp->otherSettings.max_allowed_scan_number =
            atoi(sz_max_allowed_scan_number);

    return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
}

static int TIFFjpeg_read_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines,
                                   int max_lines)
{
#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
    return CALLJPEG(sp, -1,
                    (int)jpeg12_read_scanlines(&sp->cinfo.d, scanlines,
                                               (JDIMENSION)max_lines));
#else
    return CALLJPEG(sp, -1,
                    (int)jpeg_read_scanlines(&sp->cinfo.d, scanlines,
                                             (JDIMENSION)max_lines));
#endif
}

static int TIFFjpeg_read_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data,
                                  int max_lines)
{
#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
    return CALLJPEG(
        sp, -1,
        (int)jpeg12_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines));
#else
    return CALLJPEG(
        sp, -1,
        (int)jpeg_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines));
#endif
}

static int TIFFjpeg_finish_decompress(JPEGState *sp)
{
    return CALLJPEG(sp, -1, (int)jpeg_finish_decompress(&sp->cinfo.d));
}

static int TIFFjpeg_abort(JPEGState *sp)
{
    return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm));
}

static int TIFFjpeg_destroy(JPEGState *sp)
{
    return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm));
}

static JSAMPARRAY TIFFjpeg_alloc_sarray(JPEGState *sp, int pool_id,
                                        JDIMENSION samplesperrow,
                                        JDIMENSION numrows)
{
    return CALLJPEG(sp, (JSAMPARRAY)NULL,
                    (*sp->cinfo.comm.mem->alloc_sarray)(
                        &sp->cinfo.comm, pool_id, samplesperrow, numrows));
}

/*
 * JPEG library destination data manager.
 * These routines direct compressed data from libjpeg into the
 * libtiff output buffer.
 */

static void std_init_destination(j_compress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;
    TIFF *tif = sp->tif;

    sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata;
    sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize;
}

static boolean std_empty_output_buffer(j_compress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;
    TIFF *tif = sp->tif;

    /* the entire buffer has been filled */
    tif->tif_rawcc = tif->tif_rawdatasize;

#ifdef IPPJ_HUFF
    /*
     * The Intel IPP performance library does not necessarily fill up
     * the whole output buffer on each pass, so only dump out the parts
     * that have been filled.
     *   http://trac.osgeo.org/gdal/wiki/JpegIPP
     */
    if (sp->dest.free_in_buffer >= 0)
    {
        tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer;
    }
#endif

    if (!TIFFFlushData1(tif))
        return FALSE;
    sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata;
    sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize;

    return (TRUE);
}

static void std_term_destination(j_compress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;
    TIFF *tif = sp->tif;

    tif->tif_rawcp = (uint8_t *)sp->dest.next_output_byte;
    tif->tif_rawcc = tif->tif_rawdatasize - (tmsize_t)sp->dest.free_in_buffer;
    /* NB: libtiff does the final buffer flush */
}

static void TIFFjpeg_data_dest(JPEGState *sp, TIFF *tif)
{
    (void)tif;
    sp->cinfo.c.dest = &sp->dest;
    sp->dest.init_destination = std_init_destination;
    sp->dest.empty_output_buffer = std_empty_output_buffer;
    sp->dest.term_destination = std_term_destination;
}

/*
 * Alternate destination manager for outputting to JPEGTables field.
 */

static void tables_init_destination(j_compress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;

    /* while building, otherSettings.jpegtables_length is allocated buffer size
     */
    sp->dest.next_output_byte = (JOCTET *)sp->otherSettings.jpegtables;
    sp->dest.free_in_buffer = (size_t)sp->otherSettings.jpegtables_length;
}

static boolean tables_empty_output_buffer(j_compress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;
    void *newbuf;

    /* the entire buffer has been filled; enlarge it by 1000 bytes */
    newbuf =
        _TIFFreallocExt(sp->tif, (void *)sp->otherSettings.jpegtables,
                        (tmsize_t)(sp->otherSettings.jpegtables_length + 1000));
    if (newbuf == NULL)
        ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
    sp->dest.next_output_byte =
        (JOCTET *)newbuf + sp->otherSettings.jpegtables_length;
    sp->dest.free_in_buffer = (size_t)1000;
    sp->otherSettings.jpegtables = newbuf;
    sp->otherSettings.jpegtables_length += 1000;
    return (TRUE);
}

static void tables_term_destination(j_compress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;

    /* set tables length to number of bytes actually emitted */
    sp->otherSettings.jpegtables_length -= (uint32_t)sp->dest.free_in_buffer;
}

static int TIFFjpeg_tables_dest(JPEGState *sp, TIFF *tif)
{
    (void)tif;
    /*
     * Allocate a working buffer for building tables.
     * Initial size is 1000 bytes, which is usually adequate.
     */
    if (sp->otherSettings.jpegtables)
        _TIFFfreeExt(tif, sp->otherSettings.jpegtables);
    sp->otherSettings.jpegtables_length = 1000;
    sp->otherSettings.jpegtables = (void *)_TIFFmallocExt(
        tif, (tmsize_t)sp->otherSettings.jpegtables_length);
    if (sp->otherSettings.jpegtables == NULL)
    {
        sp->otherSettings.jpegtables_length = 0;
        TIFFErrorExtR(sp->tif, "TIFFjpeg_tables_dest",
                      "No space for JPEGTables");
        return (0);
    }
    sp->cinfo.c.dest = &sp->dest;
    sp->dest.init_destination = tables_init_destination;
    sp->dest.empty_output_buffer = tables_empty_output_buffer;
    sp->dest.term_destination = tables_term_destination;
    return (1);
}

/*
 * JPEG library source data manager.
 * These routines supply compressed data to libjpeg.
 */

static void std_init_source(j_decompress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;
    TIFF *tif = sp->tif;

    sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata;
    sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
}

static boolean std_fill_input_buffer(j_decompress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;
    static const JOCTET dummy_EOI[2] = {0xFF, JPEG_EOI};

#ifdef IPPJ_HUFF
    /*
     * The Intel IPP performance library does not necessarily read the whole
     * input buffer in one pass, so it is possible to get here with data
     * yet to read.
     *
     * We just return without doing anything, until the entire buffer has
     * been read.
     * http://trac.osgeo.org/gdal/wiki/JpegIPP
     */
    if (sp->src.bytes_in_buffer > 0)
    {
        return (TRUE);
    }
#endif

    /*
     * Normally the whole strip/tile is read and so we don't need to do
     * a fill.  In the case of CHUNKY_STRIP_READ_SUPPORT we might not have
     * all the data, but the rawdata is refreshed between scanlines and
     * we push this into the io machinery in JPEGDecode().
     * http://trac.osgeo.org/gdal/ticket/3894
     */

    WARNMS(cinfo, JWRN_JPEG_EOF);
    /* insert a fake EOI marker */
    sp->src.next_input_byte = dummy_EOI;
    sp->src.bytes_in_buffer = 2;
    return (TRUE);
}

static void std_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
    JPEGState *sp = (JPEGState *)cinfo;

    if (num_bytes > 0)
    {
        if ((size_t)num_bytes > sp->src.bytes_in_buffer)
        {
            /* oops, buffer overrun */
            (void)std_fill_input_buffer(cinfo);
        }
        else
        {
            sp->src.next_input_byte += (size_t)num_bytes;
            sp->src.bytes_in_buffer -= (size_t)num_bytes;
        }
    }
}

static void std_term_source(j_decompress_ptr cinfo)
{
    /* No work necessary here */
    (void)cinfo;
}

static void TIFFjpeg_data_src(JPEGState *sp)
{
    sp->cinfo.d.src = &sp->src;
    sp->src.init_source = std_init_source;
    sp->src.fill_input_buffer = std_fill_input_buffer;
    sp->src.skip_input_data = std_skip_input_data;
    sp->src.resync_to_restart = jpeg_resync_to_restart;
    sp->src.term_source = std_term_source;
    sp->src.bytes_in_buffer = 0; /* for safety */
    sp->src.next_input_byte = NULL;
}

/*
 * Alternate source manager for reading from JPEGTables.
 * We can share all the code except for the init routine.
 */

static void tables_init_source(j_decompress_ptr cinfo)
{
    JPEGState *sp = (JPEGState *)cinfo;

    sp->src.next_input_byte = (const JOCTET *)sp->otherSettings.jpegtables;
    sp->src.bytes_in_buffer = (size_t)sp->otherSettings.jpegtables_length;
}

static void TIFFjpeg_tables_src(JPEGState *sp)
{
    TIFFjpeg_data_src(sp);
    sp->src.init_source = tables_init_source;
}

/*
 * Allocate downsampled-data buffers needed for downsampled I/O.
 * We use values computed in jpeg_start_compress or jpeg_start_decompress.
 * We use libjpeg's allocator so that buffers will be released automatically
 * when done with strip/tile.
 * This is also a handy place to compute samplesperclump, bytesperline.
 */
static int alloc_downsampled_buffers(TIFF *tif, jpeg_component_info *comp_info,
                                     int num_components)
{
    JPEGState *sp = JState(tif);
    int ci;
    jpeg_component_info *compptr;
    TIFF_JSAMPARRAY buf;
    int samples_per_clump = 0;

    for (ci = 0, compptr = comp_info; ci < num_components; ci++, compptr++)
    {
        samples_per_clump += compptr->h_samp_factor * compptr->v_samp_factor;
        buf = (TIFF_JSAMPARRAY)TIFFjpeg_alloc_sarray(
            sp, JPOOL_IMAGE, compptr->width_in_blocks * DCTSIZE,
            (JDIMENSION)(compptr->v_samp_factor * DCTSIZE));
        if (buf == NULL)
            return (0);
        sp->ds_buffer[ci] = buf;
    }
    sp->samplesperclump = samples_per_clump;
    return (1);
}

/*
 * JPEG Decoding.
 */

#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING

#define JPEG_MARKER_SOF0 0xC0
#define JPEG_MARKER_SOF1 0xC1
#define JPEG_MARKER_SOF2 0xC2
#define JPEG_MARKER_SOF9 0xC9
#define JPEG_MARKER_SOF10 0xCA
#define JPEG_MARKER_DHT 0xC4
#define JPEG_MARKER_SOI 0xD8
#define JPEG_MARKER_SOS 0xDA
#define JPEG_MARKER_DQT 0xDB
#define JPEG_MARKER_DRI 0xDD
#define JPEG_MARKER_APP0 0xE0
#define JPEG_MARKER_COM 0xFE
struct JPEGFixupTagsSubsamplingData
{
    TIFF *tif;
    void *buffer;
    uint32_t buffersize;
    uint8_t *buffercurrentbyte;
    uint32_t bufferbytesleft;
    uint64_t fileoffset;
    uint64_t filebytesleft;
    uint8_t filepositioned;
};
static void JPEGFixupTagsSubsampling(TIFF *tif);
static int
JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data);
static int
JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data,
                                 uint8_t *result);
static int
JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data,
                                 uint16_t *result);
static void
JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data,
                             uint16_t skiplength);

#endif

static int JPEGFixupTags(TIFF *tif)
{
#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
    JPEGState *sp = JState(tif);
    if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) &&
        (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) &&
        (tif->tif_dir.td_samplesperpixel == 3) &&
        !sp->otherSettings.ycbcrsampling_fetched)
        JPEGFixupTagsSubsampling(tif);
#endif

    return (1);
}

#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING

static void JPEGFixupTagsSubsampling(TIFF *tif)
{
    /*
     * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in
     * the TIFF tags, but still use non-default (2,2) values within the jpeg
     * data stream itself.  In order for TIFF applications to work properly
     * - for instance to get the strip buffer size right - it is imperative
     * that the subsampling be available before we start reading the image
     * data normally.  This function will attempt to analyze the first strip in
     * order to get the sampling values from the jpeg data stream.
     *
     * Note that JPEGPreDeocode() will produce a fairly loud warning when the
     * discovered sampling does not match the default sampling (2,2) or whatever
     * was actually in the tiff tags.
     *
     * See the bug in bugzilla for details:
     *
     * http://bugzilla.remotesensing.org/show_bug.cgi?id=168
     *
     * Frank Warmerdam, July 2002
     * Joris Van Damme, May 2007
     */
    static const char module[] = "JPEGFixupTagsSubsampling";
    struct JPEGFixupTagsSubsamplingData m;
    uint64_t fileoffset = TIFFGetStrileOffset(tif, 0);

    if (fileoffset == 0)
    {
        /* Do not even try to check if the first strip/tile does not
           yet exist, as occurs when GDAL has created a new NULL file
           for instance. */
        return;
    }

    m.tif = tif;
    m.buffersize = 2048;
    m.buffer = _TIFFmallocExt(tif, m.buffersize);
    if (m.buffer == NULL)
    {
        TIFFWarningExtR(tif, module,
                        "Unable to allocate memory for auto-correcting of "
                        "subsampling values; auto-correcting skipped");
        return;
    }
    m.buffercurrentbyte = NULL;
    m.bufferbytesleft = 0;
    m.fileoffset = fileoffset;
    m.filepositioned = 0;
    m.filebytesleft = TIFFGetStrileByteCount(tif, 0);
    if (!JPEGFixupTagsSubsamplingSec(&m))
        TIFFWarningExtR(
            tif, module,
            "Unable to auto-correct subsampling values, likely corrupt JPEG "
            "compressed data in first strip/tile; auto-correcting skipped");
    _TIFFfreeExt(tif, m.buffer);
}

static int
JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data)
{
    static const char module[] = "JPEGFixupTagsSubsamplingSec";
    uint8_t m;
    while (1)
    {
        while (1)
        {
            if (!JPEGFixupTagsSubsamplingReadByte(data, &m))
                return (0);
            if (m == 255)
                break;
        }
        while (1)
        {
            if (!JPEGFixupTagsSubsamplingReadByte(data, &m))
                return (0);
            if (m != 255)
                break;
        }
        switch (m)
        {
            case JPEG_MARKER_SOI:
                /* this type of marker has no data and should be skipped */
                break;
            case JPEG_MARKER_COM:
            case JPEG_MARKER_APP0:
            case JPEG_MARKER_APP0 + 1:
            case JPEG_MARKER_APP0 + 2:
            case JPEG_MARKER_APP0 + 3:
            case JPEG_MARKER_APP0 + 4:
            case JPEG_MARKER_APP0 + 5:
            case JPEG_MARKER_APP0 + 6:
            case JPEG_MARKER_APP0 + 7:
            case JPEG_MARKER_APP0 + 8:
            case JPEG_MARKER_APP0 + 9:
            case JPEG_MARKER_APP0 + 10:
            case JPEG_MARKER_APP0 + 11:
            case JPEG_MARKER_APP0 + 12:
            case JPEG_MARKER_APP0 + 13:
            case JPEG_MARKER_APP0 + 14:
            case JPEG_MARKER_APP0 + 15:
            case JPEG_MARKER_DQT:
            case JPEG_MARKER_SOS:
            case JPEG_MARKER_DHT:
            case JPEG_MARKER_DRI:
                /* this type of marker has data, but it has no use to us and
                 * should be skipped */
                {
                    uint16_t n;
                    if (!JPEGFixupTagsSubsamplingReadWord(data, &n))
                        return (0);
                    if (n < 2)
                        return (0);
                    n -= 2;
                    if (n > 0)
                        JPEGFixupTagsSubsamplingSkip(data, n);
                }
                break;
            case JPEG_MARKER_SOF0:  /* Baseline sequential Huffman */
            case JPEG_MARKER_SOF1:  /* Extended sequential Huffman */
            case JPEG_MARKER_SOF2:  /* Progressive Huffman: normally not allowed
                                       by  TechNote, but that doesn't hurt
                                       supporting it */
            case JPEG_MARKER_SOF9:  /* Extended sequential arithmetic */
            case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not
                                       allowed by TechNote, but that doesn't
                                       hurt supporting it */
                /* this marker contains the subsampling factors we're scanning
                 * for */
                {
                    uint16_t n;
                    uint16_t o;
                    uint8_t p;
                    uint8_t ph, pv;
                    if (!JPEGFixupTagsSubsamplingReadWord(data, &n))
                        return (0);
                    if (n != 8 + data->tif->tif_dir.td_samplesperpixel * 3)
                        return (0);
                    JPEGFixupTagsSubsamplingSkip(data, 7);
                    if (!JPEGFixupTagsSubsamplingReadByte(data, &p))
                        return (0);
                    ph = (p >> 4);
                    pv = (p & 15);
                    JPEGFixupTagsSubsamplingSkip(data, 1);
                    for (o = 1; o < data->tif->tif_dir.td_samplesperpixel; o++)
                    {
                        JPEGFixupTagsSubsamplingSkip(data, 1);
                        if (!JPEGFixupTagsSubsamplingReadByte(data, &p))
                            return (0);
                        if (p != 0x11)
                        {
                            TIFFWarningExtR(data->tif, module,
                                            "Subsampling values inside JPEG "
                                            "compressed data "
                                            "have no TIFF equivalent, "
                                            "auto-correction of TIFF "
                                            "subsampling values failed");
                            return (1);
                        }
                        JPEGFixupTagsSubsamplingSkip(data, 1);
                    }
                    if (((ph != 1) && (ph != 2) && (ph != 4)) ||
                        ((pv != 1) && (pv != 2) && (pv != 4)))
                    {
                        TIFFWarningExtR(data->tif, module,
                                        "Subsampling values inside JPEG "
                                        "compressed data have no TIFF "
                                        "equivalent, auto-correction of TIFF "
                                        "subsampling values failed");
                        return (1);
                    }
                    if ((ph != data->tif->tif_dir.td_ycbcrsubsampling[0]) ||
                        (pv != data->tif->tif_dir.td_ycbcrsubsampling[1]))
                    {
                        TIFFWarningExtR(
                            data->tif, module,
                            "Auto-corrected former TIFF subsampling values "
                            "[%" PRIu16 ",%" PRIu16
                            "] to match subsampling values inside JPEG "
                            "compressed data [%" PRIu8 ",%" PRIu8 "]",
                            data->tif->tif_dir.td_ycbcrsubsampling[0],
                            data->tif->tif_dir.td_ycbcrsubsampling[1], ph, pv);
                        data->tif->tif_dir.td_ycbcrsubsampling[0] = ph;
                        data->tif->tif_dir.td_ycbcrsubsampling[1] = pv;
                    }
                }
                return (1);
            default:
                return (0);
        }
    }
}

static int
JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data,
                                 uint8_t *result)
{
    if (data->bufferbytesleft == 0)
    {
        uint32_t m;
        if (data->filebytesleft == 0)
            return (0);
        if (!data->filepositioned)
        {
            if (TIFFSeekFile(data->tif, data->fileoffset, SEEK_SET) ==
                (toff_t)-1)
            {
                return 0;
            }
            data->filepositioned = 1;
        }
        m = data->buffersize;
        if ((uint64_t)m > data->filebytesleft)
            m = (uint32_t)data->filebytesleft;
        assert(m < 0x80000000UL);
        if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m)
            return (0);
        data->buffercurrentbyte = data->buffer;
        data->bufferbytesleft = m;
        data->fileoffset += m;
        data->filebytesleft -= m;
    }
    *result = *data->buffercurrentbyte;
    data->buffercurrentbyte++;
    data->bufferbytesleft--;
    return (1);
}

static int
JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data,
                                 uint16_t *result)
{
    uint8_t ma;
    uint8_t mb;
    if (!JPEGFixupTagsSubsamplingReadByte(data, &ma))
        return (0);
    if (!JPEGFixupTagsSubsamplingReadByte(data, &mb))
        return (0);
    *result = (ma << 8) | mb;
    return (1);
}

static void
JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data,
                             uint16_t skiplength)
{
    if ((uint32_t)skiplength <= data->bufferbytesleft)
    {
        data->buffercurrentbyte += skiplength;
        data->bufferbytesleft -= skiplength;
    }
    else
    {
        uint16_t m;
        m = (uint16_t)(skiplength - data->bufferbytesleft);
        if (m <= data->filebytesleft)
        {
            data->bufferbytesleft = 0;
            data->fileoffset += m;
            data->filebytesleft -= m;
            data->filepositioned = 0;
        }
        else
        {
            data->bufferbytesleft = 0;
            data->filebytesleft = 0;
        }
    }
}

#endif

static int JPEGSetupDecode(TIFF *tif)
{
    JPEGState *sp = JState(tif);
    TIFFDirectory *td = &tif->tif_dir;

#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12)
    if (tif->tif_dir.td_bitspersample == 12)
    {
        /* We pass a pointer to a copy of otherSettings, since */
        /* TIFFReInitJPEG_12() will clear sp */
        JPEGOtherSettings savedOtherSettings = sp->otherSettings;
        return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 0);
    }
#endif

    JPEGInitializeLibJPEG(tif, TRUE);

    assert(sp != NULL);
    assert(sp->cinfo.comm.is_decompressor);

    /* Read JPEGTables if it is present */
    if (TIFFFieldSet(tif, FIELD_JPEGTABLES))
    {
        TIFFjpeg_tables_src(sp);
        if (TIFFjpeg_read_header(sp, FALSE) != JPEG_HEADER_TABLES_ONLY)
        {
            TIFFErrorExtR(tif, "JPEGSetupDecode", "Bogus JPEGTables field");
            return (0);
        }
    }

    /* Grab parameters that are same for all strips/tiles */
    sp->photometric = td->td_photometric;
    switch (sp->photometric)
    {
        case PHOTOMETRIC_YCBCR:
            sp->h_sampling = td->td_ycbcrsubsampling[0];
            sp->v_sampling = td->td_ycbcrsubsampling[1];
            break;
        default:
            /* TIFF 6.0 forbids subsampling of all other color spaces */
            sp->h_sampling = 1;
            sp->v_sampling = 1;
            break;
    }

    /* Set up for reading normal data */
    TIFFjpeg_data_src(sp);
    tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
    return (1);
}

/* Returns 1 if the full strip should be read, even when doing scanline per */
/* scanline decoding. This happens when the JPEG stream uses multiple scans. */
/* Currently only called in CHUNKY_STRIP_READ_SUPPORT mode through */
/* scanline interface. */
/* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */
/* tif->tif_rawcc members. */
/* Can be called independently of the usual setup/predecode/decode states */
int TIFFJPEGIsFullStripRequired(TIFF *tif)
{
    int ret;
    JPEGState state;

#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12)
    if (tif->tif_dir.td_bitspersample == 12)
        return TIFFJPEGIsFullStripRequired_12(tif);
#endif

    memset(&state, 0, sizeof(JPEGState));
    state.tif = tif;

    TIFFjpeg_create_decompress(&state);

    TIFFjpeg_data_src(&state);

    if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK)
    {
        TIFFjpeg_destroy(&state);
        return (0);
    }
    ret = TIFFjpeg_has_multiple_scans(&state);

    TIFFjpeg_destroy(&state);

    return ret;
}

/*
 * Set up for decoding a strip or tile.
 */
/*ARGSUSED*/ static int JPEGPreDecode(TIFF *tif, uint16_t s)
{
    JPEGState *sp = JState(tif);
    TIFFDirectory *td = &tif->tif_dir;
    static const char module[] = "JPEGPreDecode";
    uint32_t segment_width, segment_height;
    int downsampled_output;
    int ci;

    assert(sp != NULL);

    if (sp->cinfo.comm.is_decompressor == 0)
    {
        tif->tif_setupdecode(tif);
    }

    assert(sp->cinfo.comm.is_decompressor);
    /*
     * Reset decoder state from any previous strip/tile,
     * in case application didn't read the whole strip.
     */
    if (!TIFFjpeg_abort(sp))
        return (0);
    /*
     * Read the header for this strip/tile.
     */

    if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK)
        return (0);

    tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
    tif->tif_rawcc = sp->src.bytes_in_buffer;

    /*
     * Check image parameters and set decompression parameters.
     */
    if (isTiled(tif))
    {
        segment_width = td->td_tilewidth;
        segment_height = td->td_tilelength;
        sp->bytesperline = TIFFTileRowSize(tif);
    }
    else
    {
        segment_width = td->td_imagewidth;
        segment_height = td->td_imagelength - tif->tif_row;
        if (segment_height > td->td_rowsperstrip)
            segment_height = td->td_rowsperstrip;
        sp->bytesperline = TIFFScanlineSize(tif);
    }
    if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
    {
        /*
         * For PC 2, scale down the expected strip/tile size
         * to match a downsampled component
         */
        if (sp->h_sampling == 0 || sp->v_sampling == 0)
        {
            TIFFErrorExtR(tif, module,
                          "JPEG horizontal or vertical sampling is zero");
            return (0);
        }
        segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
        segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
    }
    if (sp->cinfo.d.image_width < segment_width ||
        sp->cinfo.d.image_height < segment_height)
    {
        TIFFWarningExtR(tif, module,
                        "Improper JPEG strip/tile size, "
                        "expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
                        segment_width, segment_height, sp->cinfo.d.image_width,
                        sp->cinfo.d.image_height);
    }
    if (sp->cinfo.d.image_width == segment_width &&
        sp->cinfo.d.image_height > segment_height &&
        tif->tif_row + segment_height == td->td_imagelength && !isTiled(tif))
    {
        /* Some files have a last strip, that should be truncated, */
        /* but their JPEG codestream has still the maximum strip */
        /* height. Warn about this as this is non compliant, but */
        /* we can safely recover from that. */
        TIFFWarningExtR(tif, module,
                        "JPEG strip size exceeds expected dimensions,"
                        " expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
                        segment_width, segment_height, sp->cinfo.d.image_width,
                        sp->cinfo.d.image_height);
    }
    else if (sp->cinfo.d.image_width > segment_width ||
             sp->cinfo.d.image_height > segment_height)
    {
        /*
         * This case could be dangerous, if the strip or tile size has
         * been reported as less than the amount of data jpeg will
         * return, some potential security issues arise. Catch this
         * case and error out.
         */
        TIFFErrorExtR(tif, module,
                      "JPEG strip/tile size exceeds expected dimensions,"
                      " expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
                      segment_width, segment_height, sp->cinfo.d.image_width,
                      sp->cinfo.d.image_height);
        return (0);
    }
    if (sp->cinfo.d.num_components !=
        (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
                                                    : 1))
    {
        TIFFErrorExtR(tif, module, "Improper JPEG component count");
        return (0);
    }
#ifdef JPEG_LIB_MK1
    if (12 != td->td_bitspersample && 8 != td->td_bitspersample)
    {
        TIFFErrorExtR(tif, module, "Improper JPEG data precision");
        return (0);
    }
    sp->cinfo.d.data_precision = td->td_bitspersample;
    sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
#else
    if (sp->cinfo.d.data_precision != td->td_bitspersample)
    {
        TIFFErrorExtR(tif, module, "Improper JPEG data precision");
        return (0);
    }
#endif

    if (sp->cinfo.d.progressive_mode &&
        !sp->otherSettings.has_warned_about_progressive_mode)
    {
        TIFFWarningExtR(tif, module,
                        "The JPEG strip/tile is encoded with progressive mode, "
                        "which is normally not legal for JPEG-in-TIFF.\n"
                        "libtiff should be able to decode it, but it might "
                        "cause compatibility issues with other readers");
        sp->otherSettings.has_warned_about_progressive_mode = TRUE;
    }

    /* In some cases, libjpeg needs to allocate a lot of memory */
    /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
     */
    if (TIFFjpeg_has_multiple_scans(sp))
    {
        /* In this case libjpeg will need to allocate memory or backing */
        /* store for all coefficients */
        /* See call to jinit_d_coef_controller() from master_selection() */
        /* in libjpeg */

        /* 1 MB for regular libjpeg usage */
        toff_t nRequiredMemory = 1024 * 1024;

        for (ci = 0; ci < sp->cinfo.d.num_components; ci++)
        {
            const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]);
            if (compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0)
            {
                nRequiredMemory +=
                    (toff_t)(((compptr->width_in_blocks +
                               compptr->h_samp_factor - 1) /
                              compptr->h_samp_factor)) *
                    ((compptr->height_in_blocks + compptr->v_samp_factor - 1) /
                     compptr->v_samp_factor) *
                    sizeof(JBLOCK);
            }
        }

        if (sp->cinfo.d.mem->max_memory_to_use > 0 &&
            nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) &&
            getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL)
        {
            TIFFErrorExtR(
                tif, module,
                "Reading this image would require libjpeg to allocate "
                "at least %" PRIu64 " bytes. "
                "This is disabled since above the %ld threshold. "
                "You may override this restriction by defining the "
                "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
                "or setting the JPEGMEM environment variable to a value "
                "greater "
                "or equal to '%" PRIu64 "M'",
                nRequiredMemory, sp->cinfo.d.mem->max_memory_to_use,
                (nRequiredMemory + 1000000u - 1u) / 1000000u);
            return 0;
        }
    }

    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
    {
        /* Component 0 should have expected sampling factors */
        if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
            sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling)
        {
            TIFFErrorExtR(tif, module,
                          "Improper JPEG sampling factors %d,%d\n"
                          "Apparently should be %" PRIu16 ",%" PRIu16 ".",
                          sp->cinfo.d.comp_info[0].h_samp_factor,
                          sp->cinfo.d.comp_info[0].v_samp_factor,
                          sp->h_sampling, sp->v_sampling);
            return (0);
        }
        /* Rest should have sampling factors 1,1 */
        for (ci = 1; ci < sp->cinfo.d.num_components; ci++)
        {
            if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 ||
                sp->cinfo.d.comp_info[ci].v_samp_factor != 1)
            {
                TIFFErrorExtR(tif, module, "Improper JPEG sampling factors");
                return (0);
            }
        }
    }
    else
    {
        /* PC 2's single component should have sampling factors 1,1 */
        if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 ||
            sp->cinfo.d.comp_info[0].v_samp_factor != 1)
        {
            TIFFErrorExtR(tif, module, "Improper JPEG sampling factors");
            return (0);
        }
    }
    downsampled_output = FALSE;
    if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
        sp->photometric == PHOTOMETRIC_YCBCR &&
        sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB)
    {
        /* Convert YCbCr to RGB */
        sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
        sp->cinfo.d.out_color_space = JCS_RGB;
    }
    else
    {
        /* Suppress colorspace handling */
        sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
        sp->cinfo.d.out_color_space = JCS_UNKNOWN;
        if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
            (sp->h_sampling != 1 || sp->v_sampling != 1))
            downsampled_output = TRUE;
        /* XXX what about up-sampling? */
    }
    if (downsampled_output)
    {
        /* Need to use raw-data interface to libjpeg */
        sp->cinfo.d.raw_data_out = TRUE;
#if JPEG_LIB_VERSION >= 70
        sp->cinfo.d.do_fancy_upsampling = FALSE;
#endif /* JPEG_LIB_VERSION >= 70 */
        tif->tif_decoderow = DecodeRowError;
        tif->tif_decodestrip = JPEGDecodeRaw;
        tif->tif_decodetile = JPEGDecodeRaw;
    }
    else
    {
        /* Use normal interface to libjpeg */
        sp->cinfo.d.raw_data_out = FALSE;
        tif->tif_decoderow = JPEGDecode;
        tif->tif_decodestrip = JPEGDecode;
        tif->tif_decodetile = JPEGDecode;
    }
    /* Start JPEG decompressor */
    if (!TIFFjpeg_start_decompress(sp))
        return (0);
    /* Allocate downsampled-data buffers if needed */
    if (downsampled_output)
    {
        if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
                                       sp->cinfo.d.num_components))
            return (0);
        sp->scancount = DCTSIZE; /* mark buffer empty */
    }
    return (1);
}

/*
 * Decode a chunk of pixels.
 * "Standard" case: returned data is not downsampled.
 */
#if !JPEG_LIB_MK1_OR_12BIT
static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
    JPEGState *sp = JState(tif);
    tmsize_t nrows;
    (void)s;

    /*
    ** Update available information, buffer may have been refilled
    ** between decode requests
    */
    sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp;
    sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;

    if (sp->bytesperline == 0)
    {
        memset(buf, 0, (size_t)cc);
        return 0;
    }

    nrows = cc / sp->bytesperline;
    if (cc % sp->bytesperline)
        TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read");

    if (nrows > (tmsize_t)sp->cinfo.d.image_height)
        nrows = sp->cinfo.d.image_height;

    /* data is expected to be read in multiples of a scanline */
    if (nrows)
    {
        do
        {
            /*
             * In the libjpeg6b-9a 8bit case.  We read directly into
             * the TIFF buffer.
             */
            JSAMPROW bufptr = (JSAMPROW)buf;

            if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
            {
                memset(buf, 0, (size_t)cc);
                return (0);
            }

            ++tif->tif_row;
            buf += sp->bytesperline;
            cc -= sp->bytesperline;
        } while (--nrows > 0);
    }

    /* Update information on consumed data */
    tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
    tif->tif_rawcc = sp->src.bytes_in_buffer;

    /* Close down the decompressor if we've finished the strip or tile. */
    return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
           TIFFjpeg_finish_decompress(sp);
}
#endif /* !JPEG_LIB_MK1_OR_12BIT */

#if JPEG_LIB_MK1_OR_12BIT
/*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc,
                                   uint16_t s)
{
    JPEGState *sp = JState(tif);
    tmsize_t nrows;
    (void)s;

    /*
    ** Update available information, buffer may have been refilled
    ** between decode requests
    */
    sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp;
    sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;

    if (sp->bytesperline == 0)
    {
        memset(buf, 0, (size_t)cc);
        return 0;
    }

    nrows = cc / sp->bytesperline;
    if (cc % sp->bytesperline)
        TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read");

    if (nrows > (tmsize_t)sp->cinfo.d.image_height)
        nrows = sp->cinfo.d.image_height;

    /* data is expected to be read in multiples of a scanline */
    if (nrows)
    {
        TIFF_JSAMPROW line_work_buf = NULL;

        /*
         * For 6B, only use temporary buffer for 12 bit imagery.
         * For Mk1 always use it.
         */
        if (sp->cinfo.d.data_precision == 12)
        {
            line_work_buf = (TIFF_JSAMPROW)_TIFFmallocExt(
                tif, sizeof(short) * sp->cinfo.d.output_width *
                         sp->cinfo.d.num_components);
        }

        do
        {
            if (line_work_buf != NULL)
            {
                /*
                 * In the MK1 case, we always read into a 16bit
                 * buffer, and then pack down to 12bit or 8bit.
                 * In 6B case we only read into 16 bit buffer
                 * for 12bit data, which we need to repack.
                 */
                if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
                {
                    memset(buf, 0, (size_t)cc);
                    return (0);
                }

                if (sp->cinfo.d.data_precision == 12)
                {
                    int value_pairs = (sp->cinfo.d.output_width *
                                       sp->cinfo.d.num_components) /
                                      2;
                    int iPair;

                    for (iPair = 0; iPair < value_pairs; iPair++)
                    {
                        unsigned char *out_ptr =
                            ((unsigned char *)buf) + iPair * 3;
                        TIFF_JSAMPLE *in_ptr = line_work_buf + iPair * 2;

                        out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
                        out_ptr[1] =
                            (unsigned char)(((in_ptr[0] & 0xf) << 4) |
                                            ((in_ptr[1] & 0xf00) >> 8));
                        out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0));
                    }
                }
                else if (sp->cinfo.d.data_precision == 8)
                {
                    int value_count =
                        (sp->cinfo.d.output_width * sp->cinfo.d.num_components);
                    int iValue;

                    for (iValue = 0; iValue < value_count; iValue++)
                    {
                        ((unsigned char *)buf)[iValue] =
                            line_work_buf[iValue] & 0xff;
                    }
                }
            }

            ++tif->tif_row;
            buf += sp->bytesperline;
            cc -= sp->bytesperline;
        } while (--nrows > 0);

        if (line_work_buf != NULL)
            _TIFFfreeExt(tif, line_work_buf);
    }

    /* Update information on consumed data */
    tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
    tif->tif_rawcc = sp->src.bytes_in_buffer;

    /* Close down the decompressor if we've finished the strip or tile. */
    return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
           TIFFjpeg_finish_decompress(sp);
}
#endif /* JPEG_LIB_MK1_OR_12BIT */

/*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc,
                                       uint16_t s)

{
    (void)buf;
    (void)cc;
    (void)s;

    TIFFErrorExtR(
        tif, "TIFFReadScanline",
        "scanline oriented access is not supported for downsampled JPEG "
        "compressed images, consider enabling TIFFTAG_JPEGCOLORMODE as "
        "JPEGCOLORMODE_RGB.");
    return 0;
}

/*
 * Decode a chunk of pixels.
 * Returned data is downsampled per sampling factors.
 */
/*ARGSUSED*/ static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc,
                                      uint16_t s)
{
    JPEGState *sp = JState(tif);
    tmsize_t nrows;
    TIFFDirectory *td = &tif->tif_dir;
    (void)s;

    nrows = sp->cinfo.d.image_height;
    /* For last strip, limit number of rows to its truncated height */
    /* even if the codestream height is larger (which is not compliant, */
    /* but that we tolerate) */
    if ((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif))
        nrows = td->td_imagelength - tif->tif_row;

#if defined(JPEG_LIB_MK1_OR_12BIT)
    unsigned short *tmpbuf = NULL;
#endif

    /* data is expected to be read in multiples of a scanline */
    if (nrows != 0)
    {

        /* Cb,Cr both have sampling factors 1, so this is correct */
        JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
        int samples_per_clump = sp->samplesperclump;

#if defined(JPEG_LIB_MK1_OR_12BIT)
        tmpbuf = _TIFFmallocExt(tif, sizeof(unsigned short) *
                                         sp->cinfo.d.output_width *
                                         sp->cinfo.d.num_components);
        if (tmpbuf == NULL)
        {
            TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory");
            return 0;
        }
#endif

        do
        {
            jpeg_component_info *compptr;
            int ci, clumpoffset;

            if (cc < sp->bytesperline)
            {
                TIFFErrorExtR(
                    tif, "JPEGDecodeRaw",
                    "application buffer not large enough for all data.");
                goto error;
            }

            /* Reload downsampled-data buffer if needed */
            if (sp->scancount >= DCTSIZE)
            {
                int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;
                if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n)
                    goto error;
                sp->scancount = 0;
            }
            /*
             * Fastest way to unseparate data is to make one pass
             * over the scanline for each row of each component.
             */
            clumpoffset = 0; /* first sample in clump */
            for (ci = 0, compptr = sp->cinfo.d.comp_info;
                 ci < sp->cinfo.d.num_components; ci++, compptr++)
            {
                int hsamp = compptr->h_samp_factor;
                int vsamp = compptr->v_samp_factor;
                int ypos;

                for (ypos = 0; ypos < vsamp; ypos++)
                {
                    TIFF_JSAMPLE *inptr =
                        sp->ds_buffer[ci][sp->scancount * vsamp + ypos];
                    JDIMENSION nclump;
#if defined(JPEG_LIB_MK1_OR_12BIT)
                    TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)tmpbuf + clumpoffset;
#else
                    TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)buf + clumpoffset;
                    if (cc < (tmsize_t)(clumpoffset +
                                        (tmsize_t)samples_per_clump *
                                            (clumps_per_line - 1) +
                                        hsamp))
                    {
                        TIFFErrorExtR(
                            tif, "JPEGDecodeRaw",
                            "application buffer not large enough for all data, "
                            "possible subsampling issue");
                        goto error;
                    }
#endif

                    if (hsamp == 1)
                    {
                        /* fast path for at least Cb and Cr */
                        for (nclump = clumps_per_line; nclump-- > 0;)
                        {
                            outptr[0] = *inptr++;
                            outptr += samples_per_clump;
                        }
                    }
                    else
                    {
                        int xpos;

                        /* general case */
                        for (nclump = clumps_per_line; nclump-- > 0;)
                        {
                            for (xpos = 0; xpos < hsamp; xpos++)
                                outptr[xpos] = *inptr++;
                            outptr += samples_per_clump;
                        }
                    }
                    clumpoffset += hsamp;
                }
            }

#if defined(JPEG_LIB_MK1_OR_12BIT)
            {
                if (sp->cinfo.d.data_precision == 8)
                {
                    int i = 0;
                    int len =
                        sp->cinfo.d.output_width * sp->cinfo.d.num_components;
                    for (i = 0; i < len; i++)
                    {
                        ((unsigned char *)buf)[i] = tmpbuf[i] & 0xff;
                    }
                }
                else
                { /* 12-bit */
                    int value_pairs = (sp->cinfo.d.output_width *
                                       sp->cinfo.d.num_components) /
                                      2;
                    int iPair;
                    for (iPair = 0; iPair < value_pairs; iPair++)
                    {
                        unsigned char *out_ptr =
                            ((unsigned char *)buf) + iPair * 3;
                        TIFF_JSAMPLE *in_ptr =
                            (TIFF_JSAMPLE *)(tmpbuf + iPair * 2);
                        out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
                        out_ptr[1] =
                            (unsigned char)(((in_ptr[0] & 0xf) << 4) |
                                            ((in_ptr[1] & 0xf00) >> 8));
                        out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0));
                    }
                }
            }
#endif

            sp->scancount++;
            tif->tif_row += sp->v_sampling;

            buf += sp->bytesperline;
            cc -= sp->bytesperline;

            nrows -= sp->v_sampling;
        } while (nrows > 0);

#if defined(JPEG_LIB_MK1_OR_12BIT)
        _TIFFfreeExt(tif, tmpbuf);
#endif
    }

    /* Close down the decompressor if done. */
    return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
           TIFFjpeg_finish_decompress(sp);

error:
#if defined(JPEG_LIB_MK1_OR_12BIT)
    _TIFFfreeExt(tif, tmpbuf);
#endif
    return 0;
}

/*
 * JPEG Encoding.
 */

static void unsuppress_quant_table(JPEGState *sp, int tblno)
{
    JQUANT_TBL *qtbl;

    if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
        qtbl->sent_table = FALSE;
}

static void suppress_quant_table(JPEGState *sp, int tblno)
{
    JQUANT_TBL *qtbl;

    if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
        qtbl->sent_table = TRUE;
}

static void unsuppress_huff_table(JPEGState *sp, int tblno)
{
    JHUFF_TBL *htbl;

    if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
        htbl->sent_table = FALSE;
    if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
        htbl->sent_table = FALSE;
}

static void suppress_huff_table(JPEGState *sp, int tblno)
{
    JHUFF_TBL *htbl;

    if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
        htbl->sent_table = TRUE;
    if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
        htbl->sent_table = TRUE;
}

static int prepare_JPEGTables(TIFF *tif)
{
    JPEGState *sp = JState(tif);

    /* Initialize quant tables for current quality setting */
    if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE))
        return (0);
    /* Mark only the tables we want for output */
    /* NB: chrominance tables are currently used only with YCbCr */
    if (!TIFFjpeg_suppress_tables(sp, TRUE))
        return (0);
    if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT)
    {
        unsuppress_quant_table(sp, 0);
        if (sp->photometric == PHOTOMETRIC_YCBCR)
            unsuppress_quant_table(sp, 1);
    }
    if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF)
    {
        unsuppress_huff_table(sp, 0);
        if (sp->photometric == PHOTOMETRIC_YCBCR)
            unsuppress_huff_table(sp, 1);
    }
    /* Direct libjpeg output into otherSettings.jpegtables */
    if (!TIFFjpeg_tables_dest(sp, tif))
        return (0);
    /* Emit tables-only datastream */
    if (!TIFFjpeg_write_tables(sp))
        return (0);

    return (1);
}

#if defined(JPEG_LIB_VERSION_MAJOR) &&                                         \
    (JPEG_LIB_VERSION_MAJOR > 9 ||                                             \
     (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4))
/* This is a modified version of std_huff_tables() from jcparam.c
 * in libjpeg-9d because it no longer initializes default Huffman
 * tables in jpeg_set_defaults(). */
static void TIFF_std_huff_tables(j_compress_ptr cinfo)
{

    if (cinfo->dc_huff_tbl_ptrs[0] == NULL)
    {
        (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 0);
    }
    if (cinfo->ac_huff_tbl_ptrs[0] == NULL)
    {
        (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 0);
    }
    if (cinfo->dc_huff_tbl_ptrs[1] == NULL)
    {
        (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 1);
    }
    if (cinfo->ac_huff_tbl_ptrs[1] == NULL)
    {
        (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 1);
    }
}
#endif

static int JPEGSetupEncode(TIFF *tif)
{
    JPEGState *sp = JState(tif);
    TIFFDirectory *td = &tif->tif_dir;
    static const char module[] = "JPEGSetupEncode";

#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12)
    if (tif->tif_dir.td_bitspersample == 12)
    {
        /* We pass a pointer to a copy of otherSettings, since */
        /* TIFFReInitJPEG_12() will clear sp */
        JPEGOtherSettings savedOtherSettings = sp->otherSettings;
        return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 1);
    }
#endif

    JPEGInitializeLibJPEG(tif, FALSE);

    assert(sp != NULL);
    assert(!sp->cinfo.comm.is_decompressor);

    sp->photometric = td->td_photometric;

    /*
     * Initialize all JPEG parameters to default values.
     * Note that jpeg_set_defaults needs legal values for
     * in_color_space and input_components.
     */
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
    {
        sp->cinfo.c.input_components = td->td_samplesperpixel;
        if (sp->photometric == PHOTOMETRIC_YCBCR)
        {
            if (sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB)
            {
                sp->cinfo.c.in_color_space = JCS_RGB;
            }
            else
            {
                sp->cinfo.c.in_color_space = JCS_YCbCr;
            }
        }
        else
        {
            if ((td->td_photometric == PHOTOMETRIC_MINISWHITE ||
                 td->td_photometric == PHOTOMETRIC_MINISBLACK) &&
                td->td_samplesperpixel == 1)
                sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
            else if (td->td_photometric == PHOTOMETRIC_RGB &&
                     td->td_samplesperpixel == 3)
                sp->cinfo.c.in_color_space = JCS_RGB;
            else if (td->td_photometric == PHOTOMETRIC_SEPARATED &&
                     td->td_samplesperpixel == 4)
                sp->cinfo.c.in_color_space = JCS_CMYK;
            else
                sp->cinfo.c.in_color_space = JCS_UNKNOWN;
        }
    }
    else
    {
        sp->cinfo.c.input_components = 1;
        sp->cinfo.c.in_color_space = JCS_UNKNOWN;
    }
    if (!TIFFjpeg_set_defaults(sp))
        return (0);

    /* mozjpeg by default enables progressive JPEG, which is illegal in
     * JPEG-in-TIFF */
    /* So explicitly disable it. */
    if (sp->cinfo.c.num_scans != 0 &&
        (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0)
    {
        /* it has been found that mozjpeg could create corrupt strips/tiles */
        /* in non optimize_coding mode. */
        TIFFWarningExtR(
            tif, module,
            "mozjpeg library likely detected. Disable emission of "
            "Huffman tables in JpegTables tag, and use optimize_coding "
            "to avoid potential issues");
        sp->otherSettings.jpegtablesmode &= ~JPEGTABLESMODE_HUFF;
    }
    sp->cinfo.c.num_scans = 0;
    sp->cinfo.c.scan_info = NULL;

    /* Set per-file parameters */
    switch (sp->photometric)
    {
        case PHOTOMETRIC_YCBCR:
            sp->h_sampling = td->td_ycbcrsubsampling[0];
            sp->v_sampling = td->td_ycbcrsubsampling[1];
            if (sp->h_sampling == 0 || sp->v_sampling == 0)
            {
                TIFFErrorExtR(tif, module,
                              "Invalig horizontal/vertical sampling value");
                return (0);
            }
            if (td->td_bitspersample > 16)
            {
                TIFFErrorExtR(tif, module,
                              "BitsPerSample %" PRIu16 " not allowed for JPEG",
                              td->td_bitspersample);
                return (0);
            }

            /*
             * A ReferenceBlackWhite field *must* be present since the
             * default value is inappropriate for YCbCr.  Fill in the
             * proper value if application didn't set it.
             */
            {
                float *ref;
                if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref))
                {
                    float refbw[6];
                    long top = 1L << td->td_bitspersample;
                    refbw[0] = 0;
                    refbw[1] = (float)(top - 1L);
                    refbw[2] = (float)(top >> 1);
                    refbw[3] = refbw[1];
                    refbw[4] = refbw[2];
                    refbw[5] = refbw[1];
                    TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw);
                }
            }
            break;
        case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */
        case PHOTOMETRIC_MASK:
            TIFFErrorExtR(tif, module,
                          "PhotometricInterpretation %" PRIu16
                          " not allowed for JPEG",
                          sp->photometric);
            return (0);
        default:
            /* TIFF 6.0 forbids subsampling of all other color spaces */
            sp->h_sampling = 1;
            sp->v_sampling = 1;
            break;
    }

        /* Verify miscellaneous parameters */

        /*
         * This would need work if libtiff ever supports different
         * depths for different components, or if libjpeg ever supports
         * run-time selection of depth.  Neither is imminent.
         */
#ifdef JPEG_LIB_MK1
    /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */
    if (td->td_bitspersample != 8 && td->td_bitspersample != 12)
#else
    if (td->td_bitspersample != BITS_IN_JSAMPLE)
#endif
    {
        TIFFErrorExtR(tif, module,
                      "BitsPerSample %" PRIu16 " not allowed for JPEG",
                      td->td_bitspersample);
        return (0);
    }
    sp->cinfo.c.data_precision = td->td_bitspersample;
#ifdef JPEG_LIB_MK1
    sp->cinfo.c.bits_in_jsample = td->td_bitspersample;
#endif
    if (isTiled(tif))
    {
        if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0)
        {
            TIFFErrorExtR(tif, module,
                          "JPEG tile height must be multiple of %" PRIu32,
                          (uint32_t)(sp->v_sampling * DCTSIZE));
            return (0);
        }
        if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0)
        {
            TIFFErrorExtR(tif, module,
                          "JPEG tile width must be multiple of %" PRIu32,
                          (uint32_t)(sp->h_sampling * DCTSIZE));
            return (0);
        }
    }
    else
    {
        if (td->td_rowsperstrip < td->td_imagelength &&
            (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0)
        {
            TIFFErrorExtR(tif, module,
                          "RowsPerStrip must be multiple of %" PRIu32
                          " for JPEG",
                          (uint32_t)(sp->v_sampling * DCTSIZE));
            return (0);
        }
    }

    /* Create a JPEGTables field if appropriate */
    if (sp->otherSettings.jpegtablesmode &
        (JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF))
    {
        if (sp->otherSettings.jpegtables == NULL ||
            memcmp(sp->otherSettings.jpegtables, "\0\0\0\0\0\0\0\0\0", 8) == 0)
        {
#if defined(JPEG_LIB_VERSION_MAJOR) &&                                         \
    (JPEG_LIB_VERSION_MAJOR > 9 ||                                             \
     (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4))
            if ((sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0 &&
                (sp->cinfo.c.dc_huff_tbl_ptrs[0] == NULL ||
                 sp->cinfo.c.dc_huff_tbl_ptrs[1] == NULL ||
                 sp->cinfo.c.ac_huff_tbl_ptrs[0] == NULL ||
                 sp->cinfo.c.ac_huff_tbl_ptrs[1] == NULL))
            {
                /* libjpeg-9d no longer initializes default Huffman tables in */
                /* jpeg_set_defaults() */
                TIFF_std_huff_tables(&sp->cinfo.c);
            }
#endif

            if (!prepare_JPEGTables(tif))
                return (0);
            /* Mark the field present */
            /* Can't use TIFFSetField since BEENWRITING is already set! */
            tif->tif_flags |= TIFF_DIRTYDIRECT;
            TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
        }
    }
    else
    {
        /* We do not support application-supplied JPEGTables, */
        /* so mark the field not present */
        TIFFClrFieldBit(tif, FIELD_JPEGTABLES);
    }

    /* Direct libjpeg output to libtiff's output buffer */
    TIFFjpeg_data_dest(sp, tif);

    return (1);
}

/*
 * Set encoding state at the start of a strip or tile.
 */
static int JPEGPreEncode(TIFF *tif, uint16_t s)
{
    JPEGState *sp = JState(tif);
    TIFFDirectory *td = &tif->tif_dir;
    static const char module[] = "JPEGPreEncode";
    uint32_t segment_width, segment_height;
    int downsampled_input;

    assert(sp != NULL);

    if (sp->cinfo.comm.is_decompressor == 1)
    {
        tif->tif_setupencode(tif);
    }

    assert(!sp->cinfo.comm.is_decompressor);
    /*
     * Set encoding parameters for this strip/tile.
     */
    if (isTiled(tif))
    {
        segment_width = td->td_tilewidth;
        segment_height = td->td_tilelength;
        sp->bytesperline = TIFFTileRowSize(tif);
    }
    else
    {
        segment_width = td->td_imagewidth;
        segment_height = td->td_imagelength - tif->tif_row;
        if (segment_height > td->td_rowsperstrip)
            segment_height = td->td_rowsperstrip;
        sp->bytesperline = TIFFScanlineSize(tif);
    }
    if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
    {
        /* for PC 2, scale down the strip/tile size
         * to match a downsampled component
         */
        if (sp->h_sampling == 0 || sp->v_sampling == 0)
        {
            TIFFErrorExtR(tif, module,
                          "JPEG horizontal or vertical sampling is zero");
            return (0);
        }
        segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
        segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
    }
    if (segment_width > (uint32_t)JPEG_MAX_DIMENSION ||
        segment_height > (uint32_t)JPEG_MAX_DIMENSION)
    {
        TIFFErrorExtR(tif, module,
                      "Strip/tile too large for JPEG. Maximum dimension is %d",
                      (int)JPEG_MAX_DIMENSION);
        return (0);
    }
    sp->cinfo.c.image_width = segment_width;
    sp->cinfo.c.image_height = segment_height;
    downsampled_input = FALSE;
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
    {
        sp->cinfo.c.input_components = td->td_samplesperpixel;
        if (sp->photometric == PHOTOMETRIC_YCBCR)
        {
            if (sp->otherSettings.jpegcolormode != JPEGCOLORMODE_RGB)
            {
                if (sp->h_sampling != 1 || sp->v_sampling != 1)
                    downsampled_input = TRUE;
            }
            if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr))
                return (0);
            /*
             * Set Y sampling factors;
             * we assume jpeg_set_colorspace() set the rest to 1
             */
            sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
            sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
        }
        else
        {
            if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
                return (0);
            /* jpeg_set_colorspace set all sampling factors to 1 */
        }
    }
    else
    {
        if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
            return (0);
        sp->cinfo.c.comp_info[0].component_id = s;
        /* jpeg_set_colorspace() set sampling factors to 1 */
        if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0)
        {
            sp->cinfo.c.comp_info[0].quant_tbl_no = 1;
            sp->cinfo.c.comp_info[0].dc_tbl_no = 1;
            sp->cinfo.c.comp_info[0].ac_tbl_no = 1;
        }
    }
    /* ensure libjpeg won't write any extraneous markers */
    sp->cinfo.c.write_JFIF_header = FALSE;
    sp->cinfo.c.write_Adobe_marker = FALSE;
    /* set up table handling correctly */
    /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged
     */
    /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT
     */
    /* mode, so we must manually suppress them. However TIFFjpeg_set_quality()
     */
    /* should really be called when dealing with files with directories with */
    /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */
    if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE))
        return (0);
    if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT)
    {
        suppress_quant_table(sp, 0);
        suppress_quant_table(sp, 1);
    }
    else
    {
        unsuppress_quant_table(sp, 0);
        unsuppress_quant_table(sp, 1);
    }
    if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF)
    {
        /* Explicit suppression is only needed if we did not go through the */
        /* prepare_JPEGTables() code path, which may be the case if updating */
        /* an existing file */
        suppress_huff_table(sp, 0);
        suppress_huff_table(sp, 1);
        sp->cinfo.c.optimize_coding = FALSE;
    }
    else
        sp->cinfo.c.optimize_coding = TRUE;
    if (downsampled_input)
    {
        /* Need to use raw-data interface to libjpeg */
        sp->cinfo.c.raw_data_in = TRUE;
        tif->tif_encoderow = JPEGEncodeRaw;
        tif->tif_encodestrip = JPEGEncodeRaw;
        tif->tif_encodetile = JPEGEncodeRaw;
    }
    else
    {
        /* Use normal interface to libjpeg */
        sp->cinfo.c.raw_data_in = FALSE;
        tif->tif_encoderow = JPEGEncode;
        tif->tif_encodestrip = JPEGEncode;
        tif->tif_encodetile = JPEGEncode;
    }
    /* Start JPEG compressor */
    if (!TIFFjpeg_start_compress(sp, FALSE))
        return (0);
    /* Allocate downsampled-data buffers if needed */
    if (downsampled_input)
    {
        if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
                                       sp->cinfo.c.num_components))
            return (0);
    }
    sp->scancount = 0;
    sp->encode_raw_error = FALSE;

    return (1);
}

/*
 * Encode a chunk of pixels.
 * "Standard" case: incoming data is not downsampled.
 */
static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
    JPEGState *sp = JState(tif);
    tmsize_t nrows;
    TIFF_JSAMPROW bufptr[1];
    short *line16 = NULL;
    int line16_count = 0;

    (void)s;
    assert(sp != NULL);
    /* data is expected to be supplied in multiples of a scanline */
    nrows = cc / sp->bytesperline;
    if (cc % sp->bytesperline)
        TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded");

    /* The last strip will be limited to image size */
    if (!isTiled(tif) && tif->tif_row + nrows > tif->tif_dir.td_imagelength)
        nrows = tif->tif_dir.td_imagelength - tif->tif_row;

    if (sp->cinfo.c.data_precision == 12)
    {
        line16_count = (int)((sp->bytesperline * 2) / 3);
        line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count);
        if (!line16)
        {
            TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory");

            return 0;
        }
    }

    while (nrows-- > 0)
    {

        if (sp->cinfo.c.data_precision == 12)
        {

            int value_pairs = line16_count / 2;
            int iPair;

            bufptr[0] = (TIFF_JSAMPROW)line16;

            for (iPair = 0; iPair < value_pairs; iPair++)
            {
                unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3;
                TIFF_JSAMPLE *out_ptr = (TIFF_JSAMPLE *)(line16 + iPair * 2);

                out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4);
                out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2];
            }
        }
        else
        {
            bufptr[0] = (TIFF_JSAMPROW)buf;
        }
        if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
            return (0);
        if (nrows > 0)
            tif->tif_row++;
        buf += sp->bytesperline;
    }

    if (sp->cinfo.c.data_precision == 12)
    {
        _TIFFfreeExt(tif, line16);
    }

    return (1);
}

/*
 * Encode a chunk of pixels.
 * Incoming data is expected to be downsampled per sampling factors.
 */
static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
    JPEGState *sp = JState(tif);
    TIFF_JSAMPLE *inptr;
    TIFF_JSAMPLE *outptr;
    tmsize_t nrows;
    JDIMENSION clumps_per_line, nclump;
    int clumpoffset, ci, xpos, ypos;
    jpeg_component_info *compptr;
    int samples_per_clump = sp->samplesperclump;
    tmsize_t bytesperclumpline;

    (void)s;
    assert(sp != NULL);

    if (sp->encode_raw_error)
    {
        TIFFErrorExtR(tif, tif->tif_name, "JPEGEncodeRaw() already failed");
        return 0;
    }

    /* data is expected to be supplied in multiples of a clumpline */
    /* a clumpline is equivalent to v_sampling desubsampled scanlines */
    /* TODO: the following calculation of bytesperclumpline, should substitute
     * calculation of sp->bytesperline, except that it is per v_sampling lines
     */
    bytesperclumpline =
        ((((tmsize_t)sp->cinfo.c.image_width + sp->h_sampling - 1) /
          sp->h_sampling) *
             ((tmsize_t)sp->h_sampling * sp->v_sampling + 2) *
             sp->cinfo.c.data_precision +
         7) /
        8;

    nrows = (cc / bytesperclumpline) * sp->v_sampling;
    if (cc % bytesperclumpline)
        TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded");

    /* Cb,Cr both have sampling factors 1, so this is correct */
    clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width;

    while (nrows > 0)
    {
        /*
         * Fastest way to separate the data is to make one pass
         * over the scanline for each row of each component.
         */
        clumpoffset = 0; /* first sample in clump */
        for (ci = 0, compptr = sp->cinfo.c.comp_info;
             ci < sp->cinfo.c.num_components; ci++, compptr++)
        {
            int hsamp = compptr->h_samp_factor;
            int vsamp = compptr->v_samp_factor;
            int padding = (int)(compptr->width_in_blocks * DCTSIZE -
                                clumps_per_line * hsamp);
            for (ypos = 0; ypos < vsamp; ypos++)
            {
                inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset;
                outptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos];
                if (hsamp == 1)
                {
                    /* fast path for at least Cb and Cr */
                    for (nclump = clumps_per_line; nclump-- > 0;)
                    {
                        *outptr++ = inptr[0];
                        inptr += samples_per_clump;
                    }
                }
                else
                {
                    /* general case */
                    for (nclump = clumps_per_line; nclump-- > 0;)
                    {
                        for (xpos = 0; xpos < hsamp; xpos++)
                            *outptr++ = inptr[xpos];
                        inptr += samples_per_clump;
                    }
                }
                /* pad each scanline as needed */
                for (xpos = 0; xpos < padding; xpos++)
                {
                    *outptr = outptr[-1];
                    outptr++;
                }
                clumpoffset += hsamp;
            }
        }
        sp->scancount++;
        if (sp->scancount >= DCTSIZE)
        {
            int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
            if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
            {
                sp->encode_raw_error = TRUE;
                return (0);
            }
            sp->scancount = 0;
        }
        tif->tif_row += sp->v_sampling;
        buf += bytesperclumpline;
        nrows -= sp->v_sampling;
    }
    return (1);
}

/*
 * Finish up at the end of a strip or tile.
 */
static int JPEGPostEncode(TIFF *tif)
{
    JPEGState *sp = JState(tif);

    if (sp->scancount > 0)
    {
        /*
         * Need to emit a partial bufferload of downsampled data.
         * Pad the data vertically.
         */
        int ci, ypos, n;
        jpeg_component_info *compptr;

        for (ci = 0, compptr = sp->cinfo.c.comp_info;
             ci < sp->cinfo.c.num_components; ci++, compptr++)
        {
            int vsamp = compptr->v_samp_factor;
            tmsize_t row_width =
                compptr->width_in_blocks * DCTSIZE * sizeof(JSAMPLE);
            for (ypos = sp->scancount * vsamp; ypos < DCTSIZE * vsamp; ypos++)
            {
                _TIFFmemcpy((void *)sp->ds_buffer[ci][ypos],
                            (void *)sp->ds_buffer[ci][ypos - 1], row_width);
            }
        }
        n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
        if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
            return (0);
    }

    return (TIFFjpeg_finish_compress(JState(tif)));
}

static void JPEGCleanup(TIFF *tif)
{
    JPEGState *sp = JState(tif);

    assert(sp != 0);

    tif->tif_tagmethods.vgetfield = sp->otherSettings.vgetparent;
    tif->tif_tagmethods.vsetfield = sp->otherSettings.vsetparent;
    tif->tif_tagmethods.printdir = sp->otherSettings.printdir;
    if (sp->cinfo_initialized)
        TIFFjpeg_destroy(sp);         /* release libjpeg resources */
    if (sp->otherSettings.jpegtables) /* tag value */
        _TIFFfreeExt(tif, sp->otherSettings.jpegtables);
    _TIFFfreeExt(tif, tif->tif_data); /* release local state */
    tif->tif_data = NULL;

    _TIFFSetDefaultCompressionState(tif);
}

static void JPEGResetUpsampled(TIFF *tif)
{
    JPEGState *sp = JState(tif);
    TIFFDirectory *td = &tif->tif_dir;

    /*
     * Mark whether returned data is up-sampled or not so TIFFStripSize
     * and TIFFTileSize return values that reflect the true amount of
     * data.
     */
    tif->tif_flags &= ~TIFF_UPSAMPLED;
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
    {
        if (td->td_photometric == PHOTOMETRIC_YCBCR &&
            sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB)
        {
            tif->tif_flags |= TIFF_UPSAMPLED;
        }
        else
        {
#ifdef notdef
            if (td->td_ycbcrsubsampling[0] != 1 ||
                td->td_ycbcrsubsampling[1] != 1)
                ; /* XXX what about up-sampling? */
#endif
        }
    }

    /*
     * Must recalculate cached tile size in case sampling state changed.
     * Should we really be doing this now if image size isn't set?
     */
    if (tif->tif_tilesize > 0)
        tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
    if (tif->tif_scanlinesize > 0)
        tif->tif_scanlinesize = TIFFScanlineSize(tif);
}

static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
    JPEGState *sp = JState(tif);
    const TIFFField *fip;
    uint32_t v32;

    assert(sp != NULL);

    switch (tag)
    {
        case TIFFTAG_JPEGTABLES:
            v32 = (uint32_t)va_arg(ap, uint32_t);
            if (v32 == 0)
            {
                /* XXX */
                return (0);
            }
            _TIFFsetByteArrayExt(tif, &sp->otherSettings.jpegtables,
                                 va_arg(ap, void *), v32);
            sp->otherSettings.jpegtables_length = v32;
            TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
            break;
        case TIFFTAG_JPEGQUALITY:
            sp->otherSettings.jpegquality = (int)va_arg(ap, int);
            return (1); /* pseudo tag */
        case TIFFTAG_JPEGCOLORMODE:
            sp->otherSettings.jpegcolormode = (int)va_arg(ap, int);
            JPEGResetUpsampled(tif);
            return (1); /* pseudo tag */
        case TIFFTAG_PHOTOMETRIC:
        {
            int ret_value = (*sp->otherSettings.vsetparent)(tif, tag, ap);
            JPEGResetUpsampled(tif);
            return ret_value;
        }
        case TIFFTAG_JPEGTABLESMODE:
            sp->otherSettings.jpegtablesmode = (int)va_arg(ap, int);
            return (1); /* pseudo tag */
        case TIFFTAG_YCBCRSUBSAMPLING:
            /* mark the fact that we have a real ycbcrsubsampling! */
            sp->otherSettings.ycbcrsampling_fetched = 1;
            /* should we be recomputing upsampling info here? */
            return (*sp->otherSettings.vsetparent)(tif, tag, ap);
        default:
            return (*sp->otherSettings.vsetparent)(tif, tag, ap);
    }

    if ((fip = TIFFFieldWithTag(tif, tag)) != NULL)
    {
        TIFFSetFieldBit(tif, fip->field_bit);
    }
    else
    {
        return (0);
    }

    tif->tif_flags |= TIFF_DIRTYDIRECT;
    return (1);
}

static int JPEGVGetField(TIFF *tif, uint32_t tag, va_list ap)
{
    JPEGState *sp = JState(tif);

    assert(sp != NULL);

    switch (tag)
    {
        case TIFFTAG_JPEGTABLES:
            *va_arg(ap, uint32_t *) = sp->otherSettings.jpegtables_length;
            *va_arg(ap, const void **) = sp->otherSettings.jpegtables;
            break;
        case TIFFTAG_JPEGQUALITY:
            *va_arg(ap, int *) = sp->otherSettings.jpegquality;
            break;
        case TIFFTAG_JPEGCOLORMODE:
            *va_arg(ap, int *) = sp->otherSettings.jpegcolormode;
            break;
        case TIFFTAG_JPEGTABLESMODE:
            *va_arg(ap, int *) = sp->otherSettings.jpegtablesmode;
            break;
        default:
            return (*sp->otherSettings.vgetparent)(tif, tag, ap);
    }
    return (1);
}

static void JPEGPrintDir(TIFF *tif, FILE *fd, long flags)
{
    JPEGState *sp = JState(tif);

    assert(sp != NULL);
    (void)flags;

    if (sp != NULL)
    {
        if (TIFFFieldSet(tif, FIELD_JPEGTABLES))
            fprintf(fd, "  JPEG Tables: (%" PRIu32 " bytes)\n",
                    sp->otherSettings.jpegtables_length);
        if (sp->otherSettings.printdir)
            (*sp->otherSettings.printdir)(tif, fd, flags);
    }
}

static uint32_t JPEGDefaultStripSize(TIFF *tif, uint32_t s)
{
    JPEGState *sp = JState(tif);
    TIFFDirectory *td = &tif->tif_dir;

    s = (*sp->otherSettings.defsparent)(tif, s);
    if (s < td->td_imagelength)
        s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE);
    return (s);
}

static void JPEGDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th)
{
    JPEGState *sp = JState(tif);
    TIFFDirectory *td = &tif->tif_dir;

    (*sp->otherSettings.deftparent)(tif, tw, th);
    *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE);
    *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE);
}

/*
 * The JPEG library initialized used to be done in TIFFInitJPEG(), but
 * now that we allow a TIFF file to be opened in update mode it is necessary
 * to have some way of deciding whether compression or decompression is
 * desired other than looking at tif->tif_mode.  We accomplish this by
 * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry.
 * If so, we assume decompression is desired.
 *
 * This is tricky, because TIFFInitJPEG() is called while the directory is
 * being read, and generally speaking the BYTECOUNTS tag won't have been read
 * at that point.  So we try to defer jpeg library initialization till we
 * do have that tag ... basically any access that might require the compressor
 * or decompressor that occurs after the reading of the directory.
 *
 * In an ideal world compressors or decompressors would be setup
 * at the point where a single tile or strip was accessed (for read or write)
 * so that stuff like update of missing tiles, or replacement of tiles could
 * be done. However, we aren't trying to crack that nut just yet ...
 *
 * NFW, Feb 3rd, 2003.
 */

static int JPEGInitializeLibJPEG(TIFF *tif, int decompress)
{
    JPEGState *sp = JState(tif);

    if (sp->cinfo_initialized)
    {
        if (!decompress && sp->cinfo.comm.is_decompressor)
            TIFFjpeg_destroy(sp);
        else if (decompress && !sp->cinfo.comm.is_decompressor)
            TIFFjpeg_destroy(sp);
        else
            return 1;

        sp->cinfo_initialized = 0;
    }

    /*
     * Initialize libjpeg.
     */
    if (decompress)
    {
        if (!TIFFjpeg_create_decompress(sp))
            return (0);
    }
    else
    {
        if (!TIFFjpeg_create_compress(sp))
            return (0);
#ifndef TIFF_JPEG_MAX_MEMORY_TO_USE
#define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024)
#endif
        /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */
        /* store implementation, so better not set max_memory_to_use ourselves.
         */
        /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */
        if (sp->cinfo.c.mem->max_memory_to_use > 0)
        {
            /* This is to address bug related in ticket GDAL #1795. */
            if (getenv("JPEGMEM") == NULL)
            {
                /* Increase the max memory usable. This helps when creating
                 * files */
                /* with "big" tile, without using libjpeg temporary files. */
                /* For example a 512x512 tile with 3 bands */
                /* requires 1.5 MB which is above libjpeg 1MB default */
                if (sp->cinfo.c.mem->max_memory_to_use <
                    TIFF_JPEG_MAX_MEMORY_TO_USE)
                    sp->cinfo.c.mem->max_memory_to_use =
                        TIFF_JPEG_MAX_MEMORY_TO_USE;
            }
        }
    }

    sp->cinfo_initialized = TRUE;

    return 1;
}

/* Common to tif_jpeg.c and tif_jpeg_12.c */
static void TIFFInitJPEGCommon(TIFF *tif)
{
    JPEGState *sp;

    sp = JState(tif);
    sp->tif = tif; /* back link */

    /* Default values for codec-specific fields */
    sp->otherSettings.jpegtables = NULL;
    sp->otherSettings.jpegtables_length = 0;
    sp->otherSettings.jpegquality = 75; /* Default IJG quality */
    sp->otherSettings.jpegcolormode = JPEGCOLORMODE_RAW;
    sp->otherSettings.jpegtablesmode =
        JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;
    sp->otherSettings.ycbcrsampling_fetched = 0;

    tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */
    tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */
    tif->tif_tagmethods.printdir = JPEGPrintDir;   /* hook for codec tags */

    /*
     * Install codec methods.
     */
    tif->tif_fixuptags = JPEGFixupTags;
    tif->tif_setupdecode = JPEGSetupDecode;
    tif->tif_predecode = JPEGPreDecode;
    tif->tif_decoderow = JPEGDecode;
    tif->tif_decodestrip = JPEGDecode;
    tif->tif_decodetile = JPEGDecode;
    tif->tif_setupencode = JPEGSetupEncode;
    tif->tif_preencode = JPEGPreEncode;
    tif->tif_postencode = JPEGPostEncode;
    tif->tif_encoderow = JPEGEncode;
    tif->tif_encodestrip = JPEGEncode;
    tif->tif_encodetile = JPEGEncode;
    tif->tif_cleanup = JPEGCleanup;

    tif->tif_defstripsize = JPEGDefaultStripSize;
    tif->tif_deftilesize = JPEGDefaultTileSize;
    tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */
    sp->cinfo_initialized = FALSE;
}

int TIFFInitJPEG(TIFF *tif, int scheme)
{
    JPEGState *sp;

    (void)scheme;
    assert(scheme == COMPRESSION_JPEG);

    /*
     * Merge codec-specific tag information.
     */
    if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields)))
    {
        TIFFErrorExtR(tif, "TIFFInitJPEG",
                      "Merging JPEG codec-specific tags failed");
        return 0;
    }

    /*
     * Allocate state block so tag methods have storage to record values.
     */
    tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(JPEGState));

    if (tif->tif_data == NULL)
    {
        TIFFErrorExtR(tif, "TIFFInitJPEG", "No space for JPEG state block");
        return 0;
    }
    _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState));

    sp = JState(tif);
    /*
     * Override parent get/set field methods.
     */
    sp->otherSettings.vgetparent = tif->tif_tagmethods.vgetfield;
    sp->otherSettings.vsetparent = tif->tif_tagmethods.vsetfield;
    sp->otherSettings.printdir = tif->tif_tagmethods.printdir;

    sp->otherSettings.defsparent = tif->tif_defstripsize;
    sp->otherSettings.deftparent = tif->tif_deftilesize;

    TIFFInitJPEGCommon(tif);

    /*
    ** Create a JPEGTables field if no directory has yet been created.
    ** We do this just to ensure that sufficient space is reserved for
    ** the JPEGTables field.  It will be properly created the right
    ** size later.
    */
    if (tif->tif_diroff == 0)
    {
#define SIZE_OF_JPEGTABLES 2000
        /*
        The following line assumes incorrectly that all JPEG-in-TIFF files will
        have a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags
        to be written when the JPEG data is placed with TIFFWriteRawStrip.  The
        field bit should be set, anyway, later when actual JPEGTABLES header is
        generated, so removing it here hopefully is harmless.
        TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
        */
        sp->otherSettings.jpegtables_length = SIZE_OF_JPEGTABLES;
        sp->otherSettings.jpegtables =
            (void *)_TIFFmallocExt(tif, sp->otherSettings.jpegtables_length);
        if (sp->otherSettings.jpegtables)
        {
            _TIFFmemset(sp->otherSettings.jpegtables, 0, SIZE_OF_JPEGTABLES);
        }
        else
        {
            TIFFErrorExtR(tif, "TIFFInitJPEG",
                          "Failed to allocate memory for JPEG tables");
            return 0;
        }
#undef SIZE_OF_JPEGTABLES
    }
    return 1;
}
#endif /* JPEG_SUPPORT */
