00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #include "libavutil/intreadwrite.h"
00029 #define OPJ_STATIC
00030 #include <openjpeg.h>
00031
00032 #define JP2_SIG_TYPE 0x6A502020
00033 #define JP2_SIG_VALUE 0x0D0A870A
00034
00035 typedef struct {
00036 opj_dparameters_t dec_params;
00037 AVFrame image;
00038 } LibOpenJPEGContext;
00039
00040 static int check_image_attributes(opj_image_t *image)
00041 {
00042 return image->comps[0].dx == image->comps[1].dx &&
00043 image->comps[1].dx == image->comps[2].dx &&
00044 image->comps[0].dy == image->comps[1].dy &&
00045 image->comps[1].dy == image->comps[2].dy &&
00046 image->comps[0].prec == image->comps[1].prec &&
00047 image->comps[1].prec == image->comps[2].prec;
00048 }
00049
00050 static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
00051 {
00052 LibOpenJPEGContext *ctx = avctx->priv_data;
00053
00054 opj_set_default_decoder_parameters(&ctx->dec_params);
00055 avctx->coded_frame = &ctx->image;
00056 return 0;
00057 }
00058
00059 static int libopenjpeg_decode_frame(AVCodecContext *avctx,
00060 void *data, int *data_size,
00061 AVPacket *avpkt)
00062 {
00063 const uint8_t *buf = avpkt->data;
00064 int buf_size = avpkt->size;
00065 LibOpenJPEGContext *ctx = avctx->priv_data;
00066 AVFrame *picture = &ctx->image, *output = data;
00067 opj_dinfo_t *dec;
00068 opj_cio_t *stream;
00069 opj_image_t *image;
00070 int width, height, has_alpha = 0, ret = -1;
00071 int x, y, index;
00072 uint8_t *img_ptr;
00073 int adjust[4];
00074
00075 *data_size = 0;
00076
00077
00078 if((AV_RB32(buf) == 12) &&
00079 (AV_RB32(buf + 4) == JP2_SIG_TYPE) &&
00080 (AV_RB32(buf + 8) == JP2_SIG_VALUE)) {
00081 dec = opj_create_decompress(CODEC_JP2);
00082 } else {
00083
00084
00085 if (AV_RB32(buf + 4) == AV_RB32("jp2c"))
00086 buf += 8;
00087 dec = opj_create_decompress(CODEC_J2K);
00088 }
00089
00090 if(!dec) {
00091 av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
00092 return -1;
00093 }
00094 opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
00095
00096 ctx->dec_params.cp_reduce = avctx->lowres;
00097
00098 opj_setup_decoder(dec, &ctx->dec_params);
00099 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
00100 if(!stream) {
00101 av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
00102 opj_destroy_decompress(dec);
00103 return -1;
00104 }
00105
00106
00107 image = opj_decode_with_info(dec, stream, NULL);
00108 opj_cio_close(stream);
00109 if(!image) {
00110 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
00111 opj_destroy_decompress(dec);
00112 return -1;
00113 }
00114 width = image->comps[0].w << avctx->lowres;
00115 height = image->comps[0].h << avctx->lowres;
00116 if(avcodec_check_dimensions(avctx, width, height) < 0) {
00117 av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
00118 goto done;
00119 }
00120 avcodec_set_dimensions(avctx, width, height);
00121
00122 switch(image->numcomps)
00123 {
00124 case 1: avctx->pix_fmt = PIX_FMT_GRAY8;
00125 break;
00126 case 3: if(check_image_attributes(image)) {
00127 avctx->pix_fmt = PIX_FMT_RGB24;
00128 } else {
00129 avctx->pix_fmt = PIX_FMT_GRAY8;
00130 av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n");
00131 }
00132 break;
00133 case 4: has_alpha = 1;
00134 avctx->pix_fmt = PIX_FMT_RGBA;
00135 break;
00136 default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps);
00137 goto done;
00138 }
00139
00140 if(picture->data[0])
00141 avctx->release_buffer(avctx, picture);
00142
00143 if(avctx->get_buffer(avctx, picture) < 0) {
00144 av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n");
00145 return -1;
00146 }
00147
00148 for(x = 0; x < image->numcomps; x++) {
00149 adjust[x] = FFMAX(image->comps[x].prec - 8, 0);
00150 }
00151
00152 for(y = 0; y < avctx->height; y++) {
00153 index = y*avctx->width;
00154 img_ptr = picture->data[0] + y*picture->linesize[0];
00155 for(x = 0; x < avctx->width; x++, index++) {
00156 *img_ptr++ = image->comps[0].data[index] >> adjust[0];
00157 if(image->numcomps > 2 && check_image_attributes(image)) {
00158 *img_ptr++ = image->comps[1].data[index] >> adjust[1];
00159 *img_ptr++ = image->comps[2].data[index] >> adjust[2];
00160 if(has_alpha)
00161 *img_ptr++ = image->comps[3].data[index] >> adjust[3];
00162 }
00163 }
00164 }
00165
00166 *output = ctx->image;
00167 *data_size = sizeof(AVPicture);
00168 ret = buf_size;
00169
00170 done:
00171 opj_image_destroy(image);
00172 opj_destroy_decompress(dec);
00173 return ret;
00174 }
00175
00176 static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx)
00177 {
00178 LibOpenJPEGContext *ctx = avctx->priv_data;
00179
00180 if(ctx->image.data[0])
00181 avctx->release_buffer(avctx, &ctx->image);
00182 return 0 ;
00183 }
00184
00185
00186 AVCodec libopenjpeg_decoder = {
00187 "libopenjpeg",
00188 AVMEDIA_TYPE_VIDEO,
00189 CODEC_ID_JPEG2000,
00190 sizeof(LibOpenJPEGContext),
00191 libopenjpeg_decode_init,
00192 NULL,
00193 libopenjpeg_decode_close,
00194 libopenjpeg_decode_frame,
00195 CODEC_CAP_DR1,
00196 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"),
00197 } ;