1 /*
2 * DPX (.dpx) image decoder
3 * Copyright (c) 2009 Jimmy Christensen
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
27
29 {
31 if (is_big) {
33 } else {
35 }
36 *ptr += 4;
38 }
39
41 int * n_datum, int is_big)
42 {
43 if (*n_datum)
44 (*n_datum)--;
45 else {
46 *lbuf =
read32(ptr, is_big);
47 *n_datum = 2;
48 }
49
50 *lbuf = (*lbuf << 10) | (*lbuf >> 22);
51
52 return *lbuf & 0x3FF;
53 }
54
57 int *got_frame,
59 {
61 int buf_size = avpkt->
size;
64
66 int magic_num, endian;
68 int w, h, bits_per_color, descriptor, elements, packing, total_size;
69
70 unsigned int rgbBuffer = 0;
71 int n_datum = 0;
72
73 if (avpkt->
size <= 1634) {
76 }
77
79 buf += 4;
80
81 /* Check if the files "magic number" is "SDPX" which means it uses
82 * big-endian or XPDS which is for little-endian files */
83 if (magic_num ==
AV_RL32(
"SDPX")) {
84 endian = 0;
85 }
else if (magic_num ==
AV_RB32(
"SDPX")) {
86 endian = 1;
87 } else {
90 }
91
92 offset =
read32(&buf, endian);
93 if (avpkt->
size <= offset) {
96 }
97 // Need to end in 0x304 offset from start of file
98 buf = avpkt->
data + 0x304;
103
106
107 // Need to end in 0x320 to read the descriptor
108 buf += 20;
109 descriptor = buf[0];
110
111 // Need to end in 0x323 to read the bits per color
112 buf += 3;
114 bits_per_color = buf[0];
115 buf++;
116 packing = *((uint16_t*)buf);
117
118 buf += 824;
124 0x10000);
125 else
127
128 switch (descriptor) {
129 case 51: // RGBA
130 elements = 4;
131 break;
132 case 50: // RGB
133 elements = 3;
134 break;
135 default:
138 }
139
140 switch (bits_per_color) {
141 case 8:
142 if (elements == 4) {
144 } else {
146 }
147 total_size = avctx->
width * avctx->
height * elements;
148 break;
149 case 10:
150 if (!packing) {
152 return -1;
153 }
155 total_size = (avctx->
width * elements + 2) / 3 * 4 * avctx->
height;
156 break;
157 case 12:
160 return -1;
161 }
162 if (endian) {
164 } else {
166 }
167 total_size = 2 * avctx->
width * avctx->
height * elements;
168 break;
169 case 16:
170 if (endian) {
172 } else {
174 }
175 total_size = 2 * avctx->
width * avctx->
height * elements;
176 break;
177 default:
180 }
181
184
185 // Move pointer to offset from start of file
187
190
191 if (total_size + (int64_t)offset > avpkt->
size) {
194 }
195 switch (bits_per_color) {
196 case 10:
197 for (x = 0; x < avctx->
height; x++) {
198 uint16_t *dst[3] = {(uint16_t*)ptr[0],
199 (uint16_t*)ptr[1],
200 (uint16_t*)ptr[2]};
201 for (y = 0; y < avctx->
width; y++) {
203 &n_datum, endian);
205 &n_datum, endian);
207 &n_datum, endian);
208 // For 10 bit, ignore alpha
209 if (elements == 4)
211 &n_datum, endian);
212 }
213 n_datum = 0;
214 for (i = 0; i < 3; i++)
216 }
217 break;
218 case 12:
219 for (x = 0; x < avctx->
height; x++) {
220 uint16_t *dst[3] = {(uint16_t*)ptr[0],
221 (uint16_t*)ptr[1],
222 (uint16_t*)ptr[2]};
223 for (y = 0; y < avctx->
width; y++) {
224 *dst[2] = *((uint16_t*)buf);
225 *dst[2] = (*dst[2] >> 4) | (*dst[2] << 12);
226 dst[2]++;
227 buf += 2;
228 *dst[0] = *((uint16_t*)buf);
229 *dst[0] = (*dst[0] >> 4) | (*dst[0] << 12);
230 dst[0]++;
231 buf += 2;
232 *dst[1] = *((uint16_t*)buf);
233 *dst[1] = (*dst[1] >> 4) | (*dst[1] << 12);
234 dst[1]++;
235 buf += 2;
236 // For 12 bit, ignore alpha
237 if (elements == 4)
238 buf += 2;
239 }
240 for (i = 0; i < 3; i++)
242 }
243 break;
244 case 16:
245 elements *= 2;
246 case 8:
247 for (x = 0; x < avctx->
height; x++) {
248 memcpy(ptr[0], buf, elements*avctx->
width);
250 buf += elements*avctx->
width;
251 }
252 break;
253 }
254
255 *got_frame = 1;
256
257 return buf_size;
258 }
259
267 };