Additional fixes for PR #530

* Reword syntax explanation of --raw-color
* Add alpha plane NULL (similar to adjacent YUV plane checks)
* Refactor avifImageYUVToRGB to avoid goto and make flow clearer, add comments
diff --git a/apps/avifdec.c b/apps/avifdec.c
index 62544de..9a70122 100644
--- a/apps/avifdec.c
+++ b/apps/avifdec.c
@@ -34,7 +34,7 @@
     printf("    -d,--depth D      : Output depth [8,16]. (PNG only; For y4m, depth is retained, and JPEG is always 8bpc)\n");
     printf("    -q,--quality Q    : Output quality [0-100]. (JPEG only, default: %d)\n", DEFAULT_JPEG_QUALITY);
     printf("    -u,--upsampling U : Chroma upsampling (for 420/422). automatic (default), fastest, best, nearest, or bilinear\n");
-    printf("    -r,--raw-color    : Output original color data for opaque output (JPEG only; always true for y4m)\n");
+    printf("    -r,--raw-color    : Output raw values instead of multiplying alpha when saving to opaque formats (JPEG only; always true for y4m)\n");
     printf("    -i,--info         : Decode all frames and display all image information instead of saving to disk\n");
     printf("    --ignore-icc      : If the input file contains an embedded ICC profile, ignore it (no-op if absent)\n");
     printf("\n");
diff --git a/src/reformat.c b/src/reformat.c
index 4ecaf4c..bd1acfc 100644
--- a/src/reformat.c
+++ b/src/reformat.c
@@ -142,7 +142,7 @@
         }
     } else {
         if (!image->alphaPremultiplied && rgb->alphaPremultiplied) {
-           state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY;
+            state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY;
         } else if (image->alphaPremultiplied && !rgb->alphaPremultiplied) {
             state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_UNMULTIPLY;
         }
@@ -443,7 +443,7 @@
         const uint8_t * ptrY8 = &yPlane[j * yRowBytes];
         const uint8_t * ptrU8 = uPlane ? &uPlane[(uvJ * uRowBytes)] : NULL;
         const uint8_t * ptrV8 = vPlane ? &vPlane[(uvJ * vRowBytes)] : NULL;
-        const uint8_t * ptrA8 = &aPlane[j * aRowBytes];
+        const uint8_t * ptrA8 = aPlane ? &aPlane[j * aRowBytes] : NULL;
         const uint16_t * ptrY16 = (const uint16_t *)ptrY8;
         const uint16_t * ptrU16 = (const uint16_t *)ptrU8;
         const uint16_t * ptrV16 = (const uint16_t *)ptrV8;
@@ -1078,7 +1078,6 @@
 
     avifBool convertedWithLibYUV = AVIF_FALSE;
     avifResult libyuvResult = avifImageYUVToRGBLibYUV(image, rgb);
-    avifResult convertResult = AVIF_RESULT_NOT_IMPLEMENTED;
     if (libyuvResult == AVIF_RESULT_OK) {
         convertedWithLibYUV = AVIF_TRUE;
     } else {
@@ -1087,8 +1086,9 @@
         }
     }
 
-    // Reformat alpha, if user asks for it, or (un)multiply processing need it.
-    if (avifRGBFormatHasAlpha(rgb->format) && (!rgb->ignoreAlpha || state.toRGBAlphaMode != AVIF_ALPHA_MULTIPLY_MODE_NO_OP)) {
+    // Reformat alpha, if user asks for it, or (un)multiply processing needs it.
+    avifAlphaMultiplyMode alphaMultiplyMode = state.toRGBAlphaMode;
+    if (avifRGBFormatHasAlpha(rgb->format) && (!rgb->ignoreAlpha || (alphaMultiplyMode != AVIF_ALPHA_MULTIPLY_MODE_NO_OP))) {
         avifAlphaParams params;
 
         params.width = rgb->width;
@@ -1116,112 +1116,113 @@
         }
     }
 
-    // Do this after alpha conversion
-    if (convertedWithLibYUV) {
-        if (state.toRGBAlphaMode == AVIF_ALPHA_MULTIPLY_MODE_NO_OP) {
-            return AVIF_RESULT_OK;
-        } else {
-            // Need to do alpha (un)multiply
-            goto AlphaPremultiply;
+    if (!convertedWithLibYUV) {
+        // libyuv is either unavailable or unable to perform the specific conversion required here.
+        // Look over the available built-in "fast" routines for YUV->RGB conversion and see if one
+        // fits the current combination, or as a last resort, call avifImageYUVAnyToRGBAnySlow(),
+        // which handles every possibly YUV->RGB combination, but very slowly (in comparison).
+
+        avifResult convertResult = AVIF_RESULT_NOT_IMPLEMENTED;
+
+        avifChromaUpsampling chromaUpsampling;
+        switch (rgb->chromaUpsampling) {
+            case AVIF_CHROMA_UPSAMPLING_AUTOMATIC:
+            case AVIF_CHROMA_UPSAMPLING_BEST_QUALITY:
+            case AVIF_CHROMA_UPSAMPLING_BILINEAR:
+            default:
+                chromaUpsampling = AVIF_CHROMA_UPSAMPLING_BILINEAR;
+                break;
+
+            case AVIF_CHROMA_UPSAMPLING_FASTEST:
+            case AVIF_CHROMA_UPSAMPLING_NEAREST:
+                chromaUpsampling = AVIF_CHROMA_UPSAMPLING_NEAREST;
+                break;
         }
-    }
 
-    avifChromaUpsampling chromaUpsampling;
-    switch (rgb->chromaUpsampling) {
-        case AVIF_CHROMA_UPSAMPLING_AUTOMATIC:
-        case AVIF_CHROMA_UPSAMPLING_BEST_QUALITY:
-        case AVIF_CHROMA_UPSAMPLING_BILINEAR:
-        default:
-            chromaUpsampling = AVIF_CHROMA_UPSAMPLING_BILINEAR;
-            break;
+        const avifBool hasColor =
+            (image->yuvRowBytes[AVIF_CHAN_U] && image->yuvRowBytes[AVIF_CHAN_V] && (image->yuvFormat != AVIF_PIXEL_FORMAT_YUV400));
 
-        case AVIF_CHROMA_UPSAMPLING_FASTEST:
-        case AVIF_CHROMA_UPSAMPLING_NEAREST:
-            chromaUpsampling = AVIF_CHROMA_UPSAMPLING_NEAREST;
-            break;
-    }
+        if ((!hasColor || (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) || (chromaUpsampling == AVIF_CHROMA_UPSAMPLING_NEAREST)) &&
+            (alphaMultiplyMode == AVIF_ALPHA_MULTIPLY_MODE_NO_OP || avifRGBFormatHasAlpha(rgb->format))) {
+            // Explanations on the above conditional:
+            // * None of these fast paths currently support bilinear upsampling, so avoid all of them
+            //   unless the YUV data isn't subsampled or they explicitly requested AVIF_CHROMA_UPSAMPLING_NEAREST.
+            // * None of these fast paths currently handle alpha (un)multiply, so avoid all of them
+            //   if we can't do alpha (un)multiply as a separated post step (destination format doesn't have alpha).
 
-    const avifBool hasColor =
-        (image->yuvRowBytes[AVIF_CHAN_U] && image->yuvRowBytes[AVIF_CHAN_V] && (image->yuvFormat != AVIF_PIXEL_FORMAT_YUV400));
-
-    if ((!hasColor || (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) || (chromaUpsampling == AVIF_CHROMA_UPSAMPLING_NEAREST)) &&
-        (state.toRGBAlphaMode == AVIF_ALPHA_MULTIPLY_MODE_NO_OP || avifRGBFormatHasAlpha(rgb->format))) {
-        // None of these fast paths currently support bilinear upsampling, so avoid all of them
-        // unless the YUV data isn't subsampled or they explicitly requested AVIF_CHROMA_UPSAMPLING_NEAREST.
-
-        // None of these fast paths currently handle alpha (un)multiply, so avoid all of them
-        // if we can't do alpha (un)multiply as a separated post step (destination format doesn't have alpha).
-
-        if (state.mode == AVIF_REFORMAT_MODE_IDENTITY) {
-            if ((image->depth == 8) && (rgb->depth == 8) && (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) &&
-                (image->yuvRange == AVIF_RANGE_FULL)) {
-                convertResult = avifImageIdentity8ToRGB8ColorFullRange(image, rgb, &state);
-            }
-
-            // TODO: Add more fast paths for identity
-        } else if (state.mode == AVIF_REFORMAT_MODE_YUV_COEFFICIENTS) {
-            if (image->depth > 8) {
-                // yuv:u16
-
-                if (rgb->depth > 8) {
-                    // yuv:u16, rgb:u16
-
-                    if (hasColor) {
-                        convertResult = avifImageYUV16ToRGB16Color(image, rgb, &state);
-                    } else {
-                        convertResult = avifImageYUV16ToRGB16Mono(image, rgb, &state);
-                    }
-                } else {
-                    // yuv:u16, rgb:u8
-
-                    if (hasColor) {
-                        convertResult = avifImageYUV16ToRGB8Color(image, rgb, &state);
-                    } else {
-                        convertResult = avifImageYUV16ToRGB8Mono(image, rgb, &state);
-                    }
+            if (state.mode == AVIF_REFORMAT_MODE_IDENTITY) {
+                if ((image->depth == 8) && (rgb->depth == 8) && (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) &&
+                    (image->yuvRange == AVIF_RANGE_FULL)) {
+                    convertResult = avifImageIdentity8ToRGB8ColorFullRange(image, rgb, &state);
                 }
-            } else {
-                // yuv:u8
 
-                if (rgb->depth > 8) {
-                    // yuv:u8, rgb:u16
+                // TODO: Add more fast paths for identity
+            } else if (state.mode == AVIF_REFORMAT_MODE_YUV_COEFFICIENTS) {
+                if (image->depth > 8) {
+                    // yuv:u16
 
-                    if (hasColor) {
-                        convertResult = avifImageYUV8ToRGB16Color(image, rgb, &state);
+                    if (rgb->depth > 8) {
+                        // yuv:u16, rgb:u16
+
+                        if (hasColor) {
+                            convertResult = avifImageYUV16ToRGB16Color(image, rgb, &state);
+                        } else {
+                            convertResult = avifImageYUV16ToRGB16Mono(image, rgb, &state);
+                        }
                     } else {
-                        convertResult = avifImageYUV8ToRGB16Mono(image, rgb, &state);
+                        // yuv:u16, rgb:u8
+
+                        if (hasColor) {
+                            convertResult = avifImageYUV16ToRGB8Color(image, rgb, &state);
+                        } else {
+                            convertResult = avifImageYUV16ToRGB8Mono(image, rgb, &state);
+                        }
                     }
                 } else {
-                    // yuv:u8, rgb:u8
+                    // yuv:u8
 
-                    if (hasColor) {
-                        convertResult = avifImageYUV8ToRGB8Color(image, rgb, &state);
+                    if (rgb->depth > 8) {
+                        // yuv:u8, rgb:u16
+
+                        if (hasColor) {
+                            convertResult = avifImageYUV8ToRGB16Color(image, rgb, &state);
+                        } else {
+                            convertResult = avifImageYUV8ToRGB16Mono(image, rgb, &state);
+                        }
                     } else {
-                        convertResult = avifImageYUV8ToRGB8Mono(image, rgb, &state);
+                        // yuv:u8, rgb:u8
+
+                        if (hasColor) {
+                            convertResult = avifImageYUV8ToRGB8Color(image, rgb, &state);
+                        } else {
+                            convertResult = avifImageYUV8ToRGB8Mono(image, rgb, &state);
+                        }
                     }
                 }
             }
         }
+
+        if (convertResult == AVIF_RESULT_NOT_IMPLEMENTED) {
+            // If we get here, there is no fast path for this combination. Time to be slow!
+            convertResult = avifImageYUVAnyToRGBAnySlow(image, rgb, &state, chromaUpsampling);
+
+            // The slow path also handles alpha (un)multiply, so forget the operation here.
+            alphaMultiplyMode = AVIF_ALPHA_MULTIPLY_MODE_NO_OP;
+        }
+
+        if (convertResult != AVIF_RESULT_OK) {
+            return convertResult;
+        }
     }
 
-    if (convertResult == AVIF_RESULT_NOT_IMPLEMENTED) {
-        // If we get here, there is no fast path for this combination. Time to be slow!
-        // This slow path also handles alpha (un)multiply so we can return.
-        return avifImageYUVAnyToRGBAnySlow(image, rgb, &state, chromaUpsampling);
+    // Process alpha premultiplication, if necessary
+    if (alphaMultiplyMode == AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY) {
+        return avifRGBImagePremultiplyAlpha(rgb);
+    } else if (alphaMultiplyMode == AVIF_ALPHA_MULTIPLY_MODE_UNMULTIPLY) {
+        return avifRGBImageUnpremultiplyAlpha(rgb);
     }
 
-    if (convertResult != AVIF_RESULT_OK) {
-        return convertResult;
-    }
-
-AlphaPremultiply:
-    if (state.toRGBAlphaMode == AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY) {
-        convertResult = avifRGBImagePremultiplyAlpha(rgb);
-    } else if (state.toRGBAlphaMode == AVIF_ALPHA_MULTIPLY_MODE_UNMULTIPLY) {
-        convertResult = avifRGBImageUnpremultiplyAlpha(rgb);
-    }
-
-    return convertResult;
+    return AVIF_RESULT_OK;
 }
 
 // Limited -> Full