Image::Format Image::detectFormat(const unsigned char * data, ssize_t dataLen) { if (isPng(data, dataLen)) { return Format::PNG; } else if (isJpg(data, dataLen)) { return Format::JPG; } else if (isTiff(data, dataLen)) { return Format::TIFF; } else if (isWebp(data, dataLen)) { return Format::WEBP; } else if (isPvr(data, dataLen)) { return Format::PVR; } else if (isEtc(data, dataLen)) { return Format::ETC; } else if (isS3TC(data, dataLen)) { return Format::S3TC; } else if (isATITC(data, dataLen)) { return Format::ATITC; } else { return Format::UNKNOWN; } }
bool Bitmap::getImageSize(const io::Producer &file, size_t &width, size_t &height) { StackBuffer<256> data; if (file.seekAndRead(0, data, 30) < 30) { return false; } if (isPng(data.data(), data.size()) && data.size() >= 24) { auto reader = DataReader<ByteOrder::Network>(data.data() + 16, 8); width = reader.readUnsigned32(); height = reader.readUnsigned32(); return true; } else if(isJpg(data.data(), data.size())) { size_t offset = 2; uint16_t len = 0; uint8_t marker = 0; auto reader = DataReader<ByteOrder::Network>(data.data() + 2, data.size() - 2); while (reader.is((uint8_t)0xFF)) { ++ reader; } marker = reader.readUnsigned(); len = reader.readUnsigned16(); while (marker < 0xC0 || marker > 0xCF) { offset += 2 + len; data.clear(); if (file.seekAndRead(offset, data, 12) != 12) { return false; } if (data.size() >= 12) { reader = data.get<DataReader<ByteOrder::Network>>(); while (reader.is((uint8_t)0xFF)) { ++ reader; } marker = reader.readUnsigned(); len = reader.readUnsigned16(); } else { reader.clear(); break; } } if (reader >= 5 && marker >= 0xC0 && marker <= 0xCF) { ++ reader; height = reader.readUnsigned16(); width = reader.readUnsigned16(); return true; } return false; } else if (isGif(data.data(), data.size())) { auto reader = DataReader<ByteOrder::Little>(data.data() + 6, 4); width = reader.readUnsigned16(); height = reader.readUnsigned16(); return true; } else if (isWebp(data.data(), data.size())) { auto reader = DataReader<ByteOrder::Little>(data.data() + 26, 4); width = reader.readUnsigned16(); height = reader.readUnsigned16(); return true; } else if (isTiff(data.data(), data.size())) { if (memcmp(data.data(), "II", 2) == 0) { if (Bitmap_getTiffImageSize<DataReader<ByteOrder::Little>>(data, file, width, height)) { return true; } } else { if (Bitmap_getTiffImageSize<DataReader<ByteOrder::Big>>(data, file, width, height)) { return true; } } } return false; }