Credit Andrew R for finding the direct copy mods for exr and ppm sequences
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / filedpx.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21 #ifdef HAVE_LIBDPX
22
23 #include "asset.h"
24 #include "file.h"
25 #include "filedpx.h"
26
27 class DPXInStream : public InStream
28 {
29 public:
30         DPXInStream(char * ptr, size_t sz);
31         virtual ~DPXInStream();
32
33         void Close();
34         void Rewind();
35         size_t Read(void * buf, const size_t size);
36         size_t ReadDirect(void * buf, const size_t size);
37         bool EndOfFile() const;
38         bool Seek(long offset, Origin origin);
39
40 private:
41         char *databuf;
42         size_t pos;
43         size_t bufsize;
44 };
45
46 DPXInStream::DPXInStream(char * ptr, size_t sz) :
47         databuf(ptr),
48         pos(0),
49         bufsize(sz)
50 {
51 }
52
53 DPXInStream::~DPXInStream()
54 {
55         Close();
56 }
57
58 void DPXInStream::Close()
59 {
60         databuf = nullptr;
61         bufsize = 0;
62         pos = 0;
63 }
64
65 void DPXInStream::Rewind()
66 {
67         pos = 0;
68 }
69
70 size_t DPXInStream::Read(void * buf, const size_t size)
71 {
72         size_t data_to_read = MIN(size, bufsize - pos);
73         if ( data_to_read > 0 )
74         {
75                 memcpy(buf, &databuf[pos], data_to_read);
76                 pos += data_to_read;
77         }
78         return data_to_read;
79 }
80
81 size_t DPXInStream::ReadDirect(void * buf, const size_t size)
82 {
83         this->Read(buf, size);
84 }
85
86 bool DPXInStream::EndOfFile() const
87 {
88         if ( pos >= bufsize )
89                 return true;
90         return false;
91 }
92
93 bool DPXInStream::Seek(long offset, Origin origin)
94 {
95         bool result = true;
96         switch ( origin )
97         {
98         case kStart:
99                 if ( (size_t)offset < bufsize )
100                         pos = offset;
101                 else
102                         result = false;
103         break;
104
105         case kCurrent:
106                 if ( pos+offset < bufsize )
107                         pos += offset;
108                 else
109                         result = false;
110         break;
111
112         case kEnd:
113                 if ( (size_t)offset < bufsize )
114                         pos = bufsize - offset - 1;
115                 else
116                         result = false;
117         break;
118         }
119         return result;
120 }
121
122
123
124
125 FileDPX::FileDPX(Asset *asset, File *file)
126  : FileList(asset, file, "DPXLIST", ".dpx", FILE_DPX, FILE_DPX_LIST)
127 {
128         if(asset->format == FILE_UNKNOWN) 
129                 asset->format = FILE_DPX_LIST;
130 }
131
132 FileDPX::~FileDPX()
133 {
134 }
135
136 void FileDPX::get_parameters(BC_WindowBase *parent_window,
137         Asset *asset, BC_WindowBase* &format_window,
138         int audio_options, int video_options, EDL *edl)
139 {
140 }
141
142 int FileDPX::check_sig(Asset *asset, char *test)
143 {
144         if(test[0] == 'D' && test[1] == 'P' && test[2] == 'X' &&
145                 test[3] == 'L' && test[4] == 'I' && test[5] == 'S' && test[6] == 'T')
146         {
147                 return 1;
148         }
149         return 0;
150 }
151
152 int FileDPX::get_best_colormodel(Asset *asset, int driver)
153 {
154         return BC_RGB161616;
155 }
156
157 int FileDPX::colormodel_supported(int colormodel)
158 {
159         return color_model;
160 }
161
162 int FileDPX::read_frame_header(char *path)
163 {
164         int result = 0;
165
166         InStream img;
167         if (!img.Open(path))
168         {
169                 return 1;
170         }
171         
172         dpx::Header header;     
173         if (!header.Read(&img))
174         {               
175                 return 1;
176         }
177                 
178         asset->width = header.Width();
179         asset->height = header.Height();
180         switch ( header.ComponentDataSize(0) )
181         {
182                 case dpx::DataSize::kByte:
183                         color_model = BC_RGB888;
184                         break;
185                 
186                 case dpx::DataSize::kWord:
187                         color_model = BC_RGB161616;
188                         break;
189
190                 case dpx::DataSize::kInt:
191                 case dpx::DataSize::kFloat:
192                 case dpx::DataSize::kDouble:
193                         color_model = BC_RGB_FLOAT;
194                         break;
195         }
196         return result;
197 }
198
199 int FileDPX::read_frame(VFrame *frame, VFrame *data)
200 {       
201         DPXInStream inStream((char*)data->get_data(), data->get_compressed_size());
202         dpx::Reader dpxReader;
203
204         dpxReader.SetInStream(&inStream);
205         dpxReader.ReadHeader();
206         return dpxReader.ReadImage(0, frame->get_data()) ? 0 : 1;
207 }
208
209 #endif