Afegeixo el Makefile.am que falta.
#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);
}