<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Storing (16, 24, 32)bpp bitmaps in binary files.</title>
		<link>http://www.allegro.cc/forums/view/588101</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Fri, 20 Oct 2006 20:26:11 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Due to the complexity of my game I have decided to create my own file format for graphic data storage.<br />I never did this before, so I want to begin with something simple.<br />I want to begin writing simple bitmaps to binary files.<br />Let&#39;s say I want to store 5 frames of a 100x100x16bpp bitmap in a binary file.<br />I guess I will need something like this:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">typedef</span> <span class="k1">struct</span> <span class="k2">{</span>
  <span class="k1">int</span> frame_number<span class="k2">;</span>
  <span class="k1">char</span> bytes<span class="k2">[</span><span class="n">10000</span><span class="k2">]</span><span class="k2">;</span>  <span class="c">/* How many bytes do I need to store a single pixel in 16bpp? */</span>
<span class="k2">}</span>my_frame<span class="k2">;</span>
</pre></div></div><p>

I want to LEARN how to deal whit this, so detailed explanation, theory,  and/or links will be accepted! thanks!<br />C only please.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Paul whoknows)</author>
		<pubDate>Wed, 18 Oct 2006 21:36:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I don&#39;t have one with me, but I use</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">typedef</span> <span class="k1">struct</span>
<span class="k2">{</span>
 <span class="k1">int</span> width<span class="k2">;</span>   <span class="c">//pixels, not bytes per line</span>
 <span class="k1">int</span> height<span class="k2">;</span>
 <span class="k1">int</span> color_depth<span class="k2">;</span> <span class="c">//in bytes, not bits per pixel</span>
 <span class="k1">int</span> rgba<span class="k2">;</span>        <span class="c">//set to 1 for rgba (when color_depth == 4) or 0 for bgra</span>
 <span class="k1">int</span> version<span class="k2">;</span>     <span class="c">//very helpful when you change this struct!</span>
<span class="k2">}</span>TEXHEADER<span class="k2">;</span>
</pre></div></div><p>

so size of image data is width*height*color_depth.  You could also have another int for how many bytes past TEXHEADER the actual pixel data starts to make room for variable sized comment strings or something.</p><p>I just seen you want 5 frames, maybe add yet another int for how many times the pixel data is repeated?</p><p>[EDIT] I just remembered that the color_depth doesn&#39;t discriminate between 15/16 bits per pixel, but I don&#39;t use 15, or 8 for that matter.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Arthur Kalliokoski)</author>
		<pubDate>Wed, 18 Oct 2006 23:03:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks very much!<br />Another int added for frames, just like you said, but to make life easier I won&#39;t allow different size frames...just for now.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">typedef</span> <span class="k1">struct</span>
<span class="k2">{</span>
 <span class="k1">int</span> width<span class="k2">;</span>   <span class="c">//pixels, not bytes per line</span>
 <span class="k1">int</span> height<span class="k2">;</span>
 <span class="k1">int</span> color_depth<span class="k2">;</span> <span class="c">//in bytes, not bits per pixel</span>
 <span class="k1">int</span> rgba<span class="k2">;</span>        <span class="c">//set to 1 for rgba (when color_depth == 4) or 0 for bgra</span>
 <span class="k1">int</span> version<span class="k2">;</span>     <span class="c">//very helpful when you change this struct!</span>
 <span class="k1">int</span> frames<span class="k2">;</span>    <span class="c">//amount of frames  </span>
<span class="k2">}</span>TEXHEADER<span class="k2">;</span>
</pre></div></div><p>

So the header should look like this:<br /><sup>
<tt>	
0000	Width
0001
0002
0003

0004	Height
0005
0006
0007

0008	color depth
0009
000A
000B

000C	rgba
000D
000E
000F

0010	version
0011
0012
0013

0014	frames 
0015
0016
0017

0018 Begin of data
.
.


</tt>
</sup></p><p>I don&#39;t understand the rgba flag, what&#39;s the diference between bgra or rgba? <br />I am not sure about how I should store my bytes, little or big endian???
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Paul whoknows)</author>
		<pubDate>Wed, 18 Oct 2006 23:56:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Assuming for OpenGL:</p><p>rgba vs. bgra is the order the red, blue, green values are stored, Windows uses bgr and I&#39;ve read on an Nvidia page that they&#39;ve optimized bgr as opposed to rgb due to Windows.  Some older cards may not handle the bgr order, check the flags.  If you&#39;re worried about porting to other cpu&#39;s, you could either store/load the bytes individually or (probably faster) swap them around after loading from disk.  I haven&#39;t had a big-endian computer (well, Motorola 8 bit doesn&#39;t <u>have</u> an endianness) but</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">union</span>
<span class="k2">{</span>
 <span class="k1">int</span> a<span class="k2">;</span>
 <span class="k1">char</span> b<span class="k2">[</span><span class="n">4</span><span class="k2">]</span><span class="k2">;</span>
<span class="k2">}</span>endian<span class="k2">;</span>

<span class="k1">int</span> is_small_endian <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>

endian.a <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
is_small_endian <span class="k3">=</span> endian.b<span class="k2">[</span><span class="n">3</span><span class="k2">]</span><span class="k2">;</span>  <span class="c">//little endian would set b[0]</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Arthur Kalliokoski)</author>
		<pubDate>Thu, 19 Oct 2006 00:10:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="source-code snippet"><div class="inner"><pre><span class="p">#define POST_PACKED __attribute__((packed))</span>

<span class="k1">struct</span> TEXHEADER
<span class="k2">{</span>
 int32_t width<span class="k2">;</span>   <span class="c">//pixels, not bytes per line</span>
 int32_t height<span class="k2">;</span>
 int32_t color_depth<span class="k2">;</span> <span class="c">//in bytes, not bits per pixel</span>
 int32_t rgba<span class="k2">;</span>        <span class="c">//set to 1 for rgba (when color_depth == 4) or 0 for bgra</span>
 int32_t version<span class="k2">;</span>     <span class="c">//very helpful when you change this struct!</span>
 int32_t frames<span class="k2">;</span>    <span class="c">//amount of frames  </span>
<span class="k2">}</span> POST_PACKED<span class="k2">;</span>
</pre></div></div><p>
<b>Now</b> you&#39;re rollin.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Thu, 19 Oct 2006 00:35:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That doesn&#39;t actually change the size of the struct in question (try a sizeof on it both ways, on any platform gcc supports today), and it breaks compatibility with some compilers.  </p><p>edit: okay, I&#39;m just whining pointlessly; the #define could be #ifdefed to something equivalent on another compiler to improve compatibility, and while packing it doesn&#39;t change this <b>particular</b> struct, it is vaguely appropriate for structs corresponding to formats on disk.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (orz)</author>
		<pubDate>Thu, 19 Oct 2006 02:04:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">union</span>
<span class="k2">{</span>
 <span class="k1">int</span> a<span class="k2">;</span>
 <span class="k1">char</span> b<span class="k2">[</span><span class="n">4</span><span class="k2">]</span><span class="k2">;</span>
<span class="k2">}</span>endian<span class="k2">;</span>
</pre></div></div><p>
</p></div></div><p>

That&#39;s amazing! really useful, thanks! </p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
#define POST_PACKED __attribute__((packed))
</p></div></div><p>

Dustin I don&#39;t know what are you doing here, please can you comment it?<br />I do never use structs, I use typedefs structs instead, something wrong with that?<br />Problems with ifferent size of ints isn&#39;t a problem right now, but perhaps this would be a better alternative:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">typedef</span> <span class="k1">struct</span>
<span class="k2">{</span>
 <span class="c">/* width */</span>
 <span class="k1">char</span> width<span class="k2">[</span><span class="n">4</span><span class="k2">]</span><span class="k2">;</span>
 <span class="k1">char</span> height<span class="k2">[</span><span class="n">4</span><span class="k2">]</span><span class="k2">;</span>
.
.
. <span class="k1">and</span> so on
</pre></div></div><p>
EDITED!!!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Paul whoknows)</author>
		<pubDate>Thu, 19 Oct 2006 05:32:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Dustin I don&#39;t know what are you doing here, please can you comment it?<br />I do never use structs, I use typedefs structs instead, something wrong with that?<br />Problems with ifferent size of ints isn&#39;t a problem right now, but perhaps this would be a better alternative:
</p></div></div><p>
If you&#39;re going to be accessing the data of a struct manually, then specify the packed option.  Don&#39;t do it and the god of coding karma will strike you down.</p><p>You might as well just use the struct name, unless you&#39;re trying to conform to an old C standard.  typedef went out of style decades ago.</p><p>Different sized ints are always a problem.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Thu, 19 Oct 2006 07:19:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
if you&#39;re going to be accessing the data of a struct manually, then specify the packed option. Don&#39;t do it and the god of coding karma will strike you down.
</p></div></div><p>
The keyword <u>_attribute</u>_ doesn&#39;t exist in my Borland 5.0 compiler! is that ANSI C supported?</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
You might as well just use the struct name, unless you&#39;re trying to conform to an old C standard.
</p></div></div><p>

Like I said at the beginning of this post I am using C.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Paul whoknows)</author>
		<pubDate>Thu, 19 Oct 2006 07:59:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
The keyword <u>_attribute</u>_ doesn&#39;t exist in my Borland 5.0 compiler! is that ANSI C supported?
</p></div></div><p>
It&#39;s gcc-only.  There are equivalents in most compilers though.  I don&#39;t know about Borland.  Try looking up &quot;packing&quot; or &quot;alignment&quot;, or anything about controlling the actual layout of structure members in memory in any docs you have.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (orz)</author>
		<pubDate>Thu, 19 Oct 2006 08:59:05 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Isn&#39;t packing only relevant when you directly write the struct to disk? I thikn it&#39;s better to simply write the fields one after another insteda of all of them at the same time.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ron Ofir)</author>
		<pubDate>Fri, 20 Oct 2006 19:10:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Isn&#39;t packing only relevant when you directly write the struct to disk?
</p></div></div><p>Pretty much.  It can effect the size of the struct in memory as well, but that&#39;s not usually important.  </p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I thikn it&#39;s better to simply write the fields one after another insteda of all of them at the same time.
</p></div></div><p>Some people find it easier to code / maintain / examine / debug / etc to let that happen automatically in a single fwrite call or whatever.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (orz)</author>
		<pubDate>Fri, 20 Oct 2006 19:35:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Some people find it easier to code / maintain / examine / debug / etc to let that happen automatically in a single fwrite call or whatever.
</p></div></div><p>And now you have endian dependant files. Not as important as it once was, but if you ever want those images to load properly on a BigEndian machine, never write the struct directly.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Fri, 20 Oct 2006 20:03:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
And now you have endian dependant files. Not as important as it once was, but if you ever want those images to load properly on a BigEndian machine, never write the struct directly.
</p></div></div><p>
Some people use the structs with endian-independant integer types (ie plain ints on one endianness, #ifdefed to classes that emulate non-native endiannes ints on the other endianness).  Not a very popular practice admittedly, but I know a few.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (orz)</author>
		<pubDate>Fri, 20 Oct 2006 20:19:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The &quot;best&quot; (IMO) method is just to store and read the ints in a single endian, and convert to the proper endian on load (if needed).</p><p>for example, you can use:
</p><div class="source-code snippet"><div class="inner"><pre><span class="c">// set 1</span>
<a href="http://www.allegro.cc/manual/pack_igetw" target="_blank"><span class="a">pack_igetw</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <a href="http://www.allegro.cc/manual/pack_iputw" target="_blank"><span class="a">pack_iputw</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <span class="c">// 16 bit</span>
<a href="http://www.allegro.cc/manual/pack_igetl" target="_blank"><span class="a">pack_igetl</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <a href="http://www.allegro.cc/manual/pack_iputl" target="_blank"><span class="a">pack_iputl</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <span class="c">// 32 bit</span>

<span class="c">// set 2</span>
<a href="http://www.allegro.cc/manual/pack_mgetw" target="_blank"><span class="a">pack_mgetw</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <a href="http://www.allegro.cc/manual/pack_mputw" target="_blank"><span class="a">pack_mputw</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/pack_mgetl" target="_blank"><span class="a">pack_mgetl</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <a href="http://www.allegro.cc/manual/pack_mputl" target="_blank"><span class="a">pack_mputl</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

Use one or the other, and your ints will be properly saved and loaded, without having to worry about endianess.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Fri, 20 Oct 2006 20:26:11 +0000</pubDate>
	</item>
</rss>
