| 219 | } |
| 220 | |
| 221 | static int encode_scanline_rle(EXRContext *s, const AVFrame *frame) |
| 222 | { |
| 223 | const int64_t element_size = s->pixel_type == EXR_HALF ? 2LL : 4LL; |
| 224 | |
| 225 | for (int y = 0; y < frame->height; y++) { |
| 226 | EXRScanlineData *scanline = &s->scanline[y]; |
| 227 | int64_t tmp_size = element_size * s->planes * frame->width; |
| 228 | int64_t max_compressed_size = tmp_size * 3 / 2; |
| 229 | |
| 230 | av_fast_padded_malloc(&scanline->uncompressed_data, &scanline->uncompressed_size, tmp_size); |
| 231 | if (!scanline->uncompressed_data) |
| 232 | return AVERROR(ENOMEM); |
| 233 | |
| 234 | av_fast_padded_malloc(&scanline->tmp, &scanline->tmp_size, tmp_size); |
| 235 | if (!scanline->tmp) |
| 236 | return AVERROR(ENOMEM); |
| 237 | |
| 238 | av_fast_padded_malloc(&scanline->compressed_data, &scanline->compressed_size, max_compressed_size); |
| 239 | if (!scanline->compressed_data) |
| 240 | return AVERROR(ENOMEM); |
| 241 | |
| 242 | switch (s->pixel_type) { |
| 243 | case EXR_FLOAT: |
| 244 | for (int p = 0; p < s->planes; p++) { |
| 245 | int ch = s->ch_order[p]; |
| 246 | |
| 247 | memcpy(scanline->uncompressed_data + frame->width * 4 * p, |
| 248 | frame->data[ch] + y * frame->linesize[ch], frame->width * 4); |
| 249 | } |
| 250 | break; |
| 251 | case EXR_HALF: |
| 252 | for (int p = 0; p < s->planes; p++) { |
| 253 | int ch = s->ch_order[p]; |
| 254 | uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + frame->width * 2 * p); |
| 255 | const uint32_t *src = (const uint32_t *)(frame->data[ch] + y * frame->linesize[ch]); |
| 256 | |
| 257 | for (int x = 0; x < frame->width; x++) |
| 258 | dst[x] = float2half(src[x], &s->f2h_tables); |
| 259 | } |
| 260 | break; |
| 261 | } |
| 262 | |
| 263 | reorder_pixels(scanline->tmp, scanline->uncompressed_data, tmp_size); |
| 264 | predictor(scanline->tmp, tmp_size); |
| 265 | scanline->actual_size = rle_compress(scanline->compressed_data, |
| 266 | max_compressed_size, |
| 267 | scanline->tmp, tmp_size); |
| 268 | |
| 269 | if (scanline->actual_size <= 0 || scanline->actual_size >= tmp_size) { |
| 270 | FFSWAP(uint8_t *, scanline->uncompressed_data, scanline->compressed_data); |
| 271 | FFSWAP(int, scanline->uncompressed_size, scanline->compressed_size); |
| 272 | scanline->actual_size = tmp_size; |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | return 0; |
| 277 | } |
| 278 |
no test coverage detected