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/** 23* @file libavcodec/libopenjpeg.c 24* JPEG 2000 decoder using libopenjpeg 25*/ 26 27#include "avcodec.h" 28#include "libavutil/intreadwrite.h" 29#define OPJ_STATIC 30#include <openjpeg.h> 31 32#define JP2_SIG_TYPE 0x6A502020 33#define JP2_SIG_VALUE 0x0D0A870A 34 35typedef struct { 36 opj_dparameters_t dec_params; 37 AVFrame image; 38} LibOpenJPEGContext; 39 40static int check_image_attributes(opj_image_t *image) 41{ 42 return(image->comps[0].dx == image->comps[1].dx && 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 && 47 image->comps[1].prec == image->comps[2].prec); 48} 49 50static 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 59static int libopenjpeg_decode_frame(AVCodecContext *avctx, 60 void *data, int *data_size, 61 const uint8_t *buf, int buf_size) 62{ 63 LibOpenJPEGContext *ctx = avctx->priv_data; 64 AVFrame *picture = &ctx->image, *output = data; 65 opj_dinfo_t *dec; 66 opj_cio_t *stream; 67 opj_image_t *image; 68 int width, height, has_alpha = 0, ret = -1; 69 int x, y, index; 70 uint8_t *img_ptr; 71 int adjust[4]; 72 73 *data_size = 0; 74 75 // Check if input is a raw jpeg2k codestream or in jp2 wrapping 76 if((AV_RB32(buf) == 12) && 77 (AV_RB32(buf + 4) == JP2_SIG_TYPE) && 78 (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { 79 dec = opj_create_decompress(CODEC_JP2); 80 } else { 81 dec = opj_create_decompress(CODEC_J2K); 82 } 83 84 if(!dec) { 85 av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); 86 return -1; 87 } 88 opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); 89 90 // Tie decoder with decoding parameters 91 opj_setup_decoder(dec, &ctx->dec_params); 92 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); 93 if(!stream) { 94 av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); 95 opj_destroy_decompress(dec); 96 return -1; 97 } 98 99 // Decode the codestream 100 image = opj_decode_with_info(dec, stream, NULL); 101 opj_cio_close(stream); 102 if(!image) { 103 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); 104 opj_destroy_decompress(dec); 105 return -1; 106 } 107 width = image->comps[0].w; 108 height = image->comps[0].h; 109 if(avcodec_check_dimensions(avctx, width, height) < 0) { 110 av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); 111 goto done; 112 } 113 avcodec_set_dimensions(avctx, width, height); 114 115 switch(image->numcomps) 116 { 117 case 1: avctx->pix_fmt = PIX_FMT_GRAY8; 118 break; 119 case 3: if(check_image_attributes(image)) { 120 avctx->pix_fmt = PIX_FMT_RGB24; 121 } else { 122 avctx->pix_fmt = PIX_FMT_GRAY8; 123 av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n"); 124 } 125 break; 126 case 4: has_alpha = 1; 127 avctx->pix_fmt = PIX_FMT_RGB32; 128 break; 129 default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); 130 goto done; 131 } 132 133 if(picture->data[0]) 134 avctx->release_buffer(avctx, picture); 135 136 if(avctx->get_buffer(avctx, picture) < 0) { 137 av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n"); 138 return -1; 139 } 140 141 for(x = 0; x < image->numcomps; x++) { 142 adjust[x] = FFMAX(image->comps[x].prec - 8, 0); 143 } 144 145 for(y = 0; y < height; y++) { 146 index = y*width; 147 img_ptr = picture->data[0] + y*picture->linesize[0]; 148 for(x = 0; x < width; x++, index++) { 149 *img_ptr++ = image->comps[0].data[index] >> adjust[0]; 150 if(image->numcomps > 2 && check_image_attributes(image)) { 151 *img_ptr++ = image->comps[1].data[index] >> adjust[1]; 152 *img_ptr++ = image->comps[2].data[index] >> adjust[2]; 153 if(has_alpha) 154 *img_ptr++ = image->comps[3].data[index] >> adjust[3]; 155 } 156 } 157 } 158 159 *output = ctx->image; 160 *data_size = sizeof(AVPicture); 161 ret = buf_size; 162 163done: 164 opj_image_destroy(image); 165 opj_destroy_decompress(dec); 166 return ret; 167} 168 169static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) 170{ 171 LibOpenJPEGContext *ctx = avctx->priv_data; 172 173 if(ctx->image.data[0]) 174 avctx->release_buffer(avctx, &ctx->image); 175 return 0 ; 176} 177 178 179AVCodec libopenjpeg_decoder = { 180 "libopenjpeg", 181 CODEC_TYPE_VIDEO, 182 CODEC_ID_JPEG2000, 183 sizeof(LibOpenJPEGContext), 184 libopenjpeg_decode_init, 185 NULL, 186 libopenjpeg_decode_close, 187 libopenjpeg_decode_frame, 188 NULL, 189 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), 190} ; 191