Class BitmapIO

3DS Max Plug-In SDK

Class BitmapIO

See Also: Class Bitmap, Class BitmapStorage, Class BitmapInfo, Working with Bitmaps.

class BitmapIO : public BaseInterfaceServer

Description:

This is the base class used by developers creating image loader / saver plug-ins. Developers implement pure virtual methods of this class to load the image, open it for output, write to it, close it, and to provide information about the image loader/saver they are creating. These are properties such as the author name, copyright, image format description, filename extension(s) used, and the capabilities of the image loader / saver.

When a BitmapIO derived image reader reads an image, it creates a storage class that makes sense to it. For example, a paletted 8 bit is perfect for loading GIF's but not for loading 32 bit Targas. The inverse is also true. There is no point in creating a TRUE_64 storage to load a GIF. Because this is how image buffers are managed, it is also important to note that if a developer writes an image loader that creates images from scratch (a gradient generator for instance), there is no need to have any real memory allocated. The plug-in would simply derive a new type of BitmapStorage and provide the pixels through the common methods (virtual buffer), creating them as they are requested.

Method Groups:

The hyperlinks below jump to the start of related methods within the class:

Loading

Output/Write/Close

Filename Extension

Author/Description/Copyright/Version

Capabilities

Parameter Block Methods

ShowAbout/ShowImage/ShowControl

Image Information

Gamma Setting

Dithering

DIB Access

Palette Calculation

Storage / Bitmap Access

Silent Mode Setting

G-Buffer Channels Required

Internal Methods

Data Members:

protected:

float gamma;

The gamma setting.

Bitmap *map;

The Bitmap using this OUTPUT handler.

BitmapStorage *storage;

The storage used by this INPUT handler.

int openMode;

The mode that the IO module is open for. See List of Bitmap Open Mode Types.

BitmapIO *prevIO;

A linked list pointer to the previous IO module for multiple outputs of a single bitmap.

BitmapIO *nextIO;

A linked list pointer to the next IO module for multiple outputs of a single bitmap.

public:

BitmapInfo bi;

Describes the properties of the bitmap being handled by the instance of this class.

Methods:

Output Pixels

public:

Prototype:

int GetOutputPixels(int x,int y,int pixels,BMM_Color_64 *ptr,BOOL preMultAlpha=TRUE);

Remarks:

Implemented by the System.

This method is used by the subclassed BitmapIO to get pixels for output with the appropriate output gamma correction.

Parameters:

int x

Source x location.

int y

Source y location.

int pixels

Number of pixels to retrieve.

BMM_Color_64 *ptr

Pointer to storage for the retrieved pixels. See Structure BMM_Color_64.

BOOL preMultAlpha=TRUE

This parameter is available in release 3.0 and later only.

Setting this parameter to FALSE will cause pixels with non-premultiplied alpha to be returned.

Return Value:

Nonzero if the pixels were retrieved; otherwise zero.

Prototype:

int GetDitheredOutputPixels(int x,int y,int pixels,BMM_Color_32 *ptr,BOOL preMultAlpha=TRUE);

Remarks:

Implemented by the System.

This method is used by the subclassed BitmapIO to get 32 bit pixels for output with the appropriate output gamma correction and dither. Note that this method works on only a single scanline of pixels at a time.

Parameters:

int x

Source x location.

int y

Source y location.

int pixels

Number of pixels to retrieve.

BMM_Color_32 *ptr

Pointer to storage for the retrieved pixels. See Structure BMM_Color_32.

BOOL preMultAlpha=TRUE

This parameter is available in release 3.0 and later only.

Setting this parameter to FALSE will cause pixels with non-premultiplied alpha to be returned.

Return Value:

Nonzero if the pixels were retrieved; otherwise zero.

DIB Access

Prototype:

PBITMAPINFO GetOutputDib(int depth = 24);

Remarks:

Implemented by the System.

This method is used by the subclassed BitmapIO to get a DIB for output with the appropriate output gamma correction.

Parameters:

int depth = 24

Specifies the depth of the DIB. This may be either 24 or 32.

Prototype:

PBITMAPINFO GetDitheredOutputDib(int depth = 24);

Remarks:

Implemented by the System.

This methods is used by the subclassed BitmapIO to get a DIB for output with the appropriate output gamma correction and dither.

Parameters:

int depth = 24

Specifies the depth of the DIB. This may be either 24 or 32.

Output Gamma Setting

Prototype:

float OutputGamma();

Remarks:

Implemented by the System.

Returns the output gamma setting.

Dithering

Prototype:

BOOL DitherTrueColor();

Remarks:

Implemented by the System.

If a BitmapIO wants to do its own dithering, it should call this method to find out if dithering is wanted for true color images. If it is a 24 bit or 32 bit format, it would usually just call GetDitheredOutputPixels() instead.

Return Value:

TRUE if dithering is desired; otherwise FALSE.

Prototype:

BOOL DitherPaletted();

Remarks:

Implemented by the System.

If a BitmapIO wants to do its own dithering, it should call this method to find out if dithering is wanted for paletted images.

Return Value:

TRUE if dithering is desired; otherwise FALSE.

Palette Computation

Prototype:

int CalcOutputPalette(int palsize, BMM_Color_48 *pal);

Remarks:

Calculate a color palette for output color packing for the map that is using this output handler (this is the map pointed at by the protected data member Bitmap *map). This method performs gamma correction. See Class ColorPacker, Class Quantizer.

Parameters:

int palsize

The size of the palette to compute.

BMM_Color_48 *pal

Storage for the palette.

Return Value:

Nonzero if the palette was computed; otherwise zero.

Open Mode Setting

Prototype:

inline int OpenMode()

Remarks:

Implemented by the System.

Returns the open mode setting. See Bitmap Open Mode Types.

Storage / Bitmap Access

Prototype:

BitmapStorage *Storage()

Remarks:

Implemented by the System.

Returns a pointer to the BitmapStorage for this image input handler.

Prototype:

inline Bitmap *Map()

Remarks:

Implemented by the System.

Returns a pointer to the Bitmap using this output handler.

Filename Extensions

Prototype:

virtual int ExtCount() = 0

Remarks:

Implemented by the Plug-In.

Returns the number of filename extensions supported by this IO module. For example the EPS plug-in supports "EPS" and "PS", and thus returns 2.

Prototype:

virtual const TCHAR *Ext( int n ) = 0;

Remarks:

Implemented by the Plug-In.

The extensions are accessed using a virtual array. This method returns the 'i-th' filename extension supported by the IO module, (i.e. "EPS").

Parameters:

int i

Specifies which filename extension to return.

Author/Desc/Copyright/Version

Prototype:

virtual const TCHAR *LongDesc( ) = 0

Remarks:

Implemented by the Plug-In.

Returns a long ASCII description of the image format (i.e. "Targa 2.0 Image File").

Prototype:

virtual const TCHAR *ShortDesc() = 0

Remarks:

Implemented by the Plug-In.

Returns a short ASCII description of the image format (i.e. "Targa").

Prototype:

virtual const TCHAR *AuthorName() = 0

Remarks:

Implemented by the Plug-In.

Returns the ASCII Author name of the IO module.

Prototype:

virtual const TCHAR *CopyrightMessage() = 0;

Remarks:

Implemented by the Plug-In.

Returns the ASCII Copyright message for the IO module.

Prototype:

virtual UINT Version() = 0;

Remarks:

Implemented by the Plug-In.

Returns the IO module version number * 100 (i.e. v3.01 = 301)

Capabilities

Prototype:

virtual int Capability() = 0;

Remarks:

Implemented by the Plug-In.

Returns the IO module capability flags. These describe the capabilities of the plug-in such as if it supports reading images, writing images, multiple files, and whether it has its own information and control dialog boxes. See BitmapIO Capability Flags.

ShowAbout / ShowImage / ShowControl

Prototype:

virtual void ShowAbout( HWND hWnd ) = 0;

Remarks:

Implemented by the Plug-In.

This method is called to show the plug-in's "About" box. This is called, for example, from the About button of the Add Image Input Event dialog in Video Post.

Parameters:

HWND hWnd

The handle of the owner window.

Prototype:

virtual BOOL ShowImage(HWND hWnd, BitmapInfo *bi)

Remarks:

Implemented by the Plug-In.

If the BMMIO_OWN_VIEWER flag is set in the flags returned from the Capability() method, this method will be called whenever the user wants to view an image for this device. This is for devices which can "play" image sequences such as AVIs, FLCs, etc.

Parameters:

HWND hWnd

The handle of the owner window.

BitmapInfo *bi

The bitmap to view.

Return Value:

TRUE if the viewing the image was successful; otherwise FALSE.

Default Implementation:

{ return FALSE; }

Prototype:

virtual BOOL ShowControl( HWND hWnd, DWORD flag )

Remarks:

Implemented by the Plug-In.

Displays the Control Panel of the IO module. This function is only called if the plug-in has defined it supports it (through the Capability flag returned from Capability(), ie. BMMIO_CONTROLREAD, etc.). See BitmapIO Capability Flags.

Parameters:

HWND hWnd

The handle of the owner window.

DWORD flag

Indicates to the plug-in what operation the control is for (read, write, or generic). See BitmapIO Capability Flags

Return Value:

If the user exits the box through an OK, this function should return TRUE. If the user cancels out, it will should FALSE. FALSE indicates nothing has changed so the system won't bother asking the plug-in if it wants to save data.

Default Implementation:

{ return FALSE; }

Parameter Block Methods

The following methods (EvaluateConfigure(), LoadConfigure(), SaveConfigure()) deal with parameter block loading and saving. See the sample code below to see how the EPS BitmapIO plug-in uses these methods.

typedef struct userSettable {

int units; // Inches or MM

int binary; // Whether want binary image data or not

int preview; // Whether want TIFF preview in file

int orientation; // Options are portrait or landscape

int colorType; // Whether image is output as rgb or gray

float paperHeight; // Height of output (for centering image)

float paperWidth; // Width of output (for centering image)

float xResolution; // In dots per inch

float yResolution; // In dots per inch

} UserSettable;

 

DWORD BitmapIO_EPS::EvaluateConfigure () {

return sizeof (UserSettable);

}

 

BOOL BitmapIO_EPS::LoadConfigure (void *ptr) {

UserSettable *buf = (UserSettable *) ptr;

memcpy (&userSettings, ptr, sizeof(UserSettable));

return TRUE;

}

 

BOOL BitmapIO_EPS::SaveConfigure (void *ptr) {

if (ptr) {

memcpy (ptr, &userSettings, sizeof(UserSettable));

return TRUE;

} else

return FALSE;

}

Prototype:

virtual DWORD EvaluateConfigure( ) = 0;

Remarks:

Implemented by the Plug-In.

This method is called by 3ds max to determine the buffer size required by the plug-in. The plug-in implements this method and returns the number of bytes of configuration data it needs to save.

Return Value:

The buffer size required by the plug-in (in bytes).

Prototype:

virtual BOOL LoadConfigure( void *ptr ) = 0;

Remarks:

Implemented by the Plug-In.

This method is called by 3ds max to allow the plug-in to load any configuration data.

Parameters:

void *ptr

Pointer initialized to point to the previously saved configuration data.

Return Value:

Returns TRUE if the data was loaded properly; otherwise FALSE.

Prototype:

virtual BOOL SaveConfigure( void *ptr ) = 0;

Remarks:

Implemented by the Plug-In.

This method is called by 3ds max to allow the plug-in to save any configuration data.

Parameters:

void *ptr

Pointer initialized to a pre-allocated buffer where the plug-in may save data.

Return Value:

Returns TRUE if the data was saved; otherwise FALSE.

Silent Mode Setting

Prototype:

BOOL SilentMode()

Remarks:

Implemented by the System.

Returns the state of the silent mode flag. If this flag is TRUE the plug-in should NOT post a dialog displaying any error messages.

Prototype:

BMMRES GetFrame(BitmapInfo *fbi, int *frame);

Remarks:

Implemented by the System.

This method is for use with multi-frame sequences. It processes the desired frame based on the user options. For example the user can tell the system to hold on the last frame of the sequence, loop back to the beginning, or return an error. This method does all the checking automatically based on the BitmapInfo object passed and computes the proper frame number.

Parameters:

BitmapInfo *fbi

A pointer to the BitmapInfo that contains the user options. This is the instance passed to Load().

int *frame

A pointer to an integer to receive the frame number

Return Value:

One of the following values:

BMMRES_SUCCESS

BMMRES_BADFRAME

Critical Error Handling

Prototype:

BMMRES ProcessImageIOError(BitmapInfo *bi, TCHAR *string = NULL);

Remarks:

Implemented by the System.

This method may be called to present the user with the 3ds max Image IO Error dialog box. The dialog displays the bitmap file name or device name, and the specified error message. The user may choose Cancel or Retry from the dialog. An appropriate value is returned based on the users selection.

This method is used to handle hardware I/O errors automatically or display the given string.

In this method, if Silent Mode is on (for example network rendering is being done), no dialog is presented and BMMRES_ERRORTAKENCARE is returned.

Parameters:

BitmapInfo *bi

A pointer to the BitmapInfo. This is used to retrieve the file or device name (using bi->Name() or bi->Device()).

TCHAR *string = NULL

The error message to present in the dialog. If NULL this method will query the operating system for the last I/O error and give its own interpretation of the error. This will work for all "File Not Found", "Permission Denied", etc. type errors.

Return Value:

One of the following values:

BMMRES_ERRORTAKENCARE

Returned if the user selected OK from the dialog or the error was taken care of (silent mode was on).

BMMRES_ERRORRETRY

The user has selected Retry from the dialog.

Prototype:

BMMRES ProcessImageIOError(BitmapInfo *bi, int errorcode);

Remarks:

Implemented by the System.

This method may be called to present the user with the 3ds max Image IO Error dialog box displaying the specified error message based on the error code passed. The user may choose Cancel or Retry from the dialog. An appropriate value is returned based on the users selection. If Silent Mode is on (for example network rendering is being done) no dialog is presented and BMMRES_ERRORTAKENCARE is returned.

Parameters:

BitmapInfo *bi

A pointer to the BitmapInfo. This is used to retrieve the file or device name (using bi->Name() or bi->Device()).

int errorcode

The error code. Pass one of the following values and the string shown to its right will be presented.

BMMRES_INTERNALERROR - Internal Error

BMMRES_NUMBEREDFILENAMEERROR - Error Creating Numbered File Name.

BMMRES_BADFILEHEADER - Invalid Image File Header

BMMRES_CANTSTORAGE - Error Creating Image Storage

BMMRES_MEMORYERROR - Memory Error

BMMRES_BADFRAME - Invalid Frame Requested

Any other values produce - Unknown Error

Return Value:

One of the following values:

BMMRES_ERRORTAKENCARE

Returned if the user selected Cancel from the dialog or the error was taken care of (silent mode was on).

BMMRES_ERRORRETRY

The user has selected Retry from the dialog.

Sample Code:

BMMRES BitmapIO_JPEG::Write(int frame) {

 //-- If we haven't gone through an OpenOutput(), leave

 if (openMode != BMM_OPEN_W)

  return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR));

 //-- Resolve Filename --------------------------------

 TCHAR filename[MAX_PATH];

 if (frame == BMM_SINGLEFRAME) {

  _tcscpy(filename,bi.Name());

 } else {

  if (!BMMCreateNumberedFilename(bi.Name(),frame,filename)) {

   return (ProcessImageIOError(&bi,BMMRES_NUMBEREDFILENAMEERROR));

  }

 }

G-Buffer Channels Required

Prototype:

virtual DWORD ChannelsRequired()

Remarks:

Implemented by the Plug-In.

These are the channels required for output. By setting this flag, the plug-in can request that 3ds max generate the given channels. Prior to rendering, 3ds max will scan the plug-ins in the chain of events and list all types of channels being requested. The plug-in, at the time of the Write() method, will have access to these channels through the channel interface described in BitmapStorage.

Return Value:

See List of Image Channels.

Default Implementation:

{ return BMM_CHAN_NONE; }

Image Information

Prototype:

virtual BMMRES GetImageInfoDlg( HWND hWnd, BitmapInfo *bi, const TCHAR *filename = NULL )

Remarks:

Implemented by the Plug-In.

This method will display a dialog with information about the given bitmap (either defined in bi.Name()/bi.Device() or explicitly in the filename passed). The default method will retrieve image information using the mandatory GetImageInfo() and display a generic information dialog. If an image loader / writer wants to show its own info dialog, perhaps showing an image property not found in the generic dialog, it can implement its own function (and notify the system using the BMM_INFODLG flag in the capabilities flag).

Parameters:

HWND hWnd

The parent window handle calling the dialog.

BitmapInfo *bi

Defines the name of the bitmap or device (unless specified below).

const TCHAR *filename = NULL

Specifies the filename to use explicitly.

Return Value:

The result of the operation. See Bitmap Error Codes.

Prototype:

virtual BMMRES GetImageInfo( BitmapInfo *bi ) = 0;

Remarks:

Implemented by the Plug-In.

The BitmapIO module implements this method to initialize the BitmapInfo instance passed in with information about the image. This information might be obtained from read the image header for example. The BitmapInfo passed contains the name of the image to get the information about.

Parameters:

BitmapInfo *bi

A pointer to an instance of the class BitmapInfo.

Return Value:

If an error occurs, the plug-in should process the error (display a message if appropriate) and return BMMRES_ERRORTAKENCARE. If everything went OK, the plug-in should return BMMRES_SUCCESS.

Sample Code:

bi->SetWidth(640);

bi->SetHeight(480);

bi->SetType(BMM_TRUE_24);

bi->SetAspect(1.0f);

bi->SetGamma(1.0f);

bi->SetFirstFrame(0);

bi->SetLastFrame(0);

return BMM_SUCCESS;

Prototype:

virtual BMMRES GetImageName( BitmapInfo *bi, TCHAR *filename)

Remarks:

Implemented by the Plug-In.

This method is implemented by image file loaders (IFL handlers). It is called to update the filename passed based on the properties of the BitmapInfo passed. See the implementation of this method in \MAXSDK\SAMPLES\IO\IFL.CPP.

Parameters:

BitmapInfo *bi

Specifies the properties of the IFL sequence.

TCHAR *filename

The filename to update based on the properties of bi.

Return Value:

See Bitmap Error Codes.

Prototype:

virtual void EvalMatch(TCHAR *matchString);

Remarks:

This method is available in release 2.0 and later only.

The bitmap manager caches images in order to speed its process. When a new image is requested, if it's

already loaded, a pointer to it is passed around as opposed to loading an entire new copy of it. It does so by comparing the image name and the frame number requested (in case of multiframe files and/or devices).

This works fine in most cases, however consider the following scenario. The Accom device generates images just as if you were loading Targa files. The comparison explained above works fine. The problem however, is that within the Accom private setup, you can determine where in the Accom to start reading frames. In other words, you may have a sequence of images recorded in the Accom starting at frame 300 for instance. Once in the Accom setup, you define your starting frame at 300 and whenever 3ds max requests a frame, the Accom driver offsets the requested frame number by 300. For example, when 3ds max is rendering its 10th frame and requests a frame from the Accom (for a Map or for a background, etc.), the Accom will see that 3ds max wants frame 10 and the user had setup the starting frame at 300. After computing the offset the Accom driver returns frame 310. Now, if two or more maps are used in a scene, the cache match mechanism explained above fails as it does not take in consideration the "starting frame" parameter of the Accom driver. For it, the name matches (Accom) and the frame number matches (frame 10 in the example above). If two or more maps start at different positions within the Accom, the first one defined will be used as it satisfies the match.

To handle this condition this new method saves extra information (driver private information) about a frame. Basically, part of the match process is now handled by those drivers that implement this method.

If a driver has some private data (handled by its own setup dialogue) that defines anything in how images are returned (in other words, if different images are returned because of those private settings being different), it must define the BMMIO_EVALMATCH return flag and must also implement this method. The flag is necessary to avoid wasting time setting up instances of the driver just to call the (possibly unimplemented) method.

Parameters:

TCHAR *matchString

The match string. The driver simply builds a string made of its own "per frame" parameters and retuns it so 3ds max can compare it with another instance of the driver.

Loading

Prototype:

virtual BitmapStorage *Load( BitmapInfo *bi, Bitmap *map, BMMRES *status ) = 0;

Remarks:

Implemented by the Plug-In.

This is the method that is called to actually load and store the image. This method usually creates the storage for the image data, allocates storage space, and puts the image to the storage one scanline at a time. This method also usually sets the BitmapIO::openMode flag to BMM_OPEN_R to indicate the image is loaded and open for reading.

Parameters:

BitmapInfo *bi

Points to an instance of class BitmapInfo. This has the name of the bitmap / device to load.

Bitmap *map

This points to the bitmap to be loaded.

BMMRES *status

The result of the bitmap load operation. See Bitmap Error Codes.

Return Value:

The BitmapStorage created to manages this bitmap.

Sample Code:

See the Load() method of \MAXSDK\SAMPLES\IO\JPEG\JPEG.CPP.

Output / Write / Close

Prototype:

virtual int OpenOutput(BitmapInfo *bi, Bitmap *map);

Remarks:

Implemented by the Plug-In.

This method opens the image for output and prepare to write to it. This is the time that the plug-in receives the information about what to write, the flags, etc. When the Write() method is called the only thing passed is the frame number.

Parameters:

BitmapInfo *bi

The image information.

Bitmap *map

Points to the bitmap to save.

Return Value:

Returns nonzero if everything was OK; otherwise 0.

Sample Code:

See the OpenOutput() method of \MAXSDK\SAMPLES\IO\JPEG\JPEG.CPP.

Prototype:

virtual int Write(int frame);

Remarks:

Implemented by the Plug-In.

This method is called to write the image from the BitmapStorage to disk. The data member bi contains the relevant information (for example bi.Name() contains the name of the file to write).

Parameters:

DWORD frame

Specifies the frame to write. For single image formats this will be BMM_SINGLEFRAME.

Return Value:

Returns nonzero if everything was OK; otherwise 0.

Sample Code:

See the Write() method of \MAXSDK\SAMPLES\IO\JPEG\JPEG.CPP.

Prototype:

virtual int Close(int flag);

Remarks:

Implemented by the Plug-In.

Closes the output file and saves or discards the changes based on the flag passed.

Parameters:

int flag

See List of Bitmap Close Types.

Return Value:

Returns nonzero if output was closed successfully; otherwise 0.

Sample Code:

See the Close() method of \MAXSDK\SAMPLES\IO\WSD\WSD.CPP.

Internal use

Prototype:

void InitOutputGammaTable(BitmapInfo*bi);

Remarks:

Implemented by the System.

This method is used internally to build the output gamma table.

Prototype:

virtual PAVIFILE GetPaviFile();

Remarks:

Implemented by the System.

This method is used internally.

Default Implementation:

{ return NULL; }

Prototype:

inline void SetPrev(BitmapIO *prev)

Remarks:

Implemented by the System.

This method is used internally.

Prototype:

inline void SetNext(BitmapIO *next);

Remarks:

Implemented by the System.

This method is used internally.

Prototype:

inline BitmapIO *Prev();

Remarks:

Implemented by the System.

This method is used internally.

Prototype:

inline BitmapIO *Next();

Remarks:

Implemented by the System.

This method is used internally.