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
27#include "libavutil/common.h"
28#include "libavutil/imgutils.h"
29#include "libavutil/intreadwrite.h"
30#include "libavutil/opt.h"
31#include "avcodec.h"
32#include "codec_internal.h"
33#include "encode.h"
34#include <openjpeg.h>
35
36typedef struct LibOpenJPEGContext {
37    AVClass *avclass;
38    opj_cparameters_t enc_params;
39    int format;
40    int profile;
41    int prog_order;
42    int cinema_mode;
43    int numresolution;
44    int irreversible;
45    int disto_alloc;
46    int fixed_quality;
47} LibOpenJPEGContext;
48
49static void error_callback(const char *msg, void *data)
50{
51    av_log(data, AV_LOG_ERROR, "%s\n", msg);
52}
53
54static void warning_callback(const char *msg, void *data)
55{
56    av_log(data, AV_LOG_WARNING, "%s\n", msg);
57}
58
59static void info_callback(const char *msg, void *data)
60{
61    av_log(data, AV_LOG_DEBUG, "%s\n", msg);
62}
63
64typedef struct PacketWriter {
65    int pos;
66    AVPacket *packet;
67} PacketWriter;
68
69static OPJ_SIZE_T stream_write(void *out_buffer, OPJ_SIZE_T nb_bytes, void *user_data)
70{
71    PacketWriter *writer = user_data;
72    AVPacket *packet = writer->packet;
73    int remaining = packet->size - writer->pos;
74    if (nb_bytes > remaining) {
75        OPJ_SIZE_T needed = nb_bytes - remaining;
76        int max_growth = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - packet->size;
77        if (needed > max_growth) {
78            return (OPJ_SIZE_T)-1;
79        }
80        if (av_grow_packet(packet, (int)needed)) {
81            return (OPJ_SIZE_T)-1;
82        }
83    }
84    memcpy(packet->data + writer->pos, out_buffer, nb_bytes);
85    writer->pos += (int)nb_bytes;
86    return nb_bytes;
87}
88
89static OPJ_OFF_T stream_skip(OPJ_OFF_T nb_bytes, void *user_data)
90{
91    PacketWriter *writer = user_data;
92    AVPacket *packet = writer->packet;
93    if (nb_bytes < 0) {
94        if (writer->pos == 0) {
95            return (OPJ_SIZE_T)-1;
96        }
97        if (nb_bytes + writer->pos < 0) {
98            nb_bytes = -writer->pos;
99        }
100    } else {
101        int remaining = packet->size - writer->pos;
102        if (nb_bytes > remaining) {
103            OPJ_SIZE_T needed = nb_bytes - remaining;
104            int max_growth = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - packet->size;
105            if (needed > max_growth) {
106                return (OPJ_SIZE_T)-1;
107            }
108            if (av_grow_packet(packet, (int)needed)) {
109                return (OPJ_SIZE_T)-1;
110            }
111        }
112    }
113    writer->pos += (int)nb_bytes;
114    return nb_bytes;
115}
116
117static OPJ_BOOL stream_seek(OPJ_OFF_T nb_bytes, void *user_data)
118{
119    PacketWriter *writer = user_data;
120    AVPacket *packet = writer->packet;
121    if (nb_bytes < 0) {
122        return OPJ_FALSE;
123    }
124    if (nb_bytes > packet->size) {
125        if (nb_bytes > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
126            av_grow_packet(packet, (int)nb_bytes - packet->size)) {
127            return OPJ_FALSE;
128        }
129    }
130    writer->pos = (int)nb_bytes;
131    return OPJ_TRUE;
132}
133
134static void cinema_parameters(opj_cparameters_t *p)
135{
136    p->tile_size_on = 0;
137    p->cp_tdx = 1;
138    p->cp_tdy = 1;
139
140    /* Tile part */
141    p->tp_flag = 'C';
142    p->tp_on = 1;
143
144    /* Tile and Image shall be at (0, 0) */
145    p->cp_tx0 = 0;
146    p->cp_ty0 = 0;
147    p->image_offset_x0 = 0;
148    p->image_offset_y0 = 0;
149
150    /* Codeblock size= 32 * 32 */
151    p->cblockw_init = 32;
152    p->cblockh_init = 32;
153    p->csty |= 0x01;
154
155    /* The progression order shall be CPRL */
156    p->prog_order = OPJ_CPRL;
157
158    /* No ROI */
159    p->roi_compno = -1;
160
161    /* No subsampling */
162    p->subsampling_dx = 1;
163    p->subsampling_dy = 1;
164
165    /* 9-7 transform */
166    p->irreversible = 1;
167
168    p->tcp_mct = 1;
169}
170
171static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters)
172{
173    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
174    opj_image_cmptparm_t cmptparm[4] = {{0}};
175    opj_image_t *img;
176    int i;
177    int sub_dx[4];
178    int sub_dy[4];
179    int numcomps;
180    OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_UNKNOWN;
181
182    sub_dx[0] = sub_dx[3] = 1;
183    sub_dy[0] = sub_dy[3] = 1;
184    sub_dx[1] = sub_dx[2] = 1 << desc->log2_chroma_w;
185    sub_dy[1] = sub_dy[2] = 1 << desc->log2_chroma_h;
186
187    numcomps = desc->nb_components;
188
189    switch (avctx->pix_fmt) {
190    case AV_PIX_FMT_GRAY8:
191    case AV_PIX_FMT_YA8:
192    case AV_PIX_FMT_GRAY10:
193    case AV_PIX_FMT_GRAY12:
194    case AV_PIX_FMT_GRAY14:
195    case AV_PIX_FMT_GRAY16:
196    case AV_PIX_FMT_YA16:
197        color_space = OPJ_CLRSPC_GRAY;
198        break;
199    case AV_PIX_FMT_RGB24:
200    case AV_PIX_FMT_RGBA:
201    case AV_PIX_FMT_RGB48:
202    case AV_PIX_FMT_RGBA64:
203    case AV_PIX_FMT_GBR24P:
204    case AV_PIX_FMT_GBRP9:
205    case AV_PIX_FMT_GBRP10:
206    case AV_PIX_FMT_GBRP12:
207    case AV_PIX_FMT_GBRP14:
208    case AV_PIX_FMT_GBRP16:
209    case AV_PIX_FMT_XYZ12:
210        color_space = OPJ_CLRSPC_SRGB;
211        break;
212    case AV_PIX_FMT_YUV410P:
213    case AV_PIX_FMT_YUV411P:
214    case AV_PIX_FMT_YUV420P:
215    case AV_PIX_FMT_YUV422P:
216    case AV_PIX_FMT_YUV440P:
217    case AV_PIX_FMT_YUV444P:
218    case AV_PIX_FMT_YUVA420P:
219    case AV_PIX_FMT_YUVA422P:
220    case AV_PIX_FMT_YUVA444P:
221    case AV_PIX_FMT_YUV420P9:
222    case AV_PIX_FMT_YUV422P9:
223    case AV_PIX_FMT_YUV444P9:
224    case AV_PIX_FMT_YUVA420P9:
225    case AV_PIX_FMT_YUVA422P9:
226    case AV_PIX_FMT_YUVA444P9:
227    case AV_PIX_FMT_YUV420P10:
228    case AV_PIX_FMT_YUV422P10:
229    case AV_PIX_FMT_YUV444P10:
230    case AV_PIX_FMT_YUVA420P10:
231    case AV_PIX_FMT_YUVA422P10:
232    case AV_PIX_FMT_YUVA444P10:
233    case AV_PIX_FMT_YUV420P12:
234    case AV_PIX_FMT_YUV422P12:
235    case AV_PIX_FMT_YUV444P12:
236    case AV_PIX_FMT_YUV420P14:
237    case AV_PIX_FMT_YUV422P14:
238    case AV_PIX_FMT_YUV444P14:
239    case AV_PIX_FMT_YUV420P16:
240    case AV_PIX_FMT_YUV422P16:
241    case AV_PIX_FMT_YUV444P16:
242    case AV_PIX_FMT_YUVA420P16:
243    case AV_PIX_FMT_YUVA422P16:
244    case AV_PIX_FMT_YUVA444P16:
245        color_space = OPJ_CLRSPC_SYCC;
246        break;
247    default:
248        av_log(avctx, AV_LOG_ERROR,
249               "The requested pixel format '%s' is not supported\n",
250               av_get_pix_fmt_name(avctx->pix_fmt));
251        return NULL;
252    }
253
254    for (i = 0; i < numcomps; i++) {
255        cmptparm[i].prec = desc->comp[i].depth;
256        cmptparm[i].bpp  = desc->comp[i].depth;
257        cmptparm[i].sgnd = 0;
258        cmptparm[i].dx = sub_dx[i];
259        cmptparm[i].dy = sub_dy[i];
260        cmptparm[i].w = (avctx->width + sub_dx[i] - 1) / sub_dx[i];
261        cmptparm[i].h = (avctx->height + sub_dy[i] - 1) / sub_dy[i];
262    }
263
264    img = opj_image_create(numcomps, cmptparm, color_space);
265
266    if (!img)
267        return NULL;
268
269    // x0, y0 is the top left corner of the image
270    // x1, y1 is the width, height of the reference grid
271    img->x0 = 0;
272    img->y0 = 0;
273    img->x1 = (avctx->width  - 1) * parameters->subsampling_dx + 1;
274    img->y1 = (avctx->height - 1) * parameters->subsampling_dy + 1;
275
276    return img;
277}
278
279static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
280{
281    LibOpenJPEGContext *ctx = avctx->priv_data;
282    int err = 0;
283
284    opj_set_default_encoder_parameters(&ctx->enc_params);
285
286    switch (ctx->cinema_mode) {
287    case OPJ_CINEMA2K_24:
288        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
289        ctx->enc_params.max_cs_size = OPJ_CINEMA_24_CS;
290        ctx->enc_params.max_comp_size = OPJ_CINEMA_24_COMP;
291        break;
292    case OPJ_CINEMA2K_48:
293        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
294        ctx->enc_params.max_cs_size = OPJ_CINEMA_48_CS;
295        ctx->enc_params.max_comp_size = OPJ_CINEMA_48_COMP;
296        break;
297    case OPJ_CINEMA4K_24:
298        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_4K;
299        ctx->enc_params.max_cs_size = OPJ_CINEMA_24_CS;
300        ctx->enc_params.max_comp_size = OPJ_CINEMA_24_COMP;
301        break;
302    }
303
304    switch (ctx->profile) {
305    case OPJ_CINEMA2K:
306        if (ctx->enc_params.rsiz == OPJ_PROFILE_CINEMA_4K) {
307            err = AVERROR(EINVAL);
308            break;
309        }
310        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
311        break;
312    case OPJ_CINEMA4K:
313        if (ctx->enc_params.rsiz == OPJ_PROFILE_CINEMA_2K) {
314            err = AVERROR(EINVAL);
315            break;
316        }
317        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_4K;
318        break;
319    }
320
321    if (err) {
322        av_log(avctx, AV_LOG_ERROR,
323               "Invalid parameter pairing: cinema_mode and profile conflict.\n");
324        return err;
325    }
326
327    if (!ctx->numresolution) {
328        ctx->numresolution = 6;
329        while (FFMIN(avctx->width, avctx->height) >> ctx->numresolution < 1)
330            ctx->numresolution --;
331    }
332
333    ctx->enc_params.prog_order = ctx->prog_order;
334    ctx->enc_params.numresolution = ctx->numresolution;
335    ctx->enc_params.irreversible = ctx->irreversible;
336    ctx->enc_params.cp_disto_alloc = ctx->disto_alloc;
337    ctx->enc_params.cp_fixed_quality = ctx->fixed_quality;
338    ctx->enc_params.tcp_numlayers = 1;
339    ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;
340
341    if (ctx->cinema_mode > 0) {
342        cinema_parameters(&ctx->enc_params);
343    }
344
345    return 0;
346}
347
348static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const uint8_t *src[4],
349                                    const int linesize[4], opj_image_t *image)
350{
351    int compno;
352    int x;
353    int y;
354    int *image_line;
355    int frame_index;
356    const int numcomps = image->numcomps;
357
358    for (compno = 0; compno < numcomps; ++compno) {
359        if (image->comps[compno].w > linesize[0] / numcomps) {
360            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
361            return 0;
362        }
363    }
364
365    for (compno = 0; compno < numcomps; ++compno) {
366        for (y = 0; y < avctx->height; ++y) {
367            image_line = image->comps[compno].data + y * image->comps[compno].w;
368            frame_index = y * linesize[0] + compno;
369            for (x = 0; x < avctx->width; ++x) {
370                image_line[x] = src[0][frame_index];
371                frame_index += numcomps;
372            }
373            for (; x < image->comps[compno].w; ++x) {
374                image_line[x] = image_line[x - 1];
375            }
376        }
377        for (; y < image->comps[compno].h; ++y) {
378            image_line = image->comps[compno].data + y * image->comps[compno].w;
379            for (x = 0; x < image->comps[compno].w; ++x) {
380                image_line[x] = image_line[x - (int)image->comps[compno].w];
381            }
382        }
383    }
384
385    return 1;
386}
387
388// for XYZ 12 bit
389static int libopenjpeg_copy_packed12(AVCodecContext *avctx, const uint8_t *src[4],
390                                    const int linesize[4], opj_image_t *image)
391{
392    int compno;
393    int x, y;
394    int *image_line;
395    int frame_index;
396    const int numcomps  = image->numcomps;
397    const uint16_t *frame_ptr = (const uint16_t *)src[0];
398
399    for (compno = 0; compno < numcomps; ++compno) {
400        if (image->comps[compno].w > linesize[0] / numcomps) {
401            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
402            return 0;
403        }
404    }
405
406    for (compno = 0; compno < numcomps; ++compno) {
407        for (y = 0; y < avctx->height; ++y) {
408            image_line = image->comps[compno].data + y * image->comps[compno].w;
409            frame_index = y * (linesize[0] / 2) + compno;
410            for (x = 0; x < avctx->width; ++x) {
411                image_line[x] = frame_ptr[frame_index] >> 4;
412                frame_index += numcomps;
413            }
414            for (; x < image->comps[compno].w; ++x) {
415                image_line[x] = image_line[x - 1];
416            }
417        }
418        for (; y < image->comps[compno].h; ++y) {
419            image_line = image->comps[compno].data + y * image->comps[compno].w;
420            for (x = 0; x < image->comps[compno].w; ++x) {
421                image_line[x] = image_line[x - (int)image->comps[compno].w];
422            }
423        }
424    }
425
426    return 1;
427}
428
429static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const uint8_t *src[4],
430                                    const int linesize[4], opj_image_t *image)
431{
432    int compno;
433    int x;
434    int y;
435    int *image_line;
436    int frame_index;
437    const int numcomps = image->numcomps;
438    const uint16_t *frame_ptr = (const uint16_t*)src[0];
439
440    for (compno = 0; compno < numcomps; ++compno) {
441        if (image->comps[compno].w > linesize[0] / numcomps) {
442            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
443            return 0;
444        }
445    }
446
447    for (compno = 0; compno < numcomps; ++compno) {
448        for (y = 0; y < avctx->height; ++y) {
449            image_line = image->comps[compno].data + y * image->comps[compno].w;
450            frame_index = y * (linesize[0] / 2) + compno;
451            for (x = 0; x < avctx->width; ++x) {
452                image_line[x] = frame_ptr[frame_index];
453                frame_index += numcomps;
454            }
455            for (; x < image->comps[compno].w; ++x) {
456                image_line[x] = image_line[x - 1];
457            }
458        }
459        for (; y < image->comps[compno].h; ++y) {
460            image_line = image->comps[compno].data + y * image->comps[compno].w;
461            for (x = 0; x < image->comps[compno].w; ++x) {
462                image_line[x] = image_line[x - (int)image->comps[compno].w];
463            }
464        }
465    }
466
467    return 1;
468}
469
470static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, const uint8_t *src[4],
471                                    const int linesize[4], opj_image_t *image)
472{
473    int compno;
474    int x;
475    int y;
476    int width;
477    int height;
478    int *image_line;
479    int frame_index;
480    const int numcomps = image->numcomps;
481
482    for (compno = 0; compno < numcomps; ++compno) {
483        if (image->comps[compno].w > linesize[compno]) {
484            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
485            return 0;
486        }
487    }
488
489    for (compno = 0; compno < numcomps; ++compno) {
490        width  = (avctx->width + image->comps[compno].dx - 1) / image->comps[compno].dx;
491        height = (avctx->height + image->comps[compno].dy - 1) / image->comps[compno].dy;
492        for (y = 0; y < height; ++y) {
493            image_line = image->comps[compno].data + y * image->comps[compno].w;
494            frame_index = y * linesize[compno];
495            for (x = 0; x < width; ++x)
496                image_line[x] = src[compno][frame_index++];
497            for (; x < image->comps[compno].w; ++x) {
498                image_line[x] = image_line[x - 1];
499            }
500        }
501        for (; y < image->comps[compno].h; ++y) {
502            image_line = image->comps[compno].data + y * image->comps[compno].w;
503            for (x = 0; x < image->comps[compno].w; ++x) {
504                image_line[x] = image_line[x - (int)image->comps[compno].w];
505            }
506        }
507    }
508
509    return 1;
510}
511
512static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const uint8_t *src[4],
513                                    const int linesize[4], opj_image_t *image)
514{
515    int compno;
516    int x;
517    int y;
518    int width;
519    int height;
520    int *image_line;
521    int frame_index;
522    const int numcomps = image->numcomps;
523
524    for (compno = 0; compno < numcomps; ++compno) {
525        if (image->comps[compno].w > linesize[compno]) {
526            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
527            return 0;
528        }
529    }
530
531    for (compno = 0; compno < numcomps; ++compno) {
532        const uint16_t *frame_ptr = (const uint16_t *)src[compno];
533        width     = (avctx->width + image->comps[compno].dx - 1) / image->comps[compno].dx;
534        height    = (avctx->height + image->comps[compno].dy - 1) / image->comps[compno].dy;
535        for (y = 0; y < height; ++y) {
536            image_line = image->comps[compno].data + y * image->comps[compno].w;
537            frame_index = y * (linesize[compno] / 2);
538            for (x = 0; x < width; ++x)
539                image_line[x] = frame_ptr[frame_index++];
540            for (; x < image->comps[compno].w; ++x) {
541                image_line[x] = image_line[x - 1];
542            }
543        }
544        for (; y < image->comps[compno].h; ++y) {
545            image_line = image->comps[compno].data + y * image->comps[compno].w;
546            for (x = 0; x < image->comps[compno].w; ++x) {
547                image_line[x] = image_line[x - (int)image->comps[compno].w];
548            }
549        }
550    }
551
552    return 1;
553}
554
555static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
556                                    const AVFrame *frame, int *got_packet)
557{
558    LibOpenJPEGContext *ctx = avctx->priv_data;
559    int ret;
560    int cpyresult = 0;
561    PacketWriter writer     = { 0 };
562    opj_codec_t *compress   = NULL;
563    opj_stream_t *stream    = NULL;
564    opj_image_t *image      = mj2_create_image(avctx, &ctx->enc_params);
565    const uint8_t *data[4] = { frame->data[0], frame->data[1],
566                               frame->data[2], frame->data[3] };
567    int linesize[4]        = { frame->linesize[0], frame->linesize[1],
568                               frame->linesize[2], frame->linesize[3] };
569    if (!image) {
570        av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
571        ret = AVERROR(EINVAL);
572        goto done;
573    }
574
575    switch (avctx->pix_fmt) {
576    case AV_PIX_FMT_RGB24:
577    case AV_PIX_FMT_RGBA:
578    case AV_PIX_FMT_YA8:
579        cpyresult = libopenjpeg_copy_packed8(avctx, data, linesize, image);
580        break;
581    case AV_PIX_FMT_XYZ12:
582        cpyresult = libopenjpeg_copy_packed12(avctx, data, linesize, image);
583        break;
584    case AV_PIX_FMT_RGB48:
585    case AV_PIX_FMT_RGBA64:
586    case AV_PIX_FMT_YA16:
587        cpyresult = libopenjpeg_copy_packed16(avctx, data, linesize, image);
588        break;
589    case AV_PIX_FMT_GBR24P:
590    case AV_PIX_FMT_GBRP9:
591    case AV_PIX_FMT_GBRP10:
592    case AV_PIX_FMT_GBRP12:
593    case AV_PIX_FMT_GBRP14:
594    case AV_PIX_FMT_GBRP16:
595        data[0] = frame->data[2]; // swap to be rgb
596        data[1] = frame->data[0];
597        data[2] = frame->data[1];
598        linesize[0] = frame->linesize[2];
599        linesize[1] = frame->linesize[0];
600        linesize[2] = frame->linesize[1];
601        if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) {
602            cpyresult = libopenjpeg_copy_unpacked8(avctx, data, linesize, image);
603        } else {
604            cpyresult = libopenjpeg_copy_unpacked16(avctx, data, linesize, image);
605        }
606        break;
607    case AV_PIX_FMT_GRAY8:
608    case AV_PIX_FMT_YUV410P:
609    case AV_PIX_FMT_YUV411P:
610    case AV_PIX_FMT_YUV420P:
611    case AV_PIX_FMT_YUV422P:
612    case AV_PIX_FMT_YUV440P:
613    case AV_PIX_FMT_YUV444P:
614    case AV_PIX_FMT_YUVA420P:
615    case AV_PIX_FMT_YUVA422P:
616    case AV_PIX_FMT_YUVA444P:
617        cpyresult = libopenjpeg_copy_unpacked8(avctx, data, linesize, image);
618        break;
619    case AV_PIX_FMT_GRAY10:
620    case AV_PIX_FMT_GRAY12:
621    case AV_PIX_FMT_GRAY14:
622    case AV_PIX_FMT_GRAY16:
623    case AV_PIX_FMT_YUV420P9:
624    case AV_PIX_FMT_YUV422P9:
625    case AV_PIX_FMT_YUV444P9:
626    case AV_PIX_FMT_YUVA420P9:
627    case AV_PIX_FMT_YUVA422P9:
628    case AV_PIX_FMT_YUVA444P9:
629    case AV_PIX_FMT_YUV444P10:
630    case AV_PIX_FMT_YUV422P10:
631    case AV_PIX_FMT_YUV420P10:
632    case AV_PIX_FMT_YUVA444P10:
633    case AV_PIX_FMT_YUVA422P10:
634    case AV_PIX_FMT_YUVA420P10:
635    case AV_PIX_FMT_YUV420P12:
636    case AV_PIX_FMT_YUV422P12:
637    case AV_PIX_FMT_YUV444P12:
638    case AV_PIX_FMT_YUV420P14:
639    case AV_PIX_FMT_YUV422P14:
640    case AV_PIX_FMT_YUV444P14:
641    case AV_PIX_FMT_YUV444P16:
642    case AV_PIX_FMT_YUV422P16:
643    case AV_PIX_FMT_YUV420P16:
644    case AV_PIX_FMT_YUVA444P16:
645    case AV_PIX_FMT_YUVA422P16:
646    case AV_PIX_FMT_YUVA420P16:
647        cpyresult = libopenjpeg_copy_unpacked16(avctx, data, linesize, image);
648        break;
649    default:
650        av_log(avctx, AV_LOG_ERROR,
651               "The frame's pixel format '%s' is not supported\n",
652               av_get_pix_fmt_name(avctx->pix_fmt));
653        ret = AVERROR(EINVAL);
654        goto done;
655        break;
656    }
657
658    if (!cpyresult) {
659        av_log(avctx, AV_LOG_ERROR,
660               "Could not copy the frame data to the internal image buffer\n");
661        ret = -1;
662        goto done;
663    }
664
665    if ((ret = ff_alloc_packet(avctx, pkt, 1024)) < 0)
666        goto done;
667
668    compress = opj_create_compress(ctx->format);
669    if (!compress) {
670        av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
671        ret = AVERROR(ENOMEM);
672        goto done;
673    }
674
675    if (!opj_set_error_handler(compress, error_callback, avctx) ||
676        !opj_set_warning_handler(compress, warning_callback, avctx) ||
677        !opj_set_info_handler(compress, info_callback, avctx)) {
678        av_log(avctx, AV_LOG_ERROR, "Error setting the compressor handlers\n");
679        ret = AVERROR_EXTERNAL;
680        goto done;
681    }
682
683    if (!opj_setup_encoder(compress, &ctx->enc_params, image)) {
684        av_log(avctx, AV_LOG_ERROR, "Error setting up the compressor\n");
685        ret = AVERROR_EXTERNAL;
686        goto done;
687    }
688    stream = opj_stream_default_create(OPJ_STREAM_WRITE);
689
690    if (!stream) {
691        av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n");
692        ret = AVERROR(ENOMEM);
693        goto done;
694    }
695
696    writer.packet = pkt;
697    opj_stream_set_write_function(stream, stream_write);
698    opj_stream_set_skip_function(stream, stream_skip);
699    opj_stream_set_seek_function(stream, stream_seek);
700    opj_stream_set_user_data(stream, &writer, NULL);
701
702    if (!opj_start_compress(compress, image, stream) ||
703        !opj_encode(compress, stream) ||
704        !opj_end_compress(compress, stream)) {
705        av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
706        ret = AVERROR_EXTERNAL;
707        goto done;
708    }
709
710    av_shrink_packet(pkt, writer.pos);
711
712    *got_packet = 1;
713    ret = 0;
714
715done:
716    opj_stream_destroy(stream);
717    opj_destroy_codec(compress);
718    opj_image_destroy(image);
719    return ret;
720}
721
722#define OFFSET(x) offsetof(LibOpenJPEGContext, x)
723#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
724static const AVOption options[] = {
725    { "format",        "Codec Format",      OFFSET(format),        AV_OPT_TYPE_INT,   { .i64 = OPJ_CODEC_JP2   }, OPJ_CODEC_J2K, OPJ_CODEC_JP2,   VE, "format"      },
726    { "j2k",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_CODEC_J2K   }, 0,         0,           VE, "format"      },
727    { "jp2",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_CODEC_JP2   }, 0,         0,           VE, "format"      },
728    { "profile",       NULL,                OFFSET(profile),       AV_OPT_TYPE_INT,   { .i64 = OPJ_STD_RSIZ    }, OPJ_STD_RSIZ,  OPJ_CINEMA4K,    VE, "profile"     },
729    { "jpeg2000",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_STD_RSIZ    }, 0,         0,           VE, "profile"     },
730    { "cinema2k",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA2K    }, 0,         0,           VE, "profile"     },
731    { "cinema4k",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA4K    }, 0,         0,           VE, "profile"     },
732    { "cinema_mode",   "Digital Cinema",    OFFSET(cinema_mode),   AV_OPT_TYPE_INT,   { .i64 = OPJ_OFF         }, OPJ_OFF,       OPJ_CINEMA4K_24, VE, "cinema_mode" },
733    { "off",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_OFF         }, 0,         0,           VE, "cinema_mode" },
734    { "2k_24",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA2K_24 }, 0,         0,           VE, "cinema_mode" },
735    { "2k_48",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA2K_48 }, 0,         0,           VE, "cinema_mode" },
736    { "4k_24",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA4K_24 }, 0,         0,           VE, "cinema_mode" },
737    { "prog_order",    "Progression Order", OFFSET(prog_order),    AV_OPT_TYPE_INT,   { .i64 = OPJ_LRCP    }, OPJ_LRCP,  OPJ_CPRL,    VE, "prog_order"  },
738    { "lrcp",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_LRCP    }, 0,         0,           VE, "prog_order"  },
739    { "rlcp",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_RLCP    }, 0,         0,           VE, "prog_order"  },
740    { "rpcl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_RPCL    }, 0,         0,           VE, "prog_order"  },
741    { "pcrl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_PCRL    }, 0,         0,           VE, "prog_order"  },
742    { "cprl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ_CPRL    }, 0,         0,           VE, "prog_order"  },
743    { "numresolution", NULL,                OFFSET(numresolution), AV_OPT_TYPE_INT,   { .i64 = 6            }, 0,         33,          VE                },
744    { "irreversible",  NULL,                OFFSET(irreversible),  AV_OPT_TYPE_INT,   { .i64 = 0            }, 0,         1,           VE                },
745    { "disto_alloc",   NULL,                OFFSET(disto_alloc),   AV_OPT_TYPE_INT,   { .i64 = 1            }, 0,         1,           VE                },
746    { "fixed_quality", NULL,                OFFSET(fixed_quality), AV_OPT_TYPE_INT,   { .i64 = 0            }, 0,         1,           VE                },
747    { NULL },
748};
749
750static const AVClass openjpeg_class = {
751    .class_name = "libopenjpeg",
752    .item_name  = av_default_item_name,
753    .option     = options,
754    .version    = LIBAVUTIL_VERSION_INT,
755};
756
757const FFCodec ff_libopenjpeg_encoder = {
758    .p.name         = "libopenjpeg",
759    .p.long_name    = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
760    .p.type         = AVMEDIA_TYPE_VIDEO,
761    .p.id           = AV_CODEC_ID_JPEG2000,
762    .priv_data_size = sizeof(LibOpenJPEGContext),
763    .init           = libopenjpeg_encode_init,
764    FF_CODEC_ENCODE_CB(libopenjpeg_encode_frame),
765    .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
766    .p.pix_fmts     = (const enum AVPixelFormat[]) {
767        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48,
768        AV_PIX_FMT_RGBA64, AV_PIX_FMT_GBR24P,
769        AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
770        AV_PIX_FMT_GRAY8, AV_PIX_FMT_YA8, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YA16,
771        AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14,
772        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P,
773        AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA422P,
774        AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA444P,
775        AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
776        AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9,
777        AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
778        AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
779        AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12,
780        AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14,
781        AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
782        AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16,
783        AV_PIX_FMT_XYZ12,
784        AV_PIX_FMT_NONE
785    },
786    .p.priv_class   = &openjpeg_class,
787    .p.wrapper_name = "libopenjpeg",
788};
789