00001
00020 #include "mfcpch.h"
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include "fileerr.h"
00024 #include "tprintf.h"
00025 #include "grphics.h"
00026 #include "img.h"
00027
00028 #include "imgscale.h"
00029 #include "scaleimg.h"
00030
00039 void scale_image(
00040 IMAGE &image,
00041 IMAGE &target_image
00042 ) {
00043 INT32 xsize, ysize, new_xsize, new_ysize;
00044 IMAGELINE line, new_line;
00045 int *hires, *lores, *oldhires, *oldlores;
00046 int i, j, n, oldn, row, col;
00047 int offset = 0;
00048 float factor;
00049 UINT8 curr_colour, new_colour;
00050 int dummy = -1;
00051 IMAGE image2;
00052
00053 xsize = image.get_xsize ();
00054 ysize = image.get_ysize ();
00055 new_xsize = target_image.get_xsize ();
00056 new_ysize = target_image.get_ysize ();
00057 if (new_ysize > new_xsize)
00058 new_line.init (new_ysize);
00059 else
00060 new_line.init (new_xsize);
00061
00062 factor = (float) xsize / (float) new_xsize;
00063
00064 hires = (int *) calloc (xsize, sizeof (int));
00065 lores = (int *) calloc (new_xsize, sizeof (int));
00066 oldhires = (int *) calloc (xsize, sizeof (int));
00067 oldlores = (int *) calloc (new_xsize, sizeof (int));
00068 if ((hires == NULL) || (lores == NULL) || (oldhires == NULL)
00069 || (oldlores == NULL)) {
00070 fprintf (stderr, "Calloc error in scale_image\n");
00071 err_exit();
00072 }
00073
00074 image2.create (new_xsize, ysize, image.get_bpp ());
00075
00076 oldn = 0;
00077
00078 image.fast_get_line (0, 0, xsize, &line);
00079
00080 curr_colour = 1;
00081 n = 0;
00082 for (i = 0; i < xsize; i++) {
00083 new_colour = *(line.pixels + i);
00084 if (new_colour != curr_colour) {
00085 hires[n] = i;
00086 n++;
00087 curr_colour = new_colour;
00088 }
00089 }
00090 if (offset != 0)
00091 for (i = 0; i < n; i++)
00092 hires[i] += offset;
00093
00094 if (n > new_xsize) {
00095 tprintf ("Too many transitions (%d) on line 0\n", n);
00096 scale_image_cop_out(image,
00097 target_image,
00098 factor,
00099 hires,
00100 lores,
00101 oldhires,
00102 oldlores);
00103 return;
00104 }
00105 else if (n > 0)
00106 dyn_prog (n, hires, lores, new_xsize, &dummy, &dummy, 0, factor);
00107 else
00108 lores[0] = new_xsize;
00109
00110 curr_colour = 1;
00111 j = 0;
00112 for (i = 0; i < new_xsize; i++) {
00113 if (lores[j] == i) {
00114 curr_colour = 1 - curr_colour;
00115 j++;
00116 }
00117 *(new_line.pixels + i) = curr_colour;
00118 }
00119 image2.put_line (0, 0, new_xsize, &new_line, 0);
00120
00121 for (i = 0; i < n; i++) {
00122 oldhires[i] = hires[i];
00123 oldlores[i] = lores[i];
00124 }
00125
00126 for (i = n; i < oldn; i++) {
00127 oldhires[i] = 0;
00128 oldlores[i] = 0;
00129 }
00130 oldn = n;
00131
00132 for (row = 1; row < ysize; row++) {
00133 image.fast_get_line (0, row, xsize, &line);
00134
00135 curr_colour = 1;
00136 n = 0;
00137 for (i = 0; i < xsize; i++) {
00138 new_colour = *(line.pixels + i);
00139 if (new_colour != curr_colour) {
00140 hires[n] = i;
00141 n++;
00142 curr_colour = new_colour;
00143 }
00144 }
00145 for (i = n; i < oldn; i++) {
00146 hires[i] = 0;
00147 lores[i] = 0;
00148 }
00149 if (offset != 0)
00150 for (i = 0; i < n; i++)
00151 hires[i] += offset;
00152
00153 if (n > new_xsize) {
00154 tprintf ("Too many transitions (%d) on line %d\n", n, row);
00155 scale_image_cop_out(image,
00156 target_image,
00157 factor,
00158 hires,
00159 lores,
00160 oldhires,
00161 oldlores);
00162 return;
00163 }
00164 else if (n > 0)
00165 dyn_prog(n, hires, lores, new_xsize, oldhires, oldlores, oldn, factor);
00166 else
00167 lores[0] = new_xsize;
00168
00169 curr_colour = 1;
00170 j = 0;
00171 for (i = 0; i < new_xsize; i++) {
00172 if (lores[j] == i) {
00173 curr_colour = 1 - curr_colour;
00174 j++;
00175 }
00176 *(new_line.pixels + i) = curr_colour;
00177 }
00178 image2.put_line (0, row, new_xsize, &new_line, 0);
00179
00180 for (i = 0; i < n; i++) {
00181 oldhires[i] = hires[i];
00182 oldlores[i] = lores[i];
00183 }
00184 for (i = n; i < oldn; i++) {
00185 oldhires[i] = 0;
00186 oldlores[i] = 0;
00187 }
00188 oldn = n;
00189 }
00190
00191 free(hires);
00192 free(lores);
00193 free(oldhires);
00194 free(oldlores);
00195
00199 xsize = new_xsize;
00200 factor = (float) ysize / (float) new_ysize;
00201 offset = 0;
00202
00203 hires = (int *) calloc (ysize, sizeof (int));
00204 lores = (int *) calloc (new_ysize, sizeof (int));
00205 oldhires = (int *) calloc (ysize, sizeof (int));
00206 oldlores = (int *) calloc (new_ysize, sizeof (int));
00207 if ((hires == NULL) || (lores == NULL) || (oldhires == NULL)
00208 || (oldlores == NULL)) {
00209 fprintf (stderr, "Calloc error in scale_image (vert)\n");
00210 err_exit();
00211 }
00212
00213 oldn = 0;
00214
00215 image2.get_column (0, 0, ysize, &line, 0);
00216
00217 curr_colour = 1;
00218 n = 0;
00219 for (i = 0; i < ysize; i++) {
00220 new_colour = *(line.pixels + i);
00221 if (new_colour != curr_colour) {
00222 hires[n] = i;
00223 n++;
00224 curr_colour = new_colour;
00225 }
00226 }
00227
00228 if (offset != 0)
00229 for (i = 0; i < n; i++)
00230 hires[i] += offset;
00231
00232 if (n > new_ysize) {
00233 tprintf ("Too many transitions (%d) on column 0\n", n);
00234 scale_image_cop_out(image,
00235 target_image,
00236 factor,
00237 hires,
00238 lores,
00239 oldhires,
00240 oldlores);
00241 return;
00242 }
00243 else if (n > 0)
00244 dyn_prog (n, hires, lores, new_ysize, &dummy, &dummy, 0, factor);
00245 else
00246 lores[0] = new_ysize;
00247
00248 curr_colour = 1;
00249 j = 0;
00250 for (i = 0; i < new_ysize; i++) {
00251 if (lores[j] == i) {
00252 curr_colour = 1 - curr_colour;
00253 j++;
00254 }
00255 *(new_line.pixels + i) = curr_colour;
00256 }
00257 target_image.put_column (0, 0, new_ysize, &new_line, 0);
00258
00259 for (i = 0; i < n; i++) {
00260 oldhires[i] = hires[i];
00261 oldlores[i] = lores[i];
00262 }
00263 for (i = n; i < oldn; i++) {
00264 oldhires[i] = 0;
00265 oldlores[i] = 0;
00266 }
00267 oldn = n;
00268
00269 for (col = 1; col < xsize; col++) {
00270 image2.get_column (col, 0, ysize, &line, 0);
00271
00272 curr_colour = 1;
00273 n = 0;
00274 for (i = 0; i < ysize; i++) {
00275 new_colour = *(line.pixels + i);
00276 if (new_colour != curr_colour) {
00277 hires[n] = i;
00278 n++;
00279 curr_colour = new_colour;
00280 }
00281 }
00282 for (i = n; i < oldn; i++) {
00283 hires[i] = 0;
00284 lores[i] = 0;
00285 }
00286
00287 if (offset != 0)
00288 for (i = 0; i < n; i++)
00289 hires[i] += offset;
00290
00291 if (n > new_ysize) {
00292 tprintf ("Too many transitions (%d) on column %d\n", n, col);
00293 scale_image_cop_out(image,
00294 target_image,
00295 factor,
00296 hires,
00297 lores,
00298 oldhires,
00299 oldlores);
00300 return;
00301 }
00302 else if (n > 0)
00303 dyn_prog(n, hires, lores, new_ysize, oldhires, oldlores, oldn, factor);
00304 else
00305 lores[0] = new_ysize;
00306
00307 curr_colour = 1;
00308 j = 0;
00309 for (i = 0; i < new_ysize; i++) {
00310 if (lores[j] == i) {
00311 curr_colour = 1 - curr_colour;
00312 j++;
00313 }
00314 *(new_line.pixels + i) = curr_colour;
00315 }
00316 target_image.put_column (col, 0, new_ysize, &new_line, 0);
00317
00318 for (i = 0; i < n; i++) {
00319 oldhires[i] = hires[i];
00320 oldlores[i] = lores[i];
00321 }
00322 for (i = n; i < oldn; i++) {
00323 oldhires[i] = 0;
00324 oldlores[i] = 0;
00325 }
00326 oldn = n;
00327 }
00328 free(hires);
00329 free(lores);
00330 free(oldhires);
00331 free(oldlores);
00332 }
00333
00334
00338 void scale_image_cop_out(
00339 IMAGE &image,
00340 IMAGE &target_image,
00341 float factor,
00342 int *hires,
00343 int *lores,
00344 int *oldhires,
00345 int *oldlores) {
00346 INT32 xsize, ysize, new_xsize, new_ysize;
00347
00348 xsize = image.get_xsize ();
00349 ysize = image.get_ysize ();
00350 new_xsize = target_image.get_xsize ();
00351 new_ysize = target_image.get_ysize ();
00352
00353 if (factor <= 0.5)
00354 reduce_sub_image (&image, 0, 0, xsize, ysize,
00355 &target_image, 0, 0, (INT32) (1.0 / factor), FALSE);
00356 else if (factor >= 2)
00357 enlarge_sub_image (&image, 0, 0, &target_image,
00358 0, 0, new_xsize, new_ysize, (INT32) factor, FALSE);
00359 else
00360 copy_sub_image (&image, 0, 0, xsize, ysize, &target_image, 0, 0, FALSE);
00361 free(hires);
00362 free(lores);
00363 free(oldhires);
00364 free(oldlores);
00365 }