📄 memfile.cpp
字号:
/*****************************************************************************
* RelayFax Open Source Project
* Copyright 1996-2004 Alt-N Technologies, Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the RelayFax Open
* Source License. A copy of this license is available in file LICENSE
* in the top-level directory of the distribution.
*
* RelayFax is a registered trademark of Alt-N Technologies, Ltd.
*
* Individual files and/or contributed packages may be copyright by
* other parties and subject to additional restrictions.
*****************************************************************************/
#include "stdafx.h"
#include "FaxFile.h"
#include "memfile.h"
#include "FaxAPI.h"
// static functions
CMemFile* mf_open();
unsigned int mf_lseek (thandle_t fd, unsigned int offset, int whence);
int mf_read (thandle_t fd, void *buf, int size);
int mf_write (thandle_t fd, void *buf, int size);
unsigned int mf_size (thandle_t fd);
int mf_map (thandle_t fd, void **addr, size_t *len);
void mf_unmap (thandle_t fd, void *addr, size_t len);
int mf_close (thandle_t fd);
// CMemFile - unnamed memory mapped file implementation
CMemFile::CMemFile() : m_buf(NULL), m_off(0), m_size(0), m_dataPtr(0), m_dataLen(0), m_dataMark(false)
{
m_hMapping = ::CreateFileMapping( INVALID_HANDLE_VALUE, // handle to file
NULL, // security
PAGE_READWRITE, // protection
0, // high-order DWORD of size
MaxSize, // low-order DWORD of size
NULL); // object name
if( m_hMapping != NULL )
{
m_buf = (unsigned char*)
MapViewOfFile( m_hMapping, // handle to file-mapping object
FILE_MAP_WRITE, // access mode
0, // high-order DWORD of offset
0, // low-order DWORD of offset
0); // number of bytes to map
}
}
CMemFile::~CMemFile()
{
// free the data pointer
if (m_buf != NULL)
{
UnmapViewOfFile(m_buf);
m_buf = NULL;
}
// remove the file mapping
if (m_hMapping != NULL)
{
CloseHandle(m_hMapping);
m_hMapping = NULL;
}
}
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
int CMemFile::ReadPage( TIFF* in, int nEncodeType )
{
uint32 g4opts = 0, g3opts = 0;
uint16 compression = COMPRESSION_NONE;
bool bDecode = true;
int n;
uint16 fillorder = 1;
m_off = 0;
m_size = 0;
if( TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) == 0 )
return 1;
if( compression == COMPRESSION_CCITTFAX3 )
{
TIFFGetField(in, TIFFTAG_GROUP3OPTIONS, &g3opts );
}
else if( compression == COMPRESSION_CCITTFAX4 )
{
TIFFGetField(in, TIFFTAG_GROUP4OPTIONS, &g4opts );
}
switch( nEncodeType )
{
case FAXAPI_ENC_CCITT_1D:
if( ( compression == COMPRESSION_CCITTFAX3 ) && (g3opts == 0) )
{
bDecode = false;
}
break;
case FAXAPI_ENC_CCITT_2D:
if( (compression == COMPRESSION_CCITTFAX3 ) && (g3opts == GROUP3OPT_2DENCODING) )
{
bDecode = false;
}
break;
case FAXAPI_ENC_CCITT_UNC:
if( compression == COMPRESSION_NONE )
{
bDecode = false;
}
break;
case FAXAPI_ENC_CCITT_T6:
if( (compression == COMPRESSION_CCITTFAX4 ) && (g4opts == 0) )
{
bDecode = false;
}
break;
}
if( TIFFGetField( in, TIFFTAG_FILLORDER, &fillorder) && fillorder != 1 )
{
bDecode = true;
}
if( bDecode )
{
TIFF* out = TIFFClientOpen( "memory file", "w", (thandle_t)this, mf_read, mf_write,
mf_lseek, mf_close, mf_size, mf_map, mf_unmap );
uint16 bitspersample;
uint32 width, length, rowsperstrip;
uint16 photometric;
uint16 config = PLANARCONFIG_CONTIG;
uint16 resunit = RESUNIT_INCH;
float xres = 204.0f, yres = 196.0f;
CopyField(TIFFTAG_IMAGEWIDTH, width);
CopyField(TIFFTAG_IMAGELENGTH, length);
CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
CopyField(TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField( out, TIFFTAG_FILLORDER, 1 );
CopyField(TIFFTAG_PLANARCONFIG, config);
CopyField(TIFFTAG_XRESOLUTION, xres );
CopyField(TIFFTAG_YRESOLUTION, yres );
CopyField(TIFFTAG_RESOLUTIONUNIT, resunit );
CopyField( TIFFTAG_ROWSPERSTRIP, rowsperstrip );
TIFFGetField(in, TIFFTAG_COMPRESSION, &compression);
if( compression == COMPRESSION_CCITTFAX3 )
{
n = TIFFGetField(in, TIFFTAG_GROUP3OPTIONS, &g3opts );
}
else if( compression == COMPRESSION_CCITTFAX4 )
{
TIFFGetField(in, TIFFTAG_GROUP4OPTIONS, &g4opts );
}
switch( nEncodeType )
{
case FAXAPI_ENC_CCITT_1D:
if( ( compression == COMPRESSION_CCITTFAX3 ) && (g3opts == 0) )
{
bDecode = false;
}
TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3);
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, 0 ); // 0 = 1D, 1 = 2D No byte-aligned EOLs
break;
case FAXAPI_ENC_CCITT_2D:
if( (compression == COMPRESSION_CCITTFAX3 ) && (g3opts == GROUP3OPT_2DENCODING) )
{
bDecode = false;
}
TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3);
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, GROUP3OPT_2DENCODING ); // No byte-aligned EOLs
break;
case FAXAPI_ENC_CCITT_UNC:
if( compression == COMPRESSION_NONE )
{
bDecode = false;
}
TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
break;
case FAXAPI_ENC_CCITT_T6:
if( (compression == COMPRESSION_CCITTFAX4 ) && (g4opts == 0) )
{
bDecode = false;
}
TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
TIFFSetField(out, TIFFTAG_GROUP4OPTIONS, 0 ); // 0 = data compressed
break;
}
tstrip_t s = 0;
tsize_t stripsize = TIFFStripSize(in);
tdata_t buf = _TIFFmalloc(stripsize);
if( TIFFReadEncodedStrip(in, s, buf, stripsize) == -1 )
{
_TIFFfree(buf);
TIFFClose( out );
return 2;
}
MarkDataPtr( true );
if( TIFFWriteEncodedStrip(out, s, buf, stripsize) == -1 )
{
_TIFFfree(buf);
TIFFClose( out );
return 3;
}
MarkDataPtr( false );
_TIFFfree(buf);
// n = TIFFWriteDirectory(out);
TIFFClose( out );
}
else
{
tstrip_t s = 0;
tsize_t stripsize = TIFFRawStripSize(in, s);
m_off = 0;
m_size = stripsize;
m_dataPtr = 0;
m_dataLen = stripsize;
if( TIFFReadRawStrip(in, s, m_buf, stripsize) == -1 )
return 4;
}
return 0;
}
CMemFile* mf_open(void)
{
return new CMemFile();
}
CMemFile* CheckHandle( thandle_t fd )
{
if( fd == 0 )
{
return NULL;
}
CMemFile* pFile = (CMemFile*)fd;
if( pFile->GetData(0) )
{
return pFile;
}
else
{
return NULL;
}
}
unsigned int mf_lseek (thandle_t fd, unsigned int offset, int whence)
{
CMemFile* pFile = CheckHandle( fd );
if( pFile == NULL )
return -1;
return pFile->Seek( offset, whence );
}
unsigned int CMemFile::Seek( unsigned int offset, int whence )
{
unsigned int ret = -1;
unsigned int test_off;
switch (whence)
{
case SEEK_SET:
if (offset > CMemFile::MaxSize)
{
ret = -1;
}
else
{
m_off = offset;
if( offset > m_size )
{
m_size = offset;
}
ret = offset;
}
break;
case SEEK_CUR:
test_off = m_off + offset;
if (test_off < 0)
{
ret = -1;
}
else
{
if (test_off > CMemFile::MaxSize)
{
ret = -1;
}
else
{
m_off = test_off;
ret = test_off;
}
}
break;
case SEEK_END:
test_off = m_size + offset;
if (test_off < 0)
{
ret = -1;
}
else
{
if (test_off > CMemFile::MaxSize)
{
ret = -1;
}
else
{
m_off = test_off;
ret = test_off;
}
}
break;
default:
ret = -1;
break;
}
return ret;
}
int mf_read (thandle_t fd, void *buf, int size)
{
CMemFile* pFile = CheckHandle( fd );
if( pFile == NULL )
return -1;
return pFile->Read( buf, size );
}
int CMemFile::Read( void* buf, int size )
{
if( m_off + size > m_size )
{
return -1;
}
memcpy( buf, m_buf + m_off, size );
m_off += size;
return size;
}
int mf_write (thandle_t fd, void *buf, int size)
{
CMemFile* pFile = CheckHandle( fd );
if( pFile == NULL )
return -1;
return pFile->Write( buf, size );
}
int CMemFile::Write( void* buf, int size )
{
if( m_off + size > CMemFile::MaxSize )
{
return -1;
}
if( m_dataMark )
{
if( m_dataPtr == 0 )
{
m_dataPtr = m_off;
}
m_dataLen += size;
}
memcpy( m_buf + m_off, buf, size );
if( m_off + size > m_size )
{
m_size = m_off + size;
}
m_off += size;
return size;
}
void CMemFile::AddDataByte( unsigned char b)
{
if( m_off < MaxSize)
{
m_buf[m_off] = b;
m_off++;
if( m_off > m_size )
{
m_size = m_off;
}
}
}
unsigned int mf_size (thandle_t fd)
{
CMemFile* pFile = CheckHandle( fd );
if( pFile == NULL )
return -1;
return pFile->Size();
}
int mf_map (thandle_t fd, void **addr, size_t *len)
{
// CMemFile* pFile = CheckHandle( fd );
// if( pFile == NULL )
// return -1;
return 0;
}
void mf_unmap (thandle_t fd, void *addr, size_t len)
{
// CMemFile* pFile = CheckHandle( fd );
// if( pFile == NULL )
// return;
}
int mf_close (thandle_t fd)
{
CMemFile* pFile = CheckHandle( fd );
if( pFile == NULL )
return -1;
return 0;
}
/*
void DebugOut( CMemFile* pFile, char* szOut )
{
FILE* fp = fopen( szOut, "wb" );
fwrite( pFile->m_buf, 1, pFile->m_size, fp );
fclose( fp );
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -