--- /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);
+}