454 lines
14 KiB
C++
454 lines
14 KiB
C++
//
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
// Copyright (c) Contributors to the OpenEXR Project.
|
|
//
|
|
|
|
#ifndef INCLUDED_IMF_MISC_H
|
|
#define INCLUDED_IMF_MISC_H
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Miscellaneous helper functions for OpenEXR image file I/O
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "ImfForward.h"
|
|
|
|
#include "ImfArray.h"
|
|
#include "ImfCompressor.h"
|
|
#include "ImfPixelType.h"
|
|
|
|
#include <cstddef>
|
|
#include <vector>
|
|
|
|
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
|
|
|
|
//
|
|
// Return the size of a single value of the indicated type,
|
|
// in the machine's native format.
|
|
//
|
|
|
|
IMF_EXPORT
|
|
int pixelTypeSize (PixelType type);
|
|
|
|
//
|
|
// Return the number of samples a channel with subsampling rate
|
|
// s has in the interval [a, b]. For example, a channel with
|
|
// subsampling rate 2 (and samples at 0, 2, 4, 6, 8, etc.) has
|
|
// 2 samples in the interval [1, 5] and three samples in the
|
|
// interval [2, 6].
|
|
//
|
|
|
|
IMF_EXPORT
|
|
int numSamples (int s, int a, int b);
|
|
|
|
//
|
|
// Build a table that lists, for each scanline in a file's
|
|
// data window, how many bytes are required to store all
|
|
// pixels in all channels in that scanline (assuming that
|
|
// the pixel data are tightly packed).
|
|
//
|
|
|
|
IMF_EXPORT
|
|
size_t
|
|
bytesPerLineTable (const Header& header, std::vector<size_t>& bytesPerLine);
|
|
|
|
//
|
|
// Get the sample count for pixel (x, y) using the array base
|
|
// pointer, xStride and yStride.
|
|
//
|
|
|
|
inline int&
|
|
sampleCount (char* base, int xStride, int yStride, int x, int y)
|
|
{
|
|
char* ptr = base + y * ptrdiff_t (yStride) + x * ptrdiff_t (xStride);
|
|
int* intPtr = (int*) ptr;
|
|
|
|
return *intPtr;
|
|
}
|
|
|
|
inline const int&
|
|
sampleCount (const char* base, int xStride, int yStride, int x, int y)
|
|
{
|
|
const char* ptr = base + y * ptrdiff_t (yStride) + x * ptrdiff_t (xStride);
|
|
int* intPtr = (int*) ptr;
|
|
|
|
return *intPtr;
|
|
}
|
|
|
|
//
|
|
// Build a table that lists, for each scanline in a DEEP file's
|
|
// data window, how many bytes are required to store all
|
|
// pixels in all channels in scanlines ranged in [minY, maxY]
|
|
// (assuming that the pixel data are tightly packed).
|
|
//
|
|
|
|
IMF_EXPORT
|
|
size_t bytesPerDeepLineTable (
|
|
const Header& header,
|
|
int minY,
|
|
int maxY,
|
|
const char* base,
|
|
int xStride,
|
|
int yStride,
|
|
std::vector<size_t>& bytesPerLine);
|
|
|
|
//
|
|
// Build a table that lists, for each scanline in a DEEP file's
|
|
// data window, how many bytes are required to store all
|
|
// pixels in all channels in every scanline (assuming that
|
|
// the pixel data are tightly packed).
|
|
//
|
|
|
|
IMF_EXPORT
|
|
size_t bytesPerDeepLineTable (
|
|
const Header& header,
|
|
char* base,
|
|
int xStride,
|
|
int yStride,
|
|
std::vector<size_t>& bytesPerLine);
|
|
|
|
//
|
|
// For scanline-based files, pixels are read or written in
|
|
// in multi-scanline blocks. Internally, class OutputFile
|
|
// and class ScanLineInputFile store a block of scan lines
|
|
// in a "line buffer". Function offsetInLineBufferTable()
|
|
// builds a table that lists, scanlines within range
|
|
// [scanline1, scanline2], the location of the pixel data
|
|
// for the scanline relative to the beginning of the line buffer,
|
|
// where scanline1 = 0 represents the first line in the DATA WINDOW.
|
|
// The one without specifying the range will make scanline1 = 0
|
|
// and scanline2 = bytesPerLine.size().
|
|
//
|
|
|
|
IMF_EXPORT
|
|
void offsetInLineBufferTable (
|
|
const std::vector<size_t>& bytesPerLine,
|
|
int scanline1,
|
|
int scanline2,
|
|
int linesInLineBuffer,
|
|
std::vector<size_t>& offsetInLineBuffer);
|
|
|
|
IMF_EXPORT
|
|
void offsetInLineBufferTable (
|
|
const std::vector<size_t>& bytesPerLine,
|
|
int linesInLineBuffer,
|
|
std::vector<size_t>& offsetInLineBuffer);
|
|
|
|
//
|
|
// For a scanline-based file, compute the range of scanlines
|
|
// that occupy the same line buffer as a given scanline, y.
|
|
// (minY is the minimum y coordinate of the file's data window.)
|
|
//
|
|
|
|
IMF_EXPORT int lineBufferMinY (int y, int minY, int linesInLineBuffer);
|
|
IMF_EXPORT int lineBufferMaxY (int y, int minY, int linesInLineBuffer);
|
|
|
|
//
|
|
// Return a compressor's data format (Compressor::NATIVE or Compressor::XDR).
|
|
// If compressor is 0, return Compressor::XDR.
|
|
//
|
|
|
|
IMF_EXPORT
|
|
Compressor::Format defaultFormat (Compressor* compressor);
|
|
|
|
//
|
|
// Return the number of scan lines a compressor wants to compress
|
|
// or uncompress at once. If compressor is 0, return 1.
|
|
//
|
|
|
|
IMF_EXPORT
|
|
int numLinesInBuffer (Compressor* compressor);
|
|
|
|
//
|
|
// Copy a single channel of a horizontal row of pixels from an
|
|
// input file's internal line buffer or tile buffer into a
|
|
// frame buffer slice. If necessary, perform on-the-fly data
|
|
// type conversion.
|
|
//
|
|
// readPtr initially points to the beginning of the
|
|
// data in the line or tile buffer. readPtr
|
|
// is advanced as the pixel data are copied;
|
|
// when copyIntoFrameBuffer() returns,
|
|
// readPtr points just past the end of the
|
|
// copied data.
|
|
//
|
|
// writePtr, endPtr point to the lefmost and rightmost pixels
|
|
// in the frame buffer slice
|
|
//
|
|
// xStride the xStride for the frame buffer slice
|
|
//
|
|
// format indicates if the line or tile buffer is
|
|
// in NATIVE or XDR format.
|
|
//
|
|
// typeInFrameBuffer the pixel data type of the frame buffer slice
|
|
//
|
|
// typeInFile the pixel data type in the input file's channel
|
|
//
|
|
|
|
IMF_EXPORT
|
|
void copyIntoFrameBuffer (
|
|
const char*& readPtr,
|
|
char* writePtr,
|
|
char* endPtr,
|
|
size_t xStride,
|
|
bool fill,
|
|
double fillValue,
|
|
Compressor::Format format,
|
|
PixelType typeInFrameBuffer,
|
|
PixelType typeInFile);
|
|
|
|
//
|
|
// Copy a single channel of a horizontal row of pixels from an
|
|
// input file's internal line buffer or tile buffer into a
|
|
// frame buffer slice. If necessary, perform on-the-fly data
|
|
// type conversion.
|
|
//
|
|
// readPtr initially points to the beginning of the
|
|
// data in the line or tile buffer. readPtr
|
|
// is advanced as the pixel data are copied;
|
|
// when copyIntoFrameBuffer() returns,
|
|
// readPtr points just past the end of the
|
|
// copied data.
|
|
//
|
|
// base point to each pixel in the framebuffer
|
|
//
|
|
// sampleCountBase, provide the number of samples in each pixel
|
|
// sampleCountXStride,
|
|
// sampleCountYStride
|
|
//
|
|
// y the scanline to copy. The coordinate is
|
|
// relative to the datawindow.min.y.
|
|
//
|
|
// minX, maxX used to indicate which pixels in the scanline
|
|
// will be copied.
|
|
//
|
|
// xOffsetForSampleCount, used to offset the sample count array
|
|
// yOffsetForSampleCount, and the base array.
|
|
// xOffsetForData,
|
|
// yOffsetForData
|
|
//
|
|
// xStride the xStride for the frame buffer slice
|
|
//
|
|
// format indicates if the line or tile buffer is
|
|
// in NATIVE or XDR format.
|
|
//
|
|
// typeInFrameBuffer the pixel data type of the frame buffer slice
|
|
//
|
|
// typeInFile the pixel data type in the input file's channel
|
|
//
|
|
|
|
IMF_EXPORT
|
|
void copyIntoDeepFrameBuffer (
|
|
const char*& readPtr,
|
|
char* base,
|
|
const char* sampleCountBase,
|
|
ptrdiff_t sampleCountXStride,
|
|
ptrdiff_t sampleCountYStride,
|
|
int y,
|
|
int minX,
|
|
int maxX,
|
|
int xOffsetForSampleCount,
|
|
int yOffsetForSampleCount,
|
|
int xOffsetForData,
|
|
int yOffsetForData,
|
|
ptrdiff_t xStride,
|
|
ptrdiff_t xPointerStride,
|
|
ptrdiff_t yPointerStride,
|
|
bool fill,
|
|
double fillValue,
|
|
Compressor::Format format,
|
|
PixelType typeInFrameBuffer,
|
|
PixelType typeInFile);
|
|
|
|
//
|
|
// Given a pointer into a an input file's line buffer or tile buffer,
|
|
// skip over the data for xSize pixels of type typeInFile.
|
|
// readPtr initially points to the beginning of the data to be skipped;
|
|
// when skipChannel() returns, readPtr points just past the end of the
|
|
// skipped data.
|
|
//
|
|
|
|
IMF_EXPORT
|
|
void skipChannel (const char*& readPtr, PixelType typeInFile, size_t xSize);
|
|
|
|
//
|
|
// Convert an array of pixel data from the machine's native
|
|
// representation to XDR format.
|
|
//
|
|
// toPtr, fromPtr initially point to the beginning of the input
|
|
// and output pixel data arrays; when convertInPlace()
|
|
// returns, toPtr and fromPtr point just past the
|
|
// end of the input and output arrays.
|
|
// If the native representation of the data has the
|
|
// same size as the XDR data, then the conversion
|
|
// can take in place, without an intermediate
|
|
// temporary buffer (toPtr and fromPtr can point
|
|
// to the same location).
|
|
//
|
|
// type the pixel data type
|
|
//
|
|
// numPixels number of pixels in the input and output arrays
|
|
//
|
|
|
|
IMF_EXPORT
|
|
void convertInPlace (
|
|
char*& toPtr, const char*& fromPtr, PixelType type, size_t numPixels);
|
|
|
|
//
|
|
// Copy a single channel of a horizontal row of pixels from a
|
|
// a frame buffer into an output file's internal line buffer or
|
|
// tile buffer.
|
|
//
|
|
// writePtr initially points to the beginning of the
|
|
// data in the line or tile buffer. writePtr
|
|
// is advanced as the pixel data are copied;
|
|
// when copyFromFrameBuffer() returns,
|
|
// writePtr points just past the end of the
|
|
// copied data.
|
|
//
|
|
// readPtr, endPtr point to the lefmost and rightmost pixels
|
|
// in the frame buffer slice
|
|
//
|
|
// xStride the xStride for the frame buffer slice
|
|
//
|
|
// format indicates if the line or tile buffer is
|
|
// in NATIVE or XDR format.
|
|
//
|
|
// type the pixel data type in the frame buffer
|
|
// and in the output file's channel (function
|
|
// copyFromFrameBuffer() doesn't do on-the-fly
|
|
// data type conversion)
|
|
//
|
|
|
|
IMF_EXPORT
|
|
void copyFromFrameBuffer (
|
|
char*& writePtr,
|
|
const char*& readPtr,
|
|
const char* endPtr,
|
|
size_t xStride,
|
|
Compressor::Format format,
|
|
PixelType type);
|
|
|
|
//
|
|
// Copy a single channel of a horizontal row of pixels from a
|
|
// a frame buffer in a deep data file into an output file's
|
|
// internal line buffer or tile buffer.
|
|
//
|
|
// writePtr initially points to the beginning of the
|
|
// data in the line or tile buffer. writePtr
|
|
// is advanced as the pixel data are copied;
|
|
// when copyFromDeepFrameBuffer() returns,
|
|
// writePtr points just past the end of the
|
|
// copied data.
|
|
//
|
|
// base the start pointer of each pixel in this channel.
|
|
// It points to the real data in FrameBuffer.
|
|
// It is different for different channels.
|
|
// dataWindowMinX and dataWindowMinY are involved in
|
|
// locating for base.
|
|
//
|
|
// sampleCountBase, used to locate the position to get
|
|
// sampleCountXStride, the number of samples for each pixel.
|
|
// sampleCountYStride Used to determine how far we should
|
|
// read based on the pointer provided by base.
|
|
//
|
|
// y the scanline to copy. If we are dealing
|
|
// with a tiled deep file, then probably a portion
|
|
// of the scanline is copied.
|
|
//
|
|
// xMin, xMax used to indicate which pixels in the scanline
|
|
// will be copied.
|
|
//
|
|
// xOffsetForSampleCount, used to offset the sample count array
|
|
// yOffsetForSampleCount, and the base array.
|
|
// xOffsetForData,
|
|
// yOffsetForData
|
|
//
|
|
// xStride the xStride for the frame buffer slice
|
|
//
|
|
// format indicates if the line or tile buffer is
|
|
// in NATIVE or XDR format.
|
|
//
|
|
// type the pixel data type in the frame buffer
|
|
// and in the output file's channel (function
|
|
// copyFromFrameBuffer() doesn't do on-the-fly
|
|
// data type conversion)
|
|
//
|
|
|
|
IMF_EXPORT
|
|
void copyFromDeepFrameBuffer (
|
|
char*& writePtr,
|
|
const char* base,
|
|
char* sampleCountBase,
|
|
ptrdiff_t sampleCountXStride,
|
|
ptrdiff_t sampleCountYStride,
|
|
int y,
|
|
int xMin,
|
|
int xMax,
|
|
int xOffsetForSampleCount,
|
|
int yOffsetForSampleCount,
|
|
int xOffsetForData,
|
|
int yOffsetForData,
|
|
ptrdiff_t sampleStride,
|
|
ptrdiff_t xStrideForData,
|
|
ptrdiff_t yStrideForData,
|
|
Compressor::Format format,
|
|
PixelType type);
|
|
|
|
//
|
|
// Fill part of an output file's line buffer or tile buffer with
|
|
// zeroes. This routine is called when an output file contains
|
|
// a channel for which the frame buffer contains no corresponding
|
|
// slice.
|
|
//
|
|
// writePtr initially points to the beginning of the
|
|
// data in the line or tile buffer. When
|
|
// fillChannelWithZeroes() returns, writePtr
|
|
// points just past the end of the zeroed
|
|
// data.
|
|
//
|
|
// format indicates if the line or tile buffer is
|
|
// in NATIVE or XDR format.
|
|
//
|
|
// type the pixel data type in the line or frame buffer.
|
|
//
|
|
// xSize number of pixels to be filled with zeroes.
|
|
//
|
|
|
|
IMF_EXPORT
|
|
void fillChannelWithZeroes (
|
|
char*& writePtr, Compressor::Format format, PixelType type, size_t xSize);
|
|
|
|
IMF_EXPORT
|
|
bool usesLongNames (const Header& header);
|
|
|
|
//
|
|
// compute size of chunk offset table - for existing types, computes
|
|
// the chunk size from the image size, compression type, and tile
|
|
// description (for tiled types). If the type is not supported, uses
|
|
// the chunkCount attribute if present, or throws an exception
|
|
// otherwise
|
|
//
|
|
|
|
IMF_EXPORT
|
|
int getChunkOffsetTableSize (const Header& header);
|
|
|
|
//
|
|
// Convert a filename to a wide string. This is useful for working with
|
|
// filenames on Windows.
|
|
//
|
|
|
|
IMF_EXPORT
|
|
std::wstring WidenFilename (const char* filename);
|
|
|
|
//
|
|
// Return the string that describes the major.minor.patch release version
|
|
//
|
|
|
|
IMF_EXPORT const char* getLibraryVersion ();
|
|
|
|
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
|
|
|
|
#endif
|