Tesseract
3.02
|
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 }