/*---------------------------------------------------------
   ISIOManagers.h : part of the ImgSource library.
   
   Source and destination manager functions.

   See ImgSource.rtf for usage notes.

   This code copyright (c) 2000-2016, Smaller Animals Software, Inc..

   No portion of this code may be copied or distributed without 
   permission of Smaller Animals Software, Inc..
   http://www.smalleranimals.com

---------------------------------------------------------*/

#ifndef is6_SOURCEFILEIOH
#define is6_SOURCEFILEIOH

#if !defined is6_SOURCEH && !defined is6_INTERNAL
#error Need to include ISource.h before this file.
#endif

#ifdef __cplusplus
extern "C" {
#endif


////////////////////////////////////////////////////////
// Source open

/*---------------------------------------------------------
   is6_OpenFileSource / _is6_OpenFileSource

   Purpose : 
   Create a file source object.

    See is6_OpenFileSourceW, for wide-character filenames.

    Maximum size of the file is 2^32 bytes.

   Param                Use
   ------------------------------------
   pFileName            input file path

   Return
   ------
   NULL on failure, else a valid ImgSource source object.
   You must call is6_CloseSource to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISSRC         _ISCConv _ISFn( is6_OpenFileSource )(const char * pFileName);
                                                
/*---------------------------------------------------------
   is6_OpenFileSourceW / _is6_OpenFileSourceW

   Purpose : 
   Create a file source object, using a wide character filename.

   Maximum size of the file is 2^32 bytes.

   Param                Use
   ------------------------------------
   pFileNameW           input file path

   Return
   ------
   NULL on failure, else a valid ImgSource source object.
   You must call is6_CloseSource to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISSRC         _ISCConv _ISFn( is6_OpenFileSourceW )(const wchar_t * pFileNameW);

/*---------------------------------------------------------
   is6_OpenHandleSource / _is6_OpenHandleSource

   Purpose : 
   Create a source object using a Windows HANDLE.

   The HANDLE must already be opened and ready for reading.
   
   If you are using a HANDLE to a non-seeking device, such as a pipe 
   or a communications channel, some ImgSource file format reading 
   and writing operations may fail. Use ::GetFileType to determine 
   the HANDLE type, if unsure.

   Calling is6_CloseSource will not close the handle, that is left
   to the caller. But, you still need to call is6_CloseSource to
   release the ImgSource source object.

   Maximum size of the file is 2^32 bytes.

   Param                Use
   ------------------------------------
   handle               Windows HANDLE

   Return
   ------
   NULL on failure, else a valid ImgSource source object.
   
---------------------------------------------------------*/
_ISDeclSpec HISSRC         _ISCConv _ISFn( is6_OpenHandleSource )(HANDLE handle);

/*---------------------------------------------------------
   is6_OpenMemorySource / _is6_OpenMemorySource

   Purpose : 
   Create a memory-based source object.

   Maximum size of the memory buffer is 2^32 bytes.

   Param                Use
   ------------------------------------
   pInBuf               input buffer
   uBufLen              length of input buffer

   Return
   ------
   NULL on failure, else a valid ImgSource source object.
   You must call is6_CloseSource to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISSRC         _ISCConv _ISFn( is6_OpenMemorySource )(const BYTE *pInBuf, const UINT32 uBufLen);

/*---------------------------------------------------------
   is6_OpenUserSource / _is6_OpenUserSource

   Purpose : 
   Create a user-defined source object. Call this with
   pointers to caller-defined functions. 

   Maximum size of the file is 2^32 bytes.

   Param                Use
   ------------------------------------
   pOpenFn              source open function
                        called during is6_OpenUserSource
                           BOOL bOk = Open(uUserData);

   pReadFn              file read   
                           UINT32 uReadLen = Read(pBuffer, uNumBytes, uUserData);

   pSeekFn              file seek. not all formats use this (PCX, TIFF and TGA do)
                           BOOL bOK = Seek(uOffset, uOrigin, uUserData);

                        uOrigin is one of :
                           0: Set absolute position (always positive. treat as unsigned)
                           1: Offset from current position
                           2: From EOF. Offset is negative
                        

   pPosFn               get file position
                           BOOL ok = GetPos(uUserData, &uPos);

   pSizeFn              get file size
                           BOOL ok = GetSize(uUserData, &uSize);

   pEOFFn               is end of file
                           BOOL bEOF = EOF(uUserData);

   pCloseFn             source close
                           BOOL ok = Close(uUserData);
               
   uUserInfo            user-defined value. This will be
                        passed to all of the functions in this
                        ImgSource source object. The value can
                        be used to identify which source object is
                        being used, if you have multiple source
                        objects open.

   Return
   ------
   NULL on failure, else a valid ImgSource source object.
   You must call is6_CloseSource to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISSRC         _ISCConv _ISFn( is6_OpenUserSource )(const is6_SourceOpenFn pOpenFn,
                                  const is6_SourceReadFn pReadFn,
                                  const is6_SourceSeekFn pSeekFn,
                                  const is6_SourceGetPosFn pPosFn,
                                  const is6_SourceGetSizeFn pSizeFn,
                                  const is6_SourceEOFFn pEOFFn,
                                  const is6_SourceCloseFn pCloseFn,
                                  const IS_CALLBACK_DATA uUserInfo);

/*---------------------------------------------------------
   is6_CloseSource / _is6_CloseSource

   Purpose : 
   Close the source object.

   Param                Use
   ------------------------------------
   hSource              valid source manager

   Return
   ------
   Final position reached by the source data pointer. 
   Usually equal to the number of BYTEs read.
---------------------------------------------------------*/
_ISDeclSpec UINT32        _ISCConv _ISFn( is6_CloseSource )(HISSRC hSource);

/*---------------------------------------------------------
   is6_OpenFileDest / _is6_OpenFileDest

   Purpose : 
   Create a file destination object.

   See is6_OpenFileDestW, for wide-character filenames.

   Param             Use
   ------------------------------------
   pFileName         output file path

   bAppend           allow the destination object to be used in
                     operations that require appending to an existing
                     data stream.
   Return
   ------
   NULL on failure, else a valid ImgSource destination object.
   You must call is6_CloseDest to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISDEST         _ISCConv _ISFn( is6_OpenFileDest )(const char *pFileName, BOOL bAppend);

/*---------------------------------------------------------
   is6_OpenFileDestW / _is6_OpenFileDestW

   Purpose : 
   Create a file destination object, using a wide character filename.

   Maximum size of the file is 2^32 bytes.

   Param             Use
   ------------------------------------
   pFileNameW        output file path

   bAppend           allow the destination object to be used in
                     operations that require appending to an existing
                     data stream.
   Return
   ------
   NULL on failure, else a valid ImgSource destination object.
   You must call is6_CloseDest to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISDEST         _ISCConv _ISFn( is6_OpenFileDestW )(const wchar_t *pFileName, BOOL bAppend);

/*---------------------------------------------------------
   is6_OpenHandleDest / _is6_OpenHandleDest

   Purpose : 
   Create a file destination object using a Windows HANDLE.

   The HANDLE must be opened, positioned at the start of the
   file/stream and ready for writing.

   If you are using a HANDLE to a non-seeking device, such as a pipe 
   or a communications channel, some ImgSource file format reading 
   and writing operations may fail. Use ::GetFileType to determine 
   the HANDLE type, if unsure.

   Calling is6_CloseDest will not close the handle, that is left
   to the caller. But, you still need to call is6_CloseDest to
   release the ImgSource destination object.

   Maximum size of the file is 2^32 bytes.

   Param             Use
   ------------------------------------
   handle            opened Windows HANDLE

   bAppend           allow the destination object to be used in
                     operations that require appending to an existing
                     data stream.
   Return
   ------
   NULL on failure, else a valid ImgSource destination object.

---------------------------------------------------------*/
_ISDeclSpec HISDEST         _ISCConv _ISFn( is6_OpenHandleDest )(HANDLE handle, BOOL bAppend);

/*---------------------------------------------------------
   is6_OpenMemoryDest / _is6_OpenMemoryDest

   Purpose : 
   Create a memory destination object.

   Maximum size of the memory buffer is 2^32 bytes.

   Param             Use
   ------------------------------------
   pOutBuf           output buffer. allocated by called
   uBufLen           length of output buffer

   bAppend           allow the destination object to be used in
                     operations that require appending to an existing
                     data stream.

   Return
   ------
   NULL on failure, else a valid ImgSource destination object.
   You must call is6_CloseDest to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISDEST         _ISCConv _ISFn( is6_OpenMemoryDest )(BYTE *pOutBuf, const UINT32 uBufLen, BOOL bAppend);

/*---------------------------------------------------------
   is6_OpenDynamicMemoryDest / _is6_OpenDynamicMemoryDest

   Purpose : 
   Create a dynamic memory destination object. This object will
    increase its internal buffer size as you write to it.

    You can use this as an easy way to create in-memory image files:

        // 1. create the dest object
        HISDEST hDynMem = is6_OpenDynamicMemoryDest(0);

        // 2. use it in a file write
        is6_WriteJPG(hDynMem, ...);

        // 3. get the number of bytes written
        UINT32 size;
        is6_GetSize(hDynMem, &size);

        // 4. rewind the file to the beginning
        is6_Seek(hDynMem, 0, 0);

        // 5. read the contents to a memory buffer
        BYTE *pOutput = new BYTE[size];
        is6_Read(hDynMem, pOutput, size);

        // 6. done
        is6_CloseDest(hDynMem);

   Maximum size of the memory buffer is 2^32 bytes.

   Param             Use
   ------------------------------------
   bAppend           allow the destination object to be used in
                     operations that require appending to an existing
                     data stream.

   Return
   ------
   NULL on failure, else a valid ImgSource destination object.
   You must call is6_CloseDest to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISDEST         _ISCConv _ISFn( is6_OpenDynamicMemoryDest )(BOOL bAppend);

/*---------------------------------------------------------
   is6_OpenUserDest / _is6_OpenUserDest

   Purpose : 
   Create a user-defined destination object. Call this with
   pointers to caller-defined functions. 

   Maximum size of the file is 2^32 bytes.

   Param             Use
   ------------------------------------
   pOpenFn           source open function
                     called during is6_OpenUserDest!!
                        BOOL bOk = Open(uUserData);

   pWriteFn          file write
                        BOOL bOK = Write(pBuffer, uNumBytes, uUserData);

   pReadFn           file read. this is optional unless you are using
                        this dest object in a situation where both reading 
                        and writing are required (appending to a multi-page 
                        TIFF file, for example).

                        UINT32 uReadLen = Read(pBuffer, uNumBytes, uUserData);

   pSeekFn           file seek. not all formats use this (TIFF does)
                        BOOL bOK = Seek(uOffset, uOrigin, uUserData);
                        uOrigin is one of :
                           0: Set absolute position (always positive. treat as unsigned)
                           1: Offset from current position
                           2: From EOF. Offset is negative

   pPosFn            get file position
                        BOOL ok = GetPos(uUserData, &uPos);

   pSizeFn           get file size
                        BOOL ok = GetSize(uUserData, &uSize);

   pEOFFn            is end of file
                        BOOL bEOF = EOF(uUserData);

   pCloseFn          source close
                        BOOL ok = Close(uUserData);
         
   bAppend           allow the destination object to be used in
                     operations that require appending to an existing
                     data stream.

   uUserInfo         user-defined value. This will be
                     passed to all of the functions in this
                     ImgSource destination object. The value can
                     be used to identify which destination object is
                     being used, if you have multiple destination
                     objects open.

   Return
   ------
   NULL on failure, else a valid ImgSource destination object.
   You must call is6_CloseDest to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISDEST         _ISCConv _ISFn( is6_OpenUserDest )(const is6_SourceOpenFn pOpenFn,
                                  const is6_SourceWriteFn pWriteFn,
                                  const is6_SourceReadFn pReadFn,
                                  const is6_SourceSeekFn pSeekFn,
                                  const is6_SourceGetPosFn pPosFn,
                                  const is6_SourceGetSizeFn pSizeFn,
                                  const is6_SourceEOFFn pEOFFn,
                                  const is6_SourceCloseFn pCloseFn,
                                  BOOL bAppend,
                                  const IS_CALLBACK_DATA uUserInfo);

/*---------------------------------------------------------
   is6_OpenNullDest / _is6_OpenNullDest

   Purpose : 
   Create a Null destination object.

   A Null destination object discards all input but maintains 
   a file pointer, so you can see how many bytes would have 
   been written, without actually writing the data anywhere.

   This can be used to do file size calculations with most 
   formats, as it's much faster than actually writing the 
   file data.

   It can be used with any format, except for TIFF. 

   Example:

      HISDEST hDest = is6_OpenNullDest(0);
      is6_WriteJPG(hDest, pImage, w, h, ...);
      UINT32 uFileSize = is6_CloseDest(hDest);

      Now, without actually having created a file, you'll
      know how large that file would have been.

   Maximum size allowed is 2^32.

   Param             Use
   ------------------------------------

   uFlags            bit      purpose
                     ---      -------
                      0       if set, this will allow reads
                              to succeed - though all data 
                              returned will be zero. otherwise,
                              reads will simply fail.

   Return
   ------
   NULL on failure, else a valid ImgSource destination object.
   You must call is6_CloseDest to delete this object!
---------------------------------------------------------*/
_ISDeclSpec HISDEST         _ISCConv _ISFn( is6_OpenNullDest )(UINT32 uFlags);

/*---------------------------------------------------------
   is6_CloseDest / _is6_CloseDest

   Purpose : 
   Close the destination object. 

   Param               Use
   ------------------------------------
   hDest               valid dest manager

   Return
   ------
   Highest position reached by the destination data pointer.
   Usually equal to the number of BYTEs written.
---------------------------------------------------------*/
_ISDeclSpec UINT32        _ISCConv _ISFn( is6_CloseDest )(HISDEST hDest);

/*---------------------------------------------------------
   is6_Read / _is6_Read

   Purpose : 
   Read from the source manager object.

   This can be used for testing custom managers, or for
   providing extra functionality for your application.

   Param             Use
   ------------------------------------
   hSource           valid source manager
   pData             buffer to hold the data
   uDataLen          length of data to read

   Return
   ------
   The number of bytes read.
---------------------------------------------------------*/
_ISDeclSpec UINT32        _ISCConv _ISFn( is6_Read )(HANDLE hSource, BYTE * pData, const UINT32 uDataLen);

/*---------------------------------------------------------
   is6_Write / _is6_Write

   Purpose : 
   Write from a destination manager object.

   This can be used for testing custom managers, or for
   providing extra functionality for your application.

   Param             Use
   ------------------------------------
   hDest             valid destination manager
   pData             data to write
   uDataLen          length of data to write

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_Write )(HANDLE hSource, const BYTE * pData, const UINT32 uDataLen);

/*---------------------------------------------------------
   is6_Seek / _is6_Seek

   Purpose : 
   Set the file pointer.

   This can be used for testing custom managers, or for
   providing extra functionality for your application.

   This will fail, if you are using a HANDLE manager and 
   the HANDLE is to a non-seeking device, such as a pipe or
   a communications channel. Use ::GetFileType to determine 
   the HANDLE type, if unsure.

   Param               Use
   ------------------------------------
   hMgr              valid source or destination manager
   uOffset           offset bytes

   uOrigin           starting place for repositioning :
                     0: Set absolute position (uOffset >= 0)
                     1: Offset from current position 
                     2: From EOF. Offset is negative (uOffset <= 0)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_Seek )(HANDLE hMgr, __int32 uOffset, UINT32 uOrigin);

/*---------------------------------------------------------
   is6_GetPos / _is6_GetPos

   Purpose : 
   Return the file pointer.

   This can be used for testing custom managers, or for
   providing extra functionality for your application.

   This will fail, if you are using a HANDLE manager and 
   the HANDLE is to a non-seeking device, such as a pipe or
   a communications channel. Use ::GetFileType to determine 
   the HANDLE type, if unsure.

   Param             Use
   ------------------------------------
   hMgr              valid source or destination manager
   puPos             receives file position

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL        _ISCConv _ISFn( is6_GetPos )(HANDLE hMgr, UINT32 *puPos);

/*---------------------------------------------------------
   is6_GetSize / _is6_GetSize

   Purpose : 
   Return the size of the current file. 
   
   If this is used on a memory destination object, it 
   returns the highest position reached by a write 
   operation.

   This can be used for testing custom managers, or for
   providing extra functionality for your application.

   This will fail, if you are using a HANDLE manager and 
   the HANDLE is to a non-seeking device, such as a pipe or
   a communications channel. Use ::GetFileType to determine 
   the HANDLE type, if unsure.

   Param             Use
   ------------------------------------
   hMgr              valid source or destination manager
   puSize            The size of the current file.

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL        _ISCConv _ISFn( is6_GetSize )(HANDLE hMgr, UINT32 *puSize);

/*---------------------------------------------------------
   is6_EOF / _is6_EOF

   Purpose : 
   Test end of file condition

   This can be used for testing custom managers, or for
   providing extra functionality for your application.

   Param             Use
   ------------------------------------
   hMgr              valid source or destination manager

   Return
   ------
   TRUE if EOF
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_EOF )(HANDLE hMgr);

/*---------------------------------------------------------
   is6_IsValidManager / _is6_IsValidManager

   Purpose : 
   Test that the source / dest manager object is valid.

   Param             Use
   ------------------------------------
   hMgr              source or destination manager

   Return
   ------
   TRUE if valid
---------------------------------------------------------*/
_ISDeclSpec BOOL          _ISCConv _ISFn( is6_IsValidManager )(HANDLE hMgr);

/*---------------------------------------------------------
   is6_IsValidManagerNoErr / _is6_IsValidManagerNoErr

   Purpose : 
   Test that the source / dest manager object is valid,
   but do no set the global error value.

   Param             Use
   ------------------------------------
   hMgr              source or destination manager

   Return
   ------
   TRUE if valid
---------------------------------------------------------*/
_ISDeclSpec BOOL          _ISCConv _ISFn( is6_IsValidManagerNoErr )(HANDLE hMgr);


#ifdef __cplusplus
}
#endif

#endif