Feb 08 2006
GDAL-based DEM utilities
A few months ago, I began looking for some efficient command-line tools to analyze and visualize DEMs. I typically use GRASS for such tasks but GRASS only works with it’s native raster format. Sure you can import/export to common formats but that’s not as efficient as a single command line tool that could work with the native DEM format, run on systems without GRASS installed and provide easy scriptablity.
Not having found anything that fit the bill, I decided to port some of the common GRASS DEM modules to C++ using the GDAL libraries. For someone with very little experience with C++, this was surprisingly not that difficult though I learned quite alot along the way. The result: 3 command line utilities to generate hillshades, slope and aspect maps and 1 excellent utility contributed by Paul Surgeon to apply color ramping to a DEM.
Installation
Requirements
I built these utilities on Ubuntu Linux. I admittedly have no idea how to compile them on Windows but some folks have confirmed that the hillshade code compiles under VC++. So to get these running under Linux (and presumably other *nixes), there are very minimal requirements:
- GDAL shared libraries
- GNU C++ Compiler
Download
Get the current source and unzip it. EDIT : This code is now avaible through my SVN repository : http://perrygeo.googlecode.com/svn/trunk/demtools/,
Compiling
Alas there is no makefile but installation should be fairly painless. To compile the source code under linux, the following commands should take care of it:
g++ hillshade.cpp -lgdal -o hillshade g++ color-relief.cxx -lgdal -o color-relief g++ aspect.cpp -lgdal -o aspect g++ slope.cpp -lgdal -o slope
The four binaries can then be placed wherever your local binaries reside (typically /usr/local/bin)
Examples
The original DEM
In this particular example the input DEM is a GeoTIFF but these utilities can use any GDAL-supported raster source.

Slope
This command will take a DEM raster and output a 32-bit GeoTiff with slope values. You have the option of specifying the type of slope value you want: degrees or percent slope. In cases where the horizontal units differ from the vertical units, you can also supply a scaling factor.
slope dem.tif slope.tif

Aspect
This command outputs a 32-bit GeoTiff with values between 0 and 360 representing the azimuth of the terrain.
aspect dem.tif aspect.tif

Hillshade
This command outputs an 8-bit GeoTiff with a nice shaded relief effect. It’s very useful for visualizing the terrain. You can optionally specify the azimuth and altitude of the light source, a vertical exaggeration factor and a scaling factor to account for differences between vertical and horizontal units.
hillshade dem.tif shade.tif

Color ramps
After I posted the hillshade utility to the gdal-dev mailing list, there was some discussion about creating color relief maps to supplement the hillshades. Paul Surgeon took up the challenge and created a gdal-based C++ utility to colorize DEMs (or any other single band raster data sources for that matter). The technique is simple and powerful; by using a text-based color configuration file, you can create any range of color ramps for your data.
color-relief dem.tif scale.txt colordem.tif
Where scale.txt is a text file containting 4 columns per line, the elevation value and the corresponding RGB values:
3500 255 255 255 2500 235 220 175 1500 190 185 135 700 240 250 150 0 50 180 50 -32768 200 230 255
The colors between the given elevation values are blended smoothly and the result is a nice colorized DEM:

Color Shaded Relief (blending hillshade and colorized DEM)
There are two ways I’ve come up with to blend the hillshade and the colorized DEM:
- Using GIMP or Photoshop, open both images, copy the shaded relief, paste on top of the color DEM and adjust the opacity in the layers dialog.
- If you’re publishing to the web with Mapserver, just stack the two images in your mapfile and set the TRANSPARENCY for the hillshade to a value between 30 and 70 depending on your preference
Though both methods work nicely, neither is really ideal since they don’t generate a georeferenced tiff. You can get around this in the GIMP method by creating a world file (.tfw) for the output tiff. It might be nice, in the future, to do this step programatically but for now…

Let me know if you’ve got any suggestions or comments. The technique for all of these utilities is a simple 3×3 moving window so this code might serve as a good template to develop other raster processing utilities… let me know what you come up with!
You can also combine the hillshade and color ramp images with ImageMagick, eg. by using “composite -compose multiply shade.tif ramp.tif output.tif”. However, the output image might need some value-wise scaling.
Have you taken a look at Microdem 8/9?
http://www.nadn.navy.mil/Users/oceano/pguth/website/microdem.htm
I think it will do much of what you want, and a lot more.
Leszek,
Thanks for the link to MicroDEM. Unfortunately it’s windows only (ouch), doesn’t handle some of the formats I work with and doesn’t have a command-line interface. It looks like a pretty powerful tool, though.. it’s got enough raster analysis tools to rival GRASS or SAGA GIS. I’ll definitely check it out.
1. MicroDEM will run in Ubuntu Breezy under Wine for the most part (OpenGL-based functions don’t work, sometimes function windows disappear behind the main window requiring you to resize the main window to find them, and other minor quirks pop up from time to time). I was unable to start it up from a shortcut/link, but it seems to run fine from the Winefile GUI.
2. In addition to the DEM formats supported by the File => Open DEM command, the Import function in the Data Manipulation window supports a few more DEM formats, some of which may be ones you need to have.
3. Nope, no command-file option. For this kind of work, though, I tend to have to fiddle around a lot with the parameters to optimize the look. For that, the instant visual feedback of a GUI-based program is far superior to a command-line approach. For scripts and batch processing, though, command-line is clearly superior.
Wish I had a copy of Visual C++ - I’d like to try these out on Windows. Guess I’ll have to break down and use them in Ubuntu instead.
Hi Matt,
I’m trying to compile these, and everything works except for the color-relief.cxx file. I get the following errors:
stringtok.h:10: error: ‘string’ has not been declared
stringtok.h: In function ‘void stringtok(Container&, const int&, const char*)’:
stringtok.h:13: error: ‘string’ has not been declared
stringtok.h:13: error: ‘size_type’ does not name a type
stringtok.h:14: error: ‘string’ has not been declared
stringtok.h:14: error: ‘size_type’ was not declared in this scope
stringtok.h:14: error: expected `;’ before ‘i’
stringtok.h:16: error: ‘i’ was not declared in this scope
stringtok.h:16: error: ‘len’ was not declared in this scope
stringtok.h:19: error: request for member ‘find_first_not_of’ in ‘in’, which is of non-class type ‘const int’
stringtok.h:20: error: ‘string’ has not been declared
stringtok.h:20: error: ‘npos’ was not declared in this scope
stringtok.h:24: error: ‘string’ has not been declared
stringtok.h:24: error: expected `;’ before ‘j’
stringtok.h:27: error: ‘j’ was not declared in this scope
stringtok.h:27: error: ‘string’ has not been declared
stringtok.h:27: error: ‘npos’ was not declared in this scope
stringtok.h:28: error: request for member ‘substr’ in ‘in’, which is of non-class type ‘const int’
stringtok.h:31: error: request for member ‘substr’ in ‘in’, which is of non-class type ‘const int’
stringtok.h:34: error: ‘j’ was not declared in this scope
color-relief.cxx: At global scope:
color-relief.cxx:35: error: expected constructor, destructor, or type conversion before ‘, std::allocator >, std::allocator, std::allocator > > >]’
color-relief.cxx:78: error: ‘ColorPointList’ was not declared in this scope
color-relief.cxx: In function ‘SColor GetColor(float)’:
color-relief.cxx:101: error: ‘ColorPointList’ was not declared in this scope
color-relief.cxx:112: error: ‘ColorPointList’ was not declared in this scope
I’m attempting to compile in Ubuntu 6.06, and I’m rather new to linux, so forgive my ignorance.
Any Ideas?
Thanks,
Rob
So here’s a Makefile for win32. Unzip the code in a directory on under the gdal source tree.
There are two changes needed for this build:
1) add “using namespace std;” to stringtok.h
2) aspect.cpp:165 should become:
if ((aspect 0))
Also I don’t think it will link in external libraries right now - depending on what you’re gdal is build with.
The makefile:
GDAL_ROOT = ..\
MORE_LIBS =
!INCLUDE $(GDAL_ROOT)\nmake.opt
default: hillshade.exe slope.exe aspect.exe color-relief.exe
hillshade.exe: hillshade.cpp
$(CC) $(CFLAGS) $(XTRAFLAGS) hillshade.cpp $(XTRAOBJ) $(EXTERNAL_LIBS) ..\gdal.lib /link $(LINKER_FLAGS)
slope.exe: slope.cpp
$(CC) $(CFLAGS) $(XTRAFLAGS) slope.cpp $(XTRAOBJ) $(EXTERNAL_LIBS) ..\gdal.lib /link $(LINKER_FLAGS)
aspect.exe: aspect.cpp
$(CC) $(CFLAGS) $(XTRAFLAGS) aspect.cpp $(XTRAOBJ) $(EXTERNAL_LIBS) ..\gdal.lib /link $(LINKER_FLAGS)
color-relief.exe: color-relief.cxx
$(CC) $(CFLAGS) $(XTRAFLAGS) /nodefaultlib:libc.lib color-relief.cxx $(MORE_LIBS) $(XTRAOBJ) $(EXTERNAL_LIBS) ..\gdal.lib /link $(LINKER_FLAGS)
I am having the same problem as Rob above. The include is not working when compiling color-relief. Any advice on what other libraries need to be loaded under Ubuntu 6.06? The other programs are working.
Thanks
Bob F
color-relief compiles with gcc 4.x (i.e. Ubuntu 6.06) if you add and move the namespace declaration around in color-relief.cpp, thusly:
#include
#include
#include “gdal_priv.h”
using namespace std;
#include “stringtok.h”
-jonathan
Sorry, the blog parser didn’t like the angled brackets, let’s try again
#include <list> // include systems “list” header file
#include <vector> // include systems “vector” header file
#include “gdal_priv.h”
using namespace std;
#include “stringtok.h”
This stuff is so cool, combined with the gdal/libgeotiff/image magick,
here’s a small script to convert a GDAL recognised contour file into a
GeoTIFF, blending the results of hillshade and color-relief
(sic) as a pretty geo-referenced image.
#!/bin/sh
INFILE=$1
OUTFILE=${2:-hillrelief.tif}
PID=$$
hillshade $INFILE .s_$PID.tif -s 370400 -z 20
color-relief $INFILE scale.txt .c_$PID.tif
listgeo .s_$PID.tif > .info_$PID.dat
# The ugly bit. Via a GIF to force 256 colours
# Otherwise QGIS looks very strange
composite -blend 50 .c_$PID.tif .s_$PID.tif .geo_$PID.gif
convert .geo_$PID.gif .geo_$PID.tif
geotifcp -g .info_$PID.dat .geo_$PID.tif $OUTFILE
rm -f .s_$PID.tif .c_$PID.tif .geo_$PID.gif .geo_$PID.tif .info_$PID.dat
Save as mkrelief.sh
$ mkrelief.sh INPUT output.tif
Using an SRTM file in ESRI binary grid format (IIRC).
$ mkrelief.sh w001001.adf iow.tif
The full (2.5MB) Geotiff may be found
here.
I am having trouble compiling… I am running Fedora Core 5 and have never compiled software so I am sure this is a “user error”
I get the following errors:
hillshade.cpp:10:23: error: gdal_priv.h: No such file or directory
hillshade.cpp: In function \u2018int main(int, char**)\u2019:
hillshade.cpp:14: error: \u2018GDALDataset\u2019 was not declared in this scope
hillshade.cpp:14: error: \u2018poDataset\u2019 was not declared in this scope
… there is more
I have confirmed that gdal_priv.h exists in /usr/include/gdal
Is there aproblem with a search path or environment variable that I should set???
Looking forward to using hillshade with these tools!
Regards
Hans
Hello,
I want to implement the hillshade code using Delphi but I cannot understand what the win (array) values stand for. Does this array hold the real elevation values?
Kindest regards
Johnnix,
The win array holds the 9 elevation values representing a 3×3 window used to calculate slope, aspect, etc.
thanks for your interest,
matt
Thank you Matt for the prompt reply. I guess now that the shadeBuf holds the new elevation data transformed to a gray scale color value.
Kindest regards
A couple of tips :
1.
I didn’t write any hillshade and colorized DEM merging functionality because one has far better control inside a graphics app like GIMP or Photoshop.
Here’s an example of the South Eastern Alps :
2.
I prefer to use listgeo and geotifcp for re-applying the projection meta data.
It tends to be less messy than dragging world files around the place.
Thanks to Perry for the fine examples he gave me to hack.
Hmmm … HTML markup didn’t work - here’s the URL : http://img379.imageshack.us/img379/6114/cr1yb2.png
Oh and I meant South Western Alps. :-$
This is an excellent set of utilities.
On Mac OS X, this will build and work fine if you install gdal from source. It will fail using the gdal framework from kyngchaos.com, probably because the libraries are dynamic rather than static.
I am executing now using the scale.txt colors. Does anyone know of a resource for other color maps that can be used to produce color dems? TIA
I made my own color map using some satellite images to create a fairly (overly?) complex set of rules. These are designed specifically for Nevada, USA, but might work well in other areas also. Here is the ruleset based on the GRASS r.colors implementation:
0% white
3% white
7% 253 251 203
20% 185 167 127
33% 164 140 98
50% 103 101 50
60% 54 62 13
93% 255 255 255
100% 255 255 255
To build on OSX using gdal frameworks from KyngChaos.com you need to specify the location of the library and header files, eg:
g++ hillshade.cpp -I /Library/Frameworks/GDAL.framework/unix/include/ -L/Library/Frameworks/GDAL.framework/unix/lib/ -lgdal -o hillshade
g++ color-relief.cxx -I /Library/Frameworks/GDAL.framework/unix/include/ -L/Library/Frameworks/GDAL.framework/unix/lib/ -lgdal -o color-relief
g++ aspect.cpp -I /Library/Frameworks/GDAL.framework/unix/include/ -L/Library/Frameworks/GDAL.framework/unix/lib/ -lgdal -o aspect
g++ slope.cpp -I /Library/Frameworks/GDAL.framework/unix/include/ -L/Library/Frameworks/GDAL.framework/unix/lib/ -lgdal -o slope
Cheers, Dave
Thanks for making these tools available. They are much easier to work with than grass. Now, can anyone tell me how to convert a shapefile containing contour line vectors into a dem? The shapefile is large (500Mb) and grass seems to run out of memory even on a machine with 2Gb RAM, so does anyone know of a memory-efficient tool or algorithm to do the job?
Cheers, Dave.
Great utility Matt (and contributors). I compiled the 4 utilities on win32 and will include them in the next MS4W release for all to use.
thanks!
–
jeff
I am new to doing any building of gdal libraries. I am working on a Windows system and would like to write some c++ image processing functions using gdal. I am confused about what I need to download, build, install to actually use the gdal header files, etc in my c++ code. Can you or anyone else out there provide me some clear instructions on what steps I need to take?
Thank you in advance.
Nate
By the way, these DEM utilities are now available for windows users as part of MS4W base installer: http://www.maptools.org/ms4w/index.phtml?page=downloads.html
-jeff
You already provide everything you need to blend the colorized DEM with the hillshade. Simply intergerize your cang variable in the hillshade code and subtract that from 255 (since white = 255 and black = 0). This gives you an integer “darkening” variable. It might look something like this…
int darkening;
darkening = 255 - (int)(hillshade.value);
Then for your final color at a given pixel…
Color.Red = Color.Red - darkening;
if( Color.Red < 0 )
Color.Red = 0;
… and the same for green and blue.
If the image is darker than you like, you can either make a brighter color scale by increasing each rgb value or adjust the darkening value by some percentage.
Hi,
I need to display DTED level0 map in my application,
can you suggest how to redirect the output to a monitor(preferably to a QWidget) instead of putting it into a file.
–Giri
Very useful tools! You should talk to the GDAL author about getting them included in the official source tree.
It’s been a log time since I have looked at all of this. I managed to get everything running well on OS X (thanks Dave). I spent some time tweaking the script provided by J Hudson above and came up with on that does a few things. First, a little error checking and a usage example if you do not provide the correct inputs. Second, a check to see if you have a scale.txt file and an example if you do not prior to wasting cpu cycles. And third, the option to save your hillshade separate of the color shaded relief map. I like having these for overlays when making field maps.
I hope others find this useful. By all means, provide improvements as I am not a scripting pro by any stretch.
#!/bin/sh
#****************************************************#
# makerelief.sh #
# modified from J Hudson #
# by John C. Tull #
# 09/11/2008 #
# Build shaded relief map #
# using Matthew Perry’s demtools from: #
# http://perrygeo.googlecode.com/svn/trunk/demtools/ #
#****************************************************#
INFILE=$1
OUTFILE=$2
PID=$$
SCALE=”scale.txt”
EXPECTED_ARGS=2
if [ ! -f “$INFILE” -o $# -ne $EXPECTED_ARGS ]; then
echo “makerelief.sh infile outfile”
echo “Author: J Hudson Sept. 9, 2006; modified by John C. Tull Sept. 11 2008″
exit $?
fi
if [[ -r $SCALE ]]; then
echo hillshade $INFILE .s_$PID.tif -s 370400 -z 20
hillshade $INFILE .s_$PID.tif -s 370400 -z 20
echo color-relief $INFILE scale.txt .c_$PID.tif
color-relief $INFILE scale.txt .c_$PID.tif
echo listgeo .s_$PID.tif > .info_$PID.dat
listgeo .s_$PID.tif > .info_$PID.dat
# The ugly bit. Via a GIF to force 256 colours
# Otherwise QGIS looks very strange
echo composite -blend 50 .c_$PID.tif .s_$PID.tif .geo_$PID.tif
composite -blend 50 .c_$PID.tif .s_$PID.tif .geo_$PID.tif
# echo convert .geo_$PID.gif .geo_$PID.tif
# convert .geo_$PID.gif .geo_$PID.tif
echo geotifcp -g .info_$PID.dat .geo_$PID.tif $OUTFILE
geotifcp -g .info_$PID.dat .geo_$PID.tif $OUTFILE
echo “Do you want to keep your hillshade? (y/n) ”
read -n 1 -s answer1
if [ “$answer1″ == “n” -o “$answer1″ == “N” ]; then
rm -f .s_$PID.tif .c_$PID.tif .geo_$PID.tif .info_$PID.dat
exit $?
else
echo “What do you want to name your hillshade file? (e.g., hillshade.tif) ”
read answer2
mv .s_$PID.tif $answer2
rm -f .s_$PID.tif .c_$PID.tif .geo_$PID.tif .info_$PID.dat
exit $?
fi
else
echo “You do not have a scale.txt file!”
echo “Try:”
echo ” 3500 255 255 255″
echo ” 2500 235 220 175″
echo ” 1500 190 185 135″
echo ” 700 240 250 150″
echo ” 0 50 180 50″
echo ” -32768 200 230 255″
fi
I’m a little late here, but wanted to thank you for this very easy (easy w/ Dave Robertson’s OSX tip) suite of tools. Very useful, and great to be able to do this with a swift trip to the command line.
I finally managed to get these compiled on Debian. It was necessary to change the compile flags in the makefile to this, in case it’s helpful to anyone:
GDAL_LIB=-I /usr/include/gdal/ -L/usr/lib/ -lgdal1.5.0
[…] was created in a primarily two-step process. The hillshade was created using Matt Perry’s GDAL DEM tools. This command line addition to the GDAL suite of tools negated having to import the DEM into a new […]
Just leaving this here as reminder to myself, other may benefit too.
1 - svn checkout http://perrygeo.googlecode.com/svn/trunk/demtools/
2- vi color-relief.cpp
#include // include systems “list” header file
#include // include systems “vector” header file
#include “gdal_priv.h”
using namespace std;
#include “stringtok.h”
3- g++ color-relief.cpp -L/opt/local/lib -lgdal -I/opt/local/include -o color-relief
These tools will be incorporated in GDAL 1.7+ as the “gdaldem” utility. Thanks for the great work Matt!
[…] the recent addition of gdaldem (previously available as DEMtools) to the set of GDAL utility programs, there are now several GDAL programs available for working […]
Hi Matt,
I try to use your tools to obtain a hillshading + colorrelief map.
I have some dted file (dt1).
Using hillshade the resulting tiff seams good but when I apply color-relief with the default scale.txt file I obtain an all green image.
What is wrong ?
my steps are:
>hillshade filename.dt1 filenameT.tiff
>color-relief filenameT.tiff scale.txt filenameC.tiff
Thanks
Lux7, make sure scale.txt contains appropriate values for the range of elevation values in your DEM.
hi, Thanks.
Once I have the hillshade+color-relief tile (combined) and open it in a gis tool (i.e Qgis),
how can I get the elevation values from the tile ?
thanks in advance
Lux7,
You can inspect the *original* DEM using a tool like gdalinfo or QGIS to get the min/max values of that raster.
In qgis, go to raster properties > symbology > load min max values.
Using gdalinfo: gdalinfo -mm filename.gt1
Hi Matt,
I am not interested to get the min/max but for example the elevation values of the entire raster to compute some Line of Sight or something like that. The issue is to get a matrix containing the elevation values of a specified region.
Suggestions ?
Thanks
Lux7,
The DEM raster, by definition, is a matrix of elevation values.
Yes Ok,
but I have a picture, so in some way I have to transofrm an RGB value in an elevation value.
Am I wrong ?
Lux7,
Once you’ve created a shaded relief or hillshade or most any other derivative product from a DEM, there is not way to reverse engineer it to get the elevation values. The RGB colors on the shaded relief image are simply R, G and B - it no longer holds ANY information about the original elevation value. Thats what the original source DEM is for.
oh,
so how can I get an elevation matrix from a lot of dted/dem if for example the region that I want is shared between 2 or more dted/dem files ?
Is not clear for me.
Does exists some tool ?
Lux
Lux7,
If I understand correctly, you’re looking to merge or mosaic the rasters into a single file? Try gdal_merge (http://www.gdal.org/gdal_merge.html) or a VRT. Most any image software or GIS software will have capability to merge rasters.
Hi,
I try to explain me as better as possible.
I have 2 problems:
1)Create a color-relief + hillshade map from a lot of dted1 files and open it in qgis.
To solve this problem I think to use your utility to create the color-relief+hillshade tiles (one for each dted file) and use gdalbuildvrt + gdaladdo to create a virtual raster layer with pyramids. This layer will be loaded in qgis.
2) Selecting a region of this virtual raster layer (i.e giving the two corner of a box in lat/lon and the number of point in height and width of the box) I want to develop a Qgis plugin that:
2a)get the elevation values of the region specified by the box and the correct number of point (interpolating if necessary).
2b)Using the resulting matrix(or buffer) of elevation values make some specific computation like LOS etc.
any suggetsions to solve it ?
thanks again for you patience
[…] Using the same LiDAR DEM from which we generated the contours, we can create hillshade tifs using http://www.perrygeo.net/wordpress/?p=7. It compiles easily on a mac, probably even easier on a Linux machine following his directions. […]
hi,
Why I see the sea green ?
I have added the line
0.1 50 180 50
0 0 0 255
in the scale.txt
Thanks
Hi!
I’m using GDALDEM utilities from FWTools shell and I want to make a DSM color relief based on a color text file.
But I’m having problems in aplying the color blue only to “NoData” pixels.
This is the color table that I’m using:
nv 148 184 235
0 137 90 68
5 76 115 0
10 38 115 0
20 76 92 0
50 17 69 17
What can I do to solve this problem?
Should I classify the noDATA pixels to a specific number like “99″…
Thanks
Cecília
@Cecilia
Just simply add to the end of color text file this line:
nv 0 0 0
Ops, for blue color:
nv 0 0 255
right?
Hi,
using : nv 0 0 0 I dont’ see blue sea yet. It is still green
Further suggestions ?
Do you know the free software SpacEyes3D Viewer / DEM tool box, it’s a graphic interface based on gdaldem that allows to easy handle all gdaldem tools with a friendly QT interface, including a realtime preview (windows only).
http://technology.slashgeo.org/technology/09/10/29/1632224.shtml
To compile on ubuntu 9.10 I did:
g++ `gdal-config –cflags` hillshade.cpp -o hillshade `gdal-config –libs`
etc.
Dear Matthew
Please, could you tell me what kind of color ramp and shadow relief image combination algorithm are you using in your color-relief program?
The problem is common GIS programs usually use a difference or addition algorithm and resulting images look dull but I ‘ve seen an image example at http://wiki.openstreetmap.org/wiki/HikingBikingMaps produced by your program and it looks with nice colors and balanced shadows. It is seems your program conserve color tones and shadows.
Thanks in advance for your help
Gabriel,
The color-relief program does not actually do any shaded relief/shadowing at all. It just assigns colors based on the raster value. You can generate a hillshade map separately and combine them using some of the options discussed in this comment thread (I’m sure there are other ways as well).
This little and powerful toolset saved my day!
FWTools do not have gdaltodem , and they are not updated either.
Compiling Gdal on my system is not possible: process is failing after some time.
I was looking for a linux batch mode for creating a raster image of a dem file, and here I found the solution.
THANKS!
I suggest TIFF Tools for linux, and ImageMagick, plus the pnm tools for conversions.
slope src.tif dst.tif
tifftopnm dst.tif >dst.pnm
pnmtojpeg dst.pnm >dst.jpg
as a workaround to convert into jpeg, because the “convert” tool for TIFF complains.
Overall, when someone wants to deal with rastering a dem and creating an image of it from linux he has to know that this process is not straightforward nor this simple, because tools involved are complicated , require compiling etc.
*except THESE tools*