Skip to content

.exr File Saved with 16-bit Depth Instead of 32-bit Float When Using EXR_FLOAT #26

@karel-tomanec

Description

@karel-tomanec

Description

When saving a .exr file using FreeImage with a FIBITMAP of type FIT_RGBF and the EXR_FLOAT flag, the resulting file is saved with a 16-bit depth per channel instead of the expected 32-bit float depth. This behavior persists even though the EXR_FLOAT flag is explicitly passed to the FreeImage_Save function.

My code:

Click to expand code
#include <FreeImage.h>
#include <iostream>
#include <string>

FIBITMAP* CreateTestImage(unsigned width, unsigned height)
{
	FIBITMAP* bitmap = FreeImage_AllocateT(FIT_RGBF, width, height);
	if (!bitmap)
	{
		std::cerr << "Failed to allocate image." << std::endl;
		return nullptr;
	}

	// Fill the image with a gradient
	float* bits = reinterpret_cast<float*>(FreeImage_GetBits(bitmap));
	for (unsigned y = 0; y < height; ++y)
	{
		for (unsigned x = 0; x < width; ++x)
		{
			unsigned index = (y * width + x) * 3;
			bits[index + 0] = static_cast<float>(x) / width;
			bits[index + 1] = static_cast<float>(y) / height;
			bits[index + 2] = 0.5f;
		}
	}

	return bitmap;
}

void SaveTestImage(const std::string& filename, FIBITMAP* bitmap, int flags)
{
	if (!bitmap)
	{
		std::cerr << "Invalid bitmap, cannot save." << std::endl;
		return;
	}

	unsigned width = FreeImage_GetWidth(bitmap);
	unsigned height = FreeImage_GetHeight(bitmap);
	unsigned bpp = FreeImage_GetBPP(bitmap);
	FREE_IMAGE_TYPE type = FreeImage_GetImageType(bitmap);

	std::cout << "Image properties:" << std::endl;
	std::cout << "  Width: " << width << std::endl;
	std::cout << "  Height: " << height << std::endl;
	std::cout << "  Bits per pixel: " << bpp << std::endl;
	std::cout << "  Image type: " << type << std::endl;

	std::cout << "Saving image to " << filename << "..." << std::endl;
	if (FreeImage_Save(FIF_EXR, bitmap, filename.c_str(), flags))
	{
		std::cout << "Image saved successfully: " << filename << std::endl;
	}
	else
	{
		std::cerr << "Failed to save image: " << filename << std::endl;
	}
}

int main()
{
	FreeImage_Initialise();

	const unsigned width = 512;
	const unsigned height = 512;
	const std::string filename = "test_image.exr";

	FIBITMAP* bitmap = CreateTestImage(width, height);
	if (!bitmap)
	{
		FreeImage_DeInitialise();
		return 1;
	}

	int flags = EXR_FLOAT;
	SaveTestImage(filename, bitmap, flags);

	FreeImage_Unload(bitmap);
	FreeImage_DeInitialise();

	return 0;
}

magick output:

Click to expand loge
 magick identify -verbose test_image.exr
Image:
  Filename: test_image.exr
  Permissions: rw-rw-rw-
  Format: EXR (High Dynamic-range (HDR))
  Class: DirectClass
  Geometry: 512x512+0+0
  Units: Undefined
  Colorspace: sRGB
  Type: TrueColor
  Base type: Undefined
  Endianness: Undefined
  Depth: 16-bit
  Channels: 3.0
  Channel depth:
    Red: 16-bit
    Green: 16-bit
    Blue: 16-bit
  Channel statistics:
    Pixels: 262144
    Red:
      min: 0  (0)
      max: 65407 (0.998047)
      mean: 32703.5 (0.499023)
      median: 32639.5 (0.498047)
      standard deviation: 18918.3 (0.288675)
      kurtosis: -1.20002
      skewness: -9.10919e-10
      entropy: 1
    Green:
      min: 0  (0)
      max: 65407 (0.998047)
      mean: 32703.5 (0.499023)
      median: 32639.5 (0.498047)
      standard deviation: 18918.3 (0.288675)
      kurtosis: -1.20002
      skewness: -9.10884e-10
      entropy: 1
    Blue:
      min: 32767.5  (0.5)
      max: 32767.5 (0.5)
      mean: 32767.5 (0.5)
      median: 32767.5 (0.5)
      standard deviation: 0 (0)
      kurtosis: 0
      skewness: 0
      entropy: 0
  Image statistics:
    Overall:
      min: 0  (0)
      max: 65407 (0.998047)
      mean: 32724.8 (0.499349)
      median: 32682.2 (0.498698)
      standard deviation: 12612.2 (0.19245)
      kurtosis: -0.800015
      skewness: -6.07268e-10
      entropy: 0.666667
  Rendering intent: Perceptual
  Gamma: 1
  Chromaticity:
    red primary: (0.64,0.33,0.03)
    green primary: (0.3,0.6,0.1)
    blue primary: (0.15,0.06,0.79)
    white point: (0.3127,0.329,0.3583)
  Matte color: grey74
  Background color: white
  Border color: srgb(223,223,223)
  Transparent color: black
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 512x512+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Piz
  Orientation: Undefined
  Properties:
    date:create: 2025-01-28T10:44:56+00:00
    date:modify: 2025-01-28T11:12:23+00:00
    date:timestamp: 2025-01-28T11:18:29+00:00
    signature: e3e00cda1b1142bd3ac1a130f916bddddfdde7e6f4442f15fa24bef51628bfe3
  Artifacts:
    verbose: true
  Tainted: False
  Filesize: 203153B
  Number pixels: 262144
  Pixel cache type: Memory
  Pixels per second: 48.2761MP
  User time: 0.005u
  Elapsed time: 0:01.005
  Version: ImageMagick 7.1.1-36 Q16-HDRI x64 852a4e9:20240727 https://imagemagick.org

Expected Behaviour

The .exr file should be saved with 32-bit float depth per channel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions