Mercurial > libavcodec.hg
annotate libopenjpeg.c @ 12391:4be72e19ab0e libavcodec
imc: fix undefined float to int conversion
Conversion of an out of range float to int is undefined. Clipping to
the final range first avoids such problems. This fixes decoding on
MIPS, which handles these conversions differently from many other CPUs.
author | mru |
---|---|
date | Thu, 19 Aug 2010 16:51:26 +0000 |
parents | 7e9b2d528e59 |
children | ffb3668ff7af |
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; | |
12372
914f484bb476
Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents:
12108
diff
changeset
|
117 if(av_check_image_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 } ; |