Working with the RAW File Filter
The RAW File Filter can be used to load and save raw uncompressed data. The raw data can have
any offset in the file
any bits per pixel
any width/height
each line padded to 4 bytes
any view perspective
BGR or RGB color order
Loading a file with the RAW filter
Parameters for loading raw uncompressed data are set through the LBaseFile::LoadInfoCallBack. To do this you must override LBaseFile::LoadInfoCallBack function. When calling the file load functions (LFile::LoadFile, LFile::LoadBitmap, etc) , it is also necessary to pass a FILEINFO structure with the Format field set to FILE_RAW and the Flags field set to FILEINFO_FORMATVALID. This triggers your LBaseFile::LoadInfoCallBack function.
Inside the LBaseFile::LoadInfoCallBack, set the Format field to FILE_RAW. Valid values must be set for the following LOADINFO fields: Width, Height, BitsPerPixel, Offset (byte location in file where raw data begins). If each line of RAW data is padded so that the number of bytes is a multiple of 4 (as is the case with raw Windows BMP data), include LOADINFO_PAD4 in the Flags field. Include an orientation flag in the Flags field to load with the proper orientation. For example, raw Windows BMP data is stored with a BOTTOM_LEFT orientation. If the orientation is unknown, include the TOP_LEFT flag. If the raw data is 8 bits per pixel or less, then the image is palletized and a palette must be generated. If this is the case, include the LOADINFO_PALETTE flag, and fill in the first (2BitsPerPixel) entries of the rgbQuad field.
If the color order is ORDER_RGB then include this flag. If the ORDER_RGB flag is not included, the data will be loaded as ORDER_BGR.
Saving a file with the RAW filter
To save raw uncompressed data, an image must already be loaded into a LBitmapBase object. When saving raw uncompressed data, the raw data will be correspond to the width, height, bits per pixel, and color order, and view perspective of the image when it was loaded. For example, suppose a Window BMP file that is 300x400 24-bit color is loaded. If this file is saved as raw uncompressed data, the raw data is 24-bit, ORDER_BGR, with a view perspective BOTTOM_LEFT (the first bytes in the file correspond to the bottom-left of the image). The total size of the raw data file will be 300x400x3 = 360,000 bytes.
You can affect the way the raw data is saved by setting certain parameters in the SAVEFILEOPTION structure. A pointer to a SAVEFILEOPTION structure is an argument to all the file save Class Library functions (LFile::SaveFile, LFile::SaveBitmap, etc).
The bits in each byte can be reversed by including the ESO_REVERSEBITS flag in SAVEFILEOPTION.Flags. Each line of raw data can be padded so that the length is a multiple of four bytes by including the ESO_PAD4 flag in SAVEFILEOPTION.Flags. The raw data can be saved at any offset in the file by using the LFile::SaveOffset.
LEAD also supports saving Raw LZW data using the FILE_RAW_LZW file format constant when saving the data. Please note that when this option is used, the view perspective is ignored. The main purpose of this option is to provide support for saving LZW images that are embedded in other file formats such as PDF.
When using LFile::SaveFile to save RAW data that is 8 bits per pixel or less, it is necessary to pass the OPTIMIZED_PALETTE flag to disable any dithering prior to the save. Note that no palette information is saved in the RAW file. Consequently, after loading RAW data, it is necessary to supply a palette.(see Loading a file with the RAW filter above)
The following examples demonstrate how to load and save raw uncompressed data.
typedef struct tagRAWLOADDATA
{
L_INT nWidth; //width of image
L_INT nHeight; //height of image
L_INT nBitsPerPixel; //bits per pixel of image--if palettized, a gray palette is generated
L_INT nViewPerspective; //view perspective of raw data (TOP_LEFT, BOTTOM_LEFT, etc)
L_INT nOrder; //ORDER_RGB or ORDER_BGR
L_INT nOffset; //offset into file where raw data begins
L_INT bPadding; //TRUE if each line of data is padded to four bytes
L_INT bReverseBits; //TRUE if the bits of each byte are reversed
} RAWLOADDATA, L_FAR *LPRAWLOADDATA;
class LUserFile : public LFile
{
protected:
RAWLOADDATA m_RawData;
public:
void SetRawLoadData(LPRAWLOADDATA pRawData);
LUserFile();
~LUserFile();
L_INT LoadInfoCallBack(L_INT fd,pLOADINFO pInfo);
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
LUserFile::LUserFile()
{
ZeroMemory( &m_RawData, sizeof(RAWLOADDATA)) ;
}
LUserFile::~LUserFile()
{
}
void LUserFile::SetRawLoadData(LPRAWLOADDATA pRawData)
{
m_RawData.nWidth = pRawData->nWidth;
m_RawData.nHeight = pRawData->nHeight;
m_RawData.nBitsPerPixel = pRawData->nBitsPerPixel;
m_RawData.nViewPerspective = pRawData->nViewPerspective;
m_RawData.nOrder = pRawData->nOrder;
m_RawData.nOffset = pRawData->nOffset;
m_RawData.bPadding = pRawData->bPadding;
m_RawData.bReverseBits = pRawData->bReverseBits;
}
L_INT LUserFile::LoadInfoCallBack(L_INT fd,pLOADINFO pInfo)
{
UNREFERENCED_PARAMETER(fd);
pInfo->Format = FILE_RAW;
pInfo->Width = m_RawData.nWidth;
pInfo->Height = m_RawData.nHeight;
pInfo->BitsPerPixel = m_RawData.nBitsPerPixel;
pInfo->XResolution = 150;
pInfo->YResolution = 150;
pInfo->Offset = m_RawData.nOffset;
pInfo->Flags = 0;
if (m_RawData.bPadding)
pInfo->Flags |= LOADINFO_PAD4;
if (m_RawData.nOrder == ORDER_RGB)
pInfo->Flags |= LOADINFO_ORDERRGB;
if (m_RawData.bReverseBits)
pInfo->Flags |= LOADINFO_LSB;
switch(m_RawData.nViewPerspective)
{
case TOP_LEFT:
pInfo->Flags |= LOADINFO_TOPLEFT;
break;
case BOTTOM_LEFT:
pInfo->Flags |= LOADINFO_REVERSE;
break;
case TOP_RIGHT://BOTTOM_LEFT180
pInfo->Flags |= LOADINFO_BOTTOMLEFT180;
break;
case BOTTOM_RIGHT: //TOP_LEFT180
pInfo->Flags |= LOADINFO_TOPLEFT180;
break;
case RIGHT_TOP: //TOP_LEFT90
pInfo->Flags |= LOADINFO_TOPLEFT90;
break;
case LEFT_BOTTOM: //TOP_LEFT270
pInfo->Flags |= LOADINFO_TOPLEFT270;
break;
case LEFT_TOP: //BOTTOM_LEFT90
pInfo->Flags |= LOADINFO_BOTTOMLEFT90;
break;
case RIGHT_BOTTOM: //BOTTOM_LEFT270
pInfo->Flags |= LOADINFO_BOTTOMLEFT270;
break;
}
//if image is palettized create a grayscale palette
if ( pInfo->BitsPerPixel <= 8)
{
L_INT nColors, i;
nColors = 1 << pInfo->BitsPerPixel;
pInfo->Flags |= LOADINFO_PALETTE;
for (i=0; i<nColors; i++)
{
pInfo->rgbQuad[i].rgbBlue = (i * 256) / nColors;
pInfo->rgbQuad[i].rgbGreen = (i * 256) / nColors;
pInfo->rgbQuad[i].rgbRed = (i * 256) / nColors;
pInfo->rgbQuad[i].rgbReserved = 0;
}
}
return SUCCESS;
}
//This example loads RAW data into a LEAD LBitmapBase object.
//Raw data parameters are set in the overridden LUserFile::LoadInfoCallBack function,
//which gets called when the file format is FILE_RAW, or any unrecognized file format.
//The LUserFile::LoadInfoCallBack obtains information through a user-defined structure.
//In this example it is RAWLOADDATA
L_INT LoadRawData(L_TCHAR *pszFile, LBitmapBase* pLEADBitmap, LPRAWLOADDATA pRawData)
{
L_INT nRet = FALSE ;
FILEINFO fileInfo;
LUserFile file;
memset(&fileInfo, 0, sizeof(fileInfo));
fileInfo.uStructSize = sizeof(fileInfo);
fileInfo.Format = FILE_RAW;
fileInfo.Flags = FILEINFO_FORMATVALID;
file.SetBitmap(pLEADBitmap);
file.SetFileName(pszFile);
file.SetRawLoadData(pRawData);
file.EnableLoadInfoCallBack(TRUE);
nRet = file.LoadFile( 0, ORDER_BGR, LOADFILE_ALLOCATE | LOADFILE_STORE, NULL, &fileInfo);
file.EnableLoadInfoCallBack(FALSE);
return nRet;
}
//This example saves a LEAD LBitmapBase object as RAW data starting at offset uOffset.
//The data is padded so that each line of bytes is evenly divided by 4.
//The bits in each byte are reversed before saving.
//The bits per pixel of the raw data is the same as the bits per pixel of pLEADBitmap.
//If pLEADBitmap is a palettized image, the palette is not saved--only the raw data.
//The OPTIMIZED_PALETTE flag is used to disable dithering on images with 8 bits or pixel or less.
//Note that when saving a file as RAW data, the view perspective is ignored.
L_INT SaveRawData(L_TCHAR *pszFileName, LBitmapBase* pLEADBitmap,
L_UINT32 uOffset, LUserFile& file)
{
SAVEFILEOPTION SaveFileOption;
L_INT nRet;
memset(&SaveFileOption, 0, sizeof(SaveFileOption));
SaveFileOption.uStructSize = sizeof(SaveFileOption);
SaveFileOption.Flags = ESO_PAD4 | ESO_REVERSEBITS;
file.SetBitmap(pLEADBitmap);
file.SetFileName(pszFileName);
file.EnableCallBack(FALSE);
if (uOffset == 0)
{
nRet = file.SaveFile( FILE_RAW, 0, 0, SAVEFILE_OPTIMIZEDPALETTE, &SaveFileOption);
}
else
{
HFILE hFile;
L_INT32 SizeWritten;
#ifdef UNICODE
hFile = _wcreat(pszFileName, 0);
#else
hFile = _lcreat(pszFileName, 0);
#endif
nRet = file.SaveOffset(hFile, uOffset, &SizeWritten, FILE_RAW, 0, 0, SAVEFILE_OPTIMIZEDPALETTE, &SaveFileOption);
_lclose(hFile);
}
return nRet;
}
void CAnasDemoView::OnSettxtoptionsTxt()
{
LBitmapBase LEADBitmap;
LUserFile LeadFile;
//LoadRawData(TEXT("C:\\Raw Data.raw"), &LEADBitmap);
JBIG2OptionsExample();
LoadTXTFile( TEXT("C:\\txt.txt"), &LeadFile, 50,
50, 50, 50);
}