History

avcodec/exr: add support for half-float DWAA/B compression

Fixes ticket #11555.

James Almer committed 1 year ago

Commit d08c5521 parent 0cabfdc2 files · +42 −16Browse files

Showing the changes to libavcodec (2 of 2 files). Show all

Unified · Split

2 files
  1. libavcodec/exr.c +41 −15
  2. libavcodec/version.h +1 −1
libavcodec/exr.c+41−15
@@ -1129,15 +1129,40 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse · 1128 unmodified lines
1129 1129
1130 {1130 {
1131 const int o = s->nb_channels == 4;1131 const int o = s->nb_channels == 4;
1132 float *yb = td->block[0];
1133 float *ub = td->block[1];
1134 float *vb = td->block[2];
1135 if (s->pixel_type == EXR_HALF) {
1136 uint16_t *bo = ((uint16_t *)td->uncompressed_data) +
1137 y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x;
1138 uint16_t *go = ((uint16_t *)td->uncompressed_data) +
1139 y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x;
1140 uint16_t *ro = ((uint16_t *)td->uncompressed_data) +
1141 y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x;
1142
1143 for (int yy = 0; yy < 8; yy++) {
1144 for (int xx = 0; xx < 8; xx++) {
1145 const int idx = xx + yy * 8;
1146 float b, g, r;
1147
1148 convert(yb[idx], ub[idx], vb[idx], &b, &g, &r);
1149
1150 bo[xx] = float2half(av_float2int(to_linear(b, 1.f)), &s->f2h_tables);
1151 go[xx] = float2half(av_float2int(to_linear(g, 1.f)), &s->f2h_tables);
1152 ro[xx] = float2half(av_float2int(to_linear(r, 1.f)), &s->f2h_tables);
1153 }
1154
1155 bo += td->xsize * s->nb_channels;
1156 go += td->xsize * s->nb_channels;
1157 ro += td->xsize * s->nb_channels;
1158 }
1159 } else {
1132 float *bo = ((float *)td->uncompressed_data) +1160 float *bo = ((float *)td->uncompressed_data) +
1133 y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x;1161 y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x;
1134 float *go = ((float *)td->uncompressed_data) +1162 float *go = ((float *)td->uncompressed_data) +
1135 y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x;1163 y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x;
1136 float *ro = ((float *)td->uncompressed_data) +1164 float *ro = ((float *)td->uncompressed_data) +
1137 y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x;1165 y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x;
1138 float *yb = td->block[0];
1139 float *ub = td->block[1];
1140 float *vb = td->block[2];
1141 1166
1142 for (int yy = 0; yy < 8; yy++) {1167 for (int yy = 0; yy < 8; yy++) {
1143 for (int xx = 0; xx < 8; xx++) {1168 for (int xx = 0; xx < 8; xx++) {
@@ -1154,6 +1179,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse · 10 unmodified lines
1154 go += td->xsize * s->nb_channels;1179 go += td->xsize * s->nb_channels;
1155 ro += td->xsize * s->nb_channels;1180 ro += td->xsize * s->nb_channels;
1156 }1181 }
1182 }
1157 }1183 }
1158 }1184 }
1159 }1185 }
@@ -1161,6 +1187,16 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse · 1 unmodified line
1161 if (s->nb_channels < 4)1187 if (s->nb_channels < 4)
1162 return 0;1188 return 0;
1163 1189
1190 if (s->pixel_type == EXR_HALF) {
1191 for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
1192 uint16_t *ao = ((uint16_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
1193 uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
1194 uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2;
1195
1196 for (int x = 0; x < td->xsize; x++)
1197 ao[x] = ai0[x] | (ai1[x] << 8);
1198 }
1199 } else {
1164 for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {1200 for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
1165 uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;1201 uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
1166 uint8_t *ai0 = td->rle_raw_data + y * td->xsize;1202 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 · 5 unmodified lines
1172 ao[x] = half2float(ha, &s->h2f_tables);1208 ao[x] = half2float(ha, &s->h2f_tables);
1173 }1209 }
1174 }1210 }
1211 }
1175 1212
1176 return 0;1213 return 0;
1177}1214}
@@ -1387,9 +1424,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, · 209 unmodified lines
1387 if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)1424 if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
1388 memset(ptr, 0, bxmin);1425 memset(ptr, 0, bxmin);
1389 1426
1390 if (s->pixel_type == EXR_FLOAT ||1427 if (s->pixel_type == EXR_FLOAT) {
1391 s->compression == EXR_DWAA ||
1392 s->compression == EXR_DWAB) {
1393 // 32-bit1428 // 32-bit
1394#if FF_API_EXR_GAMMA1429#if FF_API_EXR_GAMMA
1395 if (trc_func && (!c || (c < 3 && s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))) {1430 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, · 643 unmodified lines
2039 if ((ret = decode_header(s, picture)) < 0)2074 if ((ret = decode_header(s, picture)) < 0)
2040 return ret;2075 return ret;
2041 2076
2042 if ((s->compression == EXR_DWAA || s->compression == EXR_DWAB) &&
2043 s->pixel_type == EXR_HALF) {
2044 s->current_channel_offset *= 2;
2045 for (int i = 0; i < 4; i++)
2046 s->channel_offsets[i] *= 2;
2047 }
2048
2049 switch (s->pixel_type) {2077 switch (s->pixel_type) {
2050 case EXR_HALF:2078 case EXR_HALF:
2051 if (!(s->compression == EXR_DWAA || s->compression == EXR_DWAB)) {
2052 if (s->channel_offsets[3] >= 0) {2079 if (s->channel_offsets[3] >= 0) {
2053 if (!s->is_luma) {2080 if (!s->is_luma) {
2054 avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;2081 avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
@@ -2063,7 +2090,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture, · 8 unmodified lines
2063 }2090 }
2064 }2091 }
2065 break;2092 break;
2066 }
2067 case EXR_FLOAT:2093 case EXR_FLOAT:
2068 if (s->channel_offsets[3] >= 0) {2094 if (s->channel_offsets[3] >= 0) {
2069 if (!s->is_luma) {2095 if (!s->is_luma) {
libavcodec/version.h+1−1
@@ -30,7 +30,7 @@ · 29 unmodified lines
30#include "version_major.h"30#include "version_major.h"
31 31
32#define LIBAVCODEC_VERSION_MINOR 332#define LIBAVCODEC_VERSION_MINOR 3
33#define LIBAVCODEC_VERSION_MICRO 10033#define LIBAVCODEC_VERSION_MICRO 101
34 34
35#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \35#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
36 LIBAVCODEC_VERSION_MINOR, \36 LIBAVCODEC_VERSION_MINOR, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t