From 72a7c912f371feaddfaa9133b34e87671b870f3c Mon Sep 17 00:00:00 2001
From: Manuel Virgilio <real_virgil@yahoo.it>
Date: Wed, 2 Mar 2022 19:47:40 +0100
Subject: [PATCH 4/4] added dpx support to cinelerra

---
 cinelerra-5.1/cinelerra/Makefile    |   1 +
 cinelerra-5.1/cinelerra/file.C      |  31 +++++-
 cinelerra-5.1/cinelerra/file.inc    |   4 +
 cinelerra-5.1/cinelerra/filedpx.C   | 206 ++++++++++++++++++++++++++++++++++++
 cinelerra-5.1/cinelerra/filedpx.h   |  49 +++++++++
 cinelerra-5.1/cinelerra/filedpx.inc |  27 +++++
 cinelerra-5.1/cinelerra/filelist.C  |   2 +-
 7 files changed, 318 insertions(+), 2 deletions(-)
 create mode 100644 cinelerra-5.1/cinelerra/filedpx.C
 create mode 100644 cinelerra-5.1/cinelerra/filedpx.h
 create mode 100644 cinelerra-5.1/cinelerra/filedpx.inc

diff --git a/cinelerra-5.1/cinelerra/Makefile b/cinelerra-5.1/cinelerra/Makefile
index 1c10fc0..30f5e2c 100644
--- a/cinelerra-5.1/cinelerra/Makefile
+++ b/cinelerra-5.1/cinelerra/Makefile
@@ -133,6 +133,7 @@ OBJS := $(OVERLAYS) \
 	$(OBJDIR)/filebaseulaw.o \
 	$(OBJDIR)/filecr2.o \
 	$(OBJDIR)/filedv.o \
+	$(OBJDIR)/filedpx.o \
 	$(OBJDIR)/fileexr.o \
 	$(OBJDIR)/fileffmpeg.o \
 	$(OBJDIR)/fileflac.o \
diff --git a/cinelerra-5.1/cinelerra/file.C b/cinelerra-5.1/cinelerra/file.C
index 03941d9..4113d64 100644
--- a/cinelerra-5.1/cinelerra/file.C
+++ b/cinelerra-5.1/cinelerra/file.C
@@ -45,6 +45,7 @@
 #include "filecr2.h"
 #include "filedb.h"
 #include "filedv.h"
+#include "filedpx.h"
 #include "fileexr.h"
 #include "fileffmpeg.h"
 #include "fileflac.h"
@@ -210,6 +211,11 @@ int File::get_options(FormatTools *format,
 		FileJPEG::get_parameters(parent_window, asset, format_window,
 			audio_options, video_options, edl);
 		break;
+	case FILE_DPX:
+	case FILE_DPX_LIST:
+		FileDPX::get_parameters(parent_window, asset, format_window,
+			audio_options, video_options, edl);
+		break;
 #ifdef HAVE_OPENEXR
 	case FILE_EXR:
 	case FILE_EXR_LIST:
@@ -278,6 +284,7 @@ int File::can_scale_input(Asset *asset)
 	case FILE_MPEG:
 	case FILE_FFMPEG:
 		return 1;
+	case FILE_DPX:
 	case FILE_EXR:
 	case FILE_JPEG:
 	case FILE_PNG:
@@ -379,6 +386,7 @@ const char *File::default_probes[] = {
 	"PPM",
 	"JPEG",
 	"GIF",
+	"DPX",
 #ifdef HAVE_OPENEXR
 	"EXR",
 #endif
@@ -392,7 +400,7 @@ const char *File::default_probes[] = {
 #endif
 	"MPEG",
 	"EDL",
-       	"FFMPEG_Late", 
+	"FFMPEG_Late",
 }; 
 const int File::nb_probes =
 	sizeof(File::default_probes)/sizeof(File::default_probes[0]); 
@@ -463,6 +471,11 @@ int File::probe()
 			else continue;
 			return FILE_OK;
 		}
+		if( !strcmp(pref->name,"DPX") ) { // DPX file
+			if( !FileDPX::check_sig(this->asset, data) ) continue;
+			file = new FileDPX(this->asset, this);
+			return FILE_OK;
+		}
 #ifdef HAVE_OPENEXR
 		if( !strcmp(pref->name,"EXR") ) { // EXR file
 			if( !FileEXR::check_sig(this->asset, data)) continue;
@@ -590,12 +603,18 @@ int File::open_file(Preferences *preferences,
 		file = new FileGIFList(this->asset, this);
 		break;
 
+	case FILE_DPX:
+	case FILE_DPX_LIST:
+		file = new FileDPX(this->asset, this);
+		break;
+
 #ifdef HAVE_OPENEXR
 	case FILE_EXR:
 	case FILE_EXR_LIST:
 		file = new FileEXR(this->asset, this);
 		break;
 #endif
+
 	case FILE_FLAC:
 		file = new FileFLAC(this->asset, this);
 		break;
@@ -1273,6 +1292,8 @@ int File::strtoformat(const char *format)
 	if( !strcasecmp(format, _(TIFF_LIST_NAME)) ) return FILE_TIFF_LIST;
 	if( !strcasecmp(format, _(JPEG_NAME)) ) return FILE_JPEG;
 	if( !strcasecmp(format, _(JPEG_LIST_NAME)) ) return FILE_JPEG_LIST;
+	if( !strcasecmp(format, _(DPX_NAME)) ) return FILE_DPX;
+	if( !strcasecmp(format, _(DPX_LIST_NAME)) ) return FILE_DPX_LIST;
 	if( !strcasecmp(format, _(EXR_NAME)) ) return FILE_EXR;
 	if( !strcasecmp(format, _(EXR_LIST_NAME)) ) return FILE_EXR_LIST;
 	if( !strcasecmp(format, _(FLAC_NAME)) ) return FILE_FLAC;
@@ -1317,6 +1338,8 @@ const char* File::formattostr(int format)
 	case FILE_FLAC:		return _(FLAC_NAME);
 	case FILE_GIF:		return _(GIF_NAME);
 	case FILE_GIF_LIST:	return _(GIF_LIST_NAME);
+	case FILE_DPX:		return _(DPX_NAME);
+	case FILE_DPX_LIST:	return _(DPX_LIST_NAME);
 	case FILE_EXR:		return _(EXR_NAME);
 	case FILE_EXR_LIST:	return _(EXR_LIST_NAME);
 #ifdef HAVE_LIBZMPEG
@@ -1409,6 +1432,8 @@ int File::get_best_colormodel(Asset *asset, int driver)
 #endif
 	case FILE_JPEG:
 	case FILE_JPEG_LIST:	return FileJPEG::get_best_colormodel(asset, driver);
+	case FILE_DPX:
+	case FILE_DPX_LIST:	return FileDPX::get_best_colormodel(asset, driver);	
 #ifdef HAVE_OPENEXR
 	case FILE_EXR:
 	case FILE_EXR_LIST:	return FileEXR::get_best_colormodel(asset, driver);
@@ -1544,7 +1569,9 @@ const char* File::get_tag(int format)
 	case FILE_AU:           return "au";
 	case FILE_RAWDV:        return "dv";
 	case FILE_DB:           return "db";
+	case FILE_DPX:          return "dpx";
 	case FILE_EXR:          return "exr";
+	case FILE_DPX_LIST:     return "dpxs";
 	case FILE_EXR_LIST:     return "exrs";
 	case FILE_FLAC:         return "flac";
 	case FILE_JPEG:         return "jpg";
@@ -1594,6 +1621,8 @@ const char* File::get_prefix(int format)
 	case FILE_PNG_LIST:	return "PNG_LIST";
 	case FILE_PPM_LIST:	return "PPM_LIST";
 	case FILE_AC3:		return "AC3";
+	case FILE_DPX:		return "DPX";
+	case FILE_DPX_LIST:	return "DPX_LIST";
 	case FILE_EXR:		return "EXR";
 	case FILE_EXR_LIST:	return "EXR_LIST";
 	case FILE_CR2:		return "CR2";
diff --git a/cinelerra-5.1/cinelerra/file.inc b/cinelerra-5.1/cinelerra/file.inc
index c6228a2..ff758ee 100644
--- a/cinelerra-5.1/cinelerra/file.inc
+++ b/cinelerra-5.1/cinelerra/file.inc
@@ -93,6 +93,8 @@
 #define FILE_PPM                38
 #define FILE_PPM_LIST           39
 #define FILE_REF                40
+#define FILE_DPX                41
+#define FILE_DPX_LIST           42
 
 // For formats supported by plugins, the format number is the plugin number in the
 // plugin list ORed with 0x8000.
@@ -170,6 +172,8 @@ N_("Reference to EDL")
 #define VORBIS_NAME		"OGG Vorbis"
 #define WAV_NAME		"Microsoft WAV"
 #define REF_NAME		"Reference EDL"
+#define DPX_NAME		"DPX"
+#define DPX_LIST_NAME	"DPX Sequence"
 
 #define BITSLINEAR8    8
 #define BITSLINEAR16   16
diff --git a/cinelerra-5.1/cinelerra/filedpx.C b/cinelerra-5.1/cinelerra/filedpx.C
new file mode 100644
index 0000000..4c5fda6
--- /dev/null
+++ b/cinelerra-5.1/cinelerra/filedpx.C
@@ -0,0 +1,206 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "asset.h"
+#include "file.h"
+#include "filedpx.h"
+
+class DPXInStream : public InStream
+{
+public:
+	DPXInStream(char * ptr, size_t sz);
+	virtual ~DPXInStream();
+
+	void Close();
+	void Rewind();
+	size_t Read(void * buf, const size_t size);
+	size_t ReadDirect(void * buf, const size_t size);
+	bool EndOfFile() const;
+	bool Seek(long offset, Origin origin);
+
+private:
+	char *databuf;
+	size_t pos;
+	size_t bufsize;
+};
+
+DPXInStream::DPXInStream(char * ptr, size_t sz) :
+	databuf(ptr),
+	pos(0),
+	bufsize(sz)
+{
+}
+
+DPXInStream::~DPXInStream()
+{
+	Close();
+}
+
+void DPXInStream::Close()
+{
+	databuf = nullptr;
+	bufsize = 0;
+	pos = 0;
+}
+
+void DPXInStream::Rewind()
+{
+	pos = 0;
+}
+
+size_t DPXInStream::Read(void * buf, const size_t size)
+{
+	size_t data_to_read = MIN(size, bufsize - pos);
+	if ( data_to_read > 0 )
+	{
+		memcpy(buf, &databuf[pos], data_to_read);
+		pos += data_to_read;
+	}
+	return data_to_read;
+}
+
+size_t DPXInStream::ReadDirect(void * buf, const size_t size)
+{
+	this->Read(buf, size);
+}
+
+bool DPXInStream::EndOfFile() const
+{
+	if ( pos >= bufsize )
+		return true;
+	return false;
+}
+
+bool DPXInStream::Seek(long offset, Origin origin)
+{
+	bool result = true;
+	switch ( origin )
+	{
+	case kStart:
+		if ( (size_t)offset < bufsize )
+			pos = offset;
+		else
+			result = false;
+	break;
+
+	case kCurrent:
+		if ( pos+offset < bufsize )
+			pos += offset;
+		else
+			result = false;
+	break;
+
+	case kEnd:
+		if ( (size_t)offset < bufsize )
+			pos = bufsize - offset - 1;
+		else
+			result = false;
+	break;
+	}
+	return result;
+}
+
+
+
+
+FileDPX::FileDPX(Asset *asset, File *file)
+ : FileList(asset, file, "DPXLIST", ".dpx", FILE_DPX, FILE_DPX_LIST)
+{
+	if(asset->format == FILE_UNKNOWN) 
+		asset->format = FILE_DPX_LIST;
+}
+
+FileDPX::~FileDPX()
+{
+}
+
+void FileDPX::get_parameters(BC_WindowBase *parent_window,
+	Asset *asset, BC_WindowBase* &format_window,
+	int audio_options, int video_options, EDL *edl)
+{
+}
+
+int FileDPX::check_sig(Asset *asset, char *test)
+{
+	if(test[0] == 'D' && test[1] == 'P' && test[2] == 'X' &&
+		test[3] == 'L' && test[4] == 'I' && test[5] == 'S' && test[6] == 'T')
+	{
+		return 1;
+	}
+	return 0;
+}
+
+int FileDPX::get_best_colormodel(Asset *asset, int driver)
+{
+	return BC_RGB161616;
+}
+
+int FileDPX::colormodel_supported(int colormodel)
+{
+	return color_model;
+}
+
+int FileDPX::read_frame_header(char *path)
+{
+	int result = 0;
+
+	InStream img;
+	if (!img.Open(path))
+	{
+		return 1;
+	}
+	
+	dpx::Header header;	
+	if (!header.Read(&img))
+	{		
+		return 1;
+	}
+		
+	asset->width = header.Width();
+	asset->height = header.Height();
+	switch ( header.ComponentDataSize(0) )
+	{
+		case dpx::DataSize::kByte:
+			color_model = BC_RGB888;
+			break;
+		
+		case dpx::DataSize::kWord:
+			color_model = BC_RGB161616;
+			break;
+
+		case dpx::DataSize::kInt:
+		case dpx::DataSize::kFloat:
+		case dpx::DataSize::kDouble:
+			color_model = BC_RGB_FLOAT;
+			break;
+	}
+	return result;
+}
+
+int FileDPX::read_frame(VFrame *frame, VFrame *data)
+{	
+	DPXInStream inStream((char*)data->get_data(), data->get_compressed_size());
+	dpx::Reader dpxReader;
+
+	dpxReader.SetInStream(&inStream);
+	dpxReader.ReadHeader();
+	return dpxReader.ReadImage(0, frame->get_data()) ? 0 : 1;
+}
\ No newline at end of file
diff --git a/cinelerra-5.1/cinelerra/filedpx.h b/cinelerra-5.1/cinelerra/filedpx.h
new file mode 100644
index 0000000..2fd4331
--- /dev/null
+++ b/cinelerra-5.1/cinelerra/filedpx.h
@@ -0,0 +1,49 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef FILEDPX_H
+#define FILEDPX_H
+
+#include "file.inc"
+#include "filedpx.inc"
+#include "filelist.h"
+#include "DPX.h"
+
+class FileDPX : public FileList
+{
+public:
+	FileDPX(Asset *asset, File *file);
+	~FileDPX();
+
+	static void get_parameters(BC_WindowBase *parent_window,
+		Asset *asset, BC_WindowBase* &format_window,
+		int audio_options, int video_options, EDL *edl);
+	static int check_sig(Asset *asset, char *test);
+	static int get_best_colormodel(Asset *asset, int driver);
+	int colormodel_supported(int colormodel);
+	int read_frame_header(char *path);
+	int read_frame(VFrame *frame, VFrame *data);
+
+private:
+	int color_model;
+};
+
+#endif
diff --git a/cinelerra-5.1/cinelerra/filedpx.inc b/cinelerra-5.1/cinelerra/filedpx.inc
new file mode 100644
index 0000000..bd6a307
--- /dev/null
+++ b/cinelerra-5.1/cinelerra/filedpx.inc
@@ -0,0 +1,27 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef FILEDPX_INC
+#define FILEDPX_INC
+
+class FileDPX;
+
+#endif
diff --git a/cinelerra-5.1/cinelerra/filelist.C b/cinelerra-5.1/cinelerra/filelist.C
index 4819cb5..8c92340 100644
--- a/cinelerra-5.1/cinelerra/filelist.C
+++ b/cinelerra-5.1/cinelerra/filelist.C
@@ -115,7 +115,7 @@ int FileList::open_file(int rd, int wr)
 				int width = asset->width, height = asset->height;
 				char string[BCTEXTLEN];
 				int len = strlen(list_prefix);
-				int ret = fread(string, 1, strlen(list_prefix), stream);
+				int ret = fread(string, 1, len, stream);
 				fclose(stream);
 				result = len == ret ? 0 : 1;
 				if( !result && !strncasecmp(string, list_prefix, len)) {
-- 
2.14.5

