Page.cc
changeset 0 6b8091ca909a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Page.cc	Thu May 18 23:12:51 2006 +0200
@@ -0,0 +1,334 @@
+#include "Page.h" // Inclou pam.h
+#include "Bitmap.h"
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "Errors.h"
+
+Page::Page(const char *filename)
+{
+	map = NULL;
+	hist = NULL;
+	text = NULL;
+	readMap(filename);
+}
+
+Page::~Page()
+{
+	delete map;
+}
+
+void Page::readMap(const char *filename)
+{
+	FILE *fp;
+	int i,j;
+	char *image; // FIXME: Good type
+	tuple *tuplerow;
+
+	if (!strcmp(filename, "-"))
+		fp = stdin;
+	else
+		// FIXME: exception
+		
+		if(!(fp = fopen(filename,"r")))
+			Errors::Fatal("Cannot open filename.");
+
+	// Si existia un mapa, el borrem.
+	if(map != NULL)
+		delete map;
+
+	pnm_readpaminit(fp, &pamImage, sizeof(pamImage));
+	// FIXME: Read ok
+
+	width = pamImage.width;
+	height = pamImage.height;
+
+	map = new Bitmap(width,height);
+	tuplerow = pnm_allocpamrow(&pamImage);
+
+
+	for (i=0; i<height; i++)
+	{
+		pnm_readpamrow(&pamImage, tuplerow);
+		for (j=0; j<width; j++)
+		{
+			// We only read the first sample (changing 0 and 1)
+			map->pixels[i][j] = tuplerow[j][0]?0:1;
+		}
+	}
+	pnm_freepamrow(tuplerow);
+
+	fclose(fp);
+}
+
+void Page::writeMap(const char *filename) const
+{
+	pam outpam;
+	FILE *fp;
+	tuple *tuplerow;
+	int i,j;
+
+	outpam = pamImage;
+	outpam.width = width;
+	outpam.height = height;
+	
+	fprintf(stderr,"Writting %s: w:%i,h:%i\n", filename, width, height);
+
+	if (!strcmp(filename, "-"))
+		fp = stdout;
+	else
+		// FIXME: exception
+		
+		if(!(fp = fopen(filename,"w")))
+			Errors::Fatal("Cannot open filename.");
+
+	outpam.file = fp;
+
+	pnm_writepaminit(&outpam);
+
+	tuplerow = pnm_allocpamrow(&outpam);
+
+	for (i=0; i<height; i++)
+	{
+		for (j=0; j<width; j++)
+		{
+			// We only write the first sample (changing 0 and 1)
+			tuplerow[j][0] = map->pixels[i][j]?0:1;
+		}
+		pnm_writepamrow(&outpam, tuplerow);
+	}
+	pnm_freepamrow(tuplerow);
+	
+	fclose(fp);
+}
+
+/*
+static void Page::Initialize()
+{
+	pnm_init(NULL,NULL);
+}
+*/
+
+float Page::ratioBlackWhite() const
+{
+	int i,j;
+	float white=0, black=0;
+
+	for(i=0; i<height; i++)
+		for (j=0; j<width; j++)
+			if (map->pixels[i][j] == 0)
+				white++;
+			else
+				black++;
+	return black/white;
+}
+
+void Page::calcHistogram()
+{
+	if (hist!=NULL)
+		delete hist;
+
+	map->calcHistogram(hist);
+}
+
+void Page::rotateMap(float angle)
+{
+	Bitmap *newmap;
+	rotateMap(angle, newmap);
+
+	// Interchange maps: New -> Page's
+	delete map;
+	map = newmap;
+
+	height = map->get_height();
+	width = map->get_width();
+}
+
+void Page::rotateMap(float angle, Bitmap* &mapNew)
+{
+	// Code taken from OCRchie
+  int nx,ny,newheight,newwidth,oldheight,oldwidth,i,j,halfnewheight,halfnewwidth;
+  int halfoldheight,halfoldwidth;
+  double radians;
+  double cosval,sinval;
+
+  radians =  -(angle) / ((180 / 3.142));
+  cosval = cos(radians);
+  sinval = sin(radians);
+
+  oldheight = height;
+  oldwidth = width;
+  
+  newwidth = (int)abs((int)(oldwidth*cosval)) + (int)abs((int)(oldheight*sinval));
+  newheight = (int)abs((int)(-oldwidth*sinval)) + (int)abs((int)(oldheight*cosval));
+
+  halfnewheight = newheight / 2;
+  halfnewwidth = newwidth / 2;
+  halfoldwidth = oldwidth /2;
+  halfoldheight = oldheight /2 ;
+
+  int num_chars = (newwidth / 8) + 1;
+
+  mapNew = new Bitmap(newwidth,newheight);
+  mapNew->setToZero();
+
+  for(i=0;i < newheight;i++)
+      {
+        for(j=0;j < newwidth;j++)
+            {
+              nx =(int)( (j - halfnewwidth)*cosval + (i-halfnewheight)*sinval);
+              ny =(int)( -((j - halfnewwidth)*sinval) + (i - halfnewheight)*cosval);
+              nx = nx + halfoldwidth;
+              ny = ny + halfoldheight;
+              if ((nx < oldwidth) && (ny < oldheight) && (nx > 0) && (ny > 0))
+                {
+		    mapNew->pixels[i][j] = map->pixels[ny][nx];
+                }
+              else
+                  {
+		    mapNew->pixels[i][j] = 0;
+                  }
+            }
+      }
+
+
+}
+
+void Page::tryAngles(float min, float max, float step)
+{
+	float i;
+	float std_dev;
+
+
+	for(i=min; i<=max; i+=step)
+	{
+		std_dev = std_dev_lines_angle(i);
+		fprintf(stderr, "Angle: %f, Dev: %f\n", i,
+			std_dev);
+	}
+}
+
+float Page::std_dev_lines_angle(float angle)
+{
+	float retval;
+
+	Bitmap *tmpmap;
+	Histogram *tmphist;
+
+
+	if (angle == 0)
+	{
+		map->calcHistogram(tmphist);
+	}
+	else
+	{
+		rotateMap(angle,tmpmap);
+		tmpmap->calcHistogram(tmphist);
+		delete tmpmap;
+	}
+
+	retval = tmphist->get_std_dev();
+
+	delete tmphist;
+
+	return retval;
+}
+
+float Page::getSkew(int depth, float margin)
+{
+	float x1,x2,x3;
+	float y1,y2,y3;
+	float newx, newy;
+	int i;
+
+	x1 = -margin;
+	x2 = 0;
+	x3 = margin;
+
+	/* Bret's Method */
+	/*
+	for (i=0; i<depth; i++)
+	{
+		y1 = std_dev_lines_angle(x1);
+		y2 = std_dev_lines_angle(x2);
+		y3 = std_dev_lines_angle(x3);
+		fprintf(stderr, "New stddevs: %f, %f, %f\n", y1, y2, y3);
+
+		newx = x2 - 0.5 * ((x2-x1)*(x2-x1) * (y2-y3) -
+			(x2-x3)*(x2-x3) * (y2-y1)) /
+			((x2-x1) * (y2-y3) - (x2-x3) * (y2-y1));
+
+		// Comprovacions
+
+		// Resultat
+		if (newx > x1 && newx < x2)
+		{
+			x3 = x2;
+			x2 = newx;
+		}
+		else if (newx > x2 && newx < x3)
+		{
+			x1 = x2;
+			x2 = newx;
+		}
+		else
+			Errors::Fatal("No convergence!");
+		fprintf(stderr, "Nous punts: %f, %f, %f\n", x1,x2,x3);
+	}
+	*/
+
+	/* Golden Slice */
+	y1 = std_dev_lines_angle(x1);
+	y2 = std_dev_lines_angle(x2);
+	y3 = std_dev_lines_angle(x3);
+
+	for (i=0; i<depth; i++)
+	{
+
+		// Flanc esquerra
+		newx = (x2+x1)/2;
+		newy = std_dev_lines_angle(newx);
+
+		// Resultat
+		if (newy < y2 )
+		{
+			x1 = newx;
+			y1 = newy;
+		}
+		else // newy < y2
+		{
+			x3 = x2;
+			y3 = y2;
+			x2 = newx;
+			y2 = newy;
+		}
+
+		// Flanc dret
+		newx = (x3+x2)/2;
+		newy = std_dev_lines_angle(newx);
+
+		// Resultat
+		if (newy < y2 )
+		{
+			x3 = newx;
+			y3 = newy;
+		}
+		else // newy < y2
+		{
+			x1 = x2;
+			y1 = y2;
+			x2 = newx;
+			y2 = newy;
+		}
+		fprintf(stderr, "Nous punts: %f, %f, %f\n", x1,x2,x3);
+	}
+	return x2;
+}
+
+void Page::getText()
+{
+	if (text == NULL)
+		text = new Text();
+
+	text->getLines(map);
+}