goto statement considered harmful – but not by Samsung??

Back in 1968,the  Dutch computer scientist Edsger Dijkstra published a paper entitled "Go To Statement Considered Harmful" in which he explains why the “goto” statement must be abandoned in favor of structural programming. That paper effectively put an end to gotos and spaghetti programming

 

Well, at least until the world largest manufacturer of electronics decided they knew better. Consider for example the following snippet, copied from the Samsung Bada OS samples:

result MyVibratorClass::VibratorExample() {

	result r = vibrator.Construct();
	if (IsFailed(r)) {
		goto CATCH;
	}

	// Vibrate with a given pattern and level
	vibrator.Start(2000, 1000, 1, 50);
	Thread::Sleep(5000);

CATCH:
	// Do some exception handling
	return r;
}

 

The SDK is literally full of this kind of code:

$ cd /c/mingw/bada/1.0.0b3

$ grep -r goto Examples Samples | wc
    411    1423   25557
$ grep -r CATCH Examples Samples | wc
    498    1471   29823 

 

Now, I know that there are places when you have to use goto (there are quite a few gotos in the Linux code tree), but I am not convinced that that is the case here :(

 

Disclaimer

I am currently playing with Bada and I have to say that while the coding style is really weird, the OS itself seems to be very nice and the development documentation and libraries are very well done and polished.

I am not sure why their code looks like this, maybe I am missing something?  If there are any Samsung developers out there reading this blog, please correct me if I am wrong!

Brainfuck: a very challenging programming language

The Brainfuck programming language is a 8-instruction esoteric programming language that is probably best known for its name.

The Brainfuck J2ME application is an integrated development environment for J2ME-enabled devices. You can download the latest version from getjar.com, or visit the development page here.



Please use this thread to post bug reports.

Evolution of a J2ME user interface

 

From the debugger screen in my Brainfuck app:

First try

Final result

 

For the curious, this is what happened in between:

The green theme was used since all images in this app are kind of Matrix inspired…

 

By the way, this is my first published project that uses the imagelib to scale images on the device.

From breadboard to PCB in 60 seconds

Just a quick one for all you Do-It-Yourselfers out there.

 

Assume you have prototyped some cool electronics on a breadboard. You would love to have your prototype in a more accessible form, but you don’t have enough time or money to design and order a PCB for it. You could like most other DIY:er use a “stripboard” for your prototype, but I found it much faster/easier to use a “prototyping board” which mirrors the connection on the breadboard:

 

CIMG3661 STPBRD2

PROTO777

Breadboard Stripboard “Protoboard”

 

You just “lift” your components from the breadboard to the protoboard and solder the back. This is very easy and there is almost no risk of mistakes – you won’t need to spend hours debugging your circuit afterwards ;)

 

This may sound pretty trivial, but none of the experienced electronic designers I talked to knew about this!

 

The protoboards are slightly more expensive than stripboards, but they are well worth the extra cost. Furthermore, you usually only use a fraction of one board for each project:

 

CIMG3662

(a guitar distortion module and the “Little Gem” amp module– each consuming less than 1/4 of a protoboard)

 

If your local shop does not sell protoboards, you can always order them from DIY-friendly online shops such as Futerlec Electronics.

 

CIMG3665

(my current pile of “work in progress” audio designs)

Image manipulation with J2ME, part 2

(the first article in this series is found here)

Continuing my last post about image manipulation, this article will introduce image resizing routines which are very handy in J2ME application and games where the artwork must look good on many device with different screen sizes.

 

Direct image mapping

Assume you have an image with the dimensions W1xH1, which you want to resize to W2xH2. The easiest way to do this is to that for each pixel (X2, Y2) in the resized image compute the corresponding pixel in the original image:

X1 = (W1 * X2) / W2

Y1 = (H1 * Y2) / H2

Then simply fill pixel (X2, Y2) with the value found at position (X1, Y1) in the original image.

This approach is very simple but the result suffers from jagged pixels that reminds me of the early 3D games:

org resize_direct
Original image Resized image using direct mapping

 

The reason for the artifacts that some reverse-mapped pints (X1, Y1) contain non-integer values and do not directly corresponds to unique pixels.

Filtered mapping

A variation of the direct mapping which produces much better results is the “filtered mapping” algorithm. It uses the interpolation of four points closest to the mapped pixel to achieve better results.

As an example, assume that the direct mapping of the pixel (X2, Y2) gives us the coordinates

P = (X1, Y1) = (10.30, 15.85)

With the direct mapping approach we would simply lookup the pixel (10, 15), but in filtered mapping we will lookup the four pixels

P1 = (10, 15), P2 = (11, 15), P3 = (10, 16), P4 = (11, 16)

Then we will blend all four pixels into a single color using the interpolation factors 30% and 85%.

C = blend( blend(C1, C2, 0.30), blend(C3, ebC4, 0.30), 0.85)

(assuming the C1 is the color of pixel P1 and so on)

Compared to the direct approach, this will produce much better results:

resize_direct resize_aliased
Resized image using direct mapping Resized image using filtered mapping

 

Using mipmaps to reduce artifacts

The filtering algorithm works well when the images are stretched, but when they are shrunken another problem is observed: artifacts in small images. This problem is seen in the image to the left below, where the original phone picture is shrunken from 240×320 to 13×18:

 

resize

mipmap

org
Directly shrunken image ( and then enlarged 10 times to the right) Mipmap-shrunken image The original image

 

Without going into any technical details, we will solve this problem using a variation of tri-linear filtering implemented with the same “halve” operation that we used to generate mipmaps. This approach will result in much more accurate images as seen in the middle image above.

 

The tube42 basic image manipulation library

The image resizing algorithms are stuff I will use very frequently in my upcoming J2ME projects. I also know that some developers are struggling with similar problems in absence of a good standard image library, so I have decided to put together a very basic library and publish it as open source. The library is very simple and contains two short files which are used for color and image manipulation:

 

All color manipulation is done in the ColorUtils class:

// tube42.lib.ui.ColorUtils:
    public static final int blend(int c1, int c2, int value256 )
    public static int mix(int c1, int c2 )
    public static int mix(int c1, int c2, int c3, int c4 )

 

The image manipulation stuff is in the ImageUtils class:

// tube42.lib.ui.ImageUtils:
    public static Image blend(Image img1, Image img2, int value256 )
    public static Image halve(Image org )
    public static Image resize(Image src_i,
              int size_w, int size_h, boolean filter, boolean mipmap )

 

I have also included a very simple demo application to help you get started.

 

Where to get it?

The development page will contain the latest source codes.

Have fun playing with images in Java. And please post ideas, suggestions and report bug to this thread.

Image manipulation with J2ME, part 1

I often need to manipulate images within a J2ME application. The most common case is when I need to scale sprites and images to different screen resolutions. A quick Google search shows that more developers are struggling with image manipulation tasks. Therefore, I have decided to write some very basic image manipulation functions once and for all and release them under the LGPL license.

Of course, the JSR 234: (Advanced Multimedia Supplements) already implements many efficient image manipulation functions, but it is not available on all devices.

 

Color manipulation – 101

In Java, images are generally represented using the 32-bit ARGB8888 format. In this format, each component (Alpha/Red/Green/Blue) is represented by an 8-bit number (0 to 255). The four components are packed into a 32-bit number.

For color manipulation, you usually need to extract each component and manipulate it separately, then join them back to the original 32-bit format. As an example study the following code, which will make the color 50% “darker”:

        int color = ...
	// Extract each component
        int a = (color >> 24) & 0xFF;
        int r = (color >> 16) & 0xFF;
        int g = (color >>  8 ) & 0xFF;
        int b = (color >>  0) & 0xFF;
	// manipulate it:
	r = r / 2;
	g = g / 2;
	b = b / 2;
	// now write it back
        color = (a << 24 ) | (r << 16 ) | (g << 8 ) | b;

Color blending

Assume you have two colors c1 and c2, and you want to compute a new color c3 which is 25% of c1 and 75% of c2. This is often called “blending” and is a very common color operation. The straightforward of doing this is linear interpolation, the naive implementation of which looks like this:

    public static final int blend(int c1, int c2, int value256)
    {
        // how much should we take from each color?
        int v1 = value256 & 0xFF;
        int v2 = 255 - v1;
        // get components
        int a1 = (c1 >> 24 ) & 0xFF;
        int r1 = (c1 >> 16 ) & 0xFF;
        int g1 = (c1 >>  8 ) & 0xFF;
        int b1 = (c1 >>  0 ) & 0xFF;
        int a2 = (c2 >> 24 ) & 0xFF;
        int r2 = (c2 >> 16 ) & 0xFF;
        int g2 = (c2 >>  8 ) & 0xFF;
        int b2 = (c2 >>  0 ) & 0xFF;
        // mix them given the requested amount
        int a = (a1 * v1 + a2 * v2) >> 8;
        int r = (r1 * v1 + r2 * v2) >> 8;
        int g = (g1 * v1 + g2 * v2) >> 8;
        int b = (b1 * v1 + b2 * v2) >> 8;

        return (a << 24) | (r << 16) | (g << 8 ) | b;
    }

A slightly faster version takes advantage of the fact that you can manipulate two components at a time if they cannot overlap. Just split the color = (A, R, G,B) into color1 = (A, _, G, _) and color2 = (_, R, _, B) and you will be fine:

    public static final int blend(int c1, int c2, int value256)
    {
        int v1 = value256 & 0xFF;
        int v2 = 255 - v1;

        int c1_RB = c1 & 0x00FF00FF;
        int c2_RB = c2 & 0x00FF00FF;
        int c1_AG = (c1 >>> 8 ) & 0x00FF00FF;
        int c2_AG = (c2 >>> 8 ) & 0x00FF00FF;
        return
              (((c1_RB * v1 + c2_RB * v2) >> 8 ) & 0x00FF00FF) |
              ((c1_AG * v1 + c2_AG * v2) & 0xFF00FF00);
    }    

Please also note that ">>>" operator in the code above performs unsigned shift in Java, this is often forgotten which leads to very weird problems:

       int a = 0x80000000  >> 1; // this will become 0xC0000000
       int b = 0x80000000 >>> 1; // this will become 0x40000000

Color mixing:

A special case of blending is when you take N colors and mix them equally. Using the previous optimization, the two color version can be written like this:

    public static int mix(int c1, int c2)
    {
        // This corresponds to "blend(c1, c2, 0x7f)"
        int c_RB = (((c1 & 0x00FF00FF) + (c2 & 0x00FF00FF)) >> 1) & 0x00FF00FF;
        int c_AG = (((c1 & 0xFF00FF00) >>> 1) + ((c2 & 0xFF00FF00) >>> 1)) & 0xFF00FF00;
        return c_RB | c_AG;
    }

This becomes just slightly more complicated for four colors:

    public static int mix(int c1, int c2, int c3, int c4)
    {
        int c_RB = (
                  ((c1 & 0x00FF00FF) + (c2 & 0x00FF00FF) + (c3 & 0x00FF00FF)
                   + (c4 & 0x00FF00FF)) >> 2) & 0x00FF00FF;

        int c_AG = (
                  ((c1 & 0xFF00FF00) >>> 2) + ((c2 & 0xFF00FF00) >>> 2) +
                  ((c3 & 0xFF00FF00) >>> 2) + ((c4 & 0xFF00FF00) >>> 2)
                  ) & 0xFF00FF00;
        return c_RB | c_AG;
    }

The 4-color mix is a very handy operation for creating mip-maps,which works like this: take an NxN image and convert it to a (N/2)x(N/2) image by "mixing" every four pixels into a single one. The exact implementation will be shown in a moment.

 

By the way, the above code is actually more clever than it meets the eye. Notice that the Alpha and Green colors are shifted before addition while Red and Blue are shifted after addition. Can you tell me why it must be done this way?

 

Working with images:

To access individual pixels in an image, you can read them to an array of integers using the getRGB function:

public void Image.getRGB(int[] rgbData,
                   int offset,
                   int scanlength,
                   int x,
                   int y,
                   int width,
                   int height)

To put pixels back into an image, you will need to use the drawRGB function of the Graphics class:

public void Graphics.drawRGB(int[] rgbData,
                    int offset,
                    int scanlength,
                    int x,
                    int y,
                    int width,
                    int height,
                    boolean processAlpha)

Of course, if you want to update all pixels at once, you can instead create a new Image using the following function:

public static Image Image.createRGBImage(int[] rgb,
                                   int width,
                                   int height,
                                   boolean processAlpha)

It should be mentioned that the returned image is a memory buffer and is not hardware accelerated. To enable hardware acceleration, you need to create a new Image from it:

        Image img_not_accelerated = Image.createRGBImage(data, w, h, true);
        Image img_accelerated     = Image.createImage(img_not_accelerated);

Blending images

To give you a real example, here a functions which "blends" two whole images into one:

    // blend two images:
    public static Image blend(Image img1, Image img2, int value256)
    {
        // 1. get blended image:
        int w1 = img1.getWidth();
        int h1 = img1.getHeight();
        int w2 = img2.getWidth();
        int h2 = img2.getHeight();

        int w0 = Math.min(w1, w2);
        int h0 = Math.min(h1, h2);
        int [] data = new int[w0 * h0];
        int [] b1 = new int[w0];
        int [] b2 = new int[w0];

        for(int offset = 0, i = 0; i < h0; i++) {
            img1.getRGB( b1, 0, w1, 0, i, w0, 1); // get one line from each
            img2.getRGB( b2, 0, w2, 0, i, w0, 1);

            for(int j = 0; j < w0; j++)  // blend all pixels
                data[offset ++] = blend( b1[j], b2[j], value256);
        }

        return Image.createRGBImage(data, w0, h0, true);
    }

Notice that we read the source images one row at a time. We could read the whole images into the b1 and b2 buffers, but then we would risk running out of memory. There is actually a clever “optimization” that not only reduces memory usage but also speeds things up considerably. I leave that one as an exercise to you :)

 

The above routine was used to create the following series of images which achieve a “morphing” effect:

blend

(blending between two images, click on the image to enlarge)

 

In case you are wondering, the source images are these two:

img2 img1

 

Creating mip-maps:

Another good example for image manipulation is the "halve" function which halves the input images. This function is used to create "mip-maps" , and it build upon our “mix” function which was explained earlier:

    // reduce image dimension to half
    public static Image halve(Image org)
    {
        int w1 = org.getWidth();
        int h1 = org.getHeight();
        int w2 = w1 / 2;
        int h2 = h1 / 2;
        int [] data = new int[w2 * h2];
        int [] buffer = new int[w1 * 2];
        for(int offset = 0, i = 0; i < h2; i++) {
            org.getRGB( buffer, 0, w1, 0, i * 2, w1, 2); // 2 lines from the original

            int o1 = 0, o2 = 1, o3 = w1, o4 = w1 + 1;
            for(int j = 0; j < w2; j++) {
                data[offset ++] = mix( buffer[o1], buffer[o2], buffer[o3], buffer[o4]);
                o1 += 2;
                o2 += 2;
                o3 += 2;
                o4 += 2;
            }
        }

        Image tmp = Image.createRGBImage(data, w2, h2, true);
        data = null; // can this help GC at this point?

        Image ret = Image.createImage(tmp);
        return ret;
    }    

To be continued…

This post is getting a little bit heavy on code snippets. To make things more readable, I will continue the rest in another article, where we will look into image resizing and explain how to make the produced images look “good”.

 

Furthermore, I will release the image manipulation library I promised earlier as open source :)

Color Invasion: yet another color-logic puzzle

Color Invasion is a color puzzle game for J2ME handsets with keypad or touchscreen. The goal of this is to control the entire board with a single color, within a limited number of moves.

 

 

You can download the game from getjar.com, and you will find the development page here.

NOTE: this game is based on the Android game "Coloroid" by Benjamin Lewis.

Your suggestions and ideas are welcome!

Please leave a comment in this thread if you want to report a bug, or suggest improvements.

Mr. Ballmer, would you like to see a paid “Zune ” account on every PC out there?

  1. Migrate all your payment platforms to “Zune Network” and “Zune Store”
  2. Stop giving away Microsoft Live Essentials for free :(
  3. Move all “must have” Windows freebies to Microsoft Live Essentials
  4. Sell the new-and-improved Microsoft Live Essentials for $1.00 (!!) through the Zune Store (this will force everyone to register a paid account)
  5. Charge $0.50 for the yearly upgrade to Microsoft Live Essentials (this make sure that the installed accounts are kept alive)
  6. Release the Windows Phone 7 Series (which are highly integrated to the Zune Store)
  7. ???
  8. profit!!

    Playing with Euler Math Toolbox

    I saw this code on Aaron Ardiri’s blog:

    /* C */
    /**
     ** source piece to convert 8khz to 22khz on the fly (2.75x scaler)
     **/
    
    // 8khz
    //   _MemMove(sound -> pcm, data, size);
    
    // 22khz (converted from 8khz)
         src = data;
         dst = sound -> pcm;
    
         idx = 0;
         for (i=0; i < cnt; i++)
         {
           idx += 93; if (idx > 256) { idx -= 256; src++; }
           *dst++ = *src;
         } 
      This code does a 22/8 scaling. It should be mentioned that you can do this slightly more efficiently by replacing the if-statement with the carry bit:
    /* C */
         for (...){
           tmp  = idx + 94;
           src += tmp >> 8;      // USE THE CARRY BIT INSTEAD OF IF!!!
           idx  = tmp & 0xFF;
           *dst++ = *src;
         } 

    But… the above code is still much slower than the vanilla “unrolled” version:

    /* C */
         [...]
         for (i=cnt/4-1; i; --i) {
           *dst++ = *src;
           *dst++ = *src;
           *dst++ = *src++;
           *dst++ = *src;
           *dst++ = *src++;
           *dst++ = *src;
           *dst++ = *src++;
           // continue this way until we have all 11 samples
           ...
         } 

    In either case, this simple scaling algorithm adds a lot of artifacts to the sample. To visualize this, I created a short 8KHz sample and set Euler Math Toolbox  to plot it together with its spectrum:

    test_org test_org_bode
    Part of the original 8KHz signal (the sound is A4 + 50% A5 + 25% A6, in case you are wondering) The original signal in the frequency domain

     

    This is very easy to do in Euler:

    // Euler
    t = soundsec(0.3, 8000); // 300 ms at 8 KHz
    y = sin(t * 440) + sin(t * 2 * 440) / 2 + sin(t * 4 * 440) / 3;
    
    plot(t[1:100], y[1:100]);
    analyzesound(y, 10, 4000, 8000, 1024);

    Then, using Aaron‘s code, I “scaled”  the sample to 22KHz and this is what I got:

    test_mod test_mod_bode_all
    The “scaled” 22KHz signal in the time domain The “scaled” signal in the frequency domain.

     

    The original signal is there (as the first, second and fourth component in the figure to the right) but  the signal is not “clean” anymore. I used linear interpolation as a cheap way to “fix” this problem:

    /* C */
         [...]
         for (i=cnt/4-1; i; --i) {
           *dst++ = *src;
           *dst++ = *src;
           *dst++ = (3 * *src++) / 4 + (1 * *src) / 4;
           *dst++ = *src;
           *dst++ = *src;
           *dst++ = (2 * *src++) / 4 + (2 * *src) / 4;
           *dst++ = *src;
           *dst++ = *src;
           *dst++ = (1 * *src++) / 4 + (3 * *src) / 4;
           *dst++ = *src;
           *dst++ = *src;
         } 

    The new sample, which sounds far more pleasant to my ears, is shown below:

    test_mod2 test_mod2_bode_all
    The linear interpolation of the scaled signal. In the frequency domain…

     

    The DSP amateur in me is currently trying to figure why these high frequency (4 to 11 KHz) artifices show up after scaling. To solve this mystery I need a math tool with good DSP support.

    The bad news is that there is no DSP support in Euler. The good news is that I am adding it myself, I have already a filter library in place and if Euler can just stop crashing for a second, I may even add some sound processing code. The even better news is that once this is done, it will make it ways into my next mobile app which will be about audio processing …

    So until then, “stay tuned“ ;)

    Well… what do you know…

    bestgame

    Next Page »

  1. My J2ME apps

  2. Tags

    apps Bixi brainfuck Brickade ColorInvasion DSP FPGA GHDL GTKWave hacks imagelib J2ME Java Jibberish KeyInfo Linux NetMonitor OpenSource PRNG PSP rant Roses SameSame SensorApp ZPU
  3. Recent Posts

  4. Categories

  5. Archives

  6. Switch to our mobile site