Documentation
¶
Index ¶
- func Rewrite(out io.Writer, readers ...tiff.ReadAtReadSeeker) error
- type Config
- func (cfg Config) Rewrite(out io.Writer, readers ...tiff.ReadAtReadSeeker) error
- func (cfg Config) RewriteIFDHeader(ifd *IFD, out io.Writer) error
- func (cfg Config) RewriteIFDTree(ifd *IFD, out io.Writer) error
- func (cfg Config) RewriteIFDTreeSplitted(ifd *IFD, headerOut, tileDataOut io.Writer) error
- func (cfg Config) RewriteSplitted(headerOut, dataOut io.Writer, readers ...tiff.ReadAtReadSeeker) error
- type Dag
- type ErrInvalidOption
- type IFD
- func (ifd *IFD) AddMask(msk *IFD) error
- func (ifd *IFD) AddOverview(ovr *IFD) error
- func (ifd *IFD) NPlanes() int
- func (ifd *IFD) NTilesX() int
- func (ifd *IFD) NTilesY() int
- func (ifd *IFD) SetPlanarInterleaving(pi PlanarInterleaving) error
- func (ifd *IFD) TileFromIdx(idx int) (x, y, plane int)
- func (ifd *IFD) TileIdx(x, y, plane int) int
- type Image
- type Node
- type PlanarInterleaving
- type Pyramid
- type Strip
- type Stripper
- func (t Stripper) AssembleStrips(srcStrips [][]tiff.ReadAtReadSeeker) (*IFD, error)
- func (s Stripper) FullresStripHeightMultiple() int
- func (s Stripper) InternalTileSize() (int, int)
- func (s Stripper) MinOverviewSize() int
- func (s Stripper) OverviewCount() int
- func (t Stripper) Pyramid() Pyramid
- func (s Stripper) Size() (int, int)
- func (s Stripper) TargetPixelCount() int
- type StripperOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Config ¶ added in v0.1.0
type Config struct {
//Encoding selects big or little endian tiff encoding. Default: little
Encoding binary.ByteOrder
//BigTIFF forces bigtiff creation. Default: false, i.e. only if needed
BigTIFF bool
// PlanarInterleaving for separate-plane files.
// Default: nil resulting in {{0,1,...n}} i.e. interleaved planes
PlanarInterleaving PlanarInterleaving
//WithGDALGhostArea inserts gdal specific read optimizations
WithGDALGhostArea bool
}
func DefaultConfig ¶ added in v0.1.0
func DefaultConfig() Config
func (Config) RewriteIFDHeader ¶ added in v0.1.0
func (Config) RewriteIFDTree ¶ added in v0.1.0
func (Config) RewriteIFDTreeSplitted ¶ added in v0.1.0
func (Config) RewriteSplitted ¶ added in v0.1.0
type Dag ¶ added in v0.1.0
type Dag [][]Node
A DAG can be used further optimize parrallel strip computing, by explicitely referencing which parent strips are needed to be used to downsample the given strip of an overview. For advanced usage; it is simpler to process all images of a pyramid level in parallel before moving down to the next level
type ErrInvalidOption ¶ added in v0.1.0
type ErrInvalidOption struct {
// contains filtered or unexported fields
}
func (ErrInvalidOption) Error ¶ added in v0.1.0
func (err ErrInvalidOption) Error() string
type IFD ¶
type IFD struct {
//Any field added here should also be accounted for in computeStructure and writeIFD
SubfileType uint32 `tiff:"field,tag=254"`
ImageWidth uint64 `tiff:"field,tag=256"`
ImageHeight uint64 `tiff:"field,tag=257"`
BitsPerSample []uint16 `tiff:"field,tag=258"`
Compression uint16 `tiff:"field,tag=259"`
PhotometricInterpretation uint16 `tiff:"field,tag=262"`
DocumentName string `tiff:"field,tag=269"`
SamplesPerPixel uint16 `tiff:"field,tag=277"`
PlanarConfiguration uint16 `tiff:"field,tag=284"`
Software string `tiff:"field,tag=305"`
DateTime string `tiff:"field,tag=306"`
Predictor uint16 `tiff:"field,tag=317"`
Colormap []uint16 `tiff:"field,tag=320"`
TileWidth uint16 `tiff:"field,tag=322"`
TileHeight uint16 `tiff:"field,tag=323"`
TileOffsets []uint64 `tiff:"field,tag=324"`
TileByteCounts []uint64 `tiff:"field,tag=325"`
ExtraSamples []uint16 `tiff:"field,tag=338"`
SampleFormat []uint16 `tiff:"field,tag=339"`
JPEGTables []byte `tiff:"field,tag=347"`
Copyright string `tiff:"field,tag=33432"`
ModelPixelScaleTag []float64 `tiff:"field,tag=33550"`
ModelTiePointTag []float64 `tiff:"field,tag=33922"`
ModelTransformationTag []float64 `tiff:"field,tag=34264"`
GeoKeyDirectoryTag []uint16 `tiff:"field,tag=34735"`
GeoDoubleParamsTag []float64 `tiff:"field,tag=34736"`
GeoAsciiParamsTag string `tiff:"field,tag=34737"`
GDALMetaData string `tiff:"field,tag=42112"`
NoData string `tiff:"field,tag=42113"`
LERCParams []uint32 `tiff:"field,tag=50674"`
RPCs []float64 `tiff:"field,tag=50844"`
LoadTile func(idx int, data []byte) error
// contains filtered or unexported fields
}
func (*IFD) AddMask ¶
AddMask sets msk as a mask for ifd. Must not be called after SetPlanarInterleaving
func (*IFD) AddOverview ¶
func (*IFD) SetPlanarInterleaving ¶ added in v0.1.0
func (ifd *IFD) SetPlanarInterleaving(pi PlanarInterleaving) error
SetPlanarInterleaving configures a non-default planar interleaving for this ifd. Must be called after AddMask.
func (*IFD) TileFromIdx ¶ added in v0.1.0
type Image ¶ added in v0.1.0
An Image is a Width*Height rectangle of pixels (i.e. there are no overviews at this level) and its decompostion into Strips that can be processed concurrently
type Node ¶ added in v0.1.0
type Node struct {
// Parents are the indexes of the parent strips that will be used to compose the current strip
Parents []int
//ParentOffset is the Y position in the parent image of the top-most parent strip
ParentOffset int
}
A Node represents a single Strip in the Dag
type PlanarInterleaving ¶ added in v0.1.0
type PlanarInterleaving [][]int
PlanarInterleaving describes how the band data should be interleaved for tiffs with more than 1 plane and with PlanarConfiguration=2
This is an advanced usage option that does not modify the actual image data but tweaks the order in which each plane's (i.e. band's) tile is written in the resulting file.
Examples for a 3-band rgb image:
- [[0,1,2]] will result in tiles written in the order r1,g1,b1,r2,g2,b2...rn,gn,bn. This is the default.
- [0],[1],[2]] => r1,r2...rn,g1,g2....gn,b1,b2...bn
- [0],[2],[1]] => r1,r2...rn,b1,b2....bn,g1,g2...gn
- [0,1],[2]] => r1,g1,r2,g2...rn,gn,b1,b2....bn
Examples for a 3-band rgb image with mask:
- [[0,1,2,3]] will result in tiles written in the order r1,g1,b1,m1,r2,g2,b2,m2...rn,gn,bn,mn. This is the default.
- [0],[1],[2],[3]] => r1,r2...rn,g1,g2...gn,b1,b2...bn,m1,m2...mn
- [0],[3],[2],[1]] => r1,r2...rn,m1,m2...m3,b1,b2...bn,g1,g2...gn
- [0,1],[2],[3]] => r1,g1,r2,g2...rn,gn,b1,b2....bn,m1m2...mn
For a n-band image, each band index from 0 to n-1 must appear exactly once in the array. If the image also has a mask, the index n must also appear exactly once and represents the mask position.
type Pyramid ¶ added in v0.1.0
type Pyramid []Image
The Image at index 0 is the full resolution image, and Pyramid[0]'s Strip's Source properties reference the pixel frame of the input image.
The Images at index >0 are the overviews, who's Strip's sources reference the image at the previous index
type Strip ¶ added in v0.1.0
type Strip struct {
Width, Height int
TopLeftX, TopLeftY int
SrcTopLeftX, SrcTopLeftY float64
SrcWidth, SrcHeight float64
}
A Strip is the basic building block of an Image, and corresponds to a rectangle of Width*Height pixels who's upper left corner is TopLeftX,TopLeftY. The TopLeftX and TopLeftY properties are informative only and are not needed in order to process an image with this API.
In order to populate the pixels of a given strip, data must be copied or downsampled from a window of a source Image. Depending on the context, the source can either be the original image when creating the full-resolution IFD, or the full-resolution IFD when creating the first overview, or the previous overview when creating another overview. The source window is defined by it's upper left corner (SrcTopLeftX and SrcTopLeftY) and size (SrcWidth and SrcHeight)
In gdal lingo, this strip can be calculated by running
gdal_translate source_dataset.tif strip.tif -srcwin <SrcTopLeftX> <SrcTopLeftY> <SrcWidth> <SrcHeight> -outsize <Width> <Height> -r average
type Stripper ¶ added in v0.1.0
type Stripper struct {
// contains filtered or unexported fields
}
A Stripper holds the information to inform how to split an image and its overviews into strips of roughly similar sizes, allowing these strips to be produced outside of the cogger library itself, and ensuring that the internal tiling of these individaul strips will be compatible with a cog reconstruction.
The usual workflow is to create a Stripper matching the input image's dimensions, rough size of each strip to be processed, and output cog parameters (namely internal tiling size)
For a full example, see the cmd/pcogger utility
Example ¶
// let's imagine we have an input.jp2 file of size 12345x23456 pixels, that we want to convert to a cog
//
// we will do this in parallel using gdal and cogger, using the stripper class to subdivide the task
inputFile := os.Getenv("STRIPPER_INPUT")
if inputFile == "" {
inputFile = "input.jp2"
}
width, _ := strconv.Atoi(os.Getenv("STRIPPER_WIDTH"))
if width == 0 {
width = 12345
}
height, _ := strconv.Atoi(os.Getenv("STRIPPER_HEIGHT"))
if height == 0 {
height = 23456
}
stripper, _ := NewStripper(width, height)
pyr := stripper.Pyramid()
tx, ty := stripper.InternalTileSize()
copts := fmt.Sprintf("-co TILED=YES -co COMPRESS=LZW -co BLOCKXSIZE=%d -co BLOCKYSIZE=%d", tx, ty)
srcStrips := [][]tiff.ReadAtReadSeeker{} //used to accumulate the readers of intermediate strips. the ordering must be identical to Pyramid/Pyramid.Strips
vrt_accum := []string{}
for l := range pyr {
fmt.Printf("\nbatch %d\n\n", l+1)
infile := inputFile
if l > 0 {
// if we are in an overview level, optionally build a vrt file making a single gdal image from the all the strips created at the previous level
if len(vrt_accum) > 1 {
infile = fmt.Sprintf("l_%d.vrt", l-1)
fmt.Printf("gdalbuildvrt %s %s\n", infile, strings.Join(vrt_accum, " "))
} else {
infile = vrt_accum[0]
}
vrt_accum = []string{}
}
lStrips := []tiff.ReadAtReadSeeker{}
for s, strip := range pyr[l].Strips {
stripname := fmt.Sprintf("tmp_%d_%d.tif", l, s)
vrt_accum = append(vrt_accum, stripname)
resizeOpts := ""
if l > 0 {
resizeOpts = fmt.Sprintf("-outsize %d %d -r average", strip.Width, strip.Height)
}
fmt.Printf("gdal_translate %s %s %s %s -srcwin 0 %g %g %g\n", infile, stripname, copts, resizeOpts,
strip.SrcTopLeftY, strip.SrcWidth, strip.SrcHeight)
rs, _ := os.Open(stripname)
lStrips = append(lStrips, rs)
}
srcStrips = append(srcStrips, lStrips)
}
outcog, _ := os.Create("stripper-example-output.tif")
//defer os.Remove(outcog.Name())
ifdtree, _ := stripper.AssembleStrips(srcStrips)
_ = ifdtree
DefaultConfig().RewriteIFDTree(ifdtree, outcog)
outcog.Close()
////output: foo
func NewStripper ¶ added in v0.1.0
func NewStripper(width, height int, options ...StripperOption) (Stripper, error)
NewStripper create a stripper for an image of given width and height. Default options are: - 64 MPixel strips - 256x256 internal tiling - overviews down to just under 256 pixels
func (Stripper) AssembleStrips ¶ added in v0.1.0
func (t Stripper) AssembleStrips(srcStrips [][]tiff.ReadAtReadSeeker) (*IFD, error)
AssembleStrips takes the strips that have been created by following the corresponding Pyramid structure. The ordering of the strip readers in the srcStrips double array must be the same as that of the pyramid structure.
This create a "virtual" IFD tree that has all the caracteristics of final COG file, with the tile loading functions that will reference which tile from which strip to use.
func (Stripper) FullresStripHeightMultiple ¶ added in v0.1.0
func (Stripper) InternalTileSize ¶ added in v0.1.0
func (Stripper) MinOverviewSize ¶ added in v0.1.0
func (Stripper) OverviewCount ¶ added in v0.1.0
func (Stripper) TargetPixelCount ¶ added in v0.1.0
type StripperOption ¶ added in v0.1.0
func FullresStripHeightMultiple ¶ added in v0.1.0
func FullresStripHeightMultiple(heightBase int) StripperOption
FullresStripHeightMultiple forces the strip height to be a multiple of the given heightBase value provided. This can be useful to ensure that the full resolution strip heights are a multiple of the internal tiling height of the source dataset to avoid duplicated source-tile decompressions.
func InternalTileSize ¶ added in v0.1.0
func InternalTileSize(width, height int) StripperOption
InternalTileSize sets the internal tiling size of the TIF file
func MinOverviewSize ¶ added in v0.1.0
func MinOverviewSize(size int) StripperOption
MinOverviewSize sets the minimal overview size of the TIF file. i.e. overviews will stop being added once one of width or height has reached this value, even if the other dimension is still over the internal tile size
func OverviewCount ¶ added in v0.1.0
func OverviewCount(count int) StripperOption
OverviewCount forces the number of overviews to create. By default we create as many as needed in order to reach a size that fits into a single internal TIF tile
func TargetPixelCount ¶ added in v0.1.0
func TargetPixelCount(count int) StripperOption
Approximate number of pixels to use for a single strip. i.e. a single subjob will have to process approximately this number of pixels, whatever the size of the whole image. Will be adjusted to fit the internal tiling size