Tesseract  3.02
tesseract-ocr/ccmain/scaleimg.cpp
Go to the documentation of this file.
00001 /**********************************************************************
00002  * File:        scaleimg.cpp  (Formerly scaleim.c)
00003  * Description: 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  * You simply call scale_image() passing in source and target images. The target
00023  * image should be empty, but created - in order to define the destination
00024  * size.
00025  *************************************************************************/
00026 
00027 #ifdef _MSC_VER
00028 #pragma warning(disable:4244)  // Conversion warnings
00029 #endif
00030 
00031 #include "mfcpch.h"
00032 #include          <stdlib.h>
00033 #include          <string.h>
00034 #include          "fileerr.h"
00035 #include          "tprintf.h"
00036 //#include          "grphics.h"
00037 #include          "img.h"
00038 //#include                                      "basefile.h"
00039 #include          "imgscale.h"
00040 #include          "scaleimg.h"
00041 
00042 void scale_image(                     //scale an image
00043                  IMAGE &image,        //source image
00044                  IMAGE &target_image  //target image
00045                 ) {
00046   inT32 xsize, ysize, new_xsize, new_ysize;
00047   IMAGELINE line, new_line;
00048   int *hires, *lores, *oldhires, *oldlores;
00049   int i, j, n, oldn, row, col;
00050   int offset = 0;                //not used here
00051   float factor;
00052   uinT8 curr_colour, new_colour;
00053   int dummy = -1;
00054   IMAGE image2;                  //horiz scaled image
00055 
00056   xsize = image.get_xsize ();
00057   ysize = image.get_ysize ();
00058   new_xsize = target_image.get_xsize ();
00059   new_ysize = target_image.get_ysize ();
00060   if (new_ysize > new_xsize)
00061     new_line.init (new_ysize);
00062   else
00063     new_line.init (new_xsize);
00064 
00065   factor = (float) xsize / (float) new_xsize;
00066 
00067   hires = (int *) calloc (xsize, sizeof (int));
00068   lores = (int *) calloc (new_xsize, sizeof (int));
00069   oldhires = (int *) calloc (xsize, sizeof (int));
00070   oldlores = (int *) calloc (new_xsize, sizeof (int));
00071   if ((hires == NULL) || (lores == NULL) || (oldhires == NULL)
00072   || (oldlores == NULL)) {
00073     fprintf (stderr, "Calloc error in scale_image\n");
00074     err_exit();
00075   }
00076 
00077   image2.create (new_xsize, ysize, image.get_bpp ());
00078 
00079   oldn = 0;
00080   /* do first row separately because hires[col-1] doesn't make sense here */
00081   image.fast_get_line (0, 0, xsize, &line);
00082   /* each line nominally begins with white */
00083   curr_colour = 1;
00084   n = 0;
00085   for (i = 0; i < xsize; i++) {
00086     new_colour = *(line.pixels + i);
00087     if (new_colour != curr_colour) {
00088       hires[n] = i;
00089       n++;
00090       curr_colour = new_colour;
00091     }
00092   }
00093   if (offset != 0)
00094     for (i = 0; i < n; i++)
00095       hires[i] += offset;
00096 
00097   if (n > new_xsize) {
00098     tprintf ("Too many transitions (%d) on line 0\n", n);
00099     scale_image_cop_out(image,
00100                         target_image,
00101                         factor,
00102                         hires,
00103                         lores,
00104                         oldhires,
00105                         oldlores);
00106     return;
00107   }
00108   else if (n > 0)
00109     dyn_prog (n, hires, lores, new_xsize, &dummy, &dummy, 0, factor);
00110   else
00111     lores[0] = new_xsize;
00112 
00113   curr_colour = 1;
00114   j = 0;
00115   for (i = 0; i < new_xsize; i++) {
00116     if (lores[j] == i) {
00117       curr_colour = 1 - curr_colour;
00118       j++;
00119     }
00120     *(new_line.pixels + i) = curr_colour;
00121   }
00122   image2.put_line (0, 0, new_xsize, &new_line, 0);
00123 
00124   for (i = 0; i < n; i++) {
00125     oldhires[i] = hires[i];
00126     oldlores[i] = lores[i];
00127   }
00128 
00129   for (i = n; i < oldn; i++) {
00130     oldhires[i] = 0;
00131     oldlores[i] = 0;
00132   }
00133   oldn = n;
00134 
00135   for (row = 1; row < ysize; row++) {
00136     image.fast_get_line (0, row, xsize, &line);
00137     /* each line nominally begins with white */
00138     curr_colour = 1;
00139     n = 0;
00140     for (i = 0; i < xsize; i++) {
00141       new_colour = *(line.pixels + i);
00142       if (new_colour != curr_colour) {
00143         hires[n] = i;
00144         n++;
00145         curr_colour = new_colour;
00146       }
00147     }
00148     for (i = n; i < oldn; i++) {
00149       hires[i] = 0;
00150       lores[i] = 0;
00151     }
00152     if (offset != 0)
00153       for (i = 0; i < n; i++)
00154         hires[i] += offset;
00155 
00156     if (n > new_xsize) {
00157       tprintf ("Too many transitions (%d) on line %d\n", n, row);
00158       scale_image_cop_out(image,
00159                           target_image,
00160                           factor,
00161                           hires,
00162                           lores,
00163                           oldhires,
00164                           oldlores);
00165       return;
00166     }
00167     else if (n > 0)
00168       dyn_prog(n, hires, lores, new_xsize, oldhires, oldlores, oldn, factor);
00169     else
00170       lores[0] = new_xsize;
00171 
00172     curr_colour = 1;
00173     j = 0;
00174     for (i = 0; i < new_xsize; i++) {
00175       if (lores[j] == i) {
00176         curr_colour = 1 - curr_colour;
00177         j++;
00178       }
00179       *(new_line.pixels + i) = curr_colour;
00180     }
00181     image2.put_line (0, row, new_xsize, &new_line, 0);
00182 
00183     for (i = 0; i < n; i++) {
00184       oldhires[i] = hires[i];
00185       oldlores[i] = lores[i];
00186     }
00187     for (i = n; i < oldn; i++) {
00188       oldhires[i] = 0;
00189       oldlores[i] = 0;
00190     }
00191     oldn = n;
00192   }
00193 
00194   free(hires);
00195   free(lores);
00196   free(oldhires);
00197   free(oldlores);
00198 
00199   /* NOW DO THE VERTICAL SCALING from image2 to target_image*/
00200 
00201   xsize = new_xsize;
00202   factor = (float) ysize / (float) new_ysize;
00203   offset = 0;
00204 
00205   hires = (int *) calloc (ysize, sizeof (int));
00206   lores = (int *) calloc (new_ysize, sizeof (int));
00207   oldhires = (int *) calloc (ysize, sizeof (int));
00208   oldlores = (int *) calloc (new_ysize, sizeof (int));
00209   if ((hires == NULL) || (lores == NULL) || (oldhires == NULL)
00210   || (oldlores == NULL)) {
00211     fprintf (stderr, "Calloc error in scale_image (vert)\n");
00212     err_exit();
00213   }
00214 
00215   oldn = 0;
00216   /* do first col separately because hires[col-1] doesn't make sense here */
00217   image2.get_column (0, 0, ysize, &line, 0);
00218   /* each line nominally begins with white */
00219   curr_colour = 1;
00220   n = 0;
00221   for (i = 0; i < ysize; i++) {
00222     new_colour = *(line.pixels + i);
00223     if (new_colour != curr_colour) {
00224       hires[n] = i;
00225       n++;
00226       curr_colour = new_colour;
00227     }
00228   }
00229 
00230   if (offset != 0)
00231     for (i = 0; i < n; i++)
00232       hires[i] += offset;
00233 
00234   if (n > new_ysize) {
00235     tprintf ("Too many transitions (%d) on column 0\n", n);
00236     scale_image_cop_out(image,
00237                         target_image,
00238                         factor,
00239                         hires,
00240                         lores,
00241                         oldhires,
00242                         oldlores);
00243     return;
00244   }
00245   else if (n > 0)
00246     dyn_prog (n, hires, lores, new_ysize, &dummy, &dummy, 0, factor);
00247   else
00248     lores[0] = new_ysize;
00249 
00250   curr_colour = 1;
00251   j = 0;
00252   for (i = 0; i < new_ysize; i++) {
00253     if (lores[j] == i) {
00254       curr_colour = 1 - curr_colour;
00255       j++;
00256     }
00257     *(new_line.pixels + i) = curr_colour;
00258   }
00259   target_image.put_column (0, 0, new_ysize, &new_line, 0);
00260 
00261   for (i = 0; i < n; i++) {
00262     oldhires[i] = hires[i];
00263     oldlores[i] = lores[i];
00264   }
00265   for (i = n; i < oldn; i++) {
00266     oldhires[i] = 0;
00267     oldlores[i] = 0;
00268   }
00269   oldn = n;
00270 
00271   for (col = 1; col < xsize; col++) {
00272     image2.get_column (col, 0, ysize, &line, 0);
00273     /* each line nominally begins with white */
00274     curr_colour = 1;
00275     n = 0;
00276     for (i = 0; i < ysize; i++) {
00277       new_colour = *(line.pixels + i);
00278       if (new_colour != curr_colour) {
00279         hires[n] = i;
00280         n++;
00281         curr_colour = new_colour;
00282       }
00283     }
00284     for (i = n; i < oldn; i++) {
00285       hires[i] = 0;
00286       lores[i] = 0;
00287     }
00288 
00289     if (offset != 0)
00290       for (i = 0; i < n; i++)
00291         hires[i] += offset;
00292 
00293     if (n > new_ysize) {
00294       tprintf ("Too many transitions (%d) on column %d\n", n, col);
00295       scale_image_cop_out(image,
00296                           target_image,
00297                           factor,
00298                           hires,
00299                           lores,
00300                           oldhires,
00301                           oldlores);
00302       return;
00303     }
00304     else if (n > 0)
00305       dyn_prog(n, hires, lores, new_ysize, oldhires, oldlores, oldn, factor);
00306     else
00307       lores[0] = new_ysize;
00308 
00309     curr_colour = 1;
00310     j = 0;
00311     for (i = 0; i < new_ysize; i++) {
00312       if (lores[j] == i) {
00313         curr_colour = 1 - curr_colour;
00314         j++;
00315       }
00316       *(new_line.pixels + i) = curr_colour;
00317     }
00318     target_image.put_column (col, 0, new_ysize, &new_line, 0);
00319 
00320     for (i = 0; i < n; i++) {
00321       oldhires[i] = hires[i];
00322       oldlores[i] = lores[i];
00323     }
00324     for (i = n; i < oldn; i++) {
00325       oldhires[i] = 0;
00326       oldlores[i] = 0;
00327     }
00328     oldn = n;
00329   }
00330   free(hires);
00331   free(lores);
00332   free(oldhires);
00333   free(oldlores);
00334 }
00335 
00336 
00337 /**********************************************************************
00338  * scale_image_cop_out
00339  *
00340  * Cop-out of scale_image by doing it the easy way and free the data.
00341  **********************************************************************/
00342 
00343 void scale_image_cop_out(                      //scale an image
00344                          IMAGE &image,         //source image
00345                          IMAGE &target_image,  //target image
00346                          float factor,         //scale factor
00347                          int *hires,
00348                          int *lores,
00349                          int *oldhires,
00350                          int *oldlores) {
00351   inT32 xsize, ysize, new_xsize, new_ysize;
00352 
00353   xsize = image.get_xsize ();
00354   ysize = image.get_ysize ();
00355   new_xsize = target_image.get_xsize ();
00356   new_ysize = target_image.get_ysize ();
00357 
00358   if (factor <= 0.5)
00359     reduce_sub_image (&image, 0, 0, xsize, ysize,
00360       &target_image, 0, 0, (inT32) (1.0 / factor), FALSE);
00361   else if (factor >= 2)
00362     enlarge_sub_image (&image, 0, 0, &target_image,
00363         0, 0, new_xsize, new_ysize, (inT32) factor, FALSE);
00364   else
00365     copy_sub_image (&image, 0, 0, xsize, ysize, &target_image, 0, 0, FALSE);
00366   free(hires);
00367   free(lores);
00368   free(oldhires);
00369   free(oldlores);
00370 }