# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Do not use the targets in this file unless you need a certain libjpeg
# implementation. Use the meta target //third_party:jpeg instead.

import("//build/config/features.gni")
import("//build/config/sanitizers/sanitizers.gni")
if (current_cpu == "arm" || current_cpu == "arm64") {
  import("//build/config/arm.gni")
}

assert(
    use_blink,
    "This is not used if blink is not enabled, don't drag it in unintentionally")

source_set("libjpeg_headers") {
  sources = [
    "jconfig.h",
    "jdct.h",
    "jinclude.h",
    "jmorecfg.h",
    "jpeglib.h",
    "jpeglibmangler.h",
  ]
}

if (current_cpu == "x86" || current_cpu == "x64") {
  import("//third_party/nasm/nasm_assemble.gni")

  nasm_assemble("simd_asm") {
    defines = []
    include_dirs = [ "simd/nasm/" ]

    inputs = [
      "simd/nasm/jdct.inc",
      "simd/nasm/jsimdcfg.inc",
      "simd/nasm/jsimdext.inc",
      "simd/nasm/jcolsamp.inc",
    ]

    if (current_cpu == "x86") {
      include_dirs += [ "simd/i386/" ]
      inputs += [
        "simd/i386/jccolext-avx2.asm",
        "simd/i386/jccolext-mmx.asm",
        "simd/i386/jccolext-sse2.asm",
        "simd/i386/jcgryext-avx2.asm",
        "simd/i386/jcgryext-mmx.asm",
        "simd/i386/jcgryext-sse2.asm",
        "simd/i386/jdcolext-avx2.asm",
        "simd/i386/jdcolext-mmx.asm",
        "simd/i386/jdcolext-sse2.asm",
        "simd/i386/jdmrgext-avx2.asm",
        "simd/i386/jdmrgext-mmx.asm",
        "simd/i386/jdmrgext-sse2.asm",
      ]
      sources = [
        "simd/i386/jccolor-avx2.asm",
        "simd/i386/jccolor-mmx.asm",
        "simd/i386/jccolor-sse2.asm",
        "simd/i386/jcgray-avx2.asm",
        "simd/i386/jcgray-mmx.asm",
        "simd/i386/jcgray-sse2.asm",
        "simd/i386/jchuff-sse2.asm",
        "simd/i386/jcphuff-sse2.asm",
        "simd/i386/jcsample-avx2.asm",
        "simd/i386/jcsample-mmx.asm",
        "simd/i386/jcsample-sse2.asm",
        "simd/i386/jdcolor-avx2.asm",
        "simd/i386/jdcolor-mmx.asm",
        "simd/i386/jdcolor-sse2.asm",
        "simd/i386/jdmerge-avx2.asm",
        "simd/i386/jdmerge-mmx.asm",
        "simd/i386/jdmerge-sse2.asm",
        "simd/i386/jdsample-avx2.asm",
        "simd/i386/jdsample-mmx.asm",
        "simd/i386/jdsample-sse2.asm",
        "simd/i386/jfdctflt-3dn.asm",
        "simd/i386/jfdctflt-sse.asm",
        "simd/i386/jfdctfst-mmx.asm",
        "simd/i386/jfdctfst-sse2.asm",
        "simd/i386/jfdctint-avx2.asm",
        "simd/i386/jfdctint-mmx.asm",
        "simd/i386/jfdctint-sse2.asm",
        "simd/i386/jidctflt-3dn.asm",
        "simd/i386/jidctflt-sse.asm",
        "simd/i386/jidctflt-sse2.asm",
        "simd/i386/jidctfst-mmx.asm",
        "simd/i386/jidctfst-sse2.asm",
        "simd/i386/jidctint-avx2.asm",
        "simd/i386/jidctint-mmx.asm",
        "simd/i386/jidctint-sse2.asm",
        "simd/i386/jidctred-mmx.asm",
        "simd/i386/jidctred-sse2.asm",
        "simd/i386/jquant-3dn.asm",
        "simd/i386/jquant-mmx.asm",
        "simd/i386/jquant-sse.asm",
        "simd/i386/jquantf-sse2.asm",
        "simd/i386/jquanti-avx2.asm",
        "simd/i386/jquanti-sse2.asm",
        "simd/i386/jsimdcpu.asm",
      ]
      defines += [
        "__x86__",
        "PIC",
      ]
    } else if (current_cpu == "x64") {
      include_dirs += [ "simd/x86_64/" ]
      inputs += [
        "simd/x86_64/jccolext-avx2.asm",
        "simd/x86_64/jccolext-sse2.asm",
        "simd/x86_64/jcgryext-avx2.asm",
        "simd/x86_64/jcgryext-sse2.asm",
        "simd/x86_64/jdcolext-avx2.asm",
        "simd/x86_64/jdcolext-sse2.asm",
        "simd/x86_64/jdmrgext-avx2.asm",
        "simd/x86_64/jdmrgext-sse2.asm",
      ]
      sources = [
        "simd/x86_64/jccolor-avx2.asm",
        "simd/x86_64/jccolor-sse2.asm",
        "simd/x86_64/jcgray-avx2.asm",
        "simd/x86_64/jcgray-sse2.asm",
        "simd/x86_64/jchuff-sse2.asm",
        "simd/x86_64/jcphuff-sse2.asm",
        "simd/x86_64/jcsample-avx2.asm",
        "simd/x86_64/jcsample-sse2.asm",
        "simd/x86_64/jdcolor-avx2.asm",
        "simd/x86_64/jdcolor-sse2.asm",
        "simd/x86_64/jdmerge-avx2.asm",
        "simd/x86_64/jdmerge-sse2.asm",
        "simd/x86_64/jdsample-avx2.asm",
        "simd/x86_64/jdsample-sse2.asm",
        "simd/x86_64/jfdctflt-sse.asm",
        "simd/x86_64/jfdctfst-sse2.asm",
        "simd/x86_64/jfdctint-avx2.asm",
        "simd/x86_64/jfdctint-sse2.asm",
        "simd/x86_64/jidctflt-sse2.asm",
        "simd/x86_64/jidctfst-sse2.asm",
        "simd/x86_64/jidctint-avx2.asm",
        "simd/x86_64/jidctint-sse2.asm",
        "simd/x86_64/jidctred-sse2.asm",
        "simd/x86_64/jquantf-sse2.asm",
        "simd/x86_64/jquanti-avx2.asm",
        "simd/x86_64/jquanti-sse2.asm",
        "simd/x86_64/jsimdcpu.asm",
      ]
      defines += [
        "__x86_64__",
        "PIC",
      ]
    }

    if (is_win) {
      defines += [ "MSVC" ]
      if (current_cpu == "x86") {
        defines += [ "WIN32" ]
      } else {
        defines += [ "WIN64" ]
      }
    } else if (is_mac || is_ios) {
      defines += [ "MACHO" ]
    } else if (is_linux || is_android || is_fuchsia || is_chromeos) {
      defines += [ "ELF" ]
    }
  }
}

static_library("simd") {
  include_dirs = [ "." ]
  deps = [ ":libjpeg_headers" ]
  defines = [ "MANGLE_JPEG_NAMES" ]

  if (current_cpu == "x86") {
    deps += [ ":simd_asm" ]
    sources = [ "simd/i386/jsimd.c" ]
  } else if (current_cpu == "x64") {
    deps += [ ":simd_asm" ]
    sources = [ "simd/x86_64/jsimd.c" ]
  } else if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon) {
    include_dirs += [ "simd/arm/" ]

    sources = [
      "simd/arm/jccolor-neon.c",
      "simd/arm/jcgray-neon.c",
      "simd/arm/jcphuff-neon.c",
      "simd/arm/jcsample-neon.c",
      "simd/arm/jdcolor-neon.c",
      "simd/arm/jdmerge-neon.c",
      "simd/arm/jdsample-neon.c",
      "simd/arm/jfdctfst-neon.c",
      "simd/arm/jfdctint-neon.c",
      "simd/arm/jidctfst-neon.c",
      "simd/arm/jidctint-neon.c",
      "simd/arm/jidctred-neon.c",
      "simd/arm/jquanti-neon.c",
    ]
    if (current_cpu == "arm") {
      sources += [
        "simd/arm/aarch32/jchuff-neon.c",
        "simd/arm/aarch32/jsimd.c",
      ]
    } else if (current_cpu == "arm64") {
      sources += [
        "simd/arm/aarch64/jchuff-neon.c",
        "simd/arm/aarch64/jsimd.c",
      ]
    }

    defines += [ "NEON_INTRINSICS" ]

    configs -= [ "//build/config/compiler:default_optimization" ]
    configs += [ "//build/config/compiler:optimize_speed" ]
  } else {
    sources = [ "jsimd_none.c" ]
  }

  if (is_win) {
    cflags = [ "/wd4245" ]
  }
}

config("libjpeg_config") {
  include_dirs = [ "." ]
  defines = [ "MANGLE_JPEG_NAMES" ]
}

static_library("libjpeg") {
  sources = [
    "jcapimin.c",
    "jcapistd.c",
    "jccoefct.c",
    "jccolor.c",
    "jcdctmgr.c",
    "jchuff.c",
    "jcicc.c",
    "jcinit.c",
    "jcmainct.c",
    "jcmarker.c",
    "jcmaster.c",
    "jcomapi.c",
    "jcparam.c",
    "jcphuff.c",
    "jcprepct.c",
    "jcsample.c",
    "jctrans.c",
    "jdapimin.c",
    "jdapistd.c",
    "jdatadst.c",
    "jdatasrc.c",
    "jdcoefct.c",
    "jdcolor.c",
    "jddctmgr.c",
    "jdhuff.c",
    "jdicc.c",
    "jdinput.c",
    "jdmainct.c",
    "jdmarker.c",
    "jdmaster.c",
    "jdmerge.c",
    "jdphuff.c",
    "jdpostct.c",
    "jdsample.c",
    "jdtrans.c",
    "jerror.c",
    "jfdctflt.c",
    "jfdctfst.c",
    "jfdctint.c",
    "jidctflt.c",
    "jidctfst.c",
    "jidctint.c",
    "jidctred.c",
    "jmemmgr.c",
    "jmemnobs.c",
    "jpeg_nbits_table.c",
    "jquant1.c",
    "jquant2.c",
    "jutils.c",
  ]

  defines = [
    "WITH_SIMD",
    "NO_GETENV",
    "NO_PUTENV",
  ]

  configs += [ ":libjpeg_config" ]

  public_configs = [ ":libjpeg_config" ]
  public_deps = [ ":libjpeg_headers" ]

  # MemorySanitizer doesn't support assembly code, so keep it disabled in x86
  # and x64 MSan builds for now.
  if (is_msan && (current_cpu == "x86" || current_cpu == "x64")) {
    sources += [ "jsimd_none.c" ]
  } else {
    public_deps += [ ":simd" ]

    if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon) {
      defines += [ "NEON_INTRINSICS" ]
    }
  }
}

static_library("turbojpeg") {
  sources = [
    "jdatadst-tj.c",
    "jdatasrc-tj.c",
    "rdbmp.c",
    "rdppm.c",
    "transupp.c",
    "turbojpeg.c",
    "wrbmp.c",
    "wrppm.c",
  ]

  defines = [
    "WITH_SIMD",
    "BMP_SUPPORTED",
    "PPM_SUPPORTED",
  ]

  configs += [ ":libjpeg_config" ]

  public_configs = [ ":libjpeg_config" ]
  public_deps = [ ":libjpeg" ]
}

if (build_with_chromium) {
  import("//testing/test.gni")

  test("libjpeg_turbo_unittests") {
    testonly = true

    sources = [
      "cdjpeg.c",
      "cjpeg.c",
      "djpeg.c",
      "gtest/cjpeg-gtest-wrapper.cpp",
      "gtest/djpeg-gtest-wrapper.cpp",
      "gtest/gtest-utils.cpp",
      "gtest/jpegtran-gtest-wrapper.cpp",
      "gtest/tjbench-gtest-wrapper.cpp",
      "gtest/tjunittest-gtest-wrapper.cpp",
      "jpegtran.c",
      "md5/md5.c",
      "md5/md5hl.c",
      "rdcolmap.c",
      "rdgif.c",
      "rdswitch.c",
      "tjbench.c",
      "tjunittest.c",
      "tjutil.c",
    ]

    deps = [
      ":turbojpeg",
      "//base",
      "//testing/gtest",
      "//testing/gtest:gtest_main",
    ]

    data = [ "testimages/" ]

    defines = [
      "GTEST",
      "WITH_SIMD",
      "BMP_SUPPORTED",
      "PPM_SUPPORTED",
    ]

    include_dirs = [
      "//third_party/googletest/src/googletest/include/gtest",
      ".",
    ]

    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [ "//build/config/compiler:no_chromium_code" ]

    if (is_win) {
      cflags = [ "-U_CRT_SECURE_NO_DEPRECATE" ]
    }
  }
}
