//========================================================================
//
// TiffWriter.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2010, 2012 William Bader <williambader@hotmail.com>
// Copyright (C) 2012, 2021, 2022 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2012, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2012 Pino Toscano <pino@kde.org>
// Copyright (C) 2014 Steven Lee <roc.sky@gmail.com>
//
//========================================================================

#include "TiffWriter.h"

#ifdef ENABLE_LIBTIFF

#    include <cstring>

#    ifdef _WIN32
#        include <io.h>
#    endif

extern "C" {
#    include <tiffio.h>
}

#    include <cstdint>

struct TiffWriterPrivate
{
    TIFF *f; // LibTiff file context
    int numRows; // number of rows in the image
    int curRow; // number of rows written
    const char *compressionString; // compression type
    TiffWriter::Format format; // format of image data
};

TiffWriter::~TiffWriter()
{
    delete priv;
}

TiffWriter::TiffWriter(Format formatA)
{
    priv = new TiffWriterPrivate;
    priv->f = nullptr;
    priv->numRows = 0;
    priv->curRow = 0;
    priv->compressionString = nullptr;
    priv->format = formatA;
}

// Set the compression type

void TiffWriter::setCompressionString(const char *compressionStringArg)
{
    priv->compressionString = compressionStringArg;
}

// Write a TIFF file.

bool TiffWriter::init(FILE *openedFile, int width, int height, double hDPI, double vDPI)
{
    unsigned int compression;
    uint16_t photometric = 0;
    uint32_t rowsperstrip = (uint32_t)-1;
    int bitspersample;
    uint16_t samplesperpixel = 0;
    const struct compression_name_tag
    {
        const char *compressionName; // name of the compression option from the command line
        unsigned int compressionCode; // internal libtiff code
        const char *compressionDescription; // descriptive name
    } compressionList[] = { { "none", COMPRESSION_NONE, "no compression" },
                            { "ccittrle", COMPRESSION_CCITTRLE, "CCITT modified Huffman RLE" },
                            { "ccittfax3", COMPRESSION_CCITTFAX3, "CCITT Group 3 fax encoding" },
                            { "ccittt4", COMPRESSION_CCITT_T4, "CCITT T.4 (TIFF 6 name)" },
                            { "ccittfax4", COMPRESSION_CCITTFAX4, "CCITT Group 4 fax encoding" },
                            { "ccittt6", COMPRESSION_CCITT_T6, "CCITT T.6 (TIFF 6 name)" },
                            { "lzw", COMPRESSION_LZW, "Lempel-Ziv  & Welch" },
                            { "ojpeg", COMPRESSION_OJPEG, "!6.0 JPEG" },
                            { "jpeg", COMPRESSION_JPEG, "%JPEG DCT compression" },
                            { "next", COMPRESSION_NEXT, "NeXT 2-bit RLE" },
                            { "packbits", COMPRESSION_PACKBITS, "Macintosh RLE" },
                            { "ccittrlew", COMPRESSION_CCITTRLEW, "CCITT modified Huffman RLE w/ word alignment" },
                            { "deflate", COMPRESSION_DEFLATE, "Deflate compression" },
                            { "adeflate", COMPRESSION_ADOBE_DEFLATE, "Deflate compression, as recognized by Adobe" },
                            { "dcs", COMPRESSION_DCS, "Kodak DCS encoding" },
                            { "jbig", COMPRESSION_JBIG, "ISO JBIG" },
                            { "jp2000", COMPRESSION_JP2000, "Leadtools JPEG2000" },
                            { nullptr, 0, nullptr } };

    // Initialize

    priv->f = nullptr;
    priv->curRow = 0;

    // Store the number of rows

    priv->numRows = height;

    // Set the compression

    compression = COMPRESSION_NONE;

    if (priv->compressionString == nullptr || strcmp(priv->compressionString, "") == 0) {
        compression = COMPRESSION_NONE;
    } else {
        int i;
        for (i = 0; compressionList[i].compressionName != nullptr; i++) {
            if (strcmp(priv->compressionString, compressionList[i].compressionName) == 0) {
                compression = compressionList[i].compressionCode;
                break;
            }
        }
        if (compressionList[i].compressionName == nullptr) {
            fprintf(stderr, "TiffWriter: Unknown compression type '%.10s', using 'none'.\n", priv->compressionString);
            fprintf(stderr, "Known compression types (the tiff library might not support every type)\n");
            for (i = 0; compressionList[i].compressionName != nullptr; i++) {
                fprintf(stderr, "%10s %s\n", compressionList[i].compressionName, compressionList[i].compressionDescription);
            }
        }
    }

    // Set bits per sample, samples per pixel, and photometric type from format

    bitspersample = (priv->format == MONOCHROME ? 1 : 8);

    switch (priv->format) {
    case MONOCHROME:
    case GRAY:
        samplesperpixel = 1;
        photometric = PHOTOMETRIC_MINISBLACK;
        break;

    case RGB:
        samplesperpixel = 3;
        photometric = PHOTOMETRIC_RGB;
        break;

    case RGBA_PREMULTIPLIED:
        samplesperpixel = 4;
        photometric = PHOTOMETRIC_RGB;
        break;

    case CMYK:
        samplesperpixel = 4;
        photometric = PHOTOMETRIC_SEPARATED;
        break;

    case RGB48:
        samplesperpixel = 3;
        bitspersample = 16;
        photometric = PHOTOMETRIC_RGB;
        break;
    }

    // Open the file

    if (openedFile == nullptr) {
        fprintf(stderr, "TiffWriter: No output file given.\n");
        return false;
    }

#    ifdef _WIN32
    // Convert C Library handle to Win32 Handle
    priv->f = TIFFFdOpen(_get_osfhandle(fileno(openedFile)), "-", "w");
#    else
    priv->f = TIFFFdOpen(fileno(openedFile), "-", "w");
#    endif

    if (!priv->f) {
        return false;
    }

    // Set TIFF tags

    TIFFSetField(priv->f, TIFFTAG_IMAGEWIDTH, width);
    TIFFSetField(priv->f, TIFFTAG_IMAGELENGTH, height);
    TIFFSetField(priv->f, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
    TIFFSetField(priv->f, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
    TIFFSetField(priv->f, TIFFTAG_BITSPERSAMPLE, bitspersample);
    TIFFSetField(priv->f, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
    TIFFSetField(priv->f, TIFFTAG_PHOTOMETRIC, photometric);
    TIFFSetField(priv->f, TIFFTAG_COMPRESSION, (uint16_t)compression);
    TIFFSetField(priv->f, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(priv->f, rowsperstrip));
    TIFFSetField(priv->f, TIFFTAG_XRESOLUTION, hDPI);
    TIFFSetField(priv->f, TIFFTAG_YRESOLUTION, vDPI);
    TIFFSetField(priv->f, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);

    if (priv->format == RGBA_PREMULTIPLIED) {
        uint16_t extra = EXTRASAMPLE_ASSOCALPHA;
        TIFFSetField(priv->f, TIFFTAG_EXTRASAMPLES, 1, &extra);
    }

    if (priv->format == CMYK) {
        TIFFSetField(priv->f, TIFFTAG_INKSET, INKSET_CMYK);
        TIFFSetField(priv->f, TIFFTAG_NUMBEROFINKS, 4);
    }

    return true;
}

bool TiffWriter::writePointers(unsigned char **rowPointers, int rowCount)
{
    // Write all rows to the file

    for (int row = 0; row < rowCount; row++) {
        if (TIFFWriteScanline(priv->f, rowPointers[row], row, 0) < 0) {
            fprintf(stderr, "TiffWriter: Error writing tiff row %d\n", row);
            return false;
        }
    }

    return true;
}

bool TiffWriter::writeRow(unsigned char **rowData)
{
    // Add a single row

    if (TIFFWriteScanline(priv->f, *rowData, priv->curRow, 0) < 0) {
        fprintf(stderr, "TiffWriter: Error writing tiff row %d\n", priv->curRow);
        return false;
    }

    priv->curRow++;

    return true;
}

bool TiffWriter::close()
{
    // Close the file

    TIFFClose(priv->f);

    return true;
}

#endif
