Libav
|
00001 /* 00002 * JPEG 2000 decoding support via OpenJPEG 00003 * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net> 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg 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 * FFmpeg 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 FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 // Check if input is a raw jpeg2k codestream or in jp2 wrapping 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 // If the AVPacket contains a jp2c box, then skip to 00084 // the starting byte of the codestream. 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 // Tie decoder with decoding parameters 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 // Decode the codestream 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 } ;