...

Chasys Draw IES Help:


SDK - Device Plug-ins
 

Interface Rules

The following rules apply to all plug-ins implementing this interface:

  • Device plug-ins need not be re-entrant. This interface is always called from a single thread as it requires a GUI.
  • The interface currently only allows the plug-in to access one layer per call; this layer is chosen by the user during plug-in invocation
  • The plug-in should allow the user to set any necessary parameters via an appropriate dialog box.
  • The image buffer for this interface is prelocked, and can be accessed at any time

 

Interface Description

The file format plug-in interface is made up of three functions in addition to the general interface:

  • dev_ReadImage - Used to read images from external devices
  • dev_SendImage - Used to send images to external devices

Plug-ins are not required to implement the entire interface - you may implement dev_ReadImage, or dev_SendImage or both of them as you see fit.

 

Image Import via dev_ReadImage()

Chasys Draw IES looks for a function named dev_ReadImage() in the plug-in the user selects. If it finds this function, Chasys Draw IES calls it with a pointer to a dev_IMAGE_R structure.

int __cdecl dev_ReadImage(dev_IMAGE_R* data);

struct dev_IMAGE_R

{

      unsigned long     width;

      unsigned long     height;

      unsigned long     pitch;

      unsigned long*    lp_pix;

//16

      HWND              hwnd;

      unsigned long     unused_1;

      int               (__cdecl* create)(dev_IMAGE_R* self);

      unsigned char     img_type;

      unsigned char     img_subtype;

      unsigned short    unused_2;

//32

      unsigned long     layer_count;

      short             x_pos;

      short             y_pos;

      wchar_t           name[32];

      unsigned short    options;

      unsigned short    frame_delay;

      unsigned char     group_id;

      unsigned char     transparency;

      unsigned char     unused_3[18];

//128

      unsigned char*    meta_data;

      int               (__cdecl* meta_write)(dev_IMAGE_R* self,char* type,int size);

//136

      unsigned char     reserved_1[252-136];//do not touch

      unsigned long     timeout;

//256

      pi_STATESTORE*    pi_StateStore;

      pi_METAMARKUP*    pi_MetaMarkup;

      pi_BASICQUERY*    pi_BasicQuery;

      pi_BASICIMAGE*    pi_BasicImage;

      pi_BASICCOLOR*    pi_BasicColor;

      pi_BASICUTILS*    pi_BasicUtils;

//280

      unsigned char     reserved_x[1024-280];//do not touch

};

dev_ReadImage is expected to set the width and height members, then call the create() member function to request Chasys Draw IES to allocate the bitmap for each layer in the image.

create() returns non-zero to indicate success. It also sets the width, height, pitch (in number of pixels, not bytes) and lp_pix. If the requested size is too large for the host to allocate, it allocates a smaller bitmap of the same aspect ratio, sets width and height to the new values, then returns a negative value. In this case, the host requires that the plug-in resizes the image locally. Your plug-in should either resize the loaded image internally without assistance from the host, or indicate failure by returning the error code PLUGIN_ERR_BAD_PARAM.

The plug-in proceeds to fill lp_pix as an array of 32 bit integers, each representing a pixel in BGRA format (blue LSB, alpha MSB), with alpha values of zero(0x00) for opaque and 255 (0xff) for transparent.

If the image has additional layers, the plug-in sets width, height, etc, then calls create() again; this is repeated until all the layers have been loaded.

The plug-in returns (from dev_ReadImage) the number of layers loaded (greater than 0) to indicate success. If the image had more layers but the plug-in was unable to load them due to internal or host constraints, it should set truncated to 1 to inform the host that the image may be incomplete. Failure is indicated by returning the relevant PLUGIN_ERR_* code (these codes are defined in plugin.h).

The color-space is always sRGB. You are not required to perform any color matching except converting colors to sRGB if the file format uses another color-space.

The hwnd member being set to a valid handle (non-zero) is an indication to the plug-in that it is free to display a dialog box. Do not display a user interface of any sort if this member is zero. Device plugins that must show dialogs should interpret this as an error and return 0.

If the plug-in generates metadata (a.k.a. layer attachments), the metadata archive handle should be passed to the create() function via the meta_block parameter. If the create() succeeds, the host is responsible for freeing the memory handle, otherwise, the plug-in must free the handle. If the plugin doesn't know how to create an archive, it can pass the metadata entry by entry after calling create() by setting meta_data to the memory location of the data and calling the meta_write() function with the size and type of data, e.g. calling meta_write(data,"MARK",256) will create an attachment of type MARK and write 256 bytes of data into it from meta_data.

Please note that the metadata function pointers can be zero if the interface is not implemented or is disabled by the user. Also note that errors result in zero returns. The plug-in is expected to degrade gracefully in these circumstances.

These are the flags for the img_type and img_subtype members (this list is not exhaustive. See plugin.h for complete list):

PLUGIN_IMGTYPE_LAYERED 0x00000000
PLUGIN_IMGTYPE_MULTIRES 0x00000001
PLUGIN_IMGTYPE_ANIMATION

0x00000002

   
PLUGIN_IMGSUBTYPE_NORMAL

0x00000000

PLUGIN_IMGSUBTYPE_CLIPPED, PLUGIN_IMGSUBTYPE_MULTIRES, PLUGIN_IMGSUBTYPE_ONIONSKIN 0x00000001

The following may be used in combination for the options member (this list is not exhaustive. See layerdefs.h for complete list):

LAYER_BLEND_NORM /* Blend mode = Alpha blend */ 0x00000000
LAYER_BLEND_ADD /* Blend mode = Additive */ 0x00000001
LAYER_BLEND_SUB /* Blend mode = Subtractive */ 0x00000002
LAYER_BLEND_MUL /* Blend mode = Multiplicative */ 0x00000003
LAYER_BLEND_OVER /* Blend mode = Overlay */ 0x00000004
LAYER_BLEND_HUE /* Blend mode = Hue */ 0x00000005
LAYER_BLEND_CLR /* Blend mode = Chroma */ 0x00000006
LAYER_BLEND_LUM /* Blend mode = Luma */ 0x00000007
LAYER_BLEND_SCRN /* Blend mode = Screen */ 0x00000008
LAYER_BLEND_MASK /* Blend mode = Mask */ 0x00000009
LAYER_BLEND_DIV /* Blend mode = Divide */ 0x0000000a
LAYER_BLEND_DIFF /* Blend mode = Difference */ 0x0000000b
LAYER_BLEND_MIN /* Blend mode = Minimum */ 0x0000000c
LAYER_BLEND_MAX /* Blend mode = Maximum */ 0x0000000d
LAYER_BLEND_SAT /* Blend mode = Saturation */ 0x0000000e
     
LAYER_OPTION_HIDDEN /* Hidden layer */ 0x00000100
LAYER_OPTION_LOCKED /* Locked layer */ 0x00000200
LAYER_OPTION_EXCLUDED /* Excluded layer */ 0x00000400
LAYER_OPTION_PROTECT /* Alpha-protected layer */ 0x00000800
LAYER_OPTION_CLICKTHRU /* Click-thru layer */ 0x00001000
LAYER_OPTION_FLOATING /* Floating layer */ 0x00002000

 

The maximum allowed number of layers is application-dependent. If create() fails, your plug-in should abort decoding. Do not attempt to perform any memory management functions (like de-allocation or page-locking) on lp_pix.

 

Image Export via dev_SendImage()

Chasys Draw IES calls dev_SendImage with all the members set; i.e. width, height, pitch (in number of pixels, not bytes) and lp_pix are set to describe the bitmap, file to the save path, and hwnd to the parent window. Initially, flayerrame_count will be set to the number of layers in the image.

Initially, layer_count will be set to the number of layers in the image. If your plug-in does not support layers, or layer_count is greater than what your plug-in can handle, you should abort immediately by returning PLUGIN_ERR_NOT_FLAT. The host will then flatten the image for you and call flt_SaveImage again with the flattened image and a layer_count of 1.

int __cdecl dev_SendImage(dev_IMAGE_S* data);

struct dev_IMAGE_S

{

      unsigned long     width;

      unsigned long     height;

      unsigned long     pitch;

      unsigned long*    lp_pix;

//16

      HWND              hwnd;

      unsigned long     unused_1;

      int               (__cdecl* select)(dev_IMAGE_S* self,int layer_id);

      unsigned char     img_type;

      unsigned char     img_subtype;

      unsigned short    unused_2;

//32

      unsigned long     layer_count;

      short             x_pos;

      short             y_pos;

      wchar_t           name[32];

      unsigned short    options;

      unsigned short    frame_delay;

      unsigned char     group_id;

      unsigned char     transparency;

      unsigned char     unused_3[18];

//128

      unsigned char*    meta_data;

      int               (__cdecl* meta_read)(dev_IMAGE_S* self,char* type);

//136

      unsigned char     reserved_1[252-136];//do not touch

      unsigned long     timeout;

//256

      pi_STATESTORE*    pi_StateStore;

      pi_METAMARKUP*    pi_MetaMarkup;

      pi_BASICQUERY*    pi_BasicQuery;

      pi_BASICIMAGE*    pi_BasicImage;

      pi_BASICCOLOR*    pi_BasicColor;

      pi_BASICUTILS*    pi_BasicUtils;

//280

      unsigned char     reserved_x[1024-280];//do not touch

};

As usual, lp_pix is an array of 32 bit integers, each representing a pixel in BGRA format (blue LSB, alpha MSB), with alpha values of zero (0x00) for opaque and 255 (0xff) for transparent. It should not be altered by the plug-in in any way. The plug-in, if capable of storing alpha data, should check all pixels to determine whether or not the alpha values are used (i.e. some are non-zero). If the plug-in is capable of handling layered images, it should check the transparency value as well.

If the image has metadata, the meta_data parameter will be a non-zero metadata archive handle. The host owns this memory handle; the plug-in should not free or change it. If the plug-in doesn't know how to process a metadata archive, it can call the meta_read() function to load specific metadata elements into meta_data, e.g. calling meta_read(data,"MARK") will load the markup attachment if available. The function returns the size of the metadata or zero if the type is not found. Setting type to zero will load the entire metadata archive.

After the plug-in sends the current frame, it calls select() with the zero-based identifier of the next layer to retrieve it; the data for which is placed in the width, height, pitch and lp_pix members. This is repeated until all the frames have been sent. Please note that the select() member may be null if there's only one layer.

The img_type and options members have the same meanings are described above.

The plug-in should return the number of layers sent (greater than 0) if it succeeds. Failure is indicated by returning the relevant PLUGIN_ERR_* code (these codes are defined in plugin.h).

 

 

Copyright © John Paul Chacha, 2001-2017

The information herein is subject to change without any notice. The author makes no guarantees as to the completeness of this documentation.