/// <summary> /// Gets the meta-data bytes. /// </summary> /// <param name="id">The identifier.</param> /// <returns>The meta-data bytes.</returns> /// <exception cref="HeifException"> /// A LibHeif error occurred. /// /// -or- /// /// The meta-data block is larger than 2 GB. /// </exception> /// <exception cref="ObjectDisposedException">The object has been disposed.</exception> public byte[] GetMetadata(HeifItemId id) { VerifyNotDisposed(); ulong size = LibHeifNative.heif_image_handle_get_metadata_size(this.imageHandle, id).ToUInt64(); if (size == 0) { return(null); } if (size > int.MaxValue) { ExceptionUtil.ThrowHeifException(Resources.MetadataBlockLargerThan2Gb); } byte[] metadata = new byte[size]; unsafe { fixed(byte *ptr = metadata) { var error = LibHeifNative.heif_image_handle_get_metadata(this.imageHandle, id, ptr); error.ThrowIfError(); } } return(metadata); }
/// <summary> /// Gets a list of the thumbnail image ids. /// </summary> /// <returns>A list of the thumbnail image ids.</returns> /// <exception cref="HeifException">Could not get all of the thumbnail image ids.</exception> /// <exception cref="ObjectDisposedException">The object has been disposed.</exception> public IReadOnlyList <HeifItemId> GetThumbnailImageIds() { VerifyNotDisposed(); int count = LibHeifNative.heif_image_handle_get_number_of_thumbnails(this.imageHandle); if (count == 0) { return(Array.Empty <HeifItemId>()); } var ids = new HeifItemId[count]; unsafe { fixed(HeifItemId *ptr = ids) { int filledCount = LibHeifNative.heif_image_handle_get_list_of_thumbnail_IDs(this.imageHandle, ptr, count); if (filledCount != count) { ExceptionUtil.ThrowHeifException(Resources.CannotGetAllThumbnailIds); } } } return(ids); }
internal unsafe SafeHeifDecodingOptions CreateDecodingOptions() { var decodingOptions = LibHeifNative.heif_decoding_options_alloc(); if (decodingOptions.IsInvalid) { ExceptionUtil.ThrowHeifException(Properties.Resources.HeifDecodingOptionsCreationFailed); } byte version = Marshal.ReadByte(decodingOptions.DangerousGetHandle()); if (version >= 2) { var options = (DecodeOptionsVersion2 *)decodingOptions.DangerousGetHandle(); options->ignore_transformations = (byte)(this.IgnoreTransformations ? 1 : 0); options->convert_hdr_to_8bit = (byte)(this.ConvertHdrToEightBit ? 1 : 0); } else { var options = (DecodeOptionsVersion1 *)decodingOptions.DangerousGetHandle(); options->ignore_transformations = (byte)(this.IgnoreTransformations ? 1 : 0); } return(decodingOptions); }
/// <summary> /// Create a <see cref="HeifIccColorProfile"/> from the specified image handle. /// </summary> /// <param name="handle">The handle.</param> /// <returns>The created profile.</returns> /// <exception cref="HeifException"> /// A LibHeif error occurred. /// /// -or- /// /// The ICC profile is larger than 2 GB. /// </exception> internal static unsafe HeifIccColorProfile TryCreate(SafeHeifImageHandle handle) { HeifIccColorProfile profile = null; ulong iccProfileSize = LibHeifNative.heif_image_handle_get_raw_color_profile_size(handle).ToUInt64(); if (iccProfileSize > 0) { if (iccProfileSize > int.MaxValue) { ExceptionUtil.ThrowHeifException(Resources.IccProfileLargerThan2Gb); } byte[] iccProfileBytes = new byte[iccProfileSize]; fixed(byte *ptr = iccProfileBytes) { var error = LibHeifNative.heif_image_handle_get_raw_color_profile(handle, ptr); error.ThrowIfError(); } profile = new HeifIccColorProfile(iccProfileBytes, copyToNewArray: false); } return(profile); }
/// <summary> /// Gets a list of the meta-data block ids. /// </summary> /// <param name="type">The meta-data block type.</param> /// <param name="contentType">The meta-data block content type.</param> /// <returns>A list of the meta-data block ids.</returns> /// <exception cref="HeifException">Could not get all of the meta-data block ids.</exception> /// <exception cref="ObjectDisposedException">The object has been disposed.</exception> public IReadOnlyList <HeifItemId> GetMetadataBlockIds(string type = null, string contentType = null) { VerifyNotDisposed(); int count = LibHeifNative.heif_image_handle_get_number_of_metadata_blocks(this.imageHandle, type); if (count == 0) { return(Array.Empty <HeifItemId>()); } var ids = new HeifItemId[count]; unsafe { fixed(HeifItemId *ptr = ids) { int filledCount = LibHeifNative.heif_image_handle_get_list_of_metadata_block_IDs(this.imageHandle, type, ptr, count); if (filledCount != count) { ExceptionUtil.ThrowHeifException(Resources.CannotGetAllMetadataBlockIds); } } } // The type must be defined in order to filter by content type. if (type != null && contentType != null) { var matchingItems = new List <HeifItemId>(); for (int i = 0; i < ids.Length; i++) { var id = ids[i]; var metadataContentType = LibHeifNative.heif_image_handle_get_metadata_content_type(this.imageHandle, id); if (contentType.Equals(metadataContentType.GetStringValue(), StringComparison.Ordinal)) { matchingItems.Add(id); } } return(matchingItems); } else { return(ids); } }
/// <summary> /// Creates the encoding options. /// </summary> /// <returns>The encoding options.</returns> /// <exception cref="HeifException">Unable to create the native HeifEncodingOptions.</exception> internal unsafe SafeHeifEncodingOptions CreateEncodingOptions() { var encodingOptions = LibHeifNative.heif_encoding_options_alloc(); if (encodingOptions.IsInvalid) { ExceptionUtil.ThrowHeifException(Properties.Resources.HeifEncodingOptionsCreationFailed); } var options = (EncodingOptionsVersion1 *)encodingOptions.DangerousGetHandle(); options->save_alpha_channel = (byte)(this.SaveAlphaChannel ? 1 : 0); return(encodingOptions); }
/// <summary> /// Gets the image data for the specified plane. /// </summary> /// <param name="channel">The channel.</param> /// <returns>The image plane data.</returns> /// <exception cref="HeifException">The image does not contain the specified channel.</exception> /// <exception cref="ObjectDisposedException">The object has been disposed.</exception> public HeifPlaneData GetPlane(HeifChannel channel) { VerifyNotDisposed(); if (!LibHeifNative.heif_image_has_channel(this.image, channel)) { ExceptionUtil.ThrowHeifException(Resources.ImageDoesNotContainChannel); } int width = LibHeifNative.heif_image_get_width(this.image, channel); int height = LibHeifNative.heif_image_get_height(this.image, channel); var scan0 = LibHeifNative.heif_image_get_plane(this.image, channel, out int stride); if (scan0 == IntPtr.Zero || width == -1 || height == -1) { ExceptionUtil.ThrowHeifException(Resources.ImageDoesNotContainChannel); } return(new HeifPlaneData(width, height, stride, channel, scan0)); }
/// <summary> /// Gets a list of the auxiliary image ids. /// </summary> /// <returns>A list of the auxiliary image ids.</returns> /// <exception cref="HeifException">A LibHeif error occurred.</exception> /// <exception cref="ObjectDisposedException">The object has been disposed.</exception> /// <remarks> /// <para>The alpha and/or depth images are omitted from this list.</para> /// <para> /// LibHeif will include the alpha image (if present) when you call <see cref="Decode(HeifColorspace, HeifChroma, HeifDecodingOptions)"/> /// with the <see cref="HeifChroma"/> parameter set to one of the <c>InterleavedRgba</c> values. /// </para> /// <para> /// To read the depth images use <see cref="GetDepthImageIds"/> to get a list of the depth image item ids and /// <see cref="GetDepthImage(HeifItemId)"/> to convert the item id to a <see cref="HeifImageHandle"/>. /// </para> /// </remarks> /// <seealso cref="GetAuxiliaryImage(HeifItemId)"/> /// <seealso cref="GetAuxiliaryType"/> public IReadOnlyList <HeifItemId> GetAuxiliaryImageIds() { VerifyNotDisposed(); if (LibHeifVersion.Is1Point11OrLater) { const heif_auxiliary_image_filter filter = heif_auxiliary_image_filter.OmitAlpha | heif_auxiliary_image_filter.OmitDepth; int count = LibHeifNative.heif_image_handle_get_number_of_auxiliary_images(this.imageHandle, filter); if (count == 0) { return(Array.Empty <HeifItemId>()); } var ids = new HeifItemId[count]; unsafe { fixed(HeifItemId *ptr = ids) { int filledCount = LibHeifNative.heif_image_handle_get_list_of_auxiliary_image_IDs(this.imageHandle, filter, ptr, count); if (filledCount != count) { ExceptionUtil.ThrowHeifException(Resources.CannotGetAllAuxillaryImages); } } } return(ids); } else { return(Array.Empty <HeifItemId>()); } }
/// <summary> /// Initializes a new instance of the <see cref="HeifIccColorProfile"/> class. /// </summary> /// <param name="handle">The handle.</param> /// <exception cref="HeifException"> /// A LibHeif error occurred. /// /// -or- /// /// The ICC profile is zero bytes. /// /// -or- /// /// The ICC profile is larger than 2 GB. /// </exception> internal unsafe HeifIccColorProfile(SafeHeifImageHandle handle) : base(ColorProfileType.Icc) { ulong iccProfileSize = LibHeifNative.heif_image_handle_get_raw_color_profile_size(handle).ToUInt64(); if (iccProfileSize == 0) { ExceptionUtil.ThrowHeifException(Resources.IccProfileZeroBytes); } else if (iccProfileSize > int.MaxValue) { ExceptionUtil.ThrowHeifException(Resources.IccProfileLargerThan2Gb); } this.iccProfileBytes = new byte[iccProfileSize]; fixed(byte *ptr = this.iccProfileBytes) { var error = LibHeifNative.heif_image_handle_get_raw_color_profile(handle, ptr); error.ThrowIfError(); } }