Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
scaleimg.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 * File: scaleimg.cpp (Formerly scaleim.c)
3 * Description: Smart scaling of images.
4 * Author: Phil Cheatle
5 * Created: Wed Nov 18 16:12:03 GMT 1992
6 *
7 * (C) Copyright 1992, Hewlett-Packard Ltd.
8 ** Licensed under the Apache License, Version 2.0 (the "License");
9 ** you may not use this file except in compliance with the License.
10 ** You may obtain a copy of the License at
11 ** http://www.apache.org/licenses/LICENSE-2.0
12 ** Unless required by applicable law or agreed to in writing, software
13 ** distributed under the License is distributed on an "AS IS" BASIS,
14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ** See the License for the specific language governing permissions and
16 ** limitations under the License.
17 *
18 **********************************************************************/
19
20 /*************************************************************************
21 * This is really Sheelagh's code that I've hacked into a more usable form.
22 * You simply call scale_image() passing in source and target images. The target
23 * image should be empty, but created - in order to define the destination
24 * size.
25 *************************************************************************/
26
27 #ifdef _MSC_VER
28 #pragma warning(disable:4244) // Conversion warnings
29 #endif
30
31 #include "mfcpch.h"
32 #include <stdlib.h>
33 #include <string.h>
34 #include "fileerr.h"
35 #include "tprintf.h"
36 //#include "grphics.h"
37 #include "img.h"
38 //#include "basefile.h"
39 #include "imgscale.h"
40 #include "scaleimg.h"
41
42 void scale_image( //scale an image
43 IMAGE &image, //source image
44 IMAGE &target_image //target image
45 ) {
46 inT32 xsize, ysize, new_xsize, new_ysize;
47 IMAGELINE line, new_line;
48 int *hires, *lores, *oldhires, *oldlores;
49 int i, j, n, oldn, row, col;
50 int offset = 0; //not used here
51 float factor;
52 uinT8 curr_colour, new_colour;
53 int dummy = -1;
54 IMAGE image2; //horiz scaled image
55
56 xsize = image.get_xsize ();
57 ysize = image.get_ysize ();
58 new_xsize = target_image.get_xsize ();
59 new_ysize = target_image.get_ysize ();
60 if (new_ysize > new_xsize)
61 new_line.init (new_ysize);
62 else
63 new_line.init (new_xsize);
64
65 factor = (float) xsize / (float) new_xsize;
66
67 hires = (int *) calloc (xsize, sizeof (int));
68 lores = (int *) calloc (new_xsize, sizeof (int));
69 oldhires = (int *) calloc (xsize, sizeof (int));
70 oldlores = (int *) calloc (new_xsize, sizeof (int));
71 if ((hires == NULL) || (lores == NULL) || (oldhires == NULL)
72 || (oldlores == NULL)) {
73 fprintf (stderr, "Calloc error in scale_image\n");
74 err_exit();
75 }
76
77 image2.create (new_xsize, ysize, image.get_bpp ());
78
79 oldn = 0;
80 /* do first row separately because hires[col-1] doesn't make sense here */
81 image.fast_get_line (0, 0, xsize, &line);
82 /* each line nominally begins with white */
83 curr_colour = 1;
84 n = 0;
85 for (i = 0; i < xsize; i++) {
86 new_colour = *(line.pixels + i);
87 if (new_colour != curr_colour) {
88 hires[n] = i;
89 n++;
90 curr_colour = new_colour;
91 }
92 }
93 if (offset != 0)
94 for (i = 0; i < n; i++)
95 hires[i] += offset;
96
97 if (n > new_xsize) {
98 tprintf ("Too many transitions (%d) on line 0\n", n);
99 scale_image_cop_out(image,
100 target_image,
101 factor,
102 hires,
103 lores,
104 oldhires,
105 oldlores);
106 return;
107 }
108 else if (n > 0)
109 dyn_prog (n, hires, lores, new_xsize, &dummy, &dummy, 0, factor);
110 else
111 lores[0] = new_xsize;
112
113 curr_colour = 1;
114 j = 0;
115 for (i = 0; i < new_xsize; i++) {
116 if (lores[j] == i) {
117 curr_colour = 1 - curr_colour;
118 j++;
119 }
120 *(new_line.pixels + i) = curr_colour;
121 }
122 image2.put_line (0, 0, new_xsize, &new_line, 0);
123
124 for (i = 0; i < n; i++) {
125 oldhires[i] = hires[i];
126 oldlores[i] = lores[i];
127 }
128
129 for (i = n; i < oldn; i++) {
130 oldhires[i] = 0;
131 oldlores[i] = 0;
132 }
133 oldn = n;
134
135 for (row = 1; row < ysize; row++) {
136 image.fast_get_line (0, row, xsize, &line);
137 /* each line nominally begins with white */
138 curr_colour = 1;
139 n = 0;
140 for (i = 0; i < xsize; i++) {
141 new_colour = *(line.pixels + i);
142 if (new_colour != curr_colour) {
143 hires[n] = i;
144 n++;
145 curr_colour = new_colour;
146 }
147 }
148 for (i = n; i < oldn; i++) {
149 hires[i] = 0;
150 lores[i] = 0;
151 }
152 if (offset != 0)
153 for (i = 0; i < n; i++)
154 hires[i] += offset;
155
156 if (n > new_xsize) {
157 tprintf ("Too many transitions (%d) on line %d\n", n, row);
158 scale_image_cop_out(image,
159 target_image,
160 factor,
161 hires,
162 lores,
163 oldhires,
164 oldlores);
165 return;
166 }
167 else if (n > 0)
168 dyn_prog(n, hires, lores, new_xsize, oldhires, oldlores, oldn, factor);
169 else
170 lores[0] = new_xsize;
171
172 curr_colour = 1;
173 j = 0;
174 for (i = 0; i < new_xsize; i++) {
175 if (lores[j] == i) {
176 curr_colour = 1 - curr_colour;
177 j++;
178 }
179 *(new_line.pixels + i) = curr_colour;
180 }
181 image2.put_line (0, row, new_xsize, &new_line, 0);
182
183 for (i = 0; i < n; i++) {
184 oldhires[i] = hires[i];
185 oldlores[i] = lores[i];
186 }
187 for (i = n; i < oldn; i++) {
188 oldhires[i] = 0;
189 oldlores[i] = 0;
190 }
191 oldn = n;
192 }
193
194 free(hires);
195 free(lores);
196 free(oldhires);
197 free(oldlores);
198
199 /* NOW DO THE VERTICAL SCALING from image2 to target_image*/
200
201 xsize = new_xsize;
202 factor = (float) ysize / (float) new_ysize;
203 offset = 0;
204
205 hires = (int *) calloc (ysize, sizeof (int));
206 lores = (int *) calloc (new_ysize, sizeof (int));
207 oldhires = (int *) calloc (ysize, sizeof (int));
208 oldlores = (int *) calloc (new_ysize, sizeof (int));
209 if ((hires == NULL) || (lores == NULL) || (oldhires == NULL)
210 || (oldlores == NULL)) {
211 fprintf (stderr, "Calloc error in scale_image (vert)\n");
212 err_exit();
213 }
214
215 oldn = 0;
216 /* do first col separately because hires[col-1] doesn't make sense here */
217 image2.get_column (0, 0, ysize, &line, 0);
218 /* each line nominally begins with white */
219 curr_colour = 1;
220 n = 0;
221 for (i = 0; i < ysize; i++) {
222 new_colour = *(line.pixels + i);
223 if (new_colour != curr_colour) {
224 hires[n] = i;
225 n++;
226 curr_colour = new_colour;
227 }
228 }
229
230 if (offset != 0)
231 for (i = 0; i < n; i++)
232 hires[i] += offset;
233
234 if (n > new_ysize) {
235 tprintf ("Too many transitions (%d) on column 0\n", n);
236 scale_image_cop_out(image,
237 target_image,
238 factor,
239 hires,
240 lores,
241 oldhires,
242 oldlores);
243 return;
244 }
245 else if (n > 0)
246 dyn_prog (n, hires, lores, new_ysize, &dummy, &dummy, 0, factor);
247 else
248 lores[0] = new_ysize;
249
250 curr_colour = 1;
251 j = 0;
252 for (i = 0; i < new_ysize; i++) {
253 if (lores[j] == i) {
254 curr_colour = 1 - curr_colour;
255 j++;
256 }
257 *(new_line.pixels + i) = curr_colour;
258 }
259 target_image.put_column (0, 0, new_ysize, &new_line, 0);
260
261 for (i = 0; i < n; i++) {
262 oldhires[i] = hires[i];
263 oldlores[i] = lores[i];
264 }
265 for (i = n; i < oldn; i++) {
266 oldhires[i] = 0;
267 oldlores[i] = 0;
268 }
269 oldn = n;
270
271 for (col = 1; col < xsize; col++) {
272 image2.get_column (col, 0, ysize, &line, 0);
273 /* each line nominally begins with white */
274 curr_colour = 1;
275 n = 0;
276 for (i = 0; i < ysize; i++) {
277 new_colour = *(line.pixels + i);
278 if (new_colour != curr_colour) {
279 hires[n] = i;
280 n++;
281 curr_colour = new_colour;
282 }
283 }
284 for (i = n; i < oldn; i++) {
285 hires[i] = 0;
286 lores[i] = 0;
287 }
288
289 if (offset != 0)
290 for (i = 0; i < n; i++)
291 hires[i] += offset;
292
293 if (n > new_ysize) {
294 tprintf ("Too many transitions (%d) on column %d\n", n, col);
295 scale_image_cop_out(image,
296 target_image,
297 factor,
298 hires,
299 lores,
300 oldhires,
301 oldlores);
302 return;
303 }
304 else if (n > 0)
305 dyn_prog(n, hires, lores, new_ysize, oldhires, oldlores, oldn, factor);
306 else
307 lores[0] = new_ysize;
308
309 curr_colour = 1;
310 j = 0;
311 for (i = 0; i < new_ysize; i++) {
312 if (lores[j] == i) {
313 curr_colour = 1 - curr_colour;
314 j++;
315 }
316 *(new_line.pixels + i) = curr_colour;
317 }
318 target_image.put_column (col, 0, new_ysize, &new_line, 0);
319
320 for (i = 0; i < n; i++) {
321 oldhires[i] = hires[i];
322 oldlores[i] = lores[i];
323 }
324 for (i = n; i < oldn; i++) {
325 oldhires[i] = 0;
326 oldlores[i] = 0;
327 }
328 oldn = n;
329 }
330 free(hires);
331 free(lores);
332 free(oldhires);
333 free(oldlores);
334 }
335
336
337 /**********************************************************************
338 * scale_image_cop_out
339 *
340 * Cop-out of scale_image by doing it the easy way and free the data.
341 **********************************************************************/
342
343 void scale_image_cop_out( //scale an image
344 IMAGE &image, //source image
345 IMAGE &target_image, //target image
346 float factor, //scale factor
347 int *hires,
348 int *lores,
349 int *oldhires,
350 int *oldlores) {
351 inT32 xsize, ysize, new_xsize, new_ysize;
352
353 xsize = image.get_xsize ();
354 ysize = image.get_ysize ();
355 new_xsize = target_image.get_xsize ();
356 new_ysize = target_image.get_ysize ();
357
358 if (factor <= 0.5)
359 reduce_sub_image (&image, 0, 0, xsize, ysize,
360 &target_image, 0, 0, (inT32) (1.0 / factor), FALSE);
361 else if (factor >= 2)
362 enlarge_sub_image (&image, 0, 0, &target_image,
363 0, 0, new_xsize, new_ysize, (inT32) factor, FALSE);
364 else
365 copy_sub_image (&image, 0, 0, xsize, ysize, &target_image, 0, 0, FALSE);
366 free(hires);
367 free(lores);
368 free(oldhires);
369 free(oldlores);
370 }