RISC OS Open
A fast and easily customised operating system for ARM devices
ROOL
Home | News | Downloads | Bugs | Bounties | Forum | Documents | Photos | Contact us
Account
Forums → Bounties →

PNG export bounty

Subscribe to PNG export bounty 24 posts, 11 voices

 
Apr 28, 2019 9:05pm
Avatar Adrian Lees (1349) 122 posts

Re this new bounty, a couple of comments: PNG supports only a single lossless compression format, and has no uncompressed representation, so the text should be revised. Also, I see little point writing a PNG encoder from scratch; libpng works well (although do remember to set PNG_IMAGE_FLAG_FAST, otherwise encoding is painfully slow!) and equally libjpeg will handle import/export of JPEGs if SpriteExtend/CompressJPEG cannot.

I have used both a couple of times in the past to good effect, and actually have local hacks to !Paint because I find it – well – embarrassing as well as frustrating that commonplace image formats are not directly supported. I’d rather hoped some of the improvements to Paint, along with the ImageFileConvert/Render modules might meander over from the ‘other’ OS fork.

I see both libraries have been built as ELF shared libraries, and it’d definitely be preferable to avoid needlessly/dangerously running this user-level code in SVC mode in the RMA. AFAIK there will be practical problems using these shared objects from either !Paint or !ChangeFSI so perhaps static linking to local copies of these standard libraries would be a practical first step towards sharing later?

 
Apr 29, 2019 10:41pm
Avatar Andrew Rawnsley (492) 1229 posts

I agree with Adrian. Unless you’re going “full on ImageFileConvert” a la Adjust, creating a shared module for just Paint and ChangeFSI seems, erm, excessive/wasteful.

You could add a module to ChangeFSI and then have !Paint use ChangeFSI (automatically) for PNG/JPEG ops. That would be good. But really, one is BASIC, one is C. It just seems needlessly complicated to make the bounty use a single module, and 3rd party apps can use !ChangeFSI to convert data as needed.

Adrian already has JPEG/PNG in !Paint which is what most of us want anyway.

So, let’s do that first.

Then, get PNG rendering into SpriteExtend (or some such) so that apps can have native PNG rendering (preferably with a soft-load support module for older OSs). Although, I suppose, this may depend on whather Postscript supports PNG objects, otherwise life is trickier for the printing system. I’ll leave that one for others to figure out.

Either way, it is almost certainly better to incorporate existing improvements to !Paint than sit around waiting for someone else. Unless someone has already started and the bounty exists more as a “letter of intent”?

 
Apr 29, 2019 10:45pm
Avatar nemo (145) 2136 posts

So much for unifying API. I’m done here.

 
Apr 30, 2019 2:30am
Avatar Bryan Hogan (339) 448 posts

This bounty seems a bit half-arsed. Why bodge one particular image format into a couple of apps, rather than implement the ImageFileRender/Convert API instead?

That way the facilities become available to all standard apps (Paint, Draw, Filer, Pinboard, etc – import and export) and developers have only one API to deal with across all RISC OS versions to add the facilities to their apps.

 
Apr 30, 2019 7:51am
Avatar Steve Pampling (1551) 6545 posts

Very much in agreement with Bryan and Nemo – one API, no bodges please.

 
Apr 30, 2019 9:00am
Avatar Andrew Rawnsley (492) 1229 posts

To be fair, that’s why I prefixed my message with “Unless you’re going full on ImageFileConvert”. That’s clearly the desireable route, but not what the bounty requests.

I’d dearly love someone (Nemo?) with an understanding of the APIs to do ImageFileConvert. ROD would be happy to fund such work, I suspect (I’d want to check with Richard).

But, here we have a bounty from ROOL, which could be more-or-less achieved with existing (unreleased) work.

 
Apr 30, 2019 12:36pm
Avatar Rick Murray (539) 10579 posts

one API, no bodges please.

I sort of agree. It is “unusual” to implement specific types of alien image handling within Paint, when really this should be an OS service used by Paint.

However, we should not be constrained by an old API unless said API is suitable. I don’t know about you, but I found the IFR API to be somewhat convoluted.

 
Apr 30, 2019 1:14pm
Avatar Steffen Huber (91) 1645 posts

This bounty seems a bit half-arsed. Why bodge one particular image format into a couple of apps, rather than implement the ImageFileRender/Convert API instead?

Because for the “bodge”, it means a simple use of an existing and well-tested library linked directly to the application code and therefore running in user mode which every application code should really do.

For what seems to be considered the “proper” solution, you’d have to

  • define a proper codec API or read and understand and possibly extend and/or fix the IFR/IFC API
  • connect whatever library is suitable for running in a module context
  • end up with something running in supervisor mode that should really run in user mode

Looking at Apache Commons Imaging and Java ImageIO, I am not sure if it is THAT easy to define a sensible API for bitmap conversion/handling!

Always trying to do the universal-and-the-kitchen-sink solution is a sure way to never deliver add-on value for the user in a reasonable time frame. Also, I think that only working with an API will ultimately shape a really good API. Attaching say libpng to !Paint might be a good way to get inspiration for such an API, so although it might look like duplicate work, it might still be a first sensible step.

 
Apr 30, 2019 1:35pm
Avatar Rick Murray (539) 10579 posts

end up with something running in supervisor mode that should really run in user mode

That horse has not only left the stable, it’s gotten old and died and then Hollywood made a movie about it and that was followed by two sequels and associated merchandise.

 
May 1, 2019 5:13pm
Avatar Bryan Hogan (339) 448 posts

Also just realised this is only adding PNG saving to Paint. Surely loading should be in there too?

 
May 1, 2019 5:27pm
Avatar John Williams (567) 773 posts

Can the expertise of Darren Salt be enjoined here: Author of Spr2Png (which works in both directions and more!) – an essential utility in my armoury!

 
May 6, 2019 2:07pm
Avatar Steffen Huber (91) 1645 posts
end up with something running in supervisor mode that should really run in user mode

That horse has not only left the stable, it’s gotten old and died and then Hollywood made a movie about it and that was followed by two sequels and associated merchandise.

And yet, every once in a while when still heading along that dead-end street, it might be valuable to check whether it makes sense to do it in a better way.

Ideal world:

  • the same, interchangeable “shared libraries in userspace” support for DDE and GCC, built into the OS, and accessible from BBC BASIC

Not-ideal-but-vastly-better-than-today world:

  • ELF support for DDE, common libraries are regularly updated and built by ROOL and part of !Boot updates

Still-a-lot-better-than-today world:

  • common libraries are regularly updated and built by ROOL for use by all developers (e.g. SSL/TLS, PNG, JPEG, to name a few of those being discussed in recent bounties)

All IMHO of course. The time taken to convert mbedTLS into a meaningful module is – again IMHO – a sign that this is not the way to handle such libraries in the future.

 
May 6, 2019 2:25pm
Avatar Steve Pampling (1551) 6545 posts

The time taken to convert mbedTLS into a meaningful module is

…probably mostly measured in the time taken to ensure that older (dare I say legacy?) applications can use it as though it was the old SSL module while also allowing new applications to use it in a more modern fashion.

Note that part way through the dev/test period the base code had a security update which appeared faster than the equivalent for a certain mainstream OS (or two). I’m not convinced that would happen if the conversion route had not been used.

 
May 6, 2019 4:49pm
Avatar Steffen Huber (91) 1645 posts

…probably mostly measured in the time taken to ensure that older (dare I say legacy?) applications can use it as though it was the old SSL module while also allowing new applications to use it in a more modern fashion.

Probably it is just me, but I fail to see the big benefit that !Browse can now connect securely to that part of the Internet that is still HTML3.2.

Note that part way through the dev/test period the base code had a security update which appeared faster than the equivalent for a certain mainstream OS (or two). I’m not convinced that would happen if the conversion route had not been used.

If one of the first two scenarios I described would exist, the update could have happened even faster.

 
May 6, 2019 6:48pm
Avatar Steve Pampling (1551) 6545 posts

Probably it is just me, but I fail to see the big benefit that !Browse can now connect securely to that part of the Internet that is still HTML3.2.

I think you missed the point as you say.

The point being that the element of backward compatibility was so good that an elderly item like Browse could use the new module to do something it couldn’t do before.
In the RO world there is a need to smooth the path behind to allow others to catch up to the current situation and move forward to a new situation. This was an instance of that being achieved.
You may not be able to make an omelette without breaking a few eggs, but there really is no need to demolish the whole farm.

 
May 6, 2019 8:20pm
Avatar Rick Murray (539) 10579 posts

it might be valuable to check whether it makes sense to do it in a better way.

Certainly it does. I think system modules (which could be filing systems) should not be in ordinary user space, but then they shouldn’t be in kernel space either. It just so happens that there’s a shiny new1 mode just for this sort of thing. So who’s up for modifying the entirety of RISC OS to handle modules sensibly?
Oh, right. Yeah, I forgot… Developers…

and accessible from BBC BASIC

I wouldn’t hold your breath. BASIC can call SWIs. It can’t deal with code in libraries (of any flavour), and it’s absolutely not APCS compliant. It pretty much predates ALL of that.

The time taken to convert mbedTLS into a meaningful module is – again IMHO – a sign that this is not the way to handle such libraries in the future.

That depends upon the implementation of said conversion. There are essentially two parts – the SSL library, and all the module crap that makes it work on RISC OS.
And, there are essentially two ways of going about such a conversion. Hack the hell out of the library code to bend it to the RISC OS way, or try to touch it as little as possible and keep it as a compartmentalised entity that is built and linked with an appropriate module wrapper.

That we got a security update before certain other mainstream OSs means that the conversion method is just fine, thanks.
Maybe this is an idea of how to do things in the future?

but I fail to see the big benefit that !Browse can now connect securely

You are, of course, making the assumption that it’s only Browse that ever used (or had interest in using) AcornSSL.

If one of the first two scenarios I described would exist, the update could have happened even faster.

Perhaps, but I’d prefer a little slower for something that works well with the rest of the system, than something rushed out “latest greatest” that may not be.

And, let’s face reality here. There are two SSL products. AcornSSL that is new, and SecureSockets that is pretty damn easy to use, but appears to be heavily customised to RISC OS (meaning an update to newer SSL is unlikely). It has to be one or the other because huge swathes of RISC OS use SWIs. A module interface into kernel level code, yes. But it’s a bit churlish to complain about one thing being in kernel space when, in reality, it’s only the user application part of the application that is. Wimp? It’s a module. FileCore? FileAction? Filer? Any FS you care to name? The entire networking stack? All modules. My MIDI module? Guess what… [admittedly the callback handler does run in USR mode, but the SWIs are SVC and the CallAfter is possibly IRQ]

So, we now have an SSL solution from this side of the Millennium Bug and it appears to be fairly easy to update the mbedTLS part and it runs in the expected RISC OS manner.
So your complaint is…?

1 New as in about a quarter century old, but that’s about right, isn’t it?

 
May 6, 2019 9:28pm
Avatar Chris Mahoney (1684) 1687 posts

Probably it is just me, but I fail to see the big benefit that !Browse can now connect securely to that part of the Internet that is still HTML3.2.

It’s not just Browse; anything that uses AcornHTTP got HTTPS “for free”.

 
May 6, 2019 10:06pm
Avatar Steffen Huber (91) 1645 posts

I wouldn’t hold your breath. BASIC can call SWIs. It can’t deal with code in libraries (of any flavour), and it’s absolutely not APCS compliant. It pretty much predates ALL of that.

Surprisingly, my “ideal world” scenario is not yet reality – who would have guessed that.

but I fail to see the big benefit that !Browse can now connect securely

You are, of course, making the assumption that it’s only Browse that ever used

I thought long and hard about any other app, but failed to remember a second one. After all, who in their right mind would have waited 20 years for an update of AcornSSL if security was of any importance?

(or had interest in using) AcornSSL.

If AcornSSL had been kept up-to-date, I am sure that it would have been the go-to solution for a lot of software.

In my mind, both the 20 year update delay of AcornSSL and the SecureSockets update problem show conclusively that putting application code into a module is a bad idea (and keeping it closed source for most of the time is another bad idea of course). For a very long time, the only halfway secure app on RISC OS was NetSurf. Which – surprise, surprise – “just” linked to a lib instead of waiting to get something converted into a module.

And, let’s face reality here. There are two SSL products. AcornSSL that is new, and SecureSockets that is pretty damn easy to use, but appears to be heavily customised to RISC OS (meaning an update to newer SSL is unlikely). It has to be one or the other because huge swathes of RISC OS use SWIs.

There are two examples that used SSL/TLS without either AcornSSL or SecureSockets: NetSurf, and the POPS/SMTPS handlers done by Alex Ausserstorfer (GnuTLS IIRC). This should prove that SWIs are not needed here (although I am not sure if that was your point, because it makes little sense to me).

A module interface into kernel level code, yes. But it’s a bit churlish to complain about one thing being in kernel space when, in reality, it’s only the user application part of the application that is. Wimp? It’s a module. FileCore? FileAction? Filer? Any FS you care to name? The entire networking stack? All modules. My MIDI module?

We are writing in a thread where it was suggested that graphics conversion code should be put into a module and being part of the OS itself. AcornSSL had a certain part of prior history, so you might argue that the damage was already done and to keep it backwards compatible was a good idea. What is the case for the graphics conversion code?

Much of your examples are examples of RISC OS weaknesses that pretty much force you to use modules for certain things. All I’m saying is that, if there are no such reasons that force you to use a module, you shouldn’t (and additionally, developer time would be better invested in removing the weaknesses). Remember the Toolbox desaster? I think the only reason to put a high-level UI library into modules is to keep BASIC programmers happy (and Acorn said so in their reasoning about the way the Toolbox was designed IIRC). There was a great piece of critique written by Mark Wooding about the whole story.

So, we now have an SSL solution from this side of the Millennium Bug and it appears to be fairly easy to update the mbedTLS part and it runs in the expected RISC OS manner.
So your complaint is…?

As long as it will always be kept up to date in a timely manner, and mbedTLS is kept secure by ARM, everything is fine. I just have my doubts that the RISC OS community has the manpower to keep it up to date in the way of a module. See the SecureSockets history.

There are a lot of TLS libs out there. You never know where the next security leak will happen. You might remember heartbleed. And there is the problem of keeping up with new developments like TLS 1.3, elliptic curves and what not. Will the next best lib still fit the AcornSSL way of working?

 
May 6, 2019 11:33pm
Avatar Steve Pampling (1551) 6545 posts

There are two examples that used SSL/TLS without either AcornSSL or SecureSockets: NetSurf, and the POPS/SMTPS handlers done by Alex Ausserstorfer (GnuTLS IIRC). This should prove that SWIs are not needed here (although I am not sure if that was your point, because it makes little sense to me).

Which count as two examples of people being forced down the road of re-inventing the wheel (SSL) because there was no available built in version that could do the job.

What is the case for the graphics conversion code?

The case for building the functionality into the OS or making it match (or least not massively break) existing API’s?

There are a lot of TLS libs out there. You never know where the next security leak will happen.

The patch we got before the final beta of the new SSL wasn’t patching fluff.

And there is the problem of keeping up with new developments like TLS 1.3, elliptic curves and what not.

We will need to deal with TLS 1.3 when it moves from its current experimental status, no doubt the wait for 1.3 support may be as long as the one for the security patch.

 
May 7, 2019 12:58pm
Avatar Rick Murray (539) 10579 posts

There are two examples that used SSL/TLS without either AcornSSL or SecureSockets: NetSurf, and the POPS/SMTPS handlers

Unfortunately the argument falls flat on its face when we look at mbedTLS’s most recent version dates from the end the March of this year. The latest NetSurf, on the other hand…

This should prove that SWIs are not needed here (although I am not sure if that was your point, because it makes little sense to me).

The point being, SWIs are the primary interface RISC OS uses (for better or worse), and if a system resource (a module) gets updated, then everything using it will benefit. Your example of NetSurf, the fetchers, plus Otter and the other one whose name I forget……all would need to be updated individually.

In my mind, both the 20 year update delay of AcornSSL and the SecureSockets update problem show conclusively that putting application code into a module is a bad idea

………this is surely troll logic? There’s nothing, repeat nothing that stopped it being done in the past twenty years other than the fact that nobody did. I’ll add a small disclaimer because I am on break at work, so I can’t look up the age of SecureSockets.

the only halfway secure app on RISC OS was NetSurf. Which – surprise, surprise – “just” linked to a lib instead of waiting to get something converted into a module.

And, yet…

What is the case for the graphics conversion code?

Simple. The module system is how RISC OS works. It was a potentially shonky design decision back in the mid ’80s. However, it is what it is.

The graphics conversion code is because in this day and age, people just expect a modern system to understand certain types of image without needing to jump through hoops like ChangeFSI.

I think the only reason to put a high-level UI library into modules is to keep BASIC programmers happy

Plus the ability to have one copy of the code in memory, instead of every application carrying around the same baggage.
It doesn’t really matter now, with 256MiB as a baseline minimum on new hardware, however back then when 4MiB was the maximum a lot of people had… even the modules alone were seen as too much and as bloat.

You never know where the next security leak will happen.

That is true, however your argument would carry some weight if not for the fact that:

  • This horrible awful module would appear to be the most up to date SSL implementation we have right now.

and:

  • RISC OS is comically insecure. SSL isn’t a magic solution that makes everything bulletproof.

Much of your examples are examples of RISC OS weaknesses that pretty much force you to use modules for certain things.

We’ll all await a better solution that is drop-dead-easy to use from C, assembler, BASIC, and anybody’s favourite script language.
I can see a point for such things as the shared libraries and dynamic linking – just as sure as we don’t travel the route of DLL Hell, one of the weaknesses of RISC OS (can only load one version of a module) forced us all to give a shit about backwards compatibility; not to lead us into a situation where “let’s completely change the API and bump the version number”. However, version stupidity aside, I don’t see a simple (emphasis on SIMPLE) way that such a thing could be implemented from assembler.

Consider http://heyrick.co.uk/random/errorcancel.s.txt which is a module to detect an error opening on the screen, takes a copy of the error text and sends it to DADebug, and sets up an event to automatically cancel the error dialogue after a few seconds. This is to stop ReportError tying up an unattended machine. It is small and simple exactly because of the mechanisms involved. I don’t have to worry about libraries or calling conventions, or anything like that. I simply call a few SWIs and let the OS do the work. I can’t see that using any form of library is going to match that level of simplicity. The fact that BASIC cannot use DDE style AOF libraries pretty much makes that point for me.

Breaktime over. Ho hum. At least I’m now stuffed full of Tetley. :-)

 
May 7, 2019 3:47pm
Avatar Steve Pampling (1551) 6545 posts

Consider http://heyrick.co.uk/random/errorcancel.s.txt which is a module to detect an error opening on the screen, takes a copy of the error text and sends it to DADebug, and sets up an event to automatically cancel the error dialogue after a few seconds. This is to stop ReportError tying up an unattended machine.

Of course if there was a built in logging setup that took all errors and kept them in a file while the multitasking GUI element only popped up notifications for a delimited time.
Note I state delimited rather than limited which should give you the idea that the pop-up error time is configurable, and possibly infinite, while the multitasking element gives the scope to build in things like calling debug tools.

 
May 23, 2019 7:06pm
Avatar Andy Vawer (5817) 21 posts

Looking back it appears that people have various thoughts on what would be nice for image export. The bounty is just for PNG export from Paint/ChangeFSI, but it would make sense to do a little more with it.

It looks like people would like

  • API accessible from C or BASIC but as a shared resource
  • running in USR mode preferably
  • image import as well as export

I’ve done a little experimenting and my thoughts are along the lines of…

  • Create an API that allows conversion from one specified image format to another (eg Sprite→PNG or PNG→Sprite)
  • Some form of enumeration of known formats is useful together with export options
    • Something like Paint can then offer save as PNG, JPEG, etc
    • When a new module is released, the export/import options automatically become available to applications without any further changes to them
  • Build as a module. Probably a single module as with the open source option then other file formats can be incorporated fairly easily in the future by others.
  • Use existing resources rather than reinventing (libpng makes sense)
  • Have a core API for generic conversions but perhaps expose more finetuning options to ‘aware’ applications
  • Call the main workhorse of the API without using SWIs…
    • this allows the main library stuff to run in USR mode
    • from C, it would be a similar idea to the SharedCLibrary. The application requests a jump table from the module and can then call all of the various functions directly. They then run as part of that application.
      • the tiny local part can just be linked directly to the application to hide the jump table part if need be, just exposing a set of library calls.
    • BASIC doesn’t do APCS-32 (or any APCS, really). However, a bit of tinkering has resulted in a veneer that allows direct calling of library functions and extraction of passed BASIC variables.
      • BASIC program issues a SWI to request the jump table.
      • BASIC program can then call library functions using something like CALL jumptable%!convert%, sprite_to_png%, input_buffer%, input_length%, “spritename”, output_buffer%, output_length%, returnblock% to get the same result in USR mode.

Once there’s a functional converter, then an image renderer could be added on as well.

Obviously this works a little differently to the previous API, but I think is quite doable. It still potentially fulfills the bounty requirement when completed (PNG export from Paint/ChangeFSI) but has a little more flexibility. What are people’s thoughts? I’m considering taking this on once my current contributions in progress have been completed.

 
May 24, 2019 1:41am
Avatar Adrian Lees (1349) 122 posts

AFAIK there’s no reason that BASIC could not just use a regular SWI interface (akin to ImageFileConvert/Render) and have the SWI handlers drop into USR mode to call into a shared library, thus reducing stability issues. I could be wrong; perhaps this would violate some assumption of background code in SharedCLibrary/UnixLib somewhere, whichever were used.

Geminus does exactly that, setting up its own USR stack obviously, in order to decode and render large JPEGs whilst allowing background code such as audio streamers to continue running. It’s never caused any problems to my knowledge, but then it doesn’t use a C library.

I’d only suggest that approach if providing an implementation of those existing Image.. APIs, however. A tiny stub module just to provide SWIs in this one specific case would be ugly.

Moreover if an interface to APCSx shared library code were to be implemented, I’d suggest that be separated out from this bounty, and made generic for use with any/all other such libraries, because it’s one thing to make a simple function (appear to) work but quite another to be sure that all the background ugliness* in SharedCLibrary is correctly accommodated.

  • environment handlers, event/vector handlers, static data, workspace pointer.
 
May 24, 2019 1:10pm
Avatar Jeffrey Lee (213) 5852 posts

I could be wrong; perhaps this would violate some assumption of background code in SharedCLibrary/UnixLib somewhere, whichever were used.

I don’t think there’s anything in SCL/UnixLib to worry about. TaskWindow, pthreads, etc. all make use of non-transient callbacks, so they’ll only be invoked when the supervisor stack is empty.

Reply

To post replies, please first log in.

Forums → Bounties →

Search forums

Social

Follow us on and

ROOL Store

Buy RISC OS Open merchandise here, including SD cards for Raspberry Pi and more.

Donate! Why?

Help ROOL make things happen – please consider donating!

RISC OS IPR

RISC OS is an Open Source operating system owned by RISC OS Developments Ltd and licensed primarily under the Apache 2.0 license.

Description

Discussion of items in the bounty list.

Voices

  • Adrian Lees (1349)
  • Andrew Rawnsley (492)
  • nemo (145)
  • Bryan Hogan (339)
  • Steve Pampling (1551)
  • Rick Murray (539)
  • Steffen Huber (91)
  • John Williams (567)
  • Chris Mahoney (1684)
  • Andy Vawer (5817)
  • Jeffrey Lee (213)

Options

  • Forums
  • Login
Site design © RISC OS Open Limited 2018 except where indicated
The RISC OS Open Beast theme is based on Beast's default layout

Valid XHTML 1.0  |  Valid CSS

Powered by Beast © 2006 Josh Goebel and Rick Olson
This site runs on Rails

Hosted by Arachsys