Libav 0.7.1
|
00001 /* 00002 * JPEG 2000 decoding support via OpenJPEG 00003 * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net> 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 avctx->coded_frame = &ctx->image; 00057 return 0; 00058 } 00059 00060 static int libopenjpeg_decode_frame(AVCodecContext *avctx, 00061 void *data, int *data_size, 00062 AVPacket *avpkt) 00063 { 00064 const uint8_t *buf = avpkt->data; 00065 int buf_size = avpkt->size; 00066 LibOpenJPEGContext *ctx = avctx->priv_data; 00067 AVFrame *picture = &ctx->image, *output = data; 00068 opj_dinfo_t *dec; 00069 opj_cio_t *stream; 00070 opj_image_t *image; 00071 int width, height, has_alpha = 0, ret = -1; 00072 int x, y, index; 00073 uint8_t *img_ptr; 00074 int adjust[4]; 00075 00076 *data_size = 0; 00077 00078 // Check if input is a raw jpeg2k codestream or in jp2 wrapping 00079 if((AV_RB32(buf) == 12) && 00080 (AV_RB32(buf + 4) == JP2_SIG_TYPE) && 00081 (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { 00082 dec = opj_create_decompress(CODEC_JP2); 00083 } else { 00084 // If the AVPacket contains a jp2c box, then skip to 00085 // the starting byte of the codestream. 00086 if (AV_RB32(buf + 4) == AV_RB32("jp2c")) 00087 buf += 8; 00088 dec = opj_create_decompress(CODEC_J2K); 00089 } 00090 00091 if(!dec) { 00092 av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); 00093 return -1; 00094 } 00095 opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); 00096 00097 ctx->dec_params.cp_reduce = avctx->lowres; 00098 // Tie decoder with decoding parameters 00099 opj_setup_decoder(dec, &ctx->dec_params); 00100 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); 00101 if(!stream) { 00102 av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); 00103 opj_destroy_decompress(dec); 00104 return -1; 00105 } 00106 00107 // Decode the codestream 00108 image = opj_decode_with_info(dec, stream, NULL); 00109 opj_cio_close(stream); 00110 if(!image) { 00111 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); 00112 opj_destroy_decompress(dec); 00113 return -1; 00114 } 00115 width = image->comps[0].w << avctx->lowres; 00116 height = image->comps[0].h << avctx->lowres; 00117 if(av_image_check_size(width, height, 0, avctx) < 0) { 00118 av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); 00119 goto done; 00120 } 00121 avcodec_set_dimensions(avctx, width, height); 00122 00123 switch(image->numcomps) 00124 { 00125 case 1: avctx->pix_fmt = PIX_FMT_GRAY8; 00126 break; 00127 case 3: if(check_image_attributes(image)) { 00128 avctx->pix_fmt = PIX_FMT_RGB24; 00129 } else { 00130 avctx->pix_fmt = PIX_FMT_GRAY8; 00131 av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n"); 00132 } 00133 break; 00134 case 4: has_alpha = 1; 00135 avctx->pix_fmt = PIX_FMT_RGBA; 00136 break; 00137 default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); 00138 goto done; 00139 } 00140 00141 if(picture->data[0]) 00142 avctx->release_buffer(avctx, picture); 00143 00144 if(avctx->get_buffer(avctx, picture) < 0) { 00145 av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n"); 00146 return -1; 00147 } 00148 00149 for(x = 0; x < image->numcomps; x++) { 00150 adjust[x] = FFMAX(image->comps[x].prec - 8, 0); 00151 } 00152 00153 for(y = 0; y < avctx->height; y++) { 00154 index = y*avctx->width; 00155 img_ptr = picture->data[0] + y*picture->linesize[0]; 00156 for(x = 0; x < avctx->width; x++, index++) { 00157 *img_ptr++ = image->comps[0].data[index] >> adjust[0]; 00158 if(image->numcomps > 2 && check_image_attributes(image)) { 00159 *img_ptr++ = image->comps[1].data[index] >> adjust[1]; 00160 *img_ptr++ = image->comps[2].data[index] >> adjust[2]; 00161 if(has_alpha) 00162 *img_ptr++ = image->comps[3].data[index] >> adjust[3]; 00163 } 00164 } 00165 } 00166 00167 *output = ctx->image; 00168 *data_size = sizeof(AVPicture); 00169 ret = buf_size; 00170 00171 done: 00172 opj_image_destroy(image); 00173 opj_destroy_decompress(dec); 00174 return ret; 00175 } 00176 00177 static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) 00178 { 00179 LibOpenJPEGContext *ctx = avctx->priv_data; 00180 00181 if(ctx->image.data[0]) 00182 avctx->release_buffer(avctx, &ctx->image); 00183 return 0 ; 00184 } 00185 00186 00187 AVCodec ff_libopenjpeg_decoder = { 00188 "libopenjpeg", 00189 AVMEDIA_TYPE_VIDEO, 00190 CODEC_ID_JPEG2000, 00191 sizeof(LibOpenJPEGContext), 00192 libopenjpeg_decode_init, 00193 NULL, 00194 libopenjpeg_decode_close, 00195 libopenjpeg_decode_frame, 00196 CODEC_CAP_DR1, 00197 .max_lowres = 5, 00198 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), 00199 } ;