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