You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avcodec/exr: add support for half-float DWAA/B compression
Fixes ticket #11555. Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@ -1129,15 +1129,40 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
|||||||
|
|
||||||
{
|
{
|
||||||
const int o = s->nb_channels == 4;
|
const int o = s->nb_channels == 4;
|
||||||
|
float *yb = td->block[0];
|
||||||
|
float *ub = td->block[1];
|
||||||
|
float *vb = td->block[2];
|
||||||
|
if (s->pixel_type == EXR_HALF) {
|
||||||
|
uint16_t *bo = ((uint16_t *)td->uncompressed_data) +
|
||||||
|
y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x;
|
||||||
|
uint16_t *go = ((uint16_t *)td->uncompressed_data) +
|
||||||
|
y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x;
|
||||||
|
uint16_t *ro = ((uint16_t *)td->uncompressed_data) +
|
||||||
|
y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x;
|
||||||
|
|
||||||
|
for (int yy = 0; yy < 8; yy++) {
|
||||||
|
for (int xx = 0; xx < 8; xx++) {
|
||||||
|
const int idx = xx + yy * 8;
|
||||||
|
float b, g, r;
|
||||||
|
|
||||||
|
convert(yb[idx], ub[idx], vb[idx], &b, &g, &r);
|
||||||
|
|
||||||
|
bo[xx] = float2half(av_float2int(to_linear(b, 1.f)), &s->f2h_tables);
|
||||||
|
go[xx] = float2half(av_float2int(to_linear(g, 1.f)), &s->f2h_tables);
|
||||||
|
ro[xx] = float2half(av_float2int(to_linear(r, 1.f)), &s->f2h_tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
bo += td->xsize * s->nb_channels;
|
||||||
|
go += td->xsize * s->nb_channels;
|
||||||
|
ro += td->xsize * s->nb_channels;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
float *bo = ((float *)td->uncompressed_data) +
|
float *bo = ((float *)td->uncompressed_data) +
|
||||||
y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x;
|
y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x;
|
||||||
float *go = ((float *)td->uncompressed_data) +
|
float *go = ((float *)td->uncompressed_data) +
|
||||||
y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x;
|
y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x;
|
||||||
float *ro = ((float *)td->uncompressed_data) +
|
float *ro = ((float *)td->uncompressed_data) +
|
||||||
y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x;
|
y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x;
|
||||||
float *yb = td->block[0];
|
|
||||||
float *ub = td->block[1];
|
|
||||||
float *vb = td->block[2];
|
|
||||||
|
|
||||||
for (int yy = 0; yy < 8; yy++) {
|
for (int yy = 0; yy < 8; yy++) {
|
||||||
for (int xx = 0; xx < 8; xx++) {
|
for (int xx = 0; xx < 8; xx++) {
|
||||||
@ -1154,6 +1179,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
|||||||
go += td->xsize * s->nb_channels;
|
go += td->xsize * s->nb_channels;
|
||||||
ro += td->xsize * s->nb_channels;
|
ro += td->xsize * s->nb_channels;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1161,6 +1187,16 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
|||||||
if (s->nb_channels < 4)
|
if (s->nb_channels < 4)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (s->pixel_type == EXR_HALF) {
|
||||||
|
for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
|
||||||
|
uint16_t *ao = ((uint16_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
|
||||||
|
uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
|
||||||
|
uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2;
|
||||||
|
|
||||||
|
for (int x = 0; x < td->xsize; x++)
|
||||||
|
ao[x] = ai0[x] | (ai1[x] << 8);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
|
for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
|
||||||
uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
|
uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
|
||||||
uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
|
uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
|
||||||
@ -1172,6 +1208,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
|||||||
ao[x] = half2float(ha, &s->h2f_tables);
|
ao[x] = half2float(ha, &s->h2f_tables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1387,9 +1424,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
|
|||||||
if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
|
if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
|
||||||
memset(ptr, 0, bxmin);
|
memset(ptr, 0, bxmin);
|
||||||
|
|
||||||
if (s->pixel_type == EXR_FLOAT ||
|
if (s->pixel_type == EXR_FLOAT) {
|
||||||
s->compression == EXR_DWAA ||
|
|
||||||
s->compression == EXR_DWAB) {
|
|
||||||
// 32-bit
|
// 32-bit
|
||||||
#if FF_API_EXR_GAMMA
|
#if FF_API_EXR_GAMMA
|
||||||
if (trc_func && (!c || (c < 3 && s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))) {
|
if (trc_func && (!c || (c < 3 && s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))) {
|
||||||
@ -2039,16 +2074,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
|||||||
if ((ret = decode_header(s, picture)) < 0)
|
if ((ret = decode_header(s, picture)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((s->compression == EXR_DWAA || s->compression == EXR_DWAB) &&
|
|
||||||
s->pixel_type == EXR_HALF) {
|
|
||||||
s->current_channel_offset *= 2;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
s->channel_offsets[i] *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (s->pixel_type) {
|
switch (s->pixel_type) {
|
||||||
case EXR_HALF:
|
case EXR_HALF:
|
||||||
if (!(s->compression == EXR_DWAA || s->compression == EXR_DWAB)) {
|
|
||||||
if (s->channel_offsets[3] >= 0) {
|
if (s->channel_offsets[3] >= 0) {
|
||||||
if (!s->is_luma) {
|
if (!s->is_luma) {
|
||||||
avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
|
avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
|
||||||
@ -2063,7 +2090,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case EXR_FLOAT:
|
case EXR_FLOAT:
|
||||||
if (s->channel_offsets[3] >= 0) {
|
if (s->channel_offsets[3] >= 0) {
|
||||||
if (!s->is_luma) {
|
if (!s->is_luma) {
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "version_major.h"
|
#include "version_major.h"
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MINOR 3
|
#define LIBAVCODEC_VERSION_MINOR 3
|
||||||
#define LIBAVCODEC_VERSION_MICRO 100
|
#define LIBAVCODEC_VERSION_MICRO 101
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
LIBAVCODEC_VERSION_MINOR, \
|
LIBAVCODEC_VERSION_MINOR, \
|
||||||
|
Reference in New Issue
Block a user