//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//

#ifndef INCLUDED_IMF_C_RGBA_FILE_H
#define INCLUDED_IMF_C_RGBA_FILE_H

#include "ImfExport.h"

#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
** File names passed to ImfOpen* functions are UTF-8 encoded (see ImfIO.h in the
** C++ API).
*/

/*
** Interpreting unsigned shorts as 16-bit floating point numbers
*/

typedef unsigned short ImfHalf;

IMF_EXPORT
void ImfFloatToHalf (float f, ImfHalf* h);

IMF_EXPORT
void ImfFloatToHalfArray (int n, const float f[/*n*/], ImfHalf h[/*n*/]);

IMF_EXPORT
float ImfHalfToFloat (ImfHalf h);

IMF_EXPORT
void ImfHalfToFloatArray (int n, const ImfHalf h[/*n*/], float f[/*n*/]);

/*
** RGBA pixel; memory layout must be the same as struct Imf::Rgba.
*/

struct ImfRgba
{
    ImfHalf r;
    ImfHalf g;
    ImfHalf b;
    ImfHalf a;
};

typedef struct ImfRgba ImfRgba;

/*
** Magic number; this must be the same as Imf::MAGIC
*/

#define IMF_MAGIC 20000630

/*
** Version number; this must be the same as Imf::EXR_VERSION
*/

#define IMF_VERSION_NUMBER 2

/*
** Line order; values must be the same as in Imf::LineOrder.
*/

#define IMF_INCREASING_Y 0
#define IMF_DECREASING_Y 1
#define IMF_RANDOM_Y 2

/*
** Compression types; values must be the same as in Imf::Compression.
*/

#define IMF_NO_COMPRESSION 0
#define IMF_RLE_COMPRESSION 1
#define IMF_ZIPS_COMPRESSION 2
#define IMF_ZIP_COMPRESSION 3
#define IMF_PIZ_COMPRESSION 4
#define IMF_PXR24_COMPRESSION 5
#define IMF_B44_COMPRESSION 6
#define IMF_B44A_COMPRESSION 7
#define IMF_DWAA_COMPRESSION 8
#define IMF_DWAB_COMPRESSION 9
#define IMF_HTJ2K256_COMPRESSION 10
#define IMF_HTJ2K32_COMPRESSION 11
#define IMF_NUM_COMPRESSION_METHODS 12

/*
** Channels; values must be the same as in Imf::RgbaChannels.
*/

#define IMF_WRITE_R 0x01
#define IMF_WRITE_G 0x02
#define IMF_WRITE_B 0x04
#define IMF_WRITE_A 0x08
#define IMF_WRITE_Y 0x10
#define IMF_WRITE_C 0x20
#define IMF_WRITE_RGB 0x07
#define IMF_WRITE_RGBA 0x0f
#define IMF_WRITE_YC 0x30
#define IMF_WRITE_YA 0x18
#define IMF_WRITE_YCA 0x38

/*
** Level modes; values must be the same as in Imf::LevelMode
*/

#define IMF_ONE_LEVEL 0
#define IMF_MIPMAP_LEVELS 1
#define IMF_RIPMAP_LEVELS 2

/*
** Level rounding modes; values must be the same as in Imf::LevelRoundingMode
*/

#define IMF_ROUND_DOWN 0
#define IMF_ROUND_UP 1

/*
** RGBA file header
*/

struct ImfHeader;
typedef struct ImfHeader ImfHeader;

IMF_EXPORT
ImfHeader* ImfNewHeader (void);

IMF_EXPORT
void ImfDeleteHeader (ImfHeader* hdr);

IMF_EXPORT
ImfHeader* ImfCopyHeader (const ImfHeader* hdr);

IMF_EXPORT
void ImfHeaderSetDisplayWindow (
    ImfHeader* hdr, int xMin, int yMin, int xMax, int yMax);

IMF_EXPORT
void ImfHeaderDisplayWindow (
    const ImfHeader* hdr, int* xMin, int* yMin, int* xMax, int* yMax);

IMF_EXPORT
void
ImfHeaderSetDataWindow (ImfHeader* hdr, int xMin, int yMin, int xMax, int yMax);

IMF_EXPORT
void ImfHeaderDataWindow (
    const ImfHeader* hdr, int* xMin, int* yMin, int* xMax, int* yMax);

IMF_EXPORT
void ImfHeaderSetPixelAspectRatio (ImfHeader* hdr, float pixelAspectRatio);

IMF_EXPORT
float ImfHeaderPixelAspectRatio (const ImfHeader* hdr);

IMF_EXPORT
void ImfHeaderSetScreenWindowCenter (ImfHeader* hdr, float x, float y);

IMF_EXPORT
void ImfHeaderScreenWindowCenter (const ImfHeader* hdr, float* x, float* y);

IMF_EXPORT
void ImfHeaderSetScreenWindowWidth (ImfHeader* hdr, float width);

IMF_EXPORT
float ImfHeaderScreenWindowWidth (const ImfHeader* hdr);

IMF_EXPORT
void ImfHeaderSetLineOrder (ImfHeader* hdr, int lineOrder);

IMF_EXPORT
int ImfHeaderLineOrder (const ImfHeader* hdr);

IMF_EXPORT
void ImfHeaderSetCompression (ImfHeader* hdr, int compression);

IMF_EXPORT
int ImfHeaderCompression (const ImfHeader* hdr);

IMF_EXPORT
int ImfHeaderSetIntAttribute (ImfHeader* hdr, const char name[], int value);

IMF_EXPORT
int ImfHeaderIntAttribute (const ImfHeader* hdr, const char name[], int* value);

IMF_EXPORT
int ImfHeaderSetFloatAttribute (ImfHeader* hdr, const char name[], float value);

IMF_EXPORT
int
ImfHeaderSetDoubleAttribute (ImfHeader* hdr, const char name[], double value);

IMF_EXPORT
int
ImfHeaderFloatAttribute (const ImfHeader* hdr, const char name[], float* value);

IMF_EXPORT
int ImfHeaderDoubleAttribute (
    const ImfHeader* hdr, const char name[], double* value);

IMF_EXPORT
int ImfHeaderSetStringAttribute (
    ImfHeader* hdr, const char name[], const char value[]);

IMF_EXPORT
int ImfHeaderStringAttribute (
    const ImfHeader* hdr, const char name[], const char** value);

IMF_EXPORT
int ImfHeaderSetBox2iAttribute (
    ImfHeader* hdr, const char name[], int xMin, int yMin, int xMax, int yMax);

IMF_EXPORT
int ImfHeaderBox2iAttribute (
    const ImfHeader* hdr,
    const char       name[],
    int*             xMin,
    int*             yMin,
    int*             xMax,
    int*             yMax);

IMF_EXPORT
int ImfHeaderSetBox2fAttribute (
    ImfHeader* hdr,
    const char name[],
    float      xMin,
    float      yMin,
    float      xMax,
    float      yMax);

IMF_EXPORT
int ImfHeaderBox2fAttribute (
    const ImfHeader* hdr,
    const char       name[],
    float*           xMin,
    float*           yMin,
    float*           xMax,
    float*           yMax);

IMF_EXPORT
int ImfHeaderSetV2iAttribute (ImfHeader* hdr, const char name[], int x, int y);

IMF_EXPORT
int
ImfHeaderV2iAttribute (const ImfHeader* hdr, const char name[], int* x, int* y);

IMF_EXPORT
int
ImfHeaderSetV2fAttribute (ImfHeader* hdr, const char name[], float x, float y);

IMF_EXPORT
int ImfHeaderV2fAttribute (
    const ImfHeader* hdr, const char name[], float* x, float* y);

IMF_EXPORT
int ImfHeaderSetV3iAttribute (
    ImfHeader* hdr, const char name[], int x, int y, int z);

IMF_EXPORT
int ImfHeaderV3iAttribute (
    const ImfHeader* hdr, const char name[], int* x, int* y, int* z);

IMF_EXPORT
int ImfHeaderSetV3fAttribute (
    ImfHeader* hdr, const char name[], float x, float y, float z);

IMF_EXPORT
int ImfHeaderV3fAttribute (
    const ImfHeader* hdr, const char name[], float* x, float* y, float* z);

IMF_EXPORT
int ImfHeaderSetM33fAttribute (
    ImfHeader* hdr, const char name[], const float m[3][3]);

IMF_EXPORT
int
ImfHeaderM33fAttribute (const ImfHeader* hdr, const char name[], float m[3][3]);

IMF_EXPORT
int ImfHeaderSetM44fAttribute (
    ImfHeader* hdr, const char name[], const float m[4][4]);

IMF_EXPORT
int
ImfHeaderM44fAttribute (const ImfHeader* hdr, const char name[], float m[4][4]);

/*
** RGBA output file
*/

struct ImfOutputFile;
typedef struct ImfOutputFile ImfOutputFile;

IMF_EXPORT
ImfOutputFile*
ImfOpenOutputFile (const char name[], const ImfHeader* hdr, int channels);

IMF_EXPORT
int ImfCloseOutputFile (ImfOutputFile* out);

IMF_EXPORT
int ImfOutputSetFrameBuffer (
    ImfOutputFile* out, const ImfRgba* base, size_t xStride, size_t yStride);

IMF_EXPORT
int ImfOutputWritePixels (ImfOutputFile* out, int numScanLines);

IMF_EXPORT
int ImfOutputCurrentScanLine (const ImfOutputFile* out);

IMF_EXPORT
const ImfHeader* ImfOutputHeader (const ImfOutputFile* out);

IMF_EXPORT
int ImfOutputChannels (const ImfOutputFile* out);

/*
** Tiled RGBA output file
*/

struct ImfTiledOutputFile;
typedef struct ImfTiledOutputFile ImfTiledOutputFile;

IMF_EXPORT
ImfTiledOutputFile* ImfOpenTiledOutputFile (
    const char       name[],
    const ImfHeader* hdr,
    int              channels,
    int              xSize,
    int              ySize,
    int              mode,
    int              rmode);

IMF_EXPORT
int ImfCloseTiledOutputFile (ImfTiledOutputFile* out);

IMF_EXPORT
int ImfTiledOutputSetFrameBuffer (
    ImfTiledOutputFile* out,
    const ImfRgba*      base,
    size_t              xStride,
    size_t              yStride);

IMF_EXPORT
int ImfTiledOutputWriteTile (
    ImfTiledOutputFile* out, int dx, int dy, int lx, int ly);

IMF_EXPORT
int ImfTiledOutputWriteTiles (
    ImfTiledOutputFile* out,
    int                 dxMin,
    int                 dxMax,
    int                 dyMin,
    int                 dyMax,
    int                 lx,
    int                 ly);

IMF_EXPORT
const ImfHeader* ImfTiledOutputHeader (const ImfTiledOutputFile* out);

IMF_EXPORT
int ImfTiledOutputChannels (const ImfTiledOutputFile* out);

IMF_EXPORT
int ImfTiledOutputTileXSize (const ImfTiledOutputFile* out);

IMF_EXPORT
int ImfTiledOutputTileYSize (const ImfTiledOutputFile* out);

IMF_EXPORT
int ImfTiledOutputLevelMode (const ImfTiledOutputFile* out);

IMF_EXPORT
int ImfTiledOutputLevelRoundingMode (const ImfTiledOutputFile* out);

/*
** RGBA input file
*/

struct ImfInputFile;
typedef struct ImfInputFile ImfInputFile;

IMF_EXPORT
ImfInputFile* ImfOpenInputFile (const char name[]);

IMF_EXPORT
int ImfCloseInputFile (ImfInputFile* in);

IMF_EXPORT
int ImfInputSetFrameBuffer (
    ImfInputFile* in, ImfRgba* base, size_t xStride, size_t yStride);

IMF_EXPORT
int ImfInputReadPixels (ImfInputFile* in, int scanLine1, int scanLine2);

IMF_EXPORT
const ImfHeader* ImfInputHeader (const ImfInputFile* in);

IMF_EXPORT
int ImfInputChannels (const ImfInputFile* in);

IMF_EXPORT
const char* ImfInputFileName (const ImfInputFile* in);

/*
** Tiled RGBA input file
*/

struct ImfTiledInputFile;
typedef struct ImfTiledInputFile ImfTiledInputFile;

IMF_EXPORT
ImfTiledInputFile* ImfOpenTiledInputFile (const char name[]);

IMF_EXPORT
int ImfCloseTiledInputFile (ImfTiledInputFile* in);

IMF_EXPORT
int ImfTiledInputSetFrameBuffer (
    ImfTiledInputFile* in, ImfRgba* base, size_t xStride, size_t yStride);

IMF_EXPORT
int
ImfTiledInputReadTile (ImfTiledInputFile* in, int dx, int dy, int lx, int ly);

IMF_EXPORT
int ImfTiledInputReadTiles (
    ImfTiledInputFile* in,
    int                dxMin,
    int                dxMax,
    int                dyMin,
    int                dyMax,
    int                lx,
    int                ly);

IMF_EXPORT
const ImfHeader* ImfTiledInputHeader (const ImfTiledInputFile* in);

IMF_EXPORT
int ImfTiledInputChannels (const ImfTiledInputFile* in);

IMF_EXPORT
const char* ImfTiledInputFileName (const ImfTiledInputFile* in);

IMF_EXPORT
int ImfTiledInputTileXSize (const ImfTiledInputFile* in);

IMF_EXPORT
int ImfTiledInputTileYSize (const ImfTiledInputFile* in);

IMF_EXPORT
int ImfTiledInputLevelMode (const ImfTiledInputFile* in);

IMF_EXPORT
int ImfTiledInputLevelRoundingMode (const ImfTiledInputFile* in);

/*
** Lookup tables
*/

struct ImfLut;
typedef struct ImfLut ImfLut;

IMF_EXPORT
ImfLut* ImfNewRound12logLut (int channels);

IMF_EXPORT
ImfLut* ImfNewRoundNBitLut (unsigned int n, int channels);

IMF_EXPORT
void ImfDeleteLut (ImfLut* lut);

IMF_EXPORT
void ImfApplyLut (ImfLut* lut, ImfRgba* data, int nData, int stride);
/*
** Most recent error message
*/

IMF_EXPORT
const char* ImfErrorMessage (void);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif
