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 {
59
61 {
63 }
64
66 {
68 }
69
71 {
73 }
74
76 {
78 opj_image_cmptparm_t *cmptparm;
80 int i;
81 int sub_dx[4];
82 int sub_dy[4];
83 int numcomps;
84 OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN;
85
86 sub_dx[0] = sub_dx[3] = 1;
87 sub_dy[0] = sub_dy[3] = 1;
90
92
97 color_space = CLRSPC_GRAY;
98 break;
103 color_space = CLRSPC_SRGB;
104 break;
138 color_space = CLRSPC_SYCC;
139 break;
140 default:
142 "The requested pixel format '%s' is not supported\n",
145 }
146
147 cmptparm =
av_mallocz(numcomps *
sizeof(*cmptparm));
148 if (!cmptparm) {
151 }
152 for (i = 0; i < numcomps; i++) {
155 cmptparm[i].sgnd = 0;
156 cmptparm[i].dx = sub_dx[i];
157 cmptparm[i].dy = sub_dy[i];
158 cmptparm[i].w = avctx->
width / sub_dx[i];
159 cmptparm[i].h = avctx->
height / sub_dy[i];
160 }
161
162 img = opj_image_create(numcomps, cmptparm, color_space);
165 }
166
168 {
171
172 opj_set_default_encoder_parameters(&ctx->
enc_params);
173
184
189 }
190
194 goto fail;
195 }
196
201 goto fail;
202 }
203
204 memset(&ctx->
event_mgr, 0,
sizeof(opj_event_mgr_t));
209
210 return 0;
211
212 fail:
215 return err;
216 }
217
219 {
220 int compno;
221 int x;
222 int y;
223 int image_index;
224 int frame_index;
225 const int numcomps = image->numcomps;
226
227 for (compno = 0; compno < numcomps; ++compno) {
228 if (image->comps[compno].w > frame->
linesize[0] / numcomps) {
230 return 0;
231 }
232 }
233
234 for (compno = 0; compno < numcomps; ++compno) {
235 for (y = 0; y < avctx->
height; ++y) {
236 image_index = y * avctx->
width;
237 frame_index = y * frame->
linesize[0] + compno;
238 for (x = 0; x < avctx->
width; ++x) {
239 image->comps[compno].data[image_index++] = frame->
data[0][frame_index];
240 frame_index += numcomps;
241 }
242 }
243 }
244
245 return 1;
246 }
247
249 {
250 int compno;
251 int x;
252 int y;
253 int image_index;
254 int frame_index;
255 const int numcomps = image->numcomps;
256 uint16_t *frame_ptr = (uint16_t*)frame->
data[0];
257
258 for (compno = 0; compno < numcomps; ++compno) {
259 if (image->comps[compno].w > frame->
linesize[0] / numcomps) {
261 return 0;
262 }
263 }
264
265 for (compno = 0; compno < numcomps; ++compno) {
266 for (y = 0; y < avctx->
height; ++y) {
267 image_index = y * avctx->
width;
268 frame_index = y * (frame->
linesize[0] / 2) + compno;
269 for (x = 0; x < avctx->
width; ++x) {
270 image->comps[compno].data[image_index++] = frame_ptr[frame_index];
271 frame_index += numcomps;
272 }
273 }
274 }
275
276 return 1;
277 }
278
280 {
281 int compno;
282 int x;
283 int y;
286 int image_index;
287 int frame_index;
288 const int numcomps = image->numcomps;
289
290 for (compno = 0; compno < numcomps; ++compno) {
291 if (image->comps[compno].w > frame->
linesize[compno]) {
293 return 0;
294 }
295 }
296
297 for (compno = 0; compno < numcomps; ++compno) {
298 width = avctx->
width / image->comps[compno].dx;
299 height = avctx->
height / image->comps[compno].dy;
300 for (y = 0; y <
height; ++y) {
301 image_index = y *
width;
302 frame_index = y * frame->
linesize[compno];
303 for (x = 0; x <
width; ++x)
304 image->comps[compno].data[image_index++] = frame->
data[compno][frame_index++];
305 }
306 }
307
308 return 1;
309 }
310
312 {
313 int compno;
314 int x;
315 int y;
318 int image_index;
319 int frame_index;
320 const int numcomps = image->numcomps;
321 uint16_t *frame_ptr;
322
323 for (compno = 0; compno < numcomps; ++compno) {
324 if (image->comps[compno].w > frame->
linesize[compno]) {
326 return 0;
327 }
328 }
329
330 for (compno = 0; compno < numcomps; ++compno) {
331 width = avctx->
width / image->comps[compno].dx;
332 height = avctx->
height / image->comps[compno].dy;
333 frame_ptr = (uint16_t*)frame->
data[compno];
335 image_index = y *
width;
336 frame_index = y * (frame->
linesize[compno] / 2);
337 for (x = 0; x <
width; ++x)
338 image->comps[compno].data[image_index++] = frame_ptr[frame_index++];
339 }
340 }
341
342 return 1;
343 }
344
347 {
349 opj_cinfo_t *compress = ctx->
compress;
350 opj_image_t *image = ctx->
image;
351 opj_cio_t *stream;
352 int cpyresult = 0;
354
355 // x0, y0 is the top left corner of the image
356 // x1, y1 is the width, height of the reference grid
357 image->x0 = 0;
358 image->y0 = 0;
361
367 break;
371 break;
383 break;
410 break;
411 default:
413 "The frame's pixel format '%s' is not supported\n",
416 break;
417 }
418
419 if (!cpyresult) {
421 "Could not copy the frame data to the internal image buffer\n");
422 return -1;
423 }
424
425 opj_setup_encoder(compress, &ctx->
enc_params, image);
426 stream = opj_cio_open((opj_common_ptr)compress,
NULL, 0);
427 if (!stream) {
430 }
431
432 if (!opj_encode(compress, stream, image,
NULL)) {
433 opj_cio_close(stream);
435 return -1;
436 }
437
438 len = cio_tell(stream);
440 opj_cio_close(stream);
441 return ret;
442 }
443
444 memcpy(pkt->
data, stream->buffer, len);
446 *got_packet = 1;
447 opj_cio_close(stream);
448 return 0;
449 }
450
452 {
454
455 opj_destroy_compress(ctx->
compress);
456 opj_image_destroy(ctx->
image);
458 return 0;
459 }
460
461 #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
462 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
464 {
"format",
"Codec Format",
OFFSET(format),
AV_OPT_TYPE_INT, { .i64 = CODEC_JP2 }, CODEC_J2K, CODEC_JP2,
VE,
"format" },
471 {
"cinema_mode",
"Digital Cinema",
OFFSET(cinema_mode),
AV_OPT_TYPE_INT, { .i64 = OFF }, OFF, CINEMA4K_24,
VE,
"cinema_mode" },
476 {
"prog_order",
"Progression Order",
OFFSET(prog_order),
AV_OPT_TYPE_INT, { .i64 = LRCP }, LRCP, CPRL,
VE,
"prog_order" },
488 };
489
495 };
496
498 .
name =
"libopenjpeg",
505 .capabilities = 0,
521 },
523 .priv_class = &class,
524 };