(Optional) Building zlib, libjpeg, libpng, libtiff and giflib

For some reason, you might want to build the image libraries liblept uses. The process involves downloading and extracting the library sources, building them, and then copying the required header files to BuildFolder\include, and the libraries to BuildFolder\lib.

Using the same runtime library

A very important consideration to keep in mind is that all parts of a program have to be built with references to the exact same runtime library. Or as Visual C++ Compiler Options /MD, /MT, /LD (Use Run-Time Library) succinctly states:

All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option (/MD, /MT, /LD).

In our case this means consistently using the Multi-threaded Debug DLL (/MDd) or the Multi-threaded DLL (/MD) compiler option. See How to link with the correct C Run-Time (CRT) library for more details. If you attempt to mix and match libraries and object files built with references to different runtime libraries you’ll get lots of warning messages similar to the following:

LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of
other libs; use /NODEFAULTLIB:library

LIBCMTD.lib(crt0dat.obj) : error LNK2005: _exit already defined in
MSVCRTD.lib(MSVCR90D.dll)

In particular you can’t even mix and match libraries built with references to the Multi-threaded Debug DLL (/MDd) runtime library with those built with references to the Multi-threaded DLL (/MD) runtime library. This is the reason why the libraries built in this section have such long filenames. They are needed to make sure that only libraries referencing the same runtime library are used together.

To diagnose these kinds of issues you can use dumpbin /directives somelibrary.lib from the command line to see which runtime library somelibrary.lib was built to use. Use dumpbin /imports somelibrary.dll to check dynamic-link libraries.

The /MD and /MDd switches were chosen because the /clr option which enables linking with .NET languages can only be used with those runtime libraries. See C Run-Time Libraries for more details.

Download and extract the image libraries

  1. Download zlib125.zip and extract its contents to BuildFolder\zlib. Note that the libpng.sln provided with libpng requires zlib to be in this location.

  2. Download lpng143.zip, jpegsr8c.zip, tiff-3.9.4.zip and giflib-4.1.6.tar.gz. Extract them to BuildFolder. You should now have:

    BuildFolder\
      giflib-4.1.6\
      include\
      jpeg-8c\
      leptonica-1.68\
      lib\
      libtiff-3.9.4\
      lpng143\
      zlib\
    

At this point you might want to empty your include and lib directories to get rid of any files that were supplied with the pre-built binaries archive.

Building zlib

  1. Open a Command Prompt window and execute C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat to set some environmental variables correctly.

  2. cd to the BuildFolder\zlib\contrib\masmx86 directory. Then execute:

    bld_ml32.bat
    

    to assemble the asm files required for the zlib Release configuration.

  3. Using Visual Studio 2008, open BuildFolder\zlib\contrib\vstudio\vc9\zlibvc.sln.

  4. Select the desired build configuration (either Debug or Release and probably Win32).

  5. Right-click zlibstat and choose Properties. Change Configuration Properties | C/C++ | Code Generation | Runtime Library to either Multi-threaded Debug DLL (/MDd) if building a Debug configuration or Multi-threaded DLL (/MD) if building a Release configuration.

    Also remove ZLIB_WINAPI from Configuration Properties | C/C++ | Preprocessor | Preprocessor Definitions. If you don’t do this you’ll get undefined symbol error messages when trying to build libpng and libtiff.

  6. Right-click zlibstat and choose Build. This will make zlibstat.lib. It will be in zlib\contrib\vstudio\vc9\x86\ZlibStatDebug or zlib\contrib\vstudio\vc9\x86\ZlibStatRelease. Copy it to BuildFolder\lib. To avoid confusion (and to match what the leptonica.vcproj settings say), rename it to follow the ClanLib naming conventions. So they should be:

    zlib125-static-mtdll.lib or
    zlib125-static-mtdll-debug.lib
    
  7. Copy zlib\zlib.h and zconf.h to BuildFolder\include.

To test the zlib static library, you first have to change the testzlib project (the supplied project just directly includes the .c source files instead of linking with the static library).

  1. From its Source Files solution folder, remove all files except for testzlib.c.

    Then right-click testzlib and choose Properties. Change Configuration Properties | Linker | General | Additional Library Directories to x86/ZlibStatRelease. To Configuration Properties | Linker | Input | Additional Dependencies add zlibstat.lib.

  2. Right-click testzlib and choose Properties. Change Configuration Properties | C/C++ | Code Generation | Runtime Library to either Multi-threaded Debug DLL (/MDd) if building a Debug configuration or Multi-threaded DLL (/MD) if building a Release configuration.

    Also remove ZLIB_WINAPI from Configuration Properties | C/C++ | Preprocessor | Preprocessor Definitions.

    Change Configuration Properties | Linker | Manifest File | Generate Manifest to Yes, otherwise when you attempt to run testzlib.exe you’ll get a “MSVCR90.dll was not found” error.

  3. Right-click testzlib and choose Build.

  4. In a Command Prompt window, cd to the BuildFolder\zlib\contrib\vstudio\vc9\x86\TestZlibRelease directory. Then execute:

    testzlib.exe testzlib.pdb
    

    You should see the following:

    file testzlib.pdb read, 1100800 bytes
    total compress size = 178215, in 34 step
    time = 125 msec = 0.125000 sec
    defcpr time QP = 129 msec = 0.129000 sec
    defcpr result rdtsc = 1025607f
    
    total uncompress size = 1100800, in 34 step
    time = 16 msec = 0.016000 sec
    uncpr  time QP = 0 msec = 0.000000 sec
    uncpr  result rdtsc = 139d5ce
    
    compare ok
    

Building libpng

  1. Open BuildFolder\lpng143\projects\visualc71\libpng.sln (Just click Next thru the Visual Studio Conversion Wizard). There are five different configurations you can build. Normally you’ll want LIB Release or LIB Debug.

  2. To be compatible with the way the other library Debug versions are built, you might want to change the LIB Debug Configuration Properties | C/C++ | General | Debug Information Format from Program Database for Edit & Continue (/ZI) to C7 Compatible (/Z7). This embeds debug information directly in the generated .lib so you don’t have to worry about also copying .pdb files.

  3. Build the libpng by right-clicking it and choosing Build. This will make libpng.lib (or libpngd.lib). They’ll be in lpng143\projects\visualc71\Win32_LIB_Release or lpng143\projects\visualc71\Win32_LIB_Debug. Copy them to BuildFolder\lib. To avoid confusion (and to match what the leptonica.vcproj settings say), rename them following the ClanLib naming conventions. So they should be:

    libpng143-static-mtdll.lib or
    libpng143-static-mtdll-debug.lib
    

    The libpng project erroneously includes a dependency on the zlib project, so you’ll get an error message about not being able to find gzio.c. Since you previously made zlib separately (specifically to avoid this problem), you can ignore this message.

  4. Copy lpng143\png.h and pngconf.h to BuildFolder\include.

You can test libpng by building pngtest.exe.

  1. Right-click pngtest and choose Properties. Change Configuration Properties | Linker | General | Additional Library Directories to ..\..\..\lib. To Configuration Properties | Linker | Input | Additional Dependencies add zlib125-static-mtdll-debug.lib.

  2. Build and run pngtest by right-clicking it and choosing Build.

    You should see the following:

    2>Testing...
    2> Testing libpng version 1.4.3
    2>   with zlib   version 1.2.5
    2>libpng version 1.4.3 - June 26, 2010
      Copyright (c) 1998-2010 Glenn Randers-Pehrson
      Copyright (c) 1996-1997 Andreas Dilger
      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. library (10403):
      libpng version 1.4.3 - June 26, 2010
    2> pngtest (10403): libpng version 1.4.3 - June 26, 2010
    2> sizeof(png_struct)=656, sizeof(png_info)=288
    2> Testing ..\..\pngtest.png:
    2> Pass 0: rwrwrwrwrwrwrwrwrw
    2> Pass 1: rwrwrwrwrwrwrwrwrw
    2> Pass 2: rwrwrwrwrwrwrwrw
    2> Pass 3: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
    2> Pass 4: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
    2> Pass 5: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
    2>         rwrwrwrw
    2> Pass 6: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
    2>         rwrwrwrwrw
    2> PASS (9782 zero samples)
    2> Filter 0 was used 21 times
    2> Filter 1 was used 15 times
    2> Filter 2 was used 52 times
    2> Filter 3 was used 10 times
    2> Filter 4 was used 33 times
    2> tIME = 7 Jun 1996 17:58:08 +0000
    2> libpng passes test
    

Building libjpeg

Unfortunately, as of jpeg-8b Visual Studio 2008 is no longer supported, only Visual Studio 2010. This seems a bit premature to me but the solution recommended by the developers is to download jpeg-8a and copy the required solution and project files.

Therefore, I supply a Visual Studio 2008 Solution for jpeg-8c in leptonica-1.68\vs2008\jpeg-8c-vs2008.zip. Extract it to BuildFolder\jpeg-8c.

  1. Open BuildFolder\jpeg-8c\jpeg.sln.

  2. Select the desired build configuration (either Debug or Release and probably Win32).

  3. Build the Solution.

  4. Copy BuildFolder\jpeg-8c\Release\jpeg.lib to BuildFolder\lib. Rename it to: libjpeg8c-static-mtdll.lib

    and/or copy BuildFolder\jpeg-8c\Debug\jpeg.lib to BuildFolder\lib. Rename it to: libjpeg8c-static-mtdll-debug.lib.

  5. Copy jpeglib.h, jconfig.h, jmorecfg.h, and jerror.h to BuildFolder\include.

To test libjpeg8c do the following:

  1. Open BuildFolder\jpeg-8c\apps.sln.

  2. Select the Release and probably Win32 build configuration.

  3. Build the Solution.

  4. Make a new directory called BuildFolder\jpeg-8c\bin and copy BuildFolder\jpeg-8c\cjpeg\Release\cjpeg.exe, BuildFolder\jpeg-8c\djpeg\Release\djpeg.exe, and BuildFolder\jpeg-8c\jpegtran\Release\jpegtran.exe to your new BuildFolder\jpeg-8c\bin directory.

  5. Copy all the test images from BuildFolder\jpeg-8c to BuildFolder\jpeg-8c\bin.

  6. Copy BuildFolder\jpeg-8c\makefile.vc to BuildFolder\jpeg-8c\bin.

  7. Open up a Command Prompt window, cd to BuildFolder\jpeg-8c\bin and run:

    /nmake makefile.vc test
    

    You should see something like:

    Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    IF EXIST testout* del testout*
    .\djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
    .\djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
    .\cjpeg -dct int -outfile testout.jpg  testimg.ppm
    .\djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
    .\cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
    .\jpegtran -outfile testoutt.jpg testprog.jpg
    fc /b testimg.ppm testout.ppm
    Comparing files testimg.ppm and TESTOUT.PPM
    FC: no differences encountered
    
    fc /b testimg.bmp testout.bmp
    Comparing files testimg.bmp and TESTOUT.BMP
    FC: no differences encountered
    
    fc /b testimg.jpg testout.jpg
    Comparing files testimg.jpg and TESTOUT.JPG
    FC: no differences encountered
    
    fc /b testimg.ppm testoutp.ppm
    Comparing files testimg.ppm and TESTOUTP.PPM
    FC: no differences encountered
    
    fc /b testimgp.jpg testoutp.jpg
    Comparing files testimgp.jpg and TESTOUTP.JPG
    FC: no differences encountered
    
    fc /b testorig.jpg testoutt.jpg
    Comparing files testorig.jpg and TESTOUTT.JPG
    FC: no differences encountered
    

Building libtiff

After a long quiet period, libtiff is undergoing a flurry of changes so it seems best to get the latest version (currently 3.9.4).

  1. Building the Software under Windows 95/98/NT/2000 with MS VC++ explains the overall process of building libtiff. However, in order to use the correct include and lib dirs, and allow creation of Debug builds without manual editing of the nmake.opt file, I supply leptonica-1.68\vs2008\libtiff3.9.4-vs2008-makefiles-for-leptonica.zip which contains custom versions of Makefile.vc, nmake.opt, libtiff\Makefile.vc and tools\Makefile.vc.

  2. Extract libtiff3.9.4-vs2008-makefiles-for-leptonica.zip to BuildFolder\tiff-3.9.4. This will overwrite the existing versions of the above files so you might want to back them up first.

  3. To build libtiff, open a Command Prompt window and first execute C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat to set some environmental variables correctly.

  4. cd to the BuildFolder\tiff-3.9.4\libtiff directory. Then do:

    nmake /f makefile.vc clean
    

    Then to make a Debug build of libtiff:

    nmake /f makefile.vc DEBUG=1
    nmake /f makefile.vc DEBUG=1 install
    

    or to make a Release build:

    nmake /f makefile.vc
    nmake /f makefile.vc install
    

    The last nmake command copies the required libtiff header files and the library to the BuildFolder\include and BuildFolder\lib directories.

  5. (Optional but recommended) To build the tiff tools, cd to the BuildFolder\tiff-3.9.4 directory.

    Then to make the tiff tools:

    nmake /f makefile.vc DEBUG=1
    

    or to make a Release build:

    nmake /f makefile.vc
    

    You can’t build the tiff tools and libtiff together initially because the linker expects to find .pdb files where the .lib is. Thus you first have to make and install libtiff394-static-mtdll(-debug).lib so that the linker can find libjpeg8c-static-mtdll.pdb and libjpeg8c-static-mtdll-debug.pdb.

    To test your build of libtiff, cd to the BuildFolder\tiff-3.9.4\tools directory, then execute the following from the command line:

    tiffinfo.exe ..\..\leptonica-1.68\prog\feyn.tif
    

    You should see the following output:

    TIFF Directory at offset 0x1989e (104606)
      Image Width: 2528 Image Length: 3300
      Resolution: 300, 300 pixels/inch
      Bits/Sample: 1
      Compression Scheme: CCITT Group 4
      Photometric Interpretation: min-is-white
      Orientation: row 0 top, col 0 lhs
      Samples/Pixel: 1
      Rows/Strip: 3300
      Planar Configuration: single image plane
    

Building giflib

  1. I supply a Visual Studio 2008 Solution for giflib in leptonica-1.68\vs2008\giflib4.1.6.zip. Extract it to BuildFolder\giflib-4.1.6\windows.

  2. giflib requires stdint.h Before building it you’ll need to download http://www.azillionmonkeys.com/qed/pstdint.h, rename it to stdint.h, and then move it to the standard Visual C++ include directory: C:\Program Files\Microsoft Visual Studio 9.0\VC\include.

  3. Open BuildFolder\giflib-4.1.6\windows\giflib\giflib.sln.

  4. Select the desired build configuration (either Debug or Release and probably Win32).

    Debug builds use the following C compiler options:

    /Od
    /D "WIN32" /D "WINDOWS32" /D "_DEBUG" /D "_LIB" /D "_OPEN_BINARY"
    /D "HAVE_IO_H" /D "HAVE_FCNTL_H" /D "HAVE_STDARG_H" /D "HAVE_BASETSD_H"
    /D "HAVE_STDINT_H" /D "HAVE_SYS_TYPES_H" /D "_MBCS"
    /FD /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb"
    /W3 /nologo /c /Z7 /errorReport:prompt
    

    Release builds use the following C compiler options:

    /O2 /Oi
    /D "WIN3" /D "WINDOWS32" /D "NDEBUG" /D "_LIB" /D "_OPEN_BINARY"
    /D "HAVE_IO_H" /D "HAVE_FCNTL_H" /D "HAVE_STDARG_H" /D "HAVE_BASETSD_H"
    /D "HAVE_STDINT_H" /D "HAVE_SYS_TYPES_H" /D "_MBCS"
    /FD /EHsc /MD /Fo"Release\\" /Fd"Release\vc90.pdb"
    /W3 /nologo /c /errorReport:prompt
    
  5. Build the Solution.

    This will make giflib.lib (or giflibd.lib). They’ll be in BuildFolder\giflib-4.1.6\windows\giflib\Release or BuildFolder\giflib-4.1.6\windows\giflib\Debug. Copy them to BuildFolder\lib. To avoid confusion (and to match what the leptonica.vcproj settings say), rename them following the ClanLib naming conventions. So they should be:

    giflib416-static-mtdll.lib or
    giflib416-static-mtdll-debug.lib
    
  6. Copy giflib-4.1.6\lib\gif_lib.h to BuildFolder\include.

  7. To help test giflib, the Solution also makes giftext in the same directory that it puts the library. cd to that directory and then run the following command:

    giftext ..\..\..\pic\porsche.gif
    

    You should see the following:

    ..\..\..\pic\porsche.gif:
            Screen Size - Width = 320, Height = 200.
            ColorResolution = 4, BitsPerPixel = 5, BackGround = 0.
            Has Global Color Map.
    Image #1:
            Image Size - Left = 0, Top = 0, Width = 320, Height = 200.
            Image is Non Interlaced.
            No Image Color Map.
    Gif file terminated normally.
    

Re-adding GIF support to liblept

The include\leptonica\environ.h that is part of the pre-built binary package already has GIF support enabled. However, if you are building from the official distribution of liblept you have to turn on giflib support yourself.

  1. Edit leptonica-1.68\src\environ.h. Change:

    #define  HAVE_LIBGIF      0
    

    to:

    #define  HAVE_LIBGIF      1
    
  2. Copy the changed leptonica-1.68\src\environ.h to BuildFolder\include\leptonica.

Statically linking with giflib

Any applications that statically link with either liblept168-static-mtdll.lib or liblept168-static-mtdll-debug.lib will also have to be linked with giflib now. This is already done with the supplied ioformats_reg project but we’ll demonstrate the process anyway by building a LIB Debug version of gifio_reg to make sure the library was built correctly.

  1. See Using the Create Leptonica prog Project AddIn to create a Visual Studio 2008 Project for leptonica-1.68\prog\gifio_reg.c.

  2. In Solution Explorer right-click gifio_reg, then choose Properties from the context menu.

  3. Set Configuration: to LIB Debug.

  4. Add giflib$(GIFLIB_VERSION)-static-mtdll-debug.lib to Configuration Properties | Linker | Input | Additional Dependencies. (You would add giflib$(GIFLIB_VERSION)-static-mtdll.lib if you were building LIB Release)

  5. Right-click gifio_reg and choose Set as Startup Project.

  6. Choose Build ‣ Build gifio_reg (Shift+F6).

  7. Choose Debug ‣ Start Debugging (F5).

    A Command Prompt window will pop-up, and show something like the following:

    Read time for 8 Mpix 1 bpp:   0.281 sec
    Write time for 8 Mpix 1 bpp:   0.438
    Correct for feyn.tif
       depth: pixs = 1, pix1 = 1
    Correct for weasel2.4g.png
       depth: pixs = 2, pix1 = 2
    Correct for weasel4.16c.png
       depth: pixs = 4, pix1 = 4
    Info in pixEqualWithCmap: colormap sizes are different
    Correct for dreyfus8.png
       depth: pixs = 8, pix1 = 8
    Info in pixEqualWithCmap: colormap sizes are different
    Correct for weasel8.240c.png
       depth: pixs = 8, pix1 = 8
    Correct for test8.jpg
       depth: pixs = 8, pix1 = 8
    Correct for test16.tif
       depth: pixs = 16, pix1 = 8
    Info in pixConvertRGBToColormap: More than 256 colors; using octree quant with dithering
    Correct for marge.jpg
       depth: pixs = 32, pix1 = 8
    

    And then an IrFanview Thumbnails window will appear showing you a number of png’s. Hit the Escape key to close the window and exit the program.

gifio_reg IrFanview Thumbnail window output

Build liblept

Since header files may have changed, build liblept by following these instructions.

At this point you should build and create ioformats_reg by following the instructions for either the command line or Visual Studio 2008 to make sure all the image libraries were built successfully.