# This makefile is a simpler alternative to the CMake build system, for simple
# local building of the libraries and tools.
# It will not install the libraries system-wide, but just create the 'sjpeg',
# and 'vjpeg' tools in the examples/ directory, along with the static
# library 'src/libsjpeg.a'.
#
# To build the library and examples, use 'make' from this top directory.

#### Customizable part ####

# Taken from SJPEG_VERSION (0xMMmmpp) in src/sjpeg.h.
VERSION=$(shell sed -n 's/^\#define SJPEG_VERSION 0x\(..\)\(..\)\(..\).*/0x\1 0x\2 0x\3/p' \
                 src/sjpeg.h | xargs printf '%d.%d.%d')
ARCHIVE_FILE=sjpeg-$(VERSION).tar.gz

# Set to 0 to build without progressive JPEG encoding support.
SJPEG_HAVE_PROGRESSIVE ?= 1
# Set to 0 to build without multi-threaded encoding support.
SJPEG_HAVE_MULTITHREADING ?= 1
# Trimming: set any of these to 0 to strip the feature out (see README.md).
SJPEG_HAVE_RISKINESS ?= 1
SJPEG_HAVE_SHARP_YUV ?= 1
SJPEG_HAVE_SEARCH ?= 1
SJPEG_HAVE_ADAPTIVE_QUANT ?= 1
SJPEG_HAVE_METADATA ?= 1
SJPEG_HAVE_C_FALLBACK ?= 1

EXTRA_FLAGS= -DSJPEG_HAVE_PNG -DSJPEG_HAVE_JPEG
ifeq ($(SJPEG_HAVE_PROGRESSIVE), 0)
  EXTRA_FLAGS += -DSJPEG_NO_PROGRESSIVE
endif
ifeq ($(SJPEG_HAVE_MULTITHREADING), 0)
  EXTRA_FLAGS += -DSJPEG_NO_MULTITHREADING
else
  EXTRA_FLAGS += -pthread
endif
$(foreach f,RISKINESS SHARP_YUV SEARCH ADAPTIVE_QUANT METADATA C_FALLBACK,\
  $(if $(filter 0,$(SJPEG_HAVE_$(f))),$(eval EXTRA_FLAGS += -DSJPEG_NO_$(f))))
UTILS_LIBS= -lpng -ljpeg

# we use C++-11
EXTRA_FLAGS += -std=c++11

# OpenGL and GLUT
ifeq ($(strip $(shell uname)), Darwin)
  # Homebrew and MacPorts use different prefixes for libpng / libjpeg.
  LOCAL_PREFIX = $(firstword $(wildcard /opt/homebrew /opt/local) /usr/local)
  EXTRA_FLAGS += -I$(LOCAL_PREFIX)/include
  EXTRA_FLAGS += -Wno-deprecated-declarations
  EXTRA_LIBS  += -L$(LOCAL_PREFIX)/lib
  GL_LIBS = -framework GLUT -framework OpenGL
  EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H
else
  EXTRA_FLAGS += -I/usr/local/include
  EXTRA_LIBS  += -L/usr/local/lib
  GL_LIBS = -lglut -lGL
  EXTRA_FLAGS += -DHAVE_GL_GLUT_H
endif

# Uncomment for build for 32bit platform
# Alternatively, you can just use the command
# 'make EXTRA_FLAGS=-m32' to that effect.
# EXTRA_FLAGS += -m32

# Extra strictness flags
EXTRA_FLAGS += -Wextra
EXTRA_FLAGS += -Wunused
EXTRA_FLAGS += -Wshadow
EXTRA_FLAGS += -Wformat-security -Wformat-nonliteral

# EXTRA_FLAGS += -Wvla

# NEON-specific flags:
# EXTRA_FLAGS += -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8
# -> seems to make the overall lib slower: -fno-split-wide-types

# AVX2 support: opt-in, off by default. When on, the AVX2-specific files
# (src/*_avx2.cc) are built with -mavx2 while the rest of the library stays
# at its normal baseline -- AVX2 support is picked at runtime (SupportsAVX2()
# in enc.cc), so the resulting binary still runs on non-AVX2 CPUs.
# 'make HAVE_AVX2=1' to enable.
HAVE_AVX2 ?= 0
ifeq ($(HAVE_AVX2), 1)
EXTRA_FLAGS += -DSJPEG_HAVE_AVX2
src/%_avx2.o: EXTRA_FLAGS += -mavx2
endif

#### Nothing should normally be changed below this line ####

AR = ar
ARFLAGS = r
ifeq ($(origin CXX), default)
CXX = g++
endif
CXXFLAGS = -Isrc/ -Wall $(EXTRA_FLAGS)
ifeq ($(DEBUG), 1)
  CXXFLAGS += -g
else
  CXXFLAGS += -O3 -DNDEBUG
endif
INSTALL = install
GROFF = /usr/bin/groff
COL = /usr/bin/col
LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm

SJPEG_OBJS = \
    src/api.o \
    src/bit_writer.o \
    src/colors_rgb.o \
    src/dichotomy.o \
    src/enc.o \
    src/enc_parallel.o \
    src/encoders.o \
    src/entropy.o \
    src/fdct.o \
    src/headers.o \
    src/histogram.o \
    src/jpeg_tools.o \
    src/quantize.o \
    src/score_175.o  \
    src/yuv_convert.o \

ifeq ($(SJPEG_HAVE_PROGRESSIVE), 1)
  SJPEG_OBJS += src/prog.o
endif


ifeq ($(HAVE_AVX2), 1)
SJPEG_OBJS += src/colors_rgb_avx2.o
SJPEG_OBJS += src/fdct_avx2.o
SJPEG_OBJS += src/histogram_avx2.o
SJPEG_OBJS += src/quantize_avx2.o
SJPEG_OBJS += src/riskiness_avx2.o
SJPEG_OBJS += src/yuv_convert_avx2.o
endif

UTILS_OBJS = \
    examples/utils.o \

HDRS_INSTALLED = \
    src/sjpeg.h \

HDRS = \
    examples/utils.h \
    src/simd.h \
    src/sjpegi.h \
    src/bit_writer.h \
    src/blocks.h \
    src/common.h \
    src/entropy.h \
    src/headers.h \
    src/dsp.h \
    src/slices.h \
    $(HDRS_INSTALLED) \

OUT_LIBS = src/libsjpeg.a examples/libutils.a
OUT_EXAMPLES =  examples/sjpeg
OUT_EXAMPLES += examples/vjpeg
OUT_TESTS = tests/unit_test

OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES) $(OUT_TESTS)

# Without this, the built-in '%: %.o' rule takes over 'unit_test' and links it
# with $(CC) instead of running it.
.PHONY: all clean dist ex pak test test_cmd test_png_jpg unit_test

ex: $(OUT_EXAMPLES)
all: ex

%.o: %.cc $(HDRS)
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@

examples/libutils.a: $(UTILS_OBJS)
src/libsjpeg.a: $(SJPEG_OBJS)

%.a:
	$(AR) $(ARFLAGS) $@ $^

examples/sjpeg: examples/sjpeg.o
examples/sjpeg: examples/libutils.a
examples/sjpeg: src/libsjpeg.a
examples/sjpeg: EXTRA_LIBS += $(UTILS_LIBS)

examples/vjpeg: examples/vjpeg.o
examples/vjpeg: examples/libutils.a
examples/vjpeg: src/libsjpeg.a
examples/vjpeg: EXTRA_LIBS += $(UTILS_LIBS)
# warning! -lpthread must be declared first, before GL_LIBS:
examples/vjpeg: EXTRA_LIBS += -lpthread $(GL_LIBS)
examples/vjpeg: EXTRA_FLAGS += -DSJPEG_HAVE_OPENGL

$(OUT_EXAMPLES):
	$(CXX) -o $@ $^ $(LDFLAGS)

tests/unit_test: tests/unit_test.o
tests/unit_test: src/libsjpeg.a
# the tests encode from several threads at once
tests/unit_test: EXTRA_LIBS += -lpthread

$(OUT_TESTS):
	$(CXX) -o $@ $^ $(LDFLAGS)

test: unit_test test_cmd test_png_jpg

unit_test: $(OUT_TESTS)
	./tests/unit_test

test_cmd: $(OUT_EXAMPLES)
	cd tests && ./test_cmd.sh

test_png_jpg: $(OUT_EXAMPLES)
	cd tests && ./test_png_jpg.sh

dist: DESTDIR := dist
dist: all
	$(INSTALL) -m755 -d $(DESTDIR)/include/ \
	           $(DESTDIR)/bin $(DESTDIR)/doc $(DESTDIR)/lib
	$(INSTALL) -m755 -s $(OUT_EXAMPLES) $(DESTDIR)/bin
	$(INSTALL) -m644 $(HDRS_INSTALLED) $(DESTDIR)/include
	$(INSTALL) -m644 src/libsjpeg.a $(DESTDIR)/lib
	umask 022; \
	for m in man/sjpeg.1 man/vjpeg.1; do \
	  basenam=$$(basename $$m .1); \
	  $(GROFF) -t -e -man -T utf8 $$m \
	    | $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
	  $(GROFF) -t -e -man -T html $$m \
	    | $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
	done

clean:
	$(RM) $(OUTPUT) *~ \
              examples/*.o examples/*~ man/*~ src/*.o src/*~ \
              tests/*.o tests/*~ \
              examples/*.lo src/*.lo

DIST_FILES= \
         Application.mk  \
         Android.mk  \
         AUTHORS  \
         ChangeLog  \
         COPYING  \
         INSTALL  \
         Makefile \
         NEWS  \
         README.md  \
         CMakeLists.txt \
         cmake/android.cmake \
         cmake/cpu.cmake \
         cmake/sjpegConfig.cmake.in \
         cmake/sjpeg.pc.in \
         appveyor.yml \
         src/api.cc  \
         src/bit_writer.cc  \
         src/bit_writer.h  \
         src/colors_rgb.cc  \
         src/colors_rgb_avx2.cc  \
         src/dichotomy.cc  \
         src/enc.cc  \
         src/enc_parallel.cc  \
         src/encoders.cc  \
         src/entropy.cc  \
         src/entropy.h  \
         src/fdct.cc  \
         src/fdct_avx2.cc  \
         src/headers.cc \
         src/headers.h \
         src/dsp.h \
         src/blocks.h \
         src/common.h \
         src/slices.h \
         src/histogram.cc  \
         src/histogram_avx2.cc  \
         src/jpeg_tools.cc  \
         src/prog.cc  \
         src/quantize.cc  \
         src/quantize_avx2.cc  \
         src/riskiness_avx2.cc  \
         src/md5sum.h \
         src/score_175.cc  \
         src/simd.h  \
         src/sjpeg.h  \
         src/sjpegi.h  \
         src/yuv_convert.cc \
         src/yuv_convert_avx2.cc \
         man/sjpeg.1  \
         man/vjpeg.1  \
         examples/Android.mk  \
         examples/sjpeg.cc  \
         examples/vjpeg.cc  \
         examples/utils.h  \
         examples/utils.cc  \
         tests/test_cmd.sh  \
         tests/test_png_jpg.sh  \
         tests/unit_test.cc  \
         tests/testdata/source1.png \
         tests/testdata/source1.itl.png \
         tests/testdata/source2.jpg \
         tests/testdata/source3.jpg \
         tests/testdata/source4.ppm \
         tests/testdata/test_exif_xmp.png \
         tests/testdata/test_icc.jpg \
         examples/vjpeg_sample.jpg \

pak: clean
ifeq ($(strip $(shell uname)), Darwin)
	COPYFILE_DISABLE=1 tar -s ,.*,sjpeg-$(VERSION)\/~,p -czf $(ARCHIVE_FILE) $(DIST_FILES)
else
	tar --transform="s#^#sjpeg-$(VERSION)/#" -czf $(ARCHIVE_FILE) $(DIST_FILES)
endif
	@echo "GENERATED ARCHIVE: $(ARCHIVE_FILE)"

.SUFFIXES:
