-
Notifications
You must be signed in to change notification settings - Fork 1
/
dpxRead.m
587 lines (435 loc) · 18.9 KB
/
dpxRead.m
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
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
% reads dpx file
function fileData = dpxRead(filename)
% open file
fp = fopen(filename);
if (fp == -1)
error('File could not be opened.');
end
% Get byte order 0 = forward, 1 = reverse
order = getOrder(fp);
if (order == -1)
error('Incorrect syntax. File could not be read.');
end
% Field 4 Data Offset
dataOffset = getInfo(fp, 4, 4, 'U32', order);
fprintf('Offset: %u\n', dataOffset);
% Field 3 Version Number
version = getInfo(fp, 8, 8, 'ASCII', order);
fprintf('Version: %s\n', version);
% Field 4 Total Image Size
fileSize = getInfo(fp, 16, 4, 'U32', order);
fprintf('Image Size (bytes): %u\n', fileSize);
% Field 5 Ditto Key
dittoKey = getInfo(fp, 20, 4, 'U32', order);
fprintf('Ditto Key: %u\n', dittoKey);
% Field 6 Generic Section Header Length (bytes)
genericHeaderLen = getInfo(fp, 24, 4, 'U32', order);
fprintf('Generic Section Header Length (bytes): %u\n', genericHeaderLen);
% Field 7 Industry Specific Header Length (bytes)
industryHeaderLen = getInfo(fp, 28, 4, 'U32', order);
fprintf('Industry Specific Header Length (bytes): %u\n', industryHeaderLen);
% Field 8 User Defined Header Length (bytes)
userHeaderLen = getInfo(fp, 32, 4, 'U32', order);
fprintf('User Defined Header Length (bytes): %u\n', userHeaderLen);
% Field 9 Image Filename
imageFilename = getInfo(fp, 36, 100, 'ASCII', order);
fprintf('Image Filename: %s\n', imageFilename);
% Field 10 Creation date/time
creationTime = getInfo(fp, 136, 24, 'ASCII', order);
fprintf('Creation Time: %s\n', creationTime);
% Field 12 Creator
creator = getInfo(fp, 160, 100, 'ASCII', order);
fprintf('Creator: %s\n', creator);
% Field 13 Project Name
projectName = getInfo(fp, 260, 200, 'ASCII', order);
fprintf('Project Name: %s\n', projectName);
% Field 14 Right to Use Copyright Statement
copywriteStatement = getInfo(fp, 460, 200, 'ASCII', order);
fprintf('Right to Use Copyright Statement: %s\n', copywriteStatement);
% Field 15
encryptionKey = getInfo(fp, 660, 4, 'U32', order);
fprintf('Encryption Key: %x\n', encryptionKey);
% Image Information Header
% Field 17 Image Orientation
orientation = getInfo(fp, 768, 2, 'U16', order);
fprintf('Image Orientation: %u\n', orientation);
% Field 18 Number of Image Elements (1 - 8)
numElements = getInfo(fp, 770, 2, 'U16', order);
fprintf('Number of Image Elements: %u\n', numElements);
% Field 19 Number of Pixels per Line
pixelsPerLine = getInfo(fp, 772, 4, 'U32', order);
fprintf('Pixels per Line: %u\n', pixelsPerLine);
% Field 20 Lines per Image Element
linesPerElement = getInfo(fp, 776, 4, 'U32', order);
fprintf('Lines per Image Element: %u\n', linesPerElement);
% Field 21 Data Structure for Image Element
dataSign = zeros(1, 8);
lowData = zeros(1, 8);
lowQuantity = zeros(1, 8);
highData = zeros(1, 8);
highQuantity = zeros(1, 8);
descriptor = zeros(1, 8);
transferChar = zeros(1, 8);
colorSpec = zeros(1, 8);
bitDepth = zeros(1, 8);
packing = zeros(1, 8);
encoding = zeros(1, 8);
offsetToData = zeros(1, 8);
linePadding = zeros(1, 8);
imagePadding = zeros(1, 8);
descImageElement = [];
for i=1:numElements
% need offset as if we have multiple elements
elementOffset = 72*(i - 1);
% Field 21.1 Data Sign
dataSign(i) = getInfo(fp, 780 + elementOffset, 4, 'U32', order);
fprintf('Data Sign %d: %u\n', i, dataSign(i));
% Field 21.2 Reference Low Data Code Value
lowData(i) = getInfo(fp, 784 + elementOffset, 4, 'U32', order);
fprintf('Reference Low Data Code Value %d: %u\n', i, lowData(i));
% Field 21.3 Reference Low Quantity Represented
lowQuantity(i) = getInfo(fp, 788 + elementOffset, 4, 'U32', order);
fprintf('Reference Low Quantity Represented %d: %u\n', i, lowQuantity(i));
% Field 21.4 Reference High Data Code Value
highData(i) = getInfo(fp, 792 + elementOffset, 4, 'U32', order);
fprintf('Reference High Data Code Value %d: %u\n', i, highData(i));
% Field 21.5 Reference Low Quantity Represented
highQuantity(i) = getInfo(fp, 796 + elementOffset, 4, 'U32', order);
fprintf('Reference High Quantity Represented %d: %u\n', i, highQuantity(i));
% Field 21.6 Descriptor
descriptor(i) = getInfo(fp, 800 + elementOffset, 1, 'U8', order);
fprintf('Descriptor %d: %u\n', i, descriptor(i));
% Field 21.7 Transfer Characteristics
transferChar(i) = getInfo(fp, 801 + elementOffset, 1, 'U8', order);
fprintf('Transfer Characteristics %d: %u\n', i, transferChar(i));
% Field 21.8 Colorimetric Specification
colorSpec(i) = getInfo(fp, 802 + elementOffset, 1, 'U8', order);
fprintf('Transfer Characteristics %d: %u\n', i, colorSpec(i));
% Field 21.9 Bit Depth
bitDepth(i) = getInfo(fp, 803 + elementOffset, 1, 'U8', order);
fprintf('Bit Depth %d: %u\n', i, bitDepth(i));
% Field 21.10 Packing
packing(i) = getInfo(fp, 804 + elementOffset, 2, 'U16', order);
fprintf('Packing %d: %u\n', i, packing(i));
% Field 21.11 Encoding
encoding(i) = getInfo(fp, 806 + elementOffset, 2, 'U16', order);
fprintf('Encoding %d: %u\n', i, encoding(i));
% Field 21.12 Offset to Data
offsetToData(i) = getInfo(fp, 808 + elementOffset, 4, 'U32', order);
fprintf('Offset to Data %d: %u\n', i, offsetToData(i));
% Field 21.13 End of Line Padding
linePadding(i) = getInfo(fp, 812 + elementOffset, 4, 'U32', order);
fprintf('End-of-line padding %d: %u\n', i, linePadding(i));
% Field 21.14 End of Image Padding
imagePadding(i) = getInfo(fp, 816 + elementOffset, 4, 'U32', order);
fprintf('End-of-image padding %d: %u\n', i, imagePadding(i));
% Field 21.15 Description of image element
descImageElement = [ descImageElement, getInfo(fp, 820 + elementOffset, 32, 'ASCII', order) ];
fprintf('Description of image element %d: %s\n', i, descImageElement(i));
end
% Image information header
% Field 30 X Offset
xOffset = getInfo(fp, 1408, 4, 'U32', order);
fprintf('X Offset: %u\n', xOffset);
% Field 31 Y Offset
yOffset = getInfo(fp, 1412, 4, 'U32', order);
fprintf('Y Offset: %u\n', yOffset);
% Field 32 X Center
xCenter = getInfo(fp, 1416, 4, 'R32', order);
fprintf('X Center: %d\n', xCenter);
% Field 33 Y Center
yCenter = getInfo(fp, 1420, 4, 'R32', order);
fprintf('Y Center: %d\n', yCenter);
% Field 34 X Original Size
xOrigSize = getInfo(fp, 1424, 4, 'U32', order);
fprintf('X Original Size: %u\n', xOrigSize);
% Field 35 Y Original Size
yOrigSize = getInfo(fp, 1428, 4, 'U32', order);
fprintf('Y Original Size: %u\n', yOrigSize);
% Field 36 Source Image Filename
srcImageFilename = getInfo(fp, 1432, 100, 'ASCII', order);
fprintf('Source Image Filename: %s\n', srcImageFilename);
% Field 37 Source Image Date
srcImageDate = getInfo(fp, 1532, 24, 'ASCII', order);
fprintf('Source Image Date: %s\n', srcImageDate);
% Field 38 Input Device Name
inputDevice = getInfo(fp, 1556, 32, 'ASCII', order);
fprintf('Input Device Name: %s\n', inputDevice);
% Field 39 Input Device Serial Number
inputDeviceSerial = getInfo(fp, 1588, 32, 'ASCII', order);
fprintf('Input Device Serial Number: %s\n', inputDeviceSerial);
% Field 40 Border Validity
borderValidity = getInfo(fp, 1620, 8, 'U16', order);
fprintf('Border Validity XL: %u XR: %u YT: %u YB: %u\n', borderValidity(1), borderValidity(2), borderValidity(3), borderValidity(4));
% Field 41 Pixel Aspect Ratio
pixelAspectRatio = getInfo(fp, 1628, 8, 'U32', order);
fprintf('Pixel Aspect Ratio Horizontal: %u Vertical: %u\n ', pixelAspectRatio(1), pixelAspectRatio(2));
% Field 42 Data structure for additional source image information
% Field 42.1 X Scanned Size
xScannedSize = getInfo(fp, 1636, 4, 'R32', order);
fprintf('X Scanned Size: %d\n', xScannedSize);
% Field 42.2 Y Scanned Size
yScannedSize = getInfo(fp, 1640, 4, 'R32', order);
fprintf('Y Scanned Size: %d\n', yScannedSize);
% Motion-picture Film Information Header
% Field 43 Film mfg. ID Code
filmmfg = getInfo(fp, 1664, 2, 'ASCII', order);
fprintf('Film mfg. ID Code: %s\n', filmmfg);
% Field 44 Film Type
filmType = getInfo(fp, 1666, 2, 'ASCII', order);
fprintf('Film Type: %s\n', filmType);
% Field 45 Offset in Perfs
offsetPerfs = getInfo(fp, 1668, 2, 'ASCII', order);
fprintf('Offset in Perfs: %s\n', offsetPerfs);
% Field 47 Prefix
prefix = getInfo(fp, 1670, 6, 'ASCII', order);
fprintf('Prefix: %s\n', prefix);
% Field 48 Count
count = getInfo(fp, 1676, 4, 'ASCII', order);
fprintf('Count: %s\n', count);
% Field 49 Format
format = getInfo(fp, 1680, 32, 'ASCII', order);
fprintf('Format: %s\n', format);
% Field 50 Frame Position in Sequence
framePosSeq = getInfo(fp, 1712, 4, 'U32', order);
fprintf('Frame Position in Sequence: %u\n', framePosSeq);
% Field 51 Sequence Length (frames)
seqLength = getInfo(fp, 1716, 4, 'U32', order);
fprintf('Sequence Length (frames): %u\n', seqLength);
% Field 52 Held Count
heldCount = getInfo(fp, 1720, 4, 'U32', order);
fprintf('Held Count: %u\n', heldCount);
% Field 53 Frame Rate of Original (fps)
fpsOriginal = getInfo(fp, 1724, 4, 'R32', order);
fprintf('Frame Rate of Original (fps): %d\n', fpsOriginal);
% Field 54 Shuttle Angle (degrees)
shuttleAngle = getInfo(fp, 1728, 4, 'R32', order);
fprintf('Shuttle Angle (degrees): %d\n', shuttleAngle);
% Field 55 Frame Identification
frameID = getInfo(fp, 1732, 32, 'ASCII', order);
fprintf('Frame Identification: %s\n', frameID);
% Field 56 Slate Information
slateInfo = getInfo(fp, 1764, 100, 'ASCII', order);
fprintf('Slate Information: %s\n', slateInfo);
% Television Information Header
% Field 58 SMPTE Time Code
SMPTETimeCode = getInfo(fp, 1920, 4, 'U32', order);
fprintf('SMPTE Time Code: %u\n', SMPTETimeCode);
% Field 59 SMPTE User Bits
SMPTEUserBits = getInfo(fp, 1924, 4, 'U32', order);
fprintf('SMPTE User Bits: %u\n', SMPTEUserBits);
% Field 60 Interlace
interlace = getInfo(fp, 1928, 1, 'U8', order);
fprintf('Interlace: %u\n', interlace);
% Field 61 Field Number
fieldNum = getInfo(fp, 1929, 1, 'U8', order);
fprintf('Field Number: %u\n', fieldNum);
% Field 62 Video Signal Standard
vidSigStnd = getInfo(fp, 1930, 1, 'U8', order);
fprintf('Video Signal Standard: %u\n', vidSigStnd);
% Field 63 Byte Alignment
zero = getInfo(fp, 1931, 1, 'U8', order);
fprintf('Byte Alignment: %u\n', zero);
% Field 64 Horizontal Sampling Rate (Hz)
horzSampleRate = getInfo(fp, 1932, 4, 'R32', order);
fprintf('Horizontal Sampling Rate (Hz): %d\n', horzSampleRate);
% Field 65 Verticle Sampling Rate (Hz)
vertSampleRate = getInfo(fp, 1936, 4, 'R32', order);
fprintf('Verticle Sampling Rate (Hz): %d\n', vertSampleRate);
% Field 66 Temporal Sampling Rate (Hz)
tempSampleRate = getInfo(fp, 1940, 4, 'R32', order);
fprintf('Temporal Sampling Rate (Hz): %d\n', tempSampleRate);
% Field 67 Time Offset from Sync to First Pixel (ms)
timeOffsetSync = getInfo(fp, 1944, 4, 'R32', order);
fprintf('Time Offset from Sync to First Pixel (ms): %d\n', timeOffsetSync);
% Field 68 Gamma
gamma = getInfo(fp, 1948, 4, 'R32', order);
fprintf('Gamma: %d\n', gamma);
% Field 69 Black Level
blackLevel = getInfo(fp, 1952, 4, 'R32', order);
fprintf('Black Level: %d\n', blackLevel);
% Field 70 Black Gain
blackGain = getInfo(fp, 1956, 4, 'R32', order);
fprintf('Black Gain: %d\n', blackGain);
% Field 71 Breakpoint
breakpoint = getInfo(fp, 1960, 4, 'R32', order);
fprintf('Breakpoint: %d\n', breakpoint);
% Field 72 White Level
whiteLevel = getInfo(fp, 1964, 4, 'R32', order);
fprintf('White Level: %d\n', whiteLevel);
% Field 73 Integration Time
integTime = getInfo(fp, 1968, 4, 'R32', order);
fprintf('Integration Time: %d\n', integTime);
% Field 77 Image data
frewind(fp);
headerData = fread(fp, dataOffset/4, 'uint32', 0, 'b');
imageData = getImageData(fp, dataOffset, bitDepth(1), pixelsPerLine, linesPerElement, packing(1), descriptor(i));
fileData = { headerData imageData };
% get the image data
function data = getImageData(fp, offset, depth, xRes, yRes, packing, descriptor)
depthType = getDepthType(depth);
fseek(fp, offset, 'bof');
compLen = getCompLen(descriptor);
numElements = xRes*yRes*compLen;
dataItr = 1;
if (depth == 10 || depth == 12)
% datum is sequential
if (packing == 0)
lnBitLen = xRes*compLen*depth;
pad = 32 - mod(lnBitLen, 32);
buffer = zeros(1, numElements);
for i = 1:yRes
buffer(dataItr:(dataItr + xRes - 1)) = fread(fp, xRes, depthType);
fread(fp, pad, 'ubit1');
dataItr = dataItr + xRes;
end
R = buffer(1:3:end);
G = buffer(2:3:end);
B = buffer(3:3:end);
redChan = reshape(R, xRes, yRes);
greenChan = reshape(G, xRes, yRes);
blueChan = reshape(B, xRes, yRes);
data = cat(3, redChan, greenChan, blueChan);
% packing type 1
elseif (packing == 1)
% Read 10 bit files with packing type 1
if (depth == 10)
buffer = fread(fp, xRes*yRes, 'uint32', 0, 'b');
c1 = bitshift(buffer, -2);
c2 = bitshift(buffer, -12);
c3 = bitshift(buffer, -22);
R = bitand(c1, 1023);
G = bitand(c2, 1023);
B = bitand(c3, 1023);
redChan = reshape(R, xRes, yRes);
greenChan = reshape(G, xRes, yRes);
blueChan = reshape(B, xRes, yRes);
data = cat(3, redChan, greenChan, blueChan);
% 12 bit files with packing type 1
else
buffLen = floor(double(numElements)/2.0);
if (mod(numElements, 2) ~= 0)
buffLen = buffLen + 1;
end
if (mod(numElements, 2) ~= 0)
buffLen = buffLen + 1;
end
buffer = fread(fp, buffLen, 'uint32', 0, 'b');
c1 = bitshift(buffer, -4);
c2 = bitshift(buffer, -20);
c1 = bitand(c1, 4095);
c2 = bitand(c2, 4095);
arr = zeros(1, 3*xRes*yRes);
arr(1:2:end) = c1;
arr(2:2:end) = c2;
R = arr(1:3:end);
G = arr(2:3:end);
B = arr(3:3:end);
redChan = reshape(R, xRes, yRes);
greenChan = reshape(G, xRes, yRes);
blueChan = reshape(B, xRes, yRes);
data = cat(3, redChan, greenChan, blueChan);
end
else
error('Cannot handle packing format.');
end
else
buffer = uint64(fread(fp, numElements, depthType, 0, 'b'));
R = buffer(1:3:end);
G = buffer(2:3:end);
B = buffer(3:3:end);
redChan = reshape(R, xRes, yRes);
greenChan = reshape(G, xRes, yRes);
blueChan = reshape(B, xRes, yRes);
data = cat(3, redChan, greenChan, blueChan);
end
fclose(fp);
% get string for bit depth
function depthType = getDepthType(depth)
switch depth
case 1
depthType = 'ubit1';
case 8
depthType = 'ubit8';
case 10
depthType = 'ubit10';
case 12
depthType = 'ubit12';
case 16
depthType = 'ubit16';
case 32
depthType = 'ubit32';
case 64
depthType = 'ubit64';
otherwise
error('Depth not valid');
end
% gets the length of a component
% as of now only hold RGB
function compLen = getCompLen(desc)
switch desc
case 50
compLen = 3;
otherwise
error('Cannot handle descriptor type.');
end
% seeks to a position from the beginning of the file
function seek(fp, pos)
status = fseek(fp, pos, 'bof');
if (status ~= 0)
error('Error seeking file.');
end
%returns the byte order. 0 = forward, 1 = reverse, -1 = wrong syntax
function order = getOrder(fp)
seek(fp, 0);
magicNum = fread(fp, 4, '*char');
byteFor = ['S', 'D', 'P', 'X']';
byteRev = ['X', 'P', 'D', 'S']';
if isequal(magicNum, byteFor)
order = 0;
elseif isequal(magicNum, byteRev)
order = 1;
else
order = -1;
end
% gets file information
function value = getInfo(fp, offset, length, type, order)
seek(fp, offset);
if (strcmp(type,'U8'))
count = length;
if (order)
value = uint8(fread(fp, count, 'uint8', 0, 'l'));
else
value = uint8(fread(fp, count, 'uint8', 0, 'b'));
end
elseif (strcmp(type,'U16'))
count = length/2;
if (order)
value = uint16(fread(fp, count, 'uint16', 0, 'l'));
else
value = uint16(fread(fp, count, 'uint16', 0, 'b'));
end
elseif (strcmp(type,'U32'))
count = length/4;
if (order)
value = uint32(fread(fp, count, 'uint32', 0 ,'l'));
else
value = uint32(fread(fp, count, 'uint32', 0, 'b'));
end
elseif (strcmp(type,'R32'))
count = length/4;
if (order)
value = int32(fread(fp, count, 'int32', 0, 'l'));
else
value = int32(fread(fp, count, 'int32', 0, 'b'));
end
elseif (strcmp(type,'ASCII'))
count = length;
if (order)
value = fliplr(char(fread(fp, count, '*char')'));
else
value = char(fread(fp, count, '*char')');
end
else
error('Not a known type');
end