Mercurial > libavcodec.hg
annotate libopenjpeg.c @ 9077:ad7fd7a40717 libavcodec
Do not read uninitialized buffer, no matter if it will be multiplied by
zero later. This should fix some valgrind warnings and hopefully FATE
ra144 test on ARM.
author | vitor |
---|---|
date | Sun, 01 Mar 2009 11:14:21 +0000 |
parents | 9575568668c4 |
children | 54bc8a2727b0 |
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 /** | |
23 * @file libavcodec/libopenjpeg.c | |
24 * JPEG 2000 decoder using libopenjpeg | |
25 */ | |
26 | |
27 #include "avcodec.h" | |
28 #include "libavutil/intreadwrite.h" | |
29 #define OPJ_STATIC | |
8787
9575568668c4
Use default system include path for an installed OpenJPEG library.
diego
parents:
8747
diff
changeset
|
30 #include <openjpeg.h> |
8747 | 31 |
32 #define JP2_SIG_TYPE 0x6A502020 | |
33 #define JP2_SIG_VALUE 0x0D0A870A | |
34 | |
35 typedef struct { | |
36 opj_dparameters_t dec_params; | |
37 AVFrame image; | |
38 } LibOpenJPEGContext; | |
39 | |
40 static int check_image_attributes(opj_image_t *image) | |
41 { | |
42 return(image->comps[0].dx == image->comps[1].dx && | |
43 image->comps[1].dx == image->comps[2].dx && | |
44 image->comps[0].dy == image->comps[1].dy && | |
45 image->comps[1].dy == image->comps[2].dy && | |
46 image->comps[0].prec == image->comps[1].prec && | |
47 image->comps[1].prec == image->comps[2].prec); | |
48 } | |
49 | |
50 static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) | |
51 { | |
52 LibOpenJPEGContext *ctx = avctx->priv_data; | |
53 | |
54 opj_set_default_decoder_parameters(&ctx->dec_params); | |
55 avctx->coded_frame = &ctx->image; | |
56 return 0; | |
57 } | |
58 | |
59 static int libopenjpeg_decode_frame(AVCodecContext *avctx, | |
60 void *data, int *data_size, | |
61 const uint8_t *buf, int buf_size) | |
62 { | |
63 LibOpenJPEGContext *ctx = avctx->priv_data; | |
64 AVFrame *picture = &ctx->image, *output = data; | |
65 opj_dinfo_t *dec; | |
66 opj_cio_t *stream; | |
67 opj_image_t *image; | |
68 int width, height, has_alpha = 0, ret = -1; | |
69 int x, y, index; | |
70 uint8_t *img_ptr; | |
71 int adjust[4]; | |
72 | |
73 *data_size = 0; | |
74 | |
75 // Check if input is a raw jpeg2k codestream or in jp2 wrapping | |
76 if((AV_RB32(buf) == 12) && | |
77 (AV_RB32(buf + 4) == JP2_SIG_TYPE) && | |
78 (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { | |
79 dec = opj_create_decompress(CODEC_JP2); | |
80 } else { | |
81 dec = opj_create_decompress(CODEC_J2K); | |
82 } | |
83 | |
84 if(!dec) { | |
85 av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); | |
86 return -1; | |
87 } | |
88 opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); | |
89 | |
90 // Tie decoder with decoding parameters | |
91 opj_setup_decoder(dec, &ctx->dec_params); | |
92 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); | |
93 if(!stream) { | |
94 av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); | |
95 opj_destroy_decompress(dec); | |
96 return -1; | |
97 } | |
98 | |
99 // Decode the codestream | |
100 image = opj_decode_with_info(dec, stream, NULL); | |
101 opj_cio_close(stream); | |
102 if(!image) { | |
103 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); | |
104 opj_destroy_decompress(dec); | |
105 return -1; | |
106 } | |
107 width = image->comps[0].w; | |
108 height = image->comps[0].h; | |
109 if(avcodec_check_dimensions(avctx, width, height) < 0) { | |
110 av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); | |
111 goto done; | |
112 } | |
113 avcodec_set_dimensions(avctx, width, height); | |
114 | |
115 switch(image->numcomps) | |
116 { | |
117 case 1: avctx->pix_fmt = PIX_FMT_GRAY8; | |
118 break; | |
119 case 3: if(check_image_attributes(image)) { | |
120 avctx->pix_fmt = PIX_FMT_RGB24; | |
121 } else { | |
122 avctx->pix_fmt = PIX_FMT_GRAY8; | |
123 av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n"); | |
124 } | |
125 break; | |
126 case 4: has_alpha = 1; | |
127 avctx->pix_fmt = PIX_FMT_RGB32; | |
128 break; | |
129 default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); | |
130 goto done; | |
131 } | |
132 | |
133 if(picture->data[0]) | |
134 avctx->release_buffer(avctx, picture); | |
135 | |
136 if(avctx->get_buffer(avctx, picture) < 0) { | |
137 av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n"); | |
138 return -1; | |
139 } | |
140 | |
141 for(x = 0; x < image->numcomps; x++) { | |
142 adjust[x] = FFMAX(image->comps[x].prec - 8, 0); | |
143 } | |
144 | |
145 for(y = 0; y < height; y++) { | |
146 index = y*width; | |
147 img_ptr = picture->data[0] + y*picture->linesize[0]; | |
148 for(x = 0; x < width; x++, index++) { | |
149 *img_ptr++ = image->comps[0].data[index] >> adjust[0]; | |
150 if(image->numcomps > 2 && check_image_attributes(image)) { | |
151 *img_ptr++ = image->comps[1].data[index] >> adjust[1]; | |
152 *img_ptr++ = image->comps[2].data[index] >> adjust[2]; | |
153 if(has_alpha) | |
154 *img_ptr++ = image->comps[3].data[index] >> adjust[3]; | |
155 } | |
156 } | |
157 } | |
158 | |
159 *output = ctx->image; | |
160 *data_size = sizeof(AVPicture); | |
161 ret = buf_size; | |
162 | |
163 done: | |
164 opj_image_destroy(image); | |
165 opj_destroy_decompress(dec); | |
166 return ret; | |
167 } | |
168 | |
169 static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) | |
170 { | |
171 LibOpenJPEGContext *ctx = avctx->priv_data; | |
172 | |
173 if(ctx->image.data[0]) | |
174 avctx->release_buffer(avctx, &ctx->image); | |
175 return 0 ; | |
176 } | |
177 | |
178 | |
179 AVCodec libopenjpeg_decoder = { | |
180 "libopenjpeg", | |
181 CODEC_TYPE_VIDEO, | |
182 CODEC_ID_JPEG2000, | |
183 sizeof(LibOpenJPEGContext), | |
184 libopenjpeg_decode_init, | |
185 NULL, | |
186 libopenjpeg_decode_close, | |
187 libopenjpeg_decode_frame, | |
188 NULL, | |
189 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), | |
190 } ; |