IM: im_binfile.h Source File

IM - An Imaging Tool

im_binfile.h

Go to the documentation of this file.
00001 /** \file
00002  * \brief Binary File Access.
00003  *
00004  * See Copyright Notice in im_lib.h
00005  * $Id: im_binfile.h,v 1.4 2006/11/21 11:56:16 scuri Exp $
00006  */
00007 
00008 #include "im_util.h"
00009 
00010 #ifndef __IM_BINFILE_H
00011 #define __IM_BINFILE_H
00012 
00013 #if defined(__cplusplus)
00014 extern "C" {
00015 #endif
00016 
00017 
00018 /** \defgroup binfile Binary File Access 
00019  *
00020  * \par
00021  * These functions are very usefull for reading/writing binary files 
00022  * that have headers or data that have to be converted depending on 
00023  * the current CPU byte order. It can invert 2, 4 or 8 bytes numbers to/from little/big-endian orders.
00024  * \par
00025  * It will process the data only if the file format is diferent from the current CPU.
00026  * \par
00027  * Can read from disk or memory. In case of a memory buffer, the file name must be the \ref imBinMemoryFileName structure.
00028  * \par
00029  * See \ref im_binfile.h
00030  * \ingroup util */
00031 
00032 typedef struct _imBinFile imBinFile;
00033 
00034 /** Opens an existant binary file for reading.
00035  * The default file byte order is the CPU byte order.
00036  * Returns NULL if failed.
00037  * \ingroup binfile */
00038 imBinFile* imBinFileOpen(const char* pFileName);
00039 
00040 /** Creates a new binary file for writing.
00041  * The default file byte order is the CPU byte order.
00042  * Returns NULL if failed.
00043  * \ingroup binfile */
00044 imBinFile* imBinFileNew(const char* pFileName);
00045 
00046 /** Closes the file.
00047  * \ingroup binfile */
00048 void imBinFileClose(imBinFile* bfile);
00049 
00050 /** Indicates that was an error on the last operation.
00051  * \ingroup binfile */
00052 int imBinFileError(imBinFile* bfile);
00053 
00054 /** Returns the file size in bytes.
00055  * \ingroup binfile */
00056 unsigned long imBinFileSize(imBinFile* bfile);
00057 
00058 /** Changes the file byte order. Returns the old one.
00059  * \ingroup binfile */
00060 int imBinFileByteOrder(imBinFile* bfile, int pByteOrder);
00061 
00062 /** Reads an array of count values with byte sizes: 1, 2, 4, or 8. And invert the byte order if necessary after read.
00063  * \ingroup binfile */
00064 unsigned long imBinFileRead(imBinFile* bfile, void* pValues, unsigned long pCount, int pSizeOf);
00065 
00066 /** Writes an array of values with sizes: 1, 2, 4, or 8. And invert the byte order if necessary before write.\n
00067  * <b>ATENTION</b>: The function will not make a temporary copy of the values to invert the byte order.\n
00068  * So after the call the values will be invalid, if the file byte order is diferent from the CPU byte order. 
00069  * \ingroup binfile */
00070 unsigned long imBinFileWrite(imBinFile* bfile, void* pValues, unsigned long pCount, int pSizeOf);
00071 
00072 /** Writes a string without the NULL terminator. The function uses sprintf to compose the string. \n
00073  * The internal buffer is fixed at 4096 bytes.
00074  * \ingroup binfile */
00075 unsigned long imBinFilePrintf(imBinFile* bfile, char *format, ...);
00076 
00077 /** Moves the file pointer from the begining of the file.\n
00078  * When writing to a file seeking can go beyond the end of the file.
00079  * \ingroup binfile */
00080 void imBinFileSeekTo(imBinFile* bfile, unsigned long pOffset);
00081 
00082 /** Moves the file pointer from current position.\n
00083  * If the offset is a negative value the pointer moves backwards.
00084  * \ingroup binfile */
00085 void imBinFileSeekOffset(imBinFile* bfile, long pOffset);
00086 
00087 /** Moves the file pointer from the end of the file.\n
00088  * The offset is usually a negative value.
00089  * \ingroup binfile */
00090 void imBinFileSeekFrom(imBinFile* bfile, long pOffset);
00091 
00092 /** Returns the current offset position.
00093  * \ingroup binfile */
00094 unsigned long imBinFileTell(imBinFile* bfile);
00095 
00096 /** Indicates that the file pointer is at the end of the file.
00097  * \ingroup binfile */
00098 int imBinFileEndOfFile(imBinFile* bfile);
00099 
00100 /** Predefined I/O Modules.
00101  * \ingroup binfile */
00102 enum imBinFileModule  
00103 {               
00104   IM_RAWFILE,   /**< System dependent file I/O Rotines. */
00105   IM_STREAM,    /**< Standard Ansi C Stream I/O Rotines. */
00106   IM_MEMFILE,   /**< Uses a memory buffer. */
00107   IM_SUBFILE,   /**< It is a sub file. FileName is a imBinFile* pointer from any other module. */
00108   IM_FILEHANDLE,/**< System dependent file I/O Rotines, but FileName is a system file handle ("int" in UNIX and "HANDLE" in Windows). */
00109   IM_IOCUSTOM0  /**< Other registered modules starts from here. */
00110 };
00111 
00112 /** Sets the current I/O module.
00113  * \returns the previous function set, or -1 if failed.
00114  * See also \ref imBinFileModule.
00115  * \ingroup binfile */
00116 int imBinFileSetCurrentModule(int pModule);
00117 
00118 /** \brief Memory File I/O Filename
00119  *
00120  * \par
00121  *  Fake file name for the memory I/O module.
00122  * \ingroup binfile */
00123 typedef struct _imBinMemoryFileName
00124 {
00125   unsigned char *buffer; /**< The memory buffer. If you are reading the buffer must exists. 
00126                           *   If you are writing the buffer can be internally allocated to the given size. The buffer is never free.
00127                           *   The buffer is allocated using "malloc", and reallocated using "realloc". Use "free" to release it. 
00128                           *   To avoid RTL conflicts use the function imBinMemoryRelease. */
00129   int size;              /**< Size of the buffer. */ 
00130   float reallocate;      /**< Reallocate factor for the memory buffer when writing (size += reallocate*size). 
00131                           *   Set reallocate to 0 to disable reallozation, in this case buffer must not be NULL. */
00132 }imBinMemoryFileName;
00133                                              
00134 /** Release the internal memory allocated when writing a Memory File.
00135  * \ingroup binfile */
00136 void imBinMemoryRelease(unsigned char *buffer);
00137 
00138 
00139 #if defined(__cplusplus)
00140 }
00141 #endif
00142 
00143 
00144 #if defined(__cplusplus)
00145 
00146 /** Base class to help the creation of new modules.\n
00147  * It handles the read/write operations with byte order correction if necessary.
00148  * \ingroup binfile */
00149 class imBinFileBase
00150 {
00151   friend class imBinSubFile;
00152 
00153 protected:
00154   int IsNew,
00155       FileByteOrder,
00156       DoByteOrder;   // to speed up byte order checking
00157 
00158   // These will actually read/write the data
00159   virtual unsigned long ReadBuf(void* pValues, unsigned long pSize) = 0;
00160   virtual unsigned long WriteBuf(void* pValues, unsigned long pSize) = 0;
00161 
00162 public:
00163 
00164   int InitByteOrder(int ByteOrder)
00165   {
00166     int old_byte_order = this->FileByteOrder;
00167     this->FileByteOrder = ByteOrder;
00168     
00169     if (ByteOrder != imBinCPUByteOrder())
00170       this->DoByteOrder = 1;
00171     else
00172       this->DoByteOrder = 0;
00173     return old_byte_order;
00174   }
00175 
00176   // These will take care of byte swap if needed.
00177 
00178   unsigned long Read(void* pValues, unsigned long pCount, int pSizeOf)
00179   {
00180     unsigned long rSize = ReadBuf(pValues, pCount * pSizeOf);
00181     if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf);
00182     return rSize/pSizeOf;
00183   }
00184 
00185   unsigned long Write(void* pValues, unsigned long pCount, int pSizeOf)
00186   {
00187     if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf);
00188     return WriteBuf(pValues, pCount * pSizeOf)/pSizeOf;
00189   }
00190 
00191   virtual void Open(const char* pFileName) = 0;
00192   virtual void New(const char* pFileName) = 0;
00193   virtual void Close() = 0;
00194   virtual unsigned long FileSize() = 0;
00195   virtual int HasError() const = 0;
00196   virtual void SeekTo(unsigned long pOffset) = 0;
00197   virtual void SeekOffset(long pOffset) = 0;
00198   virtual void SeekFrom(long pOffset) = 0;
00199   virtual unsigned long Tell() const = 0;
00200   virtual int EndOfFile() const = 0;
00201 };
00202 
00203 /** File I/O module creation callback.
00204  * \ingroup binfile */
00205 typedef imBinFileBase* (*imBinFileNewFunc)();
00206 
00207 /** Register a user I/O module.\n
00208  * Returns the new function set id.\n
00209  * Accepts up to 10 modules.
00210  * \ingroup binfile */
00211 int imBinFileRegisterModule(imBinFileNewFunc pNewFunc);
00212 
00213 #endif
00214 
00215 #endif