summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'leptonica/prog/listtest.c')
-rw-r--r--leptonica/prog/listtest.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/leptonica/prog/listtest.c b/leptonica/prog/listtest.c
new file mode 100644
index 00000000..ecbb43df
--- /dev/null
+++ b/leptonica/prog/listtest.c
@@ -0,0 +1,279 @@
+/*====================================================================*
+ - Copyright (C) 2001 Leptonica. All rights reserved.
+ -
+ - Redistribution and use in source and binary forms, with or without
+ - modification, are permitted provided that the following conditions
+ - are met:
+ - 1. Redistributions of source code must retain the above copyright
+ - notice, this list of conditions and the following disclaimer.
+ - 2. Redistributions in binary form must reproduce the above
+ - copyright notice, this list of conditions and the following
+ - disclaimer in the documentation and/or other materials
+ - provided with the distribution.
+ -
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
+ - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *====================================================================*/
+
+
+/*
+ * listtest.c
+ *
+ * This file tests the main functions in the generic
+ * list facility, given in list.c and list.h.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config_auto.h>
+#endif /* HAVE_CONFIG_H */
+
+#include "allheaders.h"
+
+int main(int argc,
+ char **argv)
+{
+char *filein;
+l_int32 i, n, w, h, samecount, count;
+BOX *box, *boxc;
+BOXA *boxa, *boxan;
+DLLIST *head, *tail, *head2, *tail2, *elem, *nextelem;
+PIX *pixs;
+static char mainName[] = "listtest";
+
+ if (argc != 2)
+ return ERROR_INT(" Syntax: listtest filein", mainName, 1);
+ filein = argv[1];
+ setLeptDebugOK(1);
+
+ boxa = boxan = NULL;
+ if ((pixs = pixRead(filein)) == NULL)
+ return ERROR_INT("pix not made", mainName, 1);
+
+ /* start with a boxa */
+ boxa = pixConnComp(pixs, NULL, 4);
+ n = boxaGetCount(boxa);
+
+ /*-------------------------------------------------------*
+ * Do one of these two ...
+ *-------------------------------------------------------*/
+ if (1) {
+ /* listAddToTail(): make a list by adding to tail */
+ head = NULL;
+ tail = NULL;
+ for (i = 0; i < n; i++) {
+ box = boxaGetBox(boxa, i, L_CLONE);
+ listAddToTail(&head, &tail, box);
+ }
+ } else {
+ /* listAddToHead(): make a list by adding to head */
+ head = NULL;
+ for (i = 0; i < n; i++) {
+ box = boxaGetBox(boxa, i, L_CLONE);
+ listAddToHead(&head, box);
+ }
+ }
+
+ /* list concatenation */
+ head2 = NULL; /* cons up 2nd list from null */
+ tail2 = NULL;
+ for (i = 0; i < n; i++) {
+ box = boxaGetBox(boxa, i, L_CLONE);
+ listAddToTail(&head2, &tail2, box);
+ }
+ listJoin(&head, &head2);
+
+ count = listGetCount(head);
+ lept_stderr("%d items in list\n", count);
+ listReverse(&head);
+ count = listGetCount(head);
+ lept_stderr("%d items in reversed list\n", count);
+ listReverse(&head);
+ count = listGetCount(head);
+ lept_stderr("%d items in doubly reversed list\n", count);
+
+ boxan = boxaCreate(n);
+
+ /*-------------------------------------------------------*
+ * Then do one of these ...
+ *-------------------------------------------------------*/
+ if (1) {
+ /* Removal of all elements and data from a list,
+ * without using L_BEGIN_LIST_FORWARD macro */
+ for (elem = head; elem; elem = nextelem) {
+ nextelem = elem->next;
+ box = (BOX *)elem->data;
+ boxaAddBox(boxan, box, L_INSERT);
+ elem->data = NULL;
+ listRemoveElement(&head, elem);
+ }
+ } else if (0) {
+ /* Removal of all elements and data from a list,
+ * using L_BEGIN_LIST_FORWARD macro */
+ L_BEGIN_LIST_FORWARD(head, elem)
+ box = (BOX *)elem->data;
+ boxaAddBox(boxan, box, L_INSERT);
+ elem->data = NULL;
+ listRemoveElement(&head, elem);
+ L_END_LIST
+ } else if (0) {
+ /* Removal of all elements and data from a list,
+ * using L_BEGIN_LIST_REVERSE macro */
+ tail = listFindTail(head);
+ L_BEGIN_LIST_REVERSE(tail, elem)
+ box = (BOX *)elem->data;
+ boxaAddBox(boxan, box, L_INSERT);
+ elem->data = NULL;
+ listRemoveElement(&head, elem);
+ L_END_LIST
+ } else if (0) {
+ /* boxa and boxan are same when list made with listAddToHead() */
+ tail = listFindTail(head);
+ L_BEGIN_LIST_REVERSE(tail, elem)
+ box = (BOX *)elem->data;
+ boxaAddBox(boxan, box, L_INSERT);
+ elem->data = NULL;
+ listRemoveElement(&head, elem);
+ L_END_LIST
+ for (i = 0, samecount = 0; i < n; i++) {
+ if (boxa->box[i]->w == boxan->box[i]->w &&
+ boxa->box[i]->h == boxan->box[i]->h)
+ samecount++;
+ }
+ lept_stderr(" num boxes = %d, same count = %d\n",
+ boxaGetCount(boxa), samecount);
+ } else if (0) {
+ /* boxa and boxan are same when list made with listAddToTail() */
+ L_BEGIN_LIST_FORWARD(head, elem)
+ box = (BOX *)elem->data;
+ boxaAddBox(boxan, box, L_INSERT);
+ elem->data = NULL;
+ listRemoveElement(&head, elem);
+ L_END_LIST
+ for (i = 0, samecount = 0; i < n; i++) {
+ if (boxa->box[i]->w == boxan->box[i]->w &&
+ boxa->box[i]->h == boxan->box[i]->h)
+ samecount++;
+ }
+ lept_stderr(" num boxes = %d, same count = %d\n",
+ boxaGetCount(boxa), samecount);
+ } else if (0) {
+ /* Destroy the boxes and then the list */
+ L_BEGIN_LIST_FORWARD(head, elem)
+ box = (BOX *)elem->data;
+ boxDestroy(&box);
+ elem->data = NULL;
+ L_END_LIST
+ listDestroy(&head);
+ } else if (0) {
+ /* listInsertBefore(): inserting a copy BEFORE each element */
+ L_BEGIN_LIST_FORWARD(head, elem)
+ box = (BOX *)elem->data;
+ boxc = boxCopy(box);
+ listInsertBefore(&head, elem, boxc);
+ L_END_LIST
+ L_BEGIN_LIST_FORWARD(head, elem)
+ box = (BOX *)elem->data;
+ boxaAddBox(boxan, box, L_INSERT);
+ elem->data = NULL;
+ L_END_LIST
+ listDestroy(&head);
+ } else if (0) {
+ /* listInsertAfter(): inserting a copy AFTER that element */
+ L_BEGIN_LIST_FORWARD(head, elem)
+ box = (BOX *)elem->data;
+ boxc = boxCopy(box);
+ listInsertAfter(&head, elem, boxc);
+ L_END_LIST
+ L_BEGIN_LIST_FORWARD(head, elem)
+ box = (BOX *)elem->data;
+ boxaAddBox(boxan, box, L_INSERT);
+ elem->data = NULL;
+ listRemoveElement(&head, elem);
+ L_END_LIST
+/* listDestroy(&head); */
+ } else if (0) {
+ /* Test listRemoveFromHead(), to successively
+ * remove the head of the list for all elements. */
+ count = 0;
+ while (head) {
+ box = (BOX *)listRemoveFromHead(&head);
+ boxDestroy(&box);
+ count++;
+ }
+ lept_stderr("removed %d items\n", count);
+ } else if (0) {
+ /* Another version to test listRemoveFromHead(), using
+ * an iterator macro. */
+ count = 0;
+ L_BEGIN_LIST_FORWARD(head, elem)
+ box = (BOX *)listRemoveFromHead(&head);
+ boxDestroy(&box);
+ count++;
+ L_END_LIST
+ lept_stderr("removed %d items\n", count);
+ } else if (0) {
+ /* test listRemoveFromTail(), to successively remove
+ * the tail of the list for all elements. */
+ count = 0;
+ tail = NULL; /* will find tail automatically */
+ while (head) {
+ box = (BOX *)listRemoveFromTail(&head, &tail);
+ boxDestroy(&box);
+ count++;
+ }
+ lept_stderr("removed %d items\n", count);
+ } else if (0) {
+ /* another version to test listRemoveFromTail(), using
+ * an iterator macro. */
+ count = 0;
+ tail = listFindTail(head); /* need to initialize tail */
+ L_BEGIN_LIST_REVERSE(tail, elem)
+ box = (BOX *)listRemoveFromTail(&head, &tail);
+ boxDestroy(&box);
+ count++;
+ L_END_LIST
+ lept_stderr("removed %d items\n", count);
+ } else if (0) {
+ /* Iterate backwards over the box array, and use
+ * listFindElement() to find each corresponding data structure
+ * within the list; then remove it. Should completely
+ * destroy the list. Note that listFindElement()
+ * returns the cell without removing it from the list! */
+ n = boxaGetCount(boxa);
+ for (i = 0, count = 0; i < n; i++) {
+ box = boxaGetBox(boxa, n - i - 1, L_CLONE);
+ if (i % 1709 == 0) boxPrintStreamInfo(stderr, box);
+ elem = listFindElement(head, box);
+ boxDestroy(&box);
+ if (elem) { /* found */
+ box = (BOX *)listRemoveElement(&head, elem);
+ if (i % 1709 == 0) boxPrintStreamInfo(stderr, box);
+ boxDestroy(&box);
+ count++;
+ }
+ }
+ lept_stderr("removed %d items\n", count);
+ }
+
+ lept_stderr("boxa count = %d; boxan count = %d\n",
+ boxaGetCount(boxa), boxaGetCount(boxan));
+ boxaGetExtent(boxa, &w, &h, NULL);
+ lept_stderr("boxa extent = (%d, %d)\n", w, h);
+ boxaGetExtent(boxan, &w, &h, NULL);
+ lept_stderr("boxan extent = (%d, %d)\n", w, h);
+
+ pixDestroy(&pixs);
+ boxaDestroy(&boxa);
+ boxaDestroy(&boxan);
+ return 0;
+}
+