The Cloanto Personal Input/Output Library System December 12, 1996 - Personal I/O Libraries Version 5  For more information please send E-mail to ,  or visit our web site .  Introduction The Personal I/O Library System was designed by Cloanto to simplify the development of modular I/O code that could be shared by different applications. Cloanto programs like Personal Paint, Personal Fonts Maker 2 and ColorType use these libraries. A functional implementation of the Personal I/O Library System is divided in a library and a client part. The library part resides in the external I/O library, whereas the client part resides in the application (which is the "client" of the library). This documentation and the included skeleton and example source code files are library-centric, and explain how to write libraries compatible with different versions of clients. The library version described here remains always version 5. Libraries developed following these guidelines should have a version root number of "5", and a freely selectable revision number (5.0 to 5.999...) Each Personal I/O library can support one or more picture types. The number of picture types can be fixed or variable (i.e. defined at run time). The "SView" I/O library, for example, can handle zero or more picture types, based on the presence of "superview.library" (tested with version 11.7) and on the available "svobjects"). Further control is achieved by properly setting the library options. Within the library, each picture type can have its own options. They allow the client program to control some details of the loaded/saved data. The I/O libraries can handle file-based (e.g. ILBM, PNG, etc.), device-based (scanned, digitized, etc.) or rendered (e.g. fractal, random dot, etc.) images. The client program doesn't even know where a picture comes from or where it goes to: the I/O libraries hide the loading and saving details, while offering power and flexibility. The I/O libraries can selectively load or save certain pieces of information (e.g. a palette or an image mask, instead of the whole image). The Personal I/O interface and functions are a superset of other picture I/O systems (e.g. "DataType", "iffparse", "SView", "MultiPic", etc.): some "translator" I/O libraries are available and some others can easily be created. These libraries provide the foreign picture system's functionality via the Personal I/O interface. This documentation and the included source code files are aimed at developers of Personal I/O libraries version 5. No information is provided here about the client program side of the interface (as is integrated in Personal Paint, ColorType, etc.), nor about certain specific features and behaviors of I/O library versions prior to version 5. All versions of the I/O library specification are designed to remain usable by all versions of I/O library clients (except by client versions 1 and 2, which were used only to process files in limited formats, and never reached wide diffusion). I/O library clients, however, make use of additional information about the different library versions which is not included here. There are two known bugs ("SeekFile" section) affecting older versions of I/O library clients, in parts which are used mainly by more complex libraries. Since it has always been a policy of the I/O library specification to remain as compatible as possible both backwards and forwards, simple workarounds are described here for the two bugs. I/O libraries are requested to check the version of the client, and to act accordingly. Initialization and Picture Type Query The client program first searches for I/O libraries in its own "Libs" directory (e.g. "PPaint/Libs"), and then performs a new search in the system "LIBS:" path. If different versions of the same library are found in the two locations, the client automatically selects the newer library. Library names must match the "personal_#?_io.library" pattern and should use only lowercase characters. The client program opens each library conforming to the above specifications and queries it about the picture types supported. The functions involved are GetFirstDataInfo() and GetNextDataInfo(); the following is a typical client program's loop: for (ok = GetFirstDataInfo(dinfo); ok; ok = GetNextDataInfo(dinfo)) { /* The program here stores or somehow processes the DataInfo structure which describes a specific picture type. */ } Some I/O libraries may count on the fact that this loop calls GetNextDataInfo() until FALSE is returned to perform resource deallocation. A support library can be opened or some memory can be allocated by the GetFirstDataInfo() function, then GetNextDataInfo() keeps on using the resources until it has no more picture types to describe (the resources are deallocated and a FALSE code is returned). While I/O libraries and clients prior to version 4 use different types of authentication and handshaking on a case by case basis, from version 5 a simplified authentication mechanism is part of each picture type description (both in GetFirstDataInfo() and in GetNextDataInfo()): 1) A "Cloanto®" character string (case sensitive) must be part of the file containing the I/O library. 2) If the client is a version prior to 5, points 3) and 4) must be skipped by the I/O library. 3) The I/O library must check if the HandshakeText field of the DataInfo structure points to a "Cloanto®" string (case sensitive). If this is not the case, the library must abort the query phase. 4) The HandshakeText field must be changed to point to a "Cloanto®" string inside the library memory. If conditions 1) and 4) are not met, the client (or a future client) may abort the query phase. Use of the "Cloanto" registered trademark is subject to a license agreement, as explained in the dedicated section of this documentation. The DataInfo Structure The DataInfo structure identifies and describes a specific picture type within an I/O library. Picture types are local to the I/O library: there is no danger of accidentally duplicating picture type information (the Priority field being an exception) of other I/O libraries. DataInfo structures are used in several contexts: in the query phase (to describe the library's picture types), during a load operation (to force the loading of a specific type), during a save operation (to select the save format) and, in general, in every situation where a picture type must be specified. DataInfo fields Version  This is the client program interface version. Third parts I/O libraries should abort every operation based on a DataInfo with a Version less than 3. Code  The Code field identifies a library picture type. Any value can be used as a type code, as long as there are no duplicated codes within the library. The code 0xFFFFFFFF (DIC_ANYDATA) is reserved and is used in a load operation to allow every picture type to be loaded. Flags  This field describes the picture type characteristics: DIF_LOAD Planar (up to 256 colors) images can be loaded. DIF_LOAD_24 True color (16.7 million colors) images can be loaded. DIF_SAVE Planar (up to 256 colors) images can be saved. DIF_SAVE_24 True color (16.7 million colors) images can be saved. DIF_LOADFILE Pictures are loaded from file. The file data can be accessed through the client program's I/O functions (asynchronous, double buffered, speed optimized) or using the plain filing system (see DIF_CUSTOMIO). If this bit is not set, the picture data is rendered (e.g. fractal images) or otherwise acquired (e.g. scanner loader). DIF_SAVEFILE Pictures are saved to a file. The data can be written using the client program's I/O functions (asynchronous, double buffered, speed optimized) or the plain filing system (see DIF_CUSTOMIO). Writers of non-DIF_SAVEFILE libraries should read the "SeekFile" (PictureInfo structure field) section. DIF_RECOGNIZE The library can identify picture files based on this format. A DIF_RECOGNIZE type must be DIF_LOADFILE too, but not vice versa: the structure of some file types (e.g. raw data files) cannot be recognized. DIF_ENCRYPTED The file format is encrypted. The client program's encryption functions can be used to encrypt/decrypt the file. These functions hide the encryption mechanism used, which can be based on user specified keys or not. DIF_CUSTOMIO The client program is not allowed to perform any I/O operation on the file to be loaded or saved. When the flag is not set, the program opens the file, provides high-level, speed-optimized I/O functions to read and write data and, finally, closes the file. Writers of DIF_CUSTOMIO libraries should read the "SeekFile" (PictureInfo structure field) section. DIF_LOADOPTS A group of options is available to fine-tune the loading process. DIF_SAVEOPTS A group of options is available to fine-tune the saving process. DIF_SELFLOPT The library's user interface is used to set the load-options. The interface must be activated whenever the client program issues the command: "SetOption(dinfo, SOPT_SELFLOPT);". When the flag is not set, the client program's Option requester is used instead. DIF_SELFSOPT The library's user interface is used to set the save-options. The interface must be activated whenever the client program issues the command: "SetOption(dinfo, SOPT_SELFSOPT);". When the flag is not set, the client program's Option requester is used instead. DIF_CONVERTED The picture type is based on a "foreign" picture I/O system (e.g. "DataType", "SView", "MultiPic", etc.). This flag is checked by the client program to avoid possible deadlocks or endless loops if the Personal I/O library is being called, directly or indirectly, by one of the same foreign I/O systems which the I/O library itself, directly or indirectly, may try to access. In case of doubts about the use of this flag when a Personal I/O library uses another library, it is usually safe to set the flag. If it is absolutely certain that the foreign I/O system terminates the chain by, for example, getting all of its I/O data from a hardware device such as a scanner, then it is not necessary to set this flag. ProcessData  This field of bits states which information can be loaded/saved: PCDT_FORMAT Format information (image width, height and depth). PCDT_IMAGE Image bitmap. PCDT_MASK Stencil mask. PCDT_PALETTE Color palette. PCDT_PRJINFO Project information: author, copyright and annotation strings. PCDT_DPI Picture ratio: horizontal and vertical DPI (dots per inch). PCDT_DISPID Amiga display mode ID. PCDT_HANDLE Handle (or hot spot). Brush related information. PCDT_EDGES Left edge and top edge. Brush related information (coordinates where the brush was cut from). PCDT_SRCDIM Width and height of the source image. Brush related information (format of the image where the brush was cut from). PCDT_TRANSPT Transparency type. PCDT_TRANSPC Transparent color. Priority  This is the sort priority of the picture type. The priority affects the order in which the I/O libraries are queried to detect file type (low priority types are checked first) and the order in the client program's listboxes (low priority types are listed first). The picture types which share the same priority are sorted by name. The currently used priorities are: Format Priority Load Save Library -------------------------------------------------------------------------- IFF ILBM 100 Yes Yes personal_ilbm_io.library PNG 150 Yes Yes personal_png_io.library GIF 200 Yes Yes personal_gif_io.library Windows Bitmap 250 Yes Yes personal_bmp_io.library OS/2 Bitmap 251 Yes Yes personal_bmp_io.library PCX 300 Yes Yes personal_pcx_io.library IFF ACBM 350 Yes Yes personal_ilbm_io.library Encrypted 400 Yes Yes personal_gif_io.library PBM 450 Yes Yes personal_pbm_io.library JPEG 475 Yes No personal_jpeg_io.library Photo CD 487 Yes No personal_pcd_io.library Photo CD Overview 488 Yes No personal_pcd_io.library C Source 500 No Yes personal_csrc_io.library Raw Data 550 No Yes personal_raw_io.library ASCII 600 No Yes personal_ascii_io.library SV AUTOMATIC 9000 Yes No personal_sview_io.library SV ... 9001 ... ... personal_sview_io.library DataType 10000 Yes No personal_datatypes_io.library Plasma 10100 Yes No personal_plasma_io.library Scanner I/O 20000 Yes No personal_scanquix_io.library In general, DIF_CONVERTED types should be positioned after non-DIF_CONVERTED types and non-DIF_LOAD/SAVEFILE should follow file-based types. It is suggested to always keep some free entries between the priorities used by different libraries, and to register both the library name and its priorities with Cloanto. Additional information on the above libraries is available from Cloanto. Name  Full name of the picture type (up to 39 characters, 12 recommended). It is typically used in the progress requester (e.g. "Reading ... File") and in contexts where space is not an issue. ShortName  Short name of the picture type (up to 15 characters, 6 recommended). It is typically used in file requesters (file type selection listboxes) and in other situations where it is important to save space. FileSuffix  Up to three suffixes (15 characters maximum, including leading ".", case insensitive) generally used for file names based on this format (e.g. ".jpeg" and ".jpg" for the JPEG format). These fields are used to automatically detect the file type from a file name (e.g. in the system file requester, which lacks a format selection listbox). HandshakeText  Used by the authentication mechanism of the library query functions (GetFirstDataInfo() and GetNextDataInfo(), see above). This field is present in DataInfo structures having version 5 or greater. Options Query Just like each library can be queried about its picture types, each picture type can be queried about its options. The typical client program options loop resembles the picture type loop described above: for (ok = GetFirstOption(dinfo, dopt); ok; ok = GetNextOption(dinfo, dopt)) { /* The program here stores or somehow processes the DataOption structure. */ } There are several types of options: integer, fraction, boolean, depth values and strings. The options can be set (SetOption() function) before starting a load or a save operation; the assigned values remain valid until new values are assigned (they are stored in a copy of the library memory owned by the client program). The ResetOptions() function sets all the options of a given type back to their default values. The DataOption Structure An option is made up of a name, a value and other attributes describing its characteristics (needed to control the user interface input). DataOption Fields Version  This is the client program interface version. New I/O libraries should abort every operation based on a DataOption with a Version lower than 3. Type  It is the type of value stored in the option: DOT_INTSTR Integer value. The client program should use a string gadget to set this option. DOT_INTSLIDE Integer value. The client program should use a proportional gadget to set this option. DOT_10000STR Fractional value in integer form (10000=1.0, 15000=1.5, ...). The client program should use a string gadget to set this option and the values should be displayed in a fractional form (1.0, 1.5, ...). DOT_BOOL Boolean value (0/1). The client program should use a check box to set this option. DOT_STRING String (79 characters maximum). The client program should use a string gadget to set this option. DOT_COLSLIDE Number of bitplanes. The client program should use a proportional gadget to set this option and the value displayed should be expressed in number of colors (2 to the power of ). Name  The option's name (up to 39 characters, upper case recommended). It is used to identify the option (e.g. in SetOption() operations) and as a gadget label (client program's Option requester) when no UITextStr is given (see below). It should be as descriptive as possible. UITextStr  This field contains a user interface text code (see defines in "libraries/personal_io.h"): it defines the gadget label to be used in the client program's Option requester (the string displayed matches the language selected). When no predefined string is applicable, the code DOUI_NONE should be used (the option's name is used as a gadget label). Flags  When the DOF_LOADOPTION bit is set, the option can be used to control load operations. When the bit is not set, the option just affects picture saving. Value  The option's value (not for DOT_STRING options). Min, Max, Default  The option's minimum, maximum and default values (not for DOT_STRING options). String  The string of a DOT_STRING option (79 characters maximum). Loading a Picture When the GetPictureInfo() is called, the library must identify the picture file (DIF_LOADFILE libraries only) and provide image format information. When the DIF_CUSTOMIO bit is not set, the file has already been opened and its first 128 bytes have been stored in the FileHead field of the PictureInfo structure (GetPictureInfo()'s argument). When the first 128 bytes are not sufficient to identify the file type, further file analysis can be performed. When the file has been identified, it can be accessed to retrieve the picture format (size, depth, etc.) information. The GetPictureInfo() function overhead should be minimum. When the file has been identified, but retrieving the image format would require much more time, the function return code should be PIOERR_OK (file identified), but the PCDT_FORMAT bit of the ProcessedData field (PictureInfo structure) should not be set. The client program can now use the picture type information (e.g. a "Reading xxx File" requester is opened) and ask for the file analysis to be completed (GetPictureInfo() is called again). As mentioned above, when GetPictureInfo() is called for a non-DIF_LOADFILE picture type (e.g. a fractal image), no file recognition must be performed and just the image format must be provided. The format could be based on load-options (e.g. "WIDTH", "HEIGH" and "DEPTH") or on the format of the client program's image being replaced (the Width, Height and Depth fields of the PictureInfo structure are preloaded with this information). The user could, for example, define a "dummy" brush in the client program, then replace it by loading a fractal brush of the same size and same number of colors. The client's "AUTO" pseudo-loader submits the file being loaded to every DIF_RECOGNIZE library (in order of priority). When GetPictureInfo() does not recognize the file, a PIOERR_BADTYPE error code must be returned: the file will be submitted to the next library. Other codes are associated to other situations: the file has been identified (PIOERR_OK), the file is encrypted and the current encryption key is wrong (PIOERR_NODECRYP: in such a case, the client asks the user for a new key, then GetPictureInfo() is called again) or the file has been identified but some error occurred (e.g. PIOERR_FILE_ERR, when the file cannot be read). Once the format information is known, the client program allocates the needed resources (image bitmap, color palette, etc.) and passes them to the ReadPicture() function. The required file data (PCDT_XXX bits in the ProcessData field) is now read in the storage areas provided. The bitmap data can be organized in bitplanes (palette based images, chip memory storage) or in hybrid chunky format (true color, fast memory storage). The hybrid chunky format uses the first three planes of a bitmap to store, respectively, red, green and blue information. Each byte of a chunky plane describes a pixel color component. Many file formats store the image data in chunky format (even for palette based images). The PictureInfo structure gives access to powerful and fast "chunky to planar" functions, which can be used to store this kind of data in a standard (planar) bitmap. True color data, instead, must be manipulated directly (note: HAM image data must be converted to true color data). While reading a HAM or true color picture, the client program can display it in a "preview" screen: the original (unconverted HAM or true color) image data is fed to it, row by row. Some kind of save-options must be updated while the picture is being read. This is the case for some file attributes (e.g. progressive display, image compression, file subtype, etc.). After the picture has been read, the client program queries the I/O library about the save-options and stores a copy of these options. When the picture is saved again, the original format and the original options can be used. When ReadPicture() returns, the IOLibCleanup() function is called to release allocated resources (if any). This is done because the file recognition and the file reading phases can share such resources (opened libraries, temporary bitmaps, etc.). The IOLibCleanup() function is not called if just a simple file recognition has been performed (GetPictureInfo() has set the PCDT_FORMAT bit and returned PIOERR_OK) and no ReadPicture() command has been issued. Saving a Picture The saving process is much simpler than the loading process. Picture data and information is stored or referenced to in the PictureInfo structure, which is passed to the WritePicture() function. The client program may just want a few pieces of information to be written (e.g. palette saving). The ProcessData field describes which data should be saved. Progress Requester Information The GetProgressBumps() function gives information about the "time" required for the load and save operations to be completed. The value returned should be the number of BumpProgress() calls (see below) made by the ReadPicture() and WritePicture() functions (if zero, the operations won't be interruptible). The PictureInfo structure (function argument) can be used to adapt the bump value to the picture being load/saved (the value returned is usually equal to the picture height). The PictureInfo Structure A PictureInfo structure pointer is the only argument passed to the GetPictureInfo(), ReadPicture(), WritePicture() and GetProgressBumps() functions. The structure is used to store information, to reference storage areas, to pass library bases and to give access to the client's file or picture handling functions. PictureInfo Fields Version  This is the client program interface version. Third party I/O libraries should abort every operation based on a PictureInfo with a Version number smaller than 3. FileName  The field points to the name (including path) of the file being loaded or saved (DIF_LOADFILE and DIF_SAVEFILE picture types only). It can be used by DIF_CUSTOMIO libraries to open the picture file. FileHead  This array contains the first 128 bytes of the file to be identified (GetPictureInfo() function, non-DIF_CUSTOMIO types only). Data  This DataInfo structure identifies the library format to be used. Load operations (multiple-type libraries only): if the DataInfo Code is DIC_ANYDATA, any of the library file formats can be recognized/loaded, otherwise just Code-typed files can be loaded. Save operations (multiple-type libraries only): the DataInfo Code selects which file format should be used to save the picture. ProcessData  The PCDT_XXX bits (see above) select which pieces of information should be loaded/saved (the remaining data should be skipped/ignored). ProcessedData  The ReadPicture() and WritePicture() functions should set a PCDT_XXX bit in this field for every piece of information loaded/saved. In load operations, the PCDT_FORMAT bit must be set by GetPictureInfo() (see above). Flags, Parameters  Currently unused. User1, User2, User3  General-purpose pointers to library data extensions. These fields are ignored by client programs. Width, Height, Depth  Size of the picture being loaded/saved. Load operations: before calling GetPictureInfo(), the client program sets the fields to the format of the picture/brush being replaced. Some libraries (e.g. fractal loader) can use this information to load pictures based on the same format. These fields are associated to the PCDT_FORMAT bit. HandleX, HandleY  Picture handle (or hot spot), relative to the upper left image pixel. It is typically used in brush load/save operations. These fields are associated to the PCDT_HANDLE bit. HorizDPI, VertDPI  Picture ratio (in dots per inch units). These fields are associated to the PCDT_DPI bit. LeftEdge, TopEdge  Source picture coordinates where a brush was cut from. These fields are associated to the PCDT_EDGES bit. SourceWidth, SourceHeight  Source picture format (brush-related information). These fields are associated to the PCDT_SRCDIM bit. TranspType  One of the following transparency types (which match the IFF-ILBM masking types): BTR_NONE No transparency. All the image pixels should be considered opaque. BTR_CUSTOM The image data includes a transparency plane. BTR_TRANSPCOL A background color is defined. All the background-colored pixels are transparent. BTR_BACKFILL Only the background-colored areas which surround the image are set to be transparent. The TranspType field is associated to the PCDT_TRANSPT bit. TransparentColor  This is the background color index (used by BTR_TRANSPCOL and BTR_BACKFILL images). The field is associated to the PCDT_TRANSPC bit. DisplayID  An Amiga display mode ID (system include file "graphics/modeid.h"). The specified video mode (where available) should be used to display the image. The field is associated to the PCDT_DISPID bit. BMap  This field points to the image bitmap. Resource allocation, bitmap formats an data manipulation are discussed in the section "Loading a picture". The field is associated to the PCDT_IMAGE bit. MaskPlane  Transparency/stencil plane (BTR_CUSTOM images only). The plane shares the same BMap format (BytesPerRow, Rows, etc.). The field is associated to the PCDT_MASK bit. Palette  Points to an array of Color structures (array size = 1 << Depth), where image palette information is stored. struct Color { UBYTE Red, Green, Blue; /* color components */ UBYTE EFlag; /* unused: set to 0 */ }; The Red, Green and Blue range is 0..255 (white is 255,255,255, black is 0,0,0). EFlag is currently unused and should be set to 0. The field Palette is associated to the PCDT_PALETTE bit. ProjInfo  This field points to a ProjectInfo resource. The project information (author, copyright and annotation strings) can be accessed using the GetProjectInfo() and SetProjectInfo() functions (see below). Starting from version 4 of the library interface, there is no length limit for such strings. The field is associated to the PCDT_PRJINFO bit (note: even though this bit is set, one or more information strings can be empty: only non-empty string must be saved). PreviewDepth  GetPictureInfo() should set this field to 0 (no preview possible or desired), 6 or 8 (HAM-6 or HAM-8 preview screen) or 24 (true color preview screen), if a HAM or a 24-bit image is being loaded/inquired. The client program can disable the preview feature by setting this field back to 0 (e.g. video hardware unavailable, user deselection, etc.): the ReadPicture() function should only supply image preview rows (see below) when the PreviewDepth field is not 0. PreviewPalette  This field points to the color palette to be used for the HAM preview screen (typically 16 or 64 colors, for HAM-6 and HAM-8 respectively). Unlike other PictureInfo resources, the owner of the color array memory is the I/O library, which is responsible for allocating/deallocating the needed memory. PreviewDisplayID  This field describes the display mode to be used for the HAM preview screen. True color screen modes are selected at run-time (choice based on the hardware availability). UILanguage  This is the language code currently active in the client program: 00 = English 01 = German 02 = Italian 03 = French 04 = Spanish 05 = Dutch 06 = Swedish 07 = Danish 08 = Norwegian 09 = Finnish 10 = Portuguese 11 = Polish 12 = Hungarian 13 = Czech 14 = Slowak 15 = Slovenian 16 = Croatian 17 = Serbo-Croatian 18 = Lithuanian 19 = Latvian 20 = Welsh LibUIText  This field points to an array of string pointers. The texts referenced (localized to the client program's currently active language) are those associated to the DataOption UITextStr field (see defines in "libraries/personal_io.h"). SysBase, DOSBase, GfxBase, IntuitionBase, IconBase  System libraries. They can be directly used in conjunction with the compiler pragmas (see the included I/O library sample code). ReadFile  This field points to the function BOOL ReadFile (UBYTE *buffer, LONG bytes); It can be used to read a variable amount of data from the picture file, starting from the current file position (see SeekFile()). This and the following file I/O functions are only available to non-DIF_CUSTOMIO picture types. Arguments: buffer - area to read bytes into bytes - number of bytes to read Result: TRUE, if the transfer was fully successful, FALSE otherwise. WriteFile  This field points to the function BOOL WriteFile (UBYTE *buffer, LONG bytes); It can be used to write a variable amount of data to the picture file, at the current file position (see SeekFile()). Arguments: buffer - area to write bytes from bytes - number of bytes to write Result: TRUE, if the transfer was fully successful, FALSE otherwise. SeekFile  (multiple seeks from V5) This field points to the function LONG SeekFile (WORD mode, LONG bytes); SeekFile() sets/queries the read/write position of the picture file. Arguments: mode - SKF_ABSOLUTE: the position specified is an absolute file position SKF_FROMCURR: the position is relative to the current position bytes - position (can be negative, in conjunction with SKF_FROMCURR, to move backward in the file) Result: the previous absolute position in the file or -1, if an error occurred. Bugs: I/O library clients up to version 4 have a problem in the file caching system which produces erratic behavior when the I/O library requests a sequence of more than one seek from the client. A single seek is performed properly. Successive seeks are not. To ensure total compatibility with all versions of I/O clients, any library requiring complex seek functionality should access files directly, using AmigaDOS commands (this is what version 5.1 of the "personal_jpeg_io.library" does, for example). This bug was fixed at some time in version 4 of the client code, but it is not possible to determine the presence of the bug from the library side. The original Personal Paint 6.4 (Amiga Magic pack), for example, has this bug, whereas the version later published by Cloanto (with the anim-brush extensions) doesn't. This is not considered a serious bug, because a single seek is sufficient for most types of file format detection and access, and multiple seeks can be implemented using AmigaDOS rather than the library client. Due to a different bug in some client programs up to version 4, the function pointed to by SeekFile is called after WritePicture() operations (in order to flush the write buffer) even when it shouldn't (DIF_SAVEFILE or DIF_CUSTOMIO picture type saving). Before terminating such operations, the SeekFile field should be changed to point to a dummy, do-nothing function (within the library body), like the following: static LONG DummySeekFile(WORD mode, LONG bytes) { return(0); } This is a DIF_SAVEFILE/DIF_CUSTOMIO WritePicture() sample: __asm WORD __saveds WritePicture(register __a0 struct PictureInfo *picinfo) { ... if (picinfo->Version < 5) picinfo->SeekFile = DummySeekFile; return(...); } BumpProgress  This field may point to the function BOOL BumpProgress (void); Each time this function is called, the client program's progress bar advances (more in the section "Progress Requester Information"). The user break status is also checked. Result: TRUE, if the user pressed the progress requester Stop gadget, FALSE, otherwise Note: this field may be NULL (progress requester feature disabled). FastReadPix  This field points to the function UBYTE FastReadPix (struct BitMap *bmap, WORD x, WORD y); Planar bitmap access can often be quite slow. This function reads the color index at a given pixel position, using fast (buffered) techniques. The fastest performance is achieved by reading contiguous pixels. An initialization call must precede the reading, as in the following example: picinfo->FastReadPix(img_bmap, FBMP_INIT, 0); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { color = picinfo->FastReadPix(img_bmap, x, y); } } Arguments: bmap - bitmap to read from x - x coordinate or FBMP_INIT (read initialization) y - y coordinate Result: pixel color index (pen) FastWritePix  This field points to the function void FastWritePix (struct BitMap *bmap, WORD x, WORD y, UBYTE col); This is the counterpart of FastReadPix. The specified color index is stored in the given planar bitmap. The fastest performance is achieved by writing contiguous pixels. An initialization call must precede the writing and, before accessing a new row, a flush action must be performed, just like in the following example: picinfo->FastWritePix(img_bmap, FBMP_INIT, 0, 0); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { picinfo->FastWritePix(img_bmap, x, y, color_index); } picinfo->FastWritePix(img_bmap, FBMP_FLUSH, 0, 0); } Arguments: bmap - bitmap to write to x - x coordinate or FBMP_INIT (write initialization) or FBMP_FLUSH (row buffer flush) y - y coordinate col - pixel color index (pen) ChunkyToBMap  This field points to the function void ChunkyToBMap (UBYTE *pixbuf, struct BitMap *bmap, LONG offs); This low-level function is more efficient in writing to planar bitmaps than FastWritePix(). There are some restrictions in the number of pixels which can be written and their position. ChunkyToBMap() can only write exactly 32 pixel at a time, and their horizontal position must be word-aligned, like in the following example: if ((width & 31) == 0) { for (y = 0; y < height; y++) { offs = img_bmap->BytesPerRow * y; for (lw = width / 32; lw > 0; --lw, pixbuf += 32, offs += 4) { picinfo->ChunkyToBMap(pixbuf, img_bmap, offs); } } } Arguments: pixbuf - pointer to 32 color indexes bmap - bitmap to write to offs - offset in the plane memory (must be an even number) CommentToProjInfo  This field points to the function void CommentToProjInfo (UBYTE *buffer, struct ProjectInfo *pinfo); Some file formats do not provide for the separate storage of project information fields (author, copyright, annotation): two or more strings must be packed into a longer non-specific comment string. The string format is: "string <(c)>string string" where each piece of information is optional and may appear in any order. An unformatted string (not introduced by a code) is considered an annotation string. This function parses such strings and stores the information in a ProjectInfo resource. Arguments: buffer - pointer to a formatted/unformatted string pinfo - pointer to a ProjectInfo resource ProjInfoToComment  This field points to the function BOOL ProjInfoToComment (struct ProjectInfo *pinfo, UBYTE *buffer, WORD maxsize, BOOL do_auth, BOOL do_cpyr, BOOL do_note); The project information is translated into a formatted string (see CommentToProjInfo()). If the client program interface version is greater than 3, the ProjectInfoToComment() function should be used instead (by the client). Arguments: pinfo - pointer to a ProjectInfo structure buffer - destination string buffer maxsize - buffer size do_auth - if TRUE, the author string is included do_cpyr - if TRUE, the copyright string is included do_note - if TRUE, the annotation string is included Result: TRUE, if the information was successfully translated, FALSE otherwise (e.g. the supplied buffer was not big enough) CryptKeyChar  This field points to the function UBYTE CryptKeyChar (BOOL reset); Each time this function is called a new encryption character is returned. Such codes are based on a user specified encryption key and can be combined (e.g. XORed) with the image data being encrypted/decrypted. When the supplied argument is TRUE, the encryption character sequence is restarted. Arguments: reset - if FALSE, an encryption character is returned, if TRUE, the encryption character sequence is restarted Result: an encryption character CryptKeySign  This field points to the function WORD CryptKeySign (void); This function returns a 16 bit encryption signature, based on the user-specified encryption key. The signature can be stored in the first bytes of an encrypted file. When the file is read, the signature can be compared to the current signature: if they match, the key entered by the user is likely to be correct and the data can be successfully decrypted. Result: an encryption signature PreviewRow  This field points to the function void PreviewRow (struct BitMap *bmap, WORD y); When the client program's preview screen is opened (the PictureInfo PreviewDepth is not 0), HAM or 24-bit data can be transferred to it with this function. The image must be transferred row by row, from top to bottom. Arguments: bmap - HAM or true color bitmap (source) y - source bitmap row CreateBitMap  This field points to the function struct BitMap *CreateBitMap (WORD width, WORD height, UBYTE depth, UWORD flags); This function allocates and initializes a bitmap structure and the associated resources. Unles a specific memory type flag is specified (CB_ANYMEM, CB_FASTMEM or CB_CHIPMEM), the software allocates whatever type of memory is supported by the virtual blitter library currently in use (e.g. Agnus Blitter, 68K or PowerPC). Arguments: width - the bitmap width height - the bitmap height depth - the bitmap depth (1..8 / 24) flags - CB_CLEAR : clear all the bitplane memory to 0 CB_CLEAN : clear the unused (rightmost) bitplane memory to 0 CB_KEEPWB : do not use virtual memory or close the Workbench screen to collect enough memory for the bitmap CB_ANYMEM : use fast (preferred) or chip memory bitplanes (it is implicit for 24-bit bitmaps) CB_FASTMEM: use only fast memory for bitplanes CB_LONGW : force the bitmap's BytesPerRow to a multiple of 4. CB_CHIPMEM: use only chip memory for bitplanes Result: a bitmap pointer, if successful, NULL otherwise DeleteBitMap  This field points to the function void DeleteBitMap (struct BitMap *bmap); Free a bitmap structure and the allocated resources. Arguments: bmap - a bitmap created by CreateBitMap() GetProjectInfo  (V4) This field points to the function UBYTE *GetProjectInfo (struct ProjectInfo *pinfo, WORD type); Starting with version 4 of the library interface, the ProjectInfo structure cannot be accessed directly. This function selectively reads a string (returning a pointer to it) from the project information. Arguments: pinfo - pointer to a ProjectInfo resource type - piece of information to read: AUTHOR_INFO, COPYRIGHT_INFO or ANNOTATION_INFO Result: pointer to the desired string SetProjectInfo  (V4) This field points to the function BOOL SetProjectInfo (struct ProjectInfo *pinfo, WORD type, UBYTE *string); Starting with version 4 of the library interface, the ProjectInfo structure cannot be accessed directly. This function stores a string in the project information. Arguments: pinfo - pointer to a ProjectInfo resource type - piece of information to memorize: AUTHOR_INFO, COPYRIGHT_INFO or ANNOTATION_INFO string - the string to memorize Result: TRUE, if the string was successfully stored, FALSE otherwise (e.g. not enough memory) ProjectInfoToComment  (V4) This field points to the function BOOL ProjectInfoToComment (struct ProjectInfo *pinfo, UBYTE *buffer, WORD maxsize, ULONG do_flags); This is the V4 equivalent of ProjInfoToComment() (see above). Arguments: pinfo - pointer to a ProjectInfo structure buffer - destination string buffer maxsize - buffer size do_flags - a mix of the following flags: AUTHOR_INFOF (the author string is included) COPYRIGHT_INFOF (the copyright string is included) ANNOTATION_INFOF (the annotation string is included) Result: TRUE, if the information was successfully translated, FALSE otherwise (e.g. the supplied buffer was not big enough) Sample Library Code: The PBM Library The PBM library is a typical file loading/saving library. Both true color and planar bitmaps can be loaded (the true color preview mechanism is also used): standard code to write data in such bitmaps is included. The library can only save planar bitmaps: due to the PBM file structure, the bitmap data is automatically converted to true color, grayscale or monochrome data, before being written to the file. The PBM library source code is simple enough to be used as a base for a new file loading/saving library.  Sample Library Code: The SView Library [The author of the "SuperView" system kindly requested that this sample be removed from this distribution. As a replacement sample of a "universal" library code, we are including the Datatypes loader.] The SView library code is more complex than the PBM code. Many functions just deal with the SView library system, while others deal with specific Personal I/O features: splitted file recognition, picture types defined at run time, loading and saving of DIF_CONVERTED images, etc. As mentioned above, splitted recognition is a technique required in those contexts (SView, DataType, etc.) where the only way to get the picture format is actually loading it. In such cases, the format information is given in two steps: the first one (low overhead) provides the file type information, the picture size is retrieved in the second step (high overhead - image loading). Important: The SView I/O code was developed when the "SuperView" system and its complete documentation were freely distributable, and implementations (including commercial ones) of compatibility interfaces were actively and expressly encouraged by the Author. It now appears that this policy is being changed. We therefore recommend to carefully study the instructions included with newer versions of the "SuperView" system in order to ensure both technical and legal compliance. I/O Libraries Implementation: The Global Data Storage The Personal I/O libraries usually contain global data: picture type tables, type option settings, etc. Some information (e.g. the option settings) should be client based: when two client programs (e.g. PPaint and ColorType) open an I/O library and set their options, no access conflict nor data overwriting should affect the operations (each program might use different option settings). The typical Personal I/O library implementation is based on a special SAS/C feature which allows automatic creation of global data copies: each library client just acts on its own copy of the library data. The "LIB:libinitr.o" library initialization module provides this special mechanism: it must be included in the linking process (see "smakefile" in the source directory). Licensing Ever since the development of the first I/O libraries, at Cloanto we have taken a very "liberal" approach over the release and distribution of new and enhanced libraries. Now that the libraries are fully documented, and that any third party has the technical information to develop new libraries, we would like to retain certain rights over certain steps. In particular, we would like to be in agreement with developers about library names, version numbers, picture type priorities, and about the fact that the release of a new library is constructive for all parties involved. We care a lot about the quality of each new library, and about the consistency of the complete set of libraries. The only way in which we can release the complete documentation on the I/O libraries and at the same time retain some control over its use, is by maintaining the client/library handshaking mechanism documented here, which uses our registered trademark. In order to use and distribute a library compliant with this specification, the use of the handshaking procedure must be licensed. Non-commercial licenses are usually concluded at no charge to the developer. Copyright This documentation and the accompanying files are Copyright © 1994-1996 Cloanto Italia srl (Cloanto), unless otherwise indicated in the files or in the following notice. No part of this material may be reproduced, transmitted, transcribed, stored in a retrieval system, or translated into any language or computer language, in any form or by any means, optical, electronic, magnetic, biological, chemical, mechanical, acoustic, manual or otherwise without the prior written permission of Cloanto. Disclaimer and Limitation of Liability This documentation and the accompanying files are provided "as is", without warranty of any kind, either expressed or implied, statutory or otherwise. By using this material, you accept the entire risk as to its quality and performance. Neither Cloanto nor any other party involved in the creation, production or delivery of the documentation, software and data files shall be liable for any direct, indirect, special, consequential or incidental damages, including without limitation damages for loss of profits, loss of use or loss of anticipated costs, expenses or damages, and any data or information which may be lost or rendered inaccurate, even if Cloanto is advised of the possibility of such damages. Trademarks Cloanto and the Cloanto logo are registered trademarks, and ColorType, Personal Fonts Maker, PFM, Personal Paint, PPaint, Personal Write, PWrite, Personal Suite, PSuite and The Kara Collection are trademarks of Cloanto Italia srl. All other trademarks, property of their respective owners, are acknowledged.