Page.cc
changeset 0 6b8091ca909a
equal deleted inserted replaced
-1:000000000000 0:6b8091ca909a
       
     1 #include "Page.h" // Inclou pam.h
       
     2 #include "Bitmap.h"
       
     3 #include <stdio.h>
       
     4 #include <string.h>
       
     5 #include <math.h>
       
     6 #include "Errors.h"
       
     7 
       
     8 Page::Page(const char *filename)
       
     9 {
       
    10 	map = NULL;
       
    11 	hist = NULL;
       
    12 	text = NULL;
       
    13 	readMap(filename);
       
    14 }
       
    15 
       
    16 Page::~Page()
       
    17 {
       
    18 	delete map;
       
    19 }
       
    20 
       
    21 void Page::readMap(const char *filename)
       
    22 {
       
    23 	FILE *fp;
       
    24 	int i,j;
       
    25 	char *image; // FIXME: Good type
       
    26 	tuple *tuplerow;
       
    27 
       
    28 	if (!strcmp(filename, "-"))
       
    29 		fp = stdin;
       
    30 	else
       
    31 		// FIXME: exception
       
    32 		
       
    33 		if(!(fp = fopen(filename,"r")))
       
    34 			Errors::Fatal("Cannot open filename.");
       
    35 
       
    36 	// Si existia un mapa, el borrem.
       
    37 	if(map != NULL)
       
    38 		delete map;
       
    39 
       
    40 	pnm_readpaminit(fp, &pamImage, sizeof(pamImage));
       
    41 	// FIXME: Read ok
       
    42 
       
    43 	width = pamImage.width;
       
    44 	height = pamImage.height;
       
    45 
       
    46 	map = new Bitmap(width,height);
       
    47 	tuplerow = pnm_allocpamrow(&pamImage);
       
    48 
       
    49 
       
    50 	for (i=0; i<height; i++)
       
    51 	{
       
    52 		pnm_readpamrow(&pamImage, tuplerow);
       
    53 		for (j=0; j<width; j++)
       
    54 		{
       
    55 			// We only read the first sample (changing 0 and 1)
       
    56 			map->pixels[i][j] = tuplerow[j][0]?0:1;
       
    57 		}
       
    58 	}
       
    59 	pnm_freepamrow(tuplerow);
       
    60 
       
    61 	fclose(fp);
       
    62 }
       
    63 
       
    64 void Page::writeMap(const char *filename) const
       
    65 {
       
    66 	pam outpam;
       
    67 	FILE *fp;
       
    68 	tuple *tuplerow;
       
    69 	int i,j;
       
    70 
       
    71 	outpam = pamImage;
       
    72 	outpam.width = width;
       
    73 	outpam.height = height;
       
    74 	
       
    75 	fprintf(stderr,"Writting %s: w:%i,h:%i\n", filename, width, height);
       
    76 
       
    77 	if (!strcmp(filename, "-"))
       
    78 		fp = stdout;
       
    79 	else
       
    80 		// FIXME: exception
       
    81 		
       
    82 		if(!(fp = fopen(filename,"w")))
       
    83 			Errors::Fatal("Cannot open filename.");
       
    84 
       
    85 	outpam.file = fp;
       
    86 
       
    87 	pnm_writepaminit(&outpam);
       
    88 
       
    89 	tuplerow = pnm_allocpamrow(&outpam);
       
    90 
       
    91 	for (i=0; i<height; i++)
       
    92 	{
       
    93 		for (j=0; j<width; j++)
       
    94 		{
       
    95 			// We only write the first sample (changing 0 and 1)
       
    96 			tuplerow[j][0] = map->pixels[i][j]?0:1;
       
    97 		}
       
    98 		pnm_writepamrow(&outpam, tuplerow);
       
    99 	}
       
   100 	pnm_freepamrow(tuplerow);
       
   101 	
       
   102 	fclose(fp);
       
   103 }
       
   104 
       
   105 /*
       
   106 static void Page::Initialize()
       
   107 {
       
   108 	pnm_init(NULL,NULL);
       
   109 }
       
   110 */
       
   111 
       
   112 float Page::ratioBlackWhite() const
       
   113 {
       
   114 	int i,j;
       
   115 	float white=0, black=0;
       
   116 
       
   117 	for(i=0; i<height; i++)
       
   118 		for (j=0; j<width; j++)
       
   119 			if (map->pixels[i][j] == 0)
       
   120 				white++;
       
   121 			else
       
   122 				black++;
       
   123 	return black/white;
       
   124 }
       
   125 
       
   126 void Page::calcHistogram()
       
   127 {
       
   128 	if (hist!=NULL)
       
   129 		delete hist;
       
   130 
       
   131 	map->calcHistogram(hist);
       
   132 }
       
   133 
       
   134 void Page::rotateMap(float angle)
       
   135 {
       
   136 	Bitmap *newmap;
       
   137 	rotateMap(angle, newmap);
       
   138 
       
   139 	// Interchange maps: New -> Page's
       
   140 	delete map;
       
   141 	map = newmap;
       
   142 
       
   143 	height = map->get_height();
       
   144 	width = map->get_width();
       
   145 }
       
   146 
       
   147 void Page::rotateMap(float angle, Bitmap* &mapNew)
       
   148 {
       
   149 	// Code taken from OCRchie
       
   150   int nx,ny,newheight,newwidth,oldheight,oldwidth,i,j,halfnewheight,halfnewwidth;
       
   151   int halfoldheight,halfoldwidth;
       
   152   double radians;
       
   153   double cosval,sinval;
       
   154 
       
   155   radians =  -(angle) / ((180 / 3.142));
       
   156   cosval = cos(radians);
       
   157   sinval = sin(radians);
       
   158 
       
   159   oldheight = height;
       
   160   oldwidth = width;
       
   161   
       
   162   newwidth = (int)abs((int)(oldwidth*cosval)) + (int)abs((int)(oldheight*sinval));
       
   163   newheight = (int)abs((int)(-oldwidth*sinval)) + (int)abs((int)(oldheight*cosval));
       
   164 
       
   165   halfnewheight = newheight / 2;
       
   166   halfnewwidth = newwidth / 2;
       
   167   halfoldwidth = oldwidth /2;
       
   168   halfoldheight = oldheight /2 ;
       
   169 
       
   170   int num_chars = (newwidth / 8) + 1;
       
   171 
       
   172   mapNew = new Bitmap(newwidth,newheight);
       
   173   mapNew->setToZero();
       
   174 
       
   175   for(i=0;i < newheight;i++)
       
   176       {
       
   177         for(j=0;j < newwidth;j++)
       
   178             {
       
   179               nx =(int)( (j - halfnewwidth)*cosval + (i-halfnewheight)*sinval);
       
   180               ny =(int)( -((j - halfnewwidth)*sinval) + (i - halfnewheight)*cosval);
       
   181               nx = nx + halfoldwidth;
       
   182               ny = ny + halfoldheight;
       
   183               if ((nx < oldwidth) && (ny < oldheight) && (nx > 0) && (ny > 0))
       
   184                 {
       
   185 		    mapNew->pixels[i][j] = map->pixels[ny][nx];
       
   186                 }
       
   187               else
       
   188                   {
       
   189 		    mapNew->pixels[i][j] = 0;
       
   190                   }
       
   191             }
       
   192       }
       
   193 
       
   194 
       
   195 }
       
   196 
       
   197 void Page::tryAngles(float min, float max, float step)
       
   198 {
       
   199 	float i;
       
   200 	float std_dev;
       
   201 
       
   202 
       
   203 	for(i=min; i<=max; i+=step)
       
   204 	{
       
   205 		std_dev = std_dev_lines_angle(i);
       
   206 		fprintf(stderr, "Angle: %f, Dev: %f\n", i,
       
   207 			std_dev);
       
   208 	}
       
   209 }
       
   210 
       
   211 float Page::std_dev_lines_angle(float angle)
       
   212 {
       
   213 	float retval;
       
   214 
       
   215 	Bitmap *tmpmap;
       
   216 	Histogram *tmphist;
       
   217 
       
   218 
       
   219 	if (angle == 0)
       
   220 	{
       
   221 		map->calcHistogram(tmphist);
       
   222 	}
       
   223 	else
       
   224 	{
       
   225 		rotateMap(angle,tmpmap);
       
   226 		tmpmap->calcHistogram(tmphist);
       
   227 		delete tmpmap;
       
   228 	}
       
   229 
       
   230 	retval = tmphist->get_std_dev();
       
   231 
       
   232 	delete tmphist;
       
   233 
       
   234 	return retval;
       
   235 }
       
   236 
       
   237 float Page::getSkew(int depth, float margin)
       
   238 {
       
   239 	float x1,x2,x3;
       
   240 	float y1,y2,y3;
       
   241 	float newx, newy;
       
   242 	int i;
       
   243 
       
   244 	x1 = -margin;
       
   245 	x2 = 0;
       
   246 	x3 = margin;
       
   247 
       
   248 	/* Bret's Method */
       
   249 	/*
       
   250 	for (i=0; i<depth; i++)
       
   251 	{
       
   252 		y1 = std_dev_lines_angle(x1);
       
   253 		y2 = std_dev_lines_angle(x2);
       
   254 		y3 = std_dev_lines_angle(x3);
       
   255 		fprintf(stderr, "New stddevs: %f, %f, %f\n", y1, y2, y3);
       
   256 
       
   257 		newx = x2 - 0.5 * ((x2-x1)*(x2-x1) * (y2-y3) -
       
   258 			(x2-x3)*(x2-x3) * (y2-y1)) /
       
   259 			((x2-x1) * (y2-y3) - (x2-x3) * (y2-y1));
       
   260 
       
   261 		// Comprovacions
       
   262 
       
   263 		// Resultat
       
   264 		if (newx > x1 && newx < x2)
       
   265 		{
       
   266 			x3 = x2;
       
   267 			x2 = newx;
       
   268 		}
       
   269 		else if (newx > x2 && newx < x3)
       
   270 		{
       
   271 			x1 = x2;
       
   272 			x2 = newx;
       
   273 		}
       
   274 		else
       
   275 			Errors::Fatal("No convergence!");
       
   276 		fprintf(stderr, "Nous punts: %f, %f, %f\n", x1,x2,x3);
       
   277 	}
       
   278 	*/
       
   279 
       
   280 	/* Golden Slice */
       
   281 	y1 = std_dev_lines_angle(x1);
       
   282 	y2 = std_dev_lines_angle(x2);
       
   283 	y3 = std_dev_lines_angle(x3);
       
   284 
       
   285 	for (i=0; i<depth; i++)
       
   286 	{
       
   287 
       
   288 		// Flanc esquerra
       
   289 		newx = (x2+x1)/2;
       
   290 		newy = std_dev_lines_angle(newx);
       
   291 
       
   292 		// Resultat
       
   293 		if (newy < y2 )
       
   294 		{
       
   295 			x1 = newx;
       
   296 			y1 = newy;
       
   297 		}
       
   298 		else // newy < y2
       
   299 		{
       
   300 			x3 = x2;
       
   301 			y3 = y2;
       
   302 			x2 = newx;
       
   303 			y2 = newy;
       
   304 		}
       
   305 
       
   306 		// Flanc dret
       
   307 		newx = (x3+x2)/2;
       
   308 		newy = std_dev_lines_angle(newx);
       
   309 
       
   310 		// Resultat
       
   311 		if (newy < y2 )
       
   312 		{
       
   313 			x3 = newx;
       
   314 			y3 = newy;
       
   315 		}
       
   316 		else // newy < y2
       
   317 		{
       
   318 			x1 = x2;
       
   319 			y1 = y2;
       
   320 			x2 = newx;
       
   321 			y2 = newy;
       
   322 		}
       
   323 		fprintf(stderr, "Nous punts: %f, %f, %f\n", x1,x2,x3);
       
   324 	}
       
   325 	return x2;
       
   326 }
       
   327 
       
   328 void Page::getText()
       
   329 {
       
   330 	if (text == NULL)
       
   331 		text = new Text();
       
   332 
       
   333 	text->getLines(map);
       
   334 }