JPG and PNG decoder
I've been working on decoders for simple (baseline) JPEG and PNG's, mostly for my own amusement, and they seem to work ok now, so if anyone has need of some simple D modules to load these formats you can grab them here: https://github.com/callumenator/imaged Notes: - Will load 8-bit baseline sequential JPEG's only. All PNG image types are supported (only critical chunks are decoded however). - Can load from a stream or a file. In the case of the PNG's, this allows progressive display with an interlaced image. - I haven't put much effort into speeding up these routines, and have not tested the JPEG decoder extensively, so there are bound to be bugs and there is plenty room for improvement. - The example shows stream usage, and uses Adam Ruppe's simpledisplay to make a little viewer, that can flick through all images in a directory. Cheers, cal
Re: JPG and PNG decoder
On Sunday, 17 June 2012 at 07:07:35 UTC, Philippe Sigaud wrote: Still, I'm interested in writing a JPEG/PNG to disk from a ubyte[3][][], or whatever. Do you mean that you want to encode a ubyte array to disk as JPEG/PNG? Encoding a JPEG would be a bit of work I think, the format's kind of a monster. PNG should be easier, depending on how good you want the compression to be. If you don't care too much about compression level, you simply zlib compress the data, write it out by image row/scanline, include appropriate header and chunk info, and you're done. I'll give a simple encoder a go if you think you could use it. Cheers, cal
Re: JPG and PNG decoder
On Sunday, 17 June 2012 at 12:15:36 UTC, bearophile wrote: Suggestions on the code: - Try to use final switches. - switch cases don't need (), so instead of case(foo): write case foo: - Try to add const/immutable/pure/nothrow where possible. Bye, bearophile Problem with final switches in this context is that images may be corrupt or badly encoded or something, which the decoder should just handle gracefully through a default I think, without crashing. The case statements though I will change, and though I have worlds of trouble with const-ness, I will endeavour to add those guarantees :) Thanks for looking through
Re: JPG and PNG decoder
On Sunday, 17 June 2012 at 12:35:41 UTC, David wrote: Cool so I don't need to use my stb_image binding ( https://bitbucket.org/dav1d/gl-utils/src/0b97f77c14d7/stb_image ) anylonger! I used stb_image with C++ opengl projects, and it was great. stb_truetype is another gem, I would love to write a truetype loader, but I think the payoff is not worth the effort given the freetype bindings.
Re: JPG and PNG decoder
On Sunday, 17 June 2012 at 23:17:54 UTC, Stewart Gordon wrote: You two should fuse it into one module, to give us loading/writing. That would be quite cool. I don't know how much of the code will need rewriting in order to support interlacing or all PNG colour types/depths. But I also began writing a PNG library a while back - with the intention that it will be a full PNG editing library, not just encoding/decoding of the image data. But I haven't had much time to work on it recently. And it would help a lot if we could have the replacement for std.stream some time soon. Stewart. I just pushed an update which implements a PNG encoder. It is implemented in the Image class as a write method. If you have a raw buffer, and want to encode it, you can do something like this: ubyte[] data = some data; Image img = new Img!(Px.R8G8B8)(width, height, data); img.write("mypng.png"); It uses adaptive filtering, and should work with the pixel formats supported by the image class (except for the 16 bit ones I've just realised). I've only tested it on images that I have previously loaded in however. Stewart, I used your makepng.d as a template for this, can I add you to the author list? Also, if preferred, I can keep the master branch as a single merged module, just let me know. Cheers, cal
Re: JPG and PNG decoder
On Thursday, 21 June 2012 at 17:58:47 UTC, Stewart Gordon wrote: On 18/06/2012 00:49, cal wrote: ubyte[] data = some data; Image img = new Img!(Px.R8G8B8)(width, height, data); Image? Img? img.write("mypng.png"); Image is the interface, Img the templated class that does all the work. It is parameterized by the pixel format. It may not be the best strategy (or naming scheme!) but enumerating the formats and templating based on that limited the number of cases I had to think about. Does it always take in a ubyte[], or does that depend on the bit depth? It currently just takes a ubyte, and doesn't do any rearranging of the array, so it will only work for 8-bit depths. If you had 4-bit greyscale tightly packed into your ubyte (two pixels per byte) then it would not be correctly interpreted, nor would 16 bit. The reason was I didn't want to have the Image class 'own' the passed-in array. If it did own it, then it would be free to unpack the smaller bit depths the way it does when decoding. I will fix this when I have time to think about it a bit more.
Re: NaNs Just Don't Get No Respect
On Monday, 20 August 2012 at 19:28:33 UTC, Peter Alexander wrote: On Sunday, 19 August 2012 at 22:22:28 UTC, Walter Bright wrote: > I find it more likely that the NaN will go unnoticed and > cause rare bugs. NaNs in your output are pretty obvious. For example, if your accounting program prints "NAN" for the amount on the payroll cheques, someone is guaranteed to notice. But if it's a few cents off in your disfavor, it might take you years to discover there's a problem. Critical systems also would find a NaN command a lot easier to detect than an off-by-two command, and would be able to shut down and engage the backup. The problem is that it's easy for even NaN's to be filtered out. float x = 0.0f; float y; // oops float z = min(x, y); // NaN has disappeared, unnoticed! My argument is that conservative compile time errors on uninitialised variables are more likely to catch these errors. I just tried this: float a, b = 10; writeln(min(a, b), ", ", fmin(a, b)); Result: nan, 10 I think that is incorrect - both should give NaN. The scientific viz software I use at work returns NaN for any numerical operation on NaN values, means, smoothing, etc.
Re: NaNs Just Don't Get No Respect
On Tuesday, 21 August 2012 at 08:15:10 UTC, Don Clugston wrote: No, it's the other way around. The IEEE 754 standard defines min(x, NaN) == min(NaN, x) == x. According to the C standard, fmin() should be returning 10, as well. There is a bug in fmin(). However min() and max() are extremely unusual in this respect. Almost everything else involving a NaN returns NaN. I did not know that. It seems like a not-so-useful rule but I guess they have their reasons. Note that in my example, fmin() _did_ return 10 - it was min() that returned NaN...
Re: gl3n - OpenGL Maths for D
On Friday, 31 August 2012 at 16:54:49 UTC, David wrote: Anything you miss? Matrix constructor for building projection matrices (I have a bit of code for doing this from near/far + FOV if you want it, but there are plenty examples on google). I've also found it useful to be able to set a given matrix column using a vector, I didn't see a function specifically for this (row-major makes it handy to have a dedicated function for this). Nice work!
Re: early alpha of D REPL
On Tuesday, 11 February 2014 at 11:33:53 UTC, thedeemon wrote: Have you seen Dabble? https://github.com/callumenator/dabble Just found out its author added Linux support. I was able to build an x86 version but it didn't work properly in a 64 bit system: it assumes dmd makes x86 binaries by default while it really makes 64-bit ones. And for 64 bits Dabble doesn't compile: as it often happens, it's too easy to forget that array.length is not always uint. I don't have a 64-bit tool-chain to play with, could submit those 64 bit build errors on github?
Re: early alpha of D REPL
On Wednesday, 12 February 2014 at 18:08:11 UTC, Martin Nowak wrote: For example it should be possible to call a function or inherit from a class that were defined earlier. Dabble allows both of these things, if I understand your comment correctly.
Re: early alpha of D REPL
On Tuesday, 11 February 2014 at 04:46:41 UTC, Martin Nowak wrote: Barely running but already fun and a little useful. Example: D> import std.algorithm, std.array, std.file; => std D> auto name(T)(T t) { | return t.name; | } => name D> dirEntries(".", SpanMode.depth).map!name.join(", ") => ./drepl_sandbox D> https://github.com/MartinNowak/drepl http://drepl.dawg.eu/ This approach with separate modules is far superior to what I did with dabble, and much simpler. My target was windows initially, where I guess this won't work currently. Hopefully the situation there will improve soon.