Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/dpx.imageio/dpxinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ DPXInput::seek_subimage(int subimage, int miplevel)
m_spec = ImageSpec(m_dpx.header.Width(), m_dpx.header.Height(),
m_dpx.header.ImageElementComponentCount(subimage),
typedesc);
if (!check_open(m_spec, { 0, 1 << 20, 0, 1 << 20, 0, 1 << 16, 0, 8 }))
return false;

// xOffset/yOffset are defined as unsigned 32-bit integers, but m_spec.x/y are signed
// avoid casts that would result in negative values
Expand Down Expand Up @@ -599,7 +601,8 @@ DPXInput::read_native_scanlines(int subimage, int miplevel, int ybegin,
} else {
// read the scanline and convert to RGB
unsigned char* ptr = (unsigned char*)data;
int bufsize = dpx::QueryRGBBufferSize(m_dpx.header, subimage, block);
int64_t bufsize = dpx::QueryRGBBufferSize(m_dpx.header, subimage,
block);
if (bufsize > 0) {
m_decodebuf.resize(bufsize);
ptr = m_decodebuf.data();
Expand Down
84 changes: 45 additions & 39 deletions src/dpx.imageio/libdpx/DPXColorConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,22 @@


#include "DPXColorConverter.h"
#include <OpenImageIO/fmath.h>
#include <OpenImageIO/span.h>
#include <algorithm>

namespace dpx {
template <typename DATA>
static inline bool SwapRGBABytes(const DATA *input, DATA *output, int pixels) {
// copy the data that could be destroyed to an additional buffer in case input == output
DATA tmp[2];
for (int i = 0; i < pixels; i++) {
memcpy(tmp, &input[i * 4], sizeof(DATA) * 2);
output[i * 4 + 0] = input[i * 4 + 3];
output[i * 4 + 1] = input[i * 4 + 2];
output[i * 4 + 2] = tmp[1];
output[i * 4 + 3] = tmp[0];
static inline bool SwapRGBABytes(OIIO::cspan<DATA> input, OIIO::span<DATA> output) {
// Because we are within the lengths by definition, we can just use
// data pointers below to avoid a bounds check on every one.
size_t pixels = input.size() / 4;
for (size_t i = 0; i < pixels; i++) {
DATA a = input.data()[i * 4 + 0], b = input.data()[i * 4 + 1];
output.data()[i * 4 + 0] = input.data()[i * 4 + 3];
output.data()[i * 4 + 1] = input.data()[i * 4 + 2];
output.data()[i * 4 + 2] = b;
output.data()[i * 4 + 3] = a;
}
return true;
}
Expand Down Expand Up @@ -107,12 +110,12 @@ namespace dpx {

// 4:4:4
template <typename DATA, unsigned int max>
static bool ConvertCbYCrToRGB(const Characteristic space, const DATA *input, DATA *output, const int pixels) {
static bool ConvertCbYCrToRGB(const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
const float *matrix = GetYCbCrToRGBColorMatrix(space);
if (matrix == NULL)
return false;
DATA RGB[3];
for (int i = 0; i < pixels; i++) {
for (size_t i = 0; i < pixels; i++) {
ConvertPixelYCbCrToRGB<DATA, max>(&input[i * 3], RGB, matrix);
memcpy(&output[i * 3], RGB, sizeof(DATA) * 3);
}
Expand All @@ -121,12 +124,12 @@ namespace dpx {

// 4:4:4:4
template <typename DATA, unsigned int max>
static bool ConvertCbYCrAToRGBA(const Characteristic space, const DATA *input, DATA *output, const int pixels) {
static bool ConvertCbYCrAToRGBA(const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
const float *matrix = GetYCbCrToRGBColorMatrix(space);
if (matrix == NULL)
return false;
DATA RGBA[4];
for (int i = 0; i < pixels; i++) {
for (size_t i = 0; i < pixels; i++) {
ConvertPixelYCbCrToRGB<DATA, max>(&input[i * 4], RGBA, matrix);
RGBA[3] = input[i * 4 + 3];
memcpy(&output[i * 4], RGBA, sizeof(DATA) * 4);
Expand All @@ -136,12 +139,12 @@ namespace dpx {

// 4:2:2
template <typename DATA, unsigned int max>
static bool ConvertCbYCrYToRGB(const Characteristic space, const DATA *input, DATA *output, const int pixels) {
static bool ConvertCbYCrYToRGB(const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
const float *matrix = GetYCbCrToRGBColorMatrix(space);
if (matrix == NULL)
return false;
DATA CbYCr[3];
for (int i = 0; i < pixels; i++) {
for (size_t i = 0; i < pixels; i++) {
// upsample to 4:4:4
// FIXME: proper interpolation
CbYCr[0] = input[(i | 1) * 2]; // Cb
Expand All @@ -155,12 +158,12 @@ namespace dpx {

// 4:2:2:4
template <typename DATA, unsigned int max>
static bool ConvertCbYACrYAToRGBA(const Characteristic space, const DATA *input, DATA *output, const int pixels) {
static bool ConvertCbYACrYAToRGBA(const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
const float *matrix = GetYCbCrToRGBColorMatrix(space);
if (matrix == NULL)
return false;
DATA CbYCr[3];
for (int i = 0; i < pixels; i++) {
for (size_t i = 0; i < pixels; i++) {
// upsample to 4:4:4
// FIXME: proper interpolation
CbYCr[0] = input[(i | 1) * 3]; // Cb
Expand All @@ -174,7 +177,7 @@ namespace dpx {
}

static inline bool ConvertToRGBInternal(const Descriptor desc, const DataSize size, const Characteristic space,
const void *input, void *output, const int pixels) {
const void *input, void *output, const size_t pixels) {
switch (desc) {
// redundant calls
case kRGB:
Expand All @@ -185,19 +188,19 @@ namespace dpx {
case kABGR:
switch (size) {
case kByte:
return SwapRGBABytes<U8>((const U8 *)input, (U8 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<U8>((const U8*)input, pixels*4), OIIO::span<U8>((U8*)output, pixels*4));
case kWord:
return SwapRGBABytes<U16>((const U16 *)input, (U16 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<U16>((const U16*)input, pixels*4), OIIO::span<U16>((U16*)output, pixels*4));
case kInt:
return SwapRGBABytes<U32>((const U32 *)input, (U32 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<U32>((const U32*)input, pixels*4), OIIO::span<U32>((U32*)output, pixels*4));
case kFloat:
return SwapRGBABytes<R32>((const R32 *)input, (R32 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<R32>((const R32*)input, pixels*4), OIIO::span<R32>((R32*)output, pixels*4));
case kDouble:
return SwapRGBABytes<R64>((const R64 *)input, (R64 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<R64>((const R64*)input, pixels*4), OIIO::span<R64>((R64*)output, pixels*4));
}
// shouldn't ever get here
return false;


// FIXME: can this be translated to RGB?
//case kCompositeVideo:
Expand Down Expand Up @@ -287,7 +290,7 @@ namespace dpx {
}
}

static inline int QueryRGBBufferSizeInternal(const Descriptor desc, const int pixels, const int bytes) {
static inline int64_t QueryRGBBufferSizeInternal(const Descriptor desc, const size_t pixels, const size_t bytes) {
switch (desc) {
//case kCompositeVideo: // FIXME: can this be translated to RGB?
case kCbYCrY: // 4:2:2 -> RGB, requires allocation
Expand Down Expand Up @@ -329,9 +332,10 @@ namespace dpx {
}
}

int QueryRGBBufferSize(const Header &header, const int element, const Block &block) {
int64_t QueryRGBBufferSize(const Header &header, const size_t element, const Block &block) {
return QueryRGBBufferSizeInternal(header.ImageDescriptor(element),
(block.x2 - block.x1 + 1) * (block.y2 - block.y1 + 1),
OIIO::clamped_mult64(block.x2 - block.x1 + 1,
block.y2 - block.y1 + 1),
header.ComponentByteCount(element));
}

Expand All @@ -344,10 +348,12 @@ namespace dpx {
#endif /* NOT USED IN OIIO */

bool ConvertToRGB(const Header &header, const int element, const void *input, void *output, const Block &block) {
return ConvertToRGBInternal(header.ImageDescriptor(element),
header.ComponentDataSize(element), header.Colorimetric(element),
input, output, (block.x2 - block.x1 + 1) * (block.y2 - block.y1 + 1));
}
return ConvertToRGBInternal(
header.ImageDescriptor(element),
header.ComponentDataSize(element), header.Colorimetric(element),
input, output, OIIO::clamped_mult64(block.x2 - block.x1 + 1,
block.y2 - block.y1 + 1));
}

#if 0 /* NOT USED IN OIIO */
bool ConvertToRGB(const Header &header, const int element, const void *input, void *output) {
Expand Down Expand Up @@ -479,7 +485,7 @@ namespace dpx {
#endif /* NOT USED IN OIIO */

static inline bool ConvertToNativeInternal(const Descriptor desc, const DataSize size, const Characteristic space,
const void *input, void *output, const int pixels) {
const void *input, void *output, const size_t pixels) {
switch (desc) {
// redundant calls
case kRGB:
Expand All @@ -491,15 +497,15 @@ namespace dpx {
case kABGR:
switch (size) {
case kByte:
return SwapRGBABytes<U8>((const U8 *)input, (U8 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<U8>((const U8*)input, pixels*4), OIIO::span<U8>((U8*)output, pixels*4));
case kWord:
return SwapRGBABytes<U16>((const U16 *)input, (U16 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<U16>((const U16*)input, pixels*4), OIIO::span<U16>((U16*)output, pixels*4));
case kInt:
return SwapRGBABytes<U32>((const U32 *)input, (U32 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<U32>((const U32*)input, pixels*4), OIIO::span<U32>((U32*)output, pixels*4));
case kFloat:
return SwapRGBABytes<R32>((const R32 *)input, (R32 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<R32>((const R32*)input, pixels*4), OIIO::span<R32>((R32*)output, pixels*4));
case kDouble:
return SwapRGBABytes<R64>((const R64 *)input, (R64 *)output, pixels);
return SwapRGBABytes(OIIO::cspan<R64>((const R64*)input, pixels*4), OIIO::span<R64>((R64*)output, pixels*4));
}
// shouldn't ever get here
return false;
Expand Down Expand Up @@ -647,7 +653,7 @@ namespace dpx {
}
#endif /* NOT USED IN OIIO */

bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const int width, const int height, const void *input, void *output) {
return ConvertToNativeInternal(desc, compSize, cmetr, input, output, width * height);
bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const size_t width, const size_t height, const void *input, void *output) {
return ConvertToNativeInternal(desc, compSize, cmetr, input, output, OIIO::clamped_mult64(width, height));
}
}
10 changes: 7 additions & 3 deletions src/dpx.imageio/libdpx/DPXColorConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ namespace dpx
* of the buffer in bytes; sign: positive - memory needs to be allocated,
* negative - allocation is optional, decoded data can replace the input
*/
int QueryRGBBufferSize(const Header &header, const int element, const Block &block);
int64_t QueryRGBBufferSize(const Header &header, const size_t element, const Block &block);

#if 0 /* NOT USED IN OIIO */
/*!
* \brief Query the size of the buffer necessary to hold the decoded RGB data
* \param header DPX header
Expand All @@ -64,7 +65,8 @@ namespace dpx
* of the buffer in bytes; sign: positive - memory needs to be allocated,
* negative - allocation is optional, decoded data can replace the input
*/
int QueryRGBBufferSize(const Header &header, const int element);
int QueryRGBBufferSize(const Header &header, const size_t element);
#endif

/*!
* \brief Convert native data from the input buffer into RGB in the output buffer
Expand All @@ -78,6 +80,7 @@ namespace dpx
*/
bool ConvertToRGB(const Header &header, const int element, const void *input, void *output, const Block &block);

#if 0 /* NOT USED IN OIIO */
/*!
* \brief Convert native data from the input buffer into RGB in the output buffer
* \param header DPX header
Expand Down Expand Up @@ -122,6 +125,7 @@ namespace dpx
* \return success true/false
*/
bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const void *input, void *output, const Block &block);
#endif

/*!
* \brief Convert RGB data from the input buffer into native format in the output buffer
Expand All @@ -132,7 +136,7 @@ namespace dpx
* \param output output buffer data; can be same as input if \ref QueryNativeBufferSize returns a negative number
* \return success true/false
*/
bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const int width, const int height, const void *input, void *output);
bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const size_t width, const size_t height, const void *input, void *output);

}

Expand Down
Loading