Commit d267b339 authored by Carl Eugen Hoyos's avatar Carl Eugen Hoyos

Lagarith decoder by Nathan Caldwell, saintdev at gmail

Originally committed as revision 26270 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent c392cc0a
......@@ -71,6 +71,7 @@ version <next>:
- FFmpeg metadata format muxer and demuxer
- SubRip (srt) subtitle decoder
- floating-point AC-3 encoder added
- Lagarith decoder
version 0.6:
......
......@@ -424,6 +424,7 @@ following image formats are supported:
@tab Codec used in Worms games.
@item Kega Game Video (KGV1) @tab @tab X
@tab Kega emulator screen capture codec.
@item Lagarith @tab @tab X
@item LCL (LossLess Codec Library) MSZH @tab @tab X
@item LCL (LossLess Codec Library) ZLIB @tab E @tab E
@item LOCO @tab @tab X
......
......@@ -185,6 +185,7 @@ OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o \
OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o
OBJS-$(CONFIG_KGV1_DECODER) += kgv1dec.o
OBJS-$(CONFIG_KMVC_DECODER) += kmvc.o
OBJS-$(CONFIG_LAGARITH_DECODER) += lagarith.o lagarithrac.o
OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc.o mjpeg.o \
mpegvideo_enc.o motion_est.o \
ratecontrol.o mpeg12data.o \
......
......@@ -128,6 +128,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (JPEGLS, jpegls);
REGISTER_DECODER (KGV1, kgv1);
REGISTER_DECODER (KMVC, kmvc);
REGISTER_DECODER (LAGARITH, lagarith);
REGISTER_ENCODER (LJPEG, ljpeg);
REGISTER_DECODER (LOCO, loco);
REGISTER_DECODER (MDEC, mdec);
......
......@@ -32,7 +32,7 @@
#include "libavutil/cpu.h"
#define LIBAVCODEC_VERSION_MAJOR 52
#define LIBAVCODEC_VERSION_MINOR 107
#define LIBAVCODEC_VERSION_MINOR 108
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
......@@ -259,6 +259,7 @@ enum CodecID {
CODEC_ID_A64_MULTI5,
CODEC_ID_R10K,
CODEC_ID_MXPEG,
CODEC_ID_LAGARITH,
/* various PCM "codecs" */
CODEC_ID_PCM_S16LE= 0x10000,
......
This diff is collapsed.
/*
* Lagarith range decoder
* Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
* Copyright (c) 2009 David Conrad
*
* 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/lagarithrac.c
* Lagarith range decoder
* @author Nathan Caldwell
* @author David Conrad
*/
#include "get_bits.h"
#include "lagarithrac.h"
void lag_rac_init(lag_rac *l, GetBitContext *gb, int length)
{
int i, j;
/* According to reference decoder "1st byte is garbage",
* however, it gets skipped by the call to align_get_bits()
*/
align_get_bits(gb);
l->bytestream_start =
l->bytestream = gb->buffer + get_bits_count(gb) / 8;
l->bytestream_end = l->bytestream_start + length;
l->range = 0x80;
l->low = *l->bytestream >> 1;
l->hash_shift = FFMAX(l->scale - 8, 0);
for (i = j = 0; i < 256; i++) {
unsigned r = i << l->hash_shift;
while (l->prob[j + 1] <= r)
j++;
l->range_hash[i] = j;
}
/* Add conversion factor to hash_shift so we don't have to in lag_get_rac. */
l->hash_shift += 23;
}
/*
* Lagarith range decoder
* Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
* Copyright (c) 2009 David Conrad
*
* 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/lagarithrac.h
* Lagarith range decoder
* @author Nathan Caldwell
* @author David Conrad
*/
#ifndef AVCODEC_LAGARITHRAC_H
#define AVCODEC_LAGARITHRAC_H
#include <stdint.h>
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "get_bits.h"
typedef struct lag_rac {
AVCodecContext *avctx;
unsigned low;
unsigned range;
unsigned scale; /*!< Number of bits of precision in range. */
unsigned hash_shift; /*!< Number of bits to shift to calculate hash for radix search. */
const uint8_t *bytestream_start; /*!< Start of input bytestream. */
const uint8_t *bytestream; /*!< Current position in input bytestream. */
const uint8_t *bytestream_end; /*!< End position of input bytestream. */
uint32_t prob[258]; /*!< Table of cumulative probability for each symbol. */
uint8_t range_hash[256]; /*!< Hash table mapping upper byte to approximate symbol. */
} lag_rac;
void lag_rac_init(lag_rac *l, GetBitContext *gb, int length);
/* TODO: Optimize */
static inline void lag_rac_refill(lag_rac *l)
{
while (l->range <= 0x800000) {
l->low <<= 8;
l->range <<= 8;
l->low |= 0xff & (AV_RB16(l->bytestream) >> 1);
if (l->bytestream < l->bytestream_end)
l->bytestream++;
}
}
/**
* Decode a single byte from the compressed plane described by *l.
* @param l pointer to lag_rac for the current plane
* @return next byte of decoded data
*/
static inline uint8_t lag_get_rac(lag_rac *l)
{
unsigned range_scaled, low_scaled, div;
int val;
uint8_t shift;
lag_rac_refill(l);
range_scaled = l->range >> l->scale;
if (l->low < range_scaled * l->prob[255]) {
/* val = 0 is frequent enough to deserve a shortcut */
if (l->low < range_scaled * l->prob[1]) {
val = 0;
} else {
/* FIXME __builtin_clz is ~20% faster here, but not allowed in generic code. */
shift = 30 - av_log2(range_scaled);
div = ((range_scaled << shift) + (1 << 23) - 1) >> 23;
/* low>>24 ensures that any cases too big for exact FASTDIV are
* under- rather than over-estimated
*/
low_scaled = FASTDIV(l->low - (l->low >> 24), div);
shift -= l->hash_shift;
shift &= 31;
low_scaled = (low_scaled << shift) | (low_scaled >> (32 - shift));
/* low_scaled is now a lower bound of low/range_scaled */
val = l->range_hash[(uint8_t) low_scaled];
while (l->low >= range_scaled * l->prob[val + 1])
val++;
}
l->range = range_scaled * (l->prob[val + 1] - l->prob[val]);
} else {
val = 255;
l->range -= range_scaled * l->prob[255];
}
l->low -= range_scaled * l->prob[val];
return val;
}
#endif /* AVCODEC_LAGARITHRAC_H */
......@@ -257,6 +257,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_AURA2, MKTAG('A', 'U', 'R', '2') },
{ CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') },
{ CODEC_ID_KGV1, MKTAG('K', 'G', 'V', '1') },
{ CODEC_ID_LAGARITH, MKTAG('L', 'A', 'G', 'S') },
{ CODEC_ID_NONE, 0 }
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment