Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add advanced usage options/functionality #9

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 113 additions & 44 deletions cmd/cogger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,132 @@ package main

import (
"context"
"flag"
"fmt"
"io"
"os"
"path/filepath"
"os/signal"
"strconv"
"strings"
"syscall"

"github.com/airbusgeo/cogger"
"github.com/spf13/cobra"

"github.com/google/tiff"
_ "github.com/google/tiff/bigtiff"
)

func main() {
ctx := context.Background()
err := run(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
ctx, cncl := signal.NotifyContext(context.Background(),
syscall.SIGINT, syscall.SIGTERM)
defer cncl()
exitCode := 0
if err := newRootCommand().ExecuteContext(ctx); err != nil {
exitCode = 1
}
os.Exit(exitCode)
}

func run(ctx context.Context) error {
outfile := flag.String("output", "out.tif", "destination file")
flag.Parse()

args := flag.Args()
if len(args) < 1 {
fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] file.tif [overview.tif...]\nOptions:\n", filepath.Base(os.Args[0]))
flag.PrintDefaults()
return fmt.Errorf("")
func newRootCommand() *cobra.Command {
outfile := "out.tif"
skipGhostAreas := false
keepBigtiff := false
forceBigtiff := false
keptOverviewsS := ""
keptMasksS := ""
var keptMasks []int = nil
var keptOverviews []int = nil
cmd := &cobra.Command{
Use: "cogger [main.tif] [overview.tif]...",
Short: "cogger is a tool for creating Cloud Optimized GeoTIFFs",
Args: cobra.MinimumNArgs(1),
PreRunE: func(cmd *cobra.Command, _ []string) error {
flags := cmd.Flags()
if flags.Changed("keep-masks") {
if keptMasksS == "" {
keptMasks = []int{}
} else {
ks := strings.Split(keptMasksS, ",")
keptMasks = make([]int, len(ks))
for k := range ks {
kv, err := strconv.Atoi(ks[k])
if err != nil {
return fmt.Errorf("invalid mask index %s: %w", ks[k], err)
}
keptMasks[k] = kv
}
}
}
if flags.Changed("keep-overviews") {
if keptOverviewsS == "" {
keptOverviews = []int{}
} else {
ks := strings.Split(keptOverviewsS, ",")
keptOverviews = make([]int, len(ks))
for k := range ks {
kv, err := strconv.Atoi(ks[k])
if err != nil {
return fmt.Errorf("invalid overview index %s: %w", ks[k], err)
}
keptOverviews[k] = kv
}
}
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
readers := make([]tiff.ReadAtReadSeeker, len(args))
for i, input := range args {
topFile, err := os.Open(input)
if err != nil {
return fmt.Errorf("open %s: %w", args[0], err)
}
defer topFile.Close()
readers[i] = topFile
}
out, err := os.Create(outfile)
if err != nil {
return fmt.Errorf("create %s: %w", outfile, err)
}
cfg := cogger.DefaultConfig()
if keepBigtiff {
tif0, err := tiff.Parse(readers[0], nil, nil)
if err != nil {
return fmt.Errorf("parse %s: %w", args[0], err)
}
if tif0.Version() == 0x2B {
cfg.BigTIFF = true
}
readers[0].Seek(0, io.SeekStart)
}
if forceBigtiff {
cfg.BigTIFF = true
}
if skipGhostAreas {
cfg.WithGDALGhostArea = false
}
cfg.KeptMasks = keptMasks
cfg.KeptOverviews = keptOverviews
err = cfg.Rewrite(out, readers...)
if err != nil {
return fmt.Errorf("cogger.rewrite: %w", err)
}
err = out.Close()
if err != nil {
return fmt.Errorf("close %s: %w", outfile, err)
}
return nil
},
}
flags := cmd.Flags()
flags.StringVar(&outfile, "output", outfile, "destination file")
flags.BoolVar(&skipGhostAreas, "skip-gdal-ghost-areas", skipGhostAreas, "omit writing gdal ghost areas")
flags.BoolVar(&keepBigtiff, "keep-bigtiff", keepBigtiff, "produce a bigtiff file if the input is bigtiff")
flags.BoolVar(&forceBigtiff, "force-bigtiff", forceBigtiff, "produce a bigtiff output even if the size is less than 4Gb")
flags.StringVar(&keptOverviewsS, "keep-overviews", "", "comma separated list of overview levels to keep")
flags.StringVar(&keptMasksS, "keep-masks", "", "comma separated list of mask levels to keep")
cmd.MarkFlagsMutuallyExclusive("keep-bigtiff", "force-bigtiff")
flags.SortFlags = false

totalSize := int64(0)
readers := make([]tiff.ReadAtReadSeeker, len(args))
for i, input := range args {
topFile, err := os.Open(input)
if err != nil {
return fmt.Errorf("open %s: %w", args[0], err)
}
defer topFile.Close()
st, err := topFile.Stat()
if err != nil {
return fmt.Errorf("stat %s: %w", args[0], err)
}
totalSize += st.Size()
readers[i] = topFile
}
out, err := os.Create(*outfile)
if err != nil {
return fmt.Errorf("create %s: %w", *outfile, err)
}
err = cogger.Rewrite(out, readers...)
if err != nil {
return fmt.Errorf("mucog write: %w", err)
}
err = out.Close()
if err != nil {
return fmt.Errorf("close %s: %w", *outfile, err)
}
return nil
return cmd
}
94 changes: 94 additions & 0 deletions cmd/tiler/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
FROM golang:bullseye AS builder
ARG COGGER_IMAGE

RUN apt update && apt -y install \
build-essential \
cmake \
curl \
libbrotli-dev \
libgflags-dev \
libjpeg-dev \
libopenjp2-7-dev \
libpng-dev \
libsqlite3-dev \
libwebp-dev \
libzstd-dev \
libproj-dev \
pkgconf \
sqlite3 \
unzip

WORKDIR /build/jxl
#main from 10/05/2022
ARG JXLVERSION=ff65c387ac98c7f597ed7e954c28fb32065bf553
RUN curl -sL https://github.com/libjxl/libjxl/archive/$JXLVERSION.tar.gz -o jxl.tgz &&\
tar xzf jxl.tgz &&\
cd libjxl-$JXLVERSION &&\
./deps.sh &&\
mkdir build && cd build &&\
cmake .. -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release &&\
make -j8 &&\
make install &&\
cd /build && rm -rf jxl


WORKDIR /build/gdal
ARG GDALVERSION=release/3.5
RUN curl -sL https://github.com/OSGeo/gdal/archive/$GDALVERSION.tar.gz -o gdal.tar.gz &&\
tar xzf gdal.tar.gz --strip-components 1 &&\
mkdir build && cd build &&\
cmake .. \
-DOGR_BUILD_OPTIONAL_DRIVERS=OFF \
-DGDAL_ENABLE_DRIVER_DIMAP=ON \
-DGDAL_ENABLE_DRIVER_JP2OPENJPEG=ON \
-DGDAL_ENABLE_DRIVER_WEBP=ON \
-DGDAL_ENABLE_DRIVER_JPEG=ON \
-DGDAL_ENABLE_DRIVER_PNG=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTING=OFF \
-DGDAL_USE_CURL=OFF \
-DGDAL_USE_SQLITE3=OFF \
-DGDAL_ENABLE_DRIVER_ISO8211=OFF \
-DGDAL_BUILD_OPTIONAL_DRIVERS=OFF \
-DGDAL_USE_JXL=ON \
-DGDAL_USE_KDU=OFF \
-DGDAL_USE_TIFF_INTERNAL=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_PYTHON_BINDINGS=OFF \
-DENABLE_GNM=OFF\
-DGDAL_USE_XERCESC=OFF &&\
make -j8 && \
make install &&\
ldconfig /usr/local/lib &&\
cd /build && rm -rf gdal

WORKDIR /cogger
COPY go.* /cogger/
COPY vendor.docker vendor
COPY go.* /cogger/
RUN cd vendor && go build ./... && cd ..
COPY *.go /cogger/
COPY cmd/tiler/*.go /cogger/cmd/tiler/
WORKDIR /cogger/cmd/tiler
RUN go build -ldflags "-X main.defaultImage=$COGGER_IMAGE" -o tiler .

FROM debian:bullseye
RUN apt update && apt install -y \
libbrotli1 \
libjpeg62-turbo \
libopenjp2-7 \
libpng16-16 \
libproj19 \
libsqlite3-0 \
libwebp6 \
libzstd1 &&\
apt clean &&\
rm -rf /var/lib/apt/lists/*


COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/local/lib/*.so /usr/local/lib/
COPY --from=builder /usr/local/share/* /usr/local/share/
RUN ldconfig
COPY --from=builder /cogger/cmd/tiler/tiler /usr/local/bin/tiler

12 changes: 12 additions & 0 deletions cmd/tiler/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
IMAGE:=eu.gcr.io/d-dzm-deepzoom/cogger/cogger:20220817

build:
@go mod vendor && mv ../../vendor ../../vendor.docker
-docker build -t $(IMAGE) --build-arg COGGER_IMAGE=$(IMAGE) -f Dockerfile ../..
@rm -rf ../../vendor.docker

push:
docker push $(IMAGE)

build-local:
go build -ldflags "-X main.defaultImage=$(IMAGE)" .
Loading