Move some Exif functions to apps/shared/avifexif

So that the avif_apps target does not depend on avif_internal.
Fix avifSetExifOrientation() comment.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5fbea3f..2a8b8cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -504,10 +504,10 @@
     find_package(JPEG REQUIRED)
 
     add_library(
-        avif_apps STATIC apps/shared/avifjpeg.c apps/shared/iccjpeg.c apps/shared/avifpng.c apps/shared/avifutil.c
-                         apps/shared/y4m.c
+        avif_apps STATIC apps/shared/avifexif.c apps/shared/avifjpeg.c apps/shared/iccjpeg.c apps/shared/avifpng.c
+                         apps/shared/avifutil.c apps/shared/y4m.c
     )
-    target_link_libraries(avif_apps avif_internal ${AVIF_PLATFORM_LIBRARIES} ${PNG_LIBRARY} ${ZLIB_LIBRARY} ${JPEG_LIBRARY})
+    target_link_libraries(avif_apps avif ${AVIF_PLATFORM_LIBRARIES} ${PNG_LIBRARY} ${ZLIB_LIBRARY} ${JPEG_LIBRARY})
     # In GitHub CI's macos-latest os image, /usr/local/include has not only the headers of libpng
     # libjpeg but also the headers of an older version of libavif. Put the avif include directory
     # before ${PNG_PNG_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} to prevent picking up old libavif headers
diff --git a/README.md b/README.md
index 77b5dc2..b1a9c81 100644
--- a/README.md
+++ b/README.md
@@ -76,9 +76,9 @@
 
 ```sh
 clang-format -style=file -i \
-  apps/*.c apps/shared/avifjpeg.* apps/shared/avifpng.* \
-  apps/shared/avifutil.* apps/shared/y4m.* examples/*.c \
-  include/avif/*.h src/*.c tests/*.c \
+  apps/*.c apps/shared/avifexif.* apps/shared/avifjpeg.* \
+  apps/shared/avifpng.* apps/shared/avifutil.* apps/shared/y4m.* \
+  examples/*.c include/avif/*.h src/*.c tests/*.c \
   tests/gtest/*.h tests/gtest/*.cc tests/oss-fuzz/*.cc
 ```
 
diff --git a/apps/shared/avifexif.c b/apps/shared/avifexif.c
new file mode 100644
index 0000000..626a244
--- /dev/null
+++ b/apps/shared/avifexif.c
@@ -0,0 +1,63 @@
+// Copyright 2022 Google LLC
+// SPDX-License-Identifier: BSD-2-Clause
+
+#include "avifexif.h"
+#include "avif/avif.h"
+
+uint8_t avifImageGetExifOrientationFromIrotImir(const avifImage * image)
+{
+    if ((image->transformFlags & AVIF_TRANSFORM_IROT) && (image->irot.angle == 1)) {
+        if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
+            if (image->imir.mode) {
+                return 7; // 90 degrees anti-clockwise then swap left and right.
+            }
+            return 5; // 90 degrees anti-clockwise then swap top and bottom.
+        }
+        return 6; // 90 degrees anti-clockwise.
+    }
+    if ((image->transformFlags & AVIF_TRANSFORM_IROT) && (image->irot.angle == 2)) {
+        if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
+            if (image->imir.mode) {
+                return 4; // 180 degrees anti-clockwise then swap left and right.
+            }
+            return 2; // 180 degrees anti-clockwise then swap top and bottom.
+        }
+        return 3; // 180 degrees anti-clockwise.
+    }
+    if ((image->transformFlags & AVIF_TRANSFORM_IROT) && (image->irot.angle == 3)) {
+        if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
+            if (image->imir.mode) {
+                return 5; // 270 degrees anti-clockwise then swap left and right.
+            }
+            return 7; // 270 degrees anti-clockwise then swap top and bottom.
+        }
+        return 8; // 270 degrees anti-clockwise.
+    }
+    if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
+        if (image->imir.mode) {
+            return 2; // Swap left and right.
+        }
+        return 4; // Swap top and bottom.
+    }
+    return 1; // Default orientation ("top-left", no-op).
+}
+
+avifResult avifSetExifOrientation(avifRWData * exif, uint8_t orientation)
+{
+    size_t offset;
+    const avifResult result = avifGetExifOrientationOffset(exif->data, exif->size, &offset);
+    if (result != AVIF_RESULT_OK) {
+        return result;
+    }
+    if (offset < exif->size) {
+        exif->data[offset] = orientation;
+        return AVIF_RESULT_OK;
+    }
+    // No Exif orientation was found.
+    if (orientation == 1) {
+        // The default orientation is 1, so if the given orientation is 1 too, do nothing.
+        return AVIF_RESULT_OK;
+    }
+    // Adding an orientation tag to an Exif payload is involved.
+    return AVIF_RESULT_NOT_IMPLEMENTED;
+}
diff --git a/apps/shared/avifexif.h b/apps/shared/avifexif.h
new file mode 100644
index 0000000..0c99a61
--- /dev/null
+++ b/apps/shared/avifexif.h
@@ -0,0 +1,23 @@
+// Copyright 2022 Google LLC
+// SPDX-License-Identifier: BSD-2-Clause
+
+#ifndef LIBAVIF_APPS_SHARED_AVIFEXIF_H
+#define LIBAVIF_APPS_SHARED_AVIFEXIF_H
+
+#include "avif/avif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Converts image->transformFlags, image->irot and image->imir to the equivalent Exif orientation value in [1:8].
+uint8_t avifImageGetExifOrientationFromIrotImir(const avifImage * image);
+
+// Attempts to parse the Exif payload until the orientation is found, then sets it to the given value.
+avifResult avifSetExifOrientation(avifRWData * exif, uint8_t orientation);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ifndef LIBAVIF_APPS_SHARED_AVIFEXIF_H
diff --git a/apps/shared/avifjpeg.c b/apps/shared/avifjpeg.c
index 707ef40..6d7deb8 100644
--- a/apps/shared/avifjpeg.c
+++ b/apps/shared/avifjpeg.c
@@ -2,7 +2,7 @@
 // SPDX-License-Identifier: BSD-2-Clause
 
 #include "avifjpeg.h"
-#include "avif/internal.h"
+#include "avifexif.h"
 #include "avifutil.h"
 
 #include <assert.h>
diff --git a/apps/shared/avifpng.c b/apps/shared/avifpng.c
index 684970a..775ce73 100644
--- a/apps/shared/avifpng.c
+++ b/apps/shared/avifpng.c
@@ -2,7 +2,7 @@
 // SPDX-License-Identifier: BSD-2-Clause
 
 #include "avifpng.h"
-#include "avif/internal.h"
+#include "avifexif.h"
 #include "avifutil.h"
 
 #include "png.h"
diff --git a/include/avif/avif.h b/include/avif/avif.h
index dd7dc31..fab51a5 100644
--- a/include/avif/avif.h
+++ b/include/avif/avif.h
@@ -187,6 +187,15 @@
 AVIF_API void avifRWDataFree(avifRWData * raw);
 
 // ---------------------------------------------------------------------------
+// Metadata
+
+// Validates the first bytes of the Exif payload and finds the TIFF header offset (up to UINT32_MAX).
+AVIF_API avifResult avifGetExifTiffHeaderOffset(const uint8_t * exif, size_t exifSize, size_t * offset);
+// Returns the offset to the Exif 8-bit orientation value and AVIF_RESULT_OK, or an error.
+// If the offset is set to exifSize, there was no parsing error but no orientation tag was found.
+AVIF_API avifResult avifGetExifOrientationOffset(const uint8_t * exif, size_t exifSize, size_t * offset);
+
+// ---------------------------------------------------------------------------
 // avifPixelFormat
 //
 // Note to libavif maintainers: The lookup tables in avifImageYUVToRGBLibYUV
diff --git a/include/avif/internal.h b/include/avif/internal.h
index 04d2619..1fd7f3e 100644
--- a/include/avif/internal.h
+++ b/include/avif/internal.h
@@ -207,15 +207,9 @@
 // ---------------------------------------------------------------------------
 // Metadata
 
-// Validates the first bytes of the Exif payload and finds the TIFF header offset (up to UINT32_MAX).
-avifResult avifGetExifTiffHeaderOffset(const uint8_t * exif, size_t exifSize, size_t * offset);
 // Attempts to parse the image->exif payload for Exif orientation and sets image->transformFlags, image->irot and
 // image->imir on success. Returns AVIF_RESULT_INVALID_EXIF_PAYLOAD on failure.
 avifResult avifImageExtractExifOrientationToIrotImir(avifImage * image);
-// Converts image->transformFlags, image->irot and image->imir to the equivalent Exif orientation value in [1:8].
-uint8_t avifImageGetExifOrientationFromIrotImir(const avifImage * image);
-// Attempts to parse the image->exif payload until the Exif orientation is found, then sets it to the given value.
-avifResult avifSetExifOrientation(avifRWData * exif, uint8_t orientation);
 
 // ---------------------------------------------------------------------------
 // avifCodecDecodeInput
diff --git a/src/exif.c b/src/exif.c
index 58489b3..82bf6f3 100644
--- a/src/exif.c
+++ b/src/exif.c
@@ -22,7 +22,7 @@
 
 // Returns the offset to the Exif 8-bit orientation value and AVIF_RESULT_OK, or an error.
 // If the offset is set to exifSize, there was no parsing error but no orientation tag was found.
-static avifResult avifGetExifOrientationOffset(const uint8_t * exif, size_t exifSize, size_t * offset)
+avifResult avifGetExifOrientationOffset(const uint8_t * exif, size_t exifSize, size_t * offset)
 {
     const avifResult result = avifGetExifTiffHeaderOffset(exif, exifSize, offset);
     if (result != AVIF_RESULT_OK) {
@@ -142,64 +142,6 @@
     return AVIF_RESULT_OK;
 }
 
-uint8_t avifImageGetExifOrientationFromIrotImir(const avifImage * image)
-{
-    if ((image->transformFlags & AVIF_TRANSFORM_IROT) && (image->irot.angle == 1)) {
-        if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
-            if (image->imir.mode) {
-                return 7; // 90 degrees anti-clockwise then swap left and right.
-            }
-            return 5; // 90 degrees anti-clockwise then swap top and bottom.
-        }
-        return 6; // 90 degrees anti-clockwise.
-    }
-    if ((image->transformFlags & AVIF_TRANSFORM_IROT) && (image->irot.angle == 2)) {
-        if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
-            if (image->imir.mode) {
-                return 4; // 180 degrees anti-clockwise then swap left and right.
-            }
-            return 2; // 180 degrees anti-clockwise then swap top and bottom.
-        }
-        return 3; // 180 degrees anti-clockwise.
-    }
-    if ((image->transformFlags & AVIF_TRANSFORM_IROT) && (image->irot.angle == 3)) {
-        if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
-            if (image->imir.mode) {
-                return 5; // 270 degrees anti-clockwise then swap left and right.
-            }
-            return 7; // 270 degrees anti-clockwise then swap top and bottom.
-        }
-        return 8; // 270 degrees anti-clockwise.
-    }
-    if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
-        if (image->imir.mode) {
-            return 2; // Swap left and right.
-        }
-        return 4; // Swap top and bottom.
-    }
-    return 1; // Default orientation ("top-left", no-op).
-}
-
-avifResult avifSetExifOrientation(avifRWData * exif, uint8_t orientation)
-{
-    size_t offset;
-    const avifResult result = avifGetExifOrientationOffset(exif->data, exif->size, &offset);
-    if (result != AVIF_RESULT_OK) {
-        return result;
-    }
-    if (offset < exif->size) {
-        exif->data[offset] = orientation;
-        return AVIF_RESULT_OK;
-    }
-    // No Exif orientation was found.
-    if (orientation == 1) {
-        // The default orientation is 1, so if the given orientation is 1 too, do nothing.
-        return AVIF_RESULT_OK;
-    }
-    // Adding an orientation tag to an Exif payload is involved.
-    return AVIF_RESULT_NOT_IMPLEMENTED;
-}
-
 void avifImageSetMetadataExif(avifImage * image, const uint8_t * exif, size_t exifSize)
 {
     avifRWDataSet(&image->exif, exif, exifSize);