image-in-browser
Version:
Package for encoding / decoding images, transforming images, applying filters, drawing primitives on images on the client side (no need for server Node.js)
77 lines • 3.1 kB
JavaScript
import { Format, FormatType } from '../color/format.js';
import { OutputBuffer } from '../common/output-buffer.js';
import { LibError } from '../error/lib-error.js';
import { ExifData } from '../exif/exif-data.js';
import { IfdUndefinedValue } from '../exif/ifd-value/ifd-undefined-value.js';
import { TiffCompression } from './tiff/tiff-compression.js';
import { TiffFormat } from './tiff/tiff-format.js';
import { TiffPhotometricType } from './tiff/tiff-photometric-type.js';
export class TiffEncoder {
constructor() {
this._supportsAnimation = false;
}
get supportsAnimation() {
return this._supportsAnimation;
}
getSampleFormat(image) {
switch (image.formatType) {
case FormatType.uint:
return TiffFormat.uint;
case FormatType.int:
return TiffFormat.int;
case FormatType.float:
return TiffFormat.float;
}
throw new LibError('Unknown TIFF format type.');
}
encode(opt) {
var _a;
const skipExif = (_a = opt.skipExif) !== null && _a !== void 0 ? _a : false;
let image = opt.image;
const out = new OutputBuffer();
const exif = new ExifData();
if (image.exifData.size > 0 && !skipExif) {
exif.imageIfd.copyFrom(image.exifData.imageIfd);
}
if (image.isHdrFormat) {
image = image.convert({
format: Format.uint8,
});
}
const type = image.numChannels === 1
? TiffPhotometricType.blackIsZero
: image.hasPalette
? TiffPhotometricType.palette
: TiffPhotometricType.rgb;
const nc = image.numChannels;
const ifd0 = exif.imageIfd;
ifd0.setValue('ImageWidth', image.width);
ifd0.setValue('ImageHeight', image.height);
ifd0.setValue('BitsPerSample', image.bitsPerChannel);
ifd0.setValue('SampleFormat', this.getSampleFormat(image));
ifd0.setValue('SamplesPerPixel', image.hasPalette ? 1 : nc);
ifd0.setValue('Compression', TiffCompression.none);
ifd0.setValue('PhotometricInterpretation', type);
ifd0.setValue('RowsPerStrip', image.height);
ifd0.setValue('PlanarConfiguration', 1);
ifd0.setValue('TileWidth', image.width);
ifd0.setValue('TileLength', image.height);
ifd0.setValue('StripByteCounts', image.byteLength);
ifd0.setValue('StripOffsets', new IfdUndefinedValue(image.toUint8Array()));
if (image.hasPalette) {
const p = image.palette;
const numCh = 3;
const numC = p.numColors;
const colorMap = new Uint16Array(numC * numCh);
for (let c = 0, ci = 0; c < numCh; ++c) {
for (let i = 0; i < numC; ++i) {
colorMap[ci++] = Math.trunc(p.get(i, c)) << 8;
}
}
ifd0.setValue('ColorMap', colorMap);
}
exif.write(out);
return out.getBytes();
}
}
//# sourceMappingURL=tiff-encoder.js.map