Mercurial > libavcodec.hg
annotate libopenjpeg.c @ 11803:f443ef5ec4e2 libavcodec
Cosmetics: consistently apply K&R style.
Make me and Diego happy.
| author | stefano |
|---|---|
| date | Tue, 01 Jun 2010 08:07:15 +0000 |
| parents | 7dd2a45249a9 |
| children | c35d7bc64882 |
| 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 | |
| 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 { | |
|
10436
a050e8857f00
cosmetics: Remove pointless parentheses from return statement.
diego
parents:
9804
diff
changeset
|
42 return image->comps[0].dx == image->comps[1].dx && |
| 8747 | 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 && | |
|
10436
a050e8857f00
cosmetics: Remove pointless parentheses from return statement.
diego
parents:
9804
diff
changeset
|
47 image->comps[1].prec == image->comps[2].prec; |
| 8747 | 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, | |
|
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8787
diff
changeset
|
61 AVPacket *avpkt) |
| 8747 | 62 { |
|
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8787
diff
changeset
|
63 const uint8_t *buf = avpkt->data; |
|
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8787
diff
changeset
|
64 int buf_size = avpkt->size; |
| 8747 | 65 LibOpenJPEGContext *ctx = avctx->priv_data; |
| 66 AVFrame *picture = &ctx->image, *output = data; | |
| 67 opj_dinfo_t *dec; | |
| 68 opj_cio_t *stream; | |
| 69 opj_image_t *image; | |
| 70 int width, height, has_alpha = 0, ret = -1; | |
| 71 int x, y, index; | |
| 72 uint8_t *img_ptr; | |
| 73 int adjust[4]; | |
| 74 | |
| 75 *data_size = 0; | |
| 76 | |
| 77 // Check if input is a raw jpeg2k codestream or in jp2 wrapping | |
| 78 if((AV_RB32(buf) == 12) && | |
| 79 (AV_RB32(buf + 4) == JP2_SIG_TYPE) && | |
| 80 (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { | |
| 10507 | 81 dec = opj_create_decompress(CODEC_JP2); |
| 8747 | 82 } else { |
|
10508
f33404f82b9e
Handle JPEG2000 frames stored in the Quicktime container.
jai_menon
parents:
10507
diff
changeset
|
83 // 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
|
84 // the starting byte of the codestream. |
|
f33404f82b9e
Handle JPEG2000 frames stored in the Quicktime container.
jai_menon
parents:
10507
diff
changeset
|
85 if (AV_RB32(buf + 4) == AV_RB32("jp2c")) |
|
f33404f82b9e
Handle JPEG2000 frames stored in the Quicktime container.
jai_menon
parents:
10507
diff
changeset
|
86 buf += 8; |
| 10507 | 87 dec = opj_create_decompress(CODEC_J2K); |
| 8747 | 88 } |
| 89 | |
| 90 if(!dec) { | |
| 91 av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); | |
| 92 return -1; | |
| 93 } | |
| 94 opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); | |
| 95 | |
| 9715 | 96 ctx->dec_params.cp_reduce = avctx->lowres; |
| 8747 | 97 // Tie decoder with decoding parameters |
| 98 opj_setup_decoder(dec, &ctx->dec_params); | |
| 99 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); | |
| 100 if(!stream) { | |
| 101 av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); | |
| 102 opj_destroy_decompress(dec); | |
| 103 return -1; | |
| 104 } | |
| 105 | |
| 106 // Decode the codestream | |
| 107 image = opj_decode_with_info(dec, stream, NULL); | |
| 108 opj_cio_close(stream); | |
| 109 if(!image) { | |
| 110 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); | |
| 111 opj_destroy_decompress(dec); | |
| 112 return -1; | |
| 113 } | |
| 9715 | 114 width = image->comps[0].w << avctx->lowres; |
| 115 height = image->comps[0].h << avctx->lowres; | |
| 8747 | 116 if(avcodec_check_dimensions(avctx, width, height) < 0) { |
| 117 av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); | |
| 118 goto done; | |
| 119 } | |
| 120 avcodec_set_dimensions(avctx, width, height); | |
| 121 | |
| 122 switch(image->numcomps) | |
| 123 { | |
| 124 case 1: avctx->pix_fmt = PIX_FMT_GRAY8; | |
| 125 break; | |
| 126 case 3: if(check_image_attributes(image)) { | |
| 127 avctx->pix_fmt = PIX_FMT_RGB24; | |
| 128 } else { | |
| 129 avctx->pix_fmt = PIX_FMT_GRAY8; | |
| 130 av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n"); | |
| 131 } | |
| 132 break; | |
| 133 case 4: has_alpha = 1; | |
| 10737 | 134 avctx->pix_fmt = PIX_FMT_RGBA; |
| 8747 | 135 break; |
| 136 default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); | |
| 137 goto done; | |
| 138 } | |
| 139 | |
| 140 if(picture->data[0]) | |
| 141 avctx->release_buffer(avctx, picture); | |
| 142 | |
| 143 if(avctx->get_buffer(avctx, picture) < 0) { | |
| 144 av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n"); | |
| 145 return -1; | |
| 146 } | |
| 147 | |
| 148 for(x = 0; x < image->numcomps; x++) { | |
| 149 adjust[x] = FFMAX(image->comps[x].prec - 8, 0); | |
| 150 } | |
| 151 | |
|
9714
5df11d49abb7
Use dimensions stored in AVCodecContext instead of local variables.
jai_menon
parents:
9355
diff
changeset
|
152 for(y = 0; y < avctx->height; y++) { |
|
5df11d49abb7
Use dimensions stored in AVCodecContext instead of local variables.
jai_menon
parents:
9355
diff
changeset
|
153 index = y*avctx->width; |
| 8747 | 154 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
|
155 for(x = 0; x < avctx->width; x++, index++) { |
| 8747 | 156 *img_ptr++ = image->comps[0].data[index] >> adjust[0]; |
| 157 if(image->numcomps > 2 && check_image_attributes(image)) { | |
| 158 *img_ptr++ = image->comps[1].data[index] >> adjust[1]; | |
| 159 *img_ptr++ = image->comps[2].data[index] >> adjust[2]; | |
| 160 if(has_alpha) | |
| 161 *img_ptr++ = image->comps[3].data[index] >> adjust[3]; | |
| 162 } | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 *output = ctx->image; | |
| 167 *data_size = sizeof(AVPicture); | |
| 168 ret = buf_size; | |
| 169 | |
| 170 done: | |
| 171 opj_image_destroy(image); | |
| 172 opj_destroy_decompress(dec); | |
| 173 return ret; | |
| 174 } | |
| 175 | |
| 176 static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) | |
| 177 { | |
| 178 LibOpenJPEGContext *ctx = avctx->priv_data; | |
| 179 | |
| 180 if(ctx->image.data[0]) | |
| 181 avctx->release_buffer(avctx, &ctx->image); | |
| 182 return 0 ; | |
| 183 } | |
| 184 | |
| 185 | |
| 186 AVCodec libopenjpeg_decoder = { | |
| 187 "libopenjpeg", | |
|
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10737
diff
changeset
|
188 AVMEDIA_TYPE_VIDEO, |
| 8747 | 189 CODEC_ID_JPEG2000, |
| 190 sizeof(LibOpenJPEGContext), | |
| 191 libopenjpeg_decode_init, | |
| 192 NULL, | |
| 193 libopenjpeg_decode_close, | |
| 194 libopenjpeg_decode_frame, | |
|
9804
00581e706e1d
libopenjpeg wrapper uses get_buffer, set CODEC_CAP_DR1
bcoudurier
parents:
9715
diff
changeset
|
195 CODEC_CAP_DR1, |
| 8747 | 196 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), |
| 197 } ; |
