]> git.sesse.net Git - ffmpeg/blob - libavcodec/libopenjpegdec.c
Support decoding rgba64 with libopenjpeg.
[ffmpeg] / libavcodec / libopenjpegdec.c
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/imgutils.h"
28 #include "libavutil/pixfmt.h"
29 #include "avcodec.h"
30 #include "libavutil/intreadwrite.h"
31 #include "thread.h"
32 #define  OPJ_STATIC
33 #include <openjpeg.h>
34
35 #define JP2_SIG_TYPE    0x6A502020
36 #define JP2_SIG_VALUE   0x0D0A870A
37
38 typedef struct {
39     opj_dparameters_t dec_params;
40     AVFrame image;
41 } LibOpenJPEGContext;
42
43 static enum PixelFormat check_image_attributes(AVCodecContext *avctx, opj_image_t *image)
44 {
45     opj_image_comp_t c0 = image->comps[0];
46     opj_image_comp_t c1 = image->comps[1];
47     opj_image_comp_t c2 = image->comps[2];
48     int compRatio = 0;
49     compRatio |= c0.dx << 15 | c0.dy << 12;
50     compRatio |= c1.dx << 9  | c1.dy << 6;
51     compRatio |= c2.dx << 3  | c2.dy;
52
53     if (image->numcomps == 4) {
54         if (c0.prec == 8) {
55             if (compRatio == 0112222 &&
56                 image->comps[3].dx == 1 && image->comps[3].dy == 1) {
57                 return PIX_FMT_YUVA420P;
58             } else {
59                 return PIX_FMT_RGBA;
60             }
61         } else {
62             return PIX_FMT_RGBA64;
63         }
64     }
65
66     switch (compRatio) {
67     case 0111111: goto libopenjpeg_yuv444_rgb;
68     case 0111212: return PIX_FMT_YUV440P;
69     case 0112121: goto libopenjpeg_yuv422;
70     case 0112222: goto libopenjpeg_yuv420;
71     default: goto libopenjpeg_rgb;
72     }
73
74 libopenjpeg_yuv420:
75     switch (c0.prec) {
76     case 8:  return PIX_FMT_YUV420P;
77     case 9:  return PIX_FMT_YUV420P9;
78     case 10: return PIX_FMT_YUV420P10;
79     case 16: return PIX_FMT_YUV420P16;
80     }
81
82 libopenjpeg_yuv422:
83     switch (c0.prec) {
84     case 8:  return PIX_FMT_YUV422P;
85     case 9:  return PIX_FMT_YUV422P9;
86     case 10: return PIX_FMT_YUV422P10;
87     case 16: return PIX_FMT_YUV422P16;
88     }
89
90 libopenjpeg_yuv444_rgb:
91     switch (c0.prec) {
92     case 8:  return PIX_FMT_RGB24;
93     case 9:  return PIX_FMT_YUV444P9;
94     case 10: return PIX_FMT_YUV444P10;
95     case 16: return PIX_FMT_YUV444P16;
96     }
97
98 libopenjpeg_rgb:
99     switch (c0.prec) {
100     case 8: return PIX_FMT_RGB24;
101     default: return PIX_FMT_RGB48;
102     }
103
104     return PIX_FMT_RGB24;
105 }
106
107 static inline int libopenjpeg_ispacked(enum PixelFormat pix_fmt) {
108     int i, component_plane;
109     component_plane = av_pix_fmt_descriptors[pix_fmt].comp[0].plane;
110     for(i = 1; i < av_pix_fmt_descriptors[pix_fmt].nb_components; i++) {
111         if (component_plane != av_pix_fmt_descriptors[pix_fmt].comp[i].plane)
112             return 0;
113     }
114     return 1;
115 }
116
117 static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image) {
118     uint8_t *img_ptr;
119     int index, x, y, c;
120     for(y = 0; y < picture->height; y++) {
121         index = y*picture->width;
122         img_ptr = picture->data[0] + y*picture->linesize[0];
123         for(x = 0; x < picture->width; x++, index++) {
124             for(c = 0; c < image->numcomps; c++) {
125                 *img_ptr++ = image->comps[c].data[index];
126             }
127         }
128     }
129 }
130
131 static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) {
132     uint16_t *img_ptr;
133     int index, x, y, c;
134     int adjust[4];
135     for (x = 0; x < image->numcomps; x++) {
136         adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0);
137     }
138     for (y = 0; y < picture->height; y++) {
139         index = y*picture->width;
140         img_ptr = (uint16_t*) (picture->data[0] + y*picture->linesize[0]);
141         for (x = 0; x < picture->width; x++, index++) {
142             for (c = 0; c < image->numcomps; c++) {
143                 *img_ptr++ = image->comps[c].data[index] << adjust[c];
144             }
145         }
146     }
147 }
148
149 static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {
150     int *comp_data;
151     uint8_t *img_ptr;
152     int index, x, y;
153
154     for(index = 0; index < image->numcomps; index++) {
155         comp_data = image->comps[index].data;
156         for(y = 0; y < image->comps[index].h; y++) {
157             img_ptr = picture->data[index] + y * picture->linesize[index];
158             for(x = 0; x < image->comps[index].w; x++) {
159                 *img_ptr = (uint8_t) *comp_data;
160                 img_ptr++;
161                 comp_data++;
162             }
163         }
164     }
165 }
166
167 static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) {
168     int *comp_data;
169     uint16_t *img_ptr;
170     int index, x, y;
171     for(index = 0; index < image->numcomps; index++) {
172         comp_data = image->comps[index].data;
173         for(y = 0; y < image->comps[index].h; y++) {
174             img_ptr = (uint16_t*) (picture->data[index] + y * picture->linesize[index]);
175             for(x = 0; x < image->comps[index].w; x++) {
176                 *img_ptr = *comp_data;
177                 img_ptr++;
178                 comp_data++;
179             }
180         }
181     }
182 }
183
184 static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
185 {
186     LibOpenJPEGContext *ctx = avctx->priv_data;
187
188     opj_set_default_decoder_parameters(&ctx->dec_params);
189     avcodec_get_frame_defaults(&ctx->image);
190     avctx->coded_frame = &ctx->image;
191     return 0;
192 }
193
194 static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx)
195 {
196     LibOpenJPEGContext *ctx = avctx->priv_data;
197
198     avctx->coded_frame = &ctx->image;
199     return 0;
200 }
201
202 static int libopenjpeg_decode_frame(AVCodecContext *avctx,
203                                     void *data, int *data_size,
204                                     AVPacket *avpkt)
205 {
206     uint8_t *buf = avpkt->data;
207     int buf_size = avpkt->size;
208     LibOpenJPEGContext *ctx = avctx->priv_data;
209     AVFrame *picture = &ctx->image, *output = data;
210     opj_dinfo_t *dec;
211     opj_cio_t *stream;
212     opj_image_t *image;
213     int width, height, ret = -1;
214     int pixel_size = 0;
215     int ispacked = 0;
216
217     *data_size = 0;
218
219     // Check if input is a raw jpeg2k codestream or in jp2 wrapping
220     if((AV_RB32(buf) == 12) &&
221        (AV_RB32(buf + 4) == JP2_SIG_TYPE) &&
222        (AV_RB32(buf + 8) == JP2_SIG_VALUE)) {
223         dec = opj_create_decompress(CODEC_JP2);
224     } else {
225         // If the AVPacket contains a jp2c box, then skip to
226         // the starting byte of the codestream.
227         if (AV_RB32(buf + 4) == AV_RB32("jp2c"))
228             buf += 8;
229         dec = opj_create_decompress(CODEC_J2K);
230     }
231
232     if(!dec) {
233         av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
234         return -1;
235     }
236     opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
237
238     ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
239     // Tie decoder with decoding parameters
240     opj_setup_decoder(dec, &ctx->dec_params);
241     stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
242     if(!stream) {
243         av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
244         opj_destroy_decompress(dec);
245         return -1;
246     }
247
248     // Decode the header only
249     image = opj_decode_with_info(dec, stream, NULL);
250     opj_cio_close(stream);
251     if(!image) {
252         av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
253         opj_destroy_decompress(dec);
254         return -1;
255     }
256     width  = image->x1 - image->x0;
257     height = image->y1 - image->y0;
258     if(av_image_check_size(width, height, 0, avctx) < 0) {
259         av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
260         goto done;
261     }
262     avcodec_set_dimensions(avctx, width, height);
263
264     switch (image->numcomps) {
265     case 1:  avctx->pix_fmt = (image->comps[0].bpp == 8) ? PIX_FMT_GRAY8 : PIX_FMT_GRAY16;
266              break;
267     case 2:  avctx->pix_fmt = PIX_FMT_GRAY8A;
268              break;
269     case 3:
270     case 4:  avctx->pix_fmt = check_image_attributes(avctx, image);
271              break;
272     default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps);
273              goto done;
274     }
275
276     if(picture->data[0])
277         ff_thread_release_buffer(avctx, picture);
278
279     if(ff_thread_get_buffer(avctx, picture) < 0){
280         av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n");
281         return -1;
282     }
283
284     ctx->dec_params.cp_limit_decoding = NO_LIMITATION;
285     ctx->dec_params.cp_reduce = avctx->lowres;
286     // Tie decoder with decoding parameters
287     opj_setup_decoder(dec, &ctx->dec_params);
288     stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
289     if(!stream) {
290         av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
291         opj_destroy_decompress(dec);
292         return -1;
293     }
294
295     // Decode the codestream
296     image = opj_decode_with_info(dec, stream, NULL);
297     opj_cio_close(stream);
298
299     pixel_size = av_pix_fmt_descriptors[avctx->pix_fmt].comp[0].step_minus1 + 1;
300     ispacked = libopenjpeg_ispacked(avctx->pix_fmt);
301
302     switch (pixel_size) {
303     case 1:
304         if (ispacked) {
305             libopenjpeg_copy_to_packed8(picture, image);
306         } else {
307             libopenjpeg_copyto8(picture, image);
308         }
309         break;
310     case 2:
311         if (ispacked) {
312             libopenjpeg_copy_to_packed8(picture, image);
313         } else {
314             libopenjpeg_copyto16(picture, image);
315         }
316         break;
317     case 3:
318     case 4:
319         if (ispacked) {
320             libopenjpeg_copy_to_packed8(picture, image);
321         }
322         break;
323     case 6:
324     case 8:
325         if (ispacked) {
326             libopenjpeg_copy_to_packed16(picture, image);
327         }
328         break;
329     default:
330         av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size);
331         goto done;
332     }
333
334     *output    = ctx->image;
335     *data_size = sizeof(AVPicture);
336     ret = buf_size;
337
338 done:
339     opj_image_destroy(image);
340     opj_destroy_decompress(dec);
341     return ret;
342 }
343
344 static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx)
345 {
346     LibOpenJPEGContext *ctx = avctx->priv_data;
347
348     if(ctx->image.data[0])
349         ff_thread_release_buffer(avctx, &ctx->image);
350     return 0 ;
351 }
352
353
354 AVCodec ff_libopenjpeg_decoder = {
355     .name           = "libopenjpeg",
356     .type           = AVMEDIA_TYPE_VIDEO,
357     .id             = CODEC_ID_JPEG2000,
358     .priv_data_size = sizeof(LibOpenJPEGContext),
359     .init           = libopenjpeg_decode_init,
360     .close          = libopenjpeg_decode_close,
361     .decode         = libopenjpeg_decode_frame,
362     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
363     .max_lowres     = 5,
364     .long_name      = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"),
365     .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy)
366 };