├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── COPYING ├── INSTALL ├── Makefile.am ├── NEWS ├── README.md ├── configure.ac ├── debian ├── .gitignore ├── changelog ├── compat ├── control ├── copyright ├── libminidjvu-mod-dev.docs ├── libminidjvu-mod-dev.install ├── libminidjvu-mod0.install ├── minidjvu-mod.docs ├── minidjvu-mod.install ├── rules └── source │ └── format ├── doc ├── Makefile.am ├── minidjvu-mod.1 └── ru │ ├── Makefile.am │ └── minidjvu-mod.1 ├── include ├── Makefile.am └── minidjvu-mod │ ├── alg │ ├── adjust_y.h │ ├── alg.h │ ├── average.h │ ├── blitsort.h │ ├── classify.h │ ├── clean.h │ ├── compress.h │ ├── delegate.h │ ├── erosion.h │ ├── nosubst.h │ ├── render.h │ ├── smooth.h │ └── split.h │ ├── base │ ├── 0porting.h │ ├── 1error.h │ ├── 2io.h │ ├── 3graymap.h │ ├── 4bitmap.h │ ├── 5image.h │ ├── 6string.h │ ├── base.h │ └── version.h │ ├── djvu │ ├── djvu.h │ └── iff.h │ ├── image-io │ ├── bmp.h │ ├── image-io.h │ ├── pbm.h │ └── tiff.h │ ├── jb2.h │ ├── matcher.h │ └── minidjvu-mod.h ├── m4 └── acinclude.m4 ├── po ├── LINGUAS ├── Makevars ├── POTFILES.in └── ru.po ├── src ├── README ├── alg │ ├── README │ ├── adjust_y.c │ ├── average.c │ ├── blitsort.c │ ├── classify.c │ ├── clean.c │ ├── compress.c │ ├── delegate.c │ ├── erosion.c │ ├── render.c │ ├── smooth.c │ └── split.c ├── base │ ├── 0porting.c │ ├── 1error.c │ ├── 2io.c │ ├── 3graymap.c │ ├── 4bitmap.c │ ├── 5image.c │ ├── 6string.c │ ├── README │ ├── mdjvucfg.h │ └── version.c ├── djvu │ ├── bs.cpp │ ├── bs.h │ ├── djvudir.cpp │ ├── djvuinfo.c │ ├── djvuload.c │ ├── djvusave.c │ └── iff.c ├── image-io │ ├── bmp.c │ ├── pbm.c │ ├── tiff.c │ ├── tiffload.c │ └── tiffsave.c ├── jb2 │ ├── README │ ├── bmpcoder.cpp │ ├── bmpcoder.h │ ├── jb2coder.cpp │ ├── jb2coder.h │ ├── jb2const.h │ ├── jb2load.cpp │ ├── jb2save.cpp │ ├── proto.c │ ├── zp.cpp │ └── zp.h ├── matcher │ ├── bitmaps.c │ ├── bitmaps.h │ ├── common.h │ ├── cuts.c │ ├── frames.c │ ├── no_mdjvu.h │ └── patterns.c └── windows │ └── minidjvu.nsi ├── tools ├── README ├── minidjvu-mod.c └── settings-reader │ ├── AppOptions.cpp │ ├── AppOptions.h │ ├── Arrays.cpp │ ├── Arrays.h │ ├── ByteStream.cpp │ ├── ByteStream.h │ ├── COPYING │ ├── COPYRIGHT │ ├── DjVuGlobal.cpp │ ├── DjVuGlobal.h │ ├── GContainer.cpp │ ├── GContainer.h │ ├── GException.cpp │ ├── GException.h │ ├── GOS.cpp │ ├── GOS.h │ ├── GSmartPointer.cpp │ ├── GSmartPointer.h │ ├── GString.cpp │ ├── GString.h │ ├── GURL.cpp │ ├── GURL.h │ ├── GUnicode.cpp │ ├── ParsingByteStream.cpp │ ├── ParsingByteStream.h │ ├── README │ ├── SettingsReader.cpp │ ├── SettingsReader.h │ ├── SettingsReaderAdapter.cpp │ ├── SettingsReaderAdapter.h │ ├── UnicodeByteStream.cpp │ ├── UnicodeByteStream.h │ ├── atomic.cpp │ └── atomic.h └── wscript /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '39 10 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'cpp', 'python' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | # - name: Autobuild 57 | # uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | - run: | 67 | sudo -n apt-get install -y autopoint gettext 68 | autoreconf --install 69 | ./configure 70 | make 71 | 72 | - name: Perform CodeQL Analysis 73 | uses: github/codeql-action/analyze@v1 74 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.la 2 | *.lo 3 | *.o 4 | .deps/ 5 | .dirstamp 6 | .libs/ 7 | /ABOUT-NLS 8 | /aclocal.m4 9 | /autom4te.cache/ 10 | /config.h 11 | /config.log 12 | /config.status 13 | /config/config.guess 14 | /config/config.h.in 15 | /config/config.rpath 16 | /config/config.sub 17 | /config/depcomp 18 | /config/install-sh 19 | /config/ltmain.sh 20 | /config/missing 21 | /configure 22 | /libtool 23 | /m4/*.m4 24 | /minidjvu-mod 25 | /minidjvu-mod.pc 26 | /po/Makefile.in.in 27 | /po/Makevars.template 28 | /po/POTFILES 29 | /po/Rules-quot 30 | /po/boldquot.sed 31 | /po/en@boldquot.header 32 | /po/en@quot.header 33 | /po/insert-header.sin 34 | /po/minidjvu-mod.pot 35 | /po/quot.sed 36 | /po/remove-potcdate.sed 37 | /po/remove-potcdate.sin 38 | /po/ru.gmo 39 | /po/stamp-po 40 | /stamp-h1 41 | Makefile 42 | Makefile.in 43 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | USUAL AUTOTOOLS-BASED INSTALLATION 2 | __________________ 3 | 4 | Check that development package of libtiff is installed. 5 | Run: 6 | autoreconf --install 7 | ./configure 8 | make 9 | make install 10 | Will install minidjvu-mod executable into /usr/local/bin/, as well as 11 | various support files, documentation, development files, etc. 12 | 13 | 14 | 15 | BLOODSHED DEV-C++ 16 | _________________ 17 | 18 | In case if you want to compile it for Windows, there's a project 19 | file for Bloodshed Dev-C++. You will also need Libtiff for Windows, 20 | which may be found here: 21 | http://gnuwin32.sourceforge.net/packages/tiff.htm 22 | 23 | 24 | 25 | CUSTOM COMPILATION 26 | __________________ 27 | 28 | If you want to compile it all manually, read this. 29 | 30 | The release directory should be treated as an include directory 31 | (usually -I or /I option). That applies both to the library and the program. 32 | 33 | The library is built from sources in `minidjvu-mod' subdirectory. 34 | The program is built from sources in `src' subdirectory. 35 | 36 | To enable TIFF support, define HAVE_LIBTIFF to 1, add libtiff include directory 37 | to the include path, then link against libtiff. 38 | 39 | 40 | 41 | OTHERWISE 42 | _________ 43 | 44 | Under Linux, you can always try something like 45 | 46 | g++ -Iinclude `find -name "*.c*"` -O2 -o minidjvu-mod 47 | 48 | or, if you want TIFF support, 49 | 50 | g++ -DHAVE_LIBTIFF=1 -Iinclude `find -name "*.c*"` -O2 -ltiff -o minidjvu-mod 51 | 52 | Under MSVC, watch for those __declspec directives in 53 | `minidjvu-mod/base/0porting/0porting.h' - if you wish a DLL, turn them on. 54 | 55 | 56 | 57 | COMPILING ON MAC 58 | ________________ 59 | 60 | That instruction was useful when there were configure scripts (are they 61 | really useful if they can't handle the Mac stuff?). 62 | 63 | /* This instructions were kindly sent to me by Alejandro David Weil. 64 | * Apparently, there are some problems with Macs, but I don't know why. 65 | */ 66 | 67 | After some tries I got minidjvu-mod built and running on mac os X panther. 68 | I had to make this: 69 | 70 | 1. setup: 71 | export MACOSX_DEPLOYMENT_TARGET=10.3 72 | 73 | 2. run configure in this way: 74 | LDFLAGS="-L/sw/lib" ./configure 75 | 76 | 3.before compile, modify file libtool changing the allow_undefined_flag to: 77 | allow_undefined_flag="-undefined dynamic_lookup" 78 | 79 | 4. now run: 80 | make 81 | 82 | 83 | 84 | PORTING 85 | _______ 86 | 87 | Browse through `minidjvu-mod/base/0porting.h' to see if it needs changing. 88 | What next, I don't know :) 89 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | SUBDIRS = include doc po 4 | 5 | AM_CPPFLAGS = -Iinclude 6 | AM_CPPFLAGS += -D__STRICT_ANSI__ 7 | AM_CPPFLAGS += -DNDEBUG 8 | 9 | WARNFLAGS = -Wall 10 | WARNFLAGS += -Wshadow 11 | WARNFLAGS += -pedantic-errors -Wpointer-arith -Waggregate-return 12 | WARNFLAGS += -Wlong-long -Wredundant-decls -Wcast-qual -Wcast-align 13 | WARNFLAGS += -Wmissing-declarations 14 | 15 | AM_CFLAGS = $(WARNFLAGS) -Wmissing-prototypes -Wstrict-prototypes $(OPENMP_CXXFLAGS) -std=c11 -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE 16 | AM_CXXFLAGS = $(WARNFLAGS) $(OPENMP_CXXFLAGS) -std=c++11 -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE 17 | 18 | localedir = $(datadir)/locale 19 | DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ 20 | 21 | lib_LTLIBRARIES = libminidjvu-mod.la libminidjvu-mod-settings.la 22 | #noinst_LTLIBRARIES = libminidjvu-mod-settings.la 23 | 24 | libminidjvu_mod_la_SOURCES = src/matcher/no_mdjvu.h src/matcher/bitmaps.h \ 25 | src/matcher/common.h src/djvu/bs.h src/jb2/jb2coder.h \ 26 | src/jb2/bmpcoder.h src/jb2/zp.h src/jb2/jb2const.h \ 27 | src/base/mdjvucfg.h src/matcher/cuts.c src/matcher/patterns.c \ 28 | src/matcher/frames.c src/matcher/bitmaps.c \ 29 | src/alg/erosion.c src/alg/smooth.c src/alg/delegate.c \ 30 | src/alg/classify.c src/alg/render.c src/alg/clean.c \ 31 | src/alg/adjust_y.c src/alg/blitsort.c src/alg/split.c \ 32 | src/alg/average.c src/alg/compress.c src/djvu/djvuload.c \ 33 | src/djvu/djvusave.c src/djvu/djvuinfo.c src/djvu/iff.c \ 34 | src/image-io/tiffload.c src/image-io/tiff.c src/image-io/pbm.c \ 35 | src/image-io/tiffsave.c src/image-io/bmp.c src/jb2/proto.c \ 36 | src/base/3graymap.c src/base/2io.c src/base/5image.c \ 37 | src/base/4bitmap.c src/base/version.c src/base/6string.c \ 38 | src/base/1error.c src/base/0porting.c src/djvu/djvudir.cpp \ 39 | src/djvu/bs.cpp src/jb2/jb2coder.cpp src/jb2/bmpcoder.cpp \ 40 | src/jb2/jb2load.cpp src/jb2/zp.cpp src/jb2/jb2save.cpp 41 | 42 | libminidjvu_mod_settings_la_SOURCES = \ 43 | tools/settings-reader/Arrays.cpp tools/settings-reader/Arrays.h \ 44 | tools/settings-reader/atomic.cpp tools/settings-reader/atomic.h \ 45 | tools/settings-reader/ByteStream.cpp tools/settings-reader/ByteStream.h \ 46 | tools/settings-reader/DjVuGlobal.cpp tools/settings-reader/DjVuGlobal.h \ 47 | tools/settings-reader/GContainer.cpp tools/settings-reader/GContainer.h \ 48 | tools/settings-reader/GException.cpp tools/settings-reader/GException.h \ 49 | tools/settings-reader/GOS.cpp tools/settings-reader/GOS.h \ 50 | tools/settings-reader/GSmartPointer.cpp tools/settings-reader/GSmartPointer.h \ 51 | tools/settings-reader/GString.cpp tools/settings-reader/GString.h \ 52 | tools/settings-reader/GUnicode.cpp \ 53 | tools/settings-reader/GURL.cpp tools/settings-reader/GURL.h \ 54 | tools/settings-reader/ParsingByteStream.cpp tools/settings-reader/ParsingByteStream.h \ 55 | tools/settings-reader/UnicodeByteStream.cpp tools/settings-reader/UnicodeByteStream.h \ 56 | tools/settings-reader/SettingsReader.cpp tools/settings-reader/SettingsReader.h \ 57 | tools/settings-reader/AppOptions.cpp tools/settings-reader/AppOptions.h \ 58 | tools/settings-reader/SettingsReaderAdapter.cpp 59 | 60 | bin_PROGRAMS = minidjvu-mod 61 | 62 | minidjvu_mod_SOURCES = tools/minidjvu-mod.c 63 | 64 | minidjvu_mod_LDADD = libminidjvu-mod.la libminidjvu-mod-settings.la 65 | 66 | minidjvu-mod.pc: 67 | echo 'prefix=$(prefix)' > $@ 68 | echo 'exec_prefix=$(exec_prefix)' >> $@ 69 | echo 'includedir=$(includedir)' >> $@ 70 | echo 'libdir=$(libdir)' >> $@ 71 | echo >> $@ 72 | echo 'Name: $(PACKAGE_TARNAME)' >> $@ 73 | echo 'Description: $(PACKAGE_NAME)' >> $@ 74 | echo 'URL: $(PACKAGE_URL)' >> $@ 75 | echo 'Version: $(PACKAGE_VERSION)' >> $@ 76 | echo 'Cflags: -I$(includedir)' >> $@ 77 | echo 'Libs: -L$(libdir) -lminidjvu-mod' >> $@ 78 | echo 'Libs.private: $(LDFLAGS) $(LIBS)' >> $@ 79 | 80 | pkgconfigdir = $(libdir)/pkgconfig 81 | pkgconfig_DATA = minidjvu-mod.pc 82 | 83 | MOSTLYCLEANFILES = $(pkgconfig_DATA) 84 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | --- 2 | 0.9m07 3 | --- 4 | Allow directory as an input command line argument. Encoder will process all 5 | supported images (TIFF, BMP, PBM) found in it (non recursive) in alphabetical 6 | order. 7 | Change the way DIRM saved to bundled multipage document to workaround problems 8 | caused by limitation on number simultaniously opened file handles. 9 | bugfix: correct reading chunk id of the image from the settings file. 10 | 11 | --- 12 | 0.9m06 13 | --- 14 | Use DjVuLibre's connected components detection algorithm as old contour walking 15 | approach sometimes failed to detect characters in table rects. 16 | Enforce lossless classification for the not-a-letter elements. Now pieces of the 17 | graphics, like table lines, may be losslessly compressed in shared dictionary. 18 | Empty Sjbz chunk is not saved for empty pages anymore. 19 | bugfix: now images with same basename (but different paths) may be used in 20 | one bundled document. Their chunk ids (constructed from basename by default) 21 | are ensured to be unique. Settings file may be used to control page chunk id 22 | of the corresponding image. 23 | 24 | --- 25 | 0.9m05 26 | --- 27 | 28 | Replace classifier with a more accurate version. No ceache is longer 29 | used in it so RAM consumption become smaller. -C option has been removed. 30 | So now only one classifier is supported. 31 | bugfix: missing AT&T id in single-page djvus 32 | bugfix: long horisontal lines was splitted to a too small pieces 33 | bugfix: Fixed few minor bugs 34 | 35 | --- 36 | 0.9m04 37 | --- 38 | Fixed a bug with case-sensitive filesystems 39 | 40 | --- 41 | 0.9m03 42 | --- 43 | Multiple bugs fixed. 44 | 45 | --- 46 | 0.9m02 47 | --- 48 | Added settings file support that may be passed via -S key. Settings file allows to 49 | fine-tune DjVu encoding process and set per-page/per-djbz parameters. 50 | Documentation and translation is updated. 51 | 52 | --- 53 | 0.9m01 54 | --- 55 | A forked modified version. From now on fork version will contain version of minidjvu 56 | that it based on + "m" + version of modification. 57 | 58 | --- 59 | 0.9 60 | --- 61 | Relicensed to GPL3+. 62 | 63 | --- 64 | 0.8 65 | --- 66 | Pattern matching algorithm is adjusted to prevent some undesired 67 | substitutions (for example, quite different shapes sometimes were unified 68 | if minidjvu could somehow link them with a chunk of intermediate forms). 69 | bugfix: specifying aggression level above 100 actually resulted in producing 70 | larger files. 71 | Letter averaging now works also in multipage mode. 72 | minidjvu now produces multipage DJVU documents (either bundled or indirect) 73 | when processing images in the multipage mode. 74 | A new file naming convention for the multipage mode: pages are now generated with the 75 | same base names as the original images, just the extension is changed to 76 | 'djvu'. A numerical suffix is added to the base name in case of a name clash. 77 | So the 'pattern' parameter is gone: instead the same command line syntax is used 78 | both for single page and multipage mode. 79 | Localization via gettext (currently doesn't work under Windows) implemented 80 | and a Russian man page added. 81 | Configure scripts rewritten from scratch and added to the source tree. 82 | The minidjvu library has been separated from the executable (once again). 83 | However under Windows (mingw32) a single statically linked binary is generated 84 | by default. 85 | Multipage TIFF files now directly supported. 86 | The Windows installable package is now called just "minidjvu", as all "friends" are gone. 87 | 88 | --- 89 | 0.7 90 | --- 91 | bugfix: no more attempts to substitute pictures on multipage compression 92 | bugfix: no longer writes full paths to INCL chunks 93 | Memory leaks (hopefully) eliminated. 94 | Slightly increased aggression. 95 | A javascripted page illustrating using the most common options; 96 | under Windows, that will be a GUI (not too pretty, but better than nothing). 97 | 98 | 99 | --- 100 | 0.6 101 | --- 102 | bugfix: new pattern matcher works multipagely 103 | Letter averaging. Only single-page for now. 104 | (I'm still not completely convinced that it's the Right Thing.) 105 | pages-per-dict now defaults to 5. 106 | Directory layout changed. 107 | Configure scripts missing. I wonder whether they really should be back. 108 | (All that's because I have to use Windows due to hardware crash.) 109 | 110 | 111 | --- 112 | 0.5 113 | --- 114 | Improved pattern matcher. 115 | 116 | 117 | --- 118 | 0.4 119 | --- 120 | 121 | bugfix: no more "some weird error happened" messages on color TIFFs 122 | Binaries are built in bin/ now, where they should be 123 | Experimental multipage compression (cannot bundle pages yet, however) 124 | 125 | 126 | ---- 127 | 0.33 128 | ---- 129 | 130 | bugfix: no more crashes on pages with gray background 131 | bugfix: configure script now works with gcc3 (renamed all to C++) 132 | 133 | 134 | --- 135 | 0.3 136 | --- 137 | 138 | Lossy compression 139 | New "erosion" algorithm (gains about 10% in file size) 140 | TIFF support (through libtiff) 141 | Command-line interface improved 142 | man page added 143 | 144 | 145 | --- 146 | 0.2 147 | --- 148 | 149 | Added lossless compression (runs slow) 150 | Added "smooth" filter (gains about 5% in file size) 151 | Added minimal error-handling 152 | Documentation is now nonzero! 153 | 154 | 155 | --- 156 | 0.1 157 | --- 158 | 159 | Initial release. 160 | Supports only decompression of black-and-white single-page DjVu files. 161 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Windows: [![Build status](https://ci.appveyor.com/api/projects/status/v71a13vhb65ji614?svg=true)](https://ci.appveyor.com/project/Truf/minidjvu-mod-windows), Linux: [![Build status](https://ci.appveyor.com/api/projects/status/11629wtfwqp9ni0j?svg=true)](https://ci.appveyor.com/project/Truf/minidjvu-mod-ubuntu) 2 | 3 | minidjvu-mod is a multipage DjVu encoder and single page encoder/decoder. 4 | No colors or grayscales - just black and white. 5 | 6 | Besides DjVu, minidjvu-mod understands PBM, Windows BMP and TIFF (through libtiff). 7 | 8 | minidjvu-mod is a fork of minidjvu project made by Ilya Mezhirov and Alexey Kryukov. 9 | 10 | minidjvu is derived from DjVuLibre, the primary DjVu support library. 11 | DjVuLibre may be found at 12 | http://djvulibre.djvuzone.org 13 | 14 | 15 | Enjoy! 16 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ([2.67]) 2 | AC_INIT([minidjvu-mod],[0.9m07],[trufanovan@gmail.com],,[https://github.com/trufanov-nok/minidjvu_mod/]) 3 | AC_CONFIG_AUX_DIR(config) 4 | AC_CONFIG_HEADER(config.h:config/config.h.in) 5 | AC_CONFIG_MACRO_DIR([m4]) 6 | AC_PREFIX_DEFAULT(/usr/local) 7 | 8 | AM_INIT_AUTOMAKE([subdir-objects foreign -Wall]) 9 | 10 | AC_LANG([C++]) 11 | 12 | AM_GNU_GETTEXT([external]) 13 | AM_GNU_GETTEXT_VERSION([0.18.1]) 14 | 15 | # Checks for programs. 16 | AC_PROG_CXX 17 | AC_PROG_AWK 18 | AC_PROG_CC 19 | AC_PROG_CPP 20 | AC_PROG_INSTALL 21 | AC_PROG_LN_S 22 | AC_PROG_MAKE_SET 23 | AC_PATH_PROG(GZIP, gzip) 24 | AC_PATH_PROG(RM, rm) 25 | AM_PROG_AR 26 | 27 | LT_INIT 28 | 29 | PKG_INSTALLDIR 30 | 31 | # Checks for libraries. 32 | 33 | AC_CHECK_LIB(z, inflate) 34 | AC_CHECK_LIB(jpeg, jpeg_destroy_decompress) 35 | AC_CHECK_LIB(tiff, TIFFOpen) 36 | AC_CHECK_LIB(jemalloc,malloc) 37 | # Check for OpenMP 38 | AC_OPENMP 39 | 40 | 41 | # Checks for header files. 42 | AC_CHECK_HEADERS([libintl.h locale.h stdint.h stdlib.h string.h]) 43 | 44 | # Checks for typedefs, structures, and compiler characteristics. 45 | AC_SYS_LARGEFILE 46 | AC_HEADER_STDBOOL 47 | AC_C_INLINE 48 | AC_TYPE_SIZE_T 49 | AC_TYPE_INT16_T 50 | AC_TYPE_INT32_T 51 | AC_TYPE_SIZE_T 52 | AC_TYPE_UINT16_T 53 | AC_TYPE_UINT32_T 54 | 55 | # Checks for library functions. 56 | #AC_FUNC_MALLOC 57 | #AC_FUNC_REALLOC 58 | AC_CHECK_FUNCS([memset pow setlocale strcspn strrchr strerror]) 59 | 60 | 61 | ############################################### 62 | # start # checks required for settings-reader # 63 | ############################################### 64 | 65 | AC_CHECK_DECL([_WIN32],[have_os_win32=yes],[have_os_win32=no]) 66 | AM_CONDITIONAL([HAVE_OS_WIN32], [test "x${have_os_win32}" = "xyes"]) 67 | 68 | AC_CHECK_DECL([__APPLE__],[have_os_apple=yes],[have_os_apple=no]) 69 | AM_CONDITIONAL([HAVE_OS_APPLE], [test "x${have_os_apple}" = "xyes"]) 70 | 71 | 72 | # C++ 73 | AC_LANG(C++) 74 | AC_CXX_BOOL 75 | AC_CXX_EXCEPTIONS 76 | AC_CXX_TYPENAME 77 | AC_CXX_STDINCLUDES 78 | AC_CXX_NAMESPACES 79 | AC_CXX_MEMBER_TEMPLATES 80 | AC_CXX_INTEL_ATOMIC_BUILTINS 81 | AC_CXX_GCCTLS 82 | 83 | AC_CHECK_HEADERS(wchar.h wctype.h inttypes.h) 84 | AC_CHECK_TYPES(wchar_t) 85 | AC_CHECK_TYPES(mbstate_t,,,[#include "wchar.h"]) 86 | 87 | # Search for PTHREADS (when not on windows) 88 | have_pthread=no 89 | AM_COND_IF([HAVE_OS_WIN32],,[AC_PATH_PTHREAD([have_pthread=yes])]) 90 | 91 | # ---------------------------------------- 92 | # Stuff added to config.h 93 | # ---------------------------------------- 94 | 95 | # Fence 96 | AH_TOP([ 97 | #ifndef CONFIG_H 98 | #define CONFIG_H 99 | /* config.h: begin */ 100 | ]) 101 | 102 | # L18N Macros 103 | AH_BOTTOM([ 104 | 105 | /* - Miscellaneous */ 106 | #define AUTOCONF 1 107 | #if defined(__CYGWIN32__) || !defined(_WIN32) 108 | # define UNIX 1 109 | #endif 110 | 111 | /* - WCHAR etc.*/ 112 | #if ! defined(HAVE_WCHAR_T) 113 | #define HAS_WCHAR 0 114 | #define HAS_WCTYPE 0 115 | #define HAS_MBSTATE 0 116 | #else 117 | #define HAS_WCHAR 1 118 | #if defined(HAVE_WCTYPE_H) && defined(HAVE_ISWSPACE) 119 | #define HAS_WCTYPE 1 120 | #endif 121 | #if defined(HAVE_MBSTATE_T) && defined(HAVE_WCRTOMB) 122 | #define HAS_MBSTATE 1 123 | #endif 124 | #endif 125 | 126 | /* config.h: end */ 127 | #endif 128 | ]) 129 | 130 | ############################################# 131 | # end # checks required for settings-reader # 132 | ############################################# 133 | 134 | # Trailer 135 | AC_CONFIG_FILES([Makefile 136 | doc/Makefile 137 | doc/ru/Makefile 138 | include/Makefile 139 | po/Makefile.in]) 140 | AC_OUTPUT 141 | -------------------------------------------------------------------------------- /debian/.gitignore: -------------------------------------------------------------------------------- 1 | /*.debhelper 2 | /*.log 3 | /*.substvars 4 | /autoreconf.after 5 | /autoreconf.before 6 | /files 7 | /libminidjvu-mod-dev/ 8 | /libminidjvu-mod0/ 9 | /minidjvu-mod/ 10 | /tmp/ 11 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: minidjvu-mod 2 | Section: graphics 3 | Priority: optional 4 | Maintainer: Alexander Trufanov 5 | Build-Depends: debhelper (>= 9), dh-autoreconf, 6 | libtiff-dev, 7 | libz-dev, 8 | libjpeg-dev, 9 | libjemalloc-dev 10 | Homepage: https://github.com/trufanov-nok/minidjvu_mod 11 | #Vcs-Git: https://salsa.debian.org/debian/minidjvu-mod.git 12 | #Vcs-Browser: https://salsa.debian.org/debian/minidjvu-mod 13 | Standards-Version: 4.2.1 14 | 15 | Package: minidjvu-mod 16 | Architecture: any 17 | Depends: ${shlibs:Depends}, ${misc:Depends}, libminidjvu-mod0 (>= ${binary:Version}) 18 | Suggests: djview4 | djview3 | djvu-viewer, djvulibre-bin, pdf2djvu 19 | Description: Monochrome DjVu multipage encoder, single page encoder/decoder 20 | Minidjvu is a multipage DjVu encoder and single page encoder/decoder. 21 | No colors or grayscale, just black and white. 22 | In addition to the DjVu format, minidjvu-mod reads and writes 23 | PBM, Windows BMP, and TIFF. 24 | 25 | Package: libminidjvu-mod0 26 | Architecture: any 27 | Section: libs 28 | Pre-Depends: ${misc:Pre-Depends} 29 | Depends: ${shlibs:Depends}, ${misc:Depends} 30 | Description: Small DjVu encoder/decoder, shared library 31 | MiniDjVu shared library, for DjVu format encoding and decoding. 32 | 33 | Package: libminidjvu-mod-dev 34 | Architecture: any 35 | Section: libdevel 36 | Depends: ${shlibs:Depends}, ${misc:Depends}, libminidjvu-mod0 (= ${binary:Version}) 37 | Suggests: minidjvu-mod 38 | Description: Small DjVu encoder/decoder, development files 39 | MiniDjVu library development files, for DjVu format encoding and 40 | decoding. 41 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by: 2 | 3 | Barak A. Pearlmutter on Tue, 01 Sep 2009 12:51:48 +0200 4 | 5 | It was downloaded from: 6 | 7 | http://sourceforge.net/projects/minidjvu/files/ (tarballs) 8 | https://minidjvu.svn.sourceforge.net/svnroot/minidjvu (tracking SVN) 9 | 10 | Upstream Authors: 11 | 12 | Ilya Mezhirov 13 | Alexey Kryukov 14 | 15 | Copyright: 16 | 17 | Copyright (C) 2006 Ilya Mezhirov (original releases; most code) 18 | Copyright (C) 2009 Alexey Kryukov (some updates; v0.8 mods) 19 | Copyright (C) 2019 Alexander Trufanov (*-mod fork) 20 | 21 | License: 22 | 23 | This package is free software; you can redistribute it and/or modify 24 | it under the terms of the GNU General Public License as published by 25 | the Free Software Foundation; either version 2 of the License, or 26 | (at your option) any later version. 27 | 28 | This package is distributed in the hope that it will be useful, 29 | but WITHOUT ANY WARRANTY; without even the implied warranty of 30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 | GNU General Public License for more details. 32 | 33 | You should have received a copy of the GNU General Public License 34 | along with this package; if not, write to the Free Software 35 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 36 | 37 | On Debian systems, the complete text of the GNU General 38 | Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'. 39 | 40 | The Debian packaging is: 41 | 42 | Copyright (C) 2009 Barak A. Pearlmutter 43 | 44 | and is licensed under the GPL version 2 or (at your option) any later 45 | version, see `/usr/share/common-licenses/GPL-2'. 46 | -------------------------------------------------------------------------------- /debian/libminidjvu-mod-dev.docs: -------------------------------------------------------------------------------- 1 | NEWS 2 | README.md 3 | -------------------------------------------------------------------------------- /debian/libminidjvu-mod-dev.install: -------------------------------------------------------------------------------- 1 | usr/lib/*/libminidjvu-mod.a 2 | usr/lib/*/libminidjvu-mod.so 3 | usr/include 4 | usr/lib/*/pkgconfig/*.pc 5 | -------------------------------------------------------------------------------- /debian/libminidjvu-mod0.install: -------------------------------------------------------------------------------- 1 | usr/lib/*/libminidjvu-mod.so.* 2 | -------------------------------------------------------------------------------- /debian/minidjvu-mod.docs: -------------------------------------------------------------------------------- 1 | NEWS 2 | README.md 3 | -------------------------------------------------------------------------------- /debian/minidjvu-mod.install: -------------------------------------------------------------------------------- 1 | usr/bin 2 | usr/share/locale 3 | usr/share/man 4 | usr/lib/*/libminidjvu-mod-settings.so.* 5 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | export DH_VERBOSE=1 4 | 5 | DEB_CMAKE_EXTRA_FLAGS := -DCMAKE_BUILD_TYPE=Release 6 | 7 | %: 8 | dh $@ --with autoreconf 9 | 10 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = ru 2 | 3 | dist_man_MANS = minidjvu-mod.1 4 | 5 | doc_DATA = 6 | 7 | -------------------------------------------------------------------------------- /doc/ru/Makefile.am: -------------------------------------------------------------------------------- 1 | mandir = @mandir@/ru 2 | dist_man_MANS = minidjvu-mod.1 3 | -------------------------------------------------------------------------------- /include/Makefile.am: -------------------------------------------------------------------------------- 1 | nobase_include_HEADERS = minidjvu-mod/jb2.h minidjvu-mod/alg/classify.h \ 2 | minidjvu-mod/alg/compress.h minidjvu-mod/alg/split.h minidjvu-mod/alg/render.h \ 3 | minidjvu-mod/alg/smooth.h minidjvu-mod/alg/alg.h minidjvu-mod/alg/adjust_y.h \ 4 | minidjvu-mod/alg/clean.h minidjvu-mod/alg/nosubst.h minidjvu-mod/alg/erosion.h \ 5 | minidjvu-mod/alg/blitsort.h minidjvu-mod/alg/delegate.h \ 6 | minidjvu-mod/alg/average.h minidjvu-mod/djvu/iff.h minidjvu-mod/djvu/djvu.h \ 7 | minidjvu-mod/image-io/tiff.h minidjvu-mod/image-io/pbm.h \ 8 | minidjvu-mod/image-io/image-io.h minidjvu-mod/image-io/bmp.h \ 9 | minidjvu-mod/minidjvu-mod.h minidjvu-mod/base/4bitmap.h minidjvu-mod/base/1error.h \ 10 | minidjvu-mod/base/3graymap.h minidjvu-mod/base/0porting.h \ 11 | minidjvu-mod/base/version.h minidjvu-mod/base/6string.h \ 12 | minidjvu-mod/base/5image.h minidjvu-mod/base/base.h minidjvu-mod/base/2io.h \ 13 | minidjvu-mod/matcher.h 14 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/adjust_y.h: -------------------------------------------------------------------------------- 1 | /* 2 | * adjust_y.h - adjust y coordinates of blits so the text won't look bumpy 3 | */ 4 | 5 | /* 6 | * For every blit B pointing to a bitmap with a substitution S, 7 | * set B pointing to S instead and adjust its X and Y accordingly. 8 | * X is matched by bounding box centers, but Y is not that simple... 9 | */ 10 | MDJVU_FUNCTION void mdjvu_adjust(mdjvu_image_t image); 11 | 12 | 13 | /* 14 | * The same for multipage case. 15 | * Before the call, pages *may not* contain blits from dictionary bitmaps. 16 | */ 17 | MDJVU_FUNCTION void mdjvu_multipage_adjust(mdjvu_image_t dict, 18 | int32 npages, 19 | mdjvu_image_t *); 20 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/alg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * alg.h - and intermediate header to include all algorithms' headers 3 | */ 4 | 5 | /* algorithms are listed in the approximate order they're applied */ 6 | 7 | #include "../matcher.h" 8 | #include "render.h" 9 | #include "smooth.h" 10 | #include "split.h" 11 | #include "clean.h" 12 | #include "nosubst.h" 13 | #include "blitsort.h" 14 | #include "classify.h" 15 | #include "average.h" 16 | #include "adjust_y.h" 17 | #include "erosion.h" 18 | #include "delegate.h" 19 | #include "compress.h" 20 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/average.h: -------------------------------------------------------------------------------- 1 | /* 2 | * average.h - computing average bitmap 3 | */ 4 | 5 | 6 | /* Compute an "average" bitmap and return it. 7 | * The result is to be destroyed with mdjvu_bitmap_destroy(). 8 | * 9 | * Additionally, centers must be given. 10 | */ 11 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_average(mdjvu_bitmap_t *bitmaps, 12 | int32 n, 13 | int32 *centers_x, 14 | int32 *centers_y); 15 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/blitsort.h: -------------------------------------------------------------------------------- 1 | /* 2 | * blitsort.h - sorting blits in an image 3 | */ 4 | 5 | MDJVU_FUNCTION void mdjvu_sort_blits(mdjvu_image_t); 6 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/classify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * classify.h - classifying patterns 3 | */ 4 | 5 | 6 | #ifndef MDJVU_CLASSIFY_H 7 | #define MDJVU_CLASSIFY_H 8 | 9 | /* Classifies a set of patterns. 10 | * result - array of tags ranging from 1 to return value, 11 | * and 0 for those cells which were NULL (yes, NULLs are permitted). 12 | * Every tag has at least one pattern to which it's attached. 13 | * Equally tagged images are classified equivalent. 14 | */ 15 | 16 | MDJVU_FUNCTION int32 mdjvu_classify_patterns 17 | (mdjvu_pattern_t *, int32 *result, int32 n, int32 dpi, 18 | mdjvu_matcher_options_t, int verbose); 19 | 20 | #ifndef NO_MINIDJVU /* that's for DjVuLibre */ 21 | 22 | /* Special tag 0 is reserved for bitmaps marked "no-substitution". 23 | * If centers_needed, also extract bitmap centers from the patterns. 24 | */ 25 | MDJVU_FUNCTION int32 mdjvu_classify_bitmaps 26 | (mdjvu_image_t, int32 *result, mdjvu_matcher_options_t, int centers_needed, int verbose); 27 | 28 | 29 | 30 | /* MULTIPAGE CLASSIFICATION */ 31 | 32 | /* npages - number of pages 33 | * total_npatterns - total number of patterns (must be sum over npatterns) 34 | * npatterns[i] - number of patterns on the i-th page 35 | * dpi[i] - resolution of the i-th page 36 | * result[i] - i-th tag; tags from all pages are put consecutively 37 | * 38 | * return value - maximal tag 39 | * 40 | * XXX: dpi is not correctly handled 41 | */ 42 | 43 | MDJVU_FUNCTION int32 mdjvu_multipage_classify_patterns 44 | (int32 npages, int32 total_npatterns, const int32 *npatterns, mdjvu_pattern_t **, 45 | int32 *result, const int32 *dpi, mdjvu_matcher_options_t, 46 | void (*report)(void *, int), int verbose); 47 | 48 | MDJVU_FUNCTION int32 mdjvu_multipage_classify_bitmaps 49 | (int32 npages, int32 total_npatterns, mdjvu_image_t *, 50 | int32 *result, mdjvu_matcher_options_t, 51 | void (*report)(void *, int), int centers_needed, int verbose); 52 | 53 | 54 | /* Decide what bitmaps will be put into the dictionary (by tag). 55 | * This implementation simply chooses tags which occur more than in one page. 56 | * 57 | * Arguments: 58 | * dictionary_flags - [0..max_tag] array of 1/0 flags; it's the result 59 | */ 60 | 61 | MDJVU_FUNCTION void mdjvu_multipage_get_dictionary_flags 62 | (int32 npages, const int32 *npatterns, int32 max_tag, 63 | const int32 *tags, unsigned char *dictionary_flags); 64 | 65 | 66 | 67 | #endif /* NO_MINIDJVU */ 68 | 69 | #endif /* MDJVU_CLASSIFY_H */ 70 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/clean.h: -------------------------------------------------------------------------------- 1 | /* 2 | * clean.h - removing small flyspecks 3 | */ 4 | 5 | MDJVU_FUNCTION void mdjvu_clean(mdjvu_image_t); 6 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/compress.h: -------------------------------------------------------------------------------- 1 | /* 2 | * compress.h - using all the stuff to compress 3 | */ 4 | 5 | typedef struct MinidjvuCompressionOptions *mdjvu_compression_options_t; 6 | 7 | /* 8 | * By default, options correspond to `minidjvu-mod' run with no options. 9 | * That is, lossless encoding and not verbose. 10 | */ 11 | MDJVU_FUNCTION mdjvu_compression_options_t mdjvu_compression_options_create(void); 12 | MDJVU_FUNCTION void mdjvu_compression_options_destroy(mdjvu_compression_options_t); 13 | 14 | /* 15 | * This function gives sets matcher options. 16 | * To disable the matcher, pass NULL here (it's the default). 17 | * By calling this, you give the matcher options into ownership. 18 | * That is, DON'T destroy matcher options afterwards. 19 | */ 20 | MDJVU_FUNCTION void mdjvu_set_matcher_options(mdjvu_compression_options_t, mdjvu_matcher_options_t); 21 | MDJVU_FUNCTION void mdjvu_set_clean(mdjvu_compression_options_t, int); 22 | MDJVU_FUNCTION void mdjvu_set_verbose(mdjvu_compression_options_t, int); 23 | MDJVU_FUNCTION void mdjvu_set_no_prototypes(mdjvu_compression_options_t, int); 24 | MDJVU_FUNCTION void mdjvu_set_averaging(mdjvu_compression_options_t, int); 25 | MDJVU_FUNCTION void mdjvu_set_report(mdjvu_compression_options_t, int); 26 | MDJVU_FUNCTION void mdjvu_set_report_start_page(mdjvu_compression_options_t, int); 27 | MDJVU_FUNCTION void mdjvu_set_report_total_pages(mdjvu_compression_options_t, int); 28 | 29 | MDJVU_FUNCTION void mdjvu_compress_image(mdjvu_image_t, mdjvu_compression_options_t); 30 | MDJVU_FUNCTION mdjvu_image_t mdjvu_compress_multipage(int n, mdjvu_image_t *pages, mdjvu_compression_options_t); 31 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/delegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * delegate.h - choosing a representative over a class of letters 3 | */ 4 | 5 | MDJVU_FUNCTION void mdjvu_multipage_choose_representatives 6 | (int32 npages, 7 | mdjvu_image_t *pages, 8 | int32 max_tag, 9 | int32 *tags, 10 | mdjvu_bitmap_t *representatives, 11 | unsigned char *dictionary_flags); 12 | 13 | MDJVU_FUNCTION mdjvu_image_t mdjvu_multipage_choose_average_representatives 14 | (int32 npages, 15 | mdjvu_image_t *pages, 16 | int32 total_count, 17 | int32 max_tag, 18 | int32 *tags, 19 | mdjvu_bitmap_t *representatives, 20 | unsigned char *dictionary_flags); 21 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/erosion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * erosion.h - determine candidates for flipping by image encoder 3 | */ 4 | 5 | 6 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_get_erosion_mask(mdjvu_bitmap_t bmp); 7 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/nosubst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * nosubst.h - guessing what chunks are not letters and should not be changed 3 | */ 4 | 5 | /* 6 | * This is the algorithm that mark bitmaps that cannot have a substitution. 7 | * 8 | * First, it looks what blits are suspiciously big. They will be no-subst. 9 | * A blit with a bounding box that intersects a no-subst box will also be no-subst. 10 | * And so no-subst infection is spread until no more new no-substs are found. 11 | * 12 | * You may ask, why this \expandafter when the splitter could simply mark results 13 | * of splitting suspiciously big bitmaps as no-subst? 14 | * Answer: this algorithm works even when we've read a DjVu page and didn't 15 | * actually render it. Well, it works at least with cjb2-encoded files. 16 | */ 17 | 18 | MDJVU_FUNCTION void mdjvu_calculate_not_a_letter_flags(mdjvu_image_t); 19 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/render.h: -------------------------------------------------------------------------------- 1 | /* 2 | * render.h - rendering a split image into a bitmap 3 | */ 4 | 5 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_render(mdjvu_image_t); 6 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/smooth.h: -------------------------------------------------------------------------------- 1 | /* 2 | * smooth.h - pre-filtering bitmap before splitting 3 | */ 4 | 5 | 6 | /* 7 | * `smooth' is applied to a bitmap even before it is split. 8 | * 9 | * Right now, the algorithm flips pixels which are surrounded 10 | * by at least 3 of 4 neighboring pixels of another color. 11 | */ 12 | 13 | MDJVU_FUNCTION void mdjvu_smooth(mdjvu_bitmap_t b); 14 | -------------------------------------------------------------------------------- /include/minidjvu-mod/alg/split.h: -------------------------------------------------------------------------------- 1 | /* 2 | * split.h - splitting bitmaps to letters 3 | */ 4 | 5 | typedef struct MinidjvuSplitOptions *mdjvu_split_options_t; 6 | 7 | 8 | MDJVU_FUNCTION mdjvu_split_options_t mdjvu_split_options_create(void); 9 | /* 10 | * This is only a recomendation, nothing is guaranteed. 11 | */ 12 | MDJVU_FUNCTION void mdjvu_split_options_set_maximum_shape_size(mdjvu_split_options_t, int32 s); 13 | MDJVU_FUNCTION void mdjvu_split_options_destroy(mdjvu_split_options_t); 14 | 15 | 16 | MDJVU_FUNCTION mdjvu_image_t 17 | mdjvu_split(mdjvu_bitmap_t, int32 dpi, mdjvu_split_options_t); 18 | -------------------------------------------------------------------------------- /include/minidjvu-mod/base/0porting.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 0porting.h - a portability header 3 | */ 4 | 5 | /* 6 | * "0porting" keeps several typedefs and MDJVU_FUNCTION/MDJVU_IMPLEMENT macros. 7 | * 8 | * To compile a native Windows DLL, you need to put "__declspec(dllexport)" before 9 | * every exported function. To use a DLL, you have to put "__declspec(dllimport)" 10 | * before every function prototype you use. That's why we need macros here. 11 | * 12 | * So, a function prototype 13 | * 14 | * MDJVU_FUNCTION void mdjvu_foo(void); 15 | * 16 | * under Windows (when compiling the library) will expand into 17 | * 18 | * __declspec(dllexport) void mdjvu_foo(void); 19 | * 20 | * and when compiling any other application - into 21 | * 22 | * __declspec(dllimport) void mdjvu_foo(void); 23 | * 24 | * Under Linux this will lead to 25 | * 26 | * void mdjvu_foo(void); 27 | * 28 | * in both cases. 29 | * 30 | * (Also, under C++, there will be an `extern "C"' modifier). 31 | */ 32 | 33 | 34 | #ifndef MDJVU_USE_TIFFIO /* kluge not to typedef twice when using tiffio.h */ 35 | #ifdef HAVE_STDINT_H 36 | #include 37 | typedef int32_t int32; 38 | typedef uint32_t uint32; 39 | typedef int16_t int16; 40 | typedef uint16_t uint16; 41 | #else 42 | typedef int int32; 43 | typedef unsigned int uint32; 44 | typedef unsigned short uint16; 45 | typedef short int16; 46 | #endif 47 | #endif 48 | 49 | #ifndef HAVE_STDINT_H 50 | #define INT32_MAX 0x7FFFFFFF 51 | #endif 52 | 53 | #define MDJVU_INT32_FORMAT "%d" 54 | #define MDJVU_INT16_FORMAT "%d" 55 | #define MDJVU_UINT32_FORMAT "%u" 56 | #define MDJVU_UINT16_FORMAT "%u" 57 | 58 | /* MDJVU_FUNCTION and MDJVU_IMPLEMENT are prefixes of exported functions. 59 | * MDJVU_FUNCTION is for declarations, MDJVU_IMPLEMENT is for implementations. 60 | * So, it's like this: 61 | * 62 | * // foo.h 63 | * MDJVU_FUNCTION mdjvu_foo(void); 64 | * 65 | * // foo.c 66 | * MDJVU_IMPLEMENT mdjvu_foo(void) 67 | * { 68 | * ... 69 | * } 70 | */ 71 | 72 | #ifdef _MSC_VER 73 | #define _CRT_SECURE_NO_WARNINGS 74 | 75 | #define __LITTLE_ENDIAN 1234 76 | #define __BIG_ENDIAN 4321 77 | #define __BYTE_ORDER __LITTLE_ENDIAN 78 | #endif 79 | 80 | #if defined(__cplusplus) 81 | #define MDJVU_C_EXPORT_PREFIX extern "C" 82 | #else 83 | #define MDJVU_C_EXPORT_PREFIX 84 | #endif 85 | 86 | /* This Microsoft abomination of __declspec does not exist under mingw. 87 | */ 88 | #define MDJVU_SUPPRESS_DECLSPEC 89 | #if (defined(windows) || defined(WIN32) || defined(_WIN32)) && !defined(MDJVU_SUPPRESS_DECLSPEC) 90 | #ifdef MINIDJVU_INCLUDED_FROM_INSIDE 91 | #define MDJVU_FUNCTION MDJVU_C_EXPORT_PREFIX __declspec(dllexport) 92 | #define MDJVU_IMPLEMENT __declspec(dllexport) 93 | #else 94 | #define MDJVU_FUNCTION MDJVU_C_EXPORT_PREFIX __declspec(dllimport) 95 | #define MDJVU_IMPLEMENT __declspec(dllimport) 96 | #endif 97 | #else 98 | #define MDJVU_FUNCTION MDJVU_C_EXPORT_PREFIX 99 | #define MDJVU_IMPLEMENT 100 | #endif 101 | 102 | /* Convenience macros. */ 103 | #define MDJVU_MALLOC(T) ((T *) malloc(sizeof(T))) 104 | #define MDJVU_MALLOCV(T,N) ((T *) malloc((N) * sizeof(T))) 105 | #define MDJVU_CALLOC(T) ((T *) calloc(1, sizeof(T))) 106 | #define MDJVU_CALLOCV(T,N) ((T *) calloc(N, sizeof(T))) 107 | #define MDJVU_FREE(P) free(P) 108 | #define MDJVU_FREEV(P) free(P) 109 | 110 | 111 | /* Check that the portability typedefs work as expected. 112 | * If not, returns an error message. 113 | * Returns NULL if OK. 114 | */ 115 | MDJVU_FUNCTION const char *mdjvu_check_sanity(void); 116 | -------------------------------------------------------------------------------- /include/minidjvu-mod/base/1error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 1error.h - error handling 3 | */ 4 | 5 | typedef const struct MinidjvuError *mdjvu_error_t; 6 | 7 | /* TODO: distinguish non-bitonal and corrupted files */ 8 | 9 | typedef enum 10 | { 11 | mdjvu_error_fopen_write, 12 | mdjvu_error_fopen_read, 13 | mdjvu_error_io, 14 | mdjvu_error_corrupted_pbm, 15 | mdjvu_error_corrupted_bmp, 16 | mdjvu_error_corrupted_djvu, 17 | mdjvu_error_corrupted_jb2, 18 | mdjvu_error_corrupted_tiff, 19 | mdjvu_error_wrong_djvu_type, 20 | mdjvu_error_djvu_no_Sjbz, 21 | mdjvu_error_recursive_prototypes, 22 | mdjvu_error_tiff_support_disabled, 23 | mdjvu_error_png_support_disabled 24 | } MinidjvuErrorType; 25 | 26 | MDJVU_FUNCTION const char *mdjvu_get_error_message(mdjvu_error_t); 27 | MDJVU_FUNCTION mdjvu_error_t mdjvu_get_error(MinidjvuErrorType); 28 | -------------------------------------------------------------------------------- /include/minidjvu-mod/base/2io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 2io.h - a stdio wrapper 3 | */ 4 | 5 | 6 | /* Under Windows there is no libc. So it may well occur that minidjvu-mod uses one 7 | * stdio implementation, and an application linked against minidjvu-mod uses another. 8 | * In that case we can't exchange (FILE *) pointers reliably. So here is a simple 9 | * stdio wrapper to allow applications invoke our stdio. 10 | * 11 | * Also added some integer read/write functions. 12 | */ 13 | 14 | 15 | /* Structure MinidjvuFile is never defined. 16 | * Inside the minidjvu-mod library, mdjvu_file_t is FILE *. 17 | */ 18 | typedef struct MinidjvuFile *mdjvu_file_t; 19 | 20 | /* These functions just call stdio. So there's no documentation for them. */ 21 | 22 | MDJVU_FUNCTION mdjvu_file_t mdjvu_fopen(const char *path, const char *mode); 23 | MDJVU_FUNCTION void mdjvu_fclose(mdjvu_file_t); 24 | 25 | MDJVU_FUNCTION int32 mdjvu_fread 26 | (void *, int32 size, int32 n, mdjvu_file_t); 27 | MDJVU_FUNCTION int32 mdjvu_fwrite 28 | (const void *, int32 size, int32 n, mdjvu_file_t); 29 | 30 | MDJVU_FUNCTION void mdjvu_write_big_endian_int32(int32, mdjvu_file_t); 31 | MDJVU_FUNCTION void mdjvu_write_little_endian_int32(int32, mdjvu_file_t); 32 | MDJVU_FUNCTION int32 mdjvu_read_big_endian_int32(mdjvu_file_t); 33 | MDJVU_FUNCTION int32 mdjvu_read_little_endian_int32(mdjvu_file_t); 34 | MDJVU_FUNCTION void mdjvu_write_big_endian_int16(int16, mdjvu_file_t); 35 | MDJVU_FUNCTION void mdjvu_write_little_endian_int16(int16, mdjvu_file_t); 36 | MDJVU_FUNCTION int16 mdjvu_read_big_endian_int16(mdjvu_file_t); 37 | MDJVU_FUNCTION int16 mdjvu_read_little_endian_int16(mdjvu_file_t); 38 | -------------------------------------------------------------------------------- /include/minidjvu-mod/base/3graymap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3graymap.h - just a couple of functions, possibly will be bigger later 3 | */ 4 | 5 | 6 | /* There's no special graymap type in minidjvu-mod, and adding it is not planned. 7 | * So, graymaps are stored in three variables: unsigned char **, int32 and int32 8 | * (data, width and height). 9 | * 10 | * Overall, graymap support is poor: there is only create/destroy functions. 11 | * Since no algorithms in minidjvu-mod use graymaps yet, there's no need to have more. 12 | */ 13 | 14 | 15 | /* Create a two-dimensional array of pixels with initial value 0. 16 | * The array is in fact one-dimensional, and you may use that. 17 | * But do not permute the array of row pointers. 18 | * The returned array must be released by mdjvu_destroy_2d_array(). 19 | */ 20 | MDJVU_FUNCTION unsigned char **mdjvu_create_2d_array(int32 w, int32 h); 21 | 22 | /* Destroy a two-dimensional pixel array. */ 23 | MDJVU_FUNCTION void mdjvu_destroy_2d_array(unsigned char **); 24 | -------------------------------------------------------------------------------- /include/minidjvu-mod/base/4bitmap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 4bitmap.h - routines for handling packed bitmaps 3 | */ 4 | 5 | typedef struct MinidjvuBitmap *mdjvu_bitmap_t; 6 | 7 | 8 | #ifndef NDEBUG 9 | extern int32 alive_bitmap_counter; 10 | #endif 11 | 12 | 13 | /* Create a bitmap. 14 | * Width and height must be positive, or NULL is returned. 15 | */ 16 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_bitmap_create(int32 width, int32 height); 17 | 18 | /* Destroy a bitmap. Each created bitmap must be destroyed sometime. */ 19 | MDJVU_FUNCTION void mdjvu_bitmap_destroy(mdjvu_bitmap_t); 20 | 21 | /* Return size of a bitmap in memory in bytes. */ 22 | MDJVU_FUNCTION int mdjvu_bitmap_mem_size(mdjvu_bitmap_t bmp); 23 | 24 | /* Get the width and height of a bitmap. */ 25 | MDJVU_FUNCTION int32 mdjvu_bitmap_get_width(mdjvu_bitmap_t); 26 | MDJVU_FUNCTION int32 mdjvu_bitmap_get_height(mdjvu_bitmap_t); 27 | 28 | /* Each bitmap keeps its index. 29 | * If this bitmap is not attached to an image, the index will be -1. 30 | */ 31 | MDJVU_FUNCTION int32 mdjvu_bitmap_get_index(mdjvu_bitmap_t); 32 | MDJVU_FUNCTION void mdjvu_bitmap_set_index(mdjvu_bitmap_t, int32 new_value); 33 | 34 | /* Returns the size of a packed row in bytes. 35 | * Packing stores 8 pixels to a byte, 36 | * so the answer is (width + 7) / 8. 37 | */ 38 | MDJVU_FUNCTION int32 mdjvu_bitmap_get_packed_row_size(mdjvu_bitmap_t); 39 | 40 | 41 | /* Get a pointer to the bitmap's packed row. Use with caution. 42 | * Packing is PBM-ish: 43 | * most significant bit is the leftmost one, 44 | * bytes go left to right. 45 | */ 46 | MDJVU_FUNCTION unsigned char * 47 | mdjvu_bitmap_access_packed_row(mdjvu_bitmap_t, int32); 48 | 49 | MDJVU_FUNCTION unsigned char ** 50 | mdjvu_bitmap_access_packed_data(mdjvu_bitmap_t b); 51 | 52 | /* Fill a given row by the shape's row with the given Y coordinate. 53 | * The coordinate varies from 0 (top) to height-1 (bottom). 54 | * The memory should be enough to write bytes. 55 | * White is 0, black is an undefined nonzero value. 56 | */ 57 | MDJVU_FUNCTION void 58 | mdjvu_bitmap_unpack_row(mdjvu_bitmap_t, unsigned char *, int32); 59 | 60 | /* Same as mdjvu_bitmap_unpack_row, but writes exactly 1 for black. */ 61 | MDJVU_FUNCTION void 62 | mdjvu_bitmap_unpack_row_0_or_1(mdjvu_bitmap_t, unsigned char *, int32); 63 | 64 | /* Fill the shape's row with the given array of bytes. 65 | * 0 is white, nonzero is black. 66 | */ 67 | MDJVU_FUNCTION void 68 | mdjvu_bitmap_pack_row(mdjvu_bitmap_t, unsigned char *, int32 y); 69 | 70 | /* Copy given bytes from or to the given shape. 71 | * The given array should contain height rows, top to bottom, by width bytes. 72 | */ 73 | MDJVU_FUNCTION void mdjvu_bitmap_pack_all(mdjvu_bitmap_t, unsigned char **); 74 | MDJVU_FUNCTION void mdjvu_bitmap_unpack_all(mdjvu_bitmap_t, unsigned char **); 75 | MDJVU_FUNCTION void mdjvu_bitmap_unpack_all_0_or_1 76 | (mdjvu_bitmap_t, unsigned char **); 77 | 78 | /* Exchange and assign do NOT touch indices. */ 79 | MDJVU_FUNCTION void mdjvu_bitmap_assign(mdjvu_bitmap_t d, mdjvu_bitmap_t src); 80 | MDJVU_FUNCTION void mdjvu_bitmap_exchange(mdjvu_bitmap_t d, mdjvu_bitmap_t src); 81 | MDJVU_FUNCTION void mdjvu_bitmap_clear(mdjvu_bitmap_t); 82 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_bitmap_crop 83 | (mdjvu_bitmap_t b, int32 left, int32 top, int32 w, int32 h); 84 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_bitmap_clone(mdjvu_bitmap_t b); 85 | MDJVU_FUNCTION int mdjvu_bitmap_match(mdjvu_bitmap_t img1, mdjvu_bitmap_t img2); 86 | 87 | MDJVU_FUNCTION void mdjvu_bitmap_get_bounding_box 88 | (mdjvu_bitmap_t b, int32 *pl, int32 *pt, int32 *pw, int32 *ph); 89 | 90 | /* Remove white edges from the bitmap. 91 | * The given bitmap is changed. 92 | * The left top corner of the bitmap's bounding box is written into *x and *y. 93 | * Blits that access this shape may become invalid (add x and y to them). 94 | */ 95 | MDJVU_FUNCTION void mdjvu_bitmap_remove_margins 96 | (mdjvu_bitmap_t, int32 *x, int32 *y); 97 | 98 | /* Count the number of black pixels in the bitmap. 99 | * The results are not cached, so it uses O(width * height) time each call. 100 | */ 101 | MDJVU_FUNCTION int32 mdjvu_bitmap_get_mass(mdjvu_bitmap_t); 102 | 103 | #ifdef MINIDJVU_WRAPPERS 104 | struct MinidjvuBitmap 105 | { 106 | inline static MinidjvuBitmap *create(int32 w, int32 h) 107 | { return mdjvu_bitmap_create(w,h); } 108 | inline void destroy() 109 | { mdjvu_bitmap_destroy(this); } 110 | 111 | inline int32 get_width() 112 | { return mdjvu_bitmap_get_width(this); } 113 | inline int32 get_height() 114 | { return mdjvu_bitmap_get_height(this); } 115 | 116 | inline int32 get_index() 117 | { return mdjvu_bitmap_get_index(this); } 118 | inline void set_index(int32 new_value) 119 | { mdjvu_bitmap_set_index(this, new_value); } 120 | 121 | inline int32 get_packed_row_size() 122 | { return mdjvu_bitmap_get_packed_row_size(this); } 123 | 124 | inline unsigned char *access_packed_row(int32 y) 125 | { return mdjvu_bitmap_access_packed_row(this, y); } 126 | 127 | inline void pack_row(unsigned char *buf, int32 y) 128 | { mdjvu_bitmap_pack_row(this, buf, y); } 129 | 130 | inline void unpack_row(unsigned char *buf, int32 y) 131 | { mdjvu_bitmap_unpack_row(this, buf, y); } 132 | 133 | inline void unpack_row_0_or_1(unsigned char *buf, int32 y) 134 | { mdjvu_bitmap_unpack_row_0_or_1(this, buf, y); } 135 | 136 | inline void pack_all(unsigned char **buf2d) 137 | { mdjvu_bitmap_pack_all(this, buf2d); } 138 | 139 | inline void unpack_all(unsigned char **buf2d) 140 | { mdjvu_bitmap_unpack_all(this, buf2d);} 141 | 142 | inline void unpack_all_0_or_1(unsigned char **buf2d) 143 | { mdjvu_bitmap_unpack_all_0_or_1(this, buf2d);} 144 | 145 | inline void assign(mdjvu_bitmap_t src) 146 | { mdjvu_bitmap_assign(this, src); } 147 | inline void clear() 148 | { mdjvu_bitmap_clear(this); } 149 | 150 | inline mdjvu_bitmap_t crop(int32 l, int32 t, int32 w, int32 h) 151 | { return mdjvu_bitmap_crop(this, l, t, w, h); } 152 | 153 | inline void remove_margins(int32 *x, int32 *y) 154 | { mdjvu_bitmap_remove_margins(this, x, y); } 155 | 156 | inline int32 get_mass() 157 | { return mdjvu_bitmap_get_mass(this); } 158 | }; 159 | #endif 160 | -------------------------------------------------------------------------------- /include/minidjvu-mod/base/6string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 6string.h - some standard funtions for string manipulation 3 | */ 4 | 5 | MDJVU_FUNCTION int mdjvu_ends_with_ignore_case(const char *s, const char *prefix); 6 | 7 | -------------------------------------------------------------------------------- /include/minidjvu-mod/base/base.h: -------------------------------------------------------------------------------- 1 | /* 2 | * base.h - an intermediate header to include all `base' headers in proper order 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "version.h" 13 | -------------------------------------------------------------------------------- /include/minidjvu-mod/base/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * version.h - returning version 3 | */ 4 | 5 | /* 6 | * This is the version of the headers. 7 | */ 8 | #define MDJVU_VERSION "0.9m07" 9 | 10 | /* 11 | * This function returns the compile-time version stamp. 12 | */ 13 | MDJVU_FUNCTION const char *mdjvu_get_version(void); 14 | -------------------------------------------------------------------------------- /include/minidjvu-mod/djvu/djvu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * djvu.h - functions to load from single-page DjVuBitonal files 3 | */ 4 | 5 | #ifndef MDJVU_DJVU_H 6 | #define MDJVU_DJVU_H 7 | 8 | #include "iff.h" 9 | 10 | MDJVU_FUNCTION int mdjvu_locate_jb2_chunk(mdjvu_file_t file, int32 *plength, mdjvu_error_t *); 11 | 12 | /* 13 | * BUG: resolution is not loaded 14 | */ 15 | 16 | MDJVU_FUNCTION mdjvu_image_t mdjvu_file_load_djvu_page(mdjvu_file_t file, mdjvu_error_t *); 17 | MDJVU_FUNCTION mdjvu_image_t mdjvu_load_djvu_page(const char *path, mdjvu_error_t *); 18 | 19 | /* 20 | * 1 - success, 0 - failure 21 | * After mdjvu_file_save_djvu_page() the file cursor is before the JB2 chunk. 22 | */ 23 | MDJVU_FUNCTION int mdjvu_files_save_djvu_dir(char **elements, int *sizes, int n, 24 | mdjvu_file_t file, mdjvu_file_t* tempfiles, int num_tempfiles, mdjvu_error_t *perr); 25 | #if defined(_WIN32) || defined(__CYGWIN__) 26 | MDJVU_FUNCTION int mdjvu_filenames_save_djvu_dir(char **elements, int *sizes, int n, 27 | mdjvu_file_t file, char** temp_filenames, int num_temp_filenames, mdjvu_error_t *perr); 28 | #endif 29 | 30 | MDJVU_FUNCTION int mdjvu_file_save_djvu_dir( char **elements, int *sizes, int n, 31 | mdjvu_file_t file, mdjvu_file_t tmpfile, mdjvu_error_t *perr); 32 | MDJVU_FUNCTION int mdjvu_save_djvu_dir(char **elements, int *sizes, int n, const char *path, mdjvu_error_t *perr); 33 | 34 | MDJVU_FUNCTION int mdjvu_file_save_djvu_page(mdjvu_image_t, mdjvu_file_t, const char *dict_name, 35 | int insert_magic, mdjvu_error_t *perr, int erosion); 36 | MDJVU_FUNCTION int mdjvu_save_djvu_page(mdjvu_image_t image, const char *path, const char *dict_name, mdjvu_error_t *perr, int erosion); 37 | 38 | MDJVU_FUNCTION int mdjvu_file_save_djvu_dictionary(mdjvu_image_t, mdjvu_file_t, 39 | int insert_magic, mdjvu_error_t *, int erosion); 40 | MDJVU_FUNCTION int mdjvu_save_djvu_dictionary(mdjvu_image_t image, const char *path, mdjvu_error_t *, int erosion); 41 | 42 | MDJVU_FUNCTION void mdjvu_write_dirm_bundled(char **elements, int *sizes, int n, mdjvu_file_t f, mdjvu_error_t *perr); 43 | MDJVU_FUNCTION void mdjvu_write_dirm_indirect(char **elements, int *sizes, int n, mdjvu_file_t f, mdjvu_error_t *perr); 44 | 45 | /* Writes DjVu INFO chunk, as described in DjVu 2 Spec., 6.4.2, page 7. 46 | * Gamma and version numbers are always default. 47 | * This function does not write the chunk header. 48 | */ 49 | MDJVU_FUNCTION void mdjvu_write_info_chunk(mdjvu_file_t, mdjvu_image_t image); 50 | 51 | /* Reads DjVu INFO chunk, as described in DjVu 2 Spec., 6.4.2, page 7. 52 | * Gamma and version numbers are dropped; width, height and dpi are returned. 53 | * Pointers may be NULL. 54 | * This function assumes the cursor is positioned to the start of chunk. 55 | */ 56 | MDJVU_FUNCTION void mdjvu_read_info_chunk(mdjvu_file_t, 57 | int32 *w, int32 *h, int32 *dpi); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/minidjvu-mod/djvu/iff.h: -------------------------------------------------------------------------------- 1 | /* 2 | * iff.h - read/write IFF files (DjVu files are IFF) 3 | */ 4 | 5 | 6 | /* IFF is a very simple format that allows some parts of a file to be decorated 7 | * as "IFF chunks". An IFF chunk looks like this: 8 | * __________________________________________ _ 9 | * | | | | ... | 10 | * | padding (if needed) | ID | length | data ... | 11 | * |_____________________|____|________|______ ... _| 12 | * 13 | * IFF chunks may be nested. 14 | * 15 | * See DjVu 2 Spec., page 5, "Structure of DjVu files" for deeper description. 16 | */ 17 | 18 | 19 | /* IFF chunk identifiers are 32-bit integers. 20 | * The macro is here because MDJVU_IFF_ID("DJVU") looks better than 0x444A5655. 21 | */ 22 | #define MDJVU_IFF_ID(S) \ 23 | ((S)[0] << 24) | \ 24 | ((S)[1] << 16) | \ 25 | ((S)[2] << 8) | \ 26 | (S)[3] 27 | 28 | /* mdjvu_iff_t represents one IFF chunk. */ 29 | typedef struct MdjvuNonexistentIffStruct *mdjvu_iff_t; 30 | 31 | /* Get the ID of the chunk. */ 32 | MDJVU_FUNCTION int32 mdjvu_iff_get_id(mdjvu_iff_t); 33 | 34 | /* Get the length of the chunk's data. 35 | * Useful only when reading; returns 0 if we're writing to the chunk instead. 36 | */ 37 | MDJVU_FUNCTION int32 mdjvu_iff_get_length(mdjvu_iff_t); 38 | 39 | /* Opens a chunk for reading. The file must be seekable. */ 40 | MDJVU_FUNCTION mdjvu_iff_t mdjvu_iff_read_chunk(mdjvu_file_t); 41 | 42 | /* Opens a chunk for writing. The file must be seekable. */ 43 | MDJVU_FUNCTION mdjvu_iff_t mdjvu_iff_write_chunk(int32 id, mdjvu_file_t); 44 | 45 | /* Closes a chunk. 46 | * If we're reading, the file cursor is set to the end of chunk. 47 | * If we're writing, the file cursor must be at the end of chunk before calling. 48 | * 49 | * The mdjvu_iff_t object is destroyed. 50 | * 51 | * No checks are made to ensure that chunks are closed in the proper order 52 | * (that is, first opened - last closed). But please do it properly. 53 | */ 54 | MDJVU_FUNCTION void mdjvu_iff_close_chunk(mdjvu_iff_t, mdjvu_file_t); 55 | -------------------------------------------------------------------------------- /include/minidjvu-mod/image-io/bmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bmp.h - saving bitmaps in Windows BMP format 3 | */ 4 | 5 | /* 6 | * 1 - success, 0 - failure 7 | */ 8 | MDJVU_FUNCTION int mdjvu_save_bmp(mdjvu_bitmap_t, const char *path, int32 resolution, mdjvu_error_t *); 9 | MDJVU_FUNCTION int mdjvu_file_save_bmp(mdjvu_bitmap_t, mdjvu_file_t, int32 resolution, mdjvu_error_t *); 10 | 11 | /* 12 | * These functions return NULL if failed 13 | */ 14 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_load_bmp(const char *path, mdjvu_error_t *); 15 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_file_load_bmp(mdjvu_file_t, mdjvu_error_t *); 16 | -------------------------------------------------------------------------------- /include/minidjvu-mod/image-io/image-io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * formats.h - an intermediate header to include format support headers 3 | */ 4 | 5 | #ifndef MDJVU_IMAGE_IO_H 6 | #define MDJVU_IMAGE_IO_H 7 | 8 | #include "pbm.h" 9 | #include "bmp.h" 10 | #include "tiff.h" 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /include/minidjvu-mod/image-io/pbm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pbm.h - loading and saving in PBM ("portable bitmap") format 3 | */ 4 | 5 | /* 6 | * 1 - success, 0 - failure 7 | */ 8 | MDJVU_FUNCTION int mdjvu_save_pbm(mdjvu_bitmap_t, const char *path, mdjvu_error_t *); 9 | MDJVU_FUNCTION int mdjvu_file_save_pbm(mdjvu_bitmap_t, mdjvu_file_t, mdjvu_error_t *); 10 | 11 | /* 12 | * These functions return NULL if failed 13 | */ 14 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_load_pbm(const char *path, mdjvu_error_t *); 15 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_file_load_pbm(mdjvu_file_t, mdjvu_error_t *); 16 | -------------------------------------------------------------------------------- /include/minidjvu-mod/image-io/tiff.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tiff.h - TIFF support 3 | */ 4 | 5 | 6 | /* TODO: save resolution */ 7 | 8 | MDJVU_FUNCTION int mdjvu_save_tiff(mdjvu_bitmap_t, const char *path, mdjvu_error_t *); 9 | 10 | 11 | /* If the TIFF file has no resolution information, 12 | * then `resolution' will be unchanged. 13 | * `resolution' also may be NULL. 14 | */ 15 | MDJVU_FUNCTION mdjvu_bitmap_t mdjvu_load_tiff(const char *path, int32 *resolution, mdjvu_error_t *, uint32 idx); 16 | 17 | MDJVU_FUNCTION int mdjvu_have_tiff_support(void); 18 | 19 | MDJVU_FUNCTION void mdjvu_disable_tiff_warnings(void); 20 | 21 | MDJVU_FUNCTION uint32 mdjvu_get_tiff_page_count(const char *path); 22 | -------------------------------------------------------------------------------- /include/minidjvu-mod/jb2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jb2.h - functions to load from JB2 raw streams (that's part of DjVu format) 3 | */ 4 | 5 | 6 | /* 7 | * These functions return NULL if failed to read JB2. 8 | * Loading jb2 by path is not supported. 9 | */ 10 | MDJVU_FUNCTION mdjvu_image_t mdjvu_file_load_jb2(mdjvu_file_t, int32 length, mdjvu_error_t *); 11 | 12 | /* 13 | * 1 - success, 0 - error 14 | * Cannot save images that use shared dictionary. 15 | * With erosion turned on, this function changes the image. 16 | */ 17 | MDJVU_FUNCTION int mdjvu_save_jb2(mdjvu_image_t, const char *path, mdjvu_error_t *, int erosion); 18 | MDJVU_FUNCTION int mdjvu_file_save_jb2(mdjvu_image_t, mdjvu_file_t, mdjvu_error_t *, int erosion); 19 | 20 | MDJVU_FUNCTION int mdjvu_save_jb2_dictionary(mdjvu_image_t, const char *path, mdjvu_error_t *, int erosion); 21 | MDJVU_FUNCTION int mdjvu_file_save_jb2_dictionary(mdjvu_image_t, mdjvu_file_t, mdjvu_error_t *, int erosion); 22 | 23 | 24 | /* 25 | * This is called automatically by xxx_save_jb2() functions. 26 | * This function finds "cross-coding prototypes" (see DjVu spec). 27 | * It's VERY SLOW. 28 | */ 29 | 30 | MDJVU_FUNCTION void mdjvu_find_prototypes(mdjvu_image_t); 31 | 32 | /* 33 | * This is the multipage version. Does not search prototypes in the dictionary. 34 | * Is not invoked by xxx_save_jb2(). 35 | */ 36 | MDJVU_FUNCTION void mdjvu_multipage_find_prototypes 37 | (mdjvu_image_t dict, int32 npages, mdjvu_image_t *pages, 38 | void (*report)(void *param, int page), void *param); 39 | -------------------------------------------------------------------------------- /include/minidjvu-mod/matcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * matcher.h - matching patterns 3 | */ 4 | 5 | #ifndef MDJVU_MATCHER_H 6 | #define MDJVU_MATCHER_H 7 | 8 | 9 | typedef struct MinidjvuMatcherOptions *mdjvu_matcher_options_t; 10 | 11 | MDJVU_FUNCTION mdjvu_matcher_options_t mdjvu_matcher_options_create(void); 12 | MDJVU_FUNCTION void mdjvu_set_aggression(mdjvu_matcher_options_t, int level); 13 | 14 | /* "matcher methods" (bitmask, not enum) */ 15 | #define MDJVU_MATCHER_DEFAULT 0 16 | #define MDJVU_MATCHER_PITH_2 1 17 | #define MDJVU_MATCHER_RAMPAGE 2 18 | 19 | /* turn method on (|=) */ 20 | MDJVU_FUNCTION void mdjvu_use_matcher_method(mdjvu_matcher_options_t, int method); 21 | 22 | MDJVU_FUNCTION void mdjvu_matcher_options_destroy(mdjvu_matcher_options_t); 23 | 24 | 25 | /* To get an image ready for comparisons, one have to `prepare' it. 26 | * A prepared image is called a `pattern' here. 27 | * A pattern is mostly opaque except that its center may be retrieved. 28 | */ 29 | 30 | 31 | /* the struct itself is not defined in this header */ 32 | typedef struct MinidjvuPattern *mdjvu_pattern_t; 33 | 34 | 35 | /* Allocate a pattern and calculate all necessary information. 36 | * Memory consumption is byte per pixel + constant (with default matcher). 37 | * The pattern would be independent on the bitmap given. 38 | * (that is, you can destroy the bitmap immediately) 39 | */ 40 | #ifndef NO_MINIDJVU 41 | MDJVU_FUNCTION mdjvu_pattern_t mdjvu_pattern_create(mdjvu_matcher_options_t, mdjvu_bitmap_t, int32); 42 | #endif 43 | 44 | /* Return size of a pattern in memory in bytes */ 45 | 46 | MDJVU_FUNCTION int mdjvu_pattern_mem_size(mdjvu_pattern_t p); 47 | 48 | /* Destroy the pattern. */ 49 | 50 | MDJVU_FUNCTION void mdjvu_pattern_destroy(mdjvu_pattern_t); 51 | 52 | 53 | /* get a center (in 1/MDJVU_CENTER_QUANT pixels; defined in the header for image) */ 54 | MDJVU_FUNCTION void mdjvu_pattern_get_center(mdjvu_pattern_t, int32 *cx, int32 *cy); 55 | 56 | /* Compare patterns. 57 | * Returns 58 | * +1 if images are considered equivalent, 59 | * -1 if they are considered totally different (just to speed up things), 60 | * 0 if unknown, but probably different. 61 | * Exchanging the order of arguments should not change the outcome. 62 | * If you have found that A ~ B and B ~ C, 63 | * then you may assume A ~ C regardless of this function's result. 64 | * 65 | * Options may be NULL. 66 | */ 67 | 68 | MDJVU_FUNCTION int mdjvu_match_patterns(mdjvu_pattern_t, mdjvu_pattern_t, 69 | int32 dpi, 70 | mdjvu_matcher_options_t); 71 | 72 | 73 | /* Auxiliary functions used in pattern matcher (TODO: comment them) */ 74 | 75 | /* `result' and `pixels' may be the same array */ 76 | MDJVU_FUNCTION void mdjvu_soften_pattern(unsigned char **result, 77 | unsigned char **pixels, int32 w, int32 h); 78 | 79 | MDJVU_FUNCTION void mdjvu_get_gray_signature( 80 | unsigned char **data, int32 w, int32 h, 81 | unsigned char *result, int32 size); 82 | 83 | MDJVU_FUNCTION void mdjvu_get_black_and_white_signature( 84 | unsigned char **data, int32 w, int32 h, 85 | unsigned char *result, int32 size); 86 | 87 | #endif /* MDJVU_PATTERNS_H */ 88 | -------------------------------------------------------------------------------- /include/minidjvu-mod/minidjvu-mod.h: -------------------------------------------------------------------------------- 1 | /* 2 | * minidjvu-mod.h - the main include file for the library, includes all others 3 | */ 4 | 5 | #ifndef MINIDJVU_H 6 | #define MINIDJVU_H 7 | 8 | #include "base/base.h" 9 | #include "alg/alg.h" 10 | #include "image-io/image-io.h" 11 | #include "djvu/djvu.h" 12 | #include "jb2.h" 13 | #include "matcher.h" 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | ru 2 | -------------------------------------------------------------------------------- /po/Makevars: -------------------------------------------------------------------------------- 1 | # Makefile variables for PO directory in any package using GNU gettext. 2 | 3 | # Usually the message domain is the same as the package name. 4 | DOMAIN = $(PACKAGE) 5 | 6 | # These two variables depend on the location of this directory. 7 | subdir = po 8 | top_builddir = .. 9 | 10 | # These options get passed to xgettext. 11 | XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ 12 | 13 | # This is the copyright holder that gets inserted into the header of the 14 | # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding 15 | # package. (Note that the msgstr strings, extracted from the package's 16 | # sources, belong to the copyright holder of the package.) Translators are 17 | # expected to transfer the copyright for their translations to this person 18 | # or entity, or to disclaim their copyright. The empty string stands for 19 | # the public domain; in this case the translators are expected to disclaim 20 | # their copyright. 21 | COPYRIGHT_HOLDER = Ilya Mezhirov and Alexey Kryukov 22 | 23 | # This is the email address or URL to which the translators shall report 24 | # bugs in the untranslated strings: 25 | # - Strings which are not entire sentences, see the maintainer guidelines 26 | # in the GNU gettext documentation, section 'Preparing Strings'. 27 | # - Strings which use unclear terms or require additional context to be 28 | # understood. 29 | # - Strings which make invalid assumptions about notation of date, time or 30 | # money. 31 | # - Pluralisation problems. 32 | # - Incorrect English spelling. 33 | # - Incorrect formatting. 34 | # It can be your email address, or a mailing list address where translators 35 | # can write to without being subscribed, or the URL of a web page through 36 | # which the translators can contact you. 37 | MSGID_BUGS_ADDRESS = trufanovan@gmail.com 38 | 39 | # This is the list of locale categories, beyond LC_MESSAGES, for which the 40 | # message catalogs shall be used. It is usually empty. 41 | EXTRA_LOCALE_CATEGORIES = 42 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | # List of source files which contain translatable strings. 2 | src/alg/compress.c 3 | src/base/1error.c 4 | src/base/mdjvucfg.h 5 | tools/minidjvu-mod.c 6 | tools/settings-reader/AppOptions.cpp 7 | tools/settings-reader/SettingsReader.cpp 8 | -------------------------------------------------------------------------------- /src/README: -------------------------------------------------------------------------------- 1 | This is the source directory for the minidjvu-mod library. 2 | 3 | It contains the following subdirectories: 4 | 5 | base - basic things like bitmaps; all the other code uses the base. 6 | alg - various image processing algoritms 7 | image-io - support for some common file formats: PBM, BMP, TIFF 8 | jb2 - JB2 format support (DjVu stores bitonal images in JB2) 9 | djvu - DjVu format support (excluding JB2) 10 | matcher - the pattern matcher 11 | -------------------------------------------------------------------------------- /src/alg/README: -------------------------------------------------------------------------------- 1 | This is the collection of algorithms that together do the job. 2 | Here is the quick list of them; 3 | they are listed in the order they are naturally used to compress. 4 | 5 | smooth - remove pixels that look bad 6 | split - split a bitmap into pieces (result is a mdjvu_image_t object) 7 | clean - remove small marks 8 | nosubst - determining what pieces are letters and what are not 9 | blitsort - sorting letters in approximate reading order 10 | patterns - compare letters (to find if one may be substituted for another) 11 | classify - classify letters; uses the pattern matcher (`patterns') 12 | average - producing an "average" bitmap to use as a representative 13 | delegate - pick up a representative from each class of equivalent letters 14 | adjust_y - adjust substitution positions (otherwise the text looks bumpy) 15 | erosion - determine what pixels may be eroded 16 | -------------------------------------------------------------------------------- /src/alg/adjust_y.c: -------------------------------------------------------------------------------- 1 | /* 2 | * adjust_y.c - adjust y coordinates of blits so the text won't look bumpy 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | #define DO_NOT_ADJUST -10000 12 | 13 | 14 | /* 15 | * This algorithm was made by Leon Bottou. 16 | * I remember, I had another (simpler) version 17 | * and I couldn't see the difference between results, 18 | * but he said this version is cooler. 19 | */ 20 | 21 | 22 | /* Estimate position of baseline. 23 | * The baseline position is measured in quarter pixels. 24 | * Using fractional pixels makes a big improvement. 25 | */ 26 | static int32 compute_baseline(mdjvu_bitmap_t bitmap) 27 | { 28 | int32 w = mdjvu_bitmap_get_width(bitmap); 29 | int32 h = mdjvu_bitmap_get_height(bitmap); 30 | int32 *mass = (int32 *) malloc(h * sizeof(int32)); 31 | unsigned char *row = (unsigned char *) malloc(w); 32 | int32 i, j, m; 33 | int32 tm = 0; 34 | for (i = 0; i < h; i++) 35 | { 36 | mdjvu_bitmap_unpack_row(bitmap, row, i); 37 | for (j = 0; j < w; j++) 38 | { 39 | if (row[j]) 40 | break; 41 | } 42 | for (m = w - j; m > 0; m--) 43 | { 44 | if (row[j + m - 1]) 45 | break; 46 | } 47 | mass[h - i - 1] = m; 48 | tm += m; 49 | } 50 | 51 | m = 0; 52 | i = 0; 53 | 54 | while (m * 6 < tm * 4) 55 | { 56 | m += mass[i/4]; 57 | i += 1; 58 | } 59 | 60 | free(row); 61 | free(mass); 62 | 63 | return 4 * (h - 1) - i; 64 | } 65 | 66 | /* 67 | * Set blits to their substitutes using given x and y adjustments. 68 | * Before this, blits may not use dictionary bitmaps. 69 | */ 70 | static void update_blits(mdjvu_image_t image, int32 *x_adjust, int32 *y_adjust) 71 | { 72 | int32 b = mdjvu_image_get_blit_count(image); 73 | int32 i; 74 | for (i = 0; i < b; i++) 75 | { 76 | int32 x = mdjvu_image_get_blit_x(image, i); 77 | int32 y = mdjvu_image_get_blit_y(image, i); 78 | mdjvu_bitmap_t bitmap = mdjvu_image_get_blit_bitmap(image, i); 79 | mdjvu_bitmap_t subst = mdjvu_image_get_substitution(image, bitmap); 80 | int32 k = mdjvu_bitmap_get_index(bitmap); 81 | 82 | mdjvu_image_set_blit_x(image, i, x + x_adjust[k]); 83 | mdjvu_image_set_blit_y(image, i, y + y_adjust[k]); 84 | mdjvu_image_set_blit_bitmap(image, i, subst); 85 | } 86 | } 87 | 88 | /* 89 | * Return the baselines array. To be MDJVU_FREEV'ed later. 90 | */ 91 | static int32 *get_baselines(mdjvu_image_t image) 92 | { 93 | int32 i; 94 | int32 n = mdjvu_image_get_bitmap_count(image); 95 | int32 *baseline = MDJVU_MALLOCV(int32, n); 96 | for (i = 0; i < n; i++) 97 | { 98 | mdjvu_bitmap_t bitmap = mdjvu_image_get_bitmap(image, i); 99 | if (mdjvu_image_has_not_a_letter_flags(image) && !mdjvu_image_get_not_a_letter_flag(image, bitmap)) 100 | baseline[i] = compute_baseline(bitmap); 101 | else 102 | baseline[i] = DO_NOT_ADJUST; 103 | } 104 | return baseline; 105 | } 106 | 107 | 108 | /* 109 | * Computes x and y adjustsments. 110 | * bitmap != subst. 111 | */ 112 | static void compute_adjustments(mdjvu_bitmap_t bitmap, mdjvu_bitmap_t subst, 113 | int32 b_base, int32 s_base, 114 | int32 *dx, int32 *dy) 115 | { 116 | int32 w, h, subst_w, subst_h, adjust; 117 | 118 | /* Compute coordinate adjustment */ 119 | w = mdjvu_bitmap_get_width(bitmap); 120 | h = mdjvu_bitmap_get_height(bitmap); 121 | subst_w = mdjvu_bitmap_get_width(subst); 122 | subst_h = mdjvu_bitmap_get_height(subst); 123 | *dx = (w - subst_w) / 2; 124 | *dy = (h - subst_h) / 2; 125 | 126 | /* Refine vertical adjustment */ 127 | adjust = b_base - s_base; 128 | 129 | if (adjust < 0) 130 | adjust = - (2 - adjust) / 4; 131 | else 132 | adjust = (2 + adjust) / 4; 133 | 134 | if (abs(adjust - *dy) <= 1 + w/16 ) 135 | *dy = adjust; 136 | } 137 | 138 | MDJVU_IMPLEMENT void mdjvu_adjust(mdjvu_image_t image) 139 | { 140 | int32 b = mdjvu_image_get_blit_count(image); 141 | int32 n = mdjvu_image_get_bitmap_count(image); 142 | int32 *baseline = get_baselines(image); 143 | 144 | int32 i; 145 | int32 *x_adjust = (int32 *) calloc(n, sizeof(int32)); 146 | int32 *y_adjust = (int32 *) calloc(n, sizeof(int32)); 147 | 148 | for (i = 0; i < b; i++) 149 | { 150 | mdjvu_bitmap_t bitmap = mdjvu_image_get_blit_bitmap(image, i); 151 | mdjvu_bitmap_t subst = mdjvu_image_get_substitution(image, bitmap); 152 | assert(subst); 153 | 154 | if (subst == bitmap) continue; 155 | 156 | compute_adjustments(bitmap, subst, 157 | baseline[i], 158 | baseline[mdjvu_bitmap_get_index(subst)], 159 | &x_adjust[i], &y_adjust[i]); 160 | } 161 | 162 | MDJVU_FREEV(baseline); 163 | 164 | update_blits(image, x_adjust, y_adjust); 165 | 166 | free(x_adjust); 167 | free(y_adjust); 168 | } 169 | 170 | static void adjust_page(mdjvu_image_t dict, 171 | int32 *dict_baselines, 172 | mdjvu_image_t image) 173 | { 174 | int32 b = mdjvu_image_get_blit_count(image); 175 | int32 n = mdjvu_image_get_bitmap_count(image); 176 | int32 *baseline = get_baselines(image); 177 | 178 | int32 i; 179 | int32 *x_adjust = (int32 *) calloc(n, sizeof(int32)); 180 | int32 *y_adjust = (int32 *) calloc(n, sizeof(int32)); 181 | 182 | for (i = 0; i < b; i++) 183 | { 184 | mdjvu_bitmap_t bitmap = mdjvu_image_get_blit_bitmap(image, i); 185 | mdjvu_bitmap_t subst = mdjvu_image_get_substitution(image, bitmap); 186 | int32 subst_baseline; 187 | 188 | if (subst == bitmap || baseline[i] == DO_NOT_ADJUST) continue; 189 | 190 | if (mdjvu_image_has_bitmap(dict, subst)) 191 | subst_baseline = dict_baselines[mdjvu_bitmap_get_index(subst)]; 192 | else 193 | { 194 | assert(mdjvu_image_has_bitmap(image, subst)); 195 | subst_baseline = baseline[mdjvu_bitmap_get_index(subst)]; 196 | } 197 | 198 | compute_adjustments(bitmap, subst, 199 | baseline[i], 200 | subst_baseline, 201 | &x_adjust[i], &y_adjust[i]); 202 | } 203 | 204 | MDJVU_FREEV(baseline); 205 | 206 | update_blits(image, x_adjust, y_adjust); 207 | 208 | free(x_adjust); 209 | free(y_adjust); 210 | } 211 | 212 | 213 | MDJVU_FUNCTION void mdjvu_multipage_adjust(mdjvu_image_t dict, 214 | int32 npages, 215 | mdjvu_image_t *pages) 216 | { 217 | int32 *dict_baselines = get_baselines(dict); 218 | int32 i; 219 | for (i = 0; i < npages; i++) 220 | adjust_page(dict, dict_baselines, pages[i]); 221 | MDJVU_FREEV(dict_baselines); 222 | } 223 | -------------------------------------------------------------------------------- /src/alg/average.c: -------------------------------------------------------------------------------- 1 | /* 2 | * average.c - computing average bitmap 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_average(mdjvu_bitmap_t *bitmaps, 12 | int32 n, 13 | int32 *cx, int32 *cy) 14 | { 15 | int32 i; 16 | int32 min_x = 0, min_y = 0, max_x_plus_1 = 0, max_y_plus_1 = 0; 17 | int32 *buf; 18 | int32 buf_w, buf_h; 19 | unsigned char *row; 20 | int32 tmp_x, tmp_y; 21 | int32 threshold = n / 2; 22 | mdjvu_bitmap_t result; 23 | 24 | if (n == 1) 25 | { 26 | return mdjvu_bitmap_clone(bitmaps[0]); 27 | } 28 | 29 | for (i = 0; i < n; i++) 30 | { 31 | int32 w = mdjvu_bitmap_get_width(bitmaps[i]); 32 | int32 h = mdjvu_bitmap_get_height(bitmaps[i]); 33 | int32 ncx = cx[i] / MDJVU_CENTER_QUANT; 34 | int32 ncy = cy[i] / MDJVU_CENTER_QUANT; 35 | 36 | assert(ncx >= 0 && ncx < w); 37 | assert(ncy >= 0 && ncy < h); 38 | 39 | if (-ncx < min_x) min_x = -ncx; 40 | if (-ncy < min_y) min_y = -ncy; 41 | if (w-ncx > max_x_plus_1) max_x_plus_1 = w-ncx; 42 | if (h-ncy > max_y_plus_1) max_y_plus_1 = h-ncy; 43 | } 44 | 45 | buf_w = max_x_plus_1 - min_x; 46 | buf_h = max_y_plus_1 - min_y; 47 | buf = (int32 *) calloc(buf_w * buf_h, sizeof(int32)); 48 | row = (unsigned char *) malloc(buf_w); 49 | 50 | /* Now adding the bitmaps to the buffer */ 51 | for (i = 0; i < n; i++) 52 | { 53 | int32 w = mdjvu_bitmap_get_width(bitmaps[i]); 54 | int32 h = mdjvu_bitmap_get_height(bitmaps[i]); 55 | int32 sx = min_x + cx[i] / MDJVU_CENTER_QUANT, sy = min_y + cy[i] / MDJVU_CENTER_QUANT; 56 | int32 x, y; 57 | 58 | for (y = 0; y < h; y++) 59 | { 60 | int32 *buf_row = buf + buf_w * (y - sy); 61 | mdjvu_bitmap_unpack_row(bitmaps[i], row, y); 62 | for (x = 0; x < w; x++) 63 | { 64 | if (row[x]) 65 | buf_row[x - sx]++; 66 | } 67 | } 68 | } 69 | 70 | result = mdjvu_bitmap_create(buf_w, buf_h); 71 | for (i = 0; i < buf_h; i++) 72 | { 73 | int32 j; 74 | for (j = 0; j < buf_w; j++) 75 | { 76 | row[j] = ( buf[i * buf_w + j] > threshold ? 1 : 0 ); 77 | } 78 | mdjvu_bitmap_pack_row(result, row, i); 79 | } 80 | 81 | mdjvu_bitmap_remove_margins(result, &tmp_x, &tmp_y); 82 | 83 | free(row); 84 | free(buf); 85 | 86 | return result; 87 | } 88 | -------------------------------------------------------------------------------- /src/alg/blitsort.c: -------------------------------------------------------------------------------- 1 | /* 2 | * blitsort.c - sorting blits in an image 3 | */ 4 | 5 | /* The algorithm is taken from DjVuLibre with minor (stupid) changes. */ 6 | 7 | 8 | #include "../base/mdjvucfg.h" 9 | #include 10 | #include 11 | 12 | 13 | 14 | typedef struct 15 | { 16 | int32 left, top, right, bottom; 17 | int32 original_index; 18 | } BlitPassport; 19 | 20 | 21 | static int compare_top_edges_downward(const void *p1, const void *p2) 22 | { 23 | const BlitPassport *bp1 = (const BlitPassport *) p1; 24 | const BlitPassport *bp2 = (const BlitPassport *) p2; 25 | int32 d; 26 | d = bp1->top - bp2->top; 27 | if (d) return d; 28 | d = bp1->left - bp2->left; 29 | if (d) return d; 30 | return 0; 31 | } 32 | 33 | static int compare_left_edges_rightward(const void *p1, const void *p2) 34 | { 35 | const BlitPassport *bp1 = (const BlitPassport *) p1; 36 | const BlitPassport *bp2 = (const BlitPassport *) p2; 37 | int32 d; 38 | d = bp1->left - bp2->left; 39 | if (d) return d; 40 | d = bp1->top - bp2->top; 41 | if (d) return d; 42 | return 0; 43 | } 44 | 45 | static int compare_integers_reversed(const void *p1, const void *p2) 46 | { 47 | if (sizeof(int) == sizeof(int32)) /* hopefully compilers will optimize it */ 48 | { 49 | return * (const int *) p2 - * (const int *) p1; 50 | } 51 | else 52 | { 53 | int32 d = * (const int32 *) p2 - * (const int32 *) p1; 54 | return d > 0 ? 1 : 55 | d < 0 ? -1 : 0; 56 | } 57 | } 58 | 59 | 60 | MDJVU_IMPLEMENT void mdjvu_sort_blits(mdjvu_image_t img) 61 | { 62 | /* We're going to sort only blits with `is_a_letter' flag set. */ 63 | 64 | int32 char_blit_count = 0; 65 | int32 blit_count, i, j, maxtopchange, ccno; 66 | BlitPassport *bps; 67 | int32 *bottoms, *passport_of_blit; 68 | 69 | /* Count letter blits */ 70 | blit_count = mdjvu_image_get_blit_count(img); 71 | for (i = 0; i < blit_count; i++) 72 | { 73 | mdjvu_bitmap_t bmp = mdjvu_image_get_blit_bitmap(img, i); 74 | if (!mdjvu_image_get_not_a_letter_flag(img, bmp)) 75 | char_blit_count++; 76 | } 77 | 78 | if (char_blit_count < 2) return; 79 | 80 | /* Allocate `bps' and `bottoms' arrays */ 81 | bps = (BlitPassport *) malloc(char_blit_count * sizeof(BlitPassport)); 82 | bottoms = (int32 *) malloc(char_blit_count * sizeof(int32)); 83 | 84 | /* Fill in `bps' with character blit passports */ 85 | j = 0; 86 | for (i = 0; i < blit_count; i++) 87 | { 88 | mdjvu_bitmap_t bmp = mdjvu_image_get_blit_bitmap(img, i); 89 | if (!mdjvu_image_get_not_a_letter_flag(img, bmp)) 90 | { 91 | int32 x = bps[j].left = mdjvu_image_get_blit_x(img, i); 92 | int32 y = bps[j].top = mdjvu_image_get_blit_y(img, i);; 93 | bps[j].right = x + mdjvu_bitmap_get_width(bmp) - 1; 94 | bps[j].bottom = y + mdjvu_bitmap_get_height(bmp) - 1; 95 | bps[j].original_index = i; 96 | j++; 97 | } 98 | } 99 | 100 | /* Sort the BlitPassports list in top-to-bottom order. */ 101 | qsort(bps, char_blit_count, sizeof(BlitPassport), 102 | &compare_top_edges_downward); 103 | 104 | /* Subdivide the ccarray list roughly into text lines [LYB] */ 105 | /* Determine maximal top deviation */ 106 | maxtopchange = mdjvu_image_get_width(img) / 40; 107 | if (maxtopchange < 32) maxtopchange = 32; 108 | 109 | /* Loop until processing all ccs */ 110 | ccno = 0; 111 | while (ccno < char_blit_count) /* ccno will be increasing constantly */ 112 | { 113 | /* Gather first line approximation */ 114 | int32 sublist_top = bps[ccno].top; 115 | int32 sublist_bottom = bps[ccno].bottom; 116 | 117 | int32 nccno; 118 | 119 | /* nccno will be at least ccno + 1, 120 | * or otherwise we're hung. 121 | */ 122 | for (nccno = ccno; nccno < char_blit_count; nccno++) 123 | { 124 | int32 bottom; 125 | if (bps[nccno].top > sublist_bottom) break; 126 | if (bps[nccno].top > sublist_top + maxtopchange) break; 127 | bottom = bps[nccno].bottom; 128 | bottoms[nccno - ccno] = bottom; 129 | if (bottom > sublist_bottom) 130 | sublist_bottom = bottom; 131 | } 132 | 133 | /* If more than one candidate cc for the line */ 134 | if (nccno > ccno + 1) 135 | { 136 | /* Compute median bottom */ 137 | int32 bottom; 138 | qsort(bottoms, nccno - ccno, sizeof(int32), 139 | &compare_integers_reversed); 140 | bottom = bottoms[ (nccno - ccno - 1) / 2 ]; 141 | 142 | /* Compose final line */ 143 | for (nccno = ccno; nccno < char_blit_count; nccno++) 144 | if (bps[nccno].top > bottom) 145 | break; 146 | 147 | /* Sort final line */ 148 | qsort(bps + ccno, nccno - ccno, sizeof(BlitPassport), 149 | &compare_left_edges_rightward); 150 | } 151 | 152 | /* Next line */ 153 | ccno = nccno; 154 | } 155 | 156 | /* Permute the blits according to `bps' */ 157 | passport_of_blit = (int32 *) malloc(blit_count * sizeof(int32)); 158 | for (i = 0; i < blit_count; i++) 159 | passport_of_blit[i] = -1; 160 | for (i = 0; i < char_blit_count; i++) 161 | passport_of_blit[bps[i].original_index] = i; 162 | 163 | /* We'll maintain that bps[i].original_index points to the same blit */ 164 | for (i = 0; i < char_blit_count; i++) 165 | { 166 | int32 blit_to_put_here = bps[i].original_index; 167 | mdjvu_image_exchange_blits(img, blit_to_put_here, i); 168 | if (passport_of_blit[i] != -1) 169 | bps[passport_of_blit[i]].original_index = blit_to_put_here; 170 | passport_of_blit[blit_to_put_here] = passport_of_blit[i]; 171 | } 172 | 173 | free(passport_of_blit); 174 | free(bps); 175 | free(bottoms); 176 | } 177 | -------------------------------------------------------------------------------- /src/alg/clean.c: -------------------------------------------------------------------------------- 1 | /* 2 | * clean.c - removing small flyspecks 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | 9 | /* 10 | * This implementation is very simple. 11 | * Most likely halftone patterns will get deleted... 12 | */ 13 | 14 | MDJVU_IMPLEMENT void mdjvu_clean(mdjvu_image_t image) 15 | { 16 | int32 b = mdjvu_image_get_blit_count(image), i; 17 | int32 dpi = mdjvu_image_get_resolution(image); 18 | int32 tinysize = dpi*dpi/20000 - 1; 19 | mdjvu_image_enable_masses(image); 20 | if (tinysize <= 0) return; 21 | 22 | for (i = 0; i < b; i++) 23 | { 24 | mdjvu_bitmap_t bitmap = mdjvu_image_get_blit_bitmap(image, i); 25 | int32 mass = mdjvu_image_get_mass(image, bitmap); 26 | /* Don't cleanup blits which were produced as a result of splitting larger 27 | * shapes (such as horizontal rulers) */ 28 | int32 big = mdjvu_image_get_suspiciously_big_flag(image, bitmap); 29 | if (mass <= tinysize && !big) 30 | mdjvu_image_set_blit_bitmap(image, i, NULL); 31 | } 32 | 33 | mdjvu_image_remove_NULL_blits(image); 34 | mdjvu_image_remove_unused_bitmaps(image); 35 | } 36 | -------------------------------------------------------------------------------- /src/alg/delegate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * delegate.c - choosing a representative over a class of letters 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | MDJVU_IMPLEMENT void mdjvu_multipage_choose_representatives 12 | (int32 npages, 13 | mdjvu_image_t *pages, 14 | int32 max_tag, 15 | int32 *tags, 16 | mdjvu_bitmap_t *representatives, 17 | unsigned char *dictionary_flags) 18 | { 19 | int page_number; 20 | int32 total_bitmaps_passed = 0; 21 | memset(representatives, 0, (max_tag + 1) * sizeof(mdjvu_bitmap_t)); 22 | for (page_number = 0; page_number < npages; page_number++) 23 | { 24 | mdjvu_image_t page = pages[page_number]; 25 | int32 bitmap_count = mdjvu_image_get_bitmap_count(page); 26 | int32 i; /* index of bitmap in a page */ 27 | 28 | for (i = 0; i < bitmap_count; i++) 29 | { 30 | int32 tag = tags[total_bitmaps_passed++]; 31 | if (!tag || !dictionary_flags[tag]) continue; /* skip non-substitutable bitmaps */ 32 | if (!representatives[tag]) 33 | representatives[tag] = mdjvu_image_get_bitmap(page, i); 34 | } 35 | } 36 | } 37 | 38 | MDJVU_IMPLEMENT mdjvu_image_t mdjvu_multipage_choose_average_representatives 39 | (int32 npages, 40 | mdjvu_image_t *pages, 41 | int32 total_count, 42 | int32 max_tag, 43 | int32 *tags, 44 | mdjvu_bitmap_t *representatives, 45 | unsigned char *dictionary_flags) 46 | { 47 | int32 page_number, tag; 48 | mdjvu_bitmap_t *sources; 49 | int32 *cx, *cy; 50 | mdjvu_image_t dictionary = mdjvu_image_create(0,0); /* 0 x 0 image */ 51 | 52 | memset(representatives, 0, (max_tag + 1) * sizeof(mdjvu_bitmap_t)); 53 | 54 | sources = (mdjvu_bitmap_t *) malloc(total_count * sizeof(mdjvu_bitmap_t)); 55 | cx = (int32 *) malloc(total_count * sizeof(int32)); 56 | cy = (int32 *) malloc(total_count * sizeof(int32)); 57 | 58 | for (tag = 1; tag <= max_tag; tag++) 59 | { 60 | int32 sources_found = 0, total_bitmaps_passed = 0; 61 | mdjvu_bitmap_t rep; 62 | if (!dictionary_flags[tag]) continue; 63 | 64 | memset(sources, 0, total_count * sizeof(mdjvu_bitmap_t)); 65 | memset(cx, 0, total_count * sizeof(int32)); 66 | memset(cy, 0, total_count * sizeof(int32)); 67 | int32 stop_searching = 0; 68 | for (page_number = 0; page_number < npages; page_number++) 69 | { 70 | mdjvu_image_t page = pages[page_number]; 71 | int32 bitmap_count = mdjvu_image_get_bitmap_count(page); 72 | int32 i; /* index of bitmap in a page */ 73 | 74 | for (i = 0; i < bitmap_count; i++) 75 | { 76 | if (tags[total_bitmaps_passed++] == tag) 77 | { 78 | sources[sources_found] = mdjvu_image_get_bitmap(page, i); 79 | mdjvu_image_get_center(page, sources[sources_found], &cx[sources_found], &cy[sources_found]); 80 | sources_found++; 81 | if (sources_found == 1 && 82 | mdjvu_image_get_not_a_letter_flag(page, sources[0])) { 83 | // check if it's a losslessly compressed class. If so - one sample is enough 84 | stop_searching = 1; 85 | break; 86 | } 87 | } 88 | } 89 | 90 | if (stop_searching) break; 91 | } 92 | 93 | if (sources_found) 94 | { 95 | rep = mdjvu_average(sources, sources_found, cx, cy); 96 | representatives[tag] = rep; 97 | } 98 | } 99 | free(cx); 100 | free(cy); 101 | free(sources); 102 | 103 | for (page_number = 0; page_number < npages; page_number++) 104 | mdjvu_image_disable_centers(pages[page_number]); 105 | 106 | for (tag = 1; tag <= max_tag; tag++) 107 | { 108 | mdjvu_bitmap_t rep; 109 | 110 | if (!dictionary_flags[tag] || (rep = representatives[tag]) == NULL) continue; 111 | mdjvu_image_add_bitmap(dictionary, rep); 112 | } 113 | return dictionary; 114 | } 115 | -------------------------------------------------------------------------------- /src/alg/erosion.c: -------------------------------------------------------------------------------- 1 | /* 2 | * erosion.c - determine candidates for flipping by image encoder 3 | */ 4 | 5 | 6 | #include "../base/mdjvucfg.h" 7 | #include 8 | #include 9 | 10 | 11 | /* ERROR ALERT: 12 | * We should never declare border pixels 13 | * as erosion candidates or otherwise bounding boxes may change 14 | * with unpredictable consequences. 15 | * (this implementation is OK) 16 | */ 17 | 18 | /* 19 | * it all resembles `smooth' algorithm very much. 20 | */ 21 | 22 | /* 23 | * This implementation permits flipping of a pixel 24 | * when it has exactly 2 of 4 edge neighbors black 25 | * and exactly 2 of 4 vertex (diagonal) neighbors black. 26 | */ 27 | 28 | 29 | /* all input rows must be 0-or-1 unpacked */ 30 | static void get_erosion_candidates_in_a_row( 31 | unsigned char *r, /* result */ 32 | unsigned char *u, /* upper row */ 33 | unsigned char *t, /* this row */ 34 | unsigned char *l, /* lower row */ 35 | int32 n) 36 | { 37 | int32 i; 38 | n--; 39 | r[0] = 0; 40 | r[n] = 0; 41 | for (i = 1; i < n; i++) 42 | { 43 | int score_4 = u[i] + l[i] + t[i-1] + t[i+1] - 2; 44 | int score_d = u[i-1] + l[i-1] + u[i+1] + l[i+1] - 2; 45 | 46 | r[i] = !score_4 && !score_d ? 1 : 0; 47 | } 48 | } 49 | 50 | MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_get_erosion_mask(mdjvu_bitmap_t bmp) 51 | { 52 | int32 w = mdjvu_bitmap_get_width(bmp); 53 | int32 h = mdjvu_bitmap_get_height(bmp); 54 | mdjvu_bitmap_t result = mdjvu_bitmap_create(w, h); 55 | int32 i; 56 | unsigned char *u, *t, *l, *r; 57 | 58 | if (h < 3) return result; 59 | 60 | u = (unsigned char *) malloc(w); /* upper row */ 61 | t = (unsigned char *) malloc(w); /* this row */ 62 | l = (unsigned char *) malloc(w); /* lower row */ 63 | r = (unsigned char *) malloc(w); /* result */ 64 | 65 | mdjvu_bitmap_unpack_row_0_or_1(bmp, t, 0); 66 | mdjvu_bitmap_unpack_row_0_or_1(bmp, l, 1); 67 | for (i = 1; i < h - 1; i++) 68 | { 69 | unsigned char *tmp = u; 70 | u = t; 71 | t = l; 72 | l = tmp; 73 | 74 | mdjvu_bitmap_unpack_row_0_or_1(bmp, l, i + 1); 75 | 76 | get_erosion_candidates_in_a_row(r, u, t, l, w); 77 | mdjvu_bitmap_pack_row(result, r, i); 78 | } 79 | 80 | free(u); 81 | free(t); 82 | free(l); 83 | free(r); 84 | 85 | return result; 86 | } 87 | -------------------------------------------------------------------------------- /src/alg/render.c: -------------------------------------------------------------------------------- 1 | /* 2 | * render.c - rendering a split image into a bitmap 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | 10 | MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_render(mdjvu_image_t img) 11 | { 12 | int32 width = mdjvu_image_get_width (img); 13 | int32 height = mdjvu_image_get_height(img); 14 | unsigned char **b = mdjvu_create_2d_array(width, height); 15 | unsigned char *row_buffer = (unsigned char *) malloc(width); 16 | int32 blit_count = mdjvu_image_get_blit_count(img); 17 | int32 i; 18 | mdjvu_bitmap_t result = mdjvu_bitmap_create(width, height); 19 | 20 | /* Fill the canvas with white */ 21 | for (i = 0; i < height; i++) 22 | memset(b[i], 0, width); 23 | 24 | /* Render the split image blit by blit */ 25 | for (i = 0; i < blit_count; i++) 26 | { 27 | int32 x = mdjvu_image_get_blit_x(img, i); 28 | int32 y = mdjvu_image_get_blit_y(img, i); 29 | mdjvu_bitmap_t current_bitmap = mdjvu_image_get_blit_bitmap(img, i); 30 | int32 w = mdjvu_bitmap_get_width(current_bitmap); 31 | int32 h = mdjvu_bitmap_get_height(current_bitmap); 32 | 33 | /* Now w and h are dimensions of the current shape, 34 | * and width and height are dimensions of the whole image. 35 | */ 36 | 37 | int32 min_col = x >= 0 ? 0 : - x; 38 | int32 max_col_plus_one = x + w <= width ? w : width - x; 39 | 40 | int32 min_row = y >= 0 ? 0 : - y; 41 | int32 max_row_plus_one = y + h <= height ? h : height - y; 42 | 43 | int32 row; 44 | 45 | /* Render the current blit row by row */ 46 | for (row = min_row; row < max_row_plus_one; row++) 47 | { 48 | int32 col; 49 | unsigned char *target = b[y + row] + x; 50 | mdjvu_bitmap_unpack_row(current_bitmap, row_buffer, row); 51 | for (col = min_col; col < max_col_plus_one; col++) 52 | target[col] |= row_buffer[col]; 53 | } 54 | } 55 | 56 | free(row_buffer); 57 | 58 | /* Convert 2D array to a Bitmap and return it */ 59 | mdjvu_bitmap_pack_all(result, b); 60 | mdjvu_destroy_2d_array(b); 61 | return result; 62 | } 63 | -------------------------------------------------------------------------------- /src/alg/smooth.c: -------------------------------------------------------------------------------- 1 | /* 2 | * smooth.c - pre-filtering bitmap before splitting 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | #ifndef _MSC_VER 10 | #include 11 | #endif 12 | 13 | /* all input rows must be 0-or-1 unpacked */ 14 | //static void smooth_row(unsigned char *r, /* result */ 15 | // unsigned char *u, /* upper row */ 16 | // unsigned char *t, /* this row - must have margin 1 */ 17 | // unsigned char *l, /* lower row */ 18 | // int32 n) 19 | //{ 20 | // int32 i; 21 | // for (i = 0; i < n; i++) 22 | // { 23 | // int score = u[i] + l[i] + t[i-1] + t[i+1]; 24 | 25 | // if (t[i] == 0) 26 | // { 27 | // /* Only turn white into black for a good reason. */ 28 | // r[i] = (score == 4); 29 | // } 30 | // else if (score == 0) 31 | // { 32 | // /* Good reason to clear the pixel. */ 33 | // r[i] = 0; 34 | // } 35 | // else if (score == 1) 36 | // { 37 | // /* Check for weak horizontal or vertical linking. */ 38 | // if (u[i] | l[i]) 39 | // r[i] = (u[i-1] & l[i-1]) | (u[i+1] & l[i+1]); 40 | // else 41 | // r[i] = (u[i-1] & u[i+1]) | (l[i-1] & l[i+1]); 42 | // } 43 | // else 44 | // { 45 | // /* Keep it black. */ 46 | // r[i] = 1; 47 | // } 48 | 49 | // } 50 | //} 51 | 52 | __inline size_t get_smooth(size_t u, size_t t, size_t d) 53 | { 54 | size_t ul = u >> 1, l = t >> 1, dl = d >> 1; 55 | size_t ur = u << 1, r = t << 1, dr = d << 1; 56 | 57 | size_t res0 = l & r & u & d; // score 4 regardles t 58 | size_t res1 = /*t &*/ ( (l & u) | (u & r) | (r & d) | (l & d) | (l & r) | (u & d) ); // score >= 2 59 | 60 | // score 1 61 | size_t res2 = /*t &*/ (u | d) & ( (ul & dl) | (ur & dr) ); 62 | res2 |= /*t &*/ (l | r) & ( (ul & ur) | (dl & dr) ); 63 | 64 | return res0 | (t & (res1 | res2)); 65 | } 66 | 67 | #if __BYTE_ORDER == __BIG_ENDIAN 68 | __inline size_t swap_t(size_t* val, unsigned int size) { 69 | if (size >= sizeof (size_t)) 70 | return *val; 71 | 72 | size_t res = 0; 73 | memcpy(&res, val, size); 74 | return res; 75 | } 76 | #elif __BYTE_ORDER == __LITTLE_ENDIAN 77 | __inline size_t swap_t(size_t* val, unsigned int size) { 78 | size_t res = 0; 79 | unsigned char * a = (unsigned char *) &res; 80 | memcpy(&res, val, size); 81 | unsigned char t; 82 | for (unsigned int i = 0; i < (sizeof (size_t)/2); i++) { 83 | t = a[i]; 84 | a[i] = a[sizeof (size_t) - i - 1]; 85 | a[sizeof (size_t) - i - 1] = t; 86 | } 87 | return res; 88 | } 89 | #endif 90 | 91 | static void smooth_row(unsigned char *r, /* result */ 92 | unsigned char *u, /* upper row */ 93 | unsigned char *t, /* this row - must have margin 1 */ 94 | unsigned char *l, /* lower row */ 95 | int32 n) 96 | { 97 | if ( !n ) return; 98 | const size_t int_len_in_bits = sizeof (size_t)*8; 99 | const size_t len = (n + (int_len_in_bits -1) ) / int_len_in_bits; 100 | const size_t tail_len = (n % int_len_in_bits) ? ((n % int_len_in_bits) + 7) >> 3 : sizeof (size_t); 101 | 102 | size_t *r_p = (size_t *) r; /* result */ 103 | size_t *u_p = (size_t *) u; 104 | size_t *t_p = (size_t *) t; 105 | size_t *l_p = (size_t *) l; 106 | 107 | size_t u_buf = 0, t_buf = 0, l_buf = 0; 108 | size_t u_val = 0, t_val = 0, l_val = 0; 109 | size_t u_cur = 0, t_cur = 0, l_cur = 0; 110 | 111 | const size_t mask1 = (~(size_t)0x0) << 1; //0b11111..110 112 | const size_t mask2 = (size_t)0x01 << (int_len_in_bits-1); //0b100000.00 113 | const size_t mask3 = mask2 >> 1; //0b01000..00 114 | const size_t mask4 = mask3 >> 1; //0b00100..00 115 | const size_t mask5 = mask1 & ~mask2; //0b01111..10 116 | 117 | 118 | for (unsigned int i = 0; i < len; i++) { 119 | if (u_p) { 120 | u_cur = swap_t(u_p++, i==len-1?tail_len:sizeof (size_t)); 121 | u_val = u_buf | (u_cur >> 2); 122 | u_buf = u_cur << (int_len_in_bits - 2); 123 | } 124 | if (l_p) { 125 | l_cur = swap_t(l_p++, i==len-1?tail_len:sizeof (size_t)); 126 | l_val = l_buf | (l_cur >> 2); 127 | l_buf = l_cur << (int_len_in_bits - 2); 128 | } 129 | 130 | t_cur = swap_t(t_p++, i==len-1?tail_len:sizeof (size_t)); 131 | t_val = t_buf | (t_cur >> 2); 132 | t_buf = t_cur << (int_len_in_bits - 2); 133 | 134 | size_t res = get_smooth(u_val, t_val, l_val); 135 | 136 | size_t tail = res & mask3; 137 | size_t head = res & mask4; 138 | 139 | if (tail) { 140 | // for i == 0 tail is always false and this is not called 141 | // we access last byte instead of size_t* to not mess with int endiannes 142 | *(((unsigned char *)r_p)-1) |= 1;; // last bit is always 0 bcs of mask5 143 | } 144 | 145 | 146 | res = get_smooth(u_cur, t_cur, l_cur); 147 | res &= mask5; 148 | if (head) { 149 | res |= mask2; 150 | } 151 | 152 | res = swap_t(&res, /*i==len-1?tail_len:*/sizeof (size_t)); 153 | memcpy(r_p++, &res, (i==len-1)?tail_len:sizeof (size_t)); 154 | } 155 | 156 | 157 | if (n % 8) { 158 | r += ((n+7)>>3)-1; 159 | *r &= 0xFF << (8- n % 8); 160 | } 161 | } 162 | 163 | MDJVU_IMPLEMENT void mdjvu_smooth(mdjvu_bitmap_t b) 164 | { 165 | int32 w = mdjvu_bitmap_get_width(b); 166 | int32 h = mdjvu_bitmap_get_height(b); 167 | int32 i; 168 | unsigned char *u = NULL, /* upper row */ 169 | *t = NULL, /* this row */ 170 | *l = NULL; /* lower row */ 171 | 172 | if (h < 3) return; 173 | 174 | const int32 row_size = mdjvu_bitmap_get_packed_row_size(b); 175 | 176 | unsigned char *r = (unsigned char *) malloc(row_size*h); /* result */ 177 | 178 | l = mdjvu_bitmap_access_packed_row(b, 0); 179 | for (i = 0; i < h; i++) { 180 | u = t; 181 | t = l; 182 | 183 | if (i + 1 < h) 184 | l = mdjvu_bitmap_access_packed_row(b, i+1); 185 | else 186 | l = NULL; 187 | 188 | smooth_row(r+row_size*i, u, t, l, w); 189 | } 190 | 191 | 192 | memcpy(mdjvu_bitmap_access_packed_row(b, 0), r, row_size*h); 193 | 194 | free(r); 195 | } 196 | -------------------------------------------------------------------------------- /src/base/0porting.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 0porting.c - checking sanity of typedefs 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | 10 | #ifdef HAVE_GETTEXT 11 | #include 12 | #endif 13 | 14 | MDJVU_IMPLEMENT const char *mdjvu_check_sanity(void) 15 | { 16 | if (sizeof(int32) != 4) 17 | return "mdjvu_check_sanity(): sizeof(int32) != 4"; 18 | 19 | if (sizeof(uint32) != 4) 20 | return "mdjvu_check_sanity(): sizeof(uint32) != 4"; 21 | 22 | if (sizeof(int16) != 2) 23 | return "mdjvu_check_sanity(): sizeof(int16) != 2"; 24 | 25 | if (sizeof(uint16) != 2) 26 | return "mdjvu_check_sanity(): sizeof(uint16) != 2"; 27 | 28 | return NULL; 29 | } 30 | 31 | 32 | static int initialized = 0; 33 | 34 | void mdjvu_init(void) 35 | { 36 | const char *sanity_error_message; 37 | 38 | if (initialized) 39 | return; 40 | 41 | #ifdef HAVE_GETTEXT 42 | bindtextdomain("minidjvu-mod", LOCALEDIR); 43 | #endif 44 | 45 | /* check sizeof(int32) == 4 and such gibberish */ 46 | sanity_error_message = mdjvu_check_sanity(); 47 | if (sanity_error_message) 48 | { 49 | fprintf(stderr, "%s\n", sanity_error_message); 50 | exit(1); 51 | } 52 | 53 | initialized = 1; 54 | } 55 | -------------------------------------------------------------------------------- /src/base/1error.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 1error.c - error handling 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | 8 | MDJVU_IMPLEMENT const char *mdjvu_get_error_message(mdjvu_error_t error) 9 | { 10 | return (const char *) error; 11 | } 12 | 13 | MDJVU_IMPLEMENT mdjvu_error_t mdjvu_get_error(MinidjvuErrorType e) 14 | { 15 | switch(e) 16 | { 17 | case mdjvu_error_fopen_write: 18 | return (mdjvu_error_t) _("unable to write to file"); 19 | case mdjvu_error_fopen_read: 20 | return (mdjvu_error_t) _("unable to read from file"); 21 | case mdjvu_error_io: 22 | return (mdjvu_error_t) _("I/O error"); 23 | case mdjvu_error_corrupted_pbm: 24 | return (mdjvu_error_t) _("bad PBM file"); 25 | case mdjvu_error_corrupted_bmp: 26 | return (mdjvu_error_t) _("bad Windows BMP file (perhaps it has non-bitonal data)"); 27 | case mdjvu_error_corrupted_djvu: 28 | return (mdjvu_error_t) _("bad DjVu file"); 29 | case mdjvu_error_corrupted_jb2: 30 | return (mdjvu_error_t) _("bad bilevel data in DjVu file"); 31 | case mdjvu_error_corrupted_tiff: 32 | return (mdjvu_error_t) _("bad TIFF file (perhaps it has non-bitonal data)"); 33 | case mdjvu_error_wrong_djvu_type: 34 | return (mdjvu_error_t) _("unsupported type of DjVu file"); 35 | case mdjvu_error_djvu_no_Sjbz: 36 | return (mdjvu_error_t) _("bilevel data not found in DjVu file"); 37 | case mdjvu_error_recursive_prototypes: 38 | return (mdjvu_error_t) _("somehow prototype references recursed"); 39 | case mdjvu_error_tiff_support_disabled: 40 | return (mdjvu_error_t) _("minidjvu-mod was compiled without TIFF support"); 41 | case mdjvu_error_png_support_disabled: 42 | return (mdjvu_error_t) _("minidjvu-mod was compiled without PNG support"); 43 | } 44 | return (mdjvu_error_t) 45 | _("some weird error happened, probably caused by a bug in minidjvu-mod"); 46 | } 47 | -------------------------------------------------------------------------------- /src/base/2io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 2io.c - a stdio wrapper 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | 9 | MDJVU_IMPLEMENT mdjvu_file_t mdjvu_fopen(const char *path, const char *mode) 10 | { return (mdjvu_file_t) fopen(path, mode); } 11 | 12 | MDJVU_IMPLEMENT void mdjvu_fclose(mdjvu_file_t f) 13 | { fclose((FILE *) f); } 14 | 15 | MDJVU_IMPLEMENT int32 mdjvu_fread(void *p, int32 size, int32 n, mdjvu_file_t f) 16 | { return (int32) fread(p, size, n, (FILE *) f); } 17 | 18 | MDJVU_IMPLEMENT int32 19 | mdjvu_fwrite(const void *p, int32 size, int32 n, mdjvu_file_t f) 20 | { return (int32) fwrite(p, size, n, (FILE *) f); } 21 | 22 | MDJVU_IMPLEMENT void mdjvu_write_big_endian_int32(int32 i, mdjvu_file_t file) 23 | { 24 | FILE *f = (FILE *) file; 25 | putc(i >> 24, f); 26 | putc(i >> 16, f); 27 | putc(i >> 8, f); 28 | putc(i, f); 29 | } 30 | 31 | MDJVU_IMPLEMENT void mdjvu_write_little_endian_int32(int32 i, mdjvu_file_t file) 32 | { 33 | FILE *f = (FILE *) file; 34 | putc(i, f); 35 | putc(i >> 8, f); 36 | putc(i >> 16, f); 37 | putc(i >> 24, f); 38 | } 39 | 40 | MDJVU_IMPLEMENT void mdjvu_write_big_endian_int16(int16 i, mdjvu_file_t file) 41 | { 42 | FILE *f = (FILE *) file; 43 | putc(i >> 8, f); 44 | putc(i, f); 45 | } 46 | 47 | MDJVU_IMPLEMENT void mdjvu_write_little_endian_int16(int16 i, mdjvu_file_t file) 48 | { 49 | FILE *f = (FILE *) file; 50 | putc(i, f); 51 | putc(i >> 8, f); 52 | } 53 | 54 | MDJVU_IMPLEMENT int32 mdjvu_read_big_endian_int32(mdjvu_file_t file) 55 | { 56 | FILE *f = (FILE *) file; 57 | int32 r = getc(f) << 24; 58 | r |= getc(f) << 16; 59 | r |= getc(f) << 8; 60 | r |= getc(f); 61 | return r; 62 | } 63 | 64 | MDJVU_IMPLEMENT int16 mdjvu_read_big_endian_int16(mdjvu_file_t file) 65 | { 66 | FILE *f = (FILE *) file; 67 | int16 r = getc(f) << 8; 68 | r |= getc(f); 69 | return r; 70 | } 71 | 72 | MDJVU_IMPLEMENT int32 mdjvu_read_little_endian_int32(mdjvu_file_t file) 73 | { 74 | FILE *f = (FILE *) file; 75 | int32 r = getc(f); 76 | r |= getc(f) << 8; 77 | r |= getc(f) << 16; 78 | r |= getc(f) << 24; 79 | return r; 80 | } 81 | 82 | MDJVU_IMPLEMENT int16 mdjvu_read_little_endian_int16(mdjvu_file_t file) 83 | { 84 | FILE *f = (FILE *) file; 85 | int32 r = getc(f); 86 | r |= getc(f) << 8; 87 | return r; 88 | } 89 | -------------------------------------------------------------------------------- /src/base/3graymap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3graymap.c - very simple 2d array handling 3 | */ 4 | 5 | #include "mdjvucfg.h" 6 | #include 7 | #include 8 | 9 | MDJVU_IMPLEMENT unsigned char **mdjvu_create_2d_array(int32 w, int32 h) 10 | { 11 | int32 i; 12 | unsigned char *data, **result; 13 | result = (unsigned char **) calloc(h, sizeof(unsigned char *) + w); 14 | data = (unsigned char *) (result + h); 15 | 16 | for (i = 0; i < h; i++) 17 | { 18 | result[i] = data + w * i; 19 | } 20 | 21 | return result; 22 | } 23 | 24 | MDJVU_IMPLEMENT void mdjvu_destroy_2d_array(unsigned char **p) 25 | { 26 | free(p); 27 | } 28 | -------------------------------------------------------------------------------- /src/base/6string.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 6string.c - some standard funtions for string manipulation 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /* Under Windows (MSVC), there is usually no strcasecmp. 14 | * So here's the rewrite. 15 | */ 16 | static int my_strcasecmp(const char *s1, const char *s2) 17 | { 18 | int c1, c2; 19 | while(*s1) 20 | { 21 | int d; 22 | c1 = tolower(*s1++); c2 = tolower(*s2++); 23 | d = c1 - c2; 24 | if (d) return d; 25 | } 26 | return *s2; 27 | } 28 | 29 | MDJVU_IMPLEMENT int mdjvu_ends_with_ignore_case(const char *s, const char *prefix) 30 | { 31 | size_t sl = strlen(s); 32 | size_t pl = strlen(prefix); 33 | if (sl < pl) return 0; 34 | return !my_strcasecmp(s + sl - pl, prefix); 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/base/README: -------------------------------------------------------------------------------- 1 | This is the `base' of minidjvu-mod. All algorithms depend on the base. 2 | 3 | The base units may depend on each other in the order suggested by the numbers. 4 | So, `0porting' does not depend on anything and `5image' may depend on all. 5 | 6 | Here is the description of units: 7 | 8 | 0porting - portability stuff (several typedefs) 9 | 1error - error handling 10 | 2io - stdio wrapper (we can have many `stdio's on Windows) 11 | 3graymap - small number of 2D-arrays handling routines 12 | 4bitmap - the bitmap class (useful in a bitmap-processing library, right?) 13 | 5image - the "split" image class (that's what minidjvu-mod is all about) 14 | 6string - just one routine that should probably go elsewhere 15 | -------------------------------------------------------------------------------- /src/base/mdjvucfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mdjvucfg.h - file to be included first in all C sources in the library 3 | */ 4 | 5 | #ifdef MINIDJVU_INCLUDED_FROM_INSIDE 6 | #error mdjvucfg.h should be included only once in every minidjvu-mod source file 7 | #endif 8 | 9 | 10 | /* 11 | * This is needed, for example, to distinguish between dllexport and dllimport. 12 | */ 13 | #define MINIDJVU_INCLUDED_FROM_INSIDE 14 | 15 | /* 16 | * Bridge to autoconf configuration file. 17 | */ 18 | #ifdef HAVE_CONFIG_H 19 | #include 20 | #endif 21 | 22 | /* IM: I'm commenting #ifdef out because it looks like we must use dgettext in 23 | * the shared library. Yes, it's ugly to redefine a system macro but... 24 | * #ifndef _ 25 | */ 26 | 27 | #ifdef HAVE_GETTEXT 28 | #include 29 | #define _(msgid) dgettext("minidjvu-mod", msgid) 30 | #else 31 | #define _(msgid) (msgid) 32 | #endif 33 | 34 | /* #endif */ 35 | 36 | 37 | /** 38 | * Global initialization of the shared library. 39 | * It's OK to call it more than once. 40 | * This function is to be called from every constructor 41 | * so that there's no type-correct way to use minidjvu-mod 42 | * without calling mdjvu_init() behind the scenes. 43 | * 44 | * This function is implemented in 0porting.c. 45 | */ 46 | void mdjvu_init(void); 47 | -------------------------------------------------------------------------------- /src/base/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * version.c - a placeholder for a compiled-in version stamp 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | 8 | MDJVU_IMPLEMENT const char *mdjvu_get_version() 9 | { 10 | return MDJVU_VERSION; 11 | } 12 | -------------------------------------------------------------------------------- /src/djvu/bs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bs.h - BZZ-coder from DjVuLibre, a general purpose compressor 3 | * based on the Burrows-Wheeler (or "block sorting") transform. 4 | */ 5 | 6 | #include "../jb2/zp.h" 7 | 8 | class BSEncoder 9 | { 10 | public: 11 | BSEncoder(FILE *, int blocksize = 1024); 12 | ~BSEncoder(); 13 | 14 | long tell(void) const; 15 | void flush(void); 16 | void close(void); 17 | 18 | size_t write(void *buffer, size_t sz); 19 | void write8 (unsigned int card); 20 | void write16 (unsigned int card); 21 | void write24 (unsigned int card); 22 | void write32 (unsigned int card); 23 | 24 | private: 25 | size_t writall(void *buffer, size_t size); 26 | unsigned int encode(void); 27 | 28 | // Data 29 | long offset; 30 | int bptr; 31 | unsigned int blocksize; 32 | int size; 33 | unsigned char *data; 34 | 35 | // Coder 36 | ZPEncoder gzp; 37 | ZPBitContext ctx[300]; 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /src/djvu/djvudir.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * djvusave.c - saving DjVuBitonal pages 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include "bs.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | MDJVU_IMPLEMENT void mdjvu_write_dirm_bundled(char **elements, int * sizes, 14 | int n, mdjvu_file_t f, mdjvu_error_t *perr) 15 | { 16 | int i, flag, offpos, end, off, *offsets; 17 | 18 | // version number and the DJVU bundled flag 19 | fputc(1 | ((1)<<7), (FILE *) f); 20 | // Number of files 21 | mdjvu_write_big_endian_int16((uint16) n, f); 22 | 23 | offpos = ftell((FILE *) f); 24 | offsets = (int *) calloc(n, sizeof(int)); 25 | // Dummy offsets (will rewrite them later) 26 | for (i=0; i 7 | 8 | #define DEFAULT_VERSION_STAMP 24 9 | #define DEFAULT_RESOLUTION 300 /* used only if unknown */ 10 | #define DEFAULT_GAMMA 278 11 | 12 | MDJVU_FUNCTION void mdjvu_write_info_chunk(mdjvu_file_t f, mdjvu_image_t image) 13 | { 14 | int32 w = mdjvu_image_get_width(image); 15 | int32 h = mdjvu_image_get_height(image); 16 | int32 dpi = mdjvu_image_get_resolution(image); 17 | 18 | if (!dpi) dpi = DEFAULT_RESOLUTION; 19 | 20 | mdjvu_write_big_endian_int16((uint16) w, f); 21 | mdjvu_write_big_endian_int16((uint16) h, f); 22 | mdjvu_write_little_endian_int16(DEFAULT_VERSION_STAMP, f); 23 | mdjvu_write_little_endian_int16((uint16) dpi, f); 24 | mdjvu_write_little_endian_int16(DEFAULT_GAMMA, f); 25 | } 26 | 27 | MDJVU_IMPLEMENT void mdjvu_read_info_chunk(mdjvu_file_t f, int32 *pw, int32 *ph, int32 *pdpi) 28 | { 29 | int16 w = mdjvu_read_big_endian_int16(f); 30 | int16 h = mdjvu_read_big_endian_int16(f); 31 | int16 dpi; 32 | mdjvu_read_little_endian_int16(f); /* version stamp */ 33 | dpi = mdjvu_read_little_endian_int16(f); 34 | mdjvu_read_little_endian_int16(f); /* gamma */ 35 | 36 | if (pw) *pw = w; 37 | if (ph) *ph = h; 38 | if (pdpi) *pdpi = dpi; 39 | } 40 | -------------------------------------------------------------------------------- /src/djvu/djvuload.c: -------------------------------------------------------------------------------- 1 | /* 2 | * djvuload.c - functions to load from single-page DjVuBitonal files 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | 10 | static uint32 read_uint32_most_significant_byte_first(FILE *f) 11 | { 12 | uint32 r = fgetc(f) << 24; 13 | r |= fgetc(f) << 16; 14 | r |= fgetc(f) << 8; 15 | r |= fgetc(f); 16 | return r; 17 | } 18 | 19 | typedef struct IFFChunk 20 | { 21 | uint32 id; 22 | uint32 length; 23 | uint32 skipped; 24 | struct IFFChunk *parent; 25 | } IFFChunk; 26 | 27 | static void skip_in_chunk(IFFChunk *chunk, unsigned len) 28 | { 29 | while (chunk) 30 | { 31 | chunk->skipped += len; 32 | chunk = chunk->parent; 33 | } 34 | } 35 | 36 | static void skip_to_next_sibling_chunk(FILE *file, IFFChunk *chunk) 37 | { 38 | skip_in_chunk(chunk->parent, chunk->length + 8); 39 | fseek(file, (chunk->length + 1) & ~1, SEEK_CUR); 40 | chunk->id = read_uint32_most_significant_byte_first(file); 41 | chunk->length = read_uint32_most_significant_byte_first(file); 42 | chunk->skipped = 0; 43 | } 44 | 45 | static void get_child_chunk(FILE *file, IFFChunk *chunk, IFFChunk *parent) 46 | { 47 | chunk->id = read_uint32_most_significant_byte_first(file); 48 | chunk->length = read_uint32_most_significant_byte_first(file); 49 | chunk->skipped = 0; 50 | chunk->parent = parent; 51 | skip_in_chunk(parent, 8); 52 | } 53 | 54 | static int find_sibling_chunk(FILE *file, IFFChunk *chunk, uint32 id) 55 | { 56 | while (chunk->id != id) 57 | { 58 | if (chunk->parent && chunk->parent->skipped >= chunk->parent->length) 59 | return 0; 60 | skip_to_next_sibling_chunk(file, chunk); 61 | } 62 | return 1; 63 | } 64 | 65 | #define CHUNK_ID_AT_AND_T 0x41542654 66 | #define CHUNK_ID_FORM 0x464F524D 67 | #define ID_DJVU 0x444A5655 68 | #define CHUNK_ID_Sjbz 0x536A627A 69 | 70 | MDJVU_IMPLEMENT int mdjvu_locate_jb2_chunk(mdjvu_file_t file, int32 *plength, mdjvu_error_t *perr) 71 | { 72 | IFFChunk FORM, Sjbz; 73 | FILE *f = (FILE *) file; 74 | uint32 i = read_uint32_most_significant_byte_first(f); 75 | if (perr) *perr = NULL; 76 | if (i != CHUNK_ID_AT_AND_T) 77 | { 78 | if (perr) *perr = mdjvu_get_error(mdjvu_error_corrupted_djvu); 79 | return 0; 80 | } 81 | 82 | get_child_chunk(f, &FORM, NULL); 83 | if (!find_sibling_chunk(f, &FORM, CHUNK_ID_FORM)) 84 | { 85 | if (perr) *perr = mdjvu_get_error(mdjvu_error_corrupted_djvu); 86 | return 0; 87 | } 88 | 89 | if (read_uint32_most_significant_byte_first(f) != ID_DJVU) 90 | { 91 | if (perr) *perr = mdjvu_get_error(mdjvu_error_wrong_djvu_type); 92 | return 0; 93 | } 94 | 95 | skip_in_chunk(&FORM, 4); 96 | 97 | get_child_chunk(f, &Sjbz, &FORM); 98 | if (!find_sibling_chunk(f, &Sjbz, CHUNK_ID_Sjbz)) 99 | { 100 | if (perr) *perr = mdjvu_get_error(mdjvu_error_djvu_no_Sjbz); 101 | return 0; 102 | } 103 | 104 | *plength = (int32) Sjbz.length; 105 | 106 | return 1; 107 | } 108 | 109 | MDJVU_IMPLEMENT mdjvu_image_t mdjvu_file_load_djvu_page(mdjvu_file_t file, mdjvu_error_t *perr) 110 | { 111 | int32 length; 112 | if (!mdjvu_locate_jb2_chunk(file, &length, perr)) 113 | return NULL; 114 | return mdjvu_file_load_jb2(file, length, perr); 115 | } 116 | 117 | MDJVU_IMPLEMENT mdjvu_image_t mdjvu_load_djvu_page(const char *path, mdjvu_error_t *perr) 118 | { 119 | mdjvu_image_t result; 120 | FILE *f = fopen(path, "rb"); 121 | if (perr) *perr = NULL; 122 | if (!f) 123 | { 124 | if (perr) *perr = mdjvu_get_error(mdjvu_error_fopen_read); 125 | return NULL; 126 | } 127 | result = mdjvu_file_load_djvu_page((mdjvu_file_t) f, perr); 128 | fclose(f); 129 | return result; 130 | } 131 | 132 | -------------------------------------------------------------------------------- /src/djvu/iff.c: -------------------------------------------------------------------------------- 1 | /* 2 | * iff.c - read/write IFF files (DjVu files are IFF) 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | static void read_align(FILE *f) 12 | { 13 | long pos = ftell(f); 14 | if (pos & 1) fgetc(f); 15 | } 16 | 17 | static void write_align(FILE *f) 18 | { 19 | long pos = ftell(f); 20 | if (pos & 1) fputc(0, f); 21 | } 22 | 23 | 24 | typedef struct 25 | { 26 | int32 id; 27 | uint32 start; 28 | uint32 length; 29 | int write; 30 | } Chunk; 31 | 32 | MDJVU_IMPLEMENT int32 mdjvu_iff_get_id(mdjvu_iff_t iff) 33 | { 34 | return ((Chunk *) iff) -> id; 35 | } 36 | 37 | MDJVU_IMPLEMENT int32 mdjvu_iff_get_length(mdjvu_iff_t iff) 38 | { 39 | return ((Chunk *) iff) -> length; 40 | } 41 | 42 | MDJVU_IMPLEMENT mdjvu_iff_t mdjvu_iff_read_chunk(mdjvu_file_t file) 43 | { 44 | FILE *f = (FILE *) file; 45 | Chunk *chunk = (Chunk *) malloc(sizeof(Chunk)); 46 | read_align(f); 47 | chunk->id = mdjvu_read_big_endian_int32(file); 48 | chunk->length = mdjvu_read_big_endian_int32(file); 49 | chunk->start = ftell(f); 50 | chunk->write = 0; 51 | 52 | return (mdjvu_iff_t) chunk; 53 | } 54 | 55 | MDJVU_IMPLEMENT mdjvu_iff_t mdjvu_iff_write_chunk(int32 id, mdjvu_file_t file) 56 | { 57 | FILE *f = (FILE *) file; 58 | Chunk *chunk = (Chunk *) malloc(sizeof(Chunk)); 59 | write_align(f); 60 | mdjvu_write_big_endian_int32(id, file); 61 | mdjvu_write_big_endian_int32(0, file); /* will be length */ 62 | 63 | chunk->id = id; 64 | chunk->start = ftell(f); 65 | chunk->length = 0; 66 | chunk->write = 1; 67 | 68 | return (mdjvu_iff_t) chunk; 69 | } 70 | 71 | MDJVU_IMPLEMENT void mdjvu_iff_close_chunk(mdjvu_iff_t iff, mdjvu_file_t file) 72 | { 73 | FILE *f = (FILE *) file; 74 | Chunk *chunk = (Chunk *) iff; 75 | 76 | if (chunk->write) 77 | { 78 | long pos = ftell(f); 79 | uint32 length = pos - chunk->start; 80 | fseek(f, chunk->start - 4, SEEK_SET); 81 | mdjvu_write_big_endian_int32(length, file); 82 | fseek(f, pos, SEEK_SET); 83 | } 84 | else 85 | { 86 | fseek(f, chunk->start + chunk->length, SEEK_SET); 87 | } 88 | 89 | free(chunk); 90 | } 91 | -------------------------------------------------------------------------------- /src/image-io/pbm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pbm.c - loading and saving in PBM ("portable bitmap") format 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | 9 | static void skip_to_the_end_of_line(FILE *file) 10 | { 11 | while (1) 12 | { 13 | switch(fgetc(file)) 14 | { 15 | case -1: case '\r': case '\n': 16 | return; 17 | } 18 | } 19 | } 20 | 21 | static void mdjvu_skip_pbm_whitespace_and_comments(mdjvu_file_t f) 22 | { 23 | FILE *file = (FILE *) f; 24 | int c = fgetc(file); 25 | while(1) 26 | { 27 | switch(c) 28 | { 29 | case ' ': case '\t': case '\r': case '\n': 30 | c = fgetc(file); 31 | break; 32 | case '#': 33 | skip_to_the_end_of_line(file); 34 | c = fgetc(file); 35 | break; 36 | default: 37 | ungetc(c,file); 38 | return; 39 | } 40 | } 41 | } 42 | 43 | MDJVU_IMPLEMENT int mdjvu_save_pbm(mdjvu_bitmap_t b, const char *path, mdjvu_error_t *perr) 44 | { 45 | FILE *file = fopen(path, "wb"); 46 | int result; 47 | if (perr) *perr = NULL; 48 | if (!file) 49 | { 50 | if (perr) *perr = mdjvu_get_error(mdjvu_error_fopen_write); 51 | return 0; 52 | } 53 | result = mdjvu_file_save_pbm(b, (mdjvu_file_t) file, perr); 54 | fclose(file); 55 | return result; 56 | } 57 | 58 | MDJVU_IMPLEMENT int mdjvu_file_save_pbm(mdjvu_bitmap_t b, mdjvu_file_t f, mdjvu_error_t *perr) 59 | { 60 | FILE *file = (FILE *) f; 61 | int32 bytes_per_row = mdjvu_bitmap_get_packed_row_size(b); 62 | int32 width = mdjvu_bitmap_get_width(b); 63 | int32 height = mdjvu_bitmap_get_height(b); 64 | int32 i; 65 | 66 | if (perr) *perr = NULL; 67 | 68 | fprintf(file, "P4\n"MDJVU_INT32_FORMAT" "MDJVU_INT32_FORMAT"\n", 69 | width, height); 70 | 71 | for (i = 0; i < height; i++) 72 | { 73 | unsigned char *row = mdjvu_bitmap_access_packed_row(b, i); 74 | if (fwrite(row, bytes_per_row, 1, file) != 1) 75 | { 76 | if (perr) *perr = mdjvu_get_error(mdjvu_error_io); 77 | return 0; 78 | } 79 | } 80 | return 1; 81 | } 82 | 83 | MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_load_pbm(const char *path, mdjvu_error_t *perr) 84 | { 85 | FILE *file = fopen(path, "rb"); 86 | mdjvu_bitmap_t result; 87 | if (perr) *perr = NULL; 88 | if (!file) 89 | { 90 | if(perr) *perr = mdjvu_get_error(mdjvu_error_fopen_read); 91 | return NULL; 92 | } 93 | result = mdjvu_file_load_pbm((mdjvu_file_t) file, perr); 94 | fclose(file); 95 | return result; 96 | } 97 | 98 | #define COMPLAIN \ 99 | { \ 100 | if (perr) *perr = mdjvu_get_error(mdjvu_error_corrupted_pbm); \ 101 | return NULL; \ 102 | } 103 | MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_file_load_pbm(mdjvu_file_t f, mdjvu_error_t *perr) 104 | { 105 | FILE *file = (FILE *) f; 106 | int32 width, height, bytes_per_row, i; 107 | mdjvu_bitmap_t result; 108 | if (perr) *perr = NULL; 109 | if (fgetc(file) != 'P') COMPLAIN; 110 | if (fgetc(file) != '4') COMPLAIN; 111 | mdjvu_skip_pbm_whitespace_and_comments((mdjvu_file_t) file); 112 | if (fscanf(file, 113 | MDJVU_INT32_FORMAT" "MDJVU_INT32_FORMAT, &width, &height) != 2) 114 | { 115 | COMPLAIN; 116 | } 117 | 118 | /* a fancy way to write if ( || || || ) - maybe, abandon this switch? */ 119 | switch(fgetc(file)) 120 | { 121 | case ' ': case '\t': case '\r': case '\n': 122 | break; 123 | default: 124 | COMPLAIN; 125 | } 126 | 127 | result = mdjvu_bitmap_create(width, height); 128 | bytes_per_row = mdjvu_bitmap_get_packed_row_size(result); 129 | for (i = 0; i < height; i++) 130 | { 131 | unsigned char *current_row = mdjvu_bitmap_access_packed_row(result, i); 132 | if (fread(current_row, bytes_per_row, 1, file) != 1) 133 | { 134 | mdjvu_bitmap_destroy(result); 135 | COMPLAIN; 136 | } 137 | } 138 | return result; 139 | } 140 | -------------------------------------------------------------------------------- /src/image-io/tiff.c: -------------------------------------------------------------------------------- 1 | /* 2 | * tiff.c - just a couple of functions that are neither loading nor saving 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | 7 | #ifdef HAVE_LIBTIFF 8 | #include 9 | #define MDJVU_USE_TIFFIO 10 | #endif 11 | 12 | #include 13 | #include 14 | 15 | MDJVU_IMPLEMENT int mdjvu_have_tiff_support(void) 16 | { 17 | #ifdef HAVE_LIBTIFF 18 | return 1; 19 | #else 20 | return 0; 21 | #endif 22 | } 23 | 24 | MDJVU_IMPLEMENT void mdjvu_disable_tiff_warnings(void) 25 | { 26 | #ifdef HAVE_LIBTIFF 27 | TIFFSetWarningHandler(NULL); 28 | #endif 29 | } 30 | -------------------------------------------------------------------------------- /src/image-io/tiffload.c: -------------------------------------------------------------------------------- 1 | /* 2 | * tiffload.c - loading TIFF bitmaps 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | 7 | #ifdef HAVE_LIBTIFF 8 | #include 9 | #define MDJVU_USE_TIFFIO 10 | #endif 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #ifdef HAVE_LIBTIFF 17 | 18 | static mdjvu_bitmap_t load_tiff(const char *path, int32 *presolution, mdjvu_error_t *perr, uint32 idx) 19 | { 20 | uint16 photometric; 21 | uint32 w, h; 22 | uint16 bits_per_sample = 0, samples_per_pixel = 0; 23 | float dpi; 24 | mdjvu_bitmap_t result; 25 | tsize_t scanline_size; 26 | unsigned char *scanline; 27 | uint32 i; 28 | 29 | TIFF *tiff = TIFFOpen(path, "r"); 30 | for ( i=0; tiff != NULL && i> (w & 7)); 112 | 113 | memcpy(mdjvu_bitmap_access_packed_row(result, i), 114 | scanline, 115 | mdjvu_bitmap_get_packed_row_size(result)); 116 | } 117 | 118 | free(scanline); 119 | 120 | TIFFClose(tiff); 121 | return result; 122 | } 123 | 124 | MDJVU_IMPLEMENT uint32 mdjvu_get_tiff_page_count(const char *path) 125 | { 126 | int dircount = 0; 127 | TIFF* tif = TIFFOpen(path, "r"); 128 | 129 | /* a "directory" is a page in a multipage tiff */ 130 | 131 | if ( tif ) { 132 | do { 133 | dircount++; 134 | } while ( TIFFReadDirectory(tif) ); 135 | TIFFClose(tif); 136 | } 137 | return dircount; 138 | } 139 | 140 | #endif /* HAVE_LIBTIFF */ 141 | 142 | MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_load_tiff(const char *path, int32 *presolution, mdjvu_error_t *perr, uint32 idx) 143 | { 144 | #ifdef HAVE_LIBTIFF 145 | return load_tiff(path, presolution, perr, idx); 146 | #else 147 | *perr = mdjvu_get_error(mdjvu_error_tiff_support_disabled); 148 | return NULL; 149 | #endif 150 | } 151 | -------------------------------------------------------------------------------- /src/image-io/tiffsave.c: -------------------------------------------------------------------------------- 1 | /* 2 | * tiffsave.c - saving TIFF bitmaps 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | 7 | #ifdef HAVE_LIBTIFF 8 | #include 9 | #define MDJVU_USE_TIFFIO 10 | #endif 11 | 12 | #include 13 | 14 | #ifdef HAVE_LIBTIFF 15 | 16 | #ifndef COMPRESSION_PACKBITS 17 | #define COMPRESSION_PACKBITS 32771 18 | #endif 19 | 20 | static int save_tiff(mdjvu_bitmap_t bitmap, const char *path, mdjvu_error_t *perr) 21 | { 22 | int32 w = mdjvu_bitmap_get_width(bitmap); 23 | int32 h = mdjvu_bitmap_get_height(bitmap); 24 | int32 compression = COMPRESSION_NONE; 25 | int32 i; 26 | TIFF * tiff; 27 | 28 | *perr = NULL; 29 | 30 | if (TIFFFindCODEC(COMPRESSION_PACKBITS)) 31 | compression = COMPRESSION_PACKBITS; 32 | 33 | tiff = TIFFOpen(path, "w"); 34 | 35 | if (!tiff) 36 | { 37 | *perr = mdjvu_get_error(mdjvu_error_fopen_write); 38 | return 0; 39 | } 40 | 41 | /* FIXME: save resolution */ 42 | TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, (uint32) w); 43 | TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, (uint32) h); 44 | TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, (uint16) 1); 45 | TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16) 1); 46 | TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 47 | TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression); 48 | TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); 49 | 50 | if (mdjvu_bitmap_get_packed_row_size(bitmap) != TIFFScanlineSize(tiff)) 51 | { 52 | /* FIXME: not very accurate error reporting */ 53 | *perr = mdjvu_get_error(mdjvu_error_fopen_write); 54 | return 0; 55 | } 56 | 57 | for (i = 0; i < h; i++) 58 | TIFFWriteScanline(tiff, 59 | mdjvu_bitmap_access_packed_row(bitmap, i), i, 60 | 0); 61 | 62 | TIFFClose(tiff); 63 | 64 | return 1; 65 | } 66 | 67 | #endif /* HAVE_LIBTIFF */ 68 | 69 | MDJVU_IMPLEMENT int mdjvu_save_tiff(mdjvu_bitmap_t bitmap, const char *path, mdjvu_error_t *perr) 70 | { 71 | #ifdef HAVE_LIBTIFF 72 | return save_tiff(bitmap, path, perr); 73 | #else 74 | *perr = mdjvu_get_error(mdjvu_error_tiff_support_disabled); 75 | return 0; 76 | #endif 77 | } 78 | -------------------------------------------------------------------------------- /src/jb2/README: -------------------------------------------------------------------------------- 1 | JB2 is the bitonal compression algorithm of DjVu. 2 | 3 | 4 | With DjVuLibre, you can extract a raw JB2 chunk from a DjVu file by 5 | 6 | djvuextract input.djvu Sjbz=output.jb2 7 | 8 | and assemble it back to DjVu with 9 | 10 | djvumake output.djvu Sjbz=input.jb2 11 | -------------------------------------------------------------------------------- /src/jb2/bmpcoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bmpcoder.h - encoding/decoding bitmaps (DjVu 2 specification, 8.5.9-10) 3 | */ 4 | 5 | #ifndef MDJVU_BMPCODER_H 6 | #define MDJVU_BMPCODER_H 7 | 8 | #include "jb2const.h" 9 | #include "zp.h" 10 | 11 | class JB2BitmapCoder 12 | { 13 | public: 14 | void reset_numcontexts(); // this was introduced in DjVu 3 15 | protected: 16 | ZPBitContext bitmap_direct[1024]; 17 | ZPBitContext bitmap_refine[2048]; 18 | ZPNumContext 19 | symbol_width, 20 | symbol_height, 21 | symbol_width_difference, 22 | symbol_height_difference; 23 | JB2BitmapCoder(ZPMemoryWatcher *w = NULL); 24 | 25 | virtual ~JB2BitmapCoder(); 26 | 27 | void code_row_directly(int32 n, unsigned char *up2, 28 | unsigned char *up1, 29 | unsigned char *target, 30 | unsigned char *erosion); 31 | void code_row_by_refinement(int32 n, 32 | unsigned char *up1, 33 | unsigned char *target, 34 | unsigned char *p_up, 35 | unsigned char *p_sm, 36 | unsigned char *p_dn, 37 | unsigned char *erosion); 38 | void code_image_directly(mdjvu_bitmap_t, mdjvu_bitmap_t erosion_mask); 39 | void code_image_by_refinement(mdjvu_bitmap_t, mdjvu_bitmap_t prototype, mdjvu_bitmap_t erosion_mask); 40 | 41 | virtual int code_pixel(ZPBitContext &, unsigned char *pixel, int erosion) = 0; 42 | virtual void load_row(mdjvu_bitmap_t, int32 y, unsigned char *row) = 0; 43 | virtual void save_row(mdjvu_bitmap_t, int32 y, unsigned char *row, int erosion) = 0; 44 | }; 45 | 46 | class JB2BitmapDecoder : public JB2BitmapCoder 47 | { 48 | public: 49 | mdjvu_bitmap_t decode(mdjvu_image_t, 50 | mdjvu_bitmap_t prototype = NULL); 51 | JB2BitmapDecoder(ZPDecoder &, ZPMemoryWatcher *w = NULL); 52 | private: 53 | ZPDecoder &zp; 54 | // JB3BitmapDecoder jb3; /* XXX */ 55 | virtual int code_pixel(ZPBitContext &, unsigned char *pixel, int erosion); 56 | virtual void load_row(mdjvu_bitmap_t, int32 y, unsigned char *row); 57 | virtual void save_row(mdjvu_bitmap_t, int32 y, unsigned char *row, int erosion); 58 | }; 59 | 60 | class JB2BitmapEncoder : public JB2BitmapCoder 61 | { 62 | public: 63 | void encode(mdjvu_bitmap_t, mdjvu_bitmap_t prototype = NULL, mdjvu_bitmap_t erosion_mask = NULL); 64 | JB2BitmapEncoder(ZPEncoder &, ZPMemoryWatcher *w = NULL); 65 | private: 66 | ZPEncoder &zp; 67 | // JB3BitmapEncoder jb3; /* XXX */ 68 | virtual int code_pixel(ZPBitContext &, unsigned char *pixel, int erosion); 69 | virtual void load_row(mdjvu_bitmap_t, int32 y, unsigned char *row); 70 | virtual void save_row(mdjvu_bitmap_t, int32 y, unsigned char *row, int erosion); 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/jb2/jb2coder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * jb2coder.cpp - coding character positions and JB2 records 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include "jb2coder.h" 7 | 8 | // JB2Coder implementation {{{ 9 | 10 | JB2Coder::JB2Coder() : 11 | watcher(), 12 | image_size(0, jb2_big_positive_number, &watcher), 13 | matching_symbol_index(0, 0, &watcher),// changed on the fly 14 | symbol_column_number(0, 0, &watcher), // changed after start_of_image 15 | symbol_row_number(0, 0, &watcher), // changed after start_of_image 16 | same_line_column_offset 17 | (jb2_big_negative_number, jb2_big_positive_number, &watcher), 18 | same_line_row_offset 19 | (jb2_big_negative_number, jb2_big_positive_number, &watcher), 20 | new_line_column_offset 21 | (jb2_big_negative_number, jb2_big_positive_number, &watcher), 22 | new_line_row_offset 23 | (jb2_big_negative_number, jb2_big_positive_number, &watcher), 24 | comment_length(0, jb2_big_positive_number, &watcher), 25 | comment_octet(0, 255, &watcher), 26 | required_dictionary_size(0, jb2_big_positive_number, &watcher), 27 | record_type(0, 11, &watcher), 28 | first(-1, 0, 0, 1), 29 | line_counter(0) 30 | { 31 | } 32 | 33 | JB2Coder::~JB2Coder() 34 | { 35 | } 36 | 37 | void JB2Coder::reset_numcontexts() 38 | { 39 | record_type.reset(); 40 | image_size.reset(); 41 | matching_symbol_index.reset(); 42 | symbol_column_number.reset(); 43 | symbol_row_number.reset(); 44 | same_line_column_offset.reset(); 45 | same_line_row_offset.reset(); 46 | new_line_column_offset.reset(); 47 | new_line_row_offset.reset(); 48 | comment_length.reset(); 49 | comment_octet.reset(); 50 | required_dictionary_size.reset(); 51 | } 52 | 53 | // JB2Coder implementation }}} 54 | 55 | JB2Decoder::JB2Decoder(FILE *f, int32 length) 56 | : JB2BitmapDecoder(zp), zp(f, length) {} 57 | JB2Encoder::JB2Encoder(FILE *f) 58 | : JB2BitmapEncoder(zp), zp(f), no_symbols_yet(true) {} 59 | 60 | // Coding character positions {{{ 61 | 62 | void JB2Decoder::decode_character_position(int32 &x, int32 &y, int32 w, int32 h)/*{{{*/ 63 | { 64 | // implements section 8.5.8 (page 31) of DjVu 2 specs 65 | // FIXME: too much code is duplicated with encode_character_position() 66 | 67 | if (zp.decode(offset_type)) 68 | { 69 | // new line 70 | 71 | x = first.left + zp.decode(new_line_column_offset); 72 | int dy = zp.decode(new_line_row_offset); 73 | y = first.top + first.height - 1 - dy; // their offset is up, not down 74 | 75 | // start a new line with the current symbol 76 | line_counter = 1; 77 | first.left = x; 78 | first.top = y; 79 | first.width = w; 80 | first.height = h; 81 | prev1 = first; 82 | } 83 | else 84 | { 85 | x = prev1.left + prev1.width - 1 + zp.decode(same_line_column_offset); 86 | int baseline; 87 | 88 | if (line_counter < 3) 89 | { 90 | baseline = first.top + first.height; 91 | } 92 | else 93 | { 94 | int b1 = prev1.top + prev1.height; 95 | int b2 = prev2.top + prev2.height; 96 | int b3 = prev3.top + prev3.height; 97 | 98 | // baseline is the median of b1, b2 and b3 99 | if (b1 > b2) {int t = b1; b1 = b2; b2 = t;} 100 | if (b1 > b3) {int t = b1; b1 = b3; b3 = t;} 101 | if (b2 > b3) {int t = b2; b2 = b3; b3 = t;} 102 | 103 | baseline = b2; 104 | } 105 | 106 | y = baseline - h - zp.decode(same_line_row_offset); 107 | 108 | // continue the current line with the current symbol 109 | line_counter++; 110 | prev3 = prev2; 111 | prev2 = prev1; 112 | prev1.left = x; 113 | prev1.top = y; 114 | prev1.width = w; 115 | prev1.height = h; 116 | } 117 | }/*}}}*/ 118 | void JB2Encoder::encode_character_position(int x, int y, int w, int h)/*{{{*/ 119 | { 120 | // implements section 8.5.8 (page 31) of DjVu 2 specs 121 | // FIXME: too much code is duplicated with decode_character_position() 122 | 123 | int new_line; 124 | if (no_symbols_yet) 125 | { 126 | no_symbols_yet = false; 127 | new_line = true; 128 | } 129 | else 130 | { 131 | new_line = x < prev1.left; // taken from DjVuLibre 132 | } 133 | 134 | zp.encode(new_line ? 1 : 0, offset_type); 135 | if (new_line) 136 | { 137 | // new line 138 | 139 | zp.encode(x - first.left, new_line_column_offset); 140 | zp.encode(first.top + first.height - 1 - y, new_line_row_offset); 141 | 142 | // start a new line with the current symbol 143 | line_counter = 1; 144 | first.left = x; 145 | first.top = y; 146 | first.width = w; 147 | first.height = h; 148 | prev1 = first; 149 | } 150 | else 151 | { 152 | zp.encode(x - prev1.left - prev1.width + 1, same_line_column_offset); 153 | int baseline; 154 | 155 | if (line_counter < 3) 156 | { 157 | baseline = first.top + first.height; 158 | } 159 | else 160 | { 161 | int b1 = prev1.top + prev1.height; 162 | int b2 = prev2.top + prev2.height; 163 | int b3 = prev3.top + prev3.height; 164 | 165 | // baseline is the median of b1, b2 and b3 166 | if (b1 > b2) {int t = b1; b1 = b2; b2 = t;} 167 | if (b1 > b3) {int t = b1; b1 = b3; b3 = t;} 168 | if (b2 > b3) {int t = b2; b2 = b3; b3 = t;} 169 | 170 | baseline = b2; 171 | } 172 | 173 | zp.encode(baseline - h - y, same_line_row_offset); 174 | 175 | // continue the current line with the current symbol 176 | line_counter++; 177 | prev3 = prev2; 178 | prev2 = prev1; 179 | prev1.left = x; 180 | prev1.top = y; 181 | prev1.width = w; 182 | prev1.height = h; 183 | } 184 | }/*}}}*/ 185 | 186 | // Coding character positions }}} 187 | 188 | int32 JB2Decoder::decode_blit(mdjvu_image_t img, int32 shape_index) 189 | { 190 | mdjvu_bitmap_t shape = mdjvu_image_get_bitmap(img, shape_index); 191 | int32 w = mdjvu_bitmap_get_width(shape); 192 | int32 h = mdjvu_bitmap_get_height(shape); 193 | int32 x, y; 194 | decode_character_position(x, y, w, h); 195 | return mdjvu_image_add_blit(img, x, y, shape); 196 | } 197 | 198 | void JB2Encoder::encode_blit(mdjvu_image_t img, int32 blit, int32 w, int32 h) 199 | { 200 | int32 x = mdjvu_image_get_blit_x(img, blit); 201 | int32 y = mdjvu_image_get_blit_y(img, blit); 202 | encode_character_position(x, y, w, h); 203 | } 204 | 205 | void JB2Encoder::open_record(JB2RecordType type) 206 | { 207 | zp.encode(type, record_type); 208 | } 209 | 210 | void JB2Encoder::close_record() 211 | { 212 | if (watcher.count > JB2_NUMBER_CONTEXTS_MEMORY_BOUND) 213 | { 214 | zp.encode(jb2_require_dictionary_or_reset, record_type); 215 | JB2Coder::reset_numcontexts(); 216 | JB2BitmapEncoder::reset_numcontexts(); 217 | watcher.reset(); 218 | } 219 | } 220 | 221 | void JB2Decoder::reset() 222 | { 223 | JB2Coder::reset_numcontexts(); 224 | JB2BitmapDecoder::reset_numcontexts(); 225 | } 226 | 227 | JB2RecordType JB2Decoder::decode_record_type() 228 | { 229 | return (JB2RecordType) zp.decode(record_type); 230 | } 231 | -------------------------------------------------------------------------------- /src/jb2/jb2coder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jb2coder.h - coding character positions and JB2 records 3 | */ 4 | 5 | #ifndef MDJVU_JB2CODER_H 6 | #define MDJVU_JB2CODER_H 7 | 8 | #include "bmpcoder.h" 9 | 10 | // struct JB2Rect - a simple rectangle class {{{ 11 | 12 | struct JB2Rect 13 | { 14 | int left, top, width, height; 15 | inline JB2Rect() {} 16 | inline JB2Rect(int l, int t, int w, int h) 17 | : left(l), top(t), width(w), height(h) {} 18 | }; 19 | 20 | // struct JB2Rect }}} 21 | 22 | // JB2Coder interface {{{ 23 | 24 | /* Watcher interface + implementation {{{ */ 25 | 26 | struct Watcher : ZPMemoryWatcher 27 | { 28 | int32 count; 29 | Watcher() : count(0) {} 30 | 31 | virtual void handle_allocation() 32 | { 33 | count++; 34 | } 35 | 36 | void reset() {count = 0;} 37 | }; 38 | 39 | /* Watcher }}} */ 40 | 41 | class JB2Coder 42 | { 43 | public: 44 | Watcher watcher; 45 | ZPNumContext 46 | image_size, 47 | matching_symbol_index, 48 | symbol_column_number, 49 | symbol_row_number, 50 | same_line_column_offset, 51 | same_line_row_offset, 52 | new_line_column_offset, 53 | new_line_row_offset, 54 | comment_length, 55 | comment_octet, 56 | required_dictionary_size; 57 | 58 | ZPBitContext eventual_image_refinement, offset_type; 59 | JB2Coder(); 60 | ~JB2Coder(); 61 | 62 | protected: 63 | ZPNumContext record_type; 64 | JB2Rect first, prev3, prev2, prev1; 65 | int line_counter; 66 | void reset_numcontexts(); 67 | }; 68 | 69 | // JB2Coder interface }}} 70 | 71 | // JB2Decoder interface {{{ 72 | 73 | struct JB2Decoder : JB2Coder, JB2BitmapDecoder 74 | { 75 | ZPDecoder zp; 76 | JB2Decoder(FILE *f, int32 chunk_length); 77 | JB2RecordType decode_record_type(); 78 | 79 | // decodes character position and creates a new blit 80 | int32 decode_blit(mdjvu_image_t, int32 shape_index); 81 | 82 | void reset(); // resets numcontexts as required by "reset" record 83 | 84 | private: 85 | void decode_character_position(int32 &x, int32 &y, int32 w, int32 h); 86 | }; 87 | 88 | // JB2Decoder interface }}} 89 | 90 | // JB2Encoder interface {{{ 91 | 92 | struct JB2Encoder : JB2Coder, JB2BitmapEncoder 93 | { 94 | ZPEncoder zp; 95 | JB2Encoder(FILE *f); 96 | 97 | // encodes blit position 98 | // w and h are passed here in case of substitution 99 | void encode_blit(mdjvu_image_t img, int32 blit, int32 w, int32 h); 100 | 101 | void open_record(JB2RecordType); 102 | void close_record(); // takes care of the DjVu 3 numcontext reset 103 | 104 | private: 105 | void encode_character_position(int x, int y, int w, int h); 106 | bool no_symbols_yet; 107 | }; 108 | 109 | // JB2Encoder interface }}} 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /src/jb2/jb2const.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jb2const.h - some constants defined by DjVu specification 3 | */ 4 | 5 | #ifndef MDJVU_JB2CONST_H 6 | #define MDJVU_JB2CONST_H 7 | 8 | #define JB2_NUMBER_CONTEXTS_MEMORY_BOUND 20000 9 | 10 | enum JB2RecordType 11 | { 12 | jb2_start_of_image, 13 | jb2_new_symbol_add_to_image_and_library, 14 | jb2_new_symbol_add_to_library_only, 15 | jb2_new_symbol_add_to_image_only, 16 | jb2_matched_symbol_with_refinement_add_to_image_and_library, 17 | jb2_matched_symbol_with_refinement_add_to_library_only, 18 | jb2_matched_symbol_with_refinement_add_to_image_only, 19 | jb2_matched_symbol_copy_to_image_without_refinement, 20 | jb2_non_symbol_data, 21 | jb2_require_dictionary_or_reset, 22 | jb2_comment, 23 | jb2_end_of_data 24 | }; 25 | 26 | enum {jb2_big_negative_number = -262143, 27 | jb2_big_positive_number = 262142}; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/jb2/jb2load.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * jb2load.cpp - loading JB2 files by interpreting them record-by-record 3 | */ 4 | 5 | #include "../base/mdjvucfg.h" 6 | #include 7 | #include 8 | #include 9 | #include "zp.h" 10 | #include "jb2coder.h" 11 | 12 | // A piece of my old code... should it be eliminated? 13 | template inline T * 14 | append_to_list(T *&list, int32 &count, int32 &allocated) 15 | { 16 | if (allocated == count) 17 | { 18 | allocated <<= 1; 19 | list = (T *) realloc(list, allocated * sizeof(T)); 20 | } 21 | return &list[count++]; 22 | } 23 | 24 | static mdjvu_bitmap_t decode_lib_shape/*{{{*/ 25 | (JB2Decoder &jb2, mdjvu_image_t img, bool with_blit, mdjvu_bitmap_t proto) 26 | { 27 | int32 blit = -1; // to please compilers 28 | int32 index = mdjvu_image_get_bitmap_count(img); 29 | 30 | mdjvu_bitmap_t shape = jb2.decode(img, proto); 31 | if (with_blit) 32 | { 33 | blit = jb2.decode_blit(img, index); 34 | } 35 | 36 | int32 x, y; 37 | mdjvu_bitmap_remove_margins(shape, &x, &y); 38 | 39 | if (with_blit) 40 | { 41 | mdjvu_image_set_blit_x(img, blit, mdjvu_image_get_blit_x(img, blit) + x); 42 | mdjvu_image_set_blit_y(img, blit, mdjvu_image_get_blit_y(img, blit) + y); 43 | } 44 | 45 | return shape; 46 | }/*}}}*/ 47 | 48 | #define COMPLAIN \ 49 | { \ 50 | if (perr) *perr = mdjvu_get_error(mdjvu_error_corrupted_jb2); \ 51 | return NULL; \ 52 | } 53 | MDJVU_IMPLEMENT mdjvu_image_t mdjvu_file_load_jb2(mdjvu_file_t file, int32 length, mdjvu_error_t *perr)/*{{{*/ 54 | { 55 | if (perr) *perr = NULL; 56 | FILE *f = (FILE *) file; 57 | JB2Decoder jb2(f, length); 58 | ZPDecoder &zp = jb2.zp; 59 | 60 | int32 d = 0; 61 | int32 t = jb2.decode_record_type(); 62 | 63 | if (t == jb2_require_dictionary_or_reset) 64 | { 65 | d = zp.decode(jb2.required_dictionary_size); 66 | t = jb2.decode_record_type(); 67 | } 68 | 69 | if (t != jb2_start_of_image) COMPLAIN; 70 | 71 | int32 w = zp.decode(jb2.image_size); 72 | int32 h = zp.decode(jb2.image_size); 73 | zp.decode(jb2.eventual_image_refinement); // dropped 74 | jb2.symbol_column_number.set_interval(1, w); 75 | jb2.symbol_row_number.set_interval(1, h); 76 | 77 | mdjvu_image_t img = mdjvu_image_create(w, h); /* d is dropped for now - XXX*/ 78 | 79 | int32 lib_count = 0, lib_alloc = 128; 80 | mdjvu_bitmap_t *library; 81 | 82 | library = (mdjvu_bitmap_t *) malloc(lib_alloc * sizeof(mdjvu_bitmap_t)); 83 | 84 | while(1) 85 | { 86 | t = jb2.decode_record_type(); 87 | switch(t) 88 | { 89 | case jb2_new_symbol_add_to_image_and_library: 90 | *(append_to_list(library, lib_count, lib_alloc)) 91 | = decode_lib_shape(jb2, img, true, NULL); 92 | break; 93 | case jb2_new_symbol_add_to_library_only: 94 | *(append_to_list(library, lib_count, lib_alloc)) 95 | = decode_lib_shape(jb2, img, false, NULL); 96 | break; 97 | case jb2_new_symbol_add_to_image_only: 98 | { 99 | jb2.decode(img); 100 | jb2.decode_blit(img, mdjvu_image_get_bitmap_count(img)-1); 101 | } 102 | break; 103 | case jb2_matched_symbol_with_refinement_add_to_image_and_library: 104 | { 105 | if (!lib_count) 106 | { 107 | mdjvu_image_destroy(img); 108 | free(library); 109 | COMPLAIN; 110 | } 111 | jb2.matching_symbol_index.set_interval(0, lib_count - 1); 112 | int32 match = zp.decode(jb2.matching_symbol_index); 113 | *(append_to_list(library, lib_count, lib_alloc)) 114 | = decode_lib_shape(jb2, img, true, library[match]); 115 | } 116 | break; 117 | case jb2_matched_symbol_with_refinement_add_to_library_only: 118 | { 119 | if (!lib_count) 120 | { 121 | mdjvu_image_destroy(img); 122 | free(library); 123 | COMPLAIN; 124 | } 125 | jb2.matching_symbol_index.set_interval(0, lib_count - 1); 126 | int32 match = zp.decode(jb2.matching_symbol_index); 127 | *(append_to_list(library, lib_count, lib_alloc)) 128 | = decode_lib_shape(jb2, img, false, library[match]); 129 | } 130 | break; 131 | case jb2_matched_symbol_with_refinement_add_to_image_only: 132 | { 133 | if (!lib_count) 134 | { 135 | mdjvu_image_destroy(img); 136 | free(library); 137 | COMPLAIN; 138 | } 139 | jb2.matching_symbol_index.set_interval(0, lib_count - 1); 140 | int32 match = zp.decode(jb2.matching_symbol_index); 141 | jb2.decode(img, library[match]); 142 | jb2.decode_blit(img, mdjvu_image_get_bitmap_count(img)-1); 143 | } 144 | break; 145 | case jb2_matched_symbol_copy_to_image_without_refinement: 146 | { 147 | if (!lib_count) 148 | { 149 | mdjvu_image_destroy(img); 150 | free(library); 151 | COMPLAIN; 152 | } 153 | jb2.matching_symbol_index.set_interval(0, lib_count - 1); 154 | int32 match = zp.decode(jb2.matching_symbol_index); 155 | jb2.decode_blit(img, match); 156 | } 157 | break; 158 | case jb2_non_symbol_data: 159 | { 160 | mdjvu_bitmap_t bmp = jb2.decode(img); 161 | int32 x = zp.decode(jb2.symbol_column_number) - 1; 162 | int32 y = h - zp.decode(jb2.symbol_row_number); 163 | mdjvu_image_add_blit(img, x, y, bmp); 164 | } 165 | break; 166 | 167 | case jb2_require_dictionary_or_reset: 168 | jb2.reset(); 169 | break; 170 | 171 | case jb2_comment: 172 | { 173 | int32 len = zp.decode(jb2.comment_length); 174 | while (len--) zp.decode(jb2.comment_octet); 175 | } 176 | break; 177 | 178 | case jb2_end_of_data: 179 | free(library); 180 | return img; 181 | default: 182 | free(library); 183 | mdjvu_image_destroy(img); 184 | COMPLAIN; 185 | } // switch 186 | } // while(1) 187 | }/*}}}*/ 188 | -------------------------------------------------------------------------------- /src/jb2/zp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * zp.h - ZP-coder from DjVuLibre, an adaptive arithmetical binary coder 3 | */ 4 | 5 | /* The DjVuLibre code is a bit reorganized, but the algorithms are the same. 6 | * Z-coder was stripped. 7 | */ 8 | 9 | 10 | #ifndef ZP_H 11 | #define ZP_H 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | typedef int Bit; 19 | 20 | 21 | /* ZPBitContext is an adaptation variable. 22 | * A ZP-coder works together with a context, 23 | * and both are changed in the process, 24 | * but the context is detachable. 25 | */ 26 | 27 | class ZPBitContext 28 | { 29 | public: 30 | ZPBitContext(); 31 | private: 32 | unsigned char value; 33 | 34 | friend class ZPNumContext; 35 | friend class ZPEncoder; 36 | friend class ZPDecoder; 37 | 38 | public: 39 | inline Bit get_more_probable_bit() {return value & 1;} 40 | inline void assign(ZPBitContext &c) {value = c.value;} 41 | }; 42 | 43 | inline ZPBitContext::ZPBitContext(): value(0) {} 44 | 45 | 46 | /* ZPMemoryWatcher is a purely abstract class. 47 | * Its only goal is to receive notifications 48 | * when a ZPNumContext has allocated a bit context. 49 | * This unit contains no implementation of ZPMemoryWatcher. 50 | */ 51 | class ZPMemoryWatcher 52 | { 53 | public: 54 | virtual void handle_allocation() = 0; 55 | virtual ~ZPMemoryWatcher(); 56 | }; 57 | 58 | 59 | /* ZPNumContext is a tree of ZPBitContexts. 60 | * Its nodes are accessed by indices. 61 | * Root node always has the index of 0. 62 | * 63 | * Nodes are created automatically. 64 | */ 65 | class ZPNumContext 66 | { 67 | public: 68 | ZPNumContext(int32 amin, int32 amax, ZPMemoryWatcher *w = NULL); 69 | ~ZPNumContext(); 70 | void set_interval(int32 new_min, int32 new_max); 71 | void reset(); 72 | private: 73 | int32 min, max; 74 | ZPMemoryWatcher *watcher; 75 | ZPBitContext *nodes; 76 | uint16 n; 77 | uint16 allocated; 78 | uint16 *left, *right; // 0 means nil 79 | uint16 new_node(); 80 | uint16 get_left(uint16); 81 | uint16 get_right(uint16); 82 | void init(); 83 | friend class ZPEncoder; 84 | friend class ZPDecoder; 85 | }; 86 | 87 | 88 | class ZPEncoder 89 | { 90 | public: 91 | ZPEncoder(FILE *); // does not close it on destruction 92 | virtual ~ZPEncoder(); 93 | void encode_without_context(Bit); 94 | void encode(Bit, ZPBitContext &); 95 | void encode(int32, ZPNumContext &); 96 | void close(); 97 | 98 | private: 99 | FILE *file; 100 | void emit_byte(unsigned char); 101 | uint32 a, nrun, subend, buffer; 102 | unsigned char delay, byte, scount; 103 | bool closed; 104 | 105 | void outbit(Bit); 106 | void zemit(Bit); 107 | void export_bits(); 108 | void encode_mps(ZPBitContext &, uint32); 109 | void encode_lps(ZPBitContext &, uint32); 110 | void encode_mps_simple(uint32); 111 | void encode_lps_simple(uint32); 112 | }; 113 | 114 | 115 | class ZPDecoder 116 | { 117 | public: 118 | ZPDecoder(FILE *, int32 length); // does not close it on destruction 119 | Bit decode_without_context(); 120 | Bit decode(ZPBitContext &); 121 | int32 decode(ZPNumContext &); 122 | private: 123 | FILE *file; 124 | uint32 a, code, fence, buffer; 125 | int32 bytes_left; 126 | unsigned char byte, scount, delay; 127 | bool next_byte(unsigned char &); 128 | void open(); 129 | void preload(); 130 | int32 ffz(uint32); 131 | Bit decode_sub(ZPBitContext &, uint32); 132 | Bit decode_sub_simple(uint32); 133 | }; 134 | 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /src/matcher/bitmaps.h: -------------------------------------------------------------------------------- 1 | /* Plasma OCR - an OCR engine 2 | * 3 | * bitmaps.h - some routines that work with bitmaps 4 | * 5 | * Copyright (C) 2006 Ilya Mezhirov 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | 23 | /* Since Plasma is going into touch with many other projects, 24 | * I've decided not to write nor use any class for bitmaps. 25 | * It's always just (unsigned char **pixels, int w, int h). 26 | */ 27 | 28 | #ifndef PLASMA_OCR_BITMAP_H 29 | #define PLASMA_OCR_BITMAP_H 30 | 31 | 32 | #include "common.h" 33 | 34 | FUNCTIONS_BEGIN 35 | 36 | /* Just allocate a w * h array. */ 37 | unsigned char **allocate_bitmap(int w, int h); 38 | void free_bitmap(unsigned char **); 39 | void assign_bitmap(unsigned char **dst, unsigned char **src, int w, int h); 40 | void assign_unpacked_bitmap(unsigned char **dst, unsigned char **src, int w, int h); 41 | void assign_unpacked_bitmap_with_shift(unsigned char **dst, unsigned char **src, int w, int h, int N); 42 | unsigned char **copy_bitmap(unsigned char **, int w, int h); 43 | 44 | 45 | 46 | /* Allocate a w * h bitmap with margins of 1 pixels at each side. 47 | * Indices into such a bitmap range from -1 to w or h. 48 | * Free the allocated bitmap with free_bitmap_with_margins(). 49 | */ 50 | unsigned char **allocate_bitmap_with_margins(int w, int h); 51 | void free_bitmap_with_margins(unsigned char **); 52 | 53 | /* Allocate bitmap with margins and clear those margins. */ 54 | unsigned char **allocate_bitmap_with_white_margins(int w, int h); 55 | 56 | 57 | void print_bitmap(unsigned char **, int w, int h); 58 | 59 | 60 | /* Allocate a w * h bitmap with margins of 1 pixels at each side. 61 | * Copy `pixels' there and clear the margins. 62 | */ 63 | unsigned char **provide_margins(unsigned char **, int w, int h, int make_it_0_or_1); 64 | 65 | 66 | void make_bitmap_0_or_1(unsigned char **, int w, int h); 67 | 68 | 69 | void invert_bitmap_0_or_1(unsigned char **, int w, int h); 70 | 71 | // same as invert_bitmap_0_or_1 but for unpacked bitmaps 72 | void invert_bitmap(unsigned char **, int w, int h); 73 | void invert_bitmap_old(unsigned char **pixels, int w, int h, int first_make_it_0_or_1); 74 | 75 | void clear_bitmap(unsigned char **pixels, int w, int h); 76 | 77 | 78 | /* Clear pixels that have exactly 1 of 4 (or 8) neighbors. 79 | * (Well, I have in mind some usage for this one). 80 | * 81 | * `pixels' must have margins. 82 | * 83 | * `result' cannot coincide with `pixels'. 84 | */ 85 | void strip_endpoints_4(unsigned char **result, unsigned char **pixels, int w, int h); 86 | void strip_endpoints_8(unsigned char **result, unsigned char **pixels, int w, int h); 87 | 88 | FUNCTIONS_END 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /src/matcher/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * common.h - some common macros 3 | */ 4 | 5 | 6 | #ifndef MDJVU_COMMON_H 7 | #define MDJVU_COMMON_H 8 | 9 | 10 | #ifdef HAVE_CONFIG_H 11 | #include "config.h" 12 | #endif 13 | 14 | 15 | #ifdef __cplusplus 16 | # define FUNCTIONS_BEGIN extern "C" { 17 | # define FUNCTIONS_END } 18 | #else 19 | # define FUNCTIONS_BEGIN 20 | # define FUNCTIONS_END 21 | #endif 22 | 23 | 24 | 25 | #include 26 | 27 | #ifdef __cplusplus 28 | /* Stuff for not using malloc in C++ 29 | * (made by Leon Bottou; has no use in minidjvu-mod, 30 | * but left here for potential DjVuLibre compatibility) 31 | */ 32 | # define MALLOC1(Type) new Type 33 | # define FREE1(p) delete (p) 34 | # define MALLOC(Type,n) new Type[n] 35 | # define FREE(p) delete [] (p) 36 | # define REALLOC oops! I hope we have no REALLOC in minidjvu-mod... 37 | #else 38 | # define MALLOC1(TYPE) ( (TYPE *) malloc(sizeof(TYPE)) ) 39 | # define MALLOC(TYPE, N) ( (TYPE *) malloc((N) * sizeof(TYPE)) ) 40 | # define REALLOC(TYPE, PTR, N) ( (TYPE *) realloc(PTR, (N) * sizeof(TYPE)) ) 41 | # define FREE1(PTR) free(PTR) 42 | # define FREE(PTR) free(PTR) 43 | #endif 44 | 45 | /* Yeah, I know this is ugly and there are C++ templates for that. 46 | * But this is for C code. 47 | */ 48 | #define LIST_APPEND(TYPE, LIST, COUNT, ALLOCATED) \ 49 | { \ 50 | if ((COUNT) == (ALLOCATED)) \ 51 | { \ 52 | (ALLOCATED) <<= 1; /* double the list */ \ 53 | (LIST) = REALLOC(TYPE, LIST, ALLOCATED); \ 54 | } \ 55 | return &(LIST)[(COUNT)++]; \ 56 | } 57 | 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/matcher/cuts.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cuts.c - finding "cuts signature" consisting of consecutive cut positions 3 | */ 4 | 5 | 6 | /* We cut an image horizontally in such a way 7 | * that below and above the cut the blackness is roughly the same. 8 | * Than cutting each of the two pieces vertically in the same fashion. 9 | * Then horizontally, and so on until SIGNATURE_SIZE - 1 cuts. 10 | * The position of each cut is normalized into 0..255 and put into signature. 11 | */ 12 | 13 | #include "../base/mdjvucfg.h" 14 | #include 15 | #include 16 | 17 | 18 | /* Stuff for not using malloc in C++ 19 | * (made by Leon Bottou; has no use in minidjvu-mod, 20 | * but left here for potential DjVuLibre compatibility) 21 | */ 22 | #ifdef __cplusplus 23 | # define MALLOC(Type) new Type 24 | # define FREE(p) delete p 25 | # define MALLOCV(Type,n) new Type[n] 26 | # define FREEV(p) delete [] p 27 | #else 28 | # define MALLOC(Type) ((Type*)malloc(sizeof(Type))) 29 | # define FREE(p) do{if(p)free(p);}while(0) 30 | # define MALLOCV(Type,n) ((Type*)malloc(sizeof(Type)*(n))) 31 | # define FREEV(p) do{if(p)free(p);}while(0) 32 | #endif 33 | 34 | 35 | typedef unsigned char byte; 36 | 37 | static int32 sum_column_gray(byte **pixels, int32 x, int32 y1, int32 y2) 38 | { 39 | int sum = 0, y; 40 | for (y = y1; y <= y2; y++) sum += pixels[y][x]; 41 | return sum; 42 | } 43 | 44 | static int32 sum_row_gray(byte *row, int32 x1, int32 x2) 45 | { 46 | int sum = 0, x, n = x2 - x1; 47 | byte *p = row + x1; 48 | for (x = 0; x <= n; x++) sum += p[x]; 49 | return sum; 50 | } 51 | 52 | static int32 sum_column_black_and_white(byte **pixels, int32 x, int32 y1, int32 y2) 53 | { 54 | int sum = 0, y; 55 | for (y = y1; y <= y2; y++) if (pixels[y][x]) sum++; 56 | return sum; 57 | } 58 | 59 | static int32 sum_row_black_and_white(byte *row, int32 x1, int32 x2) 60 | { 61 | int sum = 0, x, n = x2 - x1; 62 | byte *p = row + x1; 63 | for (x = 0; x <= n; x++) if (p[x]) sum++; 64 | return sum; 65 | } 66 | 67 | static void make_vcut(int32 a, int32 l, int32 w, int32 h, byte **pixels, 68 | byte *sig, int32 k, 69 | int32 s_row(byte *, int32, int32), 70 | int32 s_col(byte **, int32, int32, int32), 71 | int32 size); 72 | 73 | static void make_hcut(int32 a, int32 l, int32 w, int32 h, 74 | byte **pixels, byte *sig, int32 k, 75 | int32 s_row(byte *, int32, int32), 76 | int32 s_col(byte **, int32, int32, int32), 77 | int32 size) 78 | { 79 | int32 cut = 0; /* how many rows are in the top part */ 80 | int32 up_weight = 0; 81 | 82 | if (k >= size) return; 83 | 84 | if (a) 85 | { 86 | int32 last_row_weight = 0; 87 | 88 | assert(w && h); 89 | 90 | while ((up_weight << 1) < a) 91 | { 92 | last_row_weight = s_row(pixels[cut], l, l + w - 1); 93 | up_weight += last_row_weight; 94 | cut++; 95 | } 96 | cut--; 97 | up_weight -= last_row_weight; 98 | sig[k] = (byte) ((256 * 99 | (cut * w + w * ((a >> 1) - up_weight) / last_row_weight)) 100 | / (w * h)); 101 | if (a - (up_weight << 1) > last_row_weight) 102 | { 103 | cut++; 104 | up_weight += last_row_weight; 105 | } 106 | } 107 | else 108 | { 109 | cut = h / 2; 110 | sig[k] = 128; 111 | } 112 | 113 | make_vcut(up_weight, l, w, cut, pixels, sig, k << 1, s_row, s_col, size); 114 | make_vcut(a - up_weight, l, w, h - cut, pixels + cut, sig, (k << 1) | 1, s_row, s_col, size); 115 | } 116 | 117 | static void make_vcut(int32 a, int32 l, int32 w, int32 h, 118 | byte **pixels, byte *sig, int32 k, 119 | int32 s_row(byte *, int32, int32), 120 | int32 s_col(byte **, int32, int32, int32), 121 | int32 size) 122 | { 123 | int32 cut = 0; /* how many columns are in the left part */ 124 | int32 left_weight = 0; 125 | 126 | if (k >= size) return; 127 | 128 | if (a) 129 | { 130 | int32 last_col_weight = 0; 131 | 132 | assert(w && h); 133 | 134 | while ((left_weight << 1) < a) 135 | { 136 | last_col_weight = s_col(pixels, l + cut, 0, h-1); 137 | left_weight += last_col_weight; 138 | cut++; 139 | } 140 | cut--; 141 | left_weight -= last_col_weight; 142 | sig[k] = (byte) ((256 * 143 | (cut * h + h * ((a >> 1) - left_weight) / last_col_weight)) 144 | / (w * h)); 145 | if (a - (left_weight << 1) > last_col_weight) 146 | { 147 | cut++; left_weight += last_col_weight; 148 | } 149 | } 150 | else 151 | { 152 | cut = w / 2; 153 | sig[k] = 128; 154 | } 155 | 156 | make_hcut(left_weight, l, cut, h, pixels, sig, k << 1, s_row, s_col, size); 157 | make_hcut(a - left_weight, l + cut, w - cut, h, pixels, sig, (k << 1) | 1, s_row, s_col, size); 158 | } 159 | 160 | static void get_signature(int32 width, int32 height, byte **pixels, byte *sig, 161 | int32 s_row(byte *, int32, int32), 162 | int32 s_col(byte **, int32, int32, int32), 163 | int32 size) 164 | { 165 | int32 area = 0, i; 166 | for (i = 0; i < height; i++) 167 | { 168 | area += s_row(pixels[i], 0, width - 1); 169 | } 170 | /* FIXME: sig[0] is wasted */ 171 | make_hcut(area, 0, width, height, pixels, sig, 1, s_row, s_col, size); 172 | } 173 | 174 | MDJVU_IMPLEMENT void mdjvu_get_gray_signature(byte **data, int32 w, int32 h, 175 | byte *result, int32 size) 176 | { 177 | get_signature(w, h, data, result, sum_row_gray, sum_column_gray, size); 178 | } 179 | 180 | MDJVU_IMPLEMENT void mdjvu_get_black_and_white_signature 181 | (byte **data, int32 w, int32 h, 182 | byte *result, int32 size) 183 | { 184 | get_signature(w, h, data, result, sum_row_black_and_white, sum_column_black_and_white, size); 185 | } 186 | -------------------------------------------------------------------------------- /src/matcher/no_mdjvu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * no_mdjvu.h - stuff for compiling the pattern matcher outside of minidjvu-mod 3 | */ 4 | 5 | 6 | /* 7 | * to compile the pattern matcher without the rest of minidjvu-mod, 8 | * do this: 9 | * 10 | * mv no_mdjvu.h minidjvu-mod.h 11 | * touch mdjvucfg.h 12 | * g++ -c *.cpp 13 | */ 14 | 15 | #define NO_MINIDJVU 16 | #define MDJVU_FUNCTION 17 | #define MDJVU_IMPLEMENT 18 | typedef int int32; 19 | #include "patterns.h" 20 | #include "classify.h" /* to compile it with the classificator */ 21 | -------------------------------------------------------------------------------- /src/windows/minidjvu.nsi: -------------------------------------------------------------------------------- 1 | !include "MUI.nsh" 2 | 3 | ;Name and file 4 | Name "Minidjvu 0.9m07" 5 | OutFile "minidjvu-mod-0.9m07.exe" 6 | 7 | ;Default installation folder 8 | InstallDir "$PROGRAMFILES\minidjvu-mod" 9 | 10 | ;Get installation folder from registry if available 11 | InstallDirRegKey HKCU "Software\minidjvu-mod" "" 12 | 13 | 14 | ;-------------------------------- 15 | ;Interface Settings 16 | 17 | !define MUI_ABORTWARNING 18 | 19 | ;-------------------------------- 20 | ;Pages 21 | 22 | !insertmacro MUI_PAGE_WELCOME 23 | !insertmacro MUI_PAGE_LICENSE "COPYING" 24 | !insertmacro MUI_PAGE_DIRECTORY 25 | !insertmacro MUI_PAGE_INSTFILES 26 | !insertmacro MUI_PAGE_FINISH 27 | 28 | !insertmacro MUI_UNPAGE_CONFIRM 29 | !insertmacro MUI_UNPAGE_INSTFILES 30 | 31 | ;-------------------------------- 32 | ;Languages 33 | 34 | !insertmacro MUI_LANGUAGE "English" 35 | !insertmacro MUI_LANGUAGE "Russian" 36 | 37 | ;-------------------------------- 38 | ;Installer Sections 39 | 40 | Section "Install" 41 | 42 | SetOutPath "$INSTDIR" 43 | 44 | Delete "$INSTDIR\bash.dll" 45 | Delete "$INSTDIR\bash.exe" 46 | Delete "$INSTDIR\djvm.exe" 47 | Delete "$INSTDIR\jpeg_lic.html" 48 | Delete "$INSTDIR\jpeg62.dll" 49 | Delete "$INSTDIR\libtiff3.dll" 50 | Delete "$INSTDIR\rm.exe" 51 | Delete "$INSTDIR\tiff_lic.html" 52 | Delete "$INSTDIR\tiffinfo.exe" 53 | Delete "$INSTDIR\tiffsplit.exe" 54 | Delete "$INSTDIR\windjview.exe" 55 | Delete "$INSTDIR\zlib1.dll" 56 | Delete "$INSTDIR\README.html" 57 | Delete "$SMPROGRAMS\minidjvu-mod\README.lnk" 58 | Delete "$INSTDIR\minidjvu-mod.nsi" 59 | 60 | File "COPYING" 61 | File "News" 62 | File "bin\minidjvu-mod.exe" 63 | CreateDirectory $INSTDIR\doc 64 | 65 | CreateDirectory $SMPROGRAMS\minidjvu-mod 66 | CreateShortcut $SMPROGRAMS\minidjvu-mod\Uninstall.lnk $INSTDIR\Uninstall.exe 67 | 68 | ;Store installation folder 69 | WriteRegStr HKCU "Software\minidjvu-mod" "" $INSTDIR 70 | 71 | ;Create uninstaller 72 | WriteUninstaller "$INSTDIR\Uninstall.exe" 73 | 74 | SectionEnd 75 | 76 | ;Uninstaller Section 77 | 78 | Section "Uninstall" 79 | 80 | Delete "$INSTDIR\COPYING" 81 | Delete "$INSTDIR\minidjvu-mod.exe" 82 | 83 | Delete "$INSTDIR\Uninstall.exe" 84 | 85 | RMDir "$INSTDIR\doc" 86 | RMDir "$INSTDIR" 87 | 88 | Delete "$SMPROGRAMS\minidjvu-mod\Uninstall.lnk" 89 | RMDir "$SMPROGRAMS\minidjvu-mod" 90 | 91 | DeleteRegKey /ifempty HKCU "Software\minidjvu-mod" 92 | SectionEnd 93 | -------------------------------------------------------------------------------- /tools/README: -------------------------------------------------------------------------------- 1 | This is the source directory for `minidjvu-mod' executable. 2 | The sources for the minidjvu-mod library are in "src/". 3 | -------------------------------------------------------------------------------- /tools/settings-reader/AppOptions.h: -------------------------------------------------------------------------------- 1 | #ifndef APPOPTIONS_H 2 | #define APPOPTIONS_H 3 | 4 | #include 5 | #include // for NULL 6 | #include // for FILE 7 | 8 | 9 | struct ChunkFile 10 | { 11 | FILE * file; 12 | char * filename; 13 | int indirect_mode; 14 | }; 15 | 16 | struct ImageOptions 17 | { 18 | int dpi_specified; 19 | int dpi; 20 | int smooth; 21 | int clean; 22 | int erosion; 23 | 24 | // if is_virtual == 1 the file isn't really read and it's existance isn't checked 25 | // instead encoder will treat such file as empty image with size (virtual_w, virtual_h) 26 | // and dpi specified as usual. 27 | int is_virtual; 28 | int virtual_w; 29 | int virtual_h; 30 | }; 31 | 32 | struct DjbzOptions; 33 | 34 | struct InputFile 35 | { 36 | char* name; 37 | int page; 38 | // if null, use AppOptions::default_image_options 39 | struct ImageOptions* image_options; 40 | 41 | // 42 | 43 | // output_dpi is the dpi that used for saving result image. 44 | // it's 300 by default. And may be overriden by default image options 45 | // or image options if they have dpi_specified flag. 46 | // if they aren't specified the encoder will try to determine dpi 47 | // from x resolution of tiff file and use it. 48 | int output_dpi; 49 | char * id; // equal to filename without extension if not set in settings file 50 | // if page > 0 it will be added to the id. 51 | // encoder will ensure that all id's are unique 52 | char * chunk_id; // id + ".djvu" (".jb2" if -j arg is used) 53 | int output_size; 54 | 55 | struct ChunkFile chunk_file; 56 | struct DjbzOptions* djbz; 57 | }; 58 | 59 | struct FileList 60 | { 61 | int size; 62 | int data_size; 63 | struct InputFile** files; 64 | }; 65 | 66 | struct DjbzOptions 67 | { 68 | char * id; 69 | char* dict_suffix; 70 | int averaging; 71 | int aggression; 72 | int no_prototypes; 73 | int erosion; 74 | struct FileList file_list_ref; 75 | // 76 | char * chunk_id; 77 | int do_not_save; 78 | int output_size; 79 | struct ChunkFile chunk_file; 80 | }; 81 | 82 | struct DjbzList 83 | { 84 | int size; 85 | int data_size; 86 | struct DjbzOptions** djbzs; 87 | }; 88 | 89 | struct AppOptions 90 | { 91 | int pages_per_dict; /* 0 means infinity */ 92 | int verbose; 93 | int match; 94 | int Match; 95 | int report; 96 | int warnings; 97 | int indirect; 98 | 99 | #ifdef _OPENMP 100 | int max_threads; 101 | #endif 102 | 103 | struct ImageOptions* default_image_options; 104 | struct FileList file_list; 105 | 106 | struct DjbzOptions* default_djbz_options; 107 | struct DjbzList djbz_list; 108 | 109 | char* output_file; 110 | int save_as_chunk; 111 | 112 | }; 113 | 114 | #ifdef __cplusplus 115 | extern "C" { 116 | #endif 117 | 118 | void copy_str_alloc(char** dest, const char *src); 119 | void replace_suffix(char *name, const char *suffix); 120 | 121 | struct ImageOptions* image_options_create(struct ImageOptions* defaults); 122 | 123 | void file_list_init(struct FileList* fl); 124 | void file_list_reserve(struct FileList* fl, int size); 125 | void file_list_clear(struct FileList *fl); 126 | int file_list_find(struct FileList* fl, const struct InputFile* in); 127 | void file_list_add_file_ref(struct FileList* fl, struct InputFile *file); 128 | void file_list_add_filename(struct FileList *fl, const char* fname, const char* id, struct ImageOptions* options); 129 | void file_list_add_filename_with_filter(struct FileList *fl, const char* fname, const char* id, int pg_min, int pg_max, struct ImageOptions* options); 130 | void file_list_add_ref(struct FileList* dest, struct FileList* src, const char* fname); 131 | void file_list_add_ref_with_filter(struct FileList* dest, struct FileList* src, const char* fname, int pg_min, int pg_max); 132 | 133 | struct DjbzOptions* djbz_setting_create(struct DjbzOptions *defaults); 134 | void djbz_setting_destroy(struct DjbzOptions* sett); 135 | 136 | void djbz_list_init(struct DjbzList* dl); 137 | void djbz_list_reserve(struct DjbzList *dl, int size); 138 | void djbz_list_clear(struct DjbzList* dl); 139 | void djbz_list_add_option(struct DjbzList* dl, struct DjbzOptions* djbz); 140 | 141 | void chunk_file_create(struct ChunkFile* cf, char* fname); 142 | void chunk_file_open(struct ChunkFile* cf); 143 | void chunk_file_close(struct ChunkFile* cf); 144 | void chunk_file_destroy(struct ChunkFile* cf); 145 | 146 | 147 | void app_options_init(struct AppOptions* opts); 148 | void app_options_free(struct AppOptions* opts); 149 | void app_options_set_djbz_suffix(struct AppOptions* opts, char* suffix); 150 | void app_options_set_output_file(struct AppOptions* opts, const char* filename); 151 | 152 | // search for input-files that aren't belong to any Djbz dict 153 | // and assign them to a new Djbz according to default options. 154 | void app_options_autocomplete_djbzs(struct AppOptions* opts); 155 | 156 | void app_options_construct_chunk_ids(struct AppOptions* opts); 157 | 158 | #ifdef __cplusplus 159 | } 160 | #endif 161 | 162 | #endif // APPOPTIONS_H 163 | -------------------------------------------------------------------------------- /tools/settings-reader/COPYRIGHT: -------------------------------------------------------------------------------- 1 | //C- -*- C++ -*- 2 | //C- ------------------------------------------------------------------- 3 | //C- DjVuLibre-3.5 4 | //C- Copyright (c) 2002 Leon Bottou and Yann Le Cun. 5 | //C- Copyright (c) 2001 AT&T 6 | //C- 7 | //C- This software is subject to, and may be distributed under, the 8 | //C- GNU General Public License, either Version 2 of the license, 9 | //C- or (at your option) any later version. The license should have 10 | //C- accompanied the software or you may obtain a copy of the license 11 | //C- from the Free Software Foundation at http://www.fsf.org . 12 | //C- 13 | //C- This program is distributed in the hope that it will be useful, 14 | //C- but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | //C- GNU General Public License for more details. 17 | //C- 18 | //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from 19 | //C- Lizardtech Software. Lizardtech Software has authorized us to 20 | //C- replace the original DjVu(r) Reference Library notice by the following 21 | //C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu): 22 | //C- 23 | //C- ------------------------------------------------------------------ 24 | //C- | DjVu (r) Reference Library (v. 3.5) 25 | //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved. 26 | //C- | The DjVu Reference Library is protected by U.S. Pat. No. 27 | //C- | 6,058,214 and patents pending. 28 | //C- | 29 | //C- | This software is subject to, and may be distributed under, the 30 | //C- | GNU General Public License, either Version 2 of the license, 31 | //C- | or (at your option) any later version. The license should have 32 | //C- | accompanied the software or you may obtain a copy of the license 33 | //C- | from the Free Software Foundation at http://www.fsf.org . 34 | //C- | 35 | //C- | The computer code originally released by LizardTech under this 36 | //C- | license and unmodified by other parties is deemed "the LIZARDTECH 37 | //C- | ORIGINAL CODE." Subject to any third party intellectual property 38 | //C- | claims, LizardTech grants recipient a worldwide, royalty-free, 39 | //C- | non-exclusive license to make, use, sell, or otherwise dispose of 40 | //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 41 | //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 42 | //C- | General Public License. This grant only confers the right to 43 | //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 44 | //C- | the extent such infringement is reasonably necessary to enable 45 | //C- | recipient to make, have made, practice, sell, or otherwise dispose 46 | //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 47 | //C- | any greater extent that may be necessary to utilize further 48 | //C- | modifications or combinations. 49 | //C- | 50 | //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY 51 | //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 52 | //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF 53 | //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 54 | //C- +------------------------------------------------------------------ 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /tools/settings-reader/GOS.h: -------------------------------------------------------------------------------- 1 | //C- -*- C++ -*- 2 | //C- ------------------------------------------------------------------- 3 | //C- DjVuLibre-3.5 4 | //C- Copyright (c) 2002 Leon Bottou and Yann Le Cun. 5 | //C- Copyright (c) 2001 AT&T 6 | //C- 7 | //C- This software is subject to, and may be distributed under, the 8 | //C- GNU General Public License, either Version 2 of the license, 9 | //C- or (at your option) any later version. The license should have 10 | //C- accompanied the software or you may obtain a copy of the license 11 | //C- from the Free Software Foundation at http://www.fsf.org . 12 | //C- 13 | //C- This program is distributed in the hope that it will be useful, 14 | //C- but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | //C- GNU General Public License for more details. 17 | //C- 18 | //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from 19 | //C- Lizardtech Software. Lizardtech Software has authorized us to 20 | //C- replace the original DjVu(r) Reference Library notice by the following 21 | //C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu): 22 | //C- 23 | //C- ------------------------------------------------------------------ 24 | //C- | DjVu (r) Reference Library (v. 3.5) 25 | //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved. 26 | //C- | The DjVu Reference Library is protected by U.S. Pat. No. 27 | //C- | 6,058,214 and patents pending. 28 | //C- | 29 | //C- | This software is subject to, and may be distributed under, the 30 | //C- | GNU General Public License, either Version 2 of the license, 31 | //C- | or (at your option) any later version. The license should have 32 | //C- | accompanied the software or you may obtain a copy of the license 33 | //C- | from the Free Software Foundation at http://www.fsf.org . 34 | //C- | 35 | //C- | The computer code originally released by LizardTech under this 36 | //C- | license and unmodified by other parties is deemed "the LIZARDTECH 37 | //C- | ORIGINAL CODE." Subject to any third party intellectual property 38 | //C- | claims, LizardTech grants recipient a worldwide, royalty-free, 39 | //C- | non-exclusive license to make, use, sell, or otherwise dispose of 40 | //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 41 | //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 42 | //C- | General Public License. This grant only confers the right to 43 | //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 44 | //C- | the extent such infringement is reasonably necessary to enable 45 | //C- | recipient to make, have made, practice, sell, or otherwise dispose 46 | //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 47 | //C- | any greater extent that may be necessary to utilize further 48 | //C- | modifications or combinations. 49 | //C- | 50 | //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY 51 | //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 52 | //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF 53 | //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 54 | //C- +------------------------------------------------------------------ 55 | 56 | #ifndef _GOS_H_ 57 | #define _GOS_H_ 58 | #ifdef HAVE_CONFIG_H 59 | #include "config.h" 60 | #endif 61 | #if NEED_GNUG_PRAGMAS 62 | # pragma interface 63 | #endif 64 | 65 | /** @name GOS.h 66 | Files #"GOS.h"# and #"GOS.cpp"# implement operating system 67 | dependent functions with a unified interface. All these functions 68 | are implemented as static member of class \Ref{GOS}. 69 | Functions are provided for testing the presence of a file or a directory 70 | (\Ref{GOS::is_file}, \Ref{GOS::is_dir}), for manipulating file and directory names 71 | (\Ref{GOS::dirname}, \Ref{GOS::basename}, \Ref{GOS::expand_name}, 72 | for obtaining and changing the current directory (\Ref{GOS::cwd}), 73 | for converting between file names and urls (\Ref{GOS::filename_to_url}, 74 | \Ref{GOS::url_to_filename}), and for counting time (\Ref{GOS::ticks}, 75 | \Ref{GOS::sleep}). 76 | 77 | @memo 78 | Operating System dependent functions. 79 | @author 80 | L\'eon Bottou -- Initial implementation 81 | */ 82 | //@{ 83 | 84 | #include "DjVuGlobal.h" 85 | #include "GString.h" 86 | 87 | #ifdef HAVE_NAMESPACES 88 | namespace DJVU { 89 | # ifdef NOT_DEFINED // Just to fool emacs c++ mode 90 | } 91 | #endif 92 | #endif 93 | 94 | 95 | class GURL; 96 | 97 | /** Operating System dependent functions. */ 98 | class DJVUAPI GOS 99 | { 100 | public: 101 | // ----------------------------------------- 102 | // Functions for dealing with filenames 103 | // ----------------------------------------- 104 | 105 | /** Returns the last component of file name #filename#. If the filename 106 | suffix matches argument #suffix#, the filename suffix is removed. This 107 | function works like the unix command #/bin/basename#, but also supports 108 | the naming conventions of other operating systems. */ 109 | static GUTF8String basename(const GUTF8String &filename, const char *suffix=0); 110 | 111 | /** Sets and returns the current working directory. 112 | When argument #dirname# is specified, the current directory is changed 113 | to #dirname#. This function always returns the fully qualified name 114 | of the current directory. */ 115 | static GUTF8String cwd(const GUTF8String &dirname=GUTF8String()); 116 | 117 | // ----------------------------------------- 118 | // Functions for measuring time 119 | // ----------------------------------------- 120 | 121 | /** Returns a number of elapsed milliseconds. This number counts elapsed 122 | milliseconds since a operating system dependent date. This function is 123 | useful for timing code. */ 124 | static unsigned long ticks(); 125 | 126 | /** Sleeps during the specified time expressed in milliseconds. 127 | Other threads can run while the calling thread sleeps. */ 128 | static void sleep(int milliseconds); 129 | 130 | /// Read the named variable from the environment, and converts it to UTF8. 131 | static GUTF8String getenv(const GUTF8String &name); 132 | 133 | #if 0 134 | // ------------------------------------------- 135 | // Functions for converting filenames and urls 136 | // ------------------------------------------- 137 | /** Encodes all reserved characters, so that the #filename# can be 138 | used inside a URL. Every reserved character is encoded using escape 139 | sequence in the form of #%XX#. The legal characters are alphanumeric and 140 | #$-_.+!*'(),:#. 141 | Use \Ref{decode_reserved}() to convert the URL back to the filename. */ 142 | // static GString encode_reserved(const char * filename); 143 | static GString encode_mbcs_reserved(const char * filename);/*MBCS*/ 144 | #endif 145 | 146 | }; 147 | 148 | 149 | //@} 150 | // ------------ 151 | 152 | #ifdef HAVE_NAMESPACES 153 | } 154 | # ifndef NOT_USING_DJVU_NAMESPACE 155 | using namespace DJVU; 156 | # endif 157 | #endif 158 | #endif 159 | -------------------------------------------------------------------------------- /tools/settings-reader/GSmartPointer.cpp: -------------------------------------------------------------------------------- 1 | //C- -*- C++ -*- 2 | //C- ------------------------------------------------------------------- 3 | //C- DjVuLibre-3.5 4 | //C- Copyright (c) 2002 Leon Bottou and Yann Le Cun. 5 | //C- Copyright (c) 2001 AT&T 6 | //C- 7 | //C- This software is subject to, and may be distributed under, the 8 | //C- GNU General Public License, either Version 2 of the license, 9 | //C- or (at your option) any later version. The license should have 10 | //C- accompanied the software or you may obtain a copy of the license 11 | //C- from the Free Software Foundation at http://www.fsf.org . 12 | //C- 13 | //C- This program is distributed in the hope that it will be useful, 14 | //C- but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | //C- GNU General Public License for more details. 17 | //C- 18 | //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from 19 | //C- Lizardtech Software. Lizardtech Software has authorized us to 20 | //C- replace the original DjVu(r) Reference Library notice by the following 21 | //C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu): 22 | //C- 23 | //C- ------------------------------------------------------------------ 24 | //C- | DjVu (r) Reference Library (v. 3.5) 25 | //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved. 26 | //C- | The DjVu Reference Library is protected by U.S. Pat. No. 27 | //C- | 6,058,214 and patents pending. 28 | //C- | 29 | //C- | This software is subject to, and may be distributed under, the 30 | //C- | GNU General Public License, either Version 2 of the license, 31 | //C- | or (at your option) any later version. The license should have 32 | //C- | accompanied the software or you may obtain a copy of the license 33 | //C- | from the Free Software Foundation at http://www.fsf.org . 34 | //C- | 35 | //C- | The computer code originally released by LizardTech under this 36 | //C- | license and unmodified by other parties is deemed "the LIZARDTECH 37 | //C- | ORIGINAL CODE." Subject to any third party intellectual property 38 | //C- | claims, LizardTech grants recipient a worldwide, royalty-free, 39 | //C- | non-exclusive license to make, use, sell, or otherwise dispose of 40 | //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 41 | //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 42 | //C- | General Public License. This grant only confers the right to 43 | //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 44 | //C- | the extent such infringement is reasonably necessary to enable 45 | //C- | recipient to make, have made, practice, sell, or otherwise dispose 46 | //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 47 | //C- | any greater extent that may be necessary to utilize further 48 | //C- | modifications or combinations. 49 | //C- | 50 | //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY 51 | //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 52 | //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF 53 | //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 54 | //C- +------------------------------------------------------------------ 55 | 56 | #ifdef HAVE_CONFIG_H 57 | # include "config.h" 58 | #endif 59 | #if NEED_GNUG_PRAGMAS 60 | # pragma implementation 61 | #endif 62 | 63 | // - Author: Leon Bottou, 05/1997 64 | 65 | // From: Leon Bottou, 1/31/2002 66 | // Class GPBuffer has been added (but not documented) by Lizardtech. 67 | // Our original implementation consisted of multiple classes. 68 | // . 69 | 70 | #include 71 | #include 72 | #if PARANOID_DEBUG 73 | # include 74 | #endif 75 | 76 | //#include "GThreads.h" 77 | #include "GSmartPointer.h" 78 | #include "GException.h" 79 | 80 | #ifdef HAVE_NAMESPACES 81 | namespace DJVU { 82 | # ifdef NOT_DEFINED // Just to fool emacs c++ mode 83 | } 84 | #endif 85 | #endif 86 | 87 | 88 | // ------ GPENABLED 89 | 90 | GPEnabled::~GPEnabled() 91 | { 92 | #if DISABLED_BECAUSE_OF_CXX11_DESTRUCTORS_BEING_NOEXCEPT 93 | if (count > 0) 94 | G_THROW( ERR_MSG("GSmartPointer.suspicious") ); 95 | #endif 96 | } 97 | 98 | void 99 | GPEnabled::destroy() 100 | { 101 | // Only delete if the counter is still zero. 102 | // because someone may have rescued the object... 103 | // If yes, set the counter to -0x7fff to mark 104 | // the object as doomed and make sure things 105 | // will work if the destructor uses a GP... 106 | if (! atomicCompareAndSwap(&count, 0, -0x7fff)) 107 | delete this; 108 | } 109 | 110 | 111 | // ------ GPBASE 112 | 113 | 114 | GPBase& 115 | GPBase::assign (const GPBase &sptr) 116 | { 117 | GPEnabled *nptr = sptr.ptr; 118 | if (nptr && atomicIncrement(&nptr->count) <= 0) 119 | nptr = 0; 120 | GPEnabled *optr = (GPEnabled*)atomicExchangePointer((void**)&ptr, (void*)nptr); 121 | if (optr) 122 | optr->unref(); 123 | return *this; 124 | } 125 | 126 | GPBase& 127 | GPBase::assign (GPEnabled *nptr) 128 | { 129 | if (nptr && atomicIncrement(&nptr->count) <= 0) 130 | nptr = 0; 131 | GPEnabled *optr = (GPEnabled*)atomicExchangePointer((void**)&ptr, (void*)nptr); 132 | if (optr) 133 | optr->unref(); 134 | return *this; 135 | } 136 | 137 | 138 | 139 | 140 | // ------ GPBUFFERBASE 141 | 142 | 143 | void 144 | GPBufferBase::replace(void *nptr,const size_t n) 145 | { 146 | resize(0,0); 147 | ptr=nptr; 148 | num=n; 149 | } 150 | 151 | GPBufferBase::GPBufferBase(void *&xptr,const size_t n,const size_t t) 152 | : ptr(xptr), num(n) 153 | { 154 | if (n) 155 | xptr = ::operator new(n*t); 156 | else 157 | xptr = 0; 158 | } 159 | 160 | GPBufferBase::~GPBufferBase() 161 | { 162 | ::operator delete(ptr); 163 | } 164 | 165 | void 166 | GPBufferBase::swap(GPBufferBase &other) 167 | { 168 | void * const temp_ptr=ptr; 169 | ptr=other.ptr; 170 | other.ptr=temp_ptr; 171 | const size_t temp_num=num; 172 | num=other.num; 173 | other.num=temp_num; 174 | } 175 | 176 | void 177 | GPBufferBase::resize(const size_t n, const size_t t) 178 | { 179 | if(!n && !ptr) 180 | { 181 | num=0; 182 | } 183 | else 184 | { 185 | const size_t s=ptr?(((num gbs; // NOTE: keeping a copy, otherwise bs is destroyed while using in SettingsReader.cpp 75 | ByteStream &bs; 76 | unsigned char buffer[bufsize]; 77 | int bufpos; 78 | int bufend; 79 | bool goteof; 80 | ParsingByteStream(const GP &gbs); 81 | int getbom(int c); 82 | public: 83 | static GP create(const GP &gbs) 84 | { return new ParsingByteStream(gbs); } 85 | size_t read(void *buffer, size_t size); 86 | size_t write(const void *buffer, size_t size); 87 | long int tell() const; 88 | int eof(); 89 | int unget(int c); 90 | inline int get(); 91 | int get_spaces(bool skipseparator=false); 92 | GUTF8String get_token(bool skipseparator=false, bool* delimited = nullptr, bool compat=false); 93 | const char *get_error_context(int c=EOF); 94 | }; 95 | 96 | 97 | #endif // PARSINGBYTESTREAM_H 98 | -------------------------------------------------------------------------------- /tools/settings-reader/README: -------------------------------------------------------------------------------- 1 | This subfolder contains a significant piece of DjVuLibre sourcecode which 2 | is build and linked as a shared c++ library: libminidjvu-mod-settings. 3 | 4 | The code is required to obtain ParsingByteStream class functionality. 5 | It's used for reading minidjvu options from a file. Reusage of ParsingByteStream 6 | to stick to djvused-like input files format. 7 | -------------------------------------------------------------------------------- /tools/settings-reader/SettingsReader.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGSREADER_H 2 | #define SETTINGSREADER_H 3 | 4 | #include "AppOptions.h" 5 | 6 | class ParsingByteStream; 7 | template class GP; 8 | class GUTF8String; 9 | 10 | class SettingsReader 11 | { 12 | public: 13 | SettingsReader(const char* settings_file, struct AppOptions * appOptions); 14 | bool readAllOptions(); 15 | ~SettingsReader(); 16 | private: 17 | // bool readToken(GUTF8String& token); 18 | bool readAppOptions(); 19 | bool readFile(struct FileList *file_list, bool ref_only); 20 | bool readInputFiles(struct FileList *file_list, bool ref_only); 21 | bool readDjbzOptions(struct DjbzOptions *djbz, bool is_defaults); 22 | bool readImageOptions(struct ImageOptions *opts); 23 | 24 | bool readValInt(const char* name, int &src, int min = 0, int max = 1); 25 | bool readValStr(const char* name, GUTF8String &src); 26 | private: 27 | GP* m_bs; 28 | struct AppOptions* m_appOptions; 29 | }; 30 | 31 | #endif // SETTINGSREADER_H 32 | -------------------------------------------------------------------------------- /tools/settings-reader/SettingsReaderAdapter.cpp: -------------------------------------------------------------------------------- 1 | #include "SettingsReaderAdapter.h" 2 | #include "SettingsReader.h" 3 | #include "GException.h" 4 | 5 | int read_app_options_from_file(const char* fname, struct AppOptions* opts) 6 | { 7 | if (opts) { 8 | G_TRY { 9 | SettingsReader reader(fname, opts); 10 | return reader.readAllOptions(); 11 | } G_CATCH(exc) { 12 | exc.perror(); 13 | exit(-2); 14 | } G_ENDCATCH; 15 | } 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /tools/settings-reader/SettingsReaderAdapter.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGSREADERADAPTER_H 2 | #define SETTINGSREADERADAPTER_H 3 | 4 | #include "AppOptions.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | int read_app_options_from_file(const char* fname, struct AppOptions* opts); 11 | 12 | #ifdef __cplusplus 13 | } 14 | 15 | #endif 16 | 17 | 18 | #endif // SETTINGSREADERADAPTER_H 19 | -------------------------------------------------------------------------------- /tools/settings-reader/UnicodeByteStream.cpp: -------------------------------------------------------------------------------- 1 | //C- -*- C++ -*- 2 | //C- ------------------------------------------------------------------- 3 | //C- DjVuLibre-3.5 4 | //C- Copyright (c) 2002 Leon Bottou and Yann Le Cun. 5 | //C- Copyright (c) 2001 AT&T 6 | //C- 7 | //C- This software is subject to, and may be distributed under, the 8 | //C- GNU General Public License, either Version 2 of the license, 9 | //C- or (at your option) any later version. The license should have 10 | //C- accompanied the software or you may obtain a copy of the license 11 | //C- from the Free Software Foundation at http://www.fsf.org . 12 | //C- 13 | //C- This program is distributed in the hope that it will be useful, 14 | //C- but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | //C- GNU General Public License for more details. 17 | //C- 18 | //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from 19 | //C- Lizardtech Software. Lizardtech Software has authorized us to 20 | //C- replace the original DjVu(r) Reference Library notice by the following 21 | //C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu): 22 | //C- 23 | //C- ------------------------------------------------------------------ 24 | //C- | DjVu (r) Reference Library (v. 3.5) 25 | //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved. 26 | //C- | The DjVu Reference Library is protected by U.S. Pat. No. 27 | //C- | 6,058,214 and patents pending. 28 | //C- | 29 | //C- | This software is subject to, and may be distributed under, the 30 | //C- | GNU General Public License, either Version 2 of the license, 31 | //C- | or (at your option) any later version. The license should have 32 | //C- | accompanied the software or you may obtain a copy of the license 33 | //C- | from the Free Software Foundation at http://www.fsf.org . 34 | //C- | 35 | //C- | The computer code originally released by LizardTech under this 36 | //C- | license and unmodified by other parties is deemed "the LIZARDTECH 37 | //C- | ORIGINAL CODE." Subject to any third party intellectual property 38 | //C- | claims, LizardTech grants recipient a worldwide, royalty-free, 39 | //C- | non-exclusive license to make, use, sell, or otherwise dispose of 40 | //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 41 | //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 42 | //C- | General Public License. This grant only confers the right to 43 | //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 44 | //C- | the extent such infringement is reasonably necessary to enable 45 | //C- | recipient to make, have made, practice, sell, or otherwise dispose 46 | //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 47 | //C- | any greater extent that may be necessary to utilize further 48 | //C- | modifications or combinations. 49 | //C- | 50 | //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY 51 | //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 52 | //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF 53 | //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 54 | //C- +------------------------------------------------------------------ 55 | 56 | #ifdef HAVE_CONFIG_H 57 | # include "config.h" 58 | #endif 59 | #if NEED_GNUG_PRAGMAS 60 | # pragma implementation 61 | #endif 62 | 63 | #include "UnicodeByteStream.h" 64 | #include "ByteStream.h" 65 | 66 | 67 | #ifdef HAVE_NAMESPACES 68 | namespace DJVU { 69 | # ifdef NOT_DEFINED // Just to fool emacs c++ mode 70 | } 71 | #endif 72 | #endif 73 | 74 | UnicodeByteStream::UnicodeByteStream(const UnicodeByteStream &uni) 75 | : bs(uni.bs), buffer(uni.buffer), bufferpos(uni.bufferpos), linesread(0) 76 | { 77 | startpos=bs->tell(); 78 | } 79 | 80 | UnicodeByteStream::UnicodeByteStream( 81 | GP ibs,const GStringRep::EncodeType et) 82 | : bs(ibs), bufferpos(0), linesread(0) 83 | { 84 | buffer=GUTF8String::create(0,0,et); 85 | startpos=bs->tell(); 86 | } 87 | 88 | UnicodeByteStream::~UnicodeByteStream() 89 | {} 90 | 91 | static int 92 | CountLines(const GUTF8String &str) 93 | { 94 | int retval=0; 95 | static const unsigned long lf='\n'; 96 | for(int pos=0;(pos=str.search(lf,pos)+1)>0;++retval) 97 | EMPTY_LOOP; 98 | return retval; 99 | } 100 | 101 | void 102 | UnicodeByteStream::set_encodetype(const GStringRep::EncodeType et) 103 | { 104 | seek(startpos,SEEK_SET); 105 | bufferpos=0; 106 | buffer=GUTF8String::create(0,0,et); 107 | } 108 | 109 | void 110 | UnicodeByteStream::set_encoding(const GUTF8String &xencoding) 111 | { 112 | seek(startpos,SEEK_SET); 113 | bufferpos=0; 114 | buffer=GUTF8String::create(0,0,xencoding); 115 | } 116 | 117 | size_t 118 | UnicodeByteStream::read(void *buf, size_t size) 119 | { 120 | bufferpos=0; 121 | const int retval=bs->read(buf,size); 122 | if(retval) 123 | { 124 | buffer=GUTF8String::create( 125 | (unsigned char const *)buf,retval,buffer.get_remainder()); 126 | }else 127 | { 128 | buffer=GUTF8String::create(0,0,buffer.get_remainder()); 129 | } 130 | return retval; 131 | } 132 | 133 | size_t 134 | UnicodeByteStream::write(const void *buf, size_t size) 135 | { 136 | bufferpos=0; 137 | buffer=GUTF8String::create(0,0,buffer.get_remainder()); 138 | return bs->write(buf,size); 139 | } 140 | 141 | long 142 | UnicodeByteStream::tell(void) const 143 | { 144 | return bs->tell(); 145 | } 146 | 147 | UnicodeByteStream & 148 | UnicodeByteStream::operator=(UnicodeByteStream &uni) 149 | { 150 | bs=uni.bs; 151 | bufferpos=uni.bufferpos; 152 | buffer=uni.buffer; 153 | return *this; 154 | } 155 | 156 | int 157 | UnicodeByteStream::seek 158 | (long offset, int whence, bool nothrow) 159 | { 160 | int retval=bs->seek(offset,whence,nothrow); 161 | bufferpos=0; 162 | buffer=GUTF8String::create(0,0,buffer.get_remainder()); 163 | return retval; 164 | } 165 | 166 | void 167 | UnicodeByteStream::flush(void) 168 | { 169 | bs->flush(); 170 | bufferpos=0; 171 | buffer=GUTF8String::create(0,0,buffer.get_remainder()); 172 | } 173 | 174 | 175 | 176 | GUTF8String 177 | UnicodeByteStream::gets( 178 | size_t const t,unsigned long const stopat,bool const inclusive) 179 | { 180 | GUTF8String retval; 181 | unsigned int len=buffer.length()-bufferpos; 182 | if(!len) 183 | { 184 | int i; 185 | char *buf; 186 | static const size_t bufsize=327680; 187 | GPBuffer gbuf(buf,bufsize); 188 | while((i=read(buf,bufsize)>0)) 189 | { 190 | if((len=buffer.length()-bufferpos)) 191 | break; 192 | } 193 | } 194 | if(len) 195 | { 196 | int i=buffer.search((char)stopat,bufferpos); 197 | if(i>=0) 198 | { 199 | if(inclusive) 200 | { 201 | ++i; 202 | } 203 | if(t&&(i>(int)t+bufferpos)) 204 | { 205 | i=t+bufferpos; 206 | } 207 | if(i>bufferpos) 208 | { 209 | retval=buffer.substr(bufferpos,i-bufferpos); 210 | } 211 | bufferpos=i; 212 | linesread+=CountLines(retval); 213 | }else 214 | { 215 | retval=buffer.substr(bufferpos,len); 216 | bufferpos=buffer.length(); 217 | linesread+=CountLines(retval); 218 | retval+=gets(t?(t-(i-bufferpos)):0,stopat,inclusive); 219 | } 220 | } 221 | return retval; 222 | } 223 | 224 | #ifdef HAVE_NAMESPACES 225 | } 226 | # ifndef NOT_USING_DJVU_NAMESPACE 227 | using namespace DJVU; 228 | # endif 229 | #endif 230 | -------------------------------------------------------------------------------- /tools/settings-reader/atomic.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C -*- 2 | // ------------------------------------------------------------------- 3 | // Atomic primitives 4 | // Copyright (c) 2008 Leon Bottou. All rights reserved 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining 7 | // a copy of this software and associated documentation files (the 8 | // "Software"), to deal in the Software without restriction, including 9 | // without limitation the rights to use, copy, modify, merge, publish, 10 | // distribute, sublicense, and/or sell copies of the Software, and to 11 | // permit persons to whom the Software is furnished to do so, subject to 12 | // the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be 15 | // included in all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | // 25 | // ------------------------------------------------------------------- */ 26 | 27 | #include "atomic.h" 28 | 29 | #ifndef ATOMIC_MACROS 30 | 31 | #if HAVE_PTHREAD 32 | # include 33 | #elif HAVE_QTHREAD // never defined at the moment. 34 | # include 35 | # include 36 | #else 37 | # include "GThreads.h" 38 | #endif 39 | 40 | /* Select synchronization primitives */ 41 | 42 | # if defined(_WIN32) || defined(_WIN64) 43 | 44 | namespace { 45 | struct CS { 46 | CRITICAL_SECTION cs; 47 | CS() { InitializeCriticalSection(&cs); } 48 | ~CS() { DeleteCriticalSecton(&cs); } }; } 49 | static CS globalCS; 50 | # define MUTEX_LEAVE LeaveCriticalSection(&globalCS.cs) 51 | # define MUTEX_ENTER EnterCriticalSection(&globalCS.cs); 52 | 53 | # elif defined (PTHREAD_MUTEX_INITIALIZER) 54 | 55 | static pthread_mutex_t ptm = PTHREAD_MUTEX_INITIALIZER; 56 | # define MUTEX_ENTER pthread_mutex_lock(&ptm) 57 | # define MUTEX_LEAVE pthread_mutex_unlock(&ptm) 58 | 59 | # elif defined(__cplusplus) && defined(_GTHREADS_H_) 60 | 61 | static GMonitor m; 62 | # define MUTEX_ENTER m.enter() 63 | # define MUTEX_LEAVE m.leave() 64 | 65 | # elif defined(__cplusplus) && defined(QMUTEX_H) 66 | 67 | static QMutex qtm; 68 | # define MUTEX_ENTER qtm.lock() 69 | # define MUTEX_LEAVE qtm.unlock() 70 | 71 | # endif 72 | 73 | 74 | /* atomic primitive emulation */ 75 | 76 | int 77 | atomicIncrement(int volatile *var) 78 | { 79 | int res; 80 | MUTEX_ENTER; 81 | res = ++(*var); 82 | MUTEX_LEAVE; 83 | return res; 84 | } 85 | 86 | int 87 | atomicDecrement(int volatile *var) 88 | { 89 | int res; 90 | MUTEX_ENTER; 91 | res = --(*var); 92 | MUTEX_LEAVE; 93 | return res; 94 | } 95 | 96 | int 97 | atomicCompareAndSwap(int volatile *var, int oldval, int newval) 98 | { 99 | int ret; 100 | MUTEX_ENTER; 101 | ret = *var; 102 | if (ret == oldval) 103 | *var = newval; 104 | MUTEX_LEAVE; 105 | return ret; 106 | } 107 | 108 | int 109 | atomicExchange(int volatile *var, int newval) 110 | { 111 | int ret; 112 | MUTEX_ENTER; 113 | ret = *var; 114 | *var = newval; 115 | MUTEX_LEAVE; 116 | return ret; 117 | } 118 | 119 | void* 120 | atomicExchangePointer(void* volatile *var, void* newval) 121 | { 122 | void *ret; 123 | MUTEX_ENTER; 124 | ret = *var; 125 | *var = newval; 126 | MUTEX_LEAVE; 127 | return ret; 128 | } 129 | 130 | #endif 131 | 132 | 133 | -------------------------------------------------------------------------------- /tools/settings-reader/atomic.h: -------------------------------------------------------------------------------- 1 | /* -*- C -*- 2 | // ------------------------------------------------------------------- 3 | // Atomic primitives 4 | // Copyright (c) 2008 Leon Bottou. All rights reserved 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining 7 | // a copy of this software and associated documentation files (the 8 | // "Software"), to deal in the Software without restriction, including 9 | // without limitation the rights to use, copy, modify, merge, publish, 10 | // distribute, sublicense, and/or sell copies of the Software, and to 11 | // permit persons to whom the Software is furnished to do so, subject to 12 | // the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be 15 | // included in all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | // 25 | // ------------------------------------------------------------------- */ 26 | 27 | #ifndef ATOMIC_H 28 | #define ATOMIC_H 29 | 30 | #ifdef HAVE_CONFIG_H 31 | # include "config.h" 32 | #endif 33 | 34 | /* This file defines macros or functions performing 35 | // the following atomic operations with a full memory barrier. 36 | // 37 | // int atomicIncrement(int volatile *var) 38 | // { *var += 1; return *var; } 39 | // 40 | // int atomicDecrement(int volatile *var); 41 | // { *var -= 1; return *var; } 42 | // 43 | // int atomicCompareAndSwap(int volatile *var, int oldval, int newval); 44 | // { int val = *var; if (val == oldval) { *var = newval }; returl val; } 45 | // 46 | // int atomicExchange(int volatile *var, int val); 47 | // { int tmp = *var; *var = val; return tmp; } 48 | // 49 | // void* atomicExchangePointer(void* volatile *var, int val); 50 | // { void* tmp = *var; *var = val; return tmp; } 51 | */ 52 | 53 | #ifdef __cplusplus 54 | extern "C" { 55 | #endif 56 | 57 | #if !defined(ATOMIC_MACROS) && defined(_WIN64) 58 | # define ATOMIC_MACROS "WIN64" 59 | # include 60 | # define atomicIncrement(var) \ 61 | (int)(InterlockedIncrement((LONG volatile*)(var))) 62 | # define atomicDecrement(var) \ 63 | (int)(InterlockedDecrement((LONG volatile*)(var))) 64 | # define atomicCompareAndSwap(var,ov,nv) \ 65 | (InterlockedCompareExchange((LONG volatile*)(var),(LONG)(nv),(LONG)(ov))) 66 | # define atomicExchange(var,nv) \ 67 | (int)(InterlockedExchange((LONG volatile*)(var),(LONG)(nv))) 68 | # define atomicExchangePointer(var,nv) \ 69 | (void*)(InterlockedExchangePointer((PVOID volatile*)(var),(PVOID)(nv))) 70 | #endif 71 | 72 | #if !defined(ATOMIC_MACROS) && defined(_WIN32) 73 | # define ATOMIC_MACROS "WIN32" 74 | # include 75 | # define atomicIncrement(var) \ 76 | (int)(InterlockedIncrement((LONG volatile*)(var))) 77 | # define atomicDecrement(var) \ 78 | (int)(InterlockedDecrement((LONG volatile*)(var))) 79 | # define atomicCompareAndSwap(var,ov,nv) \ 80 | (InterlockedCompareExchange((LONG volatile*)(var),(LONG)(nv),(LONG)(ov))) 81 | # define atomicExchange(var,nv) \ 82 | (int)(InterlockedExchange((LONG volatile*)(var),(LONG)(nv))) 83 | # define atomicExchangePointer(var,nv) \ 84 | (void*)(InterlockedExchange((LONG volatile*)(var),(LONG)(nv))) 85 | #endif 86 | 87 | #if !defined(ATOMIC_MACROS) && defined(HAVE_INTEL_ATOMIC_BUILTINS) 88 | # define ATOMIC_MACROS "INTEL" 89 | # define atomicIncrement(var) \ 90 | (__sync_add_and_fetch((int volatile *)(var), 1)) 91 | # define atomicDecrement(var) \ 92 | (__sync_add_and_fetch((int volatile *)(var), -1)) 93 | # define atomicCompareAndSwap(var,ov,nv) \ 94 | (__sync_val_compare_and_swap((int volatile*)(var),(int)(ov),(int)(nv))) 95 | # if defined(__i386__) || defined(__x86_64__) || defined(__amd64__) 96 | # define atomicExchange(var,nv) \ 97 | (__sync_lock_test_and_set((int volatile*)(var),(int)(nv))) 98 | # define atomicExchangePointer(var,nv) \ 99 | (__sync_lock_test_and_set((void* volatile*)(var),(void*)(nv))) 100 | # else 101 | static inline int atomicExchange(int volatile *var, int nv) { 102 | int ov; do { ov = *var; /* overkill */ 103 | } while (! __sync_bool_compare_and_swap(var, ov, nv)); 104 | return ov; 105 | } 106 | static inline void* atomicExchangePointer(void* volatile *var, void* nv) { 107 | void *ov; do { ov = *var; /* overkill */ 108 | } while (! __sync_bool_compare_and_swap(var, ov, nv)); 109 | return ov; 110 | } 111 | # endif 112 | #endif 113 | 114 | #if !defined(ATOMIC_MACROS) && defined(__GNUC__) 115 | # if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) 116 | # define ATOMIC_MACROS "GNU86" 117 | static inline int atomicIncrement(int volatile *var) { 118 | int ov; __asm__ __volatile__ ("lock; xaddl %0, %1" 119 | : "=r" (ov), "=m" (*var) : "0" (1), "m" (*var) : "cc" ); 120 | return ov + 1; 121 | } 122 | static inline int atomicDecrement(int volatile *var) { 123 | int ov; __asm__ __volatile__ ("lock; xaddl %0, %1" 124 | : "=r" (ov), "=m" (*var) : "0" (-1), "m" (*var) : "cc" ); 125 | return ov - 1; 126 | } 127 | static inline int atomicExchange(int volatile *var, int nv) { 128 | int ov; __asm__ __volatile__ ("xchgl %0, %1" 129 | : "=r" (ov), "=m" (*var) : "0" (nv), "m" (*var)); 130 | return ov; 131 | } 132 | static inline int atomicCompareAndSwap(int volatile *var, int ov, int nv) { 133 | int rv; __asm __volatile ("lock; cmpxchgl %2, %1" 134 | : "=a" (rv), "=m" (*var) : "r" (nv), "0" (ov), "m" (*var) : "cc"); 135 | return rv; 136 | } 137 | static inline void *atomicExchangePointer(void * volatile *var, void *nv) { 138 | void *ov; __asm__ __volatile__ ( 139 | # if defined(__x86_64__) || defined(__amd64__) 140 | "xchgq %0, %1" 141 | # else 142 | "xchgl %0, %1" 143 | # endif 144 | : "=r" (ov), "=m" (*var) : "0" (nv), "m" (*var)); 145 | return ov; 146 | } 147 | # endif 148 | #endif 149 | 150 | 151 | #ifndef ATOMIC_MACROS 152 | /* emulation */ 153 | extern int atomicIncrement(int volatile *var); 154 | extern int atomicDecrement(int volatile *var); 155 | extern int atomicCompareAndSwap(int volatile *var, int ov, int nv); 156 | extern int atomicExchange(int volatile *var, int nv); 157 | extern void* atomicExchangePointer(void* volatile *var, void* nv); 158 | #endif 159 | 160 | 161 | # ifdef __cplusplus 162 | } 163 | # endif 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /wscript: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | 4 | VERSION = '0.9' 5 | APPNAME = 'minidjvu-mod' 6 | 7 | srcdir = '.' 8 | blddir = 'build' 9 | 10 | 11 | def configure(conf): 12 | conf.check_tool('gcc g++') 13 | 14 | conf.check(header_name='math.h') 15 | conf.check(lib='m') 16 | 17 | conf.check(header_name='tiffio.h', define_name='HAVE_LIBTIFF') 18 | conf.check(lib='tiff') 19 | 20 | conf.check(header_name='libintl.h', define_name='HAVE_I18N') 21 | 22 | conf.check(header_name='stdint.h', define_name='HAVE_STDINT_H') 23 | conf.write_config_header('config.h') # included from mdjvucfg.h 24 | 25 | # Compilation flags 26 | common_cflags = '-pipe -O3 -Wall -DHAVE_CONFIG_H -DNDEBUG'.split() 27 | conf.env.append_value('CCFLAGS', common_cflags + ''' 28 | -D__STRICT_ANSI__ -Wshadow -pedantic-errors 29 | -Wpointer-arith -Waggregate-return -Wlong-long 30 | -Wredundant-decls -Wcast-qual -Wcast-align 31 | '''.split()) 32 | conf.env.append_value('CXXFLAGS', common_cflags) 33 | 34 | 35 | def build(bld): 36 | bld.new_task_gen( 37 | features = 'cc cxx cstaticlib', # cshlib 38 | source = bld.glob('src/*/*.c') + bld.glob('src/*/*.cpp'), 39 | target = 'minidjvu-mod', 40 | includes = '# include', # '#' is where config.h is generated 41 | install_path = '${PREFIX}/lib', 42 | uselib = 'M TIFF' 43 | ) 44 | 45 | bld.new_task_gen( 46 | features = 'cc cxx cprogram', 47 | source = 'tools/minidjvu-mod.c', 48 | target = 'minidjvu-mod', 49 | includes = '# include', 50 | install_path = '${PREFIX}/bin', 51 | uselib = 'M TIFF', 52 | uselib_local = 'minidjvu-mod' 53 | ) 54 | 55 | headers = bld.glob('include/minidjvu-mod/*.h') + \ 56 | bld.glob('include/minidjvu-mod/*/*.h') 57 | for i in headers: 58 | bld.install_files('${PREFIX}/' + i, i) 59 | --------------------------------------------------------------------------------