⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readjnb.c

📁 图像处理的压缩算法
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------*
 * File Name:	readjnb.c														*
 * Creation:	GRD 8/7/2001													*
 * Purpose:		OriginC Source C file											*
 * Copyright (c) OriginLab Corp. 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008	*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:	GRD 2003.01.14 No new worksheet for Text+Binary			*
 *------------------------------------------------------------------------------*/
 
#include <origin.h>
#include "readjnb.h"

#define DATA_RECORD	1
#define NAME_RECORD	2
#define EOF_RECORD	134

#define	FILETYPE1	1
#define	FILETYPE2	2

#define	ERR1	1	// Could not open file.
#define ERR2	2	// File truncated.
#define ERR3	3	// This file type is unknown.
#define ERR4	4	// Failed to identify more records.
#define ERR5	5	// Failed to find records.

// The main function

int readjnb(String filename, String strWksName)
{
	file	fid;				// The file handle
	uint	iFileSize = 0;		// The file size
	uint	iFileType = 0;		// Type 1 or Type 2
	uint	iRecordType = 0;	// Record types allowed : Data, Name and EOF	

	uint	iBytesRead = 0;		// Generic, returns bytes read using file.Read()
	uint	iTemp = 0;			// Generic
	uint	iStatus = 0;		// Status/Error of import
	uint	iNumCols = 0;		// Number of Columns
	uint	iOffset = 0;		// Offset to next record

// Begin code
	if( fid.Open(filename, file::modeRead) )
	{
		// What size is the file
		iFileSize = fid.SeekToEnd();
		// Rewind
		fid.SeekToBegin();
		iBytesRead = fid.Read(&iTemp, sizeof(iTemp));
		fid.SeekToBegin();
		if((iTemp & 255) == 0)
		{
			// This is a worksheet file, start with the header
			iStatus = read_header(fid, &iFileType, &iNumCols, iFileSize);
			if(iStatus)
			{
				fid.Close();
				return iStatus;
			}
			// Locate the first record
			iStatus = seek_start(fid, iFileSize, &iOffset, &iRecordType);
			if(iStatus)
			{
				fid.Close();
				return iStatus;
			}
			// Process the records
			iStatus = read_file(fid, &iOffset, iFileSize, iFileType, &iRecordType);
			if(iStatus)
			{
				fid.Close();
				return iStatus;
			}
		}
		else
		{
			// This is a text file
			fid.Close();
			// No new worksheet for Text+Binary
			return 2;
			
			// In case I decide to handle these ...
			if((iTemp & 255) == 255)
			{
				// This is a long text file
				iTemp = (iTemp&16776960)/256;
				LT_execute("Type -a $OMRDJNB.Warnings.Text;");
			}
			else
			{
				// This is a short text file
				iTemp&255;
				LT_execute("Type -a $OMRDJNB.Warnings.Text;");
			}
		}
	}
	else
	{
		// Couldn't open the file
		iStatus = 1;
		printf("Error %u in %s:\n", iStatus, filename);
		LT_execute("Type -a $OMRDJNB.Errors.Err1;");
	}
	fid.Close();
	return iStatus;
}


// Header contains the File Type and the Number of Columns
int read_header(file &fid, uint *piFileType, uint *piNumCols, uint iFileSize)
{
	const int	cM0 = 360704;
	const int	cM1 = 28674;
	const int	cM2 = 8324;
	uint		iBytesRead = 0;
	uint		iValue = 0;
	uint		iJunk = 0;
	ushort		iShort = 0;
	uint		iPos = 0;
	uint		iOffset = 0;
	char		cFlag1 = 0;
	char		cFlag2 = 0;
	
	// Must read this value
	iBytesRead = fid.Read(&iValue, sizeof(iValue));	// 0x00 0x81 0x05 0x00
	if(cM0 != iValue)
	{
		printf("Error : 21\n");
		LT_execute("type -a $OMRDJNB.Errors.general;");
		return 21;
	}

	// True file size should match internal description
	iBytesRead = fid.Read(&iValue, sizeof(iValue));
	if(iFileSize != (iValue + 8)) LT_execute("type -a OMRDJNB.Warnings.warn1");

	// Must read this value
	iBytesRead = fid.Read(&iValue, sizeof(iValue));	// 0x02 0x70 0x00 0x00
	if(cM1 != iValue)
	{
		printf("Error : 22\n");
		LT_execute("type -a $OMRDJNB.Errors.general;");
		return 21;
	}

	// Skip over standard header stuff
	iBytesRead = fid.Read(&iOffset, sizeof(iOffset));
	iPos = fid.GetPosition();
	iPos += iOffset;
	fid.Seek(iPos, file::begin);

	// Must read this value
	iBytesRead = fid.Read(&iShort, sizeof(iShort));	// 0x84 0x20
	if(cM2 != iShort)
	{
		printf("Error : 23\n");
		LT_execute("type -a $OMRDJNB.Errors.general;");
		return 23;
	}

	// Establish file Type
	iBytesRead = fid.Read(&cFlag1, sizeof(cFlag1));
	iBytesRead = fid.Read(&cFlag2, sizeof(cFlag2));
	if(3 != cFlag1 && 5 != cFlag1)
	{
		printf("Error : 24\n");
		LT_execute("type -a $OMRDJNB.Errors.general;");
		return 24;
	}
	iBytesRead = fid.Read(&iValue, sizeof(iValue));
	if(8 != iValue && 16 != iValue)
	{
		printf("Error : 25\n");
		LT_execute("type -a $OMRDJNB.Errors.general;");
		return 25;
	}

	// Set the file Type and get the number of columns
	iBytesRead = fid.Read(&iJunk, sizeof(iJunk));
	if(8 == iValue)
	{
		*piFileType = FILETYPE1;
		iBytesRead = fid.Read(&iShort, sizeof(iShort));
		*piNumCols = (uint) iShort + 1;
		iBytesRead = fid.Read(&iShort, sizeof(iShort)); // maxRows0 - not needed
	}
	else
	{
		*piFileType = FILETYPE2;
		iBytesRead = fid.Read(&iJunk, sizeof(iJunk));
		iBytesRead = fid.Read(&iValue, sizeof(iValue));
		*piNumCols = iValue + 1;
		iBytesRead = fid.Read(&iValue, sizeof(iValue)); // maxRows0 - not needed
	}

	// Update the worksheet with the number of columns
	LT_set_var("ncols", *piNumCols);
	LT_execute("if(ncols > wks.ncols) wo -a $(ncols - wks.ncols);");
	// This 'short-circuits' the rest of the code if this is Type1 format
	// Return of 99 means use old SPW routine to read stream stored in TEMPfolder
	// When we have a routine that reads long double, we can eliminate this line
	if(*piFileType == 1) return 99; else return 0;
}


// Skip over unprocessed record types, establish current record type and offset to next record
int	seek_start(file &fid, uint iFileSize, uint *piOffset, uint *piRecordType)
{
	uint	iPos = 0;
	uint	iMax = 0;
	uint	iLoop = 0;
	uint	iBytesRead = 0;
	char	cChar[4];

	iPos = fid.GetPosition();
	iMax = iFileSize - 4;
	// An infinite loop
	for(iLoop = 0; iLoop == 0 && iPos < iMax; )
	{
		iBytesRead = fid.Read(&cChar, 4);
		*piRecordType = (int) cChar[0];
		if(1 == cChar[0] || 2 == cChar[0])
		{
			if(32 == cChar[1] && 5 == cChar[2] && 0 == cChar[3])
				iLoop = 1;
		}
		else
		{
			iPos +=1;
			fid.Seek(iPos, file::begin);
		}
	}	// End for loop
	if(!iLoop)
	{
		LT_execute("type -a $OMRDJNB.Warnings.eof;");
		return 31;
	}
	iBytesRead = fid.Read(&iLoop, sizeof(iLoop)); // this is the offset to the next record
	*piOffset = iLoop;
	return 0;
}


// Apologies for the long function. This was translated from LabTalk.
// Read the file records
int	read_file(file &fid, uint *piOffset, uint iFileSize, uint iFileType, uint *piRecordType)
{
	uint		iBytesRead = 0;
	uint		iValue = 0;
	uint		iPos = 0;
	uint		iLastPos = 0;
	uint		iStatus = 0;
	uint		iDone = 0;
	char		cChar = 0;
	uint		iThisCol =0;
	uint		iNumRows = 0;
	uint		iThisRow = 0;
	uint		iIgnore = 0;
	double		dBlockFlag = 0;
	string		sColName;	// this didn't work too well
	char		cBuffer[256];	// try this
	unsigned char		cTag = 0;
	double		dValue = 0;
	uint		iLength = 0;
	
	const uint	cM2 = 83914754;
	const uint	cM3 = 235085952;
	const uint	cM4 = 1253505;
	const uint	cM5 = 201662592;
	const uint	cM6 = 1253511;
	const uint	cM7 = 6;
	const uint	cM8 = 0;
	const uint	cM9 = 83914754;
	const uint	cM10 = 0;
	const uint	cM11 = 8322;
	const uint	cM12 = 16;
	const uint	cM13 = 204931;
	const uint	cM14 = 8;
	const uint	cM15 = 256;
	const uint	cM16 = 336003;
	const uint	cM17 = 16;

	// Set up an infinite loop with no third expression
	for(iDone = 0; iDone == 0; )
	{
		iLastPos = fid.GetPosition();
		switch(*piRecordType)
		{
			case DATA_RECORD:
				// Reading Data
				// Must read this value
				iBytesRead = fid.Read(&iValue, sizeof(iValue));	// 0x02 0x70 0x00 0x05
				if(cM2 != iValue)
				{
					printf("Error : 51\n");
					LT_execute("type -a $OMRDJNB.Errors.general;");
					return 51;
				}
				// Must read this value
				iBytesRead = fid.Read(&iValue, sizeof(iValue));	// 0x00 0x00 0x00 0x00
				if(cM8 != iValue)
				{
					printf("Error : 52\n");
					LT_execute("type -a $OMRDJNB.Errors.general;");
					return 52;
				}
				switch(iFileType)
				{
					case FILETYPE1:
						// This code does not handle Type1
						break;
					case FILETYPE2:
						// Must read this value
						iBytesRead = fid.Read(&iValue, sizeof(iValue));	// 0x80 0x20 0x05 0x0C
						if(cM5 != iValue)
						{
							printf("Error : 53\n");
							LT_execute("type -a $OMRDJNB.Errors.general;");
							return 53;
						}
						
						iBytesRead = fid.Read(&iThisCol, sizeof(iThisCol)); // indexed from zero
						
						// Must read this value
						iBytesRead = fid.Read(&iValue, sizeof(iValue));	// 0x87 0x20 0x13 0x00
						if(cM6 != iValue)
						{
							printf("Error : 54\n");
							LT_execute("type -a $OMRDJNB.Errors.general;");
							return 54;
						}
						iBytesRead = fid.Read(&iIgnore, sizeof(iIgnore));	// Ignore this
						

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -