/*====================================================================* - 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 #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; }