Mercurial > libavcodec.hg
annotate libopenjpeg.c @ 9273:42c63846b321 libavcodec
Replace many tiny loops in the interplayvideo decoder by memset, memcpy
or initializers.
author | reimar |
---|---|
date | Sun, 29 Mar 2009 17:23:40 +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 } ; |