/**
* @file encode.c
+ *
* @author Mathis Rosenhauer, Deutsches Klimarechenzentrum
+ * @author Moritz Hanke, Deutsches Klimarechenzentrum
+ * @author Joerg Behrens, Deutsches Klimarechenzentrum
+ * @author Luis Kornblueh, Max-Planck-Institut fuer Meteorologie
+ *
+ * @section LICENSE
+ * Copyright 2012
+ *
+ * Mathis Rosenhauer, Luis Kornblueh
+ * Moritz Hanke,
+ * Joerg Behrens
+ *
+ * Deutsches Klimarechenzentrum GmbH Max-Planck-Institut fuer Meteorologie
+ * Bundesstr. 45a Bundesstr. 53
+ * 20146 Hamburg 20146 Hamburg
+ * Germany Germany
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
* @section DESCRIPTION
*
* Adaptive Entropy Encoder
{
/**
Preprocess RSI of unsigned samples.
+
+ Combining preprocessing and converting to uint32_t in one loop
+ is slower due to the data dependance on x_i-1.
*/
- int64_t D;
+ uint32_t D;
struct internal_state *state = strm->state;
const uint32_t *x = state->data_raw;
uint32_t *d = state->data_pp;
while (rsi--) {
if (x[1] >= x[0]) {
D = x[1] - x[0];
- if (D <= x[0]) {
+ if (D <= x[0])
*d = 2 * D;
- } else {
+ else
*d = x[1];
- }
} else {
D = x[0] - x[1];
- if (D <= xmax - x[0]) {
+ if (D <= xmax - x[0])
*d = 2 * D - 1;
- } else {
+ else
*d = xmax - x[1];
- }
}
d++;
x++;
}
+ state->ref = 1;
}
static void preprocess_signed(struct aec_stream *strm)
x++;
d++;
}
+ state->ref = 1;
}
static uint64_t block_fs(struct aec_stream *strm, int k)
}
emit(state, 0, state->bits);
- if (state->direct_out == 0)
- *strm->next_out++ = *state->cds;
- strm->avail_out--;
- strm->total_out++;
-
+ if (strm->avail_out > 0) {
+ if (!state->direct_out)
+ *strm->next_out++ = *state->cds;
+ strm->avail_out--;
+ strm->total_out++;
+ }
return M_EXIT;
}
} else {
}
} while (++state->i < strm->rsi * strm->block_size);
- state->blocks_avail = strm->rsi - 1;
- if (strm->flags & AEC_DATA_PREPROCESS) {
+ if (strm->flags & AEC_DATA_PREPROCESS)
state->preprocess(strm);
- state->ref = 1;
- }
return m_check_zero_block(strm);
}
}
if (state->blocks_avail == 0) {
+ state->blocks_avail = strm->rsi - 1;
state->block = state->data_pp;
- if (strm->avail_in >= state->block_len * strm->rsi) {
+ if (strm->avail_in >= state->rsi_len) {
state->get_rsi(strm);
- state->blocks_avail = strm->rsi - 1;
-
- if (strm->flags & AEC_DATA_PREPROCESS) {
+ if (strm->flags & AEC_DATA_PREPROCESS)
state->preprocess(strm);
- state->ref = 1;
- }
+
return m_check_zero_block(strm);
} else {
state->i = 0;
if (strm->rsi > 4096)
return AEC_CONF_ERROR;
- state = (struct internal_state *)malloc(sizeof(struct internal_state));
+ state = malloc(sizeof(struct internal_state));
if (state == NULL)
return AEC_MEM_ERROR;
if (strm->bits_per_sample <= 24
&& strm->flags & AEC_DATA_3BYTE) {
- state->block_len = 3 * strm->block_size;
+ state->rsi_len = 3;
if (strm->flags & AEC_DATA_MSB) {
- state->get_sample = get_msb_24;
- state->get_rsi = get_rsi_msb_24;
+ state->get_sample = aec_get_msb_24;
+ state->get_rsi = aec_get_rsi_msb_24;
} else {
- state->get_sample = get_lsb_24;
- state->get_rsi = get_rsi_lsb_24;
+ state->get_sample = aec_get_lsb_24;
+ state->get_rsi = aec_get_rsi_lsb_24;
}
} else {
- state->block_len = 4 * strm->block_size;
+ state->rsi_len = 4;
if (strm->flags & AEC_DATA_MSB) {
- state->get_sample = get_msb_32;
- state->get_rsi = get_rsi_msb_32;
+ state->get_sample = aec_get_msb_32;
+ state->get_rsi = aec_get_rsi_msb_32;
} else {
- state->get_sample = get_lsb_32;
- state->get_rsi = get_rsi_lsb_32;
+ state->get_sample = aec_get_lsb_32;
+ state->get_rsi = aec_get_rsi_lsb_32;
}
}
}
else if (strm->bits_per_sample > 8) {
/* 16 bit settings */
state->id_len = 4;
- state->block_len = 2 * strm->block_size;
+ state->rsi_len = 2;
if (strm->flags & AEC_DATA_MSB) {
- state->get_sample = get_msb_16;
- state->get_rsi = get_rsi_msb_16;
+ state->get_sample = aec_get_msb_16;
+ state->get_rsi = aec_get_rsi_msb_16;
} else {
- state->get_sample = get_lsb_16;
- state->get_rsi = get_rsi_lsb_16;
+ state->get_sample = aec_get_lsb_16;
+ state->get_rsi = aec_get_rsi_lsb_16;
}
} else {
/* 8 bit settings */
state->id_len = 3;
- state->block_len = strm->block_size;
+ state->rsi_len = 1;
- state->get_sample = get_8;
- state->get_rsi = get_rsi_8;
+ state->get_sample = aec_get_8;
+ state->get_rsi = aec_get_rsi_8;
}
+ state->rsi_len *= strm->rsi * strm->block_size;
if (strm->flags & AEC_DATA_SIGNED) {
state->xmin = -(1ULL << (strm->bits_per_sample - 1));
state->kmax = (1U << state->id_len) - 3;
- state->data_pp = (uint32_t *)malloc(strm->rsi
- * strm->block_size
- * sizeof(uint32_t));
+ state->data_pp = malloc(strm->rsi
+ * strm->block_size
+ * sizeof(uint32_t));
if (state->data_pp == NULL)
return AEC_MEM_ERROR;
if (strm->flags & AEC_DATA_PREPROCESS) {
- state->data_raw = (uint32_t *)malloc(strm->rsi
- * strm->block_size
- * sizeof(uint32_t));
+ state->data_raw = malloc(strm->rsi
+ * strm->block_size
+ * sizeof(uint32_t));
if (state->data_raw == NULL)
return AEC_MEM_ERROR;
} else {
/* Largest possible CDS according to specs */
state->cds_len = (5 + 64 * 32) / 8 + 3;
- state->cds_buf = (uint8_t *)malloc(state->cds_len);
+ state->cds_buf = malloc(state->cds_len);
if (state->cds_buf == NULL)
return AEC_MEM_ERROR;