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