Skip to content
Merged
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
39 changes: 15 additions & 24 deletions packages/geotiff/src/array.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import type { Affine } from "@developmentseed/affine";
import type { ProjJson } from "./crs.js";
import type {
DecodedBandSeparate,
DecodedPixelInterleaved,
DecodedPixels,
} from "./decode.js";

/** Typed arrays supported for raster sample storage. */
export type RasterTypedArray =
Expand Down Expand Up @@ -38,36 +43,22 @@ type RasterArrayBase = {
*/
transform: Affine;

/** Coordinate reference system information. */
crs: number | ProjJson;

/** Nodata value from `GDAL_NODATA` TIFF tag. */
nodata: number | null;
};

/** Raster stored in one typed array per band (band-major / planar). */
export type BandRasterArray = RasterArrayBase & {
layout: "band-separate";
/**
* One typed array per band, each length = width * height.
*
* This is the preferred representation when uploading one texture per band.
*/
bands: RasterTypedArray[];
};
export type RasterArrayBandSeparate = RasterArrayBase & DecodedBandSeparate;

/** Raster stored in one pixel-interleaved typed array. */
export type PixelRasterArray = RasterArrayBase & {
layout: "pixel-interleaved";
/**
* Pixel-interleaved raster data:
* [p00_band0, p00_band1, ..., p01_band0, ...]
*
* Length = width * height * count.
*/
data: RasterTypedArray;
};
export type RasterArrayPixelInterleaved = RasterArrayBase &
DecodedPixelInterleaved;

/** Decoded raster data from a GeoTIFF region. */
export type RasterArray = BandRasterArray | PixelRasterArray;
export type RasterArray = RasterArrayBase & DecodedPixels;

/** Options for packing band data to a 4-channel pixel-interleaved array. */
export type PackBandsToRGBAOptions = {
Expand All @@ -81,7 +72,7 @@ export type PackBandsToRGBAOptions = {
};

/** Convert any raster layout to a band-separate representation. */
export function toBandSeparate(array: RasterArray): BandRasterArray {
export function toBandSeparate(array: RasterArray): RasterArrayBandSeparate {
validateRasterShape(array);
if (array.layout === "band-separate") {
return array;
Expand Down Expand Up @@ -115,7 +106,7 @@ export function toBandSeparate(array: RasterArray): BandRasterArray {
export function toPixelInterleaved(
array: RasterArray,
order?: readonly number[],
): PixelRasterArray {
): RasterArrayPixelInterleaved {
validateRasterShape(array);

const defaultOrder = Array.from({ length: array.count }, (_, i) => i);
Expand Down Expand Up @@ -158,7 +149,7 @@ export function toPixelInterleaved(
export function reorderBands(
array: RasterArray,
order: readonly number[],
): BandRasterArray {
): RasterArrayBandSeparate {
validateRasterShape(array);
validateBandOrder(order, array.count);
const src = toBandSeparate(array);
Expand All @@ -178,7 +169,7 @@ export function reorderBands(
export function packBandsToRGBA(
array: RasterArray,
options: PackBandsToRGBAOptions = {},
): PixelRasterArray {
): RasterArrayPixelInterleaved {
const order = options.order ?? [0, 1, 2, null];
const fillValue = options.fillValue ?? 0;

Expand Down
27 changes: 24 additions & 3 deletions packages/geotiff/src/decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,31 @@ import type { RasterTypedArray } from "./array.js";
import { decode as decodeViaCanvas } from "./codecs/canvas.js";
import { applyPredictor } from "./codecs/predictor.js";

/** Raster stored in one pixel-interleaved typed array. */
export type DecodedPixelInterleaved = {
layout: "pixel-interleaved";
/**
* Pixel-interleaved raster data:
* [p00_band0, p00_band1, ..., p01_band0, ...]
*
* Length = width * height * count.
*/
data: RasterTypedArray;
};

/** Raster stored in one typed array per band (band-major / planar). */
export type DecodedBandSeparate = {
layout: "band-separate";
/**
* One typed array per band, each length = width * height.
*
* This is the preferred representation when uploading one texture per band.
*/
bands: RasterTypedArray[];
};

/** The result of a decoding process */
export type DecodedPixels =
| { layout: "pixel-interleaved"; data: RasterTypedArray }
| { layout: "band-separate"; bands: RasterTypedArray[] };
export type DecodedPixels = DecodedPixelInterleaved | DecodedBandSeparate;

/** Metadata from the TIFF IFD, passed to decoders that need it. */
export type DecoderMetadata = {
Expand Down
13 changes: 8 additions & 5 deletions packages/geotiff/tests/array.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { Affine } from "@developmentseed/affine";
import { describe, expect, it } from "vitest";
import type { BandRasterArray, PixelRasterArray } from "../src/array.js";
import type {
RasterArrayBandSeparate,
RasterArrayPixelInterleaved,
} from "../src/array.js";
import {
packBandsToRGBA,
reorderBands,
Expand Down Expand Up @@ -89,7 +92,7 @@ function baseMetadata() {

describe("RasterArray helpers", () => {
it("converts band-separate data to pixel-interleaved", () => {
const raster: BandRasterArray = {
const raster: RasterArrayBandSeparate = {
...baseMetadata(),
layout: "band-separate",
count: 3,
Expand All @@ -108,7 +111,7 @@ describe("RasterArray helpers", () => {
});

it("converts pixel-interleaved data to band-separate", () => {
const raster: PixelRasterArray = {
const raster: RasterArrayPixelInterleaved = {
...baseMetadata(),
layout: "pixel-interleaved",
count: 3,
Expand All @@ -123,7 +126,7 @@ describe("RasterArray helpers", () => {
});

it("reorders bands without repacking to pixel layout", () => {
const raster: BandRasterArray = {
const raster: RasterArrayBandSeparate = {
...baseMetadata(),
layout: "band-separate",
count: 3,
Expand All @@ -142,7 +145,7 @@ describe("RasterArray helpers", () => {
});

it("packs selected bands to RGBA", () => {
const raster: BandRasterArray = {
const raster: RasterArrayBandSeparate = {
...baseMetadata(),
layout: "band-separate",
count: 3,
Expand Down
Loading