blob: ce4e2b098a52d1ad8306f20940d190536779b9a0
1 | /* |
2 | * JPEG 2000 decoding support via OpenJPEG |
3 | * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net> |
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 decoder 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 "libavutil/pixfmt.h" |
32 | |
33 | #include "avcodec.h" |
34 | #include "internal.h" |
35 | #include "thread.h" |
36 | |
37 | #if HAVE_OPENJPEG_2_1_OPENJPEG_H |
38 | # include <openjpeg-2.1/openjpeg.h> |
39 | #elif HAVE_OPENJPEG_2_0_OPENJPEG_H |
40 | # include <openjpeg-2.0/openjpeg.h> |
41 | #elif HAVE_OPENJPEG_1_5_OPENJPEG_H |
42 | # include <openjpeg-1.5/openjpeg.h> |
43 | #else |
44 | # include <openjpeg.h> |
45 | #endif |
46 | |
47 | #if HAVE_OPENJPEG_2_1_OPENJPEG_H || HAVE_OPENJPEG_2_0_OPENJPEG_H |
48 | # define OPENJPEG_MAJOR_VERSION 2 |
49 | # define OPJ(x) OPJ_##x |
50 | #else |
51 | # define OPENJPEG_MAJOR_VERSION 1 |
52 | # define OPJ(x) x |
53 | #endif |
54 | |
55 | #define JP2_SIG_TYPE 0x6A502020 |
56 | #define JP2_SIG_VALUE 0x0D0A870A |
57 | |
58 | // pix_fmts with lower bpp have to be listed before |
59 | // similar pix_fmts with higher bpp. |
60 | #define RGB_PIXEL_FORMATS AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, \ |
61 | AV_PIX_FMT_RGB48, AV_PIX_FMT_RGBA64 |
62 | |
63 | #define GRAY_PIXEL_FORMATS AV_PIX_FMT_GRAY8, AV_PIX_FMT_YA8, \ |
64 | AV_PIX_FMT_GRAY16, AV_PIX_FMT_YA16 |
65 | |
66 | #define YUV_PIXEL_FORMATS AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUVA420P, \ |
67 | AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA422P, \ |
68 | AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, \ |
69 | AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, \ |
70 | AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, \ |
71 | AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, \ |
72 | AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, \ |
73 | AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, \ |
74 | AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, \ |
75 | AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, \ |
76 | AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16 |
77 | |
78 | #define XYZ_PIXEL_FORMATS AV_PIX_FMT_XYZ12 |
79 | |
80 | static const enum AVPixelFormat libopenjpeg_rgb_pix_fmts[] = { |
81 | RGB_PIXEL_FORMATS |
82 | }; |
83 | static const enum AVPixelFormat libopenjpeg_gray_pix_fmts[] = { |
84 | GRAY_PIXEL_FORMATS |
85 | }; |
86 | static const enum AVPixelFormat libopenjpeg_yuv_pix_fmts[] = { |
87 | YUV_PIXEL_FORMATS |
88 | }; |
89 | static const enum AVPixelFormat libopenjpeg_all_pix_fmts[] = { |
90 | RGB_PIXEL_FORMATS, GRAY_PIXEL_FORMATS, YUV_PIXEL_FORMATS, XYZ_PIXEL_FORMATS |
91 | }; |
92 | |
93 | typedef struct LibOpenJPEGContext { |
94 | AVClass *class; |
95 | opj_dparameters_t dec_params; |
96 | #if OPENJPEG_MAJOR_VERSION == 1 |
97 | opj_event_mgr_t event_mgr; |
98 | #endif // OPENJPEG_MAJOR_VERSION == 1 |
99 | int lowqual; |
100 | } LibOpenJPEGContext; |
101 | |
102 | static void error_callback(const char *msg, void *data) |
103 | { |
104 | av_log(data, AV_LOG_ERROR, "%s", msg); |
105 | } |
106 | |
107 | static void warning_callback(const char *msg, void *data) |
108 | { |
109 | av_log(data, AV_LOG_WARNING, "%s", msg); |
110 | } |
111 | |
112 | static void info_callback(const char *msg, void *data) |
113 | { |
114 | av_log(data, AV_LOG_DEBUG, "%s", msg); |
115 | } |
116 | |
117 | #if OPENJPEG_MAJOR_VERSION == 2 |
118 | typedef struct BufferReader { |
119 | int pos; |
120 | int size; |
121 | const uint8_t *buffer; |
122 | } BufferReader; |
123 | |
124 | static OPJ_SIZE_T stream_read(void *out_buffer, OPJ_SIZE_T nb_bytes, void *user_data) |
125 | { |
126 | BufferReader *reader = user_data; |
127 | int remaining; |
128 | |
129 | if (reader->pos == reader->size) { |
130 | return (OPJ_SIZE_T)-1; |
131 | } |
132 | remaining = reader->size - reader->pos; |
133 | if (nb_bytes > remaining) { |
134 | nb_bytes = remaining; |
135 | } |
136 | memcpy(out_buffer, reader->buffer + reader->pos, nb_bytes); |
137 | reader->pos += (int)nb_bytes; |
138 | return nb_bytes; |
139 | } |
140 | |
141 | static OPJ_OFF_T stream_skip(OPJ_OFF_T nb_bytes, void *user_data) |
142 | { |
143 | BufferReader *reader = user_data; |
144 | if (nb_bytes < 0) { |
145 | if (reader->pos == 0) { |
146 | return (OPJ_SIZE_T)-1; |
147 | } |
148 | if (nb_bytes + reader->pos < 0) { |
149 | nb_bytes = -reader->pos; |
150 | } |
151 | } else { |
152 | int remaining; |
153 | |
154 | if (reader->pos == reader->size) { |
155 | return (OPJ_SIZE_T)-1; |
156 | } |
157 | remaining = reader->size - reader->pos; |
158 | if (nb_bytes > remaining) { |
159 | nb_bytes = remaining; |
160 | } |
161 | } |
162 | reader->pos += (int)nb_bytes; |
163 | return nb_bytes; |
164 | } |
165 | |
166 | static OPJ_BOOL stream_seek(OPJ_OFF_T nb_bytes, void *user_data) |
167 | { |
168 | BufferReader *reader = user_data; |
169 | if (nb_bytes < 0 || nb_bytes > reader->size) { |
170 | return OPJ_FALSE; |
171 | } |
172 | reader->pos = (int)nb_bytes; |
173 | return OPJ_TRUE; |
174 | } |
175 | #endif // OPENJPEG_MAJOR_VERSION == 2 |
176 | |
177 | static inline int libopenjpeg_matches_pix_fmt(const opj_image_t *image, enum AVPixelFormat pix_fmt) |
178 | { |
179 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); |
180 | int match = 1; |
181 | |
182 | if (desc->nb_components != image->numcomps) { |
183 | return 0; |
184 | } |
185 | |
186 | switch (desc->nb_components) { |
187 | case 4: |
188 | match = match && |
189 | desc->comp[3].depth >= image->comps[3].prec && |
190 | 1 == image->comps[3].dx && |
191 | 1 == image->comps[3].dy; |
192 | case 3: |
193 | match = match && |
194 | desc->comp[2].depth >= image->comps[2].prec && |
195 | 1 << desc->log2_chroma_w == image->comps[2].dx && |
196 | 1 << desc->log2_chroma_h == image->comps[2].dy; |
197 | case 2: |
198 | match = match && |
199 | desc->comp[1].depth >= image->comps[1].prec && |
200 | 1 << desc->log2_chroma_w == image->comps[1].dx && |
201 | 1 << desc->log2_chroma_h == image->comps[1].dy; |
202 | case 1: |
203 | match = match && |
204 | desc->comp[0].depth >= image->comps[0].prec && |
205 | 1 == image->comps[0].dx && |
206 | 1 == image->comps[0].dy; |
207 | default: |
208 | break; |
209 | } |
210 | |
211 | return match; |
212 | } |
213 | |
214 | static inline enum AVPixelFormat libopenjpeg_guess_pix_fmt(const opj_image_t *image) { |
215 | int index; |
216 | const enum AVPixelFormat *possible_fmts = NULL; |
217 | int possible_fmts_nb = 0; |
218 | |
219 | switch (image->color_space) { |
220 | case OPJ(CLRSPC_SRGB): |
221 | possible_fmts = libopenjpeg_rgb_pix_fmts; |
222 | possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_rgb_pix_fmts); |
223 | break; |
224 | case OPJ(CLRSPC_GRAY): |
225 | possible_fmts = libopenjpeg_gray_pix_fmts; |
226 | possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_gray_pix_fmts); |
227 | break; |
228 | case OPJ(CLRSPC_SYCC): |
229 | possible_fmts = libopenjpeg_yuv_pix_fmts; |
230 | possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_yuv_pix_fmts); |
231 | break; |
232 | default: |
233 | possible_fmts = libopenjpeg_all_pix_fmts; |
234 | possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_all_pix_fmts); |
235 | break; |
236 | } |
237 | |
238 | for (index = 0; index < possible_fmts_nb; ++index) |
239 | if (libopenjpeg_matches_pix_fmt(image, possible_fmts[index])) { |
240 | return possible_fmts[index]; |
241 | } |
242 | |
243 | return AV_PIX_FMT_NONE; |
244 | } |
245 | |
246 | static inline int libopenjpeg_ispacked(enum AVPixelFormat pix_fmt) |
247 | { |
248 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); |
249 | int i, component_plane; |
250 | |
251 | if (pix_fmt == AV_PIX_FMT_GRAY16) |
252 | return 0; |
253 | |
254 | component_plane = desc->comp[0].plane; |
255 | for (i = 1; i < desc->nb_components; i++) |
256 | if (component_plane != desc->comp[i].plane) |
257 | return 0; |
258 | return 1; |
259 | } |
260 | |
261 | static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image) { |
262 | uint8_t *img_ptr; |
263 | int index, x, y, c; |
264 | for (y = 0; y < picture->height; y++) { |
265 | index = y * picture->width; |
266 | img_ptr = picture->data[0] + y * picture->linesize[0]; |
267 | for (x = 0; x < picture->width; x++, index++) |
268 | for (c = 0; c < image->numcomps; c++) |
269 | *img_ptr++ = 0x80 * image->comps[c].sgnd + image->comps[c].data[index]; |
270 | } |
271 | } |
272 | |
273 | static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) { |
274 | uint16_t *img_ptr; |
275 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(picture->format); |
276 | int index, x, y, c; |
277 | int adjust[4]; |
278 | for (x = 0; x < image->numcomps; x++) |
279 | adjust[x] = FFMAX(FFMIN(desc->comp[x].depth - image->comps[x].prec, 8), 0) + desc->comp[x].shift; |
280 | |
281 | for (y = 0; y < picture->height; y++) { |
282 | index = y * picture->width; |
283 | img_ptr = (uint16_t *) (picture->data[0] + y * picture->linesize[0]); |
284 | for (x = 0; x < picture->width; x++, index++) |
285 | for (c = 0; c < image->numcomps; c++) |
286 | *img_ptr++ = (1 << image->comps[c].prec - 1) * image->comps[c].sgnd + |
287 | (unsigned)image->comps[c].data[index] << adjust[c]; |
288 | } |
289 | } |
290 | |
291 | static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) { |
292 | int *comp_data; |
293 | uint8_t *img_ptr; |
294 | int index, x, y; |
295 | |
296 | for (index = 0; index < image->numcomps; index++) { |
297 | comp_data = image->comps[index].data; |
298 | for (y = 0; y < image->comps[index].h; y++) { |
299 | img_ptr = picture->data[index] + y * picture->linesize[index]; |
300 | for (x = 0; x < image->comps[index].w; x++) { |
301 | *img_ptr = 0x80 * image->comps[index].sgnd + *comp_data; |
302 | img_ptr++; |
303 | comp_data++; |
304 | } |
305 | } |
306 | } |
307 | } |
308 | |
309 | static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) { |
310 | int *comp_data; |
311 | uint16_t *img_ptr; |
312 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(picture->format); |
313 | int index, x, y; |
314 | int adjust[4]; |
315 | for (x = 0; x < image->numcomps; x++) |
316 | adjust[x] = FFMAX(FFMIN(desc->comp[x].depth - image->comps[x].prec, 8), 0) + desc->comp[x].shift; |
317 | |
318 | for (index = 0; index < image->numcomps; index++) { |
319 | comp_data = image->comps[index].data; |
320 | for (y = 0; y < image->comps[index].h; y++) { |
321 | img_ptr = (uint16_t *)(picture->data[index] + y * picture->linesize[index]); |
322 | for (x = 0; x < image->comps[index].w; x++) { |
323 | *img_ptr = (1 << image->comps[index].prec - 1) * image->comps[index].sgnd + |
324 | (unsigned)*comp_data << adjust[index]; |
325 | img_ptr++; |
326 | comp_data++; |
327 | } |
328 | } |
329 | } |
330 | } |
331 | |
332 | static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) |
333 | { |
334 | LibOpenJPEGContext *ctx = avctx->priv_data; |
335 | |
336 | opj_set_default_decoder_parameters(&ctx->dec_params); |
337 | return 0; |
338 | } |
339 | |
340 | static int libopenjpeg_decode_frame(AVCodecContext *avctx, |
341 | void *data, int *got_frame, |
342 | AVPacket *avpkt) |
343 | { |
344 | uint8_t *buf = avpkt->data; |
345 | int buf_size = avpkt->size; |
346 | LibOpenJPEGContext *ctx = avctx->priv_data; |
347 | ThreadFrame frame = { .f = data }; |
348 | AVFrame *picture = data; |
349 | const AVPixFmtDescriptor *desc; |
350 | int width, height, ret; |
351 | int pixel_size = 0; |
352 | int ispacked = 0; |
353 | int i; |
354 | opj_image_t *image = NULL; |
355 | #if OPENJPEG_MAJOR_VERSION == 1 |
356 | opj_dinfo_t *dec = NULL; |
357 | opj_cio_t *stream = NULL; |
358 | #else // OPENJPEG_MAJOR_VERSION == 2 |
359 | BufferReader reader = {0, avpkt->size, avpkt->data}; |
360 | opj_codec_t *dec = NULL; |
361 | opj_stream_t *stream = NULL; |
362 | #endif // OPENJPEG_MAJOR_VERSION == 1 |
363 | |
364 | *got_frame = 0; |
365 | |
366 | // Check if input is a raw jpeg2k codestream or in jp2 wrapping |
367 | if ((AV_RB32(buf) == 12) && |
368 | (AV_RB32(buf + 4) == JP2_SIG_TYPE) && |
369 | (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { |
370 | dec = opj_create_decompress(OPJ(CODEC_JP2)); |
371 | } else { |
372 | /* If the AVPacket contains a jp2c box, then skip to |
373 | * the starting byte of the codestream. */ |
374 | if (AV_RB32(buf + 4) == AV_RB32("jp2c")) |
375 | buf += 8; |
376 | dec = opj_create_decompress(OPJ(CODEC_J2K)); |
377 | } |
378 | |
379 | if (!dec) { |
380 | av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); |
381 | ret = AVERROR_EXTERNAL; |
382 | goto done; |
383 | } |
384 | |
385 | #if OPENJPEG_MAJOR_VERSION == 1 |
386 | memset(&ctx->event_mgr, 0, sizeof(ctx->event_mgr)); |
387 | ctx->event_mgr.info_handler = info_callback; |
388 | ctx->event_mgr.error_handler = error_callback; |
389 | ctx->event_mgr.warning_handler = warning_callback; |
390 | opj_set_event_mgr((opj_common_ptr) dec, &ctx->event_mgr, avctx); |
391 | ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; |
392 | ctx->dec_params.cp_layer = ctx->lowqual; |
393 | #else // OPENJPEG_MAJOR_VERSION == 2 |
394 | if (!opj_set_error_handler(dec, error_callback, avctx) || |
395 | !opj_set_warning_handler(dec, warning_callback, avctx) || |
396 | !opj_set_info_handler(dec, info_callback, avctx)) { |
397 | av_log(avctx, AV_LOG_ERROR, "Error setting decoder handlers.\n"); |
398 | ret = AVERROR_EXTERNAL; |
399 | goto done; |
400 | } |
401 | |
402 | ctx->dec_params.cp_layer = ctx->lowqual; |
403 | ctx->dec_params.cp_reduce = avctx->lowres; |
404 | #endif // OPENJPEG_MAJOR_VERSION == 1 |
405 | |
406 | // Tie decoder with decoding parameters |
407 | opj_setup_decoder(dec, &ctx->dec_params); |
408 | |
409 | #if OPENJPEG_MAJOR_VERSION == 1 |
410 | stream = opj_cio_open((opj_common_ptr) dec, buf, buf_size); |
411 | #else // OPENJPEG_MAJOR_VERSION == 2 |
412 | stream = opj_stream_default_create(OPJ_STREAM_READ); |
413 | #endif // OPENJPEG_MAJOR_VERSION == 1 |
414 | |
415 | if (!stream) { |
416 | av_log(avctx, AV_LOG_ERROR, |
417 | "Codestream could not be opened for reading.\n"); |
418 | ret = AVERROR_EXTERNAL; |
419 | goto done; |
420 | } |
421 | |
422 | #if OPENJPEG_MAJOR_VERSION == 1 |
423 | // Decode the header only. |
424 | image = opj_decode_with_info(dec, stream, NULL); |
425 | opj_cio_close(stream); |
426 | stream = NULL; |
427 | ret = !image; |
428 | #else // OPENJPEG_MAJOR_VERSION == 2 |
429 | opj_stream_set_read_function(stream, stream_read); |
430 | opj_stream_set_skip_function(stream, stream_skip); |
431 | opj_stream_set_seek_function(stream, stream_seek); |
432 | #if HAVE_OPENJPEG_2_1_OPENJPEG_H |
433 | opj_stream_set_user_data(stream, &reader, NULL); |
434 | #elif HAVE_OPENJPEG_2_0_OPENJPEG_H |
435 | opj_stream_set_user_data(stream, &reader); |
436 | #else |
437 | #error Missing call to opj_stream_set_user_data |
438 | #endif |
439 | opj_stream_set_user_data_length(stream, avpkt->size); |
440 | // Decode the header only. |
441 | ret = !opj_read_header(stream, dec, &image); |
442 | #endif // OPENJPEG_MAJOR_VERSION == 1 |
443 | |
444 | if (ret) { |
445 | av_log(avctx, AV_LOG_ERROR, "Error decoding codestream header.\n"); |
446 | ret = AVERROR_EXTERNAL; |
447 | goto done; |
448 | } |
449 | |
450 | width = image->x1 - image->x0; |
451 | height = image->y1 - image->y0; |
452 | |
453 | ret = ff_set_dimensions(avctx, width, height); |
454 | if (ret < 0) |
455 | goto done; |
456 | |
457 | if (avctx->pix_fmt != AV_PIX_FMT_NONE) |
458 | if (!libopenjpeg_matches_pix_fmt(image, avctx->pix_fmt)) |
459 | avctx->pix_fmt = AV_PIX_FMT_NONE; |
460 | |
461 | if (avctx->pix_fmt == AV_PIX_FMT_NONE) |
462 | avctx->pix_fmt = libopenjpeg_guess_pix_fmt(image); |
463 | |
464 | if (avctx->pix_fmt == AV_PIX_FMT_NONE) { |
465 | av_log(avctx, AV_LOG_ERROR, "Unable to determine pixel format.\n"); |
466 | ret = AVERROR_UNKNOWN; |
467 | goto done; |
468 | } |
469 | for (i = 0; i < image->numcomps; i++) |
470 | if (image->comps[i].prec > avctx->bits_per_raw_sample) |
471 | avctx->bits_per_raw_sample = image->comps[i].prec; |
472 | |
473 | if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) |
474 | goto done; |
475 | |
476 | #if OPENJPEG_MAJOR_VERSION == 1 |
477 | ctx->dec_params.cp_limit_decoding = NO_LIMITATION; |
478 | ctx->dec_params.cp_reduce = avctx->lowres; |
479 | // Tie decoder with decoding parameters. |
480 | opj_setup_decoder(dec, &ctx->dec_params); |
481 | stream = opj_cio_open((opj_common_ptr) dec, buf, buf_size); |
482 | if (!stream) { |
483 | av_log(avctx, AV_LOG_ERROR, |
484 | "Codestream could not be opened for reading.\n"); |
485 | ret = AVERROR_EXTERNAL; |
486 | goto done; |
487 | } |
488 | opj_image_destroy(image); |
489 | // Decode the codestream |
490 | image = opj_decode_with_info(dec, stream, NULL); |
491 | ret = !image; |
492 | #else // OPENJPEG_MAJOR_VERSION == 2 |
493 | ret = !opj_decode(dec, stream, image); |
494 | #endif // OPENJPEG_MAJOR_VERSION == 1 |
495 | |
496 | if (ret) { |
497 | av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); |
498 | ret = AVERROR_EXTERNAL; |
499 | goto done; |
500 | } |
501 | |
502 | for (i = 0; i < image->numcomps; i++) { |
503 | if (!image->comps[i].data) { |
504 | av_log(avctx, AV_LOG_ERROR, |
505 | "Image component %d contains no data.\n", i); |
506 | ret = AVERROR_INVALIDDATA; |
507 | goto done; |
508 | } |
509 | } |
510 | |
511 | desc = av_pix_fmt_desc_get(avctx->pix_fmt); |
512 | pixel_size = desc->comp[0].step; |
513 | ispacked = libopenjpeg_ispacked(avctx->pix_fmt); |
514 | |
515 | switch (pixel_size) { |
516 | case 1: |
517 | if (ispacked) { |
518 | libopenjpeg_copy_to_packed8(picture, image); |
519 | } else { |
520 | libopenjpeg_copyto8(picture, image); |
521 | } |
522 | break; |
523 | case 2: |
524 | if (ispacked) { |
525 | libopenjpeg_copy_to_packed8(picture, image); |
526 | } else { |
527 | libopenjpeg_copyto16(picture, image); |
528 | } |
529 | break; |
530 | case 3: |
531 | case 4: |
532 | if (ispacked) { |
533 | libopenjpeg_copy_to_packed8(picture, image); |
534 | } |
535 | break; |
536 | case 6: |
537 | case 8: |
538 | if (ispacked) { |
539 | libopenjpeg_copy_to_packed16(picture, image); |
540 | } |
541 | break; |
542 | default: |
543 | avpriv_report_missing_feature(avctx, "Pixel size %d", pixel_size); |
544 | ret = AVERROR_PATCHWELCOME; |
545 | goto done; |
546 | } |
547 | |
548 | *got_frame = 1; |
549 | picture->pict_type = AV_PICTURE_TYPE_I; |
550 | picture->key_frame = 1; |
551 | ret = buf_size; |
552 | |
553 | done: |
554 | opj_image_destroy(image); |
555 | #if OPENJPEG_MAJOR_VERSION == 2 |
556 | opj_stream_destroy(stream); |
557 | opj_destroy_codec(dec); |
558 | #else |
559 | opj_cio_close(stream); |
560 | opj_destroy_decompress(dec); |
561 | #endif |
562 | return ret; |
563 | } |
564 | |
565 | static av_cold void libopenjpeg_static_init(AVCodec *codec) |
566 | { |
567 | const char *version = opj_version(); |
568 | int major, minor; |
569 | |
570 | if (sscanf(version, "%d.%d", &major, &minor) == 2 && 1000*major + minor <= 1003) |
571 | codec->capabilities |= AV_CODEC_CAP_EXPERIMENTAL; |
572 | } |
573 | |
574 | #define OFFSET(x) offsetof(LibOpenJPEGContext, x) |
575 | #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM |
576 | |
577 | static const AVOption options[] = { |
578 | { "lowqual", "Limit the number of layers used for decoding", |
579 | OFFSET(lowqual), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD }, |
580 | { NULL }, |
581 | }; |
582 | |
583 | static const AVClass openjpeg_class = { |
584 | .class_name = "libopenjpeg", |
585 | .item_name = av_default_item_name, |
586 | .option = options, |
587 | .version = LIBAVUTIL_VERSION_INT, |
588 | }; |
589 | |
590 | AVCodec ff_libopenjpeg_decoder = { |
591 | .name = "libopenjpeg", |
592 | .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"), |
593 | .type = AVMEDIA_TYPE_VIDEO, |
594 | .id = AV_CODEC_ID_JPEG2000, |
595 | .priv_data_size = sizeof(LibOpenJPEGContext), |
596 | .init = libopenjpeg_decode_init, |
597 | .decode = libopenjpeg_decode_frame, |
598 | .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, |
599 | .max_lowres = 31, |
600 | .priv_class = &openjpeg_class, |
601 | .init_static_data = libopenjpeg_static_init, |
602 | }; |
603 |