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
92
94 {
96
98
104 break;
109 break;
114 break;
115 default:
117 }
118
119 switch (
s->compression) {
123 s->scanline_height = 1;
124 s->nb_scanlines = avctx->
height;
125 break;
127 s->scanline_height = 16;
128 s->nb_scanlines = (avctx->
height +
s->scanline_height - 1) /
s->scanline_height;
129 break;
130 default:
132 }
133
134 s->scanline =
av_calloc(
s->nb_scanlines,
sizeof(*
s->scanline));
137
138 return 0;
139 }
140
142 {
144
145 for (
int y = 0; y <
s->nb_scanlines &&
s->scanline; y++) {
147
151 }
152
154
155 return 0;
156 }
157
159 {
160 const ptrdiff_t half_size = (
size + 1) / 2;
162 uint8_t *
t2 = dst + half_size;
163
164 for (ptrdiff_t
i = 0;
i < half_size;
i++) {
167 }
168 }
169
171 {
173
174 for (ptrdiff_t
i = 1;
i <
size;
i++) {
175 int d =
src[
i] - p + 384;
176
179 }
180 }
181
183 const uint8_t *in,
int64_t in_size)
184 {
186
187 while (
i < in_size) {
188 while (
i +
run < in_size && in[
i] == in[
i +
run] &&
run < 128)
190
193 return -1;
197 } else {
198 if (
i +
run < in_size)
202
204 return -1;
206
207 for (
int x = 0; x <
copy; x++)
208 out[o + x] = in[
i + x];
209
213 }
214
216 }
217
218 return o;
219 }
220
222 {
224
228 int64_t max_compressed_size = tmp_size * 3 / 2;
229
233
237
241
242 switch (
s->pixel_type) {
244 for (
int p = 0; p <
s->planes; p++) {
245 int ch =
s->ch_order[p];
246
249 }
250 break;
252 for (
int p = 0; p <
s->planes; p++) {
253 int ch =
s->ch_order[p];
256
259 }
260 break;
261 }
262
266 max_compressed_size,
267 scanline->
tmp, tmp_size);
268
273 }
274 }
275
276 return 0;
277 }
278
280 {
282
283 for (
int y = 0; y <
s->nb_scanlines; y++) {
285 const int scanline_height =
FFMIN(
s->scanline_height,
frame->
height - y *
s->scanline_height);
287 int64_t max_compressed_size = tmp_size * 3 / 2;
288 unsigned long actual_size, source_size;
289
293
297
301
302 switch (
s->pixel_type) {
304 for (int l = 0; l < scanline_height; l++) {
305 const int scanline_size =
frame->
width * 4 *
s->planes;
306
307 for (
int p = 0; p <
s->planes; p++) {
308 int ch =
s->ch_order[p];
309
313 }
314 }
315 break;
317 for (int l = 0; l < scanline_height; l++) {
318 const int scanline_size =
frame->
width * 2 *
s->planes;
319
320 for (
int p = 0; p <
s->planes; p++) {
321 int ch =
s->ch_order[p];
324
327 }
328 }
329 break;
330 }
331
334 source_size = tmp_size;
335 actual_size = max_compressed_size;
337 scanline->
tmp, source_size);
338
344 }
345 }
346
347 return 0;
348 }
349
352 {
360 avctx->
height, 64) * 3LL / 2;
361
364
366
367 bytestream2_put_le32(pb, 20000630);
368 bytestream2_put_byte(pb, 2);
369 bytestream2_put_le24(pb, 0);
371 bytestream2_put_le32(pb,
s->planes * 18 + 1);
372
373 for (
int p = 0; p <
s->planes; p++) {
374 bytestream2_put_byte(pb,
s->ch_names[p]);
375 bytestream2_put_byte(pb, 0);
376 bytestream2_put_le32(pb,
s->pixel_type);
377 bytestream2_put_le32(pb, 0);
378 bytestream2_put_le32(pb, 1);
379 bytestream2_put_le32(pb, 1);
380 }
381 bytestream2_put_byte(pb, 0);
382
384 bytestream2_put_le32(pb, 1);
385 bytestream2_put_byte(pb,
s->compression);
386
388 bytestream2_put_le32(pb, 16);
389 bytestream2_put_le32(pb, 0);
390 bytestream2_put_le32(pb, 0);
391 bytestream2_put_le32(pb, avctx->
width - 1);
392 bytestream2_put_le32(pb, avctx->
height - 1);
393
395 bytestream2_put_le32(pb, 16);
396 bytestream2_put_le32(pb, 0);
397 bytestream2_put_le32(pb, 0);
398 bytestream2_put_le32(pb, avctx->
width - 1);
399 bytestream2_put_le32(pb, avctx->
height - 1);
400
402 bytestream2_put_le32(pb, 1);
403 bytestream2_put_byte(pb, 0);
404
406 bytestream2_put_le32(pb, 8);
407 bytestream2_put_le64(pb, 0);
408
410 bytestream2_put_le32(pb, 4);
412
415 bytestream2_put_le32(pb, 4);
417 }
418
421 bytestream2_put_le32(pb, 8);
424 }
425
427 bytestream2_put_le32(pb, 4);
429
431 bytestream2_put_le32(pb, 4);
433 bytestream2_put_byte(pb, 0);
434
435 switch (
s->compression) {
437 /* nothing to do */
438 break;
441 break;
445 break;
446 default:
448 }
449
450 switch (
s->compression) {
453
455
456 for (
int y = 0; y < avctx->
height; y++) {
457 bytestream2_put_le64(pb,
offset);
459 }
460
461 for (
int y = 0; y < avctx->
height; y++) {
462 bytestream2_put_le32(pb, y);
463 bytestream2_put_le32(pb,
s->planes * avctx->
width * 4);
464 for (
int p = 0; p <
s->planes; p++) {
465 int ch =
s->ch_order[p];
468 }
469 }
470 } else {
471 for (
int y = 0; y < avctx->
height; y++) {
472 bytestream2_put_le64(pb,
offset);
474 }
475
476 for (
int y = 0; y < avctx->
height; y++) {
477 bytestream2_put_le32(pb, y);
478 bytestream2_put_le32(pb,
s->planes * avctx->
width * 2);
479 for (
int p = 0; p <
s->planes; p++) {
480 int ch =
s->ch_order[p];
482
485 }
486 }
487 }
488 break;
493
494 for (
int y = 0; y <
s->nb_scanlines; y++) {
496
497 bytestream2_put_le64(pb,
offset);
499 }
500
501 for (
int y = 0; y <
s->nb_scanlines; y++) {
503
504 bytestream2_put_le32(pb, y *
s->scanline_height);
508 }
509 break;
510 default:
512 }
513
515
516 *got_packet = 1;
517
518 return 0;
519 }
520
521 #define OFFSET(x) offsetof(EXRContext, x)
522 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
534 };
535
541 };
542
560 };