Mercurial > libavcodec.hg
annotate libopenjpeg.c @ 12468:443f38ceeaad libavcodec
Reimplement av_picture_data_copy() avoiding the use of PixFmtInfo
information.
Required for moving the function to libavcore.
author | stefano |
---|---|
date | Tue, 07 Sep 2010 21:23:52 +0000 |
parents | ffb3668ff7af |
children |
rev | line source |
---|---|
8747 | 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 /** | |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11560
diff
changeset
|
23 * @file |
8747 | 24 * JPEG 2000 decoder using libopenjpeg |
25 */ | |
26 | |
12376
7e9b2d528e59
Fix the compilation of some libavcodec/lib* files which were not
stefano
parents:
12372
diff
changeset
|
27 #include "libavcore/imgutils.h" |
8747 | 28 #include "avcodec.h" |
29 #include "libavutil/intreadwrite.h" | |
30 #define OPJ_STATIC | |
8787
9575568668c4
Use default system include path for an installed OpenJPEG library.
diego
parents:
8747
diff
changeset
|
31 #include <openjpeg.h> |
8747 | 32 |
33 #define JP2_SIG_TYPE 0x6A502020 | |
34 #define JP2_SIG_VALUE 0x0D0A870A | |
35 | |
36 typedef struct { | |
37 opj_dparameters_t dec_params; | |
38 AVFrame image; | |
39 } LibOpenJPEGContext; | |
40 | |
41 static int check_image_attributes(opj_image_t *image) | |
42 { | |
10436
a050e8857f00
cosmetics: Remove pointless parentheses from return statement.
diego
parents:
9804
diff
changeset
|
43 return image->comps[0].dx == image->comps[1].dx && |
8747 | 44 image->comps[1].dx == image->comps[2].dx && |
45 image->comps[0].dy == image->comps[1].dy && | |
46 image->comps[1].dy == image->comps[2].dy && | |
47 image->comps[0].prec == image->comps[1].prec && | |
10436
a050e8857f00
cosmetics: Remove pointless parentheses from return statement.
diego
parents:
9804
diff
changeset
|
48 image->comps[1].prec == image->comps[2].prec; |
8747 | 49 } |
50 | |
51 static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) | |
52 { | |
53 LibOpenJPEGContext *ctx = avctx->priv_data; | |
54 | |
55 opj_set_default_decoder_parameters(&ctx->dec_params); | |
56 avctx->coded_frame = &ctx->image; | |
57 return 0; | |
58 } | |
59 | |
60 static int libopenjpeg_decode_frame(AVCodecContext *avctx, | |
61 void *data, int *data_size, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8787
diff
changeset
|
62 AVPacket *avpkt) |
8747 | 63 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8787
diff
changeset
|
64 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8787
diff
changeset
|
65 int buf_size = avpkt->size; |
8747 | 66 LibOpenJPEGContext *ctx = avctx->priv_data; |
67 AVFrame *picture = &ctx->image, *output = data; | |
68 opj_dinfo_t *dec; | |
69 opj_cio_t *stream; | |
70 opj_image_t *image; | |
71 int width, height, has_alpha = 0, ret = -1; | |
72 int x, y, index; | |
73 uint8_t *img_ptr; | |
74 int adjust[4]; | |
75 | |
76 *data_size = 0; | |
77 | |
78 // Check if input is a raw jpeg2k codestream or in jp2 wrapping | |
79 if((AV_RB32(buf) == 12) && | |
80 (AV_RB32(buf + 4) == JP2_SIG_TYPE) && | |
81 (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { | |
10507 | 82 dec = opj_create_decompress(CODEC_JP2); |
8747 | 83 } else { |
10508
f33404f82b9e
Handle JPEG2000 frames stored in the Quicktime container.
jai_menon
parents:
10507
diff
changeset
|
84 // If the AVPacket contains a jp2c box, then skip to |
f33404f82b9e
Handle JPEG2000 frames stored in the Quicktime container.
jai_menon
parents:
10507
diff
changeset
|
85 // the starting byte of the codestream. |
f33404f82b9e
Handle JPEG2000 frames stored in the Quicktime container.
jai_menon
parents:
10507
diff
changeset
|
86 if (AV_RB32(buf + 4) == AV_RB32("jp2c")) |
f33404f82b9e
Handle JPEG2000 frames stored in the Quicktime container.
jai_menon
parents:
10507
diff
changeset
|
87 buf += 8; |
10507 | 88 dec = opj_create_decompress(CODEC_J2K); |
8747 | 89 } |
90 | |
91 if(!dec) { | |
92 av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); | |
93 return -1; | |
94 } | |
95 opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); | |
96 | |
9715 | 97 ctx->dec_params.cp_reduce = avctx->lowres; |
8747 | 98 // Tie decoder with decoding parameters |
99 opj_setup_decoder(dec, &ctx->dec_params); | |
100 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); | |
101 if(!stream) { | |
102 av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); | |
103 opj_destroy_decompress(dec); | |
104 return -1; | |
105 } | |
106 | |
107 // Decode the codestream | |
108 image = opj_decode_with_info(dec, stream, NULL); | |
109 opj_cio_close(stream); | |
110 if(!image) { | |
111 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); | |
112 opj_destroy_decompress(dec); | |
113 return -1; | |
114 } | |
9715 | 115 width = image->comps[0].w << avctx->lowres; |
116 height = image->comps[0].h << avctx->lowres; | |
12462
ffb3668ff7af
Use new imgutils.h API names, fix deprecation warnings.
stefano
parents:
12376
diff
changeset
|
117 if(av_image_check_size(width, height, 0, avctx) < 0) { |
8747 | 118 av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); |
119 goto done; | |
120 } | |
121 avcodec_set_dimensions(avctx, width, height); | |
122 | |
123 switch(image->numcomps) | |
124 { | |
125 case 1: avctx->pix_fmt = PIX_FMT_GRAY8; | |
126 break; | |
127 case 3: if(check_image_attributes(image)) { | |
128 avctx->pix_fmt = PIX_FMT_RGB24; | |
129 } else { | |
130 avctx->pix_fmt = PIX_FMT_GRAY8; | |
131 av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n"); | |
132 } | |
133 break; | |
134 case 4: has_alpha = 1; | |
10737 | 135 avctx->pix_fmt = PIX_FMT_RGBA; |
8747 | 136 break; |
137 default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); | |
138 goto done; | |
139 } | |
140 | |
141 if(picture->data[0]) | |
142 avctx->release_buffer(avctx, picture); | |
143 | |
144 if(avctx->get_buffer(avctx, picture) < 0) { | |
145 av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n"); | |
146 return -1; | |
147 } | |
148 | |
149 for(x = 0; x < image->numcomps; x++) { | |
150 adjust[x] = FFMAX(image->comps[x].prec - 8, 0); | |
151 } | |
152 | |
9714
5df11d49abb7
Use dimensions stored in AVCodecContext instead of local variables.
jai_menon
parents:
9355
diff
changeset
|
153 for(y = 0; y < avctx->height; y++) { |
5df11d49abb7
Use dimensions stored in AVCodecContext instead of local variables.
jai_menon
parents:
9355
diff
changeset
|
154 index = y*avctx->width; |
8747 | 155 img_ptr = picture->data[0] + y*picture->linesize[0]; |
9714
5df11d49abb7
Use dimensions stored in AVCodecContext instead of local variables.
jai_menon
parents:
9355
diff
changeset
|
156 for(x = 0; x < avctx->width; x++, index++) { |
8747 | 157 *img_ptr++ = image->comps[0].data[index] >> adjust[0]; |
158 if(image->numcomps > 2 && check_image_attributes(image)) { | |
159 *img_ptr++ = image->comps[1].data[index] >> adjust[1]; | |
160 *img_ptr++ = image->comps[2].data[index] >> adjust[2]; | |
161 if(has_alpha) | |
162 *img_ptr++ = image->comps[3].data[index] >> adjust[3]; | |
163 } | |
164 } | |
165 } | |
166 | |
167 *output = ctx->image; | |
168 *data_size = sizeof(AVPicture); | |
169 ret = buf_size; | |
170 | |
171 done: | |
172 opj_image_destroy(image); | |
173 opj_destroy_decompress(dec); | |
174 return ret; | |
175 } | |
176 | |
177 static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) | |
178 { | |
179 LibOpenJPEGContext *ctx = avctx->priv_data; | |
180 | |
181 if(ctx->image.data[0]) | |
182 avctx->release_buffer(avctx, &ctx->image); | |
183 return 0 ; | |
184 } | |
185 | |
186 | |
187 AVCodec libopenjpeg_decoder = { | |
188 "libopenjpeg", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10737
diff
changeset
|
189 AVMEDIA_TYPE_VIDEO, |
8747 | 190 CODEC_ID_JPEG2000, |
191 sizeof(LibOpenJPEGContext), | |
192 libopenjpeg_decode_init, | |
193 NULL, | |
194 libopenjpeg_decode_close, | |
195 libopenjpeg_decode_frame, | |
9804
00581e706e1d
libopenjpeg wrapper uses get_buffer, set CODEC_CAP_DR1
bcoudurier
parents:
9715
diff
changeset
|
196 CODEC_CAP_DR1, |
12108
c35d7bc64882
Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents:
11644
diff
changeset
|
197 .max_lowres = 5, |
8747 | 198 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), |
199 } ; |