Skip to content

Commit aa048aa

Browse files
committed
Audit avifImageYUVAnyToRGBAnySlow(): use signed arithmetic for UV sampling offsets
1 parent 0f430db commit aa048aa

1 file changed

Lines changed: 32 additions & 29 deletions

File tree

src/reformat.c

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -683,10 +683,10 @@ static avifResult avifImageYUVAnyToRGBAnySlow(const avifImage * image,
683683
for (uint32_t j = 0; j < image->height; ++j) {
684684
// uvJ is used only when yuvHasColor is true.
685685
const uint32_t uvJ = yuvHasColor ? (j >> state->yuv.formatInfo.chromaShiftY) : 0;
686-
const uint8_t * ptrY8 = &yPlane[j * yRowBytes];
687-
const uint8_t * ptrU8 = uPlane ? &uPlane[(uvJ * uRowBytes)] : NULL;
688-
const uint8_t * ptrV8 = vPlane ? &vPlane[(uvJ * vRowBytes)] : NULL;
689-
const uint8_t * ptrA8 = aPlane ? &aPlane[j * aRowBytes] : NULL;
686+
const uint8_t * ptrY8 = &yPlane[(size_t)j * yRowBytes];
687+
const uint8_t * ptrU8 = uPlane ? &uPlane[(size_t)uvJ * uRowBytes] : NULL;
688+
const uint8_t * ptrV8 = vPlane ? &vPlane[(size_t)uvJ * vRowBytes] : NULL;
689+
const uint8_t * ptrA8 = aPlane ? &aPlane[(size_t)j * aRowBytes] : NULL;
690690
const uint16_t * ptrY16 = (const uint16_t *)ptrY8;
691691
const uint16_t * ptrU16 = (const uint16_t *)ptrU8;
692692
const uint16_t * ptrV16 = (const uint16_t *)ptrV8;
@@ -761,17 +761,17 @@ static avifResult avifImageYUVAnyToRGBAnySlow(const avifImage * image,
761761
uint16_t unormU[2][2], unormV[2][2];
762762

763763
// How many bytes to add to a uint8_t pointer index to get to the adjacent (lesser) sample in a given direction
764-
int uAdjCol, vAdjCol, uAdjRow, vAdjRow;
764+
ptrdiff_t uAdjCol, vAdjCol, uAdjRow, vAdjRow;
765765
if ((i == 0) || ((i == (image->width - 1)) && ((i % 2) != 0))) {
766766
uAdjCol = 0;
767767
vAdjCol = 0;
768768
} else {
769769
if ((i % 2) != 0) {
770-
uAdjCol = yuvChannelBytes;
771-
vAdjCol = yuvChannelBytes;
770+
uAdjCol = (ptrdiff_t)yuvChannelBytes;
771+
vAdjCol = (ptrdiff_t)yuvChannelBytes;
772772
} else {
773-
uAdjCol = -1 * yuvChannelBytes;
774-
vAdjCol = -1 * yuvChannelBytes;
773+
uAdjCol = -(ptrdiff_t)yuvChannelBytes;
774+
vAdjCol = -(ptrdiff_t)yuvChannelBytes;
775775
}
776776
}
777777

@@ -783,32 +783,35 @@ static avifResult avifImageYUVAnyToRGBAnySlow(const avifImage * image,
783783
vAdjRow = 0;
784784
} else {
785785
if ((j % 2) != 0) {
786-
uAdjRow = (int)uRowBytes;
787-
vAdjRow = (int)vRowBytes;
786+
uAdjRow = (ptrdiff_t)uRowBytes;
787+
vAdjRow = (ptrdiff_t)vRowBytes;
788788
} else {
789-
uAdjRow = -1 * (int)uRowBytes;
790-
vAdjRow = -1 * (int)vRowBytes;
789+
uAdjRow = -(ptrdiff_t)uRowBytes;
790+
vAdjRow = -(ptrdiff_t)vRowBytes;
791791
}
792792
}
793793

794+
const ptrdiff_t uBase = (ptrdiff_t)uvJ * uRowBytes + (ptrdiff_t)uvI * yuvChannelBytes;
795+
const ptrdiff_t vBase = (ptrdiff_t)uvJ * vRowBytes + (ptrdiff_t)uvI * yuvChannelBytes;
796+
794797
if (image->depth == 8) {
795-
unormU[0][0] = uPlane[(uvJ * uRowBytes) + (uvI * yuvChannelBytes)];
796-
unormV[0][0] = vPlane[(uvJ * vRowBytes) + (uvI * yuvChannelBytes)];
797-
unormU[1][0] = uPlane[(uvJ * uRowBytes) + (uvI * yuvChannelBytes) + uAdjCol];
798-
unormV[1][0] = vPlane[(uvJ * vRowBytes) + (uvI * yuvChannelBytes) + vAdjCol];
799-
unormU[0][1] = uPlane[(uvJ * uRowBytes) + (uvI * yuvChannelBytes) + uAdjRow];
800-
unormV[0][1] = vPlane[(uvJ * vRowBytes) + (uvI * yuvChannelBytes) + vAdjRow];
801-
unormU[1][1] = uPlane[(uvJ * uRowBytes) + (uvI * yuvChannelBytes) + uAdjCol + uAdjRow];
802-
unormV[1][1] = vPlane[(uvJ * vRowBytes) + (uvI * yuvChannelBytes) + vAdjCol + vAdjRow];
798+
unormU[0][0] = uPlane[uBase];
799+
unormV[0][0] = vPlane[vBase];
800+
unormU[1][0] = uPlane[uBase + uAdjCol];
801+
unormV[1][0] = vPlane[vBase + vAdjCol];
802+
unormU[0][1] = uPlane[uBase + uAdjRow];
803+
unormV[0][1] = vPlane[vBase + vAdjRow];
804+
unormU[1][1] = uPlane[uBase + uAdjCol + uAdjRow];
805+
unormV[1][1] = vPlane[vBase + vAdjCol + vAdjRow];
803806
} else {
804-
unormU[0][0] = *((const uint16_t *)&uPlane[(uvJ * uRowBytes) + (uvI * yuvChannelBytes)]);
805-
unormV[0][0] = *((const uint16_t *)&vPlane[(uvJ * vRowBytes) + (uvI * yuvChannelBytes)]);
806-
unormU[1][0] = *((const uint16_t *)&uPlane[(uvJ * uRowBytes) + (uvI * yuvChannelBytes) + uAdjCol]);
807-
unormV[1][0] = *((const uint16_t *)&vPlane[(uvJ * vRowBytes) + (uvI * yuvChannelBytes) + vAdjCol]);
808-
unormU[0][1] = *((const uint16_t *)&uPlane[(uvJ * uRowBytes) + (uvI * yuvChannelBytes) + uAdjRow]);
809-
unormV[0][1] = *((const uint16_t *)&vPlane[(uvJ * vRowBytes) + (uvI * yuvChannelBytes) + vAdjRow]);
810-
unormU[1][1] = *((const uint16_t *)&uPlane[(uvJ * uRowBytes) + (uvI * yuvChannelBytes) + uAdjCol + uAdjRow]);
811-
unormV[1][1] = *((const uint16_t *)&vPlane[(uvJ * vRowBytes) + (uvI * yuvChannelBytes) + vAdjCol + vAdjRow]);
807+
unormU[0][0] = *((const uint16_t *)&uPlane[uBase]);
808+
unormV[0][0] = *((const uint16_t *)&vPlane[vBase]);
809+
unormU[1][0] = *((const uint16_t *)&uPlane[uBase + uAdjCol]);
810+
unormV[1][0] = *((const uint16_t *)&vPlane[vBase + vAdjCol]);
811+
unormU[0][1] = *((const uint16_t *)&uPlane[uBase + uAdjRow]);
812+
unormV[0][1] = *((const uint16_t *)&vPlane[vBase + vAdjRow]);
813+
unormU[1][1] = *((const uint16_t *)&uPlane[uBase + uAdjCol + uAdjRow]);
814+
unormV[1][1] = *((const uint16_t *)&vPlane[vBase + vAdjCol + vAdjRow]);
812815

813816
// clamp incoming data to protect against bad LUT lookups
814817
for (int bJ = 0; bJ < 2; ++bJ) {

0 commit comments

Comments
 (0)