#ifndef _IMG_IMG_H_ #define _IMG_IMG_H_ #ifndef _APRICOT_H_ #include #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; 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 */ } 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