summaryrefslogtreecommitdiff
path: root/support/pbm2tex/pbm2tex.c
blob: be8c2e27f3413ce9720d6f37c37e908637cb63aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#define VERSIONNUMBER "1.0"

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define PUTDEFENITION \
	"\\newcommand{\\PP}[3]"\
	"{\\put(#1){\\rule{#2\\unitlength}{#3\\unitlength}}}\n"

#define RESTBIT(x) (RestImage[(x)/8] & (UnsCharEins<<(7-(x)%8)))
#define OLDBIT(x) (OldImage[(x)/8] & (UnsCharEins << (7-(x)%8)))

#define SETRESTBIT(x) RestImage[(x)/8] |= (UnsCharEins << (7-(x)%8))
#define DELETERESTBIT(x) RestImage[(x)/8] &= ~(UnsCharEins << (7-(x)%8))
#define SETOLDBIT(x)  OldImage[(x)/8] |= (UnsCharEins << (7-(x)%8))

/************************************************************************/
/*									*/
/*			NO WARRANTY!!					*/
/*									*/
/*	There is absolutely no warranty on this program! Feel free to	*/
/*	use, modify and redistribute this program in any way, but	*/
/*	anything you do with it, you do on your very own risk!		*/
/*									*/
/*	If you find bugs in this program please let me know. If you	*/
/*	modify it in some useful way I would be glad to receive a copy	*/
/*	of the modified source. (My e-mail address see below.)		*/
/*									*/
/************************************************************************/
/* 									*/
/*	program:	pbm2TeX						*/
/* 									*/
/*	author:		Andreas Barth					*/
/*			Universitaet Ulm	(Germany)		*/
/*			Abteilung Mathematische Physik			*/
/*			bar@physik.uni-ulm.de				*/
/* 									*/
/*	date:		some sunday in 1990 version 0.1			*/
/*	date:		november 1993 (version 0.2)			*/
/*	date:		january 1994 (version 1.0)			*/
/* 									*/
/************************************************************************/
/*									*/
/*	This is pbm2TeX, an image converter from the pbm (portable	*/
/*	bitmap) format to a LaTeX picture environment.			*/
/*									*/
/************************************************************************/
/*									*/
/* 	There are no special system requirements. Just compile this	*/
/*	program	with your favourite C-copiler. 				*/
/*									*/
/************************************************************************/
/*									*/
/*	This program is intended to make the import of graphic easy	*/
/*	and as portable as possible. There are many DVI drivers who	*/
/*	allow to import different graphic formats but you at least	*/
/*	have to pay the price of restricted portability. 		*/
/*									*/
/*	To get fully portable graphics inclusion into my LaTeX docu-	*/
/*	ments I some years ago wrote a program that converted pixel	*/
/*	images to LaTeX picture environments. This program worked fine,	*/
/*	but the time TeX needed to compile the documents grow rapidly	*/
/*	(I had a document with 19 x-y-plots in about 30 pages that	*/
/*	needed about one hour to compile!) and so I gave it up. But	*/
/*	the computer power increased considerably and the TeX imple-	*/
/*	mentations I use are perhaps a hundred times faster than those	*/
/*	I used at the first try. So I decided to rewrite the program	*/
/*	and try again to use it. I hope in future I can reduce the	*/
/*	number of rules used to build the pcture. This version (0.1)	*/
/*	works not very optimized. (I am thinking about a smarter algo-	*/
/*	rithm!)								*/
/*									*/
/*	(The transform algorithm was modified in version 1.0.)		*/
/*									*/
/************************************************************************/
/*									*/
/*	useage:	pbm2TeX works as a pipeline. Just pipe the pbm image	*/
/*		into the program and redirect the LaTeX output into a	*/
/*		file you may include into your document:		*/
/*									*/
/*			pbm2TeX <myimage.pbm >myimage.tex		*/
/*									*/
/*		There is a single command line option at this  time.	*/
/*		This is the -L option. It is needed because in some	*/
/*		environments a newline may be two bytes long and so	*/
/*		in case of a binary image (magic number 4) there may	*/
/*		be two bytes between the end of the image width number	*/
/*		and the start of the image. This aditional byte is	*/
/*		skipped when using the -L option.			*/
/*									*/
/*	limitation: At this time (version 1.0) comments in the image	*/
/*		file are not supported (I never saw a pbm image that	*/
/*		contained any).						*/
/*									*/
/************************************************************************/

unsigned char UnsCharEins=1, DummyC;
int ImageWidth=0, ImageHeight=0;
int LinefeedFlag=0;
unsigned char * OldImage;
unsigned char * RestImage;

void readimage(void)
{
int MagicNumber;
register int i;

scanf("P%d%d%d",&MagicNumber, &ImageWidth, &ImageHeight);

OldImage = (unsigned char *) malloc( (ImageWidth*ImageHeight+7)/8);
RestImage = (unsigned char *) malloc( (ImageWidth*ImageHeight+7)/8);

if( NULL == OldImage || NULL == RestImage)
	{
	fprintf(stderr,"\ncan't allocate enough memory! => exit");
	exit(1);
	}

for(i=0; i<(ImageWidth*ImageHeight+7)/8; i++) 
	{
	OldImage[i]=0;
	}

if(1 == MagicNumber)
	{
	for(i=0; i<(ImageWidth*ImageHeight); i++)
		{
		int v;
		scanf("%d", &v);
		if(v != 0) SETOLDBIT(i);
		}
	memcpy(RestImage,OldImage,(ImageWidth*ImageHeight+7)/8);
	}
else if(4 == MagicNumber)
	{
	if(LinefeedFlag)
		{
		char c;
		fread(&c,1,1,stdin);
		}
	fread(OldImage,(ImageWidth*ImageHeight+7)/8,1,stdin);
	memcpy(RestImage,OldImage,(ImageWidth*ImageHeight+7)/8);
	}
else
	{
	fprintf(stderr,"\nbad magic number: %d (1 or 4 expected) => exit");
	exit(1);
	}
}


int LowerBorder(int x1, int x2, int y)
{
int lower=y+1;
int x;
unsigned char there=255;

while(there && lower < ImageHeight)
	{
	for(x=x1; x<x2; x++)
		{
		there = there && OLDBIT(lower*ImageWidth+x);
		}
	if(there) lower++;
	}
return(lower);
}


void NoteSquare(int Xmin, int Xmax, int Ymin, int Ymax)
{
register int x,y;
for(y=Ymin; y<Ymax; y++)
	{
	for(x=Xmin; x<Xmax; x++)
		{
		DELETERESTBIT(x+ImageWidth*y);
		}
	}
printf("\\PP{%d,%d}{%d}{%d}\n",
	Xmin,
	ImageHeight-Ymin-(Ymax-Ymin),
	Xmax-Xmin,
	Ymax-Ymin);
}


int InsideSquare(int Xmin, int Xmax, int Ymin, int Ymax)
{
register int M=0;
register int x,y;
for(y=Ymin; y<Ymax; y++)
	{
	for(x=Xmin; x<Xmax; x++)
		{
		if(RESTBIT(y*ImageWidth+x)) M++;
		}
	}
return(M);
}


int main(int argc, char * args[])
{
register int l,i;

for(i=1; i<argc; i++)
	{
	if('-' == args[i][0] && 'L' == args[i][1])
		LinefeedFlag=1;
	}

fprintf(stderr,"\nthis is pbm2TeX %s",VERSIONNUMBER);
readimage();
fprintf(stderr,"\nimage of size %d X %d read",
	ImageWidth,ImageHeight);

printf("%%%%This is an output from pbm2TeX ver. %s!\n",VERSIONNUMBER);
printf("%%%%To resize the image change the definition\n");
printf("%%%%of \\unitlength\n");
printf("{\n");
printf(PUTDEFENITION);
printf("\\setlength{\\unitlength}{0.0846666mm}\n");
printf("\\begin{picture}(%d,%d)\n",ImageWidth,ImageHeight);

for(l=0; l<ImageHeight; l++)
	{
	int s;
	fprintf(stderr,".");
	for(s=0; s<ImageWidth; s++)
		{
		if(RESTBIT(l*ImageWidth+s))
			{
			int XA,XE,Xa,Xe,Xmin,Xmax,Y,YN,NT,N=0;

			Xmin= s;
			while( Xmin>0 &&
				OLDBIT(l*ImageWidth+Xmin-1) )
				Xmin--;
			Xmax = s+1;
			while(Xmax<ImageWidth &&
				OLDBIT(l*ImageWidth+Xmax)) Xmax++;

			for(Xa=Xmin; Xa<=s; Xa++)
				{
				for(Xe=s+1; Xe<=Xmax; Xe++)
					{
					Y=LowerBorder(Xa,Xe,l);
					NT=InsideSquare(Xa,Xe,l,Y);
					if(NT >= N)
						{
						YN=Y;
						XA=Xa;
						XE=Xe;
						N=NT;
						}
					}
				}

			NoteSquare(XA,XE,l,YN);
			}
		}
	}
printf("\\end{picture}\n");
printf("}\n");
printf("%%%%end output from pbm2TeX ver. %s\n",VERSIONNUMBER);
exit(0);
}