1 /*
2 * JPEG 2000 encoding support via OpenJPEG
3 * Copyright (c) 2011 Michael Bradshaw <mjbshaw gmail com>
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
22 /**
23 * @file
24 * JPEG 2000 encoder using libopenjpeg
25 */
26
28
36
37 #if HAVE_OPENJPEG_1_5_OPENJPEG_H
38 # include <openjpeg-1.5/openjpeg.h>
39 #else
40 # include <openjpeg.h>
41 #endif
42
43 typedef struct {
60
62 {
64 }
65
67 {
69 }
70
72 {
74 }
75
77 {
79 opj_image_cmptparm_t cmptparm[4] = {{0}};
81 int i;
82 int sub_dx[4];
83 int sub_dy[4];
84 int numcomps;
85 OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN;
86
87 sub_dx[0] = sub_dx[3] = 1;
88 sub_dy[0] = sub_dy[3] = 1;
91
93
98 color_space = CLRSPC_GRAY;
99 break;
111 color_space = CLRSPC_SRGB;
112 break;
146 color_space = CLRSPC_SYCC;
147 break;
148 default:
150 "The requested pixel format '%s' is not supported\n",
152 return NULL;
153 }
154
155 for (i = 0; i < numcomps; i++) {
158 cmptparm[i].sgnd = 0;
159 cmptparm[i].dx = sub_dx[i];
160 cmptparm[i].dy = sub_dy[i];
161 cmptparm[i].w = (avctx->
width + sub_dx[i] - 1) / sub_dx[i];
162 cmptparm[i].h = (avctx->
height + sub_dy[i] - 1) / sub_dy[i];
163 }
164
165 img = opj_image_create(numcomps, cmptparm, color_space);
166
167 // x0, y0 is the top left corner of the image
168 // x1, y1 is the width, height of the reference grid
169 img->x0 = 0;
170 img->y0 = 0;
171 img->x1 = (avctx->
width - 1) * parameters->subsampling_dx + 1;
172 img->y1 = (avctx->
height - 1) * parameters->subsampling_dy + 1;
173
175 }
176
178 {
181
182 opj_set_default_encoder_parameters(&ctx->
enc_params);
183
194
199 /* no subsampling */
204 /* Tile and Image shall be at (0,0) */
209 /* Codeblock size= 32*32 */
213 /* No ROI */
215
219 }
222 }
223
228 }
229
234 goto fail;
235 }
237
238 ctx->
stream = opj_cio_open((opj_common_ptr)ctx->
compress, NULL, 0);
242 goto fail;
243 }
244
248 goto fail;
249 }
250
251 memset(&ctx->
event_mgr, 0,
sizeof(opj_event_mgr_t));
256
257 return 0;
258
259 fail:
260 opj_cio_close(ctx->
stream);
262 opj_destroy_compress(ctx->
compress);
264 opj_image_destroy(ctx->
image);
267 return err;
268 }
269
271 {
272 int compno;
273 int x;
275 int *image_line;
276 int frame_index;
277 const int numcomps = image->numcomps;
278
279 for (compno = 0; compno < numcomps; ++compno) {
280 if (image->comps[compno].w > frame->
linesize[0] / numcomps) {
282 return 0;
283 }
284 }
285
286 for (compno = 0; compno < numcomps; ++compno) {
287 for (y = 0; y < avctx->
height; ++
y) {
288 image_line = image->comps[compno].data + y * image->comps[compno].w;
289 frame_index = y * frame->
linesize[0] + compno;
290 for (x = 0; x < avctx->
width; ++x) {
291 image_line[x] = frame->
data[0][frame_index];
292 frame_index += numcomps;
293 }
294 for (; x < image->comps[compno].w; ++x) {
295 image_line[x] = image_line[x - 1];
296 }
297 }
298 for (; y < image->comps[compno].h; ++
y) {
299 image_line = image->comps[compno].data + y * image->comps[compno].w;
300 for (x = 0; x < image->comps[compno].w; ++x) {
301 image_line[x] = image_line[x - image->comps[compno].w];
302 }
303 }
304 }
305
306 return 1;
307 }
308
309 // for XYZ 12 bit
311 {
312 int compno;
313 int x;
315 int *image_line;
316 int frame_index;
317 const int numcomps = image->numcomps;
318 uint16_t *frame_ptr = (uint16_t*)frame->
data[0];
319
320 for (compno = 0; compno < numcomps; ++compno) {
321 if (image->comps[compno].w > frame->
linesize[0] / numcomps) {
323 return 0;
324 }
325 }
326
327 for (compno = 0; compno < numcomps; ++compno) {
328 for (y = 0; y < avctx->
height; ++
y) {
329 image_line = image->comps[compno].data + y * image->comps[compno].w;
330 frame_index = y * (frame->
linesize[0] / 2) + compno;
331 for (x = 0; x < avctx->
width; ++x) {
332 image_line[x] = frame_ptr[frame_index] >> 4;
333 frame_index += numcomps;
334 }
335 for (; x < image->comps[compno].w; ++x) {
336 image_line[x] = image_line[x - 1];
337 }
338 }
339 for (; y < image->comps[compno].h; ++
y) {
340 image_line = image->comps[compno].data + y * image->comps[compno].w;
341 for (x = 0; x < image->comps[compno].w; ++x) {
342 image_line[x] = image_line[x - image->comps[compno].w];
343 }
344 }
345 }
346
347 return 1;
348 }
349
351 {
352 int compno;
353 int x;
355 int *image_line;
356 int frame_index;
357 const int numcomps = image->numcomps;
358 uint16_t *frame_ptr = (uint16_t*)frame->
data[0];
359
360 for (compno = 0; compno < numcomps; ++compno) {
361 if (image->comps[compno].w > frame->
linesize[0] / numcomps) {
363 return 0;
364 }
365 }
366
367 for (compno = 0; compno < numcomps; ++compno) {
368 for (y = 0; y < avctx->
height; ++
y) {
369 image_line = image->comps[compno].data + y * image->comps[compno].w;
370 frame_index = y * (frame->
linesize[0] / 2) + compno;
371 for (x = 0; x < avctx->
width; ++x) {
372 image_line[x] = frame_ptr[frame_index];
373 frame_index += numcomps;
374 }
375 for (; x < image->comps[compno].w; ++x) {
376 image_line[x] = image_line[x - 1];
377 }
378 }
379 for (; y < image->comps[compno].h; ++
y) {
380 image_line = image->comps[compno].data + y * image->comps[compno].w;
381 for (x = 0; x < image->comps[compno].w; ++x) {
382 image_line[x] = image_line[x - image->comps[compno].w];
383 }
384 }
385 }
386
387 return 1;
388 }
389
391 {
392 int compno;
393 int x;
397 int *image_line;
398 int frame_index;
399 const int numcomps = image->numcomps;
400
401 for (compno = 0; compno < numcomps; ++compno) {
402 if (image->comps[compno].w > frame->
linesize[compno]) {
404 return 0;
405 }
406 }
407
408 for (compno = 0; compno < numcomps; ++compno) {
409 width = avctx->
width / image->comps[compno].dx;
410 height = avctx->
height / image->comps[compno].dy;
412 image_line = image->comps[compno].data + y * image->comps[compno].w;
413 frame_index = y * frame->
linesize[compno];
414 for (x = 0; x <
width; ++x)
415 image_line[x] = frame->
data[compno][frame_index++];
416 for (; x < image->comps[compno].w; ++x) {
417 image_line[x] = image_line[x - 1];
418 }
419 }
420 for (; y < image->comps[compno].h; ++
y) {
421 image_line = image->comps[compno].data + y * image->comps[compno].w;
422 for (x = 0; x < image->comps[compno].w; ++x) {
423 image_line[x] = image_line[x - image->comps[compno].w];
424 }
425 }
426 }
427
428 return 1;
429 }
430
432 {
433 int compno;
434 int x;
438 int *image_line;
439 int frame_index;
440 const int numcomps = image->numcomps;
441 uint16_t *frame_ptr;
442
443 for (compno = 0; compno < numcomps; ++compno) {
444 if (image->comps[compno].w > frame->
linesize[compno]) {
446 return 0;
447 }
448 }
449
450 for (compno = 0; compno < numcomps; ++compno) {
451 width = avctx->
width / image->comps[compno].dx;
452 height = avctx->
height / image->comps[compno].dy;
453 frame_ptr = (uint16_t*)frame->
data[compno];
455 image_line = image->comps[compno].data + y * image->comps[compno].w;
456 frame_index = y * (frame->
linesize[compno] / 2);
457 for (x = 0; x <
width; ++x)
458 image_line[x] = frame_ptr[frame_index++];
459 for (; x < image->comps[compno].w; ++x) {
460 image_line[x] = image_line[x - 1];
461 }
462 }
463 for (; y < image->comps[compno].h; ++
y) {
464 image_line = image->comps[compno].data + y * image->comps[compno].w;
465 for (x = 0; x < image->comps[compno].w; ++x) {
466 image_line[x] = image_line[x - image->comps[compno].w];
467 }
468 }
469 }
470
471 return 1;
472 }
473
476 {
478 opj_cinfo_t *compress = ctx->
compress;
479 opj_image_t *image = ctx->
image;
480 opj_cio_t *stream = ctx->
stream;
481 int cpyresult = 0;
484
490 break;
493 break;
497 break;
505 if (!gbrframe)
508 gbrframe->
data[0] = frame->
data[2];
// swap to be rgb
516 } else {
518 }
520 break;
532 break;
559 break;
560 default:
562 "The frame's pixel format '%s' is not supported\n",
565 break;
566 }
567
568 if (!cpyresult) {
570 "Could not copy the frame data to the internal image buffer\n");
571 return -1;
572 }
573
574 cio_seek(stream, 0);
575 if (!opj_encode(compress, stream, image, NULL)) {
577 return -1;
578 }
579
580 len = cio_tell(stream);
583 }
584
585 memcpy(pkt->
data, stream->buffer, len);
587 *got_packet = 1;
588 return 0;
589 }
590
592 {
594
595 opj_cio_close(ctx->
stream);
597 opj_destroy_compress(ctx->
compress);
599 opj_image_destroy(ctx->
image);
602 return 0;
603 }
604
605 #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
606 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
608 {
"format",
"Codec Format",
OFFSET(format),
AV_OPT_TYPE_INT, { .i64 = CODEC_JP2 }, CODEC_J2K, CODEC_JP2,
VE,
"format" },
615 {
"cinema_mode",
"Digital Cinema",
OFFSET(cinema_mode),
AV_OPT_TYPE_INT, { .i64 = OFF }, OFF, CINEMA4K_24,
VE,
"cinema_mode" },
620 {
"prog_order",
"Progression Order",
OFFSET(prog_order),
AV_OPT_TYPE_INT, { .i64 = LRCP }, LRCP, CPRL,
VE,
"prog_order" },
631 { NULL },
632 };
633
639 };
640
642 .
name =
"libopenjpeg",
650 .capabilities = 0,
669 },
671 };