forked from usc-imi/aeo-light
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDPX.h
514 lines (413 loc) · 11.9 KB
/
DPX.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
// vi: ts=4
/*! \file DPX.h */
/*
* Copyright (c) 2009, Patrick A. Palmer.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Patrick A. Palmer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DPX_H
#define _DPX_H 1
#include <cstdio>
#include <limits>
#include "DPXHeader.h"
#include "DPXStream.h"
/*!
* \def OPENDPX_VERSION
* \brief OpenDPX Version
*/
#define OPENDPX_VERSION "0.5.0"
/*!
* \namespace dpx
* \brief OpenDPX namespace
*/
namespace dpx
{
// forward definitions
class Codec;
class ElementReadStream;
/*!
* \enum Endian
* \brief DPX files can be stored in big- or little-endian byte order
*/
enum Endian
{
kLittleEndian, //!< increasing numeric significance with increasing memory
kBigEndian //!< big end first
};
/*! \struct Block
* \brief Rectangle block definition defined by two points
*/
struct Block
{
int x1, y1, x2, y2;
/*!
* \brief Constructor
*/
inline Block();
/*!
* \brief Constructor
*
* \param x1 upper left x coordinate
* \param y1 upper left y coordinate
* \param x2 lower right x coordinate
* \param y2 lower right y coordinate
*/
Block(const int x1, const int y1, const int x2, const int y2);
/*!
* \brief Set the block coordinates
*
* \param x1 upper left x coordinate
* \param y1 upper left y coordinate
* \param x2 lower right x coordinate
* \param y2 lower right y coordinate
*/
void Set(const int x1, const int y1, const int x2, const int y2);
/*!
* \brief Check to see if a point is within the block
*
* \param x x coordinate
* \param y y coordinate
* \return true/false if coordinates within block
*/
inline bool Inside(const int x, const int y) const;
/*!
* \brief Rearrange coordinates if necessary so the first coordinate is upper left and the second is lower right
*/
inline void Check();
};
// Current platform endian byte order
extern Endian systemByteOrder;
// namespace functions
/*!
* \brief determine if the image file is DPX
*
* \param file buffer to read and search
* \return true/false if identified as DPX
*/
bool IdentifyFile(InStream *file);
/*!
* \brief determine if the image file is DPX
*
* \param data memory to search
* \return true/false if identified as DPX
*/
bool IdentifyFile(const void *data);
/*!
* \brief returns a char * of the default DPX file extension
*
* \return .dpx file extenion
*/
inline const char *DefaultExtension();
/*!
* returns a string of the highest SMPTE DPX version supported by this library
*
* \return SMPTE DPX version
*/
inline const char *Version();
/*!
* \brief returns the version string for this library
*
* \return OpenDPX version
*/
inline const char *LibraryVersion();
/*!
* \class Reader
* \brief DPX Image Reader class
*/
class Reader
{
public:
/*!
* \brief DPX header
*/
Header header;
InStream *fd;
/*!
* \brief Constructor
*/
Reader();
/*!
* \brief Destructor
*/
virtual ~Reader();
/*!
* \brief Set the InStream object to be used to read images
*
* \param stream Object to use for low level reads
*/
void SetInStream(InStream *stream);
/*!
* \brief clear any caching or memory allocated specific to an image
*/
void Reset();
/*!
* \brief Read the dpx header into the header member
*
* \return success true/false
*/
bool ReadHeader();
/*!
* \brief Read an image element into a buffer
*
* the size of the buffer must be large enough
* simple calculation would be:
* width * height * num_of_components * size_of_component
*
* \param element element (0-7)
* \param data buffer
* \return success true/false
*/
bool ReadImage(const int element, void *data);
/*!
* \brief Read an image element into a buffer that matches the image description type
*
* The DataSize allows the user to specific the buffer DataSize which can differ
* from the image element. It is possible, for example, to read an 8-bit per
* component (3 components per pixel for RGB) into 16-bits.
*
* \param data buffer
* \param size size of the buffer component
* \param desc element description type
* \return success true/false
*/
bool ReadImage(void *data, const DataSize size = kWord,
const Descriptor desc = kRGB);
/*!
* \brief Read a rectangular image block into a buffer from the specified image element
*
* \param element element (0-7)
* \param data buffer
* \param block image area to read
* \return success true/false
*/
bool ReadBlock(const int element, unsigned char *data, Block &block);
/*!
* \brief Read a rectangular image block into a buffer from the image element
* specified by the Descriptor type
*
* \param data buffer
* \param size size of the buffer component
* \param block image area to read
* \param desc element description type
* \return success true/false
*/
bool ReadBlock(void *data, const DataSize size, Block &block,
const Descriptor desc = kRGB);
/*!
* \brief Read the user data into a buffer.
*
* Buffer must be large enough to hold the user data.
*
* \param data buffer
* \return success true/false
*/
bool ReadUserData(unsigned char *data);
protected:
Codec *codex[MAX_ELEMENTS];
ElementReadStream *rio;
};
/*!
* \class Writer
* \brief DPX Image Writer class
*/
class Writer
{
public:
/*!
* \brief DPX Header
*/
Header header;
/*!
* \brief Constructor
*/
Writer();
/*!
* \brief Destructor
*/
virtual ~Writer();
/*!
* \brief Start defining the header and writing the images
*/
void Start();
/*!
* \brief Set the basic file information about DPX
*
* \param fileName name of this created file (100 characters max)
* \param creationTimeDate creation time and date - format is "YYYY:MM:DD:HH:MM:SSLTZ"
* where HH is 24 hour time, LTZ is local time zone using either
* three character notation (i.e., -04) or five character notation
* representing hours and minutes offset from Greenwich Mean time
* (i.e., -0700) (24 characters max)
* \param creator creator (100 characters max)
* \param project project name (200 characters max)
* \param copyright copyright statement (200 characters max)
* \param encryptKey encryption key
* \param swapEndian whether to write the image header in reverse to native endianness
*/
void SetFileInfo(const char *fileName, const char *creationTimeDate = 0, const char *creator = 0,
const char *project = 0, const char *copyright = 0, const U32 encryptKey = ~0,
const bool swapEndian = false);
/*!
* \brief Set the Width and Height of the images
*
* \param width width of the image
* \param height height of the image
*/
void SetImageInfo(const U32 width, const U32 height);
/*!
* \brief Get the next available element
* \return next available
*/
int NextAvailElement() const;
/*!
* \brief Set the parameters on an element
*
* There are 8 elements maximum in an single DPX and each element used must be set before writing the header
*
* \param element element number (0-7)
* \param desc image descriptor
* \param bitDepth bit depth of image, valid values are [8,10,12,16,32,64]
* \param transfer transfer characteristic
* \param colorimetric colorimetric specification
* \param packing packing type
* \param encoding encoding type
* \param dataSign
* \param lowData
* \param lowQuantity
* \param highData
* \param highQuantity
* \param eolnPadding end of line padding (in bytes)
* \param eoimPadding end of image padding (in bytes)
*/
void SetElement(const int element = 0,
const Descriptor desc = kRGB,
const U8 bitDepth = 10,
const Characteristic transfer = kLogarithmic,
const Characteristic colorimetric = kLogarithmic,
const Packing packing = kFilledMethodA,
const Encoding encoding = kNone,
const U32 dataSign = 0,
const U32 lowData = ~0, const R32 lowQuantity = std::numeric_limits<float>::quiet_NaN(),
const U32 highData = ~0, const R32 highQuantity = std::numeric_limits<float>::quiet_NaN(),
const U32 eolnPadding = 0, const U32 eoimPadding = 0);
/*!
* \brief Set the OutStream object will use to write the files
*
* \param stream OutStream object
*/
void SetOutStream(OutStream *stream);
/*!
* \brief Set the size of the user data area
*
* \param size size of user data
*/
void SetUserData(const long size);
/*!
* \brief Write the header
*
* \return success true/false
*/
bool WriteHeader();
/*!
* \brief Write the user data
*
* \param data buffer - must match size set in Writer::SetUserData()
* \return success true/false
*/
bool WriteUserData(void *data);
/*!
* \brief Write the entire element to the dpx file
*
* \param element element number (0-7)
* \param data buffer
* \return success true/false
*/
bool WriteElement(const int element, void *data);
bool WriteElement(const int element, void *data, const DataSize size);
bool WriteElement(const int element, void *data, const long count);
/**
* \brief Finish up writing image
*
* \return success true/false
*/
bool Finish();
protected:
long fileLoc;
OutStream *fd;
bool WriteThrough(void *, const U32, const U32, const int, const int, const U32, const U32, char *);
};
}
inline const char *dpx::DefaultExtension()
{
return "dpx";
}
inline const char *dpx::Version()
{
return SMPTE_VERSION;
}
inline const char *dpx::LibraryVersion()
{
return OPENDPX_VERSION;
}
inline dpx::Block::Block() : x1(0), y1(0), x2(0), y2(0)
{
}
inline dpx::Block::Block(const int x1, const int y1, const int x2, const int y2) : x1(x1), y1(y1), x2(x2), y2(y2)
{
this->Check();
}
inline void dpx::Block::Set(const int x1, const int y1, const int x2, const int y2)
{
this->x1 = x1;
this->y1 = y1;
this->x2 = x2;
this->y2 = y2;
}
// check the coordinates that x1 < x2 and y1 < y2
inline void dpx::Block::Check()
{
if (this->x1 > this->x2)
{
int t = x1;
this->x1 = this->x2;
this->x2 = t;
}
if (this->y1 > this->y2)
{
int t = y1;
this->y1 = this->y2;
this->y2 = t;
}
}
inline bool dpx::Block::Inside(const int x, const int y) const
{
if (x >= this->x1 && x <= this->x2 && y >= this->y1 && y <= this->y2)
return true;
return false;
}
#endif