| 370 | void decoderVTM::copyImgToByteArray(libVTMDec_picture *src, byteArrayAligned &dst) |
| 371 | #else |
| 372 | void decoderVTM::copyImgToByteArray(libVTMDec_picture *src, QByteArray &dst) |
| 373 | #endif |
| 374 | { |
| 375 | // How many image planes are there? |
| 376 | auto fmt = this->lib.libVTMDec_get_chroma_format(src); |
| 377 | int nrPlanes = (fmt == LIBVTMDEC_CHROMA_400) ? 1 : 3; |
| 378 | |
| 379 | // VTM always uses 16 bit as the return array |
| 380 | bool outputTwoByte = (this->lib.libVTMDec_get_internal_bit_depth(src, LIBVTMDEC_LUMA) > 8); |
| 381 | |
| 382 | // How many samples are in each component? |
| 383 | int outSizeY = this->lib.libVTMDec_get_picture_width(src, LIBVTMDEC_LUMA) * |
| 384 | this->lib.libVTMDec_get_picture_height(src, LIBVTMDEC_LUMA); |
| 385 | int outSizeCb = (nrPlanes == 1) |
| 386 | ? 0 |
| 387 | : (this->lib.libVTMDec_get_picture_width(src, LIBVTMDEC_CHROMA_U) * |
| 388 | this->lib.libVTMDec_get_picture_height(src, LIBVTMDEC_CHROMA_U)); |
| 389 | int outSizeCr = (nrPlanes == 1) |
| 390 | ? 0 |
| 391 | : (this->lib.libVTMDec_get_picture_width(src, LIBVTMDEC_CHROMA_V) * |
| 392 | this->lib.libVTMDec_get_picture_height(src, LIBVTMDEC_CHROMA_V)); |
| 393 | // How many bytes do we need in the output buffer? |
| 394 | int nrBytesOutput = (outSizeY + outSizeCb + outSizeCr) * (outputTwoByte ? 2 : 1); |
| 395 | DEBUG_DECVTM("decoderVTM::copyImgToByteArray nrBytesOutput %d", nrBytesOutput); |
| 396 | |
| 397 | // Is the output big enough? |
| 398 | if (dst.capacity() < nrBytesOutput) |
| 399 | dst.resize(nrBytesOutput); |
| 400 | |
| 401 | // The source (from VTM) is always short (16bit). The destination is a QByteArray so |
| 402 | // we have to cast it right. |
| 403 | for (int c = 0; c < nrPlanes; c++) |
| 404 | { |
| 405 | auto component = (c == 0) ? LIBVTMDEC_LUMA : (c == 1) ? LIBVTMDEC_CHROMA_U : LIBVTMDEC_CHROMA_V; |
| 406 | |
| 407 | const short *img_c = this->lib.libVTMDec_get_image_plane(src, component); |
| 408 | int stride = this->lib.libVTMDec_get_picture_stride(src, component); |
| 409 | |
| 410 | if (img_c == nullptr) |
| 411 | return; |
| 412 | |
| 413 | int width = this->lib.libVTMDec_get_picture_width(src, component); |
| 414 | int height = this->lib.libVTMDec_get_picture_height(src, component); |
| 415 | |
| 416 | if (outputTwoByte) |
| 417 | { |
| 418 | unsigned short *restrict d = (unsigned short *)dst.data(); |
| 419 | if (c > 0) |
| 420 | d += outSizeY; |
| 421 | if (c == 2) |
| 422 | d += outSizeCb; |
| 423 | |
| 424 | for (int y = 0; y < height; y++) |
| 425 | { |
| 426 | for (int x = 0; x < width; x++) |
| 427 | { |
| 428 | d[x] = (unsigned short)img_c[x]; |
| 429 | } |