xref: /haiku/src/libs/icon/flat_icon/FlatIconFormat.cpp (revision 268f99dd7dc4bd7474a8bd2742d3f1ec1de6752a)
1fb07ece0SStephan Aßmus /*
2325a6253SAxel Dörfler  * Copyright 2006-2007, Haiku. All rights reserved.
3fb07ece0SStephan Aßmus  * Distributed under the terms of the MIT License.
4fb07ece0SStephan Aßmus  *
5fb07ece0SStephan Aßmus  * Authors:
6fb07ece0SStephan Aßmus  *		Stephan Aßmus <superstippi@gmx.de>
7fb07ece0SStephan Aßmus  */
8fb07ece0SStephan Aßmus 
9325a6253SAxel Dörfler 
10fb07ece0SStephan Aßmus #include "FlatIconFormat.h"
11fb07ece0SStephan Aßmus 
12fb07ece0SStephan Aßmus #include "LittleEndianBuffer.h"
13fb07ece0SStephan Aßmus 
14325a6253SAxel Dörfler 
1525dc253dSIngo Weinhold _BEGIN_ICON_NAMESPACE
1625dc253dSIngo Weinhold 
17325a6253SAxel Dörfler 
18fb07ece0SStephan Aßmus const uint32 FLAT_ICON_MAGIC = 'ficn';
19fb07ece0SStephan Aßmus 
2070f4b8c0SStephan Aßmus const char* kVectorAttrNodeName = "BEOS:ICON";
2170f4b8c0SStephan Aßmus const char* kVectorAttrMimeName = "META:ICON";
22fb07ece0SStephan Aßmus 
23325a6253SAxel Dörfler 
24fb07ece0SStephan Aßmus // read_coord
25fb07ece0SStephan Aßmus bool
read_coord(LittleEndianBuffer & buffer,float & coord)26fb07ece0SStephan Aßmus read_coord(LittleEndianBuffer& buffer, float& coord)
27fb07ece0SStephan Aßmus {
28fb07ece0SStephan Aßmus 	uint8 value;
29fb07ece0SStephan Aßmus 	if (!buffer.Read(value))
30fb07ece0SStephan Aßmus 		return false;
31fb07ece0SStephan Aßmus 
32fb07ece0SStephan Aßmus 	if (value & 128) {
33fb07ece0SStephan Aßmus 		// high bit set, the next byte is part of the coord
34fb07ece0SStephan Aßmus 		uint8 lowValue;
35fb07ece0SStephan Aßmus 		if (!buffer.Read(lowValue))
36fb07ece0SStephan Aßmus 			return false;
37fb07ece0SStephan Aßmus 		value &= 127;
38fb07ece0SStephan Aßmus 		uint16 coordValue = (value << 8) | lowValue;
39fb07ece0SStephan Aßmus 		coord = (float)coordValue / 102.0 - 128.0;
40fb07ece0SStephan Aßmus 	} else {
41fb07ece0SStephan Aßmus 		// simple coord
42fb07ece0SStephan Aßmus 		coord = (float)value - 32.0;
43fb07ece0SStephan Aßmus 	}
44fb07ece0SStephan Aßmus 	return true;
45fb07ece0SStephan Aßmus }
46fb07ece0SStephan Aßmus 
47fb07ece0SStephan Aßmus // write_coord
48fb07ece0SStephan Aßmus bool
write_coord(LittleEndianBuffer & buffer,float coord)49fb07ece0SStephan Aßmus write_coord(LittleEndianBuffer& buffer, float coord)
50fb07ece0SStephan Aßmus {
51fb07ece0SStephan Aßmus 	// clamp coord
52fb07ece0SStephan Aßmus 	if (coord < -128.0)
53fb07ece0SStephan Aßmus 		coord = -128.0;
54fb07ece0SStephan Aßmus 	if (coord > 192.0)
55fb07ece0SStephan Aßmus 		coord = 192.0;
56fb07ece0SStephan Aßmus 
57fb07ece0SStephan Aßmus 	if (int(coord * 100.0) == (int)coord * 100
589f507806SStephan Aßmus 		&& coord >= - 32.0 && coord <= 95.0) {
59fb07ece0SStephan Aßmus 		// saving coord in 7 bit is sufficient
60fb07ece0SStephan Aßmus 		uint8 value = (uint8)(coord + 32.0);
61fb07ece0SStephan Aßmus 		return buffer.Write(value);
62fb07ece0SStephan Aßmus 	} else {
63fb07ece0SStephan Aßmus 		// needing to save coord in 15 bits
64fb07ece0SStephan Aßmus 		uint16 value = (uint16)((coord + 128.0) * 102.0);
65fb07ece0SStephan Aßmus 		// set high bit to indicate there is only one byte
66fb07ece0SStephan Aßmus 		value |= 32768;
67fb07ece0SStephan Aßmus 		uint8 highValue = value >> 8;
68fb07ece0SStephan Aßmus 		uint8 lowValue = value & 255;
69fb07ece0SStephan Aßmus 		return buffer.Write(highValue) && buffer.Write(lowValue);
70fb07ece0SStephan Aßmus 	}
71fb07ece0SStephan Aßmus }
72fb07ece0SStephan Aßmus 
73fb07ece0SStephan Aßmus // read_float_24
74fb07ece0SStephan Aßmus bool
read_float_24(LittleEndianBuffer & buffer,float & _value)75fb07ece0SStephan Aßmus read_float_24(LittleEndianBuffer& buffer, float& _value)
76fb07ece0SStephan Aßmus {
77fb07ece0SStephan Aßmus 	uint8 bufferValue[3];
78fb07ece0SStephan Aßmus 	if (!buffer.Read(bufferValue[0]) || !buffer.Read(bufferValue[1])
79fb07ece0SStephan Aßmus 		|| !buffer.Read(bufferValue[2]))
80fb07ece0SStephan Aßmus 		return false;
81fb07ece0SStephan Aßmus 
82fb07ece0SStephan Aßmus 	int shortValue = (bufferValue[0] << 16)
83fb07ece0SStephan Aßmus 		| (bufferValue[1] << 8) | bufferValue[2];
84fb07ece0SStephan Aßmus 
85fb07ece0SStephan Aßmus 	int sign = (shortValue & 0x800000) >> 23;
86fb07ece0SStephan Aßmus 	int exponent = ((shortValue & 0x7e0000) >> 17) - 32;
87fb07ece0SStephan Aßmus 	int mantissa = (shortValue & 0x01ffff) << 6;
88fb07ece0SStephan Aßmus 
89fb07ece0SStephan Aßmus 	if (shortValue == 0)
90fb07ece0SStephan Aßmus 		_value = 0.0;
91fb07ece0SStephan Aßmus 	else {
92*5b38b945SFranck LeCodeur 		union {
93*5b38b945SFranck LeCodeur 			uint32 intValue;
94*5b38b945SFranck LeCodeur 			float floatValue;
95*5b38b945SFranck LeCodeur 		} i2f;
96*5b38b945SFranck LeCodeur 		i2f.intValue = (sign << 31) | ((exponent + 127) << 23) | mantissa;
97*5b38b945SFranck LeCodeur 		_value = i2f.floatValue;
98fb07ece0SStephan Aßmus 	}
99fb07ece0SStephan Aßmus 
100fb07ece0SStephan Aßmus 	return true;
101fb07ece0SStephan Aßmus }
102fb07ece0SStephan Aßmus 
103fb07ece0SStephan Aßmus // write_float_24
104fb07ece0SStephan Aßmus bool
write_float_24(LittleEndianBuffer & buffer,float _value)105fb07ece0SStephan Aßmus write_float_24(LittleEndianBuffer& buffer, float _value)
106fb07ece0SStephan Aßmus {
107fb07ece0SStephan Aßmus 	// 1 bit sign
108fb07ece0SStephan Aßmus 	// 6 bit exponent
109fb07ece0SStephan Aßmus 	// 17 bit mantissa
110fb07ece0SStephan Aßmus 	// TODO: fixme for non-IEEE 754 architectures
111*5b38b945SFranck LeCodeur 	union {
112*5b38b945SFranck LeCodeur 		float floatValue;
113*5b38b945SFranck LeCodeur 		uint32 intValue;
114*5b38b945SFranck LeCodeur 	} f2i;
115*5b38b945SFranck LeCodeur 	f2i.floatValue = _value;
116fb07ece0SStephan Aßmus 
117*5b38b945SFranck LeCodeur 	int sign = (f2i.intValue & 0x80000000) >> 31;
118*5b38b945SFranck LeCodeur 	int exponent = ((f2i.intValue & 0x7f800000) >> 23) - 127;
119*5b38b945SFranck LeCodeur 	int mantissa = f2i.intValue & 0x007fffff;
120fb07ece0SStephan Aßmus 
121fb07ece0SStephan Aßmus 	if (exponent >= 32 || exponent < -32) {
122fb07ece0SStephan Aßmus 		uint8 zero = 0;
123fb07ece0SStephan Aßmus 		return buffer.Write(zero) && buffer.Write(zero)
124fb07ece0SStephan Aßmus 			&& buffer.Write(zero);
125fb07ece0SStephan Aßmus 	}
126fb07ece0SStephan Aßmus 
127fb07ece0SStephan Aßmus 	int shortValue = (sign << 23)
128fb07ece0SStephan Aßmus 					 | ((exponent + 32) << 17)
129fb07ece0SStephan Aßmus 					 | (mantissa >> 6);
130fb07ece0SStephan Aßmus 
131fb07ece0SStephan Aßmus 	return buffer.Write((uint8)(shortValue >> 16))
132fb07ece0SStephan Aßmus 		&& buffer.Write((uint8)((shortValue >> 8) & 0xff))
133fb07ece0SStephan Aßmus 		&& buffer.Write((uint8)(shortValue & 0xff));
134fb07ece0SStephan Aßmus }
135325a6253SAxel Dörfler 
13625dc253dSIngo Weinhold 
13725dc253dSIngo Weinhold _END_ICON_NAMESPACE
138