SDK - Callback Suites - pi_BasicImage
Callback Overview
This callback suite provides the plug-in with basic image allocation and management functionality. These include allocation, deallocation, GDI interoperability, and blitting/blending.
Callback Interface Description
This interface represents an image as an instance of an object of type pibi_IMAGE. The interface itself is encapsulated in an object of type pi_BASICIMAGE. Both objects are defined in plugin.h.
#define PI_BASICIMAGE_VERSION 0x00020001 // 11 Nov 2025
struct pibi_IMAGE
{
unsigned long width;
unsigned long height;
unsigned long pitch;
unsigned long unused;
unsigned long* p_pix;
void* reserved; //do not touch
};
struct pibi_RECT
{
long x0;
long y0;
long x1;
long y1;
bool valid;
};
struct pibi_FILEINFO
{
HWND hwnd;
const wchar_t* file;
void* memfile_data;
unsigned long memfile_size;
const wchar_t* memfile_type_hint; // e.g. ".jpg"
void* metadata_ptr;
unsigned long metadata_size;
bool get_metadata;
bool is_known;
bool bad_host;
bool partial;
unsigned long reserved_0;
const wchar_t* config_str;
int (__cdecl* progress_func(int done,int total,void* priv);
void* progress_priv;
wchar_t* err_msg[256];
};
struct pibi_DOWNSAMPLE
{
pibi_IMAGE target;
unsigned long org_w;
unsigned long org_h;
unsigned long status;
void* reserved; //do not touch
};
struct pi_BASICIMAGE
{
unsigned long version;
unsigned long host_id;
//8
int (__cdecl* create)(pibi_IMAGE* img,int width,int height);
int (__cdecl* virtualize)(pibi_IMAGE* img,int width,int height,int pitch,
unsigned long* p_pix);
int (__cdecl* destroy)(pibi_IMAGE* img);
int (__cdecl* test)(pibi_IMAGE* img);
//24
int (__cdecl* lock)(pibi_IMAGE* img);
int (__cdecl* unlock)(pibi_IMAGE* img);
//32
HDC (__cdecl* gdi_getDC)(pibi_IMAGE* img);
int (__cdecl* gdi_freeDC)(pibi_IMAGE* img,HDC* hdc);
HBITMAP (__cdecl* gdi_makeHBMP)(pibi_IMAGE* img);
void* reserved_0; //do not touch
//48
int (__cdecl* set_clip_rect)(pibi_RECT* rect);
int (__cdecl* get_clip_rect)(pibi_RECT* rect);
void* reserved_1[2]; //do not touch
//64
int (__cdecl* load_file)(pibi_IMAGE* img,pibi_FILEINFO* info);
int (__cdecl* save_file)(pibi_IMAGE* img,pibi_FILEINFO* info);
int (__cdecl* load_resource)(pibi_IMAGE* img,HMODULE* hmod,LPCTSTR* res_id,bool alpha);
void* reserved_2; //do not touch
//80
int (__cdecl* copy)(pibi_IMAGE* img,pibi_IMAGE* src);
int (__cdecl* resize)(pibi_IMAGE* img,int width,int height);
int (__cdecl* flip)(pibi_IMAGE* img,unsigned long options);
int (__cdecl* rotate)(pibi_IMAGE* img,int direction);
//96
int (__cdecl* fill)(
pibi_IMAGE* img,int x0,int y0,int x1,int y1,
unsigned long color1,unsigned long color2,
unsigned long color3,unsigned long color4,
unsigned long options,int param1,int param2);
int (__cdecl* blit)(
pibi_IMAGE* dst,int dx0,int dy0,int dx1,int dy1,
pibi_IMAGE* src,int sx0,int sy0,int sx1,int sy1,
unsigned long options,unsigned long rop_param);
int (__cdecl* quad_blit)(
pibi_IMAGE* dst,int x0,int y0,int x1,int y1,int x2,int y2,int x3,int y3,
pibi_IMAGE* src,int sx0,int sy0,int sx1,int sy1,
unsigned long options,unsigned long rop_param);
int (__cdecl* blit_DC)(
HDC hdc,int dx0,int dy0,int dx1,int dy1,
pibi_IMAGE* src,int sx0,int sy0,int sx1,int sy1,
unsigned long options);
//112
int (__cdecl* translate)(
pibi_IMAGE* img,int x0,int y0,int x1,int y1,
const unsigned char *lut_r,const unsigned char *lut_g,
const unsigned char *lut_b,const unsigned char *lut_a,
unsigned long options,const void* param);
int (__cdecl* convolute)(
pibi_IMAGE* dst,int x0,int y0,int x1,int y1,
pibi_IMAGE* src,const double *matrix,int mat_cols,int mat_rows,
unsigned long mask,unsigned long options);
int (__cdecl* compare)(pibi_IMAGE* img1,pibi_IMAGE* img2,int limit,pibi_RECT *rt_diff);
void* reserved_3; //do not touch
//128
int (__cdecl* polar)(
pibi_IMAGE* dst,int x0,int y0,int x1,int y1,
pibi_IMAGE* src,int center_x,int center_y,
unsigned long options);
void* reserved_4[3]; //do not touch
//144
int (__cdecl* downsample_init)(pibi_DOWNSAMPLE* obj,pibi_IMAGE* dst,int org_w,int org_h,
unsigned long options);
int (__cdecl* downsample_push)(pibi_DOWNSAMPLE* obj,unsigned long p_scan);
int (__cdecl* downsample_exit)(pibi_DOWNSAMPLE* obj);
void* reserved_5; //do not touch
//160
int (__cdecl* convert_alpha)(pibi_IMAGE* img,unsigned long options);
unsigned long (__cdecl* get_highlighter)(pibi_IMAGE* img);
void* reserved_6[2]; //do not touch
//176
unsigned char reserved_x[1024-176]; //do not touch
};
//flags for the "options" parameter of ::blit()
#define PI_BI_BLIT_BLOCKY 0x00000000
#define PI_BI_BLIT_STRETCH 0x00000001
#define PI_BI_BLIT_MAXQUALITY 0x00000002
#define PI_BI_BLIT_ALPHABLEND 0x00000010
#define PI_BI_BLIT_RASTEROP 0x00000020
#define PI_BI_BLIT_CLIPAREA 0x00000040
#define PI_BI_BLIT_TILE_xxx 0x00030000
#define PI_BI_BLIT_TILE_NORMAL 0x00010000
#define PI_BI_BLIT_TILE_INVERT 0x00020000
#define PI_BI_BLIT_STRETCH_MAX_Q (PI_BI_BLIT_STRETCH|PI_BI_BLIT_MAXQUALITY)
//flags for the "options" parameter of ::flip()
#define PI_BI_FLIP_HORZ 0x00000001
#define PI_BI_FLIP_VERT 0x00000002
//flags for the "options" parameter of ::fill()
//also used for "rop_param" for ::blit(...,PI_BI_BLIT_RASTEROP)
#define PI_BI_FILL_SHAPE_xxx 0x0000000f
#define PI_BI_FILL_RECTANGLE 0x00000000
#define PI_BI_FILL_ELLIPSE 0x00000001
#define PI_BI_FILL_ROUNDRECT 0x00000002
#define PI_BI_FILL_ALPHABLEND 0x00000010
#define PI_BI_FILL_GRADIENT 0x00000020
#define PI_BI_FILL_CLIPAREA 0x00000040
#define PI_BI_FILL_RASTEROP_xxx 0x00ff0000
#define PI_BI_FILL_RASTEROP_NONE 0x00000000
#define PI_BI_FILL_RASTEROP_OR 0x00010000
#define PI_BI_FILL_RASTEROP_AND 0x00020000
#define PI_BI_FILL_RASTEROP_XOR 0x00030000
#define PI_BI_FILL_RASTEROP_ADD 0x00040000
#define PI_BI_FILL_RASTEROP_SUB 0x00050000
#define PI_BI_FILL_RASTEROP_INC 0x00060000
#define PI_BI_FILL_RASTEROP_DEC 0x00070000
#define PI_BI_FILL_RASTEROP_MUL 0x00080000
#define PI_BI_FILL_RASTEROP_DIV 0x00090000
#define PI_BI_FILL_RASTEROP_OFF 0x000a0000
#define PI_BI_FILL_RASTEROP_MIN 0x000b0000
#define PI_BI_FILL_RASTEROP_MAX 0x000c0000
#define PI_BI_FILL_RASTEROP_DIFF 0x000d0000
#define PI_BI_FILL_RASTEROP_OUT 0x000e0000
#define PI_BI_FILL_RASTEROP_TEX1 0x000f0000
#define PI_BI_FILL_RASTEROP_TEX2 0x00100000
#define PI_BI_FILL_RASTEROP_SCRN 0x00110000
#define PI_BI_FILL_RASTEROP_OVER 0x00120000
#define PI_BI_FILL_RASTEROP_DODG 0x00130000
#define PI_BI_FILL_RASTEROP_BURN 0x00140000
#define PI_BI_FILL_RASTEROP_LUM 0x00150000
#define PI_BI_FILL_RASTEROP_CLR 0x00160000
#define PI_BI_FILL_RASTEROP_HUE 0x00170000
#define PI_BI_FILL_RASTEROP_SAT 0x00180000
#define PI_BI_FILL_RASTEROP_VAL 0x00190000
#define PI_BI_FILL_RASTEROP_LIT 0x001a0000
#define PI_BI_FILL_RASTEROP_LMSK 0x007c0000
#define PI_BI_FILL_RASTEROP_MASK 0x007d0000
//flags for the "options" parameter of ::convert_alpha()
#define PI_BI_ALPHA_KEEP 0x00000000
#define PI_BI_ALPHA_REMOVE 0x00000001
#define PI_BI_ALPHA_INVERT 0x00000002 //invert
#define PI_BI_ALPHA_PREMULTIPLY 0x00000003 //invert then premultiply
#define PI_BI_ALPHA_UNMULTIPLY 0x00000004 //unmultiply then invert
#define PI_BI_POLAR_SET_TO_FF 0x00000005
//flags for the "options" parameter of ::polar()
#define PI_BI_POLAR_XY_TO_RQ 0x00000000
#define PI_BI_POLAR_RQ_TO_XY 0x00000001
#define PI_BI_POLAR_INVERT_RQ 0x00000002
#define PI_BI_POLAR_ACCURATE 0x00004000
//flags for the "options" parameter of ::downsample_init()
#define PI_BI_DNSAMP_OPT_INVERT 0x00000001
#define PI_BI_DNSAMP_OPT_MAX_Q 0x00000002
#define PI_BI_DNSAMP_OPT_DRAFT 0x00000004
//values for the "status" member of pibi_DOWNSAMPLE
#define PI_BI_DNSAMP_STATUS_OKAY 0x00000000
#define PI_BI_DNSAMP_STATUS_COMPLETE 0x00000001
#define PI_BI_DNSAMP_STATUS_BAD_PARAM 0x00000002
#define PI_BI_DNSAMP_STATUS_BAD_IMAGE 0x00000003
#define PI_BI_DNSAMP_STATUS_BAD_SOURCE 0x00000004
#define PI_BI_DNSAMP_STATUS_OUT_OF_MEM 0x00000005
create() creates a new image.
virtualize() creates a virtual image, basically one that encapsulates the provided parameters. This is useful for turning the image data returned from Chasys Photo into a pibi_IMAGE. For a code example, see the source-code for the NS Contrast plug-in.
destroy() destroys an image. Both real and virtual images have to be destroyed after use.
lock() prepares an image for direct access. unlock() undoes this.
gdi_getDC() returns a GDI-compatible HDC that can be used with all GDI functions. gdi_freeDC() frees this HDC and nulls out the variable; you must call this function before you start accessing the image data directly again.
set_clip_rect() sets up the clipping rectangle that will be applied in operations where the PI_BI_BLIT_CLIPAREA flag is used. get_clip_rect() retrieves this rectangle.
blit() allows you to do bitmap copies. You can also stretch/shrink the image and perform alpha-blending using this function, by setting the appropriate flags.
fill() allows you to do bitmap fills. You can also do basic shapes, gradients and perform alpha-blending and raster operations using this function, by setting the appropriate flags.
translate() takes look-up tables as its inputs and exchanges each existing pixel value with the corresponding value in the table. This is ideal for level-shifting, as would be needed for adjusting brightness. For a code example, see the source-code for the NS Contrast plug-in.
convolute() allows you to do spatial convolution using matrices (refered to in some texts as “filtering”). Useful for things like gaussian blur. Input matrix dimensions are restricted to the range 2x2 to 32x32.
compare() allows you to generate a difference rectangle - a rectangle containing the portion of one image that is different from the corresponding area in the other image. Useful for detecting similar frames (or areas in frames) in animations. Returns -1 if the images are exactly the same and marks the returned rectangle as invalid. A return of 0 indicates an error.
polar() allows you to convert an image from cartesian to polar coordinates and vice-versa. Returns 1 to indicate success.
load_file() allows you to load an image file into a pibi_IMAGE. Any file that can be loaded by Chasys Photo can be loaded by this function. This function returns a simple image; layered images are flattened and only the first frame of an animation is loaded. You have the option of using a memory buffer as the source instead of a file. In this case, the memfile_type_hint member of pibi_FILEINFO, if not null, specifies a string from which Chasys Photo can retrieve the file extension; this can either be the extension itself preceeded by a period (e.g. “.jpg”) or the full file name. Specifying the type hint allows Chasys Photo to guess which plug-in to use, thus avoiding the overhead associated with testing the data against all installed plug-ins.
If you ask for metadata, you must free metadata_ptr using GlobalFree().
save_file() allows you to save an image file contained in a pibi_IMAGE to a file. The format is determined by the file extension. Any file that can be saved by Chasys Photo can be saved by this function. This function returns a non-zero value if the image was saved successfully. You have the option of using a memory buffer as the destination instead of a file. In this case, the file member of pibi_FILEINFO must be null and the memfile_type_hint member must point to a string contasining a suitable file extension to serve as a hint for the file format to use, preceeded by a period (e.g. “.jpg”). Chasys Photo will then save the image to a temporary file then populate the contents of the file to the memfile_data member of pibi_FILEINFO and the size to the memfile_size member. The plug-in must use GlobalFree() to free this memory after use.
downsample_init() initializes the streaming downsampler, which resizes images that are too big to be handled through normal procedures (oversized images) by processing input data scanline by scanline. The paramater obj is an object of type pibi_DOWNSAMPLE which must be initialized to zero before use. The target image, which is a valid but blank image, is provided via img as a pibi_IMAGE object that must not be touched by any other means during the downsampling sequence. The parameters org_w and org_h are the original size of the image that will be downsamlped. This function returns a non-zero value if the downsampler was initialized successfully. If an error occurs, it returns zero and sets the relevant status flags within obj.
downsample_push() pushes one scanline from the original image to the downsampler. The downsampler will cache the scanline if it needs to, but the scanlines must be pushed in order from top to bottom or bottom to top. Output data will be generated from time to time during downsample_push() calls. This function returns a positive non-zero value if the scanline was processed successfully. If the end of the image had already been reached, the function will return a negative non-zero value to indicate overrun and set status to PI_BI_DNSAMP_STATUS_COMPLETE. If an error occurs, it returns zero and sets the relevant status flags within obj.
downsample_exit() finalizes all pending work and closes the downsampler. After this, the target pibi_IMAGE object will contain the final downsampled image. This function returns a non-zero value if the image was finalized successfully. If an error occurs, it returns zero and sets the relevant status flags within obj.
convert_alpha() converts the alpha channel as specified by the options parameter.
get_highlighter() retrieves a color that contrasts with the image that can be used as a highlighting color.
The following macros may be useful when using this interface:
//--------------------------------------------------------------------------------------------------
//Macro for converting pixels between ARGB and ABGR
#define plg_swap_rgb(c) ((c&0xff00ff00)|((c>>16)&0x000000ff)|((c<<16)&0x00ff0000))
//--------------------------------------------------------------------------------------------------
//Macro for restricting a value to a given set of limits
#define plg_limit_value(a,lo,hi) { if((a)<(lo)){a=(lo);} else if((a)>(hi)){a=(hi);} }
//--------------------------------------------------------------------------------------------------
//Macro for checking a value against a given set of limits
#define plg_not_in_range(a,lo,hi) ((a<(lo))||(a>(hi)))