Leptonica 1.68
C Image Processing Library
|
00001 /*====================================================================* 00002 - Copyright (C) 2001 Leptonica. All rights reserved. 00003 - This software is distributed in the hope that it will be 00004 - useful, but with NO WARRANTY OF ANY KIND. 00005 - No author or distributor accepts responsibility to anyone for the 00006 - consequences of using this software, or for whether it serves any 00007 - particular purpose or works at all, unless he or she says so in 00008 - writing. Everyone is granted permission to copy, modify and 00009 - redistribute this source code, for commercial or non-commercial 00010 - purposes, with the following restrictions: (1) the origin of this 00011 - source code must not be misrepresented; (2) modified versions must 00012 - be plainly marked as such; and (3) this notice may not be removed 00013 - or altered from any source or modified source distribution. 00014 *====================================================================*/ 00015 00016 /* 00017 * ptra1_reg.c 00018 * 00019 * Testing basic ptra operations 00020 */ 00021 00022 #include <stdio.h> 00023 #include <stdlib.h> 00024 #include "allheaders.h" 00025 00026 static void MakePtrasFromPixa(PIXA *pixa, L_PTRA **ppapix, L_PTRA **ppabox, 00027 l_int32 copyflag); 00028 static PIXA *ReconstructPixa(L_PTRA *papix, L_PTRA *pabox, l_int32 choose); 00029 static PIXA *ReconstructPixa1(L_PTRA *papix, L_PTRA *pabox); 00030 static PIXA *ReconstructPixa2(L_PTRA *papix, L_PTRA *pabox); 00031 static void CopyPtras(L_PTRA *papixs, L_PTRA *paboxs, 00032 L_PTRA **ppapixd, L_PTRA **ppaboxd); 00033 static void DisplayResult(PIXA *pixac, PIXA **ppixa, l_int32 w, l_int32 h, 00034 l_int32 newline); 00035 00036 #define CHOOSE_RECON 2 /* 1 or 2 */ 00037 00038 00039 main(int argc, 00040 char **argv) 00041 { 00042 l_int32 i, n, w, h, nactual, j, imax; 00043 BOX *box; 00044 BOXA *boxa; 00045 PIX *pixs, *pixd, *pix; 00046 PIXA *pixas, *pixat, *pixac; 00047 L_PTRA *papix, *pabox, *papix2, *pabox2; 00048 static char mainName[] = "ptra1_reg"; 00049 00050 if (argc != 1) 00051 exit(ERROR_INT(" Syntax: ptra1_reg", mainName, 1)); 00052 00053 pixac = pixaCreate(0); 00054 00055 if ((pixs = pixRead("lucasta.1.300.tif")) == NULL) 00056 exit(ERROR_INT("pixs not made", mainName, 1)); 00057 pixGetDimensions(pixs, &w, &h, NULL); 00058 boxa = pixConnComp(pixs, &pixas, 8); 00059 pixDestroy(&pixs); 00060 boxaDestroy(&boxa); 00061 n = pixaGetCount(pixas); 00062 00063 /* Fill ptras with clones and reconstruct */ 00064 fprintf(stderr, "Fill with clones and reconstruct\n"); 00065 MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE); 00066 pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON); 00067 ptraDestroy(&papix, 0, 1); 00068 ptraDestroy(&pabox, 0, 1); 00069 DisplayResult(pixac, &pixat, w, h, 1); 00070 00071 /* Remove every other one for the first half; 00072 * with compaction at each removal */ 00073 fprintf(stderr, "Remove every other in 1st half, with compaction\n"); 00074 MakePtrasFromPixa(pixas, &papix, &pabox, L_COPY); 00075 for (i = 0; i < n / 2; i++) { 00076 if (i % 2 == 0) { 00077 pix = (PIX *)ptraRemove(papix, i, L_COMPACTION); 00078 box = (BOX *)ptraRemove(pabox, i, L_COMPACTION); 00079 pixDestroy(&pix); 00080 boxDestroy(&box); 00081 } 00082 } 00083 pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON); 00084 ptraDestroy(&papix, 0, 1); 00085 ptraDestroy(&pabox, 0, 1); 00086 DisplayResult(pixac, &pixat, w, h, 0); 00087 00088 /* Remove every other one for the entire set, 00089 * but without compaction at each removal */ 00090 fprintf(stderr, 00091 "Remove every other in 1st half, without & then with compaction\n"); 00092 MakePtrasFromPixa(pixas, &papix, &pabox, L_COPY); 00093 for (i = 0; i < n; i++) { 00094 if (i % 2 == 0) { 00095 pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION); 00096 box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION); 00097 pixDestroy(&pix); 00098 boxDestroy(&box); 00099 } 00100 } 00101 ptraCompactArray(papix); /* now do the compaction */ 00102 ptraCompactArray(pabox); 00103 pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON); 00104 ptraDestroy(&papix, 0, 1); 00105 ptraDestroy(&pabox, 0, 1); 00106 DisplayResult(pixac, &pixat, w, h, 0); 00107 00108 /* Fill ptras using insert at head, and reconstruct */ 00109 fprintf(stderr, "Insert at head and reconstruct\n"); 00110 papix = ptraCreate(n); 00111 pabox = ptraCreate(n); 00112 for (i = 0; i < n; i++) { 00113 pix = pixaGetPix(pixas, i, L_CLONE); 00114 box = pixaGetBox(pixas, i, L_CLONE); 00115 ptraInsert(papix, 0, pix, L_MIN_DOWNSHIFT); 00116 ptraInsert(pabox, 0, box, L_FULL_DOWNSHIFT); 00117 } 00118 pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON); 00119 ptraDestroy(&papix, 0, 1); 00120 ptraDestroy(&pabox, 0, 1); 00121 DisplayResult(pixac, &pixat, w, h, 1); 00122 00123 /* Reverse the arrays by swapping */ 00124 fprintf(stderr, "Reverse by swapping\n"); 00125 MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE); 00126 for (i = 0; i < n / 2; i++) { 00127 ptraSwap(papix, i, n - i - 1); 00128 ptraSwap(pabox, i, n - i - 1); 00129 } 00130 ptraCompactArray(papix); /* already compact; shouldn't do anything */ 00131 ptraCompactArray(pabox); 00132 pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON); 00133 ptraDestroy(&papix, 0, 1); 00134 ptraDestroy(&pabox, 0, 1); 00135 DisplayResult(pixac, &pixat, w, h, 0); 00136 00137 /* Remove at the top of the array and push the hole to the end 00138 * by neighbor swapping (!). This is O(n^2), so it's not a 00139 * recommended way to copy a ptra. [joke] */ 00140 fprintf(stderr, 00141 "Remove at top, pushing hole to end by swapping -- O(n^2)\n"); 00142 MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE); 00143 papix2 = ptraCreate(0); 00144 pabox2 = ptraCreate(0); 00145 while (1) { 00146 ptraGetActualCount(papix, &nactual); 00147 if (nactual == 0) break; 00148 ptraGetMaxIndex(papix, &imax); 00149 pix = (PIX *)ptraRemove(papix, 0, L_NO_COMPACTION); 00150 box = (BOX *)ptraRemove(pabox, 0, L_NO_COMPACTION); 00151 ptraAdd(papix2, pix); 00152 ptraAdd(pabox2, box); 00153 for (i = 1; i <= imax; i++) { 00154 ptraSwap(papix, i - 1, i); 00155 ptraSwap(pabox, i - 1, i); 00156 } 00157 } 00158 ptraCompactArray(papix); /* should be empty */ 00159 ptraCompactArray(pabox); /* ditto */ 00160 pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON); 00161 ptraDestroy(&papix, 0, 1); 00162 ptraDestroy(&pabox, 0, 1); 00163 DisplayResult(pixac, &pixat, w, h, 1); /* nothing there */ 00164 pixat = ReconstructPixa(papix2, pabox2, CHOOSE_RECON); 00165 ptraDestroy(&papix2, 0, 1); 00166 ptraDestroy(&pabox2, 0, 1); 00167 DisplayResult(pixac, &pixat, w, h, 0); 00168 00169 /* Remove and insert one position above, allowing minimum downshift. 00170 * If you specify L_AUTO_DOWNSHIFT, because there is only 1 hole, 00171 * it will do a full downshift at each insert. This is a 00172 * situation where the heuristic (expected number of holes) 00173 * fails to do the optimal thing. */ 00174 fprintf(stderr, "Remove and insert one position above (min downshift)\n"); 00175 MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE); 00176 for (i = 1; i < n; i++) { 00177 pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION); 00178 box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION); 00179 ptraInsert(papix, i - 1, pix, L_MIN_DOWNSHIFT); 00180 ptraInsert(pabox, i - 1, box, L_MIN_DOWNSHIFT); 00181 } 00182 pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON); 00183 ptraDestroy(&papix, 0, 1); 00184 ptraDestroy(&pabox, 0, 1); 00185 DisplayResult(pixac, &pixat, w, h, 1); 00186 00187 /* Remove and insert one position above, but this time 00188 * forcing a full downshift at each step. */ 00189 fprintf(stderr, "Remove and insert one position above (full downshift)\n"); 00190 MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE); 00191 for (i = 1; i < n; i++) { 00192 pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION); 00193 box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION); 00194 ptraInsert(papix, i - 1, pix, L_AUTO_DOWNSHIFT); 00195 ptraInsert(pabox, i - 1, box, L_AUTO_DOWNSHIFT); 00196 } 00197 /* ptraCompactArray(papix); 00198 ptraCompactArray(pabox); */ 00199 pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON); 00200 ptraDestroy(&papix, 0, 1); 00201 ptraDestroy(&pabox, 0, 1); 00202 DisplayResult(pixac, &pixat, w, h, 0); 00203 00204 pixd = pixaDisplay(pixac, 0, 0); 00205 pixDisplay(pixd, 100, 100); 00206 pixWrite("/tmp/junkptra1.png", pixd, IFF_PNG); 00207 pixDestroy(&pixd); 00208 pixaDestroy(&pixac); 00209 pixaDestroy(&pixas); 00210 return 0; 00211 } 00212 00213 00214 static void 00215 MakePtrasFromPixa(PIXA *pixa, 00216 L_PTRA **ppapix, 00217 L_PTRA **ppabox, 00218 l_int32 copyflag) 00219 { 00220 l_int32 i, n; 00221 BOX *box; 00222 PIX *pix; 00223 L_PTRA *papix, *pabox; 00224 00225 n = pixaGetCount(pixa); 00226 papix = ptraCreate(n); 00227 pabox = ptraCreate(n); 00228 for (i = 0; i < n; i++) { 00229 pix = pixaGetPix(pixa, i, copyflag); 00230 box = pixaGetBox(pixa, i, copyflag); 00231 ptraAdd(papix, pix); 00232 ptraAdd(pabox, box); 00233 } 00234 00235 *ppapix = papix; 00236 *ppabox = pabox; 00237 return; 00238 } 00239 00240 00241 static PIXA * 00242 ReconstructPixa(L_PTRA *papix, 00243 L_PTRA *pabox, 00244 l_int32 choose) 00245 { 00246 PIXA *pixa; 00247 00248 if (choose == 1) 00249 pixa = ReconstructPixa1(papix, pabox); 00250 else 00251 pixa = ReconstructPixa2(papix, pabox); 00252 return pixa; 00253 } 00254 00255 00256 /* Reconstruction without compaction */ 00257 static PIXA * 00258 ReconstructPixa1(L_PTRA *papix, 00259 L_PTRA *pabox) 00260 { 00261 l_int32 i, imax, nactual; 00262 BOX *box; 00263 PIX *pix; 00264 PIXA *pixat; 00265 00266 ptraGetMaxIndex(papix, &imax); 00267 ptraGetActualCount(papix, &nactual); 00268 fprintf(stderr, "Before removal: imax = %4d, actual = %4d\n", 00269 imax, nactual); 00270 00271 pixat = pixaCreate(imax + 1); 00272 for (i = 0; i <= imax; i++) { 00273 pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION); 00274 box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION); 00275 if (pix) pixaAddPix(pixat, pix, L_INSERT); 00276 if (box) pixaAddBox(pixat, box, L_INSERT); 00277 } 00278 00279 ptraGetMaxIndex(papix, &imax); 00280 ptraGetActualCount(papix, &nactual); 00281 fprintf(stderr, "After removal: imax = %4d, actual = %4d\n\n", 00282 imax, nactual); 00283 00284 return pixat; 00285 } 00286 00287 00288 /* Reconstruction with compaction */ 00289 static PIXA * 00290 ReconstructPixa2(L_PTRA *papix, 00291 L_PTRA *pabox) 00292 { 00293 l_int32 i, imax, nactual; 00294 BOX *box; 00295 PIX *pix; 00296 PIXA *pixat; 00297 00298 ptraGetMaxIndex(papix, &imax); 00299 ptraGetActualCount(papix, &nactual); 00300 fprintf(stderr, "Before removal: imax = %4d, actual = %4d\n", 00301 imax, nactual); 00302 00303 /* Remove half */ 00304 pixat = pixaCreate(imax + 1); 00305 for (i = 0; i <= imax; i++) { 00306 if (i % 2 == 0) { 00307 pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION); 00308 box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION); 00309 if (pix) pixaAddPix(pixat, pix, L_INSERT); 00310 if (box) pixaAddBox(pixat, box, L_INSERT); 00311 } 00312 } 00313 00314 /* Compact */ 00315 ptraGetMaxIndex(papix, &imax); 00316 ptraGetActualCount(papix, &nactual); 00317 fprintf(stderr, "Before compaction: imax = %4d, actual = %4d\n", 00318 imax, nactual); 00319 ptraCompactArray(papix); 00320 ptraCompactArray(pabox); 00321 ptraGetMaxIndex(papix, &imax); 00322 ptraGetActualCount(papix, &nactual); 00323 fprintf(stderr, "After compaction: imax = %4d, actual = %4d\n", 00324 imax, nactual); 00325 00326 /* Remove the rest (and test compaction with removal) */ 00327 while (1) { 00328 ptraGetActualCount(papix, &nactual); 00329 if (nactual == 0) break; 00330 00331 pix = (PIX *)ptraRemove(papix, 0, L_COMPACTION); 00332 box = (BOX *)ptraRemove(pabox, 0, L_COMPACTION); 00333 pixaAddPix(pixat, pix, L_INSERT); 00334 pixaAddBox(pixat, box, L_INSERT); 00335 } 00336 00337 ptraGetMaxIndex(papix, &imax); 00338 ptraGetActualCount(papix, &nactual); 00339 fprintf(stderr, "After removal: imax = %4d, actual = %4d\n\n", 00340 imax, nactual); 00341 00342 return pixat; 00343 } 00344 00345 00346 static void 00347 CopyPtras(L_PTRA *papixs, 00348 L_PTRA *paboxs, 00349 L_PTRA **ppapixd, 00350 L_PTRA **ppaboxd) 00351 { 00352 l_int32 i, imax; 00353 BOX *box; 00354 PIX *pix; 00355 00356 ptraGetMaxIndex(papixs, &imax); 00357 *ppapixd = ptraCreate(imax + 1); 00358 *ppaboxd = ptraCreate(imax + 1); 00359 for (i = 0; i <= imax; i++) { 00360 pix = pixCopy(NULL, (PIX *)ptraGetPtrToItem(papixs, i)); 00361 box = boxCopy((BOX *)ptraGetPtrToItem(paboxs, i)); 00362 ptraAdd(*ppapixd, pix); 00363 ptraAdd(*ppaboxd, box); 00364 } 00365 return; 00366 } 00367 00368 00369 static void 00370 DisplayResult(PIXA *pixac, 00371 PIXA **ppixa, 00372 l_int32 w, 00373 l_int32 h, 00374 l_int32 newline) 00375 { 00376 PIX *pixd; 00377 00378 pixd = pixaDisplay(*ppixa, w, h); 00379 pixSaveTiled(pixd, pixac, 1, newline, 30, 8); 00380 pixDestroy(&pixd); 00381 pixaDestroy(ppixa); 00382 return; 00383 } 00384 00385