summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Vignali <martin.vignali@gmail.com>2018-11-17 23:37:23 +0100
committerMartin Vignali <martin.vignali@gmail.com>2018-12-02 12:55:48 +0100
commitfddc92d45479950e5a2a718563f6347e26bc3c11 (patch)
tree742b3bf0a454d613c435f67fc9b90b0b7675f470
parent859604fe9d680fbd1abc4b78a528909904874d95 (diff)
avcodec/proresdec : add unpack alpha 12 func
-rw-r--r--libavcodec/proresdec2.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index 40d15720ba..8a537eed1a 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -46,6 +46,11 @@ static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[
dst[i] = permutation[src[i]];
}
+#define ALPHA_SHIFT_16_TO_10(alpha_val) (alpha_val >> 6)
+#define ALPHA_SHIFT_8_TO_10(alpha_val) ((alpha_val << 2) | (alpha_val >> 6))
+#define ALPHA_SHIFT_16_TO_12(alpha_val) (alpha_val >> 4)
+#define ALPHA_SHIFT_8_TO_12(alpha_val) ((alpha_val << 4) | (alpha_val >> 4))
+
static void inline unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs,
const int num_bits, const int decode_precision) {
const int mask = (1 << num_bits) - 1;
@@ -67,9 +72,17 @@ static void inline unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs
}
alpha_val = (alpha_val + val) & mask;
if (num_bits == 16) {
- dst[idx++] = alpha_val >> 6;
+ if (decode_precision == 10) {
+ dst[idx++] = ALPHA_SHIFT_16_TO_10(alpha_val);
+ } else { /* 12b */
+ dst[idx++] = ALPHA_SHIFT_16_TO_12(alpha_val);
+ }
} else {
- dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+ if (decode_precision == 10) {
+ dst[idx++] = ALPHA_SHIFT_8_TO_10(alpha_val);
+ } else { /* 12b */
+ dst[idx++] = ALPHA_SHIFT_8_TO_12(alpha_val);
+ }
}
if (idx >= num_coeffs)
break;
@@ -80,11 +93,21 @@ static void inline unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs
if (idx + val > num_coeffs)
val = num_coeffs - idx;
if (num_bits == 16) {
- for (i = 0; i < val; i++)
- dst[idx++] = alpha_val >> 6;
+ for (i = 0; i < val; i++) {
+ if (decode_precision == 10) {
+ dst[idx++] = ALPHA_SHIFT_16_TO_10(alpha_val);
+ } else { /* 12b */
+ dst[idx++] = ALPHA_SHIFT_16_TO_12(alpha_val);
+ }
+ }
} else {
- for (i = 0; i < val; i++)
- dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+ for (i = 0; i < val; i++) {
+ if (decode_precision == 10) {
+ dst[idx++] = ALPHA_SHIFT_8_TO_10(alpha_val);
+ } else { /* 12b */
+ dst[idx++] = ALPHA_SHIFT_8_TO_12(alpha_val);
+ }
+ }
}
} while (idx < num_coeffs);
}
@@ -99,6 +122,16 @@ static void unpack_alpha_10(GetBitContext *gb, uint16_t *dst, int num_coeffs,
}
}
+static void unpack_alpha_12(GetBitContext *gb, uint16_t *dst, int num_coeffs,
+ const int num_bits)
+{
+ if (num_bits == 16) {
+ unpack_alpha(gb, dst, num_coeffs, 16, 12);
+ } else { /* 8 bits alpha */
+ unpack_alpha(gb, dst, num_coeffs, 8, 12);
+ }
+}
+
static av_cold int decode_init(AVCodecContext *avctx)
{
int ret = 0;
@@ -146,6 +179,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
if (avctx->bits_per_raw_sample == 10){
ctx->unpack_alpha = unpack_alpha_10;
+ } else if (avctx->bits_per_raw_sample == 12){
+ ctx->unpack_alpha = unpack_alpha_12;
} else {
av_log(avctx, AV_LOG_ERROR, "Fail to set unpack_alpha for bits per raw sample %d\n", avctx->bits_per_raw_sample);
return AVERROR_BUG;