Friday, March 11, 2016

Compiling ImageMagick (6.9.3-2) with Android NDK

In this post i am sharing script and configuration to build ImageMagick-6.9.3-2 for Android.

I used ImageMagick source from GIT link to build my own image converter. I made app as i wanted a very simple & straight image converter with desired features. I will timely update this app which you can get from here:

https://play.google.com/store/apps/details?id=org.greh.kisimageconverter


Before starting take a look at this guide "how to build libpng using Android NDK" which describes my OS, NDK and other tools versions.

Setup:
  • Create directory IM and extract ImageMagick-6.9.3-2 package contents inside it. Go inside extracted ImageMagick (IM) directory.
  • Create directories "prefix" and "dependencies"
  • Copy lib****.a files in IM/dependencies directory. libjasper.a liblzma.a libtiff.a libfreetype.a libjpeg.a libpng.a libwebp.a. The libpng guide above is example of how to build these libraries if you don't have them. libjasper is actually not used and is replaced by OpenJpeg/OpenJP2 as i encountered. But to keep script compatible to lower versions of IM i keep this as it is.
  • Create IM/dependencies/include directory and copy APIs i.e. headers from all above libraries inside it.


Contents as reported by directory listing ls -AR command is dumped at end of this post :


Create a shell script "AndroidBuild.sh" in IM directory with contents from below link. This script does not builds c++ API.

Android NDK Linux Build Script:
http://txt.do/5ve04 Or http://textuploader.com/5ve04


Or copy script from below (can be buggy due to corruption of newlines of script due to blog editor):



#!/bin/sh
# http://www.ourinnovativemind.in
# http://www.gamesgreh.in

# use custom build environment
export DEPENDENCIES="`pwd`/dependencies"
export INC_DEPENDENCIES=${DEPENDENCIES}/include
export INC_JPEG=${INC_DEPENDENCIES}/jpeg
export INC_PNG=${INC_DEPENDENCIES}/png
export INC_TIFF=${INC_DEPENDENCIES}/tiff
export INC_WEBP=${INC_DEPENDENCIES}/webp
export INC_TTF=${INC_DEPENDENCIES}/ttf
export INC_JASPER=${INC_DEPENDENCIES}/jasper
export INC_LZMA=${INC_DEPENDENCIES}/lzma


EXTRA_INCLUDES="-I${INC_DEPENDENCIES} -I${INC_JPEG} -I${INC_PNG} -I${INC_TIFF} -I${INC_WEBP} -I${INC_TTF} -I${INC_JASPER} -I${INC_LZMA}"
EXTRA_LIBS=$DEPENDENCIES


export CONFIGURATION_OPTIONS="--disable-installed --disable-largefile --disable-openmp --enable-static --disable-shared --disable-deprecated --disable-docs --without-threads --without-dps --with-gslib --without-freetype --without-fontconfig --without-fpx --without-magick-plus-plus --without-x --without-perl --without-pango --enable-zero-configuration"



# use custom build environment

# installation directory
export PREFIX="`pwd`/prefix"

# Path of NDK. For simplicity make symlinks in home directories
export NDK=/home/bindesh/bin/ndk

# processor specific libraries and includes.
# Suffix for arch-???. arch-arm  arch-arm64  arch-mips  arch-mips64  arch-x86  arch-x86_64
export ARCH=arm

# compiler for processor
export CROSS_COMPILE=arm-linux-androideabi

# Android platform version
export PLATFORM=android-8

# GCC compiler version
export GCC_VERSION=4.8


# Getting toolchain directory inside NDK from variables set above
# Hardcoded for linux running on x86 cpu 64-Bit
export ANDROID_PREFIX="${NDK}/toolchains/$CROSS_COMPILE-$GCC_VERSION/prebuilt/linux-x86_64"

# SYSROOT. usr dir i.e. usr/include, usr/lib
export SYSROOT="${NDK}/platforms/$PLATFORM/arch-$ARCH"
export CROSS_PATH="${ANDROID_PREFIX}/bin/${CROSS_COMPILE}"

# Some compiler and binutils. More might be needed depending on source.
export CPP=${CROSS_PATH}-cpp
export AR=${CROSS_PATH}-ar
export AS=${CROSS_PATH}-as
export NM=${CROSS_PATH}-nm
export CC=${CROSS_PATH}-gcc
export CXX=${CROSS_PATH}-g++
export LD=${CROSS_PATH}-ld
export RANLIB=${CROSS_PATH}-ranlib

# for C++ extra libs
export CXX_SYSROOT=${NDK}/sources/cxx-stl/gnu-libstdc++/${COMPILER_VERSION}  # standard template library
export CXX_BITS_INCLUDE=${CXX_SYSROOT}/libs/armeabi/include

export PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig


# Flags for compiler
export CFLAGS="${CFLAGS} --sysroot=${SYSROOT} -I${SYSROOT}/usr/include -I${ANDROID_PREFIX}/include ${EXTRA_INCLUDES}"
export CPPFLAGS="${CFLAGS}"
export LDFLAGS="${LDFLAGS} -L${SYSROOT}/usr/lib -L${ANDROID_PREFIX}/lib -L${EXTRA_LIBS}"


./configure --host=${CROSS_COMPILE} --with-sysroot=${SYSROOT} --prefix=${PREFIX} "$@" $CONFIGURATION_OPTIONS
make
make install





IMPORTANT:
If there are errors of undefined reference then check the config.log file whether the library file names and the library -l parameters use the same name. e.g. we have libpng.a but IM configure script is looking for libpng16.a via -lpng16. Rename the library or pass library as parameter from script.


After all is set well execute the script from inside IM directory. It will create and copy binary files in prefix directory. I could package the prebuilt prefix folder but its size for one type of cpu build is 99MB total without any dependencies files and ImageMagick source.  Whereas libMagickCore-6.Q16.a is 6.4MB and libMagickWand-6.Q16.a is 2.4MB. config.log itself is 1MB!. These size are still without some dependencies like FreeType, Tiff. I didn't fixed them yet.



Contents of prefix folder:

ls -RA
.:
bin  etc  include  lib  share

./bin:
animate    conjure  identify       MagickCore-config  montage
compare    convert  import         MagickWand-config  stream
composite  display  Magick-config  mogrify            Wand-config

./etc:
ImageMagick-6

./etc/ImageMagick-6:
coder.xml      magic.xml               thresholds.xml        type.xml
colors.xml     mime.xml                type-dejavu.xml
delegates.xml  policy.xml              type-ghostscript.xml
log.xml        quantization-table.xml  type-windows.xml

./include:
ImageMagick-6

./include/ImageMagick-6:
magick  wand

./include/ImageMagick-6/magick:
accelerate.h  distort.h            magick.h            resize.h
animate.h     distribute-cache.h   magick-type.h       resource_.h
annotate.h    draw.h               matrix.h            segment.h
api.h         effect.h             memory_.h           semaphore.h
artifact.h    enhance.h            method-attribute.h  shear.h
attribute.h   exception.h          methods.h           signature.h
blob.h        feature.h            mime.h              splay-tree.h
cache.h       fourier.h            module.h            statistic.h
cache-view.h  fx.h                 monitor.h           stream.h
channel.h     gem.h                montage.h           string_.h
cipher.h      geometry.h           morphology.h        studio.h
client.h      hashmap.h            opencl.h            threshold.h
coder.h       histogram.h          option.h            timer.h
color.h       identify.h           paint.h             token.h
colormap.h    image.h              pixel-accessor.h    transform.h
colorspace.h  ImageMagick.h        pixel.h             type.h
compare.h     image-view.h         policy.h            utility.h
composite.h   layer.h              prepress.h          version.h
compress.h    list.h               profile.h           vision.h
configure.h   locale_.h            property.h          widget.h
constitute.h  log.h                quantize.h          xml-tree.h
decorate.h    magic.h              quantum.h           xwindow.h
delegate.h    magick-baseconfig.h  random_.h
deprecate.h   magick-config.h      registry.h
display.h     MagickCore.h         resample.h

./include/ImageMagick-6/wand:
animate.h    deprecate.h     magick-image.h     method-attribute.h  stream.h
compare.h    display.h       magick-property.h  mogrify.h           wand-view.h
composite.h  drawing-wand.h  magick_wand.h      montage.h
conjure.h    identify.h      magick-wand.h      pixel-iterator.h
convert.h    import.h        MagickWand.h       pixel-wand.h

./lib:
ImageMagick-6.9.3      libMagickCore-6.Q16.la  libMagickWand-6.Q16.la
libMagickCore-6.Q16.a  libMagickWand-6.Q16.a   pkgconfig

./lib/ImageMagick-6.9.3:
config-Q16

./lib/ImageMagick-6.9.3/config-Q16:
configure.xml

./lib/pkgconfig:
ImageMagick-6.Q16.pc  MagickCore-6.Q16.pc  MagickWand-6.Q16.pc  Wand-6.Q16.pc
ImageMagick.pc        MagickCore.pc        MagickWand.pc        Wand.pc

./share:
ImageMagick-6

./share/ImageMagick-6:
english.xml  francais.xml  locale.xml








Contents of dependencies folder:


ls -RA
.:
include        libjasper.a  liblzma.a  libtiff.a
libfreetype.a  libjpeg.a    libpng.a   libwebp.a

./include:
jasper  jpeg  lzma  png  tiff  ttf  webp

./include/jasper:
jas_cm.h         jas_fix.h     jas_malloc.h  jas_string.h   Makefile
jas_config2.h    jas_getopt.h  jas_math.h    jas_tmr.h      Makefile.am
jas_config.h     jas_icc.h     jasper.h      jas_tvp.h      Makefile.in
jas_config.h.in  jas_image.h   jas_seq.h     jas_types.h    stamp-h1
jas_debug.h      jas_init.h    jas_stream.h  jas_version.h

./include/jpeg:
cderror.h  jconfig.h  jerror.h    jmemsys.h   jpegint.h  jversion.h
cdjpeg.h   jdct.h     jinclude.h  jmorecfg.h  jpeglib.h  transupp.h

./include/lzma:
lzma  lzma.h

./include/lzma/lzma:
base.h   check.h      filter.h    index_hash.h    version.h
bcj.h    container.h  hardware.h  lzma12.h        vli.h
block.h  delta.h      index.h     stream_flags.h

./include/png:
config.h   pngdebug.h  pnginfo.h     pngpriv.h
pngconf.h  png.h       pnglibconf.h  pngstruct.h

./include/tiff:
t4.h             tif_config.wince.h  tiffconf.h        tiff.h     tiffvers.h
tif_config.h     tif_dir.h           tiffconf.vc.h     tiffio.h   tif_predict.h
tif_config.vc.h  tif_fax3.h          tiffconf.wince.h  tiffiop.h  uvcode.h

./include/ttf:
freetype  ft2build.h

./include/ttf/freetype:
config        ftcid.h     ftincrem.h  ftotval.h   ftsystem.h  tttables.h
freetype.h    fterrdef.h  ftlcdfil.h  ftoutln.h   fttrigon.h  tttags.h
ftadvanc.h    fterrors.h  ftlist.h    ftpfr.h     fttypes.h   ttunpat.h
ftbbox.h      ftgasp.h    ftlzw.h     ftrender.h  ftwinfnt.h
ftbdf.h       ftglyph.h   ftmac.h     ftsizes.h   ftxf86.h
ftbitmap.h    ftgxval.h   ftmm.h      ftsnames.h  internal
ftcache.h     ftgzip.h    ftmodapi.h  ftstroke.h  t1tables.h
ftchapters.h  ftimage.h   ftmoderr.h  ftsynth.h   ttnameid.h

./include/ttf/freetype/config:
ftconfig.h  ftheader.h  ftmodule.h  ftoption.h  ftstdlib.h

./include/ttf/freetype/internal:
autohint.h  ftdriver.h  ftobjs.h   ftserv.h    ftvalid.h   psaux.h    sfnt.h
ftcalc.h    ftgloadr.h  ftpic.h    ftstream.h  internal.h  pshints.h  t1types.h
ftdebug.h   ftmemory.h  ftrfork.h  fttrace.h   pcftypes.h  services   tttypes.h

./include/ttf/freetype/internal/services:
svbdf.h     svgxval.h  svotval.h   svpscmap.h  svttcmap.h  svwinfnt.h
svcid.h     svkern.h   svpfr.h     svpsinfo.h  svtteng.h   svxf86nm.h
svgldict.h  svmm.h     svpostnm.h  svsfnt.h    svttglyf.h

./include/webp:
decode.h  demux.h  encode.h  format_constants.h  mux.h  mux_types.h  types.h 


No comments: