/*
 * 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>
#elif defined(USE_LIBJPEG_TURBO)
#include "third_party/libjpeg_turbo/jerror.h"
#include "third_party/libjpeg_turbo/jpeglib.h"
#else
#include "third_party/libjpeg/jerror.h"
#include "third_party/libjpeg/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.
 */

#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;
} 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,
     TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL},
    {TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
     TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
    {TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
     TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
    {TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
     TIFF_SETGET_UNDEFINED, 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;
                        JSAMPLE *in_ptr = (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 > 65535 || segment_height > 65535)
    {
        TIFFErrorExtR(tif, module, "Strip/tile too large for JPEG");
        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;

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