#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                  */
/*                      [email protected]                           */
/*                                                                      */
/*      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);
}