예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <summary>
        /// Gets image color profile.
        /// </summary>
        /// <returns>The image color profile.</returns>
        /// <exception cref="HeifException">
        /// The color profile type is not supported.
        ///
        /// -or-
        ///
        /// A LibHeif error occurred.
        /// </exception>
        private unsafe HeifColorProfile GetImageColorProfile()
        {
            HeifColorProfile profile = null;

            var colorProfileType = LibHeifNative.heif_image_get_color_profile_type(this.image);

            switch (colorProfileType)
            {
            case heif_color_profile_type.None:
                break;

            case heif_color_profile_type.Nclx:
                profile = new HeifNclxColorProfile(this.image);
                break;

            case heif_color_profile_type.IccProfile:
            case heif_color_profile_type.RestrictedIcc:
                profile = new HeifIccColorProfile(this.image);
                break;

            default:
                throw new HeifException(Resources.ColorProfileTypeNotSupported);
            }

            return(profile);
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="HeifImage" /> class.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="imageHandleIccColorProfile">The image handle ICC color profile.</param>
        /// <param name="imageHandleNclxColorProfile">The image handle NCLX color profile.</param>
        internal HeifImage(SafeHeifImage image,
                           int width,
                           int height,
                           HeifIccColorProfile imageHandleIccColorProfile,
                           HeifNclxColorProfile imageHandleNclxColorProfile)
        {
            Validate.IsNotNull(image, nameof(image));

            this.image = image;
            this.cachedIccColorProfile         = imageHandleIccColorProfile;
            this.cachedNclxColorProfile        = imageHandleNclxColorProfile;
            this.fetchedColorProfilesFromImage = this.cachedIccColorProfile != null || this.cachedNclxColorProfile != null;
            this.sync       = new object();
            this.Width      = width;
            this.Height     = height;
            this.Colorspace = LibHeifNative.heif_image_get_colorspace(image);
            this.Chroma     = LibHeifNative.heif_image_get_chroma_format(image);
        }
예제 #4
0
        /// <summary>
        /// Gets image handle color profiles.
        /// </summary>
        /// <returns>The image handle color profiles.</returns>
        /// <exception cref="HeifException">
        /// The color profile type is not supported.
        ///
        /// -or-
        ///
        /// A LibHeif error occurred.
        /// </exception>
        private unsafe ImageHandleColorProfiles GetImageHandleColorProfiles()
        {
            HeifIccColorProfile  iccProfile;
            HeifNclxColorProfile nclxProfile;

            if (LibHeifVersion.Is1Point10OrLater)
            {
                iccProfile  = HeifIccColorProfile.TryCreate(this.imageHandle);
                nclxProfile = HeifNclxColorProfile.TryCreate(this.imageHandle);
            }
            else
            {
                // LibHeif versions prior to 1.10 only support one color profile per image.
                var colorProfileType = LibHeifNative.heif_image_handle_get_color_profile_type(this.imageHandle);

                switch (colorProfileType)
                {
                case heif_color_profile_type.None:
                    iccProfile  = null;
                    nclxProfile = null;
                    break;

                case heif_color_profile_type.Nclx:
                    iccProfile  = null;
                    nclxProfile = HeifNclxColorProfile.TryCreate(this.imageHandle);
                    break;

                case heif_color_profile_type.IccProfile:
                case heif_color_profile_type.RestrictedIcc:
                    iccProfile  = HeifIccColorProfile.TryCreate(this.imageHandle);
                    nclxProfile = null;
                    break;

                default:
                    throw new HeifException(Resources.ColorProfileTypeNotSupported);
                }
            }

            return(new ImageHandleColorProfiles(iccProfile, nclxProfile));
        }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="HeifImage"/> class.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="colorspace">The color space.</param>
        /// <param name="chroma">The chroma.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="width"/> is less than or equal to zero.
        ///
        /// -or-
        ///
        /// <paramref name="height"/> is less than or equal to zero.
        /// </exception>
        /// <exception cref="HeifException">
        /// A LibHeif error occurred.
        ///
        /// -or-
        ///
        /// The LibHeif version is not supported.
        /// </exception>
        public HeifImage(int width, int height, HeifColorspace colorspace, HeifChroma chroma)
        {
            Validate.IsPositive(width, nameof(width));
            Validate.IsPositive(height, nameof(height));

            LibHeifVersion.ThrowIfNotSupported();

            var error = LibHeifNative.heif_image_create(width,
                                                        height,
                                                        colorspace,
                                                        chroma,
                                                        out this.image);

            error.ThrowIfError();
            // The caller can set a color profile after the image has been created.
            this.cachedIccColorProfile         = null;
            this.cachedNclxColorProfile        = null;
            this.fetchedColorProfilesFromImage = true;
            this.sync       = new object();
            this.Width      = width;
            this.Height     = height;
            this.Colorspace = colorspace;
            this.Chroma     = chroma;
        }
예제 #6
0
        /// <summary>
        /// Updates the cached color profiles while locked.
        /// </summary>
        /// <exception cref="HeifException">
        /// The color profile type is not supported.
        ///
        /// -or-
        ///
        /// A LibHeif error occurred.
        /// </exception>
        private void UpdateCachedColorProfilesWhileLocked()
        {
            if (LibHeifVersion.Is1Point12OrLater)
            {
                this.cachedIccColorProfile  = HeifIccColorProfile.TryCreate(this.image);
                this.cachedNclxColorProfile = HeifNclxColorProfile.TryCreate(this.image);
            }
            else
            {
                // LibHeif version 1.11 and earlier will crash when retrieving the NCLX color
                // profile if the image does not have one.
                var colorProfileType = LibHeifNative.heif_image_get_color_profile_type(this.image);

                switch (colorProfileType)
                {
                case heif_color_profile_type.None:
                    this.cachedIccColorProfile  = null;
                    this.cachedNclxColorProfile = null;
                    break;

                case heif_color_profile_type.Nclx:
                    this.cachedIccColorProfile  = null;
                    this.cachedNclxColorProfile = HeifNclxColorProfile.TryCreate(this.image);
                    break;

                case heif_color_profile_type.IccProfile:
                case heif_color_profile_type.RestrictedIcc:
                    this.cachedIccColorProfile  = HeifIccColorProfile.TryCreate(this.image);
                    this.cachedNclxColorProfile = null;
                    break;

                default:
                    throw new HeifException(Resources.ColorProfileTypeNotSupported);
                }
            }
        }
예제 #7
0
 public ImageHandleColorProfiles(HeifIccColorProfile icc, HeifNclxColorProfile nclx)
 {
     this.Icc  = icc;
     this.Nclx = nclx;
 }