cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
file(READ VERSION bpg_version)
string(REPLACE "\n" "" bpg_version "${bpg_version}")
project(bpg VERSION ${bpg_version} LANGUAGES C)

option(BPG_USE_EMCC "Enable compilation of Javascript decoder with Emscripten" OFF)
option(BPG_USE_X265 "Enable x265 for the encoder" ON)
option(BPG_USE_JCTVC "Enable the JCTVC code (best quality but slow) for the encoder" OFF)
option(BPG_USE_BPGVIEW "Compile bpgview (SDL and SDL_image libraries needed)" ON)
option(BPG_USE_JCTVC_HIGH_BIT_DEPTH "Enable it to use bit depths > 12 (need more tests to validate encoder)" OFF)

find_package(PNG REQUIRED)
find_package(JPEG REQUIRED)
if (BPG_USE_BPGVIEW)
	find_package(SDL REQUIRED)
	find_package(SDL_image REQUIRED)
endif()

set(EMCC emcc)
set(common_gcc_flags "-Wall -MMD -fno-asynchronous-unwind-tables -fdata-sections -ffunction-sections -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -fomit-frame-pointer")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os ${common_gcc_flags}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os ${common_gcc_flags}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${common_gcc_flags}")

# Emscriptem config
set(EMLDFLAGS "-s \"EXPORTED_FUNCTIONS=['_bpg_decoder_open','_bpg_decoder_decode','_bpg_decoder_get_info','_bpg_decoder_start','_bpg_decoder_get_frame_duration','_bpg_decoder_get_line','_bpg_decoder_close','_malloc','_free']\"")
set(EMLDFLAGS "${EMLDFLAGS} -s NO_FILESYSTEM=1 -s NO_BROWSER=1")
set(EMLDFLAGS "${EMLDFLAGS} -O3 --memory-init-file 0 --closure 0 --pre-js pre.js --post-js post.js")

#EMCFLAGS:=$(CFLAGS)

add_library(${PROJECT_NAME}
	libavcodec/hevc_cabac.c
	libavcodec/hevc_filter.c
	libavcodec/hevc.c
	libavcodec/hevcpred.c
	libavcodec/hevc_refs.c
	libavcodec/hevcdsp.c
	libavcodec/hevc_mvs.c
	libavcodec/hevc_ps.c
	libavcodec/hevc_sei.c
	libavcodec/utils.c
	libavcodec/cabac.c
	libavcodec/golomb.c
	libavcodec/videodsp.c

	libavutil/mem.c
	libavutil/buffer.c
	libavutil/log2_tab.c
	libavutil/frame.c
	libavutil/pixdesc.c
	libavutil/md5.c

	libbpg.c
)

add_definitions(
	-D_FILE_OFFSET_BITS=64
	-D_LARGEFILE_SOURCE
	-D_REENTRANT
	-DCONFIG_BPG_VERSION=\"${bpg_version}\"
)

if (BPG_USE_JCTVC_HIGH_BIT_DEPTH)
	add_definitions(-DRExt__HIGH_BIT_DEPTH_SUPPORT)
endif()

add_executable(bpgdec
	bpgdec.c
)
target_link_libraries(bpgdec
	${PROJECT_NAME}
	${PNG_LIBRARIES}
)
target_include_directories(bpgdec SYSTEM
	PRIVATE ${PNG_INCLUDE_DIRS}
)

set(bpgenc_sources bpgenc.c)
if (BPG_USE_X265)
	list(APPEND bpgenc_sources x265_glue.c)
endif()
add_executable(bpgenc ${bpgenc_sources})
target_link_libraries(bpgenc
	PRIVATE ${PROJECT_NAME}
	PRIVATE ${PNG_LIBRARIES}
	PRIVATE ${JPEG_LIBRARIES}
)
target_include_directories(bpgenc SYSTEM
	PRIVATE ${PNG_INCLUDE_DIRS}
	PRIVATE ${JPEG_INCLUDE_DIR}
)
if (BPG_USE_X265)
	add_subdirectory(x265/source)
	target_link_libraries(bpgenc PRIVATE x265-static)
	target_compile_definitions(bpgenc PRIVATE USE_X265)
endif()

if (BPG_USE_BPGVIEW)
	add_executable(bpgview
		bpgview.c
	)
	target_link_libraries(bpgview
		PRIVATE ${PROJECT_NAME}
		PRIVATE ${SDL_LIBRARY}
		PRIVATE ${SDL_IMAGE_LIBRARIES}
	)
	target_include_directories(bpgview SYSTEM
		PRIVATE ${SDL_INCLUDE_DIR}
		PRIVATE ${SDL_IMAGE_INCLUDE_DIRS}
	)
endif()
if (BPG_USE_EMCC)
	#PROGS+=bpgdec.js bpgdec8.js bpgdec8a.js
endif()

target_compile_definitions(${PROJECT_NAME}
	PRIVATE _ISOC99_SOURCE
	PRIVATE _POSIX_C_SOURCE=200112
	PRIVATE _XOPEN_SOURCE=600
	PRIVATE HAVE_AV_CONFIG_H
	PRIVATE _GNU_SOURCE=1
	PRIVATE USE_VAR_BIT_DEPTH
	PRIVATE USE_PRED
)
target_include_directories(${PROJECT_NAME}
	PUBLIC .
)

#LIBBPG_JS_OBJS:=$(patsubst %.o, %.js.o, $(LIBBPG_OBJS)) tmalloc.js.o
#
#LIBBPG_JS8_OBJS:=$(patsubst %.o, %.js8.o, $(LIBBPG_OBJS)) tmalloc.js8.o
#
#LIBBPG_JS8A_OBJS:=$(patsubst %.o, %.js8a.o, $(LIBBPG_OBJS)) tmalloc.js8a.o
#
#$(LIBBPG_JS_OBJS): EMCFLAGS+=-D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DHAVE_AV_CONFIG_H -std=c99 -D_GNU_SOURCE=1 -DUSE_VAR_BIT_DEPTH
#
#$(LIBBPG_JS8_OBJS): EMCFLAGS+=-D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DHAVE_AV_CONFIG_H -std=c99 -D_GNU_SOURCE=1
#
#$(LIBBPG_JS8A_OBJS): EMCFLAGS+=-D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DHAVE_AV_CONFIG_H -std=c99 -D_GNU_SOURCE=1 -DUSE_PRED

#ifdef USE_JCTVC
#JCTVC_OBJS=$(addprefix jctvc/TLibEncoder/, SyntaxElementWriter.o TEncSbac.o \
#TEncBinCoderCABACCounter.o TEncGOP.o\
#TEncSampleAdaptiveOffset.o TEncBinCoderCABAC.o TEncAnalyze.o\
#TEncEntropy.o TEncTop.o SEIwrite.o TEncPic.o TEncRateCtrl.o\
#WeightPredAnalysis.o TEncSlice.o TEncCu.o NALwrite.o TEncCavlc.o\
#TEncSearch.o TEncPreanalyzer.o)
#JCTVC_OBJS+=jctvc/TLibVideoIO/TVideoIOYuv.o
#JCTVC_OBJS+=$(addprefix jctvc/TLibCommon/, TComWeightPrediction.o TComLoopFilter.o\
#TComBitStream.o TComMotionInfo.o TComSlice.o ContextModel3DBuffer.o\
#TComPic.o TComRdCostWeightPrediction.o TComTU.o TComPicSym.o\
#TComPicYuv.o TComYuv.o TComTrQuant.o TComInterpolationFilter.o\
#ContextModel.o TComSampleAdaptiveOffset.o SEI.o TComPrediction.o\
#TComDataCU.o TComChromaFormat.o Debug.o TComRom.o\
#TComPicYuvMD5.o TComRdCost.o TComPattern.o TComCABACTables.o)
#JCTVC_OBJS+=jctvc/libmd5/libmd5.o
#JCTVC_OBJS+=jctvc/TAppEncCfg.o jctvc/TAppEncTop.o jctvc/program_options_lite.o 
#
#$(JCTVC_OBJS) jctvc_glue.o: CFLAGS+=-I$(PWD)/jctvc -Wno-sign-compare
#
#jctvc/libjctvc.a: $(JCTVC_OBJS)
#	$(AR) rcs $@ $^
#
#BPGENC_OBJS+=jctvc_glue.o jctvc/libjctvc.a
#
#bpgenc.o: CFLAGS+=-DUSE_JCTVC
#endif # USE_JCTVC
#
#
#ifdef CONFIG_WIN32
#
#BPGDEC_LIBS:=-lpng -lz
#BPGENC_LIBS+=-lpng -ljpeg -lz
#BPGVIEW_LIBS:=-lmingw32 -lSDLmain -lSDL_image -lSDL -mwindows
#
#else
#
#ifdef CONFIG_APPLE
#LIBS:=
#else
#LIBS:=-lrt
#endif # !CONFIG_APPLE 
#LIBS+=-lm -lpthread
#
#BPGDEC_LIBS:=-lpng $(LIBS)
#BPGENC_LIBS+=-lpng -ljpeg $(LIBS)
#BPGVIEW_LIBS:=-lSDL_image -lSDL $(LIBS)
#
#endif #!CONFIG_WIN32
#
#bpgenc.o: CFLAGS+=-Wno-unused-but-set-variable
#
#libbpg.a: $(LIBBPG_OBJS) 
#	$(AR) rcs $@ $^
#
#bpgdec$(EXE): bpgdec.o libbpg.a
#	$(CC) $(LDFLAGS) -o $@ $^ $(BPGDEC_LIBS)
#
#bpgenc$(EXE): $(BPGENC_OBJS)
#	$(CXX) $(LDFLAGS) -o $@ $^ $(BPGENC_LIBS)
#
#bpgview$(EXE): bpgview.o libbpg.a
#	$(CC) $(LDFLAGS) -o $@ $^ $(BPGVIEW_LIBS)
#
#bpgdec.js: $(LIBBPG_JS_OBJS) post.js
#	$(EMCC) $(EMLDFLAGS) -s TOTAL_MEMORY=33554432 -o $@ $(LIBBPG_JS_OBJS)
#
#bpgdec8.js: $(LIBBPG_JS8_OBJS) post.js
#	$(EMCC) $(EMLDFLAGS) -s TOTAL_MEMORY=33554432 -o $@ $(LIBBPG_JS8_OBJS)
#
#bpgdec8a.js: $(LIBBPG_JS8A_OBJS) post.js
#	$(EMCC) $(EMLDFLAGS) -s TOTAL_MEMORY=33554432 -o $@ $(LIBBPG_JS8A_OBJS)
#
#size:
#	strip bpgdec
#	size bpgdec libbpg.o libavcodec/*.o libavutil/*.o | sort -n
#	gzip < bpgdec | wc
#
#install: bpgenc bpgdec
#	install -s -m 755 $^ $(prefix)/bin
#
#CLEAN_DIRS=doc html libavcodec libavutil \
#     jctvc jctvc/TLibEncoder jctvc/TLibVideoIO jctvc/TLibCommon jctvc/libmd5
#
#clean: x265_clean
#	rm -f $(PROGS) *.o *.a *.d *~ $(addsuffix /*.o, $(CLEAN_DIRS)) \
#          $(addsuffix /*.d, $(CLEAN_DIRS)) $(addsuffix /*~, $(CLEAN_DIRS)) \
#          $(addsuffix /*.a, $(CLEAN_DIRS))
#
#%.o: %.c
#	$(CC) $(CFLAGS) -c -o $@ $<
#
#%.o: %.cpp
#	$(CXX) $(CXXFLAGS) -c -o $@ $<
#
#%.js.o: %.c
#	$(EMCC) $(EMCFLAGS) -c -o $@ $<
#
#%.js8.o: %.c
#	$(EMCC) $(EMCFLAGS) -c -o $@ $<
#
#%.js8a.o: %.c
#	$(EMCC) $(EMCFLAGS) -c -o $@ $<
#
#-include $(wildcard *.d)
#-include $(wildcard libavcodec/*.d)
#-include $(wildcard libavutil/*.d)
#-include $(wildcard jctvc/*.d)
#-include $(wildcard jctvc/TLibEncoder/*.d)
#-include $(wildcard jctvc/TLibVideoIO/*.d)
#-include $(wildcard jctvc/TLibCommon/*.d)
#-include $(wildcard jctvc/libmd5/*.d)
