1 /*
2 * Copyright (c) 2021 Paul B Mahol
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * OpenEXR encoder
24 */
25
27 #include <zlib.h>
28
39
46 };
47
53 };
54
56 static const char bgr_chlist[4] = {
'B',
'G',
'R',
'A' };
61
65
68
71
74
77
87
89
93
95 {
97
99
105 break;
110 break;
115 break;
116 default:
118 }
119
120 switch (
s->compression) {
124 s->scanline_height = 1;
125 s->nb_scanlines = avctx->
height;
126 break;
128 s->scanline_height = 16;
129 s->nb_scanlines = (avctx->
height +
s->scanline_height - 1) /
s->scanline_height;
130 break;
131 default:
133 }
134
135 s->scanline =
av_calloc(
s->nb_scanlines,
sizeof(*
s->scanline));
138
139 return 0;
140 }
141
143 {
145
146 for (
int y = 0; y <
s->nb_scanlines &&
s->scanline; y++) {
148
152 }
153
155
156 return 0;
157 }
158
160 {
161 const ptrdiff_t half_size = (
size + 1) / 2;
163 uint8_t *
t2 = dst + half_size;
164
165 for (ptrdiff_t
i = 0;
i < half_size;
i++) {
168 }
169 }
170
172 {
174
175 for (ptrdiff_t
i = 1;
i <
size;
i++) {
176 int d =
src[
i] - p + 384;
177
180 }
181 }
182
184 const uint8_t *in, int64_t in_size)
185 {
186 int64_t
i = 0, o = 0,
run = 1,
copy = 0;
187
188 while (
i < in_size) {
189 while (
i +
run < in_size && in[
i] == in[
i +
run] &&
run < 128)
191
194 return -1;
198 } else {
199 if (
i +
run < in_size)
203
205 return -1;
207
208 for (
int x = 0; x <
copy; x++)
209 out[o + x] = in[
i + x];
210
214 }
215
217 }
218
219 return o;
220 }
221
223 {
224 const int64_t element_size =
s->pixel_type ==
EXR_HALF ? 2LL : 4LL;
225
226 for (
int y = 0; y <
frame->height; y++) {
228 int64_t tmp_size = element_size *
s->planes *
frame->width;
229 int64_t max_compressed_size = tmp_size * 3 / 2;
230
234
238
242
243 switch (
s->pixel_type) {
245 for (
int p = 0; p <
s->planes; p++) {
246 int ch =
s->ch_order[p];
247
250 }
251 break;
253 for (
int p = 0; p <
s->planes; p++) {
254 int ch =
s->ch_order[p];
256 uint32_t *
src = (uint32_t *)(
frame->data[ch] + y *
frame->linesize[ch]);
257
258 for (
int x = 0; x <
frame->width; x++)
260 }
261 break;
262 }
263
267 max_compressed_size,
268 scanline->
tmp, tmp_size);
269
274 }
275 }
276
277 return 0;
278 }
279
281 {
282 const int64_t element_size =
s->pixel_type ==
EXR_HALF ? 2LL : 4LL;
283
284 for (
int y = 0; y <
s->nb_scanlines; y++) {
286 const int scanline_height =
FFMIN(
s->scanline_height,
frame->height - y *
s->scanline_height);
287 int64_t tmp_size = element_size *
s->planes *
frame->width * scanline_height;
288 int64_t max_compressed_size = tmp_size * 3 / 2;
289 unsigned long actual_size, source_size;
290
294
298
302
303 switch (
s->pixel_type) {
305 for (int l = 0; l < scanline_height; l++) {
306 const int scanline_size =
frame->width * 4 *
s->planes;
307
308 for (
int p = 0; p <
s->planes; p++) {
309 int ch =
s->ch_order[p];
310
312 frame->data[ch] + (y *
s->scanline_height + l) *
frame->linesize[ch],
314 }
315 }
316 break;
318 for (int l = 0; l < scanline_height; l++) {
319 const int scanline_size =
frame->width * 2 *
s->planes;
320
321 for (
int p = 0; p <
s->planes; p++) {
322 int ch =
s->ch_order[p];
324 uint32_t *
src = (uint32_t *)(
frame->data[ch] + (y *
s->scanline_height + l) *
frame->linesize[ch]);
325
326 for (
int x = 0; x <
frame->width; x++)
328 }
329 }
330 break;
331 }
332
335 source_size = tmp_size;
336 actual_size = max_compressed_size;
338 scanline->
tmp, source_size);
339
345 }
346 }
347
348 return 0;
349 }
350
353 {
361 avctx->
height, 64) * 3LL / 2;
362
365
367
368 bytestream2_put_le32(pb, 20000630);
369 bytestream2_put_byte(pb, 2);
370 bytestream2_put_le24(pb, 0);
372 bytestream2_put_le32(pb,
s->planes * 18 + 1);
373
374 for (
int p = 0; p <
s->planes; p++) {
375 bytestream2_put_byte(pb,
s->ch_names[p]);
376 bytestream2_put_byte(pb, 0);
377 bytestream2_put_le32(pb,
s->pixel_type);
378 bytestream2_put_le32(pb, 0);
379 bytestream2_put_le32(pb, 1);
380 bytestream2_put_le32(pb, 1);
381 }
382 bytestream2_put_byte(pb, 0);
383
385 bytestream2_put_le32(pb, 1);
386 bytestream2_put_byte(pb,
s->compression);
387
389 bytestream2_put_le32(pb, 16);
390 bytestream2_put_le32(pb, 0);
391 bytestream2_put_le32(pb, 0);
392 bytestream2_put_le32(pb, avctx->
width - 1);
393 bytestream2_put_le32(pb, avctx->
height - 1);
394
396 bytestream2_put_le32(pb, 16);
397 bytestream2_put_le32(pb, 0);
398 bytestream2_put_le32(pb, 0);
399 bytestream2_put_le32(pb, avctx->
width - 1);
400 bytestream2_put_le32(pb, avctx->
height - 1);
401
403 bytestream2_put_le32(pb, 1);
404 bytestream2_put_byte(pb, 0);
405
407 bytestream2_put_le32(pb, 8);
408 bytestream2_put_le64(pb, 0);
409
411 bytestream2_put_le32(pb, 4);
413
416 bytestream2_put_le32(pb, 4);
418 }
419
422 bytestream2_put_le32(pb, 8);
425 }
426
428 bytestream2_put_le32(pb, 4);
430
432 bytestream2_put_le32(pb, 4);
434 bytestream2_put_byte(pb, 0);
435
436 switch (
s->compression) {
438 /* nothing to do */
439 break;
442 break;
446 break;
447 default:
449 }
450
451 switch (
s->compression) {
454
456
457 for (
int y = 0; y < avctx->
height; y++) {
458 bytestream2_put_le64(pb,
offset);
460 }
461
462 for (
int y = 0; y < avctx->
height; y++) {
463 bytestream2_put_le32(pb, y);
464 bytestream2_put_le32(pb,
s->planes * avctx->
width * 4);
465 for (
int p = 0; p <
s->planes; p++) {
466 int ch =
s->ch_order[p];
469 }
470 }
471 } else {
472 for (
int y = 0; y < avctx->
height; y++) {
473 bytestream2_put_le64(pb,
offset);
475 }
476
477 for (
int y = 0; y < avctx->
height; y++) {
478 bytestream2_put_le32(pb, y);
479 bytestream2_put_le32(pb,
s->planes * avctx->
width * 2);
480 for (
int p = 0; p <
s->planes; p++) {
481 int ch =
s->ch_order[p];
482 uint32_t *
src = (uint32_t *)(
frame->data[ch] + y *
frame->linesize[ch]);
483
484 for (
int x = 0; x <
frame->width; x++)
485 bytestream2_put_le16(pb,
float2half(
src[x],
s->basetable,
s->shifttable));
486 }
487 }
488 }
489 break;
494
495 for (
int y = 0; y <
s->nb_scanlines; y++) {
497
498 bytestream2_put_le64(pb,
offset);
500 }
501
502 for (
int y = 0; y <
s->nb_scanlines; y++) {
504
505 bytestream2_put_le32(pb, y *
s->scanline_height);
509 }
510 break;
511 default:
513 }
514
516
517 *got_packet = 1;
518
519 return 0;
520 }
521
522 #define OFFSET(x) offsetof(EXRContext, x)
523 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
535 };
536
542 };
543
561 };