#ifndef _IMG_IMG_H_
#define _IMG_IMG_H_
#ifndef _APRICOT_H_
#include <apricot.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _ImgIORequest {
ssize_t (*read) ( void * handle, size_t busize, void * buffer);
ssize_t (*write) ( void * handle, size_t busize, void * buffer);
int (*seek) ( void * handle, long offset, int whence);
long (*tell) ( void * handle);
int (*flush) ( void * handle);
int (*error) ( void * handle);
void * handle;
} ImgIORequest, *PImgIORequest;
#define req_read(req,size,buf) ((req)->read(((req)->handle),(size),(buf)))
#define req_write(req,size,buf) ((req)->write(((req)->handle),(size),(buf)))
#define req_seek(req,offset,whence) ((req)->seek(((req)->handle),(offset),(whence)))
#define req_tell(req) ((req)->tell((req)->handle))
#define req_flush(req) ((req)->flush((req)->handle))
#define req_error(req) ((req)->error((req)->handle))
/* common data, request for a whole file load */
#define IMG_EVENTS_HEADER_READY 1
#define IMG_EVENTS_DATA_READY 2
typedef struct _ImgLoadFileInstance {
/* instance data, filled by core */
char * fileName;
PImgIORequest req;
Bool req_is_stdio;
int eventMask; /* IMG_EVENTS_XXX / if set, Image:: events are issued */
/* instance data, filled by open_load */
int frameCount; /* total frames in the file; can return -1 if unknown */
HV * fileProperties; /* specific file data */
void * instance; /* user instance */
Bool wasTruncated; /* if codec can recover from EOF */
/* user-specified data - applied to whole file */
Bool loadExtras;
Bool loadAll;
Bool noImageData;
Bool iconUnmask;
Bool noIncomplete;
Bool blending;
HV * extras; /* profile applied to all frames */
/* user-specified data - applied to every frame */
HV * profile; /* frame-specific profile, in */
HV * frameProperties; /* frame-specific properties, out */
int frame; /* request frame index */
Bool jointFrame; /* true, if last frame was a previous one */
Handle object; /* to be used by load */
/* internal variables */
int frameMapSize;
int * frameMap;
Bool stop;
char * errbuf; /* $! value */
/* scanline event progress */
unsigned int eventDelay; /* in milliseconds */
struct timeval lastEventTime;
int lastEventScanline;
int lastCachedScanline;
} ImgLoadFileInstance, *PImgLoadFileInstance;
/* common data, request for a whole file save */
typedef struct _ImgSaveFileInstance {
/* instance data, filled by core */
char * fileName;
PImgIORequest req;
Bool req_is_stdio;
Bool append; /* true if append, false if rewrite */
/* instance data, filled by open_save */
void * instance; /* result of open, user data for save session */
HV * extras; /* profile applied to whole save session */
/* user-specified data - applied to every frame */
int frame;
Handle object; /* to be used by save */
HV * objectExtras; /* extras supplied to image object */
/* internal variables */
int frameMapSize;
Handle * frameMap;
char * errbuf; /* $! value */
} ImgSaveFileInstance, *PImgSaveFileInstance;
#define IMG_LOAD_FROM_FILE 0x0000001
#define IMG_LOAD_FROM_STREAM 0x0000002
#define IMG_LOAD_MULTIFRAME 0x0000004
#define IMG_SAVE_TO_FILE 0x0000010
#define IMG_SAVE_TO_STREAM 0x0000020
#define IMG_SAVE_MULTIFRAME 0x0000040
#define IMG_SAVE_APPEND 0x0000080
/* codec info */
typedef struct _ImgCodecInfo {
char * name; /* DUFF codec */
char * vendor; /* Duff & Co. */
int versionMaj; /* 1 */
int versionMin; /* 0 */
char ** fileExtensions; /* duf, duff */
char * fileType; /* Dumb File Format */
char * fileShortType; /* DUFF */
char ** featuresSupported; /* duff-version 1, duff-rgb, duff-cmyk */
char * primaModule; /* Prima::ImgPlugins::duff.pm */
char * primaPackage; /* Prima::ImgPlugins::duff */
unsigned int IOFlags; /* IMG_XXX */
int * saveTypes; /* imMono, imBW ... 0 */
char ** loadOutput; /* hash keys reported by load */
char ** mime; /* image/duf, x-image/duff */
} ImgCodecInfo, *PImgCodecInfo;
struct ImgCodec;
struct ImgCodecVMT;
typedef struct ImgCodecVMT *PImgCodecVMT;
typedef struct ImgCodec *PImgCodec;
struct ImgCodec {
struct ImgCodecVMT * vmt;
PImgCodecInfo info;
void *instance;
void *initParam;
};
struct ImgCodecVMT {
int size;
void * (* init) ( PImgCodecInfo * info, void * param);
void (* done) ( PImgCodec instance);
HV * (* load_defaults) ( PImgCodec instance);
void (* load_check_in) ( PImgCodec instance, HV * system, HV * user);
void * (* open_load) ( PImgCodec instance, PImgLoadFileInstance fi);
Bool (* load) ( PImgCodec instance, PImgLoadFileInstance fi);
void (* close_load) ( PImgCodec instance, PImgLoadFileInstance fi);
HV * (* save_defaults) ( PImgCodec instance);
void (* save_check_in) ( PImgCodec instance, HV * system, HV * user);
void * (* open_save) ( PImgCodec instance, PImgSaveFileInstance fi);
Bool (* save) ( PImgCodec instance, PImgSaveFileInstance fi);
void (* close_save) ( PImgCodec instance, PImgSaveFileInstance fi);
};
extern List imgCodecs;
extern struct ImgCodecVMT CNullImgCodecVMT;
extern char * imgPVEmptySet[];
extern int imgIVEmptySet[];
extern void apc_img_init(void);
extern void apc_img_done(void);
extern Bool apc_img_register( PImgCodecVMT codec, void * initParam);
extern int apc_img_frame_count( char * fileName, PImgIORequest ioreq);
extern PList apc_img_load( Handle self, char * fileName, PImgIORequest ioreq, HV * profile, char * error);
extern int apc_img_save( Handle self, char * fileName, PImgIORequest ioreq, HV * profile, char * error);
extern void apc_img_codecs( PList result);
extern HV * apc_img_info2hash( PImgCodec c);
extern void apc_img_profile_add( HV * to, HV * from, HV * keys);
extern int apc_img_read_palette( PRGBColor palBuf, SV * palette, Bool triplets);
/* event macros */
#define SCANLINES_DIR_LEFT_TO_RIGHT 0
#define SCANLINES_DIR_RIGHT_TO_LEFT 1
#define SCANLINES_DIR_TOP_TO_BOTTOM 2
#define SCANLINES_DIR_BOTTOM_TO_TOP 3
extern void apc_img_notify_header_ready( PImgLoadFileInstance fi);
extern void apc_img_notify_scanlines_ready( PImgLoadFileInstance fi, int scanlines, int direction);
#define EVENT_HEADER_READY(fi) \
if ( fi-> eventMask & IMG_EVENTS_HEADER_READY) \
apc_img_notify_header_ready((fi))
#define EVENT_SCANLINES_RESET(fi) {\
(fi)-> lastEventScanline = (fi)-> lastCachedScanline = 0; \
gettimeofday( &(fi)-> lastEventTime, nil);\
}
#define EVENT_SCANLINES_READY(fi,scanlines,dir) \
if ( (fi)-> eventMask & IMG_EVENTS_DATA_READY) \
apc_img_notify_scanlines_ready((fi),scanlines,dir)
#define EVENT_SCANLINES_FINISHED(fi,dir) \
if ( (fi)-> eventMask & IMG_EVENTS_DATA_READY) {\
fi-> lastEventTime.tv_sec = fi-> lastEventTime.tv_usec = 0;\
apc_img_notify_scanlines_ready((fi),0,dir); \
}
#define EVENT_TOPDOWN_SCANLINES_READY(fi,scanlines) EVENT_SCANLINES_READY(fi,scanlines,SCANLINES_DIR_TOP_TO_BOTTOM)
#define EVENT_TOPDOWN_SCANLINES_FINISHED(fi) EVENT_SCANLINES_FINISHED(fi,SCANLINES_DIR_TOP_TO_BOTTOM)
#ifdef __cplusplus
}
#endif
#endif