History

avcodec/exr: use luma+alpha float pixel formats

James Almer committed 1 year ago

Commit 04d7a6d1 parent 468577d2 files · +25 −47Browse files

Unified · Split

2 files
  1. libavcodec/exr.c +24 −46
  2. tests/ref/fate/exr-ya-scanline-zip-half-12x8 +1 −1
libavcodec/exr.c+24−46
@@ -1352,77 +1352,61 @@ static int decode_block(AVCodecContext *avctx, void *tdata, · 1351 unmodified lines
1352 data_yoffset = FFABS(FFMIN(0, line));1352 data_yoffset = FFABS(FFMIN(0, line));
1353 data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset;1353 data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset;
1354 1354
1355 if (s->channel_offsets[3] >= 0)
1356 channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
1355 if (!s->is_luma) {1357 if (!s->is_luma) {
1356 channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset;1358 channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset;
1357 channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;1359 channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
1358 channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset;1360 channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset;
1359 rgb_channel_count = 3;1361 rgb_channel_count = 3;
1360 } else { /* put y data in the first channel_buffer */1362 } else { /* put y data in the first channel_buffer and if needed, alpha in the second */
1361 channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;1363 channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
1364 if (!(s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))
1365 channel_buffer[1] = channel_buffer[3];
1362 rgb_channel_count = 1;1366 rgb_channel_count = 1;
1363 }1367 }
1364 if (s->channel_offsets[3] >= 0)
1365 channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
1366 1368
1367 if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || s->desc->nb_components == 1 ) {1369 if (s->desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
1368 /* todo: change this when a floating point pixel format with luma with alpha is implemented */1370 for (c = 0; c < s->desc->nb_components; c++) {
1369 int channel_count = s->channel_offsets[3] >= 0 ? 4 : rgb_channel_count;
1370 if (s->is_luma) {
1371 channel_buffer[1] = channel_buffer[0];
1372 channel_buffer[2] = channel_buffer[0];
1373 }
1374
1375 for (c = 0; c < channel_count; c++) {
1376 int plane = s->desc->comp[c].plane;1371 int plane = s->desc->comp[c].plane;
1377 ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step);1372 ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step) + s->desc->comp[c].offset;
1378 1373
1379 for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) {1374 for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) {
1380 const uint8_t *src;1375 const uint8_t *src = channel_buffer[c];
1376 uint8_t *ptr_x = ptr + window_xoffset * step;
1377
1378 // Zero out the start if xmin is not 0
1379 if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
1380 memset(ptr, 0, bxmin);
1381 1381
1382 if (s->pixel_type == EXR_FLOAT ||1382 if (s->pixel_type == EXR_FLOAT ||
1383 s->compression == EXR_DWAA ||1383 s->compression == EXR_DWAA ||
1384 s->compression == EXR_DWAB) {1384 s->compression == EXR_DWAB) {
1385 // 32-bit1385 // 32-bit
1386 uint8_t *ptr_x = ptr;1386 if (trc_func && (!c || (c < 3 && s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))) {
1387 1387 for (int x = 0; x < xsize; x++, ptr_x += step) {
1388 src = channel_buffer[c];
1389
1390 // Zero out the start if xmin is not 0
1391 memset(ptr_x, 0, bxmin);
1392 ptr_x += 4 * window_xoffset;
1393
1394 if (trc_func && c < 3) {
1395 for (int x = 0; x < xsize; x++, ptr_x += 4) {
1396 float f = av_int2float(bytestream_get_le32(&src));1388 float f = av_int2float(bytestream_get_le32(&src));
1397 AV_WN32A(ptr_x, av_float2int(trc_func(f)));1389 AV_WN32A(ptr_x, av_float2int(trc_func(f)));
1398 }1390 }
1399 } else if (one_gamma != 1.f) {1391 } else if (one_gamma != 1.f) {
1400 for (int x = 0; x < xsize; x++, ptr_x += 4) {1392 for (int x = 0; x < xsize; x++, ptr_x += step) {
1401 float f = av_int2float(bytestream_get_le32(&src));1393 float f = av_int2float(bytestream_get_le32(&src));
1402 if (f > 0.0f && c < 3) /* avoid negative values */1394 if (f > 0.0f && c < 3) /* avoid negative values */
1403 f = powf(f, one_gamma);1395 f = powf(f, one_gamma);
1404 AV_WN32A(ptr_x, av_float2int(f));1396 AV_WN32A(ptr_x, av_float2int(f));
1405 }1397 }
1406 } else {1398 } else {
1407 for (int x = 0; x < xsize; x++, ptr_x += 4)1399 for (int x = 0; x < xsize; x++, ptr_x += step)
1408 AV_WN32A(ptr_x, bytestream_get_le32(&src));1400 AV_WN32A(ptr_x, bytestream_get_le32(&src));
1409 }1401 }
1410 memset(ptr_x, 0, axmax);
1411 } else if (s->pixel_type == EXR_HALF) {1402 } else if (s->pixel_type == EXR_HALF) {
1412 src = channel_buffer[c];
1413
1414 // Zero out the start if xmin is not 0
1415 memset(ptr, 0, bxmin);
1416
1417 // 16-bit1403 // 16-bit
1418 for (x = window_xoffset; x < xsize + window_xoffset; x++) {1404 for (int x = 0; x < xsize; x++, ptr_x += step)
1419 int v = bytestream_get_le16(&src);1405 AV_WN16A(ptr_x, bytestream_get_le16(&src));
1420 AV_WN16(ptr + x * sizeof(uint16_t), v);
1421 }
1422 memset(ptr + x * sizeof(uint16_t), 0, axmax);
1423 }1406 }
1424 1407
1425 // Zero out the end if xmax+1 is not w1408 // Zero out the end if xmax+1 is not w
1409 memset(ptr_x, 0, axmax);
1426 channel_buffer[c] += td->channel_line_size;1410 channel_buffer[c] += td->channel_line_size;
1427 }1411 }
1428 }1412 }
@@ -2054,8 +2038,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture, · 625 unmodified lines
2054 if (!s->is_luma) {2038 if (!s->is_luma) {
2055 avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;2039 avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
2056 } else {2040 } else {
2057 /* todo: change this when a floating point pixel format with luma with alpha is implemented */2041 avctx->pix_fmt = AV_PIX_FMT_YAF16;
2058 avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
2059 }2042 }
2060 } else {2043 } else {
2061 if (!s->is_luma) {2044 if (!s->is_luma) {
@@ -2071,8 +2054,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture, · 9 unmodified lines
2071 if (!s->is_luma) {2054 if (!s->is_luma) {
2072 avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;2055 avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
2073 } else {2056 } else {
2074 /* todo: change this when a floating point pixel format with luma with alpha is implemented */2057 avctx->pix_fmt = AV_PIX_FMT_YAF32;
2075 avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
2076 }2058 }
2077 } else {2059 } else {
2078 if (!s->is_luma) {2060 if (!s->is_luma) {
@@ -2151,11 +2133,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture, · 72 unmodified lines
2151 if (!s->desc)2133 if (!s->desc)
2152 return AVERROR_INVALIDDATA;2134 return AVERROR_INVALIDDATA;
2153 2135
2154 if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR) {2136 planes = av_pix_fmt_count_planes(avctx->pix_fmt);
2155 planes = s->desc->nb_components;
2156 } else {
2157 planes = 1;
2158 }
2159 out_line_size = avctx->width * s->desc->comp[0].step;2137 out_line_size = avctx->width * s->desc->comp[0].step;
2160 2138
2161 if (s->is_tile) {2139 if (s->is_tile) {
tests/ref/fate/exr-ya-scanline-zip-half-12x8+1−1
@@ -3,4 +3,4 @@ · 2 unmodified lines
3#codec_id 0: rawvideo3#codec_id 0: rawvideo
4#dimensions 0: 12x84#dimensions 0: 12x8
5#sar 0: 1/15#sar 0: 1/1
60, 0, 0, 1, 1536, 0x2b457bd260, 0, 0, 1, 1536, 0xa33f5f69

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