<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Mac OS X Image Loader Issue (5.0.2.1)</title>
		<link>http://www.allegro.cc/forums/view/607213</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 04 May 2011 21:51:59 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ve noticed that on the OS X port the function <span class="source-code"><a href="http://www.allegro.cc/manual/al_load_bitmap_f"><span class="a">al_load_bitmap_f</span></a><span class="k2">(</span><span class="k2">)</span></span> is not completely implemented. It currently reads in the entire file, making it not work with my custom formats. Often I will have a PNG or set of PNGs embedded in a larger file and with the current native image loader all data past the first embedded image is skipped, causing my loaders to break.</p><p>Are there any plans to fix this? If not it would be good to mention somewhere that this functionality is broken in the native image loader so someone what wants to use it on OS X will know to turn <tt>WANT_NATIVE_IMAGE_LOADER</tt> off.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Todd Cope)</author>
		<pubDate>Wed, 04 May 2011 04:32:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m not sure I understand what the problem is and so I&#39;m not sure what to suggest (but if you&#39;re putting multiple resources in a single file, the proper way to deal with that is to write an I/O interface for it, but the easiest thing to do is go through PhysFS).<br />However, if there&#39;s a problem and you have a way to fix it, we gladly accept patches.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Wed, 04 May 2011 05:17:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I think we were supposed to add subfile or &quot;chunk&quot; support at some point to deal with that sort of use case. I thought Matthew or Peter had worked on it at some point.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Wed, 04 May 2011 05:35:15 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ah, ok. Probably not for the OS X native loader then. Not sure how to implement this there, but yes, this should be done then.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Wed, 04 May 2011 05:43:16 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Here&#39;s what one of my custom format loaders looks like:
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>T3F_ANIMATION <span class="k3">*</span> t3f_load_animation_f<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_FILE"><span class="a">ALLEGRO_FILE</span></a> <span class="k3">*</span> fp<span class="k2">)</span>
<span class="number">  2</span><span class="k2">{</span>
<span class="number">  3</span>  T3F_ANIMATION <span class="k3">*</span> ap<span class="k2">;</span>
<span class="number">  4</span>  <span class="k1">int</span> i<span class="k2">;</span>
<span class="number">  5</span>  <span class="k1">char</span> header<span class="k2">[</span><span class="n">12</span><span class="k2">]</span>  <span class="k3">=</span> <span class="k2">{</span><span class="n">0</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  6</span>
<span class="number">  7</span>  <a href="http://www.allegro.cc/manual/al_fread"><span class="a">al_fread</span></a><span class="k2">(</span>fp, header, <span class="n">12</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  8</span>  <span class="k1">if</span><span class="k2">(</span><span class="k3">!</span>check_header<span class="k2">(</span>header<span class="k2">)</span><span class="k2">)</span>
<span class="number">  9</span>  <span class="k2">{</span>
<span class="number"> 10</span>    <span class="k1">return</span> NULL<span class="k2">;</span>
<span class="number"> 11</span>  <span class="k2">}</span>
<span class="number"> 12</span>  
<span class="number"> 13</span>  ap <span class="k3">=</span> t3f_create_animation<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 14</span>  <span class="k1">if</span><span class="k2">(</span>ap<span class="k2">)</span>
<span class="number"> 15</span>  <span class="k2">{</span>
<span class="number"> 16</span>    ap-&gt;bitmaps <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_fread16le"><span class="a">al_fread16le</span></a><span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 17</span>    <span class="k1">for</span><span class="k2">(</span>i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> ap-&gt;bitmaps<span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
<span class="number"> 18</span>    <span class="k2">{</span>
<span class="number"> 19</span>      ap-&gt;bitmap<span class="k2">[</span>i<span class="k2">]</span> <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_load_bitmap_f"><span class="a">al_load_bitmap_f</span></a><span class="k2">(</span>fp, <span class="s">".png"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 20</span>      <span class="k1">if</span><span class="k2">(</span><span class="k3">!</span>ap-&gt;bitmap<span class="k2">[</span>i<span class="k2">]</span><span class="k2">)</span>
<span class="number"> 21</span>      <span class="k2">{</span>
<span class="number"> 22</span>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"failed to load bitmap %d\n"</span>, i<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 23</span>      <span class="k2">}</span>
<span class="number"> 24</span>    <span class="k2">}</span>
<span class="number"> 25</span>    ap-&gt;frames <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_fread16le"><span class="a">al_fread16le</span></a><span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 26</span>    <span class="k1">for</span><span class="k2">(</span>i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> ap-&gt;frames<span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
<span class="number"> 27</span>    <span class="k2">{</span>
<span class="number"> 28</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span> <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_551.html" target="_blank">malloc</a><span class="k2">(</span><span class="k1">sizeof</span><span class="k2">(</span>T3F_ANIMATION_FRAME<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 29</span>      <span class="k1">if</span><span class="k2">(</span><span class="k3">!</span>ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k2">)</span>
<span class="number"> 30</span>      <span class="k2">{</span>
<span class="number"> 31</span>        <span class="k1">return</span> NULL<span class="k2">;</span>
<span class="number"> 32</span>      <span class="k2">}</span>
<span class="number"> 33</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>bitmap <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_fread16le"><span class="a">al_fread16le</span></a><span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 34</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>x <span class="k3">=</span> t3f_fread_float<span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 35</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>y <span class="k3">=</span> t3f_fread_float<span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 36</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>z <span class="k3">=</span> t3f_fread_float<span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 37</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>width <span class="k3">=</span> t3f_fread_float<span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 38</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>height <span class="k3">=</span> t3f_fread_float<span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 39</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>angle <span class="k3">=</span> t3f_fread_float<span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 40</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>ticks <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_fread32le"><span class="a">al_fread32le</span></a><span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 41</span>      ap-&gt;frame<span class="k2">[</span>i<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>flags <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_fread32le"><span class="a">al_fread32le</span></a><span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 42</span>    <span class="k2">}</span>
<span class="number"> 43</span>    ap-&gt;flags <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_fread32le"><span class="a">al_fread32le</span></a><span class="k2">(</span>fp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 44</span>  <span class="k2">}</span>
<span class="number"> 45</span>  t3f_animation_build_frame_list<span class="k2">(</span>ap<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 46</span>  <span class="k1">return</span> ap<span class="k2">;</span>
<span class="number"> 47</span><span class="k2">}</span>
</div></div><p>
This works perfectly with the Allegro image loaders but fails on the OS X native loader (haven&#39;t tried the Windows native loader). I already looked at the code for the native loader and I can&#39;t see any obvious way to fix it. It would require knowing the size of the embedded image file ahead of time and there&#39;s no way of knowing that without adding some extra code to read to the end of the image. I didn&#39;t see anything in the CGImage API that would be useful for this.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Todd Cope)</author>
		<pubDate>Wed, 04 May 2011 07:09:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607213/916101#target">Todd Cope</a> said:</div><div class="quote"><p>I already looked at the code for the native loader and I can&#39;t see any obvious way to fix it. It would require knowing the size of the embedded image file ahead of time and there&#39;s no way of knowing that without adding some extra code to read to the end of the image. I didn&#39;t see anything in the CGImage API that would be useful for this.</p></div></div><p>
That&#39;s what I was afraid of.<br />Is it possible to figure out after the fact and seek to that location in the file?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Wed, 04 May 2011 07:12:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You will need to record the size of the PNG file within the larger file. Then you may read the number of bytes into a buffer, wrap it with [al_open_memfile] and load the image from the memfile.</p><p>The planned chunk functionality would be slightly more efficient because you wouldn&#39;t need to read the data into a temporary buffer. No one&#39;s working on it right now.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Peter Wang)</author>
		<pubDate>Wed, 04 May 2011 07:24:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607213/916101#target">Todd Cope</a> said:</div><div class="quote"><p> This works perfectly with the Allegro image loaders 
</p></div></div><p>It is not guaranteed to work, so there&#39;s nothing to fix on OS X.</p><p>I wrote slice code that should be sufficient for what you are doing. If I can find it, I&#39;ll post it later. It looks something like:
</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/ALLEGRO_FILE"><span class="a">ALLEGRO_FILE</span></a> <span class="k3">*</span>slice <span class="k3">=</span> al_open_slice<span class="k2">(</span>fp, size, flags<span class="k2">)</span><span class="k2">;</span>
ap-&gt;bitmap<span class="k2">[</span>i<span class="k2">]</span> <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_load_bitmap_f"><span class="a">al_load_bitmap_f</span></a><span class="k2">(</span>slice, <span class="s">".png"</span><span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/al_fclose"><span class="a">al_fclose</span></a><span class="k2">(</span>slice<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
The size is still sometimes necessary because some loaders might do a <span class="source-code">SEEK_END</span>, and we cannot control what the OS loaders do.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Leverton)</author>
		<pubDate>Wed, 04 May 2011 08:28:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That&#39;s what I was looking into but I can&#39;t see any way to know how much data the CGImage function actually used to load the image file.</p><p>There might be a way to get the size after the fact and seek to where we need to be. I don&#39;t know if it would work but maybe this would help:
</p><div class="source-code snippet"><div class="inner"><pre>NSImage <span class="k3">*</span>image <span class="k3">=</span> NSImageFromAllegroBitmap<span class="k2">(</span>bmp<span class="k2">)</span><span class="k2">;</span>
NSArray <span class="k3">*</span>reps <span class="k3">=</span> <span class="k2">[</span>image representations<span class="k2">]</span><span class="k2">;</span>
NSData <span class="k3">*</span>nsdata <span class="k3">=</span> <span class="k2">[</span>NSBitmapImageRep representationOfImageRepsInArray: reps usingType: type properties: nil<span class="k2">]</span><span class="k2">;</span>
<span class="k1">size_t</span> size <span class="k3">=</span> <span class="k2">(</span><span class="k1">size_t</span><span class="k2">)</span><span class="k2">[</span>nsdata length<span class="k2">]</span><span class="k2">;</span>
</pre></div></div><p>

This is how image saving works so maybe we could do something like this:
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">   1</span><span class="k1">static</span> <a href="http://www.allegro.cc/manual/ALLEGRO_BITMAP"><span class="a">ALLEGRO_BITMAP</span></a> <span class="k3">*</span>really_load_image<span class="k2">(</span><span class="k1">char</span> <span class="k3">*</span>buffer, <span class="k1">const</span> <span class="k1">char</span> <span class="k3">*</span> ident, <span class="k1">int</span> <span class="k3">*</span>size<span class="k2">)</span>
<span class="number">   2</span><span class="k2">{</span>
<span class="number">   3</span>   <a href="http://www.allegro.cc/manual/ALLEGRO_BITMAP"><span class="a">ALLEGRO_BITMAP</span></a> <span class="k3">*</span>bmp <span class="k3">=</span> NULL<span class="k2">;</span>
<span class="number">   4</span>   <span class="k1">void</span> <span class="k3">*</span>pixels <span class="k3">=</span> NULL<span class="k2">;</span>
<span class="number">   5</span>   <span class="c">/* Note: buffer is now owned (and later freed) by the data object. */</span>
<span class="number">   6</span>   NSData <span class="k3">*</span>nsdata <span class="k3">=</span> <span class="k2">[</span>NSData dataWithBytesNoCopy:buffer length:size<span class="k2">]</span><span class="k2">;</span>
<span class="number">   7</span>   NSImage <span class="k3">*</span>image <span class="k3">=</span> <span class="k2">[</span><span class="k2">[</span>NSImage alloc<span class="k2">]</span> initWithData:nsdata<span class="k2">]</span><span class="k2">;</span>
<span class="number">   8</span>   <span class="k1">bool</span> premul <span class="k3">=</span> <span class="k3">!</span><span class="k2">(</span><a href="http://www.allegro.cc/manual/al_get_new_bitmap_flags"><span class="a">al_get_new_bitmap_flags</span></a><span class="k2">(</span><span class="k2">)</span> <span class="k3">&amp;</span> ALLEGRO_NO_PREMULTIPLIED_ALPHA<span class="k2">)</span><span class="k2">;</span>
<span class="number">   9</span>   <span class="c">/* get the size to pass back to the caller so we can seek to the right place */</span>
<span class="number">  10</span>   NSBitmapImageFileType type<span class="k2">;</span>
<span class="number">  11</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span>ident, <span class="s">".bmp"</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  12</span>      type <span class="k3">=</span> NSBMPFileType<span class="k2">;</span>
<span class="number">  13</span>   <span class="k2">}</span>
<span class="number">  14</span>   <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span>ident, <span class="s">".jpg"</span><span class="k2">)</span> <span class="k3">|</span><span class="k3">|</span> <span class="k3">!</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span>ident, <span class="s">".jpeg"</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  15</span>      type <span class="k3">=</span> NSJPEGFileType<span class="k2">;</span>
<span class="number">  16</span>   <span class="k2">}</span>
<span class="number">  17</span>   <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span>ident, <span class="s">".gif"</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  18</span>      type <span class="k3">=</span> NSGIFFileType<span class="k2">;</span>
<span class="number">  19</span>   <span class="k2">}</span>
<span class="number">  20</span>   <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span>ident, <span class="s">".tif"</span><span class="k2">)</span> <span class="k3">|</span><span class="k3">|</span> <span class="k3">!</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span>ident, <span class="s">".tiff"</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  21</span>      type <span class="k3">=</span> NSTIFFFileType<span class="k2">;</span>
<span class="number">  22</span>   <span class="k2">}</span>
<span class="number">  23</span>   <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span>ident, <span class="s">".png"</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  24</span>      type <span class="k3">=</span> NSPNGFileType<span class="k2">;</span>
<span class="number">  25</span>   <span class="k2">}</span>
<span class="number">  26</span>   <span class="k1">else</span> <span class="k2">{</span>
<span class="number">  27</span>      <span class="k1">return</span> <span class="k1">false</span><span class="k2">;</span>
<span class="number">  28</span>   <span class="k2">}</span>
<span class="number">  29</span>   NSData <span class="k3">*</span>size_nsdata <span class="k3">=</span> <span class="k2">[</span>NSBitmapImageRep representationOfImageRepsInArray: reps usingType: type properties: nil<span class="k2">]</span><span class="k2">;</span>
<span class="number">  30</span>   <span class="k3">*</span>size <span class="k3">=</span> <span class="k2">(</span><span class="k1">int</span><span class="k2">)</span><span class="k2">[</span>size_nsdata length<span class="k2">]</span><span class="k2">;</span>
<span class="number">  31</span>
<span class="number">  32</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>image<span class="k2">)</span>
<span class="number">  33</span>      <span class="k1">return</span> NULL<span class="k2">;</span>
<span class="number">  34</span>
<span class="number">  35</span>   <span class="c">/* Get the image representations */</span>
<span class="number">  36</span>   NSArray <span class="k3">*</span>reps <span class="k3">=</span> <span class="k2">[</span>image representations<span class="k2">]</span><span class="k2">;</span>
<span class="number">  37</span>   NSImageRep <span class="k3">*</span>image_rep <span class="k3">=</span> <span class="k2">[</span>reps objectAtIndex: <span class="n">0</span><span class="k2">]</span><span class="k2">;</span>
<span class="number">  38</span>
<span class="number">  39</span>   <span class="c">// Note: Do we want to support this on OSX 10.5? It doesn't have</span>
<span class="number">  40</span>   <span class="c">// CGImageForProposedRect...</span>
<span class="number">  41</span>   <span class="c">//CGImageRef cgimage = [image_rep CGImageForProposedRect: nil context: nil hints: nil];</span>
<span class="number">  42</span>   
<span class="number">  43</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>image_rep<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  44</span>    <span class="k2">[</span>image release<span class="k2">]</span><span class="k2">;</span>
<span class="number">  45</span>      <span class="k1">return</span> NULL<span class="k2">;</span>
<span class="number">  46</span>   <span class="k2">}</span>
<span class="number">  47</span>
<span class="number">  48</span>   <span class="c">/* Get the actual size in pixels from the representation */</span>
<span class="number">  49</span>   <span class="k1">int</span> w <span class="k3">=</span> <span class="k2">[</span>image_rep pixelsWide<span class="k2">]</span><span class="k2">;</span>
<span class="number">  50</span>   <span class="k1">int</span> h <span class="k3">=</span> <span class="k2">[</span>image_rep pixelsHigh<span class="k2">]</span><span class="k2">;</span>
<span class="number">  51</span>
<span class="number">  52</span>   ALLEGRO_DEBUG<span class="k2">(</span><span class="s">"Read image of size %dx%d\n"</span>, w, h<span class="k2">)</span><span class="k2">;</span>
<span class="number">  53</span>
<span class="number">  54</span>   <span class="c">/* Now we need to draw the image into a memory buffer. */</span>
<span class="number">  55</span>   pixels <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_malloc"><span class="a">al_malloc</span></a><span class="k2">(</span>w <span class="k3">*</span> h <span class="k3">*</span> <span class="n">4</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  56</span>
<span class="number">  57</span>   CGFloat whitePoint<span class="k2">[</span><span class="n">3</span><span class="k2">]</span> <span class="k3">=</span> <span class="k2">{</span>
<span class="number">  58</span>      <span class="n">1</span>, <span class="n">1</span>, <span class="n">1</span>
<span class="number">  59</span>   <span class="k2">}</span><span class="k2">;</span>
<span class="number">  60</span>   CGFloat blackPoint<span class="k2">[</span><span class="n">3</span><span class="k2">]</span> <span class="k3">=</span> <span class="k2">{</span>
<span class="number">  61</span>      <span class="n">0</span>, <span class="n">0</span>, <span class="n">0</span>
<span class="number">  62</span>   <span class="k2">}</span><span class="k2">;</span>
<span class="number">  63</span>   CGFloat gamma<span class="k2">[</span><span class="n">3</span><span class="k2">]</span> <span class="k3">=</span> <span class="k2">{</span>
<span class="number">  64</span>      <span class="n">2</span>.<span class="n">2</span>, <span class="n">2</span>.<span class="n">2</span>, <span class="n">2</span>.<span class="n">2</span>
<span class="number">  65</span>   <span class="k2">}</span><span class="k2">;</span>
<span class="number">  66</span>   CGFloat matrix<span class="k2">[</span><span class="n">9</span><span class="k2">]</span> <span class="k3">=</span> <span class="k2">{</span>
<span class="number">  67</span>      <span class="n">1</span>, <span class="n">1</span>, <span class="n">1</span>,
<span class="number">  68</span>      <span class="n">1</span>, <span class="n">1</span>, <span class="n">1</span>,
<span class="number">  69</span>      <span class="n">1</span>, <span class="n">1</span>, <span class="n">1</span>
<span class="number">  70</span>   <span class="k2">}</span><span class="k2">;</span>
<span class="number">  71</span>   <span class="c">/* This sets up a color space that results in identical values</span>
<span class="number">  72</span><span class="c">    * as the image data itself, which is the same as the standalone</span>
<span class="number">  73</span><span class="c">    * libpng loader</span>
<span class="number">  74</span><span class="c">    */</span>
<span class="number">  75</span>   CGColorSpaceRef colour_space <span class="k3">=</span>
<span class="number">  76</span>      CGColorSpaceCreateCalibratedRGB<span class="k2">(</span>
<span class="number">  77</span>         whitePoint, blackPoint, gamma, matrix
<span class="number">  78</span>      <span class="k2">)</span><span class="k2">;</span>
<span class="number">  79</span>   CGContextRef context <span class="k3">=</span> CGBitmapContextCreate<span class="k2">(</span>pixels, w, h, <span class="n">8</span>, w <span class="k3">*</span> <span class="n">4</span>,
<span class="number">  80</span>      colour_space,
<span class="number">  81</span>      kCGImageAlphaPremultipliedLast<span class="k2">)</span><span class="k2">;</span>
<span class="number">  82</span>      
<span class="number">  83</span>   <span class="k2">[</span>NSGraphicsContext saveGraphicsState<span class="k2">]</span><span class="k2">;</span>
<span class="number">  84</span>   <span class="k2">[</span>NSGraphicsContext setCurrentContext:<span class="k2">[</span>NSGraphicsContext
<span class="number">  85</span>      graphicsContextWithGraphicsPort:context flipped:NO<span class="k2">]</span><span class="k2">]</span><span class="k2">;</span>
<span class="number">  86</span>   <span class="k2">[</span>image drawInRect:NSMakeRect<span class="k2">(</span><span class="n">0</span>, <span class="n">0</span>, w, h<span class="k2">)</span>
<span class="number">  87</span>      fromRect:NSZeroRect
<span class="number">  88</span>      operation <span class="k2">:</span> NSCompositeCopy
<span class="number">  89</span>      fraction <span class="k2">:</span> <span class="n">1</span>.<span class="n">0</span><span class="k2">]</span><span class="k2">;</span>
<span class="number">  90</span>   <span class="k2">[</span>NSGraphicsContext restoreGraphicsState<span class="k2">]</span><span class="k2">;</span>
<span class="number">  91</span>   
<span class="number">  92</span>   <span class="c">//CGContextDrawImage(context, CGRectMake(0.0, 0.0, (CGFloat)w, (CGFloat)h),</span>
<span class="number">  93</span>   <span class="c">//   cgimage);</span>
<span class="number">  94</span>   CGContextRelease<span class="k2">(</span>context<span class="k2">)</span><span class="k2">;</span>
<span class="number">  95</span>   CGColorSpaceRelease<span class="k2">(</span>colour_space<span class="k2">)</span><span class="k2">;</span>
<span class="number">  96</span>   
<span class="number">  97</span>   <span class="k2">[</span>image release<span class="k2">]</span><span class="k2">;</span>
<span class="number">  98</span>
<span class="number">  99</span>   <span class="c">/* Then create a bitmap out of the memory buffer. */</span>
<span class="number"> 100</span>   bmp <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_create_bitmap"><span class="a">al_create_bitmap</span></a><span class="k2">(</span>w, h<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 101</span>   <span class="k1">if</span> <span class="k2">(</span>bmp<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 102</span>      <a href="http://www.allegro.cc/manual/ALLEGRO_LOCKED_REGION"><span class="a">ALLEGRO_LOCKED_REGION</span></a> <span class="k3">*</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_539.html" target="_blank">lock</a> <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_lock_bitmap"><span class="a">al_lock_bitmap</span></a><span class="k2">(</span>bmp,
<span class="number"> 103</span>            ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 104</span>      <span class="k1">int</span> i<span class="k2">;</span>
<span class="number"> 105</span>      <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>premul<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 106</span>         <span class="k1">int</span> x<span class="k2">;</span>
<span class="number"> 107</span>         <span class="k1">for</span> <span class="k2">(</span>i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> h<span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 108</span>            <span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span>src_ptr <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span><span class="k2">)</span>pixels <span class="k3">+</span> w <span class="k3">*</span> <span class="n">4</span> <span class="k3">*</span> i<span class="k2">;</span>
<span class="number"> 109</span>            <span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span>dest_ptr <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span><span class="k2">)</span>lock-&gt;data <span class="k3">+</span>
<span class="number"> 110</span>         lock-&gt;pitch <span class="k3">*</span> i<span class="k2">;</span>
<span class="number"> 111</span>            <span class="k1">for</span> <span class="k2">(</span>x <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> x <span class="k3">&lt;</span> w<span class="k2">;</span> x<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 112</span>               <span class="k1">unsigned</span> <span class="k1">char</span> r, g, b, a<span class="k2">;</span>
<span class="number"> 113</span>               r <span class="k3">=</span> <span class="k3">*</span>src_ptr<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
<span class="number"> 114</span>               g <span class="k3">=</span> <span class="k3">*</span>src_ptr<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
<span class="number"> 115</span>               b <span class="k3">=</span> <span class="k3">*</span>src_ptr<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
<span class="number"> 116</span>               a <span class="k3">=</span> <span class="k3">*</span>src_ptr<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
<span class="number"> 117</span>            <span class="c">// NOTE: avoid divide by zero by adding a fraction</span>
<span class="number"> 118</span>               <span class="k1">float</span> alpha_mul <span class="k3">=</span> <span class="n">255</span>.<span class="n">0f</span> <span class="k3">/</span> <span class="k2">(</span>a<span class="k3">+</span><span class="n">0</span>.<span class="n">001f</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 119</span>               r <span class="k3">*</span><span class="k3">=</span> alpha_mul<span class="k2">;</span>
<span class="number"> 120</span>               g <span class="k3">*</span><span class="k3">=</span> alpha_mul<span class="k2">;</span>
<span class="number"> 121</span>               b <span class="k3">*</span><span class="k3">=</span> alpha_mul<span class="k2">;</span>
<span class="number"> 122</span>               <span class="k3">*</span>dest_ptr<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> r<span class="k2">;</span>
<span class="number"> 123</span>               <span class="k3">*</span>dest_ptr<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> g<span class="k2">;</span>
<span class="number"> 124</span>               <span class="k3">*</span>dest_ptr<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> b<span class="k2">;</span>
<span class="number"> 125</span>               <span class="k3">*</span>dest_ptr<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> a<span class="k2">;</span>
<span class="number"> 126</span>            <span class="k2">}</span>
<span class="number"> 127</span>         <span class="k2">}</span>
<span class="number"> 128</span>      <span class="k2">}</span>
<span class="number"> 129</span>      <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 130</span>         <span class="k1">for</span> <span class="k2">(</span>i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> h<span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 131</span>            <a href="http://www.delorie.com/djgpp/doc/libc/libc_566.html" target="_blank">memcpy</a><span class="k2">(</span>lock-&gt;data <span class="k3">+</span> lock-&gt;pitch <span class="k3">*</span> i, pixels <span class="k3">+</span> w <span class="k3">*</span> <span class="n">4</span> <span class="k3">*</span> i, w <span class="k3">*</span> <span class="n">4</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 132</span>         <span class="k2">}</span>
<span class="number"> 133</span>      <span class="k2">}</span>
<span class="number"> 134</span>      <a href="http://www.allegro.cc/manual/al_unlock_bitmap"><span class="a">al_unlock_bitmap</span></a><span class="k2">(</span>bmp<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 135</span>   <span class="k2">}</span>
<span class="number"> 136</span>   <a href="http://www.allegro.cc/manual/al_free"><span class="a">al_free</span></a><span class="k2">(</span>pixels<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 137</span>   <span class="k1">return</span> bmp<span class="k2">;</span>
<span class="number"> 138</span><span class="k2">}</span>
</div></div><p>
This might work depending on how NSImage handles representations. If it spits back the exact data it read when you retrieve the representation it should work.</p><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607213/916109#target">Peter Wang</a> said:</div><div class="quote"><p>You will need to record the size of the PNG file within the larger file.</p></div></div><p>
Edit: I can&#39;t know the size of the PNG before recording it. I would have to write a temporary file, get the size, then rewrite the data into my own file.
</p><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607213/916120#target">Matthew Leverton</a> said:</div><div class="quote"><p>It is not guaranteed to work, so there&#39;s nothing to fix on OS X.</p></div></div><p>
Since the function exists and doesn&#39;t work then it needs to be fixed. There is no note of &quot;not gauranteed to work&quot; in the manual. If the al_load_*_f() functions are meant to be used with memfiles then it should be noted somewhere.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Todd Cope)</author>
		<pubDate>Wed, 04 May 2011 08:30:14 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>al_load_*_f are allowed to read as much data as they like (this is a documentation bug). Some file formats simply don&#39;t have a well defined end. TGA is one. I don&#39;t remember if PNG is one.</p><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607213/916122#target">Todd Cope</a> said:</div><div class="quote"><p>
I can&#39;t know the size of the PNG before recording it. I would have to write a temporary file, get the size, then rewrite the data into my own file.
</p></div></div><p>

That&#39;s what the packfiles in A4 does.  Other possibilities: write to a memory buffer first. Or reserve a few bytes, write the PNG, then seek back to the old location and fill in the length then.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Peter Wang)</author>
		<pubDate>Wed, 04 May 2011 11:09:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607213/916122#target">Todd Cope</a> said:</div><div class="quote"><p> Since the function exists and doesn&#39;t work then it needs to be fixed. There is no note of &quot;not gauranteed to work&quot; in the manual. If the al_load_*_f() functions are meant to be used with memfiles then it should be noted somewhere.
</p></div></div><p>They aren&#39;t meant to work only with memfiles, but they do require a full random access I/O interface that represents a single file.</p><p>The native loaders (that we didn&#39;t write and have no control over) might do something like <span class="source-code">seek<span class="k2">(</span>SEEK_SET, <span class="n">0</span><span class="k2">)</span></span> or <span class="source-code">seek<span class="k2">(</span>SEEK_END, <span class="n">16</span><span class="k2">)</span></span>. If you supply a pointer to a something that represents more than a single file, there&#39;s no way for Allegro to guarantee that it works. </p><p>I don&#39;t think the proper solution is to try to hack Allegro to work around those limitations in every single loader and saver (images, sounds, fonts, etc). Instead, file slices could be used over top any underlying interface.</p><p>I proposed (and partially implemented) something like:
</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/ALLEGRO_FILE"><span class="a">ALLEGRO_FILE</span></a> <span class="k3">*</span>slice <span class="k3">=</span> al_fopen_slice<span class="k2">(</span>fp, <span class="n">0</span>, <span class="s">"rw+"</span><span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/al_save_bitmap_f"><span class="a">al_save_bitmap_f</span></a><span class="k2">(</span>slice, <span class="s">".png"</span>, bmp<span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/al_fclose"><span class="a">al_fclose</span></a><span class="k2">(</span>slice<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
In this case, the slice is opened with an initial length of 0 for read (r) and write (w) and is expandable (+).</p><p>A slice is always opened up at the current position of the file. (Opening two slices on the same file at the same time is undefined.) When closing the slice, the original file is moved to the end of the slice.</p><p>I was also considering a &quot;memory buffer&quot; (m) option that would automatically store everything in memory so that it could be used for write only streams. For example:</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/ALLEGRO_FILE"><span class="a">ALLEGRO_FILE</span></a> <span class="k3">*</span>ftp_file <span class="k3">=</span> open_ftp_file<span class="k2">(</span><span class="s">"ftp://allegro.cc/foo.png"</span><span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/ALLEGRO_FILE"><span class="a">ALLEGRO_FILE</span></a> <span class="k3">*</span>slice <span class="k3">=</span> al_fopen_slice<span class="k2">(</span>ftp_file, <span class="n">0</span>, <span class="s">"mrw+"</span><span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/al_save_bitmap_f"><span class="a">al_save_bitmap_f</span></a><span class="k2">(</span>slice, <span class="s">".png"</span>, bmp<span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/al_fclose"><span class="a">al_fclose</span></a><span class="k2">(</span>slice<span class="k2">)</span><span class="k2">;</span> <span class="c">// memory buffer is flushed  </span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Leverton)</author>
		<pubDate>Wed, 04 May 2011 11:33:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607213/916145#target">Matthew Leverton</a> said:</div><div class="quote"><p>The native loaders (that we didn&#39;t write and have no control over) might do something like seek(SEEK_SET, 0) or seek(SEEK_END, 16). If you supply a pointer to a something that represents more than a single file, there&#39;s no way for Allegro to guarantee that it works.</p></div></div><p>
The docs should mention that the stream passed to the <span class="source-code">al_load_<span class="k3">*</span>_f<span class="k2">(</span><span class="k2">)</span></span> functions should represent a single file or else the behavior is undefined. Maybe even suggest using a memfile (or slices if those are implemented) so people can understand how to use them. I know I am not the only one who assumes you can just pass an open <span class="source-code"><a href="http://www.allegro.cc/manual/ALLEGRO_FILE"><span class="a">ALLEGRO_FILE</span></a></span> stream. I can see the writer of the OS X loader was assuming this, too, based on the comments in the code.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Todd Cope)</author>
		<pubDate>Wed, 04 May 2011 21:51:59 +0000</pubDate>
	</item>
</rss>
