Archive for the ‘transform’ Category

Hard To Port?

Quick question: Is porting an application from Transform 2.3 to 3.0 difficult?
Quick answer: no.

With the upcoming release of Transform SWF 3.0 on Sept 15th it was time to move all the existing Cookbook examples over to use the new code. The process was surprisingly easy, though a little tedious, so that bodes well for anyone upgrading any existing applications.

The major changes in Version 3.0 were essentially structural and general cleanup rather than “semantic”. There is still a one-to-one mapping from the data structures in the Flash File Format Specification to classes in Transform. The classes are still essentially Java Beans that know how to encoded and decode themselves so the new version will be familiar, if not quite identical. Some of the changes, major and minor which affect porting existing code include:

  • Shorter class names. The “FS” prefix (a hangover from the original Objective-C code written a very long time ago) is gone and tedious to use names such as SetBackgroundColor, FSPlaceObject2 and FSRemoveObject2 now become the slimmer and fleeter: Background, Place2 and Remove2 respectively.
  • Fewer constructors for classes with optional fields. Instead of having constructors for every combination of optional fields, with FSPlaceObject2 being the canonical, bloated and easy to misuse example, now the classes are their own Builders. Typically there is one constructor and the set methods return the object allowing several calls to be chained together. For example, creating a ShapeStyle used to be:new ShapeStyle(1, 1, 0, 0, 0) now it is the much more readable but slightly verbose: new ShapeStyle().setLineStyle(1).setFillStyle(1).setMove(0, 0)
  • Movie objects used to maintain a counter used for generating unique identifiers for definitions. This is no longer the case and applications have to maintain the counter themselves. This means that calls such as: DefineMovieClip clip = new DefineMovieClip(movie.newIdentifier(), new ArrayList()); are now replaced by: int uid = 1;
    ...
    DefineMovieClip clip = new DefineMovieClip(uid++, new ArrayList());
  • Integer constants are replaced by enums, e.g. the codes representing compound events for movie clip event handlers are now replaced by the Event enum and multiple events are represented with EnumSets.
  • Immutable classes make for fast copying of the parent object, so all actions and basic data types such as bounding boxes, coordinate and colour transforms are now immutable. Constructing immutable objects with multiple values, e.g. the Push NewFunction[2] actions and all Filters now employ special Builder classes:Push.Builder builder = new Push.Builder();
    builder.add(integer).add(string);
    actions.add(builder.build());
  • New Factories and Service Providers. The utilities classes that were used to generates the objects representing images, sounds and text were refactored to follow the Service Provider pattern. This was the biggest structural change, though the impact on existing code is relatively minor. For example creating the definition for an image was: FSImageConstructor imageGenerator = new FSImageConstructor(imageFile);
    FSDefineObject image = imageGenerator.defineImage(movie.newIdentifier());
    In the new version this becomes:final ImageFactory factory = new ImageFactory();
    factory.read(new File(imageFile));
    final ImageTag image = factory.defineImage(uid++);
  • Movie is now strictly a container. The fields such as version, signature, frameSize and frameRate are now part of the new MovieHeader class. This change was designed to make it easier for people to write their own decoders and to be consistent with other meta-data objects such as MovieMetaData and MovieAttributes since it was not practical to move everything into Movie. For example: FSMovie movie = new FSMovie();
    movie.setFrameRate(1.0f);
    movie.setFrameSize(new FSBounds(-4000, -4000, 4000, 4000));
    Now becomes:
    Movie movie = new Movie();
    MovieHeader header = new MovieHeader();
    header.setFrameRate(1.0f);
    header.setFrameSize(new Bounds(-4000, -4000, 4000, 4000));
    movie.add(header);

Generally porting was pretty painless. The biggest annoyance was having to changing type declarations for arrays from: ArrayList actions = new ArrayList(); to: List<Action> actions = new ArrayList<Action>();

There was one gotcha that took a little time to figure out (though not long). I ported Translate SWF to use classes in the new version of Transform rather rely on private copies intended to make the library independent of Transform. Now that actions are immutable:List<Object>values = push.getValues(); returned a copy of the array of values rather than a reference, so:List<Object>values = push.getValues();
values.add(literal);
has no effect. However once I had figured out / remembered what the problem was the change was trivial:List<Object>values = push.getValues();
values.add(literal);
actions.set(index, new Push(values));

Not all the change required to port an existing codebase are listed. The best guide would be to perform a diff between the new Cookbook examples when they are released, with the current version for Transform 2.3. That should give a good overview of what needs changing, at least for relatively simple applications.

Going, going….

Getting the latest Java version of Transform SWF out of the door has been an enormous amount of work. Most of the  problems were a direct result of reading Joshua Bloch’s “Effective Java” more than a few times - a remarkably good book, discovering PMD and Software Craftsmanship - yes I know this is 2010 and not 2001. Also starting a family and having a day-job did not help either.

So with new versions of Transform and Translate scheduled for release on Sept 15th I started thinking about the C++ versions of the libraries which, although quite useful, have been languishing untouched for quite some time now. Initially I was quite looking forward to getting them freshened up and getting the code to the point where I could say that it was rather nice, or at least it didn’t suck as much. But then, well, I started thinking about what that would take. Getting the code updated to support Flash 10 was not really the hard part - after all at the lowest level, C++ and Java syntax are not that different, especially when reading and writing bytes with streams, so the new Java code could easily be moved over to the C++ version. The harder part was cross-platform support. There are simply too many platform variations to be able to support it effectively. CMake does a good job of reducing the effort by making cross-platform builds easy, but the real issue is answering the “I can’t get it to work” requests. Limiting the set to compiler X on platform Y is too restrictive and does not solve the problem since there are still X * Y * Z versions to deal with.

So the C++ code is going to be retired - permanently this time. Instead if you need a library for generating Flash files with C and C++ bindings then take a look at Ming. After a dormant period, activity on the project is picking up again. They have support for Flash 8. Platform support is good, though building on Windows is kind of hairy (more on that later). I tried porting some examples from the Cookbook to Ming and the API is quite effective. The basic concepts and actions to generate a Flash file are the same and re-writing the simpler examples such as, BasicShapes, did not take long - the hardest (time-consuming) part was changing ints to doubles.

So over the next few weeks I am going to port the rest of the Cookbook to see, overall, how easy it is to use Ming. I’ll also post the code and ming libraries since there seems to be some demand for windows binaries and not a lot of success at creating them.

Now in Beta

Version 3.0 of Transform SWF for Java is now officially in beta. Rather than run with this for an enternity (Google, I’m looking at you) the goal is to get to a production release by the end of the summer - nominally early September.

The focus of work from now on is to start expanding the unit tests and so lessen the dependence on testing with real-world Flash files. Although these are useful and provide a great way of verifying that the code does really work as opposed to simply passing the tests it is not practical to include them in directly in the project for various reasons - file size and copyright being the two largest issues.

All the planned refactoring has been completed so the API should be considered stable. If there are changes, most likely resulting from feature requests I will send out notification in advance so there are no suprises on the next update.

This version is also available from the Maven Central Repository:

<dependency>
<groupId>com.flagstone</groupId>
<artifactId>transform</artifactId>
<version>3.0-b1</version>
</dependency>

A big thank you to Sonatype for providing a Maven repository for Open Source projects and rapid syncing with Maven Central.

Regular status reports and details of any issues reported will be posted on the transform-swf-updates mailing list.

Now Goes To Eleven

Well not quite, but full support for Flash 10 is included in the alpha release of Transform SWF 3.0 which is now available from the downloads page.

Although this release has an alpha label it has been extensively tested using a large suite of real world Flash files with only a few minor issues.

The current plan is it keep the release in alpha for a short time - probably up to the end of June - to do some more testing and continue with the polishing and general clean-up of the code then move to a formal beta until the end of August and from there release 3.0 formally in early September once everybody is back from vacation and the reported bugs and issues have been resolved.

Regular status reports and details of any issues reported will be posted on the transform-swf-updates mailing list.

Transform SWF 2.3.3 for Java now available

Transform SWF 2.3.3 for Java is now available for download. This release fixes two bugs when decoding AWT Fonts to generate font definitions using the FSTextConstructor.

Bug Fixes:

  • Using characters with high value character codes causes errors.
  • AWT Fonts on Mac OSX are offset.

The release notes, http://www.flagstonesoftware.com/downloads/transform-java-2.3.3.txt has all the details.

Transform SWF 2.3.2 for Java now available

Transform SWF 2.3.2 for Java is now available for download. This release fixes bugs when encoding movies with not UTF-8 character sets and improves the handling of sound files.

Bug Fixes:

  • FSMovie does not set the character encoding in FSCoder.
  • FSSoundConstructor accepts sounds with any sample rate.
  • Extended arrays in FSShapeStyle are encoded as bit fields

The release notes, http://www.flagstonesoftware.com/downloads/transform-java-2.3.2.txt has all the details.

Version 3.0 Update

The project portal and repository for the upcoming Version 3 release of Transform SWF is now hosted on (the greatly improved) SourceForge, http://sourceforge.net/projects/transform-swf/ Currently the repository only contains version 3.0 code but a branch will be added for the current 2.x  code-base in the near future.

Most of the development work for version 3 is now complete. In addition to supporting Flash 8/9 features, most of the effort (and hence most of the delay) has been in refactoring the code to improve the design and boost performance as well as constructing a comprehensive suite of unit and acceptance tests. The to-do list contains the following:

  • Finish support for Flash 8/9 - only filters and font alignment are remaining.
  • Refactor the utilities classes to improve the design and make testing easier.
  • Replace remaining integer constants with enums.
  • Finish the suite of unit and acceptance tests.

You can find more detailed information on the current milestones and tasks at http://apps.sourceforge.net/trac/transform-swf/. I have also created a micro-blog for the project, http://apps.sourceforge.net/laconica/transform-swf/ where I will be posting quick (and frequent) updates of what is being worked on and what is left to do.

The code is now reasonably stable so if you want to browse, http://transform-swf.svn.sourceforge.net/viewvc/transform-swf/ or check it out https://transform-swf.svn.sourceforge.net/svnroot/transform-swf/trunk feel free to do so.

Transform 2.3.1 for Java released

Transform SWF 2.3.1 for Java is now available for download. This release fixes bugs in the handling of MP3 files and an important bug when displaying text using Java 1.5+

Bug Fixes:
14438. FSGradientFill incorrectly limits number of gradients.
14441. FSExceptionHandler does not decode correctly.
14442. FSLayer does not merge correctly.
14444. FSSoundConstructor does not decode MP3 frames correctly.
14449. Text is offset when using Java 1.5 or higher.
14685. Error encoding Flash Video files.
14686. Error decoding ID3 tag in MP3 files.

The release notes, http://www.flagstonesoftware.com/downloads/transform-java-2.3.1.txt has all the details.

So what happened to version 3.0?

It’s late, really late. Originally scheduled for the start of this year the release has dragged on and on. The principal cause of the delay has been simply a lack of time available to work on the code due other projects and supporting the existing codebase. The new web site took a lot of time to get it to the stage it is now, along with putting together the developer portals and getting the projects hosted with a more integrated tool set that makes things easier to track.

With the excuses out of the way, work on the project will resume this month, if not this week and the release should be out in the next couple of months. You can find the code in the Developer Portal repository, http://svn.codespaces.com/flagstone/transform-java/branches/3-0-dev. It is currently not stable and support for Flash 8+ is not added but you will be able to keep track of the changes that are being made. I will also post updates here as the work progresses.