Fix overflows in avifRGBImageAllocatePixels()

Calculate rowBytes in uint32_t. Only the allocation size needs to be
size_t.

Also make sure it is safe to cast various rowBytes fields to ptrdiff_t.
We need to do this when subtracting rowBytes from a pointer to go back
one row.

Part of the fix to https://github.com/AOMediaCodec/libavif/issues/2271.
diff --git a/src/avif.c b/src/avif.c
index 00dc4c8..3d3511b 100644
--- a/src/avif.c
+++ b/src/avif.c
@@ -352,15 +352,21 @@
     if (image->width == 0 || image->height == 0) {
         return AVIF_RESULT_INVALID_ARGUMENT;
     }
-    const size_t channelSize = avifImageUsesU16(image) ? 2 : 1;
-    if (image->width > SIZE_MAX / channelSize) {
+    const uint32_t channelSize = avifImageUsesU16(image) ? 2 : 1;
+    if (image->width > UINT32_MAX / channelSize) {
         return AVIF_RESULT_INVALID_ARGUMENT;
     }
-    const size_t fullRowBytes = channelSize * image->width;
-    if ((fullRowBytes > UINT32_MAX) || (image->height > SIZE_MAX / fullRowBytes)) {
+    const uint32_t fullRowBytes = channelSize * image->width;
+#if UINT32_MAX > PTRDIFF_MAX
+    // Make sure it is safe to cast image->yuvRowBytes[i] or image->alphaRowBytes to ptrdiff_t.
+    if (fullRowBytes > PTRDIFF_MAX) {
         return AVIF_RESULT_INVALID_ARGUMENT;
     }
-    const size_t fullSize = fullRowBytes * image->height;
+#endif
+    if (image->height > SIZE_MAX / fullRowBytes) {
+        return AVIF_RESULT_INVALID_ARGUMENT;
+    }
+    const size_t fullSize = (size_t)fullRowBytes * image->height;
 
     if ((planes & AVIF_PLANES_YUV) && (image->yuvFormat != AVIF_PIXEL_FORMAT_NONE)) {
         avifPixelFormatInfo info;
@@ -368,11 +374,11 @@
 
         image->imageOwnsYUVPlanes = AVIF_TRUE;
         if (!image->yuvPlanes[AVIF_CHAN_Y]) {
-            image->yuvRowBytes[AVIF_CHAN_Y] = (uint32_t)fullRowBytes;
             image->yuvPlanes[AVIF_CHAN_Y] = (uint8_t *)avifAlloc(fullSize);
             if (!image->yuvPlanes[AVIF_CHAN_Y]) {
                 return AVIF_RESULT_OUT_OF_MEMORY;
             }
+            image->yuvRowBytes[AVIF_CHAN_Y] = fullRowBytes;
         }
 
         if (!info.monochrome) {
@@ -381,16 +387,16 @@
             const uint32_t shiftedH = (uint32_t)(((uint64_t)image->height + info.chromaShiftY) >> info.chromaShiftY);
 
             // These are less than or equal to fullRowBytes/fullSize. No need to check overflows.
-            const size_t uvRowBytes = channelSize * shiftedW;
-            const size_t uvSize = uvRowBytes * shiftedH;
+            const uint32_t uvRowBytes = channelSize * shiftedW;
+            const size_t uvSize = (size_t)uvRowBytes * shiftedH;
 
             for (int uvPlane = AVIF_CHAN_U; uvPlane <= AVIF_CHAN_V; ++uvPlane) {
                 if (!image->yuvPlanes[uvPlane]) {
-                    image->yuvRowBytes[uvPlane] = (uint32_t)uvRowBytes;
                     image->yuvPlanes[uvPlane] = (uint8_t *)avifAlloc(uvSize);
                     if (!image->yuvPlanes[uvPlane]) {
                         return AVIF_RESULT_OUT_OF_MEMORY;
                     }
+                    image->yuvRowBytes[uvPlane] = uvRowBytes;
                 }
             }
         }
@@ -398,11 +404,11 @@
     if (planes & AVIF_PLANES_A) {
         image->imageOwnsAlphaPlane = AVIF_TRUE;
         if (!image->alphaPlane) {
-            image->alphaRowBytes = (uint32_t)fullRowBytes;
             image->alphaPlane = (uint8_t *)avifAlloc(fullSize);
             if (!image->alphaPlane) {
                 return AVIF_RESULT_OUT_OF_MEMORY;
             }
+            image->alphaRowBytes = fullRowBytes;
         }
     }
     return AVIF_RESULT_OK;
@@ -626,7 +632,20 @@
 avifResult avifRGBImageAllocatePixels(avifRGBImage * rgb)
 {
     avifRGBImageFreePixels(rgb);
-    const uint32_t rowBytes = rgb->width * avifRGBImagePixelSize(rgb);
+    const uint32_t pixelSize = avifRGBImagePixelSize(rgb);
+    if (rgb->width > UINT32_MAX / pixelSize) {
+        return AVIF_RESULT_INVALID_ARGUMENT;
+    }
+    const uint32_t rowBytes = rgb->width * pixelSize;
+#if UINT32_MAX > PTRDIFF_MAX
+    // Make sure it is safe to cast rgb->rowBytes to ptrdiff_t.
+    if (rowBytes > PTRDIFF_MAX) {
+        return AVIF_RESULT_INVALID_ARGUMENT;
+    }
+#endif
+    if (rgb->height > SIZE_MAX / rowBytes) {
+        return AVIF_RESULT_INVALID_ARGUMENT;
+    }
     rgb->pixels = (uint8_t *)avifAlloc((size_t)rowBytes * rgb->height);
     AVIF_CHECKERR(rgb->pixels, AVIF_RESULT_OUT_OF_MEMORY);
     rgb->rowBytes = rowBytes;