FileOnQ / Imaging.Heif

A C#/.NET wrapper around libheif for decoding and processing high efficiency image formats (heif, heic).
GNU Lesser General Public License v3.0
15 stars 4 forks source link

libjpeg-turbo is built under Debug mode #2

Closed SkyeHoefling closed 2 years ago

SkyeHoefling commented 3 years ago

Description

The build process compiles libjpeg-turbo in debug mode instead of release mode. This generates a file that is roughly 600kb larger than if it was built in release mode. It is a best practice to try and compile upstream libraries in release mode as the code is optimized.

During the initial proof of concept the JPEG encoder that users libjpeg-turbo was failing to save. We were seeing errors when writing to disk. After investigation it was determined that we are going to have to use debug mode for now and try and fix this later

Sample Code

The snippet below is from the original proof of concept and will change in the future

public HeifImage(string file)
{
    heifContext = LibHeifContext.heif_context_alloc();
    var error = LibHeifContext.heif_context_read_from_file(heifContext, file, IntPtr.Zero);
    if (error.Code != LibHeifContext.ErrorCode.Ok)
        throw new Exception(Marshal.PtrToStringAnsi(error.Message));

    LibHeifContext.ImageHandle* imageHandle;
    var imageError = LibHeifContext.heif_context_get_primary_image_handle(heifContext, &imageHandle);

    var numberOfThumbnails = LibHeifContext.heif_image_handle_get_number_of_thumbnails(imageHandle);
    if (numberOfThumbnails > 0)
    {
        var itemIds = new uint[numberOfThumbnails];
        fixed (uint* ptr = itemIds)
        {
            LibHeifContext.heif_image_handle_get_list_of_thumbnail_IDs(imageHandle, ptr, numberOfThumbnails);
        }

        // no idea why this is failing
        LibHeifContext.ImageHandle* thumbHandle;
        var thumbError = LibHeifContext.heif_image_handle_get_thumbnail(imageHandle, itemIds[0], &thumbHandle);
        if (thumbError.Code != LibHeifContext.ErrorCode.Ok)
            throw new Exception(Marshal.PtrToStringAnsi(thumbError.Message));

        Encode(thumbHandle);
    }
    else
    {
        Encode(imageHandle);
    }

    void Encode(LibHeifContext.ImageHandle* handle)
    {
        var hasAlpha = LibHeifContext.heif_image_handle_has_alpha_channel(handle) == 1;
        var encoder = LibEncoder.encoder_jpeg_init(90);
        var options = LibHeifContext.heif_decoding_options_alloc();
        LibEncoder.encoder_update_decoding_options(encoder, handle, options);

        var bitDepth = LibHeifContext.heif_image_handle_get_luma_bits_per_pixel(handle);
        if (bitDepth < 0)
        {
            LibHeifContext.heif_decoding_options_free(options);
            LibHeifContext.heif_image_handle_release(handle);
            throw new Exception("Input image has undefined bit-dept");
        }

        LibHeifContext.Image* outputImage;
        var decodeError = LibHeifContext.heif_decode_image(
            handle,
            &outputImage,
            LibEncoder.encoder_colorspace(encoder, hasAlpha),
            LibEncoder.encoder_chroma(encoder, hasAlpha, bitDepth),
            options);

        LibHeifContext.heif_decoding_options_free(options);

        if (decodeError.Code != LibHeifContext.ErrorCode.Ok)
        {
            LibHeifContext.heif_image_handle_release(handle);
            throw new Exception(Marshal.PtrToStringAnsi(decodeError.Message));
        }

        if ((IntPtr)outputImage != IntPtr.Zero)
        {
            bool saved = LibEncoder.encode(encoder, handle, outputImage, "output.jpeg");
            if (!saved)
                throw new Exception("Unable to save");
        }

        LibEncoder.encoder_free(encoder);
    }
}

The libjpeg-turbo code fails on LibEncoder.encode(encoder, handle, outputImage, "output.jpeg") when the library is built under release mode but works when the library is built under debug mode

Difficulty: [Hard]

SkyeHoefling commented 3 years ago

While researching #3 I discovered that we must compile FileOnQ.Imaging.Heif.Encoders in debug mode due to libjpeg-turbo compilation issues. When we solve this problem, we should be able to compile FileOnQ.Imaging.Heif.Encoders in release mode.

SkyeHoefling commented 2 years ago

Per research in https://github.com/FileOnQ/Imaging.Heif/issues/37#issuecomment-1005958923 we can submit a PR for this as we can compile libjpeg-turbo in release mode now