ImageFormat identifyImage(const unsigned char * data, int length){ if (isPng(data, length)){ return FormatPNG; } if (isBmp(data, length)){ return FormatBMP; } if (isJpg(data, length)){ return FormatJPG; } if (isPcx(data, length)){ return FormatPCX; } if (isTga(data, length)){ return FormatTGA; } if (isTif(data, length)){ return FormatTIF; } if (isXpm(data, length)){ return FormatXPM; } if (isGif(data, length)){ return FormatGIF; } return FormatUnknown; }
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; }