Skip to content
Snippets Groups Projects
Commit 9a77d59a authored by Jai Menon's avatar Jai Menon Committed by Carl Eugen Hoyos
Browse files

Use libopenjpeg for jpeg2k decoding.

Patch by Jaikrishnan Menon

Originally committed as revision 17017 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 302879cb
No related branches found
No related tags found
No related merge requests found
......@@ -147,6 +147,7 @@ version <next>
- R3D REDCODE demuxer
- ALSA support for playback and record
- Electronic Arts TQI decoder
- OpenJPEG based JPEG 2000 decoder
version 0.4.9-pre1:
......
......@@ -145,6 +145,7 @@ Codecs:
kmvc.c Kostya Shishkov
lcl*.c Roberto Togni
libgsm.c Michel Bardiaux
libopenjpeg.c Jaikrishnan Menon
libx264.c Mans Rullgard, Jason Garrett-Glaser
loco.c Kostya Shishkov
lzo.h, lzo.c Reimar Doeffinger
......
......@@ -159,6 +159,7 @@ show_help(){
echo " --enable-libmp3lame enable MP3 encoding via libmp3lame [no]"
echo " --enable-libnut enable NUT (de)muxing via libnut,"
echo " native (de)muxer exists [no]"
echo " --enable-libopenjpeg enable JPEG 2000 decoding via OpenJPEG [no]"
echo " --enable-libschroedinger enable Dirac support via libschroedinger [no]"
echo " --enable-libspeex enable Speex decoding via libspeex [no]"
echo " --enable-libtheora enable Theora encoding via libtheora [no]"
......@@ -769,6 +770,7 @@ CONFIG_LIST="
libgsm
libmp3lame
libnut
libopenjpeg
libschroedinger
libspeex
libtheora
......@@ -1062,6 +1064,7 @@ libgsm_encoder_deps="libgsm"
libgsm_ms_decoder_deps="libgsm"
libgsm_ms_encoder_deps="libgsm"
libmp3lame_encoder_deps="libmp3lame"
libopenjpeg_decoder_deps="libopenjpeg"
libschroedinger_decoder_deps="libschroedinger"
libschroedinger_encoder_deps="libschroedinger"
libspeex_decoder_deps="libspeex"
......@@ -1928,6 +1931,7 @@ enabled libfaad && require2 libfaad faad.h faacDecOpen -lfaad
enabled libgsm && require libgsm gsm.h gsm_create -lgsm
enabled libmp3lame && require libmp3lame lame/lame.h lame_init -lmp3lame -lm
enabled libnut && require libnut libnut.h nut_demuxer_init -lnut
enabled libopenjpeg && require libopenjpeg libopenjpeg/openjpeg.h opj_version -lopenjpeg
enabled libschroedinger && add_cflags $(pkg-config --cflags schroedinger-1.0) &&
require libschroedinger schroedinger/schro.h schro_init $(pkg-config --libs schroedinger-1.0)
enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex
......@@ -2243,6 +2247,7 @@ echo "libfaad dlopened ${libfaadbin-no}"
echo "libgsm enabled ${libgsm-no}"
echo "libmp3lame enabled ${libmp3lame-no}"
echo "libnut enabled ${libnut-no}"
echo "libopenjpeg enabled ${libopenjpeg-no}"
echo "libschroedinger enabled ${libschroedinger-no}"
echo "libspeex enabled ${libspeex-no}"
echo "libtheora enabled ${libtheora-no}"
......
......@@ -162,6 +162,7 @@ following image formats are supported:
@item .Y.U.V @tab X @tab X @tab one raw file per component
@item animated GIF @tab X @tab X @tab Only uncompressed GIFs are generated.
@item JPEG @tab X @tab X @tab Progressive JPEG is not supported.
@item JPEG 2000 @tab @tab E @tab decoding supported through external library libopenjpeg
@item PAM @tab X @tab X @tab PAM is a PNM extension with alpha support.
@item PCX @tab @tab X @tab PC Paintbrush
@item PGM, PPM @tab X @tab X
......@@ -176,6 +177,8 @@ following image formats are supported:
@code{X} means that encoding (resp. decoding) is supported.
@code{E} means that support is provided through an external library.
@section Video Codecs
@multitable @columnfractions .4 .1 .1 .4
......
......@@ -353,6 +353,7 @@ OBJS-$(CONFIG_LIBFAAC) += libfaac.o
OBJS-$(CONFIG_LIBFAAD) += libfaad.o
OBJS-$(CONFIG_LIBGSM) += libgsm.o
OBJS-$(CONFIG_LIBMP3LAME) += libmp3lame.o
OBJS-$(CONFIG_LIBOPENJPEG) += libopenjpeg.o
OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o libschroedinger.o libdirac_libschro.o
OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o libschroedinger.o libdirac_libschro.o
OBJS-$(CONFIG_LIBSPEEX) += libspeexdec.o
......
......@@ -294,6 +294,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (LIBGSM, libgsm);
REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms);
REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
REGISTER_DECODER (LIBOPENJPEG, libopenjpeg);
REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger);
REGISTER_DECODER (LIBSPEEX, libspeex);
REGISTER_ENCODER (LIBTHEORA, libtheora);
......
......@@ -30,7 +30,7 @@
#include "libavutil/avutil.h"
#define LIBAVCODEC_VERSION_MAJOR 52
#define LIBAVCODEC_VERSION_MINOR 12
#define LIBAVCODEC_VERSION_MINOR 13
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
......
/*
* JPEG 2000 decoding support via OpenJPEG
* Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavcodec/libopenjpeg.c
* JPEG 2000 decoder using libopenjpeg
*/
#include "avcodec.h"
#include "libavutil/intreadwrite.h"
#define OPJ_STATIC
#include <libopenjpeg/openjpeg.h>
#define JP2_SIG_TYPE 0x6A502020
#define JP2_SIG_VALUE 0x0D0A870A
typedef struct {
opj_dparameters_t dec_params;
AVFrame image;
} LibOpenJPEGContext;
static int check_image_attributes(opj_image_t *image)
{
return(image->comps[0].dx == image->comps[1].dx &&
image->comps[1].dx == image->comps[2].dx &&
image->comps[0].dy == image->comps[1].dy &&
image->comps[1].dy == image->comps[2].dy &&
image->comps[0].prec == image->comps[1].prec &&
image->comps[1].prec == image->comps[2].prec);
}
static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
{
LibOpenJPEGContext *ctx = avctx->priv_data;
opj_set_default_decoder_parameters(&ctx->dec_params);
avctx->coded_frame = &ctx->image;
return 0;
}
static int libopenjpeg_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
const uint8_t *buf, int buf_size)
{
LibOpenJPEGContext *ctx = avctx->priv_data;
AVFrame *picture = &ctx->image, *output = data;
opj_dinfo_t *dec;
opj_cio_t *stream;
opj_image_t *image;
int width, height, has_alpha = 0, ret = -1;
int x, y, index;
uint8_t *img_ptr;
int adjust[4];
*data_size = 0;
// Check if input is a raw jpeg2k codestream or in jp2 wrapping
if((AV_RB32(buf) == 12) &&
(AV_RB32(buf + 4) == JP2_SIG_TYPE) &&
(AV_RB32(buf + 8) == JP2_SIG_VALUE)) {
dec = opj_create_decompress(CODEC_JP2);
} else {
dec = opj_create_decompress(CODEC_J2K);
}
if(!dec) {
av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
return -1;
}
opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
// Tie decoder with decoding parameters
opj_setup_decoder(dec, &ctx->dec_params);
stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
if(!stream) {
av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
opj_destroy_decompress(dec);
return -1;
}
// Decode the codestream
image = opj_decode_with_info(dec, stream, NULL);
opj_cio_close(stream);
if(!image) {
av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
opj_destroy_decompress(dec);
return -1;
}
width = image->comps[0].w;
height = image->comps[0].h;
if(avcodec_check_dimensions(avctx, width, height) < 0) {
av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
goto done;
}
avcodec_set_dimensions(avctx, width, height);
switch(image->numcomps)
{
case 1: avctx->pix_fmt = PIX_FMT_GRAY8;
break;
case 3: if(check_image_attributes(image)) {
avctx->pix_fmt = PIX_FMT_RGB24;
} else {
avctx->pix_fmt = PIX_FMT_GRAY8;
av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n");
}
break;
case 4: has_alpha = 1;
avctx->pix_fmt = PIX_FMT_RGB32;
break;
default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps);
goto done;
}
if(picture->data[0])
avctx->release_buffer(avctx, picture);
if(avctx->get_buffer(avctx, picture) < 0) {
av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n");
return -1;
}
for(x = 0; x < image->numcomps; x++) {
adjust[x] = FFMAX(image->comps[x].prec - 8, 0);
}
for(y = 0; y < height; y++) {
index = y*width;
img_ptr = picture->data[0] + y*picture->linesize[0];
for(x = 0; x < width; x++, index++) {
*img_ptr++ = image->comps[0].data[index] >> adjust[0];
if(image->numcomps > 2 && check_image_attributes(image)) {
*img_ptr++ = image->comps[1].data[index] >> adjust[1];
*img_ptr++ = image->comps[2].data[index] >> adjust[2];
if(has_alpha)
*img_ptr++ = image->comps[3].data[index] >> adjust[3];
}
}
}
*output = ctx->image;
*data_size = sizeof(AVPicture);
ret = buf_size;
done:
opj_image_destroy(image);
opj_destroy_decompress(dec);
return ret;
}
static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx)
{
LibOpenJPEGContext *ctx = avctx->priv_data;
if(ctx->image.data[0])
avctx->release_buffer(avctx, &ctx->image);
return 0 ;
}
AVCodec libopenjpeg_decoder = {
"libopenjpeg",
CODEC_TYPE_VIDEO,
CODEC_ID_JPEG2000,
sizeof(LibOpenJPEGContext),
libopenjpeg_decode_init,
NULL,
libopenjpeg_decode_close,
libopenjpeg_decode_frame,
NULL,
.long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"),
} ;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment