aboutsummaryrefslogtreecommitdiff
path: root/image
diff options
context:
space:
mode:
authorPaul Gilbert2016-09-07 21:30:26 -0400
committerPaul Gilbert2016-09-10 10:08:17 -0400
commit400661182efae9659e664fec0e81c7ed8c3a10ec (patch)
treef19551bf9c7ba4b78c4a7e940d1c261b87fd4229 /image
parentc60a03019cb00649e19fa2c9baf289688237b90f (diff)
downloadscummvm-rg350-400661182efae9659e664fec0e81c7ed8c3a10ec.tar.gz
scummvm-rg350-400661182efae9659e664fec0e81c7ed8c3a10ec.tar.bz2
scummvm-rg350-400661182efae9659e664fec0e81c7ed8c3a10ec.zip
IMAGE: Indeo4 header now being successfully loaded
Diffstat (limited to 'image')
-rw-r--r--image/codecs/indeo/indeo.cpp156
-rw-r--r--image/codecs/indeo/indeo.h55
-rw-r--r--image/codecs/indeo/vlc.cpp166
-rw-r--r--image/codecs/indeo/vlc.h24
-rw-r--r--image/codecs/indeo4.cpp12
5 files changed, 243 insertions, 170 deletions
diff --git a/image/codecs/indeo/indeo.cpp b/image/codecs/indeo/indeo.cpp
index f68609dc0d..e58b4c6147 100644
--- a/image/codecs/indeo/indeo.cpp
+++ b/image/codecs/indeo/indeo.cpp
@@ -33,6 +33,7 @@
#include "image/codecs/indeo/indeo_dsp.h"
#include "image/codecs/indeo/mem.h"
#include "common/system.h"
+#include "common/algorithm.h"
#include "common/textconsole.h"
#include "common/util.h"
@@ -139,13 +140,15 @@ void IVIHuffDesc::ivi_huff_desc_copy(const IVIHuffDesc *src) {
IVIHuffTab::IVIHuffTab() {
tab = nullptr;
+ for (int idx = 0; idx < (8192 * 16); ++idx)
+ table_data[idx][0] = table_data[idx][1] = 0;
for (int i = 0; i < 8; i++) {
- ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192;
- ivi_mb_vlc_tabs[i].table_allocated = 8192;
+ ivi_mb_vlc_tabs[i]._table = table_data + i * 2 * 8192;
+ ivi_mb_vlc_tabs[i]._table_allocated = 8192;
ivi_mb_huff_desc[i].ivi_create_huff_from_desc(&ivi_mb_vlc_tabs[i], 1);
- ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192;
- ivi_blk_vlc_tabs[i].table_allocated = 8192;
+ ivi_blk_vlc_tabs[i]._table = table_data + (i * 2 + 1) * 8192;
+ ivi_blk_vlc_tabs[i]._table_allocated = 8192;
ivi_blk_huff_desc[i].ivi_create_huff_from_desc(&ivi_blk_vlc_tabs[i], 1);
}
}
@@ -174,10 +177,10 @@ int IVIHuffTab::ff_ivi_dec_huff_desc(GetBits *gb, int desc_coded, int which_tab)
new_huff.xbits[i] = gb->getBits(4);
// Have we got the same custom table? Rebuild if not.
- if (new_huff.ivi_huff_desc_cmp(&cust_desc) || !cust_tab.table) {
+ if (new_huff.ivi_huff_desc_cmp(&cust_desc) || !cust_tab._table) {
cust_desc.ivi_huff_desc_copy(&new_huff);
- if (cust_tab.table)
+ if (cust_tab._table)
cust_tab.ff_free_vlc();
result = cust_desc.ivi_create_huff_from_desc(&cust_tab, 0);
if (result) {
@@ -199,6 +202,83 @@ int IVIHuffTab::ff_ivi_dec_huff_desc(GetBits *gb, int desc_coded, int which_tab)
/*------------------------------------------------------------------------*/
+RVMapDesc::RVMapDesc() {
+ eob_sym = esc_sym = 0;
+ Common::fill(&runtab[0], &runtab[256], 0);
+ Common::fill(&valtab[0], &valtab[256], 0);
+}
+
+/*------------------------------------------------------------------------*/
+
+IVIMbInfo::IVIMbInfo() : xpos(0), ypos(0), buf_offs(0), type(0), cbp(0),
+ q_delta(0), mv_x(0), mv_y(0), b_mv_x(0), b_mv_y(0) {
+}
+
+/*------------------------------------------------------------------------*/
+
+IVITile::IVITile() : xpos(0), ypos(0), width(0), height(0), mb_size(0),
+ is_empty(0), data_size(0), num_MBs(0), mbs(nullptr), ref_mbs(nullptr) {
+}
+
+/*------------------------------------------------------------------------*/
+
+IVIBandDesc::IVIBandDesc() : plane(0), band_num(0), width(0), height(0),
+ aheight(0), data_ptr(nullptr), data_size(0), buf(nullptr),
+ ref_buf(nullptr), b_ref_buf(nullptr), pitch(0), is_empty(0),
+ mb_size(0), blk_size(0), is_halfpel(0), inherit_mv(0), bufsize(0),
+ inherit_qdelta(0), qdelta_present(0), quant_mat(0), glob_quant(0),
+ scan(nullptr), scan_size(0), num_corr(0), rvmap_sel(0), rv_map(nullptr),
+ num_tiles(0), tiles(nullptr), inv_transform(nullptr), transform_size(0),
+ dc_transform(nullptr), is_2d_trans(0), checksum(0), checksum_present(0),
+ intra_base(nullptr), inter_base(nullptr), intra_scale(nullptr),
+ inter_scale(nullptr) {
+ Common::fill(&bufs[0], &bufs[4], (int16 *)nullptr);
+ Common::fill(&corr[0], &corr[61 * 2], 0);
+}
+
+int IVIBandDesc::ivi_init_tiles(IVITile *ref_tile, int p, int b, int t_height, int t_width) {
+ int x, y;
+ IVITile *tile = tiles;
+
+ for (y = 0; y < height; y += t_height) {
+ for (x = 0; x < width; x += t_width) {
+ tile->xpos = x;
+ tile->ypos = y;
+ tile->mb_size = mb_size;
+ tile->width = MIN(width - x, t_width);
+ tile->height = MIN(height - y, t_height);
+ tile->is_empty = tile->data_size = 0;
+ // calculate number of macroblocks
+ tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height,
+ mb_size);
+
+ av_freep(&tile->mbs);
+ tile->mbs = (IVIMbInfo *)av_mallocz_array(tile->num_MBs, sizeof(IVIMbInfo));
+ if (!tile->mbs)
+ return -2;
+
+ tile->ref_mbs = 0;
+ if (p || b) {
+ if (tile->num_MBs != ref_tile->num_MBs) {
+ warning("ref_tile mismatch");
+ return -1;
+ }
+ tile->ref_mbs = ref_tile->mbs;
+ ref_tile++;
+ }
+ tile++;
+ }
+ }
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+IVIPicConfig::IVIPicConfig() : pic_width(0), pic_height(0), chroma_width(0),
+ chroma_height(0), tile_width(0), tile_height(0), luma_bands(0), chroma_bands(0) {
+}
+
bool IVIPicConfig::ivi_pic_config_cmp(const IVIPicConfig &cfg2) {
return pic_width != cfg2.pic_width || pic_height != cfg2.pic_height ||
chroma_width != cfg2.chroma_width || chroma_height != cfg2.chroma_height ||
@@ -208,6 +288,9 @@ bool IVIPicConfig::ivi_pic_config_cmp(const IVIPicConfig &cfg2) {
/*------------------------------------------------------------------------*/
+IVIPlaneDesc::IVIPlaneDesc() : width(0), height(0), num_bands(0), bands(nullptr) {
+}
+
int IVIPlaneDesc::ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg, bool is_indeo4) {
int p, b;
uint32 b_width, b_height, align_fac, width_aligned,
@@ -333,7 +416,7 @@ void IVIPlaneDesc::ivi_free_buffers(IVIPlaneDesc *planes) {
av_freep(&planes[p].bands[b].bufs[2]);
av_freep(&planes[p].bands[b].bufs[3]);
- if (planes[p].bands[b].blk_vlc.cust_tab.table)
+ if (planes[p].bands[b].blk_vlc.cust_tab._table)
planes[p].bands[b].blk_vlc.cust_tab.ff_free_vlc();
for (t = 0; t < planes[p].bands[b].num_tiles; t++)
av_freep(&planes[p].bands[b].tiles[t].mbs);
@@ -346,41 +429,22 @@ void IVIPlaneDesc::ivi_free_buffers(IVIPlaneDesc *planes) {
/*------------------------------------------------------------------------*/
-int IVIBandDesc::ivi_init_tiles(IVITile *ref_tile, int p, int b, int t_height, int t_width) {
- int x, y;
- IVITile *tile = tiles;
-
- for (y = 0; y < height; y += t_height) {
- for (x = 0; x < width; x += t_width) {
- tile->xpos = x;
- tile->ypos = y;
- tile->mb_size = mb_size;
- tile->width = MIN(width - x, t_width);
- tile->height = MIN(height - y, t_height);
- tile->is_empty = tile->data_size = 0;
- // calculate number of macroblocks
- tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height,
- mb_size);
-
- av_freep(&tile->mbs);
- tile->mbs = (IVIMbInfo *)av_mallocz_array(tile->num_MBs, sizeof(IVIMbInfo));
- if (!tile->mbs)
- return -2;
+AVFrame::AVFrame() {
+ Common::fill(&data[0], &data[AV_NUM_DATA_POINTERS], (uint8 *)nullptr);
+ Common::fill(&linesize[0], &linesize[AV_NUM_DATA_POINTERS], 0);
+}
- tile->ref_mbs = 0;
- if (p || b) {
- if (tile->num_MBs != ref_tile->num_MBs) {
- warning("ref_tile mismatch");
- return -1;
- }
- tile->ref_mbs = ref_tile->mbs;
- ref_tile++;
- }
- tile++;
- }
- }
+/*------------------------------------------------------------------------*/
- return 0;
+IVI45DecContext::IVI45DecContext() : gb(nullptr), frame_num(0), frame_type(0),
+ prev_frame_type(0), data_size(0), is_scalable(0), frame_data(0),
+ inter_scal(0), frame_size(0), pic_hdr_size(0), frame_flags(0),
+ checksum(0), buf_switch(0), dst_buf(0), ref_buf(0), ref2_buf(0),
+ b_ref_buf(0), rvmap_sel(0), in_imf(0), in_q(0), pic_glob_quant(0),
+ unknown1(0), gop_hdr_size(0), gop_flags(0), lock_word(0), has_b_frames(0),
+ has_transp(0), uses_tiling(0), uses_haar(0), uses_fullpel(0), gop_invalid(0),
+ is_indeo4(0), p_frame(nullptr), got_p_frame(0) {
+ Common::fill(&buf_invalid[0], &buf_invalid[4], 0);
}
/*------------------------------------------------------------------------*/
@@ -389,15 +453,13 @@ IndeoDecoderBase::IndeoDecoderBase(uint16 width, uint16 height) : Codec() {
_pixelFormat = g_system->getScreenFormat();
_surface = new Graphics::ManagedSurface();
_surface->create(width, height, _pixelFormat);
- _ctx.gb = nullptr;
- _ctx.pic_conf.pic_width = _ctx.pic_conf.pic_height = 0;
_ctx.b_ref_buf = 3; // buffer 2 is used for scalability mode
}
IndeoDecoderBase::~IndeoDecoderBase() {
delete _surface;
IVIPlaneDesc::ivi_free_buffers(_ctx.planes);
- if (_ctx.mb_vlc.cust_tab.table)
+ if (_ctx.mb_vlc.cust_tab._table)
_ctx.mb_vlc.cust_tab.ff_free_vlc();
delete _ctx.p_frame;
@@ -1181,16 +1243,16 @@ int IndeoDecoderBase::ivi_decode_coded_blocks(GetBits *gb, IVIBandDesc *band,
// zero column flags
memset(col_flags, 0, sizeof(col_flags));
while (scan_pos <= num_coeffs) {
- sym = gb->getVLC2(band->blk_vlc.tab->table,
+ sym = gb->getVLC2(band->blk_vlc.tab->_table,
IVI_VLC_BITS, 1);
if (sym == rvmap->eob_sym)
break; // End of block
// Escape - run/val explicitly coded using 3 vlc codes
if (sym == rvmap->esc_sym) {
- run = gb->getVLC2(band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1;
- lo = gb->getVLC2(band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
- hi = gb->getVLC2(band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
+ run = gb->getVLC2(band->blk_vlc.tab->_table, IVI_VLC_BITS, 1) + 1;
+ lo = gb->getVLC2(band->blk_vlc.tab->_table, IVI_VLC_BITS, 1);
+ hi = gb->getVLC2(band->blk_vlc.tab->_table, IVI_VLC_BITS, 1);
// merge them and convert into signed val
val = IVI_TOSIGNED((hi << 6) | lo);
} else {
diff --git a/image/codecs/indeo/indeo.h b/image/codecs/indeo/indeo.h
index fa1bc2f17d..2103ebed68 100644
--- a/image/codecs/indeo/indeo.h
+++ b/image/codecs/indeo/indeo.h
@@ -55,6 +55,17 @@ enum {
IVI4_FRAMETYPE_NULL_LAST = 6 ///< empty frame with no data
};
+enum {
+ IVI_MB_HUFF = 0, /// Huffman table is used for coding macroblocks
+ IVI_BLK_HUFF = 1 /// Huffman table is used for coding blocks
+};
+
+/**
+ * Declare inverse transform function types
+ */
+typedef void (InvTransformPtr)(const int32 *in, int16 *out, uint32 pitch, const uint8 *flags);
+typedef void (DCTransformPtr) (const int32 *in, int16 *out, uint32 pitch, int blk_size);
+
typedef void(*ivi_mc_func) (int16 *buf, const int16 *ref_buf,
uint32 pitch, int mc_type);
typedef void(*ivi_mc_avg_func) (int16 *buf, const int16 *ref_buf1,
@@ -127,26 +138,6 @@ public:
int ff_ivi_dec_huff_desc(GetBits *gb, int desc_coded, int which_tab);
};
-enum {
- IVI_MB_HUFF = 0, /// Huffman table is used for coding macroblocks
- IVI_BLK_HUFF = 1 /// Huffman table is used for coding blocks
-};
-
-
-/**
- * Common scan patterns (defined in ivi_common.c)
- */
-//extern const uint8 ff_ivi_vertical_scan_8x8[64];
-//extern const uint8 ff_ivi_horizontal_scan_8x8[64];
-//extern const uint8 ff_ivi_direct_scan_4x4[16];
-
-/**
- * Declare inverse transform function types
- */
-typedef void (InvTransformPtr)(const int32 *in, int16 *out, uint32 pitch, const uint8 *flags);
-typedef void (DCTransformPtr) (const int32 *in, int16 *out, uint32 pitch, int blk_size);
-
-
/**
* run-value (RLE) table descriptor
*/
@@ -155,10 +146,9 @@ struct RVMapDesc {
uint8 esc_sym; ///< escape symbol
uint8 runtab[256];
int8 valtab[256];
-};
-
-extern const RVMapDesc ff_ivi_rvmap_tabs[9];
+ RVMapDesc();
+};
/**
* information for Indeo macroblock (16x16, 8x8 or 4x4)
@@ -174,8 +164,9 @@ struct IVIMbInfo {
int8 mv_y; ///< motion vector (y component)
int8 b_mv_x; ///< second motion vector (x component)
int8 b_mv_y; ///< second motion vector (y component)
-};
+ IVIMbInfo();
+};
/**
* information for Indeo tile
@@ -191,8 +182,9 @@ struct IVITile {
int num_MBs; ///< number of macroblocks in this tile
IVIMbInfo * mbs; ///< array of macroblock descriptors
IVIMbInfo * ref_mbs; ///< ptr to the macroblock descriptors of the reference tile
-};
+ IVITile();
+};
/**
* information for Indeo wavelet band
@@ -242,6 +234,8 @@ struct IVIBandDesc {
const uint8 * intra_scale; ///< quantization coefficient for intra blocks
const uint8 * inter_scale; ///< quantization coefficient for inter blocks
+ IVIBandDesc();
+
int ivi_init_tiles(IVITile *ref_tile, int p, int b, int t_height, int t_width);
};
@@ -255,6 +249,8 @@ struct IVIPicConfig {
uint8 luma_bands;
uint8 chroma_bands;
+ IVIPicConfig();
+
/**
* Compare some properties of two pictures
*/
@@ -270,6 +266,8 @@ struct IVIPlaneDesc {
uint8 num_bands; ///< number of bands this plane subdivided into
IVIBandDesc *bands; ///< array of band descriptors
+ IVIPlaneDesc();
+
static int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg, bool is_indeo4);
static int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height);
@@ -314,6 +312,8 @@ struct AVFrame {
* may be extra padding present for performance reasons.
*/
int linesize[AV_NUM_DATA_POINTERS];
+
+ AVFrame();
};
struct IVI45DecContext {
@@ -367,6 +367,8 @@ struct IVI45DecContext {
AVFrame * p_frame;
int got_p_frame;
+
+ IVI45DecContext();
};
class IndeoDecoderBase : public Codec {
@@ -541,10 +543,9 @@ public:
* @param h the height of the picture
* @param log_offset the offset to sum to the log level for logging with log_ctx
* @returns >= 0 if valid, a negative error code otherwise
-*/
+ */
extern int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx);
-
} // End of namespace Indeo
} // End of namespace Image
diff --git a/image/codecs/indeo/vlc.cpp b/image/codecs/indeo/vlc.cpp
index 441596585e..485acfbe53 100644
--- a/image/codecs/indeo/vlc.cpp
+++ b/image/codecs/indeo/vlc.cpp
@@ -32,14 +32,14 @@
#include "common/util.h"
namespace Image {
-namespace Indeo {
+ namespace Indeo {
/**
* Quicksort
* This sort is fast, and fully inplace but not stable and it is possible
* to construct input that requires O(n^2) time but this is very unlikely to
* happen with non constructed input.
-*/
+ */
#define AV_QSORT(p, num, type, cmp) do {\
void *stack[64][2];\
int sp= 1;\
@@ -104,28 +104,38 @@ namespace Indeo {
}\
} while (0)
-/**
- * VLC decoding
- */
-#define GET_DATA(v, table, i, wrap, size) \
-{ \
- const uint8 *ptr = (const uint8 *)table + i * wrap; \
- switch(size) { \
- case 1: \
- v = *(const uint8 *)ptr; \
- break; \
- case 2: \
- v = *(const uint16 *)ptr; \
- break; \
- default: \
- v = *(const uint32 *)ptr; \
- break; \
- } \
-}
+#define COPY(condition)\
+ for (i = 0; i < nb_codes; i++) { \
+ buf[j].bits = getData(p_bits, i, bits_wrap, bits_size); \
+ if (!(condition)) \
+ continue; \
+ if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \
+ warning("Too long VLC (%d) in init_vlc", buf[j].bits); \
+ if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
+ free(buf); \
+ return -1; \
+ } \
+ buf[j].code = getData(codes, i, codes_wrap, codes_size); \
+ if (buf[j].code >= (1LL<<buf[j].bits)) { \
+ warning("Invalid code %x for %d in init_vlc", buf[j].code, i); \
+ if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
+ free(buf); \
+ return -1; \
+ } \
+ if (flags & INIT_VLC_LE) \
+ buf[j].code = bitswap_32(buf[j].code); \
+ else \
+ buf[j].code <<= 32 - buf[j].bits; \
+ if (symbols) \
+ buf[j].symbol = getData(symbols, i, symbols_wrap, symbols_size); \
+ else \
+ buf[j].symbol = i; \
+ j++; \
+ }
/*------------------------------------------------------------------------*/
-VLC::VLC() : bits(0), table_size(0), table_allocated(0), table(nullptr) {
+VLC::VLC() : _bits(0), _table_size(0), _table_allocated(0), _table(nullptr) {
}
int VLC::init_vlc(int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size,
@@ -143,17 +153,17 @@ int VLC::init_vlc(int nb_bits, int nb_codes, const void *p_bits, int bits_wrap,
VLC localvlc, *vlc;
vlc = this;
- vlc->bits = nb_bits;
+ vlc->_bits = nb_bits;
if (flags & INIT_VLC_USE_NEW_STATIC) {
assert((nb_codes + 1) <= FF_ARRAY_ELEMS(localbuf));
buf = localbuf;
localvlc = *this;
vlc = &localvlc;
- vlc->table_size = 0;
+ vlc->_table_size = 0;
} else {
- vlc->table = NULL;
- vlc->table_allocated = 0;
- vlc->table_size = 0;
+ vlc->_table = NULL;
+ vlc->_table_allocated = 0;
+ vlc->_table_size = 0;
buf = (VLCcode *)av_malloc_array((nb_codes + 1), sizeof(VLCcode));
assert(buf);
@@ -161,34 +171,7 @@ int VLC::init_vlc(int nb_bits, int nb_codes, const void *p_bits, int bits_wrap,
assert(symbols_size <= 2 || !symbols);
j = 0;
-#define COPY(condition)\
- for (i = 0; i < nb_codes; i++) { \
- GET_DATA(buf[j].bits, p_bits, i, bits_wrap, bits_size); \
- if (!(condition)) \
- continue; \
- if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \
- warning("Too long VLC (%d) in init_vlc", buf[j].bits); \
- if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
- free(buf); \
- return -1; \
- } \
- GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \
- if (buf[j].code >= (1LL<<buf[j].bits)) { \
- warning("Invalid code %x for %d in init_vlc", buf[j].code, i); \
- if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
- free(buf); \
- return -1; \
- } \
- if (flags & INIT_VLC_LE) \
- buf[j].code = bitswap_32(buf[j].code); \
- else \
- buf[j].code <<= 32 - buf[j].bits; \
- if (symbols) \
- GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \
- else \
- buf[j].symbol = i; \
- j++; \
- }
+
COPY(buf[j].bits > nb_bits);
// qsort is the slowest part of init_vlc, and could probably be improved or avoided
@@ -199,15 +182,15 @@ int VLC::init_vlc(int nb_bits, int nb_codes, const void *p_bits, int bits_wrap,
ret = vlc->build_table(nb_bits, nb_codes, buf, flags);
if (flags & INIT_VLC_USE_NEW_STATIC) {
- if (vlc->table_size != vlc->table_allocated)
- warning("needed %d had %d", table_size, table_allocated);
+ if (vlc->_table_size != vlc->_table_allocated)
+ warning("needed %d had %d", vlc->_table_size, vlc->_table_allocated);
assert(ret >= 0);
*this = *vlc;
} else {
free(buf);
if (ret < 0) {
- av_freep(&vlc->table);
+ av_freep(&vlc->_table);
return -1;
}
}
@@ -216,7 +199,7 @@ int VLC::init_vlc(int nb_bits, int nb_codes, const void *p_bits, int bits_wrap,
}
void VLC::ff_free_vlc() {
- free(table);
+ free(_table);
}
int VLC::compare_vlcspec(const void *a, const void *b) {
@@ -230,27 +213,26 @@ int VLC::build_table(int table_nb_bits, int nb_codes,
int table_size, table_index, index, code_prefix, symbol, subtable_bits;
int i, j, k, n, nb, inc;
uint32 code;
- // the double volatile is needed to prevent an internal compiler error in gcc 4.2
- volatile VLC_TYPE(*volatile table)[2];
-
+ VLC_TYPE (*table)[2];
table_size = 1 << table_nb_bits;
if (table_nb_bits > 30)
return -1;
table_index = alloc_table(table_size, flags & INIT_VLC_USE_NEW_STATIC);
- warning("new table index=%d size=%d", table_index, table_size);
+ //warning("new table index=%d size=%d", table_index, table_size);
if (table_index < 0)
return table_index;
- table = (volatile VLC_TYPE(*)[2])&vlc->table[table_index];
+ table = &vlc->_table[table_index];
- /* first pass: map codes and compute auxiliary table sizes */
+ // first pass: map codes and compute auxiliary table sizes
for (i = 0; i < nb_codes; i++) {
n = codes[i].bits;
code = codes[i].code;
symbol = codes[i].symbol;
- warning("i=%d n=%d code=0x%x", i, n, code);
+ //warning("i=%d n=%d code=0x%x", i, n, code);
+
if (n <= table_nb_bits) {
- /* no need to add another table */
+ // no need to add another table
j = code >> (32 - table_nb_bits);
nb = 1 << (table_nb_bits - n);
inc = 1;
@@ -260,18 +242,19 @@ int VLC::build_table(int table_nb_bits, int nb_codes,
}
for (k = 0; k < nb; k++) {
int bits = table[j][1];
- warning("%4x: code=%d n=%d", j, i, n);
+ //warning("%4x: code=%d n=%d", j, i, n);
+
if (bits != 0 && bits != n) {
warning("incorrect codes");
return -1;
}
+
table[j][1] = n; //bits
table[j][0] = symbol;
j += inc;
}
- }
- else {
- /* fill auxiliary table recursively */
+ } else {
+ // fill auxiliary table recursively
n -= table_nb_bits;
code_prefix = code >> (32 - table_nb_bits);
subtable_bits = n;
@@ -282,7 +265,7 @@ int VLC::build_table(int table_nb_bits, int nb_codes,
if (n <= 0)
break;
code = codes[k].code;
- if (code >> (32 - table_nb_bits) != code_prefix)
+ if (code >> (32 - table_nb_bits) != (uint)code_prefix)
break;
codes[k].bits = n;
codes[k].code = code << table_nb_bits;
@@ -291,12 +274,13 @@ int VLC::build_table(int table_nb_bits, int nb_codes,
subtable_bits = MIN(subtable_bits, table_nb_bits);
j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix;
table[j][1] = -subtable_bits;
- warning("%4x: n=%d (subtable)", j, codes[i].bits + table_nb_bits);
+ //warning("%4x: n=%d (subtable)", j, codes[i].bits + table_nb_bits);
index = vlc->build_table(subtable_bits, k - i, codes + i, flags);
if (index < 0)
return index;
- /* note: realloc has been done, so reload tables */
- table = (volatile VLC_TYPE(*)[2])&vlc->table[table_index];
+
+ // note: realloc has been done, so reload tables
+ table = (VLC_TYPE (*)[2])&vlc->_table[table_index];
table[j][0] = index; //code
i = k - 1;
}
@@ -312,25 +296,41 @@ int VLC::build_table(int table_nb_bits, int nb_codes,
int VLC::alloc_table(int size, int use_static) {
VLC *vlc = this;
- int index = vlc->table_size;
+ int index = vlc->_table_size;
- vlc->table_size += size;
- if (vlc->table_size > vlc->table_allocated) {
+ vlc->_table_size += size;
+ if (vlc->_table_size > vlc->_table_allocated) {
// cannot do anything, init_vlc() is used with too little memory
assert(!use_static);
- vlc->table_allocated += (1 << vlc->bits);
- vlc->table = (int16(*)[2])av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2);
- if (!vlc->table) {
- vlc->table_allocated = 0;
- vlc->table_size = 0;
+ vlc->_table_allocated += (1 << vlc->_bits);
+ vlc->_table = (int16(*)[2])av_realloc_f(vlc->_table, vlc->_table_allocated, sizeof(VLC_TYPE) * 2);
+ if (!vlc->_table) {
+ vlc->_table_allocated = 0;
+ vlc->_table_size = 0;
return -2;
}
- memset(vlc->table + vlc->table_allocated - (1 << vlc->bits), 0, sizeof(VLC_TYPE) * 2 << vlc->bits);
+ memset(vlc->_table + vlc->_table_allocated - (1 << vlc->_bits), 0, sizeof(VLC_TYPE) * 2 << vlc->_bits);
}
return index;
}
+/**
+* VLC decoding
+*/
+uint VLC::getData(const void *table, uint idx, uint wrap, uint size) {
+ const uint8 *ptr = (const uint8 *)table + idx * wrap;
+
+ switch(size) {
+ case 1:
+ return *(const uint8 *)ptr;
+ case 2:
+ return *(const uint16 *)ptr;
+ default:
+ return *(const uint32 *)ptr;
+ }
+}
+
} // End of namespace Indeo
} // End of namespace Image
diff --git a/image/codecs/indeo/vlc.h b/image/codecs/indeo/vlc.h
index 682be66e4a..01c7b1160b 100644
--- a/image/codecs/indeo/vlc.h
+++ b/image/codecs/indeo/vlc.h
@@ -37,8 +37,11 @@ namespace Image {
namespace Indeo {
#define VLC_TYPE int16
-#define INIT_VLC_LE 2
-#define INIT_VLC_USE_NEW_STATIC 4
+
+enum VLCFlag {
+ INIT_VLC_LE = 2,
+ INIT_VLC_USE_NEW_STATIC = 4
+};
struct VLCcode {
uint8 bits;
@@ -54,14 +57,21 @@ struct VLCcode {
struct VLC {
private:
static int compare_vlcspec(const void *a, const void *b);
+
+ /**
+ * Gets a value of a given size from a table
+ * @param table Table to get data from
+ * @param idx Index of value to retrieve
+ * @param wrap Size of elements with alignment
+ * @param size Size of elements
+ */
+ static uint getData(const void *table, uint idx, uint wrap, uint size);
public:
- int bits;
- VLC_TYPE (*table)[2]; ///< code, bits
- int table_size, table_allocated;
+ int _bits;
+ VLC_TYPE (*_table)[2]; ///< code, bits
+ int _table_size, _table_allocated;
VLC();
- ~VLC() { ff_free_vlc(); }
-
/* Build VLC decoding tables suitable for use with get_vlc().
diff --git a/image/codecs/indeo4.cpp b/image/codecs/indeo4.cpp
index bedc2d9af5..936d4b0456 100644
--- a/image/codecs/indeo4.cpp
+++ b/image/codecs/indeo4.cpp
@@ -476,7 +476,7 @@ int Indeo4Decoder::decode_mb_info(IVIBandDesc *band, IVITile *tile) {
mb->q_delta = 0;
if (!band->plane && !band->band_num && _ctx.in_q) {
- mb->q_delta = _ctx.gb->getVLC2(_ctx.mb_vlc.tab->table,
+ mb->q_delta = _ctx.gb->getVLC2(_ctx.mb_vlc.tab->_table,
IVI_VLC_BITS, 1);
mb->q_delta = IVI_TOSIGNED(mb->q_delta);
}
@@ -515,7 +515,7 @@ int Indeo4Decoder::decode_mb_info(IVIBandDesc *band, IVITile *tile) {
}
else if (mb->cbp || (!band->plane && !band->band_num &&
_ctx.in_q)) {
- mb->q_delta = _ctx.gb->getVLC2(_ctx.mb_vlc.tab->table,
+ mb->q_delta = _ctx.gb->getVLC2(_ctx.mb_vlc.tab->_table,
IVI_VLC_BITS, 1);
mb->q_delta = IVI_TOSIGNED(mb->q_delta);
}
@@ -536,21 +536,21 @@ int Indeo4Decoder::decode_mb_info(IVIBandDesc *band, IVITile *tile) {
}
} else {
// decode motion vector deltas
- mv_delta = _ctx.gb->getVLC2(_ctx.mb_vlc.tab->table,
+ mv_delta = _ctx.gb->getVLC2(_ctx.mb_vlc.tab->_table,
IVI_VLC_BITS, 1);
mv_y += IVI_TOSIGNED(mv_delta);
- mv_delta = _ctx.gb->getVLC2(_ctx.mb_vlc.tab->table,
+ mv_delta = _ctx.gb->getVLC2(_ctx.mb_vlc.tab->_table,
IVI_VLC_BITS, 1);
mv_x += IVI_TOSIGNED(mv_delta);
mb->mv_x = mv_x;
mb->mv_y = mv_y;
if (mb->type == 3) {
mv_delta = _ctx.gb->getVLC2(
- _ctx.mb_vlc.tab->table,
+ _ctx.mb_vlc.tab->_table,
IVI_VLC_BITS, 1);
mv_y += IVI_TOSIGNED(mv_delta);
mv_delta = _ctx.gb->getVLC2(
- _ctx.mb_vlc.tab->table,
+ _ctx.mb_vlc.tab->_table,
IVI_VLC_BITS, 1);
mv_x += IVI_TOSIGNED(mv_delta);
mb->b_mv_x = -mv_x;