Hi,

Patch attached.

Umair
From 56281948ec484c19dd9009c861ded38905e1b786 Mon Sep 17 00:00:00 2001
From: Umair Khan <omerj...@gmail.com>
Date: Sat, 25 Jun 2016 22:48:02 +0530
Subject: [PATCH] avcodec/als: floating point support in ALS decoder

Signed-off-by: Umair Khan <omerj...@gmail.com>
---
 libavcodec/Makefile           |   2 +-
 libavcodec/alsdec.c           | 286 +++++++++++++++++++++++++++++++++++++++++-
 libavcodec/mlz.c              | 162 ++++++++++++++++++++++++
 libavcodec/mlz.h              |  67 ++++++++++
 libavutil/softfloat_ieee754.h | 115 +++++++++++++++++
 5 files changed, 629 insertions(+), 3 deletions(-)
 create mode 100644 libavcodec/mlz.c
 create mode 100644 libavcodec/mlz.h
 create mode 100644 libavutil/softfloat_ieee754.h

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 8f63261..3b6c7a8 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -161,7 +161,7 @@ OBJS-$(CONFIG_ALAC_DECODER)            += alac.o alac_data.o alacdsp.o
 OBJS-$(CONFIG_ALAC_ENCODER)            += alacenc.o alac_data.o
 OBJS-$(CONFIG_ALIAS_PIX_DECODER)       += aliaspixdec.o
 OBJS-$(CONFIG_ALIAS_PIX_ENCODER)       += aliaspixenc.o
-OBJS-$(CONFIG_ALS_DECODER)             += alsdec.o bgmc.o mpeg4audio.o
+OBJS-$(CONFIG_ALS_DECODER)             += alsdec.o bgmc.o mlz.o mpeg4audio.o
 OBJS-$(CONFIG_AMRNB_DECODER)           += amrnbdec.o celp_filters.o   \
                                           celp_math.o acelp_filters.o \
                                           acelp_vectors.o             \
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 842fc7d..00c7eab 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -35,8 +35,11 @@
 #include "bgmc.h"
 #include "bswapdsp.h"
 #include "internal.h"
+#include "mlz.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/crc.h"
+#include "libavutil/softfloat_ieee754.h"
+#include "libavutil/intfloat.h"
 
 #include <stdint.h>
 
@@ -225,6 +228,14 @@ typedef struct ALSDecContext {
     int32_t **raw_samples;          ///< decoded raw samples for each channel
     int32_t *raw_buffer;            ///< contains all decoded raw samples including carryover samples
     uint8_t *crc_buffer;            ///< buffer of byte order corrected samples used for CRC check
+    MLZ* mlz;                       ///< masked lz decompression structure
+    SoftFloat_IEEE754 *acf;         ///< contains common multiplier for all channels
+    int *last_acf_mantissa;         ///< contains the last acf mantissa data of common multiplier for all channels
+    int *shift_value;               ///< value by which the binary point is to be shifted for all channels
+    int *last_shift_value;          ///< contains last shift value for all channels
+    int **raw_mantissa;             ///< decoded mantissa bits of the difference signal
+    unsigned char *larray;          ///< buffer to store the output of masked lz decompression
+    int *nbits;                     ///< contains the number of bits to read for masked lz decompression for all samples
 } ALSDecContext;
 
 
@@ -441,7 +452,6 @@ static int check_specific_config(ALSDecContext *ctx)
         }                                               \
     }
 
-    MISSING_ERR(sconf->floating,  "Floating point decoding",     AVERROR_PATCHWELCOME);
     MISSING_ERR(sconf->rlslms,    "Adaptive RLS-LMS prediction", AVERROR_PATCHWELCOME);
 
     return error;
@@ -1351,6 +1361,241 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd,
 }
 
 
+/** multiply two softfloats and handle the rounding off
+ */
+static SoftFloat_IEEE754 multiply(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) {
+    uint64_t mantissa_temp;
+    uint64_t mask_64;
+    int bit_count;
+    int cutoff_bit_count;
+    unsigned char last_2_bits;
+    unsigned int mantissa;
+    uint32_t return_val = 0;
+    int32_t sign;
+
+    sign = a.sign ^ b.sign;
+
+    //Multiply mantissa bits in a 64-bit register
+    mantissa_temp = (uint64_t)a.mant * (uint64_t)b.mant;
+
+    // Count the valid bit count
+    for(bit_count=48, mask_64=(uint64_t)0x1 << 47; !(mantissa_temp & mask_64) && mask_64; bit_count--, mask_64>>=1);
+
+    // Round off
+    cutoff_bit_count = bit_count - 24;
+    if (cutoff_bit_count > 0) {
+        last_2_bits = (unsigned char)(((unsigned int)mantissa_temp >> (cutoff_bit_count - 1)) & 0x3 );
+        if ((last_2_bits == 0x3) || ((last_2_bits == 0x1) && ((unsigned int)mantissa_temp & ((0x1UL << (cutoff_bit_count - 1)) - 1)))) {
+            // Need to round up
+            mantissa_temp += (uint64_t)0x1 << cutoff_bit_count;
+        }
+    }
+
+    mantissa = (unsigned int)(mantissa_temp >> cutoff_bit_count);
+    // Need one more shift?
+    if (mantissa & 0x01000000ul) {
+        bit_count++;
+        mantissa >>= 1;
+    }
+
+    if (!sign) {
+        return_val = 0x80000000U;
+    }
+    return_val |= (a.exp + b.exp + bit_count - 47) << 23;
+    return_val |= mantissa;
+    return av_bits2sf_ieee754(return_val);
+}
+
+
+/** Read and decode the floating point sample data
+ */
+static int read_diff_float_data(ALSDecContext *ctx, unsigned int ra_frame) {
+    AVCodecContext *avctx   = ctx->avctx;
+    GetBitContext *gb       = &ctx->gb;
+    SoftFloat_IEEE754 *acf  = ctx->acf;
+    int *shift_value        = ctx->shift_value;
+    int *last_shift_value   = ctx->last_shift_value;
+    int *last_acf_mantissa  = ctx->last_acf_mantissa;
+    int **raw_mantissa      = ctx->raw_mantissa;
+    int *nbits              = ctx->nbits;
+    unsigned char *larray   = ctx->larray;
+    int frame_length        = ctx->cur_frame_length;
+    SoftFloat_IEEE754 scale = av_int2sf_ieee754(0x1u, 23);
+    unsigned int partA_flag;
+    unsigned int highest_byte;
+    unsigned int shift_amp;
+    uint32_t tmp_32;
+    int use_acf;
+    int nchars;
+    int i;
+    int c;
+    long k;
+    long nbits_aligned;
+    unsigned long acc;
+    unsigned long j;
+    uint32_t sign;
+    uint32_t e;
+    uint32_t mantissa;
+
+    skip_bits_long(gb, 32); //num_bytes_diff_float
+    use_acf = get_bits1(gb);
+
+    if (ra_frame) {
+        for (c = 0; c < avctx->channels; ++c) {
+            last_acf_mantissa[c] = 0;
+            last_shift_value[c] = 0;
+        }
+        ff_mlz_flush_dict(ctx->mlz);
+    }
+
+    for (c = 0; c < avctx->channels; ++c) {
+        if (use_acf) {
+            //acf_flag
+            if (get_bits1(gb)) {
+                tmp_32 = get_bits(gb, 23);
+                last_acf_mantissa[c] = tmp_32;
+            } else {
+                tmp_32 = last_acf_mantissa[c];
+            }
+            acf[c] = av_bits2sf_ieee754(tmp_32);
+        } else {
+            acf[c] = FLOAT_1;
+        }
+
+        highest_byte = get_bits(gb, 2);
+        shift_amp = get_bits1(gb);
+        partA_flag = get_bits1(gb);
+
+        if (shift_amp) {
+            shift_value[c] = get_bits(gb, 8);
+            last_shift_value[c] = shift_value[c];
+        } else {
+            shift_value[c] = last_shift_value[c];
+        }
+
+        if (partA_flag) {
+            if (!get_bits1(gb)) { //uncompressed
+
+                for (i = 0; i < frame_length; ++i) {
+                    if (ctx->raw_samples[c][i] == 0) {
+                        ctx->raw_mantissa[c][i] = get_bits_long(gb, 32);
+                    }
+                }
+
+            } else { //compressed
+                nchars = 0;
+                for (i = 0; i < frame_length; ++i) {
+                    if (ctx->raw_samples[c][i] == 0) {
+                        nchars += 4;
+                    }
+                }
+
+                tmp_32 = ff_mlz_decompression(ctx->mlz, gb, nchars, larray);
+                if(tmp_32 != nchars) {
+                    av_log(ctx->avctx, AV_LOG_ERROR, "Error in MLZ decompression (%d, %d).\n", tmp_32, nchars);
+                    return AVERROR_INVALIDDATA;
+                }
+
+                for (i = 0; i < frame_length; ++i) {
+                    tmp_32 = (larray[i] << 24) | larray[i+1] << 16 | larray[i+2] << 8 | larray[i+3];
+                    ctx->raw_mantissa[c][i] = tmp_32;
+                }
+            }
+        }
+
+        //decode part B
+        if (highest_byte) {
+
+            for (i = 0; i < frame_length; ++i) {
+                if (ctx->raw_samples[c][i] != 0) {
+                    //The following logic is taken from Tabel 14.45 and 14.46 from the ISO spec
+                    if (av_cmp_sf_ieee754(acf[c], FLOAT_1)) {
+                        nbits[i] = 23 - av_log2(abs(ctx->raw_samples[c][i]));
+                    } else {
+                        nbits[i] = 23;
+                    }
+                    nbits[i] = FFMIN(nbits[i], highest_byte*8);
+                }
+            }
+
+            if (!get_bits1(gb)) { //uncompressed
+
+                for (i = 0; i < frame_length; ++i) {
+                    if (ctx->raw_samples[c][i] != 0) {
+                        raw_mantissa[c][i] = get_bits(gb, nbits[i]);
+                    }
+                }
+
+            } else { //compressed
+
+                nchars = 0;
+                for (i = 0; i < frame_length; ++i) {
+                    if (ctx->raw_samples[c][i]) {
+                        nchars += (int) nbits[i] / 8;
+                        if (nbits[i] % 8 > 0) {
+                            ++nchars;
+                        }
+                    }
+                }
+
+                tmp_32 = ff_mlz_decompression(ctx->mlz, gb, nchars, larray);
+                if(tmp_32 != nchars) {
+                    av_log(ctx->avctx, AV_LOG_ERROR, "Error in MLZ decompression (%d, %d).\n", tmp_32, nchars);
+                    return AVERROR_INVALIDDATA;
+                }
+
+                j = 0;
+                for (i = 0; i < frame_length; ++i) {
+                    if (ctx->raw_samples[c][i]) {
+                        if ((nbits[i] % 8) > 0) {
+                            nbits_aligned = 8 * ((unsigned int)(nbits[i] / 8) + 1);
+                        } else {
+                            nbits_aligned = nbits[i];
+                        }
+                        acc = 0;
+                        for (k = 0; k < nbits_aligned/8; ++k) {
+                            acc = (acc << 8) + larray[j++];
+                        }
+                        acc >>= (nbits_aligned - nbits[i]);
+                        raw_mantissa[c][i] = acc;
+                    }
+                }
+
+            }
+        }
+
+        for (i = 0; i < frame_length; ++i) {
+            SoftFloat_IEEE754 pcm_sf = av_int2sf_ieee754(ctx->raw_samples[c][i], 0);
+            pcm_sf = av_div_sf_ieee754(pcm_sf, scale);
+
+            if (ctx->raw_samples[c][i] != 0) {
+                if (!av_cmp_sf_ieee754(acf[c], FLOAT_1)) {
+                    pcm_sf = multiply(acf[c], pcm_sf);
+                }
+
+                sign = pcm_sf.sign;
+                e = pcm_sf.exp;
+                mantissa = (pcm_sf.mant | 0x800000) + raw_mantissa[c][i];
+
+                while(mantissa >= 0x1000000) {
+                    e++;
+                    mantissa >>= 1;
+                }
+                if (mantissa) e += (shift_value[c] - 127);
+                mantissa &= 0x007fffffUL;
+
+                tmp_32 = (sign << 31) | ((e + EXP_BIAS) << 23) | (mantissa);
+                ctx->raw_samples[c][i] = tmp_32;
+            } else {
+                ctx->raw_samples[c][i] = raw_mantissa[c][i] & 0x007fffffUL;
+            }
+        }
+        align_get_bits(gb);
+    }
+    return 0;
+}
+
+
 /** Read the frame data.
  */
 static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
@@ -1492,7 +1737,9 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
                     sizeof(*ctx->raw_samples[c]) * sconf->max_order);
     }
 
-    // TODO: read_diff_float_data
+    if (sconf->floating) {
+        read_diff_float_data(ctx, ra_frame);
+    }
 
     if (get_bits_left(gb) < 0) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Overread %d\n", -get_bits_left(gb));
@@ -1662,6 +1909,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
     av_freep(&ctx->chan_data_buffer);
     av_freep(&ctx->reverted_channels);
     av_freep(&ctx->crc_buffer);
+    av_freep(&ctx->mlz);
+    av_freep(&ctx->acf);
+    av_freep(&ctx->last_acf_mantissa);
+    av_freep(&ctx->shift_value);
+    av_freep(&ctx->last_shift_value);
+    av_freep(&ctx->raw_mantissa);
+    av_freep(&ctx->larray);
+    av_freep(&ctx->nbits);
 
     return 0;
 }
@@ -1798,6 +2053,33 @@ static av_cold int decode_init(AVCodecContext *avctx)
     ctx->raw_buffer       = av_mallocz_array(avctx->channels * channel_size, sizeof(*ctx->raw_buffer));
     ctx->raw_samples      = av_malloc_array(avctx->channels, sizeof(*ctx->raw_samples));
 
+    if (sconf->floating) {
+        ctx->acf =  av_malloc_array(avctx->channels, sizeof(*ctx->acf));
+        ctx->shift_value = av_malloc_array(avctx->channels, sizeof(*ctx->shift_value));
+        ctx->last_shift_value = av_malloc_array(avctx->channels, sizeof(*ctx->last_shift_value));
+        ctx->last_acf_mantissa = av_malloc_array(avctx->channels, sizeof(*ctx->last_acf_mantissa));
+        ctx->raw_mantissa = av_malloc_array(avctx->channels, sizeof(*ctx->raw_mantissa));
+        for (int c = 0; c < avctx->channels; ++c) {
+            ctx->raw_mantissa[c] = av_malloc_array(ctx->cur_frame_length, sizeof(**ctx->raw_mantissa));
+            for (int i = 0; i < ctx->cur_frame_length; ++i) {
+                ctx->raw_mantissa[c][i] = 0x0u;
+            }
+        }
+        ctx->larray = av_malloc_array(ctx->cur_frame_length * 4, sizeof(*ctx->larray));
+        ctx->nbits = av_malloc_array(ctx->cur_frame_length, sizeof(*ctx->nbits));
+
+        ctx->mlz = av_malloc(sizeof(*ctx->mlz));
+        ff_mlz_init_dict(ctx->mlz);
+        ff_mlz_flush_dict(ctx->mlz);
+
+        if (!ctx->mlz || !ctx->acf || !ctx->shift_value || !ctx->last_shift_value
+            || !ctx->last_acf_mantissa || !ctx->raw_mantissa) {
+            av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+    }
+
     // allocate previous raw sample buffer
     if (!ctx->prev_raw_samples || !ctx->raw_buffer|| !ctx->raw_samples) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
diff --git a/libavcodec/mlz.c b/libavcodec/mlz.c
new file mode 100644
index 0000000..24d48e4
--- /dev/null
+++ b/libavcodec/mlz.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2016 Umair Khan <omerj...@gmail.com>
+ *
+ * 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
+ */
+
+#include "mlz.h"
+
+av_cold void ff_mlz_init_dict(MLZ *mlz) {
+    mlz->dict = av_malloc_array(TABLE_SIZE, sizeof(*mlz->dict));
+
+    mlz->flush_code            = FLUSH_CODE;
+    mlz->current_dic_index_max = DIC_INDEX_INIT;
+    mlz->dic_code_bit          = CODE_BIT_INIT;
+    mlz->bump_code             = (DIC_INDEX_INIT - 1);
+    mlz->next_code             = FIRST_CODE;
+    mlz->freeze_flag           = 0;
+}
+
+av_cold void ff_mlz_flush_dict(MLZ *mlz) {
+    MLZDict *dict = mlz->dict;
+    int i;
+    for ( i = 0; i < TABLE_SIZE; i++ ) {
+        dict[i].string_code = CODE_UNSET;
+        dict[i].parent_code = CODE_UNSET;
+        dict[i].match_len = 0;
+    }
+    mlz->current_dic_index_max = DIC_INDEX_INIT;
+    mlz->dic_code_bit          = CODE_BIT_INIT;  // DicCodeBitInit;
+    mlz->bump_code             = mlz->current_dic_index_max - 1;
+    mlz->next_code             = FIRST_CODE;
+    mlz->freeze_flag           = 0;
+}
+
+static void set_new_entry_dict(MLZDict* dict, int string_code, int parent_code, int char_code) {
+    dict[string_code].parent_code = parent_code;
+    dict[string_code].string_code = string_code;
+    dict[string_code].char_code   = char_code;
+    if (parent_code < FIRST_CODE) {
+        dict[string_code].match_len = 2;
+    } else {
+        dict[string_code].match_len = (dict[parent_code].match_len) + 1;
+    }
+}
+
+static int decode_string(MLZDict *dict, unsigned char *buff, int string_code, int *first_char_code, unsigned long bufsize) {
+    unsigned long count, offset;
+    int current_code, parent_code, tmp_code;
+
+    count            = 0;
+    current_code     = string_code;
+    *first_char_code = CODE_UNSET;
+
+    while (count < bufsize) {
+        switch (current_code) {
+        case CODE_UNSET:
+            return count;
+            break;
+        default:
+            if (current_code < FIRST_CODE) {
+                *first_char_code = current_code;
+                buff[0] = current_code;
+                count++;
+                return count;
+            } else {
+                offset  = dict[current_code].match_len - 1;
+                tmp_code = dict[current_code].char_code;
+                buff[offset] = tmp_code;
+                count++;
+            }
+            current_code = dict[current_code].parent_code;
+            if ((current_code < 0) || (current_code > (DIC_INDEX_MAX - 1))) {
+                av_log(NULL, AV_LOG_ERROR, "Dic index error.\n");
+                return count;
+            }
+            if (current_code > FIRST_CODE) {
+                parent_code = dict[current_code].parent_code;
+                offset = (dict[current_code].match_len) - 1;
+                if (parent_code < 0 || parent_code > DIC_INDEX_MAX-1) {
+                    av_log(NULL, AV_LOG_ERROR, "Dic index error.\n");
+                    return count;
+                }
+                if (( offset > (DIC_INDEX_MAX - 1))) {
+                    av_log(NULL, AV_LOG_ERROR, "Dic offset error.\n");
+                    return count;
+                }
+            }
+            break;
+        }
+    }
+    return count;
+}
+
+int ff_mlz_decompression(MLZ* mlz, GetBitContext* gb, int size, unsigned char *buff) {
+    MLZDict *dict = mlz->dict;
+    unsigned long output_chars;
+    int string_code, last_string_code, char_code;
+
+    string_code = 0;
+    char_code   = -1;
+    last_string_code = -1;
+    output_chars = 0;
+
+    while (output_chars < size) {
+        string_code = get_bits(gb, mlz->dic_code_bit);
+        switch (string_code) {
+            case FLUSH_CODE:
+            case MAX_CODE:
+                ff_mlz_flush_dict(mlz);
+                char_code = -1;
+                last_string_code = -1;
+                break;
+            case FREEZE_CODE:
+                mlz->freeze_flag = 1;
+                break;
+            default:
+                if (string_code > mlz->current_dic_index_max) {
+                    av_log(NULL, AV_LOG_ERROR, "String code %d exceeds maximum value of %d.\n", string_code, mlz->current_dic_index_max);
+                    return output_chars;
+                }
+                if (string_code == (int) mlz->bump_code) {
+                    ++mlz->dic_code_bit;
+                    mlz->current_dic_index_max *= 2;
+                    mlz->bump_code = mlz->current_dic_index_max - 1;
+                } else {
+                    if (string_code >= mlz->next_code) {
+                        output_chars += decode_string(dict, &buff[output_chars], last_string_code, &char_code, size - output_chars);
+                        output_chars += decode_string(dict, &buff[output_chars], char_code, &char_code, size - output_chars);
+                        set_new_entry_dict(dict, mlz->next_code, last_string_code, char_code);
+                        mlz->next_code++;
+                    } else {
+                        output_chars += decode_string(dict, &buff[output_chars], string_code, &char_code, size - output_chars);
+                        if (output_chars <= size && !mlz->freeze_flag) {
+                            if (last_string_code != -1) {
+                                set_new_entry_dict(dict, mlz->next_code, last_string_code, char_code);
+                                mlz->next_code++;
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                    last_string_code = string_code;
+                }
+                break;
+        }
+    }
+    return output_chars;
+}
diff --git a/libavcodec/mlz.h b/libavcodec/mlz.h
new file mode 100644
index 0000000..00f34c1
--- /dev/null
+++ b/libavcodec/mlz.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Umair Khan <omerj...@gmail.com>
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_MLZ_H
+#define AVCODEC_MLZ_H
+
+#include "get_bits.h"
+
+#define CODE_UNSET          -1
+#define CODE_BIT_INIT       9
+#define DIC_INDEX_INIT      512     // 2^9
+#define DIC_INDEX_MAX       32768L  // 2^15
+#define FLUSH_CODE          256
+#define FREEZE_CODE         257
+#define FIRST_CODE          258
+#define MAX_CODE            32767L
+#define TABLE_SIZE          35023L  // TABLE_SIZE must be a prime number
+
+/** Dictionary structure for mlz decompression
+ */
+typedef struct MLZDict {
+    int  string_code;
+    int  parent_code;
+    int  char_code;
+    int  match_len;
+} MLZDict;
+
+/** MLZ data strucure
+ */
+typedef struct MLZ {
+    int dic_code_bit;
+    int current_dic_index_max;
+    unsigned int bump_code;
+    unsigned int flush_code;
+    int next_code;
+    int freeze_flag;
+    MLZDict* dict;
+} MLZ;
+
+/** Initialize the dictionary
+ */
+void ff_mlz_init_dict(MLZ *mlz);
+/** Flush the dictionary
+ */
+void ff_mlz_flush_dict(MLZ *dict);
+/** Run mlz decompression on the next size bits and the output will be stored in buff
+ */
+int ff_mlz_decompression(MLZ* mlz, GetBitContext* gb, int size, unsigned char *buff);
+
+#endif /*AVCODEC_MLZ_H*/
diff --git a/libavutil/softfloat_ieee754.h b/libavutil/softfloat_ieee754.h
new file mode 100644
index 0000000..7c4745b
--- /dev/null
+++ b/libavutil/softfloat_ieee754.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016 Umair Khan <omerj...@gmail.com>
+ *
+ * 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
+ */
+
+#ifndef AVUTIL_SOFTFLOAT_IEEE754_H
+#define AVUTIL_SOFTFLOAT_IEEE754_H
+
+#include <stdint.h>
+
+#define EXP_BIAS 127
+#define MANT_BITS 23
+
+typedef struct SoftFloat_IEEE754 {
+    int32_t sign;
+    uint64_t mant;
+    int32_t  exp;
+} SoftFloat_IEEE754;
+
+static const SoftFloat_IEEE754 FLOAT_0 = {0, 0, -126};
+static const SoftFloat_IEEE754 FLOAT_1 = {0, 0,    0};
+
+/** Normalize the softfloat as defined by IEEE 754 single-recision floating
+ *  point specification
+ */
+static SoftFloat_IEEE754 av_normalize_sf_ieee754(SoftFloat_IEEE754 sf) {
+    while( sf.mant >= 0x1000000UL ) {
+        sf.exp++;
+        sf.mant >>= 1;
+    }
+    sf.mant &= 0x007fffffUL;
+    return sf;
+}
+
+/** Convert integer to softfloat.
+ *  @return softfloat with value n * 2^e
+ */
+static SoftFloat_IEEE754 av_int2sf_ieee754(int64_t n, int e) {
+    int sign = 0;
+
+    if (n < 0) {
+        sign = 1;
+        n    *= -1;
+    }
+    return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, n << MANT_BITS, 0 + e});
+}
+
+/** Make a softfloat out of the bitstream. Assumes the bits are in the form as defined
+ *  by the IEEE 754 spec.
+ */
+static SoftFloat_IEEE754 av_bits2sf_ieee754(uint32_t n) {
+    return ((SoftFloat_IEEE754) { (n & 0x80000000UL), (n & 0x7F800000UL), (n & 0x7FFFFFUL) });
+}
+
+/** Convert the softfloat to integer
+ */
+static int av_sf2int_ieee754(SoftFloat_IEEE754 a) {
+    if(a.exp >= 0) return a.mant <<  a.exp ;
+    else           return a.mant >>(-a.exp);
+}
+
+/** Divide a by b. b should not be zero.
+ *  @return normalized result
+ */
+static SoftFloat_IEEE754 av_div_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) {
+    int32_t mant, exp, sign;
+    a    = av_normalize_sf_ieee754(a);
+    b    = av_normalize_sf_ieee754(b);
+    sign = a.sign ^ b.sign;
+    mant = ((((uint64_t) (a.mant | 0x00800000UL)) << MANT_BITS) / (b.mant| 0x00800000UL));
+    exp  = a.exp - b.exp;
+    return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp});
+}
+
+/** Multiply a with b
+ *  #return normalized result
+ */
+static SoftFloat_IEEE754 av_mul_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) {
+    int32_t sign, mant, exp;
+    a    = av_normalize_sf_ieee754(a);
+    b    = av_normalize_sf_ieee754(b);
+    sign = a.sign ^ b.sign;
+    mant = (((uint64_t)(a.mant|0x00800000UL) * (uint64_t)(b.mant|0x00800000UL))>>MANT_BITS);
+    exp  = a.exp + b.exp;
+    return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp});
+}
+
+/** Compare a with b strictly
+ *  @returns 1 if the a and b are equal, 0 otherwise.
+ */
+static int av_cmp_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) {
+    a = av_normalize_sf_ieee754(a);
+    b = av_normalize_sf_ieee754(b);
+    if (a.sign != b.sign) return 0;
+    if (a.mant != b.mant) return 0;
+    if (a.exp  != b.exp ) return 0;
+    return 1;
+}
+
+#endif /*AVUTIL_SOFTFLOAT_IEEE754_H*/
-- 
2.7.4

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to