1/* 2 * JPEG 2000 decoding support via OpenJPEG 3 * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net> 4 * 5 * This file is part of Libav. 6 * 7 * Libav 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 * Libav 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 Libav; 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 "libavutil/imgutils.h" 28#include "avcodec.h" 29#include "libavutil/intreadwrite.h" 30#include "thread.h" 31#define OPJ_STATIC 32#include <openjpeg.h> 33 34#define JP2_SIG_TYPE 0x6A502020 35#define JP2_SIG_VALUE 0x0D0A870A 36 37typedef struct { 38 opj_dparameters_t dec_params; 39 AVFrame image; 40} LibOpenJPEGContext; 41 42static int check_image_attributes(opj_image_t *image) 43{ 44 return image->comps[0].dx == image->comps[1].dx && 45 image->comps[1].dx == image->comps[2].dx && 46 image->comps[0].dy == image->comps[1].dy && 47 image->comps[1].dy == image->comps[2].dy && 48 image->comps[0].prec == image->comps[1].prec && 49 image->comps[1].prec == image->comps[2].prec; 50} 51 52static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) 53{ 54 LibOpenJPEGContext *ctx = avctx->priv_data; 55 56 opj_set_default_decoder_parameters(&ctx->dec_params); 57 avctx->coded_frame = &ctx->image; 58 return 0; 59} 60 61static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx) 62{ 63 LibOpenJPEGContext *ctx = avctx->priv_data; 64 65 avctx->coded_frame = &ctx->image; 66 return 0; 67} 68 69static int libopenjpeg_decode_frame(AVCodecContext *avctx, 70 void *data, int *data_size, 71 AVPacket *avpkt) 72{ 73 uint8_t *buf = avpkt->data; 74 int buf_size = avpkt->size; 75 LibOpenJPEGContext *ctx = avctx->priv_data; 76 AVFrame *picture = &ctx->image, *output = data; 77 opj_dinfo_t *dec; 78 opj_cio_t *stream; 79 opj_image_t *image; 80 int width, height, has_alpha = 0, ret = -1; 81 int x, y, index; 82 uint8_t *img_ptr; 83 int adjust[4]; 84 85 *data_size = 0; 86 87 // Check if input is a raw jpeg2k codestream or in jp2 wrapping 88 if((AV_RB32(buf) == 12) && 89 (AV_RB32(buf + 4) == JP2_SIG_TYPE) && 90 (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { 91 dec = opj_create_decompress(CODEC_JP2); 92 } else { 93 // If the AVPacket contains a jp2c box, then skip to 94 // the starting byte of the codestream. 95 if (AV_RB32(buf + 4) == AV_RB32("jp2c")) 96 buf += 8; 97 dec = opj_create_decompress(CODEC_J2K); 98 } 99 100 if(!dec) { 101 av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); 102 return -1; 103 } 104 opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); 105 106 ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; 107 // Tie decoder with decoding parameters 108 opj_setup_decoder(dec, &ctx->dec_params); 109 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); 110 if(!stream) { 111 av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); 112 opj_destroy_decompress(dec); 113 return -1; 114 } 115 116 // Decode the header only 117 image = opj_decode_with_info(dec, stream, NULL); 118 opj_cio_close(stream); 119 if(!image) { 120 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); 121 opj_destroy_decompress(dec); 122 return -1; 123 } 124 width = image->x1 - image->x0; 125 height = image->y1 - image->y0; 126 if(av_image_check_size(width, height, 0, avctx) < 0) { 127 av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); 128 goto done; 129 } 130 avcodec_set_dimensions(avctx, width, height); 131 132 switch(image->numcomps) 133 { 134 case 1: avctx->pix_fmt = PIX_FMT_GRAY8; 135 break; 136 case 3: if(check_image_attributes(image)) { 137 avctx->pix_fmt = PIX_FMT_RGB24; 138 } else { 139 avctx->pix_fmt = PIX_FMT_GRAY8; 140 av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n"); 141 } 142 break; 143 case 4: has_alpha = 1; 144 avctx->pix_fmt = PIX_FMT_RGBA; 145 break; 146 default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); 147 goto done; 148 } 149 150 if(picture->data[0]) 151 ff_thread_release_buffer(avctx, picture); 152 153 if(ff_thread_get_buffer(avctx, picture) < 0){ 154 av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n"); 155 return -1; 156 } 157 158 ff_thread_finish_setup(avctx); 159 160 ctx->dec_params.cp_limit_decoding = NO_LIMITATION; 161 ctx->dec_params.cp_reduce = avctx->lowres; 162 // Tie decoder with decoding parameters 163 opj_setup_decoder(dec, &ctx->dec_params); 164 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); 165 if(!stream) { 166 av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); 167 opj_destroy_decompress(dec); 168 return -1; 169 } 170 171 // Decode the codestream 172 image = opj_decode_with_info(dec, stream, NULL); 173 opj_cio_close(stream); 174 175 for(x = 0; x < image->numcomps; x++) { 176 adjust[x] = FFMAX(image->comps[x].prec - 8, 0); 177 } 178 179 for(y = 0; y < avctx->height; y++) { 180 index = y*avctx->width; 181 img_ptr = picture->data[0] + y*picture->linesize[0]; 182 for(x = 0; x < avctx->width; x++, index++) { 183 *img_ptr++ = image->comps[0].data[index] >> adjust[0]; 184 if(image->numcomps > 2 && check_image_attributes(image)) { 185 *img_ptr++ = image->comps[1].data[index] >> adjust[1]; 186 *img_ptr++ = image->comps[2].data[index] >> adjust[2]; 187 if(has_alpha) 188 *img_ptr++ = image->comps[3].data[index] >> adjust[3]; 189 } 190 } 191 } 192 193 *output = ctx->image; 194 *data_size = sizeof(AVPicture); 195 ret = buf_size; 196 197done: 198 opj_image_destroy(image); 199 opj_destroy_decompress(dec); 200 return ret; 201} 202 203static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) 204{ 205 LibOpenJPEGContext *ctx = avctx->priv_data; 206 207 if(ctx->image.data[0]) 208 ff_thread_release_buffer(avctx, &ctx->image); 209 return 0 ; 210} 211 212 213AVCodec ff_libopenjpeg_decoder = { 214 .name = "libopenjpeg", 215 .type = AVMEDIA_TYPE_VIDEO, 216 .id = CODEC_ID_JPEG2000, 217 .priv_data_size = sizeof(LibOpenJPEGContext), 218 .init = libopenjpeg_decode_init, 219 .close = libopenjpeg_decode_close, 220 .decode = libopenjpeg_decode_frame, 221 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, 222 .max_lowres = 5, 223 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), 224 .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy) 225}; 226