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;
314 int *image_line;
315 int frame_index;
316 const int numcomps = image->numcomps;
317 uint16_t *frame_ptr = (uint16_t *)frame->
data[0];
318
319 for (compno = 0; compno < numcomps; ++compno) {
320 if (image->comps[compno].w > frame->
linesize[0] / numcomps) {
322 return 0;
323 }
324 }
325
326 for (compno = 0; compno < numcomps; ++compno) {
327 for (y = 0; y < avctx->
height; ++
y) {
328 image_line = image->comps[compno].data + y * image->comps[compno].w;
329 frame_index = y * (frame->
linesize[0] / 2) + compno;
330 for (x = 0; x < avctx->
width; ++x) {
331 image_line[x] = frame_ptr[frame_index] >> 4;
332 frame_index += numcomps;
333 }
334 for (; x < image->comps[compno].w; ++x) {
335 image_line[x] = image_line[x - 1];
336 }
337 }
338 for (; y < image->comps[compno].h; ++
y) {
339 image_line = image->comps[compno].data + y * image->comps[compno].w;
340 for (x = 0; x < image->comps[compno].w; ++x) {
341 image_line[x] = image_line[x - image->comps[compno].w];
342 }
343 }
344 }
345
346 return 1;
347 }
348
350 {
351 int compno;
352 int x;
354 int *image_line;
355 int frame_index;
356 const int numcomps = image->numcomps;
357 uint16_t *frame_ptr = (uint16_t*)frame->
data[0];
358
359 for (compno = 0; compno < numcomps; ++compno) {
360 if (image->comps[compno].w > frame->
linesize[0] / numcomps) {
362 return 0;
363 }
364 }
365
366 for (compno = 0; compno < numcomps; ++compno) {
367 for (y = 0; y < avctx->
height; ++
y) {
368 image_line = image->comps[compno].data + y * image->comps[compno].w;
369 frame_index = y * (frame->
linesize[0] / 2) + compno;
370 for (x = 0; x < avctx->
width; ++x) {
371 image_line[x] = frame_ptr[frame_index];
372 frame_index += numcomps;
373 }
374 for (; x < image->comps[compno].w; ++x) {
375 image_line[x] = image_line[x - 1];
376 }
377 }
378 for (; y < image->comps[compno].h; ++
y) {
379 image_line = image->comps[compno].data + y * image->comps[compno].w;
380 for (x = 0; x < image->comps[compno].w; ++x) {
381 image_line[x] = image_line[x - image->comps[compno].w];
382 }
383 }
384 }
385
386 return 1;
387 }
388
390 {
391 int compno;
392 int x;
396 int *image_line;
397 int frame_index;
398 const int numcomps = image->numcomps;
399
400 for (compno = 0; compno < numcomps; ++compno) {
401 if (image->comps[compno].w > frame->
linesize[compno]) {
403 return 0;
404 }
405 }
406
407 for (compno = 0; compno < numcomps; ++compno) {
408 width = avctx->
width / image->comps[compno].dx;
409 height = avctx->
height / image->comps[compno].dy;
411 image_line = image->comps[compno].data + y * image->comps[compno].w;
412 frame_index = y * frame->
linesize[compno];
413 for (x = 0; x <
width; ++x)
414 image_line[x] = frame->
data[compno][frame_index++];
415 for (; x < image->comps[compno].w; ++x) {
416 image_line[x] = image_line[x - 1];
417 }
418 }
419 for (; y < image->comps[compno].h; ++
y) {
420 image_line = image->comps[compno].data + y * image->comps[compno].w;
421 for (x = 0; x < image->comps[compno].w; ++x) {
422 image_line[x] = image_line[x - image->comps[compno].w];
423 }
424 }
425 }
426
427 return 1;
428 }
429
431 {
432 int compno;
433 int x;
437 int *image_line;
438 int frame_index;
439 const int numcomps = image->numcomps;
440 uint16_t *frame_ptr;
441
442 for (compno = 0; compno < numcomps; ++compno) {
443 if (image->comps[compno].w > frame->
linesize[compno]) {
445 return 0;
446 }
447 }
448
449 for (compno = 0; compno < numcomps; ++compno) {
450 width = avctx->
width / image->comps[compno].dx;
451 height = avctx->
height / image->comps[compno].dy;
452 frame_ptr = (uint16_t *)frame->
data[compno];
454 image_line = image->comps[compno].data + y * image->comps[compno].w;
455 frame_index = y * (frame->
linesize[compno] / 2);
456 for (x = 0; x <
width; ++x)
457 image_line[x] = frame_ptr[frame_index++];
458 for (; x < image->comps[compno].w; ++x) {
459 image_line[x] = image_line[x - 1];
460 }
461 }
462 for (; y < image->comps[compno].h; ++
y) {
463 image_line = image->comps[compno].data + y * image->comps[compno].w;
464 for (x = 0; x < image->comps[compno].w; ++x) {
465 image_line[x] = image_line[x - image->comps[compno].w];
466 }
467 }
468 }
469
470 return 1;
471 }
472
475 {
477 opj_cinfo_t *compress = ctx->
compress;
478 opj_image_t *image = ctx->
image;
479 opj_cio_t *stream = ctx->
stream;
480 int cpyresult = 0;
483
489 break;
492 break;
496 break;
504 if (!gbrframe)
506 gbrframe->
data[0] = frame->
data[2];
// swap to be rgb
514 } else {
516 }
518 break;
530 break;
557 break;
558 default:
560 "The frame's pixel format '%s' is not supported\n",
563 break;
564 }
565
566 if (!cpyresult) {
568 "Could not copy the frame data to the internal image buffer\n");
569 return -1;
570 }
571
572 cio_seek(stream, 0);
573 if (!opj_encode(compress, stream, image, NULL)) {
575 return -1;
576 }
577
578 len = cio_tell(stream);
581 }
582
583 memcpy(pkt->
data, stream->buffer, len);
585 *got_packet = 1;
586 return 0;
587 }
588
590 {
592
593 opj_cio_close(ctx->
stream);
595 opj_destroy_compress(ctx->
compress);
597 opj_image_destroy(ctx->
image);
600 return 0;
601 }
602
603 #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
604 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
606 {
"format",
"Codec Format",
OFFSET(format),
AV_OPT_TYPE_INT, { .i64 = CODEC_JP2 }, CODEC_J2K, CODEC_JP2,
VE,
"format" },
613 {
"cinema_mode",
"Digital Cinema",
OFFSET(cinema_mode),
AV_OPT_TYPE_INT, { .i64 = OFF }, OFF, CINEMA4K_24,
VE,
"cinema_mode" },
618 {
"prog_order",
"Progression Order",
OFFSET(prog_order),
AV_OPT_TYPE_INT, { .i64 = LRCP }, LRCP, CPRL,
VE,
"prog_order" },
629 { NULL },
630 };
631
637 };
638
640 .
name =
"libopenjpeg",
667 },
669 };