Add Chromium-only Blender WebEngine parity work
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# SPDX-FileCopyrightText: 2006 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(INC
|
||||
.
|
||||
..
|
||||
../..
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
cineonlib.h
|
||||
dpxlib.h
|
||||
logImageCore.h
|
||||
logmemfile.h
|
||||
|
||||
cineon_dpx.cc
|
||||
cineonlib.cc
|
||||
dpxlib.cc
|
||||
logImageCore.cc
|
||||
logmemfile.cc
|
||||
)
|
||||
|
||||
set(LIB
|
||||
PRIVATE bf::blenkernel
|
||||
PRIVATE bf::blenlib
|
||||
PRIVATE bf::dna
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
)
|
||||
|
||||
if(WITH_IMAGE_CINEON)
|
||||
add_definitions(-DWITH_IMAGE_CINEON)
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_imbuf_cineon "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
8
blender-5.2.0/source/blender/imbuf/intern/cineon/README
Normal file
8
blender-5.2.0/source/blender/imbuf/intern/cineon/README
Normal file
@@ -0,0 +1,8 @@
|
||||
Files:
|
||||
|
||||
logImageLib.h, logImageLib.c: combined cineon/dpx image library
|
||||
dpxlib.h, dpxlib.c: dpx specific library
|
||||
dpxfile.h: dpx file structure
|
||||
cineonlib.h, cineonlib.c: cineon specific library
|
||||
cineonfile.h: cineon file structure
|
||||
logImageCore.h, logImageCore.c: log image routines common to cineon amd dpx
|
||||
196
blender-5.2.0/source/blender/imbuf/intern/cineon/cineon_dpx.cc
Normal file
196
blender-5.2.0/source/blender/imbuf/intern/cineon/cineon_dpx.cc
Normal file
@@ -0,0 +1,196 @@
|
||||
/* SPDX-FileCopyrightText: 2006 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbcineon
|
||||
*/
|
||||
|
||||
#include "logImageCore.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "IMB_colormanagement.hh"
|
||||
#include "IMB_filetype.hh"
|
||||
#include "IMB_imbuf.hh"
|
||||
#include "IMB_imbuf_types.hh"
|
||||
|
||||
#include "BKE_global.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
static ImBuf *imb_load_dpx_cineon(const uchar *mem,
|
||||
size_t size,
|
||||
int use_cineon,
|
||||
ImBufFlags flags,
|
||||
ImFileColorSpace &r_colorspace)
|
||||
{
|
||||
ImBuf *ibuf;
|
||||
LogImageFile *image;
|
||||
int width, height, depth;
|
||||
|
||||
logImageSetVerbose((G.debug & G_DEBUG) ? 1 : 0);
|
||||
|
||||
image = logImageOpenFromMemory(mem, size);
|
||||
|
||||
if (image == nullptr) {
|
||||
printf("DPX/Cineon: error opening image.\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
logImageGetSize(image, &width, &height, &depth);
|
||||
|
||||
ibuf = IMB_allocImBuf(width, height, ImBufFlags::FloatData | flags);
|
||||
if (ibuf == nullptr) {
|
||||
logImageClose(image);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!flag_is_set(flags, ImBufFlags::Test)) {
|
||||
if (logImageGetDataRGBA(image, ibuf->float_data_for_write(), 1) != 0) {
|
||||
logImageClose(image);
|
||||
IMB_freeImBuf(ibuf);
|
||||
return nullptr;
|
||||
}
|
||||
IMB_flipy(ibuf);
|
||||
}
|
||||
|
||||
logImageClose(image);
|
||||
ibuf->ftype = use_cineon ? IMB_FTYPE_CINEON : IMB_FTYPE_DPX;
|
||||
|
||||
if (flag_is_set(flags, ImBufFlags::AlphaDetect)) {
|
||||
ibuf->flags |= ImBufFlags::AlphaPremul;
|
||||
}
|
||||
|
||||
r_colorspace.is_hdr_float = true;
|
||||
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon)
|
||||
{
|
||||
LogImageFile *logImage;
|
||||
float *fbuf;
|
||||
float *fbuf_ptr;
|
||||
const uchar *rect_ptr;
|
||||
int x, y, bitspersample, rvalue;
|
||||
|
||||
logImageSetVerbose((G.debug & G_DEBUG) ? 1 : 0);
|
||||
|
||||
if (!ELEM(ibuf->color_mode, ImColorMode::RGB, ImColorMode::RGBA)) {
|
||||
printf("DPX/Cineon: only RGB/RGBA is supported, file: '%s'\n", filepath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (use_cineon) {
|
||||
/* Only 10bit is supported. */
|
||||
bitspersample = 10;
|
||||
}
|
||||
else {
|
||||
if (ibuf->foptions.flag & CINEON_10BIT) {
|
||||
bitspersample = 10;
|
||||
}
|
||||
else if (ibuf->foptions.flag & CINEON_12BIT) {
|
||||
bitspersample = 12;
|
||||
}
|
||||
else if (ibuf->foptions.flag & CINEON_16BIT) {
|
||||
bitspersample = 16;
|
||||
}
|
||||
else {
|
||||
bitspersample = 8;
|
||||
}
|
||||
}
|
||||
|
||||
const bool has_alpha = ibuf->color_mode == ImColorMode::RGBA;
|
||||
logImage = logImageCreate(filepath,
|
||||
use_cineon,
|
||||
ibuf->x,
|
||||
ibuf->y,
|
||||
bitspersample,
|
||||
has_alpha,
|
||||
(ibuf->foptions.flag & CINEON_LOG),
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
"Blender");
|
||||
|
||||
if (logImage == nullptr) {
|
||||
printf("DPX/Cineon: error creating file.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ibuf->float_data() != nullptr && bitspersample != 8) {
|
||||
/* Don't use the float buffer to save 8 BPP picture to prevent color banding
|
||||
* (there's no dithering algorithm behind the #logImageSetDataRGBA function). */
|
||||
|
||||
fbuf = MEM_new_array_uninitialized<float>(4 * size_t(ibuf->x) * size_t(ibuf->y),
|
||||
"fbuf in imb_save_dpx_cineon");
|
||||
|
||||
for (y = 0; y < ibuf->y; y++) {
|
||||
float *dst_ptr = fbuf + (4 * (size_t(ibuf->y - y - 1) * size_t(ibuf->x)));
|
||||
const float *src_ptr = ibuf->float_data() + (4 * (size_t(y) * size_t(ibuf->x)));
|
||||
|
||||
memcpy(dst_ptr, src_ptr, 4 * ibuf->x * sizeof(float));
|
||||
}
|
||||
|
||||
rvalue = (logImageSetDataRGBA(logImage, fbuf, 1) == 0);
|
||||
|
||||
MEM_delete(fbuf);
|
||||
}
|
||||
else {
|
||||
if (ibuf->byte_data()) {
|
||||
IMB_byte_from_float(ibuf);
|
||||
}
|
||||
|
||||
fbuf = MEM_new_array_uninitialized<float>(4 * size_t(ibuf->x) * size_t(ibuf->y),
|
||||
"fbuf in imb_save_dpx_cineon");
|
||||
if (fbuf == nullptr) {
|
||||
printf("DPX/Cineon: error allocating memory.\n");
|
||||
logImageClose(logImage);
|
||||
return 0;
|
||||
}
|
||||
const uint8_t *byte_data = ibuf->byte_data();
|
||||
for (y = 0; y < ibuf->y; y++) {
|
||||
fbuf_ptr = fbuf + (4 * (size_t(ibuf->y - y - 1) * size_t(ibuf->x)));
|
||||
rect_ptr = byte_data + (4 * (size_t(y) * size_t(ibuf->x)));
|
||||
for (x = 0; x < ibuf->x; x++) {
|
||||
fbuf_ptr[0] = float(rect_ptr[0]) / 255.0f;
|
||||
fbuf_ptr[1] = float(rect_ptr[1]) / 255.0f;
|
||||
fbuf_ptr[2] = float(rect_ptr[2]) / 255.0f;
|
||||
fbuf_ptr[3] = has_alpha ? (float(rect_ptr[3]) / 255.0f) : 1.0f;
|
||||
fbuf_ptr += 4;
|
||||
rect_ptr += 4;
|
||||
}
|
||||
}
|
||||
rvalue = (logImageSetDataRGBA(logImage, fbuf, 0) == 0);
|
||||
MEM_delete(fbuf);
|
||||
}
|
||||
|
||||
logImageClose(logImage);
|
||||
return rvalue;
|
||||
}
|
||||
|
||||
bool imb_save_cineon(ImBuf *buf, const char *filepath, ImBufFlags /*flags*/)
|
||||
{
|
||||
return imb_save_dpx_cineon(buf, filepath, 1);
|
||||
}
|
||||
|
||||
bool imb_is_a_cineon(const uchar *mem, size_t size)
|
||||
{
|
||||
return logImageIsCineon(mem, size);
|
||||
}
|
||||
|
||||
ImBuf *imb_load_cineon(const uchar *mem,
|
||||
size_t size,
|
||||
ImBufFlags flags,
|
||||
ImFileColorSpace &r_colorspace)
|
||||
{
|
||||
if (!imb_is_a_cineon(mem, size)) {
|
||||
return nullptr;
|
||||
}
|
||||
return imb_load_dpx_cineon(mem, size, 1, flags, r_colorspace);
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
429
blender-5.2.0/source/blender/imbuf/intern/cineon/cineonlib.cc
Normal file
429
blender-5.2.0/source/blender/imbuf/intern/cineon/cineonlib.cc
Normal file
@@ -0,0 +1,429 @@
|
||||
/* SPDX-FileCopyrightText: 1999-2001 David Hodson <hodsond@acm.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbcineon
|
||||
*
|
||||
* Cineon image file format library routines.
|
||||
*/
|
||||
|
||||
#include "cineonlib.h"
|
||||
#include "logmemfile.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/*
|
||||
* For debug purpose
|
||||
*/
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
void cineonSetVerbose(int verbosity)
|
||||
{
|
||||
verbose = verbosity;
|
||||
}
|
||||
|
||||
static void fillCineonMainHeader(LogImageFile *cineon,
|
||||
CineonMainHeader *header,
|
||||
const char *filepath,
|
||||
const char *creator)
|
||||
{
|
||||
time_t fileClock;
|
||||
const tm *fileTime;
|
||||
int i;
|
||||
|
||||
memset(header, 0, sizeof(CineonMainHeader));
|
||||
|
||||
/* --- File header --- */
|
||||
header->fileHeader.magic_num = swap_uint(CINEON_FILE_MAGIC, cineon->isMSB);
|
||||
header->fileHeader.offset = swap_uint(cineon->element[0].dataOffset, cineon->isMSB);
|
||||
header->fileHeader.gen_hdr_size = swap_uint(
|
||||
sizeof(CineonFileHeader) + sizeof(CineonImageHeader) + sizeof(CineonOriginationHeader),
|
||||
cineon->isMSB);
|
||||
header->fileHeader.ind_hdr_size = 0;
|
||||
header->fileHeader.user_data_size = 0;
|
||||
header->fileHeader.file_size = swap_uint(
|
||||
cineon->element[0].dataOffset +
|
||||
cineon->height * getRowLength(cineon->width, &cineon->element[0]),
|
||||
cineon->isMSB);
|
||||
STRNCPY(header->fileHeader.version, "v4.5");
|
||||
STRNCPY(header->fileHeader.file_name, filepath);
|
||||
fileClock = time(nullptr);
|
||||
fileTime = localtime(&fileClock);
|
||||
strftime(header->fileHeader.creation_date, 12, "%Y:%m:%d", fileTime);
|
||||
strftime(header->fileHeader.creation_time, 12, "%H:%M:%S%Z", fileTime);
|
||||
header->fileHeader.creation_time[11] = 0;
|
||||
|
||||
/* --- Image header --- */
|
||||
header->imageHeader.orientation = 0;
|
||||
header->imageHeader.elements_per_image = cineon->depth;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
header->imageHeader.element[i].descriptor1 = 0;
|
||||
header->imageHeader.element[i].descriptor2 = i;
|
||||
header->imageHeader.element[i].bits_per_sample = cineon->element[0].bitsPerSample;
|
||||
header->imageHeader.element[i].pixels_per_line = swap_uint(cineon->width, cineon->isMSB);
|
||||
header->imageHeader.element[i].lines_per_image = swap_uint(cineon->height, cineon->isMSB);
|
||||
header->imageHeader.element[i].ref_low_data = swap_uint(cineon->element[0].refLowData,
|
||||
cineon->isMSB);
|
||||
header->imageHeader.element[i].ref_low_quantity = swap_float(cineon->element[0].refLowQuantity,
|
||||
cineon->isMSB);
|
||||
header->imageHeader.element[i].ref_high_data = swap_uint(cineon->element[0].refHighData,
|
||||
cineon->isMSB);
|
||||
header->imageHeader.element[i].ref_high_quantity = swap_float(
|
||||
cineon->element[0].refHighQuantity, cineon->isMSB);
|
||||
}
|
||||
|
||||
header->imageHeader.white_point_x = swap_float(0.0f, cineon->isMSB);
|
||||
header->imageHeader.white_point_y = swap_float(0.0f, cineon->isMSB);
|
||||
header->imageHeader.red_primary_x = swap_float(0.0f, cineon->isMSB);
|
||||
header->imageHeader.red_primary_y = swap_float(0.0f, cineon->isMSB);
|
||||
header->imageHeader.green_primary_x = swap_float(0.0f, cineon->isMSB);
|
||||
header->imageHeader.green_primary_y = swap_float(0.0f, cineon->isMSB);
|
||||
header->imageHeader.blue_primary_x = swap_float(0.0f, cineon->isMSB);
|
||||
header->imageHeader.blue_primary_y = swap_float(0.0f, cineon->isMSB);
|
||||
STRNCPY(header->imageHeader.label, creator);
|
||||
header->imageHeader.interleave = 0;
|
||||
header->imageHeader.data_sign = 0;
|
||||
header->imageHeader.sense = 0;
|
||||
header->imageHeader.line_padding = swap_uint(0, cineon->isMSB);
|
||||
header->imageHeader.element_padding = swap_uint(0, cineon->isMSB);
|
||||
|
||||
switch (cineon->element[0].packing) {
|
||||
case 0:
|
||||
header->imageHeader.packing = 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
header->imageHeader.packing = 5;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
header->imageHeader.packing = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
/* --- Origination header --- */
|
||||
/* we leave it blank */
|
||||
|
||||
/* --- Film header --- */
|
||||
/* we leave it blank */
|
||||
}
|
||||
|
||||
LogImageFile *cineonOpen(const uchar *byteStuff, int fromMemory, size_t bufferSize)
|
||||
{
|
||||
CineonMainHeader header;
|
||||
LogImageFile *cineon = MEM_new_uninitialized<LogImageFile>(__func__);
|
||||
const char *filepath = reinterpret_cast<const char *>(byteStuff);
|
||||
int i;
|
||||
uint dataOffset;
|
||||
|
||||
if (cineon == nullptr) {
|
||||
if (verbose) {
|
||||
printf("Cineon: Failed to malloc cineon file structure.\n");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* zero the header */
|
||||
memset(&header, 0, sizeof(CineonMainHeader));
|
||||
|
||||
/* for close routine */
|
||||
cineon->file = nullptr;
|
||||
|
||||
if (fromMemory == 0) {
|
||||
/* byteStuff is then the filepath */
|
||||
cineon->file = BLI_fopen(filepath, "rb");
|
||||
if (cineon->file == nullptr) {
|
||||
if (verbose) {
|
||||
printf("Cineon: Failed to open file \"%s\".\n", filepath);
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
/* not used in this case */
|
||||
cineon->memBuffer = nullptr;
|
||||
cineon->memCursor = nullptr;
|
||||
cineon->memBufferSize = 0;
|
||||
}
|
||||
else {
|
||||
cineon->memBuffer = const_cast<uchar *>(byteStuff);
|
||||
cineon->memCursor = const_cast<uchar *>(byteStuff);
|
||||
cineon->memBufferSize = bufferSize;
|
||||
}
|
||||
|
||||
if (logimage_fread(&header, sizeof(header), 1, cineon) == 0) {
|
||||
if (verbose) {
|
||||
printf("Cineon: Not enough data for header in \"%s\".\n", byteStuff);
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* endianness determination */
|
||||
if (header.fileHeader.magic_num == swap_uint(CINEON_FILE_MAGIC, 1)) {
|
||||
cineon->isMSB = 1;
|
||||
if (verbose) {
|
||||
printf("Cineon: File is MSB.\n");
|
||||
}
|
||||
}
|
||||
else if (header.fileHeader.magic_num == CINEON_FILE_MAGIC) {
|
||||
cineon->isMSB = 0;
|
||||
if (verbose) {
|
||||
printf("Cineon: File is LSB.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (verbose) {
|
||||
printf("Cineon: Bad magic number %lu in \"%s\".\n",
|
||||
ulong(header.fileHeader.magic_num),
|
||||
byteStuff);
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cineon->width = swap_uint(header.imageHeader.element[0].pixels_per_line, cineon->isMSB);
|
||||
cineon->height = swap_uint(header.imageHeader.element[0].lines_per_image, cineon->isMSB);
|
||||
|
||||
if (cineon->width == 0 || cineon->height == 0) {
|
||||
if (verbose) {
|
||||
printf("Cineon: Wrong image dimension: %dx%d\n", cineon->width, cineon->height);
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cineon->depth = header.imageHeader.elements_per_image;
|
||||
cineon->srcFormat = format_Cineon;
|
||||
|
||||
if (header.imageHeader.interleave == 0) {
|
||||
cineon->numElements = 1;
|
||||
}
|
||||
else if (header.imageHeader.interleave == 2) {
|
||||
cineon->numElements = header.imageHeader.elements_per_image;
|
||||
}
|
||||
else {
|
||||
if (verbose) {
|
||||
printf("Cineon: Data interleave not supported: %d\n", header.imageHeader.interleave);
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (cineon->depth == 1) {
|
||||
/* Gray-scale image. */
|
||||
cineon->element[0].descriptor = descriptor_Luminance;
|
||||
cineon->element[0].transfer = transfer_Linear;
|
||||
cineon->element[0].depth = 1;
|
||||
}
|
||||
else if (cineon->depth == 3) {
|
||||
/* RGB image. */
|
||||
if (cineon->numElements == 1) {
|
||||
cineon->element[0].descriptor = descriptor_RGB;
|
||||
cineon->element[0].transfer = transfer_PrintingDensity;
|
||||
cineon->element[0].depth = 3;
|
||||
}
|
||||
else if (cineon->numElements == 3) {
|
||||
cineon->element[0].descriptor = descriptor_Red;
|
||||
cineon->element[0].transfer = transfer_PrintingDensity;
|
||||
cineon->element[0].depth = 1;
|
||||
cineon->element[1].descriptor = descriptor_Green;
|
||||
cineon->element[1].transfer = transfer_PrintingDensity;
|
||||
cineon->element[1].depth = 1;
|
||||
cineon->element[2].descriptor = descriptor_Blue;
|
||||
cineon->element[2].transfer = transfer_PrintingDensity;
|
||||
cineon->element[2].depth = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (verbose) {
|
||||
printf("Cineon: Cineon image depth unsupported: %d\n", cineon->depth);
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dataOffset = swap_uint(header.fileHeader.offset, cineon->isMSB);
|
||||
|
||||
for (i = 0; i < cineon->numElements; i++) {
|
||||
cineon->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
|
||||
cineon->element[i].maxValue = powf(2, cineon->element[i].bitsPerSample) - 1.0f;
|
||||
cineon->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data,
|
||||
cineon->isMSB);
|
||||
cineon->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity,
|
||||
cineon->isMSB);
|
||||
cineon->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data,
|
||||
cineon->isMSB);
|
||||
cineon->element[i].refHighQuantity = swap_float(
|
||||
header.imageHeader.element[i].ref_high_quantity, cineon->isMSB);
|
||||
|
||||
switch (header.imageHeader.packing) {
|
||||
case 0:
|
||||
cineon->element[i].packing = 0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
cineon->element[i].packing = 1;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
cineon->element[i].packing = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Not supported */
|
||||
if (verbose) {
|
||||
printf("Cineon: packing unsupported: %d\n", header.imageHeader.packing);
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (cineon->element[i].refLowData == CINEON_UNDEFINED_U32) {
|
||||
cineon->element[i].refLowData = 0;
|
||||
}
|
||||
|
||||
if (cineon->element[i].refHighData == CINEON_UNDEFINED_U32) {
|
||||
cineon->element[i].refHighData = uint(cineon->element[i].maxValue);
|
||||
}
|
||||
|
||||
if (cineon->element[i].refLowQuantity == CINEON_UNDEFINED_R32 ||
|
||||
std::isnan(cineon->element[i].refLowQuantity))
|
||||
{
|
||||
cineon->element[i].refLowQuantity = 0.0f;
|
||||
}
|
||||
|
||||
if (cineon->element[i].refHighQuantity == CINEON_UNDEFINED_R32 ||
|
||||
std::isnan(cineon->element[i].refHighQuantity))
|
||||
{
|
||||
if (cineon->element[i].transfer == transfer_PrintingDensity) {
|
||||
cineon->element[i].refHighQuantity = 2.048f;
|
||||
}
|
||||
else {
|
||||
cineon->element[i].refHighQuantity = cineon->element[i].maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
cineon->element[i].dataOffset = dataOffset;
|
||||
dataOffset += cineon->height * getRowLength(cineon->width, &cineon->element[i]);
|
||||
}
|
||||
|
||||
cineon->referenceBlack = 95.0f / 1023.0f * cineon->element[0].maxValue;
|
||||
cineon->referenceWhite = 685.0f / 1023.0f * cineon->element[0].maxValue;
|
||||
cineon->gamma = 1.7f;
|
||||
|
||||
if (verbose) {
|
||||
printf("size %d x %d x %d elements\n", cineon->width, cineon->height, cineon->numElements);
|
||||
for (i = 0; i < cineon->numElements; i++) {
|
||||
printf(" Element %d:\n", i);
|
||||
printf(" Bits per sample: %d\n", cineon->element[i].bitsPerSample);
|
||||
printf(" Depth: %d\n", cineon->element[i].depth);
|
||||
printf(" Transfer characteristics: %d\n", cineon->element[i].transfer);
|
||||
printf(" Packing: %d\n", cineon->element[i].packing);
|
||||
printf(" Descriptor: %d\n", cineon->element[i].descriptor);
|
||||
printf(" Data offset: %d\n", cineon->element[i].dataOffset);
|
||||
printf(" Reference low data: %u\n", cineon->element[i].refLowData);
|
||||
printf(" Reference low quantity: %f\n", cineon->element[i].refLowQuantity);
|
||||
printf(" Reference high data: %u\n", cineon->element[i].refHighData);
|
||||
printf(" Reference high quantity: %f\n", cineon->element[i].refHighQuantity);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Gamma: %f\n", cineon->gamma);
|
||||
printf("Reference black: %f\n", cineon->referenceBlack);
|
||||
printf("Reference white: %f\n", cineon->referenceWhite);
|
||||
printf("Orientation: %d\n", header.imageHeader.orientation);
|
||||
printf("----------------------------\n");
|
||||
}
|
||||
return cineon;
|
||||
}
|
||||
|
||||
LogImageFile *cineonCreate(
|
||||
const char *filepath, int width, int height, int bitsPerSample, const char *creator)
|
||||
{
|
||||
CineonMainHeader header;
|
||||
const char *shortFilename = nullptr;
|
||||
// uchar pad[6044];
|
||||
|
||||
LogImageFile *cineon = MEM_new_uninitialized<LogImageFile>(__func__);
|
||||
if (cineon == nullptr) {
|
||||
if (verbose) {
|
||||
printf("cineon: Failed to malloc cineon file structure.\n");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Only 10 bits Cineon are supported */
|
||||
if (bitsPerSample != 10) {
|
||||
if (verbose) {
|
||||
printf("cineon: Only 10 bits Cineon are supported.\n");
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cineon->width = width;
|
||||
cineon->height = height;
|
||||
cineon->element[0].bitsPerSample = 10;
|
||||
cineon->element[0].dataOffset = sizeof(CineonMainHeader);
|
||||
cineon->element[0].maxValue = 1023;
|
||||
cineon->isMSB = 1;
|
||||
cineon->numElements = 1;
|
||||
cineon->element[0].packing = 1;
|
||||
cineon->depth = 3;
|
||||
cineon->element[0].depth = 3;
|
||||
cineon->element[0].descriptor = descriptor_RGB;
|
||||
cineon->element[0].transfer = transfer_PrintingDensity;
|
||||
cineon->element[0].refHighQuantity = 2.048f;
|
||||
cineon->element[0].refLowQuantity = 0;
|
||||
cineon->element[0].refLowData = 0;
|
||||
cineon->element[0].refHighData = cineon->element[0].maxValue;
|
||||
cineon->referenceWhite = 685.0f;
|
||||
cineon->referenceBlack = 95.0f;
|
||||
cineon->gamma = 1.7f;
|
||||
|
||||
shortFilename = strrchr(filepath, PATHSEP_CHAR);
|
||||
if (shortFilename == nullptr) {
|
||||
shortFilename = filepath;
|
||||
}
|
||||
else {
|
||||
shortFilename++;
|
||||
}
|
||||
|
||||
cineon->file = BLI_fopen(filepath, "wb");
|
||||
if (cineon->file == nullptr) {
|
||||
if (verbose) {
|
||||
printf("cineon: Couldn't open file %s\n", filepath);
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fillCineonMainHeader(cineon, &header, shortFilename, creator);
|
||||
|
||||
if (fwrite(&header, sizeof(header), 1, cineon->file) == 0) {
|
||||
if (verbose) {
|
||||
printf("cineon: Couldn't write image header\n");
|
||||
}
|
||||
logImageClose(cineon);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return cineon;
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
118
blender-5.2.0/source/blender/imbuf/intern/cineon/cineonlib.h
Normal file
118
blender-5.2.0/source/blender/imbuf/intern/cineon/cineonlib.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/* SPDX-FileCopyrightText: 1999-2001 David Hodson <hodsond@acm.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbcineon
|
||||
*
|
||||
* Cineon image file format library definitions.
|
||||
* Also handles DPX files (almost)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "logImageCore.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
#define CINEON_FILE_MAGIC 0x802A5FD7
|
||||
#define CINEON_UNDEFINED_U8 0xFF
|
||||
#define CINEON_UNDEFINED_U16 0xFFFF
|
||||
#define CINEON_UNDEFINED_U32 0xFFFFFFFF
|
||||
#define CINEON_UNDEFINED_R32 0x7F800000
|
||||
#define CINEON_UNDEFINED_CHAR 0
|
||||
|
||||
struct CineonFileHeader {
|
||||
unsigned int magic_num;
|
||||
unsigned int offset;
|
||||
unsigned int gen_hdr_size;
|
||||
unsigned int ind_hdr_size;
|
||||
unsigned int user_data_size;
|
||||
unsigned int file_size;
|
||||
char version[8];
|
||||
char file_name[100];
|
||||
char creation_date[12];
|
||||
char creation_time[12];
|
||||
char reserved[36];
|
||||
};
|
||||
|
||||
struct CineonElementHeader {
|
||||
uchar descriptor1;
|
||||
uchar descriptor2;
|
||||
uchar bits_per_sample;
|
||||
uchar filler;
|
||||
unsigned int pixels_per_line;
|
||||
unsigned int lines_per_image;
|
||||
unsigned int ref_low_data;
|
||||
float ref_low_quantity;
|
||||
unsigned int ref_high_data;
|
||||
float ref_high_quantity;
|
||||
};
|
||||
|
||||
struct CineonImageHeader {
|
||||
uchar orientation;
|
||||
uchar elements_per_image;
|
||||
unsigned short filler;
|
||||
CineonElementHeader element[8];
|
||||
float white_point_x;
|
||||
float white_point_y;
|
||||
float red_primary_x;
|
||||
float red_primary_y;
|
||||
float green_primary_x;
|
||||
float green_primary_y;
|
||||
float blue_primary_x;
|
||||
float blue_primary_y;
|
||||
char label[200];
|
||||
char reserved[28];
|
||||
uchar interleave;
|
||||
uchar packing;
|
||||
uchar data_sign;
|
||||
uchar sense;
|
||||
unsigned int line_padding;
|
||||
unsigned int element_padding;
|
||||
char reserved2[20];
|
||||
};
|
||||
|
||||
struct CineonOriginationHeader {
|
||||
int x_offset;
|
||||
int y_offset;
|
||||
char file_name[100];
|
||||
char creation_date[12];
|
||||
char creation_time[12];
|
||||
char input_device[64];
|
||||
char model_number[32];
|
||||
char input_serial_number[32];
|
||||
float x_input_samples_per_mm;
|
||||
float y_input_samples_per_mm;
|
||||
float input_device_gamma;
|
||||
char reserved[40];
|
||||
};
|
||||
|
||||
struct CineonFilmHeader {
|
||||
uchar film_code;
|
||||
uchar film_type;
|
||||
uchar edge_code_perforation_offset;
|
||||
uchar filler;
|
||||
unsigned int prefix;
|
||||
unsigned int count;
|
||||
char format[32];
|
||||
unsigned int frame_position;
|
||||
float frame_rate;
|
||||
char attribute[32];
|
||||
char slate[200];
|
||||
char reserved[740];
|
||||
};
|
||||
|
||||
struct CineonMainHeader {
|
||||
CineonFileHeader fileHeader;
|
||||
CineonImageHeader imageHeader;
|
||||
CineonOriginationHeader originationHeader;
|
||||
CineonFilmHeader filmHeader;
|
||||
};
|
||||
|
||||
void cineonSetVerbose(int);
|
||||
LogImageFile *cineonOpen(const uchar *byteStuff, int fromMemory, size_t bufferSize);
|
||||
LogImageFile *cineonCreate(
|
||||
const char *filepath, int width, int height, int bitsPerSample, const char *creator);
|
||||
|
||||
} // namespace blender
|
||||
550
blender-5.2.0/source/blender/imbuf/intern/cineon/dpxlib.cc
Normal file
550
blender-5.2.0/source/blender/imbuf/intern/cineon/dpxlib.cc
Normal file
@@ -0,0 +1,550 @@
|
||||
/* SPDX-FileCopyrightText: 1999-2002 David Hodson <hodsond@acm.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbcineon
|
||||
*
|
||||
* DPX image file format library routines.
|
||||
*/
|
||||
|
||||
#include "dpxlib.h"
|
||||
#include "logmemfile.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/*
|
||||
* For debug purpose
|
||||
*/
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
void dpxSetVerbose(int verbosity)
|
||||
{
|
||||
verbose = verbosity;
|
||||
}
|
||||
|
||||
/*
|
||||
* Headers
|
||||
*/
|
||||
|
||||
static void fillDpxMainHeader(LogImageFile *dpx,
|
||||
DpxMainHeader *header,
|
||||
const char *filename,
|
||||
const char *creator)
|
||||
{
|
||||
time_t fileClock;
|
||||
const tm *fileTime;
|
||||
|
||||
memset(header, 0, sizeof(DpxMainHeader));
|
||||
|
||||
/* --- File header --- */
|
||||
header->fileHeader.magic_num = swap_uint(DPX_FILE_MAGIC, dpx->isMSB);
|
||||
header->fileHeader.offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
|
||||
STRNCPY(header->fileHeader.version, "V2.0");
|
||||
header->fileHeader.file_size = swap_uint(
|
||||
dpx->element[0].dataOffset + dpx->height * getRowLength(dpx->width, &dpx->element[0]),
|
||||
dpx->isMSB);
|
||||
header->fileHeader.ditto_key = 0;
|
||||
header->fileHeader.gen_hdr_size = swap_uint(
|
||||
sizeof(DpxFileHeader) + sizeof(DpxImageHeader) + sizeof(DpxOrientationHeader), dpx->isMSB);
|
||||
header->fileHeader.ind_hdr_size = swap_uint(sizeof(DpxFilmHeader) + sizeof(DpxTelevisionHeader),
|
||||
dpx->isMSB);
|
||||
header->fileHeader.user_data_size = DPX_UNDEFINED_U32;
|
||||
STRNCPY(header->fileHeader.file_name, filename);
|
||||
fileClock = time(nullptr);
|
||||
fileTime = localtime(&fileClock);
|
||||
strftime(header->fileHeader.creation_date, 24, "%Y:%m:%d:%H:%M:%S%Z", fileTime);
|
||||
header->fileHeader.creation_date[23] = 0;
|
||||
STRNCPY(header->fileHeader.creator, creator);
|
||||
header->fileHeader.project[0] = 0;
|
||||
header->fileHeader.copyright[0] = 0;
|
||||
header->fileHeader.key = 0xFFFFFFFF;
|
||||
|
||||
/* --- Image header --- */
|
||||
header->imageHeader.orientation = 0;
|
||||
header->imageHeader.elements_per_image = swap_ushort(1, dpx->isMSB);
|
||||
header->imageHeader.pixels_per_line = swap_uint(dpx->width, dpx->isMSB);
|
||||
header->imageHeader.lines_per_element = swap_uint(dpx->height, dpx->isMSB);
|
||||
|
||||
/* Fills element */
|
||||
header->imageHeader.element[0].data_sign = 0;
|
||||
header->imageHeader.element[0].ref_low_data = swap_uint(dpx->element[0].refLowData, dpx->isMSB);
|
||||
header->imageHeader.element[0].ref_low_quantity = swap_float(dpx->element[0].refLowQuantity,
|
||||
dpx->isMSB);
|
||||
header->imageHeader.element[0].ref_high_data = swap_uint(dpx->element[0].refHighData,
|
||||
dpx->isMSB);
|
||||
header->imageHeader.element[0].ref_high_quantity = swap_float(dpx->element[0].refHighQuantity,
|
||||
dpx->isMSB);
|
||||
header->imageHeader.element[0].descriptor = dpx->element[0].descriptor;
|
||||
header->imageHeader.element[0].transfer = dpx->element[0].transfer;
|
||||
header->imageHeader.element[0].colorimetric = 0;
|
||||
header->imageHeader.element[0].bits_per_sample = dpx->element[0].bitsPerSample;
|
||||
header->imageHeader.element[0].packing = swap_ushort(dpx->element[0].packing, dpx->isMSB);
|
||||
header->imageHeader.element[0].encoding = 0;
|
||||
header->imageHeader.element[0].data_offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
|
||||
header->imageHeader.element[0].line_padding = 0;
|
||||
header->imageHeader.element[0].element_padding = 0;
|
||||
header->imageHeader.element[0].description[0] = 0;
|
||||
|
||||
/* --- Orientation header --- */
|
||||
/* we leave it blank */
|
||||
|
||||
/* --- Television header --- */
|
||||
header->televisionHeader.time_code = DPX_UNDEFINED_U32;
|
||||
header->televisionHeader.user_bits = DPX_UNDEFINED_U32;
|
||||
header->televisionHeader.interlace = DPX_UNDEFINED_U8;
|
||||
header->televisionHeader.field_number = DPX_UNDEFINED_U8;
|
||||
header->televisionHeader.video_signal = DPX_UNDEFINED_U8;
|
||||
header->televisionHeader.padding = DPX_UNDEFINED_U8;
|
||||
header->televisionHeader.horizontal_sample_rate = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
|
||||
header->televisionHeader.vertical_sample_rate = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
|
||||
header->televisionHeader.frame_rate = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
|
||||
header->televisionHeader.time_offset = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
|
||||
header->televisionHeader.gamma = swap_float(dpx->gamma, dpx->isMSB);
|
||||
header->televisionHeader.black_level = swap_float(dpx->referenceBlack, dpx->isMSB);
|
||||
header->televisionHeader.black_gain = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
|
||||
header->televisionHeader.breakpoint = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
|
||||
header->televisionHeader.white_level = swap_float(dpx->referenceWhite, dpx->isMSB);
|
||||
header->televisionHeader.integration_times = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
|
||||
}
|
||||
|
||||
LogImageFile *dpxOpen(const uchar *byteStuff, int fromMemory, size_t bufferSize)
|
||||
{
|
||||
DpxMainHeader header;
|
||||
LogImageFile *dpx = MEM_new_uninitialized<LogImageFile>(__func__);
|
||||
const char *filepath = reinterpret_cast<const char *>(byteStuff);
|
||||
int i;
|
||||
|
||||
if (dpx == nullptr) {
|
||||
if (verbose) {
|
||||
printf("DPX: Failed to malloc dpx file structure.\n");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* zero the header */
|
||||
memset(&header, 0, sizeof(DpxMainHeader));
|
||||
|
||||
/* for close routine */
|
||||
dpx->file = nullptr;
|
||||
|
||||
if (fromMemory == 0) {
|
||||
/* byteStuff is then the filepath */
|
||||
dpx->file = BLI_fopen(filepath, "rb");
|
||||
if (dpx->file == nullptr) {
|
||||
if (verbose) {
|
||||
printf("DPX: Failed to open file \"%s\".\n", filepath);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
/* not used in this case */
|
||||
dpx->memBuffer = nullptr;
|
||||
dpx->memCursor = nullptr;
|
||||
dpx->memBufferSize = 0;
|
||||
}
|
||||
else {
|
||||
dpx->memBuffer = const_cast<uchar *>(byteStuff);
|
||||
dpx->memCursor = const_cast<uchar *>(byteStuff);
|
||||
dpx->memBufferSize = bufferSize;
|
||||
}
|
||||
|
||||
if (logimage_fread(&header, sizeof(header), 1, dpx) == 0) {
|
||||
if (verbose) {
|
||||
printf("DPX: Not enough data for header in \"%s\".\n", byteStuff);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* endianness determination */
|
||||
if (header.fileHeader.magic_num == swap_uint(DPX_FILE_MAGIC, 1)) {
|
||||
dpx->isMSB = 1;
|
||||
if (verbose) {
|
||||
printf("DPX: File is MSB.\n");
|
||||
}
|
||||
}
|
||||
else if (header.fileHeader.magic_num == DPX_FILE_MAGIC) {
|
||||
dpx->isMSB = 0;
|
||||
if (verbose) {
|
||||
printf("DPX: File is LSB.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (verbose) {
|
||||
printf("DPX: Bad magic number %u in \"%s\".\n", header.fileHeader.magic_num, byteStuff);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dpx->srcFormat = format_DPX;
|
||||
dpx->numElements = swap_ushort(header.imageHeader.elements_per_image, dpx->isMSB);
|
||||
size_t max_elements = ARRAY_SIZE(header.imageHeader.element);
|
||||
if (dpx->numElements == 0 || dpx->numElements >= max_elements) {
|
||||
if (verbose) {
|
||||
printf("DPX: Wrong number of elements: %d\n", dpx->numElements);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dpx->width = swap_uint(header.imageHeader.pixels_per_line, dpx->isMSB);
|
||||
dpx->height = swap_uint(header.imageHeader.lines_per_element, dpx->isMSB);
|
||||
|
||||
if (dpx->width == 0 || dpx->height == 0) {
|
||||
if (verbose) {
|
||||
printf("DPX: Wrong image dimension: %dx%d\n", dpx->width, dpx->height);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dpx->depth = 0;
|
||||
|
||||
for (i = 0; i < dpx->numElements; i++) {
|
||||
dpx->element[i].descriptor = header.imageHeader.element[i].descriptor;
|
||||
|
||||
switch (dpx->element[i].descriptor) {
|
||||
case descriptor_Red:
|
||||
case descriptor_Green:
|
||||
case descriptor_Blue:
|
||||
case descriptor_Alpha:
|
||||
case descriptor_Luminance:
|
||||
case descriptor_Chrominance:
|
||||
dpx->depth++;
|
||||
dpx->element[i].depth = 1;
|
||||
break;
|
||||
|
||||
case descriptor_CbYCrY:
|
||||
dpx->depth += 2;
|
||||
dpx->element[i].depth = 2;
|
||||
break;
|
||||
|
||||
case descriptor_RGB:
|
||||
case descriptor_CbYCr:
|
||||
case descriptor_CbYACrYA:
|
||||
dpx->depth += 3;
|
||||
dpx->element[i].depth = 3;
|
||||
break;
|
||||
|
||||
case descriptor_RGBA:
|
||||
case descriptor_ABGR:
|
||||
case descriptor_CbYCrA:
|
||||
dpx->depth += 4;
|
||||
dpx->element[i].depth = 4;
|
||||
break;
|
||||
|
||||
case descriptor_Depth:
|
||||
case descriptor_Composite:
|
||||
/* unsupported */
|
||||
break;
|
||||
}
|
||||
|
||||
if (dpx->depth == 0 || dpx->depth > 4) {
|
||||
if (verbose) {
|
||||
printf("DPX: Unsupported image depth: %d\n", dpx->depth);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dpx->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
|
||||
if (!ELEM(dpx->element[i].bitsPerSample, 1, 8, 10, 12, 16)) {
|
||||
if (verbose) {
|
||||
printf("DPX: Unsupported bitsPerSample for elements %d: %d\n",
|
||||
i,
|
||||
dpx->element[i].bitsPerSample);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dpx->element[i].maxValue = powf(2, dpx->element[i].bitsPerSample) - 1.0f;
|
||||
|
||||
dpx->element[i].packing = swap_ushort(header.imageHeader.element[i].packing, dpx->isMSB);
|
||||
if (dpx->element[i].packing > 2) {
|
||||
if (verbose) {
|
||||
printf("DPX: Unsupported packing for element %d: %d\n", i, dpx->element[i].packing);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Sometimes, the offset is not set correctly in the header */
|
||||
dpx->element[i].dataOffset = swap_uint(header.imageHeader.element[i].data_offset, dpx->isMSB);
|
||||
if (dpx->element[i].dataOffset == 0 && dpx->numElements == 1) {
|
||||
dpx->element[i].dataOffset = swap_uint(header.fileHeader.offset, dpx->isMSB);
|
||||
}
|
||||
|
||||
if (dpx->element[i].dataOffset == 0) {
|
||||
if (verbose) {
|
||||
printf("DPX: Image header is corrupted.\n");
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dpx->element[i].transfer = header.imageHeader.element[i].transfer;
|
||||
|
||||
/* if undefined, assign default */
|
||||
dpx->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, dpx->isMSB);
|
||||
dpx->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity,
|
||||
dpx->isMSB);
|
||||
dpx->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data,
|
||||
dpx->isMSB);
|
||||
dpx->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity,
|
||||
dpx->isMSB);
|
||||
|
||||
switch (dpx->element[i].descriptor) {
|
||||
case descriptor_Red:
|
||||
case descriptor_Green:
|
||||
case descriptor_Blue:
|
||||
case descriptor_Alpha:
|
||||
case descriptor_RGB:
|
||||
case descriptor_RGBA:
|
||||
case descriptor_ABGR:
|
||||
if (dpx->element[i].refLowData == DPX_UNDEFINED_U32) {
|
||||
dpx->element[i].refLowData = 0;
|
||||
}
|
||||
|
||||
if (dpx->element[i].refHighData == DPX_UNDEFINED_U32) {
|
||||
dpx->element[i].refHighData = uint(dpx->element[i].maxValue);
|
||||
}
|
||||
|
||||
if (IS_DPX_UNDEFINED_R32(dpx->element[i].refLowQuantity)) {
|
||||
dpx->element[i].refLowQuantity = 0.0f;
|
||||
}
|
||||
|
||||
if (IS_DPX_UNDEFINED_R32(dpx->element[i].refHighQuantity)) {
|
||||
if (ELEM(dpx->element[i].transfer, transfer_PrintingDensity, transfer_Logarithmic)) {
|
||||
dpx->element[i].refHighQuantity = 2.048f;
|
||||
}
|
||||
else {
|
||||
dpx->element[i].refHighQuantity = dpx->element[i].maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case descriptor_Luminance:
|
||||
case descriptor_Chrominance:
|
||||
case descriptor_CbYCrY:
|
||||
case descriptor_CbYCr:
|
||||
case descriptor_CbYACrYA:
|
||||
case descriptor_CbYCrA:
|
||||
if (dpx->element[i].refLowData == DPX_UNDEFINED_U32) {
|
||||
dpx->element[i].refLowData = 16.0f / 255.0f * dpx->element[i].maxValue;
|
||||
}
|
||||
|
||||
if (dpx->element[i].refHighData == DPX_UNDEFINED_U32) {
|
||||
dpx->element[i].refHighData = 235.0f / 255.0f * dpx->element[i].maxValue;
|
||||
}
|
||||
|
||||
if (IS_DPX_UNDEFINED_R32(dpx->element[i].refLowQuantity)) {
|
||||
dpx->element[i].refLowQuantity = 0.0f;
|
||||
}
|
||||
|
||||
if (IS_DPX_UNDEFINED_R32(dpx->element[i].refHighQuantity)) {
|
||||
dpx->element[i].refHighQuantity = 0.7f;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dpx->referenceBlack = swap_float(header.televisionHeader.black_level, dpx->isMSB);
|
||||
dpx->referenceWhite = swap_float(header.televisionHeader.white_level, dpx->isMSB);
|
||||
dpx->gamma = swap_float(header.televisionHeader.gamma, dpx->isMSB);
|
||||
|
||||
if (IS_DPX_UNDEFINED_R32(dpx->referenceBlack) ||
|
||||
(dpx->referenceWhite <= dpx->referenceBlack || IS_DPX_UNDEFINED_R32(dpx->referenceWhite)) ||
|
||||
(dpx->gamma <= 0 || IS_DPX_UNDEFINED_R32(dpx->gamma)))
|
||||
{
|
||||
dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
|
||||
dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
|
||||
dpx->gamma = 1.7f;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
printf("size %d x %d x %d elements\n", dpx->width, dpx->height, dpx->numElements);
|
||||
for (i = 0; i < dpx->numElements; i++) {
|
||||
printf(" Element %d:\n", i);
|
||||
printf(" Bits per sample: %d\n", dpx->element[i].bitsPerSample);
|
||||
printf(" Depth: %d\n", dpx->element[i].depth);
|
||||
printf(" Transfer characteristics: %d\n", dpx->element[i].transfer);
|
||||
printf(" Packing: %d\n", dpx->element[i].packing);
|
||||
printf(" Descriptor: %d\n", dpx->element[i].descriptor);
|
||||
printf(" Data offset: %d\n", dpx->element[i].dataOffset);
|
||||
printf(" Reference low data: %u\n", dpx->element[i].refLowData);
|
||||
printf(" Reference low quantity: %f\n", dpx->element[i].refLowQuantity);
|
||||
printf(" Reference high data: %u\n", dpx->element[i].refHighData);
|
||||
printf(" Reference high quantity: %f\n", dpx->element[i].refHighQuantity);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Gamma: %f\n", dpx->gamma);
|
||||
printf("Reference black: %f\n", dpx->referenceBlack);
|
||||
printf("Reference white: %f\n", dpx->referenceWhite);
|
||||
printf("Orientation: %d\n", header.imageHeader.orientation);
|
||||
printf("----------------------------\n");
|
||||
}
|
||||
return dpx;
|
||||
}
|
||||
|
||||
LogImageFile *dpxCreate(const char *filepath,
|
||||
int width,
|
||||
int height,
|
||||
int bitsPerSample,
|
||||
int hasAlpha,
|
||||
int isLogarithmic,
|
||||
int referenceWhite,
|
||||
int referenceBlack,
|
||||
float gamma,
|
||||
const char *creator)
|
||||
{
|
||||
DpxMainHeader header;
|
||||
const char *shortFilename = nullptr;
|
||||
uchar pad[6044];
|
||||
|
||||
LogImageFile *dpx = MEM_new_uninitialized<LogImageFile>(__func__);
|
||||
if (dpx == nullptr) {
|
||||
if (verbose) {
|
||||
printf("DPX: Failed to malloc dpx file structure.\n");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dpx->width = width;
|
||||
dpx->height = height;
|
||||
dpx->element[0].bitsPerSample = bitsPerSample;
|
||||
dpx->element[0].dataOffset = 8092;
|
||||
dpx->element[0].maxValue = powf(2, dpx->element[0].bitsPerSample) - 1.0f;
|
||||
dpx->isMSB = 1;
|
||||
dpx->numElements = 1;
|
||||
|
||||
switch (bitsPerSample) {
|
||||
case 8:
|
||||
case 16:
|
||||
dpx->element[0].packing = 0;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
case 12:
|
||||
/* Packed Type A padding is the most common 10/12 bits format */
|
||||
dpx->element[0].packing = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (verbose) {
|
||||
printf("DPX: bitsPerSample not supported: %d\n", bitsPerSample);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (hasAlpha == 0) {
|
||||
dpx->depth = 3;
|
||||
dpx->element[0].depth = 3;
|
||||
dpx->element[0].descriptor = descriptor_RGB;
|
||||
}
|
||||
else {
|
||||
dpx->depth = 4;
|
||||
dpx->element[0].depth = 4;
|
||||
dpx->element[0].descriptor = descriptor_RGBA;
|
||||
}
|
||||
|
||||
if (isLogarithmic == 0) {
|
||||
dpx->element[0].transfer = transfer_Linear;
|
||||
dpx->element[0].refHighQuantity = dpx->element[0].maxValue;
|
||||
}
|
||||
else {
|
||||
dpx->element[0].transfer = transfer_PrintingDensity;
|
||||
dpx->element[0].refHighQuantity = 2.048f;
|
||||
}
|
||||
|
||||
dpx->element[0].refLowQuantity = 0;
|
||||
dpx->element[0].refLowData = 0;
|
||||
dpx->element[0].refHighData = dpx->element[0].maxValue;
|
||||
|
||||
if (referenceWhite > 0) {
|
||||
dpx->referenceWhite = referenceWhite;
|
||||
}
|
||||
else {
|
||||
dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
|
||||
}
|
||||
|
||||
if (referenceBlack > 0) {
|
||||
dpx->referenceBlack = referenceBlack;
|
||||
}
|
||||
else {
|
||||
dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
|
||||
}
|
||||
|
||||
if (gamma > 0.0f) {
|
||||
dpx->gamma = gamma;
|
||||
}
|
||||
else {
|
||||
dpx->gamma = 1.7f;
|
||||
}
|
||||
|
||||
shortFilename = strrchr(filepath, PATHSEP_CHAR);
|
||||
if (shortFilename == nullptr) {
|
||||
shortFilename = filepath;
|
||||
}
|
||||
else {
|
||||
shortFilename++;
|
||||
}
|
||||
|
||||
dpx->file = BLI_fopen(filepath, "wb");
|
||||
|
||||
if (dpx->file == nullptr) {
|
||||
if (verbose) {
|
||||
printf("DPX: Couldn't open file %s\n", filepath);
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fillDpxMainHeader(dpx, &header, shortFilename, creator);
|
||||
|
||||
if (fwrite(&header, sizeof(header), 1, dpx->file) == 0) {
|
||||
if (verbose) {
|
||||
printf("DPX: Couldn't write image header\n");
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Header should be rounded to next 8k block
|
||||
* 6044 = 8092 - sizeof(DpxMainHeader) */
|
||||
memset(&pad, 0, 6044);
|
||||
if (fwrite(&pad, 6044, 1, dpx->file) == 0) {
|
||||
if (verbose) {
|
||||
printf("DPX: Couldn't write image header\n");
|
||||
}
|
||||
logImageClose(dpx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dpx;
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
146
blender-5.2.0/source/blender/imbuf/intern/cineon/dpxlib.h
Normal file
146
blender-5.2.0/source/blender/imbuf/intern/cineon/dpxlib.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/* SPDX-FileCopyrightText: 1999-2002 David Hodson <hodsond@acm.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbcineon
|
||||
*
|
||||
* DPX image file format library definitions.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "logImageCore.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
#define DPX_FILE_MAGIC 0x53445058
|
||||
#define DPX_UNDEFINED_U8 0xFF
|
||||
#define DPX_UNDEFINED_U16 0xFFFF
|
||||
#define DPX_UNDEFINED_U32 0xFFFFFFFF
|
||||
#define DPX_UNDEFINED_R32 NAN
|
||||
#define IS_DPX_UNDEFINED_R32(x) std::isnan(x)
|
||||
#define DPX_UNDEFINED_CHAR 0
|
||||
|
||||
struct DpxFileHeader {
|
||||
unsigned int magic_num;
|
||||
unsigned int offset;
|
||||
char version[8];
|
||||
unsigned int file_size;
|
||||
unsigned int ditto_key;
|
||||
unsigned int gen_hdr_size;
|
||||
unsigned int ind_hdr_size;
|
||||
unsigned int user_data_size;
|
||||
char file_name[100];
|
||||
char creation_date[24];
|
||||
char creator[100];
|
||||
char project[200];
|
||||
char copyright[200];
|
||||
unsigned int key;
|
||||
char reserved[104];
|
||||
};
|
||||
|
||||
struct DpxElementHeader {
|
||||
unsigned int data_sign;
|
||||
unsigned int ref_low_data;
|
||||
float ref_low_quantity;
|
||||
unsigned int ref_high_data;
|
||||
float ref_high_quantity;
|
||||
unsigned char descriptor;
|
||||
unsigned char transfer;
|
||||
unsigned char colorimetric;
|
||||
unsigned char bits_per_sample;
|
||||
unsigned short packing;
|
||||
unsigned short encoding;
|
||||
unsigned int data_offset;
|
||||
unsigned int line_padding;
|
||||
unsigned int element_padding;
|
||||
char description[32];
|
||||
};
|
||||
|
||||
struct DpxImageHeader {
|
||||
unsigned short orientation;
|
||||
unsigned short elements_per_image;
|
||||
unsigned int pixels_per_line;
|
||||
unsigned int lines_per_element;
|
||||
DpxElementHeader element[8];
|
||||
char reserved[52];
|
||||
};
|
||||
|
||||
struct DpxOrientationHeader {
|
||||
unsigned int x_offset;
|
||||
unsigned int y_offset;
|
||||
float x_center;
|
||||
float y_center;
|
||||
unsigned int x_original_size;
|
||||
unsigned int y_original_size;
|
||||
char file_name[100];
|
||||
char creation_time[24];
|
||||
char input_device[32];
|
||||
char input_serial_number[32];
|
||||
unsigned short border_validity[4];
|
||||
unsigned int pixel_aspect_ratio[2];
|
||||
char reserved[28];
|
||||
};
|
||||
|
||||
struct DpxFilmHeader {
|
||||
char film_manufacturer_id[2];
|
||||
char film_type[2];
|
||||
char edge_code_perforation_offset[2];
|
||||
char edge_code_prefix[6];
|
||||
char edge_code_count[4];
|
||||
char film_format[32];
|
||||
unsigned int frame_position;
|
||||
unsigned int sequence_length;
|
||||
unsigned int held_count;
|
||||
float frame_rate;
|
||||
float shutter_angle;
|
||||
char frame_identification[32];
|
||||
char slate_info[100];
|
||||
char reserved[56];
|
||||
};
|
||||
|
||||
struct DpxTelevisionHeader {
|
||||
unsigned int time_code;
|
||||
unsigned int user_bits;
|
||||
unsigned char interlace;
|
||||
unsigned char field_number;
|
||||
unsigned char video_signal;
|
||||
unsigned char padding;
|
||||
float horizontal_sample_rate;
|
||||
float vertical_sample_rate;
|
||||
float frame_rate;
|
||||
float time_offset;
|
||||
float gamma;
|
||||
float black_level;
|
||||
float black_gain;
|
||||
float breakpoint;
|
||||
float white_level;
|
||||
float integration_times;
|
||||
unsigned char reserved[76];
|
||||
};
|
||||
|
||||
struct DpxMainHeader {
|
||||
DpxFileHeader fileHeader;
|
||||
DpxImageHeader imageHeader;
|
||||
DpxOrientationHeader orientationHeader;
|
||||
DpxFilmHeader filmHeader;
|
||||
DpxTelevisionHeader televisionHeader;
|
||||
};
|
||||
|
||||
void dpxSetVerbose(int verbosity);
|
||||
LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize);
|
||||
LogImageFile *dpxCreate(const char *filepath,
|
||||
int width,
|
||||
int height,
|
||||
int bitsPerSample,
|
||||
int hasAlpha,
|
||||
int isLogarithmic,
|
||||
int referenceWhite,
|
||||
int referenceBlack,
|
||||
float gamma,
|
||||
const char *creator);
|
||||
|
||||
} // namespace blender
|
||||
1808
blender-5.2.0/source/blender/imbuf/intern/cineon/logImageCore.cc
Normal file
1808
blender-5.2.0/source/blender/imbuf/intern/cineon/logImageCore.cc
Normal file
File diff suppressed because it is too large
Load Diff
272
blender-5.2.0/source/blender/imbuf/intern/cineon/logImageCore.h
Normal file
272
blender-5.2.0/source/blender/imbuf/intern/cineon/logImageCore.h
Normal file
@@ -0,0 +1,272 @@
|
||||
/* SPDX-FileCopyrightText: 1999-2001 David Hodson <hodsond@acm.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbcineon
|
||||
*
|
||||
* Cineon image file format library definitions.
|
||||
* Cineon and DPX common structures.
|
||||
*
|
||||
* This header file contains private details.
|
||||
* User code should generally use `cineonlib.h` and `dpxlib.h` only.
|
||||
* Hmm. I thought the two formats would have more in common!
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
#ifdef _WIN32
|
||||
# define PATHSEP_CHAR '\\'
|
||||
#else
|
||||
# define PATHSEP_CHAR '/'
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Image structure
|
||||
*/
|
||||
|
||||
/* There are some differences between DPX and Cineon
|
||||
* so we need to know from what type of file the data came from. */
|
||||
enum format {
|
||||
format_DPX,
|
||||
format_Cineon,
|
||||
};
|
||||
|
||||
struct LogImageElement {
|
||||
int depth;
|
||||
int bitsPerSample;
|
||||
int dataOffset;
|
||||
int packing;
|
||||
int transfer;
|
||||
int descriptor;
|
||||
unsigned int refLowData;
|
||||
unsigned int refHighData;
|
||||
float refLowQuantity;
|
||||
float refHighQuantity;
|
||||
float maxValue; /* = 2^bitsPerSample - 1 (used internally, doesn't come from the file header) */
|
||||
};
|
||||
|
||||
struct LogImageFile {
|
||||
/* specified in header */
|
||||
int width;
|
||||
int height;
|
||||
int numElements;
|
||||
int depth;
|
||||
LogImageElement element[8];
|
||||
|
||||
/* used for log <-> lin conversion */
|
||||
float referenceBlack;
|
||||
float referenceWhite;
|
||||
float gamma;
|
||||
|
||||
/* IO stuff. */
|
||||
FILE *file;
|
||||
unsigned char *memBuffer;
|
||||
uintptr_t memBufferSize;
|
||||
unsigned char *memCursor;
|
||||
|
||||
/* is the file LSB or MSB ? */
|
||||
int isMSB;
|
||||
|
||||
/* DPX or Cineon ? */
|
||||
int srcFormat;
|
||||
};
|
||||
|
||||
/* The SMPTE defines this code:
|
||||
* 0 - User-defined
|
||||
* 1 - Printing density
|
||||
* 2 - Linear
|
||||
* 3 - Logarithmic
|
||||
* 4 - Unspecified video
|
||||
* 5 - SMPTE 240M
|
||||
* 6 - CCIR 709-1
|
||||
* 7 - CCIR 601-2 system B or G
|
||||
* 8 - CCIR 601-2 system M
|
||||
* 9 - NTSC composite video
|
||||
* 10 - PAL composite video
|
||||
* 11 - Z linear
|
||||
* 12 - homogeneous
|
||||
*
|
||||
* Note that transfer_characteristics is U8, don't need
|
||||
* check the byte order.
|
||||
*/
|
||||
|
||||
enum transfer {
|
||||
transfer_UserDefined,
|
||||
transfer_PrintingDensity,
|
||||
transfer_Linear,
|
||||
transfer_Logarithmic,
|
||||
transfer_Unspecified,
|
||||
transfer_Smpte240M,
|
||||
transfer_Ccir7091,
|
||||
transfer_Ccir6012BG,
|
||||
transfer_Ccir6012M,
|
||||
transfer_NTSC,
|
||||
transfer_PAL,
|
||||
transfer_ZLinear,
|
||||
transfer_Homogeneous,
|
||||
};
|
||||
|
||||
/* The SMPTE defines this code:
|
||||
* 0 - User-defined
|
||||
* 1 - Red
|
||||
* 2 - Green
|
||||
* 3 - Blue
|
||||
* 4 - Alpha
|
||||
* 6 - Luminance
|
||||
* 7 - Chrominance
|
||||
* 8 - Depth
|
||||
* 9 - Composite video
|
||||
* 50 - RGB
|
||||
* 51 - RGBA
|
||||
* 52 - ABGR
|
||||
* 100 - CbYCrY
|
||||
* 101 - CbYACrYA
|
||||
* 102 - CbYCr
|
||||
* 103 - CbYCrA
|
||||
* 150 - User-defined 2-component element
|
||||
* 151 - User-defined 3-component element
|
||||
* 152 - User-defined 4-component element
|
||||
* 153 - User-defined 5-component element
|
||||
* 154 - User-defined 6-component element
|
||||
* 155 - User-defined 7-component element
|
||||
* 156 - User-defined 8-component element
|
||||
*/
|
||||
|
||||
enum descriptor {
|
||||
descriptor_UserDefined,
|
||||
descriptor_Red,
|
||||
descriptor_Green,
|
||||
descriptor_Blue,
|
||||
descriptor_Alpha,
|
||||
descriptor_Luminance = 6, /* don't ask me why there's no 5 */
|
||||
descriptor_Chrominance,
|
||||
descriptor_Depth,
|
||||
descriptor_Composite,
|
||||
descriptor_RGB = 50,
|
||||
descriptor_RGBA,
|
||||
descriptor_ABGR,
|
||||
descriptor_CbYCrY = 100,
|
||||
descriptor_CbYACrYA,
|
||||
descriptor_CbYCr,
|
||||
descriptor_CbYCrA,
|
||||
descriptor_UserDefined2Elt = 150,
|
||||
descriptor_UserDefined3Elt,
|
||||
descriptor_UserDefined4Elt,
|
||||
descriptor_UserDefined5Elt,
|
||||
descriptor_UserDefined6Elt,
|
||||
descriptor_UserDefined7Elt,
|
||||
descriptor_UserDefined8Elt,
|
||||
/* following descriptors are for internal use only */
|
||||
descriptor_YA,
|
||||
};
|
||||
|
||||
/* int functions return 0 for OK */
|
||||
|
||||
void logImageSetVerbose(int verbosity);
|
||||
int logImageIsDpx(const void *buffer, unsigned int size);
|
||||
int logImageIsCineon(const void *buffer, unsigned int size);
|
||||
LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int size);
|
||||
LogImageFile *logImageOpenFromFile(const char *filepath, int cineon);
|
||||
void logImageGetSize(const LogImageFile *logImage, int *width, int *height, int *depth);
|
||||
LogImageFile *logImageCreate(const char *filepath,
|
||||
int cineon,
|
||||
int width,
|
||||
int height,
|
||||
int bitsPerSample,
|
||||
int hasAlpha,
|
||||
int isLogarithmic,
|
||||
int referenceWhite,
|
||||
int referenceBlack,
|
||||
float gamma,
|
||||
const char *creator);
|
||||
void logImageClose(LogImageFile *logImage);
|
||||
|
||||
/* Data handling */
|
||||
size_t getRowLength(size_t width, const LogImageElement *logElement);
|
||||
int logImageSetDataRGBA(LogImageFile *logImage, const float *data, int dataIsLinearRGB);
|
||||
int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB);
|
||||
|
||||
/*
|
||||
* Inline routines
|
||||
*/
|
||||
|
||||
/* Endianness swapping */
|
||||
|
||||
BLI_INLINE unsigned short swap_ushort(unsigned short x, int swap)
|
||||
{
|
||||
if (swap != 0) {
|
||||
return (x >> 8) | (x << 8);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
BLI_INLINE unsigned int swap_uint(unsigned int x, int swap)
|
||||
{
|
||||
if (swap != 0) {
|
||||
return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
BLI_INLINE float swap_float(float x, int swap)
|
||||
{
|
||||
if (swap != 0) {
|
||||
union {
|
||||
float f;
|
||||
unsigned char b[4];
|
||||
} dat1, dat2;
|
||||
|
||||
dat1.f = x;
|
||||
dat2.b[0] = dat1.b[3];
|
||||
dat2.b[1] = dat1.b[2];
|
||||
dat2.b[2] = dat1.b[1];
|
||||
dat2.b[3] = dat1.b[0];
|
||||
return dat2.f;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Other */
|
||||
|
||||
BLI_INLINE unsigned int clamp_uint(unsigned int x, unsigned int low, unsigned int high)
|
||||
{
|
||||
if (x > high) {
|
||||
return high;
|
||||
}
|
||||
if (x < low) {
|
||||
return low;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
BLI_INLINE float clamp_float(float x, float low, float high)
|
||||
{
|
||||
if (x > high) {
|
||||
return high;
|
||||
}
|
||||
if (x < low) {
|
||||
return low;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
BLI_INLINE unsigned int float_uint(float value, unsigned int max)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
return 0;
|
||||
}
|
||||
if (value > (1.0f - 0.5f / float(max))) {
|
||||
return max;
|
||||
}
|
||||
return static_cast<unsigned int>((float(max) * value) + 0.5f);
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
119
blender-5.2.0/source/blender/imbuf/intern/cineon/logmemfile.cc
Normal file
119
blender-5.2.0/source/blender/imbuf/intern/cineon/logmemfile.cc
Normal file
@@ -0,0 +1,119 @@
|
||||
/* SPDX-FileCopyrightText: 2006 Joseph Eagar <joeedh@gmail.com>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbcineon
|
||||
*
|
||||
* Cineon image file format library routines.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "logImageCore.h"
|
||||
#include "logmemfile.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
int logimage_fseek(LogImageFile *logFile, intptr_t offset, int origin)
|
||||
{
|
||||
if (logFile->file) {
|
||||
fseek(logFile->file, offset, origin);
|
||||
}
|
||||
else { /* we're seeking in memory */
|
||||
if (origin == SEEK_SET) {
|
||||
if (offset > logFile->memBufferSize) {
|
||||
return 1;
|
||||
}
|
||||
logFile->memCursor = logFile->memBuffer + offset;
|
||||
}
|
||||
else if (origin == SEEK_END) {
|
||||
if (offset > logFile->memBufferSize) {
|
||||
return 1;
|
||||
}
|
||||
logFile->memCursor = (logFile->memBuffer + logFile->memBufferSize) - offset;
|
||||
}
|
||||
else if (origin == SEEK_CUR) {
|
||||
uintptr_t pos = uintptr_t(logFile->memCursor) - uintptr_t(logFile->memBuffer);
|
||||
if (pos + offset > logFile->memBufferSize) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
logFile->memCursor += offset;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int logimage_fwrite(const void *buffer, size_t size, uint count, LogImageFile *logFile)
|
||||
{
|
||||
if (logFile->file) {
|
||||
return fwrite(buffer, size, count, logFile->file);
|
||||
}
|
||||
/* we're writing to memory */
|
||||
/* do nothing as this isn't supported yet */
|
||||
return count;
|
||||
}
|
||||
|
||||
int logimage_fread(void *buffer, size_t size, uint count, LogImageFile *logFile)
|
||||
{
|
||||
if (logFile->file) {
|
||||
return fread(buffer, size, count, logFile->file);
|
||||
}
|
||||
/* we're reading from memory */
|
||||
uchar *buf = static_cast<uchar *>(buffer);
|
||||
uintptr_t pos = uintptr_t(logFile->memCursor) - uintptr_t(logFile->memBuffer);
|
||||
size_t total_size = size * count;
|
||||
if (pos + total_size > logFile->memBufferSize) {
|
||||
/* how many elements can we read without overflow ? */
|
||||
count = (logFile->memBufferSize - pos) / size;
|
||||
/* recompute the size */
|
||||
total_size = size * count;
|
||||
}
|
||||
|
||||
if (total_size != 0) {
|
||||
memcpy(buf, logFile->memCursor, total_size);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int logimage_read_uchar(uchar *x, LogImageFile *logFile)
|
||||
{
|
||||
uintptr_t pos = uintptr_t(logFile->memCursor) - uintptr_t(logFile->memBuffer);
|
||||
if (pos + sizeof(uchar) > logFile->memBufferSize) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
*x = *static_cast<uchar *>(logFile->memCursor);
|
||||
logFile->memCursor += sizeof(uchar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int logimage_read_ushort(ushort *x, LogImageFile *logFile)
|
||||
{
|
||||
uintptr_t pos = uintptr_t(logFile->memCursor) - uintptr_t(logFile->memBuffer);
|
||||
if (pos + sizeof(ushort) > logFile->memBufferSize) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
*x = *reinterpret_cast<ushort *>(logFile->memCursor);
|
||||
logFile->memCursor += sizeof(ushort);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int logimage_read_uint(uint *x, LogImageFile *logFile)
|
||||
{
|
||||
uintptr_t pos = uintptr_t(logFile->memCursor) - uintptr_t(logFile->memBuffer);
|
||||
if (pos + sizeof(uint) > logFile->memBufferSize) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
*x = *reinterpret_cast<uint *>(logFile->memCursor);
|
||||
logFile->memCursor += sizeof(uint);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
@@ -0,0 +1,26 @@
|
||||
/* SPDX-FileCopyrightText: 2006 Joseph Eagar <joeedh@gmail.com>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbcineon
|
||||
*
|
||||
* Cineon image file format library routines.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "logImageCore.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace blender {
|
||||
|
||||
int logimage_fseek(LogImageFile *logFile, intptr_t offset, int origin);
|
||||
int logimage_fwrite(const void *buffer, size_t size, unsigned int count, LogImageFile *logFile);
|
||||
int logimage_fread(void *buffer, size_t size, unsigned int count, LogImageFile *logFile);
|
||||
int logimage_read_uchar(unsigned char *x, LogImageFile *logFile);
|
||||
int logimage_read_ushort(unsigned short *x, LogImageFile *logFile);
|
||||
int logimage_read_uint(unsigned int *x, LogImageFile *logFile);
|
||||
|
||||
} // namespace blender
|
||||
Reference in New Issue
Block a user