1 /*====================================================================*
2  -  Copyright (C) 2001 Leptonica.  All rights reserved.
3  -
4  -  Redistribution and use in source and binary forms, with or without
5  -  modification, are permitted provided that the following conditions
6  -  are met:
7  -  1. Redistributions of source code must retain the above copyright
8  -     notice, this list of conditions and the following disclaimer.
9  -  2. Redistributions in binary form must reproduce the above
10  -     copyright notice, this list of conditions and the following
11  -     disclaimer in the documentation and/or other materials
12  -     provided with the distribution.
13  -
14  -  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  -  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  -  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  -  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ANY
18  -  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  -  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  -  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  -  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  -  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  -  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  -  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
27 /*!
28  * \file convertfiles.c
29  * <pre>
30  *
31  *      Conversion to 1 bpp
32  *          l_int32    convertFilesTo1bpp()
33  *
34  *  These are utility functions that will perform depth conversion
35  *  on selected files, writing the results to a specified directory.
36  *  We start with conversion to 1 bpp.
37  * </pre>
38  */
39 
40 #include <string.h>
41 #include "allheaders.h"
42 
43 
44 /*------------------------------------------------------------------*
45  *                        Conversion to 1 bpp                       *
46  *------------------------------------------------------------------*/
47 /*!
48  * \brief   convertFilesTo1bpp()
49  *
50  * \param[in]    dirin
51  * \param[in]    substr [optional] substring filter on filenames; can be NULL
52  * \param[in]    upscaling 1, 2 or 4; only for input color or grayscale
53  * \param[in]    thresh  global threshold for binarization; use 0 for default
54  * \param[in]    firstpage
55  * \param[in]    npages use 0 to do all from %firstpage to the end
56  * \param[in]    dirout
57  * \param[in]    outformat IFF_PNG, IFF_TIFF_G4
58  * \return  0 if OK, 1 on error
59  *
60  * <pre>
61  * Notes:
62  *      (1) Images are sorted lexicographically, and the names in the
63  *          output directory are retained except for the extension.
64  * </pre>
65  */
66 l_int32
convertFilesTo1bpp(const char * dirin,const char * substr,l_int32 upscaling,l_int32 thresh,l_int32 firstpage,l_int32 npages,const char * dirout,l_int32 outformat)67 convertFilesTo1bpp(const char  *dirin,
68                    const char  *substr,
69                    l_int32      upscaling,
70                    l_int32      thresh,
71                    l_int32      firstpage,
72                    l_int32      npages,
73                    const char  *dirout,
74                    l_int32      outformat)
75 {
76 l_int32  i, nfiles;
77 char     buf[512];
78 char    *fname, *tail, *basename;
79 PIX     *pixs, *pixg1, *pixg2, *pixb;
80 SARRAY  *safiles;
81 
82     PROCNAME("convertFilesTo1bpp");
83 
84     if (!dirin)
85         return ERROR_INT("dirin", procName, 1);
86     if (!dirout)
87         return ERROR_INT("dirout", procName, 1);
88     if (upscaling != 1 && upscaling != 2 && upscaling != 4)
89         return ERROR_INT("invalid upscaling factor", procName, 1);
90     if (thresh <= 0) thresh = 180;
91     if (firstpage < 0) firstpage = 0;
92     if (npages < 0) npages = 0;
93     if (outformat != IFF_TIFF_G4)
94         outformat = IFF_PNG;
95 
96     safiles = getSortedPathnamesInDirectory(dirin, substr, firstpage, npages);
97     if (!safiles)
98         return ERROR_INT("safiles not made", procName, 1);
99     if ((nfiles = sarrayGetCount(safiles)) == 0) {
100         sarrayDestroy(&safiles);
101         return ERROR_INT("no matching files in the directory", procName, 1);
102     }
103 
104     for (i = 0; i < nfiles; i++) {
105         fname = sarrayGetString(safiles, i, L_NOCOPY);
106         if ((pixs = pixRead(fname)) == NULL) {
107             L_WARNING("Couldn't read file %s\n", procName, fname);
108             continue;
109         }
110         if (pixGetDepth(pixs) == 32)
111             pixg1 = pixConvertRGBToLuminance(pixs);
112         else
113             pixg1 = pixClone(pixs);
114         pixg2 = pixRemoveColormap(pixg1, REMOVE_CMAP_TO_GRAYSCALE);
115         if (pixGetDepth(pixg2) == 1) {
116             pixb = pixClone(pixg2);
117         } else {
118             if (upscaling == 1)
119                 pixb = pixThresholdToBinary(pixg2, thresh);
120             else if (upscaling == 2)
121                 pixb = pixScaleGray2xLIThresh(pixg2, thresh);
122             else  /* upscaling == 4 */
123                 pixb = pixScaleGray4xLIThresh(pixg2, thresh);
124         }
125         pixDestroy(&pixs);
126         pixDestroy(&pixg1);
127         pixDestroy(&pixg2);
128 
129         splitPathAtDirectory(fname, NULL, &tail);
130         splitPathAtExtension(tail, &basename, NULL);
131         if (outformat == IFF_TIFF_G4) {
132             snprintf(buf, sizeof(buf), "%s/%s.tif", dirout, basename);
133             pixWrite(buf, pixb, IFF_TIFF_G4);
134         } else {
135             snprintf(buf, sizeof(buf), "%s/%s.png", dirout, basename);
136             pixWrite(buf, pixb, IFF_PNG);
137         }
138         pixDestroy(&pixb);
139         LEPT_FREE(tail);
140         LEPT_FREE(basename);
141     }
142 
143     sarrayDestroy(&safiles);
144     return 0;
145 }
146