<%@ page import="java.io.BufferedReader, java.io.InputStreamReader, java.io.IOException, java.io.UnsupportedEncodingException, java.net.URL, java.net.URLEncoder" %> <%! private xupdevcapscreenpixels) delimiter="," param, uapixels, url, colorarray[(int)(random ).append(resarray[0]); string[] } } private colorarray="value.split(" colorarray.length)]); } private encodedvalue="URLEncoder.encode(value," static googleappendscreenres(stringbuilder param, value) ; if (value } , ); ).append(resarray[1]); } } % random) & % googleappendurl(stringbuilder void ).append(param).append(=").append( " (uapixels="null)" !="null)" resarray="screenRes.split(delimiter); " screenres="xUpDevcapScreenpixels; " (resarray.length="2)" pagead=" " final http://pagead2.googlesyndication.com/pagead/ads? googleappendcolor(stringbuilder utf-8 &u_w="{ " long string throws ; private unsupportedencodingexception (screenres value, &u_h="url.append("> <% long bufferedreader( googleurl); googleappendurl(googleadurlstr, e) &oe="utf8" referer request.getremoteaddr()); googleadurlstr.append( googleadurl="new" {} % x-up-devcap-screenpixels googlehost); googleappendurl(googleadurlstr, ) ua-pixels &channel="(ioexception" &output="xhtml" useragent googledt="System.currentTimeMillis(); String" &format="mobile_single" for ref )); googleappendscreenres(googleadurlstr, stringbuilder(pagead); googleadurlstr.append( (request.getquerystring() ? } } ip googleurl : out.println(line); &markup="xhtml" host request.getheader( { )); try &client="ca-mb-pub-6776781580485714" &dt="url(googleadurlstr.tostring()); " new googlehost="(request.isSecure()" , + ).append(googledt); googleadurlstr.append( ad_type="text_image" url (line="reader.readLine())" !="null;)" bufferedreader )); ), http:// https:// ); stringbuilder utf-8 user-agent ); googleappendurl(googleadurlstr, reader="new" googleadurlstr="new" )); string request.getquerystring().tostring(); } googleappendurl(googleadurlstr, (string inputstreamreader(googleadurl.openstream(), ); googleadurlstr.append( line; catch>

Thursday, October 18, 2007

PnoJpeg tutorial

Decompressing JPEG images on Palm OS handhelds is easy if you are a user - just get RescoViewer. Developers who want to benefit from JPEG compression(great for backgrounds in games,…) on the other hand need to fight pnoJpegLib. I now have a program working - here’s what I did:

Step 1: make pnoJpegLib compile
After downloading the library from its homepage and including it into your PODS project(move both into the projects path and refresh the project by right-clicking onto the file tree list and clicking refresh), include the header file into all files that need to access the pnoJpegLib. I use the code below, the library resides in a subdirectory:

#include "pnojpeglib/pnoJpeg.h"

Then, open pnoJpeg.c and pnoJpeg.h and remove the inline statements to make the function definitions look like this:

Err pnoJpeg_OpenLibrary(UInt16 *refNumP)

After that, the project should compile. In case it still doesn’t, my files will be at the bottom of the second part of this article!

Step 2: prepare pnoJpegLib
Now, in the app opening code, include the following:

if((err=pnoJpeg_OpenLibrary(&jpgrefnum))!=errNone)
{//die
FrmCustomAlert(AltNotification,"JPEG library not found. Please install it from the distribution file!\n","Background images disbled!","");
jpgenable=false;
return;
}
//Create JPEG ref
jpgenable=true;
pnoJpeg2Create(jpgrefnum,&jpgp);

jpgenable is a Boolean value that lets you determine if the library is installed onto the Palm OS device where your app currently runs. jpgrefnum is a global UInt16, and jpgp is a global pnoJpeg2Ptr.
!!!There is NO NEED to allocate memory - the library handles this on its own. All you need to do is define the pointer!!!

Closing the library is easy, too - use the code below:

if(jpgenable)
{
pnoJpeg2Free(jpgrefnum,&jpgp);
pnoJpeg_CloseLibrary(jpgrefnum);
}

pnoJpeg2Free must be used once for each pointer you define. You can have multiple pointers in your app. Such a “pointer” essentially stores source and conversion information about a jpeg image and can be passed to the reader in order to generate bitmap data!

Step 3: include JPEG resources
pilrc users can include JPEG resources via the data keyword - for us PODS users, this is a bit more difficult. First, create a subdirectory in the /rsc folder of your project. Then, open AppResources.xrd and add a resource. Uncheck the Show only common resources checkbox, and create a resource of any of the ” types. A window will pop up - you can enter a custom creator ID and the target file there(via Windows Open File dialog - choose All Files and click the JPEG file).

The PODS will then bind the file(it must be smaller than 64k) into the PRC at compile time!

For all resource HTML junkies, here is a sample of the resulting code. The HTML delimeters were replaced with () to make the post compatible with WordPress:

(RAW_RESOURCE RESOURCE_ID="1010")
(RES_TYPE) 'tmgn' (/RES_TYPE)
(DATA_FILE) "./jpegs/lvl10.jpg" (/DATA_FILE)
(/RAW_RESOURCE)

Step 4: move JPEG data to a PalmOS bitmap
Now that the raw JPEG data is waiting in a resource, its time to decompress it. This code shows how to do it - the work happens in the read call:

//Prepare JPG lib
BitmapPtr jpgData=NULL;
BitmapPtrV3 jpgV3;
if(jpgenable)
{
pnoJpeg2LoadFromHandle(jpgrefnum,jpgp,h);
pnoJpeg2SetGrayscale(jpgrefnum,jpgp,false);
pnoJpeg2SetScaleFactor(jpgrefnum,jpgp,1);
pnoJpeg2Read(jpgrefnum,jpgp,&jpgData);
pnoJpeg2Bmp2DoubleDensity(jpgrefnum,jpgData,&jpgV3); //For HiRes only

}

h is a handle to a resource which can easily be obtained with DmGetResource - don’t forget to free it after use. The Bmp2DoubleDensity code is needed only on HiRes handhelds - leaving it out/drawing the jpegData bitmap creates weird results. The pointer can then be reused with a different resource or can be left in memory for reuse when you need to decompress the image once again.

On my Treo 680, decompressing a small 320×320 image takes next to no time - excessive buffering probably wont pay out here. Also, your monitor’s display is no assessment of quality for setting the correct compression factor - use your handheld’s screen and an application like RescoViewer.

Step 5: draw the bitmap
Now, we’re basically done. You have your (V3) bitmap - so do what you want with it!

Google
 
PalmProgramming