<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>bitmap reader</title>
<style>
<!--
	table td.head{ 
		background-color: #3a6ba5;
		border: 1px #000000 solid;
		font-family: Verdana;
		font-weight: bold;
		font-size: 14px;
		color: #f79c19;
		padding: 6px;
	}

	table td.body{ 
		border-bottom: 1px #6699CC dotted;
		text-align: left;
		font-family: Verdana, sans-serif, Arial;
		font-weight: normal;
		font-size: 14px;
		color: #3A6BA5;
		background-color: #fafafa;
		padding: 6px;
	}
	
-->
</style>
</head>

<body>



<p align="left"><font size="6" color="#FF0000"><span lang="en-ca"><b>&nbsp; 
 
</b></span><b>&nbsp;&nbsp;&nbsp; <span lang="en-ca">&nbsp;&nbsp; </span></b></font>
<span lang="en-ca"><font size="6" color="#FF0000"><b>Reading Bitmap File and 
Draw it</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A. <span lang="en-ca">First </span>Edition</font></b></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>This is actually a practice for me to really understand 256color bitmap file and it is also a part of my searching for </b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>color index in OpenGL. Amazingly enough I cannot find a way to create &quot;color table&quot;  or palette. Of course there are many</b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>examples about creating palette with MS window GDI. But surely it is not what I expect. Finally I have to draw it with</b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>&quot;drawPixels&quot; with RGBA mode. This is a test and it is ugly. I really hesitate to post it in my archive <a href="http://tech.groups.yahoo.com/group/comp6231winter/files/My%20jpeg%20library/">like &quot;jpeg-reader&quot;</a></b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>which is simply a &quot;compiling project&quot;, pseudo-dll experiment on IJG source code. Anyway keeping the real face of history</b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>is part of my job. </b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
  <pre><span lang="en-ca"><b>In 256 color bitmap there are a color table or palette and bitmap image which is actually byte-index of color table.</b></span></pre>
	<pre><span lang="en-ca"><b>1. The file offset for &quot;image-data&quot; in BMPFILEHEADER(not exact name) is calculated from beginning of file. MSDN's </b></span></pre>
	<pre><span lang="en-ca"><b>explanation mis-guide me. Either his English writing skill or my English reading skill is poor (or both).    </b></span></pre>
	<pre><span lang="en-ca"><b>2. You must be careful to skip the &quot;padded&quot; garbage at each scan line. (This is clearly stated in documents and I simply</b></span></pre>
	<pre><span lang="en-ca"><b>don't get it at first. And I strongly believe many people make same repeat mistake like me. We are hopeless human.) In</b></span></pre>
	<pre><span lang="en-ca"><b>plain English, it means the &quot;width&quot; of pixel is not equal to &quot;width of image&quot; because it is padded with &quot;0&quot; to make it </b></span></pre>
	<pre><span lang="en-ca"><b>multiple times of 4. When reading, use paddedWidth=(pixelWidth+3)/4*4;</b></span></pre>
	<pre><span lang="en-ca"><b>3. Also there several irrelative issues here. First I find my OpenGL is not uptodate. I try to find the newest gl.h and</b></span></pre>
	<pre><span lang="en-ca"><b>cannot find in Google. Shame. Second, color table is not covered by many tutorials in web probably because they don't </b></span></pre>
	<pre><span lang="en-ca"><b>understand it at all. Third, &quot;glColorTable&quot; is treated as &quot;extension&quot; of OpenGL. And I link with &quot;glew32.dll&quot;, still I </b></span></pre>
	<pre><span lang="en-ca"><b>get access error. Strange.</b></span></pre>
	<p>
    
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></p>
	<p><b><span lang="en-ca"><font size="2">The idea is 
  truly intuitive. And as I explained above, this is purely for temporary as my 
	memory is very poor these days.</font></span></b></p></div>
<pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
<div align="left">
  <pre><span lang="en-ca"><b>.</b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">F</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>File listing</b></font></span></pre>
</div>
<div align="left">
  <pre><font size="3"><b><span lang="en-ca">1. bmpReader.cpp</span></b></font></pre>
</div>
<div align="left">
  <pre><font size="3"><b><span lang="en-ca">2. fileTool.cpp(utility tool)</span></b></font></pre>
</div>
<div align="left">
  <pre>กก</pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: bmpReader.cpp</b></font></span></pre>
</div>
<pre>#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include &lt;wingdi.h.&gt;
//#include &lt;GL/glew.h&gt;
#include &lt;GL/glut.h&gt;
//#include &quot;extsetup.h&quot;


#pragma comment(lib, &quot;glut32.lib&quot;)
#pragma comment(lib, &quot;opengl32.lib&quot;)

//#pragma comment(lib, &quot;glew32.lib&quot;)

char* fileName=&quot;input.bmp&quot;;

//const int ScreenWidth=800;
//const int ScreenHeight=600;

//typedef unsigned char myRGBQUAD[4];


struct BMP
{
	BITMAPINFO bitmapInfo;
	RGBQUAD* palette;
	unsigned char * bitmapImage;
};

BMP bmp;

bool loadBitmapFile256(char* fileName, BMP *bmp)
{
	FILE *filePtr; //our file pointer
	bool stop=true;
	int i;
	int temp;
	
	BITMAPFILEHEADER bitmapFileHeader; //our bitmap file header
	//RGBQUAD* result;
	//int imageIdx=0; //image index counter
	//unsigned char tempRGB; //our swap variable

	//open filename in read binary mode
	if ((filePtr = fopen(fileName,&quot;rb&quot;))==NULL)
	{
		return false;
	}

	//read the bitmap file header
	fread(&amp;bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1,filePtr);

	//verify that this is a bmp file by check bitmap id
	if (bitmapFileHeader.bfType !=0x4D42)
	{
		fclose(filePtr);
		return false;
	}

	//read the bitmap info header
	fread(&amp;(bmp-&gt;bitmapInfo.bmiHeader), sizeof(BITMAPINFOHEADER),1,filePtr);

	//move file point to the begging of bitmap data
	//fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
	//printf(&quot;bits offset is %d\n&quot;, bitmapFileHeader.bfOffBits);

	//allocate enough memory for the bitmap image data
	//bitmapImage = new unsigned char[pBitmapInfo-&gt;bmiHeader.biSizeImage];

	switch (bmp-&gt;bitmapInfo.bmiHeader.biBitCount)
	{
	case 0:
		printf(&quot;rgb\n&quot;);

		break;
	case 1:
		printf(&quot;monochrome\n&quot;);

		break;
	case 4:
		printf(&quot;16 color\n&quot;);
		break;

	case 8:
		printf(&quot;256 color\n&quot;);
		printf(&quot;height=%d, width=%d\n&quot;, bmp-&gt;bitmapInfo.bmiHeader.biHeight, 
			bmp-&gt;bitmapInfo.bmiHeader.biWidth);
		//pBitmapInfo-&gt;bmiColors=new 
			//RGBQUAD[pBitmapInfo-&gt;bmiHeader.biWidth*pBitmapInfo-&gt;bmiHeader.biHeight];
		printf(&quot;color used %d\n&quot;, bmp-&gt;bitmapInfo.bmiHeader.biClrUsed);
		printf(&quot;image size %d\n&quot;, bmp-&gt;bitmapInfo.bmiHeader.biSizeImage);
		stop=false;
		if (bmp-&gt;bitmapInfo.bmiHeader.biClrUsed==0)
		{
			bmp-&gt;bitmapInfo.bmiHeader.biClrUsed=256;
		}

		break;
	case 16:
		printf(&quot;16bit \n&quot;);
		break;
	case 24:
		printf(&quot;24bit\n&quot;);
		break;
	case 32:
		printf(&quot;32bit\n&quot;);

		break;
	}

	if (stop)
	{
		return false;
	}
	stop=true;
	switch (bmp-&gt;bitmapInfo.bmiHeader.biCompression)
	{
	case BI_RGB:
		printf(&quot;BI_RGB\n&quot;);
		stop=false;
		break;
	case BI_RLE8:
		printf(&quot;BI_RLE8\n&quot;);
		break;

	case BI_RLE4:
		printf(&quot;BI_RLE4\n&quot;);

		break;

	case BI_BITFIELDS:

		printf(&quot;BI_BITFIELDS\n&quot;);

		break;

	//case BI_JPEG:
	//	printf(&quot;BI_JPEG\n&quot;);

	//	break;
	}

	if (stop)
	{
		return false;
	}

	unsigned char ch;
	bmp-&gt;palette=new RGBQUAD[bmp-&gt;bitmapInfo.bmiHeader.biClrUsed];
	for (i=0; i&lt;256; i++)
	{
		
		if ((temp=fread(bmp-&gt;palette+i, sizeof(RGBQUAD), 1, filePtr))!=1)
		{
			printf(&quot;what is going on read %d and size %d\n&quot;, temp, 
				bmp-&gt;bitmapInfo.bmiHeader.biClrUsed*sizeof(RGBQUAD));
		}
		/*
		ch=bmp-&gt;palette[i].rgbBlue;
		bmp-&gt;palette[i].rgbBlue=bmp-&gt;palette[i].rgbRed;
		bmp-&gt;palette[i].rgbRed=ch;
		bmp-&gt;palette[i].rgbReserved=255;
		//bmp-&gt;palette[i].rgbGreen+=50;
		*/
		

		//bmp-&gt;palette[i].rgbBlue=255-bmp-&gt;palette[i].rgbBlue;
		//bmp-&gt;palette[i].rgbGreen=255-bmp-&gt;palette[i].rgbGreen;
		//bmp-&gt;palette[i].rgbRed=255-bmp-&gt;palette[i].rgbRed;
		//bmp-&gt;palette[i].rgbReserved=255;

	}

	//fread(bmp-&gt;palette, sizeof(RGBQUAD), bmp-&gt;bitmapInfo.bmiHeader.biClrUsed, filePtr);
	
	bmp-&gt;bitmapImage=new unsigned char[bmp-&gt;bitmapInfo.bmiHeader.biSizeImage];

	//printf(&quot;%d\n&quot;, sizeof(BITMAPFILEHEADER));

	fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);


	if ((temp=fread(bmp-&gt;bitmapImage, 1, bmp-&gt;bitmapInfo.bmiHeader.biSizeImage, filePtr))
		!=bmp-&gt;bitmapInfo.bmiHeader.biSizeImage)
	{
		printf(&quot;what is going on read %d and image is %d?\n&quot;, temp, 
			bmp-&gt;bitmapInfo.bmiHeader.biSizeImage);
	}


	 
	ch=160;
	RGBQUAD myColor={64, 128, 192, 255}; 	
	for ( i=0; i&lt;256; i++)
	{
		printf(&quot;[%d]:blue %d, green %d, red %d\n&quot;, i, bmp-&gt;palette[i].rgbBlue, bmp-&gt;palette[i].rgbGreen, 
			bmp-&gt;palette[i].rgbRed);
		
		if (memcmp(&amp;myColor, bmp-&gt;palette+i, sizeof(RGBQUAD))==0)
		{
			printf(&quot;\n*****************************************************\n&quot;);
			printf(&quot;find it\n&quot;);
			printf(&quot;\n*****************************************************\n&quot;);
		}
	}
	
	fclose(filePtr);
	return true;
}


void init()
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, bmp.bitmapInfo.bmiHeader.biWidth, 0, bmp.bitmapInfo.bmiHeader.biHeight, 0, 100);

	/*
	if (!SetupExtensionsFromString(&quot;GL_ARB_imaging&quot;))
	{
		printf(&quot;setup extension failed\n&quot;);
		exit(1);
	}
	*/
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	//glColorTable(GL_COLOR_TABLE, GL_RGBA, 256, GL_RGBA, GL_BYTE, bmp.palette);
}

void display()
{
	int paddedWidth;
	int index, width=bmp.bitmapInfo.bmiHeader.biWidth, height=bmp.bitmapInfo.bmiHeader.biHeight;
	glClearColor(255,255,255,255);
	glClear(GL_COLOR_BUFFER_BIT);

	//glEnableClientState(GL_COLOR_ARRAY);
	//glColorPointer(4, GL_BYTE, 0, bmp.palette);
	//glEnableClientState(GL_INDEX_ARRAY);
	//glIndexPointer(GL_UNSIGNED_BYTE, 0, bmp.bitmapImage);

	glRasterPos2f(0,0);

	paddedWidth=(bmp.bitmapInfo.bmiHeader.biWidth+3)/4*4;
	//glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
	//glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);


	for (int r=0; r&lt;height; r++)
	{
		for (int c=0; c&lt;width; c++)
		{
		
			glRasterPos2f(c,r);

			index=bmp.bitmapImage[r*paddedWidth+c];
			//printf(&quot;[%d,%d] %d\n&quot;, r, c, index);
			glDrawPixels(1, 1, GL_BGRA, GL_UNSIGNED_BYTE, &amp;bmp.palette[index]);
		}
	}

	//glDrawPixels(bmp.bitmapInfo.bmiHeader.biWidth, bmp.bitmapInfo.bmiHeader.biHeight,
	//	GL_COLOR_INDEX, GL_BYTE, bmp.bitmapImage);
	//glDrawElements(GL_POINTS, bmp.bitmapInfo.bmiHeader.biWidth*bmp.bitmapInfo.bmiHeader.biHeight, 
	//	GL_UNSIGNED_BYTE, bmp.bitmapImage);
		

	
	//glDrawPixels(bmp.bitmapInfo.bmiHeader.biWidth, bmp.bitmapInfo.bmiHeader.biHeight,
	//	GL_RGB, GL_BYTE, bmp.bitmapImage);
				

	glutSwapBuffers();
}


void keyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 27:
		exit(0);
	}
	glutPostRedisplay();
}

int main(int argc, char** argv)
{
	glutInit(&amp;argc, argv);
	if (!loadBitmapFile256(fileName, &amp;bmp))
	{
		return 0;
	}

	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_ALPHA);

	glutInitWindowPosition(0,0);
	glutInitWindowSize(bmp.bitmapInfo.bmiHeader.biWidth, bmp.bitmapInfo.bmiHeader.biHeight);
	glutCreateWindow(&quot;my test&quot;);

	glutDisplayFunc(display);

	glutKeyboardFunc(keyboard);

	init();


	glutMainLoop();


	return 0;
}</pre>
<pre>กก</pre>
<pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: fileTool.cpp</b></font></span></pre>
<pre>#define XMD_H 1
#define IMPORTJPGDLL 1
#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include &lt;vector&gt;
#include &lt;jpeglib.h&gt;

#pragma comment(lib, &quot;cjpeg.lib&quot;)
#pragma comment(lib, &quot;djpeg.lib&quot;)


using namespace std;



const int MY_MAX_PATH=MAX_PATH*4;

const int MaxFileCount=500;
char rootDir[MY_MAX_PATH];
char workDir[MY_MAX_PATH];
int rootDirLength=0;
int directoryCount=0;
int fileCount;
int recursionLevel=0;
vector&lt;string&gt; fileNameVector;

typedef void (*CallbackFunc)(char* dir, char* fileName);


void copyUpperLevel(char* dir, char* fileName)
{
	char oldFileName[MY_MAX_PATH];
	char newFileName[MY_MAX_PATH];
	sprintf(oldFileName, &quot;%s\\%s\\%s&quot;, rootDir, dir, fileName);
	sprintf(newFileName, &quot;%s\\%s&quot;, workDir, fileName);
	if (!MoveFile(oldFileName, newFileName))
	{
		printf(&quot;move %s to %s failed of %d\n&quot;, oldFileName, newFileName, 
			GetLastError());
	}
}

void convertJPG(char* dir, char* fileName)
{
	char oldFileName[MY_MAX_PATH];
	char newFileName[MY_MAX_PATH];
	
	char* ptr;

	if ((ptr=strrchr(fileName, '.'))!=NULL)
	{
		if (_stricmp(ptr, &quot;.jpg&quot;)!=0 &amp;&amp; _stricmp(ptr, &quot;.bmp&quot;)==0)
		{
			sprintf(oldFileName, &quot;%s\\%s\\%s&quot;, rootDir, dir, fileName);
			sprintf(newFileName, &quot;%s\\%s\\&quot;, rootDir, dir);
			strncat(newFileName, fileName, ptr-fileName);
			strcat(newFileName, &quot;.jpg&quot;);
			compressJPG(oldFileName, newFileName, 85);
			DeleteFile(oldFileName);
		}
	}
}

void CollapseAllSubTrees(char* dir, CallbackFunc callback, int level)
{
	HANDLE handle;	
	char curFileName[MY_MAX_PATH];
	char wildFileName[MY_MAX_PATH];
	
	WIN32_FIND_DATA ffd;
	
	sprintf(wildFileName, &quot;%s\\*.*&quot;, dir);
	handle=FindFirstFile(wildFileName, &amp;ffd);
	
	if (handle==INVALID_HANDLE_VALUE)
	{
		printf(&quot;findfirst failed of %s error code =%d\n&quot;, dir, GetLastError());
		exit(19);
	}

	while (FindNextFile(handle, &amp;ffd))
	{		
		if (strcmp(ffd.cFileName, &quot;..&quot;)!=0 &amp;&amp; strcmp(ffd.cFileName, &quot;.&quot;)!=0)
		{
			sprintf(curFileName, &quot;%s\\%s&quot;, dir, ffd.cFileName);
			if  ((GetFileAttributes(curFileName)&amp;FILE_ATTRIBUTE_DIRECTORY))
			{
				CollapseAllSubTrees(curFileName, callback, level+1);
			}
			else
			{
				if (level&gt;0)
				{
					callback(dir, ffd.cFileName);
				}
			}
		}			
	}
	FindClose(handle);
}

void GenericRetrieveAllFile(char* dir, CallbackFunc callback, int stopLevel)
{
	HANDLE handle;	
	char curFileName[MY_MAX_PATH];
	char wildFileName[MY_MAX_PATH];
	
	WIN32_FIND_DATA ffd;
	
	if (recursionLevel&gt;stopLevel)
	{
		return;
	}

	sprintf(wildFileName, &quot;%s\\*.*&quot;, dir);
	handle=FindFirstFile(wildFileName, &amp;ffd);
	
	if (handle==INVALID_HANDLE_VALUE)
	{
		printf(&quot;findfirst failed of %s error code =%d\n&quot;, dir, GetLastError());
		exit(19);
	}

	while (FindNextFile(handle, &amp;ffd))
	{		
		if (strcmp(ffd.cFileName, &quot;..&quot;)!=0 &amp;&amp; strcmp(ffd.cFileName, &quot;.&quot;)!=0)
		{
			sprintf(curFileName, &quot;%s\\%s&quot;, dir, ffd.cFileName);
			if  ((GetFileAttributes(curFileName)&amp;FILE_ATTRIBUTE_DIRECTORY))
			{
				recursionLevel++;
				GenericRetrieveAllFile(curFileName, callback, stopLevel);
				recursionLevel--;
			}
			else
			{
				callback(dir, ffd.cFileName);
			}
		}			
	}
	FindClose(handle);
}



void groupFile(char* dir, char* fileName)
{
	char oldFileName[MY_MAX_PATH];
	int oldDirLength, newDirLength;
	if (fileCount&lt;MaxFileCount)
	{
		//sprintf(oldFileName, &quot;%s\\%s&quot;, dir, fileName);
		fileNameVector.push_back(string(fileName));
		fileCount++;
	}
	else
	{		
		sprintf(oldFileName, &quot;%s\\%s\\&quot;, rootDir, dir);
		oldDirLength=strlen(oldFileName);
		sprintf(rootDir+rootDirLength, &quot;\\%s\\%s%d\\&quot;, dir, &quot;pretty women&quot;, directoryCount);
		newDirLength=strlen(rootDir);
		if (!CreateDirectory(rootDir, NULL))
		{
			printf(&quot;error of create directory %d\n&quot;, GetLastError());
		}
		else
		{
			for (int i=0; i&lt;fileNameVector.size(); i++)
			{
				strcpy(oldFileName+oldDirLength, fileNameVector[i].c_str());
				strcpy(rootDir+newDirLength, fileNameVector[i].c_str());			
				if (!MoveFile(oldFileName, rootDir))
				{
					printf(&quot;move %s to %s failed of %d\n&quot;, oldFileName, rootDir, 
						GetLastError());
				}
				
			}
		}
		rootDir[rootDirLength]='\0';
		fileNameVector.clear();
		fileCount=0;
		directoryCount++;
	}
}

void groupFiles(char* dir)
{
	char buffer[MAX_PATH*4];

	GetCurrentDirectory(MAX_PATH*4, buffer);
	
	sprintf(rootDir, &quot;\\\\?\\%s&quot;, buffer);
	sprintf(workDir, &quot;\\\\?\\%s\\%s&quot;, buffer, dir);
	rootDirLength=strlen(rootDir);
	recursionLevel=0;

	GenericRetrieveAllFile(dir, convertJPG, 6);
	//GenericRetrieveAllFile(dir, groupFile, 1);
	//CollapseAllSubTrees(dir, copyUpperLevel, 6);
}


int main(int argc, char** argv)
{
	if (argc==2)
	{
		groupFiles(argv[1]);
	}
	return 0;
}


</pre>
<pre>
</pre>

<p><br>
กก</p>

<pre></pre>

<pre></pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="PocketRuler.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm">
<img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>