/* * Copyright 2006-2007, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Stephan Aßmus */ #include "FlatIconFormat.h" #include "LittleEndianBuffer.h" _BEGIN_ICON_NAMESPACE const uint32 FLAT_ICON_MAGIC = 'ficn'; const char* kVectorAttrNodeName = "BEOS:ICON"; const char* kVectorAttrMimeName = "META:ICON"; // read_coord bool read_coord(LittleEndianBuffer& buffer, float& coord) { uint8 value; if (!buffer.Read(value)) return false; if (value & 128) { // high bit set, the next byte is part of the coord uint8 lowValue; if (!buffer.Read(lowValue)) return false; value &= 127; uint16 coordValue = (value << 8) | lowValue; coord = (float)coordValue / 102.0 - 128.0; } else { // simple coord coord = (float)value - 32.0; } return true; } // write_coord bool write_coord(LittleEndianBuffer& buffer, float coord) { // clamp coord if (coord < -128.0) coord = -128.0; if (coord > 192.0) coord = 192.0; if (int(coord * 100.0) == (int)coord * 100 && coord >= - 32.0 && coord <= 95.0) { // saving coord in 7 bit is sufficient uint8 value = (uint8)(coord + 32.0); return buffer.Write(value); } else { // needing to save coord in 15 bits uint16 value = (uint16)((coord + 128.0) * 102.0); // set high bit to indicate there is only one byte value |= 32768; uint8 highValue = value >> 8; uint8 lowValue = value & 255; return buffer.Write(highValue) && buffer.Write(lowValue); } } // read_float_24 bool read_float_24(LittleEndianBuffer& buffer, float& _value) { uint8 bufferValue[3]; if (!buffer.Read(bufferValue[0]) || !buffer.Read(bufferValue[1]) || !buffer.Read(bufferValue[2])) return false; int shortValue = (bufferValue[0] << 16) | (bufferValue[1] << 8) | bufferValue[2]; int sign = (shortValue & 0x800000) >> 23; int exponent = ((shortValue & 0x7e0000) >> 17) - 32; int mantissa = (shortValue & 0x01ffff) << 6; if (shortValue == 0) _value = 0.0; else { uint32 value = (sign << 31) | ((exponent + 127) << 23) | mantissa; _value = (float&)value; } return true; } // write_float_24 bool write_float_24(LittleEndianBuffer& buffer, float _value) { // 1 bit sign // 6 bit exponent // 17 bit mantissa // TODO: fixme for non-IEEE 754 architectures uint32 value = (uint32&)_value; int sign = (value & 0x80000000) >> 31; int exponent = ((value & 0x7f800000) >> 23) - 127; int mantissa = value & 0x007fffff; if (exponent >= 32 || exponent < -32) { uint8 zero = 0; return buffer.Write(zero) && buffer.Write(zero) && buffer.Write(zero); } int shortValue = (sign << 23) | ((exponent + 32) << 17) | (mantissa >> 6); return buffer.Write((uint8)(shortValue >> 16)) && buffer.Write((uint8)((shortValue >> 8) & 0xff)) && buffer.Write((uint8)(shortValue & 0xff)); } _END_ICON_NAMESPACE