This topic first defines how things work in general, and then describes how automatic gamma correction affects the SDK.
BitmapInfo
ClassThe BitmapInfo
class contains all the information about a bitmap and is used in many cases:
Bitmap
class has a BitmapInfo
member that provides information about a bitmap. The BitmapInfo
is used when loading and saving bitmaps, for example, to define what to be loaded and saved and how, what settings to use, and others.BitmapInfo
in the file dialog boxes (for example, BitmapManager::SelectFileInput()
or BitmapManager::Output()
)The BitmapInfo
contains the filename and asset tag for a bitmap and the associated gamma values and flags. It also contains an opaque data pointer with additional information that is used by a BitmapIO
plug-in when saving or loading a file. For example, the plug-in stores information about the JPEG compression settings as additional information.
You must never set, modify, or alter the plug-in data directly. It is edited by the particular setup dialog of a given BitmapIO
plug-in (the dialog that pops up when the Setup button is clicked in a bitmap file dialog).
Instead of working with file names, you must use BitmapInfo
. In general, the code must avoid dealing only with filenames. When dealing with filenames, these guidelines must be followed:
BitmapInfo
if the file type remains the same, for example, changing the path of a given .JPG.BitmapInfo::ResetPiData()
.The following cases indicate what this means:
BitmapInfo
from the user through a dialog such as BitmapManager::SelectFileInput()
when loading a bitmap file. You can use this BitmapInfo
and pass it to BitmapManager::Open()
.BitmapInfo
from the user through a dialog such as BitmapManager::SelectFileOutput()
when saving a bitmap file. You can use this BitmapInfo
and pass it to Bitmap::OpenOutput()
.BitmapInfo
obtained from the user when saving after modifying names or paths, and avoid modifying the path to a different extension.BitmapInfo
and not the filename when saving data to the scene persistently.You do not need to modify the code to support the new automatic gamma correction if these guidelines are followed. However, if your code is creating its own BitmapInfo
or modifying them extensively, or is working with only filenames, you might have to make necessary changes. See the following section for more information.
In the BitmapInfo
class, gamma correction is handled by these members: gamma
, custgamma
, and customflags
.
gamma
is the gamma value. It is the value determined by 3ds Max for file read/write. It is retrieved with BitmapInfo::Gamma()
and set with BitmapInfo::SetGamma()
.custgamma
is the custom gamma value. It maps to the Override option in the bitmap file dialog. It is retrieved with BitmapInfo::GetCustomGamma()
and set with BitmapInfo::SetCustomGamma()
.customflags
. It is retrieved with BitmapInfo::GetCustomFlags()
, and set with BitmapInfo::SetCustomFlag()
and BitmapInfo::ResetCustomFlag()
.There are a set of flags related to gamma in the customflags
member. Two of them (BMM_CUSTOM_GAMMA
and BMM_CUSTOM_FILEGAMMA
) are important for how gamma is actually read or written. There are three valid combinations:
BMM_CUSTOM_FILEGAMMA
- When set, it indicates that the actual gamma to use is in the gamma
member, and after reading it indicates that it is from the file.BMM_CUSTOM_GAMMA
- When set, it indicates that the actual gamma to use is in the custgamma
member, and that it is from a user override.These flags map to the options in the file dialog as described in Understanding the Automatic Gamma Correction. The following table shows the previous mapping.
Option | Flag |
---|---|
Use image's own gamma | BMM_CUSTOM_FILEGAMMA is set |
Override | BMM_CUSTOM_GAMMA is set |
Use System default gamma | No flag is set |
The following table shows the current mapping.
Option | Flag |
---|---|
Automatic | BMM_CUSTOM_FILEGAMMA is set |
Override | BMM_CUSTOM_GAMMA is set |
Currently, the third option where neither flag is set is no longer valid. However, it is still adhered to for compatibility reasons (files will continue to work as they did in the past), but passing a BitmapInfo
with neither flag set to any file dialog function actually converts to a matching override setting.
BMM_CUSTOM_FILEGAMMA
FlagThe change in the meaning of the BMM_CUSTOM_FILEGAMMA
flag is important and is explained in the following table.
Before | Current |
---|---|
When set before loading a file, it indicates that gamma is loaded from the file header, if it is available. | When set before loading a file, it flags the **Automatic** option. As before, the gamma value in the file header is used. If the file header does not have a gamma value, the gamma is determined based on the file type. |
When the flag remained set after loading the file, it indicates that gamma is read from the file header. If not, the flag is cleared. | The flag remains set after loading the file, and if gamma value is missing in the file header, the flag is not cleared. Instead, the new information flag `BMM_CUSTOM_INFERREDGAMMA` is set to simply inform any caller that gamma is inferred and is not read from the file header. |
It is not valid to set the flag before saving. | The flag is valid when saving, and is actually the default behaviour. The gamma used for saving the file is based on the file type, either sRGB (= gamma 2.2) or linear (= gamma 1.0). |
A new interface in the BitmapIO
class called BitmapIOMetaData
is used to determine whether the file types are saved and loaded linearly or with an embedded gamma.
The bitmap loading and saving code can inquire the appropriate BitmapIO
with GetInterface(BITMAPIOMETADATA_INTERFACE_ID)
to obtain this interface. If the interface is missing, the globally defined gamma value is used. This means that for any unmodified BitmapIO
plugin, the behavior is the same as before.
BitmapIO
plug-ins dealing with floating point data, log data, or other data that must be stored linearly can expose this interface. It has a BitmapIOMetaData::UseLinearStorage()
function which is called after loading or before saving. It returns true if linear storage is preferred, and false if not.
For information about avoiding gamma related issues when writing code, see the Automatic Gamma Correction Best Practices topic.