486 lines
15 KiB
C
486 lines
15 KiB
C
|
/* SPDX-License-Identifier: MIT */
|
||
|
/**
|
||
|
@file dpx_hdr.h
|
||
|
@brief Declaration of DpxHdr class adapted from STwo's dpx file I/O.
|
||
|
@copyright (C) 2015-2021 AJA Video Systems, Inc. All rights reserved.
|
||
|
**/
|
||
|
|
||
|
#ifndef DPX_HDR_H
|
||
|
#define DPX_HDR_H
|
||
|
|
||
|
#include "public.h"
|
||
|
#include "ajabase/common/types.h"
|
||
|
#include "ajabase/system/system.h"
|
||
|
|
||
|
#include <string>
|
||
|
|
||
|
|
||
|
#define DPX_C_MAGIC 0x53445058 /**< little-endian magic number */
|
||
|
#define DPX_C_MAGIC_BE 0x58504453 /**< big-endian magic number */
|
||
|
#define DPX_C_VERSION "V1.0"
|
||
|
#define DPX_C_UNDEFINED_FLOAT 0xffffffff /**< DPX undefined float */
|
||
|
|
||
|
#define SWAP16(e,v) ((e) ? htons(v) : (v))
|
||
|
#define SWAP32(e,v) ((e) ? htonl(v) : (v))
|
||
|
#define SWAPR32(e,v) ((e) ? htonf(v) : (v))
|
||
|
#define UNSWAP16(e,v) ((e) ? ntohs(v) : (v))
|
||
|
#define UNSWAP32(e,v) ((e) ? ntohl(v) : (v))
|
||
|
#define UNSWAPR32(e,v) ((e) ? ntohf(v) : (v))
|
||
|
|
||
|
#define DPX_VALID(p) \
|
||
|
((p) && (((p)->file_info.magic_num==DPX_C_MAGIC) || \
|
||
|
((p)->file_info.magic_num==DPX_C_MAGIC_BE)))
|
||
|
|
||
|
#define DPX_IS_BE(p) \
|
||
|
((p) && ((p)->file_info.magic_num == DPX_C_MAGIC_BE))
|
||
|
|
||
|
#define DPX_C_IMAGE_ELEM_DESC_RGB 50
|
||
|
#define DPX_C_IMAGE_ELEM_DESC_RGBA 51
|
||
|
#define DPX_C_IMAGE_ELEM_DESC_ARGB 52
|
||
|
#define DPX_C_IMAGE_ELEM_DESC_422 100
|
||
|
#define DPX_C_IMAGE_ELEM_DESC_444 102
|
||
|
|
||
|
|
||
|
typedef struct dpx_file_info_struct
|
||
|
{
|
||
|
uint32_t magic_num; /* magic number 0x53445058 (SDPX) or 0x58504453 (XPDS) */
|
||
|
uint32_t offset; /* offset to image data in bytes */
|
||
|
uint8_t vers[8]; /* which header format version is being used (v1.0)*/
|
||
|
uint32_t file_size; /* file size in bytes */
|
||
|
uint32_t ditto_key; /* read time short cut - 0 = same, 1 = new */
|
||
|
uint32_t gen_hdr_size; /* generic header length in bytes */
|
||
|
uint32_t ind_hdr_size; /* industry header length in bytes */
|
||
|
uint32_t user_data_size;/* user-defined data length in bytes */
|
||
|
uint8_t file_name[100]; /* iamge file name */
|
||
|
uint8_t create_time[24]; /* file creation date "yyyy:mm:dd:hh:mm:ss:LTZ" */
|
||
|
uint8_t creator[100]; /* file creator's name */
|
||
|
uint8_t project[200]; /* project name */
|
||
|
uint8_t copyright[200]; /* right to use or copyright info */
|
||
|
uint32_t key; /* encryption ( FFFFFFFF = unencrypted ) */
|
||
|
union
|
||
|
{
|
||
|
uint8_t Reserved[104]; /* reserved field TBD (need to pad) */
|
||
|
struct
|
||
|
{
|
||
|
uint32_t tcFrame; /* Timecode as a frame number */
|
||
|
uint32_t filenum; /* FileNumber of preallocated files */
|
||
|
uint8_t rid;
|
||
|
uint8_t sid;
|
||
|
uint8_t tid;
|
||
|
uint8_t pad;
|
||
|
} s2;
|
||
|
} resv;
|
||
|
} DPX_file_info_t;
|
||
|
|
||
|
|
||
|
typedef struct dpx_image_element_struct
|
||
|
{
|
||
|
uint32_t data_sign; /* data sign (0 = unsigned, 1 = signed ) */
|
||
|
/* "Core set images are unsigned" */
|
||
|
uint32_t ref_low_data; /* reference low data code value */
|
||
|
float ref_low_quantity; /* reference low quantity represented */
|
||
|
uint32_t ref_high_data; /* reference high data code value */
|
||
|
float ref_high_quantity; /* reference high quantity represented */
|
||
|
uint8_t descriptor; /* descriptor for image element */
|
||
|
uint8_t transfer; /* transfer uint8_tacteristics for element */
|
||
|
uint8_t colorimetric; /* colormetric specification for element */
|
||
|
uint8_t bit_size; /* bit size for element */
|
||
|
uint16_t packing; /* packing for element */
|
||
|
uint16_t encoding; /* encoding for element */
|
||
|
uint32_t data_offset; /* offset to data of element */
|
||
|
uint32_t eol_padding; /* end of line padding used in element */
|
||
|
uint32_t eo_image_padding; /* end of image padding used in element */
|
||
|
uint8_t description[32]; /* description of element */
|
||
|
} DPX_image_element_t;
|
||
|
|
||
|
|
||
|
typedef struct dpx_image_info_struct
|
||
|
{
|
||
|
uint16_t orientation; /* image orientation */
|
||
|
uint16_t element_number; /* number of image elements */
|
||
|
uint32_t pixels_per_line; /* or x value */
|
||
|
uint32_t lines_per_image_ele; /* or y value, per element */
|
||
|
DPX_image_element_t image_element[8];
|
||
|
uint8_t reserved[52]; /* reserved for future use (padding) */
|
||
|
} DPX_image_info_t;
|
||
|
|
||
|
|
||
|
|
||
|
typedef struct dpx_image_source_struct
|
||
|
{
|
||
|
uint32_t x_offset; /* X offset */
|
||
|
uint32_t y_offset; /* Y offset */
|
||
|
float x_center; /* X center */
|
||
|
float y_center; /* Y center */
|
||
|
uint32_t x_orig_size; /* X original size */
|
||
|
uint32_t y_orig_size; /* Y original size */
|
||
|
uint8_t file_name[100]; /* source image file name */
|
||
|
uint8_t creation_time[24]; /* source image creation date and time */
|
||
|
uint8_t input_dev[32]; /* input device name */
|
||
|
uint8_t input_serial[32]; /* input device serial number */
|
||
|
uint16_t border[4]; /* border validity (XL, XR, YT, YB) */
|
||
|
uint32_t pixel_aspect[2]; /* pixel aspect ratio (H:V) */
|
||
|
uint8_t reserved[28]; /* reserved for future use (padding) */
|
||
|
} DPX_image_source_t;
|
||
|
|
||
|
|
||
|
|
||
|
typedef struct dpx_motion_picture_film_header_struct
|
||
|
{
|
||
|
uint8_t film_mfg_id[2]; /* film manufacturer ID code (2 digits from film edge code) */
|
||
|
uint8_t film_type[2]; /* file type (2 digits from film edge code) */
|
||
|
uint8_t offset[2]; /* offset in perfs (2 digits from film edge code)*/
|
||
|
uint8_t prefix[6]; /* prefix (6 digits from film edge code) */
|
||
|
uint8_t count[4]; /* count (4 digits from film edge code)*/
|
||
|
uint8_t format[32]; /* format (i.e. academy) */
|
||
|
uint32_t frame_position; /* frame position in sequence */
|
||
|
uint32_t sequence_len; /* sequence length in frames */
|
||
|
uint32_t held_count; /* held count (1 = default) */
|
||
|
float frame_rate; /* frame rate of original in frames/sec */
|
||
|
float shutter_angle; /* shutter angle of camera in degrees */
|
||
|
uint8_t frame_id[32]; /* frame identification (i.e. keyframe) */
|
||
|
uint8_t slate_info[100]; /* slate information */
|
||
|
uint8_t reserved[56]; /* reserved for future use (padding) */
|
||
|
} DPX_film_t;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
typedef struct dpx_television_header_struct
|
||
|
{
|
||
|
uint32_t tim_code; /* SMPTE time code */
|
||
|
uint32_t userBits; /* SMPTE user bits */
|
||
|
uint8_t interlace; /* interlace ( 0 = noninterlaced, 1 = 2:1 interlace*/
|
||
|
uint8_t field_num; /* field number */
|
||
|
uint8_t video_signal; /* video signal standard (table 4)*/
|
||
|
uint8_t unused; /* used for byte alignment only */
|
||
|
float hor_sample_rate; /* horizontal sampling rate in Hz */
|
||
|
float ver_sample_rate; /* vertical sampling rate in Hz */
|
||
|
float frame_rate; /* temporal sampling rate or frame rate in Hz */
|
||
|
float time_offset; /* time offset from sync to first pixel */
|
||
|
float gamma; /* gamma value */
|
||
|
float black_level; /* black level code value */
|
||
|
float black_gain; /* black gain */
|
||
|
float break_point; /* breakpoint */
|
||
|
float white_level; /* reference white level code value */
|
||
|
float integration_times; /* integration time(s) */
|
||
|
uint8_t reserved[76]; /* reserved for future use (padding) */
|
||
|
} DPX_television_t;
|
||
|
|
||
|
|
||
|
typedef struct dpx_header_struct
|
||
|
{
|
||
|
DPX_file_info_t file_info;
|
||
|
DPX_image_info_t image_info;
|
||
|
DPX_image_source_t image_source;
|
||
|
DPX_film_t film_header;
|
||
|
DPX_television_t tv_header;
|
||
|
#ifdef NTV4_RAID_SUPPORT
|
||
|
uint8_t reserved[2048];
|
||
|
#endif
|
||
|
} DPX_header_t;
|
||
|
|
||
|
|
||
|
uint32_t AJA_EXPORT dpx_get_u32(const uint32_t *ptr, bool BE );
|
||
|
void AJA_EXPORT dpx_set_u32(uint32_t *ptr, bool BE, uint32_t val );
|
||
|
uint16_t AJA_EXPORT dpx_get_u16(const uint16_t *ptr, bool BE );
|
||
|
void AJA_EXPORT dpx_set_u16(uint16_t *ptr, bool BE, uint16_t val );
|
||
|
float AJA_EXPORT dpx_get_r32(const float *ptr, bool BE );
|
||
|
void AJA_EXPORT dpx_set_r32(float *ptr, bool BE, float val );
|
||
|
|
||
|
|
||
|
#define FLD_OFFET( TYPE,field) \
|
||
|
((uint32_t)(&(((TYPE *)0)->field)))
|
||
|
|
||
|
#define DPX_GET_U32(hdr,fld) \
|
||
|
DPX_VALID(hdr) ? \
|
||
|
dpx_get_u32(&(hdr)->fld,DPX_IS_BE(hdr)) : \
|
||
|
(uint32_t)(-1)
|
||
|
|
||
|
#define DPX_SET_U32(hdr,fld,val) \
|
||
|
do { \
|
||
|
if ( DPX_VALID(hdr)) \
|
||
|
dpx_set_u32(&(hdr)->fld,DPX_IS_BE(hdr),val); \
|
||
|
} while(0)
|
||
|
|
||
|
|
||
|
#define DPX_GET_R32(hdr,fld) \
|
||
|
DPX_VALID(hdr) ? \
|
||
|
dpx_get_r32(&(hdr)->fld,DPX_IS_BE(hdr)) : \
|
||
|
(float)(0xffffffff)
|
||
|
|
||
|
#define DPX_SET_R32(hdr,fld,val) \
|
||
|
do { \
|
||
|
if ( DPX_VALID(hdr)) \
|
||
|
dpx_set_r32(&(hdr)->fld,DPX_IS_BE(hdr),val); \
|
||
|
} while(0)
|
||
|
|
||
|
#define DPX_GET_U16(hdr,fld) \
|
||
|
DPX_VALID(hdr) ? \
|
||
|
dpx_get_u16(&(hdr)->fld,DPX_IS_BE(hdr)) : \
|
||
|
(uint16_t)(-1)
|
||
|
|
||
|
#define DPX_SET_U16(hdr,fld,val) \
|
||
|
do { \
|
||
|
if ( DPX_VALID(hdr)) \
|
||
|
dpx_set_u16(&(hdr)->fld,DPX_IS_BE(hdr),val); \
|
||
|
} while(0)
|
||
|
|
||
|
|
||
|
#define DPX_GET_U8(hdr,fld) \
|
||
|
DPX_VALID(hdr) ? (hdr)->fld : (uint8_t)(-1)
|
||
|
|
||
|
|
||
|
#define DPX_SET_U8(hdr,fld,val) \
|
||
|
if ( DPX_VALID(hdr)) \
|
||
|
(hdr)->fld = val
|
||
|
|
||
|
#define DPX_SET_TEXT(hdr,fld,buf,len) \
|
||
|
if ( DPX_VALID(hdr)) \
|
||
|
memcpy((void*)&((hdr)->fld),(const void*)buf,len)
|
||
|
|
||
|
|
||
|
#define DPX_GET_TEXT(hdr,fld,buf,len) \
|
||
|
DPX_VALID(hdr) ? \
|
||
|
memcpy((void*)buf,(const void*)&((hdr)->fld),len) : \
|
||
|
memset((void*)buf,0xff,len)
|
||
|
|
||
|
|
||
|
class AJA_EXPORT DpxHdr
|
||
|
{
|
||
|
public:
|
||
|
DpxHdr(void) { init(DPX_C_MAGIC_BE); }
|
||
|
~DpxHdr();
|
||
|
|
||
|
DpxHdr& operator=(const DpxHdr& rhs);
|
||
|
|
||
|
void init(uint32_t endianness);
|
||
|
bool valid() const;
|
||
|
|
||
|
bool IsBigEndian() { return DPX_IS_BE(&m_hdr); }
|
||
|
|
||
|
std::string get_fi_time_stamp() const;
|
||
|
void set_fi_time_stamp();
|
||
|
|
||
|
void set_s2_tcframe(uint32_t frame);
|
||
|
size_t get_s2_tcframe() const;
|
||
|
|
||
|
uint32_t get_s2_filenumber() const;
|
||
|
void set_s2_filenumber(uint32_t fr);
|
||
|
|
||
|
void set_s2_ids(uint8_t rid, uint8_t sid, uint8_t tid);
|
||
|
void get_s2_ids(uint8_t *rid, uint8_t *sid, uint8_t *tid) const;
|
||
|
|
||
|
size_t get_file_size();
|
||
|
size_t get_generic_hdr_size();
|
||
|
size_t get_industry_hdr_size();
|
||
|
size_t get_user_hdr_size();
|
||
|
|
||
|
// File Info access
|
||
|
//
|
||
|
size_t get_fi_image_offset() const;
|
||
|
void set_fi_image_offset(size_t offs );
|
||
|
|
||
|
size_t get_fi_file_size() const;
|
||
|
void set_fi_file_size(size_t offs );
|
||
|
|
||
|
std::string get_fi_version() const;
|
||
|
void set_fi_version(const std::string& str);
|
||
|
|
||
|
std::string get_fi_file_name() const;
|
||
|
void set_fi_file_name(const std::string& str);
|
||
|
|
||
|
std::string get_fi_creator() const;
|
||
|
void set_fi_creator(const std::string& str);
|
||
|
|
||
|
std::string get_fi_create_time() const;
|
||
|
void set_fi_create_time(const std::string& str);
|
||
|
|
||
|
std::string get_fi_project() const;
|
||
|
void set_fi_project(const std::string& str);
|
||
|
|
||
|
std::string get_fi_copyright() const;
|
||
|
void set_fi_copyright(const std::string& str);
|
||
|
|
||
|
// Image Info
|
||
|
void set_ii_orientation(uint16_t orientation );
|
||
|
uint16_t get_ii_orientation() const;
|
||
|
|
||
|
void set_ii_element_number(uint16_t element_number );
|
||
|
uint16_t get_ii_element_number() const;
|
||
|
|
||
|
void set_ii_pixels(uint32_t pixels );
|
||
|
size_t get_ii_pixels() const;
|
||
|
|
||
|
void set_ii_lines(uint32_t lines );
|
||
|
size_t get_ii_lines(void ) const;
|
||
|
|
||
|
size_t get_ii_image_size()
|
||
|
{
|
||
|
// Note: Incorrect for some configs
|
||
|
uint32_t expectedSize = -1;
|
||
|
if (get_ie_descriptor() == 50)
|
||
|
{
|
||
|
if ( get_ie_bit_size() == 10 )
|
||
|
expectedSize = (uint32_t)(get_ii_pixels() * get_ii_lines() * 4);
|
||
|
else
|
||
|
expectedSize = (uint32_t)(get_ii_pixels() * get_ii_lines() * 6); // 16 bit
|
||
|
}
|
||
|
else if (get_ie_descriptor() == 100)
|
||
|
{
|
||
|
if (get_ii_pixels() % 48 == 0)
|
||
|
expectedSize = (uint32_t)(get_ii_pixels() * get_ii_lines() * 8 / 3);
|
||
|
else
|
||
|
expectedSize = (uint32_t)(((get_ii_pixels()/48+1)*48) * get_ii_lines() * 8 / 3);
|
||
|
}
|
||
|
// rowBytes = (( width % 48 == 0 ) ? width : (((width / 48 ) + 1) * 48)) * 8 / 3;
|
||
|
|
||
|
|
||
|
if (0 == get_fi_file_size())
|
||
|
{
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
uint32_t sizeInFile = (uint32_t)(get_fi_file_size() - get_fi_image_offset());
|
||
|
|
||
|
if ( sizeInFile < expectedSize)
|
||
|
return sizeInFile;
|
||
|
else
|
||
|
return expectedSize;
|
||
|
|
||
|
}
|
||
|
|
||
|
// Image Element
|
||
|
void set_ie_data_sign (uint32_t sign, int i=0);
|
||
|
size_t get_ie_data_sign(int i = 0);
|
||
|
|
||
|
void set_ie_ref_low_data(uint32_t data, int i=0);
|
||
|
size_t get_ie_ref_low_data(int i = 0) const;
|
||
|
|
||
|
void set_ie_ref_high_data(uint32_t data, int i=0);
|
||
|
size_t get_ie_ref_high_data(int i = 0) const;
|
||
|
|
||
|
void set_ie_ref_low_quantity(float data, int i=0);
|
||
|
float get_ie_ref_low_quantity(int i = 0) const;
|
||
|
|
||
|
void set_ie_ref_high_quantity(float data, int i=0);
|
||
|
float get_ie_ref_high_quantity(int i = 0) const;
|
||
|
|
||
|
void set_ie_descriptor(uint8_t desc, int i = 0);
|
||
|
uint8_t get_ie_descriptor(int i = 0) const;
|
||
|
|
||
|
void set_ie_transfer(uint8_t trans, int i = 0);
|
||
|
uint8_t get_ie_transfer(int i = 0) const;
|
||
|
|
||
|
void set_ie_colorimetric(uint8_t c, int i = 0);
|
||
|
uint8_t get_ie_colorimetric(int i = 0) const;
|
||
|
|
||
|
void set_ie_bit_size(uint8_t bits, int i = 0);
|
||
|
uint8_t get_ie_bit_size(int i = 0) const;
|
||
|
|
||
|
void set_ie_packing(uint16_t pack, int i = 0);
|
||
|
uint16_t get_ie_packing (int i = 0) const;
|
||
|
|
||
|
void set_ie_encoding(uint16_t enc, int i = 0);
|
||
|
uint16_t get_ie_encoding(int i = 0) const;
|
||
|
|
||
|
void set_ie_data_offset(uint32_t offs, int i = 0);
|
||
|
uint32_t get_ie_data_offset (int i = 0) const;
|
||
|
|
||
|
void set_ie_eol_padding(uint32_t padding, int i = 0);
|
||
|
uint32_t get_ie_eol_padding(int i = 0) const;
|
||
|
|
||
|
void set_ie_eo_image_padding(uint32_t padding, int i = 0);
|
||
|
uint32_t get_ie_eo_image_padding(int i = 0) const;
|
||
|
|
||
|
std::string get_ie_description(int i=0) const;
|
||
|
void set_ie_description(const std::string& str, int i = 0);
|
||
|
|
||
|
// Image Source access.
|
||
|
std::string get_is_filename() const;
|
||
|
void set_is_filename(const std::string& str);
|
||
|
|
||
|
std::string get_is_creation_time() const;
|
||
|
void set_is_creation_time(const std::string& str);
|
||
|
|
||
|
std::string get_is_input_device() const;
|
||
|
void set_is_input_device(const std::string& str);
|
||
|
|
||
|
std::string get_is_input_serial() const;
|
||
|
void set_is_input_serial(const std::string& str);
|
||
|
|
||
|
// Film header
|
||
|
std::string get_film_mfg_id() const;
|
||
|
void set_film_mfg_id(const std::string& str);
|
||
|
|
||
|
std::string get_film_type() const;
|
||
|
void set_film_type(const std::string& str);
|
||
|
|
||
|
std::string get_film_offset() const;
|
||
|
void set_film_offset(const std::string& str);
|
||
|
|
||
|
std::string get_film_prefix() const;
|
||
|
void set_film_prefix(const std::string& str);
|
||
|
|
||
|
std::string get_film_count() const;
|
||
|
void set_film_count(const std::string& str);
|
||
|
|
||
|
std::string get_film_format() const;
|
||
|
void set_film_format(const std::string& str);
|
||
|
|
||
|
size_t get_film_frame_position() const;
|
||
|
void set_film_frame_position(size_t pos );
|
||
|
|
||
|
size_t get_film_sequence_len() const;
|
||
|
void set_film_sequence_len(size_t len );
|
||
|
|
||
|
size_t get_film_held_count() const;
|
||
|
void set_film_held_count(size_t count );
|
||
|
|
||
|
float get_film_frame_rate () const;
|
||
|
void set_film_frame_rate (float len );
|
||
|
|
||
|
float get_film_shutter_angle() const;
|
||
|
void set_film_shutter_angle(float );
|
||
|
|
||
|
std::string get_film_frame_id() const;
|
||
|
void set_film_frame_id(const std::string& str);
|
||
|
|
||
|
std::string get_film_slate_info() const;
|
||
|
void set_film_slate_info(const std::string& str);
|
||
|
|
||
|
// TV header
|
||
|
size_t get_tv_timecode() const;
|
||
|
void set_tv_timecode(size_t tc);
|
||
|
|
||
|
size_t get_tv_userbits() const;
|
||
|
void set_tv_userbits(size_t tc);
|
||
|
|
||
|
float get_tv_frame_rate() const;
|
||
|
void set_tv_frame_rate(float fr);
|
||
|
|
||
|
uint8_t get_tv_interlace() const;
|
||
|
void set_tv_interlace(uint8_t interlace);
|
||
|
|
||
|
const DPX_header_t& GetHdr(void) const
|
||
|
{
|
||
|
return (m_hdr);
|
||
|
}
|
||
|
|
||
|
DPX_header_t& GetHdr(void)
|
||
|
{
|
||
|
return (m_hdr);
|
||
|
}
|
||
|
|
||
|
size_t GetHdrSize(void) const
|
||
|
{
|
||
|
return (sizeof(DPX_header_t));
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
DPX_header_t m_hdr;
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif // DPX_HDR_H
|