1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5FindImageMagick
6---------------
7
8Find ImageMagick binary suite.
9
10.. versionadded:: 3.9
11  Added support for ImageMagick 7.
12
13This module will search for a set of ImageMagick tools specified as
14components in the :command:`find_package` call.  Typical components include,
15but are not limited to (future versions of ImageMagick might have
16additional components not listed here):
17
18::
19
20  animate
21  compare
22  composite
23  conjure
24  convert
25  display
26  identify
27  import
28  mogrify
29  montage
30  stream
31
32
33
34If no component is specified in the :command:`find_package` call, then it only
35searches for the ImageMagick executable directory.  This code defines
36the following variables:
37
38::
39
40  ImageMagick_FOUND                  - TRUE if all components are found.
41  ImageMagick_EXECUTABLE_DIR         - Full path to executables directory.
42  ImageMagick_<component>_FOUND      - TRUE if <component> is found.
43  ImageMagick_<component>_EXECUTABLE - Full path to <component> executable.
44  ImageMagick_VERSION_STRING         - the version of ImageMagick found
45                                       (since CMake 2.8.8)
46
47
48
49``ImageMagick_VERSION_STRING`` will not work for old versions like 5.2.3.
50
51There are also components for the following ImageMagick APIs:
52
53::
54
55  Magick++
56  MagickWand
57  MagickCore
58
59
60
61For these components the following variables are set:
62
63::
64
65  ImageMagick_FOUND                    - TRUE if all components are found.
66  ImageMagick_INCLUDE_DIRS             - Full paths to all include dirs.
67  ImageMagick_LIBRARIES                - Full paths to all libraries.
68  ImageMagick_<component>_FOUND        - TRUE if <component> is found.
69  ImageMagick_<component>_INCLUDE_DIRS - Full path to <component> include dirs.
70  ImageMagick_<component>_LIBRARIES    - Full path to <component> libraries.
71
72
73
74Example Usages:
75
76::
77
78  find_package(ImageMagick)
79  find_package(ImageMagick COMPONENTS convert)
80  find_package(ImageMagick COMPONENTS convert mogrify display)
81  find_package(ImageMagick COMPONENTS Magick++)
82  find_package(ImageMagick COMPONENTS Magick++ convert)
83
84
85
86Note that the standard :command:`find_package` features are supported (i.e.,
87``QUIET``, ``REQUIRED``, etc.).
88#]=======================================================================]
89
90find_package(PkgConfig QUIET)
91
92#---------------------------------------------------------------------
93# Helper functions
94#---------------------------------------------------------------------
95function(FIND_IMAGEMAGICK_API component header)
96  set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
97
98  pkg_check_modules(PC_${component} QUIET ${component})
99
100  find_path(ImageMagick_${component}_INCLUDE_DIR
101    NAMES ${header}
102    HINTS
103      ${PC_${component}_INCLUDEDIR}
104      ${PC_${component}_INCLUDE_DIRS}
105    PATHS
106      ${ImageMagick_INCLUDE_DIRS}
107      "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
108    PATH_SUFFIXES
109      ImageMagick ImageMagick-6 ImageMagick-7
110    DOC "Path to the ImageMagick arch-independent include dir."
111    NO_DEFAULT_PATH
112    )
113  find_path(ImageMagick_${component}_ARCH_INCLUDE_DIR
114    NAMES magick/magick-baseconfig.h
115    HINTS
116      ${PC_${component}_INCLUDEDIR}
117      ${PC_${component}_INCLUDE_DIRS}
118    PATHS
119      ${ImageMagick_INCLUDE_DIRS}
120      "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
121    PATH_SUFFIXES
122      ImageMagick ImageMagick-6 ImageMagick-7
123    DOC "Path to the ImageMagick arch-specific include dir."
124    NO_DEFAULT_PATH
125    )
126  find_library(ImageMagick_${component}_LIBRARY
127    NAMES ${ARGN}
128    HINTS
129      ${PC_${component}_LIBDIR}
130      ${PC_${component}_LIB_DIRS}
131    PATHS
132      "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib"
133    DOC "Path to the ImageMagick Magick++ library."
134    NO_DEFAULT_PATH
135    )
136
137  # old version have only indep dir
138  if(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
139    set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
140
141    # Construct per-component include directories.
142    set(ImageMagick_${component}_INCLUDE_DIRS
143      ${ImageMagick_${component}_INCLUDE_DIR}
144      )
145    if(ImageMagick_${component}_ARCH_INCLUDE_DIR)
146      list(APPEND ImageMagick_${component}_INCLUDE_DIRS
147        ${ImageMagick_${component}_ARCH_INCLUDE_DIR})
148    endif()
149    list(REMOVE_DUPLICATES ImageMagick_${component}_INCLUDE_DIRS)
150    set(ImageMagick_${component}_INCLUDE_DIRS
151      ${ImageMagick_${component}_INCLUDE_DIRS} PARENT_SCOPE)
152
153    # Add the per-component include directories to the full include dirs.
154    list(APPEND ImageMagick_INCLUDE_DIRS ${ImageMagick_${component}_INCLUDE_DIRS})
155    list(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS)
156    set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE)
157
158    list(APPEND ImageMagick_LIBRARIES
159      ${ImageMagick_${component}_LIBRARY}
160      )
161    set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE)
162  endif()
163endfunction()
164
165function(FIND_IMAGEMAGICK_EXE component)
166  set(_IMAGEMAGICK_EXECUTABLE
167    ${ImageMagick_EXECUTABLE_DIR}/${component}${CMAKE_EXECUTABLE_SUFFIX})
168  if(EXISTS ${_IMAGEMAGICK_EXECUTABLE})
169    set(ImageMagick_${component}_EXECUTABLE
170      ${_IMAGEMAGICK_EXECUTABLE}
171       PARENT_SCOPE
172       )
173    set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
174  else()
175    set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
176  endif()
177endfunction()
178
179#---------------------------------------------------------------------
180# Start Actual Work
181#---------------------------------------------------------------------
182# Try to find a ImageMagick installation binary path.
183find_path(ImageMagick_EXECUTABLE_DIR
184  NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
185  PATHS
186    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]"
187  DOC "Path to the ImageMagick binary directory."
188  NO_DEFAULT_PATH
189  )
190find_path(ImageMagick_EXECUTABLE_DIR
191  NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
192  )
193
194# Find each component. Search for all tools in same dir
195# <ImageMagick_EXECUTABLE_DIR>; otherwise they should be found
196# independently and not in a cohesive module such as this one.
197unset(ImageMagick_REQUIRED_VARS)
198unset(ImageMagick_DEFAULT_EXECUTABLES)
199foreach(component ${ImageMagick_FIND_COMPONENTS}
200    # DEPRECATED: forced components for backward compatibility
201    convert mogrify import montage composite
202    )
203  if(component STREQUAL "Magick++")
204    FIND_IMAGEMAGICK_API(Magick++ Magick++.h
205      Magick++ CORE_RL_Magick++_
206      Magick++-6 Magick++-7
207      Magick++-Q8 Magick++-Q16 Magick++-Q16HDRI Magick++-Q8HDRI
208      Magick++-6.Q64 Magick++-6.Q32 Magick++-6.Q64HDRI Magick++-6.Q32HDRI
209      Magick++-6.Q16 Magick++-6.Q8 Magick++-6.Q16HDRI Magick++-6.Q8HDRI
210      Magick++-7.Q64 Magick++-7.Q32 Magick++-7.Q64HDRI Magick++-7.Q32HDRI
211      Magick++-7.Q16 Magick++-7.Q8 Magick++-7.Q16HDRI Magick++-7.Q8HDRI
212      )
213    list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_Magick++_LIBRARY)
214  elseif(component STREQUAL "MagickWand")
215    FIND_IMAGEMAGICK_API(MagickWand "wand/MagickWand.h;MagickWand/MagickWand.h"
216      Wand MagickWand CORE_RL_wand_ CORE_RL_MagickWand_
217      MagickWand-6 MagickWand-7
218      MagickWand-Q16 MagickWand-Q8 MagickWand-Q16HDRI MagickWand-Q8HDRI
219      MagickWand-6.Q64 MagickWand-6.Q32 MagickWand-6.Q64HDRI MagickWand-6.Q32HDRI
220      MagickWand-6.Q16 MagickWand-6.Q8 MagickWand-6.Q16HDRI MagickWand-6.Q8HDRI
221      MagickWand-7.Q64 MagickWand-7.Q32 MagickWand-7.Q64HDRI MagickWand-7.Q32HDRI
222      MagickWand-7.Q16 MagickWand-7.Q8 MagickWand-7.Q16HDRI MagickWand-7.Q8HDRI
223      )
224    list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickWand_LIBRARY)
225  elseif(component STREQUAL "MagickCore")
226    FIND_IMAGEMAGICK_API(MagickCore "magick/MagickCore.h;MagickCore/MagickCore.h"
227      Magick MagickCore CORE_RL_magick_ CORE_RL_MagickCore_
228      MagickCore-6 MagickCore-7
229      MagickCore-Q16 MagickCore-Q8 MagickCore-Q16HDRI MagickCore-Q8HDRI
230      MagickCore-6.Q64 MagickCore-6.Q32 MagickCore-6.Q64HDRI MagickCore-6.Q32HDRI
231      MagickCore-6.Q16 MagickCore-6.Q8 MagickCore-6.Q16HDRI MagickCore-6.Q8HDRI
232      MagickCore-7.Q64 MagickCore-7.Q32 MagickCore-7.Q64HDRI MagickCore-7.Q32HDRI
233      MagickCore-7.Q16 MagickCore-7.Q8 MagickCore-7.Q16HDRI MagickCore-7.Q8HDRI
234      )
235    list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickCore_LIBRARY)
236  else()
237    if(ImageMagick_EXECUTABLE_DIR)
238      FIND_IMAGEMAGICK_EXE(${component})
239    endif()
240
241    if(ImageMagick_FIND_COMPONENTS)
242      list(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested)
243      if(is_requested GREATER -1)
244        list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_${component}_EXECUTABLE)
245      endif()
246    elseif(ImageMagick_${component}_EXECUTABLE)
247      # if no components were requested explicitly put all (default) executables
248      # in the list
249      list(APPEND ImageMagick_DEFAULT_EXECUTABLES ImageMagick_${component}_EXECUTABLE)
250    endif()
251  endif()
252endforeach()
253
254if(NOT ImageMagick_FIND_COMPONENTS AND NOT ImageMagick_DEFAULT_EXECUTABLES)
255  # No components were requested, and none of the default components were
256  # found. Just insert mogrify into the list of the default components to
257  # find so FPHSA below has something to check
258  list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_mogrify_EXECUTABLE)
259elseif(ImageMagick_DEFAULT_EXECUTABLES)
260  list(APPEND ImageMagick_REQUIRED_VARS ${ImageMagick_DEFAULT_EXECUTABLES})
261endif()
262
263set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS})
264set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES})
265
266if(ImageMagick_mogrify_EXECUTABLE)
267  execute_process(COMMAND ${ImageMagick_mogrify_EXECUTABLE} -version
268                  OUTPUT_VARIABLE imagemagick_version
269                  ERROR_QUIET
270                  OUTPUT_STRIP_TRAILING_WHITESPACE)
271  if(imagemagick_version MATCHES "^Version: ImageMagick ([-0-9\\.]+)")
272    set(ImageMagick_VERSION_STRING "${CMAKE_MATCH_1}")
273  endif()
274  unset(imagemagick_version)
275endif()
276
277#---------------------------------------------------------------------
278# Standard Package Output
279#---------------------------------------------------------------------
280include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
281FIND_PACKAGE_HANDLE_STANDARD_ARGS(ImageMagick
282                                  REQUIRED_VARS ${ImageMagick_REQUIRED_VARS}
283                                  VERSION_VAR ImageMagick_VERSION_STRING
284  )
285# Maintain consistency with all other variables.
286set(ImageMagick_FOUND ${IMAGEMAGICK_FOUND})
287
288#---------------------------------------------------------------------
289# DEPRECATED: Setting variables for backward compatibility.
290#---------------------------------------------------------------------
291set(IMAGEMAGICK_BINARY_PATH          ${ImageMagick_EXECUTABLE_DIR}
292    CACHE PATH "Path to the ImageMagick binary directory.")
293set(IMAGEMAGICK_CONVERT_EXECUTABLE   ${ImageMagick_convert_EXECUTABLE}
294    CACHE FILEPATH "Path to ImageMagick's convert executable.")
295set(IMAGEMAGICK_MOGRIFY_EXECUTABLE   ${ImageMagick_mogrify_EXECUTABLE}
296    CACHE FILEPATH "Path to ImageMagick's mogrify executable.")
297set(IMAGEMAGICK_IMPORT_EXECUTABLE    ${ImageMagick_import_EXECUTABLE}
298    CACHE FILEPATH "Path to ImageMagick's import executable.")
299set(IMAGEMAGICK_MONTAGE_EXECUTABLE   ${ImageMagick_montage_EXECUTABLE}
300    CACHE FILEPATH "Path to ImageMagick's montage executable.")
301set(IMAGEMAGICK_COMPOSITE_EXECUTABLE ${ImageMagick_composite_EXECUTABLE}
302    CACHE FILEPATH "Path to ImageMagick's composite executable.")
303mark_as_advanced(
304  IMAGEMAGICK_BINARY_PATH
305  IMAGEMAGICK_CONVERT_EXECUTABLE
306  IMAGEMAGICK_MOGRIFY_EXECUTABLE
307  IMAGEMAGICK_IMPORT_EXECUTABLE
308  IMAGEMAGICK_MONTAGE_EXECUTABLE
309  IMAGEMAGICK_COMPOSITE_EXECUTABLE
310  )
311