Tesseract  3.02
tesseract-ocr/ccmain/imgscale.cpp
Go to the documentation of this file.
00001 /**********************************************************************
00002  * File:        imgscale.cpp  (Formerly dyn_prog.c)
00003  * Description: Dynamic programming for smart scaling of images.
00004  * Author:      Phil Cheatle
00005  * Created:     Wed Nov 18 16:12:03 GMT 1992
00006  *
00007  * (C) Copyright 1992, Hewlett-Packard Ltd.
00008  ** Licensed under the Apache License, Version 2.0 (the "License");
00009  ** you may not use this file except in compliance with the License.
00010  ** You may obtain a copy of the License at
00011  ** http://www.apache.org/licenses/LICENSE-2.0
00012  ** Unless required by applicable law or agreed to in writing, software
00013  ** distributed under the License is distributed on an "AS IS" BASIS,
00014  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  ** See the License for the specific language governing permissions and
00016  ** limitations under the License.
00017  *
00018  **********************************************************************/
00019 
00020 /*************************************************************************
00021  * This is really Sheelagh's code that I've hacked into a more usable form.
00022  * It is used by scaleim.c  All I did to it was to change "factor" from int to
00023  * float.
00024  *************************************************************************/
00025 /************************************************************************
00026  *  This version uses the result of the previous row to influence the
00027  *  current row's calculation.
00028  ************************************************************************/
00029 
00030 #ifdef _MSC_VER
00031 #pragma warning(disable:4244)  // Conversion warnings
00032 #endif
00033 
00034 #include "mfcpch.h"
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include "errcode.h"
00038 
00039 #define f(xc, yc) ((xc - factor*yc)*(xc - factor*yc))
00040 
00041 #define g(oldyc, yc, oldxc, xc) (factor*factor*(oldyc - yc)*(oldyc - yc)/(abs(oldxc - xc) + 1))
00042 
00043 void
00044 dyn_exit (const char s[]) {
00045   fprintf (stderr, "%s", s);
00046   err_exit(); 
00047 }
00048 
00049 
00050 void dyn_prog(  //The clever bit
00051               int n,
00052               int *x,
00053               int *y,
00054               int ymax,
00055               int *oldx,
00056               int *oldy,
00057               int oldn,
00058               float factor) {
00059   int i, z, j, matchflag;
00060   int **ymin;
00061   float **F, fz;
00062 
00063   /* F[i][z] gives minimum over y <= z */
00064 
00065   F = (float **) calloc (n, sizeof (float *));
00066   ymin = (int **) calloc (n, sizeof (int *));
00067   if ((F == NULL) || (ymin == NULL))
00068     dyn_exit ("Error in calloc\n");
00069 
00070   for (i = 0; i < n; i++) {
00071     F[i] = (float *) calloc (ymax - n + i + 1, sizeof (float));
00072     ymin[i] = (int *) calloc (ymax - n + i + 1, sizeof (int));
00073     if ((F[i] == NULL) || (ymin[i] == NULL))
00074       dyn_exit ("Error in calloc\n");
00075   }
00076 
00077   F[0][0] = f (x[0], 0);
00078   /* find nearest transition of same sign (white to black) */
00079   j = 0;
00080   while ((j < oldn) && (oldx[j] < x[0]))
00081     j += 2;
00082   if (j >= oldn)
00083     j -= 2;
00084   else if ((j - 2 >= 0) && ((x[0] - oldx[j - 2]) < (oldx[j] - x[0])))
00085     j -= 2;
00086   if (abs (oldx[j] - x[0]) < factor) {
00087     matchflag = 1;
00088     F[0][0] += g (oldy[j], 0, oldx[j], x[0]);
00089   }
00090   else
00091     matchflag = 0;
00092   ymin[0][0] = 0;
00093 
00094   for (z = 1; z < ymax - n + 1; z++) {
00095     fz = f (x[0], z);
00096     /* add penalty for deviating from previous row if necessary */
00097 
00098     if (matchflag)
00099       fz += g (oldy[j], z, oldx[j], x[0]);
00100     if (fz < F[0][z - 1]) {
00101       F[0][z] = fz;
00102       ymin[0][z] = z;
00103     }
00104     else {
00105       F[0][z] = F[0][z - 1];
00106       ymin[0][z] = ymin[0][z - 1];
00107     }
00108   }
00109 
00110   for (i = 1; i < n; i++) {
00111     F[i][i] = f (x[i], i) + F[i - 1][i - 1];
00112     /* add penalty for deviating from previous row if necessary */
00113     if (j > 0)
00114       j--;
00115     else
00116       j++;
00117     while ((j < oldn) && (oldx[j] < x[i]))
00118       j += 2;
00119     if (j >= oldn)
00120       j -= 2;
00121     else if ((j - 2 >= 0) && ((x[i] - oldx[j - 2]) < (oldx[j] - x[i])))
00122       j -= 2;
00123     if (abs (oldx[j] - x[i]) < factor) {
00124       matchflag = 1;
00125       F[i][i] += g (oldy[j], i, oldx[j], x[i]);
00126     }
00127     else
00128       matchflag = 0;
00129     ymin[i][i] = i;
00130     for (z = i + 1; z < ymax - n + i + 1; z++) {
00131       fz = f (x[i], z) + F[i - 1][z - 1];
00132       /* add penalty for deviating from previous row if necessary */
00133       if (matchflag)
00134         fz += g (oldy[j], z, oldx[j], x[i]);
00135       if (fz < F[i][z - 1]) {
00136         F[i][z] = fz;
00137         ymin[i][z] = z;
00138       }
00139       else {
00140         F[i][z] = F[i][z - 1];
00141         ymin[i][z] = ymin[i][z - 1];
00142       }
00143     }
00144   }
00145 
00146   y[n - 1] = ymin[n - 1][ymax - 1];
00147   for (i = n - 2; i >= 0; i--)
00148     y[i] = ymin[i][y[i + 1] - 1];
00149 
00150   for (i = 0; i < n; i++) {
00151     free (F[i]);
00152     free (ymin[i]);
00153   }
00154   free(F); 
00155   free(ymin); 
00156 
00157   return;
00158 }