TiffImage constructor
TiffImage()
Implementation
TiffImage(InputBuffer p) {
final p3 = InputBuffer.from(p);
final numDirEntries = p.readUint16();
for (var i = 0; i < numDirEntries; ++i) {
final tag = p.readUint16();
final type = p.readUint16();
final numValues = p.readUint32();
final entry = TiffEntry(tag, type, numValues, p3);
// The value for the tag is either stored in another location,
// or within the tag itself (if the size fits in 4 bytes).
// We're not reading the data here, just storing offsets.
if (entry.numValues * entry.typeSize > 4) {
entry.valueOffset = p.readUint32();
} else {
entry.valueOffset = p.offset;
p.offset += 4;
}
tags[entry.tag] = entry;
if (entry.tag == TAG_IMAGE_WIDTH) {
width = entry.readValue();
} else if (entry.tag == TAG_IMAGE_LENGTH) {
height = entry.readValue();
} else if (entry.tag == TAG_PHOTOMETRIC_INTERPRETATION) {
photometricType = entry.readValue();
} else if (entry.tag == TAG_COMPRESSION) {
compression = entry.readValue();
} else if (entry.tag == TAG_BITS_PER_SAMPLE) {
bitsPerSample = entry.readValue();
} else if (entry.tag == TAG_SAMPLES_PER_PIXEL) {
samplesPerPixel = entry.readValue();
} else if (entry.tag == TAG_PREDICTOR) {
predictor = entry.readValue();
} else if (entry.tag == TAG_SAMPLE_FORMAT) {
sampleFormat = entry.readValue();
} else if (entry.tag == TAG_COLOR_MAP) {
colorMap = entry.readValues();
colorMapRed = 0;
colorMapGreen = colorMap!.length ~/ 3;
colorMapBlue = colorMapGreen * 2;
}
}
if (width == 0 || height == 0) {
return;
}
if (colorMap != null && bitsPerSample == 8) {
for (var i = 0, len = colorMap!.length; i < len; ++i) {
colorMap![i] >>= 8;
}
}
if (photometricType == 0) {
isWhiteZero = true;
}
if (hasTag(TAG_TILE_OFFSETS)) {
tiled = true;
// Image is in tiled format
tileWidth = _readTag(TAG_TILE_WIDTH);
tileHeight = _readTag(TAG_TILE_LENGTH);
tileOffsets = _readTagList(TAG_TILE_OFFSETS);
tileByteCounts = _readTagList(TAG_TILE_BYTE_COUNTS);
} else {
tiled = false;
tileWidth = _readTag(TAG_TILE_WIDTH, width);
if (!hasTag(TAG_ROWS_PER_STRIP)) {
tileHeight = _readTag(TAG_TILE_LENGTH, height);
} else {
final l = _readTag(TAG_ROWS_PER_STRIP);
var infinity = 1;
infinity = (infinity << 32) - 1;
if (l == infinity) {
// 2^32 - 1 (effectively infinity, entire image is 1 strip)
tileHeight = height;
} else {
tileHeight = l;
}
}
tileOffsets = _readTagList(TAG_STRIP_OFFSETS);
tileByteCounts = _readTagList(TAG_STRIP_BYTE_COUNTS);
}
// Calculate number of tiles and the tileSize in bytes
tilesX = (width + tileWidth - 1) ~/ tileWidth;
tilesY = (height + tileHeight - 1) ~/ tileHeight;
tileSize = tileWidth * tileHeight * samplesPerPixel;
fillOrder = _readTag(TAG_FILL_ORDER, 1);
t4Options = _readTag(TAG_T4_OPTIONS);
t6Options = _readTag(TAG_T6_OPTIONS);
extraSamples = _readTag(TAG_EXTRA_SAMPLES);
// Determine which kind of image we are dealing with.
switch (photometricType) {
case 0: // WhiteIsZero
case 1: // BlackIsZero
if (bitsPerSample == 1 && samplesPerPixel == 1) {
imageType = TYPE_BILEVEL;
} else if (bitsPerSample == 4 && samplesPerPixel == 1) {
imageType = TYPE_GRAY_4BIT;
} else if (bitsPerSample % 8 == 0) {
if (samplesPerPixel == 1) {
imageType = TYPE_GRAY;
} else if (samplesPerPixel == 2) {
imageType = TYPE_GRAY_ALPHA;
} else {
imageType = TYPE_GENERIC;
}
}
break;
case 2: // RGB
if (bitsPerSample % 8 == 0) {
if (samplesPerPixel == 3) {
imageType = TYPE_RGB;
} else if (samplesPerPixel == 4) {
imageType = TYPE_RGB_ALPHA;
} else {
imageType = TYPE_GENERIC;
}
}
break;
case 3: // RGB Palette
if (samplesPerPixel == 1 &&
(bitsPerSample == 4 || bitsPerSample == 8 || bitsPerSample == 16)) {
imageType = TYPE_PALETTE;
}
break;
case 4: // Transparency mask
if (bitsPerSample == 1 && samplesPerPixel == 1) {
imageType = TYPE_BILEVEL;
}
break;
case 6: // YCbCr
if (compression == COMPRESSION_JPEG &&
bitsPerSample == 8 &&
samplesPerPixel == 3) {
imageType = TYPE_RGB;
} else {
if (hasTag(TAG_YCBCR_SUBSAMPLING)) {
final v = tags[TAG_YCBCR_SUBSAMPLING]!.readValues();
chromaSubH = v[0];
chromaSubV = v[1];
} else {
chromaSubH = 2;
chromaSubV = 2;
}
if (chromaSubH * chromaSubV == 1) {
imageType = TYPE_GENERIC;
} else if (bitsPerSample == 8 && samplesPerPixel == 3) {
imageType = TYPE_YCBCR_SUB;
}
}
break;
default: // Other including CMYK, CIE L*a*b*, unknown.
if (bitsPerSample % 8 == 0) {
imageType = TYPE_GENERIC;
}
break;
}
}