B.E. (Comp. Sys. Eng.)
also known as zed
& handle of notzed
Well that was a busy weekend. I started each morning pretty slowly almost wanting to just stay inside all day but ended up a solid 5 hours each day in the yard and then some at night. Did some grocery shopping in two trips on the deadly and finally got some hay fever pills. Pruned the roses (a little late - they were already flowering again) and re-staked most of them. Stacked up the dismantled shed more neatly. Took down the last beam of the old verandah. Levelled off the shed site better. Broke a rake. Shifted 15 barrow loads of earth out of the way. Cleaned and rolled up the old sun-blind from the verandah. Sprayed the weeds. Sprayed the roses with fungicide. Cleaned and sanitised 40 longnecks. Bottled some homebrew, started a new homebrew. Baked some bread (getting quite good at that). Ripped a few heads off in God Of War 3 ...
No time or energy left for hacking. Although with the sunlight hours extending my sleep patterns are going crazy. Up early, then not tired till very late, then sleeping in and visa versa.
Last week I was looking up algorithms on the net and finally got fed up with google only showing cloaked paywall websites. I tried yahoo! (ugh, bing!) again (I usually end up doing this) and found as usual that it went more directly to the papers when they were available freely. I'll have to keep that in mind next time - it's just too time consuming finding stuff using google and resorting to google scholar is a bit hit and miss and more of a pain. Damn I wish my maths was better though - ever since matric i had trouble with differential calculus and I could really use it now.
Was having a generally brain-dead week anyway, every new bit of code I wrote seemed to be more broken than the last - after slowing down a bit I lost the knack for a bit. The hayfever hasn't been helping either.
And then there was none
Should've been working today but I was feeling very agitated and couldn't concentrate ... I borrowed a ladder yesterday so I thought I'd just take a couple of sheets of plastic off of the verandah ...
Except once I got going I couldn't stop. Ladder was pretty shaky to start with - I first tried to go up to the highest spot but it was just too much and I had to come down again. For reference the sliding doors are about 2100mm or 7' tall. But by the end I was walking down forwards carrying a few tools at the same time.
Now just a few dyna-bolts to take out for the end plank and it's done. Guy's coming to do the final measure tomorrow so i'll see what he has to say about a few mistakes I might've made - like some of the retaining wall and if I have to take out the palm tree or the rear fence ...
Although now without a verandah I think it's about to rain - might wash away some of the dust anyway.
Super Affine Tool Thing
Quite a bit of progress on ImageZ over the last few nights. Didn't get a lot done in the yard over the weekend - a visitor on Saturday and I was lazy today but I got a couple of hours of gardening in - mowed the lawns, transplanted some rhyzomes from the patch of grass i have to the patch of non-grass I don't want, weeded one of the vegetable patches and shifted most of my pots out of the way ready for more work readying the yard.
Fixed up a few issues with using non-pre-multiplied alpha, but only for normal blending mode - I know all the other blending modes are still doing it wrong.
Actually I can't really remember where I was at last time and how much i've done since then, it's all blurring into one long indistinct memory.
But I did work on what i've been calling a 'super affine tool'. It combines the various affine operations into a single tool in a way that should still be accessible.
A scaled, rotated and translated cat
I've been thinking about this for quite a while but finally sat down to nut it out. When you bring up the tool the following controls pop up in the middle of the image:
- Centre Disc
- This is the location of the image relative to the centre of the image. i.e. a simple translate.
- Inner Ring
- Sets the location of the rotation centre point on the source image.
- The two Parallelograms
- Adjust the shear in X or Y. The shapes move as you drag them in proportion to the shear amount.
- The two Rectangles
- Adjust the scaling in X or Y. The shapes scale as you drag the mouse in proportion to the scaling amount.
- Outer Ring
- Adjusts the rotation angle. Yes it probably needs some sort of indicator, although the moving image gives you that.
I'm still tweaking the affine transform matrix it produces to make it behave nicely. It applies the rotation, then the shear, scale and finally offset. This makes it behave mostly how you'd expect it to, although in some cases you'd have to run it multiple times to get exactly what you wanted. And it doesn't work properly if the view is zoomed ... and you can't actually commit the operation yet.
Damnation in hell Java is fast at this though - it must be accelerating it using the graphics card. I'm even using linear interpolation with alpha blending for the real-time preview and it's really nice and quick - at least when using one of the native layer types. Even a full-resolution image from my digital camera at 4288x2848 is flinging around at ~15-20fps.
I'm not entirely happy with the tool options on the left - there's a lot of numbers and spin buttons - but I guess it's not completely out of the question.
Actually I was also looking at putting tool options there which is why it's shown up there in the first place. But i'm not sure about that yet - if I do that then most tool options will really need to be per-image otherwise the behaviour will be a little odd. I'm not sure if this is desirable. For example if you set the tool to 'pen' you might reasonably expect it to be 'pen' on another window. Or maybe you might not - it probably doesn't matter either way.
I also had a good long dig at fixing some issues with the Amiga style menus. Basically some bugs(?) in the lightweight comboboxes were giving me nightmares. I was using an event listener on the glass pane to capture mouse button events. But the problem is when you do that you end up having to re-route the mouse events manually! I did manage to get that working quite well over the last few weeks except for the combo boxes. If you hold down the button and drag when selecting a combobox item it works fine, but if you click twice it doesn't! I eventually found similar discussions in the java forums and adopted a new version which just attaches a low-level event listener instead and simply snarfs the menu-button event. It reduces some of the flexibility I might have had in say allowing context menus as well, although I can probably hack that if required. But now the menu works reliably and doesn't interfere with the rest of the application. It's probably something that would be turned off if you wanted to use a Macintosh since that separates menus from windows already, but that is of no concern to me.
Finally the rain stopped
What a shit weekend, although at least I didn't get flooded out or anything.
Spent the whole weekend hacking on ImageZ ... although mostly hacking it to bits and making myself grumpy. I decided that obviously storing images as pre-multiplied alpha wasn't going to cut it for the integer types, so I converted the code to store using non-pre-multiplied alpha but blend to the target using pre-multiplied alpha. Straightforward (once i got the damn equations right) except for the common case where the tool layer is blended to the target layer first. God what a headache that was.
Also played with adding tool markers for things like editing the selection. For that I'm using Piccolo2d. Probably a bit of overkill but it'll let me do whatever I need for tool controls and it's easy as pie to use. It was also easy to connect up to the main window. I would also like to eventually use it for structured layers ... although I'm not sure how doable that will be since the layers are not rendered as normal components. It did throw a spanner in the works for the whole input event handling which I still haven't removed though.
And I got deeply into the image loader stuff. I was just loading into whatever ImageIO gave me and then copying across to a target layer but that doesn't scale terribly well and is pretty slow. I found out you can force it to write to a compatible type of image fairly easily (it doesn't have to match exactly the image type specifiers it gives you when queried) and is usually pretty fast. So I added yet another few more backend image types to support the common formats of images I work with and cleaned up the image loader to write directly to the target layers.
Finally I played with a translation tool which moves the origin of the layer. And that left a lot of crap to fix up which i'm sure I haven't finished yet. Everything from undo to painting broke in big or little ways.
I was hoping to just focus on a few polishing details for a while to clean up the whole thing and make it solid, stable and usable. But given how much I broke on the weekend that could be a long way off ... I had even started poking around looking for somewhere to put it, but i'm not sure I could be bothered with the approval process for Savannah, Google Code i'm not sure about since I seem to do everything on Google, and i'm not considering clitorous or github because git is offensive and the whole repository maintenance thing is a hassle I don't want to deal with. Tar is starting to look attractive.
Shed Be Gone
The council *FINALLY* came through with the approval for some building I'm doing around the house. Jesus, it only took them 10 months ... how shit is that. So given today wasn't drenching the yard with rain I thought i'd get cracking and start on some of the big tasks that need doing.
This spot is destined to be for a big shed ... so all that shit has to go, and the ground needs levelling off. And I want to kill that horrid huge ivy growing in the corner.
So I made pretty good progress today. I also loaded up the ivy with some glycophosphate which managed to kill most of the rest I have. Would've helped to have a hand but I managed doing it alone, although I might be sore in the morning. My foot was very sore last week and I don't think it was really healed enough so I'll probably aggravate that too which isn't a good thing :( Just got some tendonitis again and last time I had it that took a couple of weeks of doing almost nothing to get better. But the yard can't wait forever ... i'll have under 2 months to finish it off.
I'm surprised the yard was so relatively dry - we had over 40mm of rain over the weekend. And a shitload of wind but the house protects most of the yard from that.
I was in a weird state on the weekend, probably stressing about the yard more than anything (e.g. I think i put a retaining wall in the wrong place before I should have, so I may have to undo some ... which is an extreme amount of hassle) and for some reason I thought i'd see how easy this blog was to find. Not very it seems, at least with google. And obviously it is something only google is doing because it's on the first page of a search for 'notzed' on yahoo - maybe i swear too much or pick on google too much. I gave up trying to find it on google - the best I saw was a link to my 'blogger profile' on page 5. Given that Advogato was the first result I even considered re-starting to use that, but without pictures it's not much use and it seems pretty quiet on there. I went and reset Advogato anyway and might look at restarting the internode blog again and doing it all manually using static html (oh the shame!). It's not like comments are thick on the ground around here.
Kept plugging away and added options for new images and new layers at last.
Not all of the layer types work 100% yet, but they work for normal drawing and layer operations and PNG at least saves mono images as mono. I probably don't need them all there - I just did it because I could.
All the calculations and blending is just done in float RGBA so none of the code needed changing, although it does mean it's doing a lot of redundant work if the result is only monochrome.
Save Take 2 of 2
Had another stab at saving again today. Damn i forgot how tedious it is to try and make relatively nice looking GUI components, particularly when the layout toolkit seems to want to fight you at every stage ...
It's pretty basic but it should suffice for what I need. Actually this is the first post where I created the images using ImageZ itself, so it marks a bit of a milestone.
I haven't actually hooked up the comment stuff yet, but i've done it before and it's a matter of frobbing around with the metadata. Unfortunately it is in XML ...
I decided to leave in the RGBA support for JPEG files after reading the JPEG metadata specification for Java. Maybe nothing else will read them properly but it looks like Java will. But it defaults to flattening the image for JPEG files just to avoid confusion and i'll probably add a warning.
While doing testing I got really sick of the childish 'this file exists are you sure' crap (yeah no fucking shit sherlock!) and found I think a reasonable way to get rid of it. The file requester is used as normal to select the file to save to, and if you happen to select or enter a file that exists it just shows a warning in the bottom of the window and relabels the Save button to Overwrite. That's almost always what I want to do when I save over the same name. So the idea is not to interfere with typical use, but still let you back out if you truly made a mistake. Actually it lets you just type in a name from this window so you don't have to back out too far either.
I'm still not sure about the `Save Version' button here - the idea is that it will just create a name automatically if there is a clash. But I have a feeling that without filesystem multi-version support it's just a good way to lose what you're working on too easily.
Unfortunately behind the scenes there's still a load of rubbish to deal with such as keeping track of the meta-data from the image loading, transferring meta-data between formats, and so on.
But with this weather I might be spending a lot of time inside ... sigh, really cold, wet, windy, shitty weather. And I hurt my foot doing something I can't remember although it's getting better quickly because i'm giving it plenty of rest. Both are at quite inconvenient times, I finally got council approval for my shed and I still have a lot of work to do getting the yard ready - and soon will have a hard deadline in which to achieve it.
Had a poke at saving images tonight. I don't know where the damn day went but I only started looking at doing some hacking at 10pm tonight.
To start with I thought i'd skip any esoteric floating point formats or bothering with layers and just stick with the standard formats and trying to fit the images to suit. So about the best format is PNG with 16 bits per channel. It's a bit of a pigs breakfast but basically it scans the image to find the highest depth/format image in the layer stack and then starts trying to find an image writer for that format and just keeps dropping down to lower depth resolution until one works. e.g. it tries floats, then shorts, then bytes.
Well, things are a bit mixed ... to say the least.
PNG isn't too bad - it's saving as 16 bit per channel too - but JPEG does weird things. Actually I was surprised it even saved a 4 channel image - I expected it to fail. What's strange is that Java loads this weird 4 channel JPG just fine as an RGBA image but nothing else does. Java's in the wrong here I'm pretty sure?
Unfortunately the image writer interface doesn't let you find out what type of individual things the image format supports and all you can do is query if it supports writing a given complete format. I guess i'll just have to hardcode it for every format I will support - I suppose I need to anyway to handle the meta-data properly and stuff like compression options. The standard JRE doesn't support much anyway and besides I don't need to either. I suppose i'll use OpenRaster as the 'native' format, although TBH anything with XML and interoperability mentioned together just sounds like a nightmare.
Hmm, then there's all the state and metadata to muck about with from inside the app. Oh wont that be fun.
Storing everything as RGBA also complicates matters ... although I can cheat a bit and put options on the per-format requester for target bit depth & channels saved.
I got a fufut.
I had a go at porting Apple's OpenCL FFT to JOCL and coming up with a simple demo to add to the JOCL demo project.
Rotated image from previous post with rotated motion blur. The image on the left is used to generate the convolution kernel.
So here's a screenshot of a 'blur tool thing' I came up with. Because of screen-size I forced it to only process a 512x512 image, but even at 1024x1024 it does the convolution as fast as the mouse can send events (the raw gpu time for a 1024x1024 convolution is about 1200uS per plane, excluding data conversion). I had previously written a separable convolution for OpenCL and this is about on par with the 63x63 convolution processing time - but isn't limited to separable convolutions or small kernels (e.g. no rotation like above). Does take somewhat more processing to build the kernel though since it's the same size as the image but that's something easily off-loaded to the GPU as well.
Copyright (C) 2019 Michael Zucchi, All Rights Reserved.
Powered by gcc & me!