IM: im_binfile.h Source File
From 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.1 2005/04/02 22:07:00 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_IOCUSTOM0 /**< Other registered modules starts from here. */ 00109 }; 00110 00111 /** Sets the current I/O module. 00112 * \returns the previous function set, or -1 if failed. 00113 * \ingroup binfile */ 00114 int imBinFileSetCurrentModule(int pModule); 00115 00116 /** \brief Memory File I/O Filename 00117 * 00118 * \par 00119 * Fake file name for the memory I/O module. 00120 * \ingroup binfile */ 00121 typedef struct _imBinMemoryFileName 00122 { 00123 unsigned char *buffer; /**< The memory buffer. If you are reading the buffer must exists. 00124 * If you are writing the buffer can be internally allocated to the given size. The buffer is never free.*/ 00125 int size; /**< Size of the buffer. */ 00126 float reallocate; /**< Reallocate factor for the memory buffer when writing. size += reallocate*size. */ 00127 }imBinMemoryFileName; 00128 00129 00130 #if defined(__cplusplus) 00131 } 00132 #endif 00133 00134 00135 #if defined(__cplusplus) 00136 00137 /** Base class to help the creation of new modules.\n 00138 * It handles the read/write operations with byte order correction if necessary. 00139 * \ingroup binfile */ 00140 class imBinFileBase 00141 { 00142 friend class imBinSubFile; 00143 00144 protected: 00145 int IsNew, 00146 FileByteOrder, 00147 DoByteOrder; // to speed up byte order checking 00148 00149 // These will actually read/write the data 00150 virtual unsigned long ReadBuf(void* pValues, unsigned long pSize) = 0; 00151 virtual unsigned long WriteBuf(void* pValues, unsigned long pSize) = 0; 00152 00153 public: 00154 00155 int InitByteOrder(int ByteOrder) 00156 { 00157 int old_byte_order = this->FileByteOrder; 00158 this->FileByteOrder = ByteOrder; 00159 00160 if (ByteOrder != imBinCPUByteOrder()) 00161 this->DoByteOrder = 1; 00162 else 00163 this->DoByteOrder = 0; 00164 return old_byte_order; 00165 } 00166 00167 // These will take care of byte swap if needed. 00168 00169 unsigned long Read(void* pValues, unsigned long pCount, int pSizeOf) 00170 { 00171 unsigned long rSize = ReadBuf(pValues, pCount * pSizeOf); 00172 if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf); 00173 return rSize/pSizeOf; 00174 } 00175 00176 unsigned long Write(void* pValues, unsigned long pCount, int pSizeOf) 00177 { 00178 if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf); 00179 return WriteBuf(pValues, pCount * pSizeOf)/pSizeOf; 00180 } 00181 00182 virtual void Open(const char* pFileName) = 0; 00183 virtual void New(const char* pFileName) = 0; 00184 virtual void Close() = 0; 00185 virtual unsigned long FileSize() = 0; 00186 virtual int HasError() const = 0; 00187 virtual void SeekTo(unsigned long pOffset) = 0; 00188 virtual void SeekOffset(long pOffset) = 0; 00189 virtual void SeekFrom(long pOffset) = 0; 00190 virtual unsigned long Tell() const = 0; 00191 virtual int EndOfFile() const = 0; 00192 }; 00193 00194 /** File I/O module creation callback. 00195 * \ingroup binfile */ 00196 typedef imBinFileBase* (*imBinFileNewFunc)(); 00197 00198 /** Register a user I/O module.\n 00199 * Returns the new function set id.\n 00200 * Accepts up to 10 modules. 00201 * \ingroup binfile */ 00202 int imBinFileRegisterModule(imBinFileNewFunc pNewFunc); 00203 00204 #endif 00205 00206 #endif