/// <summary>
 /// Get the index of <paramref name="referenceImage"/> in the image library.
 /// </summary>
 /// <param name="referenceImage">The <see cref="XRReferenceImage"/> to find.</param>
 /// <returns>The zero-based index of the <paramref name="referenceImage"/>, or -1 if not found.</returns>
 public int indexOf(XRReferenceImage referenceImage)
 {
     return(m_Images.IndexOf(referenceImage));
 }
        void ValidateAndThrow(NativeSlice <byte> imageBytes, Vector2Int sizeInPixels, TextureFormat format, ref XRReferenceImage referenceImage)
        {
            unsafe
            {
                if (imageBytes.GetUnsafePtr() == null)
                {
                    throw new ArgumentException($"{nameof(imageBytes)} does not contain any bytes.", nameof(imageBytes));
                }
            }

            if (!referenceImage.guid.Equals(Guid.Empty))
            {
                throw new ArgumentException($"{nameof(referenceImage)}.{nameof(referenceImage.guid)} must be empty (all zeroes).", $"{nameof(referenceImage)}.{nameof(referenceImage.guid)}");
            }

            // Generate and assign a new guid for the new image
            referenceImage.m_SerializedGuid = GenerateNewGuid();

            if (string.IsNullOrEmpty(referenceImage.name))
            {
                throw new ArgumentNullException($"{nameof(referenceImage)}.{nameof(referenceImage.name)}");
            }

            if (referenceImage.specifySize && referenceImage.size.x <= 0)
            {
                throw new ArgumentOutOfRangeException($"{nameof(referenceImage)}.{nameof(referenceImage.size)}", referenceImage.size.x, $"Invalid physical image dimensions.");
            }

            if (!IsTextureFormatSupported(format))
            {
                throw new InvalidOperationException($"The texture format {format} is not supported by the current image tracking subsystem.");
            }

            if (sizeInPixels.x <= 0)
            {
                throw new ArgumentOutOfRangeException($"{nameof(sizeInPixels)}.{nameof(sizeInPixels.x)}", sizeInPixels.x, "Image width must be greater than zero.");
            }

            if (sizeInPixels.y <= 0)
            {
                throw new ArgumentOutOfRangeException($"{nameof(sizeInPixels)}.{nameof(sizeInPixels.y)}", sizeInPixels.y, "Image height must be greater than zero.");
            }
        }
 /// <summary>
 /// This method should schedule a [Unity Job](xref:JobSystem) which adds an image to this reference image
 /// library.
 /// </summary>
 /// <param name="imageBytes">The raw image bytes in <paramref name="format"/>. Assume the bytes will be valid
 ///     until the job completes.</param>
 /// <param name="sizeInPixels">The width and height of the image, in pixels.</param>
 /// <param name="format">The format of <paramref name="imageBytes"/>. The format has already been validated with
 ///     <see cref="IsTextureFormatSupported(TextureFormat)"/>.</param>
 /// <param name="referenceImage">The <see cref="XRReferenceImage"/> data associated with the image to add to the
 ///     library. This includes information like physical dimensions, associated
 ///     [Texture2D](xref:UnityEngine.Texture2D) (optional), and string name.</param>
 /// <param name="inputDeps">Input dependencies for the add image job.</param>
 /// <returns>A [JobHandle](xref:Unity.Jobs.JobHandle) which can be used
 /// to chain together multiple tasks or to query for completion.</returns>
 /// <seealso cref="ScheduleAddImageJob(NativeSlice{byte}, Vector2Int, TextureFormat, XRReferenceImage, JobHandle)"/>
 protected abstract JobHandle ScheduleAddImageJobImpl(
     NativeSlice <byte> imageBytes,
     Vector2Int sizeInPixels,
     TextureFormat format,
     XRReferenceImage referenceImage,
     JobHandle inputDeps);
 /// <summary>
 /// This method should schedule a [Unity Job](xref:JobSystem) which adds an image to this reference image
 /// library.
 /// </summary>
 /// <param name="imageBytes">The raw image bytes in <paramref name="format"/>. You may assume the bytes are
 ///     valid until the job completes.</param>
 /// <param name="sizeInPixels">The width and height of the image, in pixels.</param>
 /// <param name="format">The format of <paramref name="imageBytes"/>. The format has already been validated with
 ///     <see cref="IsTextureFormatSupported(TextureFormat)"/>.</param>
 /// <param name="referenceImage">The <see cref="XRReferenceImage"/> data associated with the image to add to the
 ///     library. This includes information like physical dimensions, associated
 ///     [Texture2D](xref:UnityEngine.Texture2D) (optional), and string name.</param>
 /// <param name="inputDeps">A [JobHandle](xref:Unity.Jobs.JobHandle) representing input dependencies for the add
 ///     image job.</param>
 /// <returns>Returns an <see cref="AddReferenceImageJobState"/> which contains the state of the asynchronous
 ///     image addition.</returns>
 /// <exception cref="System.NotImplementedException">Thrown by this base class implementation. If
 ///     <see cref="supportsValidation"/> is `true`, then this method should be implemented by the derived class.
 /// </exception>
 protected virtual AddReferenceImageJobState ScheduleAddImageWithValidationJobImpl(
     NativeSlice <byte> imageBytes,
     Vector2Int sizeInPixels,
     TextureFormat format,
     XRReferenceImage referenceImage,
     JobHandle inputDeps) => throw new NotImplementedException();